applications/drone-command/src/views/basicManage/deviceStock/fwDeviceTrackApi.js
@@ -35,3 +35,12 @@ params, }) } // 更新出库状态 export const fwDeviceUpdateTrackStatusApi = params => { return request({ url: `/drone-fw/device/fwDevice/updateTrackStatus`, method: 'post', params, }) } applications/drone-command/src/views/basicManage/deviceStock/index.vue
@@ -86,11 +86,17 @@ {{ getDictLabel(row.status, dictObj.deviceStatus) }} </template> </el-table-column> <el-table-column prop="yxzt" show-overflow-tooltip width="116" label="出库状态"> <template v-slot="{ row }"> {{ getDictLabel(row.trackStatus, trackStatusOptions) }} </template> </el-table-column> <el-table-column label="操作" class-name="operation-btns"> <template v-slot="{ row }"> <el-link @click="handleView(row)">查看</el-link> <el-link @click="handleEdit(row)">编辑</el-link> <el-link @click="outbound(row)">出库</el-link> <el-link v-if="row.trackStatus === 0" @click="outbound(row)">出库</el-link> <el-link v-else @click="returnDevice(row)">归还</el-link> <el-link @click="scrap(row)" v-if="row.status !== 3">报废</el-link> <!-- <el-link @click="handleDelete(row)" type="danger">删除</el-link>--> </template> @@ -121,6 +127,7 @@ import { onMounted, ref } from 'vue' import { ElMessage, ElMessageBox } from 'element-plus' import { exportFwDeviceApi, fwDevicePageApi, fwDeviceRemoveApi } from '@/views/basicManage/deviceStock/fwDevice' import { fwDeviceUpdateTrackStatusApi } from '@/views/basicManage/deviceStock/fwDeviceTrackApi' import FormDiaLog from './FormDiaLog.vue' import { getDictionaryByCode } from '@/api/system/dictbiz' import { getDeptTree } from '@/api/system/dept' @@ -162,6 +169,12 @@ provide('dictObj', dictObj) provide('deptTree', deptTree) // 出库状态 const trackStatusOptions = ref([ { dictKey: 0, dictValue: '未出库' }, { dictKey: 1, dictValue: '已出库' } ]) // 获取列表 async function getList() { const range = dateRangeFormat(dateRange.value) @@ -204,6 +217,22 @@ outboundDialogRef.value?.open({ mode: 'edit', row: { ...row } }) } // 归还 async function returnDevice(row) { await ElMessageBox.confirm(`确认归还吗?`, '提示', { type: 'warning', customClass: 'command-page-view-message-box', confirmButtonClass: 'command-message-box-confirm', cancelButtonClass: 'command-message-box-cancel', }) const payload = { deviceId: row.id } await fwDeviceUpdateTrackStatusApi(payload) ElMessage.success('归还成功') getList() } function scrap(row) { scrapDialogRef.value?.open({ mode: 'edit', row: { ...row } }) } applications/task-work-order/src/styles/common/cockpit.scss
@@ -475,7 +475,7 @@ .detail-container { display: flex; justify-content: space-between; height: 680px; max-height: 680px; .detail-left { margin-right: 20px; @@ -519,6 +519,7 @@ .label { display: inline-block; width: 88px; flex-shrink: 0; font-family: Source Han Sans CN, Source Han Sans CN; font-weight: 500; font-size: 14px; @@ -531,6 +532,8 @@ .val { margin-left: 12px; flex: 1; overflow: hidden; font-family: Source Han Sans CN, Source Han Sans CN; font-weight: 400; font-size: 14px; @@ -539,6 +542,13 @@ text-align: left; font-style: normal; text-transform: none; } .val-long { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; cursor: pointer; } } } @@ -1048,14 +1058,14 @@ th.el-table__cell { height: 40px; border-bottom: 1px solid #DBDFF1 !important; border-bottom: 1px solid #E5E6EB !important; .cell { padding: 0 0 0 16px; font-family: Source Han Sans CN, Source Han Sans CN; font-weight: 400; font-size: 14px; color: #9292C1; color: #86909C; text-align: left; font-style: normal; text-transform: none; @@ -1071,7 +1081,7 @@ font-family: Source Han Sans CN, Source Han Sans CN; font-weight: 400; font-size: 14px; color: #383874; color: #4E5969; text-align: left; font-style: normal; text-transform: none; applications/task-work-order/src/styles/tags.scss
@@ -39,7 +39,7 @@ &:active { color: #FFFFFF !important; background: #5B6BFF !important; background: #4C34FF !important; span { color: #fff !important; @@ -50,7 +50,7 @@ //padding: 0 !important; //padding-left: 20px !important; color: #FFFFFF !important; background: #5B6BFF !important; background: #4C34FF !important; .is-icon-close { //margin: 0 10px; applications/task-work-order/src/views/orderView/equipmentResource/equipmentResourceApi.js
New file @@ -0,0 +1,37 @@ import request from '@/axios' // 设备分页查询 export function getEquipmentPage(params) { return request({ url: '/drone-gd/workOrder/gdManageDevice/page', method: 'get', params // params: { descs: 'create_time', ...params }, }) } // 设备提交 export function submitExternalEquipment(data) { return request({ url: '/drone-gd/workOrder/gdManageDevice/submitExternal', method: 'post', data }) } // 设备删除 export function removeEquipment(data) { return request({ url: `/drone-gd/workOrder/gdManageDevice/remove?ids=${data.ids}`, method: 'post', }) } // 设备详情查询 export function getEquipmentDetail(params) { return request({ url: '/drone-gd/workOrder/gdManageDevice/detail', method: 'get', params }) } applications/task-work-order/src/views/orderView/flyingHand/FlyingHandDialog.vue
@@ -7,12 +7,57 @@ destroy-on-close :close-on-click-modal="false" > <el-row class="detail-row-view" v-if="dialogType === 'view'"> <el-col :span="12"> <div class="label">飞手姓名</div> <div class="val">{{ formData.flyerName }}</div> </el-col> <el-col :span="12"> <div class="label">飞手电话</div> <div class="val">{{ formData.flyerPhone }}</div> </el-col> <el-col :span="12"> <div class="label">飞行时长</div> <div class="val">{{ formData.flightHours }}</div> </el-col> <el-col :span="12"> <div class="label">技术特长</div> <div class="val">{{ getDictLabel(formData.technicalStrength, dictObj.technicalStrength) }}</div> </el-col> <el-col :span="12"> <div class="label">擅长机型</div> <div class="val">{{ getDictLabel(formData.skilledUavType, dictObj.skilledUavType) }}</div> </el-col> <el-col :span="12"> <div class="label">擅长任务类型</div> <div class="val">{{ getDictLabel(formData.skilledTaskType, dictObj.skilledTaskType) }}</div> </el-col> <el-col :span="12"> <div class="label">项目经验</div> <div class="val">{{ formData.projectExperience }}</div> </el-col> <el-col :span="12"> <div class="label">飞手证书</div> <div class="val"> <el-image v-for="(item, index) in formData.certification" :key="index" :src="item" :preview-src-list="formData.certification" class="gd-image" style="width: 100px; height: 100px; margin-right: 10px;" /> </div> </el-col> </el-row> <el-form ref="formRef" :model="formData" :rules="rules" class="gd-form" label-width="160px" v-else > <el-row> <el-col :span="12"> @@ -124,7 +169,7 @@ /> </el-form-item> </el-col> <el-col :span="24" v-if="dialogType === 'view'"> <!-- <el-col :span="24" v-if="dialogType === 'view'"> <el-form-item label="飞手证书" prop="certification"> <el-image v-for="(item, index) in formData.certification" @@ -135,11 +180,11 @@ style="width: 100px; height: 100px; margin-right: 10px;" /> </el-form-item> </el-col> </el-col> --> </el-row> </el-form> <template #footer> <el-button color="#F2F3F5" @click="handleClose">取消</el-button> <el-button v-if="dialogType !== 'view'" color="#F2F3F5" @click="handleClose">取消</el-button> <el-button v-if="dialogType !== 'view'" type="primary" @@ -155,6 +200,7 @@ import { ref, reactive, computed, watch, inject } from 'vue' import { submitFlyingHand } from './flyingHandApi' import { ElMessage } from 'element-plus' import { getDictLabel } from '@ztzf/utils' import { fieldRules } from '@ztzf/utils' @@ -188,11 +234,11 @@ const dialogTitle = computed(() => { switch (props.dialogType) { case 'add': return '添加飞手信息' return '新增' case 'edit': return '编辑飞手信息' return '编辑' case 'view': return '查看飞手信息' return '查看' default: return '飞手信息' } applications/task-work-order/src/views/orderView/flyingHand/index.vue
@@ -3,7 +3,13 @@ <basic-container> <el-form ref="queryParamsRef" :model="searchParams" class="gd-search-form"> <el-form-item label="飞手姓名" prop="flyerName"> <el-select <el-input class="gd-input gray" v-model="searchParams.flyerName" placeholder="请输入飞手姓名" clearable /> <!-- <el-select class="gd-select gray" popper-class="gd-select-popper" v-model="searchParams.flyerName" @@ -15,7 +21,7 @@ :label="item.name" :value="item.id" /> </el-select> </el-select> --> </el-form-item> <el-form-item label="擅长机型" prop="skilledUavType"> applications/task-work-order/src/views/orderView/orderDataManage/appInnovation/index.vue
@@ -64,7 +64,7 @@ <template v-slot="{ row }"> <el-link type="primary" @click="openForm('view', row)">查看</el-link> <!-- <el-link type="primary" @click="openForm('edit', row)">编辑</el-link>--> <el-link type="primary" @click="handleDelete(row)" v-if="!['1', '2'].includes(row.innovationStatus)">删除</el-link> <el-link type="primary" @click="handleDelete(row)" v-if="!['1', '2'].includes(row.innovationStatus) && row.isTheSameDepartment">删除</el-link> </template> </el-table-column> </el-table> @@ -96,7 +96,9 @@ gdApplicationInnovationPageApi, gdApplicationInnovationRemoveApi, } from '@/views/orderView/orderDataManage/appInnovation/appInnovationApi' import { useStore } from 'vuex' const store = useStore() const userDepartment = store.state.user.userInfo?.dept_id // 初始化查询参数 const initSearchParams = () => ({ caseName: '', // 案例名称 @@ -128,6 +130,9 @@ loading.value = true try { const res = await gdApplicationInnovationPageApi(searchParams.value) res?.data?.data?.records.forEach(item => { item.isTheSameDepartment = String(item.createDept) === String(userDepartment) }) list.value = res?.data?.data?.records ?? [] total.value = res?.data?.data?.total ?? 0 } finally { applications/task-work-order/src/views/orderView/orderDataManage/dataObjection/FormDiaLog.vue
@@ -7,7 +7,7 @@ destroy-on-close :close-on-click-modal="false" > <div class="detail-container" v-if="dialogReadonly"> <div class="detail-container detail-container1" v-if="dialogReadonly"> <el-row class="detail-row-view"> <el-col :span="12"> <div class="label">标题</div> @@ -50,7 +50,7 @@ <div class="val">{{ formData.reviewOpinion }}</div> </el-col> </el-row> <div v-if=" detailObjectionStatus === '1'"> <div v-if=" detailObjectionStatus === '1' && !requesterProvider"> <div class="detail-title" :style="{ marginTop:pxToRem(20)}">异议反馈</div> <el-form ref="feedbackFormRef" class="gd-dialog-form" :model="feedbackFormData" :rules="feedbackRules" label-width="140px"> @@ -153,7 +153,6 @@ <div class="upload-container"> <el-upload :http-request="handleHttpRequest" :limit="3" :on-success="handleUploadSuccess" :on-error="handleUploadError" :on-remove="handleFileRemove" @@ -166,7 +165,7 @@ <el-button type="primary">选择文件</el-button> </template> <template #tip> <div class="el-upload__tip">支持上传 (.zip/.rar/.7z/.tar/.gz)格式文件</div> <div class="el-upload__tip">支持上传 (.zip/.rar/.7z/.tar/.gz)格式</div> </template> </el-upload> </div> @@ -178,18 +177,18 @@ <template #footer> <template v-if="!dialogReadonly"> <el-button color="#F2F3F5" color="#F2F3F5" v-if="!dialogReadonly" :loading="submitting" :disabled="submitting" @click="handleSubmit" > 保存 </el-button> <el-button class="" color="#4C34FF" :loading="submitting" :disabled="submitting" @click="handleApply">申请</el-button> v-if="!dialogReadonly" :loading="submitting || uploading" :disabled="submitting || uploading" @click="handleSubmit" > 保存 </el-button> <el-button class="" color="#4C34FF" :loading="submitting || uploading" :disabled="submitting || uploading" @click="handleApply">申请</el-button> </template> <template v-if="dialogReadonly && detailObjectionStatus === '1'"> <template v-if="dialogReadonly && detailObjectionStatus === '1' && !requesterProvider"> <el-button color="#F2F3F5" :loading="submitting" :disabled="submitting" @click="visible = false">取消</el-button> <el-button @@ -233,8 +232,12 @@ } from '@/views/orderView/orderDataManage/dataObjection/dataObjectionApi' import { putFileAttachApi } from '@/views/orderView/orderDataManage/supplyAdd/supplyAddApi' import { pxToRem } from '@/utils/rem' import { useStore } from 'vuex' const store = useStore() const requesterProvider = computed(() => store.state.user.userInfo?.role_id === '2014158512610869250') // 初始化表单数据 const initForm = () => ({ id:'', title: '', objectionType: '', submitter: '', @@ -278,6 +281,7 @@ const fileList = ref([]) // 上传文件列表 const uploadedFiles = ref([]) // 已上传文件列表 const attachmentDetailsList = ref([]) const uploading = ref(false) // 文件上传中状态 // 表单校验规则 const rules = { @@ -288,6 +292,8 @@ catalogResourceName: fieldRules(true), objectionDesc: fieldRules(true), objectionBasis: fieldRules(true), // attachId: dialogMode.value === 'add' ? fieldRules(true) : fieldRules(false) } // 异议反馈表单校验规则 @@ -298,6 +304,7 @@ // 自定义上传请求 const handleHttpRequest = async options => { uploading.value = true try { const formDataObj = new FormData() formDataObj.append('file', options.file) @@ -310,16 +317,27 @@ } catch (error) { options.onError(error) console.error('文件上传失败:', error) } finally { uploading.value = false } } // 文件移除 // const handleFileRemove = (file, fileListVal) => { // uploadedFiles.value = fileListVal // } const handleFileRemove = (file, fileListVal) => { if (file.response && file.response.attachId) { uploadedFiles.value = uploadedFiles.value.filter(item => item.attachId !== file.response.attachId) } // 从展示列表中移除 fileList.value = fileListVal // 从已上传列表中移除 const index = uploadedFiles.value.findIndex(item => item.attachId === file.attachId || item.name === file.name ) if (index > -1) { uploadedFiles.value.splice(index, 1) } } // 上传前验证 const beforeFileUpload = file => { const allowedExtensions = ['.zip', '.rar', '.7z', '.tar', '.gz'] @@ -328,11 +346,11 @@ ElMessage.error('只能上传压缩文件格式:.zip/.rar/.7z/.tar/.gz') return false } const maxSize = 100 * 1024 * 1024 // 100MB if (file.size > maxSize) { ElMessage.error('文件大小不能超过100MB') return false } // const maxSize = 100 * 1024 * 1024 // 100MB // if (file.size > maxSize) { // ElMessage.error('文件大小不能超过100MB') // return false // } return true } @@ -357,35 +375,53 @@ // 提交数据的通用函数 async function submitForm(objectionStatus) { const isValid = await formRef.value?.validate().catch(() => false) if (!isValid) return submitting.value = true try { // 构建符合接口要求的提交数据 const submitData = { title: formData.value.title, objectionType: formData.value.objectionType, submitter: formData.value.submitter, submitterContact: formData.value.submitterContact, catalogResourceName: formData.value.catalogResourceName, objectionDesc: formData.value.objectionDesc, objectionBasis: formData.value.objectionBasis, areaCode: formData.value.areaCode || '', handleUnit: formData.value.handleUnit || '', // 构建附件列表 attachmentList: uploadedFiles.value.map(file => ({ attachId: file.attachId, attachName: file.originalName, })), objectionStatus: objectionStatus } await gdDataObjectionSubmitApi(submitData) ElMessage.success(dialogMode.value === 'add' ? '新增成功' : '更新成功') visible.value = false emit('success') } finally { submitting.value = false } const isValid = await formRef.value?.validate().catch(() => false) if (!isValid) return // 在编辑模式下,如果已有附件,可以不强制上传新附件 if (dialogMode.value === 'add' && uploadedFiles.value.length === 0) { return ElMessage.warning('请上传附件') } submitting.value = true try { // 构建符合接口要求的提交数据 const submitData = { // 编辑模式下传递id ...(formData.value.id && { id: formData.value.id }), title: formData.value.title, objectionType: formData.value.objectionType, submitter: formData.value.submitter, submitterContact: formData.value.submitterContact, catalogResourceName: formData.value.catalogResourceName, objectionDesc: formData.value.objectionDesc, objectionBasis: formData.value.objectionBasis, areaCode: formData.value.areaCode || '', handleUnit: formData.value.handleUnit || '', // 构建附件列表 - 使用当前已上传的文件(包括回显的) ...(uploadedFiles.value.length > 0 && { attachmentList: uploadedFiles.value.map(file => ({ attachId: file.attachId, attachName: file.originalName, })), }), objectionStatus: objectionStatus } // 如果是编辑且没有修改附件,可以保留原有附件ID if (dialogMode.value === 'edit' && formData.value.attachIds) { // 这里可以根据业务需求决定是否保留原附件ID // 如果接口支持更新时重新上传附件ID列表,可以这样做 } await gdDataObjectionSubmitApi(submitData) ElMessage.success(dialogMode.value === 'add' ? '新增成功' : '更新成功') visible.value = false emit('success') } finally { submitting.value = false } } // 提交新增/编辑(保存) @@ -422,12 +458,42 @@ } // 加载详情 async function loadDetail() { if (!formData.value.id) return const res = await gdDataObjectionDetailApi({ id: formData.value.id }) formData.value = res?.data?.data ?? {} if (formData.value.attachIds) { getAttachDetail(formData.value.attachIds) } if (!formData.value.id) return const res = await gdDataObjectionDetailApi({ id: formData.value.id }) formData.value = res?.data?.data ?? {} // 处理附件回显 if (formData.value.attachIds) { await getAttachDetail(formData.value.attachIds) // 回显到上传组件 updateFileListForDisplay() } } // 更新文件列表用于显示 function updateFileListForDisplay() { fileList.value = [] uploadedFiles.value = [] if (attachmentDetailsList.value && attachmentDetailsList.value.length > 0) { attachmentDetailsList.value.forEach(attach => { const fileItem = { name: attach.originalName || attach.name, url: attach.link, // 用于预览 attachId: attach.id, // 文件ID originalName: attach.originalName, link: attach.link } fileList.value.push({ name: fileItem.name, url: fileItem.url, status: 'success' // 已上传状态 }) uploadedFiles.value.push(fileItem) }) } } // 获取附件详情 async function getAttachDetail(attachIds) { @@ -436,7 +502,6 @@ const detailPromises = ids.map(id => getAttachDetailApi({ id })) const results = await Promise.all(detailPromises) attachmentDetailsList.value = results.map(res => res.data.data).filter(Boolean) console.log('附件详情', attachmentDetailsList.value) } // 处理附件下载 async function handleDownloadAttach() { @@ -462,25 +527,37 @@ // 打开弹框 async function open({ mode = 'add', row } = {}) { dialogMode.value = mode // 重置文件列表 fileList.value = [] uploadedFiles.value = [] // 重置表单数据 formData.value = dialogMode.value === 'add' ? initForm() : row // 重置反馈表单数据 feedbackFormData.value = initFeedbackForm() if (dialogMode.value !== 'add') { await loadDetail() } dialogMode.value = mode // 重置文件列表 fileList.value = [] uploadedFiles.value = [] // 重置表单数据 formData.value = dialogMode.value === 'add' ? initForm() : row // 重置反馈表单数据 feedbackFormData.value = initFeedbackForm() if (dialogMode.value !== 'add') { // 如果是编辑,设置ID并加载详情 if (row && row.id) { formData.value.id = row.id } await loadDetail() } } defineExpose({ open }) </script> <style scoped lang="scss"> .detail-container1 { display: flex; flex-direction: column; } .upload-container { width: 100%; .el-upload__tip { display: inline; } } .label { width: 120px !important; applications/task-work-order/src/views/orderView/orderDataManage/dataObjection/index.vue
@@ -67,7 +67,7 @@ <el-table-column prop="handleUnit" show-overflow-tooltip label="处理单位" /> <el-table-column prop="objectionDesc" show-overflow-tooltip label="异议描述" /> <el-table-column prop="objectionBasis" show-overflow-tooltip label="异议依据" /> <el-table-column prop="attachName" show-overflow-tooltip label="附件名称" /> <el-table-column prop="attachNames" show-overflow-tooltip label="附件名称" /> <el-table-column prop="reviewOpinion" show-overflow-tooltip label="审核意见" /> <el-table-column label="操作" class-name="operation-btns" width="150"> <template v-slot="{ row }"> applications/task-work-order/src/views/orderView/orderDataManage/evaluate/index.vue
@@ -56,8 +56,8 @@ <el-table-column label="操作" class-name="operation-btns" width="150"> <template v-slot="{ row }"> <el-link type="primary" @click="openForm('view', row)">查看</el-link> <el-link type="primary" @click="openForm('edit', row)">编辑</el-link> <el-link type="primary" @click="handleDelete(row)">删除</el-link> <el-link type="primary" @click="openForm('edit', row)" v-if="row.isTheSameDepartment">编辑</el-link> <el-link type="primary" @click="handleDelete(row)" v-if="row.isTheSameDepartment">删除</el-link> </template> </el-table-column> </el-table> @@ -88,7 +88,9 @@ gdDataEvaluationPageApi, gdDataEvaluationRemoveApi, } from '@/views/orderView/orderDataManage/evaluate/evaluateApi' import { useStore } from 'vuex' const store = useStore() const userDepartment = store.state.user.userInfo?.dept_id // 初始化查询参数 const initSearchParams = () => ({ title: '', // 标题 @@ -121,6 +123,9 @@ loading.value = true try { const res = await gdDataEvaluationPageApi(searchParams.value) res?.data?.data?.records.forEach(item => { item.isTheSameDepartment = String(item.createDept) === String(userDepartment) }) list.value = res?.data?.data?.records ?? [] total.value = res?.data?.data?.total ?? 0 } finally { applications/task-work-order/src/views/orderView/orderDataManage/supplyAdd/ApplyViewDialog.vue
@@ -69,7 +69,7 @@ </div> <!-- 申请中--> <div v-if="detailDemandStatus === '1' && !requesterProvider"> <div class="detail-title">数据上传</div> <div class="detail-title" :style="{ marginTop:pxToRem(10)}">数据上传</div> <div class="upload-container"> <el-upload :http-request="handleHttpRequest" @@ -107,8 +107,8 @@ </div> <template #footer> <template v-if="detailDemandStatus === '1' && !requesterProvider"> <el-button color="#F2F3F5" :loading="submitting" :disabled="submitting" @click="rejectTheApplication">拒绝申请</el-button> <el-button class="" color="#4C34FF" :loading="submitting" :disabled="submitting" @click="approvedByTheReview">审核通过</el-button> <el-button color="#F2F3F5" :loading="submitting || uploading" :disabled="submitting || uploading" @click="rejectTheApplication">拒绝申请</el-button> <el-button class="" color="#4C34FF" :loading="submitting || uploading" :disabled="submitting || uploading" @click="approvedByTheReview">审核通过</el-button> </template> <template v-if="detailDemandStatus === '2'"> <el-button class="" color="#4C34FF" @click="downloadAllFiles">全部下载</el-button> @@ -155,8 +155,10 @@ const uploadedFiles = ref([]) // 已上传文件列表 const responseData = ref(null) const submitting = ref(false) // 提交中状态 const uploading = ref(false) // 文件上传中状态 // 自定义上传请求函数 const handleHttpRequest = async (options) => { uploading.value = true try { // 创建FormData对象 const formData = new FormData() @@ -164,7 +166,6 @@ // 调用导入的API函数 const response = await putFileAttachApi(formData) console.log('response',response) if (response.data && response.data.success) { // 调用上传成功的回调 options.onSuccess(response) @@ -176,6 +177,8 @@ // 调用上传失败的回调 options.onError(error) console.error('文件上传失败:', error) } finally { uploading.value = false } } // 拒绝申请弹框控制 @@ -183,21 +186,7 @@ const tableData = ref([]) // 附件表格数据 // 文件移除 const handleFileRemove = (file, fileList) => { console.log('删除文件', fileList); uploadedFiles.value = fileList // 从已上传文件列表中移除对应文件 // if (file.response && file.response.attachId) { // // uploadedFiles.value = uploadedFiles.value.filter(item => item.attachId !== file.response.attachId) // // 找到 id=1 的对象的索引 // const index = uploadedFiles.value.findIndex(item => item.attachId !== file.response.attachId) // // 如果找到了,移除该对象 // if (index !== -1) { // uploadedFiles.value.splice(index, 1) // } // console.log('删除文件', uploadedFiles.value); // } // 清空响应数据 if (responseData.value && responseData.value.attachId === file.response?.attachId) { responseData.value = null @@ -215,11 +204,11 @@ } // 文件大小限制,这里限制为100MB const maxSize = 100 * 1024 * 1024 // 100MB if (file.size > maxSize) { ElMessage.error('文件大小不能超过100MB') return false } // const maxSize = 100 * 1024 * 1024 // 100MB // if (file.size > maxSize) { // ElMessage.error('文件大小不能超过100MB') // return false // } return true } @@ -229,7 +218,6 @@ // 添加更严格的检查,确保response不是undefined if (response && response?.data && response?.data?.success) { const fileData = response.data.data console.log('成功数据', fileData) responseData.value = fileData // 添加到已上传文件列表 uploadedFiles.value.push({ @@ -257,28 +245,13 @@ } } // 下载文件 const downloadFile = file => { if (file.link) { // 创建一个隐藏的a标签来触发下载 const a = document.createElement('a') a.href = file.link a.download = file.originalName || file.name document.body.appendChild(a) a.click() document.body.removeChild(a) } else { ElMessage.warning('文件链接无效') } } // 从表格下载文件 const downloadFileFromTable = file => { if (file.fileUrl) { // 创建一个隐藏的a标签来触发下载 const a = document.createElement('a') a.href = file.fileUrl a.download = file.name || 'attachment' a.download = file.fileOriginalName || '下载附件' document.body.appendChild(a) a.click() document.body.removeChild(a) @@ -309,7 +282,7 @@ if (file.fileUrl) { const a = document.createElement('a') a.href = file.fileUrl a.download = file.name || `attachment_${index + 1}` a.download = file.fileOriginalName || `下载附件_${index + 1}` document.body.appendChild(a) a.click() document.body.removeChild(a) @@ -389,9 +362,9 @@ // 拒绝申请 const rejectTheApplication = () => { if (uploadedFiles.value.length === 0) { return ElMessage.warning('请上传数据') } // if (uploadedFiles.value.length === 0) { // return ElMessage.warning('请上传数据') // } // 打开拒绝申请弹框 rejectionDialogVisible.value = true } @@ -503,6 +476,5 @@ :deep(.el-upload-list) { margin-top: 10px; } .el-upload-list__item.is-success:focus .el-upload-list__item-status-label, .el-upload-list__item.is-success:hover .el-upload-list__item-status-label{ display: none !important;} </style> applications/task-work-order/src/views/orderView/orderDataManage/supplyAdd/reasonForRejectionDialog.vue
@@ -10,7 +10,7 @@ :close-on-click-modal="false" > <div class="detail-container"> <div class="detail-cell"> <div class="detail-cell-reject"> <span class="cell-label">拒绝原因:</span> <el-input v-model="reasonForRejection" style="width: 380px" type="textarea" :rows="4" placeholder="请输入" /> </div> @@ -65,4 +65,8 @@ </script> <style scoped lang="scss"> .detail-cell-reject { display: flex; justify-content: flex-start; } </style> applications/task-work-order/src/views/orderView/orderManage/clueEvents/ViewDiaLog.vue
@@ -1,7 +1,7 @@ <template> <el-dialog class="gd-dialog" v-model="visible" title="查看" @closed="visible = false" width="1000px" destroy-on-close> <div v-loading="loading"> <el-table :data="list"> <el-table :data="list" class="gd-dialog-table"> <el-table-column label="线索缩略图" width="120"> <template v-slot="{ row }"> <el-image @@ -42,9 +42,9 @@ </el-table> </div> <template #footer> <!-- <template #footer> <el-button color="#F2F3F5" @click="visible = false">关闭</el-button> </template> </template> --> <DistributeDiaLog ref="distributeDialogRef" applications/task-work-order/src/views/orderView/orderManage/inspectionReport/index.vue
@@ -47,7 +47,11 @@ <el-table-column type="selection" width="46" /> <el-table-column type="index" width="64" label="序号" /> <el-table-column prop="nickName" show-overflow-tooltip label="文档名称" /> <el-table-column prop="attachSize" show-overflow-tooltip label="文档大小" /> <el-table-column prop="attachSize" show-overflow-tooltip label="文档大小"> <template v-slot="{ row }"> {{ formatFileSize(row.attachSize) }} </template> </el-table-column> <el-table-column prop="deptName" show-overflow-tooltip label="文档归属" /> <!-- <el-table-column prop="resultType" show-overflow-tooltip label="文档类型" /> --> <el-table-column prop="resultType" show-overflow-tooltip label="文档类型"> @@ -138,10 +142,10 @@ </template> <script setup> import { Search, RefreshRight, Download, Upload, Delete } from '@element-plus/icons-vue' import { fjPageApi, fjSubmitApi, fjRemoveApi, fjDetailApi, fjUploadApi } from './inspectionRequestApi' import { fjPageApi, fjSubmitApi, fjRemoveApi, fjDetailApi, fjUploadApi,fjDownloadByByteApi } from './inspectionRequestApi' import { useStore } from 'vuex' import { ref, computed, inject, onMounted } from 'vue' import { ElMessage, ElMessageBox } from 'element-plus' import { ElMessage, ElMessageBox, ElLoading } from 'element-plus' import { getDictLabel } from '@ztzf/utils' import PreviewFiles from '@/components/PreviewFiles/PreviewFiles.vue' import { getDictionaryByCode } from '@/api/system/dictbiz' @@ -203,6 +207,15 @@ }) } // 将字节大小转换为可读格式的函数 const formatFileSize = (bytes) => { if (bytes === 0 || bytes === null) return '0 B' const k = 1024 const sizes = ['B', 'KB', 'MB', 'GB', 'TB'] const i = Math.floor(Math.log(bytes) / Math.log(k)) return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i] } // 获取列表 async function getList() { loading.value = true @@ -261,9 +274,9 @@ const fileType = row?.link?.split('.').pop() || '' if (!row.link) { ElMessage.warning('文件链接不存在') }else if (allSupportedExtensions.includes(fileType)){ } else if (allSupportedExtensions.includes(fileType)){ window.open(`${VITE_APP_PREVIEW_URL}/onlinePreview?url=`+encodeURIComponent(Base64.encode(row.link))); }else { } else { ElMessage.warning(`${fileType}文件格式,可以下载再查看`) } } @@ -289,7 +302,7 @@ selectedFiles.value = rows selectedIds.value = rows.map(item => item.id) } let loadingData // 文档下载 async function handleDownload() { // 如果是勾选一个可以直接下载,超过一个打包下载 @@ -298,8 +311,9 @@ ElMessage.warning('请选择要下载的文件') return } selectedFiles.value.forEach((file, index) => { setTimeout(() => { if (selectedFiles.value.length === 1) { selectedFiles.value.forEach((file, index) => { // setTimeout(() => { if (file.link) { const a = document.createElement('a') a.href = file.link @@ -308,8 +322,32 @@ a.click() document.body.removeChild(a) } }, index * 300) // 300ms delay between downloads }) // }, index * 300) // 300ms delay between downloads }) } else { // 批量下载 try { console.log(selectedFiles.value, '9999') loadingData = ElLoading.service({ background: 'rgba(0, 0, 0, 0.5)', text: '打包中,请稍等...' }) const fileIds = selectedFiles.value.map(i => i.id) // const res = await getDownloadStatusApi({ type: 'dpsjzx' }) // if (!['CANCELLED', 'COMPLETED'].includes(res.data.data?.status || 'COMPLETED')) { // return ElMessage.warning('还有正在处理的') // } console.log(fileIds, '7777') await fjDownloadByByteApi({ attachIds: fileIds }).then(res => { if (res.data.code === 200) { ElMessage.success('下载成功') } else { ElMessage.error(res.msg || '下载失败') } }) } catch (e) { } finally { loadingData.close() } } } // 文档上传 @@ -322,6 +360,8 @@ function onUploadFileBefore(file) { // 执行文件上传 let data = new FormData() // 获取文件扩展名 const fileExtension = file.name.split('.').pop().toLowerCase(); data.append('file', file) fjUploadApi(data).then(res => { @@ -330,6 +370,11 @@ // 保存文件URL到表单 uploadName.value = res.data.data.originalName editParams.value.link = res.data.data.link editParams.value.name = res.data.data.name editParams.value.originalName = res.data.data.originalName editParams.value.attachSize = file.size; editParams.value.extension = fileExtension editParams.value.domainUrl = res.data.data.link.replace(res.data.data.name, '') } else { ElMessage.error(res.msg || '上传失败') } applications/task-work-order/src/views/orderView/orderManage/inspectionReport/inspectionRequestApi.js
@@ -43,4 +43,13 @@ method: 'post', data, }) } } // 批量打包下载 export const fjDownloadByByteApi = data => { return request({ url: `/blade-resource/attach/downloadByByte`, method: 'post', data, }) } applications/task-work-order/src/views/orderView/orderManage/inspectionRequest/ViewDiaLog.vue
@@ -6,6 +6,7 @@ @closed="visible = false" destroy-on-close :close-on-click-modal="false" width="80%" > <div class="detail-container" style="display: flex"> <div class="detail-left" v-if="dialogMode !== 'add' && processList.length"> @@ -46,7 +47,11 @@ </el-col> <el-col :span="12"> <div class="label">巡查任务航线</div> <div class="val">{{ getAirName(formData.patrolRouteUrl) }}</div> <div class="val val-long"> <el-tooltip :content="getAirName(formData.patrolRouteUrl)" placement="top"> {{ getAirName(formData.patrolRouteUrl) }} </el-tooltip> </div> </el-col> <el-col :span="12"> <div class="label">推荐飞手</div> @@ -394,6 +399,7 @@ function loadList() { gdWorkOrderFlowListApi({ workOrderId: formData.value.id, type: '1' }).then(res => { processList.value = res.data.data console.log(processList.value, 'processList.value') }) } @@ -507,4 +513,28 @@ </script> <style lang="scss" scoped> /* 时间线样式 */ :deep(.gd-timeline) { padding-left: 90px; } :deep(.el-timeline-item) { padding-bottom: 20px; .item-content { position: relative; .flowName { width: 80px; position: absolute; left: -120px; top: 0px; } } } :deep(.el-timeline-item__timestamp) { font-size: 12px; color: #999; margin-top: 2px; } </style> applications/task-work-order/src/views/orderView/orderManage/operatingIncome/index.vue
@@ -194,7 +194,7 @@ confirmButtonClass: 'gd-confirm-button', cancelButtonClass: 'gd-confirm-cancel-button', }) const ids = row ? row.id : selectedIds.value const ids = row ? [row.id] : selectedIds.value await operatingIncomeBatchDelete(ids) ElMessage.success('删除成功') selectedIds.value = [] applications/task-work-order/src/views/orderView/orderManage/orderManage/FormDiaLog.vue
@@ -63,7 +63,7 @@ </el-table> <template v-if="hasPatrolTaskList"> <div class="detail-title" :style="{ marginTop: pxToRem(20) }">巡查任务名称</div> <el-table class="setHeight" :data="patrolTaskList" row-key="id"> <el-table class="setHeight gd-dialog-table" :data="patrolTaskList" row-key="id"> <el-table-column prop="patrolTaskName" show-overflow-tooltip label="巡查任务名称" /> <el-table-column prop="patrolTaskType" show-overflow-tooltip label="巡查任务类型"> <template v-slot="{ row }"> applications/task-work-order/src/views/orderView/organizational/agenciesManagement/index.vue
@@ -357,7 +357,8 @@ const url = URL.createObjectURL(blob) const a = document.createElement('a') a.href = url a.download = `机构列表${new Date().getTime()}.xlsx` // `机构列表${new Date().getTime()}.xlsx` a.download = `机构列表.xlsx` document.body.appendChild(a) a.click() document.body.removeChild(a) applications/task-work-order/src/views/orderView/organizational/zoningManagement/FormDiaLog.vue
@@ -22,7 +22,7 @@ </el-col> <el-col :span="12"> <div class="label">区划级别</div> <div class="val"> {{ getDictLabel(formData.regionLevel, dictObj.divisionLevel) }}</div> <div class="val"> {{ getDictLabel(formData.regionLevel, dictObj.regionLevel) }}</div> </el-col> <el-col :span="12"> <div class="label">区划排序</div> @@ -86,7 +86,7 @@ placeholder="请选择" clearable > <el-option v-for="item in dictObj.divisionLevel" :key="item.dictKey" <el-option v-for="item in dictObj.regionLevel" :key="item.dictKey" :label="item.dictValue" :value="item.dictKey" /> </el-select> applications/task-work-order/src/views/orderView/organizational/zoningManagement/index.vue
@@ -56,7 +56,7 @@ <el-table-column prop="parentName" show-overflow-tooltip label="上级区划名称" /> <el-table-column prop="regionLevel" show-overflow-tooltip label="区划级别"> <template v-slot="{ row }"> {{ getDictLabel(row.regionLevel, dictObj.divisionLevel) }} {{ getDictLabel(row.regionLevel, dictObj.regionLevel) }} </template> </el-table-column> <el-table-column prop="sort" show-overflow-tooltip label="排序" /> @@ -177,7 +177,7 @@ // 获取字典列表 function getDictList() { return getDictionaryByCode('zoningStatus,divisionLevel').then(res => { return getDictionaryByCode('zoningStatus,regionLevel').then(res => { dictObj.value = res.data.data }) } uniapps/work-app/src/subPackages/workDetail/index.vue
@@ -30,7 +30,7 @@ <div class="workOrderContainer"> <div class="orderRow"> <div class="rowTitle">工单编号</div> <div>{{ workDetailData.eventCode }}</div> <div>{{ workDetailData.eventNum }}</div> </div> <div class="orderRow"> <div class="rowTitle">工单处置人</div> @@ -65,10 +65,13 @@ </div> </div> <!-- 操作按钮 --> <div class="actionButton"> <div class="btngroups"> <div class="actionButton" > <div class="btngroups" v-if="workDetailData.eventStatus !== 3"> <up-button type="primary" color="#AEAEAE" text="退回" @click="rejectTicket"></up-button> <up-button type="primary" color="#1D6FE9" text="确认" @click="confirmTheTicket"></up-button> </div> <div class="btngroups" v-if="workDetailData.eventStatus === 3"> <up-button type="primary" color="#1D6FE9" text="已确认" ></up-button> </div> </div> <!-- 分享弹出层 --> @@ -119,8 +122,6 @@ const res = await getGddetailedData(params) const response = res.data.data workDetailData.value = response console.log('详情', workDetailData.value) } // 图片预览 const previewImage = index => { @@ -162,7 +163,7 @@ }) setTimeout(() => { uni.navigateBack() }, 1500) }) }) } @@ -177,7 +178,7 @@ }) setTimeout(() => { uni.navigateBack() }, 1500) }) }) } // 分享模态框状态 uniapps/work-wx/src/subPackages/flightApplication/add.vue
@@ -334,6 +334,7 @@ v-model="startTime" mode="datetime" :min-date="minDate" :formatter="formatter" @confirm="onConfirmStartTime" @cancel="isShowStartTime = false" ></u-datetime-picker> @@ -342,6 +343,7 @@ v-model="endTime" mode="datetime" :min-date="minDate" :formatter="formatter" @confirm="onConfirmEndTime" @cancel="isShowEndTime = false" ></u-datetime-picker> @@ -548,11 +550,11 @@ const endTime = ref(Date.now()); // 设置默认值为当前时间戳 const onConfirmStartTime = (e) => { formParams.value.flightStartTime = dayjs(e.value).format('YYYY-MM-DD HH:mm:ss') formParams.value.flightStartTime = dayjs(e.value).format('YYYY-MM-DD HH:mm') isShowStartTime.value = false } const onConfirmEndTime = (e) => { formParams.value.flightEndTime = dayjs(e.value).format('YYYY-MM-DD HH:mm:ss') formParams.value.flightEndTime = dayjs(e.value).format('YYYY-MM-DD HH:mm') isShowEndTime.value = false } @@ -721,6 +723,16 @@ isSubmitDisabled.value = false }) } const formatter = (type, value) => { if (type === 'year') return `${value}年`; if (type === 'month') return `${value}月`; if (type === 'day') return `${value}日`; if (type === 'hour') return `${value}时`; if (type === 'minute') return `${value}分`; return value; }; onMounted(() => { // getProTypeApi() // getTaskType()