feat(dms): 新增派工计划、维修记录和维修工单详情页面

- 创建派工计划详情页,支持单人和团队派工模式
- 实现维修记录详情页,包含故障、维修和验收信息
- 开发维修工单详情页,支持设备选择和工程材料管理
- 添加相关API接口文件,支持完整的CRUD操作
- 集成字典数据和用户选择功能
- 实现表单验证和数据联动逻辑
master
zangch@mesnac.com 1 month ago
parent ae209ea090
commit fc5a25ad71

@ -0,0 +1,71 @@
import request from '@/utils/request'
// 查询派工计划列表
export function listDispatchPlan(query) {
return request({
url: '/dms/dispatchPlan/list',
method: 'get',
params: query
})
}
// 查询派工计划详细
export function getDispatchPlan(planId) {
return request({
url: '/dms/dispatchPlan/' + planId,
method: 'get'
})
}
// 新增派工计划
export function addDispatchPlan(data) {
return request({
url: '/dms/dispatchPlan',
method: 'post',
data: data
})
}
// 修改派工计划
export function updateDispatchPlan(data) {
return request({
url: '/dms/dispatchPlan',
method: 'put',
data: data
})
}
// 删除派工计划
export function delDispatchPlan(planId) {
return request({
url: '/dms/dispatchPlan/' + planId,
method: 'delete'
})
}
// 接收派工
export function receiveDispatch(data) {
return request({
url: '/dms/dispatchPlan/receive',
method: 'post',
data: data
})
}
// 拒绝派工
export function rejectDispatch(data) {
return request({
url: '/dms/dispatchPlan/reject',
method: 'post',
data: data
})
}
// 导出派工计划
export function exportDispatchPlan(query) {
return request({
url: '/dms/dispatchPlan/export',
method: 'get',
params: query
})
}

@ -0,0 +1,70 @@
import request from '@/utils/request'
// 查询维修记录列表
export function listRepairRecord(query) {
return request({
url: '/dms/repairRecord/list',
method: 'get',
params: query
})
}
// 查询维修记录详细
export function getRepairRecord(recordId) {
return request({
url: '/dms/repairRecord/' + recordId,
method: 'get'
})
}
// 新增维修记录
export function addRepairRecord(data) {
return request({
url: '/dms/repairRecord',
method: 'post',
data: data
})
}
// 修改维修记录
export function updateRepairRecord(data) {
return request({
url: '/dms/repairRecord',
method: 'put',
data: data
})
}
// 删除维修记录
export function delRepairRecord(recordId) {
return request({
url: '/dms/repairRecord/' + recordId,
method: 'delete'
})
}
// 存档维修记录
export function archiveRepairRecord(data) {
return request({
url: '/dms/repairRecord/archive',
method: 'post',
data: data
})
}
// 导出维修记录
export function exportRepairRecord(query) {
return request({
url: '/dms/repairRecord/export',
method: 'get',
params: query
})
}
// 按设备查询维修历史
export function getRepairHistory(deviceId) {
return request({
url: '/dms/repairRecord/history/' + deviceId,
method: 'get'
})
}

@ -0,0 +1,89 @@
import request from '@/utils/request'
// 查询维修工单列表
export function listRepairWorkOrder(query) {
return request({
url: '/dms/repairWorkOrder/list',
method: 'get',
params: query
})
}
// 查询维修工单详细
export function getRepairWorkOrder(workOrderId) {
return request({
url: '/dms/repairWorkOrder/' + workOrderId,
method: 'get'
})
}
// 新增维修工单
export function addRepairWorkOrder(data) {
return request({
url: '/dms/repairWorkOrder',
method: 'post',
data: data
})
}
// 修改维修工单
export function updateRepairWorkOrder(data) {
return request({
url: '/dms/repairWorkOrder',
method: 'put',
data: data
})
}
// 删除维修工单
export function delRepairWorkOrder(workOrderId) {
return request({
url: '/dms/repairWorkOrder/' + workOrderId,
method: 'delete'
})
}
// 派工
export function dispatchWorkOrder(data) {
return request({
url: '/dms/repairWorkOrder/dispatch',
method: 'post',
data: data
})
}
// 开始维修
export function startWorkOrder(data) {
return request({
url: '/dms/repairWorkOrder/start',
method: 'post',
data: data
})
}
// 完成维修
export function completeWorkOrder(data) {
return request({
url: '/dms/repairWorkOrder/complete',
method: 'post',
data: data
})
}
// 审批
export function approveWorkOrder(data) {
return request({
url: '/dms/repairWorkOrder/approve',
method: 'post',
data: data
})
}
// 导出维修工单
export function exportRepairWorkOrder(query) {
return request({
url: '/dms/repairWorkOrder/export',
method: 'get',
params: query
})
}

@ -0,0 +1,294 @@
<template>
<div class="app-container">
<el-form ref="form" :model="form" :rules="rules" label-width="120px">
<el-card shadow="never" style="margin-bottom: 20px;">
<div slot="header" class="clearfix">
<span>派工基本信息</span>
</div>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="派工单号" prop="planCode">
<el-input v-model="form.planCode" placeholder="自动生成" disabled />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="工单编号" prop="workOrderCode">
<el-input v-model="form.workOrderCode" placeholder="请输入工单编号" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="设备编号" prop="deviceCode">
<el-input v-model="form.deviceCode" placeholder="请输入设备编号" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="设备名称" prop="deviceName">
<el-input v-model="form.deviceName" placeholder="请输入设备名称" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="派工类型" prop="dispatchType">
<el-select v-model="form.dispatchType" placeholder="请选择派工类型" @change="handleDispatchTypeChange">
<el-option
v-for="dict in dict.type.dms_dispatch_type"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="优先级" prop="priority">
<el-select v-model="form.priority" placeholder="请选择优先级">
<el-option
v-for="dict in dict.type.dms_priority"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
<!-- 单人派工 -->
<el-row :gutter="20" v-if="form.dispatchType === '1'">
<el-col :span="12">
<el-form-item label="执行人" prop="executorId">
<el-select v-model="form.executorId" placeholder="请选择执行人" filterable @change="handleExecutorChange">
<el-option
v-for="user in userList"
:key="user.userId"
:label="user.nickName || user.userName"
:value="user.userId"
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="要求开始时间" prop="requireStartTime">
<el-date-picker
v-model="form.requireStartTime"
type="datetime"
value-format="yyyy-MM-dd HH:mm:ss"
placeholder="选择开始时间"
style="width: 100%;"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="要求完成时间" prop="requireEndTime">
<el-date-picker
v-model="form.requireEndTime"
type="datetime"
value-format="yyyy-MM-dd HH:mm:ss"
placeholder="选择完成时间"
style="width: 100%;"
/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="24">
<el-form-item label="派工说明" prop="dispatchNotes">
<el-input v-model="form.dispatchNotes" type="textarea" :rows="3" placeholder="请输入派工说明" />
</el-form-item>
</el-col>
</el-row>
</el-card>
<!-- 团队成员团队派工时显示 -->
<el-card shadow="never" v-if="form.dispatchType === '2'" style="margin-bottom: 20px;">
<div slot="header" class="clearfix">
<span>团队成员</span>
<el-button style="float: right; padding: 3px 10px" type="primary" size="mini" @click="handleAddMember"></el-button>
</div>
<el-table :data="form.dispatchMembers" border>
<el-table-column label="序号" type="index" width="50" align="center" />
<el-table-column label="成员姓名" prop="userName" min-width="120">
<template slot-scope="scope">
<el-select v-model="scope.row.userId" placeholder="请选择成员" filterable @change="handleMemberChange(scope.row, scope.$index)">
<el-option
v-for="user in userList"
:key="user.userId"
:label="user.nickName || user.userName"
:value="user.userId"
/>
</el-select>
</template>
</el-table-column>
<el-table-column label="成员角色" prop="memberRole" min-width="120">
<template slot-scope="scope">
<el-select v-model="scope.row.memberRole" placeholder="请选择角色">
<el-option
v-for="dict in dict.type.dms_member_role"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</template>
</el-table-column>
<el-table-column label="分配工时" prop="allocatedHours" min-width="100">
<template slot-scope="scope">
<el-input-number v-model="scope.row.allocatedHours" :min="0" :precision="1" style="width: 100%;" />
</template>
</el-table-column>
<el-table-column label="备注" prop="remark" min-width="150">
<template slot-scope="scope">
<el-input v-model="scope.row.remark" placeholder="请输入备注" />
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="80">
<template slot-scope="scope">
<el-button type="text" size="small" @click="handleDeleteMember(scope.$index)"></el-button>
</template>
</el-table-column>
</el-table>
</el-card>
<el-form-item>
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
import { getDispatchPlan, addDispatchPlan, updateDispatchPlan } from '@/api/dms/dispatchPlan'
import { selectUserList } from '@/api/system/user'
export default {
name: 'DispatchPlanDetail',
dicts: ['dms_dispatch_type', 'dms_priority', 'dms_member_role'],
data() {
return {
form: {
planId: null,
planCode: null,
workOrderId: null,
workOrderCode: null,
deviceId: null,
deviceCode: null,
deviceName: null,
dispatchType: '1',
executorId: null,
executorName: null,
teamId: null,
teamName: null,
requireStartTime: null,
requireEndTime: null,
priority: '3',
dispatchNotes: null,
dispatchMembers: []
},
userList: [],
rules: {
dispatchType: [{ required: true, message: '请选择派工类型', trigger: 'change' }],
executorId: [{ required: true, message: '请选择执行人', trigger: 'change' }],
requireStartTime: [{ required: true, message: '请选择要求开始时间', trigger: 'change' }],
requireEndTime: [{ required: true, message: '请选择要求完成时间', trigger: 'change' }]
}
}
},
created() {
this.loadUserList()
const planId = this.$route.params && this.$route.params.planId
if (planId && planId !== 'new') {
this.loadData(planId)
}
//
if (this.$route.query.workOrderId) {
this.form.workOrderId = this.$route.query.workOrderId
this.form.workOrderCode = this.$route.query.workOrderCode
this.form.deviceCode = this.$route.query.deviceCode
this.form.deviceName = this.$route.query.deviceName
}
},
methods: {
loadData(planId) {
getDispatchPlan(planId).then(response => {
this.form = response.data
if (!this.form.dispatchMembers) {
this.form.dispatchMembers = []
}
})
},
loadUserList() {
selectUserList({}).then(response => {
this.userList = response.rows
})
},
handleDispatchTypeChange(val) {
if (val === '1') {
//
this.form.dispatchMembers = []
this.form.teamId = null
this.form.teamName = null
} else {
//
this.form.executorId = null
this.form.executorName = null
}
},
handleExecutorChange(userId) {
const user = this.userList.find(u => u.userId === userId)
if (user) {
this.form.executorName = user.nickName || user.userName
}
},
handleAddMember() {
this.form.dispatchMembers.push({
userId: null,
userName: null,
memberRole: null,
allocatedHours: 0,
remark: null
})
},
handleMemberChange(row, index) {
const user = this.userList.find(u => u.userId === row.userId)
if (user) {
row.userName = user.nickName || user.userName
}
},
handleDeleteMember(index) {
this.form.dispatchMembers.splice(index, 1)
},
submitForm() {
this.$refs['form'].validate(valid => {
if (valid) {
if (this.form.planId) {
updateDispatchPlan(this.form).then(response => {
this.$modal.msgSuccess('修改成功')
this.cancel()
})
} else {
addDispatchPlan(this.form).then(response => {
this.$modal.msgSuccess('新增成功')
this.cancel()
})
}
}
})
},
cancel() {
this.$router.back()
}
}
}
</script>

@ -0,0 +1,305 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="88px">
<el-form-item label="派工单号" prop="planCode">
<el-input
v-model="queryParams.planCode"
placeholder="请输入派工单号"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="工单编号" prop="workOrderCode">
<el-input
v-model="queryParams.workOrderCode"
placeholder="请输入工单编号"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="设备名称" prop="deviceName">
<el-input
v-model="queryParams.deviceName"
placeholder="请输入设备名称"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="执行状态" prop="executionStatus">
<el-select v-model="queryParams.executionStatus" placeholder="请选择执行状态" clearable>
<el-option
v-for="dict in dict.type.dms_execution_status"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="接收状态" prop="receiveStatus">
<el-select v-model="queryParams.receiveStatus" placeholder="请选择接收状态" clearable>
<el-option
v-for="dict in dict.type.dms_receive_status"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery"></el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery"></el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['dms:dispatchPlan:add']"
>新增派工</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['dms:dispatchPlan:remove']"
>删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['dms:dispatchPlan:export']"
>导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="dispatchPlanList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="派工单号" align="center" prop="planCode" width="160" />
<el-table-column label="工单编号" align="center" prop="workOrderCode" width="160" />
<el-table-column label="设备名称" align="center" prop="deviceName" show-overflow-tooltip />
<el-table-column label="派工类型" align="center" prop="dispatchType" width="100">
<template slot-scope="scope">
<dict-tag :options="dict.type.dms_dispatch_type" :value="scope.row.dispatchType"/>
</template>
</el-table-column>
<el-table-column label="执行人/团队" align="center" width="120">
<template slot-scope="scope">
<span v-if="scope.row.dispatchType === '1'">{{ scope.row.executorName }}</span>
<span v-else>{{ scope.row.teamName }}</span>
</template>
</el-table-column>
<el-table-column label="优先级" align="center" prop="priority" width="80">
<template slot-scope="scope">
<dict-tag :options="dict.type.dms_priority" :value="scope.row.priority"/>
</template>
</el-table-column>
<el-table-column label="接收状态" align="center" prop="receiveStatus" width="100">
<template slot-scope="scope">
<dict-tag :options="dict.type.dms_receive_status" :value="scope.row.receiveStatus"/>
</template>
</el-table-column>
<el-table-column label="执行状态" align="center" prop="executionStatus" width="100">
<template slot-scope="scope">
<dict-tag :options="dict.type.dms_execution_status" :value="scope.row.executionStatus"/>
</template>
</el-table-column>
<el-table-column label="派工时间" align="center" prop="dispatchTime" width="160">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.dispatchTime, '{y}-{m}-{d} {h}:{i}') }}</span>
</template>
</el-table-column>
<el-table-column label="要求完成" align="center" prop="requireEndTime" width="160">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.requireEndTime, '{y}-{m}-{d} {h}:{i}') }}</span>
</template>
</el-table-column>
<el-table-column label="派工人" align="center" prop="dispatcherName" width="100" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="200">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-view"
@click="handleView(scope.row)"
v-hasPermi="['dms:dispatchPlan:query']"
>查看</el-button>
<el-button
v-if="scope.row.receiveStatus === '0'"
size="mini"
type="text"
@click="handleReceive(scope.row)"
v-hasPermi="['dms:dispatchPlan:receive']"
>接收</el-button>
<el-button
v-if="scope.row.receiveStatus === '0'"
size="mini"
type="text"
style="color: #F56C6C"
@click="handleReject(scope.row)"
v-hasPermi="['dms:dispatchPlan:reject']"
>拒绝</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 拒绝对话框 -->
<el-dialog title="拒绝派工" :visible.sync="rejectDialogVisible" width="500px" append-to-body>
<el-form ref="rejectForm" :model="rejectForm" label-width="100px">
<el-form-item label="派工单号">
<el-input v-model="rejectForm.planCode" disabled />
</el-form-item>
<el-form-item label="拒绝原因" prop="rejectReason">
<el-input v-model="rejectForm.rejectReason" type="textarea" :rows="4" placeholder="请输入拒绝原因" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="rejectDialogVisible = false"> </el-button>
<el-button type="primary" @click="submitReject"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { listDispatchPlan, getDispatchPlan, delDispatchPlan, receiveDispatch, rejectDispatch } from '@/api/dms/dispatchPlan'
export default {
name: 'DispatchPlan',
dicts: ['dms_dispatch_type', 'dms_execution_status', 'dms_receive_status', 'dms_priority'],
data() {
return {
loading: true,
ids: [],
single: true,
multiple: true,
showSearch: true,
total: 0,
dispatchPlanList: [],
queryParams: {
pageNum: 1,
pageSize: 10,
planCode: null,
workOrderCode: null,
deviceName: null,
executionStatus: null,
receiveStatus: null
},
rejectDialogVisible: false,
rejectForm: {
planId: null,
planCode: null,
rejectReason: null
}
}
},
created() {
this.getList()
},
methods: {
/** 查询列表 */
getList() {
this.loading = true
listDispatchPlan(this.queryParams).then(response => {
this.dispatchPlanList = response.rows
this.total = response.total
this.loading = false
})
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm('queryForm')
this.handleQuery()
},
/** 多选框选中数据 */
handleSelectionChange(selection) {
this.ids = selection.map(item => item.planId)
this.single = selection.length !== 1
this.multiple = !selection.length
},
/** 新增按钮操作 */
handleAdd() {
this.$router.push('/dms/dispatchPlan/detail/new')
},
/** 查看按钮操作 */
handleView(row) {
this.$router.push({
path: '/dms/dispatchPlan/detail/' + row.planId,
query: { view: 'true' }
})
},
/** 接收派工 */
handleReceive(row) {
this.$modal.confirm('是否确认接收派工单"' + row.planCode + '"').then(() => {
return receiveDispatch({ planId: row.planId })
}).then(() => {
this.getList()
this.$modal.msgSuccess('接收成功')
}).catch(() => {})
},
/** 拒绝派工 */
handleReject(row) {
this.rejectForm = {
planId: row.planId,
planCode: row.planCode,
rejectReason: null
}
this.rejectDialogVisible = true
},
/** 提交拒绝 */
submitReject() {
if (!this.rejectForm.rejectReason) {
this.$message.warning('请输入拒绝原因')
return
}
rejectDispatch(this.rejectForm).then(() => {
this.$modal.msgSuccess('操作成功')
this.rejectDialogVisible = false
this.getList()
})
},
/** 删除按钮操作 */
handleDelete(row) {
const planIds = row.planId || this.ids
this.$modal.confirm('是否确认删除选中的派工计划?').then(() => {
return delDispatchPlan(planIds)
}).then(() => {
this.getList()
this.$modal.msgSuccess('删除成功')
}).catch(() => {})
},
/** 导出按钮操作 */
handleExport() {
this.download('dms/dispatchPlan/export', {
...this.queryParams
}, `dispatchPlan_${new Date().getTime()}.xlsx`)
}
}
}
</script>

@ -0,0 +1,288 @@
<template>
<div class="app-container">
<el-form ref="form" :model="form" :rules="rules" label-width="120px">
<el-card shadow="never" style="margin-bottom: 20px;">
<div slot="header" class="clearfix">
<span>工单信息</span>
</div>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="工单编号" prop="workOrderCode">
<el-input v-model="form.workOrderCode" placeholder="请输入工单编号" disabled />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="设备编号" prop="deviceCode">
<el-input v-model="form.deviceCode" placeholder="请输入设备编号" disabled />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="设备名称" prop="deviceName">
<el-input v-model="form.deviceName" placeholder="请输入设备名称" disabled />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="维修人员" prop="repairerName">
<el-input v-model="form.repairerName" placeholder="请输入维修人员" />
</el-form-item>
</el-col>
</el-row>
</el-card>
<el-card shadow="never" style="margin-bottom: 20px;">
<div slot="header" class="clearfix">
<span>故障信息</span>
</div>
<el-row :gutter="20">
<el-col :span="24">
<el-form-item label="故障现象" prop="faultPhenomenon">
<el-input v-model="form.faultPhenomenon" type="textarea" :rows="3" placeholder="请输入故障现象" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="24">
<el-form-item label="故障原因" prop="faultCause">
<el-input v-model="form.faultCause" type="textarea" :rows="3" placeholder="请输入故障原因分析" />
</el-form-item>
</el-col>
</el-row>
</el-card>
<el-card shadow="never" style="margin-bottom: 20px;">
<div slot="header" class="clearfix">
<span>维修信息</span>
</div>
<el-row :gutter="20">
<el-col :span="24">
<el-form-item label="维修方法" prop="repairMethod">
<el-input v-model="form.repairMethod" type="textarea" :rows="2" placeholder="请输入维修方法" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="24">
<el-form-item label="维修过程" prop="repairProcess">
<el-input v-model="form.repairProcess" type="textarea" :rows="4" placeholder="请输入详细维修过程" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="24">
<el-form-item label="更换部件" prop="replacedParts">
<el-input v-model="form.replacedParts" type="textarea" :rows="2" placeholder="请输入更换的部件清单" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="开始时间" prop="startTime">
<el-date-picker
v-model="form.startTime"
type="datetime"
value-format="yyyy-MM-dd HH:mm:ss"
placeholder="选择开始时间"
style="width: 100%;"
/>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="完成时间" prop="endTime">
<el-date-picker
v-model="form.endTime"
type="datetime"
value-format="yyyy-MM-dd HH:mm:ss"
placeholder="选择完成时间"
style="width: 100%;"
/>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="维修工时" prop="repairHours">
<el-input-number v-model="form.repairHours" :min="0" :precision="1" style="width: 100%;" placeholder="小时" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="维修费用" prop="repairCost">
<el-input-number v-model="form.repairCost" :min="0" :precision="2" style="width: 100%;" placeholder="元" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="停机时长" prop="shutdownDuration">
<el-input-number v-model="form.shutdownDuration" :min="0" style="width: 100%;" placeholder="分钟" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="维修结果" prop="repairResult">
<el-select v-model="form.repairResult" placeholder="请选择维修结果" style="width: 100%;">
<el-option
v-for="dict in dict.type.dms_repair_result"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
</el-card>
<el-card shadow="never" style="margin-bottom: 20px;">
<div slot="header" class="clearfix">
<span>验收信息</span>
</div>
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="验收人" prop="acceptor">
<el-input v-model="form.acceptor" placeholder="请输入验收人" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="验收时间" prop="acceptTime">
<el-date-picker
v-model="form.acceptTime"
type="datetime"
value-format="yyyy-MM-dd HH:mm:ss"
placeholder="选择验收时间"
style="width: 100%;"
/>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="验收结果" prop="acceptResult">
<el-select v-model="form.acceptResult" placeholder="请选择验收结果" style="width: 100%;">
<el-option
v-for="dict in dict.type.dms_accept_result"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="24">
<el-form-item label="验收意见" prop="acceptOpinion">
<el-input v-model="form.acceptOpinion" type="textarea" :rows="3" placeholder="请输入验收意见" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="24">
<el-form-item label="后续建议" prop="followupSuggestion">
<el-input v-model="form.followupSuggestion" type="textarea" :rows="3" placeholder="请输入后续维护建议" />
</el-form-item>
</el-col>
</el-row>
</el-card>
<el-form-item>
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
import { getRepairRecord, addRepairRecord, updateRepairRecord } from '@/api/dms/repairRecord'
export default {
name: 'RepairRecordDetail',
dicts: ['dms_repair_result', 'dms_accept_result'],
data() {
return {
form: {
recordId: null,
workOrderId: null,
workOrderCode: null,
deviceId: null,
deviceCode: null,
deviceName: null,
faultPhenomenon: null,
faultCause: null,
repairMethod: null,
repairProcess: null,
replacedParts: null,
repairResult: null,
repairerId: null,
repairerName: null,
startTime: null,
endTime: null,
repairHours: null,
repairCost: null,
shutdownDuration: null,
acceptor: null,
acceptTime: null,
acceptResult: null,
acceptOpinion: null,
followupSuggestion: null
},
rules: {
faultPhenomenon: [{ required: true, message: '请输入故障现象', trigger: 'blur' }],
repairProcess: [{ required: true, message: '请输入维修过程', trigger: 'blur' }],
startTime: [{ required: true, message: '请选择开始时间', trigger: 'change' }],
endTime: [{ required: true, message: '请选择完成时间', trigger: 'change' }],
repairResult: [{ required: true, message: '请选择维修结果', trigger: 'change' }]
}
}
},
created() {
const recordId = this.$route.params && this.$route.params.recordId
if (recordId && recordId !== 'new') {
this.loadData(recordId)
}
//
if (this.$route.query.workOrderId) {
this.form.workOrderId = this.$route.query.workOrderId
this.form.workOrderCode = this.$route.query.workOrderCode
this.form.deviceCode = this.$route.query.deviceCode
this.form.deviceName = this.$route.query.deviceName
}
},
methods: {
loadData(recordId) {
getRepairRecord(recordId).then(response => {
this.form = response.data
})
},
submitForm() {
this.$refs['form'].validate(valid => {
if (valid) {
if (this.form.recordId) {
updateRepairRecord(this.form).then(response => {
this.$modal.msgSuccess('修改成功')
this.cancel()
})
} else {
addRepairRecord(this.form).then(response => {
this.$modal.msgSuccess('新增成功')
this.cancel()
})
}
}
})
},
cancel() {
this.$router.back()
}
}
}
</script>

@ -0,0 +1,284 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="88px">
<el-form-item label="工单编号" prop="workOrderCode">
<el-input
v-model="queryParams.workOrderCode"
placeholder="请输入工单编号"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="设备名称" prop="deviceName">
<el-input
v-model="queryParams.deviceName"
placeholder="请输入设备名称"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="维修人员" prop="repairerName">
<el-input
v-model="queryParams.repairerName"
placeholder="请输入维修人员"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="维修结果" prop="repairResult">
<el-select v-model="queryParams.repairResult" placeholder="请选择维修结果" clearable>
<el-option
v-for="dict in dict.type.dms_repair_result"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="是否存档" prop="isArchived">
<el-select v-model="queryParams.isArchived" placeholder="请选择是否存档" clearable>
<el-option label="是" value="1" />
<el-option label="否" value="0" />
</el-select>
</el-form-item>
<el-form-item label="维修日期">
<el-date-picker
v-model="dateRange"
style="width: 240px"
value-format="yyyy-MM-dd"
type="daterange"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
></el-date-picker>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery"></el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery"></el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['dms:repairRecord:add']"
>新增记录</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="success"
plain
icon="el-icon-folder"
size="mini"
:disabled="multiple"
@click="handleArchive"
v-hasPermi="['dms:repairRecord:archive']"
>存档</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['dms:repairRecord:remove']"
>删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['dms:repairRecord:export']"
>导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="repairRecordList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="工单编号" align="center" prop="workOrderCode" width="160" />
<el-table-column label="设备名称" align="center" prop="deviceName" show-overflow-tooltip />
<el-table-column label="故障现象" align="center" prop="faultPhenomenon" show-overflow-tooltip width="200" />
<el-table-column label="维修人员" align="center" prop="repairerName" width="100" />
<el-table-column label="开始时间" align="center" prop="startTime" width="160">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.startTime, '{y}-{m}-{d} {h}:{i}') }}</span>
</template>
</el-table-column>
<el-table-column label="结束时间" align="center" prop="endTime" width="160">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.endTime, '{y}-{m}-{d} {h}:{i}') }}</span>
</template>
</el-table-column>
<el-table-column label="工时(h)" align="center" prop="repairHours" width="90" />
<el-table-column label="费用(元)" align="center" prop="repairCost" width="100" />
<el-table-column label="维修结果" align="center" prop="repairResult" width="100">
<template slot-scope="scope">
<dict-tag :options="dict.type.dms_repair_result" :value="scope.row.repairResult"/>
</template>
</el-table-column>
<el-table-column label="验收结果" align="center" prop="acceptResult" width="100">
<template slot-scope="scope">
<dict-tag :options="dict.type.dms_accept_result" :value="scope.row.acceptResult"/>
</template>
</el-table-column>
<el-table-column label="是否存档" align="center" prop="isArchived" width="100">
<template slot-scope="scope">
<el-tag v-if="scope.row.isArchived === '1'" type="success"></el-tag>
<el-tag v-else type="info">未存档</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="180">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-view"
@click="handleView(scope.row)"
v-hasPermi="['dms:repairRecord:query']"
>查看</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['dms:repairRecord:edit']"
>编辑</el-button>
<el-button
v-if="scope.row.isArchived === '0'"
size="mini"
type="text"
@click="handleArchive(scope.row)"
v-hasPermi="['dms:repairRecord:archive']"
>存档</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
</div>
</template>
<script>
import { listRepairRecord, getRepairRecord, delRepairRecord, archiveRepairRecord } from '@/api/dms/repairRecord'
export default {
name: 'RepairRecord',
dicts: ['dms_repair_result', 'dms_accept_result'],
data() {
return {
loading: true,
ids: [],
single: true,
multiple: true,
showSearch: true,
total: 0,
repairRecordList: [],
dateRange: [],
queryParams: {
pageNum: 1,
pageSize: 10,
workOrderCode: null,
deviceName: null,
repairerName: null,
repairResult: null,
isArchived: null
}
}
},
created() {
this.getList()
},
methods: {
/** 查询列表 */
getList() {
this.loading = true
this.queryParams.params = {}
if (this.dateRange != null && this.dateRange !== '') {
this.queryParams.params['beginTime'] = this.dateRange[0]
this.queryParams.params['endTime'] = this.dateRange[1]
}
listRepairRecord(this.queryParams).then(response => {
this.repairRecordList = response.rows
this.total = response.total
this.loading = false
})
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.dateRange = []
this.resetForm('queryForm')
this.handleQuery()
},
/** 多选框选中数据 */
handleSelectionChange(selection) {
this.ids = selection.map(item => item.recordId)
this.single = selection.length !== 1
this.multiple = !selection.length
},
/** 新增按钮操作 */
handleAdd() {
this.$router.push('/dms/repairRecord/detail/new')
},
/** 修改按钮操作 */
handleUpdate(row) {
const recordId = row.recordId || this.ids[0]
this.$router.push('/dms/repairRecord/detail/' + recordId)
},
/** 查看按钮操作 */
handleView(row) {
this.$router.push({
path: '/dms/repairRecord/detail/' + row.recordId,
query: { view: 'true' }
})
},
/** 存档 */
handleArchive(row) {
const recordIds = row.recordId ? [row.recordId] : this.ids
this.$modal.confirm('是否确认存档选中的维修记录?').then(() => {
return archiveRepairRecord({ recordIds: recordIds })
}).then(() => {
this.getList()
this.$modal.msgSuccess('存档成功')
}).catch(() => {})
},
/** 删除按钮操作 */
handleDelete(row) {
const recordIds = row.recordId || this.ids
this.$modal.confirm('是否确认删除选中的维修记录?').then(() => {
return delRepairRecord(recordIds)
}).then(() => {
this.getList()
this.$modal.msgSuccess('删除成功')
}).catch(() => {})
},
/** 导出按钮操作 */
handleExport() {
this.download('dms/repairRecord/export', {
...this.queryParams
}, `repairRecord_${new Date().getTime()}.xlsx`)
}
}
}
</script>

@ -0,0 +1,440 @@
<template>
<div class="app-container repair-work-order-detail">
<el-card class="box-card" shadow="never">
<div slot="header" class="clearfix">
<span class="card-title">基本信息</span>
</div>
<el-form ref="form" :model="form" :rules="rules" label-width="120px">
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="工单编号" prop="workOrderCode">
<el-input v-model="form.workOrderCode" disabled placeholder="系统自动生成" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="关联故障报修">
<el-input v-model="form.faultInstanceId" placeholder="选择故障报修单" readonly @click.native="selectFaultInstance">
<el-button slot="append" icon="el-icon-search" @click="selectFaultInstance"></el-button>
</el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="优先级" prop="priority">
<el-select v-model="form.priority" placeholder="请选择优先级" :disabled="isView" style="width: 100%">
<el-option
v-for="dict in dict.type.dms_priority"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="设备" prop="deviceId">
<el-select v-model="form.deviceId" placeholder="请选择设备" :disabled="isView" filterable style="width: 100%" @change="handleDeviceChange">
<el-option
v-for="item in deviceList"
:key="item.objId || item.deviceId"
:label="item.deviceName"
:value="item.objId || item.deviceId"
>
<span style="float: left">{{ item.deviceCode }}</span>
<span style="float: right; color: #8492a6; font-size: 13px">{{ item.deviceName }}</span>
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="故障类型" prop="faultType">
<el-select v-model="form.faultType" placeholder="请选择故障类型" :disabled="isView" style="width: 100%">
<el-option
v-for="dict in dict.type.dms_fault_type"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="维修类型" prop="repairType">
<el-select v-model="form.repairType" placeholder="请选择维修类型" :disabled="isView" style="width: 100%">
<el-option
v-for="dict in dict.type.dms_repair_type"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="故障描述" prop="faultDescription">
<el-input v-model="form.faultDescription" type="textarea" :rows="3" :disabled="isView" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="维修说明" prop="repairNotes">
<el-input v-model="form.repairNotes" type="textarea" :rows="3" :disabled="isView" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="计划开始时间">
<el-date-picker
v-model="form.planStartTime"
type="datetime"
placeholder="选择日期时间"
value-format="yyyy-MM-dd HH:mm:ss"
:disabled="isView"
style="width: 100%"
/>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="计划完成时间">
<el-date-picker
v-model="form.planEndTime"
type="datetime"
placeholder="选择日期时间"
value-format="yyyy-MM-dd HH:mm:ss"
:disabled="isView"
style="width: 100%"
/>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="是否需要停机">
<el-radio-group v-model="form.needShutdown" :disabled="isView">
<el-radio label="1"></el-radio>
<el-radio label="0"></el-radio>
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="预算费用(元)">
<el-input-number v-model="form.budgetCost" :min="0" :precision="2" :disabled="isView" style="width: 100%" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="预计工时(h)">
<el-input-number v-model="form.repairHours" :min="0" :precision="1" :disabled="isView" style="width: 100%" />
</el-form-item>
</el-col>
</el-row>
</el-form>
</el-card>
<!-- 维修工程明细 -->
<el-card class="box-card" shadow="never" style="margin-top: 15px">
<div slot="header" class="clearfix">
<span class="card-title">维修工程明细</span>
<el-button v-if="!isView" style="float: right; padding: 3px 10px" type="primary" size="mini" @click="handleAddProject">
<i class="el-icon-plus"></i> 添加工程
</el-button>
</div>
<el-table :data="form.repairProjects" border>
<el-table-column label="序号" type="index" width="60" align="center" />
<el-table-column label="工程名称" align="center" prop="projectName" width="180">
<template slot-scope="scope">
<el-input v-if="!isView" v-model="scope.row.projectName" placeholder="请输入工程名称" />
<span v-else>{{ scope.row.projectName }}</span>
</template>
</el-table-column>
<el-table-column label="工程类型" align="center" prop="projectType" width="120">
<template slot-scope="scope">
<el-select v-if="!isView" v-model="scope.row.projectType" placeholder="请选择">
<el-option
v-for="dict in dict.type.dms_project_type"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
<dict-tag v-else :options="dict.type.dms_project_type" :value="scope.row.projectType"/>
</template>
</el-table-column>
<el-table-column label="工程内容" align="center" prop="projectContent" show-overflow-tooltip>
<template slot-scope="scope">
<el-input v-if="!isView" v-model="scope.row.projectContent" type="textarea" :rows="2" />
<span v-else>{{ scope.row.projectContent }}</span>
</template>
</el-table-column>
<el-table-column label="技术要求" align="center" prop="technicalRequirement" show-overflow-tooltip>
<template slot-scope="scope">
<el-input v-if="!isView" v-model="scope.row.technicalRequirement" />
<span v-else>{{ scope.row.technicalRequirement }}</span>
</template>
</el-table-column>
<el-table-column label="计划工时(h)" align="center" prop="planHours" width="120">
<template slot-scope="scope">
<el-input-number v-if="!isView" v-model="scope.row.planHours" :min="0" :precision="1" style="width: 100%" />
<span v-else>{{ scope.row.planHours }}</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="100" v-if="!isView">
<template slot-scope="scope">
<el-button size="mini" type="text" style="color: #F56C6C" @click="handleDeleteProject(scope.$index)"></el-button>
</template>
</el-table-column>
</el-table>
</el-card>
<!-- 维修材料明细 -->
<el-card class="box-card" shadow="never" style="margin-top: 15px">
<div slot="header" class="clearfix">
<span class="card-title">维修材料明细</span>
<el-button v-if="!isView" style="float: right; padding: 3px 10px" type="primary" size="mini" @click="handleAddMaterial">
<i class="el-icon-plus"></i> 添加材料
</el-button>
</div>
<el-table :data="form.repairMaterials" border>
<el-table-column label="序号" type="index" width="60" align="center" />
<el-table-column label="材料编码" align="center" prop="materialCode" width="140">
<template slot-scope="scope">
<el-input v-if="!isView" v-model="scope.row.materialCode" placeholder="请输入材料编码" />
<span v-else>{{ scope.row.materialCode }}</span>
</template>
</el-table-column>
<el-table-column label="材料名称" align="center" prop="materialName" width="180">
<template slot-scope="scope">
<el-input v-if="!isView" v-model="scope.row.materialName" placeholder="请输入材料名称" />
<span v-else>{{ scope.row.materialName }}</span>
</template>
</el-table-column>
<el-table-column label="规格型号" align="center" prop="materialSpec" show-overflow-tooltip>
<template slot-scope="scope">
<el-input v-if="!isView" v-model="scope.row.materialSpec" />
<span v-else>{{ scope.row.materialSpec }}</span>
</template>
</el-table-column>
<el-table-column label="材料类型" align="center" prop="materialType" width="110">
<template slot-scope="scope">
<el-select v-if="!isView" v-model="scope.row.materialType" placeholder="请选择">
<el-option
v-for="dict in dict.type.dms_material_type"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
<dict-tag v-else :options="dict.type.dms_material_type" :value="scope.row.materialType"/>
</template>
</el-table-column>
<el-table-column label="单位" align="center" prop="unit" width="80">
<template slot-scope="scope">
<el-input v-if="!isView" v-model="scope.row.unit" />
<span v-else>{{ scope.row.unit }}</span>
</template>
</el-table-column>
<el-table-column label="计划数量" align="center" prop="planQuantity" width="100">
<template slot-scope="scope">
<el-input-number v-if="!isView" v-model="scope.row.planQuantity" :min="0" :precision="2" style="width: 100%" />
<span v-else>{{ scope.row.planQuantity }}</span>
</template>
</el-table-column>
<el-table-column label="单价(元)" align="center" prop="unitPrice" width="100">
<template slot-scope="scope">
<el-input-number v-if="!isView" v-model="scope.row.unitPrice" :min="0" :precision="2" style="width: 100%" />
<span v-else>{{ scope.row.unitPrice }}</span>
</template>
</el-table-column>
<el-table-column label="总金额(元)" align="center" prop="totalAmount" width="120">
<template slot-scope="scope">
<span>{{ calculateAmount(scope.row) }}</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="100" v-if="!isView">
<template slot-scope="scope">
<el-button size="mini" type="text" style="color: #F56C6C" @click="handleDeleteMaterial(scope.$index)"></el-button>
</template>
</el-table-column>
</el-table>
</el-card>
<!-- 底部按钮 -->
<div class="footer-buttons" style="margin-top: 20px">
<el-button @click="goBack"> </el-button>
<el-button type="primary" @click="handleSubmit" v-if="!isView"> </el-button>
</div>
</div>
</template>
<script>
import { getRepairWorkOrder, addRepairWorkOrder, updateRepairWorkOrder } from '@/api/dms/repairWorkOrder'
import { getDeviceLedgerList } from '@/api/base/deviceLedger'
export default {
name: 'RepairWorkOrderDetail',
dicts: ['dms_priority', 'dms_fault_type', 'dms_repair_type', 'dms_project_type', 'dms_material_type'],
data() {
return {
isView: false,
workOrderId: null,
deviceList: [],
form: {
workOrderId: null,
workOrderCode: null,
faultInstanceId: null,
deviceId: null,
deviceCode: null,
deviceName: null,
faultType: null,
faultDescription: null,
repairType: null,
priority: '3',
planStartTime: null,
planEndTime: null,
repairNotes: null,
needShutdown: '0',
budgetCost: 0,
repairHours: 0,
repairProjects: [],
repairMaterials: []
},
rules: {
deviceId: [
{ required: true, message: '请选择设备', trigger: 'change' }
],
faultType: [
{ required: true, message: '请选择故障类型', trigger: 'change' }
],
repairType: [
{ required: true, message: '请选择维修类型', trigger: 'change' }
],
priority: [
{ required: true, message: '请选择优先级', trigger: 'change' }
]
}
}
},
created() {
const workOrderIdParam = this.$route.params && this.$route.params.workOrderId
this.workOrderId = workOrderIdParam && workOrderIdParam !== 'new' ? workOrderIdParam : null
this.isView = this.$route.query.view === 'true'
this.loadDeviceList()
if (this.workOrderId) {
this.loadData()
}
},
methods: {
/** 加载设备列表 */
loadDeviceList() {
getDeviceLedgerList({}).then(response => {
this.deviceList = response.data || response.rows || []
})
},
/** 加载数据 */
loadData() {
getRepairWorkOrder(this.workOrderId).then(response => {
Object.assign(this.form, response.data)
if (!this.form.repairProjects) this.form.repairProjects = []
if (!this.form.repairMaterials) this.form.repairMaterials = []
})
},
/** 设备改变 */
handleDeviceChange(val) {
const device = this.deviceList.find(d => (d.objId || d.deviceId) === val)
if (device) {
this.form.deviceId = device.objId || device.deviceId
this.form.deviceCode = device.deviceCode
this.form.deviceName = device.deviceName
}
},
/** 选择故障报修 */
selectFaultInstance() {
if (this.isView) return
this.$message.info('功能开发中...')
},
/** 添加工程 */
handleAddProject() {
this.form.repairProjects.push({
projectSeq: this.form.repairProjects.length + 1,
projectName: null,
projectType: null,
projectContent: null,
technicalRequirement: null,
planHours: 0,
executionStatus: '0'
})
},
/** 删除工程 */
handleDeleteProject(index) {
this.form.repairProjects.splice(index, 1)
},
/** 添加材料 */
handleAddMaterial() {
this.form.repairMaterials.push({
materialCode: null,
materialName: null,
materialSpec: null,
materialType: null,
unit: null,
planQuantity: 0,
unitPrice: 0,
totalAmount: 0,
receiveStatus: '0'
})
},
/** 删除材料 */
handleDeleteMaterial(index) {
this.form.repairMaterials.splice(index, 1)
},
/** 计算金额 */
calculateAmount(row) {
const amount = (row.planQuantity || 0) * (row.unitPrice || 0)
row.totalAmount = amount
return amount.toFixed(2)
},
/** 提交表单 */
handleSubmit() {
this.$refs.form.validate((valid) => {
if (valid) {
if (this.form.workOrderId) {
updateRepairWorkOrder(this.form).then(() => {
this.$modal.msgSuccess('修改成功')
this.goBack()
})
} else {
addRepairWorkOrder(this.form).then(() => {
this.$modal.msgSuccess('新增成功')
this.goBack()
})
}
}
})
},
/** 返回 */
goBack() {
this.$router.back()
}
}
}
</script>
<style scoped>
.repair-work-order-detail .card-title {
font-weight: bold;
font-size: 14px;
}
.footer-buttons {
text-align: center;
padding: 20px 0;
}
</style>

@ -0,0 +1,388 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="88px">
<el-form-item label="工单编号" prop="workOrderCode">
<el-input
v-model="queryParams.workOrderCode"
placeholder="请输入工单编号"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="设备名称" prop="deviceName">
<el-input
v-model="queryParams.deviceName"
placeholder="请输入设备名称"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="工单状态" prop="orderStatus">
<el-select v-model="queryParams.orderStatus" placeholder="请选择工单状态" clearable>
<el-option
v-for="dict in dict.type.dms_work_order_status"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="维修类型" prop="repairType">
<el-select v-model="queryParams.repairType" placeholder="请选择维修类型" clearable>
<el-option
v-for="dict in dict.type.dms_repair_type"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="执行人" prop="executorName">
<el-input
v-model="queryParams.executorName"
placeholder="请输入执行人"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery"></el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery"></el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['dms:repairWorkOrder:add']"
>新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="success"
plain
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
v-hasPermi="['dms:repairWorkOrder:edit']"
>修改</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['dms:repairWorkOrder:remove']"
>删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['dms:repairWorkOrder:export']"
>导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="repairWorkOrderList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="工单编号" align="center" prop="workOrderCode" width="160" />
<el-table-column label="设备名称" align="center" prop="deviceName" show-overflow-tooltip />
<el-table-column label="故障类型" align="center" prop="faultType" width="100">
<template slot-scope="scope">
<dict-tag :options="dict.type.dms_fault_type" :value="scope.row.faultType"/>
</template>
</el-table-column>
<el-table-column label="维修类型" align="center" prop="repairType" width="120">
<template slot-scope="scope">
<dict-tag :options="dict.type.dms_repair_type" :value="scope.row.repairType"/>
</template>
</el-table-column>
<el-table-column label="工单状态" align="center" prop="orderStatus" width="100">
<template slot-scope="scope">
<dict-tag :options="dict.type.dms_work_order_status" :value="scope.row.orderStatus"/>
</template>
</el-table-column>
<el-table-column label="优先级" align="center" prop="priority" width="80">
<template slot-scope="scope">
<dict-tag :options="dict.type.dms_priority" :value="scope.row.priority"/>
</template>
</el-table-column>
<el-table-column label="执行人" align="center" prop="executorName" width="100" />
<el-table-column label="计划开始" align="center" prop="planStartTime" width="160">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.planStartTime, '{y}-{m}-{d} {h}:{i}') }}</span>
</template>
</el-table-column>
<el-table-column label="计划完成" align="center" prop="planEndTime" width="160">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.planEndTime, '{y}-{m}-{d} {h}:{i}') }}</span>
</template>
</el-table-column>
<el-table-column label="工程数" align="center" prop="projectCount" width="80" />
<el-table-column label="材料数" align="center" prop="materialCount" width="80" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="220">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-view"
@click="handleView(scope.row)"
v-hasPermi="['dms:repairWorkOrder:query']"
>查看</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['dms:repairWorkOrder:edit']"
>编辑</el-button>
<el-button
v-if="scope.row.orderStatus === '0'"
size="mini"
type="text"
@click="handleDispatch(scope.row)"
v-hasPermi="['dms:repairWorkOrder:dispatch']"
>派工</el-button>
<el-button
v-if="scope.row.orderStatus === '1'"
size="mini"
type="text"
@click="handleStart(scope.row)"
v-hasPermi="['dms:repairWorkOrder:start']"
>开始</el-button>
<el-button
v-if="scope.row.orderStatus === '2'"
size="mini"
type="text"
@click="handleComplete(scope.row)"
v-hasPermi="['dms:repairWorkOrder:complete']"
>完成</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 派工对话框 -->
<el-dialog title="派工" :visible.sync="dispatchDialogVisible" width="500px" append-to-body>
<el-form ref="dispatchForm" :model="dispatchForm" label-width="100px">
<el-form-item label="工单编号">
<el-input v-model="dispatchForm.workOrderCode" disabled />
</el-form-item>
<el-form-item label="设备名称">
<el-input v-model="dispatchForm.deviceName" disabled />
</el-form-item>
<el-form-item label="派工类型" prop="dispatchType">
<el-radio-group v-model="dispatchForm.dispatchType">
<el-radio label="1">单人派工</el-radio>
<el-radio label="2">团队派工</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="执行人" prop="executorId" v-if="dispatchForm.dispatchType === '1'">
<el-select v-model="dispatchForm.executorId" placeholder="请选择执行人" filterable style="width: 100%">
<el-option v-for="u in userOptions" :key="u.userId" :label="u.nickName || u.userName" :value="u.userId" />
</el-select>
</el-form-item>
<el-form-item label="执行团队" prop="teamId" v-if="dispatchForm.dispatchType === '2'">
<el-select v-model="dispatchForm.teamId" placeholder="请选择执行团队" filterable style="width: 100%">
<el-option v-for="t in teamOptions" :key="t.teamId" :label="t.teamName" :value="t.teamId" />
</el-select>
</el-form-item>
<el-form-item label="要求开始时间">
<el-date-picker
v-model="dispatchForm.requireStartTime"
type="datetime"
placeholder="选择日期时间"
value-format="yyyy-MM-dd HH:mm:ss"
style="width: 100%"
/>
</el-form-item>
<el-form-item label="要求完成时间">
<el-date-picker
v-model="dispatchForm.requireEndTime"
type="datetime"
placeholder="选择日期时间"
value-format="yyyy-MM-dd HH:mm:ss"
style="width: 100%"
/>
</el-form-item>
<el-form-item label="派工说明">
<el-input v-model="dispatchForm.dispatchNotes" type="textarea" :rows="3" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dispatchDialogVisible = false"> </el-button>
<el-button type="primary" @click="submitDispatch"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { listRepairWorkOrder, getRepairWorkOrder, delRepairWorkOrder, dispatchWorkOrder, startWorkOrder, completeWorkOrder } from '@/api/dms/repairWorkOrder'
import { selectUserList } from '@/api/system/user'
export default {
name: 'RepairWorkOrder',
dicts: ['dms_work_order_status', 'dms_repair_type', 'dms_fault_type', 'dms_priority'],
data() {
return {
loading: true,
ids: [],
single: true,
multiple: true,
showSearch: true,
total: 0,
repairWorkOrderList: [],
queryParams: {
pageNum: 1,
pageSize: 10,
workOrderCode: null,
deviceName: null,
orderStatus: null,
repairType: null,
executorName: null
},
dispatchDialogVisible: false,
dispatchForm: {
workOrderId: null,
workOrderCode: null,
deviceName: null,
dispatchType: '1',
executorId: null,
teamId: null,
requireStartTime: null,
requireEndTime: null,
dispatchNotes: null
},
userOptions: [],
teamOptions: []
}
},
created() {
this.getList()
this.loadUserList()
},
methods: {
/** 查询列表 */
getList() {
this.loading = true
listRepairWorkOrder(this.queryParams).then(response => {
this.repairWorkOrderList = response.rows
this.total = response.total
this.loading = false
})
},
/** 加载用户列表 */
loadUserList() {
selectUserList({}).then(res => {
this.userOptions = (res && res.rows && res.rows.length ? res.rows : res.data) || []
})
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm('queryForm')
this.handleQuery()
},
/** 多选框选中数据 */
handleSelectionChange(selection) {
this.ids = selection.map(item => item.workOrderId)
this.single = selection.length !== 1
this.multiple = !selection.length
},
/** 新增按钮操作 */
handleAdd() {
this.$router.push('/dms/repairWorkOrder/detail/new')
},
/** 修改按钮操作 */
handleUpdate(row) {
const workOrderId = row.workOrderId || this.ids[0]
this.$router.push('/dms/repairWorkOrder/detail/' + workOrderId)
},
/** 查看按钮操作 */
handleView(row) {
this.$router.push({
path: '/dms/repairWorkOrder/detail/' + row.workOrderId,
query: { view: 'true' }
})
},
/** 派工 */
handleDispatch(row) {
this.dispatchForm = {
workOrderId: row.workOrderId,
workOrderCode: row.workOrderCode,
deviceName: row.deviceName,
dispatchType: '1',
executorId: null,
teamId: null,
requireStartTime: null,
requireEndTime: null,
dispatchNotes: null
}
this.dispatchDialogVisible = true
},
/** 提交派工 */
submitDispatch() {
dispatchWorkOrder(this.dispatchForm).then(() => {
this.$modal.msgSuccess('派工成功')
this.dispatchDialogVisible = false
this.getList()
})
},
/** 开始维修 */
handleStart(row) {
this.$modal.confirm('是否确认开始维修工单"' + row.workOrderCode + '"').then(() => {
return startWorkOrder({ workOrderId: row.workOrderId })
}).then(() => {
this.getList()
this.$modal.msgSuccess('操作成功')
}).catch(() => {})
},
/** 完成维修 */
handleComplete(row) {
this.$router.push('/dms/repairWorkOrder/complete/' + row.workOrderId)
},
/** 删除按钮操作 */
handleDelete(row) {
const workOrderIds = row.workOrderId || this.ids
this.$modal.confirm('是否确认删除选中的维修工单?').then(() => {
return delRepairWorkOrder(workOrderIds)
}).then(() => {
this.getList()
this.$modal.msgSuccess('删除成功')
}).catch(() => {})
},
/** 导出按钮操作 */
handleExport() {
this.download('dms/repairWorkOrder/export', {
...this.queryParams
}, `repairWorkOrder_${new Date().getTime()}.xlsx`)
}
}
}
</script>
Loading…
Cancel
Save