applications/task-work-order/src/styles/common/cockpit.scss
@@ -1,5 +1,6 @@ //变量 $gd-placeholder: #86909C; $form-bg:#F2F3F5; .gd-table { height: 0; @@ -77,11 +78,10 @@ } } .gd-input { .el-input__wrapper,.el-textarea__inner { padding: 0 8px !important; background: #F2F3F5; background: $form-bg; box-shadow: none !important; border: none; } @@ -107,7 +107,7 @@ .el-select__wrapper { padding: 0 8px; background: #DDE2ED; background: $form-bg; box-shadow: none !important; border: none; width: 100%; @@ -141,7 +141,7 @@ } .gd-tree-select-popper { background: #DDE2ED !important; background: $form-bg !important; border: none !important; .el-popper__arrow::before { @@ -220,7 +220,7 @@ .gd-date-picker { box-shadow: none !important; background: #DDE2ED; background: $form-bg; border: none; border-radius: 5px; box-sizing: border-box !important; @@ -562,94 +562,7 @@ .el-form-item__content { display: flex; align-items: center; .el-input, .el-input-number { width: 0; flex: 1; } .el-cascader { width: 0; flex: 1; display: flex; align-items: center; border: none; .el-input__wrapper { box-shadow: none !important; } } .el-button { color: #fff; background: #DDE2ED !important; border: none; box-shadow: none; } .gd-date-picker { background: #DDE2ED; } .gd-date-picker-popper { background: #DDE2ED !important; .el-picker-panel { .el-picker-panel__body-wrapper { .el-picker-panel__body { background: #DDE2ED !important; .el-date-picker__time-header { .el-date-picker__editor-wrap { .el-time-panel { background: #DDE2ED !important; // 将 time-picker-popper 的样式移到这里 .el-time-panel__header { background: #DDE2ED !important; } } } } } } } .el-popper__arrow { &::before { background: #DDE2ED !important; border: 1px solid #DDE2ED !important; box-sizing: border-box; } } } } .el-select { .el-select__wrapper { background: #F2F3F5; .el-select__suffix { .el-icon { color: #4E5969; } } } .el-select__placeholder { &.is-transparent { color: #86909C !important; } &.el-select__selected-item { color: #383874; } } } } } } @@ -811,7 +724,6 @@ .gd-select { .el-select__wrapper { background: #DDE2ED; width: 200px; height: 36px; } @@ -822,37 +734,30 @@ height: 36px; .el-input__wrapper { background: #DDE2ED; } &.is-disabled { .el-input__wrapper { background-color: #DDE2ED; } } } .gd-date-picker { background: #DDE2ED; } .gd-date-picker-popper { background: #DDE2ED !important; .el-picker-panel { .el-picker-panel__body-wrapper { .el-picker-panel__body { background: #DDE2ED !important; .el-date-picker__time-header { .el-date-picker__editor-wrap { .el-time-panel { background: #DDE2ED !important; // 将 time-picker-popper 的样式移到这里 .el-time-panel__header { background: #DDE2ED !important; } } } @@ -917,99 +822,6 @@ .el-button { width: 96px; height: 36px; } } .gd-dialog-form { .el-form-item { margin-left: 20px; } .el-form-item__label { font-family: Source Han Sans CN, Source Han Sans CN; font-weight: 500; font-size: 14px; color: #C5C9D6; font-style: normal; text-transform: none; } .gd-input { .el-input__wrapper { background: #DDE2ED; } &.is-disabled { .el-input__wrapper { background-color: #DDE2ED; } } } .gd-date-picker { background: #DDE2ED; } .gd-date-picker-popper { background: #DDE2ED !important; .el-picker-panel { .el-picker-panel__body-wrapper { .el-picker-panel__body { background: #DDE2ED !important; .el-date-picker__time-header { .el-date-picker__editor-wrap { .el-time-panel { background: #DDE2ED !important; // 将 time-picker-popper 的样式移到这里 .el-time-panel__header { background: #DDE2ED !important; } } } } } } } .el-popper__arrow { &::before { background: #DDE2ED !important; border: 1px solid #DDE2ED !important; box-sizing: border-box; } } } .gd-search-actions { .el-button { width: 96px; background: transparent !important; border-radius: 4px 4px 4px 4px; border: 1px solid rgba(255, 255, 255, 0.3); .el-icon { font-size: 16px; color: #fff; } } } .el-input { width: 160px; } .el-date-editor { width: 226px; } .el-select { .el-select__wrapper { width: 160px; } } } applications/task-work-order/src/views/basicManage/maintainRecord/FormDiaLog.vue
@@ -52,7 +52,7 @@ </div> <el-form class="dialog-form" class="gd-dialog-form" v-else ref="formRef" :model="formData" applications/task-work-order/src/views/orderView/orderDataManage/evaluate/FormDiaLog.vue
@@ -40,7 +40,7 @@ </div> <el-form class="dialog-form" class="gd-dialog-form" v-else ref="formRef" :model="formData" applications/task-work-order/src/views/orderView/orderDataManage/supplyAdd/FormDiaLog.vue
@@ -60,7 +60,7 @@ </div> <el-form class="dialog-form" class="gd-dialog-form" v-else ref="formRef" :model="formData" applications/task-work-order/src/views/orderView/orderManage/orderManage/FormDiaLog.vue
New file @@ -0,0 +1,274 @@ <template> <el-dialog class="gd-dialog" v-model="visible" :title="titleEnum[dialogMode]" @closed="visible = false" destroy-on-close width="1000px" > <div class="detail-container" v-if="dialogReadonly"> <el-row> <el-col :span="12"> <div class="label">工单名称</div> <div class="val">{{ formData.workOrderName }}</div> </el-col> <el-col :span="12"> <div class="label">工单类型</div> <div class="val">{{ getDictLabel(formData.workOrderType, dictObj.workOrderType) }}</div> </el-col> <el-col :span="12"> <div class="label">执行开始时间</div> <div class="val">{{ formData.executeStartTime }}</div> </el-col> <el-col :span="12"> <div class="label">执行结束时间</div> <div class="val">{{ formData.executeEndTime }}</div> </el-col> <el-col :span="12"> <div class="label">设备需求</div> <div class="val">{{ getDictLabel(formData.deviceLoadDemand, dictObj.deviceLoadDemand) }}</div> </el-col> <el-col :span="12"> <div class="label">工单备注</div> <div class="val">{{ formData.remark }}</div> </el-col> <el-col :span="24"> <div class="label">工单经纬度面</div> <div class="val">{{ formData.geom }}</div> </el-col> <el-col :span="24"> <div class="label">推荐设备</div> <div class="val">{{ formData.recommendDeviceIds }}</div> </el-col> </el-row> </div> <el-form class="gd-dialog-form" v-else ref="formRef" :model="formData" :rules="rules" :disabled="dialogReadonly" label-width="120px" > <el-row> <el-col :span="12"> <el-form-item label="工单名称" prop="workOrderName"> <el-input class="gd-input" v-model="formData.workOrderName" placeholder="请输入" clearable /> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="工单类型" prop="workOrderType"> <el-select class="gd-select" popper-class="gd-select-popper" v-model="formData.workOrderType" placeholder="请选择" clearable > <el-option v-for="item in dictObj.workOrderType" :key="item.dictKey" :label="item.dictValue" :value="item.dictKey" /> </el-select> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="执行开始时间" prop="executeStartTime"> <el-date-picker class="gd-date-picker" popper-class="gd-date-picker-popper" v-model="formData.executeStartTime" type="datetime" placeholder="请选择" value-format="YYYY-MM-DD HH:mm:ss" /> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="执行结束时间" prop="executeEndTime"> <el-date-picker class="gd-date-picker" popper-class="gd-date-picker-popper" v-model="formData.executeEndTime" type="datetime" placeholder="请选择" value-format="YYYY-MM-DD HH:mm:ss" /> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="设备需求" prop="deviceLoadDemand"> <el-select class="gd-select" popper-class="gd-select-popper" v-model="formData.deviceLoadDemand" placeholder="请选择" clearable > <el-option v-for="item in dictObj.deviceLoadDemand" :key="item.dictKey" :label="item.dictValue" :value="item.dictKey" /> </el-select> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="工单备注" prop="remark"> <el-input class="gd-input" v-model="formData.remark" placeholder="请输入" clearable /> </el-form-item> </el-col> <el-col :span="24"> <el-form-item label="工单经纬度面" prop="geom"> <el-input class="gd-input" v-model="formData.geom" placeholder="预留输入框" clearable /> </el-form-item> </el-col> <el-col :span="24"> <el-form-item label="推荐设备" prop="recommendDeviceIds"> <el-form-item prop="recommendDeviceIds" label-width="0"> <el-table class="command-data-cockpit-table" ref="deviceTableRef" :data="deviceList" row-key="id" @selection-change="handleDeviceSelectionChange" > <el-table-column type="selection" width="55" :reserve-selection="true" /> <el-table-column prop="deviceName" label="设备名称" /> <el-table-column prop="deviceCode" label="设备编码" /> <el-table-column prop="deviceType" label="设备类型" /> </el-table> </el-form-item> </el-form-item> </el-col> </el-row> </el-form> <template #footer> <el-button color="#F2F3F5" @click="visible = false">{{ dialogReadonly ? '关闭' : '取消' }}</el-button> <el-button class="save-btn" color="#4C34FF" v-if="!dialogReadonly" :loading="submitting" :disabled="submitting" @click="handleSubmit" > 保存 </el-button> </template> </el-dialog> </template> <script setup> import { computed, ref, onMounted } from 'vue' import { ElMessage } from 'element-plus' import { fieldRules } from '@ztzf/utils' import { getDictLabel } from '@ztzf/utils' import { gdWorkOrderDetailApi, gdWorkOrderSaveApi } from './orderManageApi' import { gdManageDevicePageApi } from './gdManageDeviceApi' // 初始化表单数据 const initForm = () => ({ workOrderName: '', workOrderType: '', executeStartTime: '', executeEndTime: '', deviceLoadDemand: '', remark: '', geom: '', recommendDeviceIds: '', }) const dictObj = inject('dictObj') const deptTree = inject('deptTree') const treeProps = inject('treeProps') const emit = defineEmits(['success']) const formRef = ref(null) // 表单实例 const formData = ref(initForm()) // 表单数据 const visible = defineModel() // 弹框显隐 const dialogMode = ref('add') // 弹框模式 const submitting = ref(false) // 提交中 const dialogReadonly = computed(() => dialogMode.value === 'view') const titleEnum = ref({ edit: '编辑', view: '查看', add: '新增' }) const deviceList = ref([]) // 设备列表 const selectedDevices = ref([]) // 选中的设备 const deviceTableRef = ref(null) // 设备表格实例 const rules = { workOrderName: fieldRules(true), workOrderType: fieldRules(true), executeStartTime: fieldRules(true), executeEndTime: fieldRules(true), deviceLoadDemand: fieldRules(true), } // 获取推荐设备列表 async function getDeviceList() { try { const res = await gdManageDevicePageApi({ current: 1, size: 1000 }) deviceList.value = res?.data?.data?.records ?? [] } catch (error) { console.error('获取设备列表失败:', error) } } // 设备选择变化 function handleDeviceSelectionChange(rows) { selectedDevices.value = rows formData.value.recommendDeviceIds = rows.map(item => item.id).join(',') } // 提交新增/编辑 async function handleSubmit() { const isValid = await formRef.value?.validate().catch(() => false) if (!isValid) return submitting.value = true try { await gdWorkOrderSaveApi(formData.value) ElMessage.success(dialogMode.value === 'add' ? '新增成功' : '更新成功') visible.value = false emit('success') } finally { submitting.value = false } } // 加载详情 async function loadDetail() { if (!formData.value.id) return const res = await gdWorkOrderDetailApi({ id: formData.value.id }) formData.value = res?.data?.data ?? {} // 回显选中的设备 if (formData.value.recommendDeviceIds) { const deviceIds = formData.value.recommendDeviceIds.split(',').map(id => parseInt(id)) nextTick(() => { deviceList.value.forEach(device => { if (deviceIds.includes(device.id)) { deviceTableRef.value?.toggleRowSelection(device, true) } }) }) } } // 打开弹框 async function open({ mode = 'add', row } = {}) { dialogMode.value = mode formData.value = dialogMode.value === 'add' ? initForm() : row await getDeviceList() if (dialogMode.value !== 'add') { await loadDetail() } } defineExpose({ open }) </script> applications/task-work-order/src/views/orderView/orderManage/orderManage/gdManageDeviceApi.js
New file @@ -0,0 +1,37 @@ import request from '@/axios' // 详情 export const gdManageDeviceDetailApi = params => { return request({ url: `/drone-gd/workOrder/gdManageDevice/detail`, method: 'get', params, }) } // 分页 export const gdManageDevicePageApi = params => { return request({ url: `/drone-gd/workOrder/gdManageDevice/page`, method: 'get', params, }) } // 新增或修改 export const gdManageDeviceSubmitApi = data => { return request({ url: `/drone-gd/workOrder/gdManageDevice/submit`, method: 'post', data, }) } // 逻辑删除 export const gdManageDeviceRemoveApi = params => { return request({ url: `/drone-gd/workOrder/gdManageDevice/remove`, method: 'post', params, }) } applications/task-work-order/src/views/orderView/orderManage/orderManage/index.vue
@@ -1,9 +1,249 @@ <template> <basic-container> 工单管理 </basic-container> <basic-container> <el-form ref="queryParamsRef" :model="searchParams" class="gd-search-form"> <el-form-item label="工单名称" prop="workOrderName"> <el-input class="gd-input" v-model="searchParams.workOrderName" placeholder="请输入" clearable @clear="handleSearch" /> </el-form-item> <el-form-item label="工单类型" prop="workOrderType"> <el-select class="gd-select" popper-class="gd-select-popper" v-model="searchParams.workOrderType" placeholder="请选择" clearable @change="handleSearch" > <el-option v-for="item in dictObj.workOrderType" :key="item.dictKey" :label="item.dictValue" :value="item.dictKey" /> </el-select> </el-form-item> <el-form-item label="工单状态" prop="workOrderStatus"> <el-select class="gd-select" popper-class="gd-select-popper" v-model="searchParams.workOrderStatus" placeholder="请选择" clearable @change="handleSearch" > <el-option v-for="item in dictObj.workOrderStatus" :key="item.dictKey" :label="item.dictValue" :value="item.dictKey" /> </el-select> </el-form-item> <el-form-item label="执行时间" prop="executeTime"> <el-date-picker class="gd-date-picker" popper-class="gd-date-picker-popper" v-model="executeTime" type="daterange" range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期" value-format="YYYY-MM-DD HH:mm:ss" @change="handleSearch" /> </el-form-item> <el-form-item class="gd-search-actions"> <el-button :icon="RefreshRight" @click="resetForm"></el-button> <el-button class="search-btn" :icon="Search" @click="handleSearch"></el-button> </el-form-item> </el-form> <div class="gd-table-toolbar"> <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> </div> <div class="gd-table-container" v-loading="loading"> <div class="gd-table-content gd-table-content-bg"> <el-table class="gd-table" :data="list" @selection-change="handleSelectionChange"> <el-table-column type="selection" width="46" /> <el-table-column prop="workOrderName" show-overflow-tooltip label="工单名称" /> <el-table-column prop="workOrderCode" show-overflow-tooltip label="工单编号" /> <el-table-column prop="workOrderType" show-overflow-tooltip label="工单类型"> <template v-slot="{ row }"> {{ getDictLabel(row.workOrderType, dictObj.workOrderType) }} </template> </el-table-column> <el-table-column prop="status" show-overflow-tooltip label="阶段状态" /> <el-table-column prop="workOrderStatus" show-overflow-tooltip label="工单状态"> <template v-slot="{ row }"> {{ getDictLabel(row.workOrderStatus, dictObj.workOrderStatus) }} </template> </el-table-column> <el-table-column prop="executeTime" show-overflow-tooltip label="执行时间范围"> <template v-slot="{ row }">{{ row.executeStartTime }} ~ {{ row.executeEndTime }}</template> </el-table-column> <el-table-column prop="serviceParty" show-overflow-tooltip label="服务方名称" /> <el-table-column prop="createDeptName" show-overflow-tooltip label="需求方名称" /> <el-table-column prop="createTime" show-overflow-tooltip label="工单创建时间" /> <el-table-column label="操作" class-name="operation-btns"> <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> </template> </el-table-column> </el-table> </div> <div class="gd-pagination-parent"> <el-pagination popper-class="gd-select-popper" v-model:current-page="searchParams.current" v-model:page-size="searchParams.size" layout="total, prev, pager, next, sizes" :total="total" @change="getList" /> </div> </div> <FormDiaLog ref="dialogRef" @success="getList" v-if="dialogVisible" v-model="dialogVisible" /> </basic-container> </template> <script setup> import { Search, RefreshRight, Plus, Delete } from '@element-plus/icons-vue' import { onMounted, ref } from 'vue' import { ElMessage, ElMessageBox } from 'element-plus' import { getDictionaryByCode } from '@/api/system/dictbiz' import { getDeptTree } from '@/api/system/dept' import { getDictLabel } from '@ztzf/utils' import FormDiaLog from './FormDiaLog.vue' import { gdWorkOrderPageApi, gdWorkOrderRemoveApi } from './orderManageApi' // 初始化查询参数 const initSearchParams = () => ({ workOrderName: '', // 工单名称 workOrderType: '', // 工单类型 workOrderStatus: '', // 工单状态 executeStartTime: '', // 执行开始时间 executeEndTime: '', // 执行结束时间 current: 1, // 当前页 size: 10, // 每页大小 }) const searchParams = ref(initSearchParams()) // 查询参数 const executeTime = ref([]) // 执行时间范围 const total = ref(0) // 总条数 const loading = ref(true) // 列表加载中 const list = ref([]) // 列表数据 const selectedIds = ref([]) // 勾选的ID列表 const queryParamsRef = ref(null) // 查询表单实例 const dialogRef = ref(null) // 弹框实例 const dialogVisible = ref(false) const dictObj = ref({ deviceLoadDemand: [], // 设备负载需求 workOrderType: [], // 工单类型 workOrderStatus: [], // 工单状态 }) provide('dictObj', dictObj) const deptTree = ref([]) // 部门树 const treeProps = { label: 'name', children: 'children', } provide('deptTree', deptTree) provide('treeProps', treeProps) // 获取列表 async function getList() { loading.value = true try { const res = await gdWorkOrderPageApi(searchParams.value) list.value = res?.data?.data?.records ?? [] total.value = res?.data?.data?.total ?? 0 } finally { loading.value = false } } // 查询 function handleSearch() { // 处理执行时间范围 if (executeTime.value && executeTime.value.length === 2) { searchParams.value.executeStartTime = executeTime.value[0] searchParams.value.executeEndTime = executeTime.value[1] } else { searchParams.value.executeStartTime = '' searchParams.value.executeEndTime = '' } searchParams.value.current = 1 getList() } // 重置查询 function resetForm() { queryParamsRef.value?.resetFields() executeTime.value = [] searchParams.value.current = 1 getList() } // 新增/编辑/查看 弹框 function openForm(mode, row) { dialogVisible.value = true nextTick(() => { dialogRef.value?.open({ mode, row }) }) } // 删除 async function handleDelete(row) { const tips = row ? '该条' : '选中的项' await ElMessageBox.confirm(`确认删除${tips}吗?`, '提示', { type: 'warning', customClass: 'gd-confirm-custom', confirmButtonClass: 'gd-confirm-button', cancelButtonClass: 'gd-confirm-cancel-button', }) const ids = row ? row.id : selectedIds.value.join(',') await gdWorkOrderRemoveApi({ ids }) ElMessage.success('删除成功') selectedIds.value = [] getList() } // 勾选值设置 function handleSelectionChange(rows) { selectedIds.value = rows.map(item => item.id) } // 获取字典 function getDictList() { getDictionaryByCode('deviceLoadDemand,workOrderType,workOrderStatus').then(res => { dictObj.value = res.data.data }) } // 获取部门树 function getDeptTreeFun() { getDeptTree().then(res => { deptTree.value = res.data.data }) } onMounted(() => { getList() getDictList() getDeptTreeFun() }) </script> <style scoped lang="scss"> </style> <style scoped lang="scss"></style> applications/task-work-order/src/views/orderView/orderManage/orderManage/orderManageApi.js
New file @@ -0,0 +1,37 @@ import request from '@/axios' // 获取工单列表 export const gdWorkOrderPageApi = params => { return request({ url: `/drone-gd/workOrder/gdWorkOrder/page`, method: 'get', params: { descs: 'create_time', ...params }, }) } // 新增工单 export const gdWorkOrderSaveApi = data => { return request({ url: `/drone-gd/workOrder/gdWorkOrder/save`, method: 'post', data, }) } // 删除工单 export const gdWorkOrderRemoveApi = params => { return request({ url: `/drone-gd/workOrder/gdWorkOrder/remove`, method: 'post', params, }) } // 获取工单详情 export const gdWorkOrderDetailApi = params => { return request({ url: `/drone-gd/workOrder/gdWorkOrder/detail`, method: 'get', params, }) }