金融市场-银行

V0.1
yujialong 10 months ago
parent c437da1c40
commit 4385cfab8c
  1. 0
      src/assets/images/role/market-bank.png
  2. 0
      src/assets/images/role/market-bank1.png
  3. 0
      src/assets/images/role/market-fund.png
  4. 0
      src/assets/images/role/market-fund1.png
  5. 0
      src/assets/images/role/market-insurance.png
  6. 0
      src/assets/images/role/market-insurance1.png
  7. 0
      src/assets/images/role/my-product.png
  8. 0
      src/assets/images/role/my-product1.png
  9. 10
      src/components/Back.vue
  10. 6
      src/components/Panel/index.vue
  11. 6
      src/layout/index.vue
  12. 1
      src/router/index.ts
  13. 9
      src/views/Role.vue
  14. 2
      src/views/config/param/Buyer.vue
  15. 304
      src/views/finance/Bank.vue
  16. 141
      src/views/finance/BankDetail.vue

Before

Width:  |  Height:  |  Size: 4.9 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

Before

Width:  |  Height:  |  Size: 9.7 KiB

After

Width:  |  Height:  |  Size: 9.7 KiB

@ -1,7 +1,7 @@
<template>
<div class="flex items-center p-3 mb-5 bg-white rounded-[10px]">
<div class="inline-flex items-center cursor-pointer"
@click="logout">
@click="back">
<img src="@/assets/images/back.png"
alt=""
class="" />
@ -12,12 +12,16 @@
</div>
</template>
<script setup lang="ts">
import { PropType, ref } from 'vue';
import { onMounted, ref } from 'vue';
import { useRouter, useRoute } from 'vue-router';
import { logout } from '@/store/useCurrentUser';
defineProps({
const props = defineProps({
name: { type: String, required: true },
isLogout: { type: Boolean, default: false },
});
const router = useRouter();
const back = () => {
props.isLogout ? logout() : router.back();
};
</script>

@ -644,7 +644,7 @@ const close = () => {
// socket
const initSocket = () => {
// socket
const socket = new WebSocket(`ws://${location.host}/nakadai/websocket/${param.userId}/${param.account}`);
const socket = new WebSocket(`wss://${location.host}/nakadai/websocket/${param.userId}/${param.account}`);
// this.socket = new WebSocket(`ws://121.37.12.51:9100/nakadai/websocket/${id}/${account}`)
// socket
socket.onopen = open;
@ -661,13 +661,13 @@ onMounted(() => {
param.cid && getEntryTime();
if (param.assessmentId) {
initSocket();
getAssList();
initSocket();
} else {
param.cid && getList();
if (param.competitionId) {
initSocket();
getCompetitionStatus();
initSocket();
}
}
});

@ -3,7 +3,8 @@
<app-header />
<Back v-if="hidePanel"
class="mx-3"
name="金融产品设计及数字化营销沙盘系统后台管理系统" />
name="金融产品设计及数字化营销沙盘系统后台管理系统"
:isLogout="true" />
<app-sidebar v-if="!hideNav"
class="sidebar fixed w-sidebar h-full px-5 overflow-hidden transition-width duration-300 z-40" />
<div class="main h-[calc(100vh-86px)] transition-margin duration-300 overflow-auto"
@ -32,7 +33,8 @@ export default defineComponent({
const isConfig = computed(() => route.path.startsWith('/config'));
//
const hideNav = computed(() => {
return Settings.hideNavPath.includes(route.path);
// return Settings.hideNavPath.includes(route.path);
return route.path.startsWith('/finance');
});
//
const hidePanel = computed(() => {

@ -49,6 +49,7 @@ export const routes: Array<RouteRecordRaw> = [
component: Layout,
meta: { title: '金融市场' },
children: [
{ path: 'bank', component: () => import('@/views/finance/Bank.vue'), meta: { title: '银行市场' } },
{ path: 'publish', component: () => import('@/views/finance/Publish.vue'), meta: { title: '发布' } },
{ path: 'account', component: () => import('@/views/finance/Account.vue'), meta: { title: '我的账户' } },
{ path: 'order', component: () => import('@/views/finance/Order.vue'), meta: { title: '我的订单' } },

@ -79,6 +79,12 @@
@click="selecRole(275)"></div>
<div class="role relative bottom-[70px] left-[25%] bg-[url('@/assets/images/role/fund.png')] hover:bg-[url('@/assets/images/role/fund1.png')]"
@click="selecRole(1161)"></div>
<div class="role relative bottom-[255px] left-[41%] bg-[url('@/assets/images/role/market-bank.png')] hover:bg-[url('@/assets/images/role/market-bank1.png')]"
@click="selecRole(1162)"></div>
<div class="role relative bottom-[420px] left-[52%] bg-[url('@/assets/images/role/market-insurance.png')] hover:bg-[url('@/assets/images/role/market-insurance1.png')]"
@click="selecRole(1163)"></div>
<div class="role relative bottom-[560px] left-[63%] bg-[url('@/assets/images/role/market-fund.png')] hover:bg-[url('@/assets/images/role/market-fund1.png')]"
@click="selecRole(1164)"></div>
</div>
<!-- <div class="fixed top-[80px] right-[80px]">
<div class="flex items-center h-[60px] px-4 rounded-tl-[20px] rounded-tr-[20px]"
@ -229,7 +235,8 @@ const getLevel = async () => {
};
//
const selecRole = (id: number) => {
router.push(id === 275 ? `/product/insurance` : id === 1161 ? `/product/fund` : `/product/bank?type=0&i=1&role=${id}`);
const path = id === 275 ? `/product/insurance` : id === 1161 ? `/product/fund` : id === 1162 ? `/finance/bank` : `/product/bank?type=0&i=1&role=${id}`;
router.push(path);
};
//
const toLevel = () => {

@ -1,5 +1,5 @@
<template>
<div class="max-h-[calc(100vh-250px)] overflow-auto">
<div class="max-h-[calc(100vh-290px)] overflow-auto">
<h6 class="title">城市人口及年龄参数</h6>
<el-table class="c-table"
:data="form.ageAduRatioList"

@ -0,0 +1,304 @@
<template>
<div>
<h6 class="pl-3 mb-4 text-lg font-semibold text-[#333] border-l-[5px] border-l-[#006BFF]">银行市场</h6>
<div class="filter block">
<dl>
<dt>担保方式</dt>
<div class="vals">
<dd v-for="(item, i) in productTypes"
:key="i"
:class="{ active: params.productType === item.id }"
@click="filterClick(item, 'productType')">{{ item.name }}</dd>
</div>
</dl>
<dl>
<dt>担保方式</dt>
<div class="vals">
<dd v-for="(item, i) in guarantees"
:key="i"
:class="{ active: params.guarantyStyleId === item.id }"
@click="filterClick(item, 'guarantyStyleId')">{{ item.name }}</dd>
</div>
</dl>
<dl>
<dt>贷款期限</dt>
<div class="vals">
<dd v-for="(item, i) in times"
:key="i"
:class="{ active: params.time === item.id }"
@click="filterClick(item, 'time')">{{ item.name }}</dd>
</div>
</dl>
<dl>
<dt>贷款额度</dt>
<div class="vals">
<dd v-for="(item, i) in moneys"
:key="i"
:class="{ active: params.money === item.id }"
@click="filterClick(item, 'time')">{{ item.name }}</dd>
</div>
</dl>
</div>
<div class="block mt-3">
<div class="search mb-2">
<input type="text"
placeholder="搜索"
maxlength="20" />
<img src="@/assets/images/search.png"
alt=""
class="icon" />
</div>
<el-table ref="table"
v-loading="loading"
:data="list">
<el-table-column prop="productName"
label="贷款名称"
min-width="110"></el-table-column>
<el-table-column prop="loanCeiling"
label="贷款对象"
min-width="80">
<template #default="{ row }">
{{ row.productType ? '企业' : '个人' }}
</template>
</el-table-column>
<el-table-column prop="guarantyStyle"
label="担保方式"
min-width="80"></el-table-column>
<el-table-column prop="guarantyStyle"
label="贷款期限"
min-width="80"></el-table-column>
<el-table-column prop="guarantyStyle"
label="贷款额度"
min-width="80"></el-table-column>
<el-table-column prop="guarantyStyle"
label="参考利率范围"
min-width="80"></el-table-column>
<el-table-column prop="operationTime"
label="发布日期"
min-width="80"></el-table-column>
<el-table-column prop="id"
label="操作"
width="100">
<template #default="{ row }">
<el-button type="text"
size="small"
@click="toDetail(row)">查看详情</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="getList()"
@current-change="getList()"
small
background
class="px-3 py-2 justify-end"></el-pagination>
</div>
</div>
</template>
<script setup lang="ts">
import { computed, onMounted, ref, reactive, watch } from 'vue';
import { ElMessage } from 'element-plus';
import { pageSizes, pageLayout, toParams, resetParams } from '@/utils/common';
import { getProcessInformationBasedOnRoles } from '@/api/judgment';
import { bankingProductsList, batchDeletion } from '@/api/bank';
import Search from '@/components/Search.vue';
import { useRouter, useRoute } from 'vue-router';
import Cookies from 'js-cookie';
import { productState, getExpertStatus, getStatus } from '@/store/useProduct';
const router = useRouter();
const route = useRoute();
const productTypes = ref<Record<string, any>[]>([
{
id: '',
name: '不限',
},
{
id: 0,
name: '个人',
},
{
id: 1,
name: '企业',
},
]);
const times = ref<Record<string, any>[]>([
{
id: '',
name: '不限',
},
{
id: 1,
name: '<=6个月',
},
{
id: 2,
name: '6-12个月',
},
{
id: 3,
name: '12-36个月',
},
{
id: 4,
name: '>36个月',
},
]);
const moneys = ref<Record<string, any>[]>([
{
id: '',
name: '不限',
},
{
id: 1,
name: '<=100万',
},
{
id: 2,
name: '100-200万',
},
{
id: 3,
name: '200-500万',
},
{
id: 4,
name: '500-1000万',
},
{
id: 5,
name: '>1000万',
},
]);
const projectId = +Cookies.get('sand-projectId');
const levelId = +Cookies.get('sand-level');
const params = reactive({
createDateSort: '',
guarantyStyleId: '',
keyWord: '',
productType: '',
status: '',
time: '',
money: '',
roleId: computed(() => +route.query.role || 41),
checkPointId: levelId,
projectId,
});
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 list = ref<Array<any>>([]);
const loading = ref<boolean>(false);
//
const getGuarantee = async () => {
try {
const { process } = await getProcessInformationBasedOnRoles(44);
guarantees.value = [
{
id: '',
name: '不限',
},
...process[5].recordChildren,
];
} finally {
}
};
//
const getList = async () => {
loading.value = true;
try {
const { data } = await bankingProductsList({ pageNum: currentPage.value, pageSize: pageSize.value, ...toParams(params) });
list.value = data.message.records;
total.value = data.message.total;
} finally {
loading.value = false;
}
};
//
const initList = async () => {
currentPage.value = 1;
getList();
};
onMounted(() => {
getGuarantee();
getList();
});
watch([params, () => route.query], initList);
//
const filterClick = (item: Record<string, any>, key: string) => {
params[key] = item.id;
};
//
const toDetail = async (row: Record<string, any>) => {
router.push(`/finance/bankDetail?id=${row.id}&name=${params.keyWord}`);
};
</script>
<style lang="scss" scoped>
.filter {
dl {
display: flex;
flex-wrap: wrap;
align-items: center;
margin-bottom: 17px;
&:last-child {
margin-bottom: 0;
}
dt,
dd {
font-size: 14px;
font-family: MiSans;
color: #333;
}
.vals {
display: inline-flex;
flex-wrap: wrap;
align-items: center;
margin-left: 10px;
}
dd {
padding: 6px 10px;
margin-right: 10px;
cursor: pointer;
}
.active {
color: #fff;
background: #006bff;
border-radius: 4px;
}
}
}
.search {
position: relative;
width: 320px;
padding: 0 12px;
background-color: #f6f8fc;
border-radius: 8px;
input {
width: 90%;
height: 36px;
font-size: 14px;
line-height: 36px;
color: #333;
border: 0;
background-color: transparent;
&:focus {
outline: none;
}
}
.icon {
position: absolute;
top: 9px;
right: 12px;
cursor: pointer;
}
}
</style>

@ -1,27 +1,27 @@
<template>
<div>
<back name="产品详情"></back>
<Back name="产品详情" />
<div class="flex">
<div class="item mr-[18px]">
<h6 class="text-lg font-semibold text-[#053C6A]">智信女神贷</h6>
<h6 class="text-lg font-semibold text-[#053C6A]">{{ info.productName }}</h6>
<div class="flex justify-between mt-3 text-center">
<div>
<p class="mb-1 text-lg font-semibold text-[#00347C]">3.5-4.01%</p>
<p class="mb-1 text-lg font-semibold text-[#00347C]">{{ info.minimumAprOnLoan }}-{{ info.maximumAnnualInterestRate }}%</p>
<p class="text-sm text-[#00327C]">参考利率</p>
</div>
<div>
<p class="mb-1 text-lg font-semibold text-[#00347C]">3.5-4.01%</p>
<p class="mb-1 text-lg font-semibold text-[#00347C]">{{ info.minimumLoan }}-{{ info.loanCeiling }}</p>
<p class="text-sm text-[#00327C]">贷款额度</p>
</div>
<div>
<p class="mb-1 text-lg font-semibold text-[#00347C]">3.5-4.01%</p>
<p class="mb-1 text-lg font-semibold text-[#00347C]">{{ info.minimumTermOfLoan }} - {{ info.maximumTermOfLoan }}</p>
<p class="text-sm text-[#00327C]">贷款期限</p>
</div>
</div>
</div>
<div class="item mr-[18px]">
<h6 class="text-lg font-semibold text-[#333]">产品定义</h6>
<div class="mt-3 text-sm text-[#333] leading-6">根据个人客户的信用状况为其提供的一种短期融资便利产品借款人在我行核定的额度金额内可循环周转使用贷款</div>
<div class="mt-3 text-sm text-[#333] leading-6">{{ info.productDefinition }}</div>
</div>
<div class="item">
<h6 class="text-lg font-semibold text-[#053C6A]">本产品排行</h6>
@ -45,15 +45,99 @@
<div>
<div class="line">
<span class="label">担保方式</span>
<div class="val">担保方式</div>
<div class="val">{{ info.guarantyStyle }}</div>
</div>
<div class="line">
<span class="label">贷款用途</span>
<div class="val">担保方式</div>
<div class="val">{{
info.loanPurpose === '购房'
? '可用于住房按揭贷款、二手房住房按揭贷款。'
: info.loanPurpose === '消费'
? '贷款用途可用于除购房之外的合法个人消费支出,不得用于投资经营,不得用于无指定用途的个人支出。'
: info.loanPurpose === '经营' && !info.productType
? '可用于个人或其企业生产和经营活动中临时性、季节性等流动资金周转以及购置、安装或修理小型设备和装潢经营性场所所需的人民币贷款业务。'
: info.loanPurpose === '创业'
? '用于创业或再创业过程中的资金需求。'
: info.loanPurpose === '经营' && info.productType
? '用于短期生产经营周转的可循环的人民币信用贷款业务。'
: info.otherPurposesOfLoan
}}</div>
</div>
<div class="line">
<span class="label">担保方式</span>
<div class="val">担保方式</div>
<span class="label">还款方式</span>
<div class="val">{{ info.modeRepayment }}</div>
</div>
<div class="line">
<span class="label">贷款对象</span>
<div class="val">
<p v-if="info.minimumAge">年龄{{ info.minimumAge }} - {{ info.maximumAge }}周岁</p>
<p v-if="info.educationalRequirements">取得{{ info.educationalRequirements }}以上学历</p>
<p v-if="info.currentWorkingLife">{{ info.currentWorkingLife }}</p>
<p v-if="info.providentFundAndSocialSecurity">连续缴纳本市社保或者公积金6个月</p>
<p>持有中国银行I类账户且已关联至手机银行且在我行及其他金融同业无不良信用记录</p>
</div>
</div>
<div class="line">
<span class="label">材料要求</span>
<div class="val">
<p class="text">办理账户-提供材料{{ riskInfo?.accountMaterials }}</p>
<p v-if="riskInfo?.sendingAccount"
class="text">办理账户-发放账户借记卡或放款专户</p>
<p v-if="riskInfo?.loanApplicationMethod"
class="text">贷款申请-申请方式{{ riskInfo?.loanApplicationMethod }}</p>
<p v-if="riskInfo?.borrowerMaterial"
class="text">贷款申请-提供材料-借款人材料{{ riskInfo?.borrowerMaterial }}</p>
<template v-if="info.productType">
<p v-if="riskInfo?.enterpriseMaterial"
class="text">贷款申请-提供材料-企业材料{{ riskInfo?.enterpriseMaterial }}</p>
<p v-if="riskInfo?.collateral"
class="text">贷款申请-提供材料-抵押物{{ riskInfo?.collateral }}</p>
</template>
<template v-else>
<p v-if="riskInfo?.mateMaterial"
class="text">贷款申请-提供材料-配偶材料{{ riskInfo?.mateMaterial }}</p>
<p v-if="riskInfo?.businessMaterials"
class="text">贷款申请-提供材料-经营类材料{{ riskInfo?.businessMaterials }}</p>
</template>
<p v-if="riskInfo?.supplementaryMaterials"
class="text">贷款申请-提供材料-补充材料{{ riskInfo?.supplementaryMaterials }}</p>
<p v-if="riskInfo?.runBatchObject"
class="text">系统跑批准入风控策略-跑批对象{{ riskInfo?.runBatchObject }}</p>
<p v-if="riskInfo?.accessStrategy"
class="text">系统跑批准入风控策略-准入策略{{ riskInfo?.accessStrategy }}</p>
<p v-if="riskInfo?.personalCreditScoringStrategies"
class="text">系统跑批准入风控策略-信用评分策略{{ riskInfo?.personalCreditScoringStrategies }}</p>
<p v-if="riskInfo?.riskDegreeStrategy"
class="text">系统跑批准入风控策略-风险度策略{{ riskInfo?.riskDegreeStrategy }}</p>
<p v-if="riskInfo?.interestRatePricingModel"
class="text">系统跑批准入风控策略-利率定价模型-个人额度模型{{ riskInfo?.interestRatePricingModel }}</p>
<p v-if="riskInfo?.individualInterestRateModel"
class="text">系统跑批准入风控策略-利率定价模型-个人利率模型</p>
<p v-if="riskInfo?.dueDiligenceMode"
class="text">尽职调查-尽调方式{{ riskInfo?.dueDiligenceMode }}</p>
<p v-if="riskInfo?.dueDiligenceContent"
class="text">尽职调查-尽调内容{{ riskInfo?.dueDiligenceContent }}</p>
<p v-if="riskInfo?.reviewContent"
class="text">贷款审查-审查内容{{ riskInfo?.reviewContent }}</p>
<p v-if="riskInfo?.reviewSignature"
class="text">贷款审查-审查签字{{ riskInfo?.reviewSignature }}</p>
<p v-if="riskInfo?.reviewApproveContent"
class="text">贷款审批-审批内容{{ riskInfo?.reviewApproveContent }}</p>
<p v-if="riskInfo?.approvalSignature"
class="text">贷款审批-审批签字{{ riskInfo?.approvalSignature }}</p>
<p v-if="riskInfo?.contractMaterials"
class="text">签订合同-提供的材料{{ riskInfo?.contractMaterials }}</p>
<p v-if="riskInfo?.loanContract"
class="text">签订合同-合同模板-借贷合同{{ riskInfo?.loanContract }}</p>
<p v-if="riskInfo?.mortgageContract"
class="text">签订合同-合同模板-抵押合同{{ riskInfo?.mortgageContract }}</p>
<p v-if="riskInfo?.pledgeContract"
class="text">签订合同-合同模板-质押合同{{ riskInfo?.pledgeContract }}</p>
<p v-if="riskInfo?.guaranteeContract"
class="text">签订合同-合同模板-担保合同{{ riskInfo?.guaranteeContract }}</p>
<p v-if="riskInfo?.selectionStrategy"
class="text">贷后管理-选择策略{{ riskInfo?.selectionStrategy }}</p>
</div>
</div>
</div>
<div class="user m-4">
@ -62,7 +146,7 @@
<img src="@/assets/images/bankDetail/4.png"
alt=""
class="mx-auto" />
<p class="mt-2 font-semibold text-[#114575]">刘秀</p>
<p class="mt-2 font-semibold text-[#114575]">{{ userName }}</p>
</div>
<p class="mt-2 text-[#114575]">财经学院 金融2班</p>
</div>
@ -71,17 +155,38 @@
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue';
import { ElMessage } from 'element-plus';
import { Plus } from '@element-plus/icons-vue';
import Search from '@/components/Search.vue';
import { ref, computed, watch, onMounted } from 'vue';
import { findById } from '@/api/bank';
import { getTheCurrentUserName } from '@/api/config';
import { useRouter, useRoute } from 'vue-router';
import Back from '@/components/Back.vue';
const form = ref<Object>({});
const router = useRouter();
const route = useRoute();
const id = computed(() => +route.query.id);
const info = ref<Record<string, any>>({});
const riskInfo = ref<Record<string, any>>(null);
const userName = ref<string>();
//
const getDetail = async () => {
if (id.value) {
try {
const { data } = await findById(id.value);
info.value = data;
if (info.value.riskControlDetails) riskInfo.value = data.riskControlDetails;
} finally {
}
}
};
//
const getName = async () => {
const res = await getTheCurrentUserName();
userName.value = res.userName;
};
onMounted(() => {
// getGuarantee();
// fetchData();
getDetail();
getName();
});
</script>

Loading…
Cancel
Save