政务黑名单改成列表

master
yujialong 7 months ago
parent 9cdbe2dbe7
commit ea29e820e3
  1. 3
      src/components/Back.vue
  2. 9
      src/components/Panel/index.vue
  3. 36
      src/components/StrategyConfirm.vue
  4. 2
      src/layout/components/AppSidebar/index.vue
  5. 15
      src/styles/index.scss
  6. 2
      src/views/Role.vue
  7. 2
      src/views/finance/Publish.vue
  8. 369
      src/views/product/strategy/150/Detail.vue
  9. 157
      src/views/product/strategy/150/Index.vue
  10. 37
      src/views/product/strategy/CardList.vue

@ -12,8 +12,7 @@
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { onMounted, ref } from 'vue'; import { useRouter } from 'vue-router';
import { useRouter, useRoute } from 'vue-router';
import { logout } from '@/store/useCurrentUser'; import { logout } from '@/store/useCurrentUser';
const props = defineProps({ const props = defineProps({

@ -36,11 +36,10 @@
实训{{ text }}时间 <span>{{ day }}</span> <span>{{ hour }}</span>小时 <span>{{ minutes }}</span> <span>{{ seconds }}</span> 实训{{ text }}时间 <span>{{ day }}</span> <span>{{ hour }}</span>小时 <span>{{ minutes }}</span> <span>{{ seconds }}</span>
</div> </div>
</div> </div>
<div class="item"> <div v-if="per !== 2"
<div> class="item">
总得分 总得分
<span class="total-score">{{ grade }}</span> <span class="total-score">{{ grade }}</span>
</div>
</div> </div>
<div> <div>
<el-button class="h-[40px]" <el-button class="h-[40px]"

@ -0,0 +1,36 @@
<template>
<!-- 保存策略时的confirm询问 -->
<el-dialog v-model="visible"
width="500px">
<p>修改后的策略同步已关联这条策略的贷款产品会导致关联产品下架并重新配置风控</p>
<p class="my-3 text-[#006BFF]">确定修改这条策略吗</p>
<el-checkbox v-model="syncCheck"
label="策略修改同步之前关联的产品" />
<template #footer>
<div class="dialog-footer">
<el-button @click="visible = false">取消</el-button>
<el-button type="primary"
@click="submit">确定</el-button>
</div>
</template>
</el-dialog>
</template>
<script setup lang="ts">
import { computed, ref } from 'vue';
const props = defineProps({
modelValue: { type: Boolean, default: false },
});
const emit = defineEmits(['update:modelValue', 'submit']);
const visible = computed({
get: () => props.modelValue,
set: (value) => {
emit('update:modelValue', value);
},
});
const syncCheck = ref<boolean>(false);
const submit = () => {
emit('submit');
};
</script>

@ -31,7 +31,7 @@
</div> </div>
<template #footer> <template #footer>
<span class="flex justify-center"> <span class="flex justify-center">
<div class="dia-btn mr-3 cancel" <div class="dia-btn cancel"
@click="dateVisible = false">取消</div> @click="dateVisible = false">取消</div>
<div class="dia-btn" <div class="dia-btn"
@click="submitDate">确定</div> @click="submitDate">确定</div>

@ -157,19 +157,18 @@ body {
} }
} }
.dia-btn { .dia-btn {
padding: 11px 26px; @apply py-[11px] px-[26px] text-sm leading-[1] text-white rounded-[18px] cursor-pointer;
font-size: 14px;
line-height: 1;
color: #fff;
background: linear-gradient(-36deg, #006bff, #2ab1ff); background: linear-gradient(-36deg, #006bff, #2ab1ff);
border-radius: 18px;
cursor: pointer;
&.cancel { &.cancel {
font-size: 600; @apply mr-3 font-semibold text-[#333];
color: #333;
background: #f4f8fc; background: #f4f8fc;
} }
} }
.model-drawer {
.el-drawer__header > :first-child {
@apply text-[#333] text-xl font-semibold text-center;
}
}
@media screen and (-webkit-min-device-pixel-ratio: 1.5), screen and (min-resolution: 144dpi) { @media screen and (-webkit-min-device-pixel-ratio: 1.5), screen and (min-resolution: 144dpi) {
body { body {

@ -134,7 +134,7 @@
</div> </div>
<template #footer> <template #footer>
<span class="flex justify-center"> <span class="flex justify-center">
<div class="dia-btn mr-3 cancel" <div class="dia-btn cancel"
@click="dateVisible = false">取消</div> @click="dateVisible = false">取消</div>
<div class="dia-btn" <div class="dia-btn"
@click="submitDate">确定</div> @click="submitDate">确定</div>

@ -117,7 +117,7 @@
class="px-3 py-2 justify-end"></el-pagination> class="px-3 py-2 justify-end"></el-pagination>
<template #footer> <template #footer>
<span class="flex justify-center"> <span class="flex justify-center">
<div class="dia-btn mr-3 cancel" <div class="dia-btn cancel"
@click="productVisible = false">取消</div> @click="productVisible = false">取消</div>
<div class="dia-btn" <div class="dia-btn"
@click="productVisible = false">确定</div> @click="productVisible = false">确定</div>

@ -0,0 +1,369 @@
<template>
<el-form label-width="90px"
label-suffix=":"
class="form"
:disabled="disabled">
<el-form-item label="策略名称"
prop="fundName">
<el-input class="w-[320px]"
placeholder="请输入20以内字符"
maxlength="20"
clearable
v-model="name"></el-input>
</el-form-item>
<el-form-item label="策略规则">
<el-table class="c-table"
:data="form"
max-height="calc(100vh - 230px)"
:cell-style="{background:'#fff'}"
:span-method="span"
border>
<el-table-column prop="name"
label="政务黑名单指标"
min-width="100"
align="center">
</el-table-column>
<el-table-column label="进黑名单条件"
min-width="350"
align="center">
<template #default="{ row }">
<!-- 大病报销 || 贫困户 -->
<div v-if="row.stRecordId == 161 || row.stRecordId == 164"
class="flex items-center">
<span v-if="row.recordChildren"
class="whitespace-nowrap">{{ row?.recordChildren[row.span ? 1 : 0]?.name }}</span>
<div class="w-[95px] ">
<el-select class="mx-2"
clearable
v-model="row.symbol">
<el-option v-for="item in symbols"
:key="item"
:label="item.name"
:value="item.name" />
</el-select>
</div>
<el-input class="w-[80px]"
placeholder="请输入"
v-model="row.num"></el-input>
<span class="ml-2 whitespace-nowrap">万元</span>
</div>
<!-- 大龄未婚 -->
<div v-else-if="row.stRecordId == 167"
class="flex items-center">
<template v-if="row.span">
<span class="whitespace-nowrap">且近一年</span>
<div class="w-[90px] ">
<el-select class="mx-2"
v-model="row.had">
<el-option value="有" />
<el-option value="无" />
</el-select>
</div>
<span class="ml-2 whitespace-nowrap">缴纳过社保或公积金</span>
</template>
<template v-else>
<span class="whitespace-nowrap">未婚且年龄</span>
<div class="w-[90px] ">
<el-select class="mx-2"
v-model="row.symbol">
<el-option v-for="item in symbols"
:key="item"
:label="item.name"
:value="item.name" />
</el-select>
</div>
<el-input class="w-[80px]"
placeholder="请输入"
v-model="row.num"></el-input>
<span class="ml-2 whitespace-nowrap">,</span>
<el-select class="w-[80px] ml-2"
v-model="row.had">
<el-option value="有" />
<el-option value="无" />
</el-select>
<span class="ml-2 whitespace-nowrap">固定资产</span>
</template>
</div>
<span v-else>{{ '命中' + row.name }}</span>
</template>
</el-table-column>
<el-table-column label="本人命中进黑名单"
min-width="100"
align="center">
<template #default="{ row }">
<el-checkbox v-model="row.personalHitBlacklist"
@change="e => checkRow(e, row)"></el-checkbox>
</template>
</el-table-column>
<el-table-column label="配偶命中拒入"
min-width="100"
align="center">
<template #default="{ row }">
<el-checkbox v-model="row.mateHitRejected"
@change="e => checkRow(e, row)"></el-checkbox>
</template>
</el-table-column>
<el-table-column label="父母/子女命中拒入"
min-width="100"
align="center">
<template #default="{ row }">
<el-checkbox v-model="row.parentsHitRejected"
@change="e => checkRow(e, row)"></el-checkbox>
</template>
</el-table-column>
<el-table-column label="其他家庭成员命中拒入"
min-width="100"
align="center">
<template #default="{ row }">
<el-checkbox v-model="row.otherFamilyMembersHitRejected"
@change="e => checkRow(e, row)"></el-checkbox>
</template>
</el-table-column>
<el-table-column label="企业大股东命中拒入"
min-width="100"
align="center">
<template #default="{ row }">
<el-checkbox v-model="row.corporateMajorityHitRejected"
@change="e => checkRow(e, row)"></el-checkbox>
</template>
</el-table-column>
<el-table-column label="本人及亲属企业命中准入"
min-width="120"
align="center">
<template #default="{ row }">
<el-checkbox v-model="row.hitAccess"
@change="checkNone(row)"></el-checkbox>
</template>
</el-table-column>
</el-table>
</el-form-item>
</el-form>
<div class="flex justify-end mt-3">
<div class="dia-btn cancel"
@click="emit('close')">取消</div>
<div class="dia-btn"
@click="syncVisible = true">确定</div>
</div>
<Confirm v-model="syncVisible"
@submit="submit" />
</template>
<script setup lang="ts">
import { ref, defineAsyncComponent, onMounted, computed } from 'vue';
import { ElMessage } from 'element-plus';
import { accessStrategyGovernmentBlacklistFind, accessStrategyGovernmentBlacklistSave } from '@/api/model';
import { getProcessInformationBasedOnRoles, addOperation } from '@/api/judgment';
import type { TableColumnCtx } from 'element-plus';
import { handleId, getIds } from '@/utils/common';
import Cookies from 'js-cookie';
const Confirm = defineAsyncComponent(() => import('@/components/StrategyConfirm.vue'));
const props = defineProps({
disabled: { type: Boolean, default: false },
});
const emit = defineEmits(['clsoe']);
const form = ref<Record<string, any>[]>([]);
const name = ref<string>();
const info = ref<Record<string, any>[]>([]);
const symbols: Array<Record<string, any>> = [
{
name: '>=',
},
{
name: '<',
},
{
name: '>',
},
{
name: '==',
},
{
name: '<=',
},
];
const syncVisible = ref<boolean>(false);
//
const getConfig = async () => {
const { process } = await getProcessInformationBasedOnRoles(150);
const result = [];
process.map((e) => {
const cur = info.value.find((n) => n.stRecordId === e.id);
let num = cur?.ruleOne.match(/\d+/g);
let symbol = cur?.ruleOne.match(/[<>=]+/g);
let had = cur?.ruleOne.match(/[有无]+/g);
let temp = {
...getIds(),
name: e.name,
recordChildren: e.recordChildren,
isRule: isRule(e.id) ? 1 : 0,
corporateMajorityHitRejected: !!cur?.corporateMajorityHitRejected,
hitAccess: !!cur?.hitAccess,
mateHitRejected: !!cur?.mateHitRejected,
otherFamilyMembersHitRejected: !!cur?.otherFamilyMembersHitRejected,
parentsHitRejected: !!cur?.parentsHitRejected,
personalHitBlacklist: !!cur?.personalHitBlacklist,
symbol: isRule(e.id) && symbol?.length ? symbol[0] : '',
had: e.id === 167 && had?.length ? had[0] : '',
num: isRule(e.id) && num?.length ? num[0] : '',
ruleOne: '',
ruleTwo: '',
subjectId: e.subjectId,
stRecordId: e.id,
};
result.push(temp);
if (isRule(e.id)) {
temp = JSON.parse(JSON.stringify(temp));
temp.span = 1;
num = cur?.ruleTwo?.match(/\d+/g);
if (num?.length) temp.num = num[0];
symbol = cur?.ruleTwo?.match(/[<>=]+/g);
if (symbol?.length) temp.symbol = symbol[0];
if (e.id === 167) temp.had = cur?.ruleTwo;
result.push(temp);
}
});
form.value = result;
};
//
const getDetail = async () => {
try {
const { data } = await accessStrategyGovernmentBlacklistFind();
info.value = data;
getConfig();
} finally {
}
};
onMounted(getDetail);
// 3
const isRule = (rule: number): boolean => {
return rule === 161 || rule === 164 || rule === 167;
};
interface SpanMethodProps {
row: Record<string, any>;
column: TableColumnCtx<Record<string, any>>;
rowIndex: number;
columnIndex: number;
}
//
const span = ({ row, column, rowIndex, columnIndex }: SpanMethodProps) => {
if (columnIndex === 0 || columnIndex === 2 || columnIndex === 3 || columnIndex === 4 || columnIndex === 5 || columnIndex === 6 || columnIndex === 7) {
if (rowIndex === 4 || rowIndex === 6 || rowIndex === 8) {
return {
rowspan: 2,
colspan: 1,
};
} else if (rowIndex === 5 || rowIndex === 7 || rowIndex === 9) {
return {
rowspan: 0,
colspan: 0,
};
}
}
};
const checkRow = (e: boolean, row: Record<string, any>) => {
if (e) row.hitAccess = false;
};
const checkNone = (row: Record<string, any>) => {
if (row.hitAccess) {
row.corporateMajorityHitRejected = false;
row.mateHitRejected = false;
row.otherFamilyMembersHitRejected = false;
row.parentsHitRejected = false;
row.personalHitBlacklist = false;
}
};
//
const addRecord = async (data: Record<string, any>) => {
const preIds = `1,${Cookies.get('sand-level')},42,67,147,150`; // 1id
const rule = [];
data.map((e, i) => {
const temp = [];
e.personalHitBlacklist && temp.push(300);
e.mateHitRejected && temp.push(301);
e.parentsHitRejected && temp.push(302);
e.otherFamilyMembersHitRejected && temp.push(303);
e.corporateMajorityHitRejected && temp.push(304);
e.hitAccess && temp.push(757);
if (isRule(e.stRecordId)) {
const len = e?.recordChildren?.length - 1;
e?.recordChildren.map((n, j) => {
if (j !== len) {
if (n.id === 169 && e.had) {
rule.push(handleId(n.id, n.subjectId, e.had === '有' ? 387 : 388, preIds + ',' + e.stRecordId + ',' + n.id, 1));
} else if (n.id === 168) {
const val = e.symbol + e.num;
val && rule.push(handleId(n.id, n.subjectId, val, preIds + ',' + e.stRecordId + ',' + n.id, 5));
} else if (n.id === 170 && e.had) {
rule.push(handleId(n.id, n.subjectId, e.had === '有' ? 389 : 390, preIds + ',' + e.stRecordId + ',' + n.id, 1));
} else {
const val = j ? (n.id === 168 ? e.symbol + e.num : e.ruleTwo) : e.ruleOne;
val && rule.push(handleId(n.id, n.subjectId, val, preIds + ',' + e.stRecordId + ',' + n.id, 5));
}
} else if (temp.length) {
rule.push(handleId(n.id, 71, temp.join(), preIds + ',' + e.stRecordId + ',' + n.id, 1));
}
});
} else {
temp.length && rule.push(handleId(e.stRecordId, 71, temp.join(), preIds + ',' + e.stRecordId, 1));
}
});
await addOperation({
...getIds(),
parentId: preIds,
lcJudgmentRuleReq: rule,
});
ElMessage.success('提交成功!');
syncVisible.value = false;
emit('close', 1);
};
//
const submit = async () => {
let param = JSON.parse(JSON.stringify(form.value));
param.map((e, i) => {
if (info.value.length) e.id = info.value.find((n) => n.stRecordId === e.stRecordId)?.id;
e.corporateMajorityHitRejected = +e.corporateMajorityHitRejected;
e.hitAccess = +e.hitAccess;
e.mateHitRejected = +e.mateHitRejected;
e.otherFamilyMembersHitRejected = +e.otherFamilyMembersHitRejected;
e.parentsHitRejected = +e.parentsHitRejected;
e.personalHitBlacklist = +e.personalHitBlacklist;
if (e.stRecordId == 161 || e.stRecordId == 164) {
if (e.span) {
//
param[i - 1].ruleTwo = e.symbol + e.num;
} else {
e.ruleOne = e.symbol + e.num;
}
} else if (e.stRecordId == 167) {
if (e.span) {
//
param[i - 1].ruleTwo = e.had;
} else {
e.ruleOne = e.symbol + e.num + ',' + e.had;
}
}
});
param = param.filter((e) => !e.span);
const recordParam = JSON.parse(JSON.stringify(param));
param.map((e) => {
delete e.recordChildren;
delete e.had;
delete e.name;
delete e.symbol;
delete e.num;
});
await accessStrategyGovernmentBlacklistSave({ governmentBlacklistList: param });
addRecord(recordParam);
};
</script>
<style lang="scss" scoped>
@import url(../../../../styles/form.scss);
</style>

@ -0,0 +1,157 @@
<template>
<div class="block">
<div class="flex justify-between items-center mb-5">
<search v-model="params.fundName"
@change="initList"></search>
<div class="filter">
<el-popconfirm title="确定要删除吗?"
:disabled="!multipleSelection.length"
@confirm.stop="delAll">
<template #reference>
<div :class="['add-btn mr-2', {'cursor-not-allowed': !multipleSelection.length}]">
<el-icon :size="24"
color="#fff">
<Delete />
</el-icon>
批量删除
</div>
</template>
</el-popconfirm>
<div class="add-btn"
@click="toAdd">
<img src="@/assets/images/plus.png"
alt=""
class="icon" />
新增
</div>
</div>
</div>
<el-table ref="table"
v-loading="loading"
:data="list"
@selection-change="handleSelectionChange">
<el-table-column type="selection"
width="55" />
<el-table-column label="序号"
type="index"
width="60"
align="center" />
<el-table-column prop="fundCode"
label="政务黑名单策略名称"
min-width="100" />
<el-table-column prop="operationTime"
label="新增日期"
width="140" />
<el-table-column label="操作"
width="140">
<template #default="{ row }">
<el-button type="text"
@click="toDetail(`/product/fund/detail`, row.id)"
size="small">查看</el-button>
<el-button type="text"
@click="toDetail(`/product/fund/detail`, row.id)"
size="small">编辑</el-button>
<el-popconfirm title="您确定删除吗?"
@confirm.stop="handleDelete(row.id)">
<template #reference>
<el-button type="text"
size="small">删除</el-button>
</template>
</el-popconfirm>
</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>
<el-drawer v-model="visible"
title="新增政务黑名单策略"
size="100%"
custom-class="model-drawer">
<Detail :disabled="false"
@close="closeDrawer" />
</el-drawer>
</div>
</template>
<script setup lang="ts">
import { onMounted, ref, reactive, defineAsyncComponent } from 'vue';
import { ElMessage } from 'element-plus';
import { Delete } from '@element-plus/icons-vue';
import { pageSizes, pageLayout, toParams, getIds } from '@/utils/common';
import { fundProductList, batchDeletion } from '@/api/fund';
import Search from '@/components/Search.vue';
import { useRouter, useRoute } from 'vue-router';
const Detail = defineAsyncComponent(() => import('./Detail.vue'));
const router = useRouter();
const route = useRoute();
const params = reactive({
...getIds(),
createDateSort: '',
fundName: '',
});
const currentPage = ref<number>(1);
const pageSize = ref<number>(10);
const total = ref<number>(0);
const table = ref<any>();
const multipleSelection = ref<Record<string, any>[]>([]);
const list = ref<Record<string, any>[]>([]);
const loading = ref<boolean>(false);
const visible = ref<boolean>(false);
//
const getList = async () => {
loading.value = true;
try {
const { data } = await fundProductList({ pageNum: currentPage.value, pageSize: pageSize.value, ...toParams(params) });
list.value = data.data.records;
total.value = data.data.total;
} finally {
loading.value = false;
}
};
//
const initList = async () => {
currentPage.value = 1;
getList();
};
onMounted(() => {
getList();
});
//
const handleSelectionChange = (val: Record<string, any>[]) => {
multipleSelection.value = val;
};
//
const delAll = async () => {
// handleDelete(multipleSelection.value);
};
//
const toAdd = () => {
visible.value = true;
};
//
const toDetail = async (path: string, id: number) => {
router.push(`${path}?id=${id}&name=${params.fundName}`);
};
//
const closeDrawer = (refresh?: number) => {
visible.value = false;
refresh && initList();
};
const handleDelete = async (id: number) => {
await batchDeletion([id]);
getList();
ElMessage.success('删除成功!');
};
</script>

@ -25,20 +25,15 @@
<script setup lang="ts"> <script setup lang="ts">
import { computed, onBeforeUnmount, onMounted, ref, defineAsyncComponent, getCurrentInstance } from 'vue'; import { computed, onBeforeUnmount, onMounted, ref, defineAsyncComponent, getCurrentInstance } from 'vue';
import { getProcessInformationBasedOnRoles } from '@/api/judgment'; import { getProcessInformationBasedOnRoles } from '@/api/judgment';
import { delCredit, listCredit } from '@/api/model';
import { useRouter, useRoute } from 'vue-router'; import { useRouter, useRoute } from 'vue-router';
import { ElMessage } from 'element-plus';
import { getIds } from '@/utils/common';
const router = useRouter(); const router = useRouter();
const route = useRoute(); const route = useRoute();
const curMenu = ref<string>(route.query.id); const curMenu = ref<string>(route.query.id);
const list = ref<Array<Record<string, any>>>([]); const list = ref<Array<Record<string, any>>>([]);
const id = computed(() => +route.query.id); const id = computed(() => +route.query.id);
const creditId = computed(() => +route.query.creditId);
const riskId = ref<number>();
const dynamicComponentMap = { const dynamicComponentMap = {
'150': defineAsyncComponent(() => import('./150.vue')), '150': defineAsyncComponent(() => import('./150/Index.vue')),
'151': defineAsyncComponent(() => import('./151.vue')), '151': defineAsyncComponent(() => import('./151.vue')),
'152': defineAsyncComponent(() => import('./152.vue')), '152': defineAsyncComponent(() => import('./152.vue')),
'153': defineAsyncComponent(() => import('./153.vue')), '153': defineAsyncComponent(() => import('./153.vue')),
@ -59,24 +54,14 @@ for (const [name, asyncComponent] of Object.entries(dynamicComponentMap)) {
const switchProduct = (id: number) => { const switchProduct = (id: number) => {
router.push(`/product/strategy?i=${route.query.i}&role=${route.query.role}&id=${id}`); router.push(`/product/strategy?i=${route.query.i}&role=${route.query.role}&id=${id}`);
}; };
//
const switchProductCredit = (id?: number) => {
router.push(`/product/strategy?i=${route.query.i}&role=${route.query.role}&creditId=${id}`);
};
//
const switchProductRisk = (id: number) => {
riskId.value = id;
};
// //
const getList = async (refresh?: number) => { const getList = async () => {
const { process } = await getProcessInformationBasedOnRoles(67); const { process } = await getProcessInformationBasedOnRoles(67);
// eslint-disable-next-line no-unused-expressions // eslint-disable-next-line no-unused-expressions
!id.value && switchProduct(process[0].recordChildren[0].id); !id.value && switchProduct(process[0].recordChildren[0].id);
list.value = process; list.value = process;
}; };
onMounted(() => { onMounted(getList);
getList();
});
onBeforeUnmount(() => { onBeforeUnmount(() => {
console.log('🚀 ~ onBeforeUnmount ~ app:', app); console.log('🚀 ~ onBeforeUnmount ~ app:', app);
app.component('148', null); app.component('148', null);
@ -85,22 +70,6 @@ onBeforeUnmount(() => {
const handleSelect = (key: string, keyPath: string[]) => { const handleSelect = (key: string, keyPath: string[]) => {
curMenu.value = key; curMenu.value = key;
router.push(`/product/strategy?i=${route.query.i}&role=${route.query.role}&id=${key}`); router.push(`/product/strategy?i=${route.query.i}&role=${route.query.role}&id=${key}`);
console.log(key, keyPath, curMenu.value);
};
const handleDelete = async (id: number) => {
await delCredit(id);
getList(1);
ElMessage.success('删除成功!');
};
//
const toAdd = () => {
router.push(`/product/strategy?i=${route.query.i}&role=${route.query.role}&add=1`);
};
// tab
const tabChange = () => {
// if (curTab.value === 'tab3') riskId.value = 702;
getList();
}; };
</script> </script>

Loading…
Cancel
Save