| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <div class="process-config-container"> |
| | | <!-- 左侧工åºå表 --> |
| | | <div class="process-list-section"> |
| | | <div class="section-header"> |
| | | <h3 class="section-title">å·¥åºå表</h3> |
| | | <el-button type="primary" |
| | | size="small" |
| | | @click="handleAddProcess"> |
| | | <el-icon> |
| | | <Plus /> |
| | | </el-icon>æ°å¢å·¥åº |
| | | </el-button> |
| | | </div> |
| | | <div class="process-card-list" |
| | | v-loading="processLoading"> |
| | | <div v-for="process in processValueList" |
| | | :key="process.id" |
| | | class="process-card" |
| | | :class="{ active: selectedProcess?.id === process.id }" |
| | | @click="selectProcess(process)"> |
| | | <div class="card-header"> |
| | | <div class="process-name">{{ process.name }} <span class="process-code">{{ process.no }}</span></div> |
| | | <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.name }}</div> --> |
| | | <div class="process-desc">{{ process.remark || 'ææ æè¿°' }}</div> |
| | | <div class="process-device">å
³è设å¤: {{ (deviceOptions.find(item => item.id === Number(process.deviceLedgerId))?.deviceName) || 'æªå
³è' }}</div> |
| | | </div> |
| | | <div class="card-footer"> |
| | | <div class="status-tag"> |
| | | <el-tag size="small" |
| | | :type="process.isQuality ? 'warning' : 'info'"> |
| | | {{ process.isQuality ? 'è´¨æ£' : 'éè´¨æ£' }} |
| | | </el-tag> |
| | | <el-tag size="small" |
| | | style="margin-left: 8px" |
| | | :type="process.isProduction ? 'warning' : 'info'"> |
| | | {{ process.isProduction ? 'ç产' : 'ä¸ç产' }} |
| | | </el-tag> |
| | | <el-tag v-if="process.type !== null && process.type !== undefined" |
| | | size="small" |
| | | :type="process.type == 1 ? 'primary' : 'success'" |
| | | style="margin-left: 8px"> |
| | | {{ process.type == 0 ? '计æ¶' : '计件' }} |
| | | </el-tag> |
| | | </div> |
| | | <span class="param-count">å·¥èµå®é¢: Â¥{{ process.salaryQuota || 0 }}</span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <!-- å³ä¾§åæ°å表 --> |
| | | <div class="param-list-section"> |
| | | <div class="section-header"> |
| | | <h3 class="section-title"> |
| | | {{ selectedProcess ? selectedProcess.name + ' - åæ°é
ç½®' : 'è¯·éæ©å·¥åº' }} |
| | | </h3> |
| | | <el-button type="primary" |
| | | size="small" |
| | | :disabled="!selectedProcess" |
| | | @click="openParamDialog"> |
| | | <el-icon> |
| | | <Plus /> |
| | | </el-icon>鿩忰 |
| | | </el-button> |
| | | </div> |
| | | <div class="param-table-wrapper"> |
| | | <PIMTable v-if="selectedProcess" |
| | | rowKey="id" |
| | | :column="paramColumn" |
| | | :tableData="paramList" |
| | | :page="paramPage2" |
| | | height="calc(100vh - 280px)" |
| | | :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="no"> |
| | | <el-input v-model="processForm.no" |
| | | placeholder="请è¾å
¥å·¥åºç¼ç " /> |
| | | </el-form-item> |
| | | <el-form-item label="å·¥åºåç§°" |
| | | prop="name"> |
| | | <el-input v-model="processForm.name" |
| | | placeholder="请è¾å
¥å·¥åºåç§°" /> |
| | | </el-form-item> |
| | | <el-form-item label="å·¥èµå®é¢" |
| | | prop="salaryQuota"> |
| | | <el-input v-model="processForm.salaryQuota" |
| | | type="number" |
| | | :step="0.001" /> |
| | | </el-form-item> |
| | | <el-form-item label="æ¯å¦è´¨æ£" |
| | | prop="isQuality"> |
| | | <el-switch v-model="processForm.isQuality" /> |
| | | </el-form-item> |
| | | <el-form-item label="æ¯å¦ç产" |
| | | prop="isProduction"> |
| | | <el-switch v-model="processForm.isProduction" /> |
| | | </el-form-item> |
| | | <el-form-item label="计费类å" |
| | | prop="type"> |
| | | <el-radio-group v-model="processForm.type"> |
| | | <el-radio :label="0">计æ¶</el-radio> |
| | | <el-radio :label="1">计件</el-radio> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | <el-form-item label="å
³è设å¤" |
| | | prop="deviceLedgerId"> |
| | | <el-select v-model="processForm.deviceLedgerId" |
| | | placeholder="è¯·éæ©è®¾å¤" |
| | | clearable |
| | | filterable |
| | | style="width: 100%"> |
| | | <el-option v-for="item in deviceOptions" |
| | | :key="item.id" |
| | | :label="item.deviceName" |
| | | :value="item.id" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="å·¥åºæè¿°" |
| | | prop="remark"> |
| | | <el-input v-model="processForm.remark" |
| | | type="textarea" |
| | | :rows="3" |
| | | placeholder="请è¾å
¥å·¥åºæè¿°" /> |
| | | </el-form-item> |
| | | </el-form> |
| | | <template #footer> |
| | | <span class="dialog-footer"> |
| | | <el-button type="primary" |
| | | @click="handleProcessSubmit">ç¡®å®</el-button> |
| | | <el-button @click="processDialogVisible = false">åæ¶</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="handleSelectParam"> |
| | | <template #prefix> |
| | | <el-icon> |
| | | <Search /> |
| | | </el-icon> |
| | | </template> |
| | | </el-input> |
| | | </div> |
| | | <el-table :data="filteredParamList" |
| | | height="300" |
| | | border |
| | | highlight-current-row |
| | | @current-change="handleParamSelect"> |
| | | <el-table-column prop="paramName" |
| | | label="åæ°åç§°" /> |
| | | <el-table-column prop="paramType" |
| | | label="åæ°ç±»å"> |
| | | <template #default="scope"> |
| | | <el-tag size="small" |
| | | :type="getParamTypeTag(scope.row.paramType)"> |
| | | {{ getParamTypeText(scope.row.paramType) }} |
| | | </el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | <!-- å页æ§ä»¶ --> |
| | | <div class="pagination-container" |
| | | style="margin-top: 10px;"> |
| | | <el-pagination v-model:current-page="paramPage.current" |
| | | v-model:page-size="paramPage.size" |
| | | :page-sizes="[10, 20, 50, 100]" |
| | | layout="total, sizes, prev, pager, next, jumper" |
| | | :total="paramPage.total" |
| | | @size-change="handleParamSizeChange" |
| | | @current-change="handleParamCurrentChange" |
| | | size="small" /> |
| | | </div> |
| | | </div> |
| | | <!-- å³ä¾§åæ°è¯¦æ
--> |
| | | <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.paramName }}</span> |
| | | </el-form-item> |
| | | <el-form-item label="åæ°ç±»å"> |
| | | <el-tag size="small" |
| | | :type="getParamTypeTag(selectedParam.paramType)"> |
| | | {{ getParamTypeText(selectedParam.paramType) }} |
| | | </el-tag> |
| | | </el-form-item> |
| | | <el-form-item label="åæ°æ ¼å¼"> |
| | | <span class="detail-text">{{ selectedParam.paramFormat || '-' }}</span> |
| | | </el-form-item> |
| | | <el-form-item label="åä½"> |
| | | <span class="detail-text">{{ selectedParam.unit || '-' }}</span> |
| | | </el-form-item> |
| | | <el-form-item label="æ åå¼"> |
| | | <el-input v-model="selectedParam.standardValue" |
| | | @input="val => onStandardValueInput(val, selectedParam)" |
| | | placeholder="请è¾å
¥é»è®¤å¼" /> |
| | | </el-form-item> |
| | | </el-form> |
| | | <el-empty v-else |
| | | description="请ä»å·¦ä¾§éæ©åæ°" /> |
| | | </div> |
| | | </div> |
| | | <template #footer> |
| | | <span class="dialog-footer"> |
| | | <el-button type="primary" |
| | | :disabled="!selectedParam" |
| | | @click="handleParamSubmit">ç¡®å®</el-button> |
| | | <el-button @click="paramDialogVisible = false">åæ¶</el-button> |
| | | </span> |
| | | </template> |
| | | </el-dialog> |
| | | <!-- ç¼è¾åæ°å¯¹è¯æ¡ --> |
| | | <el-dialog v-model="editParamDialogVisible" |
| | | title="ç¼è¾åæ°" |
| | | width="600px"> |
| | | <el-form :model="editParamForm" |
| | | :rules="editParamRules" |
| | | ref="editParamFormRef" |
| | | label-width="120px"> |
| | | <el-form-item label="åæ°åç§°"> |
| | | <span class="detail-text">{{ editParamForm.paramName }}</span> |
| | | </el-form-item> |
| | | <el-form-item label="æ åå¼" |
| | | prop="standardValue"> |
| | | <el-input v-model="editParamForm.standardValue" |
| | | @input="val => onStandardValueInput(val, editParamForm)" |
| | | placeholder="请è¾å
¥æ åå¼" /> |
| | | </el-form-item> |
| | | </el-form> |
| | | <template #footer> |
| | | <span class="dialog-footer"> |
| | | <el-button type="primary" |
| | | @click="handleEditParamSubmit">ç¡®å®</el-button> |
| | | <el-button @click="editParamDialogVisible = false">åæ¶</el-button> |
| | | </span> |
| | | </template> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, reactive, computed, 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"; |
| | | import { |
| | | add, |
| | | update, |
| | | del, |
| | | list as getProcessListApi, |
| | | processList, |
| | | getProcessParamList, |
| | | addProcessParam, |
| | | editProcessParam, |
| | | deleteProcessParam, |
| | | } from "@/api/productionManagement/productionProcess.js"; |
| | | import { getDeviceLedger } from "@/api/equipmentManagement/ledger"; |
| | | import { getBaseParamList } from "@/api/basicData/parameterMaintenance.js"; |
| | | |
| | | // å·¥åºåè¡¨æ°æ® |
| | | const processValueList = ref([]); |
| | | const selectedProcess = ref(null); |
| | | const processLoading = ref(false); |
| | | const deviceOptions = ref([]); |
| | | |
| | | // å·¥åºå·²éåæ°è¡¨æ ¼åé¡µï¼æ¥å£ä¸æ¬¡è¿åå
¨éï¼ |
| | | const paramPage2 = ref({ |
| | | current: 1, |
| | | size: 10, |
| | | total: 0, |
| | | }); |
| | | const paramListRaw = ref([]); |
| | | const paramList = computed(() => { |
| | | const all = paramListRaw.value; |
| | | const { current, size } = paramPage2.value; |
| | | const start = (current - 1) * size; |
| | | return all.slice(start, start + size); |
| | | }); |
| | | const paramLoading = ref(false); |
| | | |
| | | // æ°æ®åå
¸ |
| | | const dictTypes = ref([]); |
| | | |
| | | // å·¥åºå¯¹è¯æ¡ |
| | | const processDialogVisible = ref(false); |
| | | const isProcessEdit = ref(false); |
| | | const processFormRef = ref(null); |
| | | const processForm = reactive({ |
| | | id: null, |
| | | no: "", |
| | | name: "", |
| | | salaryQuota: null, |
| | | isQuality: false, |
| | | isProduction: false, |
| | | remark: "", |
| | | deviceLedgerId: null, |
| | | type: 0, |
| | | }); |
| | | const processRules = { |
| | | no: [{ required: true, message: "请è¾å
¥å·¥åºç¼ç ", trigger: "blur" }], |
| | | name: [{ required: true, message: "请è¾å
¥å·¥åºåç§°", trigger: "blur" }], |
| | | salaryQuota: [ |
| | | { |
| | | required: false, |
| | | message: "请è¾å
¥å·¥èµå®é¢", |
| | | trigger: "blur", |
| | | validator: (rule, value, callback) => { |
| | | if (isNaN(value) || value < 0) { |
| | | callback(new Error("å·¥èµå®é¢å¿
é¡»æ¯éè´æ°å")); |
| | | } else { |
| | | callback(); |
| | | } |
| | | }, |
| | | }, |
| | | ], |
| | | deviceLedgerId: [ |
| | | { required: false, message: "è¯·éæ©è®¾å¤", trigger: "change" }, |
| | | ], |
| | | type: [{ required: false, message: "è¯·éæ©è®¡è´¹ç±»å", trigger: "change" }], |
| | | }; |
| | | |
| | | // åæ°å¯¹è¯æ¡ |
| | | const paramDialogVisible = ref(false); |
| | | const availableParamList = ref([]); |
| | | const filteredParamList = ref([]); |
| | | const selectedParam = ref(null); |
| | | const paramSearchKeyword = ref(""); |
| | | |
| | | // å¯éåæ°å页 |
| | | const paramPage = reactive({ |
| | | current: 1, |
| | | size: 10, |
| | | total: 0, |
| | | }); |
| | | |
| | | // ç¼è¾åæ°å¯¹è¯æ¡ |
| | | const editParamDialogVisible = ref(false); |
| | | const editParamFormRef = ref(null); |
| | | const editParamForm = reactive({ |
| | | id: null, |
| | | technologyOperationId: null, |
| | | technologyParamId: null, |
| | | paramName: "", |
| | | standardValue: null, |
| | | paramType: null, |
| | | }); |
| | | |
| | | const onStandardValueInput = (val, target) => { |
| | | const data = target.value || target; |
| | | const type = data.paramType; |
| | | if (type === 1) { |
| | | // æ°å¼æ ¼å¼ï¼ä¸è½è¾å
¥ä¸ææè±æå符 |
| | | data.standardValue = val.replace(/[a-zA-Z\u4e00-\u9fa5]/g, ""); |
| | | } |
| | | }; |
| | | |
| | | const editParamRules = { |
| | | standardValue: [ |
| | | { |
| | | required: true, |
| | | message: "请è¾å
¥æ åå¼", |
| | | trigger: "blur", |
| | | validator: (rule, value, callback) => { |
| | | if (value === null || value === undefined || value === "") { |
| | | callback(new Error("请è¾å
¥æ åå¼")); |
| | | } else { |
| | | const type = editParamForm.paramType; |
| | | if (type === 1 && value) { |
| | | if (/[a-zA-Z\u4e00-\u9fa5]/.test(value)) { |
| | | return callback(new Error("æ°å¼æ ¼å¼ä¸è½å
å«ä¸è±æå符")); |
| | | } |
| | | } |
| | | callback(); |
| | | } |
| | | }, |
| | | }, |
| | | ], |
| | | }; |
| | | |
| | | // åæ°è¡¨æ ¼åé
ç½® |
| | | const paramColumn = ref([ |
| | | { |
| | | label: "åæ°åç§°", |
| | | prop: "paramName", |
| | | }, |
| | | { |
| | | label: "åæ°ç±»å", |
| | | prop: "paramType", |
| | | dataType: "tag", |
| | | formatType: params => { |
| | | const typeMap = { |
| | | 1: "primary", |
| | | 2: "info", |
| | | 3: "warning", |
| | | 4: "success", |
| | | }; |
| | | return typeMap[params] || "default"; |
| | | }, |
| | | formatData: val => { |
| | | const labelMap = { |
| | | 1: "æ°å¼æ ¼å¼", |
| | | 2: "ææ¬æ ¼å¼", |
| | | 3: "䏿é项", |
| | | 4: "æ¶é´æ ¼å¼", |
| | | }; |
| | | return labelMap[val] || val; |
| | | }, |
| | | }, |
| | | { |
| | | label: "å弿 ¼å¼", |
| | | prop: "paramFormat", |
| | | }, |
| | | { |
| | | label: "æ åå¼", |
| | | prop: "standardValue", |
| | | }, |
| | | { |
| | | label: "åä½", |
| | | prop: "unit", |
| | | }, |
| | | { |
| | | label: "æä½", |
| | | dataType: "action", |
| | | width: "150", |
| | | operation: [ |
| | | { |
| | | name: "ç¼è¾", |
| | | clickFun: row => handleEditParam(row), |
| | | }, |
| | | { |
| | | name: "å é¤", |
| | | clickFun: row => handleDeleteParam(row), |
| | | }, |
| | | ], |
| | | }, |
| | | ]); |
| | | |
| | | // è·åå·¥åºå表 |
| | | const getProcessList = () => { |
| | | processLoading.value = true; |
| | | getProcessListApi({ size: -1, current: -1 }) |
| | | .then(res => { |
| | | processValueList.value = res.data.records || []; |
| | | console.log( |
| | | processValueList.value, |
| | | "reprocessValueList.value==========s" |
| | | ); |
| | | }) |
| | | .catch(() => { |
| | | ElMessage.error("è·åå·¥åºå表失败"); |
| | | }) |
| | | .finally(() => { |
| | | processLoading.value = false; |
| | | }); |
| | | }; |
| | | |
| | | const loadDeviceName = async () => { |
| | | try { |
| | | const { data } = await getDeviceLedger(); |
| | | deviceOptions.value = data || []; |
| | | } catch (error) { |
| | | console.error("å 载设å¤å表失败", error); |
| | | } |
| | | }; |
| | | |
| | | // è·ååæ°å表 |
| | | const getParamList = processId => { |
| | | paramLoading.value = true; |
| | | getProcessParamList({ technologyOperationId: processId }) |
| | | .then(res => { |
| | | const list = res.data || []; |
| | | paramListRaw.value = Array.isArray(list) ? list : []; |
| | | paramPage2.value.total = paramListRaw.value.length; |
| | | const maxPage = Math.max( |
| | | 1, |
| | | Math.ceil(paramPage2.value.total / paramPage2.value.size) || 1 |
| | | ); |
| | | if (paramPage2.value.current > maxPage) { |
| | | paramPage2.value.current = maxPage; |
| | | } |
| | | }) |
| | | .catch(() => { |
| | | ElMessage.error("è·ååæ°å表失败"); |
| | | }) |
| | | .finally(() => { |
| | | paramLoading.value = false; |
| | | }); |
| | | }; |
| | | |
| | | // éæ©å·¥åº |
| | | const selectProcess = process => { |
| | | selectedProcess.value = process; |
| | | paramPage2.value.current = 1; |
| | | getParamList(process.id); |
| | | }; |
| | | |
| | | // å·¥åºæä½ |
| | | const handleAddProcess = () => { |
| | | isProcessEdit.value = false; |
| | | processForm.id = null; |
| | | processForm.no = ""; |
| | | processForm.name = ""; |
| | | processForm.salaryQuota = null; |
| | | processForm.isQuality = false; |
| | | processForm.isProduction = false; |
| | | processForm.remark = ""; |
| | | processForm.deviceLedgerId = null; |
| | | processForm.type = 0; |
| | | processDialogVisible.value = true; |
| | | }; |
| | | |
| | | const handleEditProcess = async process => { |
| | | isProcessEdit.value = true; |
| | | processForm.id = process.id; |
| | | processForm.no = process.no; |
| | | processForm.name = process.name; |
| | | processForm.salaryQuota = process.salaryQuota; |
| | | processForm.isQuality = !!process.isQuality; |
| | | processForm.isProduction = !!process.isProduction; |
| | | processForm.remark = process.remark || ""; |
| | | // å¦æè®¾å¤ ID 为 0 æè
å¨è®¾å¤åè¡¨ä¸æ¾ä¸å°ï¼ååæ¾ä¸ºç©ºï¼nullï¼ |
| | | const deviceId = Number(process.deviceLedgerId); |
| | | const hasDevice = deviceOptions.value.some(item => item.id === deviceId); |
| | | processForm.deviceLedgerId = deviceId && hasDevice ? deviceId : null; |
| | | processForm.type = process.type; |
| | | processDialogVisible.value = true; |
| | | }; |
| | | |
| | | const handleDeleteProcess = process => { |
| | | ElMessageBox.confirm("ç¡®å®è¦å é¤è¯¥å·¥åºåï¼", "æç¤º", { |
| | | confirmButtonText: "ç¡®å®", |
| | | cancelButtonText: "åæ¶", |
| | | type: "warning", |
| | | }).then(() => { |
| | | del([process.id]) |
| | | .then(() => { |
| | | ElMessage.success("å 餿å"); |
| | | getProcessList(); |
| | | if (selectedProcess.value?.id === process.id) { |
| | | selectedProcess.value = null; |
| | | paramListRaw.value = []; |
| | | paramPage2.value.total = 0; |
| | | } |
| | | }) |
| | | .catch(() => { |
| | | ElMessage.error("å é¤å¤±è´¥"); |
| | | }); |
| | | }); |
| | | }; |
| | | |
| | | const handleProcessSubmit = () => { |
| | | processFormRef.value.validate(valid => { |
| | | if (valid) { |
| | | if (processForm.id) { |
| | | update(processForm) |
| | | .then(() => { |
| | | ElMessage.success("ç¼è¾æå"); |
| | | processDialogVisible.value = false; |
| | | getProcessList(); |
| | | }) |
| | | .catch(() => { |
| | | ElMessage.error("ç¼è¾å¤±è´¥"); |
| | | }); |
| | | } else { |
| | | add(processForm) |
| | | .then(() => { |
| | | ElMessage.success("æ°å¢æå"); |
| | | processDialogVisible.value = false; |
| | | getProcessList(); |
| | | }) |
| | | .catch(() => { |
| | | ElMessage.error("æ°å¢å¤±è´¥"); |
| | | }); |
| | | } |
| | | } |
| | | }); |
| | | }; |
| | | const openParamDialog = () => { |
| | | paramSearchKeyword.value = ""; |
| | | if (!selectedProcess.value) { |
| | | ElMessage.warning("请å
éæ©ä¸ä¸ªå·¥åº"); |
| | | return; |
| | | } |
| | | // è·åå¯éåæ°å表 |
| | | getBaseParamList({ |
| | | paramName: paramSearchKeyword.value, |
| | | current: paramPage.current, |
| | | size: paramPage.size, |
| | | }).then(res => { |
| | | if (res.code === 200) { |
| | | filteredParamList.value = res.data?.records || []; |
| | | paramPage.total = res.data?.total || 0; |
| | | } else { |
| | | ElMessage.error(res.msg || "æ¥è¯¢å¤±è´¥"); |
| | | } |
| | | }); |
| | | console.log(filteredParamList.value, "å¯éåæ°å表"); |
| | | selectedParam.value = null; |
| | | paramDialogVisible.value = true; |
| | | }; |
| | | |
| | | // åæ°æä½ |
| | | const handleSelectParam = () => { |
| | | if (!selectedProcess.value) { |
| | | ElMessage.warning("请å
éæ©ä¸ä¸ªå·¥åº"); |
| | | return; |
| | | } |
| | | // è·åå¯éåæ°å表 |
| | | getBaseParamList({ |
| | | paramName: paramSearchKeyword.value, |
| | | current: paramPage.current, |
| | | size: paramPage.size, |
| | | }).then(res => { |
| | | if (res.code === 200) { |
| | | filteredParamList.value = res.data?.records || []; |
| | | paramPage.total = res.data?.total || 0; |
| | | } else { |
| | | ElMessage.error(res.msg || "æ¥è¯¢å¤±è´¥"); |
| | | } |
| | | }); |
| | | console.log(filteredParamList.value, "å¯éåæ°å表"); |
| | | selectedParam.value = null; |
| | | paramDialogVisible.value = true; |
| | | }; |
| | | |
| | | const handleParamSelect = row => { |
| | | selectedParam.value = row; |
| | | }; |
| | | |
| | | const handleParamSearch = () => { |
| | | // éç½®å页 |
| | | paramPage.current = 1; |
| | | // éæ°å è½½æ°æ® |
| | | handleSelectParam(); |
| | | }; |
| | | |
| | | // å¤çå页大å°åå |
| | | const handleParamSizeChange = size => { |
| | | paramPage.size = size; |
| | | handleSelectParam(); |
| | | }; |
| | | |
| | | // å¤çå½å页ç åå |
| | | const handleParamCurrentChange = current => { |
| | | paramPage.current = current; |
| | | handleSelectParam(); |
| | | }; |
| | | const getParamTypeText = type => { |
| | | const typeMap = { |
| | | 1: "æ°å¼æ ¼å¼", |
| | | 2: "ææ¬æ ¼å¼", |
| | | 3: "䏿é项", |
| | | 4: "æ¶é´æ ¼å¼", |
| | | }; |
| | | return typeMap[type] || "æªç¥åæ°ç±»å"; |
| | | }; |
| | | const getParamTypeTag = type => { |
| | | const typeMap = { |
| | | 1: "primary", |
| | | 2: "info", |
| | | 3: "warning", |
| | | 4: "success", |
| | | }; |
| | | return typeMap[type] || "default"; |
| | | }; |
| | | |
| | | const handleDeleteParam = row => { |
| | | ElMessageBox.confirm("ç¡®å®è¦å é¤è¯¥åæ°åï¼", "æç¤º", { |
| | | confirmButtonText: "ç¡®å®", |
| | | cancelButtonText: "åæ¶", |
| | | type: "warning", |
| | | }).then(() => { |
| | | deleteProcessParam(row.id) |
| | | .then(() => { |
| | | ElMessage.success("å 餿å"); |
| | | getParamList(selectedProcess.value.id); |
| | | }) |
| | | .catch(() => { |
| | | ElMessage.error("å é¤å¤±è´¥"); |
| | | }); |
| | | }); |
| | | }; |
| | | |
| | | const handleEditParam = row => { |
| | | editParamForm.id = row.id; |
| | | editParamForm.technologyOperationId = row.technologyOperationId; |
| | | editParamForm.technologyParamId = row.technologyParamId; |
| | | editParamForm.paramName = row.paramName; |
| | | editParamForm.standardValue = row.standardValue; |
| | | editParamForm.paramType = row.paramType; |
| | | editParamDialogVisible.value = true; |
| | | }; |
| | | |
| | | const handleEditParamSubmit = () => { |
| | | editParamFormRef.value.validate(valid => { |
| | | if (valid) { |
| | | editProcessParam(editParamForm) |
| | | .then(() => { |
| | | ElMessage.success("ç¼è¾æå"); |
| | | editParamDialogVisible.value = false; |
| | | getParamList(selectedProcess.value.id); |
| | | }) |
| | | .catch(() => { |
| | | ElMessage.error("ç¼è¾å¤±è´¥"); |
| | | }); |
| | | } |
| | | }); |
| | | }; |
| | | |
| | | const handleParamSubmit = () => { |
| | | if (!selectedParam.value) { |
| | | ElMessage.warning("请å
éæ©ä¸ä¸ªåæ°"); |
| | | return; |
| | | } |
| | | addProcessParam({ |
| | | technologyOperationId: selectedProcess.value.id, |
| | | technologyParamId: selectedParam.value.id, |
| | | standardValue: selectedParam.value.standardValue, |
| | | }) |
| | | .then(() => { |
| | | ElMessage.success("æ·»å æå"); |
| | | paramDialogVisible.value = false; |
| | | getParamList(selectedProcess.value.id); |
| | | }) |
| | | .catch(() => { |
| | | ElMessage.error("æ·»å 失败"); |
| | | }); |
| | | }; |
| | | |
| | | const handleParamPagination = obj => { |
| | | paramPage2.value.current = obj.page; |
| | | paramPage2.value.size = obj.limit; |
| | | }; |
| | | |
| | | // è·åæ°æ®åå
¸ |
| | | const getDictTypes = () => { |
| | | listType({ pageNum: 1, pageSize: 1000 }).then(res => { |
| | | dictTypes.value = res.rows || []; |
| | | }); |
| | | }; |
| | | |
| | | onMounted(() => { |
| | | loadDeviceName(); |
| | | getProcessList(); |
| | | getDictTypes(); |
| | | }); |
| | | </script> |
| | | |
| | | <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; |
| | | min-width: 370px; |
| | | flex-shrink: 0; |
| | | 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; |
| | | color: #cb9b18; |
| | | 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; |
| | | margin-bottom: 4px; |
| | | } |
| | | |
| | | .process-device { |
| | | font-size: 12px; |
| | | color: #606266; |
| | | 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; |
| | | min-width: 0; |
| | | } |
| | | |
| | | .param-table-wrapper { |
| | | flex: 1; |
| | | padding: 0 20px 20px; |
| | | overflow: auto; |
| | | min-width: 100%; |
| | | } |
| | | |
| | | /* è¡¨æ ¼æ¨ªåæ»å¨ */ |
| | | .param-table-wrapper :deep(.el-table) { |
| | | min-width: 100%; |
| | | } |
| | | |
| | | .param-table-wrapper :deep(.el-table__body-wrapper) { |
| | | overflow-x: auto; |
| | | } |
| | | |
| | | .pagination-container { |
| | | margin-top: 10px; |
| | | overflow-x: auto; |
| | | padding-bottom: 8px; |
| | | } |
| | | |
| | | .pagination-container .el-pagination { |
| | | white-space: nowrap; |
| | | } |
| | | |
| | | /* ååºå¼è°æ´ */ |
| | | @media screen and (max-width: 768px) { |
| | | .pagination-container { |
| | | font-size: 12px; |
| | | } |
| | | |
| | | .pagination-container .el-pagination__sizes { |
| | | margin-right: 8px; |
| | | } |
| | | |
| | | .pagination-container .el-pagination__jump { |
| | | margin-left: 8px; |
| | | } |
| | | |
| | | .pagination-container .el-pagination__page-size { |
| | | font-size: 12px; |
| | | } |
| | | } |
| | | |
| | | .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; |
| | | width: 380px; |
| | | 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; |
| | | flex: 1; |
| | | 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> |