src/api/safeProduction/emergencyPlanReview.js
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,35 @@ // åè´§å°è´¦é¡µé¢æ¥å£ import request from "@/utils/request"; // å页æ¥è¯¢ export function safeContingencyPlanListPage(query) { return request({ url: "/safeContingencyPlan/page", method: "get", params: query, }); } export function safeContingencyPlanAdd(query) { return request({ url: '/safeContingencyPlan', method: 'post', data: query }) } export function safeContingencyPlanUpdate(query) { return request({ url: '/safeContingencyPlan', method: 'put', data: query }) } export function safeContingencyPlanDel(ids) { return request({ url: '/safeContingencyPlan/' + ids, method: 'delete', data: ids }) } src/api/salesManagement/deliveryLedger.js
@@ -18,6 +18,14 @@ data: query, }); } // ä¿®æ¹åè´§å°è´¦ export function deductStock(query) { return request({ url: "/shippingInfo/deductStock", method: "post", data: query, }); } // å é¤åè´§å°è´¦ export function delDeliveryLedger(query) { src/views/collaborativeApproval/approvalProcess/components/approvalDia.vue
@@ -197,10 +197,6 @@ <div v-if="!activity.isShen" class="node-reason"> <span>å®¡æ¹æè§ï¼</span>{{ activity.approveNodeReason }} </div> <div v-if="!activity.isShen" class="node-reason"> <span>ç¾åï¼</span> <img :src="activity.urlTem" class="signImg" alt="" v-if="activity.urlTem"/> </div> <div v-else-if="activity.isShen"> <el-form-item :prop="'activities.' + index + '.approveNodeReason'" src/views/collaborativeApproval/approvalProcess/index.vue
@@ -45,7 +45,7 @@ type="danger" plain @click="handleDelete" v-if="currentApproveType !== 7" v-if="currentApproveType !== 5 && currentApproveType !== 6 && currentApproveType !== 7" >å é¤</el-button> </div> </div> src/views/collaborativeApproval/knowledgeBase/index.vue
@@ -46,11 +46,13 @@ </div> <!-- æ°å¢/ç¼è¾ç¥è¯å¼¹çª --> <el-dialog <FormDialog v-model="dialogVisible" :title="dialogTitle" width="800px" :close-on-click-modal="false" :width="'800px'" @close="closeKnowledgeDialog" @confirm="submitForm" @cancel="closeKnowledgeDialog" > <el-form ref="formRef" :model="form" :rules="rules" label-width="120px"> <el-row :gutter="20"> @@ -115,7 +117,14 @@ <el-row :gutter="20"> <el-col :span="12"> <el-form-item label="å建人" prop="creator"> <el-input v-model="form.creator" placeholder="请è¾å ¥å建人" /> <el-select v-model="form.creator" placeholder="è¯·éæ©å建人" style="width: 100%" filterable> <el-option v-for="user in userList" :key="user.userId" :label="user.nickName" :value="user.nickName" /> </el-select> </el-form-item> </el-col> <el-col :span="12"> @@ -125,20 +134,16 @@ </el-col> </el-row> </el-form> <template #footer> <span class="dialog-footer"> <el-button @click="dialogVisible = false">åæ¶</el-button> <el-button type="primary" @click="submitForm">ç¡®å®</el-button> </span> </template> </el-dialog> </FormDialog> <!-- æ¥çç¥è¯è¯¦æ å¼¹çª --> <el-dialog <FormDialog v-model="viewDialogVisible" title="ç¥è¯è¯¦æ " width="900px" :close-on-click-modal="false" :width="'900px'" @close="closeViewDialog" @confirm="handleViewDialogConfirm" @cancel="closeViewDialog" > <div class="knowledge-detail"> <el-descriptions :column="2" border> @@ -183,7 +188,7 @@ <h4>å ³é®è¦ç¹</h4> <div class="key-points"> <el-tag v-for="(point, index) in currentKnowledge.keyPoints.split(',')" v-for="(point, index) in currentKnowledge.keyPoints?.split(',') || []" :key="index" type="success" style="margin-right: 8px; margin-bottom: 8px;" @@ -219,24 +224,19 @@ </div> </div> </div> <template #footer> <span class="dialog-footer"> <el-button @click="viewDialogVisible = false">å ³é</el-button> <el-button type="primary" @click="copyKnowledge">å¤å¶ç¥è¯</el-button> <!-- <el-button type="success" @click="markAsFavorite">æ¶è@</el-button> --> </span> </template> </el-dialog> </FormDialog> </div> </template> <script setup> import { Search } from "@element-plus/icons-vue"; import { onMounted, ref, reactive, toRefs, getCurrentInstance, computed } from "vue"; import { onMounted, ref, reactive, toRefs, getCurrentInstance, computed, watch } from "vue"; import { ElMessage, ElMessageBox } from "element-plus"; import PIMTable from "@/components/PIMTable/PIMTable.vue"; import FormDialog from '@/components/Dialog/FormDialog.vue'; import { listKnowledgeBase, delKnowledgeBase,addKnowledgeBase,updateKnowledgeBase } from "@/api/collaborativeApproval/knowledgeBase.js"; import useUserStore from '@/store/modules/user'; import { userListNoPageByTenantId } from '@/api/system/user.js'; // 表åéªè¯è§å const rules = { @@ -302,6 +302,9 @@ // 表åå¼ç¨ const formRef = ref(); // ç¨æ·ç¸å ³ const userStore = useUserStore(); const userList = ref([]); // è¡¨æ ¼åé ç½® const tableColumn = ref([ @@ -389,6 +392,15 @@ } ]); // çå¬å¯¹è¯æ¡æå¼ï¼è·åç¨æ·å表 watch(dialogVisible, (newVal) => { if (newVal) { userListNoPageByTenantId().then((res) => { userList.value = res.data || []; }); } }); // çå½å¨æ onMounted(() => { getList(); @@ -414,7 +426,7 @@ .then(res => { tableLoading.value = false; tableData.value = res.data.records page.total = res.data.total; page.value.total = res.data.total; }).catch(err => { tableLoading.value = false; }) @@ -437,7 +449,7 @@ dialogType.value = type; if (type === "add") { dialogTitle.value = "æ°å¢ç¥è¯"; // é置表å // é置表åï¼é»è®¤å建人为å½åç¨æ· Object.assign(form.value, { title: "", type: "", @@ -446,7 +458,7 @@ problem: "", solution: "", keyPoints: "", creator: "", creator: userStore.nickName || "", usageCount: 0 }); } else if (type === "edit" && row) { @@ -550,6 +562,39 @@ }); }; // å ³éç¥è¯è¡¨åå¯¹è¯æ¡ const closeKnowledgeDialog = () => { // æ¸ ç©ºè¡¨åæ°æ®ï¼é»è®¤å建人为å½åç¨æ· Object.assign(form.value, { id: undefined, title: "", type: "", scenario: "", efficiency: "", problem: "", solution: "", keyPoints: "", creator: userStore.nickName || "", usageCount: 0 }); // æ¸ é¤è¡¨åéªè¯ç¶æ if (formRef.value) { formRef.value.clearValidate(); } dialogVisible.value = false; }; // å ³éæ¥ç详æ å¯¹è¯æ¡ const closeViewDialog = () => { viewDialogVisible.value = false; }; // å¤çæ¥ç详æ å¯¹è¯æ¡ç¡®è®¤ï¼æ§è¡å¤å¶æä½ï¼ const handleViewDialogConfirm = () => { copyKnowledge(); closeViewDialog(); }; // æäº¤ç¥è¯è¡¨å const submitForm = async () => { try { @@ -559,7 +604,7 @@ addKnowledgeBase({...form.value}).then(res => { if(res.code == 200){ ElMessage.success("æ·»å æå"); dialogVisible.value = false; closeKnowledgeDialog(); getList(); } }).catch(err => { @@ -569,7 +614,7 @@ updateKnowledgeBase({...form.value}).then(res => { if(res.code == 200){ ElMessage.success("æ´æ°æå"); dialogVisible.value = false; closeKnowledgeDialog(); getList(); } }).catch(err => { src/views/collaborativeApproval/notificationManagement/meetApplication/index.vue
@@ -127,7 +127,7 @@ <el-option v-for="person in employees" :key="person.id" :label="`${person.staffName} (${person.postName})`" :label="`${person.staffName}${person.postName ? ` (${person.postName})` : ''}`" :value="person.id" /> </el-select> @@ -307,7 +307,7 @@ size: -1, staffState: 1 }).then(res => { employees.value = res.data.records.sort((a, b) => a.postName.localeCompare(b.postName)) employees.value = res.data.records.sort((a, b) => (a.postName || '').localeCompare(b.postName || '')) }) }) </script> src/views/collaborativeApproval/notificationManagement/meetExamine/index.vue
@@ -240,7 +240,7 @@ it.participants = staffList.value.filter(staff => staffs.some(id=>id === staff.id)).map(staff => { return { id: staff.id, name: `${staff.staffName}(${staff.postName})` name: `${staff.staffName}${staff.postName ? ` (${staff.postName})` : ''}` } }) src/views/collaborativeApproval/notificationManagement/meetPublish/index.vue
@@ -239,7 +239,7 @@ it.participants = staffList.value.filter(staff => staffs.some(id=>id === staff.id)).map(staff => { return { id: staff.id, name: `${staff.staffName}(${staff.postName})` name: `${staff.staffName}${staff.postName ? ` (${staff.postName})` : ''}` } }) src/views/collaborativeApproval/notificationManagement/summary/index.vue
@@ -214,7 +214,7 @@ it.participants = staffList.value.filter(staff => staffs.some(id => id === staff.id)).map(staff => { return { id: staff.id, name: `${staff.staffName}(${staff.postName})` name: `${staff.staffName}${staff.postName ? ` (${staff.postName})` : ''}` } }) src/views/collaborativeApproval/sealManagement/index.vue
@@ -82,7 +82,14 @@ </el-card> <!-- ç¨å°ç³è¯·å¯¹è¯æ¡ --> <el-dialog v-model="showSealApplyDialog" title="ç³è¯·ç¨å°" width="600px"> <FormDialog v-model="showSealApplyDialog" title="ç³è¯·ç¨å°" :width="'600px'" @close="closeSealApplyDialog" @confirm="submitSealApplication" @cancel="closeSealApplyDialog" > <el-form :model="sealForm" :rules="sealRules" ref="sealFormRef" label-width="100px"> <el-form-item label="ç³è¯·ç¼å·" prop="applicationNum"> <el-input v-model="sealForm.applicationNum" placeholder="请è¾å ¥ç³è¯·ç¼å·" /> @@ -119,13 +126,7 @@ </el-radio-group> </el-form-item> </el-form> <template #footer> <span class="dialog-footer"> <el-button @click="showSealApplyDialog = false">åæ¶</el-button> <el-button type="primary" @click="submitSealApplication">æäº¤ç³è¯·</el-button> </span> </template> </el-dialog> </FormDialog> <!-- è§ç« å¶åº¦åå¸å¯¹è¯æ¡ --> <!-- <el-dialog v-model="showRegulationDialog" :title="operationType === 'add' ? 'åå¸å¶åº¦' : 'ç¼è¾å¶åº¦'" width="800px"> @@ -177,10 +178,17 @@ </el-dialog> --> <!-- ç¨å°è¯¦æ å¯¹è¯æ¡ --> <el-dialog v-model="showSealDetailDialog" title="ç¨å°ç³è¯·è¯¦æ " width="700px"> <FormDialog v-model="showSealDetailDialog" title="ç¨å°ç³è¯·è¯¦æ " :width="'700px'" @close="closeSealDetailDialog" @confirm="closeSealDetailDialog" @cancel="closeSealDetailDialog" > <div v-if="currentSealDetail" class="mb10"> <el-descriptions :column="2" border> <el-descriptions-item label="ç³è¯·ç¼å·">{{ currentSealDetail.id }}</el-descriptions-item> <el-descriptions-item label="ç³è¯·ç¼å·">{{ currentSealDetail.applicationNum }}</el-descriptions-item> <el-descriptions-item label="ç³è¯·æ é¢">{{ currentSealDetail.title }}</el-descriptions-item> <el-descriptions-item label="ç³è¯·äºº">{{ currentSealDetail.createUserName }}</el-descriptions-item> <el-descriptions-item label="æå±é¨é¨">{{ currentSealDetail.department }}</el-descriptions-item> @@ -194,10 +202,17 @@ <el-descriptions-item label="ç³è¯·åå " :span="2">{{ currentSealDetail.reason }}</el-descriptions-item> </el-descriptions> </div> </el-dialog> </FormDialog> <!-- è§ç« å¶åº¦è¯¦æ å¯¹è¯æ¡ --> <el-dialog v-model="showRegulationDetailDialog" title="è§ç« å¶åº¦è¯¦æ " width="800px"> <FormDialog v-model="showRegulationDetailDialog" title="è§ç« å¶åº¦è¯¦æ " :width="'800px'" @close="closeRegulationDetailDialog" @confirm="handleRegulationDetailConfirm" @cancel="closeRegulationDetailDialog" > <div v-if="currentRegulationDetail"> <el-descriptions :column="2" border> <el-descriptions-item label="å¶åº¦ç¼å·">{{ currentRegulationDetail.id }}</el-descriptions-item> @@ -216,10 +231,17 @@ <el-button type="success" @click="resetForm(currentRegulationDetail)">确认æ¥ç</el-button> </div> </div> </el-dialog> </FormDialog> <!-- çæ¬åå²å¯¹è¯æ¡ --> <el-dialog v-model="showVersionHistoryDialog" title="çæ¬åå²" width="800px"> <FormDialog v-model="showVersionHistoryDialog" title="çæ¬åå²" :width="'800px'" @close="closeVersionHistoryDialog" @confirm="closeVersionHistoryDialog" @cancel="closeVersionHistoryDialog" > <el-table :data="versionHistory" style="width: 100%;margin-bottom: 10px"> <el-table-column prop="version" label="çæ¬å·" width="100" /> <el-table-column prop="updateTime" label="æ´æ°æ¶é´" width="180" /> @@ -232,10 +254,17 @@ </template> </el-table-column> </el-table> </el-dialog> </FormDialog> <!-- é è¯»ç¶æå¯¹è¯æ¡ --> <el-dialog v-model="showReadStatusDialog" title="é è¯»ç¶æ" width="800px"> <FormDialog v-model="showReadStatusDialog" title="é è¯»ç¶æ" :width="'800px'" @close="closeReadStatusDialog" @confirm="closeReadStatusDialog" @cancel="closeReadStatusDialog" > <el-table :data="readStatusList" style="width: 100%;margin-bottom: 10px"> <el-table-column prop="employee" label="åå·¥å§å" width="120" /> <el-table-column prop="department" label="æå±é¨é¨" width="150" /> @@ -249,7 +278,7 @@ </template> </el-table-column> </el-table> </el-dialog> </FormDialog> </div> </template> @@ -263,7 +292,8 @@ import { getUserProfile, userListNoPageByTenantId } from '@/api/system/user.js' import useUserStore from '@/store/modules/user' import { userLoginFacotryList } from "@/api/system/user.js" import {staffOnJobListPage} from "@/api/personnelManagement/staffOnJob.js"; import {staffOnJobListPage} from "@/api/personnelManagement/staffOnJob.js" import FormDialog from '@/components/Dialog/FormDialog.vue' // ååºå¼æ°æ® const currentUser = ref(null) @@ -434,7 +464,7 @@ addSealApplication(sealForm).then(res => { if(res.code == 200){ ElMessage.success('ç³è¯·æäº¤æå') showSealApplyDialog.value = false closeSealApplyDialog() getSealApplicationList() Object.assign(sealForm, { applicationNum: '', @@ -447,12 +477,53 @@ }) } }).catch(err => { ElMessage.error(err.msg) console.log(err.msg) }) } catch (error) { ElMessage.error('请å®åç³è¯·ä¿¡æ¯') } } // å ³éç¨å°ç³è¯·å¯¹è¯æ¡ const closeSealApplyDialog = () => { // æ¸ ç©ºè¡¨åæ°æ® Object.assign(sealForm, { applicationNum: '', title: '', sealType: '', reason: '', approveUserId: '', urgency: 'normal', status: 'pending' }) // æ¸ é¤è¡¨åéªè¯ç¶æ if (sealFormRef.value) { sealFormRef.value.clearValidate() } showSealApplyDialog.value = false } // å ³éç¨å°è¯¦æ å¯¹è¯æ¡ const closeSealDetailDialog = () => { showSealDetailDialog.value = false } // å ³éè§ç« å¶åº¦è¯¦æ å¯¹è¯æ¡ const closeRegulationDetailDialog = () => { showRegulationDetailDialog.value = false } // å¤çè§ç« å¶åº¦è¯¦æ 确认 const handleRegulationDetailConfirm = () => { // 妿tableData>0ï¼æ§è¡ç¡®è®¤æ¥çæä½ if (currentRegulationDetail.value && tableData.value && tableData.value.length > 0) { resetForm(currentRegulationDetail.value) } closeRegulationDetailDialog() } // å ³éçæ¬åå²å¯¹è¯æ¡ const closeVersionHistoryDialog = () => { showVersionHistoryDialog.value = false } // å ³éé è¯»ç¶æå¯¹è¯æ¡ const closeReadStatusDialog = () => { showReadStatusDialog.value = false } // æ°å¢ const handleAdd = () => { @@ -735,6 +806,13 @@ }) } // å页ååå¤ç const paginationChange = (obj) => { page.current = obj.page; page.size = obj.limit; getSealApplicationList(); }; // çå¬å¯¹è¯æ¡æå¼ï¼è·åç¨æ·å表 watch(showSealApplyDialog, (newVal) => { if (newVal) { src/views/procurementManagement/invoiceEntry/index.vue
@@ -112,6 +112,8 @@ gePurchaseListPage, { purchaseContractNumber: undefined, // åªæ¥è¯¢å·²å®¡æ¹éè¿ï¼ææå®ç¶æä¸º 3ï¼çè®°å½ approvalStatus: 3, }, [ { src/views/procurementManagement/paymentEntry/index.vue
@@ -261,7 +261,6 @@ { label: "ä¾åºååç§°", prop: "supplierName", width:240 }, { label: "仿¬¾ç¶æ", @@ -282,7 +281,6 @@ label: "产å大类", prop: "productCategory", showOverflowTooltip: true, width: 100 }, { label: "è§æ ¼åå·", @@ -293,7 +291,6 @@ { label: "已仿¬¾éé¢(å )", prop: "ticketsTotal", width: 120, formatData: (params) => { return params ? parseFloat(params).toFixed(2) : 0; }, @@ -301,7 +298,6 @@ { label: "å¾ ä»æ¬¾éé¢(å )", prop: "pendingTicketsTotal", width: 120, formatData: (params) => { return params ? parseFloat(params).toFixed(2) : 0; }, @@ -327,6 +323,8 @@ searchForm: { supplierNameOrContractNo: "", status: false, // åªæ¥è¯¢å®¡æ¹ç¶æä¸º 3 çè®°å½ approvalStatus: 3, }, form: { purchaseContractNumber: "", src/views/productionManagement/productionOrder/index.vue
@@ -50,6 +50,7 @@ :tableData="tableData" :page="page" :tableLoading="tableLoading" :row-class-name="tableRowClassName" @pagination="pagination"> <template #completionStatus="{ row }"> <el-progress @@ -163,6 +164,12 @@ width: 120, }, { label: "äº¤ä»æ¥æ", prop: "deliveryDate", formatData: val => (val ? dayjs(val).format("YYYY-MM-DD") : ""), width: 120, }, { dataType: "action", label: "æä½", align: "center", @@ -228,6 +235,18 @@ if (p < 50) return "#e6a23c"; if (p < 80) return "#409eff"; return "#67c23a"; }; // æ·»å 表è¡ç±»åæ¹æ³ const tableRowClassName = ({ row }) => { switch (row.deliveryDaysDiff) { case 15: return 'yellow' case 10: return 'red' case 2: return 'purple' } }; // ç»å®å·¥èºè·¯çº¿å¼¹æ¡ @@ -388,4 +407,17 @@ <style scoped lang="scss"> .search_form{ align-items: start; }</style> } ::v-deep .yellow { background-color: #FAF0DE; } ::v-deep .red { background-color: #FAE1DE; } ::v-deep .purple{ background-color: #F4DEFA; } </style> src/views/safeProduction/emergencyPlanReview/index.vue
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,810 @@ <template> <div class="app-container"> <div class="search_form"> <div> <span class="search_title">åºæ¥é¢æ¡åç§°ï¼</span> <el-input v-model="searchForm.planName" style="width: 240px" placeholder="请è¾å ¥åºæ¥é¢æ¡åç§°æç´¢" @change="handleQuery" clearable :prefix-icon="Search" /> <span class="search_title ml10">åºæ¥é¢æ¡ç±»åï¼</span> <el-select v-model="searchForm.planType" clearable @change="handleQuery" style="width: 240px"> <el-option v-for="item in emergencyPlanTypeOptions" :key="item.value" :label="item.label" :value="item.value" /> </el-select> <el-button type="primary" @click="handleQuery" style="margin-left: 10px"> æç´¢ </el-button> </div> <div> <el-button type="primary" @click="openForm('add')">æ°å¢åºæ¥é¢æ¡</el-button> <el-button type="danger" plain @click="handleDelete">å é¤</el-button> </div> </div> <div class="table_list"> <PIMTable rowKey="id" :column="tableColumn" :tableData="tableData" :page="page" :isSelection="true" @selection-change="handleSelectionChange" :tableLoading="tableLoading" @pagination="pagination" :total="page.total"></PIMTable> </div> <!-- æ°å¢/ç¼è¾åºæ¥é¢æ¡å¼¹çª --> <el-dialog v-model="dialogVisible" :title="dialogTitle" width="800px" :close-on-click-modal="false"> <el-form ref="formRef" :model="form" :rules="rules" label-width="120px"> <el-row :gutter="20"> <el-col :span="12"> <el-form-item label="åºæ¥é¢æ¡ç¼ç " prop="planCode"> <el-input v-model="form.planCode" placeholder="请è¾å ¥åºæ¥é¢æ¡ç¼ç " /> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="åºæ¥é¢æ¡åç§°" prop="planName"> <el-input v-model="form.planName" placeholder="请è¾å ¥åºæ¥é¢æ¡åç§°" /> </el-form-item> </el-col> </el-row> <el-row :gutter="20"> <el-col :span="12"> <el-form-item label="åå¸çææ¶é´ï¼" prop="publishTime"> <el-date-picker style="width: 100%" v-model="form.publishTime" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="date" placeholder="è¯·éæ©" clearable /> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="æ ¸å¿è´£ä»»äººï¼" prop="coreResponsorUserId"> <el-select v-model="form.coreResponsorUserId" placeholder="è¯·éæ©" @change="handleChange" clearable> <el-option v-for="item in userList" :key="item.userId" :label="item.nickName" :value="item.userId" /> </el-select> </el-form-item> </el-col> </el-row> <el-row :gutter="20"> <el-col :span="12"> <el-form-item label="颿¡ç±»å" prop="planType"> <el-select v-model="form.planType" placeholder="è¯·éæ©é¢æ¡ç±»å" style="width: 100%"> <el-option v-for="item in emergencyPlanTypeOptions" :key="item.value" :label="item.label" :value="item.value" /> </el-select> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="夿³¨" prop="remark"> <el-input v-model="form.remark" placeholder="请è¾å ¥å¤æ³¨" /> </el-form-item> </el-col> </el-row> <el-form-item label="éç¨èå´" prop="applyScope"> <el-checkbox-group v-model="form.applyScope"> <el-checkbox label="all">å ¨ä½åå·¥</el-checkbox> <el-checkbox label="manager">管çå±</el-checkbox> <el-checkbox label="hr">人äºé¨é¨</el-checkbox> <el-checkbox label="finance">è´¢å¡é¨é¨</el-checkbox> <el-checkbox label="tech">ææ¯é¨é¨</el-checkbox> </el-checkbox-group> </el-form-item> <el-form-item label="åºæ¥å¤ç½®æ¥éª¤" prop="execSteps"> <div class="exec-steps-container" style="width:100%"> <div v-for="(step, index) in execStepsList" :key="index" class="exec-step-item"> <div class="step-header"> <div> <el-input v-model="step.step" placeholder="æ¥éª¤" style="width: 200px; margin-right: 10px" /> <el-button type="danger" size="small" @click="removeExecStep(index)" style="margin-left: 10px">å é¤</el-button> </div> <div style="margin-top: 5px;width: 100%;"> <el-input v-model="step.description" placeholder="æªæ½" type="textarea" :rows="2" style="flex: 1" /> </div> </div> </div> <el-button type="primary" size="small" @click="addExecStep" style="margin-top: 10px">æ·»å æ¥éª¤</el-button> </div> </el-form-item> </el-form> <template #footer> <span class="dialog-footer"> <el-button @click="dialogVisible = false">åæ¶</el-button> <el-button type="primary" @click="submitForm">ç¡®å®</el-button> </span> </template> </el-dialog> <!-- æ¥çåºæ¥é¢æ¡è¯¦æ å¼¹çª --> <el-dialog v-model="viewDialogVisible" title="åºæ¥é¢æ¡è¯¦æ " width="900px" :close-on-click-modal="false"> <div class="knowledge-detail"> <el-descriptions :column="2" border> <el-descriptions-item label="åºæ¥é¢æ¡åç§°" :span="2"> <span class="detail-title">{{ currentKnowledge.planName }}</span> </el-descriptions-item> <el-descriptions-item label="åºæ¥é¢æ¡ç¼ç "> <span>{{ currentKnowledge.planCode }}</span> </el-descriptions-item> <el-descriptions-item label="åå¸çææ¶é´"> {{ currentKnowledge.publishTime }} </el-descriptions-item> <el-descriptions-item label="æ ¸å¿è´£ä»»äºº"> {{ currentKnowledge.coreResponsorUserName }} </el-descriptions-item> <el-descriptions-item label="颿¡ç±»å"> <el-tag type="warning"> {{ currentKnowledge.planType }}</el-tag> </el-descriptions-item> <el-descriptions-item label="夿³¨"> {{ currentKnowledge.remark }} </el-descriptions-item> </el-descriptions> <div class="detail-section"> <h4>éç¨èå´</h4> <div class="key-points"> <el-tag v-for="(point, index) in currentKnowledge.applyScope.split(',')" :key="index" type="primary" style="margin-right: 8px; margin-bottom: 8px;"> {{ getApplyScopeLabel(point.trim()) }} </el-tag> </div> </div> <div class="detail-section"> <h4>åºæ¥å¤ç½®æ¥éª¤</h4> <div class="detail-content"> <div v-if="currentKnowledge.execSteps"> <div v-for="(step, index) in JSON.parse(currentKnowledge.execSteps)" :key="index" class="exec-step-view"> <span class="step-number">{{ index + 1 }}.</span> <span class="step-title">{{ step.step }}ï¼</span> <span>{{ step.description }}</span> </div> </div> <div v-else class="no-data">æ åºæ¥å¤ç½®æ¥éª¤</div> </div> </div> </div> <template #footer> <span class="dialog-footer"> <el-button @click="viewDialogVisible = false">å ³é</el-button> <!-- <el-button type="success" @click="markAsFavorite">æ¶è@</el-button> --> </span> </template> </el-dialog> </div> </template> <script setup> import { Search } from "@element-plus/icons-vue"; import { onMounted, ref, reactive, toRefs, getCurrentInstance, computed, } from "vue"; import { ElMessage, ElMessageBox } from "element-plus"; import PIMTable from "@/components/PIMTable/PIMTable.vue"; import { userListNoPage } from "@/api/system/user.js"; import { safeContingencyPlanListPage, safeContingencyPlanAdd, safeContingencyPlanUpdate, safeContingencyPlanDel, } from "@/api/safeProduction/emergencyPlanReview.js"; // 表åéªè¯è§å const rules = { planCode: [ { required: true, message: "请è¾å ¥åºæ¥é¢æ¡ç¼ç ", trigger: "blur" }, ], applyScope: [ { required: true, message: "è¯·éæ©éç¨èå´", trigger: "change" }, ], planType: [{ required: true, message: "è¯·éæ©é¢æ¡ç±»å", trigger: "change" }], planName: [ { required: true, message: "请è¾å ¥åºæ¥é¢æ¡åç§°", trigger: "blur" }, ], publishTime: [ { required: true, message: "è¯·éæ©åå¸çææ¶é´", trigger: "change" }, ], coreResponsorUserId: [ { required: true, message: "è¯·éæ©æ ¸å¿è´£ä»»äºº", trigger: "change" }, ], }; // ååºå¼æ°æ® const data = reactive({ searchForm: { planName: "", planType: "", }, tableLoading: false, page: { current: 1, size: 20, total: 0, }, tableData: [], selectedIds: [], form: { planCode: "", // 颿¡ç¼å· applyScope: [], // éç¨èå´ planType: "", // 颿¡ç±»å planName: "", // 颿¡åç§° publishTime: "", // å叿¶é´ coreResponsorUserId: "", // æ ¸å¿è´è´£äººç¨æ·ID coreResponsorUserName: "", // æ ¸å¿è´è´£äººç¨æ·å remark: "", // 夿³¨ execSteps: "", // æ§è¡æ¥éª¤ }, dialogVisible: false, dialogTitle: "", dialogType: "add", viewDialogVisible: false, currentKnowledge: {}, }); const { searchForm, tableLoading, page, tableData, selectedIds, form, dialogVisible, dialogTitle, dialogType, viewDialogVisible, currentKnowledge, } = toRefs(data); // 表åå¼ç¨ const formRef = ref(); const execStepsList = ref([]); // è¡¨æ ¼åé ç½® const tableColumn = ref([ { label: "åºæ¥é¢æ¡ç¼ç ", prop: "planCode", showOverflowTooltip: true, }, { label: "åºæ¥é¢æ¡åç§°", prop: "planName", showOverflowTooltip: true, }, { label: "åå¸çææ¶é´", prop: "publishTime", showOverflowTooltip: true, }, { label: "æ ¸å¿è´£ä»»äºº", prop: "coreResponsorUserName", showOverflowTooltip: true, }, { label: "颿¡ç±»å", prop: "planType", showOverflowTooltip: true, }, { label: "夿³¨", prop: "remark", showOverflowTooltip: true, }, { dataType: "action", label: "æä½", align: "center", fixed: "right", width: 200, operation: [ { name: "ç¼è¾", type: "text", clickFun: row => { openForm("edit", row); }, }, { name: "æ¥ç", type: "text", clickFun: row => { viewKnowledge(row); }, }, ], }, ]); const userList = ref([]); // çå½å¨æ onMounted(() => { userListNoPage().then(res => { userList.value = res.data; }); getList(); startAutoRefresh(); }); const handleChange = userId => { const selectedUser = userList.value.find(user => user.userId === userId); if (selectedUser) { form.value.coreResponsorUserName = selectedUser.nickName; } }; // åºæ¥å¤ç½®æ¥éª¤ç®¡ç const addExecStep = () => { const stepNumber = execStepsList.value.length + 1; execStepsList.value.push({ step: `æ¥éª¤${stepNumber}`, description: "", }); }; const removeExecStep = index => { execStepsList.value.splice(index, 1); }; const initExecSteps = execSteps => { if (execSteps) { try { execStepsList.value = JSON.parse(execSteps); } catch (e) { execStepsList.value = []; } } else { execStepsList.value = []; } }; // å¼å§èªå¨å·æ° const startAutoRefresh = () => { setInterval(() => { getList(); }, 600000); // 10åéå·æ°ä¸æ¬¡ (10 * 60 * 1000 = 600000ms) }; // æ¥è¯¢æ°æ® const handleQuery = () => { page.value.current = 1; getList(); }; const getList = () => { tableLoading.value = true; safeContingencyPlanListPage({ ...page.value, ...searchForm.value }) .then(res => { tableLoading.value = false; tableData.value = res.data.records; page.total = res.data.total; }) .catch(err => { tableLoading.value = false; }); }; // å页å¤ç const pagination = obj => { page.value.current = obj.page; page.value.size = obj.limit; handleQuery(); }; // éæ©ååå¤ç const handleSelectionChange = selection => { selectedIds.value = selection.map(item => item.id); }; // æå¼è¡¨å const openForm = (type, row = null) => { dialogType.value = type; if (type === "add") { dialogTitle.value = "æ°å¢åºæ¥é¢æ¡"; // é置表å Object.assign(form.value, { planCode: "", // 颿¡ç¼å· applyScope: [], // éç¨èå´ planType: "", // 颿¡ç±»å planName: "", // 颿¡åç§° publishTime: "", // å叿¶é´ coreResponsorUserId: "", // æ ¸å¿è´è´£äººç¨æ·ID coreResponsorUserName: "", // æ ¸å¿è´è´£äººç¨æ·å remark: "", // 夿³¨ execSteps: "", // æ§è¡æ¥éª¤ }); initExecSteps(""); } else if (type === "edit" && row) { dialogTitle.value = "ç¼è¾åºæ¥é¢æ¡"; Object.assign(form.value, { id: row.id, planCode: row.planCode, // 颿¡ç¼å· applyScope: row.applyScope ? row.applyScope.split(",") : [], // éç¨èå´ planType: row.planType, // 颿¡ç±»å planName: row.planName, // 颿¡åç§° publishTime: row.publishTime, // å叿¶é´ coreResponsorUserId: row.coreResponsorUserId, // æ ¸å¿è´è´£äººç¨æ·ID coreResponsorUserName: row.coreResponsorUserName, // æ ¸å¿è´è´£äººç¨æ·å remark: row.remark, // 夿³¨ execSteps: row.execSteps, // æ§è¡æ¥éª¤ }); initExecSteps(row.execSteps); } dialogVisible.value = true; }; // æ¥çåºæ¥é¢æ¡è¯¦æ const viewKnowledge = row => { currentKnowledge.value = { ...row }; viewDialogVisible.value = true; }; const getApplyScopeLabel = scope => { const scopeMap = { all: "å ¨ä½åå·¥", manager: "管çå±", hr: "人äºé¨é¨", finance: "è´¢å¡é¨é¨", tech: "ææ¯é¨é¨", }; return scopeMap[scope] || scope; }; // è·åç±»åæ ç¾ç±»å const getTypeTagType = type => { const typeMap = { contract: "success", approval: "warning", solution: "primary", experience: "info", guide: "danger", }; return typeMap[type] || "info"; }; // è·åç±»åæ ç¾ææ¬ const getTypeLabel = type => { return getKnowledgeTypeLabel(type); }; // è·åæçæ ç¾ç±»å const getEfficiencyTagType = efficiency => { const typeMap = { high: "success", medium: "warning", low: "info", }; return typeMap[efficiency] || "info"; }; // è·åæçæ ç¾ææ¬ const getEfficiencyLabel = efficiency => { const efficiencyMap = { high: "æ¾èæå", medium: "ä¸è¬æå", low: "轻微æå", }; return efficiencyMap[efficiency] || efficiency; }; // è·åæçæåç¾åæ¯ const getEfficiencyScore = efficiency => { const scoreMap = { high: 40, medium: 25, low: 15, }; return scoreMap[efficiency] || 0; }; // è·åå¹³åèçæ¶é´ const getTimeSaved = efficiency => { const timeMap = { high: "2-3天", medium: "1-2天", low: "0.5-1天", }; return timeMap[efficiency] || "æªç¥"; }; const emergencyPlanTypeOptions = computed(() => [ { value: "é¢é²æ§åºæ¥é¢æ¡", label: "é¢é²æ§åºæ¥é¢æ¡", }, { value: "åºæ¥å¤ç颿¡", label: "åºæ¥å¤ç颿¡", }, { value: "æ¢å¤æ§åºæ¥é¢æ¡", label: "æ¢å¤æ§åºæ¥é¢æ¡", }, ]); // æäº¤åºæ¥é¢æ¡è¡¨å const submitForm = async () => { try { await formRef.value.validate(); // éªè¯åºæ¥å¤ç½®æ¥éª¤ for (let i = 0; i < execStepsList.value.length; i++) { const step = execStepsList.value[i]; if (!step.step || !step.step.trim()) { ElMessage.error(`第${i + 1}æ¡æ¥éª¤ç"æ¥éª¤"ä¸è½ä¸ºç©º`); return; } if (!step.description || !step.description.trim()) { ElMessage.error(`第${i + 1}æ¡æ¥éª¤ç"æªæ½"ä¸è½ä¸ºç©º`); return; } } // å°åºæ¥å¤ç½®æ¥éª¤è½¬æ¢ä¸ºJSONå符串 form.value.execSteps = JSON.stringify(execStepsList.value); if (dialogType.value === "add") { // æ°å¢åºæ¥é¢æ¡ form.value.applyScope = form.value.applyScope.join(","); safeContingencyPlanAdd({ ...form.value }) .then(res => { if (res.code == 200) { ElMessage.success("æ·»å æå"); dialogVisible.value = false; getList(); } }) .catch(err => { ElMessage.error(err.msg); }); } else { form.value.applyScope = form.value.applyScope.join(","); safeContingencyPlanUpdate({ ...form.value }) .then(res => { if (res.code == 200) { ElMessage.success("æ´æ°æå"); dialogVisible.value = false; getList(); } }) .catch(err => { ElMessage.error(err.msg); }); } } catch (error) { console.error("表åéªè¯å¤±è´¥:", error); } }; // å é¤åºæ¥é¢æ¡ const handleDelete = () => { if (selectedIds.value.length === 0) { ElMessage.warning("è¯·éæ©è¦å é¤çåºæ¥é¢æ¡"); return; } ElMessageBox.confirm("éä¸çå 容å°è¢«å é¤ï¼æ¯å¦ç¡®è®¤å é¤ï¼", "å é¤", { confirmButtonText: "确认", cancelButtonText: "åæ¶", type: "warning", }) .then(() => { // console.log(selectedIds.value); safeContingencyPlanDel(selectedIds.value).then(res => { if (res.code == 200) { ElMessage.success("å 餿å"); selectedIds.value = []; getList(); } }); }) .catch(() => { // ç¨æ·åæ¶ }); }; // å¯¼åº const { proxy } = getCurrentInstance(); const { knowledge_type } = proxy.useDict("knowledge_type"); // åå ¸å·¥å · const knowledgeTypeOptions = computed(() => knowledge_type?.value || []); const getKnowledgeTypeLabel = val => { const item = knowledgeTypeOptions.value.find( i => String(i.value) === String(val) ); return item ? item.label : val; }; const getKnowledgeTypeTagType = val => { const item = knowledgeTypeOptions.value.find( i => String(i.value) === String(val) ); return item?.elTagType || "info"; }; const handleExport = () => { proxy.download( "/knowledgeBase/export", { ...searchForm.value }, "åºæ¥é¢æ¡åº.xlsx" ); }; </script> <style scoped> .auto-refresh-info { margin-bottom: 15px; } .auto-refresh-info .el-alert { border-radius: 8px; } .dialog-footer { text-align: right; } .knowledge-detail { padding: 20px 0; } .detail-title { font-size: 18px; font-weight: bold; color: #303133; } .detail-section { margin-top: 24px; } .detail-section h4 { margin: 0 0 12px 0; font-size: 16px; font-weight: 600; color: #303133; border-left: 4px solid #409eff; padding-left: 12px; } .detail-content { background: #f8f9fa; padding: 16px; border-radius: 6px; line-height: 1.6; color: #606266; white-space: pre-wrap; } .key-points { display: flex; flex-wrap: wrap; gap: 8px; } .usage-stats { margin-top: 16px; } .stat-item { text-align: center; padding: 20px; background: #f8f9fa; border-radius: 8px; } .stat-number { font-size: 24px; font-weight: bold; color: #409eff; margin-bottom: 8px; } .stat-label { font-size: 14px; color: #909399; } .exec-steps-container { border: 1px solid #e4e7ed; border-radius: 4px; padding: 15px; background-color: #f9fafc; } .exec-step-item { margin-bottom: 10px; padding: 10px; background-color: #ffffff; border: 1px solid #e4e7ed; border-radius: 4px; } .step-header { display: flex; align-items: flex-start; flex-direction: column; } .exec-step-view { margin-bottom: 8px; padding-left: 20px; position: relative; } .step-number { position: absolute; left: 0; font-weight: bold; color: #409eff; } .step-title { font-weight: bold; margin-right: 5px; } .no-data { color: #909399; font-style: italic; } </style> src/views/safeProduction/hazardousMaterialsControl/index.vue
@@ -53,7 +53,8 @@ v-if="dialogType === 'add'" :model="form" :rules="rules" label-width="120px"> label-width="140px" label-position="top"> <el-row :gutter="20"> <el-col :span="12"> <el-form-item label="å±é©æº" @@ -200,7 +201,8 @@ v-if="dialogType === 'edit'" :model="form" :rules="rules1" label-width="120px"> label-width="140px" label-position="top"> <el-row :gutter="20"> <el-col :span="12"> <el-form-item label="å½è¿äºº" src/views/salesManagement/deliveryLedger/index.vue
@@ -52,7 +52,7 @@ type="primary" size="small" :disabled="isApproving(scope.row.status)" @click="openForm('edit', scope.row)">ç¼è¾</el-button> @click="openForm('edit', scope.row)">è¡¥å åè´§ä¿¡æ¯</el-button> <el-button link type="danger" @@ -177,9 +177,9 @@ import { getToken } from "@/utils/auth"; import { getCurrentDate } from "@/utils/index.js"; import { deliveryLedgerListPage, addOrUpdateDeliveryLedger, delDeliveryLedger, deliveryLedgerListPage, addOrUpdateDeliveryLedger, delDeliveryLedger, deductStock, } from "@/api/salesManagement/deliveryLedger.js"; import { delLedgerFile } from "@/api/salesManagement/salesLedger.js"; @@ -392,7 +392,7 @@ expressNumber: form.value.type === "å¿«é" ? form.value.expressNumber : "", tempFileIds: tempFileIds, }; addOrUpdateDeliveryLedger(payload).then((res) => { deductStock(payload).then((res) => { proxy.$modal.msgSuccess("æä½æå"); closeDia(); getList(); src/views/salesManagement/salesLedger/index.vue
@@ -37,7 +37,7 @@ </div> </div> <el-table :data="tableData" border v-loading="tableLoading" @selection-change="handleSelectionChange" :expand-row-keys="expandedRowKeys" :row-key="(row) => row.id" show-summary style="width: 100%" :expand-row-keys="expandedRowKeys" :row-key="(row) => row.id" :row-class-name="tableRowClassName" show-summary style="width: 100%" :summary-method="summarizeMainTable" @expand-change="expandChange" height="calc(100vh - 18.5em)"> <el-table-column align="center" type="selection" width="55" fixed="left"/> <el-table-column type="expand" width="60" fixed="left"> @@ -117,6 +117,7 @@ <el-table-column label="å½å ¥äºº" prop="entryPersonName" width="100" show-overflow-tooltip /> <el-table-column label="å½å ¥æ¥æ" prop="entryDate" width="120" show-overflow-tooltip /> <el-table-column label="ç¾è®¢æ¥æ" prop="executionDate" width="120" show-overflow-tooltip /> <el-table-column label="äº¤ä»æ¥æ" prop="deliveryDate" width="120" show-overflow-tooltip /> <el-table-column fixed="right" label="æä½" min-width="100" align="center"> <template #default="scope"> <el-button link type="primary" size="small" @click="openForm('edit', scope.row)">ç¼è¾</el-button> @@ -204,6 +205,14 @@ </el-form-item> </el-col> </el-row> <el-row :gutter="30"> <el-col :span="12"> <el-form-item label="äº¤è´§æ¥æï¼" prop="entryDate"> <el-date-picker style="width: 100%" v-model="form.deliveryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="date" placeholder="è¯·éæ©" clearable /> </el-form-item> </el-col> </el-row> <el-row> <el-form-item label="产åä¿¡æ¯ï¼" prop="entryDate"> <el-button v-if="operationType !== 'view'" type="primary" @click="openProductForm('add')">æ·»å </el-button> @@ -694,6 +703,7 @@ customerId: "", entryPerson: "", entryDate: "", deliveryDate: "", maintenanceTime: "", productData: [], executionDate: "", @@ -703,6 +713,7 @@ customerId: [{ required: true, message: "è¯·éæ©", trigger: "change" }], entryPerson: [{ required: true, message: "è¯·éæ©", trigger: "change" }], entryDate: [{ required: true, message: "è¯·éæ©", trigger: "change" }], deliveryDate: [{ required: true, message: "è¯·éæ©", trigger: "change" }], executionDate: [{ required: true, message: "è¯·éæ©", trigger: "change" }], }, }); @@ -986,6 +997,18 @@ } else { expandedRowKeys.value = []; } }; // æ·»å 表è¡ç±»åæ¹æ³ const tableRowClassName = ({ row }) => { switch (row.deliveryDaysDiff) { case 15: return 'yellow' case 10: return 'red' case 2: return 'purple' } }; // 主表åè®¡æ¹æ³ const summarizeMainTable = (param) => { @@ -2084,6 +2107,19 @@ margin-left: 10px; } ::v-deep .yellow { background-color: #FAF0DE; } ::v-deep .red { background-color: #FAE1DE; } ::v-deep .purple{ background-color: #F4DEFA; } .table_list { margin-top: unset; } src/views/salesManagement/salesQuotation/index.vue
@@ -51,7 +51,7 @@ height="calc(100vh - 22em)" > <el-table-column align="center" label="åºå·" type="index" width="60" /> <el-table-column prop="quotationNo" label="æ¥ä»·åå·" width="150" /> <el-table-column prop="quotationNo" label="æ¥ä»·åå·" /> <el-table-column prop="customer" label="客æ·åç§°" /> <el-table-column prop="salesperson" label="ä¸å¡å" width="100" /> <el-table-column prop="quotationDate" label="æ¥ä»·æ¥æ" width="120" /> @@ -252,7 +252,7 @@ @change="getProductModel($event, scope.row)" > <el-option v-for="item in modelOptions" v-for="item in scope.row.modelOptions || []" :key="item.id" :label="item.model" :value="item.id" @@ -322,7 +322,7 @@ </el-descriptions-item> </el-descriptions> <div style="margin-top: 20px;"> <div style="margin: 20px 0;"> <h4>产åæç»</h4> <el-table :data="currentQuotation.products" border style="width: 100%"> <el-table-column prop="product" label="产ååç§°" /> @@ -521,7 +521,7 @@ if (!value) { row.productId = ''; row.product = ''; modelOptions.value = []; row.modelOptions = []; row.specificationId = ''; row.specification = ''; row.unit = ''; @@ -534,9 +534,9 @@ if (label) { row.product = label; } // è·åè§æ ¼åå·å表 // è·åè§æ ¼åå·å表ï¼è®¾ç½®å°å½åè¡ç modelOptions modelList({ id: value }).then((res) => { modelOptions.value = res || []; row.modelOptions = res || []; }); }; const getProductModel = (value, row) => { @@ -550,10 +550,11 @@ } // æ´æ° specificationIdï¼v-model å·²ç»èªå¨æ´æ°ï¼è¿éç¡®ä¿ä¸è´æ§ï¼ row.specificationId = value; const index = modelOptions.value.findIndex((item) => item.id === value); const modelOptions = row.modelOptions || []; const index = modelOptions.findIndex((item) => item.id === value); if (index !== -1) { row.specification = modelOptions.value[index].model; row.unit = modelOptions.value[index].unit; row.specification = modelOptions[index].model; row.unit = modelOptions[index].unit; } else { row.specification = ''; row.unit = ''; @@ -616,23 +617,46 @@ form.paymentMethod = row.paymentMethod || '' form.status = row.status || 'è稿' form.remark = row.remark || '' form.products = row.products ? row.products.map(product => { form.products = row.products ? await Promise.all(row.products.map(async (product) => { const productName = product.product || product.productName || '' // ä¼å ç¨ productIdï¼å¦æåªæåç§°ï¼å°è¯åæ¥ id 以便æ éæ©å¨åæ¾ const resolvedId = product.productId const resolvedProductId = product.productId ? Number(product.productId) : findNodeIdByLabel(productOptions.value, productName) || '' // 妿æäº§åIDï¼å 载对åºçè§æ ¼åå·å表 let modelOptions = []; let resolvedSpecificationId = product.specificationId || ''; if (resolvedProductId) { try { const res = await modelList({ id: resolvedProductId }); modelOptions = res || []; // 妿è¿åçæ°æ®æ²¡æ specificationIdï¼ä½æ specification åç§°ï¼æ ¹æ®åç§°æ¥æ¾ ID if (!resolvedSpecificationId && product.specification) { const foundModel = modelOptions.find(item => item.model === product.specification); if (foundModel) { resolvedSpecificationId = foundModel.id; } } } catch (error) { console.error('å è½½è§æ ¼åå·å¤±è´¥:', error); } } return { productId: resolvedId, productId: resolvedProductId, product: productName, specificationId: product.specificationId || '', specificationId: resolvedSpecificationId, specification: product.specification || '', quantity: product.quantity || 0, unit: product.unit || '', unitPrice: product.unitPrice || 0, amount: product.amount || 0 amount: product.amount || 0, modelOptions: modelOptions // 为æ¯è¡æ·»å ç¬ç«çè§æ ¼åå·å表 } }) : [] })) : [] form.subtotal = row.subtotal || 0 form.freight = row.freight || 0 form.otherFee = row.otherFee || 0 @@ -714,7 +738,8 @@ quantity: 1, unit: '', unitPrice: 0, amount: 0 amount: 0, modelOptions: [] // 为æ¯è¡æ·»å ç¬ç«çè§æ ¼åå·å表 }) }