军泰伟业
1.不要树形结构。根据图纸编号为唯一索引添加产品并可以导入
2.要求可以上传图纸
3.产品可以绑定工艺路线
4.工艺路线改成由工序组成,新增编辑是工序可以挪动顺序
5.工序添加报工权限字段,可以多选人员
| | |
| | | params: query |
| | | }) |
| | | } |
| | | |
| | | // è·åé¨é¨ç¨æ·æ |
| | | export function listDeptUserTree() { |
| | | return request({ |
| | | url: '/productProcess/listDeptUserTree', |
| | | method: 'get' |
| | | }) |
| | | } |
| | |
| | | clearable |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="è§æ ¼åå·" prop="drawingNumber"> |
| | | <el-input |
| | | v-model="modelForm.drawingNumber" |
| | | placeholder="请è¾å
¥è§æ ¼åå·" |
| | | clearable |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="åä½" prop="unit"> |
| | | <el-input |
| | | <el-select |
| | | v-model="modelForm.unit" |
| | | placeholder="请è¾å
¥åä½" |
| | | placeholder="è¯·éæ©åä½" |
| | | clearable |
| | | /> |
| | | style="width: 100%" |
| | | > |
| | | <el-option label="ä»¶" value="ä»¶" /> |
| | | <el-option label="å¥" value="å¥" /> |
| | | <el-option label="å°" value="å°" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="产å屿§" prop="productType"> |
| | | <el-select |
| | |
| | | <el-option label="å¤è´" :value="2" /> |
| | | <el-option label="å§å¤" :value="3" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="å·¥èºè·¯çº¿" prop="routeId"> |
| | | <el-select |
| | | v-model="modelForm.routeId" |
| | | placeholder="è¯·éæ©å·¥èºè·¯çº¿" |
| | | clearable |
| | | style="width: 100%" |
| | | filterable |
| | | > |
| | | <el-option |
| | | v-for="item in processRouteList" |
| | | :key="item.id" |
| | | :label="item.processRouteName" |
| | | :value="item.id" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="ä¸ä¼ å¾çº¸" prop="drawingFile"> |
| | | <el-upload |
| | | v-model:file-list="drawingFileList" |
| | | :action="upload.url" |
| | | :headers="upload.headers" |
| | | :data="upload.data" |
| | | :on-success="handleDrawingUploadSuccess" |
| | | :on-remove="handleDrawingRemove" |
| | | :before-upload="handleDrawingBeforeUpload" |
| | | :limit="1" |
| | | accept=".pdf,.jpg,.jpeg,.png,.dwg" |
| | | list-type="picture-card" |
| | | > |
| | | <el-icon class="avatar-uploader-icon"><Plus /></el-icon> |
| | | <template #tip> |
| | | <div class="el-upload__tip"> |
| | | æ¯æ pdfãjpgãjpegãpngãdwg æ ¼å¼ï¼å¤§å°ä¸è¶
è¿ 10MB |
| | | </div> |
| | | </template> |
| | | </el-upload> |
| | | </el-form-item> |
| | | </el-form> |
| | | </FormDialog> |
| | |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, reactive } from "vue"; |
| | | import { ref, reactive, onMounted } from "vue"; |
| | | import { ElMessageBox } from "element-plus"; |
| | | import { Plus } from "@element-plus/icons-vue"; |
| | | import { getToken } from "@/utils/auth.js"; |
| | | import { FileUpload } from "@/components/Upload"; |
| | | import FormDialog from "@/components/Dialog/FormDialog.vue"; |
| | | import { |
| | | addOrEditProductModel, |
| | |
| | | productListPage, |
| | | downloadTemplate, |
| | | } from "@/api/basicData/product.js"; |
| | | import { listPage as getProcessRouteList } from "@/api/productionManagement/processRoute.js"; |
| | | import ImportExcel from "./ImportExcel/index.vue"; |
| | | |
| | | const { proxy } = getCurrentInstance(); |
| | |
| | | const tableLoading = ref(false); |
| | | const selectedRows = ref([]); |
| | | const modelFormRef = ref(); |
| | | const processRouteList = ref([]); |
| | | const drawingFileList = ref([]); |
| | | |
| | | const upload = reactive({ |
| | | url: import.meta.env.VITE_APP_BASE_API + "/file/upload", |
| | | headers: { Authorization: "Bearer " + getToken() }, |
| | | data: { type: 13 }, |
| | | }); |
| | | |
| | | const queryForm = reactive({ |
| | | productName: "", |
| | |
| | | minWidth: 150, |
| | | }, |
| | | { |
| | | label: "è§æ ¼åå·", |
| | | prop: "drawingNumber", |
| | | label: "å·¥èºè·¯çº¿", |
| | | prop: "routeName", |
| | | minWidth: 150, |
| | | }, |
| | | { |
| | |
| | | productName: "", |
| | | model: "", |
| | | unit: "", |
| | | drawingNumber: "", |
| | | productType: null, |
| | | routeId: null, |
| | | drawingFile: "", |
| | | tempFileIds: [], |
| | | salesLedgerFiles: [], |
| | | }, |
| | | modelRules: { |
| | | productName: [ |
| | |
| | | { max: 50, message: "产ååç§°ä¸è½è¶
è¿50个å符", trigger: "blur" }, |
| | | ], |
| | | model: [{ required: true, message: "请è¾å
¥å¾çº¸ç¼å·", trigger: "blur" }], |
| | | unit: [{ required: true, message: "请è¾å
¥åä½", trigger: "blur" }], |
| | | drawingNumber: [], |
| | | unit: [{ required: true, message: "è¯·éæ©åä½", trigger: "change" }], |
| | | productType: [{ required: true, message: "è¯·éæ©äº§å屿§", trigger: "change" }], |
| | | }, |
| | | }); |
| | |
| | | modelForm.value.model = ""; |
| | | modelForm.value.id = ""; |
| | | modelForm.value.unit = ""; |
| | | modelForm.value.drawingNumber = ""; |
| | | modelForm.value.productType = null; |
| | | modelForm.value.routeId = null; |
| | | modelForm.value.drawingFile = ""; |
| | | modelForm.value.tempFileIds = []; |
| | | modelForm.value.salesLedgerFiles = []; |
| | | drawingFileList.value = []; |
| | | if (type === "edit") { |
| | | modelForm.value = { ...data }; |
| | | modelForm.value.tempFileIds = data.tempFileIds || []; |
| | | modelForm.value.salesLedgerFiles = data.salesLedgerFiles || []; |
| | | if (data.salesLedgerFiles && data.salesLedgerFiles.length > 0) { |
| | | drawingFileList.value = data.salesLedgerFiles.map(file => ({ |
| | | name: file.name, |
| | | url: file.url |
| | | })); |
| | | } else if (data.drawingFile) { |
| | | drawingFileList.value = [{ |
| | | name: data.drawingFile.split('/').pop(), |
| | | url: data.drawingFile |
| | | }]; |
| | | } |
| | | } |
| | | }; |
| | | |
| | |
| | | proxy.download("/basic/product/downloadTemplate", {}, "产å导å
¥æ¨¡æ¿.xlsx"); |
| | | }; |
| | | |
| | | getModelList(); |
| | | const getProcessRouteListData = () => { |
| | | getProcessRouteList({ current: 1, size: 1000 }).then((res) => { |
| | | processRouteList.value = res.data.records || []; |
| | | }).catch(() => { |
| | | processRouteList.value = []; |
| | | }); |
| | | }; |
| | | |
| | | const handleDrawingBeforeUpload = (file) => { |
| | | const isAllowed = [ |
| | | 'application/pdf', |
| | | 'image/jpeg', |
| | | 'image/jpg', |
| | | 'image/png', |
| | | 'application/dwg' |
| | | ].includes(file.type) || file.name.endsWith('.dwg'); |
| | | const isLt10M = file.size / 1024 / 1024 < 10; |
| | | |
| | | if (!isAllowed) { |
| | | proxy.$modal.msgError("åªè½ä¸ä¼ pdfãjpgãjpegãpngãdwg æ ¼å¼çæä»¶ï¼"); |
| | | return false; |
| | | } |
| | | if (!isLt10M) { |
| | | proxy.$modal.msgError("ä¸ä¼ æä»¶å¤§å°ä¸è½è¶
è¿ 10MBï¼"); |
| | | return false; |
| | | } |
| | | return true; |
| | | }; |
| | | |
| | | const handleDrawingUploadSuccess = (response, file, fileList) => { |
| | | console.log('ä¸ä¼ æåååº', response); |
| | | console.log('response.data', response.data); |
| | | if (response.code === 200) { |
| | | modelForm.value.tempFileIds = [response.data?.tempId]; |
| | | modelForm.value.salesLedgerFiles = [{ |
| | | tempId: response.data?.tempId, |
| | | originalName: response.data?.originalName || file.name, |
| | | tempPath: response.data?.tempPath, |
| | | type: response.data?.type || 13 |
| | | }]; |
| | | proxy.$modal.msgSuccess("ä¸ä¼ æå"); |
| | | } else { |
| | | proxy.$modal.msgError(response.msg || "ä¸ä¼ 失败"); |
| | | } |
| | | }; |
| | | |
| | | const handleDrawingRemove = (file) => { |
| | | modelForm.value.tempFileIds = []; |
| | | modelForm.value.salesLedgerFiles = []; |
| | | }; |
| | | |
| | | onMounted(() => { |
| | | getModelList(); |
| | | getProcessRouteListData(); |
| | | }); |
| | | </script> |
| | | |
| | | <style scoped> |
| | |
| | | margin-top: 16px; |
| | | } |
| | | |
| | | .avatar-uploader-icon { |
| | | font-size: 28px; |
| | | color: #8c939d; |
| | | width: 148px; |
| | | height: 148px; |
| | | text-align: center; |
| | | line-height: 148px; |
| | | } |
| | | |
| | | :deep(.el-upload--picture-card) { |
| | | width: 148px; |
| | | height: 148px; |
| | | } |
| | | |
| | | :deep(.el-upload-list__item) { |
| | | width: 148px; |
| | | height: 148px; |
| | | } |
| | | |
| | | :deep(.el-upload__tip) { |
| | | font-size: 12px; |
| | | color: #909399; |
| | | margin-top: 8px; |
| | | } |
| | | |
| | | :deep(.el-dialog__body) { |
| | | padding: 20px 24px; |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div> |
| | | <el-dialog |
| | | v-model="isShow" |
| | | :title="isEdit ? 'ç¼è¾å·¥èºè·¯çº¿' : 'å建工èºè·¯çº¿'" |
| | | width="900px" |
| | | @close="closeModal" |
| | | > |
| | | <el-form label-width="140px" :model="formState" label-position="top" ref="formRef"> |
| | | <el-form-item label="å·¥èºè·¯çº¿ç¼å·"> |
| | | <el-input v-model="formState.processRouteCode" placeholder="请è¾å
¥ï¼å¿½ç¥å°èªå¨çæ" clearable /> |
| | | </el-form-item> |
| | | |
| | | <el-form-item |
| | | label="å·¥èºè·¯çº¿åç§°" |
| | | prop="processRouteName" |
| | | :rules="[ |
| | | { |
| | | required: true, |
| | | message: '请è¾å
¥å·¥èºè·¯çº¿åç§°', |
| | | trigger: 'blur', |
| | | } |
| | | ]" |
| | | > |
| | | <el-input v-model="formState.processRouteName" placeholder="请填å" clearable /> |
| | | </el-form-item> |
| | | |
| | | <div class="section-title">å·¥åºå表</div> |
| | | |
| | | <div class="table-actions"> |
| | | <el-button type="primary" link @click="addRow"> |
| | | <el-icon><Plus /></el-icon> æ·»å ä¸è¡ |
| | | </el-button> |
| | | </div> |
| | | |
| | | <el-table |
| | | ref="tableRef" |
| | | :data="formState.processRouteItems" |
| | | border |
| | | style="width: 100%" |
| | | class="process-table" |
| | | row-key="tempId" |
| | | > |
| | | <el-table-column label="ææ½" width="60" align="center"> |
| | | <template #default> |
| | | <el-icon class="drag-handle"><Rank /></el-icon> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="å·¥åº" prop="processId" min-width="200"> |
| | | <template #header> |
| | | <span class="required">å·¥åº</span> |
| | | </template> |
| | | <template #default="scope"> |
| | | <el-select |
| | | v-model="scope.row.processId" |
| | | placeholder="è¯·éæ©" |
| | | clearable |
| | | style="width: 100%" |
| | | > |
| | | <el-option |
| | | v-for="item in processOptions" |
| | | :key="item.id" |
| | | :label="item.name" |
| | | :value="item.id" |
| | | /> |
| | | </el-select> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="æ¯å¦è´¨æ£" prop="isQuality" width="100" align="center"> |
| | | <template #default="scope"> |
| | | <el-switch v-model="scope.row.isQuality" /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="æä½" width="80" align="center" fixed="right"> |
| | | <template #default="scope"> |
| | | <el-button type="danger" link @click="deleteRow(scope.$index)"> |
| | | <el-icon><Delete /></el-icon> |
| | | </el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <el-empty v-if="formState.processRouteItems.length === 0" description="ææ æ°æ®" /> |
| | | </el-form> |
| | | |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" @click="handleSubmit">确认</el-button> |
| | | <el-button @click="closeModal">åæ¶</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import {ref, computed, getCurrentInstance, onMounted, nextTick, watch, onUnmounted} from "vue"; |
| | | import {add, update} from "@/api/productionManagement/processRoute.js"; |
| | | import {findProcessRouteItemList} from "@/api/productionManagement/processRouteItem.js"; |
| | | import {processList} from "@/api/productionManagement/productionProcess.js"; |
| | | import {Plus, Delete, Rank} from '@element-plus/icons-vue'; |
| | | import Sortable from 'sortablejs'; |
| | | |
| | | const props = defineProps({ |
| | | visible: { |
| | | type: Boolean, |
| | | required: true, |
| | | } |
| | | }); |
| | | |
| | | const emit = defineEmits(['update:visible', 'completed']); |
| | | |
| | | const isEdit = computed(() => { |
| | | return formState.value && formState.value.id; |
| | | }); |
| | | |
| | | const isShow = computed({ |
| | | get() { |
| | | return props.visible; |
| | | }, |
| | | set(val) { |
| | | emit('update:visible', val); |
| | | }, |
| | | }); |
| | | |
| | | const processOptions = ref([]); |
| | | |
| | | let { proxy } = getCurrentInstance(); |
| | | |
| | | const tableRef = ref(null); |
| | | let sortable = null; |
| | | |
| | | let tempIdCounter = 0; |
| | | |
| | | const formState = ref({ |
| | | id: undefined, |
| | | processRouteCode: '', |
| | | processRouteName: '', |
| | | processRouteItems: [], |
| | | }); |
| | | |
| | | const initSortable = () => { |
| | | if (sortable) { |
| | | sortable.destroy(); |
| | | sortable = null; |
| | | } |
| | | |
| | | nextTick(() => { |
| | | if (tableRef.value) { |
| | | const table = tableRef.value.$el.querySelector('.el-table__body-wrapper tbody'); |
| | | if (table) { |
| | | sortable = Sortable.create(table, { |
| | | animation: 150, |
| | | handle: '.drag-handle', |
| | | ghostClass: 'sortable-ghost', |
| | | onEnd: (evt) => { |
| | | const { oldIndex, newIndex } = evt; |
| | | if (oldIndex !== undefined && newIndex !== undefined && oldIndex !== newIndex) { |
| | | const item = formState.value.processRouteItems.splice(oldIndex, 1)[0]; |
| | | formState.value.processRouteItems.splice(newIndex, 0, item); |
| | | } |
| | | } |
| | | }); |
| | | } |
| | | } |
| | | }); |
| | | }; |
| | | |
| | | const getProcessList = () => { |
| | | processList({}).then(res => { |
| | | processOptions.value = res.data || []; |
| | | }).catch(err => { |
| | | console.error("è·åå·¥åºå表失败ï¼", err); |
| | | }); |
| | | }; |
| | | |
| | | const closeModal = () => { |
| | | formState.value = { |
| | | id: undefined, |
| | | processRouteCode: '', |
| | | processRouteName: '', |
| | | processRouteItems: [], |
| | | }; |
| | | isShow.value = false; |
| | | }; |
| | | |
| | | const setFormData = async () => { |
| | | if (isEdit.value) { |
| | | formState.value = { |
| | | id: props.record.id, |
| | | processRouteCode: props.record.processRouteCode || '', |
| | | processRouteName: props.record.processRouteName || '', |
| | | processRouteItems: (props.record.processRouteItems || []).map((item, index) => ({ |
| | | tempId: item.id || `temp_${tempIdCounter++}`, |
| | | processId: item.processId, |
| | | id: item.id, |
| | | isQuality: item.isQuality !== undefined ? item.isQuality : false, |
| | | dragSort: index + 1, |
| | | })), |
| | | }; |
| | | } else { |
| | | formState.value = { |
| | | id: undefined, |
| | | processRouteCode: '', |
| | | processRouteName: '', |
| | | processRouteItems: [], |
| | | }; |
| | | } |
| | | } |
| | | |
| | | const addRow = () => { |
| | | formState.value.processRouteItems.push({ |
| | | tempId: `temp_${tempIdCounter++}`, |
| | | processId: undefined, |
| | | isQuality: false, |
| | | }); |
| | | nextTick(() => { |
| | | initSortable(); |
| | | }); |
| | | }; |
| | | |
| | | const deleteRow = (index) => { |
| | | formState.value.processRouteItems.splice(index, 1); |
| | | nextTick(() => { |
| | | initSortable(); |
| | | }); |
| | | }; |
| | | |
| | | const handleSubmit = () => { |
| | | proxy.$refs["formRef"].validate(valid => { |
| | | if (valid) { |
| | | if (formState.value.processRouteItems.length === 0) { |
| | | proxy.$modal.msgError("请è³å°æ·»å ä¸ä¸ªå·¥åº"); |
| | | return; |
| | | } |
| | | |
| | | for (let i = 0; i < formState.value.processRouteItems.length; i++) { |
| | | const row = formState.value.processRouteItems[i]; |
| | | if (!row.processId) { |
| | | proxy.$modal.msgError(`第${i + 1}è¡ï¼è¯·éæ©å·¥åº`); |
| | | return; |
| | | } |
| | | } |
| | | |
| | | const submitData = { |
| | | id: formState.value.id, |
| | | processRouteCode: formState.value.processRouteCode, |
| | | processRouteName: formState.value.processRouteName, |
| | | processRouteItems: formState.value.processRouteItems.map((item, index) => ({ |
| | | id: item.id, |
| | | routeId: formState.value.id, |
| | | processId: item.processId, |
| | | isQuality: item.isQuality, |
| | | dragSort: index + 1, |
| | | })), |
| | | }; |
| | | |
| | | const apiCall = isEdit.value ? update(submitData) : add(submitData); |
| | | |
| | | apiCall.then(res => { |
| | | isShow.value = false; |
| | | emit('completed'); |
| | | proxy.$modal.msgSuccess(isEdit.value ? "ç¼è¾æå" : "æ°å¢æå"); |
| | | }); |
| | | } |
| | | }); |
| | | }; |
| | | |
| | | // çå¬ visible åå |
| | | watch(() => props.visible, (visible) => { |
| | | if (visible) { |
| | | nextTick(() => { |
| | | initSortable(); |
| | | }); |
| | | } |
| | | }); |
| | | |
| | | const setData = async (row) => { |
| | | if (row) { |
| | | formState.value = { |
| | | id: row.id, |
| | | processRouteCode: row.processRouteCode || '', |
| | | processRouteName: row.processRouteName || '', |
| | | processRouteItems: [], |
| | | }; |
| | | |
| | | const res = await findProcessRouteItemList({ routeId: row.id }); |
| | | if (res.data && Array.isArray(res.data)) { |
| | | formState.value.processRouteItems = res.data.map((item, index) => ({ |
| | | tempId: item.id || `temp_${tempIdCounter++}`, |
| | | processId: item.processId, |
| | | id: item.id, |
| | | isQuality: item.isQuality !== undefined ? item.isQuality : false, |
| | | dragSort: index + 1, |
| | | })); |
| | | } |
| | | |
| | | nextTick(() => { |
| | | initSortable(); |
| | | }); |
| | | } else { |
| | | formState.value = { |
| | | id: undefined, |
| | | processRouteCode: '', |
| | | processRouteName: '', |
| | | processRouteItems: [], |
| | | }; |
| | | |
| | | nextTick(() => { |
| | | initSortable(); |
| | | }); |
| | | } |
| | | }; |
| | | |
| | | onMounted(() => { |
| | | getProcessList(); |
| | | }); |
| | | |
| | | onUnmounted(() => { |
| | | if (sortable) { |
| | | sortable.destroy(); |
| | | sortable = null; |
| | | } |
| | | }); |
| | | |
| | | defineExpose({ |
| | | closeModal, |
| | | handleSubmit, |
| | | isShow, |
| | | setData, |
| | | }); |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .section-title { |
| | | font-size: 14px; |
| | | font-weight: bold; |
| | | margin: 20px 0 10px 0; |
| | | color: #333; |
| | | } |
| | | |
| | | .table-actions { |
| | | display: flex; |
| | | gap: 16px; |
| | | margin-bottom: 10px; |
| | | } |
| | | |
| | | .process-table { |
| | | margin-bottom: 20px; |
| | | } |
| | | |
| | | .required::before { |
| | | content: '*'; |
| | | color: #f56c6c; |
| | | margin-right: 4px; |
| | | } |
| | | |
| | | :deep(.el-dialog__body) { |
| | | padding-top: 10px; |
| | | } |
| | | |
| | | .sortable-ghost { |
| | | opacity: 0.4; |
| | | background-color: #f5f7fa; |
| | | } |
| | | |
| | | .drag-handle { |
| | | cursor: move; |
| | | font-size: 18px; |
| | | color: #909399; |
| | | } |
| | | |
| | | .drag-handle:hover { |
| | | color: #409eff; |
| | | } |
| | | </style> |
| | |
| | | <div class="app-container"> |
| | | <div class="search_form"> |
| | | <el-form :model="searchForm" :inline="true"> |
| | | <el-form-item label="è§æ ¼åç§°:"> |
| | | <el-input v-model="searchForm.model" placeholder="请è¾å
¥" clearable prefix-icon="Search" |
| | | style="width: 200px;" |
| | | @change="handleQuery" /> |
| | | <el-form-item label="å·¥èºè·¯çº¿ç¼å·"> |
| | | <el-input v-model="searchForm.processRouteCode" placeholder="请è¾å
¥å·¥èºè·¯çº¿ç¼å·" clearable style="width: 200px;" /> |
| | | </el-form-item> |
| | | <el-form-item label="å·¥èºè·¯çº¿åç§°"> |
| | | <el-input v-model="searchForm.processRouteName" placeholder="请è¾å
¥å·¥èºè·¯çº¿åç§°" clearable style="width: 200px;" /> |
| | | </el-form-item> |
| | | <el-form-item label="å·¥åºåç§°"> |
| | | <el-select v-model="searchForm.processName" placeholder="è¯·éæ©å·¥åº" clearable style="width: 200px;"> |
| | | <el-option |
| | | v-for="item in processOptions" |
| | | :key="item.id" |
| | | :label="item.name" |
| | | :value="item.name" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" @click="handleQuery">æç´¢</el-button> |
| | | <el-button @click="resetQuery">éç½®</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | </div> |
| | |
| | | :total="page.total" |
| | | /> |
| | | </div> |
| | | <new-process |
| | | v-if="isShowNewModal" |
| | | v-model:visible="isShowNewModal" |
| | | @completed="getList" |
| | | /> |
| | | |
| | | <edit-process |
| | | v-if="isShowEditModal" |
| | | v-model:visible="isShowEditModal" |
| | | :record="record" |
| | | @completed="getList" |
| | | /> |
| | | |
| | | <route-item-form |
| | | v-if="isShowItemModal" |
| | | v-model:visible="isShowItemModal" |
| | | :record="record" |
| | | <process-form |
| | | v-if="isShowFormModal" |
| | | ref="formRef" |
| | | v-model:visible="isShowFormModal" |
| | | @completed="getList" |
| | | /> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import {onMounted, ref} from "vue"; |
| | | import NewProcess from "@/views/productionManagement/processRoute/New.vue"; |
| | | import EditProcess from "@/views/productionManagement/processRoute/Edit.vue"; |
| | | import RouteItemForm from "@/views/productionManagement/processRoute/ItemsForm.vue"; |
| | | import {onMounted, ref, nextTick} from "vue"; |
| | | import ProcessForm from "@/views/productionManagement/processRoute/Form.vue"; |
| | | import {listPage, del} from "@/api/productionManagement/processRoute.js"; |
| | | import { useRouter } from 'vue-router' |
| | | import {processList} from "@/api/productionManagement/productionProcess.js"; |
| | | |
| | | const router = useRouter() |
| | | const data = reactive({ |
| | | searchForm: { |
| | | model: "", |
| | | processRouteCode: '', |
| | | processRouteName: '', |
| | | processName: undefined, |
| | | }, |
| | | }); |
| | | const { searchForm } = toRefs(data); |
| | | |
| | | const processOptions = ref([]); |
| | | const tableColumn = ref([ |
| | | { |
| | | label: "å·¥èºè·¯çº¿ç¼å·", |
| | | prop: "processRouteCode", |
| | | }, |
| | | { |
| | | label: "产ååç§°", |
| | | prop: "productName", |
| | | }, |
| | | { |
| | | label: "å¾çº¸ç¼å·", |
| | | prop: "model", |
| | | }, |
| | | { |
| | | label: "è§æ ¼åç§°", |
| | | prop: "drawingNumber", |
| | | label: "å·¥èºè·¯çº¿åç§°", |
| | | prop: "processRouteName", |
| | | }, |
| | | { |
| | | label: "BOMç¼å·", |
| | | prop: "bomNo", |
| | | label: "å·¥åºå表", |
| | | prop: "processName", |
| | | minWidth: 300, |
| | | }, |
| | | { |
| | | label: "æè¿°", |
| | | prop: "description", |
| | | label: "å建人", |
| | | prop: "createBy", |
| | | }, |
| | | { |
| | | label: "å建æ¶é´", |
| | | prop: "createTime", |
| | | }, |
| | | { |
| | | dataType: "action", |
| | | label: "æä½", |
| | | align: "center", |
| | | fixed: "right", |
| | | width: 280, |
| | | width: 150, |
| | | operation: [ |
| | | { |
| | | name: "ç¼è¾", |
| | | type: "text", |
| | | clickFun: (row) => { |
| | | showEditModal(row); |
| | | } |
| | | }, |
| | | { |
| | | name: "路线项ç®", |
| | | type: "text", |
| | | clickFun: (row) => { |
| | | showItemModal(row); |
| | | } |
| | | } |
| | | ] |
| | |
| | | const tableData = ref([]); |
| | | const selectedRows = ref([]); |
| | | const tableLoading = ref(false); |
| | | const isShowNewModal = ref(false); |
| | | const isShowEditModal = ref(false); |
| | | const isShowItemModal = ref(false); |
| | | const isShowFormModal = ref(false); |
| | | const record = ref({}); |
| | | const formRef = ref(null); |
| | | const page = reactive({ |
| | | current: 1, |
| | | size: 100, |
| | |
| | | // æ¥è¯¢å表 |
| | | /** æç´¢æé®æä½ */ |
| | | const handleQuery = () => { |
| | | page.current = 1; |
| | | getList(); |
| | | }; |
| | | |
| | | /** éç½®æé®æä½ */ |
| | | const resetQuery = () => { |
| | | searchForm.value = { |
| | | processRouteCode: '', |
| | | processRouteName: '', |
| | | processName: undefined, |
| | | }; |
| | | page.current = 1; |
| | | getList(); |
| | | }; |
| | |
| | | |
| | | // æå¼æ°å¢å¼¹æ¡ |
| | | const showNewModal = () => { |
| | | isShowNewModal.value = true |
| | | isShowFormModal.value = true; |
| | | record.value = {}; |
| | | }; |
| | | |
| | | const showEditModal = (row) => { |
| | | isShowEditModal.value = true |
| | | record.value = row |
| | | }; |
| | | |
| | | const showItemModal = (row) => { |
| | | router.push({ |
| | | path: '/productionManagement/processRouteItem', |
| | | query: { |
| | | id: row.id, |
| | | processRouteCode: row.processRouteCode || '', |
| | | drawingNumber: row.drawingNumber || "", |
| | | productName: row.productName || '', |
| | | model: row.model || '', |
| | | bomNo: row.bomNo || '', |
| | | description: row.description || '', |
| | | type: 'route', |
| | | } |
| | | }) |
| | | const showEditModal = async (row) => { |
| | | isShowFormModal.value = true; |
| | | await nextTick(); |
| | | await formRef.value && formRef.value.setData({ id: row.id, processRouteCode: row.processRouteCode, processRouteName: row.processRouteName }); |
| | | }; |
| | | |
| | | // å é¤ |
| | |
| | | } |
| | | |
| | | onMounted(() => { |
| | | getProcessList(); |
| | | getList(); |
| | | }); |
| | | |
| | | // è·åå·¥åºå表 |
| | | const getProcessList = () => { |
| | | processList({}).then(res => { |
| | | processOptions.value = res.data || []; |
| | | }).catch(err => { |
| | | console.error("è·åå·¥åºå表失败ï¼", err); |
| | | }); |
| | | }; |
| | | </script> |
| | | |
| | | <style scoped></style> |
| | |
| | | {{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"> |
| | | <template #default="scope"> |
| | | <el-button type="primary" link size="small" @click="handleEdit(scope.row)" :disabled="scope.row.isComplete">ç¼è¾</el-button> |
| | |
| | | </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(); |
| | | }); |
| | |
| | | <el-form-item label="æ¯å¦è´¨æ£" prop="isQuality"> |
| | | <el-switch v-model="formState.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="formState.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-item label="夿³¨" prop="remark"> |
| | | <el-input v-model="formState.remark" type="textarea" /> |
| | | </el-form-item> |
| | |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, computed, getCurrentInstance, watch } from "vue"; |
| | | import { ref, computed, getCurrentInstance, watch, onMounted } from "vue"; |
| | | import {update} from "@/api/productionManagement/productionProcess.js"; |
| | | import { listDeptUserTree } from "@/api/basicData/productProcess.js"; |
| | | |
| | | const props = defineProps({ |
| | | visible: { |
| | |
| | | remark: props.record.remark, |
| | | salaryQuota: props.record.salaryQuota, |
| | | isQuality: props.record.isQuality, |
| | | userPower: props.record.userPower ? props.record.userPower.split(',') : [], |
| | | }); |
| | | |
| | | const staffList = ref([]); |
| | | |
| | | const treeProps = { |
| | | label: 'label', |
| | | children: 'children', |
| | | }; |
| | | |
| | | const isShow = computed({ |
| | | get() { |
| | |
| | | // çå¬ record ååï¼æ´æ°è¡¨åæ°æ® |
| | | watch(() => props.record, (newRecord) => { |
| | | if (newRecord && isShow.value) { |
| | | const userPowerNames = newRecord.userPower ? newRecord.userPower.split(',') : []; |
| | | const userPowerIds = userPowerNames.map(name => { |
| | | const user = findUserByName(name); |
| | | return user ? user.id : null; |
| | | }).filter(id => id !== null); |
| | | |
| | | formState.value = { |
| | | id: newRecord.id, |
| | | name: newRecord.name || '', |
| | | no: newRecord.no || '', |
| | | remark: newRecord.remark || '', |
| | | salaryQuota: newRecord.salaryQuota || '', |
| | | isQuality: props.record.isQuality, |
| | | isQuality: newRecord.isQuality, |
| | | userPower: userPowerIds, |
| | | }; |
| | | } |
| | | }, { immediate: true, deep: true }); |
| | | |
| | | // çå¬å¼¹çªæå¼ï¼éæ°åå§åè¡¨åæ°æ® |
| | | watch(() => props.visible, (visible) => { |
| | | if (visible && props.record) { |
| | | formState.value = { |
| | | id: props.record.id, |
| | | name: props.record.name || '', |
| | | no: props.record.no || '', |
| | | remark: props.record.remark || '', |
| | | salaryQuota: props.record.salaryQuota || '', |
| | | isQuality: props.record.isQuality, |
| | | }; |
| | | } |
| | | }); |
| | | |
| | | let { proxy } = getCurrentInstance() |
| | | |
| | |
| | | const handleSubmit = () => { |
| | | proxy.$refs["formRef"].validate(valid => { |
| | | if (valid) { |
| | | update(formState.value).then(res => { |
| | | const userPowerNames = getAllUserNamesFromSelection(formState.value.userPower); |
| | | |
| | | const submitData = { |
| | | ...formState.value, |
| | | userPower: userPowerNames.join(',') |
| | | }; |
| | | update(submitData).then(res => { |
| | | // å
³éæ¨¡ææ¡ |
| | | isShow.value = false; |
| | | // åç¥ç¶ç»ä»¶å·²å®æ |
| | |
| | | }) |
| | | }; |
| | | |
| | | const findUserById = (userId) => { |
| | | const findInTree = (nodes) => { |
| | | for (const node of nodes) { |
| | | if (node.id === userId) { |
| | | return node; |
| | | } |
| | | if (node.children && node.children.length > 0) { |
| | | const found = findInTree(node.children); |
| | | if (found) return found; |
| | | } |
| | | } |
| | | return null; |
| | | }; |
| | | return findInTree(staffList.value); |
| | | }; |
| | | |
| | | 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)]; |
| | | }; |
| | | |
| | | onMounted(() => { |
| | | getStaffList(); |
| | | }); |
| | | |
| | | defineExpose({ |
| | | closeModal, |
| | | handleSubmit, |
| | |
| | | <!-- <el-input v-model="formState.salaryQuota" type="number" :step="0.001" />--> |
| | | <!-- </el-form-item>--> |
| | | <el-form-item label="æ¯å¦è´¨æ£" prop="isQuality"> |
| | | <el-switch v-model="formState.isQuality" :active-value="true" inactive-value="false"/> |
| | | <el-switch v-model="formState.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="formState.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-item label="夿³¨" prop="remark"> |
| | | <el-input v-model="formState.remark" type="textarea" /> |
| | |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, computed, getCurrentInstance } from "vue"; |
| | | import { ref, computed, getCurrentInstance, onMounted } from "vue"; |
| | | import {add} from "@/api/productionManagement/productionProcess.js"; |
| | | import { listDeptUserTree } from "@/api/basicData/productProcess.js"; |
| | | |
| | | const props = defineProps({ |
| | | visible: { |
| | |
| | | remark: '', |
| | | salaryQuota: '', |
| | | isQuality: false, |
| | | userPower: [], |
| | | }); |
| | | |
| | | const staffList = ref([]); |
| | | |
| | | const treeProps = { |
| | | label: 'label', |
| | | children: 'children', |
| | | }; |
| | | |
| | | const isShow = computed({ |
| | | get() { |
| | |
| | | const handleSubmit = () => { |
| | | proxy.$refs["formRef"].validate(valid => { |
| | | if (valid) { |
| | | add(formState.value).then(res => { |
| | | const userPowerNames = getAllUserNamesFromSelection(formState.value.userPower); |
| | | |
| | | const submitData = { |
| | | ...formState.value, |
| | | userPower: userPowerNames.join(',') |
| | | }; |
| | | add(submitData).then(res => { |
| | | // å
³éæ¨¡ææ¡ |
| | | isShow.value = false; |
| | | // åç¥ç¶ç»ä»¶å·²å®æ |
| | |
| | | }) |
| | | }; |
| | | |
| | | const findUserById = (userId) => { |
| | | const findInTree = (nodes) => { |
| | | for (const node of nodes) { |
| | | if (node.id === userId) { |
| | | return node; |
| | | } |
| | | if (node.children && node.children.length > 0) { |
| | | const found = findInTree(node.children); |
| | | if (found) return found; |
| | | } |
| | | } |
| | | return null; |
| | | }; |
| | | return findInTree(staffList.value); |
| | | }; |
| | | |
| | | 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)]; |
| | | }; |
| | | |
| | | onMounted(() => { |
| | | getStaffList(); |
| | | }); |
| | | |
| | | defineExpose({ |
| | | closeModal, |
| | | handleSubmit, |
| | |
| | | label: "å·¥åºåç§°", |
| | | prop: "name", |
| | | }, |
| | | { |
| | | label: "æ¥å·¥æé", |
| | | prop: "userPower", |
| | | width: 200, |
| | | }, |
| | | // { |
| | | // label: "å·¥èµå®é¢", |
| | | // prop: "salaryQuota", |