.npmrc
@@ -5,3 +5,5 @@ strict-peer-dependencies=true # 自动安装对等依赖,无需手动安装 auto-install-peers=true # 允许所有包执行构建脚本(避免新依赖安装后无法运行)pnpm9的坑 onlyBuiltDependencies=* applications/task-work-order/package.json
@@ -11,11 +11,6 @@ }, "dependencies": { "@amap/amap-jsapi-loader": "catalog:", "@ztzf/apis": "workspace:*", "@ztzf/components": "workspace:*", "@ztzf/constants": "workspace:*", "@ztzf/hooks": "workspace:*", "@ztzf/utils": "workspace:*", "@dvgis/dc-sdk": "catalog:", "@element-plus/icons-vue": "catalog:", "@saber/nf-design-base-elp": "catalog:", @@ -23,6 +18,13 @@ "@saber/nf-form-elp": "catalog:", "@smallwei/avue": "catalog:", "@turf/turf": "catalog:", "@vue-office/docx": "^1.6.3", "@vue-office/pdf": "^2.0.10", "@ztzf/apis": "workspace:*", "@ztzf/components": "workspace:*", "@ztzf/constants": "workspace:*", "@ztzf/hooks": "workspace:*", "@ztzf/utils": "workspace:*", "animate.css": "catalog:", "avue-plugin-ueditor": "catalog:", "axios": "catalog:", @@ -59,6 +61,7 @@ "video.js": "catalog:", "videojs-markers": "catalog:", "vue": "catalog:", "vue-demi": "^0.14.10", "vue-i18n": "catalog:", "vue-router": "catalog:", "vue3-clipboard": "catalog:", @@ -82,3 +85,4 @@ "vite-plugin-vue-setup-extend": "catalog:" } } applications/task-work-order/src/assets/docx/testDocx.docxBinary files differ
applications/task-work-order/src/assets/pdf/testPdf.pdfBinary files differ
applications/task-work-order/src/components/PreviewFiles/PreviewFiles.vue
New file @@ -0,0 +1,56 @@ <template> <el-dialog class="gd-dialog" v-model="visible" title="预览" @closed="visible = false" destroy-on-close fullscreen :close-on-click-modal="false" > <VueOfficeDocx v-if="type === 'docx'" :src="src" style="height: 100%;width: 100%" @rendered="onRendered" @error="onError" /> <VueOfficePdf v-else :src="src" style="height: 100%;width: 100%" @rendered="onRendered" @error="onError" /> </el-dialog> </template> <script setup> import VueOfficeDocx from '@vue-office/docx' import VueOfficePdf from '@vue-office/pdf' import '@vue-office/docx/lib/index.css' // 必须引入样式 const visible = ref(false) const props = defineProps({ src: { default: '', }, type:{ type: String, default: 'docx' } }) function onRendered() { console.log("文档渲染完成") } function onError() { console.log("文档渲染失败") } </script> <style scoped lang="scss"></style> applications/task-work-order/src/styles/common/cockpit.scss
@@ -491,7 +491,7 @@ overflow: auto; .detail-title { margin-bottom: 20px; margin-bottom: 10px; font-family: Source Han Sans CN, Source Han Sans CN; font-weight: 400; font-size: 14px; applications/task-work-order/src/views/orderView/orderDataManage/dataObjection/FormDiaLog.vue
@@ -25,10 +25,6 @@ <div class="label">提交人联系方式</div> <div class="val">{{ formData.submitterContact }}</div> </el-col> <!-- <el-col :span="12"> <div class="label">提交单位</div> <div class="val">{{ formData.submitUnitName }}</div> </el-col> --> <el-col :span="12"> <div class="label">目录/申请资源名称</div> <div class="val">{{ formData.catalogResourceName }}</div> @@ -45,7 +41,43 @@ <div class="label">相关附件</div> <div class="val">{{ formData.attachName || '暂无附件' }}</div> </el-col> <el-col :span="12" v-if="detailObjectionStatus === '2'"> <div class="label">其他异议详情</div> <div class="val">{{ formData.otherObjectionDetail }}</div> </el-col> <el-col :span="12" v-if="detailObjectionStatus === '2'"> <div class="label">审核意见</div> <div class="val">{{ formData.reviewOpinion }}</div> </el-col> </el-row> <div v-if=" detailObjectionStatus === '1'"> <div class="detail-title" :style="{ marginTop:pxToRem(20)}">异议反馈</div> <el-form ref="feedbackFormRef" class="gd-dialog-form" :model="feedbackFormData" :rules="feedbackRules" label-width="140px"> <el-row> <el-col :span="12"> <el-form-item label="其他异议详情" prop="otherObjectionDetail"> <el-input class="gd-input" v-model="feedbackFormData.otherObjectionDetail" placeholder="请输入" clearable /> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="审核意见" prop="reviewOpinion"> <el-input class="gd-input" v-model="feedbackFormData.reviewOpinion" placeholder="请输入" clearable /> </el-form-item> </el-col> </el-row> </el-form> </div> </div> <el-form @@ -55,7 +87,7 @@ :model="formData" :rules="rules" :disabled="dialogReadonly" label-width="120px" label-width="180px" > <el-row> <el-col :span="12"> @@ -91,20 +123,6 @@ <el-input class="gd-input" v-model="formData.submitterContact" placeholder="请输入" clearable /> </el-form-item> </el-col> <!-- <el-col :span="12">--> <!-- <el-form-item label="提交单位" prop="submitUnitId">--> <!-- <el-tree-select--> <!-- class="gd-select"--> <!-- popper-class="gd-tree-select-popper"--> <!-- v-model="formData.submitUnitId"--> <!-- node-key="id"--> <!-- :data="deptTree"--> <!-- :props="treeProps"--> <!-- check-strictly--> <!-- clearable--> <!-- />--> <!-- </el-form-item>--> <!-- </el-col>--> <el-col :span="12"> <el-form-item label="目录/申请资源名称" prop="catalogResourceName"> <el-input class="gd-input" v-model="formData.catalogResourceName" placeholder="请输入" clearable /> @@ -156,7 +174,9 @@ </el-col> </el-row> </el-form> <template #footer> <template v-if="!dialogReadonly"> <el-button class="save-btn" color="#4C34FF" @@ -167,8 +187,26 @@ > 保存 </el-button> <el-button color="#F2F3F5" @click="handleApply">申请</el-button> <el-button color="#F2F3F5" :loading="submitting" :disabled="submitting" @click="handleApply">申请</el-button> </template> <template v-if="dialogReadonly && detailObjectionStatus === '1'"> <el-button color="#F2F3F5" :loading="submitting" :disabled="submitting" @click="visible = false">取消</el-button> <el-button class="save-btn" color="#4C34FF" :loading="submitting" :disabled="submitting" @click="handleFeedbackSubmit" > 反馈 </el-button> </template> <template v-if="detailDemandStatus === '2'"> <el-button color="#F2F3F5" :loading="submitting" :disabled="submitting" @click="visible = false">关闭</el-button> </template> </template> </el-dialog> </template> @@ -182,7 +220,7 @@ gdDataObjectionSubmitApi, } from '@/views/orderView/orderDataManage/dataObjection/dataObjectionApi' import { putFileAttachApi } from '@/views/orderView/orderDataManage/supplyAdd/supplyAddApi' import { pxToRem } from '@/utils/rem' // 初始化表单数据 const initForm = () => ({ title: '', @@ -198,18 +236,28 @@ attachId: '', attachName: '', } ] ], objectionStatus: '', }) // 初始化异议反馈表单数据 const initFeedbackForm = () => ({ otherObjectionDetail: '', reviewOpinion: '', objectionStatus: '2' }) // 注入部门树和字典 const deptTree = inject('deptTree') const treeProps = inject('treeProps') const dictObj = inject('dictObj') const detailObjectionStatus = inject('detailObjectionStatus') const emit = defineEmits(['success']) const formRef = ref(null) // 表单实例 const feedbackFormRef = ref(null) // 反馈表单实例 const formData = ref(initForm()) // 表单数据 const feedbackFormData = ref(initFeedbackForm()) // 异议反馈表单数据 const visible = defineModel() // 弹框显隐 const dialogMode = ref('add') // 弹框模式 const submitting = ref(false) // 提交中 @@ -227,6 +275,12 @@ catalogResourceName: fieldRules(true), objectionDesc: fieldRules(true), objectionBasis: fieldRules(true), } // 异议反馈表单校验规则 const feedbackRules = { otherObjectionDetail: fieldRules(true), reviewOpinion: fieldRules(true), } // 自定义上传请求 @@ -294,8 +348,8 @@ ElMessage.error(error?.message || '文件上传失败,请重试') } // 提交新增/编辑 async function handleSubmit() { // 提交数据的通用函数 async function submitForm(objectionStatus) { const isValid = await formRef.value?.validate().catch(() => false) if (!isValid) return submitting.value = true @@ -311,14 +365,12 @@ objectionBasis: formData.value.objectionBasis, areaCode: formData.value.areaCode || '', handleUnit: formData.value.handleUnit || '', objectionStatus: formData.value.objectionStatus || '', otherObjectionDetail: formData.value.otherObjectionDetail || '', reviewOpinion: formData.value.reviewOpinion || '', // 构建附件列表 attachmentList: uploadedFiles.value.map(file => ({ attachId: file.attachId, attachName: file.originalName, })) })), objectionStatus: objectionStatus } await gdDataObjectionSubmitApi(submitData) ElMessage.success(dialogMode.value === 'add' ? '新增成功' : '更新成功') @@ -328,9 +380,38 @@ submitting.value = false } } // 提交新增/编辑(保存) async function handleSubmit() { await submitForm('0') } // 申请提交 async function handleApply() { await submitForm('1') } // 处理异议反馈提交 async function handleFeedbackSubmit() { // 验证反馈表单 const isValid = await feedbackFormRef.value?.validate().catch(() => false) if (!isValid) return submitting.value = true try { // 构建反馈提交数据 const submitData = { id: formData.value.id, otherObjectionDetail: feedbackFormData.value.otherObjectionDetail || '', reviewOpinion: feedbackFormData.value.reviewOpinion || '', objectionStatus: '2' } await gdDataObjectionSubmitApi(submitData) ElMessage.success('反馈提交成功') visible.value = false emit('success') } finally { submitting.value = false } } // 加载详情 async function loadDetail() { @@ -345,7 +426,10 @@ // 重置文件列表 fileList.value = [] uploadedFiles.value = [] // 重置表单数据 formData.value = dialogMode.value === 'add' ? initForm() : row // 重置反馈表单数据 feedbackFormData.value = initFeedbackForm() if (dialogMode.value !== 'add') { await loadDetail() } @@ -357,22 +441,11 @@ <style scoped lang="scss"> .detail-container { padding: 20px; .label { font-weight: 500; color: #333333; margin-bottom: 8px; } .val { padding: 8px; background-color: #f5f7fa; border-radius: 4px; min-height: 32px; word-break: break-all; margin-bottom: 16px; } } .upload-container { width: 100%; } .label { width: 120px !important; } </style> applications/task-work-order/src/views/orderView/orderDataManage/dataObjection/index.vue
@@ -66,8 +66,8 @@ <el-table-column label="操作" class-name="operation-btns" width="140"> <template v-slot="{ row }"> <el-link @click="openForm('view', row)">查看</el-link> <el-link @click="openForm('edit', row)">编辑</el-link> <el-link @click="handleDelete(row)">删除</el-link> <el-link @click="openForm('edit', row)" v-if="!['1', '2'].includes(row.objectionStatus)">编辑</el-link> <el-link @click="handleDelete(row)" v-if="!['1', '2'].includes(row.objectionStatus)">删除</el-link> </template> </el-table-column> </el-table> @@ -122,6 +122,8 @@ label: 'name', children: 'children', } const detailObjectionStatus = ref('') provide('detailObjectionStatus', detailObjectionStatus) provide('deptTree', deptTree) provide('treeProps', treeProps) provide('dictObj', dictObj) @@ -153,6 +155,7 @@ // 新增/编辑/查看 弹框 function openForm(mode, row) { detailObjectionStatus.value = row?.objectionStatus dialogVisible.value = true nextTick(() => { dialogRef.value?.open({ mode, row }) applications/task-work-order/src/views/orderView/orderDataManage/supplyAdd/auditRecord.vue
@@ -45,7 +45,7 @@ steps.push({ status: '0', title: '需求申请', person: sortedRecords.find(r => r.auditStatus === '0')?.createUser || '', person: sortedRecords.find(r => r.auditStatus === '0')?.userName || '', time: sortedRecords.find(r => r.auditStatus === '0')?.createTime || '' }) @@ -55,7 +55,7 @@ steps.push({ status: '1', title: '审核通过', person: approvedRecord.createUser || '', person: approvedRecord.userName || '', time: approvedRecord.createTime || '' }) } @@ -66,7 +66,7 @@ steps.push({ status: '2', title: '拒绝申请', person: rejectedRecord.createUser || '', person: rejectedRecord.userName || '', time: rejectedRecord.createTime || '' }) // 查找拒绝原因 @@ -89,6 +89,7 @@ <style scoped lang="scss"> .audit-record-container { height: 95%; .label { font-weight: 500; margin-bottom: 8px; applications/task-work-order/src/views/orderView/orderManage/clueEvents/ViewDiaLog.vue
@@ -1,8 +1,8 @@ <template> <el-dialog class="gd-dialog" :close-on-click-modal="false" v-model="visible" title="查看" @closed="visible = false" width="1000px" destroy-on-close> <div class="gd-table-container" v-loading="loading"> <div class="gd-table-content gd-table-content-bg"> <el-table class="gd-table" :data="list"> <div class="" v-loading="loading"> <div class="gd-table-content-bg"> <el-table :data="list"> <el-table-column label="线索缩略图" width="120"> <template v-slot="{ row }"> <el-image applications/task-work-order/src/views/orderView/orderManage/inspectionRequest/FormDiaLog.vue
@@ -11,8 +11,7 @@ <div class="gd-dialog-form"> <!-- 关联工单选择 --> <div class="work-order-section"> <div class="form-item-row"> <span class="label required">选择工单:</span> <div class="detail-title" :style="{marginBottom: 0,marginRight: pxToRem(10)}">选择工单</div> <el-select class="gd-select" style="width: 150px" @@ -26,7 +25,6 @@ > <el-option v-for="item in workOrderList" :key="item.id" :label="item.workOrderName" :value="item.id" /> </el-select> </div> </div> <!-- 工单信息展示 --> @@ -61,7 +59,7 @@ <!-- 子任务表格表单 --> <div class="task-table-section"> <div class="section-title">添加子任务:</div> <div class="detail-title" :style="{marginTop: pxToRem(10)}">添加子任务</div> <div class="task-table-container"> <el-table :data="taskList"> <el-table-column width="50" label=""> @@ -196,6 +194,7 @@ import { gdPatrolTaskSaveApi, gdFlyerPageApi, gdPatrolTaskAuditApi } from './inspectionRequestApi' import { gdWorkOrderPageApi } from '../orderManage/orderManageApi' import { gdManageDeviceListApi } from '../orderManage/gdManageDeviceApi' import { pxToRem } from '@/utils/rem' // 初始化任务行 const initTaskRow = () => ({ @@ -354,4 +353,12 @@ defineExpose({ open }) </script> <style scoped lang="scss"></style> <style scoped lang="scss"> .detail-row-view{ margin-top: 10px; } .work-order-section{ display: flex; align-items: center; } </style> applications/task-work-order/src/views/orderView/orderManage/inspectionRequest/ViewDiaLog.vue
@@ -336,7 +336,7 @@ async function open({ mode = 'view', row } = {}) { dialogMode.value = mode formData.value = { ...initForm(), ...row }; ['6','7','8'].includes(row.taskStatus) && getWorkOrderList() ['6','7','8'].includes(row.taskStatus) && getList() initMap() } applications/task-work-order/src/views/orderView/orderManage/orderManage/index.vue
@@ -69,6 +69,7 @@ <div class="gd-table-toolbar"> <el-button color="#F2F3F5" @click="requester = !requester">我是{{ requester ? '需求方' : '服务方' }}</el-button> <el-button color="#F2F3F5" @click="previewVisible = true">预览</el-button> <el-button :icon="Plus" color="#4C34FF" type="primary" @click="openForm('add')">新增</el-button> <el-button :icon="Delete" color="#4C34FF" :disabled="!selectedIds.length" @click="handleDelete()">删除</el-button> @@ -127,6 +128,7 @@ </div> </div> <PreviewFiles v-model="previewVisible" :src="testDock" type="docx"/> <FormDiaLog ref="dialogRef" @success="getList" v-if="dialogVisible" v-model="dialogVisible" /> </basic-container> </template> @@ -139,6 +141,9 @@ import FormDiaLog from './FormDiaLog.vue' import { gdWorkOrderPageApi, gdWorkOrderRemoveApi } from './orderManageApi' import dayjs from 'dayjs' import PreviewFiles from '@/components/PreviewFiles/PreviewFiles.vue' import testDock from '@/assets/docx/testDocx.docx' import testPdf from '@/assets/pdf/testPdf.pdf' // 初始化查询参数 const initSearchParams = () => ({ @@ -160,6 +165,7 @@ const queryParamsRef = ref(null) // 查询表单实例 const dialogRef = ref(null) // 弹框实例 const dialogVisible = ref(false) const previewVisible = ref(false) const dictObj = ref({ deviceLoadDemand: [], // 设备负载需求 workOrderType: [], // 工单类型 applications/task-work-order/vite.config.mjs
@@ -48,7 +48,7 @@ } }, }, assetsInclude: ['**/*.gltf'], assetsInclude: ['**/*.gltf','**/*.docx','**/*.pdf'], resolve: { alias: { '~': resolve(__dirname, './'), package.json
@@ -41,7 +41,9 @@ "esbuild", "protobufjs", "sharp", "vue-demi" "vue-demi", "@vue-office/docx", "@vue-office/pdf" ] }, "devDependencies": { pnpm-lock.yaml
Diff too large