Merge remote-tracking branch 'origin/master'

master
suixy 2 months ago
commit f9eec1e421

@ -337,6 +337,16 @@ export interface QcInspectionMainQuery extends PageQuery {
*/
inspectionType?: number | string;
/**
*
*/
qcInspectionType?: string;
/**
*
*/
qcInspectionTypes?: string[];
/**
* 0/1
*/

@ -64,6 +64,10 @@ export interface QcInspectionTemplateVO {
*/
description: string;
/**
* 0/1
*/
isDefault: string;
/**
@ -150,7 +154,10 @@ export interface QcInspectionTemplateForm extends BaseEntity {
*/
description?: string;
/**
* 0/1
*/
isDefault?: string;
/**
*
@ -236,6 +243,10 @@ export interface QcInspectionTemplateQuery extends PageQuery {
*/
description?: string;
/**
* 0/1
*/
isDefault?: string;
/**
*

@ -0,0 +1,604 @@
<template>
<div class="p-2">
<!-- 操作按钮区域 -->
<el-card shadow="never">
<div style="display: flex; justify-content: space-between">
<div>
<!-- 移除提交按钮Web端不再创建工单 -->
<el-button
v-if="approvalButtonShow"
:loading="buttonLoading"
type="primary"
@click="approvalVerifyOpen">
{{ currentStepName }}
</el-button>
<el-button
v-if="confirmButtonShow"
:loading="buttonLoading"
type="success"
@click="handleConfirm">
主管确认
</el-button>
<el-button
v-if="workOrder?.wfDefinitionId"
type="primary"
@click="handleApprovalRecord">
流程进度
</el-button>
</div>
<div>
<el-button @click="goBack()"></el-button>
</div>
</div>
</el-card>
<!-- 工单基本信息区域 -->
<el-card shadow="never" class="mb-[10px]">
<h4 class="form-header">工单基本信息</h4>
<el-form label-width="120px">
<el-row>
<el-col :span="8">
<el-form-item label="工单编号">
<el-input :value="workOrder?.billsFaultCode || ''" disabled />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="工单状态">
<el-input v-model="workOrderStatusText" disabled />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="申请人">
<el-input :value="workOrder?.applyUser || ''" disabled />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="8">
<el-form-item label="设备编号">
<el-input :value="workOrder?.machineCode || ''" disabled />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="设备名称">
<el-input :value="workOrder?.machineName || ''" disabled />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="申请时间">
<el-input :value="workOrder?.applyTime || ''" disabled />
</el-form-item>
</el-col>
</el-row>
</el-form>
</el-card>
<!-- PDA端创建的工单详情只读显示 -->
<el-card shadow="never">
<h4 class="form-header">PDA端创建的工单详情只读</h4>
<el-form
ref="processFormRef"
v-loading="loading"
:model="form"
:rules="rules"
label-width="120px">
<el-row>
<!-- 故障报修信息只读显示 -->
<el-col :span="8">
<el-form-item label="故障类型">
<el-input v-model="form.faultType" disabled />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="维修类型">
<el-input v-model="form.repairType" disabled />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="外协单位">
<el-input v-model="outsourcingName" disabled />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="故障描述">
<el-input
v-model="form.faultDescription"
type="textarea"
:rows="3"
disabled />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="涉及操作">
<el-input
v-model="form.designOperations"
type="textarea"
:rows="2"
disabled />
</el-form-item>
</el-col>
<!-- 维修处理信息只读显示 -->
<template v-if="form.repairer">
<el-col :span="8">
<el-form-item label="维修人">
<el-input v-model="form.repairer" disabled />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="检查后的故障判断">
<el-input
v-model="form.checkedFault"
type="textarea"
:rows="3"
disabled />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="维修措施">
<el-input
v-model="form.protectedMethod"
type="textarea"
:rows="3"
disabled />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="维修内容">
<el-input
v-model="form.repairContent"
type="textarea"
:rows="4"
disabled />
</el-form-item>
</el-col>
</template>
<!-- 审批状态选择仅在审批阶段显示 -->
<el-col :span="8" v-if="isApprovalStage">
<el-form-item label="审批状态" prop="approveStatus">
<el-select v-model="form.approveStatus" placeholder="请选择审批状态">
<el-option
v-for="dict in dms_approve_status"
:key="dict.value"
:label="dict.label"
:value="dict.value"
:disabled="dict.value === '1'">
</el-option>
</el-select>
</el-form-item>
</el-col>
<!-- 处理意见审批时需要 -->
<el-col :span="24" v-if="needProcessResolution">
<el-form-item label="处理意见" prop="processHandleResolution">
<el-input
v-model="form.processHandleResolution"
type="textarea"
:rows="3"
placeholder="请输入处理意见" />
</el-form-item>
</el-col>
</el-row>
</el-form>
</el-card>
<!-- 审批组件 -->
<submitVerify
ref="submitVerifyRef"
:task-variables="taskVariables"
@submit-callback="submitCallback" />
<!-- 审批记录组件 -->
<approvalRecord ref="approvalRecordRef" />
</div>
</template>
<script setup name="FaultWorkOrderProcess" lang="ts">
//
import { ref, reactive, computed, onMounted, getCurrentInstance, toRefs } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { ElMessageBox, type FormInstance } from 'element-plus';
import type { ComponentInternalInstance } from 'vue';
import { getDmsBillsFaultInstance, approveWorkOrder, confirmRepairResult } from '@/api/dms/dmsBillsFaultInstance';
import { getDmsBaseOutsourcingInfoList } from '@/api/dms/dmsBaseOutsourcingInfo';
import { pageByTaskWait } from '@/api/workflow/task';
import SubmitVerify from '@/views/dms/dmsFaultInstanceActivity/submitVerify.vue';
import ApprovalRecord from '@/components/Process/approvalRecord.vue';
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const { fault_repair_type, activity_fault_type, fault_repair_confirm, dms_approve_status } = toRefs<any>(proxy?.useDict('fault_repair_type', 'activity_fault_type', 'fault_repair_confirm', 'dms_approve_status'));
const route = useRoute();
const router = useRouter();
//
const loading = ref(true);
const buttonLoading = ref(false);
const routeParams = ref<Record<string, any>>({});
const workOrder = ref<any>({});
const workOrderStatusText = ref('');
const outsourceList = ref<any[]>([]);
const outsourcingName = ref('');
//
const processFormRef = ref<FormInstance>();
const submitVerifyRef = ref<InstanceType<typeof SubmitVerify>>();
const approvalRecordRef = ref<InstanceType<typeof ApprovalRecord>>();
//
const taskVariables = ref<any>({});
//
const isCurrentUserTaskAssignee = ref(false);
//
const initFormData = {
repairInstanceId: undefined,
faultType: undefined,
faultDescription: undefined,
designOperations: undefined,
repairType: undefined,
outsourcingId: undefined,
checkedFault: undefined,
repairContent: undefined,
protectedMethod: undefined,
repairer: undefined,
repairConfirm: undefined,
componentsPartsId: undefined,
processHandleResolution: undefined,
approveStatus: undefined
};
const form = reactive({ ...initFormData });
//
const rules = reactive({
approveStatus: [{ required: false, message: '审批状态不能为空', trigger: 'change' }],
processHandleResolution: [{ required: false, message: '处理意见不能为空', trigger: 'blur' }]
});
//
const isViewMode = computed(() => {
return routeParams.value.type === 'view';
});
//
const needProcessResolution = computed(() => {
//
if (isViewMode.value) return false;
return isApprovalStage.value || confirmButtonShow.value;
});
const currentStepName = computed(() => {
if (workOrder.value?.approveStatus === '1') {
return '审批工单';
}
return '处理工单';
});
const approvalButtonShow = computed(() => {
//
if (isViewMode.value) return false;
// (1) &&
return workOrder.value?.approveStatus === '1' && isCurrentUserTaskAssignee.value;
});
const confirmButtonShow = computed(() => {
//
console.log('主管确认按钮显示条件检查:', {
billsStatus: workOrder.value?.billsStatus,
billsStatusType: typeof workOrder.value?.billsStatus,
approveStatus: workOrder.value?.approveStatus,
approveStatusType: typeof workOrder.value?.approveStatus,
repairConfirm: workOrder.value?.repairConfirm,
repairConfirmType: typeof workOrder.value?.repairConfirm
});
//
// (2) && (2) && (0)
// 使
const billsStatusMatches = String(workOrder.value?.billsStatus) === '2';
const approveStatusMatches = String(workOrder.value?.approveStatus) === '2';
const repairConfirmMatches = String(workOrder.value?.repairConfirm) === '0';
//
if (isViewMode.value) return false;
//
const shouldShow = billsStatusMatches && approveStatusMatches && repairConfirmMatches && isCurrentUserTaskAssignee.value;
console.log('主管确认按钮显示结果:', {
billsStatusMatches,
approveStatusMatches,
repairConfirmMatches,
isCurrentUserTaskAssignee: isCurrentUserTaskAssignee.value,
shouldShow
});
return shouldShow;
});
//
const isApprovalStage = computed(() => {
if (isViewMode.value) return false;
return workOrder.value?.approveStatus === '1';
});
//
onMounted(async () => {
routeParams.value = route.query;
loading.value = true;
try {
//
await loadWorkOrderInfo();
//
await getOutsourceList();
//
await checkCurrentUserTaskPermission();
//
initializeFormData();
//
setDynamicValidationRules();
} catch (error) {
console.error('初始化失败:', error);
(proxy as any)?.$modal.msgError('加载数据失败');
} finally {
loading.value = false;
}
});
//
const checkCurrentUserTaskPermission = async () => {
try {
const businessId = routeParams.value.id;
if (!businessId) {
isCurrentUserTaskAssignee.value = false;
return;
}
//
const taskRes = await pageByTaskWait({
pageNum: 1,
pageSize: 100,
flowCode: 'Fault01' //
});
// ID
const matchingTask = taskRes.rows?.find(
(task: any) => String(task.businessId) === String(businessId)
);
isCurrentUserTaskAssignee.value = !!matchingTask;
console.log('用户任务权限检查:', {
businessId,
hasMatchingTask: !!matchingTask,
isCurrentUserTaskAssignee: isCurrentUserTaskAssignee.value
});
} catch (error) {
console.error('检查用户任务权限失败:', error);
isCurrentUserTaskAssignee.value = false;
}
};
//
const loadWorkOrderInfo = async () => {
// querybusinessId
const businessId = routeParams.value.id;
if (!businessId) {
(proxy as any)?.$modal.msgError('缺少工单ID参数');
return;
}
const res = await getDmsBillsFaultInstance(businessId);
workOrder.value = res.data || {}; // null
// -
workOrderStatusText.value = getStatusText(workOrder.value.billsStatus || '');
};
//
const initializeFormData = () => {
//
form.repairInstanceId = workOrder.value?.repairInstanceId;
// undefined
form.faultType = workOrder.value?.faultType || '';
form.faultDescription = workOrder.value?.faultDescription || '';
form.designOperations = workOrder.value?.designOperations || '';
form.repairType = workOrder.value?.repairType || '';
form.outsourcingId = workOrder.value?.outsourcingId || '';
form.checkedFault = workOrder.value?.checkedFault || '';
form.repairContent = workOrder.value?.repairContent || '';
form.protectedMethod = workOrder.value?.protectedMethod || '';
form.repairer = workOrder.value?.repairer || '';
form.repairConfirm = workOrder.value?.repairConfirm || '';
form.componentsPartsId = workOrder.value?.componentsPartsId || '';
//
if (form.outsourcingId && outsourceList.value.length > 0) {
const outsourcing = outsourceList.value.find(item => item.outsourcingId === form.outsourcingId);
outsourcingName.value = outsourcing?.outsourcingName || '';
}
//
if (routeParams.value.type === 'approval' && !form.approveStatus) {
form.approveStatus = undefined; //
}
};
//
const approvalVerifyOpen = async () => {
if (!processFormRef.value) return;
try {
const valid = await processFormRef.value.validate();
if (valid) {
await (proxy as any)?.$modal.confirm('是否确认提交审批?');
buttonLoading.value = true;
//
const approveStatus = form.approveStatus;
const message = form.processHandleResolution || '';
await approveWorkOrder(form.repairInstanceId, approveStatus, message);
const statusText = approveStatus === '2' ? '通过' : '拒绝';
(proxy as any)?.$modal.msgSuccess(`审批${statusText}成功`);
//
goBack();
}
} catch (error: any) {
if (error !== 'cancel' && error !== 'close') {
console.error('审批失败:', error);
(proxy as any)?.$modal.msgError('审批失败:' + (error.message || '未知错误'));
}
} finally {
buttonLoading.value = false;
}
};
//
const submitCallback = async (approvalResult?: any) => {
try {
if (routeParams.value.type === 'confirm') {
//
const confirmResult = form.repairConfirm || '1'; //
await confirmRepairResult(form.repairInstanceId, confirmResult);
(proxy as any)?.$modal.msgSuccess('确认完成');
}
//
goBack();
} catch (error: any) {
console.error('操作失败:', error);
(proxy as any)?.$modal.msgError('操作失败:' + (error.message || '未知错误'));
}
};
//
const handleConfirm = async () => {
try {
// 使
const result = await ElMessageBox.confirm(
'请选择维修结果确认方式:\n• 通过:维修通过,工单完成\n• 退回:维修不通过,返回维修环节重新维修',
'主管确认',
{
confirmButtonText: '通过',
cancelButtonText: '退回',
type: 'warning',
distinguishCancelAndClose: true
}
);
buttonLoading.value = true;
//
form.repairConfirm = '1'; // 1
//
await confirmRepairResult(form.repairInstanceId, form.repairConfirm);
(proxy as any)?.$modal.msgSuccess('确认通过完成');
goBack();
} catch (action: any) {
if (action === 'cancel') {
// 退
try {
buttonLoading.value = true;
form.repairConfirm = '2'; // 2
await confirmRepairResult(form.repairInstanceId, form.repairConfirm);
(proxy as any)?.$modal.msgSuccess('退回维修环节完成');
goBack();
} catch (confirmError: any) {
console.error('退回操作失败:', confirmError);
(proxy as any)?.$modal.msgError('退回操作失败:' + (confirmError.message || '未知错误'));
} finally {
buttonLoading.value = false;
}
} else if (action === 'close') {
// ESC
console.log('用户取消了确认操作');
} else {
console.error('确认失败:', action);
(proxy as any)?.$modal.msgError('确认失败:' + (action.message || '未知错误'));
}
} finally {
if (form.repairConfirm === '1') {
buttonLoading.value = false;
}
}
};
//
const handleApprovalRecord = () => {
approvalRecordRef.value?.init(routeParams.value.id);
};
//
const goBack = () => {
(proxy as any)?.$tab.closePage((proxy as any)?.$route);
router.go(-1);
};
//
const getOutsourceList = async () => {
try {
const res = await getDmsBaseOutsourcingInfoList(null);
outsourceList.value = res.data;
} catch (error) {
console.error('获取外协单位列表失败:', error);
}
};
//
const setDynamicValidationRules = () => {
//
Object.keys(rules).forEach(key => {
rules[key] = [{ required: false, message: rules[key][0].message, trigger: rules[key][0].trigger }];
});
//
if (workOrder.value?.approveStatus === '1') {
//
rules.approveStatus = [{ required: true, message: '审批状态不能为空', trigger: 'change' }];
rules.processHandleResolution = [{ required: true, message: '处理意见不能为空', trigger: 'blur' }];
} else if (workOrder.value?.billsStatus === '2' &&
workOrder.value?.approveStatus === '2' &&
workOrder.value?.repairConfirm === '0') {
//
rules.processHandleResolution = [{ required: true, message: '处理意见不能为空', trigger: 'blur' }];
}
};
//
const getStatusText = (status: string) => {
const statusMap = {
'0': '待维修',
'1': '维修中',
'2': '维修完成',
'draft': '草稿',
'cancel': '已取消'
};
return statusMap[status] || '未知状态';
};
</script>
<style scoped>
.form-header {
margin-bottom: 16px;
color: #303133;
font-weight: 600;
}
</style>

@ -635,17 +635,25 @@ const inspectionResultDialog = reactive<DialogOption>({
});
//inspectionType = 1 2 3
/**
* 路由参数处理
* - inspectionType=1 产品检测首检=0, 专检=1, 互检=3, 抽检=5, 成品检=6
* - inspectionType=2 原材料检测原材料检=4
* - inspectionType=3 入库检测入库检=7
*/
const inspectionType = ref();
const getInspectionType = async () => {
const route = useRoute();
inspectionType.value = route.query.inspectionType;
if (inspectionType.value == 2){
queryParams.value.inspectionType = '2';
} else if (inspectionType.value == 3){
queryParams.value.inspectionType = '3';
if (inspectionType.value == '2') {
// =4
queryParams.value.qcInspectionType = '4';
} else if (inspectionType.value == '3') {
// =7
queryParams.value.qcInspectionType = '7';
} else {
queryParams.value.inspectionType = '1';
// =0, =1, =3, =5, =6
queryParams.value.qcInspectionTypes = ['0', '1', '3', '5', '6'];
}
};
@ -749,6 +757,8 @@ const data = reactive<PageData<QcInspectionMainForm, QcInspectionMainQuery>>({
result: undefined,
workshop: undefined,
inspectionType: undefined,
qcInspectionType: undefined,
qcInspectionTypes: undefined,
status: undefined,
inspector: undefined,
shift: undefined,
@ -877,8 +887,12 @@ const handleQuery = () => {
/** 重置按钮操作 */
const resetQuery = () => {
queryFormRef.value?.resetFields();
handleQuery();
dateRange.value = [];
//
queryParams.value.qcInspectionType = undefined;
queryParams.value.qcInspectionTypes = undefined;
getInspectionType();
handleQuery();
}
/** 重置子表搜索 */

@ -66,6 +66,12 @@
<el-table-column label="供应商编码" align="center" prop="supplierCode" v-if="columns[10].visible"/>
<el-table-column label="供应商名称" align="center" prop="supplierName" v-if="columns[11].visible"/>
<el-table-column label="模板说明" align="center" prop="description" v-if="columns[12].visible"/>
<el-table-column label="是否通用模板" align="center" prop="isDefault" v-if="columns[13].visible">
<template #default="scope">
<el-tag v-if="scope.row.isDefault === '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">
<template #default="scope">
<el-tooltip content="修改" placement="top">
@ -163,7 +169,7 @@
<el-input v-model="form.templateName" placeholder="请输入模板名称" />
</el-form-item>
<el-form-item label="物料名称" prop="materialName">
<el-input v-model="form.materialName" placeholder="请点击检索物料" @click="handleMaterialAdd" readonly>
<el-input v-model="form.materialName" placeholder="请点击检索物料" @click="handleMaterialAdd" readonly :disabled="form.isDefault === '1'">
<template #append>
<el-icon class="el-input__icon">
<search />
@ -183,7 +189,7 @@
<el-input v-model="form.stationName" placeholder="请输入工位名称" />
</el-form-item> -->
<el-form-item label="工位名称" prop="stationName">
<el-select v-model="selectedStaionId" placeholder="请选择工位" filterable clearable @change="handleBaseStationInfoChange" style="width: 100%;">
<el-select v-model="selectedStaionId" placeholder="请选择工位" filterable clearable @change="handleBaseStationInfoChange" style="width: 100%;" :disabled="form.isDefault === '1'">
<el-option v-for="item in baseStationInfoList" :key="item.stationId" :label="item.stationName" :value="item.stationId" />
</el-select>
</el-form-item>
@ -194,7 +200,7 @@
<el-input v-model="form.processName" placeholder="请输入工序名称" />
</el-form-item> -->
<el-form-item label="工序名称" prop="processName">
<el-select v-model="selectedProcessId" placeholder="请选择工序" filterable clearable @change="handleBaseProcessInfoChange" style="width: 100%;">
<el-select v-model="selectedProcessId" placeholder="请选择工序" filterable clearable @change="handleBaseProcessInfoChange" style="width: 100%;" :disabled="form.isDefault === '1'">
<el-option v-for="item in baseProcessInfoList" :key="item.processId" :label="item.processName" :value="item.processId" />
</el-select>
</el-form-item>
@ -212,6 +218,15 @@
<el-form-item label="模板说明" prop="description">
<el-input v-model="form.description" placeholder="请输入模板说明" />
</el-form-item>
<el-form-item label="是否通用模板" prop="isDefault">
<el-radio-group v-model="form.isDefault">
<el-radio value="0"></el-radio>
<el-radio value="1"></el-radio>
</el-radio-group>
<div style="color: #909399; font-size: 12px; margin-top: 4px;">
通用模板不绑定具体物料工序或工位
</div>
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
@ -456,6 +471,7 @@ const columns = ref<FieldOption[]>([
{ key: 10, label: `供应商编码`, visible: true },
{ key: 11, label: `供应商名称`, visible: true },
{ key: 12, label: `模板说明`, visible: true },
{ key: 13, label: `是否通用模板`, visible: true },
]);
const initFormData: QcInspectionTemplateForm = {
@ -472,6 +488,7 @@ const initFormData: QcInspectionTemplateForm = {
supplierCode: undefined,
supplierName: undefined,
description: undefined,
isDefault: '0',
}
const initTemplateItemFormData: QcTemplateItemForm = {
@ -512,6 +529,7 @@ const data = reactive<PageData<QcInspectionTemplateForm, QcInspectionTemplateQue
supplierCode: undefined,
supplierName: undefined,
description: undefined,
isDefault: undefined,
params: {
}
},
@ -1023,6 +1041,32 @@ const filteredQcInspectionItemList = computed(() => {
});
//
watch(() => form.value.isDefault, (newVal) => {
if (newVal === '1') {
//
form.value.materialCode = '';
form.value.materialName = '';
form.value.stationCode = '';
form.value.stationName = '';
form.value.processCode = '';
form.value.processName = '';
selectedMaterialId.value = null;
selectedStaionId.value = null;
selectedProcessId.value = null;
//
ElMessageBox.alert(
'通用模板只与检测类型绑定,不绑定具体物料、工序或工位。\n勾选后该模板将作为该检测类型的兜底模板只有在其他所有模板都不匹配时才会被使用。',
'业务逻辑说明',
{
confirmButtonText: '我知道了',
type: 'info'
}
);
}
});
onMounted(() => {
getList();
getInspectionTypeList();

Loading…
Cancel
Save