我的账户、发布等

V0.1
yujialong 1 year ago
parent f2159083d7
commit 36963a0265
  1. 0
      src/assets/images/10.png
  2. BIN
      src/assets/images/account/1.png
  3. BIN
      src/assets/images/account/10.png
  4. BIN
      src/assets/images/account/2.png
  5. BIN
      src/assets/images/account/3.png
  6. BIN
      src/assets/images/account/4.png
  7. BIN
      src/assets/images/account/5.png
  8. BIN
      src/assets/images/account/6.png
  9. BIN
      src/assets/images/account/7.png
  10. BIN
      src/assets/images/account/8.png
  11. BIN
      src/assets/images/account/9.png
  12. BIN
      src/assets/images/back.png
  13. BIN
      src/assets/images/config1.png
  14. BIN
      src/assets/images/config2.png
  15. BIN
      src/assets/images/config3.png
  16. BIN
      src/assets/images/config4.png
  17. BIN
      src/assets/images/config5.png
  18. BIN
      src/assets/images/config6.png
  19. 0
      src/assets/images/fold.png
  20. 0
      src/assets/images/trash.png
  21. 0
      src/assets/images/trash1.png
  22. BIN
      src/assets/images/形状 81.png
  23. BIN
      src/assets/images/矩形 27(1).png
  24. BIN
      src/assets/images/矩形 27.png
  25. 19
      src/components/Back.vue
  26. 44
      src/components/Search.vue
  27. 29
      src/layout/index.vue
  28. 17
      src/router/index.ts
  29. 12
      src/settings.ts
  30. 105
      src/styles/form.scss
  31. 230
      src/views/finance/Account.vue
  32. 230
      src/views/finance/Publish.vue
  33. 160
      src/views/product/Add.vue
  34. 109
      src/views/product/CardList.vue
  35. 150
      src/views/product/Config.vue
  36. 229
      src/views/product/List.vue
  37. 238
      src/views/product/index.vue

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 455 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 401 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 549 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 530 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 306 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 425 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Before

Width:  |  Height:  |  Size: 243 B

After

Width:  |  Height:  |  Size: 243 B

Before

Width:  |  Height:  |  Size: 687 B

After

Width:  |  Height:  |  Size: 687 B

Before

Width:  |  Height:  |  Size: 671 B

After

Width:  |  Height:  |  Size: 671 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 321 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

@ -0,0 +1,19 @@
<template>
<div class="flex items-center p-3 mb-5 bg-white rounded-[10px]">
<div class="inline-flex items-center cursor-pointer">
<img src="@/assets/images/back.png"
alt=""
class="" />
<span class="ml-[6px] text-sm text-[#3C65FF]">返回</span>
</div>
<span class="mx-5 text-sm text-[#999]">|</span>
<span class="text-sm text-[#333]">{{ name }}</span>
</div>
</template>
<script setup lang="ts">
import { defineProps, PropType, ref } from 'vue';
defineProps({
name: { type: String, required: true },
});
</script>

@ -0,0 +1,44 @@
<template>
<div class="search">
<input type="text"
placeholder="搜索"
maxlength="20" />
<img src="@/assets/images/search.png"
alt=""
class="icon" />
</div>
</template>
<script setup lang="ts">
defineProps({
modelValue: { type: String, required: true },
});
</script>
<style lang="scss" scoped>
.search {
display: flex;
align-items: center;
width: 300px;
padding: 0 24px;
background-color: #fff;
border: 1px solid #dfe9f8;
border-radius: 18px;
input {
width: 230px;
height: 36px;
margin-right: 10px;
font-size: 14px;
line-height: 36px;
color: #333;
border: 0;
background-color: transparent;
&:focus {
outline: none;
}
}
.icon {
cursor: pointer;
}
}
</style>

@ -1,21 +1,24 @@
<template> <template>
<div :class="classObj" <div class="expand body min-h-full bg-gray-100">
class="body min-h-full bg-gray-100">
<!--遮罩层当手机模式且左边栏打开时显示遮罩层--> <!--遮罩层当手机模式且左边栏打开时显示遮罩层-->
<div v-if="showMask" <div v-if="showMask"
class="h-full mt-1 w-full absolute z-30 bg-black opacity-30 md:hidden" class="h-full mt-1 w-full absolute z-30 bg-black opacity-30 md:hidden"
@click="closeSidebar" /> @click="closeSidebar" />
<app-header /> <app-header />
<app-sidebar class="sidebar fixed h-full px-5 overflow-hidden transition-width duration-300 z-40" /> <app-sidebar v-if="!hideNav"
<div class="main transition-margin duration-300"> class="sidebar fixed h-full px-5 overflow-hidden transition-width duration-300 z-40" />
<div class="main transition-margin duration-300"
:class="{ 'md:ml-sidebar': !hideNav }">
<app-main /> <app-main />
</div> </div>
</div> </div>
</template> </template>
<script lang="ts"> <script lang="ts">
import { defineComponent, computed } from 'vue'; import { ref, defineComponent, computed, watch } from 'vue';
import { useRoute } from 'vue-router';
import { appState, closeSidebar } from '@/store/useAppState'; import { appState, closeSidebar } from '@/store/useAppState';
import Setting from '@/settings';
import { AppSidebar, AppHeader, AppMain } from './components'; import { AppSidebar, AppHeader, AppMain } from './components';
import useResizeHandler from './composables/useResizeHandler'; import useResizeHandler from './composables/useResizeHandler';
@ -23,6 +26,19 @@ export default defineComponent({
name: 'Layout', name: 'Layout',
components: { AppSidebar, AppHeader, AppMain }, components: { AppSidebar, AppHeader, AppMain },
setup() { setup() {
const route = useRoute();
const hideNav = ref<boolean>(false);
watch(
() => route.path,
(val: any) => {
hideNav.value = Setting.hideNavPath.includes(val);
console.log(33, hideNav.value);
},
{
immediate: true,
},
);
useResizeHandler(); useResizeHandler();
return { return {
closeSidebar, closeSidebar,
@ -31,6 +47,7 @@ export default defineComponent({
expand: appState.sidebar, expand: appState.sidebar,
collapse: !appState.sidebar, collapse: !appState.sidebar,
})), })),
hideNav,
}; };
}, },
}); });
@ -41,7 +58,7 @@ export default defineComponent({
@apply w-sidebar; @apply w-sidebar;
} }
.expand .main { .expand .main {
@apply ml-0 md:ml-sidebar; // @apply ml-0 md:ml-sidebar;
} }
.collapse .sidebar { .collapse .sidebar {
@apply w-0 md:w-sidebar-collapse; @apply w-0 md:w-sidebar-collapse;

@ -25,8 +25,21 @@ export const routes: Array<RouteRecordRaw> = [
path: '/product', path: '/product',
redirect: '/product/index', redirect: '/product/index',
component: Layout, component: Layout,
meta: { title: '产品经理', icon: UserFilled }, meta: { title: '产品经理' },
children: [{ path: 'index', component: () => import('@/views/product/index.vue'), meta: { title: '产品经理' } }], children: [
{ path: 'index', component: () => import('@/views/product/List.vue'), meta: { title: '产品列表' } },
{ path: 'cardList/:action', component: () => import('@/views/product/CardList.vue'), meta: { title: '配置风控' } },
],
},
{
path: '/finance',
// redirect: '/finance/index',
component: Layout,
meta: { title: '金融市场' },
children: [
{ path: 'publish', component: () => import('@/views/finance/Publish.vue'), meta: { title: '发布' } },
{ path: 'account', component: () => import('@/views/finance/Account.vue'), meta: { title: '我的账户' } },
],
}, },
// 404 page must be placed at the end !!! // 404 page must be placed at the end !!!
{ {

@ -3,14 +3,8 @@ export default {
showSettings: true, showSettings: true,
/** /**
* @type {boolean} true | false * @type {array}
* @description Whether fix the header * @description
*/ */
fixedHeader: false, hideNavPath: ['/finance/publish', '/finance/account'],
/**
* @type {boolean} true | false
* @description Whether show the logo in sidebar
*/
sidebarLogo: true,
}; };

@ -0,0 +1,105 @@
.forms {
&.step-form {
.step-name {
padding-top: 5px;
}
}
.step {
position: relative;
padding-left: 42px;
&:before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 30px;
height: 30px;
background: url(../assets/images/config1.png) no-repeat;
}
&:nth-child(2):before {
background-image: url(../assets/images/config2.png);
}
&:nth-child(3):before {
background-image: url(../assets/images/config3.png);
}
&:nth-child(4):before {
background-image: url(../assets/images/config4.png);
}
&:nth-child(5):before {
background-image: url(../assets/images/config5.png);
}
&:nth-child(6):before {
background-image: url(../assets/images/config6.png);
}
&:after {
content: '';
position: absolute;
top: 40px;
left: 14px;
width: 2px;
height: 87%;
background: #006bff;
}
}
.step-name {
font-size: 14px;
font-weight: 600;
color: #006bff;
}
.line {
display: flex;
margin-bottom: 30px;
.label {
margin-right: 5px;
font-size: 14px;
font-weight: 600;
line-height: 32px;
}
.field-name {
font-size: 14px;
font-weight: 600;
line-height: 32px;
color: #333;
}
.tips {
font-size: 14px;
color: #686868;
}
.fields {
flex: 1;
}
.num-inputs {
display: flex;
align-items: center;
.el-input {
width: 200px;
}
.split {
margin: 0 10px;
color: #ccc;
}
.unit {
margin-left: 10px;
font-size: 14px;
color: #333;
}
}
}
.text {
font-size: 14px;
color: #333;
line-height: 32px;
}
.submit {
padding: 15px 22px;
font-size: 14px;
line-height: 1;
color: #fff;
background: #006bff;
border-radius: 12px;
cursor: pointer;
&:hover {
opacity: 0.9;
}
}
}

@ -0,0 +1,230 @@
<template>
<div>
<back name="我的账户"></back>
<div class="flex">
<div class="w-[23%]">
<div class="block mb-5">
<h6 class="title mb-5">关键指标</h6>
<ul class="index">
<li>
<h6 class="title mb-[10px]">收入总额</h6>
<p class="text-lg text-[#F08B14]">696,652,660,000.00</p>
<img src="@/assets/images/account/1.png"
alt=""
class="bg" />
</li>
<li>
<h6 class="title mb-[10px]">支出总额</h6>
<p class="text-lg text-[#4488F4]">696,652,660,000.00</p>
<img src="@/assets/images/account/2.png"
alt=""
class="bg" />
</li>
<li>
<h6 class="title mb-[10px]">累计收益</h6>
<p class="text-lg text-[#FE4953]">696,652,660,000.00</p>
<img src="@/assets/images/account/3.png"
alt=""
class="bg" />
</li>
</ul>
</div>
<div class="block">
<h6 class="title mb-4">今日收入</h6>
<p class="text-lg text-[#FE4953]">696,652,660,000.00</p>
</div>
</div>
<div class="w-[calc(54%-40px)] mx-5">
<div class="block p-[30px] mb-5">
<div class="stat flex justify-between items-center">
<div>
<div class="flex items-center mb-[75px]">
<div class="icon mr-2">
<img src="@/assets/images/account/6.png"
alt="" />
</div>
<div class="">
<h6 class="mb-2 text-base text-[#333]">银行账户</h6>
<p class="text-[#24AD61] font-semibold">3656631.00</p>
</div>
</div>
<div class="flex items-center mb-[75px]">
<div class="icon mr-2">
<img src="@/assets/images/account/7.png"
alt="" />
</div>
<div class="">
<h6 class="mb-2 text-base text-[#333]">保险账户</h6>
<p class="text-[#24AD61] font-semibold">3656631.00</p>
</div>
</div>
<div class="flex items-center">
<div class="icon mr-2">
<img src="@/assets/images/account/8.png"
alt="" />
</div>
<div class="">
<h6 class="mb-2 text-base text-[#333]">基金账户</h6>
<p class="text-[#24AD61] font-semibold">3656631.00</p>
</div>
</div>
</div>
<div class="">
<h6 class="mb-4 title">我的资产(</h6>
<p class="text-xl text-[#4488F4] font-semibold">3656631.00</p>
</div>
<div>
<div class="flex items-center mb-[133px]">
<div class="">
<h6 class="mb-2 text-base text-[#333]">可用账户</h6>
<p class="text-[#448ACA] font-semibold">3656631.00</p>
</div>
<div class="icon blue ml-2">
<img src="@/assets/images/account/9.png"
alt="" />
</div>
</div>
<div class="flex items-center">
<div class="">
<h6 class="mb-2 text-base text-[#333]">冻结账户</h6>
<p class="text-[#448ACA] font-semibold">3656631.00</p>
</div>
<div class="icon blue ml-2">
<img src="@/assets/images/account/10.png"
alt="" />
</div>
</div>
</div>
</div>
</div>
<div class="flex">
<div class="block flex-1 mr-5">
<h6 class="title mb-4">今日成本</h6>
<p class="text-lg text-[#4488F4]">696,652,660,000.00</p>
</div>
<div class="block flex-1">
<h6 class="title mb-4">今日收益</h6>
<p class="text-lg text-[#8E83FB]">696,652,660,000.00</p>
</div>
</div>
</div>
<div class="w-[23%]">
<div class="block mb-5">
<div class="flex justify-between mb-4">
<h6 class="title">交易记录</h6>
<p class="text-sm text-[#333]">2023-08-07</p>
</div>
<ul class="list">
<li>
<div class="inline-flex items-center">
<p class="type">贷出</p>
<p class="des">测试测试测试</p>
</div>
<p class="num">+6,964,665.20</p>
</li>
<li>
<div class="inline-flex items-center">
<p class="type">贷出</p>
<p class="des">测试测试测试</p>
</div>
<p class="num">+6,964,665.20</p>
</li>
</ul>
</div>
<div class="block mb-5">
<h6 class="title mb-4">其他指标</h6>
<ul class="list">
<li>
<p class="type">贷出</p>
<p class="des">测试测试测试</p>
</li>
</ul>
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue';
import { ElMessage } from 'element-plus';
import { Plus } from '@element-plus/icons-vue';
import { primaryTypeOfGuarantee, bankingProductsList } from '@/api/bank';
import Search from '@/components/Search.vue';
import Back from '@/components/Back.vue';
import { pageSizes, pageLayout, toParams, resetParams } from '@/utils/common';
const form = ref<Object>({});
const productVisible = ref<boolean>(false);
const keyword = ref<string>('');
const currentPage = ref<number>(1);
const pageSize = ref<number>(10);
const total = ref<number>(0);
const table = ref<any>();
const list = ref<Array<any>>([]);
const selection = ref<Array<any>>([]);
const loading = ref<boolean>(false);
//
const showProduct = async () => {
productVisible.value = true;
};
//
const getGuarantee = async () => {
try {
const { data } = await primaryTypeOfGuarantee();
guarantees.value = data;
} finally {
}
};
onMounted(() => {
// getGuarantee();
// fetchData();
});
</script>
<style lang="scss" scoped>
.title {
@apply text-lg text-[#333] font-semibold leading-[1];
}
.index {
li {
@apply relative p-5 mb-5;
}
.bg {
@apply absolute top-0 left-0 opacity-20;
}
}
.stat {
padding: 25px 18px;
background: url(../../assets/images/account/5.png) 0 0 / 100% 100% no-repeat;
.icon {
@apply inline-flex justify-center items-center;
width: 50px;
height: 50px;
background: #2cb368;
border: 1px solid #009944;
border-radius: 50%;
&.blue {
background: #448aca;
border-color: #448aca;
}
}
}
.list {
li {
@apply flex justify-between py-2;
border-bottom: 1px solid #e7f0fc;
.type {
@apply p-[6px] mr-[14px] text-sm text-[#556FB5] bg-[rgba(85,111,181,.2)] rounded;
}
.des {
@apply text-sm text-[#333];
}
.num {
@apply text-sm text-[#F02525];
}
}
}
</style>

@ -0,0 +1,230 @@
<template>
<div>
<back name="产品详情"></back>
<div class="block">
<div class="forms w-[700px] mx-auto">
<div class="line">
<label class="label">产品类型</label>
<div class="fields">
<el-input value="银行产品"
disabled></el-input>
</div>
</div>
<div class="line">
<label class="label">选择产品</label>
<div class="fields flex items-center">
<el-input class="mr-5"
placeholder="点击选择需要发布的产品"></el-input>
<div class="btn"
@click="showProduct">新增</div>
</div>
</div>
<div class="line">
<label class="label">产品图标</label>
<div class="fields">
<p class="tips">上传产品LOGO图片</p>
<div class="avatar-uploader"
action="https://run.mocky.io/v3/9d059bf9-4660-45f2-925d-ce80ad6c4d15"
:show-file-list="false">
<img v-if="imageUrl"
:src="imageUrl"
class="avatar" />
<div v-else
class="upload">
<el-icon :size="20">
<Plus :size="20"
color="#DFE9F8" />
</el-icon>
</div>
</div>
</div>
</div>
<div class="line">
<label class="label">贷款规模</label>
<div class="fields flex items-center">
<el-input class="w-48 mr-5"></el-input>
<p class="text-sm text-[#333] ml-4">万元 不得高于现银行账户余额{银行账户余额}</p>
</div>
</div>
<div class="line">
<label class="label">百度渠道</label>
<div class="fields">
<p class="tips">选择需要购买的投放渠道</p>
<div class="route">
<p class="text">{百度广告类型}单次广告价格为{}适用于{}次扫单</p>
<el-input-number v-model="num"
:min="1"
:max="10" />
</div>
<div class="route">
<p class="text">{百度广告类型}单次广告价格为{}适用于{}次扫单</p>
<el-input-number v-model="num"
:min="1"
:max="10" />
</div>
</div>
</div>
<div class="line">
<label class="label">产品上架</label>
<div class="fields">
<el-switch v-model="form.cl" />
</div>
</div>
<div class="flex justify-center">
<div class="btn">确定并发布</div>
</div>
</div>
</div>
<el-dialog v-model="productVisible"
title="选择需要发布的银行产品"
width="1000px"
center>
<div class="flex justify-between mb-4">
<search v-model="keyword"></search>
<el-checkbox label="仅查看未发布的产品" />
</div>
<el-table ref="table"
v-loading="loading"
:data="list">
<el-table-column prop="productNumber"
label="产品名称"></el-table-column>
<el-table-column prop="productNumber"
label="产品编号"></el-table-column>
<el-table-column prop="productNumber"
label="产品对象"></el-table-column>
<el-table-column prop="parentIds"
label="担保方式"></el-table-column>
<el-table-column prop="parentIds"
label="贷款用途"></el-table-column>
<el-table-column prop="loanCeiling"
label="最高额度/年利率/期限"></el-table-column>
<el-table-column prop="createTime"
label="创建日期"></el-table-column>
<el-table-column prop="status"
label="状态"></el-table-column>
</el-table>
<el-pagination v-model:currentPage="currentPage"
v-model:pageSize="pageSize"
:total="total"
:page-sizes="pageSizes"
:layout="pageLayout"
@size-change="fetchData()"
@current-change="fetchData()"
small
background
class="px-3 py-2 justify-end"></el-pagination>
<template #footer>
<span class="flex justify-center">
<div class="btn mr-3 cancel"
@click="productVisible = false">取消</div>
<div class="btn"
@click="productVisible = false">确定</div>
</span>
</template>
</el-dialog>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue';
import { ElMessage } from 'element-plus';
import { Plus } from '@element-plus/icons-vue';
import { primaryTypeOfGuarantee, bankingProductsList } from '@/api/bank';
import Search from '@/components/Search.vue';
import Back from '@/components/Back.vue';
import { pageSizes, pageLayout, toParams, resetParams } from '@/utils/common';
const form = ref<Object>({});
const productVisible = ref<boolean>(false);
const keyword = ref<string>('');
const currentPage = ref<number>(1);
const pageSize = ref<number>(10);
const total = ref<number>(0);
const table = ref<any>();
const list = ref<Array<any>>([]);
const selection = ref<Array<any>>([]);
const loading = ref<boolean>(false);
//
const showProduct = async () => {
productVisible.value = true;
};
//
const getGuarantee = async () => {
try {
const { data } = await primaryTypeOfGuarantee();
guarantees.value = data;
} finally {
}
};
onMounted(() => {
// getGuarantee();
// fetchData();
});
</script>
<style lang="scss" scoped>
.forms {
.line {
display: flex;
margin-bottom: 12px;
}
.fields {
flex: 1;
}
.label {
margin-right: 5px;
font-size: 14px;
line-height: 32px;
color: #333;
}
.el-input {
width: 500px;
}
.tips {
margin-bottom: 12px;
font-size: 14px;
line-height: 32px;
color: #333;
}
.upload {
display: flex;
justify-content: center;
align-items: center;
width: 70px;
height: 70px;
border: 1px solid #dfe9f8;
border-radius: 8px;
cursor: pointer;
}
.route {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 6px;
.text {
font-size: 14px;
color: #333;
}
.el-input-number {
width: 100px;
}
}
}
.btn {
padding: 11px 26px;
font-size: 14px;
line-height: 1;
color: #fff;
background: linear-gradient(-36deg, #006bff, #2ab1ff);
border-radius: 18px;
cursor: pointer;
&.cancel {
font-size: 600;
color: #333;
background: #f4f8fc;
}
}
</style>

@ -0,0 +1,160 @@
<template>
<div>
<el-tabs v-model="curTab"
@tab-click="tabChange">
<el-tab-pane label="新增产品"
name="tab1">
<div class="forms">
<div class="line">
<label class="label">产品定义</label>
<div class="fields">
<el-input type="textarea"
placeholder="用一段话简单介绍一下这个产品或者描述产品的设计理念。例如:本产品根据个人客户的信用状况,为其提供的一种短期融资便利产品,借款人可在额度金额内可循环周转使用贷款。"
maxlength="200"></el-input>
</div>
</div>
<div class="line">
<label class="label">产品名称</label>
<div class="fields">
<el-input placeholder="取个有吸引力的产品名,限20字。"
maxlength="20"></el-input>
</div>
</div>
<div class="line">
<label class="label">产品币种</label>
<div class="fields">
<el-select v-model="modelValue.status"
placeholder="请选择">
<el-option label="人民币"
value="1" />
</el-select>
</div>
</div>
<div class="line">
<label class="label">贷款对象</label>
<div class="fields">
<p class="field-name">选择本产品的贷款对象</p>
<el-checkbox-group v-model="modelValue.cl">
<el-checkbox label="身份证" />
<el-checkbox label="身份证" />
</el-checkbox-group>
</div>
</div>
<div class="line">
<label class="label">贷款用途</label>
<div class="fields">
<p class="field-name">选择本产品贷款资金的用途</p>
<el-radio-group v-model="modelValue.cl">
<el-radio :label="3">Option A</el-radio>
<el-radio :label="9">Option C</el-radio>
</el-radio-group>
</div>
</div>
<div class="line">
<label class="label">担保方式</label>
<div class="fields">
<p class="field-name">选择本产品的担保种类</p>
<el-checkbox-group v-model="modelValue.cl">
<el-checkbox label="身份证" />
<el-checkbox label="身份证" />
</el-checkbox-group>
</div>
</div>
<div class="line">
<label class="label">贷款额度</label>
<div class="fields">
<div class="num-inputs">
<el-input placeholder="最小额度"
min="0"></el-input>
<span class="split">-</span>
<el-input placeholder="最高额度"
min="0"></el-input>
<span class="unit">万元</span>
</div>
</div>
</div>
<div class="line">
<label class="label">贷款利率</label>
<div class="fields">
<div class="num-inputs">
<el-input placeholder="最小年利率"
min="0"></el-input>
<span class="split">-</span>
<el-input placeholder="最高年利率"
min="0"></el-input>
<span class="unit">%</span>
</div>
</div>
</div>
<div class="line">
<label class="label">贷款期限</label>
<div class="fields">
<div class="num-inputs">
<el-input placeholder="最小期限"
min="0"></el-input>
<span class="split">-</span>
<el-input placeholder="最大期限"
min="0"></el-input>
<span class="unit"></span>
</div>
</div>
</div>
<div class="line">
<label class="label">还款方式</label>
<div class="fields">
<p class="field-name">选择本产品可以选择的还款方式</p>
<el-checkbox-group v-model="modelValue.cl">
<el-checkbox label="身份证" />
<el-checkbox label="身份证" />
</el-checkbox-group>
</div>
</div>
<div class="line">
<label class="label">提前还款</label>
<div class="fields flex items-center">
<el-switch v-model="modelValue.cl" />
<p class="tips ml-4">本产品是否支持提前还款</p>
</div>
</div>
<div class="flex justify-end">
<div class="submit">完成提交审批</div>
</div>
</div>
</el-tab-pane>
</el-tabs>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue';
import { ElMessage } from 'element-plus';
import type { TabsPaneContext } from 'element-plus';
import { primaryTypeOfGuarantee, bankingProductsList } from '@/api/bank';
defineProps({ modelValue: { type: Object, required: true } });
defineEmits({ 'update:form': null });
const curTab = ref<string>('tab1');
// tab
const tabChange = (tab: TabsPaneContext, event: Event) => {
console.log(tab, event);
};
//
const getGuarantee = async () => {
try {
const { data } = await primaryTypeOfGuarantee();
guarantees.value = data;
} finally {
}
};
onMounted(() => {
// getGuarantee();
// fetchData();
});
</script>
<style lang="scss" scoped>
@import url(../../styles/form.scss);
</style>

@ -0,0 +1,109 @@
<template>
<div class="block flex"
style="padding-top: 0">
<div class="left pr-5 py-4">
<div class="flex justify-end mb-4">
<img src="@/assets/images/fold.png"
alt=""
class="cursor-pointer" />
</div>
<ul class="products">
<li>
<img src="@/assets/images/trash.png"
alt=""
class="del" />
<h6>轻松贷</h6>
<p class="type">个人信用贷</p>
<p class="status">配置风控</p>
<p class="date">创建日期2021-02-26</p>
</li>
<li>
<h6>轻松贷</h6>
<p class="type">个人信用贷</p>
<p class="status">配置风控</p>
<p class="date">创建日期2021-02-26</p>
</li>
</ul>
</div>
<div class="right flex-1 px-5 pt-2">
<!-- <component :is="Config"
v-model="form"></component> -->
<config v-if="action === 'config'"
v-model="form"></config>
<add v-else-if="action === 'add'"
v-model="form"></add>
</div>
</div>
</template>
<script setup lang="ts">
import { computed, onMounted, ref } from 'vue';
import { ElMessage } from 'element-plus';
import { perm } from '@/store/useCurrentUser';
import { primaryTypeOfGuarantee, bankingProductsList } from '@/api/bank';
import { useRouter, useRoute } from 'vue-router';
import Config from './Config.vue';
import Add from './Add.vue';
const router = useRouter();
const route = useRoute();
const { action } = route.params;
const form = ref<any>({
cl: '',
});
const loading = ref<boolean>(false);
//
const getGuarantee = async () => {
try {
const { data } = await primaryTypeOfGuarantee();
guarantees.value = data;
} finally {
}
};
onMounted(() => {
console.log(33, useRoute().params.action);
// getGuarantee();
// fetchData();
});
const handleDelete = async (ids: number[]) => {
await deleteUser(ids);
fetchData();
// ElMessage.success(t('success'));
};
</script>
<style lang="scss" scoped>
.left {
border-right: 1px solid #e9eff2;
}
.products {
li {
position: relative;
width: 220px;
padding: 20px;
margin-bottom: 20px;
background: url(../../assets/images/10.png) 0 0/100% 100% no-repeat;
border-radius: 10px;
cursor: pointer;
}
.del {
position: absolute;
top: 0;
right: 0;
}
h6 {
color: #14436b;
}
.type,
.status {
margin: 15px 0;
font-size: 14px;
color: #333;
}
.date {
font-size: 14px;
color: #8798a9;
}
}
</style>

@ -0,0 +1,150 @@
<template>
<div>
<el-tabs v-model="curTab"
@tab-click="tabChange">
<el-tab-pane label="配置风控"
name="tab1">
<div class="audit">
<div class="line">
<span class="field">审批意见</span>
<span class="status">待审批</span>
</div>
<div class="line">
<span class="field">意见描述</span>
习近平总书记在二十届中央政治局第六次集体学习时强调党的二十大报告在总结历史经验基础上提出并阐述了
个结合六个必须坚持等推进理论创新的科学方法为继续推进党的理论创新提供了根本遵循这一重要论述两个结合
六个必须坚持一同列为推进理论创新的科学方法深刻阐明了两个结合作为认识世界
</div>
<p class="mb-2 text-sm text-[#333] text-right">审查日期2022-02-02</p>
<p class="mb-2 text-sm text-[#333] text-right">审查员公瑾</p>
</div>
<div class="forms step-form">
<div class="step">
<h6 class="step-name mb-7">办理账户</h6>
<div class="line">
<label class="label">提供材料</label>
<div class="fields">
<el-checkbox-group v-model="modelValue.cl">
<el-checkbox label="身份证" />
<el-checkbox label="身份证" />
</el-checkbox-group>
</div>
</div>
<div class="line">
<label class="label">发放账户</label>
<div class="fields">
<el-checkbox-group v-model="modelValue.cl">
<el-checkbox label="身份证" />
</el-checkbox-group>
</div>
</div>
</div>
<div class="step">
<h6 class="step-name mb-7">贷款申请</h6>
<div class="line">
<label class="label">申请方式</label>
<div class="fields">
<el-checkbox-group v-model="modelValue.cl">
<el-checkbox label="身份证" />
<el-checkbox label="身份证" />
</el-checkbox-group>
</div>
</div>
<div class="line">
<label class="label">提供材料</label>
<div class="fields">
<p class="field-name">贷款人材料</p>
<div>
<el-checkbox-group v-model="modelValue.cl">
<el-checkbox label="身份证" />
</el-checkbox-group>
</div>
<p class="field-name mt-5">配偶材料</p>
<div>
<el-checkbox-group v-model="modelValue.cl">
<el-checkbox label="身份证" />
</el-checkbox-group>
</div>
<p class="field-name mt-5">经营类材料</p>
<div>
<el-checkbox-group v-model="modelValue.cl">
<el-checkbox label="身份证" />
</el-checkbox-group>
</div>
<p class="field-name mt-5">补充材料</p>
<div>
<el-checkbox-group v-model="modelValue.cl">
<el-checkbox label="身份证" />
</el-checkbox-group>
</div>
</div>
</div>
</div>
<div class="flex justify-end">
<div class="submit">完成提交审批</div>
</div>
</div>
</el-tab-pane>
<el-tab-pane label="产品要素"
name="tab2">
<div class="forms">
<h6 class="step-name mb-4">办理账户</h6>
<p class="text">根据个人客户的信用状况为其提供的一种短期融资便利产品借款人在我行核定的额度金额内可循环周转使用贷款</p>
<h6 class="step-name mt-5">产品要素</h6>
<div class="line">
<label class="label">产品名称</label>
<p class="text">根据个人客户的信用状况为其提供的一种短期融资便利产品借款人在我行核定的额度金额内可循环周转使用贷款</p>
</div>
</div>
</el-tab-pane>
</el-tabs>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue';
import { ElMessage } from 'element-plus';
import type { TabsPaneContext } from 'element-plus';
import { primaryTypeOfGuarantee, bankingProductsList } from '@/api/bank';
defineProps({ modelValue: { type: Object, required: true } });
defineEmits({ 'update:form': null });
const curTab = ref<string>('tab1');
// tab
const tabChange = (tab: TabsPaneContext, event: Event) => {
console.log(tab, event);
};
//
const getGuarantee = async () => {
try {
const { data } = await primaryTypeOfGuarantee();
guarantees.value = data;
} finally {
}
};
onMounted(() => {
// getGuarantee();
// fetchData();
});
</script>
<style lang="scss" scoped>
@import url(../../styles/form.scss);
.audit {
padding: 20px 16px;
margin-bottom: 30px;
background: #f9fafc;
border-radius: 10px;
.line {
margin-bottom: 18px;
font-size: 14px;
line-height: 1.6;
}
.field {
font-size: 14px;
font-weight: 600;
}
}
</style>

@ -0,0 +1,229 @@
<template>
<div class="block">
<div class="flex justify-between items-center mb-5">
<search v-model="params.keyWord"></search>
<div class="filter">
<div class="select">
<el-select v-model="params.guarantyStyleId"
placeholder="担保方式"
size="large">
<el-option label="担保方式"
value="" />
<el-option v-for="item in guarantees"
:key="item.id"
:label="item.guarantyStyle"
:value="item.id" />
</el-select>
<img src="@/assets/images/7.png"
alt=""
class="icon" />
</div>
<div class="select">
<el-select v-model="params.status"
placeholder="产品进度"
size="large">
<el-option v-for="item in paces"
:key="item.id"
:label="item.name"
:value="item.id" />
</el-select>
<img src="@/assets/images/8.png"
alt=""
class="icon" />
</div>
<div class="add-btn">
<img src="@/assets/images/plus.png"
alt=""
class="icon" />
新增产品
</div>
<img src="@/assets/images/9.png"
alt=""
class="ml-4 cursor-pointer"
@click="toCardList" />
</div>
</div>
<el-table ref="table"
v-loading="loading"
:data="list"
@sort-change="handleSort">
<el-table-column prop="productName"
label="产品名称"></el-table-column>
<el-table-column prop="productNumber"
label="产品编号"></el-table-column>
<el-table-column prop="parentIds"
label="担保方式"></el-table-column>
<el-table-column prop="loanCeiling"
label="最高额度/年利率/期限"></el-table-column>
<el-table-column prop="createTime"
label="创建日期"></el-table-column>
<el-table-column prop="status"
label="产品进度"></el-table-column>
<el-table-column prop="id"
label="操作">
<template #default="{ row }">
<el-button type="text"
@click="handleEdit(row.id)"
size="small">配置要素</el-button>
<el-button type="text"
@click="handleEdit(row.id)"
size="small">产品详情</el-button>
<el-button type="text"
@click="handleEdit(row.id)"
size="small">删除</el-button>
</template></el-table-column>
</el-table>
<el-pagination v-model:currentPage="currentPage"
v-model:pageSize="pageSize"
:total="total"
:page-sizes="pageSizes"
:layout="pageLayout"
@size-change="fetchData()"
@current-change="fetchData()"
small
background
class="px-3 py-2 justify-end"></el-pagination>
</div>
</template>
<script setup lang="ts">
import { computed, onMounted, ref } from 'vue';
import { ElMessage } from 'element-plus';
import { useI18n } from 'vue-i18n';
import dayjs from 'dayjs';
import { perm } from '@/store/useCurrentUser';
import { pageSizes, pageLayout, toParams, resetParams } from '@/utils/common';
import { primaryTypeOfGuarantee, bankingProductsList } from '@/api/bank';
import Search from '@/components/Search.vue';
import { useRouter } from 'vue-router';
const { t } = useI18n();
const params = ref<any>({
createDateSort: '',
guarantyStyleId: '',
keyWord: '',
productType: '',
status: '',
});
const router = useRouter();
const sort = ref<any>();
const currentPage = ref<number>(1);
const pageSize = ref<number>(10);
const total = ref<number>(0);
const table = ref<any>();
const guarantees = ref<Array<any>>([]);
const paces = ref<Array<any>>([
{
id: 1,
name: '配置风控',
},
{
id: 2,
name: '待审批',
},
{
id: 3,
name: '审批通过',
},
{
id: 4,
name: '审批不通过',
},
{
id: 5,
name: '审批打回',
},
]);
const list = ref<Array<any>>([]);
const selection = ref<Array<any>>([]);
const loading = ref<boolean>(false);
const beanId = ref<number>();
//
const getGuarantee = async () => {
try {
const { data } = await primaryTypeOfGuarantee();
guarantees.value = data;
} finally {
}
};
//
const fetchData = async () => {
loading.value = true;
try {
const { data } = await bankingProductsList({ pageNum: currentPage.value, pageSize: pageSize.value, ...toParams(params.value) });
list.value = data.message.records;
total.value = data.message.total;
} finally {
loading.value = false;
}
};
onMounted(() => {
getGuarantee();
fetchData();
});
const handleSort = ({ column, prop, order }: { column: any; prop: string; order: string }) => {
if (prop) {
sort.value = (column.sortBy ?? prop) + (order === 'descending' ? '_desc' : '');
} else {
sort.value = undefined;
}
fetchData();
};
//
const toCardList = () => {
router.push('/product/cardList/config');
};
const handleAdd = () => {
beanId.value = undefined;
};
const handleEdit = (id: number) => {
beanId.value = id;
};
const handleDelete = async (ids: number[]) => {
await deleteUser(ids);
fetchData();
ElMessage.success(t('success'));
};
const deletable = (bean: any) => bean.id > 1;
</script>
<style lang="scss" scoped>
.filter {
display: inline-flex;
align-items: center;
.select {
position: relative;
margin-right: 12px;
.icon {
position: absolute;
top: 12px;
left: 20px;
}
:deep(.el-select) {
width: 170px;
.el-input__inner {
padding-left: 41px;
border-radius: 18px;
border-color: #dfe9f8;
}
}
}
.add-btn {
display: inline-flex;
align-items: center;
height: 36px;
padding: 0 24px;
font-size: 14px;
color: #fff;
background: linear-gradient(-36deg, #006bff, #2ab1ff);
border: 1px solid #ffffff;
border-radius: 18px;
cursor: pointer;
.icon {
margin-right: 8px;
}
}
}
</style>

@ -1,238 +0,0 @@
<template>
<div>
<div class="block">
<div class="flex justify-between items-center mb-5">
<div class="search">
<input type="text"
placeholder="搜索"
maxlength="20" />
<img src="@/assets/images/search.png"
alt=""
class="icon" />
</div>
<div class="filter">
<div class="select">
<el-select v-model="guarantyStyleId"
placeholder="担保方式"
size="large">
<el-option label="担保方式"
value="" />
<el-option v-for="item in guarantees"
:key="item.id"
:label="item.guarantyStyle"
:value="item.id" />
</el-select>
<img src="@/assets/images/7.png"
alt=""
class="icon" />
</div>
<div class="select">
<el-select v-model="pace"
placeholder="产品进度"
size="large">
<el-option v-for="item in paces"
:key="item.id"
:label="item.name"
:value="item.id" />
</el-select>
<img src="@/assets/images/8.png"
alt=""
class="icon" />
</div>
<div class="add-btn">
<img src="@/assets/images/plus.png"
alt=""
class="icon" />
新增产品
</div>
<img src="@/assets/images/9.png"
alt=""
class="ml-4 cursor-pointer" />
</div>
</div>
<el-table ref="table"
v-loading="loading"
:data="list"
@sort-change="handleSort">
<el-table-column prop="id"
label="产品名称"></el-table-column>
<el-table-column prop="id"
label="产品编号"></el-table-column>
<el-table-column prop="id"
label="担保方式"></el-table-column>
<el-table-column prop="id"
label="最高额度/年利率/期限"></el-table-column>
<el-table-column prop="id"
label="创建日期"></el-table-column>
<el-table-column prop="id"
label="产品进度"></el-table-column>
<el-table-column prop="id"
label="操作">
<template #default="{ row }">
<el-button type="text"
@click="handleEdit(row.id)"
size="small">配置要素</el-button>
<el-button type="text"
@click="handleEdit(row.id)"
size="small">产品详情</el-button>
<el-button type="text"
@click="handleEdit(row.id)"
size="small">删除</el-button>
</template></el-table-column>
</el-table>
<el-pagination v-model:currentPage="currentPage"
v-model:pageSize="pageSize"
:total="total"
:page-sizes="pageSizes"
:layout="pageLayout"
@size-change="fetchData()"
@current-change="fetchData()"
small
background
class="px-3 py-2 justify-end"></el-pagination>
</div>
</div>
</template>
<script setup lang="ts">
import { computed, onMounted, ref } from 'vue';
import { ElMessage } from 'element-plus';
import { Search } from '@element-plus/icons-vue';
import { useI18n } from 'vue-i18n';
import dayjs from 'dayjs';
import { perm } from '@/store/useCurrentUser';
import { pageSizes, pageLayout, toParams, resetParams } from '@/utils/common';
import { primaryTypeOfGuarantee, bankingProductsList } from '@/api/bank';
const { t } = useI18n();
const params = ref<any>({
createDateSort: '',
guarantyStyleId: '',
keyWord: '',
productType: '',
status: '',
});
const sort = ref<any>();
const currentPage = ref<number>(1);
const pageSize = ref<number>(10);
const total = ref<number>(0);
const table = ref<any>();
const guarantyStyleId = ref<any>('');
const guarantees = ref<Array<any>>([]);
const pace = ref<any>('');
const paces = ref<Array<any>>([]);
const list = ref<Array<any>>([]);
const selection = ref<Array<any>>([]);
const loading = ref<boolean>(false);
const beanId = ref<number>();
//
const getGuarantee = async () => {
try {
const { data } = await primaryTypeOfGuarantee();
guarantees.value = data;
} finally {
}
};
//
const fetchData = async () => {
loading.value = true;
try {
const { data } = await bankingProductsList({ pageNum: currentPage.value, pageSize: pageSize.value, ...toParams(params.value) });
list.value = data.message.records;
total.value = data.message.total;
} finally {
loading.value = false;
}
};
onMounted(() => {
getGuarantee();
fetchData();
});
const handleSort = ({ column, prop, order }: { column: any; prop: string; order: string }) => {
if (prop) {
sort.value = (column.sortBy ?? prop) + (order === 'descending' ? '_desc' : '');
} else {
sort.value = undefined;
}
fetchData();
};
const handleSearch = () => fetchData();
const handleAdd = () => {
beanId.value = undefined;
};
const handleEdit = (id: number) => {
beanId.value = id;
};
const handleDelete = async (ids: number[]) => {
await deleteUser(ids);
fetchData();
ElMessage.success(t('success'));
};
const deletable = (bean: any) => bean.id > 1;
</script>
<style lang="scss" scoped>
.search {
display: flex;
align-items: center;
width: 300px;
padding: 0 24px;
background-color: #fff;
border: 1px solid #dfe9f8;
border-radius: 18px;
input {
width: 230px;
height: 36px;
margin-right: 10px;
font-size: 14px;
line-height: 36px;
color: #333;
border: 0;
background-color: transparent;
&:focus {
outline: none;
}
}
.icon {
cursor: pointer;
}
}
.filter {
display: inline-flex;
align-items: center;
.select {
position: relative;
margin-right: 12px;
.icon {
position: absolute;
top: 12px;
left: 20px;
}
:deep(.el-select) {
width: 170px;
.el-input__inner {
padding-left: 41px;
border-radius: 18px;
border-color: #dfe9f8;
}
}
}
.add-btn {
display: inline-flex;
align-items: center;
height: 36px;
padding: 0 24px;
font-size: 14px;
color: #fff;
background: linear-gradient(-36deg, #006bff, #2ab1ff);
border: 1px solid #ffffff;
border-radius: 18px;
cursor: pointer;
.icon {
margin-right: 8px;
}
}
}
</style>
Loading…
Cancel
Save