| | |
| | | <span class="info-value">{{ routeInfo.productName || '-' }}</span> |
| | | </div> |
| | | </div> |
| | | <div class="info-item"> |
| | | <div class="info-label-wrapper"> |
| | | <span class="info-label">图纸编号</span> |
| | | </div> |
| | | <div class="info-value-wrapper"> |
| | | <span class="info-value">{{ routeInfo.model || '-' }}</span> |
| | | </div> |
| | | </div> |
| | | <div class="info-item"> |
| | | <div class="info-label-wrapper"> |
| | | <span class="info-label">产品图纸编号</span> |
| | | <span class="info-label">规格型号</span> |
| | | </div> |
| | | <div class="info-value-wrapper"> |
| | | <span class="info-value">{{ routeInfo.drawingNumber || '-' }}</span> |
| | | </div> |
| | | </div> |
| | | <div class="info-item"> |
| | | <div class="info-label-wrapper"> |
| | | <span class="info-label">规格名称</span> |
| | | </div> |
| | | <div class="info-value-wrapper"> |
| | | <span class="info-value">{{ routeInfo.model || '-' }}</span> |
| | | </div> |
| | | </div> |
| | | <div class="info-item"> |
| | |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="产品名称" prop="productName" min-width="160" /> |
| | | <el-table-column label="图纸编号" prop="drawingNumber" min-width="160" /> |
| | | <el-table-column label="规格名称" prop="model" min-width="140" /> |
| | | <el-table-column label="图纸编号" prop="model" min-width="140" /> |
| | | <el-table-column label="规格型号" prop="drawingNumber" min-width="160" /> |
| | | <el-table-column label="单位" prop="unit" width="100" /> |
| | | <el-table-column label="是否质检" prop="isQuality" width="100"> |
| | | <template #default="scope"> |
| | | {{scope.row.isQuality ? "是" : "否"}} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="报工权限" prop="userPower" min-width="200"> |
| | | <template #default="scope"> |
| | | {{ scope.row.userPower || '-' }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="操作" align="center" fixed="right" width="150"> |
| | |
| | | </el-form-item> |
| | | |
| | | <el-form-item label="是否质检" prop="isQuality"> |
| | | <el-switch v-model="form.isQuality" :active-value="true" inactive-value="false"/> |
| | | <el-switch v-model="form.isQuality" :active-value="true" :inactive-value="false"/> |
| | | </el-form-item> |
| | | <el-form-item label="报工权限" prop="userPower" :rules="[{ required: true, message: '请选择报工权限', trigger: 'change' }]"> |
| | | <el-tree-select |
| | | v-model="form.userPower" |
| | | :data="staffList" |
| | | :props="treeProps" |
| | | placeholder="请选择人员" |
| | | multiple |
| | | show-checkbox |
| | | collapse-tags |
| | | collapse-tags-tooltip |
| | | style="width: 100%" |
| | | node-key="id" |
| | | :render-after-expand="false" |
| | | /> |
| | | </el-form-item> |
| | | </el-form> |
| | | |
| | |
| | | import { findProcessRouteItemList, addOrUpdateProcessRouteItem, sortProcessRouteItem, batchDeleteProcessRouteItem } from "@/api/productionManagement/processRouteItem.js"; |
| | | import { findProductProcessRouteItemList, deleteRouteItem, addRouteItem, addOrUpdateProductProcessRouteItem, sortRouteItem } from "@/api/productionManagement/productProcessRoute.js"; |
| | | import { processList } from "@/api/productionManagement/productionProcess.js"; |
| | | import { listDeptUserTree } from "@/api/basicData/productProcess.js"; |
| | | import { useRoute } from 'vue-router' |
| | | import { ElMessageBox } from 'element-plus' |
| | | import Sortable from 'sortablejs' |
| | |
| | | |
| | | const processOptions = ref([]); |
| | | const showProductSelectDialog = ref(false); |
| | | const staffList = ref([]); |
| | | |
| | | const treeProps = { |
| | | label: 'label', |
| | | children: 'children', |
| | | }; |
| | | |
| | | let tableSortable = null; |
| | | let cardSortable = null; |
| | | |
| | |
| | | model: "", |
| | | unit: "", |
| | | isQuality: false, |
| | | userPower: [], |
| | | }); |
| | | |
| | | const rules = { |
| | |
| | | // 编辑 |
| | | const handleEdit = (row) => { |
| | | operationType.value = 'edit'; |
| | | const userPowerNames = row.userPower ? row.userPower.split(',') : []; |
| | | const userPowerIds = userPowerNames.map(name => { |
| | | const user = findUserByName(name); |
| | | return user ? user.id : null; |
| | | }).filter(id => id !== null); |
| | | |
| | | form.value = { |
| | | id: row.id, |
| | | routeId: routeId.value, |
| | |
| | | model: row.model || "", |
| | | unit: row.unit || "", |
| | | isQuality: row.isQuality, |
| | | userPower: userPowerIds, |
| | | }; |
| | | dialogVisible.value = true; |
| | | }; |
| | | |
| | | const findUserByName = (name) => { |
| | | const findInTree = (nodes) => { |
| | | for (const node of nodes) { |
| | | if (node.isUser && node.label === name) { |
| | | return node; |
| | | } |
| | | if (node.children && node.children.length > 0) { |
| | | const found = findInTree(node.children); |
| | | if (found) return found; |
| | | } |
| | | } |
| | | return null; |
| | | }; |
| | | return findInTree(staffList.value); |
| | | }; |
| | | |
| | | // 删除 |
| | |
| | | if (valid) { |
| | | submitLoading.value = true; |
| | | |
| | | const userPowerNames = getAllUserNamesFromSelection(form.value.userPower); |
| | | |
| | | if (operationType.value === 'add') { |
| | | // 新增:传单个对象,包含dragSort字段 |
| | | // dragSort = 当前列表长度 + 1,表示新增记录排在最后 |
| | |
| | | processId: form.value.processId, |
| | | productModelId: form.value.productModelId, |
| | | isQuality: form.value.isQuality, |
| | | userPower: userPowerNames.join(','), |
| | | dragSort, |
| | | }) |
| | | : addOrUpdateProcessRouteItem({ |
| | |
| | | processId: form.value.processId, |
| | | productModelId: form.value.productModelId, |
| | | isQuality: form.value.isQuality, |
| | | userPower: userPowerNames.join(','), |
| | | dragSort, |
| | | }); |
| | | |
| | |
| | | processId: form.value.processId, |
| | | productModelId: form.value.productModelId, |
| | | isQuality: form.value.isQuality, |
| | | userPower: userPowerNames.join(','), |
| | | }) |
| | | : addOrUpdateProcessRouteItem({ |
| | | routeId: routeId.value, |
| | |
| | | productModelId: form.value.productModelId, |
| | | id: form.value.id, |
| | | isQuality: form.value.isQuality, |
| | | userPower: userPowerNames.join(','), |
| | | }); |
| | | |
| | | updatePromise |
| | |
| | | getRouteInfo(); |
| | | getList(); |
| | | getProcessList(); |
| | | getStaffList(); |
| | | }); |
| | | |
| | | const getStaffList = () => { |
| | | listDeptUserTree().then(res => { |
| | | const buildTree = (nodes) => { |
| | | return nodes.map(node => { |
| | | const deptNode = { |
| | | id: `dept_${node.deptId}`, |
| | | label: node.deptName, |
| | | isUser: false, |
| | | children: [] |
| | | }; |
| | | |
| | | if (node.userList && node.userList.length > 0) { |
| | | node.userList.forEach(user => { |
| | | deptNode.children.push({ |
| | | id: user.userId, |
| | | label: user.nickName || user.userName, |
| | | isUser: true, |
| | | userName: user.userName, |
| | | nickName: user.nickName |
| | | }); |
| | | }); |
| | | } |
| | | |
| | | if (node.childrenList && node.childrenList.length > 0) { |
| | | const childNodes = buildTree(node.childrenList); |
| | | deptNode.children = deptNode.children.concat(childNodes); |
| | | } |
| | | |
| | | return deptNode; |
| | | }); |
| | | }; |
| | | staffList.value = buildTree(res.data || []); |
| | | }).catch(() => { |
| | | staffList.value = []; |
| | | }); |
| | | }; |
| | | |
| | | const getAllUserNamesFromSelection = (selectedIds) => { |
| | | const names = []; |
| | | const processNode = (node) => { |
| | | if (selectedIds.includes(node.id)) { |
| | | if (node.isUser) { |
| | | names.push(node.label); |
| | | } else { |
| | | if (node.children && node.children.length > 0) { |
| | | node.children.forEach(child => { |
| | | if (child.isUser) { |
| | | names.push(child.label); |
| | | } |
| | | }); |
| | | } |
| | | } |
| | | } |
| | | if (node.children && node.children.length > 0) { |
| | | node.children.forEach(child => processNode(child)); |
| | | } |
| | | }; |
| | | staffList.value.forEach(node => processNode(node)); |
| | | return [...new Set(names)]; |
| | | }; |
| | | |
| | | onUnmounted(() => { |
| | | destroySortable(); |
| | | }); |