| | |
| | | style="width: 200px" |
| | | placeholder="请è¾å
¥åæ°åç§°" |
| | | clearable /> |
| | | <span class="search_title ml10">å
³è产åç±»åï¼</span> |
| | | <!-- å
³è产åç±»åæç´¢ --> |
| | | <!-- <span class="search_title ml10">å
³è产åç±»åï¼</span> |
| | | <el-input v-model="searchForm.productName" |
| | | style="width: 200px" |
| | | placeholder="请è¾å
¥å
³è产åç±»å" |
| | | clearable /> |
| | | clearable /> --> |
| | | <el-button type="primary" |
| | | @click="handleQuery" |
| | | style="margin-left: 10px">æç´¢</el-button> |
| | |
| | | <el-button type="primary" |
| | | @click="handleAdd" |
| | | style="margin-left: 10px">æ°å¢åæ°</el-button> |
| | | <el-button type="primary" |
| | | <!-- 产åç±»åç»´æ¤æé® --> |
| | | <!-- <el-button type="primary" |
| | | @click="handleProductTypeMaintenance" |
| | | style="margin-left: 10px">产åç±»åç»´æ¤</el-button> |
| | | style="margin-left: 10px">产åç±»åç»´æ¤</el-button> --> |
| | | </div> |
| | | </div> |
| | | <div class="table_list"> |
| | |
| | | <el-input v-model="formData.parameterFormat" |
| | | placeholder="请è¾å
¥åæ°æ ¼å¼" /> |
| | | </el-form-item> |
| | | <el-form-item label="å
³è产åç±»å" |
| | | <!-- å
³è产åç±»å --> |
| | | <!-- <el-form-item label="å
³è产åç±»å" |
| | | prop="parameterValue"> |
| | | <el-select v-model="formData.parameterValue" |
| | | placeholder="è¯·éæ©å
³è产åç±»å"> |
| | |
| | | :label="item.label" |
| | | :value="item.value" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-form-item> --> |
| | | <el-form-item label="æ åå¼" |
| | | v-if="formData.parameterType2 === '1'" |
| | | prop="standardValue"> |
| | |
| | | </template> |
| | | </el-dialog> |
| | | <!-- 产åç±»åç»´æ¤å¯¹è¯æ¡ --> |
| | | <el-dialog v-model="productTypeDialogVisible" |
| | | <!-- <el-dialog v-model="productTypeDialogVisible" |
| | | title="产åç±»åç»´æ¤" |
| | | width="600px"> |
| | | <div class="product-type-header"> |
| | |
| | | <el-table :data="productTypeList" |
| | | border |
| | | style="width: 100%; margin-top: 10px; margin-bottom: 20px"> |
| | | <!-- <el-table-column prop="typeCode" |
| | | <el-table-column prop="typeCode" |
| | | label="ç±»åç¼ç " |
| | | width="150" /> --> |
| | | width="150" /> |
| | | <el-table-column prop="typeName" |
| | | label="ç±»ååç§°" /> |
| | | <el-table-column label="æä½" |
| | |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </el-dialog> |
| | | </el-dialog> --> |
| | | <!-- æ°å¢/ç¼è¾äº§åç±»åå¯¹è¯æ¡ --> |
| | | <el-dialog v-model="productTypeFormVisible" |
| | | <!-- <el-dialog v-model="productTypeFormVisible" |
| | | :title="productTypeDialogTitle" |
| | | width="400px"> |
| | | <el-form :model="productTypeForm" |
| | | :rules="productTypeRules" |
| | | ref="productTypeFormRef" |
| | | label-width="100px"> |
| | | <!-- <el-form-item label="ç±»åç¼ç " |
| | | <el-form-item label="ç±»åç¼ç " |
| | | prop="typeCode"> |
| | | <el-input v-model="productTypeForm.typeCode" |
| | | placeholder="请è¾å
¥ç±»åç¼ç " /> |
| | | </el-form-item> --> |
| | | </el-form-item> |
| | | <el-form-item label="ç±»ååç§°" |
| | | prop="typeName"> |
| | | <el-input v-model="productTypeForm.typeName" |
| | |
| | | @click="handleProductTypeSubmit">ç¡®å®</el-button> |
| | | </span> |
| | | </template> |
| | | </el-dialog> |
| | | </el-dialog> --> |
| | | </div> |
| | | </template> |
| | | |
| | |
| | | addParameter, |
| | | updateParameter, |
| | | delParameter, |
| | | getProductTypes as getProductTypesApi, |
| | | // getProductTypes as getProductTypesApi, |
| | | } from "@/api/basicData/parameterMaintenance.js"; |
| | | import { listType } from "@/api/system/dict/type"; |
| | | import PIMTable from "@/components/PIMTable/PIMTable.vue"; |
| | |
| | | label: "åæ°æ ¼å¼", |
| | | prop: "parameterFormat", |
| | | }, |
| | | { |
| | | label: "å
³è产åç±»å", |
| | | prop: "parameterValue", |
| | | }, |
| | | // å
³è产åç±»åå |
| | | // { |
| | | // label: "å
³è产åç±»å", |
| | | // prop: "parameterValue", |
| | | // }, |
| | | { |
| | | label: "æ åå¼", |
| | | prop: "standardValue", |
| | |
| | | parameterType2: "1", |
| | | parameterType: "", |
| | | parameterFormat: "", |
| | | parameterValue: "", |
| | | // parameterValue: "", |
| | | standardValue: "", |
| | | unit: "", |
| | | }); |
| | |
| | | parameterFormat: [ |
| | | { required: true, message: "è¯·éæ©åæ°æ ¼å¼", trigger: "change" }, |
| | | ], |
| | | parameterValue: [ |
| | | { required: true, message: "è¯·éæ©å
³è产åç±»å", trigger: "change" }, |
| | | ], |
| | | // parameterValue: [ |
| | | // { required: true, message: "è¯·éæ©å
³è产åç±»å", trigger: "change" }, |
| | | // ], |
| | | standardValue: [{ required: true, message: "请è¾å
¥æ åå¼", trigger: "blur" }], |
| | | unit: [{ required: true, message: "请è¾å
¥åä½", trigger: "blur" }], |
| | | }); |
| | | const productTypes = ref([]); |
| | | // const productTypes = ref([]); |
| | | const isEdit = ref(false); |
| | | |
| | | // 产åç±»åç»´æ¤ç¸å
³ |
| | | const productTypeDialogVisible = ref(false); |
| | | const productTypeFormVisible = ref(false); |
| | | const productTypeDialogTitle = ref(""); |
| | | const productTypeFormRef = ref(null); |
| | | const productTypeList = ref([]); |
| | | const productTypeForm = reactive({ |
| | | id: null, |
| | | // 产åç±»åç»´æ¤ç¸å
³ - 已注é |
| | | // const productTypeDialogVisible = ref(false); |
| | | // const productTypeFormVisible = ref(false); |
| | | // const productTypeDialogTitle = ref(""); |
| | | // const productTypeFormRef = ref(null); |
| | | // const productTypeList = ref([]); |
| | | // const productTypeForm = reactive({ |
| | | // id: null, |
| | | // typeCode: "", |
| | | typeName: "", |
| | | }); |
| | | const productTypeRules = reactive({ |
| | | // typeName: "", |
| | | // }); |
| | | // const productTypeRules = reactive({ |
| | | // typeCode: [{ required: true, message: "请è¾å
¥ç±»åç¼ç ", trigger: "blur" }], |
| | | typeName: [{ required: true, message: "请è¾å
¥ç±»ååç§°", trigger: "blur" }], |
| | | }); |
| | | const isProductTypeEdit = ref(false); |
| | | // typeName: [{ required: true, message: "请è¾å
¥ç±»ååç§°", trigger: "blur" }], |
| | | // }); |
| | | // const isProductTypeEdit = ref(false); |
| | | const handleParameterTypeChange = () => { |
| | | if (formData.parameterType === "æ°å¼æ ¼å¼") { |
| | | formData.parameterFormat = "#.0000"; |
| | |
| | | formData.parameterFormat = ""; |
| | | } |
| | | }; |
| | | // 产åç±»åç»´æ¤æé®ç¹å»äºä»¶ |
| | | const handleProductTypeMaintenance = () => { |
| | | productTypeDialogVisible.value = true; |
| | | getProductTypeList(); |
| | | }; |
| | | // 产åç±»åç»´æ¤æé®ç¹å»äºä»¶ - 已注é |
| | | // const handleProductTypeMaintenance = () => { |
| | | // productTypeDialogVisible.value = true; |
| | | // getProductTypeList(); |
| | | // }; |
| | | |
| | | // è·å产åç±»åå表 |
| | | const getProductTypeList = () => { |
| | | productTypeList.value = [ |
| | | { id: 1, typeCode: "TYPE001", typeName: "3.5ç å" }, |
| | | { id: 2, typeCode: "TYPE002", typeName: "5.0ç å" }, |
| | | { id: 3, typeCode: "TYPE003", typeName: "æ¿æ" }, |
| | | ]; |
| | | }; |
| | | // è·å产åç±»åå表 - 已注é |
| | | // const getProductTypeList = () => { |
| | | // productTypeList.value = [ |
| | | // { id: 1, typeCode: "TYPE001", typeName: "3.5ç å" }, |
| | | // { id: 2, typeCode: "TYPE002", typeName: "5.0ç å" }, |
| | | // { id: 3, typeCode: "TYPE003", typeName: "æ¿æ" }, |
| | | // ]; |
| | | // }; |
| | | |
| | | // æ°å¢äº§åç±»å |
| | | const handleAddProductType = () => { |
| | | isProductTypeEdit.value = false; |
| | | productTypeDialogTitle.value = "æ°å¢äº§åç±»å"; |
| | | productTypeForm.id = null; |
| | | productTypeForm.typeCode = ""; |
| | | productTypeForm.typeName = ""; |
| | | productTypeFormVisible.value = true; |
| | | }; |
| | | // æ°å¢äº§åç±»å - 已注é |
| | | // const handleAddProductType = () => { |
| | | // isProductTypeEdit.value = false; |
| | | // productTypeDialogTitle.value = "æ°å¢äº§åç±»å"; |
| | | // productTypeForm.id = null; |
| | | // productTypeForm.typeCode = ""; |
| | | // productTypeForm.typeName = ""; |
| | | // productTypeFormVisible.value = true; |
| | | // }; |
| | | |
| | | // ç¼è¾äº§åç±»å |
| | | const handleEditProductType = row => { |
| | | isProductTypeEdit.value = true; |
| | | productTypeDialogTitle.value = "ç¼è¾äº§åç±»å"; |
| | | productTypeForm.id = row.id; |
| | | productTypeForm.typeCode = row.typeCode; |
| | | productTypeForm.typeName = row.typeName; |
| | | productTypeFormVisible.value = true; |
| | | }; |
| | | // ç¼è¾äº§åç±»å - 已注é |
| | | // const handleEditProductType = row => { |
| | | // isProductTypeEdit.value = true; |
| | | // productTypeDialogTitle.value = "ç¼è¾äº§åç±»å"; |
| | | // productTypeForm.id = row.id; |
| | | // productTypeForm.typeCode = row.typeCode; |
| | | // productTypeForm.typeName = row.typeName; |
| | | // productTypeFormVisible.value = true; |
| | | // }; |
| | | |
| | | // å é¤äº§åç±»å |
| | | const handleDeleteProductType = row => { |
| | | ElMessageBox.confirm("ç¡®å®è¦å é¤è¯¥äº§åç±»ååï¼", "æç¤º", { |
| | | confirmButtonText: "ç¡®å®", |
| | | cancelButtonText: "åæ¶", |
| | | type: "warning", |
| | | }) |
| | | .then(() => { |
| | | ElMessage.success("å 餿å"); |
| | | getProductTypeList(); |
| | | }) |
| | | .catch(() => {}); |
| | | }; |
| | | // å é¤äº§åç±»å - 已注é |
| | | // const handleDeleteProductType = row => { |
| | | // ElMessageBox.confirm("ç¡®å®è¦å é¤è¯¥äº§åç±»ååï¼", "æç¤º", { |
| | | // confirmButtonText: "ç¡®å®", |
| | | // cancelButtonText: "åæ¶", |
| | | // type: "warning", |
| | | // }) |
| | | // .then(() => { |
| | | // ElMessage.success("å 餿å"); |
| | | // getProductTypeList(); |
| | | // }) |
| | | // .catch(() => {}); |
| | | // }; |
| | | |
| | | // æäº¤äº§åç±»å表å |
| | | const handleProductTypeSubmit = () => { |
| | | productTypeFormRef.value.validate(valid => { |
| | | if (valid) { |
| | | ElMessage.success(isProductTypeEdit.value ? "ç¼è¾æå" : "æ°å¢æå"); |
| | | productTypeFormVisible.value = false; |
| | | getProductTypeList(); |
| | | } |
| | | }); |
| | | }; |
| | | // æäº¤äº§åç±»å表å - 已注é |
| | | // const handleProductTypeSubmit = () => { |
| | | // productTypeFormRef.value.validate(valid => { |
| | | // if (valid) { |
| | | // ElMessage.success(isProductTypeEdit.value ? "ç¼è¾æå" : "æ°å¢æå"); |
| | | // productTypeFormVisible.value = false; |
| | | // getProductTypeList(); |
| | | // } |
| | | // }); |
| | | // }; |
| | | |
| | | // æ¥è¯¢å表 |
| | | /** æç´¢æé®æä½ */ |
| | |
| | | }, 500); |
| | | }; |
| | | |
| | | // è·å产åç±»åå表 |
| | | const getProductTypes = () => { |
| | | // 注éæAPIè°ç¨ï¼ä½¿ç¨åæ°æ® |
| | | /*getProductTypesApi() |
| | | .then(res => { |
| | | productTypes.value = res.data || []; |
| | | }) |
| | | .catch(() => { |
| | | // 失败æ¶ä½¿ç¨æ¨¡ææ°æ® |
| | | productTypes.value = [ |
| | | { label: "3.5ç å", value: "type1" }, |
| | | { label: "5.0ç å", value: "type2" }, |
| | | { label: "æ¿æ", value: "type3" }, |
| | | ]; |
| | | });*/ |
| | | |
| | | // åæ°æ® |
| | | productTypes.value = [ |
| | | { label: "3.5ç å", value: "type1" }, |
| | | { label: "5.0ç å", value: "type2" }, |
| | | { label: "æ¿æ", value: "type3" }, |
| | | ]; |
| | | }; |
| | | // è·å产åç±»åå表 - 已注é |
| | | // const getProductTypes = () => { |
| | | // productTypes.value = [ |
| | | // { label: "3.5ç å", value: "type1" }, |
| | | // { label: "5.0ç å", value: "type2" }, |
| | | // { label: "æ¿æ", value: "type3" }, |
| | | // ]; |
| | | // }; |
| | | |
| | | // æ°å¢æé®ç¹å»äºä»¶ |
| | | const handleAdd = () => { |
| | |
| | | formData.parameterType2 = "1"; |
| | | formData.parameterType = ""; |
| | | formData.parameterFormat = ""; |
| | | formData.parameterValue = ""; |
| | | // formData.parameterValue = ""; |
| | | formData.standardValue = ""; |
| | | formData.unit = ""; |
| | | dialogVisible.value = true; |
| | |
| | | formData.parameterType2 = row.parameterType2 || "1"; |
| | | formData.parameterType = row.parameterType; |
| | | formData.parameterFormat = row.parameterFormat; |
| | | formData.parameterValue = row.parameterValue; |
| | | // formData.parameterValue = row.parameterValue; |
| | | formData.standardValue = row.standardValue; |
| | | formData.unit = row.unit; |
| | | dialogVisible.value = true; |
| | |
| | | onMounted(() => { |
| | | getDictTypes(); |
| | | getList(); |
| | | getProductTypes(); |
| | | // getProductTypes(); |
| | | }); |
| | | </script> |
| | | |
| | |
| | | <template> |
| | | <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" /> |
| | | <div class="route-header"> |
| | | <div class="add-route-btn" |
| | | @click="handleAddRoute"> |
| | | <el-icon> |
| | | <Plus /> |
| | | </el-icon> |
| | | <span>æ°å¢å·¥èºè·¯çº¿</span> |
| | | </div> |
| | | </div> |
| | | <div class="route-card-list"> |
| | | <div v-for="route in routeList" |
| | | :key="route.id" |
| | | class="route-card"> |
| | | <div class="card-header"> |
| | | <div class="route-info"> |
| | | <span class="route-name"><el-icon style="margin-right: 8px;line-height: 30px;"> |
| | | <ScaleToOriginal /> |
| | | </el-icon>{{ route.routeName }}<el-tag style="margin-left: 8px" |
| | | :type="route.status == 1 ? 'warning' : 'success'">{{ route.status == 1 ? 'è稿' : 'æ¹å' }}</el-tag></span> |
| | | <span class="route-code">{{ route.routeCode }}</span> |
| | | </div> |
| | | <div class="route-actions"> |
| | | <el-button v-if="route.status === '1'" |
| | | link |
| | | type="success" |
| | | @click="handleApproveRoute(route)"> |
| | | <el-icon> |
| | | <Check /> |
| | | </el-icon> |
| | | æ¹å |
| | | </el-button> |
| | | <el-button v-if="route.status === '2'" |
| | | link |
| | | type="warning" |
| | | @click="handleRevokeApproveRoute(route)"> |
| | | <el-icon> |
| | | <Close /> |
| | | </el-icon> |
| | | æ¤éæ¹å |
| | | </el-button> |
| | | <el-button link |
| | | type="primary" |
| | | @click="handleEditRoute(route)"> |
| | | <el-icon> |
| | | <Edit /> |
| | | </el-icon> |
| | | ç¼è¾ |
| | | </el-button> |
| | | <el-button link |
| | | type="danger" |
| | | @click="handleDeleteRoute(route)"> |
| | | <el-icon> |
| | | <Delete /> |
| | | </el-icon> |
| | | å é¤ |
| | | </el-button> |
| | | </div> |
| | | </div> |
| | | <div class="card-body"> |
| | | <div class="route-desc">{{ route.routeDesc || 'ææ æè¿°' }}</div> |
| | | <el-button type="primary" |
| | | link |
| | | @click="toggleExpand(route)"> |
| | | {{ route.expanded ? 'æ¶èµ·' : 'å±å¼å·¥åºè·¯çº¿' }} |
| | | <el-icon class="expand-icon"> |
| | | <component :is="route.expanded ? 'ArrowUp' : 'ArrowDown'" /> |
| | | </el-icon> |
| | | </el-button> |
| | | </div> |
| | | <div v-if="route.expanded" |
| | | class="process-route"> |
| | | <div class="process-flow"> |
| | | <div v-for="(process, index) in route.processList" |
| | | :key="process.id" |
| | | class="process-flow-item" |
| | | draggable="true" |
| | | @dragstart="handleDragStart($event, index, route.id)" |
| | | @dragover="handleDragOver($event)" |
| | | @drop="handleDrop($event, index, route.id)" |
| | | @dragend="handleDragEnd"> |
| | | <div class="process-node" |
| | | :class="{ expanded: process.expanded }"> |
| | | <div class="process-node-header"> |
| | | <div class="process-number">{{ index + 1 }}</div> |
| | | <div class="process-actions"> |
| | | <el-button link |
| | | type="danger" |
| | | @click="handleDeleteProcess(route.id, process)"> |
| | | <el-icon> |
| | | <Delete /> |
| | | </el-icon> |
| | | </el-button> |
| | | </div> |
| | | </div> |
| | | <div class="process-node-body"> |
| | | <div class="process-code">{{ process.processCode }}</div> |
| | | <div class="process-name">{{ process.processName }}</div> |
| | | <div class="process-desc">{{ process.processDesc || 'ææ æè¿°' }}</div> |
| | | </div> |
| | | <div class="process-node-footer"> |
| | | <!-- <el-tag size="small" |
| | | :type="process.status === '1' ? 'success' : 'info'"> |
| | | {{ process.status === '1' ? 'å¯ç¨' : 'åç¨' }} |
| | | </el-tag> --> |
| | | <el-button type="primary" |
| | | link |
| | | size="small" |
| | | @click="toggleProcessParams(process)"> |
| | | {{ process.expanded ? 'æ¶èµ·åæ°' : 'å±å¼åæ°' }} |
| | | ({{ process.paramList?.length || 0 }}) |
| | | </el-button> |
| | | </div> |
| | | <div v-if="process.expanded" |
| | | class="process-params-section"> |
| | | <div class="params-header"> |
| | | <span>åæ°å表</span> |
| | | <el-button type="primary" |
| | | link |
| | | size="small" |
| | | @click="handleAddParam(route.id, process)"> |
| | | <el-icon> |
| | | <Plus /> |
| | | </el-icon>æ°å¢ |
| | | </el-button> |
| | | </div> |
| | | <div class="params-list"> |
| | | <div v-for="param in process.paramList" |
| | | :key="param.id" |
| | | class="param-item"> |
| | | <div class="param-info"> |
| | | <span class="param-code">{{ param.parameterCode }}</span> |
| | | <span class="param-name">{{ param.parameterName }}</span> |
| | | <!-- <el-tag size="small" |
| | | style="margin-right: 20px;" |
| | | :type="getParamTypeTag(param.parameterType)"> |
| | | {{ param.parameterType }} |
| | | </el-tag> --> |
| | | <span class="param-value">æ åå¼ï¼{{ param.standardValue }} {{ param.unit }}</span> |
| | | </div> |
| | | <div class="param-actions"> |
| | | <el-button link |
| | | type="primary" |
| | | size="small" |
| | | @click="handleEditParam(route.id, process, param)"> |
| | | ç¼è¾ |
| | | </el-button> |
| | | <el-button link |
| | | type="danger" |
| | | size="small" |
| | | @click="handleDeleteParam(route.id, process, param)"> |
| | | å é¤ |
| | | </el-button> |
| | | </div> |
| | | </div> |
| | | <el-empty v-if="!process.paramList || process.paramList.length === 0" |
| | | description="ææ åæ°" |
| | | :image-size="50" /> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div v-if="index < route.processList.length - 1" |
| | | class="flow-arrow"> |
| | | <el-icon> |
| | | <Right /> |
| | | </el-icon> |
| | | </div> |
| | | </div> |
| | | <div class="add-process-node" |
| | | @click="handleSelectProcess(route, index)"> |
| | | <el-icon> |
| | | <Plus /> |
| | | </el-icon> |
| | | <span>æ°å¢å·¥åº</span> |
| | | </div> |
| | | </div> |
| | | <el-empty v-if="!route.processList || route.processList.length === 0" |
| | | description="ææ å·¥åº" |
| | | :image-size="80" /> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <!-- å·¥èºè·¯çº¿æ°å¢/ç¼è¾å¯¹è¯æ¡ --> |
| | | <el-dialog v-model="routeDialogVisible" |
| | | :title="isRouteEdit ? 'ç¼è¾å·¥èºè·¯çº¿' : 'æ°å¢å·¥èºè·¯çº¿'" |
| | | width="500px"> |
| | | <el-form :model="routeForm" |
| | | :rules="routeRules" |
| | | ref="routeFormRef" |
| | | label-width="120px"> |
| | | <el-form-item label="路线ç¼ç " |
| | | prop="routeCode"> |
| | | <el-input v-model="routeForm.routeCode" |
| | | placeholder="请è¾å
¥è·¯çº¿ç¼ç " /> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" @click="handleQuery">æç´¢</el-button> |
| | | <el-form-item label="路线åç§°" |
| | | prop="routeName"> |
| | | <el-input v-model="routeForm.routeName" |
| | | placeholder="请è¾å
¥è·¯çº¿åç§°" /> |
| | | </el-form-item> |
| | | <el-form-item label="路线æè¿°" |
| | | prop="routeDesc"> |
| | | <el-input v-model="routeForm.routeDesc" |
| | | type="textarea" |
| | | :rows="3" |
| | | placeholder="请è¾å
¥è·¯çº¿æè¿°" /> |
| | | </el-form-item> |
| | | <!-- <el-form-item label="ç¶æ" |
| | | prop="status"> |
| | | <el-radio-group v-model="routeForm.status"> |
| | | <el-radio label="1">å¯ç¨</el-radio> |
| | | <el-radio label="0">åç¨</el-radio> |
| | | </el-radio-group> |
| | | </el-form-item> --> |
| | | </el-form> |
| | | <template #footer> |
| | | <span class="dialog-footer"> |
| | | <el-button @click="routeDialogVisible = false">åæ¶</el-button> |
| | | <el-button type="primary" |
| | | @click="handleRouteSubmit">ç¡®å®</el-button> |
| | | </span> |
| | | </template> |
| | | </el-dialog> |
| | | <!-- å·¥åºæ°å¢/ç¼è¾å¯¹è¯æ¡ --> |
| | | <el-dialog v-model="processDialogVisible" |
| | | :title="isProcessEdit ? 'ç¼è¾å·¥åº' : 'æ°å¢å·¥åº'" |
| | | width="500px"> |
| | | <el-form :model="processForm" |
| | | :rules="processRules" |
| | | ref="processFormRef" |
| | | label-width="120px"> |
| | | <el-form-item label="å·¥åºç¼ç " |
| | | prop="processCode"> |
| | | <el-input v-model="processForm.processCode" |
| | | placeholder="请è¾å
¥å·¥åºç¼ç " /> |
| | | </el-form-item> |
| | | <el-form-item label="å·¥åºåç§°" |
| | | prop="processName"> |
| | | <el-input v-model="processForm.processName" |
| | | placeholder="请è¾å
¥å·¥åºåç§°" /> |
| | | </el-form-item> |
| | | <el-form-item label="å·¥åºæè¿°" |
| | | prop="processDesc"> |
| | | <el-input v-model="processForm.processDesc" |
| | | type="textarea" |
| | | :rows="3" |
| | | placeholder="请è¾å
¥å·¥åºæè¿°" /> |
| | | </el-form-item> |
| | | <el-form-item label="ç¶æ" |
| | | prop="status"> |
| | | <el-radio-group v-model="processForm.status"> |
| | | <el-radio label="1">å¯ç¨</el-radio> |
| | | <el-radio label="0">åç¨</el-radio> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | </el-form> |
| | | <template #footer> |
| | | <span class="dialog-footer"> |
| | | <el-button @click="processDialogVisible = false">åæ¶</el-button> |
| | | <el-button type="primary" |
| | | @click="handleProcessSubmit">ç¡®å®</el-button> |
| | | </span> |
| | | </template> |
| | | </el-dialog> |
| | | <!-- 鿩工åºå¯¹è¯æ¡ --> |
| | | <el-dialog v-model="selectProcessDialogVisible" |
| | | title="鿩工åº" |
| | | width="1000px"> |
| | | <div class="process-select-container"> |
| | | <!-- 左侧工åºå表 --> |
| | | <div class="process-list-area"> |
| | | <div class="area-title">å¯éå·¥åº</div> |
| | | <div class="search-box"> |
| | | <el-input v-model="processSearchKeyword" |
| | | placeholder="请è¾å
¥å·¥åºåç§°æç´¢" |
| | | clearable |
| | | size="small" |
| | | @input="handleProcessSearch"> |
| | | <template #prefix> |
| | | <el-icon> |
| | | <Search /> |
| | | </el-icon> |
| | | </template> |
| | | </el-input> |
| | | </div> |
| | | <div class="table_list"> |
| | | <div style="text-align: right" class="mb10"> |
| | | <el-button type="primary" @click="showNewModal">æ°å¢å·¥èºè·¯çº¿</el-button> |
| | | <el-button type="danger" @click="handleDelete" :disabled="selectedRows.length === 0" plain>å é¤å·¥èºè·¯çº¿</el-button> |
| | | <el-table :data="filteredProcessList" |
| | | height="360" |
| | | border |
| | | highlight-current-row |
| | | @current-change="handleProcessSelect"> |
| | | <el-table-column prop="processCode" |
| | | label="å·¥åºç¼å·" |
| | | width="100" /> |
| | | <el-table-column prop="processName" |
| | | label="å·¥åºåç§°" /> |
| | | <el-table-column prop="processDesc" |
| | | label="å·¥åºæè¿°" /> |
| | | <el-table-column prop="status" |
| | | label="ç¶æ" |
| | | width="80"> |
| | | <template #default="scope"> |
| | | <el-tag size="small" |
| | | :type="scope.row.status === '1' ? 'success' : 'info'"> |
| | | {{ scope.row.status === '1' ? 'å¯ç¨' : 'åç¨' }} |
| | | </el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </div> |
| | | <PIMTable |
| | | rowKey="id" |
| | | :column="tableColumn" |
| | | :tableData="tableData" |
| | | :page="page" |
| | | :isSelection="true" |
| | | @selection-change="handleSelectionChange" |
| | | :tableLoading="tableLoading" |
| | | @pagination="pagination" |
| | | :total="page.total" |
| | | /> |
| | | <!-- å³ä¾§å·¥åºè¯¦æ
--> |
| | | <div class="process-detail-area"> |
| | | <div class="area-title">å·¥åºè¯¦æ
</div> |
| | | <el-form v-if="selectedProcessItem" |
| | | :model="selectedProcessItem" |
| | | label-width="100px" |
| | | class="process-detail-form"> |
| | | <el-form-item label="å·¥åºç¼å·"> |
| | | <span class="detail-text">{{ selectedProcessItem.processCode }}</span> |
| | | </el-form-item> |
| | | <el-form-item label="å·¥åºåç§°"> |
| | | <span class="detail-text">{{ selectedProcessItem.processName }}</span> |
| | | </el-form-item> |
| | | <el-form-item label="å·¥åºæè¿°"> |
| | | <span class="detail-text">{{ selectedProcessItem.processDesc || '-' }}</span> |
| | | </el-form-item> |
| | | <el-form-item label="ç¶æ"> |
| | | <el-tag size="small" |
| | | :type="selectedProcessItem.status === '1' ? 'success' : 'info'"> |
| | | {{ selectedProcessItem.status === '1' ? 'å¯ç¨' : 'åç¨' }} |
| | | </el-tag> |
| | | </el-form-item> |
| | | <el-form-item label="åæ°æ°é"> |
| | | <span class="detail-text">{{ selectedProcessItem.paramCount || 0 }}个</span> |
| | | </el-form-item> |
| | | </el-form> |
| | | <el-empty v-else |
| | | description="请ä»å·¦ä¾§éæ©å·¥åº" /> |
| | | </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" |
| | | @completed="getList" |
| | | /> |
| | | </div> |
| | | <template #footer> |
| | | <span class="dialog-footer"> |
| | | <el-button @click="selectProcessDialogVisible = false">åæ¶</el-button> |
| | | <el-button type="primary" |
| | | :disabled="!selectedProcessItem" |
| | | @click="handleProcessSelectSubmit">ç¡®å®</el-button> |
| | | </span> |
| | | </template> |
| | | </el-dialog> |
| | | <!-- åæ°æ°å¢/ç¼è¾å¯¹è¯æ¡ --> |
| | | <el-dialog v-model="paramDialogVisible" |
| | | :title="isParamEdit ? 'ç¼è¾åæ°' : 'æ°å¢åæ°'" |
| | | width="500px"> |
| | | <el-form :model="paramForm" |
| | | :rules="paramRules" |
| | | ref="paramFormRef" |
| | | label-width="120px"> |
| | | <el-form-item label="åæ°ç¼å·" |
| | | prop="parameterCode"> |
| | | <el-input v-model="paramForm.parameterCode" |
| | | placeholder="请è¾å
¥åæ°ç¼å·" /> |
| | | </el-form-item> |
| | | <el-form-item label="åæ°åç§°" |
| | | prop="parameterName"> |
| | | <el-input v-model="paramForm.parameterName" |
| | | placeholder="请è¾å
¥åæ°åç§°" /> |
| | | </el-form-item> |
| | | <el-form-item label="åæ°æ¨¡å¼" |
| | | prop="parameterType2"> |
| | | <el-select v-model="paramForm.parameterType2" |
| | | placeholder="è¯·éæ©åæ°æ¨¡å¼"> |
| | | <el-option label="åå¼" |
| | | value="1" /> |
| | | <el-option label="åºé´" |
| | | value="2" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="åæ°ç±»å" |
| | | prop="parameterType"> |
| | | <el-select v-model="paramForm.parameterType" |
| | | @change="handleParamTypeChange" |
| | | placeholder="è¯·éæ©åæ°ç±»å"> |
| | | <el-option label="æ°å¼æ ¼å¼" |
| | | value="æ°å¼æ ¼å¼" /> |
| | | <el-option label="ææ¬æ ¼å¼" |
| | | value="ææ¬æ ¼å¼" /> |
| | | <el-option label="䏿é项" |
| | | value="䏿é项" /> |
| | | <el-option label="æ¶é´æ ¼å¼" |
| | | value="æ¶é´æ ¼å¼" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item v-if="paramForm.parameterType === '䏿é项'" |
| | | label="æ°æ®åå
¸" |
| | | prop="parameterFormat"> |
| | | <el-select v-model="paramForm.parameterFormat" |
| | | placeholder="è¯·éæ©æ°æ®åå
¸"> |
| | | <el-option v-for="item in dictTypes" |
| | | :key="item.dictType" |
| | | :label="item.dictName" |
| | | :value="item.dictType" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item v-else-if="paramForm.parameterType === 'æ¶é´æ ¼å¼'" |
| | | label="æ¶é´æ ¼å¼" |
| | | prop="parameterFormat"> |
| | | <el-select v-model="paramForm.parameterFormat" |
| | | placeholder="è¯·éæ©æ¶é´æ ¼å¼"> |
| | | <el-option label="YYYY-MM-DD HH:mm:ss" |
| | | value="YYYY-MM-DD HH:mm:ss" /> |
| | | <el-option label="YYYY-MM-DD" |
| | | value="YYYY-MM-DD" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item v-else |
| | | label="åæ°æ ¼å¼" |
| | | prop="parameterFormat"> |
| | | <el-input v-model="paramForm.parameterFormat" |
| | | placeholder="请è¾å
¥åæ°æ ¼å¼" /> |
| | | </el-form-item> |
| | | <el-form-item label="æ åå¼" |
| | | prop="standardValue"> |
| | | <el-input v-model="paramForm.standardValue" |
| | | placeholder="请è¾å
¥æ åå¼" /> |
| | | </el-form-item> |
| | | <el-form-item label="åä½" |
| | | prop="unit"> |
| | | <el-input v-model="paramForm.unit" |
| | | placeholder="请è¾å
¥åä½" /> |
| | | </el-form-item> |
| | | </el-form> |
| | | <template #footer> |
| | | <span class="dialog-footer"> |
| | | <el-button @click="paramDialogVisible = false">åæ¶</el-button> |
| | | <el-button type="primary" |
| | | @click="handleParamSubmit">ç¡®å®</el-button> |
| | | </span> |
| | | </template> |
| | | </el-dialog> |
| | | </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 {listPage, del} from "@/api/productionManagement/processRoute.js"; |
| | | import { useRouter } from 'vue-router' |
| | | import { ref, reactive } from "vue"; |
| | | import { ElMessage, ElMessageBox } from "element-plus"; |
| | | import { |
| | | Plus, |
| | | Edit, |
| | | Delete, |
| | | ArrowUp, |
| | | ArrowDown, |
| | | Right, |
| | | Search, |
| | | Check, |
| | | Close, |
| | | } from "@element-plus/icons-vue"; |
| | | import { listType } from "@/api/system/dict/type"; |
| | | |
| | | const router = useRouter() |
| | | const data = reactive({ |
| | | searchForm: { |
| | | model: "", |
| | | }, |
| | | // å·¥èºè·¯çº¿å表 |
| | | const routeList = ref([]); |
| | | const dictTypes = ref([]); |
| | | |
| | | // å·¥èºè·¯çº¿å¯¹è¯æ¡ |
| | | const routeDialogVisible = ref(false); |
| | | const isRouteEdit = ref(false); |
| | | const routeFormRef = ref(null); |
| | | const routeForm = reactive({ |
| | | id: null, |
| | | routeCode: "", |
| | | routeName: "", |
| | | routeDesc: "", |
| | | status: "1", |
| | | }); |
| | | const { searchForm } = toRefs(data); |
| | | const tableColumn = ref([ |
| | | { |
| | | label: "å·¥èºè·¯çº¿ç¼å·", |
| | | prop: "processRouteCode", |
| | | }, |
| | | { |
| | | label: "产ååç§°", |
| | | prop: "productName", |
| | | }, |
| | | { |
| | | label: "è§æ ¼åç§°", |
| | | prop: "model", |
| | | }, |
| | | { |
| | | label: "BOMç¼å·", |
| | | prop: "bomNo", |
| | | }, |
| | | { |
| | | label: "æè¿°", |
| | | prop: "description", |
| | | }, |
| | | { |
| | | dataType: "action", |
| | | label: "æä½", |
| | | align: "center", |
| | | fixed: "right", |
| | | width: 280, |
| | | 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 record = ref({}); |
| | | const page = reactive({ |
| | | current: 1, |
| | | size: 100, |
| | | total: 0, |
| | | const routeRules = { |
| | | routeCode: [{ required: true, message: "请è¾å
¥è·¯çº¿ç¼ç ", trigger: "blur" }], |
| | | routeName: [{ required: true, message: "请è¾å
¥è·¯çº¿åç§°", trigger: "blur" }], |
| | | }; |
| | | |
| | | // å·¥åºå¯¹è¯æ¡ |
| | | const processDialogVisible = ref(false); |
| | | const isProcessEdit = ref(false); |
| | | const processFormRef = ref(null); |
| | | const currentRouteId = ref(null); |
| | | const processForm = reactive({ |
| | | id: null, |
| | | processCode: "", |
| | | processName: "", |
| | | processDesc: "", |
| | | status: "1", |
| | | }); |
| | | const { proxy } = getCurrentInstance() |
| | | |
| | | // æ¥è¯¢å表 |
| | | /** æç´¢æé®æä½ */ |
| | | const handleQuery = () => { |
| | | page.current = 1; |
| | | getList(); |
| | | const processRules = { |
| | | processCode: [{ required: true, message: "请è¾å
¥å·¥åºç¼ç ", trigger: "blur" }], |
| | | processName: [{ required: true, message: "请è¾å
¥å·¥åºåç§°", trigger: "blur" }], |
| | | }; |
| | | |
| | | const pagination = (obj) => { |
| | | page.current = obj.page; |
| | | page.size = obj.limit; |
| | | getList(); |
| | | }; |
| | | const getList = () => { |
| | | tableLoading.value = true; |
| | | const params = { ...searchForm.value, ...page }; |
| | | params.entryDate = undefined |
| | | listPage(params).then(res => { |
| | | tableLoading.value = false; |
| | | tableData.value = res.data.records.map(item => ({ |
| | | ...item, |
| | | })); |
| | | page.total = res.data.total; |
| | | }).catch(err => { |
| | | tableLoading.value = false; |
| | | }) |
| | | }; |
| | | // è¡¨æ ¼éæ©æ°æ® |
| | | const handleSelectionChange = (selection) => { |
| | | selectedRows.value = selection; |
| | | }; |
| | | // 鿩工åºå¯¹è¯æ¡ |
| | | const selectProcessDialogVisible = ref(false); |
| | | const availableProcessList = ref([]); |
| | | const filteredProcessList = ref([]); |
| | | const selectedProcessItem = ref(null); |
| | | const processSearchKeyword = ref(""); |
| | | const currentRouteIndex = ref(null); |
| | | |
| | | // æå¼æ°å¢å¼¹æ¡ |
| | | const showNewModal = () => { |
| | | isShowNewModal.value = true |
| | | }; |
| | | |
| | | const showEditModal = (row) => { |
| | | isShowEditModal.value = true |
| | | record.value = row |
| | | }; |
| | | |
| | | const showItemModal = (row) => { |
| | | router.push({ |
| | | path: '/productionManagement/processRouteItem', |
| | | query: { |
| | | id: row.id, |
| | | processRouteCode: row.processRouteCode || '', |
| | | productName: row.productName || '', |
| | | model: row.model || '', |
| | | bomNo: row.bomNo || '', |
| | | description: row.description || '', |
| | | type: 'route', |
| | | } |
| | | }) |
| | | }; |
| | | |
| | | // å é¤ |
| | | function handleDelete() { |
| | | const ids = selectedRows.value.map((item) => item.id); |
| | | proxy.$modal |
| | | .confirm('æ¯å¦ç¡®è®¤å é¤å·²å¾éçæ°æ®é¡¹ï¼') |
| | | .then(function () { |
| | | return del(ids); |
| | | }) |
| | | .then(() => { |
| | | getList(); |
| | | proxy.$modal.msgSuccess("å 餿å"); |
| | | }) |
| | | .catch(() => {}); |
| | | } |
| | | |
| | | onMounted(() => { |
| | | getList(); |
| | | // åæ°å¯¹è¯æ¡ |
| | | const paramDialogVisible = ref(false); |
| | | const isParamEdit = ref(false); |
| | | const paramFormRef = ref(null); |
| | | const currentProcessId = ref(null); |
| | | const paramForm = reactive({ |
| | | id: null, |
| | | parameterCode: "", |
| | | parameterName: "", |
| | | parameterType2: "1", |
| | | parameterType: "", |
| | | parameterFormat: "", |
| | | standardValue: "", |
| | | unit: "", |
| | | }); |
| | | const paramRules = { |
| | | parameterCode: [ |
| | | { required: true, message: "请è¾å
¥åæ°ç¼å·", trigger: "blur" }, |
| | | ], |
| | | parameterName: [ |
| | | { required: true, message: "请è¾å
¥åæ°åç§°", trigger: "blur" }, |
| | | ], |
| | | parameterType: [ |
| | | { required: true, message: "è¯·éæ©åæ°ç±»å", trigger: "change" }, |
| | | ], |
| | | }; |
| | | |
| | | // ææ½ç¸å
³ |
| | | const draggedItem = ref(null); |
| | | const draggedRouteId = ref(null); |
| | | |
| | | // è·åå·¥èºè·¯çº¿å表 |
| | | const getRouteList = () => { |
| | | routeList.value = [ |
| | | { |
| | | id: 1, |
| | | routeCode: "ROUTE001", |
| | | routeName: "æ åç åç产线", |
| | | routeDesc: "æ åç åç产æµç¨", |
| | | status: "1", |
| | | expanded: false, |
| | | processList: [ |
| | | { |
| | | id: 1, |
| | | processCode: "PROC001", |
| | | processName: "åæé
æ¯", |
| | | processDesc: "åææé
æ¯å·¥åº", |
| | | status: "1", |
| | | expanded: false, |
| | | paramList: [ |
| | | { |
| | | id: 1, |
| | | parameterCode: "P001", |
| | | parameterName: "æ°´æ³¥æ¯ä¾", |
| | | parameterType2: "1", |
| | | parameterType: "æ°å¼æ ¼å¼", |
| | | parameterFormat: "", |
| | | standardValue: "30", |
| | | unit: "%", |
| | | }, |
| | | { |
| | | id: 2, |
| | | parameterCode: "P002", |
| | | parameterName: "ç æ¯ä¾", |
| | | parameterType2: "1", |
| | | parameterType: "æ°å¼æ ¼å¼", |
| | | parameterFormat: "", |
| | | standardValue: "60", |
| | | unit: "%", |
| | | }, |
| | | ], |
| | | }, |
| | | { |
| | | id: 2, |
| | | processCode: "PROC002", |
| | | processName: "æ
ææ··å", |
| | | processDesc: "æ
ææ··åå·¥åº", |
| | | status: "1", |
| | | expanded: false, |
| | | paramList: [ |
| | | { |
| | | id: 3, |
| | | parameterCode: "P003", |
| | | parameterName: "æ
ææ¶é´", |
| | | parameterType2: "1", |
| | | parameterType: "æ°å¼æ ¼å¼", |
| | | parameterFormat: "", |
| | | standardValue: "5", |
| | | unit: "åé", |
| | | }, |
| | | ], |
| | | }, |
| | | { |
| | | id: 3, |
| | | processCode: "PROC003", |
| | | processName: "æµçæå", |
| | | processDesc: "æµçæåå·¥åº", |
| | | status: "1", |
| | | expanded: false, |
| | | paramList: [], |
| | | }, |
| | | ], |
| | | }, |
| | | { |
| | | id: 2, |
| | | routeCode: "ROUTE002", |
| | | routeName: "æ¿æç产线", |
| | | routeDesc: "æ¿æç产æµç¨", |
| | | status: "1", |
| | | expanded: false, |
| | | processList: [ |
| | | { |
| | | id: 4, |
| | | processCode: "PROC004", |
| | | processName: "åå²å å·¥", |
| | | processDesc: "åå²å 工工åº", |
| | | status: "1", |
| | | expanded: false, |
| | | paramList: [ |
| | | { |
| | | id: 4, |
| | | parameterCode: "P004", |
| | | parameterName: "åå²å°ºå¯¸", |
| | | parameterType2: "1", |
| | | parameterType: "ææ¬æ ¼å¼", |
| | | parameterFormat: "", |
| | | standardValue: "600x200x100", |
| | | unit: "mm", |
| | | }, |
| | | ], |
| | | }, |
| | | ], |
| | | }, |
| | | ]; |
| | | }; |
| | | |
| | | // å±å¼/æ¶èµ·å·¥èºè·¯çº¿ |
| | | const toggleExpand = route => { |
| | | route.expanded = !route.expanded; |
| | | }; |
| | | |
| | | // å±å¼/æ¶èµ·å·¥åºåæ° |
| | | const toggleProcessParams = process => { |
| | | process.expanded = !process.expanded; |
| | | }; |
| | | |
| | | // å·¥èºè·¯çº¿æä½ |
| | | const handleAddRoute = () => { |
| | | isRouteEdit.value = false; |
| | | routeForm.id = null; |
| | | routeForm.routeCode = ""; |
| | | routeForm.routeName = ""; |
| | | routeForm.routeDesc = ""; |
| | | routeForm.status = "1"; |
| | | routeDialogVisible.value = true; |
| | | }; |
| | | |
| | | const handleEditRoute = route => { |
| | | isRouteEdit.value = true; |
| | | routeForm.id = route.id; |
| | | routeForm.routeCode = route.routeCode; |
| | | routeForm.routeName = route.routeName; |
| | | routeForm.routeDesc = route.routeDesc; |
| | | routeForm.status = route.status; |
| | | routeDialogVisible.value = true; |
| | | }; |
| | | |
| | | const handleDeleteRoute = route => { |
| | | ElMessageBox.confirm("ç¡®å®è¦å é¤è¯¥å·¥èºè·¯çº¿åï¼", "æç¤º", { |
| | | confirmButtonText: "ç¡®å®", |
| | | cancelButtonText: "åæ¶", |
| | | type: "warning", |
| | | }).then(() => { |
| | | ElMessage.success("å 餿å"); |
| | | getRouteList(); |
| | | }); |
| | | }; |
| | | |
| | | const handleRouteSubmit = () => { |
| | | routeFormRef.value.validate(valid => { |
| | | if (valid) { |
| | | ElMessage.success(isRouteEdit.value ? "ç¼è¾æå" : "æ°å¢æå"); |
| | | routeDialogVisible.value = false; |
| | | getRouteList(); |
| | | } |
| | | }); |
| | | }; |
| | | |
| | | const handleApproveRoute = route => { |
| | | ElMessageBox.confirm("ç¡®å®è¦æ¹å该工èºè·¯çº¿åï¼", "æç¤º", { |
| | | confirmButtonText: "ç¡®å®", |
| | | cancelButtonText: "åæ¶", |
| | | type: "info", |
| | | }).then(() => { |
| | | route.status = "2"; |
| | | ElMessage.success("æ¹åæå"); |
| | | }); |
| | | }; |
| | | |
| | | const handleRevokeApproveRoute = route => { |
| | | ElMessageBox.confirm("ç¡®å®è¦æ¤éæ¹å该工èºè·¯çº¿åï¼", "æç¤º", { |
| | | confirmButtonText: "ç¡®å®", |
| | | cancelButtonText: "åæ¶", |
| | | type: "warning", |
| | | }).then(() => { |
| | | route.status = "1"; |
| | | ElMessage.success("æ¤éæ¹åæå"); |
| | | }); |
| | | }; |
| | | |
| | | // å·¥åºæä½ |
| | | const handleSelectProcess = (route, index) => { |
| | | currentRouteId.value = route.id; |
| | | currentRouteIndex.value = index; |
| | | // è·åå¯éå·¥åºå表ï¼åæ°æ®ï¼ |
| | | availableProcessList.value = [ |
| | | { |
| | | id: 1, |
| | | processCode: "PROC001", |
| | | processName: "åæé
æ¯", |
| | | processDesc: "åææé
æ¯å·¥åº", |
| | | status: "1", |
| | | paramCount: 3, |
| | | }, |
| | | { |
| | | id: 2, |
| | | processCode: "PROC002", |
| | | processName: "æ
ææ··å", |
| | | processDesc: "æ
ææ··åå·¥åº", |
| | | status: "1", |
| | | paramCount: 2, |
| | | }, |
| | | { |
| | | id: 3, |
| | | processCode: "PROC003", |
| | | processName: "æµçæå", |
| | | processDesc: "æµçæåå·¥åº", |
| | | status: "1", |
| | | paramCount: 4, |
| | | }, |
| | | { |
| | | id: 4, |
| | | processCode: "PROC004", |
| | | processName: "è¸åå
»æ¤", |
| | | processDesc: "è¸åå
»æ¤å·¥åº", |
| | | status: "0", |
| | | paramCount: 2, |
| | | }, |
| | | { |
| | | id: 5, |
| | | processCode: "PROC005", |
| | | processName: "åå²å å·¥", |
| | | processDesc: "åå²å 工工åº", |
| | | status: "1", |
| | | paramCount: 3, |
| | | }, |
| | | ]; |
| | | filteredProcessList.value = availableProcessList.value; |
| | | processSearchKeyword.value = ""; |
| | | selectedProcessItem.value = null; |
| | | selectProcessDialogVisible.value = true; |
| | | }; |
| | | |
| | | const handleEditProcess = (routeId, process) => { |
| | | currentRouteId.value = routeId; |
| | | isProcessEdit.value = true; |
| | | processForm.id = process.id; |
| | | processForm.processCode = process.processCode; |
| | | processForm.processName = process.processName; |
| | | processForm.processDesc = process.processDesc; |
| | | processForm.status = process.status; |
| | | processDialogVisible.value = true; |
| | | }; |
| | | |
| | | const handleDeleteProcess = (routeId, process) => { |
| | | ElMessageBox.confirm("ç¡®å®è¦å é¤è¯¥å·¥åºåï¼", "æç¤º", { |
| | | confirmButtonText: "ç¡®å®", |
| | | cancelButtonText: "åæ¶", |
| | | type: "warning", |
| | | }).then(() => { |
| | | ElMessage.success("å 餿å"); |
| | | getRouteList(); |
| | | }); |
| | | }; |
| | | |
| | | const handleProcessSubmit = () => { |
| | | processFormRef.value.validate(valid => { |
| | | if (valid) { |
| | | ElMessage.success(isProcessEdit.value ? "ç¼è¾æå" : "æ°å¢æå"); |
| | | processDialogVisible.value = false; |
| | | getRouteList(); |
| | | } |
| | | }); |
| | | }; |
| | | |
| | | // 鿩工åºç¸å
³æ¹æ³ |
| | | const handleProcessSearch = () => { |
| | | const keyword = processSearchKeyword.value.trim().toLowerCase(); |
| | | if (!keyword) { |
| | | filteredProcessList.value = availableProcessList.value; |
| | | } else { |
| | | filteredProcessList.value = availableProcessList.value.filter(item => |
| | | item.processName.toLowerCase().includes(keyword) |
| | | ); |
| | | } |
| | | }; |
| | | |
| | | const handleProcessSelect = row => { |
| | | selectedProcessItem.value = row; |
| | | }; |
| | | |
| | | const handleProcessSelectSubmit = () => { |
| | | if (!selectedProcessItem.value) { |
| | | ElMessage.warning("请å
éæ©ä¸ä¸ªå·¥åº"); |
| | | return; |
| | | } |
| | | |
| | | // æ£æ¥å·¥åºæ¯å¦å·²åå¨ |
| | | const route = routeList.value[currentRouteIndex.value]; |
| | | const exists = route.processList.some( |
| | | p => p.id === selectedProcessItem.value.id |
| | | ); |
| | | if (exists) { |
| | | ElMessage.warning("该工åºå·²åå¨äºå·¥èºè·¯çº¿ä¸"); |
| | | return; |
| | | } |
| | | |
| | | // æ·»å å·¥åºå°å·¥èºè·¯çº¿ |
| | | const newProcess = { |
| | | id: Date.now(), |
| | | processCode: selectedProcessItem.value.processCode, |
| | | processName: selectedProcessItem.value.processName, |
| | | processDesc: selectedProcessItem.value.processDesc, |
| | | status: selectedProcessItem.value.status, |
| | | paramList: [], |
| | | expanded: false, |
| | | }; |
| | | |
| | | route.processList.push(newProcess); |
| | | ElMessage.success("æ·»å å·¥åºæå"); |
| | | selectProcessDialogVisible.value = false; |
| | | }; |
| | | |
| | | // åæ°æä½ |
| | | const handleAddParam = (routeId, process) => { |
| | | currentRouteId.value = routeId; |
| | | currentProcessId.value = process.id; |
| | | isParamEdit.value = false; |
| | | paramForm.id = null; |
| | | paramForm.parameterCode = ""; |
| | | paramForm.parameterName = ""; |
| | | paramForm.parameterType2 = "1"; |
| | | paramForm.parameterType = ""; |
| | | paramForm.parameterFormat = ""; |
| | | paramForm.standardValue = ""; |
| | | paramForm.unit = ""; |
| | | paramDialogVisible.value = true; |
| | | }; |
| | | |
| | | const handleEditParam = (routeId, process, param) => { |
| | | currentRouteId.value = routeId; |
| | | currentProcessId.value = process.id; |
| | | isParamEdit.value = true; |
| | | paramForm.id = param.id; |
| | | paramForm.parameterCode = param.parameterCode; |
| | | paramForm.parameterName = param.parameterName; |
| | | paramForm.parameterType2 = param.parameterType2 || "1"; |
| | | paramForm.parameterType = param.parameterType; |
| | | paramForm.parameterFormat = param.parameterFormat; |
| | | paramForm.standardValue = param.standardValue; |
| | | paramForm.unit = param.unit; |
| | | paramDialogVisible.value = true; |
| | | }; |
| | | |
| | | const handleDeleteParam = (routeId, process, param) => { |
| | | ElMessageBox.confirm("ç¡®å®è¦å é¤è¯¥åæ°åï¼", "æç¤º", { |
| | | confirmButtonText: "ç¡®å®", |
| | | cancelButtonText: "åæ¶", |
| | | type: "warning", |
| | | }).then(() => { |
| | | ElMessage.success("å 餿å"); |
| | | getRouteList(); |
| | | }); |
| | | }; |
| | | |
| | | const handleParamSubmit = () => { |
| | | paramFormRef.value.validate(valid => { |
| | | if (valid) { |
| | | ElMessage.success(isParamEdit.value ? "ç¼è¾æå" : "æ°å¢æå"); |
| | | paramDialogVisible.value = false; |
| | | getRouteList(); |
| | | } |
| | | }); |
| | | }; |
| | | |
| | | const handleParamTypeChange = () => { |
| | | if (paramForm.parameterType === "æ°å¼æ ¼å¼") { |
| | | paramForm.parameterFormat = "#.0000"; |
| | | } else if (paramForm.parameterType === "æ¶é´æ ¼å¼") { |
| | | paramForm.parameterFormat = "YYYY-MM-DD HH:mm:ss"; |
| | | } else { |
| | | paramForm.parameterFormat = ""; |
| | | } |
| | | }; |
| | | |
| | | const getParamTypeTag = type => { |
| | | const typeMap = { |
| | | æ°å¼æ ¼å¼: "primary", |
| | | ææ¬æ ¼å¼: "info", |
| | | 䏿é项: "warning", |
| | | æ¶é´æ ¼å¼: "success", |
| | | }; |
| | | return typeMap[type] || "default"; |
| | | }; |
| | | |
| | | // ææ½æåº |
| | | const handleDragStart = (event, index, routeId) => { |
| | | draggedItem.value = index; |
| | | draggedRouteId.value = routeId; |
| | | event.dataTransfer.effectAllowed = "move"; |
| | | }; |
| | | |
| | | const handleDragOver = event => { |
| | | event.preventDefault(); |
| | | event.dataTransfer.dropEffect = "move"; |
| | | }; |
| | | |
| | | const handleDrop = (event, dropIndex, routeId) => { |
| | | event.preventDefault(); |
| | | if (draggedItem.value === null || draggedItem.value === dropIndex) return; |
| | | |
| | | const route = routeList.value.find(r => r.id === routeId); |
| | | if (route && route.processList) { |
| | | const draggedProcess = route.processList[draggedItem.value]; |
| | | route.processList.splice(draggedItem.value, 1); |
| | | route.processList.splice(dropIndex, 0, draggedProcess); |
| | | ElMessage.success("æåºæå"); |
| | | } |
| | | }; |
| | | |
| | | const handleDragEnd = () => { |
| | | draggedItem.value = null; |
| | | draggedRouteId.value = null; |
| | | }; |
| | | |
| | | // è·åæ°æ®åå
¸ |
| | | const getDictTypes = () => { |
| | | listType({ pageNum: 1, pageSize: 1000 }).then(res => { |
| | | dictTypes.value = res.rows || []; |
| | | }); |
| | | }; |
| | | |
| | | getRouteList(); |
| | | getDictTypes(); |
| | | </script> |
| | | |
| | | <style scoped></style> |
| | | <style scoped lang="scss"> |
| | | .app-container { |
| | | padding: 20px; |
| | | background-color: #f0f2f5; |
| | | min-height: calc(100vh - 84px); |
| | | } |
| | | |
| | | .route-header { |
| | | margin-bottom: 20px; |
| | | |
| | | .add-route-btn { |
| | | width: 100%; |
| | | display: inline-flex; |
| | | flex-direction: column; |
| | | align-items: center; |
| | | justify-content: center; |
| | | min-width: 120px; |
| | | height: 100px; |
| | | border: 2px dashed #dcdfe6; |
| | | border-radius: 12px; |
| | | background: #fafafa; |
| | | cursor: pointer; |
| | | transition: all 0.3s ease; |
| | | color: #909399; |
| | | padding: 0 20px; |
| | | |
| | | .el-icon { |
| | | font-size: 24px; |
| | | margin-bottom: 8px; |
| | | } |
| | | |
| | | span { |
| | | font-size: 13px; |
| | | } |
| | | |
| | | &:hover { |
| | | border-color: #409eff; |
| | | background: #ecf5ff; |
| | | color: #409eff; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .route-card-list { |
| | | display: flex; |
| | | flex-direction: column; |
| | | gap: 20px; |
| | | } |
| | | |
| | | .route-card { |
| | | background: #fff; |
| | | border-radius: 8px; |
| | | box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1); |
| | | overflow: hidden; |
| | | |
| | | .card-header { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | padding: 20px 40px; |
| | | border-bottom: 1px solid #ebeef5; |
| | | background: #f8f9fa; |
| | | |
| | | .route-info { |
| | | display: flex; |
| | | // flex-direction: column; |
| | | // justify-content: center; |
| | | // items-align: center; |
| | | gap: 4px; |
| | | |
| | | .route-code { |
| | | font-size: 12px; |
| | | color: #909399; |
| | | font-family: "Courier New", monospace; |
| | | line-height: 30px; |
| | | } |
| | | |
| | | .route-name { |
| | | font-size: 18px; |
| | | font-weight: 600; |
| | | color: #303133; |
| | | display: flex; |
| | | align-items: center; |
| | | } |
| | | } |
| | | |
| | | .route-actions { |
| | | display: flex; |
| | | gap: 8px; |
| | | |
| | | // .el-button { |
| | | // color: #409eff; |
| | | // } |
| | | } |
| | | } |
| | | |
| | | .card-body { |
| | | padding: 16px 40px; |
| | | |
| | | .route-desc { |
| | | font-size: 14px; |
| | | color: #606266; |
| | | margin-bottom: 12px; |
| | | } |
| | | |
| | | .expand-icon { |
| | | margin-left: 4px; |
| | | } |
| | | } |
| | | |
| | | .process-route { |
| | | padding: 0 20px 20px; |
| | | background: #f5f7fa; |
| | | border-top: 1px solid #ebeef5; |
| | | |
| | | .process-flow { |
| | | display: flex; |
| | | align-items: flex-start; |
| | | gap: 8px; |
| | | padding: 20px 0; |
| | | overflow-x: auto; |
| | | overflow-y: hidden; |
| | | |
| | | .process-flow-item { |
| | | display: flex; |
| | | align-items: center; |
| | | gap: 8px; |
| | | |
| | | .process-node { |
| | | background: #fff; |
| | | border-radius: 12px; |
| | | padding: 16px; |
| | | border: 2px solid #ebeef5; |
| | | cursor: move; |
| | | transition: all 0.3s ease; |
| | | // min-width: 180px; |
| | | // max-width: 220px; |
| | | width: 300px; |
| | | |
| | | &.expanded { |
| | | width: 400px; |
| | | } |
| | | |
| | | &:hover { |
| | | box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); |
| | | transform: translateY(-2px); |
| | | border-color: #409eff; |
| | | } |
| | | |
| | | &:active { |
| | | cursor: grabbing; |
| | | } |
| | | |
| | | .process-node-header { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | margin-bottom: 12px; |
| | | |
| | | .process-number { |
| | | width: 28px; |
| | | height: 28px; |
| | | border-radius: 50%; |
| | | background: #409eff; |
| | | color: #ffffff; |
| | | font-size: 12px; |
| | | font-weight: 600; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | } |
| | | |
| | | .process-actions { |
| | | display: flex; |
| | | gap: 4px; |
| | | } |
| | | } |
| | | |
| | | .process-node-body { |
| | | text-align: center; |
| | | margin-bottom: 12px; |
| | | |
| | | .process-code { |
| | | font-size: 11px; |
| | | color: #909399; |
| | | font-family: "Courier New", monospace; |
| | | margin-bottom: 4px; |
| | | } |
| | | |
| | | .process-name { |
| | | font-size: 15px; |
| | | font-weight: 600; |
| | | color: #303133; |
| | | margin-bottom: 6px; |
| | | } |
| | | |
| | | .process-desc { |
| | | font-size: 12px; |
| | | color: #606266; |
| | | overflow: hidden; |
| | | text-overflow: ellipsis; |
| | | display: -webkit-box; |
| | | -webkit-line-clamp: 2; |
| | | -webkit-box-orient: vertical; |
| | | } |
| | | } |
| | | |
| | | .process-node-footer { |
| | | display: flex; |
| | | justify-content: flex-end; |
| | | align-items: center; |
| | | padding-top: 10px; |
| | | border-top: 1px solid #ebeef5; |
| | | } |
| | | |
| | | .process-params-section { |
| | | margin-top: 12px; |
| | | padding-top: 12px; |
| | | border-top: 1px solid #ebeef5; |
| | | |
| | | .params-header { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | margin-bottom: 8px; |
| | | font-size: 13px; |
| | | font-weight: 600; |
| | | color: #303133; |
| | | } |
| | | |
| | | .params-list { |
| | | display: flex; |
| | | flex-direction: column; |
| | | gap: 6px; |
| | | max-height: 200px; |
| | | overflow-y: auto; |
| | | |
| | | .param-item { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | padding: 6px 8px; |
| | | background: #fafafa; |
| | | border-radius: 4px; |
| | | border-left: 2px solid #409eff; |
| | | font-size: 12px; |
| | | |
| | | .param-info { |
| | | display: flex; |
| | | flex-direction: row; |
| | | align-items: center; |
| | | gap: 6px; |
| | | flex: 1; |
| | | min-width: 0; |
| | | |
| | | .param-code { |
| | | font-size: 11px; |
| | | color: #e6a23c; |
| | | font-family: "Courier New", monospace; |
| | | margin-right: 20px; |
| | | } |
| | | |
| | | .param-name { |
| | | font-size: 12px; |
| | | color: #303133; |
| | | font-weight: 500; |
| | | margin-right: 20px; |
| | | } |
| | | |
| | | .param-value { |
| | | font-size: 11px; |
| | | color: #606266; |
| | | } |
| | | } |
| | | |
| | | .param-actions { |
| | | display: flex; |
| | | gap: 4px; |
| | | flex-shrink: 0; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | .flow-arrow { |
| | | display: flex; |
| | | align-items: center; |
| | | color: #c0c4cc; |
| | | font-size: 24px; |
| | | padding: 0 4px; |
| | | |
| | | .el-icon { |
| | | font-size: 20px; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .add-process-node { |
| | | display: flex; |
| | | flex-direction: column; |
| | | align-items: center; |
| | | justify-content: center; |
| | | min-width: 100px; |
| | | height: 175px; |
| | | border: 2px dashed #dcdfe6; |
| | | border-radius: 12px; |
| | | background: #fafafa; |
| | | cursor: pointer; |
| | | transition: all 0.3s ease; |
| | | color: #909399; |
| | | // margin-left: 10px; |
| | | |
| | | .el-icon { |
| | | font-size: 24px; |
| | | margin-bottom: 8px; |
| | | } |
| | | |
| | | span { |
| | | font-size: 13px; |
| | | } |
| | | |
| | | &:hover { |
| | | border-color: #409eff; |
| | | background: #ecf5ff; |
| | | color: #409eff; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | // ææ½æ¶çæ ·å¼ |
| | | .process-flow-item.dragging { |
| | | opacity: 0.5; |
| | | transform: scale(0.98); |
| | | } |
| | | |
| | | // 鿩工åºå¯¹è¯æ¡æ ·å¼ |
| | | .process-select-container { |
| | | display: flex; |
| | | gap: 20px; |
| | | height: 450px; |
| | | |
| | | .process-list-area { |
| | | flex: 1; |
| | | display: flex; |
| | | flex-direction: column; |
| | | |
| | | .area-title { |
| | | font-size: 14px; |
| | | font-weight: 600; |
| | | color: #303133; |
| | | margin-bottom: 12px; |
| | | padding-bottom: 8px; |
| | | border-bottom: 1px solid #ebeef5; |
| | | } |
| | | |
| | | .search-box { |
| | | margin-bottom: 12px; |
| | | |
| | | .el-input { |
| | | width: 100%; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .process-detail-area { |
| | | width: 380px; |
| | | display: flex; |
| | | flex-direction: column; |
| | | background: #f5f7fa; |
| | | border-radius: 8px; |
| | | padding: 16px; |
| | | |
| | | .area-title { |
| | | font-size: 14px; |
| | | font-weight: 600; |
| | | color: #303133; |
| | | margin-bottom: 16px; |
| | | padding-bottom: 8px; |
| | | border-bottom: 1px solid #ebeef5; |
| | | } |
| | | |
| | | .process-detail-form { |
| | | .el-form-item { |
| | | margin-bottom: 12px; |
| | | |
| | | .el-form-item__label { |
| | | color: #606266; |
| | | font-weight: 500; |
| | | } |
| | | } |
| | | |
| | | .detail-text { |
| | | color: #303133; |
| | | font-weight: 500; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </style> |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <div class="search_form"> |
| | | <el-form :model="searchForm" |
| | | :inline="true"> |
| | | <el-form-item label="å·¥åºåç§°:"> |
| | | <el-input v-model="searchForm.name" |
| | | placeholder="请è¾å
¥" |
| | | clearable |
| | | prefix-icon="Search" |
| | | style="width: 200px;" |
| | | @change="handleQuery" /> |
| | | </el-form-item> |
| | | <el-form-item label="å·¥åºç¼å·:"> |
| | | <el-input v-model="searchForm.no" |
| | | placeholder="请è¾å
¥" |
| | | clearable |
| | | prefix-icon="Search" |
| | | style="width: 200px;" |
| | | @change="handleQuery" /> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <div class="process-config-container"> |
| | | <!-- 左侧工åºå表 --> |
| | | <div class="process-list-section"> |
| | | <div class="section-header"> |
| | | <h3 class="section-title">å·¥åºå表</h3> |
| | | <el-button type="primary" |
| | | @click="handleQuery">æç´¢</el-button> |
| | | size="small" |
| | | @click="handleAddProcess"> |
| | | <el-icon> |
| | | <Plus /> |
| | | </el-icon>æ°å¢å·¥åº |
| | | </el-button> |
| | | </div> |
| | | <div class="process-card-list"> |
| | | <div v-for="process in processList" |
| | | :key="process.id" |
| | | class="process-card" |
| | | :class="{ active: selectedProcess?.id === process.id }" |
| | | @click="selectProcess(process)"> |
| | | <div class="card-header"> |
| | | <span class="process-code">{{ process.processCode }}</span> |
| | | <div class="card-actions"> |
| | | <el-button link |
| | | type="primary" |
| | | @click.stop="handleEditProcess(process)"> |
| | | <el-icon> |
| | | <Edit /> |
| | | </el-icon> |
| | | ç¼è¾ |
| | | </el-button> |
| | | <el-button link |
| | | type="danger" |
| | | @click.stop="handleDeleteProcess(process)"> |
| | | <el-icon> |
| | | <Delete /> |
| | | </el-icon> |
| | | å é¤ |
| | | </el-button> |
| | | </div> |
| | | </div> |
| | | <div class="card-body"> |
| | | <div class="process-name">{{ process.processName }}</div> |
| | | <div class="process-desc">{{ process.processDesc || 'ææ æè¿°' }}</div> |
| | | </div> |
| | | <div class="card-footer"> |
| | | <el-tag size="small" |
| | | :type="process.status === '1' ? 'success' : 'info'"> |
| | | {{ process.status === '1' ? 'å¯ç¨' : 'åç¨' }} |
| | | </el-tag> |
| | | <span class="param-count">åæ°: {{ process.paramCount || 0 }}个</span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <!-- å³ä¾§åæ°å表 --> |
| | | <div class="param-list-section"> |
| | | <div class="section-header"> |
| | | <h3 class="section-title"> |
| | | {{ selectedProcess ? selectedProcess.processName + ' - åæ°é
ç½®' : 'è¯·éæ©å·¥åº' }} |
| | | </h3> |
| | | <el-button type="primary" |
| | | size="small" |
| | | :disabled="!selectedProcess" |
| | | @click="handleSelectParam"> |
| | | <el-icon> |
| | | <Plus /> |
| | | </el-icon>鿩忰 |
| | | </el-button> |
| | | </div> |
| | | <div class="param-table-wrapper"> |
| | | <PIMTable v-if="selectedProcess" |
| | | rowKey="id" |
| | | :column="paramColumn" |
| | | :tableData="paramList" |
| | | :page="paramPage" |
| | | height="calc(100vh - 280px)" |
| | | :tableLoading="paramLoading" |
| | | :isSelection="false" |
| | | @pagination="handleParamPagination" /> |
| | | <div v-else |
| | | class="empty-tip"> |
| | | <el-empty description="请ä»å·¦ä¾§éæ©ä¸ä¸ªå·¥åº" /> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <!-- å·¥åºæ°å¢/ç¼è¾å¯¹è¯æ¡ --> |
| | | <el-dialog v-model="processDialogVisible" |
| | | :title="isProcessEdit ? 'ç¼è¾å·¥åº' : 'æ°å¢å·¥åº'" |
| | | width="500px"> |
| | | <el-form :model="processForm" |
| | | :rules="processRules" |
| | | ref="processFormRef" |
| | | label-width="100px"> |
| | | <el-form-item label="å·¥åºç¼ç " |
| | | prop="processCode"> |
| | | <el-input v-model="processForm.processCode" |
| | | placeholder="请è¾å
¥å·¥åºç¼ç " /> |
| | | </el-form-item> |
| | | <el-form-item label="å·¥åºåç§°" |
| | | prop="processName"> |
| | | <el-input v-model="processForm.processName" |
| | | placeholder="请è¾å
¥å·¥åºåç§°" /> |
| | | </el-form-item> |
| | | <el-form-item label="å·¥åºæè¿°" |
| | | prop="processDesc"> |
| | | <el-input v-model="processForm.processDesc" |
| | | type="textarea" |
| | | :rows="3" |
| | | placeholder="请è¾å
¥å·¥åºæè¿°" /> |
| | | </el-form-item> |
| | | <el-form-item label="ç¶æ" |
| | | prop="status"> |
| | | <el-radio-group v-model="processForm.status"> |
| | | <el-radio label="1">å¯ç¨</el-radio> |
| | | <el-radio label="0">åç¨</el-radio> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | </el-form> |
| | | </div> |
| | | <div class="table_list"> |
| | | <div style="text-align: right" |
| | | class="mb10"> |
| | | <template #footer> |
| | | <span class="dialog-footer"> |
| | | <el-button @click="processDialogVisible = false">åæ¶</el-button> |
| | | <el-button type="primary" |
| | | @click="showNewModal">æ°å¢å·¥åº</el-button> |
| | | <el-button type="info" |
| | | plain |
| | | @click="handleImport">导å
¥</el-button> |
| | | <el-button type="danger" |
| | | @click="handleDelete" |
| | | :disabled="selectedRows.length === 0" |
| | | plain>å é¤å·¥åº</el-button> |
| | | @click="handleProcessSubmit">ç¡®å®</el-button> |
| | | </span> |
| | | </template> |
| | | </el-dialog> |
| | | <!-- éæ©åæ°å¯¹è¯æ¡ --> |
| | | <el-dialog v-model="paramDialogVisible" |
| | | title="鿩忰" |
| | | width="1000px"> |
| | | <div class="param-select-container"> |
| | | <!-- 左侧忰å表 --> |
| | | <div class="param-list-area"> |
| | | <div class="area-title">å¯éåæ°</div> |
| | | <div class="search-box"> |
| | | <el-input v-model="paramSearchKeyword" |
| | | placeholder="请è¾å
¥åæ°åç§°æç´¢" |
| | | clearable |
| | | size="small" |
| | | @input="handleParamSearch"> |
| | | <template #prefix> |
| | | <el-icon> |
| | | <Search /> |
| | | </el-icon> |
| | | </template> |
| | | </el-input> |
| | | </div> |
| | | <PIMTable rowKey="id" |
| | | :column="tableColumn" |
| | | :tableData="tableData" |
| | | :page="page" |
| | | :isSelection="true" |
| | | @selection-change="handleSelectionChange" |
| | | :tableLoading="tableLoading" |
| | | @pagination="pagination" |
| | | :total="page.total"></PIMTable> |
| | | <el-table :data="filteredParamList" |
| | | height="360" |
| | | border |
| | | highlight-current-row |
| | | @current-change="handleParamSelect"> |
| | | <el-table-column prop="parameterCode" |
| | | label="åæ°ç¼å·" |
| | | width="100" /> |
| | | <el-table-column prop="parameterName" |
| | | label="åæ°åç§°" /> |
| | | <el-table-column prop="parameterType" |
| | | label="åæ°ç±»å" |
| | | width="100"> |
| | | <template #default="scope"> |
| | | <el-tag size="small" |
| | | :type="getParamTypeTag(scope.row.parameterType)"> |
| | | {{ scope.row.parameterType }} |
| | | </el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </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" /> |
| | | <ImportDialog ref="importDialogRef" |
| | | v-model="importDialogVisible" |
| | | title="导å
¥å·¥åº" |
| | | :action="importAction" |
| | | :headers="importHeaders" |
| | | :auto-upload="false" |
| | | :on-success="handleImportSuccess" |
| | | :on-error="handleImportError" |
| | | @confirm="handleImportConfirm" |
| | | @download-template="handleDownloadTemplate" |
| | | @close="handleImportClose" /> |
| | | <!-- å³ä¾§åæ°è¯¦æ
--> |
| | | <div class="param-detail-area"> |
| | | <div class="area-title">åæ°è¯¦æ
</div> |
| | | <el-form v-if="selectedParam" |
| | | :model="selectedParam" |
| | | label-width="100px" |
| | | class="param-detail-form"> |
| | | <el-form-item label="åæ°ç¼å·"> |
| | | <span class="detail-text">{{ selectedParam.parameterCode }}</span> |
| | | </el-form-item> |
| | | <el-form-item label="åæ°åç§°"> |
| | | <span class="detail-text">{{ selectedParam.parameterName }}</span> |
| | | </el-form-item> |
| | | <el-form-item label="åæ°æ¨¡å¼"> |
| | | <el-tag size="small" |
| | | :type="selectedParam.parameterType2 === '1' ? 'success' : 'warning'"> |
| | | {{ selectedParam.parameterType2 === '1' ? 'åå¼' : 'åºé´' }} |
| | | </el-tag> |
| | | </el-form-item> |
| | | <el-form-item label="åæ°ç±»å"> |
| | | <el-tag size="small" |
| | | :type="getParamTypeTag(selectedParam.parameterType)"> |
| | | {{ selectedParam.parameterType }} |
| | | </el-tag> |
| | | </el-form-item> |
| | | <el-form-item label="åæ°æ ¼å¼"> |
| | | <span class="detail-text">{{ selectedParam.parameterFormat || '-' }}</span> |
| | | </el-form-item> |
| | | <el-form-item label="æ åå¼"> |
| | | <span class="detail-text">{{ selectedParam.standardValue }}</span> |
| | | </el-form-item> |
| | | <el-form-item label="åä½"> |
| | | <span class="detail-text">{{ selectedParam.unit || '-' }}</span> |
| | | </el-form-item> |
| | | </el-form> |
| | | <el-empty v-else |
| | | description="请ä»å·¦ä¾§éæ©åæ°" /> |
| | | </div> |
| | | </div> |
| | | <template #footer> |
| | | <span class="dialog-footer"> |
| | | <el-button @click="paramDialogVisible = false">åæ¶</el-button> |
| | | <el-button type="primary" |
| | | :disabled="!selectedParam" |
| | | @click="handleParamSubmit">ç¡®å®</el-button> |
| | | </span> |
| | | </template> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { onMounted, ref, reactive, toRefs, getCurrentInstance } from "vue"; |
| | | import NewProcess from "@/views/productionManagement/productionProcess/New.vue"; |
| | | import EditProcess from "@/views/productionManagement/productionProcess/Edit.vue"; |
| | | import ImportDialog from "@/components/Dialog/ImportDialog.vue"; |
| | | import { |
| | | listPage, |
| | | del, |
| | | importData, |
| | | downloadTemplate, |
| | | } from "@/api/productionManagement/productionProcess.js"; |
| | | import { getToken } from "@/utils/auth"; |
| | | import { ref, reactive, onMounted } from "vue"; |
| | | import { ElMessage, ElMessageBox } from "element-plus"; |
| | | import { Plus, Edit, Delete, Search } from "@element-plus/icons-vue"; |
| | | import PIMTable from "@/components/PIMTable/PIMTable.vue"; |
| | | import { listType } from "@/api/system/dict/type"; |
| | | |
| | | const data = reactive({ |
| | | searchForm: { |
| | | name: "", |
| | | no: "", |
| | | }, |
| | | // å·¥åºåè¡¨æ°æ® |
| | | const processList = ref([]); |
| | | const selectedProcess = ref(null); |
| | | const processLoading = ref(false); |
| | | |
| | | // åæ°åè¡¨æ°æ® |
| | | const paramList = ref([]); |
| | | const paramLoading = ref(false); |
| | | const paramPage = reactive({ |
| | | current: 1, |
| | | size: 10, |
| | | total: 0, |
| | | }); |
| | | const { searchForm } = toRefs(data); |
| | | const tableColumn = ref([ |
| | | |
| | | // æ°æ®åå
¸ |
| | | const dictTypes = ref([]); |
| | | |
| | | // å·¥åºå¯¹è¯æ¡ |
| | | const processDialogVisible = ref(false); |
| | | const isProcessEdit = ref(false); |
| | | const processFormRef = ref(null); |
| | | const processForm = reactive({ |
| | | id: null, |
| | | processCode: "", |
| | | processName: "", |
| | | processDesc: "", |
| | | status: "1", |
| | | }); |
| | | const processRules = { |
| | | processCode: [{ required: true, message: "请è¾å
¥å·¥åºç¼ç ", trigger: "blur" }], |
| | | processName: [{ required: true, message: "请è¾å
¥å·¥åºåç§°", trigger: "blur" }], |
| | | }; |
| | | |
| | | // åæ°å¯¹è¯æ¡ |
| | | const paramDialogVisible = ref(false); |
| | | const availableParamList = ref([]); |
| | | const filteredParamList = ref([]); |
| | | const selectedParam = ref(null); |
| | | const paramSearchKeyword = ref(""); |
| | | |
| | | // åæ°è¡¨æ ¼åé
ç½® |
| | | const paramColumn = ref([ |
| | | { |
| | | label: "å·¥åºç¼å·", |
| | | prop: "no", |
| | | label: "åæ°ç¼å·", |
| | | prop: "parameterCode", |
| | | className: "code-cell", |
| | | }, |
| | | { |
| | | label: "å·¥åºåç§°", |
| | | prop: "name", |
| | | label: "åæ°åç§°", |
| | | prop: "parameterName", |
| | | }, |
| | | { |
| | | label: "å·¥èµå®é¢", |
| | | prop: "salaryQuota", |
| | | label: "åæ°æ¨¡å¼", |
| | | prop: "parameterType2", |
| | | dataType: "tag", |
| | | formatType: row => (row.parameterType2 === "1" ? "success" : "warning"), |
| | | formatData: row => (row.parameterType2 === "1" ? "åå¼" : "åºé´"), |
| | | }, |
| | | { |
| | | label: "æ¯å¦è´¨æ£", |
| | | prop: "isQuality", |
| | | formatData: (params) => { |
| | | return params ? "æ¯" : "å¦"; |
| | | label: "åæ°ç±»å", |
| | | prop: "parameterType", |
| | | dataType: "tag", |
| | | formatType: row => { |
| | | const typeMap = { |
| | | æ°å¼æ ¼å¼: "primary", |
| | | ææ¬æ ¼å¼: "info", |
| | | 䏿é项: "warning", |
| | | æ¶é´æ ¼å¼: "success", |
| | | }; |
| | | return typeMap[row.parameterType] || "default"; |
| | | }, |
| | | }, |
| | | { |
| | | label: "夿³¨", |
| | | prop: "remark", |
| | | label: "åæ°æ ¼å¼", |
| | | prop: "parameterFormat", |
| | | }, |
| | | { |
| | | label: "æ´æ°æ¶é´", |
| | | prop: "updateTime", |
| | | label: "æ åå¼", |
| | | prop: "standardValue", |
| | | className: row => (row.parameterType === "æ°å¼æ ¼å¼" ? "quantity-cell" : ""), |
| | | }, |
| | | { |
| | | dataType: "action", |
| | | label: "åä½", |
| | | prop: "unit", |
| | | }, |
| | | { |
| | | label: "æä½", |
| | | align: "center", |
| | | fixed: "right", |
| | | width: 280, |
| | | dataType: "action", |
| | | width: "100", |
| | | operation: [ |
| | | { |
| | | name: "ç¼è¾", |
| | | type: "text", |
| | | clickFun: row => { |
| | | showEditModal(row); |
| | | }, |
| | | name: "å é¤", |
| | | clickFun: row => handleDeleteParam(row), |
| | | }, |
| | | ], |
| | | }, |
| | | ]); |
| | | const tableData = ref([]); |
| | | const selectedRows = ref([]); |
| | | const tableLoading = ref(false); |
| | | const isShowNewModal = ref(false); |
| | | const isShowEditModal = ref(false); |
| | | const record = ref({}); |
| | | const importDialogVisible = ref(false); |
| | | const importDialogRef = ref(null); |
| | | const page = reactive({ |
| | | current: 1, |
| | | size: 100, |
| | | total: 0, |
| | | }); |
| | | const { proxy } = getCurrentInstance(); |
| | | |
| | | // 导å
¥ç¸å
³é
ç½® |
| | | const importAction = |
| | | import.meta.env.VITE_APP_BASE_API + "/productProcess/importData"; |
| | | const importHeaders = { Authorization: "Bearer " + getToken() }; |
| | | |
| | | // æ¥è¯¢å表 |
| | | /** æç´¢æé®æä½ */ |
| | | const handleQuery = () => { |
| | | page.current = 1; |
| | | getList(); |
| | | // è·åå·¥åºå表 |
| | | const getProcessList = () => { |
| | | // åæ°æ® |
| | | processList.value = [ |
| | | { |
| | | id: 1, |
| | | processCode: "PROC001", |
| | | processName: "åæé
æ¯", |
| | | processDesc: "åææé
æ¯å·¥åº", |
| | | status: "1", |
| | | paramCount: 3, |
| | | }, |
| | | { |
| | | id: 2, |
| | | processCode: "PROC002", |
| | | processName: "æ
ææ··å", |
| | | processDesc: "æ
ææ··åå·¥åº", |
| | | status: "1", |
| | | paramCount: 2, |
| | | }, |
| | | { |
| | | id: 3, |
| | | processCode: "PROC003", |
| | | processName: "æµçæå", |
| | | processDesc: "æµçæåå·¥åº", |
| | | status: "1", |
| | | paramCount: 4, |
| | | }, |
| | | { |
| | | id: 4, |
| | | processCode: "PROC004", |
| | | processName: "è¸åå
»æ¤", |
| | | processDesc: "è¸åå
»æ¤å·¥åº", |
| | | status: "0", |
| | | paramCount: 2, |
| | | }, |
| | | { |
| | | id: 5, |
| | | processCode: "PROC005", |
| | | processName: "åå²å å·¥", |
| | | processDesc: "åå²å 工工åº", |
| | | status: "1", |
| | | paramCount: 3, |
| | | }, |
| | | ]; |
| | | }; |
| | | |
| | | const pagination = obj => { |
| | | page.current = obj.page; |
| | | page.size = obj.limit; |
| | | getList(); |
| | | // è·ååæ°å表 |
| | | const getParamList = processId => { |
| | | paramLoading.value = true; |
| | | // åæ°æ® |
| | | setTimeout(() => { |
| | | paramLoading.value = false; |
| | | const mockData = { |
| | | 1: [ |
| | | { |
| | | id: 1, |
| | | parameterCode: "P001", |
| | | parameterName: "æ°´æ³¥æ¯ä¾", |
| | | parameterType2: "1", |
| | | parameterType: "æ°å¼æ ¼å¼", |
| | | parameterFormat: "", |
| | | standardValue: "30", |
| | | unit: "%", |
| | | }, |
| | | { |
| | | id: 2, |
| | | parameterCode: "P002", |
| | | parameterName: "ç æ¯ä¾", |
| | | parameterType2: "1", |
| | | parameterType: "æ°å¼æ ¼å¼", |
| | | parameterFormat: "", |
| | | standardValue: "60", |
| | | unit: "%", |
| | | }, |
| | | { |
| | | id: 3, |
| | | parameterCode: "P003", |
| | | parameterName: "æ°´æ¯ä¾", |
| | | parameterType2: "1", |
| | | parameterType: "æ°å¼æ ¼å¼", |
| | | parameterFormat: "", |
| | | standardValue: "10", |
| | | unit: "%", |
| | | }, |
| | | ], |
| | | 2: [ |
| | | { |
| | | id: 4, |
| | | parameterCode: "P004", |
| | | parameterName: "æ
ææ¶é´", |
| | | parameterType2: "1", |
| | | parameterType: "æ°å¼æ ¼å¼", |
| | | parameterFormat: "", |
| | | standardValue: "5", |
| | | unit: "åé", |
| | | }, |
| | | { |
| | | id: 5, |
| | | parameterCode: "P005", |
| | | parameterName: "æ
æé度", |
| | | parameterType2: "2", |
| | | parameterType: "æ°å¼æ ¼å¼", |
| | | parameterFormat: "", |
| | | standardValue: "100-200", |
| | | unit: "rpm", |
| | | }, |
| | | ], |
| | | 3: [ |
| | | { |
| | | id: 6, |
| | | parameterCode: "P006", |
| | | parameterName: "æµç温度", |
| | | parameterType2: "2", |
| | | parameterType: "æ°å¼æ ¼å¼", |
| | | parameterFormat: "", |
| | | standardValue: "20-30", |
| | | unit: "â", |
| | | }, |
| | | { |
| | | id: 7, |
| | | parameterCode: "P007", |
| | | parameterName: "æµçåå", |
| | | parameterType2: "1", |
| | | parameterType: "æ°å¼æ ¼å¼", |
| | | parameterFormat: "", |
| | | standardValue: "0.5", |
| | | unit: "MPa", |
| | | }, |
| | | { |
| | | id: 8, |
| | | parameterCode: "P008", |
| | | parameterName: "æåç¶æ", |
| | | parameterType2: "1", |
| | | parameterType: "䏿é项", |
| | | parameterFormat: "status", |
| | | standardValue: "æ£å¸¸", |
| | | unit: "", |
| | | }, |
| | | { |
| | | id: 9, |
| | | parameterCode: "P009", |
| | | parameterName: "æåæ¶é´", |
| | | parameterType2: "1", |
| | | parameterType: "æ¶é´æ ¼å¼", |
| | | parameterFormat: "YYYY-MM-DD HH:mm:ss", |
| | | standardValue: "2024-01-01 08:00:00", |
| | | unit: "", |
| | | }, |
| | | ], |
| | | 4: [ |
| | | { |
| | | id: 10, |
| | | parameterCode: "P010", |
| | | parameterName: "è¸å温度", |
| | | parameterType2: "2", |
| | | parameterType: "æ°å¼æ ¼å¼", |
| | | parameterFormat: "", |
| | | standardValue: "180-200", |
| | | unit: "â", |
| | | }, |
| | | { |
| | | id: 11, |
| | | parameterCode: "P011", |
| | | parameterName: "è¸ååå", |
| | | parameterType2: "1", |
| | | parameterType: "æ°å¼æ ¼å¼", |
| | | parameterFormat: "", |
| | | standardValue: "1.2", |
| | | unit: "MPa", |
| | | }, |
| | | ], |
| | | 5: [ |
| | | { |
| | | id: 12, |
| | | parameterCode: "P012", |
| | | parameterName: "åå²å°ºå¯¸", |
| | | parameterType2: "1", |
| | | parameterType: "ææ¬æ ¼å¼", |
| | | parameterFormat: "", |
| | | standardValue: "600x200x100", |
| | | unit: "mm", |
| | | }, |
| | | { |
| | | id: 13, |
| | | parameterCode: "P013", |
| | | parameterName: "åå²ç²¾åº¦", |
| | | parameterType2: "1", |
| | | parameterType: "æ°å¼æ ¼å¼", |
| | | parameterFormat: "", |
| | | standardValue: "±1", |
| | | unit: "mm", |
| | | }, |
| | | { |
| | | id: 14, |
| | | parameterCode: "P014", |
| | | parameterName: "åå²é度", |
| | | parameterType2: "1", |
| | | parameterType: "æ°å¼æ ¼å¼", |
| | | parameterFormat: "", |
| | | standardValue: "2", |
| | | unit: "m/min", |
| | | }, |
| | | ], |
| | | }; |
| | | const getList = () => { |
| | | tableLoading.value = true; |
| | | const params = { ...searchForm.value, ...page }; |
| | | params.entryDate = undefined; |
| | | listPage(params) |
| | | .then(res => { |
| | | tableLoading.value = false; |
| | | tableData.value = res.data.records.map(item => ({ |
| | | ...item, |
| | | })); |
| | | page.total = res.data.total; |
| | | }) |
| | | .catch(err => { |
| | | tableLoading.value = false; |
| | | paramList.value = mockData[processId] || []; |
| | | paramPage.total = paramList.value.length; |
| | | }, 300); |
| | | }; |
| | | |
| | | // éæ©å·¥åº |
| | | const selectProcess = process => { |
| | | selectedProcess.value = process; |
| | | getParamList(process.id); |
| | | }; |
| | | |
| | | // å·¥åºæä½ |
| | | const handleAddProcess = () => { |
| | | isProcessEdit.value = false; |
| | | processForm.id = null; |
| | | processForm.processCode = ""; |
| | | processForm.processName = ""; |
| | | processForm.processDesc = ""; |
| | | processForm.status = "1"; |
| | | processDialogVisible.value = true; |
| | | }; |
| | | |
| | | const handleEditProcess = process => { |
| | | isProcessEdit.value = true; |
| | | processForm.id = process.id; |
| | | processForm.processCode = process.processCode; |
| | | processForm.processName = process.processName; |
| | | processForm.processDesc = process.processDesc; |
| | | processForm.status = process.status; |
| | | processDialogVisible.value = true; |
| | | }; |
| | | |
| | | const handleDeleteProcess = process => { |
| | | ElMessageBox.confirm("ç¡®å®è¦å é¤è¯¥å·¥åºåï¼", "æç¤º", { |
| | | confirmButtonText: "ç¡®å®", |
| | | cancelButtonText: "åæ¶", |
| | | type: "warning", |
| | | }).then(() => { |
| | | ElMessage.success("å 餿å"); |
| | | getProcessList(); |
| | | if (selectedProcess.value?.id === process.id) { |
| | | selectedProcess.value = null; |
| | | paramList.value = []; |
| | | } |
| | | }); |
| | | }; |
| | | // è¡¨æ ¼éæ©æ°æ® |
| | | const handleSelectionChange = selection => { |
| | | selectedRows.value = selection; |
| | | |
| | | const handleProcessSubmit = () => { |
| | | processFormRef.value.validate(valid => { |
| | | if (valid) { |
| | | ElMessage.success(isProcessEdit.value ? "ç¼è¾æå" : "æ°å¢æå"); |
| | | processDialogVisible.value = false; |
| | | getProcessList(); |
| | | } |
| | | }); |
| | | }; |
| | | |
| | | // æå¼æ°å¢å¼¹æ¡ |
| | | const showNewModal = () => { |
| | | isShowNewModal.value = true; |
| | | // åæ°æä½ |
| | | const handleSelectParam = () => { |
| | | if (!selectedProcess.value) { |
| | | ElMessage.warning("请å
éæ©ä¸ä¸ªå·¥åº"); |
| | | return; |
| | | } |
| | | // è·åå¯éåæ°å表ï¼åæ°æ®ï¼ |
| | | availableParamList.value = [ |
| | | { |
| | | id: 101, |
| | | parameterCode: "P101", |
| | | parameterName: "温度", |
| | | parameterType2: "2", |
| | | parameterType: "æ°å¼æ ¼å¼", |
| | | parameterFormat: "", |
| | | standardValue: "20-30", |
| | | unit: "â", |
| | | }, |
| | | { |
| | | id: 102, |
| | | parameterCode: "P102", |
| | | parameterName: "åå", |
| | | parameterType2: "1", |
| | | parameterType: "æ°å¼æ ¼å¼", |
| | | parameterFormat: "", |
| | | standardValue: "0.5", |
| | | unit: "MPa", |
| | | }, |
| | | { |
| | | id: 103, |
| | | parameterCode: "P103", |
| | | parameterName: "湿度", |
| | | parameterType2: "2", |
| | | parameterType: "æ°å¼æ ¼å¼", |
| | | parameterFormat: "", |
| | | standardValue: "40-60", |
| | | unit: "%", |
| | | }, |
| | | { |
| | | id: 104, |
| | | parameterCode: "P104", |
| | | parameterName: "é度", |
| | | parameterType2: "1", |
| | | parameterType: "æ°å¼æ ¼å¼", |
| | | parameterFormat: "", |
| | | standardValue: "100", |
| | | unit: "m/min", |
| | | }, |
| | | { |
| | | id: 105, |
| | | parameterCode: "P105", |
| | | parameterName: "ç¶æ", |
| | | parameterType2: "1", |
| | | parameterType: "䏿é项", |
| | | parameterFormat: "status", |
| | | standardValue: "æ£å¸¸", |
| | | unit: "", |
| | | }, |
| | | { |
| | | id: 106, |
| | | parameterCode: "P106", |
| | | parameterName: "è®°å½æ¶é´", |
| | | parameterType2: "1", |
| | | parameterType: "æ¶é´æ ¼å¼", |
| | | parameterFormat: "YYYY-MM-DD HH:mm:ss", |
| | | standardValue: "2024-01-01 08:00:00", |
| | | unit: "", |
| | | }, |
| | | { |
| | | id: 107, |
| | | parameterCode: "P107", |
| | | parameterName: "夿³¨", |
| | | parameterType2: "1", |
| | | parameterType: "ææ¬æ ¼å¼", |
| | | parameterFormat: "", |
| | | standardValue: "æ ", |
| | | unit: "", |
| | | }, |
| | | ]; |
| | | filteredParamList.value = availableParamList.value; |
| | | paramSearchKeyword.value = ""; |
| | | selectedParam.value = null; |
| | | paramDialogVisible.value = true; |
| | | }; |
| | | |
| | | const showEditModal = row => { |
| | | isShowEditModal.value = true; |
| | | record.value = row; |
| | | const handleParamSelect = row => { |
| | | selectedParam.value = row; |
| | | }; |
| | | |
| | | // å é¤ |
| | | function handleDelete() { |
| | | const no = selectedRows.value.map(item => item.no); |
| | | const ids = selectedRows.value.map(item => item.id); |
| | | if (no.length > 2) { |
| | | proxy.$modal |
| | | .confirm( |
| | | 'æ¯å¦ç¡®è®¤å é¤å·¥åºç¼å·ä¸º"' + |
| | | no[0] + |
| | | "ã" + |
| | | no[1] + |
| | | '"ç' + |
| | | no.length + |
| | | "æ¡æ°æ®é¡¹ï¼" |
| | | ) |
| | | .then(function () { |
| | | return del(ids); |
| | | }) |
| | | .then(() => { |
| | | getList(); |
| | | proxy.$modal.msgSuccess("å 餿å"); |
| | | }) |
| | | .catch(() => {}); |
| | | const handleParamSearch = () => { |
| | | const keyword = paramSearchKeyword.value.trim().toLowerCase(); |
| | | if (!keyword) { |
| | | filteredParamList.value = availableParamList.value; |
| | | } else { |
| | | proxy.$modal |
| | | .confirm('æ¯å¦ç¡®è®¤å é¤å·¥åºç¼å·ä¸º"' + no + '"çæ°æ®é¡¹ï¼') |
| | | .then(function () { |
| | | return del(ids); |
| | | }) |
| | | .then(() => { |
| | | getList(); |
| | | proxy.$modal.msgSuccess("å 餿å"); |
| | | }) |
| | | .catch(() => {}); |
| | | } |
| | | } |
| | | |
| | | // 导å
¥ |
| | | const handleImport = () => { |
| | | importDialogVisible.value = true; |
| | | }; |
| | | |
| | | // 确认导å
¥ |
| | | const handleImportConfirm = () => { |
| | | if (importDialogRef.value) { |
| | | importDialogRef.value.submit(); |
| | | filteredParamList.value = availableParamList.value.filter(item => |
| | | item.parameterName.toLowerCase().includes(keyword) |
| | | ); |
| | | } |
| | | }; |
| | | |
| | | // 导å
¥æå |
| | | const handleImportSuccess = response => { |
| | | if (response.code === 200) { |
| | | proxy.$modal.msgSuccess("导å
¥æå"); |
| | | importDialogVisible.value = false; |
| | | if (importDialogRef.value) { |
| | | importDialogRef.value.clearFiles(); |
| | | } |
| | | getList(); |
| | | } else { |
| | | proxy.$modal.msgError(response.msg || "导å
¥å¤±è´¥"); |
| | | } |
| | | const getParamTypeTag = type => { |
| | | const typeMap = { |
| | | æ°å¼æ ¼å¼: "primary", |
| | | ææ¬æ ¼å¼: "info", |
| | | 䏿é项: "warning", |
| | | æ¶é´æ ¼å¼: "success", |
| | | }; |
| | | return typeMap[type] || "default"; |
| | | }; |
| | | |
| | | // 导å
¥å¤±è´¥ |
| | | const handleImportError = error => { |
| | | proxy.$modal.msgError("导å
¥å¤±è´¥ï¼" + (error.message || "æªç¥é误")); |
| | | }; |
| | | |
| | | // å
³é导å
¥å¼¹çª |
| | | const handleImportClose = () => { |
| | | if (importDialogRef.value) { |
| | | importDialogRef.value.clearFiles(); |
| | | } |
| | | }; |
| | | |
| | | // ä¸è½½æ¨¡æ¿ |
| | | const handleDownloadTemplate = async () => { |
| | | try { |
| | | const res = await downloadTemplate(); |
| | | const blob = new Blob([res], { |
| | | type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", |
| | | const handleDeleteParam = row => { |
| | | ElMessageBox.confirm("ç¡®å®è¦å é¤è¯¥åæ°åï¼", "æç¤º", { |
| | | confirmButtonText: "ç¡®å®", |
| | | cancelButtonText: "åæ¶", |
| | | type: "warning", |
| | | }).then(() => { |
| | | ElMessage.success("å 餿å"); |
| | | getParamList(selectedProcess.value.id); |
| | | }); |
| | | const url = window.URL.createObjectURL(blob); |
| | | const link = document.createElement("a"); |
| | | link.href = url; |
| | | link.download = "å·¥åºå¯¼å
¥æ¨¡æ¿.xlsx"; |
| | | link.click(); |
| | | window.URL.revokeObjectURL(url); |
| | | proxy.$modal.msgSuccess("模æ¿ä¸è½½æå"); |
| | | } catch (error) { |
| | | proxy.$modal.msgError("模æ¿ä¸è½½å¤±è´¥"); |
| | | } |
| | | }; |
| | | |
| | | // å¯¼åº |
| | | // const handleOut = () => { |
| | | // ElMessageBox.confirm("éä¸çå
容å°è¢«å¯¼åºï¼æ¯å¦ç¡®è®¤å¯¼åºï¼", "导åº", { |
| | | // confirmButtonText: "确认", |
| | | // cancelButtonText: "åæ¶", |
| | | // type: "warning", |
| | | // }) |
| | | // .then(() => { |
| | | // proxy.download("/salesLedger/scheduling/exportTwo", {}, "å·¥åºæäº§.xlsx"); |
| | | // }) |
| | | // .catch(() => { |
| | | // proxy.$modal.msg("已忶"); |
| | | // }); |
| | | // }; |
| | | const handleParamSubmit = () => { |
| | | if (!selectedParam.value) { |
| | | ElMessage.warning("请å
éæ©ä¸ä¸ªåæ°"); |
| | | return; |
| | | } |
| | | ElMessage.success("æ·»å æå"); |
| | | paramDialogVisible.value = false; |
| | | getParamList(selectedProcess.value.id); |
| | | }; |
| | | |
| | | const handleParamPagination = obj => { |
| | | paramPage.current = obj.page; |
| | | paramPage.size = obj.limit; |
| | | getParamList(selectedProcess.value.id); |
| | | }; |
| | | |
| | | // è·åæ°æ®åå
¸ |
| | | const getDictTypes = () => { |
| | | listType({ pageNum: 1, pageSize: 1000 }).then(res => { |
| | | dictTypes.value = res.rows || []; |
| | | }); |
| | | }; |
| | | |
| | | onMounted(() => { |
| | | getList(); |
| | | getProcessList(); |
| | | getDictTypes(); |
| | | }); |
| | | </script> |
| | | |
| | | <style scoped></style> |
| | | <style scoped lang="scss"> |
| | | .app-container { |
| | | padding: 20px; |
| | | background-color: #f0f2f5; |
| | | min-height: calc(100vh - 84px); |
| | | } |
| | | |
| | | .process-config-container { |
| | | display: flex; |
| | | gap: 20px; |
| | | height: calc(100vh - 124px); |
| | | } |
| | | |
| | | // 左侧工åºå表 |
| | | .process-list-section { |
| | | width: 370px; |
| | | background: #fff; |
| | | border-radius: 8px; |
| | | box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1); |
| | | display: flex; |
| | | flex-direction: column; |
| | | } |
| | | |
| | | .section-header { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | padding: 16px 20px; |
| | | border-bottom: 1px solid #ebeef5; |
| | | |
| | | .section-title { |
| | | margin: 0; |
| | | font-size: 16px; |
| | | font-weight: 600; |
| | | color: #303133; |
| | | } |
| | | } |
| | | |
| | | .process-card-list { |
| | | flex: 1; |
| | | overflow-y: auto; |
| | | padding: 16px; |
| | | } |
| | | |
| | | .process-card { |
| | | background: #fff; |
| | | border: 1px solid #ebeef5; |
| | | border-radius: 8px; |
| | | padding: 16px; |
| | | margin-bottom: 12px; |
| | | cursor: pointer; |
| | | transition: all 0.3s ease; |
| | | |
| | | &:hover { |
| | | box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); |
| | | transform: translateY(-2px); |
| | | } |
| | | |
| | | &.active { |
| | | border-color: #409eff; |
| | | background: #f5f7fa; |
| | | box-shadow: 0 4px 12px rgba(64, 158, 255, 0.2); |
| | | } |
| | | |
| | | .card-header { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | margin-bottom: 8px; |
| | | |
| | | .process-code { |
| | | font-size: 12px; |
| | | color: #909399; |
| | | font-family: "Courier New", monospace; |
| | | } |
| | | |
| | | .card-actions { |
| | | display: flex; |
| | | gap: 4px; |
| | | |
| | | .el-button { |
| | | padding: 4px; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .card-body { |
| | | margin-bottom: 12px; |
| | | |
| | | .process-name { |
| | | font-size: 16px; |
| | | font-weight: 600; |
| | | color: #303133; |
| | | margin-bottom: 4px; |
| | | } |
| | | |
| | | .process-desc { |
| | | font-size: 12px; |
| | | color: #909399; |
| | | overflow: hidden; |
| | | text-overflow: ellipsis; |
| | | white-space: nowrap; |
| | | } |
| | | } |
| | | |
| | | .card-footer { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | |
| | | .param-count { |
| | | font-size: 12px; |
| | | color: #606266; |
| | | } |
| | | } |
| | | } |
| | | |
| | | // å³ä¾§åæ°å表 |
| | | .param-list-section { |
| | | flex: 1; |
| | | background: #fff; |
| | | border-radius: 8px; |
| | | box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1); |
| | | display: flex; |
| | | flex-direction: column; |
| | | } |
| | | |
| | | .param-table-wrapper { |
| | | flex: 1; |
| | | padding: 0 20px 20px; |
| | | overflow: hidden; |
| | | } |
| | | |
| | | .empty-tip { |
| | | flex: 1; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | } |
| | | |
| | | // è¡¨æ ¼æ ·å¼ |
| | | :deep(.el-table) { |
| | | border: none; |
| | | border-radius: 6px; |
| | | overflow: hidden; |
| | | |
| | | .el-table__header-wrapper { |
| | | background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); |
| | | |
| | | th { |
| | | background: transparent; |
| | | font-weight: 600; |
| | | color: #ffffff; |
| | | border-bottom: none; |
| | | padding: 16px 0; |
| | | } |
| | | } |
| | | |
| | | .el-table__body-wrapper { |
| | | tr { |
| | | transition: all 0.3s ease; |
| | | |
| | | &:hover { |
| | | background: linear-gradient( |
| | | 90deg, |
| | | rgba(102, 126, 234, 0.05) 0%, |
| | | rgba(118, 75, 162, 0.05) 100% |
| | | ); |
| | | } |
| | | |
| | | td { |
| | | border-bottom: 1px solid #f0f0f0; |
| | | padding: 14px 0; |
| | | color: #303133; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | // ç¼ç åå
æ ¼æ ·å¼ |
| | | :deep(.code-cell) { |
| | | color: #e6a23c; |
| | | font-family: "Courier New", monospace; |
| | | font-weight: 500; |
| | | } |
| | | |
| | | // æ°å¼åå
æ ¼æ ·å¼ |
| | | :deep(.quantity-cell) { |
| | | font-weight: 600; |
| | | color: #409eff; |
| | | font-family: "Courier New", monospace; |
| | | } |
| | | |
| | | // éæ©åæ°å¯¹è¯æ¡æ ·å¼ |
| | | .param-select-container { |
| | | display: flex; |
| | | gap: 20px; |
| | | height: 450px; |
| | | |
| | | .param-list-area { |
| | | flex: 1; |
| | | display: flex; |
| | | flex-direction: column; |
| | | |
| | | .area-title { |
| | | font-size: 14px; |
| | | font-weight: 600; |
| | | color: #303133; |
| | | margin-bottom: 12px; |
| | | padding-bottom: 8px; |
| | | border-bottom: 1px solid #ebeef5; |
| | | } |
| | | |
| | | .search-box { |
| | | margin-bottom: 12px; |
| | | |
| | | .el-input { |
| | | width: 100%; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .param-detail-area { |
| | | width: 380px; |
| | | display: flex; |
| | | flex-direction: column; |
| | | background: #f5f7fa; |
| | | border-radius: 8px; |
| | | padding: 16px; |
| | | |
| | | .area-title { |
| | | font-size: 14px; |
| | | font-weight: 600; |
| | | color: #303133; |
| | | margin-bottom: 16px; |
| | | padding-bottom: 8px; |
| | | border-bottom: 1px solid #ebeef5; |
| | | } |
| | | |
| | | .param-detail-form { |
| | | .el-form-item { |
| | | margin-bottom: 12px; |
| | | |
| | | .el-form-item__label { |
| | | color: #606266; |
| | | font-weight: 500; |
| | | } |
| | | } |
| | | |
| | | .detail-text { |
| | | color: #303133; |
| | | font-weight: 500; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </style> |