Browse Source

档案保管

duy 4 months ago
parent
commit
f2e0f52c7a

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

@@ -166,6 +166,18 @@ export default [
                 meta: { title: '四性检测' },
                 component: () => import('~src/views/custody/testing.vue'),
             },
+            {
+                path: '/custody/save',
+                name: 'custody-save',
+                meta: { title: '案卷保管' },
+                component: () => import('~src/views/custody/save.vue'),
+            },
+            {
+                path: '/custody/ledger',
+                name: 'custody-ledger',
+                meta: { title: '保管台账' },
+                component: () => import('~src/views/custody/ledger.vue'),
+            },
         ],
     },
     {

+ 2 - 0
src/router/modules/token.js

@@ -14,4 +14,6 @@ export default [
     'transfer-writing-conclusion',
     'transfer-write-report',
     'test-index',
+   'custody-save', //案卷保管
+   'custody-ledger', //案卷台账
 ]

+ 232 - 0
src/views/custody/ledger.vue

@@ -0,0 +1,232 @@
+<template>
+    <hc-body :loading="treeLoading" :project-nmae="projectInfo?.name" split>
+        <template #tree>
+            <HcTree
+                :auto-expand-keys="treeAutoExpandKeys" :contract-id="contractId" :project-id="projectId"
+                @node-tap="nodeElTreeClick" @menu-tap="ElTreeMenuClick"
+                @node-loading="treeNodeLoading"
+            />
+        </template>
+        <hc-new-card>
+            <template #header>
+                <div class="ml-4 w-40">
+                    <el-select v-model="searchForm.storageTime" clearable placeholder="标段">
+                        <el-option v-for="item in sectionData" :key="item.value" :label="item.label" :value="item.value" />
+                    </el-select>
+                </div>
+                <div class="ml-3 w-40">
+                    <el-select v-model="searchForm.secretLevel" clearable placeholder="移交人">
+                        <el-option v-for="item in transferornData" :key="item.value" :label="item.label" :value="item.value" />
+                    </el-select>
+                </div>
+                <div class="ml-3 w-64">
+                    <HcDatePicker :dates="betweenTime" clearable @change="betweenTimeUpdate" />
+                </div>
+                <div class="ml-3 w-56">
+                    <el-input v-model="searchForm.name" clearable block placeholder="请输入登记表/清单名称" @keyup="keyUpEvent" />
+                </div>
+              
+               
+                <div class="ml-2">
+                    <el-button type="primary" @click="searchClick">
+                        <HcIcon name="search-2" />
+                        <span>搜索</span>
+                    </el-button>
+                </div>
+            </template>
+          
+            <div :class="tableFileShow ? 'file-table' : ''" class="body">
+                <div class="hc-c-table-box">
+                    <HcTable
+                        ref="tableRef" :check-style="{ width: 29 }" :column="tableColumn" :datas="tableData"
+                        :index-style="{ width: 70 }" :is-arr-index="false" :loading="tableLoading" :ui="hoverHand ? 'hover-hand' : ''"
+                        is-new is-current-row
+                    >
+                        <template #index="{ index }">
+                            <span>{{ index + 1 }}</span>
+                        </template>
+                    </HcTable>
+                </div>
+            </div>
+            <template #action>
+                <HcPages :pages="searchForm" :sizes="[20, 50, 100, 200, 300, 500]" @change="pageChange" />
+            </template>
+        </hc-new-card>
+    </hc-body>
+</template>
+
+<script setup>
+import { onMounted, ref, watch } from 'vue'
+import { useAppStore } from '~src/store'
+import HcTree from '~src/components/tree/hc-tree.vue'
+import { getArrValue } from 'js-fast-way'
+
+
+import tuningApi from '~api/archiveConfig/tuning.js'
+
+
+import { getStoreValue, setStoreValue } from '~src/utils/storage'
+import { toPdfPage } from '~uti/btn-auth'
+import tasksApi from '~api/tasks/data'
+
+//变量
+const useAppState = useAppStore()
+const projectId = ref(useAppState.getProjectId)
+const contractId = ref(useAppState.getContractId)
+const projectInfo = ref(useAppState.getProjectInfo)
+const isCollapse = ref(useAppState.getCollapse)
+const hoverHand = ref(true)
+
+//监听
+watch(() => [
+    useAppState.getCollapse,
+], ([Collapse]) => {
+    isCollapse.value = Collapse
+})
+
+//渲染完成
+onMounted(() => {
+ 
+    setTableColumns()
+  
+
+})
+
+
+
+//树加载
+const treeLoading = ref(true)
+const treeNodeLoading = () => {
+    treeLoading.value = false
+}
+
+//项目树被点击
+
+// const isBuiltDrawing = ref(0)
+//自动展开缓存
+const treeAutoExpandKeys = ref(getStoreValue('turningExpandKeys') || [])
+const nodeElTreeClick = ({ node, data, keys, key }) => {
+    //缓存展开的节点
+    setStoreValue('turningExpandKeys', keys)
+    treeAutoExpandKeys.value = keys || []
+    console.log('点击', data)
+    searchForm.value.total = 0
+    searchForm.value.current = 1
+    searchForm.value.size = 20
+    searchForm.value.nodeIds = data.id || ''
+    getTableData()
+}
+//树菜单被点击
+const ElTreeMenuClick = async ({ key, node, data, keys }) => {
+    setStoreValue('turningExpandKeys', keys)
+    treeAutoExpandKeys.value = keys || []
+}
+
+//日期时间被选择
+const betweenTime = ref(null)
+const betweenTimeUpdate = ({ val, arr }) => {
+    betweenTime.value = arr
+    searchForm.value.startTimeValue = val['start']
+    searchForm.value.endTimeValue = val['end']
+}
+//标段
+const sectionData = ref([
+    { label: 'T.J01标', value: '3' },
+    { label: 'T.J02标', value: '2' },
+    { label: 'T.J03标', value: '1' },
+])
+const transferornData = ref([
+    { label: '张三', value: '3' },
+    { label: '李四', value: '2' },
+    { label: '王五', value: '1' },
+])
+
+
+
+//搜索表单
+const searchForm = ref({
+    contractId: null, storageTime:'', secretLevel:'', name:'', startTimeValue: '', endTimeValue: '',
+    current: 1, size: 20, total: 0,
+})
+const searchClick = ()=>{
+    getTableData()
+}
+//回车搜索
+const keyUpEvent = (e) => {
+    if (e.key === 'Enter') {
+        searchForm.value.current = 1
+        getTableData()
+    }
+}
+
+
+//分页被点击
+const pageChange = ({ current, size }) => {
+    searchForm.value.current = current
+    searchForm.value.size = size
+    getTableData()
+}
+
+//表格数据
+const tableRef = ref(null)
+
+const tableColumn = ref([])
+//设置表头
+const setTableColumns = () => {
+    tableColumn.value = [
+        { key: 'fileNumber', name: '标段' },
+        { key: 'name', name: '移交人', width: 300 },
+        { key: 'storageTimeValue', name: '移交时间' },
+        { key: 'secretLevelValue', name: '登记表' },
+        { key: 'pageN', name: '清单' },
+     
+    ]
+}
+const tableData = ref([
+    { fileNumber: 'T.J01标', name: '张三', storageTimeValue: '2022-06-20 14:52:30', secretLevelValue: '电子档案移交接收登记表(TJ01标)', pageN: '电子档案移交接收登记表(TJ01标)' },
+])
+//获取数据
+const tableLoading = ref(false)
+const getTableData = async () => {
+ 
+    // tableLoading.value = true
+    // const { error, code, data } = await tuningApi.pageByArchive({
+    //     ...searchForm.value,
+    //     projectId: projectId.value,
+    //     contractId: contractId.value,
+    //     isArchive: 1,
+    // })
+    // tableLoading.value = false
+    // if (!error && code === 200) {
+    //     tableData.value = getArrValue(data?.records)
+    //     searchForm.value.total = data?.total || 0
+    // } else {
+    //     tableData.value = []
+    //     searchForm.value.total = 0
+    // }
+}
+
+
+
+//设置表头
+</script>
+
+<style lang="scss" scoped>
+@import '~style/archives/tuning.scss';
+// @import '~style/file/scoped/collection.scss';
+</style>
+
+<style lang="scss">
+// @import '~style/file/collection.scss';
+@import '../../styles/theme/archives/tuning.scss';
+.text-disable {
+    cursor: not-allowed
+}
+.hover-hand {
+    cursor: pointer;
+}
+.panel-body .el-checkbox {
+    white-space: normal;
+    height: auto;
+}
+</style>

+ 377 - 0
src/views/custody/save.vue

@@ -0,0 +1,377 @@
+<template>
+    <hc-body :loading="treeLoading" :project-nmae="projectInfo?.name" split>
+        <template #tree>
+            <HcTree
+                :auto-expand-keys="treeAutoExpandKeys" :contract-id="contractId" :project-id="projectId"
+                @node-tap="nodeElTreeClick" @menu-tap="ElTreeMenuClick"
+                @node-loading="treeNodeLoading"
+            />
+        </template>
+        <hc-new-card>
+            <template #header>
+                <div class="w-40">
+                    <el-select v-model="searchForm.storageTime" clearable placeholder="保管期限">
+                        <el-option v-for="item in retentionPeriod" :key="item.value" :label="item.label" :value="item.value" />
+                    </el-select>
+                </div>
+                <div class="ml-3 w-40">
+                    <el-select v-model="searchForm.secretLevel" clearable placeholder="密级">
+                        <el-option v-for="item in securityLevelData" :key="item.dictKey" :label="item.dictValue" :value="item.dictKey" />
+                    </el-select>
+                </div>
+                <div class="ml-3 w-64">
+                    <HcDatePicker :dates="betweenTime" clearable @change="betweenTimeUpdate" />
+                </div>
+                <div class="ml-3 w-56">
+                    <el-input v-model="searchForm.name" clearable block placeholder="请输入名称关键词检索" @keyup="keyUpEvent" />
+                </div>
+              
+               
+                <div class="ml-2">
+                    <el-button type="primary" @click="searchClick">
+                        <HcIcon name="search-2" />
+                        <span>搜索</span>
+                    </el-button>
+                </div>
+            </template>
+            <template #extra>
+                <!-- transfer_initial_expert_btn_sampling -->
+              
+                <HcTooltip keys="archives_tuning_btn_disassemble">
+                    <el-button :disabled="tableCheckedKeys.length <= 0" hc-btn type="danger" @click="rejectClick">驳回</el-button>
+                </HcTooltip>
+            </template>
+            <div :class="tableFileShow ? 'file-table' : ''" class="body">
+                <div class="hc-c-table-box">
+                    <HcTable
+                        ref="tableRef" :check-style="{ width: 29 }" :column="tableColumn" :datas="tableData"
+                        :index-style="{ width: 70 }" :is-arr-index="false" :loading="tableLoading" :ui="hoverHand ? 'hover-hand' : ''"
+                        is-check is-new is-current-row
+                        @selection-change="tableSelection" @row-click="tableRowClick"
+                    >
+                        <template #table-column-header-num>
+                            <HcTooltip keys="archives_tuning_btn_sort">
+                                <span class="text-link text-lg" @click="tableSortClick">
+                                    <HcIcon name="arrow-up-down" />
+                                </span>
+                            </HcTooltip>
+                        </template>
+                        <template #name="{ row }">
+                            <span class="text-link" @click="viewPdf(row.id)">{{ row?.name }}</span>
+                        </template>
+                    </HcTable>
+                </div>
+                <div v-if="tableFileShow" class="hc-f-table-box">
+                    <div class="header-box">
+                        <div class="header">卷内文件</div>
+                        <div>
+                            <HcIcon class="hc-icon-close 'text-hover'" name="close" style=" color:rgb(64, 149, 229);" @click="closetableFile" />
+                        </div>
+                    </div>
+                    <div class="hc-file-table-box">
+                        <HcTable
+                            ref="tableFileRef" :check-style="{ width: 29 }" :column="innertableColumn" :datas="intableData"
+                            :index-style="{ width: 60 }" :loading="intableLoading" is-check is-new
+                            @selection-change="intableSelection"
+                        >
+                            <template #table-column-header-num>
+                                <HcTooltip keys="archives_tuning_btn_sort">
+                                    <span class="text-link text-lg" @click="intableSortClick">
+                                        <HcIcon class="text-hover" name="arrow-up-down" />
+                                    </span>
+                                </HcTooltip>
+                            </template>
+                            <template #fileName="{ row }">
+                                <span class="text-link text-hover" @click="viewfilePdf(row)">{{ row?.fileName }}</span>
+                            </template>
+                        </HcTable>
+                        <!-- <HcPages :pages="insearchForm" @change="inpageChange"/> -->
+                    </div>
+                </div>
+            </div>
+            <template #action>
+                <HcPages :pages="searchForm" :sizes="[20, 50, 100, 200, 300, 500]" @change="pageChange" />
+            </template>
+        </hc-new-card>
+    </hc-body>
+</template>
+
+<script setup>
+import { onMounted, ref, watch } from 'vue'
+import { useAppStore } from '~src/store'
+import HcTree from '~src/components/tree/hc-tree.vue'
+import { deepClone, getArrValue } from 'js-fast-way'
+import { rowsToId, rowsToIdNumArr } from '~uti/tools'
+
+import tuningApi from '~api/archiveConfig/tuning.js'
+import archiveFileApi from '~api/archiveFile/archiveFileAuto.js'
+
+import { getStoreValue, setStoreValue } from '~src/utils/storage'
+import { toPdfPage } from '~uti/btn-auth'
+import tasksApi from '~api/tasks/data'
+
+//变量
+const useAppState = useAppStore()
+const projectId = ref(useAppState.getProjectId)
+const contractId = ref(useAppState.getContractId)
+const projectInfo = ref(useAppState.getProjectInfo)
+const isCollapse = ref(useAppState.getCollapse)
+const hoverHand = ref(true)
+
+//监听
+watch(() => [
+    useAppState.getCollapse,
+], ([Collapse]) => {
+    isCollapse.value = Collapse
+})
+
+//渲染完成
+onMounted(() => {
+ 
+    setTableColumns()
+    getSecurityLevel()
+
+})
+
+const tableFileRef = ref(null)
+
+//树加载
+const treeLoading = ref(true)
+const treeNodeLoading = () => {
+    treeLoading.value = false
+}
+
+//项目树被点击
+
+// const isBuiltDrawing = ref(0)
+//自动展开缓存
+const treeAutoExpandKeys = ref(getStoreValue('turningExpandKeys') || [])
+const nodeElTreeClick = ({ node, data, keys, key }) => {
+    //缓存展开的节点
+    setStoreValue('turningExpandKeys', keys)
+    treeAutoExpandKeys.value = keys || []
+    console.log('点击', data)
+    searchForm.value.total = 0
+    searchForm.value.current = 1
+    searchForm.value.size = 20
+    searchForm.value.nodeIds = data.id || ''
+    getTableData()
+}
+//树菜单被点击
+const ElTreeMenuClick = async ({ key, node, data, keys }) => {
+    setStoreValue('turningExpandKeys', keys)
+    treeAutoExpandKeys.value = keys || []
+}
+
+//日期时间被选择
+const betweenTime = ref(null)
+const betweenTimeUpdate = ({ val, arr }) => {
+    betweenTime.value = arr
+    searchForm.value.startTimeValue = val['start']
+    searchForm.value.endTimeValue = val['end']
+}
+//保管期限
+const retentionPeriod = ref([
+    { label: '永久', value: '3' },
+    { label: '30年', value: '2' },
+    { label: '10年', value: '1' },
+])
+
+//获取密级
+const securityLevelData = ref([])
+const getSecurityLevel = async () => {
+    const { error, code, data } = await tasksApi.queryTaskTypeStatus({
+        typeOrStatus: 'security_level',
+    })
+    //处理数据
+    if (!error && code === 200) {
+        securityLevelData.value = getArrValue(data).filter(item => item.dictKey !== '0')
+    } else {
+        securityLevelData.value = []
+    }
+}
+//搜索表单
+const searchForm = ref({
+    contractId: null, storageTime:'', secretLevel:'', name:'', startTimeValue: '', endTimeValue: '',
+    current: 1, size: 20, total: 0,
+})
+const searchClick = ()=>{
+    getTableData()
+}
+//回车搜索
+const keyUpEvent = (e) => {
+    if (e.key === 'Enter') {
+        searchForm.value.current = 1
+        getTableData()
+    }
+}
+const insearchForm = ref({
+    contractId: null, type: null, approval: null,
+    current: 1, size: 1000, total: 0,
+})
+
+
+//分页被点击
+const pageChange = ({ current, size }) => {
+    searchForm.value.current = current
+    searchForm.value.size = size
+    getTableData()
+}
+
+//表格数据
+const tableRef = ref(null)
+
+const tableColumn = ref([])
+//设置表头
+const setTableColumns = () => {
+    tableColumn.value = [
+        { key: 'fileNumber', name: '档号' },
+        { key: 'name', name: '案卷题名', width: 300 },
+        { key: 'storageTimeValue', name: '保管期限', width: 50 },
+        { key: 'secretLevelValue', name: '密级', width: 50 },
+        { key: 'pageN', name: '总页数', width: 50 },
+        { key:'unit', name: '立卷单位' },
+        { key:'createTime', name: '移交时间' },
+        { key:'unit', name: '移交单位' },
+    ]
+}
+const tableData = ref([])
+//获取数据
+const tableLoading = ref(false)
+const getTableData = async () => {
+    tableFileShow.value = false
+    tableLoading.value = true
+    const { error, code, data } = await tuningApi.pageByArchive({
+        ...searchForm.value,
+        projectId: projectId.value,
+        contractId: contractId.value,
+        isArchive: 1,
+    })
+    tableLoading.value = false
+    if (!error && code === 200) {
+        tableData.value = getArrValue(data?.records)
+        searchForm.value.total = data?.total || 0
+    } else {
+        tableData.value = []
+        searchForm.value.total = 0
+    }
+}
+
+const innertableColumn = ref([])
+const intableData = ref([])
+
+//设置表头
+const setInnertableColumn = () => {
+    innertableColumn.value = [
+        { key: 'fileNumber', name: '文件编号' },
+        { key: 'fileName', name: '文件题名', width: 500 },
+        { key: 'fileTime', name: '文件日期' },
+        { key: 'dutyUser', name: '责任者' },
+        { key: 'filePage', name: '页数' },
+    ]
+}
+const intableLoading = ref(false)
+//获取卷内文件
+const getintableData = async () => {
+    intableLoading.value = true
+    const { error, code, data } = await tuningApi.getarchiveFilePage({
+        ...insearchForm.value,
+        nodeIds: searchForm.value.nodeIds,
+        archiveId: checkInid.value,
+    })
+    intableLoading.value = false
+    if (!error && code === 200) {
+        intableData.value = getArrValue(data['records'])
+        insearchForm.value.total = data['total'] || 0
+
+    } else {
+        intableData.value = []
+        insearchForm.value.total = data['total'] || 0
+
+    }
+}
+//多选
+const tableCheckedKeys = ref([])
+const intableCheckedKeys = ref([])
+const tableSelection = (rows) => {
+    tableCheckedKeys.value = rows
+}
+const intableSelection = (rows) => {
+    intableCheckedKeys.value = rows
+}
+const rejectClick = ()=>{
+    window.$message?.warning('功能开发中')
+}
+
+
+
+
+
+
+
+
+
+//表格行被点击
+const tableFileShow = ref(false)
+const checkInid = ref('')
+const checkRow = ref({})
+const tableRowClick = ({ row }) => {
+    tableFileShow.value = true
+    checkRow.value = row
+    checkInid.value = row.id
+    setInnertableColumn()
+    getintableData()
+}
+//收起卷内文件
+const closetableFile = () => {
+    tableFileShow.value = false
+}
+
+
+
+const viewPdf = async (id) => {
+    window.$message?.info('预览案卷需要合并pdf,需要一点时间')
+    const { error, code, data, msg } = await tuningApi.printArchive({
+        id: id,
+    })
+    if (!error && code === 200) {
+        if (data) {
+            toPdfPage(data)
+            //window.open(data, '_blank')
+        } else {
+            window.$message?.warning('文件不存在')
+        }
+
+    }
+ 
+}
+//查看卷内文件pdf
+const viewfilePdf = (row) => {
+    if (row?.pdfFileUrl) {
+        toPdfPage(row?.pdfFileUrl)
+        //window.open(row?.pdfFileUrl, '_blank')
+    } else {
+        window.$message?.warning('文件不存在')
+    }
+}
+</script>
+
+<style lang="scss" scoped>
+@import '~style/archives/tuning.scss';
+// @import '~style/file/scoped/collection.scss';
+</style>
+
+<style lang="scss">
+// @import '~style/file/collection.scss';
+@import '../../styles/theme/archives/tuning.scss';
+.text-disable {
+    cursor: not-allowed
+}
+.hover-hand {
+    cursor: pointer;
+}
+.panel-body .el-checkbox {
+    white-space: normal;
+    height: auto;
+}
+</style>

+ 22 - 12
src/views/transfer/move-submit.vue

@@ -1,16 +1,25 @@
 <template>
     <div class="hc-docs-tabs-box">
-        <hc-tab-card :tabs="tabsData" :tab-key="tabsKey" @change="tabsChange">
-            <hc-pdf :src="pdfUrl" viewer="" />
-            <template #extra>
-                <el-button type="primary" @click="reportClick">
-                    <span>上报</span>
-                </el-button>
-                <el-button type="warning" class="ml-2" @click="saveClick">
-                    <span>保存</span>
-                </el-button>
+        <hc-tabs-simple :cur="tabsKey" :datas="tabsData" @tab-click="tabsChange">
+            <template #tab-one>
+                <hc-card>
+                    <template #extra>
+                        <el-button type="primary" @click="reportClick">
+                            <span>上报</span>
+                        </el-button>
+                        <el-button type="warning" class="ml-2" @click="saveClick">
+                            <span>保存</span>
+                        </el-button>
+                    </template>
+
+
+                    内容区域
+                </hc-card>
+            </template>
+            <template #tab-two>
+                <hc-pdf :src="pdfUrl" viewer="" />
             </template>
-        </hc-tab-card>
+        </hc-tabs-simple>
     </div>
 </template>
 
@@ -19,8 +28,9 @@ import { ref } from 'vue'
 //类型处理
 const tabsKey = ref('one')
 const tabsData = ref([
-    { name: '电子档案移交接收意记表', key: 'one' },
-    { name: '电子档案移交清单', key: 'two' },
+{ icon: '', label: '电子档案移交接收意记表', key: 'one' },
+    { icon: '', label: '电子档案移交清单', key: 'two' },
+    
   
 ])