浏览代码

风险等级配置

jwyu 6 月之前
父节点
当前提交
f992a3e598

+ 6 - 0
src/api/riskLevel/index.js

@@ -0,0 +1,6 @@
+import apiRiskLevelRelationShip from './relationShip'
+import apiRiskLevelProduct from './product'
+export {
+  apiRiskLevelRelationShip,
+  apiRiskLevelProduct
+}

+ 12 - 0
src/api/riskLevel/product.js

@@ -0,0 +1,12 @@
+import { get, post } from "@/api/index";
+
+export default {
+  // 品种列表
+  permissionList:()=>{
+    return get('/chart_permission/list',{})
+  },
+  // 客户风险等级选项
+  setRiskLevel:params=>{
+    return post('/chart_permission/setRiskLevel',params)
+  },
+}

+ 28 - 0
src/api/riskLevel/relationShip.js

@@ -0,0 +1,28 @@
+import { get, post } from "@/api/index";
+
+export default {
+  // 风险等级关联关系列表
+  relationList:params=>{
+    return get('/customer/mappingList',params)
+  },
+  // 客户风险等级选项
+  userRiskLevelOpts:()=>{
+    return get('/risk/customerRiskList',{})
+  },
+  // 产品风险等级选项
+  productRiskLevelOpts:()=>{
+    return get('/risk/productRiskList',{})
+  },
+  // 新增关联关系
+  relationAdd:params=>{
+    return post('/customer/addMapping',params)
+  },
+  // 编辑关联关系
+  relationEdit:params=>{
+    return post('/customer/editMapping',params)
+  },
+  // 删除关联关系
+  relationDel:params=>{
+    return post('/customer/deleteMapping',params)
+  },
+}

+ 31 - 0
src/router/modules/riskLevel.js

@@ -0,0 +1,31 @@
+import LayoutIndex from '@/layout/Index.vue'
+
+export default[
+  {
+    path:'/riskLevel',
+    component:LayoutIndex,
+    name:'RiskLevel',
+    meta:{
+      title:'风险等级配置'
+    },
+    children:[
+      {
+        path:'product',
+        component:()=>import('@/views/riskLevel/product/Index.vue'),
+        name:"RiskLevelProduct",
+        meta:{
+          title:'产品风险等级配置'
+        },
+      },
+      {
+        path:'relationShip',
+        component:()=>import('@/views/riskLevel/RelationShip/Index.vue'),
+        name:"RiskLevelRelationShip",
+        meta:{
+          title:'关联关系配置'
+        },
+      },
+    ]
+  }
+]
+

+ 111 - 0
src/views/riskLevel/RelationShip/Index.vue

@@ -0,0 +1,111 @@
+<script setup>
+import { apiRiskLevelRelationShip } from '@/api/riskLevel'
+import EditRelation from './components/EditRelation.vue'
+
+const tableColOpts = [
+  {
+    label: '用户风险等级',
+    key: 'CustomerRisk',
+  },
+  {
+    label: '产品风险等级',
+    key: 'ProductRisk',
+  },
+  {
+    label: '创建人',
+    key: 'Creator',
+  },
+  {
+    label: '更新时间',
+    key: 'UpdatedTime',
+    sort: true
+  },
+]
+const list = ref([])
+const tableLoading = ref(false)
+let sortType=''
+async function getList() {
+  tableLoading.value = true
+  const res = await apiRiskLevelRelationShip.relationList({
+    Sort:sortType
+  })
+  tableLoading.value = false
+  list.value = res.Data.List || []
+}
+getList()
+
+function handleTableSort(e) {
+  const { order, prop } = e//order:"descending",prop: "RegisterTime"
+  sortType=order === 'descending' ? 'desc' : 'asc'
+  getList()
+}
+
+
+
+const showEditRelation = ref(false)
+const editData = ref(null)
+function handleEdit(e){
+  editData.value=e
+  showEditRelation.value=true
+}
+
+
+async function handleDel(e) {
+  await ElMessageBox.confirm('删除后不可恢复,是否确认删除?', '提示', {
+    type: 'warning',
+  })
+  const res = await apiRiskLevelRelationShip.relationDel({
+    CustomerRisk: e.CustomerRisk
+  })
+  if (res.Ret !== 200) return
+  ElMessage.success('删除成功');
+  getList()
+}
+</script>
+
+<template>
+  <div>
+    <el-button
+      type="primary"
+      @click="
+        showEditRelation = true;
+        editData = null;
+      "
+      >添加关联关系</el-button
+    >
+    <div class="list-wrap" style="margin-top: 20px">
+      <el-table
+        :data="list"
+        border
+        stripe
+        element-loading-text="数据加载中..."
+        v-loading="tableLoading"
+        @sort-change="handleTableSort"
+      >
+        <el-table-column
+          v-for="column in tableColOpts"
+          :key="column.key"
+          :prop="column.key"
+          :label="column.label"
+          :sortable="column.sort ? 'custom' : false"
+        >
+        </el-table-column>
+        <el-table-column label="操作" width="160">
+          <template #default="{ row }">
+            <el-button type="primary" link @click="handleEdit(row)">编辑</el-button>
+            <el-button type="danger" link @click="handleDel(row)"
+              >删除</el-button
+            >
+          </template>
+        </el-table-column>
+      </el-table>
+    </div>
+  </div>
+
+  <!-- 添加/编辑关联关系 -->
+  <EditRelation 
+    v-model:show="showEditRelation" 
+    :editData="editData"
+    @success="getList"
+  />
+</template>

+ 140 - 0
src/views/riskLevel/RelationShip/components/EditRelation.vue

@@ -0,0 +1,140 @@
+<script setup>
+import { apiRiskLevelRelationShip } from '@/api/riskLevel'
+
+const show = defineModel('show', { type: Boolean, default: false })
+
+const props = defineProps({
+  editData: {
+    type: [Object, null],
+    default: null
+  }
+})
+const emits=defineEmits(['success'])
+
+watch(
+  ()=>show.value,
+  (n)=>{
+    if(n&&props.editData){
+      formState.userLevel=props.editData.CustomerRisk
+      formState.productLevel=props.editData.ProductRisk
+    }
+  }
+)
+
+// 用户风险等级选项
+const userRiskLevelOpts = ref([])
+async function getUserRiskLevelOpts() {
+  const res = await apiRiskLevelRelationShip.userRiskLevelOpts()
+  if (res.Ret === 200) {
+    userRiskLevelOpts.value = res.Data.List || []
+  }
+}
+getUserRiskLevelOpts()
+
+// 产品风险等级选项
+let productLevelOpts=[]
+async function getProductRiskLevelOpts() {
+  const res = await apiRiskLevelRelationShip.productRiskLevelOpts()
+  if (res.Ret === 200) {
+    const arr = res.Data.List || []
+    productLevelOpts=arr.map(item=>{
+      return {
+        ...item,
+        value:item.RiskName
+      }
+    })
+  }
+}
+getProductRiskLevelOpts()
+
+const formRef=ref(null)
+const formRules = {
+  userLevel: [{ required: true, message: '请选择用户风险等级', trigger: 'blur' },],
+  productLevel: [
+    { required: true, message: '请选择产品风险等级', trigger: 'blur' },
+    {
+      validator: (rule, value, callback) => {
+        const regex = /^R\d+$/;
+        if (!regex.test(value)) {
+          callback(new Error('输入的值必须是 R 加数字,并且不能包含空格'));
+        } else {
+          callback();
+        }
+      },
+      trigger: 'blur'
+    }
+  ]
+}
+const formState = reactive({
+  userLevel: '',
+  productLevel: ''
+})
+
+function querySearch(queryString, cb) {
+  const validLevels = productLevelOpts; // 可用的选项
+  cb(validLevels)
+}
+
+async function handleSave() {
+  await formRef.value.validate()
+  const params={
+    CustomerRisk:formState.userLevel,
+    ProductRisk:formState.productLevel
+  }
+  const res=props.editData?await apiRiskLevelRelationShip.relationEdit(params) : await apiRiskLevelRelationShip.relationAdd(params)
+  if(res.Ret!==200) return
+  ElMessage.success(props.editData?'编辑成功': '添加成功');
+  show.value=false
+  emits('success')
+}
+
+</script>
+
+<template>
+  <el-dialog
+    v-model="show"
+    width="500"
+    :title="editData ? '编辑' : '添加关联关系'"
+    draggable
+  >
+    <el-form
+      ref="formRef"
+      :model="formState"
+      :rules="formRules"
+      class="form-box"
+      label-width="130px"
+      hide-required-asterisk
+    >
+      <el-form-item prop="userLevel" label="用户风险等级">
+        <el-select
+          v-model="formState.userLevel"
+          placeholder="请选择用户风险等级"
+        >
+          <el-option
+            v-for="item in userRiskLevelOpts"
+            :key="item.Id"
+            :label="item.RiskName"
+            :value="item.RiskName"
+          ></el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item prop="productLevel" label="产品最高风险等级">
+        <el-autocomplete
+          v-model="formState.productLevel"
+          :fetch-suggestions="querySearch"
+          placeholder="请选择产品风险等级"
+        />
+      </el-form-item>
+    </el-form>
+    <template #footer>
+      <div class="footer-wrap">
+        <el-button type="primary" plain size="large" @click="show = false"
+          >取消</el-button
+        >
+        <el-button type="primary" size="large" @click="handleSave"
+          >保存</el-button
+        >
+      </div>
+    </template>
+  </el-dialog>
+</template>

+ 59 - 0
src/views/riskLevel/product/Index.vue

@@ -0,0 +1,59 @@
+<script setup>
+import { apiRiskLevelProduct } from '@/api/riskLevel'
+import SetRisk from './components/SetRisk.vue'
+
+const list = ref(null)
+function getList() {
+  apiRiskLevelProduct.permissionList().then(res => {
+    if (res.Ret === 200) {
+      list.value = res.Data.List || []
+    }
+  })
+}
+getList()
+
+const showSetRisk=ref(false)
+const editData=ref(null)
+function handleShowSetRisk(e){
+  editData.value={
+    ...e.data,
+    parentLabel:`${e.parent.data.name}/${e.data.name}`
+  }
+  showSetRisk.value=true
+}
+</script>
+
+<template>
+  <el-tree class="permission-list" :data="list">
+    <template #default="{ node, data }">
+      <span class="permission-list-item">
+        <span>{{ data.name }}</span>
+        <el-tag type="warning" v-if="data.riskLevel&&node.level>1" style="margin-left:10px">{{data.riskLevel}}</el-tag>
+        <el-button type="primary" link style="float:right" v-if="node.level>1" @click="handleShowSetRisk(node)">设置风险等级</el-button>
+      </span>
+    </template>
+  </el-tree>
+
+  <!-- 设置风险等级 -->
+  <SetRisk 
+    v-model:show="showSetRisk" 
+    :editData="editData"
+    @success="getList"
+  />
+</template>
+
+<style lang="scss" scoped>
+.permission-list{
+  padding: 20px;
+  :deep(.el-tree-node__content){
+    width: 100%;
+    height: fit-content;
+    padding-top: 10px;
+    padding-bottom: 10px;
+    border-bottom: 1px solid #c8cdd9;
+  }
+  .permission-list-item{
+    flex: 1;
+  }
+}
+</style>

+ 118 - 0
src/views/riskLevel/product/components/SetRisk.vue

@@ -0,0 +1,118 @@
+<script setup>
+import { apiRiskLevelRelationShip,apiRiskLevelProduct } from '@/api/riskLevel'
+
+const show = defineModel('show', { type: Boolean, default: false })
+
+const props = defineProps({
+  editData: {
+    type: [Object, null],
+    default: null
+  }
+})
+const emits=defineEmits(['success'])
+
+watch(
+  ()=>show.value,
+  (n)=>{
+    if(n&&props.editData){
+      formState.riskLevel=props.editData.riskLevel
+    }
+  }
+)
+
+
+// 产品风险等级选项
+let productLevelOpts=[]
+async function getProductRiskLevelOpts() {
+  const res = await apiRiskLevelRelationShip.productRiskLevelOpts()
+  if (res.Ret === 200) {
+    const arr = res.Data.List || []
+    productLevelOpts=arr.map(item=>{
+      return {
+        ...item,
+        value:item.RiskName
+      }
+    })
+  }
+}
+getProductRiskLevelOpts()
+
+const formRef=ref(null)
+const formRules = {
+  riskLevel: [
+    { required: true, message: '请选择产品风险等级', trigger: 'blur' },
+    {
+      validator: (rule, value, callback) => {
+        const regex = /^R\d+$/;
+        if (!regex.test(value)) {
+          callback(new Error('输入的值必须是 R 加数字,并且不能包含空格'));
+        } else {
+          callback();
+        }
+      },
+      trigger: 'blur'
+    }
+  ]
+}
+const formState = reactive({
+  riskLevel: ''
+})
+
+function querySearch(queryString, cb) {
+  const validLevels = productLevelOpts; // 可用的选项
+  cb(validLevels)
+}
+
+async function handleSave() {
+  await formRef.value.validate()
+  const params={
+    Id:props.editData.id,
+    RiskLevel:formState.riskLevel
+  }
+  const res=await apiRiskLevelProduct.setRiskLevel(params)
+  if(res.Ret!==200) return
+  ElMessage.success('设置成功');
+  show.value=false
+  emits('success')
+}
+
+</script>
+
+<template>
+  <el-dialog
+    v-model="show"
+    width="500"
+    title="设置风险等级 "
+    draggable
+  >
+    <el-form
+      ref="formRef"
+      :model="formState"
+      :rules="formRules"
+      class="form-box"
+      label-width="80px"
+      hide-required-asterisk
+    >
+      <el-form-item prop="permission" label="品种">
+        <span>{{props.editData.parentLabel}}</span>
+      </el-form-item>
+      <el-form-item prop="riskLevel" label="风险等级">
+        <el-autocomplete
+          v-model="formState.riskLevel"
+          :fetch-suggestions="querySearch"
+          placeholder="请选择产品风险等级"
+        />
+      </el-form-item>
+    </el-form>
+    <template #footer>
+      <div class="footer-wrap">
+        <el-button type="primary" plain size="large" @click="show = false"
+          >取消</el-button
+        >
+        <el-button type="primary" size="large" @click="handleSave"
+          >保存</el-button
+        >
+      </div>
+    </template>
+  </el-dialog>
+</template>