ZaiZai 1 éve
szülő
commit
e7822e80de

+ 1 - 1
package.json

@@ -21,7 +21,7 @@
         "dayjs": "^1.11.10",
         "echarts": "^5.5.0",
         "element-plus": "2.5.6",
-        "hc-vue3-ui": "^3.1.9",
+        "hc-vue3-ui": "^3.2.1",
         "js-base64": "^3.7.7",
         "js-fast-way": "^0.4.6",
         "js-md5": "^0.8.3",

+ 46 - 0
src/api/modules/certificate/admin.js

@@ -0,0 +1,46 @@
+import { HcApi } from '../../request/index'
+
+export default {
+    //获取所有有效项目
+    async page(form) {
+        return HcApi({
+            url: '/api/blade-manager/signPfxFile/singPfxManagementPage',
+            method: 'get',
+            params: form,
+        }, false)
+    },
+    //获取系统所有角色划分
+    async queryAllRoleList(form) {
+        return HcApi({
+            url: '/api/blade-manager/signPfxFile/queryAllRoleList',
+            method: 'get',
+            params: form,
+        }, false)
+    },
+    //获取项目列表
+    async queryProjectList() {
+        return HcApi({
+            url: '/api/blade-manager/signPfxFile/queryProjectList',
+            method: 'GET',
+            params: {},
+        }, false)
+    },
+    //获取当前项目下所有合同段
+    async queryContractList(form) {
+        return HcApi({
+            url: '/api/blade-manager/signPfxFile/queryContractList',
+            method: 'get',
+            params: form,
+        }, false)
+    },
+    //删除数据
+    async del(ids) {
+        return HcApi({
+            url: '/api/blade-manager/signPfxFile/remove',
+            method: 'post',
+            params: {
+                ids,
+            },
+        }, false)
+    },
+}

+ 40 - 0
src/api/modules/certificate/list.js

@@ -0,0 +1,40 @@
+import { HcApi } from '../../request/index'
+
+export default {
+    //分页
+    async page(form) {
+        return HcApi({
+            url: '/api/blade-system/data-scope/list',
+            method: 'get',
+            params: form,
+        }, false)
+    },
+    //详情
+    async detail(id) {
+        return HcApi({
+            url: '/api/blade-system/data-scope/detail',
+            method: 'get',
+            params: {
+                id,
+            },
+        }, false)
+    },
+    //新增和编辑
+    async submit(form) {
+        return HcApi({
+            url: '/api/blade-system/data-scope/submit',
+            method: 'post',
+            data: form,
+        }, false)
+    },
+    //删除
+    async del(ids) {
+        return HcApi({
+            url: '/api/blade-system/data-scope/remove',
+            method: 'post',
+            params: {
+                ids,
+            },
+        }, false)
+    },
+}

+ 21 - 0
src/router/modules/base.js

@@ -33,6 +33,27 @@ export default [
             },
         ],
     },
+    {
+        path: '/certificate',
+        name: 'certificate',
+        redirect: '/certificate/management',
+        meta: { title: '电签管理' },
+        component: Layout,
+        children: [
+            {
+                path: '/certificate/admin',
+                name: '/certificate/management',
+                meta: { title: '证书管理' },
+                component: () => import('~src/views/certificate/admin.vue'),
+            },
+            {
+                path: '/certificate/list',
+                name: '/certificate/list',
+                meta: { title: '证书列表' },
+                component: () => import('~src/views/certificate/list.vue'),
+            },
+        ],
+    },
     {
         path: '/authority',
         name: 'authority',

+ 0 - 6
src/styles/app/element.scss

@@ -207,9 +207,3 @@
     color: #a9abb2;
     cursor: not-allowed;
 }
-
-//弹窗卡片
-.el-dialog.hc-new-dialog.hc-modal-no-padding .el-card {
-    --el-card-border-radius: 0;
-    --el-card-padding: 8px;
-}

+ 101 - 0
src/views/certificate/admin.vue

@@ -0,0 +1,101 @@
+<template>
+    <hc-new-card>
+        <template #header>
+            <div class="w-100">
+                <el-select v-model="searchForm.projectId" filterable clearable block placeholder="选择项目" @change="searchClick">
+                    <el-option v-for="item in projectData" :key="item.id" :label="item.projectName" :value="item.id" />
+                </el-select>
+            </div>
+        </template>
+        <hc-table :column="tableColumn" :datas="tableData" :loading="tableLoading" :is-index="false" is-new>
+            <template #action="{ row }">
+                <el-link type="primary" @click="rowClick(row)">查看</el-link>
+            </template>
+        </hc-table>
+        <template #action>
+            <hc-pages :pages="searchForm" @change="pageChange" />
+        </template>
+        <!-- 查看 -->
+        <hc-new-drawer v-model="isRowDrawer" is-close to-id="hc-main-box">
+            <HcAdminSee v-if="isRowDrawer" :pid="tableRowItem.projectId" :cid="tableRowItem.contractId" />
+        </hc-new-drawer>
+    </hc-new-card>
+</template>
+
+<script setup>
+import { nextTick, onActivated, ref } from 'vue'
+import { getArrValue } from 'js-fast-way'
+import HcAdminSee from './modules/admin/see.vue'
+import mainApi from '~api/certificate/admin'
+
+//激活
+onActivated(() => {
+    getDataApi()
+})
+
+const getDataApi = async () => {
+    await getProjectData()
+    searchClick()
+}
+
+//项目列表
+const projectData = ref([])
+const getProjectData = async () => {
+    const { data } = await mainApi.queryProjectList()
+    projectData.value = getArrValue(data)
+}
+
+//搜索条件
+const searchForm = ref({ projectId: '', current: 1, size: 20, total: 0 })
+
+//搜索
+const searchClick = () => {
+    searchForm.value.current = 1
+    getTableData()
+}
+
+//分页
+const pageChange = ({ current, size }) => {
+    searchForm.value.current = current
+    searchForm.value.size = size
+    getTableData()
+}
+
+//表格数据
+const tableColumn = ref([
+    { key: 'projectName', name: '项目名称' },
+    { key: 'personalCount', name: '个人证书(个)', align: 'center' },
+    { key: 'enterpriseCount', name: '企业证书(个)', align: 'center' },
+    { key: 'action', name: '操作', width: 80, align: 'center' },
+])
+const tableData = ref([])
+
+//获取表格数据
+const tableLoading = ref(false)
+const getTableData = async () => {
+    tableData.value = []
+    tableLoading.value = true
+    const { error, code, data } = await mainApi.page({
+        ...searchForm.value,
+        total: null,
+    })
+    tableLoading.value = false
+    if (!error && code === 200) {
+        tableData.value = getArrValue(data['records'])
+        searchForm.value.total = data['total']
+    } else {
+        tableData.value = []
+        searchForm.value.total = 0
+    }
+}
+
+//点击查看
+const isRowDrawer = ref(false)
+const tableRowItem = ref({})
+const rowClick = (row) => {
+    tableRowItem.value = row
+    nextTick(() => {
+        isRowDrawer.value = true
+    })
+}
+</script>

+ 11 - 0
src/views/certificate/list.vue

@@ -0,0 +1,11 @@
+<template>
+    <div>证书列表</div>
+</template>
+
+<script setup>
+
+</script>
+
+<style scoped lang="scss">
+
+</style>

+ 141 - 0
src/views/certificate/modules/admin/see.vue

@@ -0,0 +1,141 @@
+<template>
+    <hc-body split>
+        <template #left>
+            <hc-new-card>
+                <div class="relative mb-3 w-full">
+                    <el-select v-model="currentId" filterable block placeholder="选择合同段" @change="getRoleList">
+                        <el-option v-for="item in contractData" :key="item.id" :label="item.contractName" :value="item.id" />
+                    </el-select>
+                </div>
+                <div v-loading="isRoleLoading" class="hc-sign-pfx-file-list">
+                    <el-scrollbar>
+                        <el-menu unique-opened style="border-right: 0;">
+                            <el-sub-menu v-for="(item, index) in roleListData" :key="index" :index="`${item.roleId.toString()}`">
+                                <template #title>
+                                    <i class="i-iconoir-settings-profiles" />
+                                    <span class="ml-2">{{ item.roleName }}</span>
+                                </template>
+                                <el-menu-item-group v-for="(items, indexs) in item.childRoleList" :key="indexs">
+                                    <el-menu-item :index="`${items.roleId.toString()}`" @click="signPfxClick(items)">
+                                        {{ items.roleName }}
+                                    </el-menu-item>
+                                </el-menu-item-group>
+                            </el-sub-menu>
+                        </el-menu>
+                    </el-scrollbar>
+                </div>
+            </hc-new-card>
+        </template>
+        <hc-new-card>
+            <hc-status v-if="tableData.length <= 0" text="暂无相关数据" />
+            <hc-table v-else :column="tableColumn" :datas="tableData" :is-index="false" is-new>
+                <template #signatureFileUrl="{ row }">
+                    <el-image class="h-[30px] w-[70px]" :src="row.signatureFileUrl" :preview-src-list="[row.signatureFileUrl]" fit="cover" />
+                </template>
+                <template #certificateFileName="{ row }">
+                    <el-link type="primary" :href="row.certificateFileUrl" target="_blank">{{ row.certificateFileName }}</el-link>
+                </template>
+                <template #pfxType="{ row }">
+                    {{ row.pfxType != -1 ? row.pfxType : '-' }}
+                </template>
+                <template #action="{ row, index }">
+                    <el-link type="danger" @click="delRowClick(row, index)">删除签名配置</el-link>
+                </template>
+            </hc-table>
+        </hc-new-card>
+    </hc-body>
+</template>
+
+<script setup>
+import { onMounted, ref } from 'vue'
+import { getArrValue, isNullES } from 'js-fast-way'
+import mainApi from '~api/certificate/admin'
+import { delMessage } from '~uti/tools.js'
+
+const props = defineProps({
+    pid: {
+        type: [String, Number],
+        default: '',
+    },
+    cid: {
+        type: [String, Number],
+        default: '',
+    },
+})
+
+//监听内容
+const projectId = ref(props.pid)
+const contractId = ref(props.cid)
+const currentId = ref(props.cid)
+
+//渲染完成
+onMounted(() => {
+    getDataApi()
+})
+
+//获取数据
+const getDataApi = () => {
+    if (isNullES(contractId.value)) return
+    getProjectData()
+    getRoleList()
+}
+
+//合同段列表
+const contractData = ref([])
+const getProjectData = async () => {
+    const { data } = await mainApi.queryContractList({
+        contractId: contractId.value,
+    })
+    contractData.value = getArrValue(data)
+}
+
+//获取证书列表
+const isRoleLoading = ref(false)
+const roleListData = ref([])
+const getRoleList = async () => {
+    isRoleLoading.value = true
+    const { data } = await mainApi.queryAllRoleList({
+        contractId: currentId.value,
+    })
+    roleListData.value = getArrValue(data)
+    isRoleLoading.value = false
+}
+
+//表格数据
+const tableColumn = ref([
+    { key: 'certificateUserName', name: '姓名' },
+    { key: 'signatureFileUrl', name: '签名图片' },
+    { key: 'certificateFileName', name: '证书' },
+    { key: 'pfxType', name: '签章类型' },
+    { key: 'action', name: '操作', width: 110, align: 'center' },
+])
+
+//证书点击
+const tableData = ref([])
+const signPfxClick = ({ signPfxFileList }) => {
+    tableData.value = getArrValue(signPfxFileList)
+}
+
+//删除签名配置
+const delRowClick = async (row, index) => {
+    delMessage(async () => {
+        const { code, msg } = await mainApi.del(row.id)
+        if (code === 200) {
+            window.$message.success('删除成功')
+            getRoleList().then()
+            tableData.value.splice(index, 1)
+        } else {
+            window.$message.error(msg ?? '删除失败')
+        }
+    })
+}
+</script>
+
+<style lang="scss" scoped>
+.hc-sign-pfx-file-list {
+    position: relative;
+    height: calc(100% - 42px);
+    border: 1px solid #dbdde5;
+    overflow: hidden;
+}
+</style>

+ 6 - 4
yarn.lock

@@ -2001,10 +2001,10 @@ has-flag@^4.0.0:
   resolved "http://39.108.216.210:9000/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b"
   integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==
 
-hc-vue3-ui@^3.1.9:
-  version "3.1.9"
-  resolved "http://39.108.216.210:9000/hc-vue3-ui/-/hc-vue3-ui-3.1.9.tgz#b7d9f6d664f84ddba4fa9aa6e77d388555b5227c"
-  integrity sha512-IZhDgk1pUsYEO5wUQ+c65DDLqhiImdK5IaMAjNifsrvu3ZlyZAQy/l5BDj+ValkguSsQOMiLzgcWRTnFFetxFw==
+hc-vue3-ui@^3.2.1:
+  version "3.2.1"
+  resolved "http://39.108.216.210:9000/hc-vue3-ui/-/hc-vue3-ui-3.2.1.tgz#121c2f17daf82fee61ce1c4109d3b89930298975"
+  integrity sha512-BEKN+AnXm21K9yY/xCHtBGV32MxpgSxhdhOWNytXCtTF/F/lQS+grERHwnItWUi0aHdhj+VInqvZtwXy/Nzcug==
 
 human-signals@^2.1.0:
   version "2.1.0"
@@ -2754,6 +2754,7 @@ streamx@^2.15.0:
     bare-events "^2.2.0"
 
 "string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0:
+  name string-width-cjs
   version "4.2.3"
   resolved "http://39.108.216.210:9000/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
   integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
@@ -2786,6 +2787,7 @@ string_decoder@~1.1.1:
     safe-buffer "~5.1.0"
 
 "strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1:
+  name strip-ansi-cjs
   version "6.0.1"
   resolved "http://39.108.216.210:9000/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
   integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==