| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907 |
- <!-- 排水管网工单管理 -->
- <template>
- <div class="drainage-work-order">
- <!-- 顶部搜索区 -->
- <el-card class="search-card" shadow="never">
- <div class="search-form">
- <el-form :model="queryParams" ref="queryFormRef" :inline>
- <el-form-item label="类型">
- <el-select v-model="queryParams.orderType" placeholder="全部类型" clearable style="width: 150px">
- <el-option label="故障维修" :value="1" />
- <el-option label="日常巡检" :value="2" />
- <el-option label="设备保养" :value="3" />
- </el-select>
- </el-form-item>
- <el-form-item label="优先级">
- <el-select v-model="queryParams.orderLevel" placeholder="全部优先级" clearable style="width: 120px">
- <el-option label="紧急" :value="1" />
- <el-option label="一般" :value="2" />
- <el-option label="低" :value="3" />
- </el-select>
- </el-form-item>
- <el-form-item label="状态">
- <el-select v-model="queryParams.orderStatus" placeholder="全部状态" clearable style="width: 120px">
- <el-option label="待派单" :value="1" />
- <el-option label="待接单" :value="2" />
- <el-option label="已接单" :value="3" />
- <el-option label="处理中" :value="4" />
- <el-option label="已提交验收" :value="5" />
- <el-option label="已结案" :value="6" />
- <el-option label="已驳回" :value="7" />
- </el-select>
- </el-form-item>
- <el-form-item label="关键词">
- <el-input
- v-model="queryParams.keyword"
- placeholder="工单编号/设备编码"
- clearable
- style="width: 200px"
- />
- </el-form-item>
- <el-form-item>
- <el-button type="primary" @click="handleSearch">查询</el-button>
- <el-button @click="handleReset">重置</el-button>
- </el-form-item>
- </el-form>
- </div>
- </el-card>
- <!-- 主容器 -->
- <el-row :gutter="16" style="height: calc(100vh - 200px)">
- <!-- 左侧:工单列表 -->
- <el-col :span="8" style="height: 100%">
- <el-card class="box-card" shadow="always">
- <template #header>
- <div class="card-header">
- <span>工单列表</span>
- </div>
- </template>
-
- <!-- 工单列表 -->
- <el-scrollbar style="flex: 1">
- <div class="order-list">
- <div
- v-for="order in tableData"
- :key="order.orderId"
- class="order-item"
- :class="{ 'active': selectedOrderId === order.orderId }"
- @click="handleSelectOrder(order)"
- >
- <div class="order-header">
- <span class="order-no">{{ order.orderNo }}</span>
- <el-tag
- v-if="order.orderStatus === 1"
- type="warning"
- size="small"
- effect="light"
- class="status-badge"
- >待派单</el-tag>
- <el-tag
- v-else-if="order.orderStatus === 2"
- type="info"
- size="small"
- effect="light"
- class="status-badge"
- >待接单</el-tag>
- <el-tag
- v-else-if="order.orderStatus === 3"
- type="success"
- size="small"
- effect="light"
- class="status-badge"
- >已接单</el-tag>
- <el-tag
- v-else-if="order.orderStatus === 4"
- type="danger"
- size="small"
- effect="light"
- class="status-badge"
- >处理中</el-tag>
- <el-tag
- v-else-if="order.orderStatus === 5"
- type="success"
- size="small"
- effect="light"
- class="status-badge"
- >已提交验收</el-tag>
- <el-tag
- v-else-if="order.orderStatus === 6"
- type="info"
- size="small"
- effect="light"
- class="status-badge"
- >已结案</el-tag>
- <el-tag
- v-else-if="order.orderStatus === 7"
- type="danger"
- size="small"
- effect="light"
- class="status-badge"
- >已驳回</el-tag>
- </div>
- <div class="order-body">
- <div class="order-tags">
- <el-tag :type="getLevelTag(order.orderLevel)" size="small" effect="plain">{{ getLevelLabel(order.orderLevel) }}</el-tag>
- <el-tag :type="getTypeTag(order.orderType)" size="small" effect="plain">{{ getTypeLabel(order.orderType) }}</el-tag>
- </div>
- <div class="order-desc" v-if="order.orderDesc">{{ order.orderDesc }}</div>
- <div class="device-code">设备编号:{{ order.deviceCode || '-' }}</div>
- <div class="create-time">创建:{{ formatDate(order.createTime) }}</div>
- </div>
- </div>
- <el-empty v-if="tableData.length === 0" description="暂无数据" :image-size="100"></el-empty>
- </div>
- </el-scrollbar>
-
- <!-- 分页 -->
- <div class="pagination-wrapper">
- <el-pagination
- v-model:current-page="pageNum"
- v-model:page-size="pageSize"
- :total="total"
- layout="total, prev, pager, next"
- :page-sizes="[10, 20, 50, 100]"
- @size-change="handleSizeChange"
- @current-change="handlePageChange"
- class="pagination"
- />
- </div>
- </el-card>
- </el-col>
-
- <!-- 右侧:工单详情 -->
- <el-col :span="16" style="height: 100%">
- <el-card v-loading="detailLoading" class="box-card" shadow="always">
- <template #header>
- <div class="card-header">
- <span v-if="selectedOrder && selectedOrder.orderId">工单详情 - {{ selectedOrder.orderNo }}</span>
- <span v-else>请选择工单查看详情</span>
- </div>
- </template>
-
- <div v-if="selectedOrder && selectedOrder.orderId">
- <!-- 标签页 -->
- <el-tabs v-model="activeTab" class="detail-tabs">
- <!-- 工单信息 -->
- <el-tab-pane label="工单信息" name="info">
- <el-descriptions :column="2" border size="small">
- <el-descriptions-item label="工单编号">{{ selectedOrder.orderNo }}</el-descriptions-item>
- <el-descriptions-item label="工单状态">
- <el-tag
- v-if="selectedOrder.orderStatus === 1"
- type="warning"
- size="small"
- >待派单</el-tag>
- <el-tag
- v-else-if="selectedOrder.orderStatus === 2"
- type="info"
- size="small"
- >待接单</el-tag>
- <el-tag
- v-else-if="selectedOrder.orderStatus === 3"
- type="success"
- size="small"
- >已接单</el-tag>
- <el-tag
- v-else-if="selectedOrder.orderStatus === 4"
- type="danger"
- size="small"
- >处理中</el-tag>
- <el-tag
- v-else-if="selectedOrder.orderStatus === 5"
- type="success"
- size="small"
- >已提交验收</el-tag>
- <el-tag
- v-else-if="selectedOrder.orderStatus === 6"
- type="info"
- size="small"
- >已结案</el-tag>
- <el-tag
- v-else-if="selectedOrder.orderStatus === 7"
- type="danger"
- size="small"
- >已驳回</el-tag>
- </el-descriptions-item>
- <el-descriptions-item label="关联案件编号">{{ selectedOrder.caseNo || '-' }}</el-descriptions-item>
- <el-descriptions-item label="设备编号">{{ selectedOrder.deviceCode || '-' }}</el-descriptions-item>
- <el-descriptions-item label="优先级">
- <el-tag
- v-if="selectedOrder.orderLevel === 1"
- type="danger"
- size="small"
- >紧急</el-tag>
- <el-tag
- v-else-if="selectedOrder.orderLevel === 2"
- type="warning"
- size="small"
- >一般</el-tag>
- <el-tag
- v-else
- type="info"
- size="small"
- >低</el-tag>
- </el-descriptions-item>
- <el-descriptions-item label="工单类型">{{ getOrderTypeText(selectedOrder.orderType) }}</el-descriptions-item>
- <el-descriptions-item label="问题描述" :span="2">{{ selectedOrder.orderDesc }}</el-descriptions-item>
- <el-descriptions-item label="创建时间">{{ formatDate(selectedOrder.createTime) }}</el-descriptions-item>
- <el-descriptions-item label="更新时间">{{ formatDate(selectedOrder.updateTime) }}</el-descriptions-item>
- <el-descriptions-item label="运维状态">在用</el-descriptions-item>
- <el-descriptions-item label="在线状态">在线</el-descriptions-item>
- <el-descriptions-item label="报警状态">正常</el-descriptions-item>
- <el-descriptions-item label="处置结果">{{ selectedOrder.repairResult || '-' }}</el-descriptions-item>
- </el-descriptions>
-
- <!-- 工单图片 -->
- <div v-if="workImageList.length > 0" class="image-section">
- <h4 class="section-title">工单图片</h4>
- <div class="image-list">
- <image-preview
- v-for="(img, index) in workImageList"
- :key="index"
- :src="img"
- :width="100"
- :height="100"
- />
- </div>
- </div>
-
- <!-- 工单操作 -->
- <div class="action-section">
- <h4 class="section-title">工单操作</h4>
- <div class="action-buttons">
- <el-button
- v-if="canDispatch()"
- type="primary"
- icon="Download"
- @click="handleDispatch"
- >下派任务</el-button>
- <el-button
- v-if="canVerify()"
- type="warning"
- icon="Check"
- @click="handleVerify"
- >核查</el-button>
- <el-button
- v-if="canProcess()"
- type="success"
- icon="Edit"
- @click="handleProcess"
- >处理</el-button>
- <el-button
- v-if="canComplete()"
- type="danger"
- icon="Checked"
- @click="handleComplete"
- >提交验收</el-button>
- <el-button
- v-if="canReject()"
- type="info"
- icon="Close"
- @click="handleReject"
- >驳回</el-button>
- </div>
- </div>
- </el-tab-pane>
-
- <!-- 处理历史 -->
- <el-tab-pane label="处理历史" name="history">
- <el-timeline v-if="currentOrderLogs && currentOrderLogs.length > 0">
- <el-timeline-item
- v-for="log in currentOrderLogs"
- :key="log.logId"
- :timestamp="formatDate(log.operTime)"
- placement="top"
- :type="getLogType(log.operType)"
- :size="'large'"
- >
- <el-card shadow="hover">
- <div class="timeline-content">
- <div class="operator-info">
- <span class="operator-name">{{ log.operUserName }}</span>
- <span class="oper-type">· {{ getOperTypeLabel(log.operType) }}</span>
- </div>
- <div class="oper-desc">{{ log.operDesc }}</div>
- </div>
- </el-card>
- </el-timeline-item>
- </el-timeline>
- <el-empty v-else description="暂无处理记录" :image-size="100"></el-empty>
- </el-tab-pane>
- </el-tabs>
- </div>
-
- <el-empty v-else description="请从左侧选择工单" :image-size="150"></el-empty>
- </el-card>
- </el-col>
- </el-row>
-
- <!-- 派单弹窗 -->
- <el-dialog v-model="dispatchDialogVisible" title="下派任务 - 选择接单人" width="750px">
- <div style="display: flex; gap: 16px; min-height: 350px;">
- <!-- 左侧:部门树 -->
- <div style="width: 280px; border-right: 1px solid #e4e7ed; padding-right: 12px;">
- <el-input
- v-model="deptFilterText"
- placeholder="筛选部门"
- clearable
- size="small"
- style="margin-bottom: 8px"
- />
- <el-tree
- ref="deptTreeRef"
- :data="deptTreeData"
- :props="{ label: 'deptName', children: 'children' }"
- :filter-node-method="filterDeptNode"
- node-key="deptId"
- highlight-current
- @node-click="handleDeptClick"
- style="font-size: 14px"
- />
- </div>
- <!-- 右侧:用户列表 -->
- <div style="flex: 1; min-width: 0;">
- <el-table
- :data="userList"
- border
- size="small"
- max-height="300"
- ref="userTableRef"
- row-key="userId"
- @selection-change="handleSelectionChange"
- @row-click="handleRowClick"
- >
- <el-table-column type="selection" width="40" align="center" :reserve-selection="true" />
- <el-table-column prop="userName" label="用户名" width="100" />
- <el-table-column prop="nickName" label="昵称" width="100" />
- <el-table-column prop="dept.deptName" label="部门" show-overflow-tooltip />
- </el-table>
- <div v-if="userList.length === 0" style="text-align: center; color: #909399; padding: 40px 0;">请先在左侧选择部门</div>
- </div>
- </div>
- <el-form :model="dispatchForm" label-width="80px" style="margin-top: 16px">
- <el-form-item label="备注"><el-input v-model="dispatchForm.remarks" placeholder="请输入派单备注" /></el-form-item>
- </el-form>
- <template #footer>
- <span style="float: left; line-height: 32px; color: #606266;">
- 已选人员:<span v-if="selectedUserNames.length > 0" style="color: #409eff; font-weight: bold;">{{ selectedUserNames.join(', ') }}</span>
- <span v-else style="color: #909399">未选择</span>
- (<span v-if="dispatchForm.handlerIds && dispatchForm.handlerIds.length > 0">{{ dispatchForm.handlerIds.length }}</span><span v-else>0</span>)
- </span>
- <el-button @click="dispatchDialogVisible = false">取消</el-button>
- <el-button type="primary" @click="submitDispatch">确认</el-button>
- </template>
- </el-dialog>
-
- <!-- 核查/处理弹窗 -->
- <el-dialog v-model="actionDialogVisible" :title="actionTitle" width="600px">
- <el-input v-model="actionFormData.solution" type="textarea" :rows="6" placeholder="请输入说明文字" />
- <template #footer>
- <el-button @click="actionDialogVisible = false">取消</el-button>
- <el-button type="primary" @click="submitAction">确定</el-button>
- </template>
- </el-dialog>
-
- <!-- 完成/验收弹窗 -->
- <el-dialog v-model="completeDialogVisible" title="提交验收" width="500px">
- <el-form label-width="80px">
- <el-form-item label="验收意见">
- <el-input v-model="completeForm.result" type="textarea" :rows="4" />
- </el-form-item>
- </el-form>
- <template #footer>
- <el-button @click="completeDialogVisible = false">取消</el-button>
- <el-button type="primary" @click="submitComplete">提交</el-button>
- </template>
- </el-dialog>
- </div>
- </template>
- <script setup name="DrainageWorkOrder">
- import { ElMessage } from 'element-plus'
- import ImagePreview from '@/components/ImagePreview/index.vue'
- import { listWorkOrder, getWorkOrderDetail, dispatchWorkOrder, verifyWorkOrder, processWorkOrder, completeWorkOrder } from '@/api/work/order.js'
- import { listDept } from '@/api/system/dept.js'
- import { listUser } from '@/api/system/user.js'
- import { handleTree } from '@/utils/ruoyi.js'
- const listLoading = ref(false)
- const tableData = ref([])
- const pageNum = ref(1)
- const pageSize = ref(10)
- const total = ref(0)
- const queryFormRef = ref(null)
- const queryParams = reactive({
- orderType: null,
- orderLevel: null,
- keyword: '',
- // 排水管网工单:只查询排水类型设备工单
- equipmentType: 'drainage'
- })
- // 选中的工单
- const selectedOrderId = ref(null)
- const selectedOrder = ref({})
- const activeTab = ref('info')
- const currentOrderLogs = ref([])
- // 工单图片列表(多个用逗号分隔)
- const workImageList = computed(() => {
- if (!selectedOrder.value.workImage) return []
- return selectedOrder.value.workImage.split(',').filter(img => img && img.trim())
- })
- // 派单相关
- const dispatchDialogVisible = ref(false)
- const dispatchForm = reactive({ handlerIds: [], remarks: '' })
- const deptTreeRef = ref(null)
- const userTableRef = ref(null)
- const deptTreeData = ref([])
- const deptFilterText = ref('')
- const userList = ref([])
- const selectedUserList = ref([]) // 存储选中的用户行数据
- // 部门筛选
- watch(deptFilterText, (val) => { deptTreeRef.value && deptTreeRef.value.filter(val) })
- function filterDeptNode(value, data) {
- if (!value) return true
- return data.deptName.includes(value)
- }
- // 加载部门树
- async function loadDeptTree() {
- if (deptTreeData.value.length > 0) return
- try {
- const res = await listDept()
- deptTreeData.value = handleTree(res.data || [], 'deptId')
- } catch (e) { console.error('加载部门失败', e) }
- }
- // 点击部门加载用户
- async function handleDeptClick(node) {
- try {
- // 清除当前选择
- userTableRef.value && userTableRef.value.clearSelection()
- selectedUserList.value = []
- dispatchForm.handlerIds = []
-
- const res = await listUser({ deptId: node.deptId, pageNum: 1, pageSize: 100 })
- userList.value = res.rows || []
- } catch (e) { console.error('加载用户失败', e) }
- }
- // 选择变化时触发
- function handleSelectionChange(selection) {
- selectedUserList.value = selection
- dispatchForm.handlerIds = selection.map(item => item.userId)
- }
- // 点击行切换选中状态
- function handleRowClick(row) {
- userTableRef.value && userTableRef.value.toggleRowSelection(row)
- }
- // 获取已选人员昵称(用于显示)
- const selectedUserNames = computed(() => {
- return selectedUserList.value.map(item => item.nickName || item.userName)
- })
- /** 查询工单列表 */
- async function handleSearch() {
- listLoading.value = true
- try {
- const res = await listWorkOrder(queryParams, pageNum.value, pageSize.value)
- if (res.code === 200) {
- tableData.value = res.data.records || []
- total.value = res.data.total || 0
- }
- } catch (e) {
- ElMessage.error('查询失败')
- } finally {
- listLoading.value = false
- }
- }
- /** 重置搜索 */
- function handleReset() {
- queryFormRef.value && queryFormRef.value.resetFields()
- queryParams.orderType = null
- queryParams.orderLevel = null
- queryParams.keyword = ''
- pageNum.value = 1
- selectedOrderId.value = null
- selectedOrder.value = {}
- handleSearch()
- }
- /** 选择工单 */
- async function handleSelectOrder(order) {
- selectedOrderId.value = order.orderId
- selectedOrder.value = { ...order } // 克隆对象确保更新
- activeTab.value = 'info'
- currentOrderLogs.value = []
-
- // 加载工单详情和处理历史
- await loadOrderDetail(order.orderId)
- }
- /** 分页变化 */
- function handleSizeChange() {
- pageNum.value = 1
- selectedOrderId.value = null
- selectedOrder.value = {}
- handleSearch()
- }
- function handlePageChange() {
- selectedOrderId.value = null
- selectedOrder.value = {}
- handleSearch()
- }
- /** 派单、核查、处理、完成、驳回的判断函数(示例) */
- function canDispatch() { return selectedOrder.value.orderStatus === 1 }
- function canVerify() { return [2, 3].includes(selectedOrder.value.orderStatus) }
- function canProcess() { return [3, 4].includes(selectedOrder.value.orderStatus) }
- function canComplete() { return selectedOrder.value.orderStatus === 4 }
- function canReject() { return [1, 2].includes(selectedOrder.value.orderStatus) }
- function handleDispatch() {
- if (!canDispatch()) {
- ElMessage.warning('仅可对待派单工单进行派单操作')
- return
- }
- Object.assign(dispatchForm, { handlerIds: [], remarks: '' })
- selectedUserList.value = []
- userList.value = []
- loadDeptTree()
- dispatchDialogVisible.value = true
- }
- async function submitDispatch() {
- if (!dispatchForm.handlerIds || dispatchForm.handlerIds.length === 0) {
- ElMessage.warning('请选择至少一个接单人')
- return
- }
- try {
- await dispatchWorkOrder({
- orderId: selectedOrder.value.orderId,
- handlerIds: dispatchForm.handlerIds, // 传递数组
- remarks: dispatchForm.remarks
- })
- ElMessage.success('派单成功!已向 ' + dispatchForm.handlerIds.length + ' 人下发任务')
- dispatchDialogVisible.value = false
- handleSearch()
- } catch (e) {
- ElMessage.error('派单失败')
- }
- }
- /** 核查、处理相关 */
- const actionDialogVisible = ref(false)
- const actionTitle = ref('')
- const actionFormData = reactive({ solution: '' })
- function handleVerify() {
- if (![2, 3].includes(selectedOrder.value.orderStatus)) {
- ElMessage.warning('当前工单不允许核查')
- return
- }
- actionTitle.value = '核查工单'
- actionFormData.solution = ''
- actionDialogVisible.value = true
- }
- function handleProcess() {
- if (![3, 4].includes(selectedOrder.value.orderStatus)) {
- ElMessage.warning('当前工单不允许处理')
- return
- }
- actionTitle.value = '处理工单'
- actionFormData.solution = ''
- actionDialogVisible.value = true
- }
- async function submitAction() {
- if (!actionFormData.solution.trim()) {
- ElMessage.warning('请填写说明')
- return
- }
- try {
- const data = {
- orderId: selectedOrder.value.orderId,
- handleResult: 'solved',
- solution: actionFormData.solution
- }
- if (actionTitle.value === '核查工单') {
- await verifyWorkOrder(data)
- } else {
- await processWorkOrder(data)
- }
- ElMessage.success(actionTitle.value + '成功')
- actionDialogVisible.value = false
- handleSearch()
- } catch (e) {
- ElMessage.error('操作失败')
- }
- }
- /** 完成/验收相关 */
- const completeDialogVisible = ref(false)
- const completeForm = reactive({ result: '' })
- function handleComplete() {
- if (![4, 5].includes(selectedOrder.value.orderStatus)) {
- ElMessage.warning('当前工单不允许提交验收')
- return
- }
- completeForm.result = ''
- completeDialogVisible.value = true
- }
- async function submitComplete() {
- if (!completeForm.result.trim()) {
- ElMessage.warning('请填写验收意见')
- return
- }
- try {
- await completeWorkOrder(selectedOrder.value.orderId, completeForm.result)
- ElMessage.success('提交验收成功')
- completeDialogVisible.value = false
- handleSearch()
- } catch (e) {
- ElMessage.error('提交失败')
- }
- }
- /** 驳回相关 */
- function handleReject() {
- if (![1, 2].includes(selectedOrder.value.orderStatus)) {
- ElMessage.warning('当前工单不允许驳回')
- return
- }
- ElMessage.info('驳回功能待实现')
- // TODO: 实现驳回逻辑
- }
- /** 辅助函数 */
- function getOrderTypeText(type) {
- const map = { 1: '故障维修', 2: '日常巡检', 3: '设备保养' }
- return map[type] || '-'
- }
- function getOperTypeLabel(type) {
- const map = {
- 1: '创建工单', 2: '派单', 3: '接单', 4: '开始维修',
- 5: '提交验收', 6: '验收通过', 7: '驳回工单', 8: '申请延期'
- }
- return map[type] || '-'
- }
- function getLogType(type) {
- const map = {
- 1: 'primary', 2: 'success', 3: 'warning', 4: 'danger',
- 5: 'success', 6: 'success', 7: 'danger', 8: 'warning'
- }
- return map[type] || ''
- }
- function formatDate(dateStr) {
- if (!dateStr) return '-'
- return new Date(dateStr).toLocaleString('zh-CN')
- }
- /** 优先级标签 */
- function getLevelLabel(level) {
- const map = { 1: '紧急', 2: '一般', 3: '低' }
- return map[level] || '未知'
- }
- function getLevelTag(level) {
- const map = { 1: 'danger', 2: 'warning', 3: 'info' }
- return map[level] || 'info'
- }
- /** 工单类型标签 */
- function getTypeLabel(type) {
- const map = { 1: '故障维修', 2: '日常巡检', 3: '设备保养' }
- return map[type] || '未知'
- }
- function getTypeTag(type) {
- const map = { 1: 'danger', 2: 'primary', 3: 'success' }
- return map[type] || 'info'
- }
- /** 加载工单详情和处理历史 */
- async function loadOrderDetail(orderId) {
- try {
- const res = await getWorkOrderDetail(orderId)
- if (res.code === 200) {
- selectedOrder.value = { ...selectedOrder.value, ...res.data.order }
- currentOrderLogs.value = res.data.logs || []
- }
- } catch (e) {
- ElMessage.error('加载工单详情失败')
- }
- }
- onMounted(() => {
- handleSearch()
- })
- </script>
- <style scoped lang="scss">
- .drainage-work-order {
- padding: 0 16px 16px;
-
- .search-card {
- margin-bottom: 16px;
-
- :deep(.el-card__body) {
- padding: 16px;
- }
- }
-
- .search-form {
- .el-form {
- display: flex;
- flex-wrap: wrap;
- align-items: flex-start;
- gap: 12px;
-
- .el-form-item {
- margin-bottom: 0;
- min-width: 150px;
-
- &:last-child {
- margin-left: auto;
- }
- }
- }
- }
-
- .order-list {
- overflow-y: auto;
- }
-
- .order-item {
- padding: 16px;
- margin-bottom: 8px;
- border-radius: 8px;
- cursor: pointer;
- transition: all 0.2s;
- border: 1px solid #e4e7ed;
-
- &:hover {
- background-color: #f5f7fa;
- }
-
- &.active {
- background-color: #ecf5ff;
- border-color: #409eff;
- }
-
- .order-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin-bottom: 8px;
-
- .order-no {
- font-weight: bold;
- font-size: 14px;
- }
-
- .status-badge {
- min-width: 60px;
- }
- }
-
- .order-body {
- font-size: 12px;
- color: #606266;
-
- .order-tags {
- display: flex;
- gap: 6px;
- margin-bottom: 6px;
- }
-
- .order-desc {
- margin-top: 4px;
- color: #303133;
- font-size: 13px;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
- }
-
- .device-code, .create-time {
- margin-top: 4px;
- }
- }
- }
-
- .pagination-wrapper {
- padding: 16px 0;
- border-top: 1px solid #e4e7ed;
- margin-top: 8px;
-
- .pagination {
- display: flex;
- justify-content: flex-end;
- }
- }
-
- .box-card {
- height: 100%;
- display: flex;
- flex-direction: column;
-
- :deep(.el-card__body) {
- flex: 1;
- display: flex;
- flex-direction: column;
- overflow: hidden;
- }
- }
-
- .detail-tabs {
- margin-top: 16px;
- }
-
- .image-section {
- margin-top: 24px;
- padding-top: 24px;
- border-top: 1px solid #e4e7ed;
-
- .image-list {
- display: flex;
- flex-wrap: wrap;
- gap: 12px;
- }
- }
-
- .action-section {
- margin-top: 24px;
- padding-top: 24px;
- border-top: 1px solid #e4e7ed;
-
- .section-title {
- font-size: 16px;
- font-weight: bold;
- margin-bottom: 16px;
- }
-
- .action-buttons {
- display: flex;
- gap: 12px;
- flex-wrap: wrap;
-
- .el-button {
- min-width: 100px;
- }
- }
- }
-
- .timeline-content {
- .operator-info {
- font-size: 14px;
- margin-bottom: 8px;
-
- .operator-name {
- font-weight: bold;
- color: #303133;
- }
-
- .oper-type {
- color: #909399;
- }
- }
-
- .oper-desc {
- font-size: 14px;
- color: #606266;
- }
- }
- }
- </style>
|