| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571 |
- <template>
- <!-- 下发对话框 -->
- <el-dialog title="下发" v-model="visible" width="800px" append-to-body @close="cancel">
- <div style="max-height: 500px; overflow-y: auto; padding-right: 10px;">
- <el-form ref="orderRef" :model="form" :rules="rules" label-width="120px" label-position="top">
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="工单编码" prop="workOrderProjectNo">
- <el-input v-model="form.workOrderProjectNo" placeholder="自动生成" maxlength="50" show-word-limit v-chinese-limit readonly/>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="风机编号" prop="pcsDeviceName">
- <el-input v-model="form.pcsDeviceName" readonly>
- <template #append>
- <el-button @click="handleSelectEquipment" icon="Search"></el-button>
- </template>
- </el-input>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="维保中心" prop="gxtCenter">
- <el-input v-model="form.gxtCenter" readonly />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="场站" prop="pcsStationName">
- <el-input v-model="form.pcsStationName" readonly />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="品牌" prop="brand">
- <el-input v-model="form.brand" readonly />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="机型" prop="model">
- <el-input v-model="form.model" readonly />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="信息录入" prop="infoEntry">
- <el-radio-group v-model="form.infoEntry" @change="handleInfoEntryChange">
- <el-radio
- v-for="dict in infoEntryOptions"
- :key="dict.value"
- :label="dict.value"
- >
- {{ dict.label }}
- </el-radio>
- </el-radio-group>
- </el-form-item>
- </el-col>
- <el-col :span="12" v-if="form.infoEntry == '1'">
- <el-form-item label="MIS工单编码" prop="misNo">
- <el-input v-model="form.misNo"
- placeholder="请输入MIS工单编码或点击搜索选择"
- clearable
- @focus="handleMisNoInputFocus"
- @blur="handleMisNoInputBlur"
- @input="handleMisNoInput"
- @clear="handleMisNoClear"
- >
- <template #append>
- <el-button @click="handleSelectMisInfo" icon="Search"></el-button>
- </template>
- </el-input>
- <!-- 快速检索下拉框 -->
- <div class="quick-select-dropdown" v-show="showMisNoQuickSelect && quickMisNoList.length > 0">
- <div
- v-for="item in quickMisNoList"
- :key="item.misNo"
- class="quick-select-item"
- @click="handleMisNoQuickSelect(item)">
- <span class="mis-no">{{ item.misNo }}</span>
- <!-- <span class="mis-info">-->
- <!-- <span class="device">{{ item.pcsDeviceName }}</span>-->
- <!-- <span class="station">{{ item.pcsStationName }}</span>-->
- <!-- </span>-->
- </div>
- </div>
- <div class="quick-select-dropdown no-data" v-show="showMisNoQuickSelect && quickMisNoList.length === 0 && form.misNo">
- <div>未找到匹配的MIS工单</div>
- </div>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="工作票编号" prop="workPermitNum">
- <el-input v-model="workPermitNumProxy" maxlength="20" show-word-limit />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="24">
- <el-form-item label="维保内容" prop="content" :required="form.infoEntry == '2'">
- <el-input v-model="form.content" type="textarea" :rows="3" :readonly="form.infoEntry == '1'" maxlength="500" show-word-limit />
- </el-form-item>
- </el-col>
- </el-row>
- </el-form>
- </div>
- <template #footer>
- <div class="dialog-footer">
- <el-button @click="cancel">取 消</el-button>
- <el-button type="primary" @click="submitForm('assigned')">确认下发</el-button>
- </div>
- </template>
- </el-dialog>
- <!-- MIS选择组件 -->
- <MisInfoSelectSingle :key="commonKey" v-model="misInfoSelectVisible" @onSelected="onMisInfoSelected" :pcsStationName="form.pcsStationName" :pcsDeviceName="form.pcsDeviceName"></MisInfoSelectSingle>
- <!-- 设备选择对话框 -->
- <equipment-select
- v-model="equipmentSelectVisible"
- @onSelected="onEquipmentSelected"
- />
- </template>
- <script setup>
- import {ref, reactive, nextTick, watch, getCurrentInstance, defineProps} from 'vue';
- import EquipmentSelect from '@/components/equipmentSelect/single.vue'; // 根据实际情况调整路径
- import {getOrderList, listGxtOrder, updateGxtOrder} from '@/api/gxt/gxtOrder';
- import {listMisInfo} from "@/api/gxt/misInfo.js";
- import MisInfoSelectSingle from "@/components/misInfoSelect/single.vue";
- // 获取当前实例
- const { proxy } = getCurrentInstance()
- // 定义组件属性
- const props = defineProps({
- modelValue: {
- type: Boolean,
- default: false
- },
- data: {
- type: Object,
- default: () => ({})
- },
- // 信息录入方式
- infoEntryOptions: {
- type: Array,
- default: () => ([])
- },
- // commonKey: {
- // type: Number,
- // default: 0
- // }
- });
- // 定义事件
- const emit = defineEmits(['update:modelValue', 'success']);
- // 响应式数据
- const visible = ref(false);
- const orderRef = ref()
- const form = ref({});
- const equipmentSelectVisible = ref(false);
- const misInfoSelectVisible = ref(false)
- let commonKey = 0
- // 表单验证规则
- const rules = ref({
- misNo: [{ required: true, message: "MIS编码不能为空", trigger: "change" }],
- pcsDeviceName: [
- { required: true, message: "风机编号不能为空", trigger: "change" }
- ],
- inspectionType: [
- { required: true, message: "请选择维保类型", trigger: "change" }
- ],
- content: [
- { required: true, message: "维保内容不能为空", trigger: "blur" },
- { max: 500, message: "维保内容长度不能超过500个字符", trigger: "blur" }
- ],
- workPermitNum: [
- { required: true, message: "工作票编号不能为空", trigger: "change" },
- {
- validator: (rule, value, callback) => {
- if (form.value.infoEntry == '2') {
- if (!value) {
- callback(new Error('工作票编号不能为空'))
- } else if (!/^[a-zA-Z0-9_\-\.]*$/.test(value)) {
- callback(new Error('仅支持英文、数字、下划线'))
- } else if (value.length > 20) {
- callback(new Error('不能超过20个字符'))
- } else {
- // 验证唯一性
- if (value) {
- listGxtOrder({pageNum: 1, pageSize: 10, workPermitNum: value}).then(response => {
- const gxtOrders = response.rows
- if (gxtOrders.length > 0) {
- if (form.value.id == null) {
- callback(new Error('工作票编号已存在!'))
- } else {
- if (gxtOrders[0].id != form.value.id) {
- callback(new Error('工作票编号已存在!'))
- } else {
- callback()
- }
- }
- } else {
- callback()
- }
- })
- } else {
- callback()
- }
- }
- } else {
- callback()
- }
- },
- trigger: 'blur'
- }
- ],
- });
- // 监听modelValue变化
- watch(() => props.modelValue, (val) => {
- visible.value = val
- if (val) {
- // 初始化表单数据
- form.value = { ...props.data, selectedMembers: [] }
- commonKey++
- }
- })
- // 监听visible变化
- watch(visible, (val) => {
- emit('update:modelValue', val)
- if (val) {
- // 打开对话框后重置表单验证错误
- proxy.$nextTick(() => {
- if (orderRef.value) {
- orderRef.value.clearValidate()
- }
- })
- }
- })
- // 重置表单
- function reset() {
- form.value = {};
- // 重置验证
- nextTick(() => {
- const orderRef = getCurrentInstance()?.refs?.orderRef;
- if (orderRef && orderRef.resetFields) {
- orderRef.resetFields();
- }
- });
- }
- // 取消操作
- function cancel() {
- visible.value = false;
- }
- // 提交表单
- async function submitForm(status) {
- if (!orderRef.value) return
- await orderRef.value.validate((valid) => {
- if (valid) {
- form.value.workOrderStatus = status;
- form.value.inspectionType = Array.isArray(form.value.inspectionType) ? form.value.inspectionType.join(',')
- : form.value.inspectionType || ''
- updateGxtOrder(form.value).then(response => {
- proxy.$modal.msgSuccess("下发成功")
- visible.value = false;
- emit('success');
- }).catch(error => {
- });
- }
- });
- }
- // 设备选择相关方法
- function handleSelectEquipment() {
- equipmentSelectVisible.value = true;
- }
- function onEquipmentSelected(row) {
- if (row) {
- // 检查维保中心ID和场站ID是否存在
- if (!row.maintenanceCenterId) {
- proxy.$modal.msgError("该设备的维保中心没有对应的部门,请完善部门信息后再更新设备数据!");
- return;
- }
- if (!row.stationId) {
- proxy.$modal.msgError("该设备的场站没有对应的部门,请完善部门信息后再更新设备数据!");
- return;
- }
- // 更新表单中的设备信息
- form.value.pcsDeviceId = row.equipmentId
- form.value.pcsDeviceName = row.equipmentCode
- form.value.gxtCenterId = row.maintenanceCenterId
- form.value.gxtCenter = row.maintenanceCenter
- form.value.pcsStationId = row.stationId
- form.value.pcsStationName = row.station
- form.value.brand = row.brand
- form.value.model = row.model
- }
- equipmentSelectVisible.value = false;
- commonKey++
- }
- function handleSelectMisInfo() {
- misInfoSelectVisible.value = true
- }
- // MIS工单快速检索相关响应式数据
- const showMisNoQuickSelect = ref(false)
- const quickMisNoList = ref([])
- const misNoLoading = ref(false)
- const misNoSearchTimer = ref(null)
- // 快速检索方法
- /** MIS工单编码输入框获取焦点 */
- const handleMisNoInputFocus = () => {
- showMisNoQuickSelect.value = true
- // 如果已有输入内容,立即搜索
- if (form.misNo && form.misNo.trim()) {
- handleMisNoInput(form.misNo)
- }
- }
- /** MIS工单编码输入框失去焦点 */
- const handleMisNoInputBlur = () => {
- // 延迟隐藏下拉框,确保点击选项能触发
- setTimeout(() => {
- showMisNoQuickSelect.value = false
- }, 200)
- }
- /** MIS工单编码输入事件 - 实时搜索 */
- const handleMisNoInput = (value) => {
- const searchText = value.trim()
- if (!searchText) {
- quickMisNoList.value = []
- showMisNoQuickSelect.value = false
- return
- }
- showMisNoQuickSelect.value = true
- // 清除之前的定时器
- if (misNoSearchTimer.value) {
- clearTimeout(misNoSearchTimer.value)
- }
- // 设置新的定时器,防抖处理(500ms)
- misNoSearchTimer.value = setTimeout(() => {
- searchMisNoList(searchText)
- }, 500)
- }
- /** 搜索MIS工单列表 */
- const searchMisNoList = async (keyword) => {
- if (!keyword) {
- quickMisNoList.value = []
- return
- }
- misNoLoading.value = true
- try {
- const response = await listMisInfo({
- pageNum: 1,
- // pageSize: 10, // 只显示前10条结果
- misNo: keyword,
- pcsDeviceName: form.value.pcsDeviceName,
- // pcsStationName: keyword
- // 注意:这里假设后端API支持这些字段的模糊查询
- // 如果后端不支持多字段同时查询,可能需要调整
- })
- quickMisNoList.value = response.rows || []
- // 如果没有找到结果,可以尝试更宽松的搜索
- if (quickMisNoList.value.length === 0 && keyword.length >= 2) {
- // 可以尝试只按MIS工单编码搜索
- const retryResponse = await listMisInfo({
- pageNum: 1,
- // pageSize: 10,
- misNo: keyword
- })
- quickMisNoList.value = retryResponse.rows || []
- }
- } catch (error) {
- console.error('搜索MIS工单失败:', error)
- proxy.$modal.msgError('搜索失败,请重试')
- quickMisNoList.value = []
- } finally {
- misNoLoading.value = false
- }
- }
- /** 快速选择MIS工单 */
- const handleMisNoQuickSelect = (item) => {
- onMisInfoSelected(item)
- showMisNoQuickSelect.value = false
- }
- /** 清空MIS工单编码 */
- const handleMisNoClear = () => {
- // 清空与MIS工单相关的字段
- form.value.misNo = null
- form.value.content = null
- form.value.workPermitNum = null
- // form.value.pcsDeviceName = null
- // form.value.pcsStationName = null
- // form.value.pcsDeviceId = null
- // form.value.gxtCenter = null
- // form.value.brand = null
- // form.value.model = null
- quickMisNoList.value = []
- showMisNoQuickSelect.value = false
- }
- const handleInfoEntryChange = (val) => {
- form.value.content = undefined;
- // 选中2工作票编号时修改其他值
- if (val === '2') {
- form.value.misOrderNo = undefined;
- form.value.realStartTime = undefined;
- form.value.realEndTime = undefined;
- } else {
- form.value.workPermitNum = undefined;
- }
- };
- // 计算属性:双向绑定代理
- const workPermitNumProxy = computed({
- get() {
- return form.value.workPermitNum
- },
- set(val) {
- // 1. 去掉首尾空格
- let trimmed = val.trim()
- // 2. 只保留允许的字符:中文、英文字母、数字、下划线
- // 如果你希望更宽松(比如允许横杠 -),可调整正则
- trimmed = trimmed.replace(/[^a-zA-Z0-9_\-\.]/g, '')
- // 3. 截断到 20 个字符(按字符数,不是字节)
- if (trimmed.length > 20) {
- trimmed = trimmed.substring(0, 20)
- }
- // 4. 写回表单
- form.value.workPermitNum = trimmed
- }
- })
- /** 设备MIS信息回调 */
- function onMisInfoSelected(row) {
- if (row) {
- // listGxtOrder({pageNum: 1, pageSize: 10, misNo: row.misNo }).then(response => {
- getOrderList(row.misNo).then(response => {
- const gxtOrders= response.rows
- debugger
- if (gxtOrders.length > 0) {
- if (form.value.id == null) {
- proxy.$modal.msgWarning('选择工单已存在!请重新选择!')
- return
- } else {
- if (gxtOrders[0].id != form.value.id) {
- proxy.$modal.msgWarning('选择工单已存在!请重新选择!')
- return
- }
- }
- }
- form.value.misNo = row.misNo
- form.value.content = row.content
- form.value.realStartTime = row.realStartTime
- form.value.realEndTime = row.realEndTime
- form.value.workPermitNum = row.workPermitNum
- // form.value.planStartTime = row.planStartTime
- // form.value.planEndTime = row.planEndTime
- if (!form.value.pcsDeviceId) {
- form.value.pcsDeviceName = row.pcsDeviceName
- form.value.pcsStationName = row.pcsStationName
- listEquipment({station: row.pcsStationName, equipmentCode: row.pcsDeviceName}).then(response => {
- const equipments = response.rows
- if (equipments) {
- form.value.pcsDeviceId = equipments[0].equipmentId
- form.value.gxtCenter = equipments[0].maintenanceCenter
- form.value.brand = equipments[0].brand
- form.value.model = equipments[0].model
- }
- });
- }
- misInfoSelectVisible.value = false
- })
- }
- }
- defineExpose({
- visible,
- form,
- reset,
- submitForm
- });
- </script>
- <style scoped>
- .quick-select-dropdown {
- position: absolute;
- top: calc(100% + 2px);
- left: 0;
- right: 0;
- background: #fff;
- border: 1px solid #dcdfe6;
- border-radius: 4px;
- max-height: 200px;
- overflow-y: auto;
- z-index: 1000;
- box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
- }
- .quick-select-item {
- padding: 8px 12px;
- cursor: pointer;
- transition: background-color 0.2s;
- }
- .quick-select-item:hover {
- background-color: #f5f7fa;
- }
- .quick-select-item .mis-no {
- display: inline-block;
- margin-right: 10px;
- font-weight: bold;
- color: #409eff;
- }
- .quick-select-item .mis-info {
- display: flex;
- flex-direction: column;
- align-items: flex-end;
- flex: 1;
- margin-left: 10px;
- }
- .quick-select-item .mis-info .device {
- color: #606266;
- font-size: 12px;
- margin-bottom: 2px;
- }
- .quick-select-item .mis-info .station {
- color: #909399;
- font-size: 11px;
- }
- .no-data {
- text-align: center;
- color: #909399;
- padding: 10px;
- }
- /* 输入框样式调整 */
- :deep(.el-input-group__append) {
- background-color: #409eff;
- border-color: #409eff;
- color: white;
- }
- </style>
|