123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749 |
- <template>
- <div class="hc-layout-box">
- <div id="wbs-left-tree" :style="'width:' + leftWidth + 'px;'" class="hc-layout-left-box">
- <div class="hc-project-box">
- <div class="hc-project-icon-box">
- <HcIcon name="stack"/>
- </div>
- <div class="ml-2 project-name-box">
- <span class="text-xl text-cut project-alias">{{ projectInfo['projectAlias'] }}</span>
- <div class="text-xs text-cut project-name">{{ projectInfo['name'] }}</div>
- </div>
- </div>
- <div class="hc-tree-box">
- <div class="hc-search-tree-val">
- <el-input v-model="searchTreeVal" block clearable placeholder="请输入名称关键词检索" size="large"
- @keyup="searchTreeKeyUp">
- <template #suffix>
- <HcIcon name="search-2" ui="text-xl iscusor" @click="searchTreeClick"/>
- </template>
- </el-input>
- </div>
- <div v-loading="treeLoading" class="hc-tree-scrollbar" element-loading-text="获取数据中...">
- <el-scrollbar>
- <KeepAlive>
- <template v-if="isSearchTree">
- <HcTreeData :ElTreeLoadNode="searchElTreeLoadNode" :autoExpandKeys="treeAutoExpandKeys"
- :datas="searchTreeData" :searchTreeVal="searchTreeVal"
- :submitCounts="true"
- isColor
- @changeSearch="changeisSearch"
- @changetreelaod="changetreelaod"
- @nodeTap="wbsElTreeClick"
- />
- </template>
- <template v-else>
- <WbsTree
- ref="wbstree"
- :autoExpandKeys="treeAutoExpandKeys"
- :classifyType="contractTypeTabKey"
- :contractId="contractId"
- :projectId="projectId"
- :submitCounts="true"
- :treeKey="wbstreeKey"
- isColor
- @nodeTap="wbsElTreeClick"
- />
- </template>
- </KeepAlive>
- </el-scrollbar>
- </div>
- </div>
- <div class="hc-tree-foot-tip-box">
- <div class="dot-view green">已审批</div>
- <div class="dot-view black">未填报</div>
- <div class="dot-view orange">已填报-待审批</div>
- <div class="dot-view blue">已填报-未上报</div>
- </div>
- <!--左右拖动-->
- <div class="horizontal-drag-line" @mousedown="onmousedown"/>
- </div>
- <div class="hc-layout-content-box">
- <HcCard :scrollbar="false" actionSize="lg">
- <template #header>
- <HcTooltip keys="query_report">
- <el-button :disabled="tableCheckedKeys.length <= 0" :loading="reportLoading" hc-btn
- type="primary" @click="reportModalClick">
- <HcIcon name="send-plane-2"/>
- <span>上报</span>
- </el-button>
- </HcTooltip>
- <HcTooltip keys="query_download">
- <el-button :disabled="tableCheckedKeys.length <= 0" :loading="downloadLoading" hc-btn
- @click="batchDownload">
- <HcIcon name="download"/>
- <span>下载</span>
- </el-button>
- </HcTooltip>
- <HcTooltip keys="query_print">
- <el-button :disabled="tableCheckedKeys.length <= 0" :loading="printLoading" hc-btn
- @click="batchPrint">
- <HcIcon name="printer"/>
- <span>打印</span>
- </el-button>
- </HcTooltip>
- <HcTooltip keys="query_abolish">
- <el-button :disabled="tableCheckedKeys.length <= 0" hc-btn @click="batchAbolishClick">
- <HcIcon name="delete-bin-3"/>
- <span>废除</span>
- </el-button>
- </HcTooltip>
- <HcTooltip keys="query_local_attestation">
- <el-button :disabled="tableCheckedKeys.length <= 0" :loading="localLoading" hc-btn
- @click="batchLocal">
- <HcIcon name="folder-download"/>
- <span>本地验签</span>
- </el-button>
- </HcTooltip>
- <HcTooltip keys="query_online_attestation">
- <el-button :disabled="tableCheckedKeys.length <= 0" :loading="onlineLoading" hc-btn
- @click="batchOnline">
- <HcIcon name="cloud"/>
- <span>在线验签</span>
- </el-button>
- </HcTooltip>
- </template>
- <template #search>
- <div class="flex items-center">
- <div class="w-40">
- <el-select v-model="searchForm.taskStatus" clearable placeholder="流程状态">
- <el-option v-for="item in processStatusData" :key="item.value"
- :label="item['dictValue']" :value="item['dictKey']"/>
- </el-select>
- </div>
- <div class="w-40 ml-2">
- <el-select v-model="searchForm.fileUserIdAndName" clearable placeholder="填报人">
- <el-option v-for="item in reportingPersonData" :key="item.value" :label="item['label']"
- :value="item['value']"/>
- </el-select>
- </div>
- <div class="w-40 ml-2">
- <el-select v-model="searchForm.sourceType" clearable placeholder="文件类型">
- <el-option v-for="item in fileTypeData" :key="item.value" :label="item['dictValue']"
- :value="item['dictKey']"/>
- </el-select>
- </div>
- <div class="w-32 ml-2">
- <el-select v-model="searchForm.reportNumber" clearable placeholder="上报批次">
- <el-option v-for="item in reportBatchData" :key="item" :label="item" :value="item"/>
- </el-select>
- </div>
- <div class="w-64 ml-2">
- <HcDatePicker :dates="betweenTime" clearable @change="betweenTimeUpdate"/>
- </div>
- <div class="w-60 ml-2">
- <el-input v-model="searchForm.queryValue" clearable placeholder="请输入名称关键词检索"
- @keyup="keyUpEvent"/>
- </div>
- <div class="ml-2">
- <el-button type="primary" @click="searchClick">
- <HcIcon name="search-2"/>
- <span>搜索</span>
- </el-button>
- </div>
- </div>
- </template>
- <template #extra>
- <template v-if="contractInfo?.contractType === 2 || contractInfo?.contractType === 3">
- <HcNewSwitch :datas="contractTypeTab" :keys="contractTypeTabKey"
- @change="contractTypeTabChange"/>
- </template>
- </template>
- <HcTable ref="tableListRef" :column="tableListColumn" :datas="tableListData" :loading="tableLoading"
- isCheck @selection-change="tableSelectionChange">
- <template #name="{row}">
- <span class="text-link" @click="tableRowName(row)">{{ row?.name }}</span>
- </template>
- <template #waitingUserList="{row}">
- <template v-for="item in row['waitingUserList']">
- <el-tag
- v-if="item['waitingUserName']"
- :type="`${item.status === 2 ? 'success' : item.status === 3 ? 'warning' : item.status === 999 ? 'danger' : 'info'}`"
- class="mx-1" effect="dark">{{ item['waitingUserName'] }}
- </el-tag>
- </template>
- </template>
- </HcTable>
- <template #action>
- <div class="lr-dialog-footer">
- <div class="left">
- <span class="text-success">任务人员中:</span>
- <el-tag class="mx-1" effect="dark" type="info">未签字</el-tag>
- <el-tag class="mx-1" effect="dark" type="success">已签字</el-tag>
- <el-tag class="mx-1" effect="dark" type="warning">已废除</el-tag>
- <el-tag class="mx-1" effect="dark" type="danger">签字异常</el-tag>
- </div>
- <div class="right">
- <HcPages :pages="searchForm" @change="pageChange"/>
- </div>
- </div>
- </template>
- </HcCard>
- </div>
- <!--批量上报审批-->
- <HcReportModal :contractId="contractId"
- :datas="reportDatas"
- :ids="reportIds"
- :projectId="projectId"
- :show="showReportModal"
- :taskName="reportTaskName"
- :typeData="reportTypeData"
- type="wbs"
- isDatas
- title="批量上报审批"
- url="informationWriteQuery/batchTask"
- @finish="showReportFinish"
- @hide="showReportModal = false"
- @tagClose="reportTaskTagClose"
- />
- </div>
- </template>
- <script setup>
- import {ref, watch, onMounted} from "vue";
- import {useAppStore} from "~src/store";
- import WbsTree from "./components/WbsTree.vue"
- import HcTreeData from "./components/HcTreeData.vue"
- import {getStoreValue, setStoreValue} from '~src/utils/storage'
- import {downloadBlob, isString, getObjValue, getArrValue} from "js-fast-way"
- import queryApi from '~api/data-fill/query';
- import {eVisaTaskCheckApi} from "~api/other"
- //变量
- const useAppState = useAppStore()
- const projectId = ref(useAppState.getProjectId);
- const contractId = ref(useAppState.getContractId);
- const projectInfo = ref(useAppState.getProjectInfo);
- const contractInfo = ref(useAppState.getContractInfo);
- const isCollapse = ref(useAppState.getCollapse)
- //变量
- const wbstree = ref(null)
- const wbstreeKey = ref(Math.random())
- //树搜索
- const isSearchTree = ref(false)
- //监听
- watch(() => [
- useAppState.getCollapse,
- ], ([Collapse]) => {
- isCollapse.value = Collapse
- })
- //自动展开缓存
- const treeAutoExpandKeys = ref(getStoreValue('wbsTreeExpandKeys') || [])
- //渲染完成
- onMounted(() => {
- getFileUser()
- getReportNumber()
- getFirstTaskStatus()
- getDictBizClassify()
- if (contractTypeTabKey.value == 2 || contractInfo.value?.contractType == 3) {
- getSearchTreeDataJl()
- } else {
- getSearchTreeData()
- }
- })
- const searchTreeVal = ref('')
- const searchTreeData = ref([])
- //回车
- const treeLoading = ref(false)
- const getSearchTreeData = async () => {
- // treeLoading.value = true
- searchElTreeLoadNode.value = true
- const {error, code, data} = await queryApi.getTreeall({
- contractId: contractId.value,
- projectId: projectId.value,
- wbsId: projectInfo?.value.referenceWbsTemplateId,
- type: 1
- })
- //判断状态
- if (!error && code === 200) {
- searchTreeData.value = getArrValue(data)
- searchElTreeLoadNode.value = false
- treeLoading.value = false
- } else {
- searchElTreeLoadNode.value = false
- treeLoading.value = false
- searchTreeData.value = []
- }
- }
- const searchElTreeLoadNode = ref(true)
- const getSearchTreeDataJl = async () => {
- // treeLoading.value = true
- searchElTreeLoadNode.value = true
- const {error, code, data} = await queryApi.getTreeallJl({
- contractId: contractId.value,
- type: 1
- })
- //判断状态
- if (!error && code === 200) {
- searchElTreeLoadNode.value = false
- let searchobj = getObjValue(data)
- let searcharr = []
- for (let key in searchobj) {
- searcharr.push(searchobj[key][0])
- }
- searchTreeData.value = searcharr
- treeLoading.value = false
- } else {
- treeLoading.value = false
- searchElTreeLoadNode.value = false
- searchTreeData.value = []
- }
- }
- const searchTreeKeyUp = (e) => {
- if (e.key === "Enter") {
- searchTreeClick()
- }
- }
- const searchTreeClick = async () => {
- treeLoading.value = true
- if (searchElTreeLoadNode.value === true) {
- treeLoading.value = true
- window?.$message?.warning('请加载完再次点击搜索')
- } else {
- isSearchTree.value = true
- treeLoading.value = false
- }
- }
- //树相关的变量
- const primaryKeyId = ref('')
- const nodeItemInfo = ref({})
- const nodeDataInfo = ref({})
- const changeisSearch = () => {
- isSearchTree.value = false
- }
- const changetreelaod = (val) => {
- treeLoading.value = val
- }
- //树被点击
- const wbsElTreeClick = ({node, data, keys}) => {
- nodeItemInfo.value = node
- nodeDataInfo.value = data
- primaryKeyId.value = data['primaryKeyId'] || ''
- //缓存自动展开
- treeAutoExpandKeys.value = keys
- setStoreValue('wbsTreeExpandKeys', keys)
- //改变搜索表单数据
- searchForm.value.wbsId = data['primaryKeyId']
- searchForm.value.contractIdRelation = data['contractIdRelation']
- searchForm.value.current = 1;
- getTableData()
- }
- //搜索条件
- const processStatusData = ref([]) //流程状态
- const reportingPersonData = ref([]) //填报人
- const fileTypeData = ref([]) //文件类型
- const reportBatchData = ref([]) //上报批次
- //获取所有填报人
- const getFileUser = async () => {
- const {error, code, data} = await queryApi.getFileUser({
- contractId: contractId.value
- })
- //判断状态
- if (!error && code === 200) {
- let res = getArrValue(data), userArr = [];
- res.forEach(item => {
- userArr.push({label: item['userName'], value: `${item['userId']}-${item['userName']}`})
- })
- reportingPersonData.value = userArr
- } else {
- reportingPersonData.value = []
- }
- }
- //获取上报批次
- const getReportNumber = async () => {
- const {error, code, data} = await queryApi.getReportNumber({
- contractId: contractId.value,
- projectId: projectId.value
- })
- //判断状态
- if (!error && code === 200) {
- reportBatchData.value = getArrValue(data)
- } else {
- reportBatchData.value = []
- }
- }
- //获取流程状态
- const getFirstTaskStatus = async () => {
- const {error, code, data} = await queryApi.getFirstTaskStatus()
- //判断状态
- if (!error && code === 200) {
- processStatusData.value = getArrValue(data)
- } else {
- processStatusData.value = []
- }
- }
- //获取流程状态分类和文件类型分类
- const getDictBizClassify = async () => {
- const {error, code, data} = await queryApi.getDictBizClassify({
- contractId: contractId.value,
- code: 'fileType'
- })
- //判断状态
- if (!error && code === 200) {
- fileTypeData.value = getArrValue(data)
- } else {
- fileTypeData.value = []
- }
- }
- //搜索表单
- const searchForm = ref({
- taskStatus: null, fileUserIdAndName: null, sourceType: null, reportNumber: null, betweenTime: null,
- queryValue: null, contractIdRelation: null, wbsId: null, current: 1, size: 20, total: 0
- })
- //结构类型tab数据和相关处理
- // const contractTypeTabKey = ref('1')
- const {contractType} = contractInfo.value;
- const contractTypeTabKey = ref(contractType === 2 ? '2' : '1')
- const contractTypeTab = ref([
- {key: '1', name: '施工数据'},
- {key: '2', name: '监理数据'}
- ]);
- const contractTypeTabChange = (item) => {
- contractTypeTabKey.value = item?.key;
- // window?.location?.reload() //刷新页面
- searchClick()
- }
- //获取合同段类型
- // const getContractTypeKey = () => {
- // const { contractType } = contractInfo.value;
- // if (contractType === 2 || contractType === 3) {
- // return contractTypeTabKey.value ?? '1'
- // } else {
- // return null
- // }
- // }
- //日期时间被选择
- const betweenTime = ref(null)
- const betweenTimeUpdate = ({arr, query}) => {
- betweenTime.value = arr
- searchForm.value.betweenTime = query
- }
- //回车搜索
- const keyUpEvent = (e) => {
- if (e.key === "Enter") {
- searchForm.value.current = 1;
- getTableData()
- }
- }
- //搜索
- const searchClick = () => {
- searchForm.value.current = 1;
- wbstreeKey.value = Math.random()
- getTableData()
- // wbstree.value.resetNode().then((red)=>{
- // if(red){
- // getTableData()
- // }
- // })
- }
- //分页被点击
- const pageChange = ({current, size}) => {
- searchForm.value.current = current
- searchForm.value.size = size
- getTableData()
- }
- //获取数据
- const tableListRef = ref(null)
- const tableLoading = ref(false)
- const tableListColumn = ref([
- {key: 'name', name: '文件名称'},
- {key: 'startTime', name: '开始时间'},
- {key: 'taskStatusStr', name: '流程状态'},
- {key: 'reportNumber', name: '上报批次'},
- {key: 'fileUserIdAndName', name: '填报人'},
- {key: 'waitingUserList', name: '任务人'}
- ])
- const tableListData = ref([])
- const getTableData = async () => {
- if (!!searchForm.value.wbsId) {
- tableListRef.value?.clearSelection()
- tableCheckedKeys.value = []
- tableLoading.value = true
- // const classifyType = getContractTypeKey();
- const {error, code, data} = await queryApi.getPageData({
- projectId: projectId.value,
- contractId: contractId.value,
- ...searchForm.value,
- classifyType: contractTypeTabKey.value
- })
- //处理数据
- tableLoading.value = false
- if (!error && code === 200) {
- tableListData.value = getArrValue(data['records'])
- searchForm.value.total = data.total || 0
- } else {
- tableListData.value = []
- searchForm.value.total = 0
- }
- } else {
- window?.$message?.warning('请先选择一个树节点')
- }
- }
- //多选
- const tableCheckedKeys = ref([]);
- const tableSelectionChange = (rows) => {
- tableCheckedKeys.value = rows.filter((item) => {
- return (item ?? '') !== '';
- })
- }
- //名称被点击
- const tableRowName = (row) => {
- //如果 evisaPdfUrl 不为空,使用evisaPdfUrl,反之使用pdfUrl
- if (row['evisaPdfUrl']) {
- window.open(row['evisaPdfUrl'], '_blank')
- } else if (row['pdfUrl']) {
- window.open(row['pdfUrl'], '_blank')
- } else {
- window.$message?.warning('文件不存在')
- }
- }
- //上报
- const reportIds = ref('')
- const reportTaskName = ref('')
- const reportDatas = ref([])
- const reportTypeData = ref([])
- const showReportModal = ref(false)
- const reportLoading = ref(false)
- const reportModalClick = async () => {
- const rows = tableCheckedKeys.value;
- //判断是否满足条件
- const result = rows.every(({status}) => {
- return status === 0 || status === 3
- })
- //处理数据
- let newArr = [];
- for (let i = 0; i < rows.length; i++) {
- newArr.push(rows[i]['wbsId'])
- }
- reportTypeData.value = newArr
- //判断状态
- if (result) {
- reportLoading.value = true
- const taskCheck = await eVisaTaskCheckApi({
- projectId: projectId.value,
- contractId: contractId.value
- })
- if (taskCheck) {
- //初始ID
- const row = getObjValue(rows[0])
- reportIds.value = rowsToId(rows)
- //设置任务数据
- let reportDataArr = []
- rows.forEach(item => {
- reportDataArr.push({
- id: item?.id,
- name: item?.name
- })
- })
- reportDatas.value = reportDataArr
- //设置任务名称
- reportTaskName.value = rows.length > 1 ? `${row.name}等${rows.length}个文件` : row.name
- reportLoading.value = false
- showReportModal.value = true
- } else {
- reportLoading.value = false
- }
- } else {
- window.$message?.warning('已上报的文件不能进行再次上报,若要重新上报,要先撤回之前的上报,再重新上报')
- }
- }
- //上报的审批内容移除
- const reportTaskTagClose = (index) => {
- const row = tableCheckedKeys.value[index];
- tableListRef.value?.toggleRowSelection(row, false)
- }
- //上报完成
- const showReportFinish = () => {
- showReportModal.value = false
- getTableData()
- }
- //下载
- const downloadLoading = ref(false)
- const batchDownload = async () => {
- const rows = tableCheckedKeys.value;
- const ids = rowsToId(rows)
- //批量下载
- downloadLoading.value = true
- const {error, disposition, res} = await queryApi.batchDownloadFileToZip({ids: ids})
- //处理数据
- downloadLoading.value = false
- if (!error) {
- if (disposition) {
- downloadBlob(res, disposition)
- } else {
- window.$message?.error('数据异常')
- }
- }
- }
- //打印
- const printLoading = ref(false)
- const batchPrint = async () => {
- const rows = tableCheckedKeys.value;
- const ids = rowsToId(rows)
- //批量下载
- printLoading.value = true
- const {error, code, data} = await queryApi.batchPrint({ids: ids})
- //处理数据
- printLoading.value = false
- const res = isString(data) ? data ?? '' : ''
- if (!error && code === 200 && res) {
- window.open(res, '_blank')
- }
- }
- //废除
- const batchAbolishClick = () => {
- const rows = tableCheckedKeys.value;
- //判断是否满足条件
- const result = rows.every(({status}) => {
- return status !== 0 && status !== 3
- })
- //判断状态
- if (result) {
- //拼接ID
- const ids = rowsToId(rows)
- window?.$messageBox?.alert('是否废除勾选的已上报文件?', '废除文件', {
- showCancelButton: true,
- confirmButtonText: '确定废除',
- cancelButtonText: '取消',
- callback: (action) => {
- if (action === 'confirm') {
- batchAbolishSave(ids)
- }
- }
- })
- } else {
- window.$message?.warning('未上报的文件不能废除')
- }
- }
- //废除勾选的已上报文件
- const batchAbolishSave = async (ids) => {
- const {error, code} = await queryApi.batchAbolish({ids: ids})
- //处理数据
- if (!error && code === 200) {
- window.$message?.success('批量废除成功')
- tableCheckedKeys.value = []
- getTableData()
- }
- }
- //本地验签
- const localLoading = ref(false)
- const batchLocal = async () => {
- const rows = tableCheckedKeys.value;
- //判断是否满足条件
- const result = rows.every(({status}) => {
- return status === 2
- })
- //判断状态
- if (result) {
- const ids = rowsToId(rows)
- //请求数据
- localLoading.value = true
- const {error, code, data} = await queryApi.localVerify({
- ids: ids
- })
- //处理数据
- localLoading.value = false
- if (!error && code === 200) {
- console.log(data)
- }
- } else {
- window.$message?.warning('存在未审批或未上报数据')
- }
- }
- //在线验签
- const onlineLoading = ref(false)
- const batchOnline = async () => {
- const rows = tableCheckedKeys.value;
- if (rows.length > 1) {
- window.$message?.warning('在线验签只能勾选一条数据进行验签')
- return;
- }
- if (rows[0].status !== 2) {
- window.$message?.warning('存在未审批或未上报数据')
- return;
- }
- //发起
- onlineLoading.value = true
- const {error, code, data} = await queryApi.onlineVerify({
- ids: rows[0]['id']
- })
- //处理数据
- localLoading.value = false
- if (!error && code === 200) {
- console.log(data)
- }
- }
- //拼接ID
- const rowsToId = (rows) => {
- return rows.map((obj) => {
- return obj.id;
- }).join(",")
- }
- //左右拖动,改变树形结构宽度
- const leftWidth = ref(505);
- const onmousedown = () => {
- const leftNum = isCollapse.value ? 142 : 272
- document.onmousemove = (ve) => {
- let diffVal = ve.clientX - leftNum;
- if (diffVal >= 310 && diffVal <= 900) {
- leftWidth.value = diffVal;
- }
- }
- document.onmouseup = () => {
- document.onmousemove = null;
- document.onmouseup = null;
- }
- }
- </script>
- <style lang="scss" scoped>
- @import "../../styles/data-fill/query.scss";
- .iscusor {
- cursor: pointer;
- }
- </style>
|