| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // 产åç»´æ¤é¡µé¢æ¥å£ |
| | | import request from '@/utils/request' |
| | | |
| | | // äº§åæ æ¥è¯¢ |
| | | export function productTreeList(query) { |
| | | return request({ |
| | | url: '/productMaterial/list', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | } |
| | | // 产ååç±»æ°å¢ |
| | | export function addOrEditProduct(query) { |
| | | return request({ |
| | | url: '/productMaterial/add', |
| | | method: 'post', |
| | | data: query |
| | | }) |
| | | } |
| | | // 产ååç±»ä¿®æ¹ |
| | | export function updateOrEditProduct(query) { |
| | | return request({ |
| | | url: '/productMaterial/update', |
| | | method: 'put', |
| | | data: query |
| | | }) |
| | | } |
| | | // è§æ ¼åå·æ°å¢ |
| | | export function addOrEditProductModel(query) { |
| | | return request({ |
| | | url: '/productMaterialSku/add', |
| | | method: 'post', |
| | | data: query |
| | | }) |
| | | } |
| | | // è§æ ¼åå·ä¿®æ¹ |
| | | export function updateOrEditProductModel(query) { |
| | | return request({ |
| | | url: '/productMaterialSku/update', |
| | | method: 'post', |
| | | data: query |
| | | }) |
| | | } |
| | | // 产ååç±»å é¤ |
| | | export function delProduct(query) { |
| | | return request({ |
| | | url: '/productMaterial/delete', |
| | | method: 'delete', |
| | | data: query |
| | | }) |
| | | } |
| | | // è§æ ¼åå·å é¤ |
| | | export function delProductModel(query) { |
| | | return request({ |
| | | url: '/productMaterialSku/delete', |
| | | method: 'delete', |
| | | data: query |
| | | }) |
| | | } |
| | | // è§æ ¼åå·æ¥è¯¢ |
| | | export function modelList(query) { |
| | | return request({ |
| | | url: '/basic/product/modelList', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | } |
| | | export function modelListPage(query) { |
| | | return request({ |
| | | url: '/productMaterialSku/list', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | } |
| | | |
| | | // ä¸è½½äº§å导å
¥æ¨¡æ¿ |
| | | export function downloadProductModelImportTemplate() { |
| | | return request({ |
| | | url: '/basic/product/export', |
| | | method: 'get', |
| | | responseType: 'blob' |
| | | }) |
| | | } |
| | | |
| | | // 产å大类æ°å¢ |
| | | export function addOrEditProductConfig(query) { |
| | | return request({ |
| | | url: '/productMaterial/config/add', |
| | | method: 'post', |
| | | data: query |
| | | }) |
| | | } |
| | | // 产åå¤§ç±»ä¿®æ¹ |
| | | export function updateOrEditProductConfig(query) { |
| | | return request({ |
| | | url: '/productMaterial/config/update', |
| | | method: 'put', |
| | | data: query |
| | | }) |
| | | } |
| | | |
| | | // 产å大类å é¤ |
| | | export function delProductConfig(query) { |
| | | return request({ |
| | | url: '/productMaterial/config/delete', |
| | | method: 'delete', |
| | | data: query |
| | | }) |
| | | } |
| | | |
| | | // 产åç©æä¿¡æ¯-åè´§ç±»å«æ°æ®éå |
| | | export function getinventoryCategoryList(query) { |
| | | return request({ |
| | | url: '/productMaterial/inventoryCategoryList', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | } |
| | | // 产åç©æä¿¡æ¯-ç©æç±»åæ°æ®éå |
| | | export function getmaterialTypeList(query) { |
| | | return request({ |
| | | url: '/productMaterial/materialTypeList', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // è½èææ¬æ ¸ç®æ¥å£ |
| | | import request from "@/utils/request"; |
| | | |
| | | // è½èææ¬ç»è®¡ |
| | | export function energyCostStatistics(query) { |
| | | return request({ |
| | | url: "/energyCost/statistics", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| | | |
| | | // 导åºè½èææ¬æ¥è¡¨ |
| | | export function exportEnergyCostReport(query) { |
| | | return request({ |
| | | url: "/energyCost/export", |
| | | method: "get", |
| | | params: query, |
| | | responseType: "blob", |
| | | }); |
| | | } |
| | |
| | | method: 'delete', |
| | | }) |
| | | } |
| | | |
| | | // è½èæè¡¨æç»-ç»è®¡æ¥è¯¢ |
| | | export function energyConsumptionDetailStatistics(query) { |
| | | return request({ |
| | | url: "/energyConsumptionDetail/statistics", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| | |
| | | <div class="app-container product-view"> |
| | | <div class="left"> |
| | | <div> |
| | | <el-input |
| | | v-model="search" |
| | | <el-input v-model="search" |
| | | style="width: 210px" |
| | | placeholder="è¾å
¥å
³é®åè¿è¡æç´¢" |
| | | @change="searchFilter" |
| | | @clear="searchFilter" |
| | | clearable |
| | | prefix-icon="Search" |
| | | /> |
| | | <el-button |
| | | type="primary" |
| | | @click="openProDia('addOne')" |
| | | style="margin-left: 10px" |
| | | >æ°å¢äº§å大类</el-button |
| | | > |
| | | prefix-icon="Search" /> |
| | | <el-button type="primary" |
| | | @click="openProDia1('addOne')" |
| | | style="margin-left: 10px">æ°å¢äº§å大类</el-button> |
| | | </div> |
| | | <div ref="containerRef"> |
| | | <el-tree |
| | | ref="tree" |
| | | <el-tree ref="tree" |
| | | v-loading="treeLoad" |
| | | :data="list" |
| | | @node-click="handleNodeClick" |
| | |
| | | highlight-current |
| | | node-key="id" |
| | | class="product-tree-scroll" |
| | | style="height: calc(100vh - 190px); overflow-y: auto" |
| | | > |
| | | style="height: calc(100vh - 190px); overflow-y: auto"> |
| | | <template #default="{ node, data }"> |
| | | <div class="custom-tree-node"> |
| | | <span class="tree-node-content"> |
| | |
| | | </el-icon> |
| | | <span class="tree-node-label">{{ data.label }}</span> |
| | | </span> |
| | | <div> |
| | | <el-button |
| | | type="primary" |
| | | <div v-if="!node.childNodes.length"> |
| | | <el-button type="primary" |
| | | link |
| | | @click="openProDia('edit', data)" |
| | | > |
| | | @click="openProDia('edit', data)"> |
| | | ç¼è¾ |
| | | </el-button> |
| | | <el-button type="primary" link @click="openProDia('add', data)" :disabled="node.level >= 3"> |
| | | <el-button v-if="data.children && data.children.length > 0" |
| | | type="primary" |
| | | link |
| | | @click="openProDia('add', data)"> |
| | | æ·»å 产å |
| | | </el-button> |
| | | <el-button |
| | | v-if="!node.childNodes.length" |
| | | <el-button v-if="!node.childNodes.length" |
| | | style="margin-left: 4px" |
| | | type="danger" |
| | | link |
| | | @click="remove(node, data)" |
| | | > |
| | | @click="remove(node, data)"> |
| | | å é¤ |
| | | </el-button> |
| | | </div> |
| | | <div v-else> |
| | | <!-- 大类 --> |
| | | <el-button type="primary" |
| | | link |
| | | @click="openProDia1('edit', data)"> |
| | | ç¼è¾ |
| | | </el-button> |
| | | <el-button v-if="data.children && data.children.length > 0" |
| | | type="primary" |
| | | link |
| | | @click="openProDia('add', data)"> |
| | | æ·»å 产å |
| | | </el-button> |
| | | <el-button style="margin-left: 4px" |
| | | type="danger" |
| | | link |
| | | @click="remove1(node, data)"> |
| | | å é¤ |
| | | </el-button> |
| | | </div> |
| | |
| | | </div> |
| | | </div> |
| | | <div class="right"> |
| | | <div style="margin-bottom: 10px" v-if="isShowButton"> |
| | | <el-button type="primary" @click="openModelDia('add')"> |
| | | <div style="margin-bottom: 10px" |
| | | v-if="isShowButton"> |
| | | <el-button type="primary" |
| | | @click="openModelDia('add')"> |
| | | æ°å¢è§æ ¼åå· |
| | | </el-button> |
| | | <ImportExcel :product-id="currentId" @uploadSuccess="getModelList" /> |
| | | <el-button |
| | | type="danger" |
| | | <ImportExcel :product-id="currentId" |
| | | @uploadSuccess="getModelList" /> |
| | | <el-button type="danger" |
| | | @click="handleDelete" |
| | | style="margin-left: 10px" |
| | | plain |
| | | > |
| | | plain> |
| | | å é¤ |
| | | </el-button> |
| | | </div> |
| | | <PIMTable |
| | | rowKey="id" |
| | | <PIMTable rowKey="id" |
| | | :column="tableColumn" |
| | | :tableData="tableData" |
| | | :page="page" |
| | | :isSelection="true" |
| | | @selection-change="handleSelectionChange" |
| | | :tableLoading="tableLoading" |
| | | @pagination="pagination" |
| | | ></PIMTable> |
| | | @pagination="pagination"></PIMTable> |
| | | </div> |
| | | <el-dialog v-model="productDia" title="产å" width="400px" @keydown.enter.prevent> |
| | | <el-form |
| | | :model="form" |
| | | <el-dialog v-model="productDia" |
| | | title="产å" |
| | | width="400px" |
| | | @keydown.enter.prevent> |
| | | <el-form :model="form" |
| | | label-width="140px" |
| | | label-position="top" |
| | | :rules="rules" |
| | | ref="formRef" |
| | | > |
| | | ref="formRef"> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="24"> |
| | | <el-form-item label="产ååç§°ï¼" prop="productName"> |
| | | <el-input |
| | | v-model="form.productName" |
| | | <el-form-item label="产ååç§°ï¼" |
| | | prop="materialName"> |
| | | <el-input v-model="form.materialName" |
| | | placeholder="请è¾å
¥äº§ååç§°" |
| | | maxlength="20" |
| | | show-word-limit |
| | | clearable |
| | | @keydown.enter.prevent |
| | | /> |
| | | @keydown.enter.prevent /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="24"> |
| | | <el-form-item label="åè´§ç±»å«ï¼" |
| | | prop="inventoryCategoryId"> |
| | | <el-select v-model="form.inventoryCategoryId" |
| | | placeholder="è¯·éæ©åè´§ç±»å«" |
| | | clearable |
| | | style="width: 100%"> |
| | | <el-option v-for="item in inventoryCategoryList" |
| | | :key="item.id" |
| | | :label="item.configName" |
| | | :value="item.id" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="24"> |
| | | <el-form-item label="ç©æç±»åï¼" |
| | | prop="materialTypeId"> |
| | | <el-select v-model="form.materialTypeId" |
| | | placeholder="è¯·éæ©ç©æç±»å" |
| | | clearable |
| | | style="width: 100%"> |
| | | <el-option v-for="item in materialTypeList" |
| | | :key="item.id" |
| | | :label="item.configName" |
| | | :value="item.id" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="24"> |
| | | <el-form-item label="åºæ¬åä½ï¼" |
| | | prop="baseUnit"> |
| | | <el-input v-model="form.baseUnit" |
| | | placeholder="请è¾å
¥åºæ¬åä½" |
| | | clearable |
| | | @keydown.enter.prevent /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="24"> |
| | | <el-form-item label="夿³¨ï¼"> |
| | | <el-input v-model="form.remark" |
| | | placeholder="请è¾å
¥å¤æ³¨" |
| | | type="textarea" |
| | | :rows="3" |
| | | clearable |
| | | @keydown.enter.prevent /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" @click="submitForm">确认</el-button> |
| | | <el-button type="primary" |
| | | @click="submitForm">确认</el-button> |
| | | <el-button @click="closeProDia">åæ¶</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | <el-dialog |
| | | v-model="modelDia" |
| | | <el-dialog v-model="modelDia" |
| | | title="è§æ ¼åå·" |
| | | width="400px" |
| | | @close="closeModelDia" |
| | | @keydown.enter.prevent |
| | | > |
| | | <el-form |
| | | :model="modelForm" |
| | | @keydown.enter.prevent> |
| | | <el-form :model="modelForm" |
| | | label-width="140px" |
| | | label-position="top" |
| | | :rules="modelRules" |
| | | ref="modelFormRef" |
| | | > |
| | | ref="modelFormRef"> |
| | | <el-row> |
| | | <el-col :span="24"> |
| | | <el-form-item label="è§æ ¼åå·ï¼" prop="model"> |
| | | <el-input |
| | | v-model="modelForm.model" |
| | | <el-form-item label="è§æ ¼åå·ï¼" |
| | | prop="model"> |
| | | <el-input v-model="modelForm.model" |
| | | placeholder="请è¾å
¥è§æ ¼åå·" |
| | | clearable |
| | | @keydown.enter.prevent |
| | | /> |
| | | @keydown.enter.prevent /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row> |
| | | <el-col :span="24"> |
| | | <el-form-item label="åä½ï¼" prop="unit"> |
| | | <el-input |
| | | v-model="modelForm.unit" |
| | | <el-form-item label="åä½ï¼" |
| | | prop="unit"> |
| | | <el-input v-model="modelForm.unit" |
| | | placeholder="请è¾å
¥åä½" |
| | | clearable |
| | | @keydown.enter.prevent |
| | | /> |
| | | @keydown.enter.prevent /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row> |
| | | <el-col :span="24"> |
| | | <el-form-item label="æ è¯ç¬¦ä»£ç ï¼" |
| | | prop="identifierCode"> |
| | | <el-input v-model="modelForm.identifierCode" |
| | | placeholder="请è¾å
¥æ è¯ç¬¦ä»£ç " |
| | | clearable |
| | | @keydown.enter.prevent /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row> |
| | | <el-col :span="24"> |
| | | <el-form-item label="ç©æä»£ç ï¼" |
| | | prop="materialCode"> |
| | | <el-input v-model="modelForm.materialCode" |
| | | placeholder="请è¾å
¥ç©æä»£ç " |
| | | clearable |
| | | @keydown.enter.prevent /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row> |
| | | <el-col :span="24"> |
| | | <el-form-item label="è§æ ¼ï¼" |
| | | prop="specification"> |
| | | <el-input v-model="modelForm.specification" |
| | | placeholder="请è¾å
¥è§æ ¼" |
| | | clearable |
| | | @keydown.enter.prevent /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row> |
| | | <el-col :span="24"> |
| | | <el-form-item label="ä¾åºç±»åï¼" |
| | | prop="supplyType"> |
| | | <el-input v-model="modelForm.supplyType" |
| | | placeholder="请è¾å
¥ä¾åºç±»å" |
| | | clearable |
| | | @keydown.enter.prevent /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row> |
| | | <el-col :span="24"> |
| | | <el-form-item label="åå§äººå§åï¼" |
| | | prop="originatorName"> |
| | | <el-input v-model="modelForm.originatorName" |
| | | placeholder="请è¾å
¥åå§äººå§å" |
| | | clearable |
| | | @keydown.enter.prevent /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row> |
| | | <el-col :span="24"> |
| | | <el-form-item label="åå§äººç»ç»ï¼" |
| | | prop="originatorOrg"> |
| | | <el-input v-model="modelForm.originatorOrg" |
| | | placeholder="请è¾å
¥åå§äººç»ç»" |
| | | clearable |
| | | @keydown.enter.prevent /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" @click="submitModelForm">确认</el-button> |
| | | <el-button type="primary" |
| | | @click="submitModelForm">确认</el-button> |
| | | <el-button @click="closeModelDia">åæ¶</el-button> |
| | | </div> |
| | | </template> |
| | |
| | | import { ElMessageBox } from "element-plus"; |
| | | import { |
| | | addOrEditProduct, |
| | | updateOrEditProduct, |
| | | getinventoryCategoryList, |
| | | getmaterialTypeList, |
| | | addOrEditProductModel, |
| | | updateOrEditProductModel, |
| | | delProduct, |
| | | delProductModel, |
| | | modelListPage, |
| | | productTreeList, |
| | | } from "@/api/basicData/product.js"; |
| | | addOrEditProductConfig, |
| | | updateOrEditProductConfig, |
| | | delProductConfig, |
| | | } from "@/api/basicData/newProduct.js"; |
| | | import ImportExcel from "./ImportExcel/index.vue"; |
| | | |
| | | const { proxy } = getCurrentInstance(); |
| | |
| | | const treeLoad = ref(false); |
| | | const list = ref([]); |
| | | const expandedKeys = ref([]); |
| | | const inventoryCategoryList = ref([]); |
| | | const materialTypeList = ref([]); |
| | | |
| | | // è·ååè´§ç±»å«å表 |
| | | const getInventoryCategoryList = () => { |
| | | getinventoryCategoryList() |
| | | .then(res => { |
| | | inventoryCategoryList.value = res.data.map(item => ({ |
| | | id: item.id, |
| | | configName: item.configName, |
| | | })); |
| | | }) |
| | | .catch(err => { |
| | | console.error("è·ååè´§ç±»å«å¤±è´¥:", err); |
| | | }); |
| | | }; |
| | | |
| | | // è·åç©æç±»åå表 |
| | | const getMaterialTypeList = () => { |
| | | getmaterialTypeList() |
| | | .then(res => { |
| | | materialTypeList.value = res.data.map(item => ({ |
| | | id: item.id, |
| | | configName: item.configName, |
| | | })); |
| | | }) |
| | | .catch(err => { |
| | | console.error("è·åç©æç±»å失败:", err); |
| | | }); |
| | | }; |
| | | const tableColumn = ref([ |
| | | { |
| | | label: "è§æ ¼åå·", |
| | | prop: "model", |
| | | prop: "materialName", |
| | | }, |
| | | { |
| | | label: "è§æ ¼", |
| | | prop: "specification", |
| | | }, |
| | | { |
| | | label: "åä½", |
| | | prop: "unit", |
| | | prop: "baseUnit", |
| | | }, |
| | | { |
| | | dataType: "action", |
| | |
| | | { |
| | | name: "ç¼è¾", |
| | | type: "text", |
| | | clickFun: (row) => { |
| | | clickFun: row => { |
| | | openModelDia("edit", row); |
| | | }, |
| | | }, |
| | |
| | | }); |
| | | const data = reactive({ |
| | | form: { |
| | | productName: "", |
| | | materialTypeId: null, |
| | | inventoryCategoryId: null, |
| | | materialName: "", |
| | | baseUnit: "", |
| | | remark: "", |
| | | }, |
| | | rules: { |
| | | productName: [ |
| | | materialName: [ |
| | | { required: true, message: "请è¾å
¥", trigger: "blur" }, |
| | | { max: 20, message: "产ååç§°ä¸è½è¶
è¿20个å符", trigger: "blur" }, |
| | | ], |
| | | inventoryCategoryId: [ |
| | | { required: true, message: "è¯·éæ©", trigger: "change" }, |
| | | ], |
| | | baseUnit: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | }, |
| | | modelForm: { |
| | | model: "", |
| | | unit: "", |
| | | identifierCode: "", |
| | | materialCode: "", |
| | | specification: "", |
| | | supplyType: "", |
| | | originatorName: "", |
| | | originatorOrg: "", |
| | | }, |
| | | modelRules: { |
| | | model: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | unit: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | identifierCode: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | materialCode: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | specification: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | supplyType: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | originatorName: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | originatorOrg: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | }, |
| | | }); |
| | | const { form, rules, modelForm, modelRules } = toRefs(data); |
| | |
| | | const getProductTreeList = () => { |
| | | treeLoad.value = true; |
| | | productTreeList() |
| | | .then((res) => { |
| | | list.value = res; |
| | | list.value.forEach((a) => { |
| | | expandedKeys.value.push(a.label); |
| | | }); |
| | | .then(res => { |
| | | // è½¬æ¢æ°çæ°æ®æ ¼å¼ |
| | | const newList = []; |
| | | expandedKeys.value = []; |
| | | for (const category of res.data) { |
| | | // æ·»å åç±»èç¹ |
| | | const categoryNode = { |
| | | label: category.configName, |
| | | id: category.configId, |
| | | children: category.materialList.map(item => ({ |
| | | id: item.id, |
| | | label: item.materialName, |
| | | inventoryCategoryId: item.inventoryCategoryId, |
| | | materialTypeId: item.materialTypeId, |
| | | remark: item.remark, |
| | | baseUnit: item.baseUnit, |
| | | })), |
| | | }; |
| | | newList.push(categoryNode); |
| | | expandedKeys.value.push(category.configName); |
| | | } |
| | | list.value = newList; |
| | | treeLoad.value = false; |
| | | }) |
| | | .catch((err) => { |
| | | .catch(err => { |
| | | treeLoad.value = false; |
| | | }); |
| | | }; |
| | |
| | | const openProDia = (type, data) => { |
| | | operationType.value = type; |
| | | productDia.value = true; |
| | | form.value.productName = ""; |
| | | if (type === "edit") { |
| | | form.value.productName = data.productName; |
| | | // é置表å |
| | | form.value = { |
| | | materialName: "", |
| | | inventoryCategoryId: null, |
| | | baseUnit: "", |
| | | remark: "", |
| | | materialTypeId: null, |
| | | }; |
| | | console.log(data); |
| | | if (type === "edit" && data) { |
| | | // ç¼è¾æ¨¡å¼ï¼åå¡«æ°æ® |
| | | form.value.materialName = data.label || ""; |
| | | form.value.inventoryCategoryId = data.inventoryCategoryId || null; |
| | | form.value.baseUnit = data.baseUnit || ""; |
| | | form.value.remark = data.remark || ""; |
| | | form.value.materialTypeId = data.materialTypeId || null; |
| | | form.value.id = data.id || null; |
| | | } else { |
| | | form.value.materialTypeId = data.id || null; |
| | | } |
| | | }; |
| | | // æå¼è§æ ¼åå·å¼¹æ¡ |
| | | const openModelDia = (type, data) => { |
| | | modelOperationType.value = type; |
| | | modelDia.value = true; |
| | | // éç½®ææå段 |
| | | modelForm.value.model = ""; |
| | | modelForm.value.model = ""; |
| | | modelForm.value.unit = ""; |
| | | modelForm.value.identifierCode = ""; |
| | | modelForm.value.materialCode = ""; |
| | | modelForm.value.specification = ""; |
| | | modelForm.value.supplyType = ""; |
| | | modelForm.value.originatorName = ""; |
| | | modelForm.value.originatorOrg = ""; |
| | | modelForm.value.id = ""; |
| | | if (type === "edit") { |
| | | |
| | | if (type === "edit" && data) { |
| | | // ç¼è¾æ¨¡å¼ï¼åå¡«æ°æ® |
| | | modelForm.value = { ...data }; |
| | | } |
| | | }; |
| | | // æäº¤äº§ååç§°ä¿®æ¹ |
| | | const submitForm = () => { |
| | | proxy.$refs.formRef.validate((valid) => { |
| | | proxy.$refs.formRef.validate(valid => { |
| | | if (valid) { |
| | | if (operationType.value === "add") { |
| | | form.value.parentId = currentId.value; |
| | | form.value.id = ""; |
| | | } else if (operationType.value === "addOne") { |
| | | form.value.id = ""; |
| | | form.value.parentId = ""; |
| | | } else { |
| | | form.value.id = currentId.value; |
| | | form.value.parentId = ""; |
| | | } |
| | | addOrEditProduct(form.value).then((res) => { |
| | | // æå»ºæäº¤åæ° |
| | | // const params = { |
| | | // materialTypeId: null, |
| | | // inventoryCategoryId: form.value.inventoryCategoryId, |
| | | // materialName: form.value.materialName, |
| | | // baseUnit: form.value.baseUnit, |
| | | // remark: form.value.remark, |
| | | // }; |
| | | |
| | | // if (operationType.value === "add") { |
| | | // // æ·»å å级ï¼ä¼ ç¶çº§çidä½ä¸º materialTypeId |
| | | // params.materialTypeId = currentId.value; |
| | | // } else if (operationType.value === "addOne") { |
| | | // // æ·»å ä¸çº§ï¼materialTypeId 为 null |
| | | // params.materialTypeId = null; |
| | | // } else { |
| | | // // ç¼è¾ï¼ä¼ å½åidä½ä¸º materialTypeId |
| | | // params.materialTypeId = currentId.value; |
| | | // } |
| | | console.log(form.value); |
| | | console.log(operationType.value); |
| | | if (operationType.value != "edit") { |
| | | addOrEditProduct(form.value).then(res => { |
| | | proxy.$modal.msgSuccess("æäº¤æå"); |
| | | closeProDia(); |
| | | getProductTreeList(); |
| | | }); |
| | | } else { |
| | | updateOrEditProduct(form.value).then(res => { |
| | | proxy.$modal.msgSuccess("æäº¤æå"); |
| | | closeProDia(); |
| | | getProductTreeList(); |
| | | }); |
| | | } |
| | | } |
| | | }); |
| | | }; |
| | | // å
³é产åå¼¹æ¡ |
| | | const closeProDia = () => { |
| | | proxy.$refs.formRef.resetFields(); |
| | | // æå¨éç½®é表ååæ®µ |
| | | form.value.materialTypeId = null; |
| | | form.value.remark = ""; |
| | | productDia.value = false; |
| | | }; |
| | | |
| | |
| | | .then(() => { |
| | | tableLoading.value = true; |
| | | delProduct(ids) |
| | | .then((res) => { |
| | | .then(res => { |
| | | proxy.$modal.msgSuccess("å 餿å"); |
| | | getProductTreeList(); |
| | | }) |
| | |
| | | |
| | | // æäº¤è§æ ¼åå·ä¿®æ¹ |
| | | const submitModelForm = () => { |
| | | proxy.$refs.modelFormRef.validate((valid) => { |
| | | proxy.$refs.modelFormRef.validate(valid => { |
| | | if (valid) { |
| | | modelForm.value.productId = currentId.value; |
| | | addOrEditProductModel(modelForm.value).then((res) => { |
| | | // æå»ºæäº¤åæ° |
| | | const params = { |
| | | materialId: currentId.value, |
| | | identifierCode: modelForm.value.identifierCode, |
| | | materialCode: modelForm.value.materialCode, |
| | | specification: modelForm.value.specification, |
| | | supplyType: modelForm.value.supplyType, |
| | | originatorName: modelForm.value.originatorName, |
| | | originatorOrg: modelForm.value.originatorOrg, |
| | | }; |
| | | if (modelOperationType.value === "add") { |
| | | // æ·»å è§æ ¼åå· |
| | | addOrEditProductModel(params).then(res => { |
| | | proxy.$modal.msgSuccess("æäº¤æå"); |
| | | closeModelDia(); |
| | | getModelList(); |
| | | }); |
| | | } else if (modelOperationType.value === "edit") { |
| | | // ä¿®æ¹è§æ ¼åå· |
| | | updateOrEditProductModel(params).then(res => { |
| | | proxy.$modal.msgSuccess("æäº¤æå"); |
| | | closeModelDia(); |
| | | getModelList(); |
| | | }); |
| | | } |
| | | } |
| | | }); |
| | | }; |
| | |
| | | modelDia.value = false; |
| | | }; |
| | | // è¡¨æ ¼éæ©æ°æ® |
| | | const handleSelectionChange = (selection) => { |
| | | const handleSelectionChange = selection => { |
| | | selectedRows.value = selection; |
| | | }; |
| | | |
| | | // æ¥è¯¢è§æ ¼åå· |
| | | const pagination = (obj) => { |
| | | const pagination = obj => { |
| | | page.current = obj.page; |
| | | page.size = obj.limit; |
| | | getModelList(); |
| | | }; |
| | | const getModelList = () => { |
| | | if (!currentId.value) { |
| | | return; |
| | | } |
| | | tableLoading.value = true; |
| | | modelListPage({ |
| | | id: currentId.value, |
| | | materialId: currentId.value, |
| | | current: page.current, |
| | | size: page.size, |
| | | }).then((res) => { |
| | | }).then(res => { |
| | | console.log("res", res); |
| | | tableData.value = res.records; |
| | | tableData.value = res.data; |
| | | page.total = res.total; |
| | | tableLoading.value = false; |
| | | }); |
| | |
| | | const handleDelete = () => { |
| | | let ids = []; |
| | | if (selectedRows.value.length > 0) { |
| | | ids = selectedRows.value.map((item) => item.id); |
| | | ids = selectedRows.value.map(item => item.id); |
| | | } else { |
| | | proxy.$modal.msgWarning("è¯·éæ©æ°æ®"); |
| | | return; |
| | |
| | | .then(() => { |
| | | tableLoading.value = true; |
| | | delProductModel(ids) |
| | | .then((res) => { |
| | | .then(res => { |
| | | proxy.$modal.msgSuccess("å 餿å"); |
| | | getModelList(); |
| | | }) |
| | |
| | | // 没å¹é
å°è¿åfalse |
| | | return false; |
| | | }; |
| | | // 页é¢å è½½æ¶è·åæ°æ® |
| | | getInventoryCategoryList(); |
| | | getMaterialTypeList(); |
| | | getProductTreeList(); |
| | | </script> |
| | | |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | { |
| | | "msg": "æä½æå", |
| | | "code": 200, |
| | | "data": [ |
| | | { |
| | | "configId": 19, |
| | | "configName": "æå", |
| | | "materialList": [ |
| | | { |
| | | "id": 11, |
| | | "tenantId": null, |
| | | "materialTypeId": null, |
| | | "inventoryCategoryId": null, |
| | | "materialName": "æ¿æ", |
| | | "baseUnit": null, |
| | | "remark": null, |
| | | "createTime": null, |
| | | "updateTime": null |
| | | }, |
| | | { |
| | | "id": 13, |
| | | "tenantId": null, |
| | | "materialTypeId": null, |
| | | "inventoryCategoryId": null, |
| | | "materialName": "MU20ç§ç»ç
¤ç¸ç³å®å¿ç ", |
| | | "baseUnit": null, |
| | | "remark": null, |
| | | "createTime": null, |
| | | "updateTime": null |
| | | }, |
| | | { |
| | | "id": 14, |
| | | "tenantId": null, |
| | | "materialTypeId": null, |
| | | "inventoryCategoryId": null, |
| | | "materialName": "æ°´æ³¥æ ç ", |
| | | "baseUnit": null, |
| | | "remark": null, |
| | | "createTime": null, |
| | | "updateTime": null |
| | | }, |
| | | { |
| | | "id": 15, |
| | | "tenantId": null, |
| | | "materialTypeId": null, |
| | | "inventoryCategoryId": null, |
| | | "materialName": "ç§ç»ç
¤ç¸ç³é¡µå²©å®å¿ç ", |
| | | "baseUnit": null, |
| | | "remark": null, |
| | | "createTime": null, |
| | | "updateTime": null |
| | | }, |
| | | { |
| | | "id": 16, |
| | | "tenantId": null, |
| | | "materialTypeId": null, |
| | | "inventoryCategoryId": null, |
| | | "materialName": "æ°´æ³¥ä¸è§ç ", |
| | | "baseUnit": null, |
| | | "remark": null, |
| | | "createTime": null, |
| | | "updateTime": null |
| | | }, |
| | | { |
| | | "id": 17, |
| | | "tenantId": null, |
| | | "materialTypeId": null, |
| | | "inventoryCategoryId": null, |
| | | "materialName": "æ°´æ³¥æ¹ç ", |
| | | "baseUnit": null, |
| | | "remark": null, |
| | | "createTime": null, |
| | | "updateTime": null |
| | | }, |
| | | { |
| | | "id": 18, |
| | | "tenantId": null, |
| | | "materialTypeId": null, |
| | | "inventoryCategoryId": null, |
| | | "materialName": "ç§ç»ç
¤ç¸ç³é¡µå²©ç©ºå¿ç ", |
| | | "baseUnit": null, |
| | | "remark": null, |
| | | "createTime": null, |
| | | "updateTime": null |
| | | }, |
| | | { |
| | | "id": 19, |
| | | "tenantId": null, |
| | | "materialTypeId": null, |
| | | "inventoryCategoryId": null, |
| | | "materialName": "ç§ç»ç
¤ç¸ç³é¡µå²©ç ", |
| | | "baseUnit": null, |
| | | "remark": null, |
| | | "createTime": null, |
| | | "updateTime": null |
| | | }, |
| | | { |
| | | "id": 20, |
| | | "tenantId": null, |
| | | "materialTypeId": null, |
| | | "inventoryCategoryId": null, |
| | | "materialName": "æ ç ", |
| | | "baseUnit": null, |
| | | "remark": null, |
| | | "createTime": null, |
| | | "updateTime": null |
| | | }, |
| | | { |
| | | "id": 23, |
| | | "tenantId": null, |
| | | "materialTypeId": null, |
| | | "inventoryCategoryId": null, |
| | | "materialName": "å æ°æ¿", |
| | | "baseUnit": null, |
| | | "remark": null, |
| | | "createTime": null, |
| | | "updateTime": null |
| | | } |
| | | ] |
| | | }, |
| | | |
| | | { |
| | | "configId": 27, |
| | | "configName": "ç产ç©è", |
| | | "materialList": [ |
| | | { |
| | | "id": 43, |
| | | "tenantId": null, |
| | | "materialTypeId": null, |
| | | "inventoryCategoryId": null, |
| | | "materialName": "é²å»æ¶²", |
| | | "baseUnit": null, |
| | | "remark": null, |
| | | "createTime": null, |
| | | "updateTime": null |
| | | }, |
| | | { |
| | | "id": 60, |
| | | "tenantId": null, |
| | | "materialTypeId": null, |
| | | "inventoryCategoryId": null, |
| | | "materialName": "éé
¸è°åæ¼", |
| | | "baseUnit": null, |
| | | "remark": null, |
| | | "createTime": null, |
| | | "updateTime": null |
| | | }, |
| | | { |
| | | "id": 64, |
| | | "tenantId": null, |
| | | "materialTypeId": null, |
| | | "inventoryCategoryId": null, |
| | | "materialName": "æ¸
æ´å", |
| | | "baseUnit": null, |
| | | "remark": null, |
| | | "createTime": null, |
| | | "updateTime": null |
| | | }, |
| | | { |
| | | "id": 106, |
| | | "tenantId": null, |
| | | "materialTypeId": null, |
| | | "inventoryCategoryId": null, |
| | | "materialName": "ç°æè½¦", |
| | | "baseUnit": null, |
| | | "remark": null, |
| | | "createTime": null, |
| | | "updateTime": null |
| | | }, |
| | | { |
| | | "id": 116, |
| | | "tenantId": null, |
| | | "materialTypeId": null, |
| | | "inventoryCategoryId": null, |
| | | "materialName": "æå
å¸¦ï¼æå·¥å¸¦ï¼", |
| | | "baseUnit": null, |
| | | "remark": null, |
| | | "createTime": null, |
| | | "updateTime": null |
| | | }, |
| | | { |
| | | "id": 117, |
| | | "tenantId": null, |
| | | "materialTypeId": null, |
| | | "inventoryCategoryId": null, |
| | | "materialName": "ç¨éå", |
| | | "baseUnit": null, |
| | | "remark": null, |
| | | "createTime": null, |
| | | "updateTime": null |
| | | }, |
| | | { |
| | | "id": 118, |
| | | "tenantId": null, |
| | | "materialTypeId": null, |
| | | "inventoryCategoryId": null, |
| | | "materialName": "æ¨æç", |
| | | "baseUnit": null, |
| | | "remark": null, |
| | | "createTime": null, |
| | | "updateTime": null |
| | | }, |
| | | { |
| | | "id": 310, |
| | | "tenantId": null, |
| | | "materialTypeId": null, |
| | | "inventoryCategoryId": null, |
| | | "materialName": "ä¸ä¹éèº", |
| | | "baseUnit": null, |
| | | "remark": null, |
| | | "createTime": null, |
| | | "updateTime": null |
| | | }, |
| | | { |
| | | "id": 313, |
| | | "tenantId": null, |
| | | "materialTypeId": null, |
| | | "inventoryCategoryId": null, |
| | | "materialName": "ä¹ç", |
| | | "baseUnit": null, |
| | | "remark": null, |
| | | "createTime": null, |
| | | "updateTime": null |
| | | }, |
| | | { |
| | | "id": 314, |
| | | "tenantId": null, |
| | | "materialTypeId": null, |
| | | "inventoryCategoryId": null, |
| | | "materialName": "é平油", |
| | | "baseUnit": null, |
| | | "remark": null, |
| | | "createTime": null, |
| | | "updateTime": null |
| | | }, |
| | | { |
| | | "id": 315, |
| | | "tenantId": null, |
| | | "materialTypeId": null, |
| | | "inventoryCategoryId": null, |
| | | "materialName": "çµè§£ç²", |
| | | "baseUnit": null, |
| | | "remark": null, |
| | | "createTime": null, |
| | | "updateTime": null |
| | | }, |
| | | { |
| | | "id": 316, |
| | | "tenantId": null, |
| | | "materialTypeId": null, |
| | | "inventoryCategoryId": null, |
| | | "materialName": "æå
带", |
| | | "baseUnit": null, |
| | | "remark": null, |
| | | "createTime": null, |
| | | "updateTime": null |
| | | }, |
| | | { |
| | | "id": 317, |
| | | "tenantId": null, |
| | | "materialTypeId": null, |
| | | "inventoryCategoryId": null, |
| | | "materialName": "é¢ç", |
| | | "baseUnit": null, |
| | | "remark": null, |
| | | "createTime": null, |
| | | "updateTime": null |
| | | }, |
| | | { |
| | | "id": 318, |
| | | "tenantId": null, |
| | | "materialTypeId": null, |
| | | "inventoryCategoryId": null, |
| | | "materialName": "对讲æº", |
| | | "baseUnit": null, |
| | | "remark": null, |
| | | "createTime": null, |
| | | "updateTime": null |
| | | }, |
| | | { |
| | | "id": 319, |
| | | "tenantId": null, |
| | | "materialTypeId": null, |
| | | "inventoryCategoryId": null, |
| | | "materialName": "é¢é»", |
| | | "baseUnit": null, |
| | | "remark": null, |
| | | "createTime": null, |
| | | "updateTime": null |
| | | }, |
| | | { |
| | | "id": 320, |
| | | "tenantId": null, |
| | | "materialTypeId": null, |
| | | "inventoryCategoryId": null, |
| | | "materialName": "æç£¨æ¶²åæ²¹", |
| | | "baseUnit": null, |
| | | "remark": null, |
| | | "createTime": null, |
| | | "updateTime": null |
| | | }, |
| | | { |
| | | "id": 321, |
| | | "tenantId": null, |
| | | "materialTypeId": null, |
| | | "inventoryCategoryId": null, |
| | | "materialName": "黿²¹", |
| | | "baseUnit": null, |
| | | "remark": null, |
| | | "createTime": null, |
| | | "updateTime": null |
| | | }, |
| | | { |
| | | "id": 322, |
| | | "tenantId": null, |
| | | "materialTypeId": null, |
| | | "inventoryCategoryId": null, |
| | | "materialName": "ç¼çº«æºæ²¹", |
| | | "baseUnit": null, |
| | | "remark": null, |
| | | "createTime": null, |
| | | "updateTime": null |
| | | }, |
| | | { |
| | | "id": 323, |
| | | "tenantId": null, |
| | | "materialTypeId": null, |
| | | "inventoryCategoryId": null, |
| | | "materialName": "æºæ²¹", |
| | | "baseUnit": null, |
| | | "remark": null, |
| | | "createTime": null, |
| | | "updateTime": null |
| | | }, |
| | | { |
| | | "id": 324, |
| | | "tenantId": null, |
| | | "materialTypeId": null, |
| | | "inventoryCategoryId": null, |
| | | "materialName": "æ´æ²¹", |
| | | "baseUnit": null, |
| | | "remark": null, |
| | | "createTime": null, |
| | | "updateTime": null |
| | | }, |
| | | { |
| | | "id": 325, |
| | | "tenantId": null, |
| | | "materialTypeId": null, |
| | | "inventoryCategoryId": null, |
| | | "materialName": "æä»åå
M320å¼é½¿è½®æ²¹å", |
| | | "baseUnit": null, |
| | | "remark": null, |
| | | "createTime": null, |
| | | "updateTime": null |
| | | }, |
| | | { |
| | | "id": 326, |
| | | "tenantId": null, |
| | | "materialTypeId": null, |
| | | "inventoryCategoryId": null, |
| | | "materialName": "æä»CKD320ä¸è´è·é½¿è½®æ²¹å", |
| | | "baseUnit": null, |
| | | "remark": null, |
| | | "createTime": null, |
| | | "updateTime": null |
| | | }, |
| | | { |
| | | "id": 327, |
| | | "tenantId": null, |
| | | "materialTypeId": null, |
| | | "inventoryCategoryId": null, |
| | | "materialName": "ä¸ç·", |
| | | "baseUnit": null, |
| | | "remark": null, |
| | | "createTime": null, |
| | | "updateTime": null |
| | | }, |
| | | { |
| | | "id": 328, |
| | | "tenantId": null, |
| | | "materialTypeId": null, |
| | | "inventoryCategoryId": null, |
| | | "materialName": "æä»CKC320ä¸è´è·é½¿è½®æ²¹å", |
| | | "baseUnit": null, |
| | | "remark": null, |
| | | "createTime": null, |
| | | "updateTime": null |
| | | }, |
| | | { |
| | | "id": 329, |
| | | "tenantId": null, |
| | | "materialTypeId": null, |
| | | "inventoryCategoryId": null, |
| | | "materialName": "æä»CKC150å·¥ä¸éå¼é½¿è½®æ²¹", |
| | | "baseUnit": null, |
| | | "remark": null, |
| | | "createTime": null, |
| | | "updateTime": null |
| | | }, |
| | | { |
| | | "id": 330, |
| | | "tenantId": null, |
| | | "materialTypeId": null, |
| | | "inventoryCategoryId": null, |
| | | "materialName": "æ°§æ°", |
| | | "baseUnit": null, |
| | | "remark": null, |
| | | "createTime": null, |
| | | "updateTime": null |
| | | }, |
| | | { |
| | | "id": 331, |
| | | "tenantId": null, |
| | | "materialTypeId": null, |
| | | "inventoryCategoryId": null, |
| | | "materialName": "æä»46#æç£¨æ¶²åæ²¹", |
| | | "baseUnit": null, |
| | | "remark": null, |
| | | "createTime": null, |
| | | "updateTime": null |
| | | }, |
| | | { |
| | | "id": 332, |
| | | "tenantId": null, |
| | | "materialTypeId": null, |
| | | "inventoryCategoryId": null, |
| | | "materialName": "ç³è¡", |
| | | "baseUnit": null, |
| | | "remark": null, |
| | | "createTime": null, |
| | | "updateTime": null |
| | | }, |
| | | { |
| | | "id": 335, |
| | | "tenantId": null, |
| | | "materialTypeId": null, |
| | | "inventoryCategoryId": null, |
| | | "materialName": "è±æ¨¡å", |
| | | "baseUnit": null, |
| | | "remark": null, |
| | | "createTime": null, |
| | | "updateTime": null |
| | | } |
| | | ] |
| | | }, |
| | | { |
| | | "configId": 30, |
| | | "configName": "æ²å ç å", |
| | | "materialList": [ |
| | | { |
| | | "id": 139, |
| | | "tenantId": null, |
| | | "materialTypeId": null, |
| | | "inventoryCategoryId": null, |
| | | "materialName": "æ²å ç å", |
| | | "baseUnit": null, |
| | | "remark": null, |
| | | "createTime": null, |
| | | "updateTime": null |
| | | } |
| | | ] |
| | | }, |
| | | { |
| | | "configId": 31, |
| | | "configName": "ç å", |
| | | "materialList": [ |
| | | { |
| | | "id": 12, |
| | | "tenantId": null, |
| | | "materialTypeId": null, |
| | | "inventoryCategoryId": null, |
| | | "materialName": "ç å", |
| | | "baseUnit": null, |
| | | "remark": null, |
| | | "createTime": null, |
| | | "updateTime": null |
| | | } |
| | | ] |
| | | }, |
| | | { |
| | | "configId": 35, |
| | | "configName": "è¾
婿æ", |
| | | "materialList": [ |
| | | { |
| | | "id": 22, |
| | | "tenantId": null, |
| | | "materialTypeId": null, |
| | | "inventoryCategoryId": null, |
| | | "materialName": "æ°§åé", |
| | | "baseUnit": null, |
| | | "remark": null, |
| | | "createTime": null, |
| | | "updateTime": null |
| | | }, |
| | | { |
| | | "id": 486, |
| | | "tenantId": null, |
| | | "materialTypeId": null, |
| | | "inventoryCategoryId": null, |
| | | "materialName": "塿£", |
| | | "baseUnit": null, |
| | | "remark": null, |
| | | "createTime": null, |
| | | "updateTime": null |
| | | }, |
| | | { |
| | | "id": 487, |
| | | "tenantId": null, |
| | | "materialTypeId": null, |
| | | "inventoryCategoryId": null, |
| | | "materialName": "é²è
å", |
| | | "baseUnit": null, |
| | | "remark": null, |
| | | "createTime": null, |
| | | "updateTime": null |
| | | }, |
| | | { |
| | | "id": 489, |
| | | "tenantId": null, |
| | | "materialTypeId": null, |
| | | "inventoryCategoryId": null, |
| | | "materialName": "å·æä¸", |
| | | "baseUnit": null, |
| | | "remark": null, |
| | | "createTime": null, |
| | | "updateTime": null |
| | | } |
| | | ] |
| | | }, |
| | | { |
| | | "configId": 36, |
| | | "configName": "åææ", |
| | | "materialList": [ |
| | | { |
| | | "id": 41, |
| | | "tenantId": null, |
| | | "materialTypeId": null, |
| | | "inventoryCategoryId": null, |
| | | "materialName": "çç³ç°", |
| | | "baseUnit": null, |
| | | "remark": null, |
| | | "createTime": null, |
| | | "updateTime": null |
| | | }, |
| | | { |
| | | "id": 42, |
| | | "tenantId": null, |
| | | "materialTypeId": null, |
| | | "inventoryCategoryId": null, |
| | | "materialName": "æ°´", |
| | | "baseUnit": null, |
| | | "remark": null, |
| | | "createTime": null, |
| | | "updateTime": null |
| | | }, |
| | | { |
| | | "id": 488, |
| | | "tenantId": null, |
| | | "materialTypeId": null, |
| | | "inventoryCategoryId": null, |
| | | "materialName": "ç¡
ç ", |
| | | "baseUnit": null, |
| | | "remark": null, |
| | | "createTime": null, |
| | | "updateTime": null |
| | | }, |
| | | { |
| | | "id": 490, |
| | | "tenantId": null, |
| | | "materialTypeId": null, |
| | | "inventoryCategoryId": null, |
| | | "materialName": "æ°´æ³¥", |
| | | "baseUnit": null, |
| | | "remark": null, |
| | | "createTime": null, |
| | | "updateTime": null |
| | | }, |
| | | { |
| | | "id": 491, |
| | | "tenantId": null, |
| | | "materialTypeId": null, |
| | | "inventoryCategoryId": null, |
| | | "materialName": "éç²", |
| | | "baseUnit": null, |
| | | "remark": null, |
| | | "createTime": null, |
| | | "updateTime": null |
| | | }, |
| | | { |
| | | "id": 492, |
| | | "tenantId": null, |
| | | "materialTypeId": null, |
| | | "inventoryCategoryId": null, |
| | | "materialName": "ç²ç
¤ç°", |
| | | "baseUnit": null, |
| | | "remark": null, |
| | | "createTime": null, |
| | | "updateTime": null |
| | | }, |
| | | { |
| | | "id": 493, |
| | | "tenantId": null, |
| | | "materialTypeId": null, |
| | | "inventoryCategoryId": null, |
| | | "materialName": "ç³è", |
| | | "baseUnit": null, |
| | | "remark": null, |
| | | "createTime": null, |
| | | "updateTime": null |
| | | } |
| | | ] |
| | | } |
| | | ] |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <!-- æç´¢åºå --> |
| | | <div class="search_form"> |
| | | <el-form :model="searchForm" |
| | | :inline="true"> |
| | | <el-form-item label="ç»è®¡ç»´åº¦:"> |
| | | <el-radio-group v-model="statisticsType" |
| | | @change="handleTypeChange"> |
| | | <el-radio-button label="day">ææ¥ç»è®¡</el-radio-button> |
| | | <el-radio-button label="month">ææç»è®¡</el-radio-button> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | <el-form-item label="è½èç±»å:"> |
| | | <el-select v-model="searchForm.energyType" |
| | | placeholder="å
¨é¨" |
| | | clearable |
| | | style="width: 140px;" |
| | | @change="handleQuery"> |
| | | <el-option label="å
¨é¨" |
| | | value="å
¨é¨" /> |
| | | <el-option label="æ°´" |
| | | value="æ°´" /> |
| | | <el-option label="çµ" |
| | | value="çµ" /> |
| | | <el-option label="æ°" |
| | | value="æ°" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="è½èç¨é:"> |
| | | <el-select v-model="searchForm.energyPurpose" |
| | | placeholder="å
¨é¨" |
| | | clearable |
| | | style="width: 140px;" |
| | | @change="handleQuery"> |
| | | <el-option label="å
¨é¨" |
| | | value="å
¨é¨" /> |
| | | <el-option label="ç产" |
| | | value="ç产" /> |
| | | <el-option label="åå
¬" |
| | | value="åå
¬" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="æ¶é´èå´:"> |
| | | <el-date-picker v-if="statisticsType === 'day'" |
| | | v-model="searchForm.dateRange" |
| | | type="daterange" |
| | | range-separator="è³" |
| | | start-placeholder="å¼å§æ¥æ" |
| | | end-placeholder="ç»ææ¥æ" |
| | | value-format="YYYY-MM-DD" |
| | | style="width: 240px;" |
| | | @change="handleQuery" /> |
| | | <el-date-picker v-else |
| | | v-model="searchForm.monthRange" |
| | | type="monthrange" |
| | | range-separator="è³" |
| | | start-placeholder="å¼å§æä»½" |
| | | end-placeholder="ç»ææä»½" |
| | | value-format="YYYY-MM" |
| | | style="width: 240px;" |
| | | @change="handleQuery" /> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" |
| | | @click="handleQuery">æ¥è¯¢</el-button> |
| | | <el-button @click="handleReset">éç½®</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | <div> |
| | | <el-button type="success" |
| | | @click="handleExport">å¯¼åºæ¥è¡¨</el-button> |
| | | </div> |
| | | </div> |
| | | <!-- ç»è®¡æ¦è§å¡ç --> |
| | | <div class="statistics-overview"> |
| | | <h2 class="section-header"> |
| | | <el-icon class="header-icon"> |
| | | <DataLine /> |
| | | </el-icon> |
| | | è½èææ¬æ¦è§ |
| | | </h2> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="6"> |
| | | <div class="overview-card blue-card"> |
| | | <div class="overview-icon blue-icon"> |
| | | <el-icon> |
| | | <Money /> |
| | | </el-icon> |
| | | </div> |
| | | <div class="overview-info"> |
| | | <div class="overview-label">æ»è½èææ¬</div> |
| | | <div class="overview-value">Â¥{{ overview.totalCost }}</div> |
| | | </div> |
| | | </div> |
| | | </el-col> |
| | | <el-col :span="6"> |
| | | <div class="overview-card green-card"> |
| | | <div class="overview-icon green-icon"> |
| | | <el-icon> |
| | | <DataLine /> |
| | | </el-icon> |
| | | </div> |
| | | <div class="overview-info"> |
| | | <div class="overview-label">ç产è½èææ¬</div> |
| | | <div class="overview-value">Â¥{{ overview.productionCost }}</div> |
| | | </div> |
| | | </div> |
| | | </el-col> |
| | | <el-col :span="6"> |
| | | <div class="overview-card purple-card"> |
| | | <div class="overview-icon purple-icon"> |
| | | <el-icon> |
| | | <TrendCharts /> |
| | | </el-icon> |
| | | </div> |
| | | <div class="overview-info"> |
| | | <div class="overview-label">åå
¬è½èææ¬</div> |
| | | <div class="overview-value">Â¥{{ overview.officeCost }}</div> |
| | | </div> |
| | | </div> |
| | | </el-col> |
| | | <el-col :span="6"> |
| | | <div class="overview-card gray-card"> |
| | | <div class="overview-icon gray-icon"> |
| | | <el-icon> |
| | | <Histogram /> |
| | | </el-icon> |
| | | </div> |
| | | <div class="overview-info"> |
| | | <div class="overview-label">å¹³åè½èææ¬</div> |
| | | <div class="overview-value">Â¥{{ overview.avgCost }} <span class="unit">/{{ statisticsType === 'day' ? 'æ¥' : 'æ' }}</span></div> |
| | | </div> |
| | | </div> |
| | | </el-col> |
| | | </el-row> |
| | | </div> |
| | | <!-- å¾è¡¨åºå --> |
| | | <div class="charts-container"> |
| | | <h2 class="section-header"> |
| | | <el-icon class="header-icon"> |
| | | <Histogram /> |
| | | </el-icon> |
| | | è½èææ¬åæ |
| | | </h2> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <div class="chart-card"> |
| | | <div class="chart-title">è½èææ¬è¶å¿</div> |
| | | <div ref="costChart" |
| | | class="chart-content"></div> |
| | | </div> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <div class="chart-card"> |
| | | <div class="chart-title">è½èç±»åææ¬å æ¯</div> |
| | | <div ref="typeChart" |
| | | class="chart-content"></div> |
| | | </div> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="20" |
| | | style="margin-top: 20px;"> |
| | | <el-col :span="12"> |
| | | <div class="chart-card"> |
| | | <div class="chart-title">è½èç¨éææ¬å æ¯</div> |
| | | <div ref="purposeChart" |
| | | class="chart-content"></div> |
| | | </div> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <div class="chart-card"> |
| | | <div class="chart-title">è½èå价对æ¯</div> |
| | | <div ref="priceChart" |
| | | class="chart-content"></div> |
| | | </div> |
| | | </el-col> |
| | | </el-row> |
| | | </div> |
| | | <!-- æ°æ®è¡¨æ ¼ --> |
| | | <div class="table-section"> |
| | | <h2 class="section-header"> |
| | | <el-icon class="header-icon"> |
| | | <List /> |
| | | </el-icon> |
| | | è¯¦ç»æ°æ® |
| | | </h2> |
| | | <el-table :data="tableData" |
| | | v-loading="tableLoading" |
| | | border> |
| | | <el-table-column type="index" |
| | | label="åºå·" |
| | | width="60" |
| | | align="center" /> |
| | | <el-table-column prop="timePeriod" |
| | | :label="timeColumnLabel" |
| | | align="center" /> |
| | | <el-table-column prop="energyType" |
| | | label="è½èç±»å" |
| | | width="100" |
| | | align="center"> |
| | | <template #default="scope"> |
| | | <el-tag :type="getEnergyTypeType(scope.row.energyType)"> |
| | | {{ scope.row.energyType }} |
| | | </el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="energyPurpose" |
| | | label="è½èç¨é" |
| | | width="100" |
| | | align="center"> |
| | | <template #default="scope"> |
| | | <el-tag :type="scope.row.energyPurpose === 'ç产' ? 'primary' : 'info'"> |
| | | {{ scope.row.energyPurpose }} |
| | | </el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="consumption" |
| | | label="ç¨é" |
| | | align="right"> |
| | | <template #default="scope"> |
| | | <span class="consumption-value">{{ scope.row.consumption }}</span> |
| | | <span class="consumption-unit">{{ scope.row.unit }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="price" |
| | | label="åä»·(å
)" |
| | | align="right"> |
| | | <template #default="scope"> |
| | | <span class="price-value">{{ scope.row.price }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="cost" |
| | | label="ææ¬(å
)" |
| | | align="right" |
| | | fixed="right"> |
| | | <template #default="scope"> |
| | | <span class="cost-value">Â¥{{ scope.row.cost }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </div> |
| | | <!-- å页 --> |
| | | <div class="pagination-container"> |
| | | <el-pagination v-model:current-page="page.current" |
| | | v-model:page-size="page.size" |
| | | :page-sizes="[10, 20, 50, 100]" |
| | | :total="page.total" |
| | | layout="total, sizes, prev, pager, next, jumper" |
| | | @size-change="handleSizeChange" |
| | | @current-change="handleCurrentChange" /> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, reactive, onMounted, computed, nextTick } from "vue"; |
| | | import { ElMessage } from "element-plus"; |
| | | import { |
| | | Money, |
| | | DataLine, |
| | | TrendCharts, |
| | | Histogram, |
| | | List, |
| | | } from "@element-plus/icons-vue"; |
| | | import * as echarts from "echarts"; |
| | | import { energyCostStatistics } from "@/api/costAccounting/energyCosts"; |
| | | |
| | | // ç»è®¡ç»´åº¦ï¼day-ææ¥ï¼month-ææ |
| | | const statisticsType = ref("day"); |
| | | |
| | | // æç´¢è¡¨å |
| | | const searchForm = reactive({ |
| | | energyType: "", |
| | | energyPurpose: "", |
| | | dateRange: (() => { |
| | | // é»è®¤æè¿7天 |
| | | const end = new Date(); |
| | | const start = new Date(); |
| | | start.setDate(start.getDate() - 6); |
| | | return [start.toISOString().split("T")[0], end.toISOString().split("T")[0]]; |
| | | })(), |
| | | monthRange: (() => { |
| | | // é»è®¤æè¿3个æ |
| | | const end = new Date(); |
| | | const start = new Date(); |
| | | start.setMonth(start.getMonth() - 2); |
| | | return [start.toISOString().slice(0, 7), end.toISOString().slice(0, 7)]; |
| | | })(), |
| | | }); |
| | | |
| | | // æ¶é´åæ ç¾ |
| | | const timeColumnLabel = computed(() => { |
| | | return statisticsType.value === "day" ? "æ¥æ" : "æä»½"; |
| | | }); |
| | | |
| | | // ç»è®¡æ¦è§ |
| | | const overview = reactive({ |
| | | totalCost: "0.00", |
| | | productionCost: "0.00", |
| | | officeCost: "0.00", |
| | | avgCost: "0.00", |
| | | }); |
| | | |
| | | // è¡¨æ ¼æ°æ® |
| | | const tableData = ref([]); |
| | | const tableLoading = ref(false); |
| | | |
| | | // å页 |
| | | const page = reactive({ |
| | | current: 1, |
| | | size: 10, |
| | | total: 0, |
| | | }); |
| | | |
| | | // å¾è¡¨å¼ç¨ |
| | | const costChart = ref(null); |
| | | const typeChart = ref(null); |
| | | const purposeChart = ref(null); |
| | | const priceChart = ref(null); |
| | | |
| | | // å¾è¡¨å®ä¾ |
| | | let costChartInstance = null; |
| | | let typeChartInstance = null; |
| | | let purposeChartInstance = null; |
| | | let priceChartInstance = null; |
| | | |
| | | // è·åè½èç±»åæ ç¾ç±»å |
| | | const getEnergyTypeType = type => { |
| | | const typeMap = { |
| | | æ°´: "primary", |
| | | çµ: "warning", |
| | | æ°: "success", |
| | | }; |
| | | return typeMap[type] || "info"; |
| | | }; |
| | | |
| | | // åå§åå¾è¡¨ |
| | | const initCharts = () => { |
| | | nextTick(() => { |
| | | // è½èææ¬è¶å¿å¾ |
| | | if (costChart.value) { |
| | | costChartInstance = echarts.init(costChart.value); |
| | | updateCostChart(); |
| | | } |
| | | // è½èç±»åææ¬å æ¯å¾ |
| | | if (typeChart.value) { |
| | | typeChartInstance = echarts.init(typeChart.value); |
| | | updateTypeChart(); |
| | | } |
| | | // è½èç¨éææ¬å æ¯å¾ |
| | | if (purposeChart.value) { |
| | | purposeChartInstance = echarts.init(purposeChart.value); |
| | | updatePurposeChart(); |
| | | } |
| | | // è½èå价对æ¯å¾ |
| | | if (priceChart.value) { |
| | | priceChartInstance = echarts.init(priceChart.value); |
| | | updatePriceChart(); |
| | | } |
| | | }); |
| | | }; |
| | | |
| | | // æ´æ°è½èææ¬è¶å¿å¾ |
| | | const updateCostChart = () => { |
| | | const data = tableData.value; |
| | | const option = { |
| | | tooltip: { |
| | | trigger: "axis", |
| | | axisPointer: { type: "shadow" }, |
| | | backgroundColor: "rgba(255, 255, 255, 0.95)", |
| | | borderColor: "#409EFF", |
| | | borderWidth: 1, |
| | | textStyle: { color: "#303133" }, |
| | | }, |
| | | legend: { |
| | | data: ["ç产è½èææ¬", "åå
¬è½èææ¬"], |
| | | top: 0, |
| | | right: 10, |
| | | textStyle: { color: "#606266" }, |
| | | }, |
| | | grid: { |
| | | left: "3%", |
| | | right: "4%", |
| | | bottom: "10%", |
| | | top: "15%", |
| | | containLabel: true, |
| | | }, |
| | | xAxis: { |
| | | type: "category", |
| | | data: data.map(item => item.timePeriod), |
| | | axisLabel: { |
| | | rotate: statisticsType.value === "day" ? 45 : 0, |
| | | color: "#606266", |
| | | }, |
| | | axisLine: { lineStyle: { color: "#ebeef5" } }, |
| | | splitLine: { show: false }, |
| | | }, |
| | | yAxis: { |
| | | type: "value", |
| | | name: "ææ¬(å
)", |
| | | nameTextStyle: { color: "#606266" }, |
| | | axisLabel: { color: "#606266" }, |
| | | axisLine: { show: false }, |
| | | splitLine: { lineStyle: { color: "#f0f2f5" } }, |
| | | }, |
| | | series: [ |
| | | { |
| | | name: "ç产è½èææ¬", |
| | | type: "bar", |
| | | data: data.map(item => (item.energyPurpose === "ç产" ? item.cost : 0)), |
| | | itemStyle: { |
| | | color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ |
| | | { offset: 0, color: "#409EFF" }, |
| | | { offset: 1, color: "#66b1ff" }, |
| | | ]), |
| | | borderRadius: [4, 4, 0, 0], |
| | | }, |
| | | animationDelay: function (idx) { |
| | | return idx * 100; |
| | | }, |
| | | }, |
| | | { |
| | | name: "åå
¬è½èææ¬", |
| | | type: "bar", |
| | | data: data.map(item => (item.energyPurpose === "åå
¬" ? item.cost : 0)), |
| | | itemStyle: { |
| | | color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ |
| | | { offset: 0, color: "#67C23A" }, |
| | | { offset: 1, color: "#85ce61" }, |
| | | ]), |
| | | borderRadius: [4, 4, 0, 0], |
| | | }, |
| | | animationDelay: function (idx) { |
| | | return idx * 100 + 100; |
| | | }, |
| | | }, |
| | | ], |
| | | animationEasing: "elasticOut", |
| | | animationDelayUpdate: function (idx) { |
| | | return idx * 5; |
| | | }, |
| | | }; |
| | | costChartInstance.setOption(option); |
| | | }; |
| | | |
| | | // æ´æ°è½èç±»åææ¬å æ¯å¾ |
| | | const updateTypeChart = () => { |
| | | const data = tableData.value; |
| | | const typeCosts = {}; |
| | | |
| | | data.forEach(item => { |
| | | if (!typeCosts[item.energyType]) { |
| | | typeCosts[item.energyType] = 0; |
| | | } |
| | | typeCosts[item.energyType] += parseFloat(item.cost); |
| | | }); |
| | | |
| | | const chartData = Object.entries(typeCosts).map(([name, value]) => ({ |
| | | name, |
| | | value: value.toFixed(2), |
| | | })); |
| | | |
| | | const option = { |
| | | tooltip: { |
| | | trigger: "item", |
| | | formatter: "{a} <br/>{b}: ¥{c} ({d}%)", |
| | | backgroundColor: "rgba(255, 255, 255, 0.95)", |
| | | borderColor: "#409EFF", |
| | | borderWidth: 1, |
| | | textStyle: { color: "#303133" }, |
| | | }, |
| | | legend: { |
| | | orient: "horizontal", |
| | | bottom: 0, |
| | | textStyle: { color: "#606266" }, |
| | | }, |
| | | series: [ |
| | | { |
| | | name: "è½èç±»åææ¬", |
| | | type: "pie", |
| | | radius: ["40%", "70%"], |
| | | center: ["50%", "40%"], |
| | | avoidLabelOverlap: false, |
| | | itemStyle: { |
| | | borderRadius: 4, |
| | | borderColor: "#fff", |
| | | borderWidth: 2, |
| | | }, |
| | | label: { |
| | | show: false, |
| | | position: "center", |
| | | }, |
| | | emphasis: { |
| | | label: { |
| | | show: true, |
| | | fontSize: "18", |
| | | fontWeight: "bold", |
| | | color: "#303133", |
| | | }, |
| | | itemStyle: { |
| | | shadowBlur: 10, |
| | | shadowOffsetX: 0, |
| | | shadowColor: "rgba(0, 0, 0, 0.3)", |
| | | }, |
| | | }, |
| | | labelLine: { |
| | | show: false, |
| | | }, |
| | | data: chartData, |
| | | }, |
| | | ], |
| | | color: ["#409EFF", "#67C23A", "#E6A23C"], |
| | | }; |
| | | typeChartInstance.setOption(option); |
| | | }; |
| | | |
| | | // æ´æ°è½èç¨éææ¬å æ¯å¾ |
| | | const updatePurposeChart = () => { |
| | | const data = tableData.value; |
| | | const purposeCosts = { |
| | | ç产: 0, |
| | | åå
¬: 0, |
| | | }; |
| | | |
| | | data.forEach(item => { |
| | | if (purposeCosts.hasOwnProperty(item.energyPurpose)) { |
| | | purposeCosts[item.energyPurpose] += parseFloat(item.cost); |
| | | } |
| | | }); |
| | | |
| | | const chartData = Object.entries(purposeCosts).map(([name, value]) => ({ |
| | | name, |
| | | value: value.toFixed(2), |
| | | })); |
| | | |
| | | const option = { |
| | | tooltip: { |
| | | trigger: "item", |
| | | formatter: "{a} <br/>{b}: ¥{c} ({d}%)", |
| | | backgroundColor: "rgba(255, 255, 255, 0.95)", |
| | | borderColor: "#409EFF", |
| | | borderWidth: 1, |
| | | textStyle: { color: "#303133" }, |
| | | }, |
| | | legend: { |
| | | orient: "horizontal", |
| | | bottom: 0, |
| | | textStyle: { color: "#606266" }, |
| | | }, |
| | | series: [ |
| | | { |
| | | name: "è½èç¨éææ¬", |
| | | type: "pie", |
| | | radius: "60%", |
| | | center: ["50%", "40%"], |
| | | data: chartData, |
| | | emphasis: { |
| | | itemStyle: { |
| | | shadowBlur: 10, |
| | | shadowOffsetX: 0, |
| | | shadowColor: "rgba(0, 0, 0, 0.3)", |
| | | }, |
| | | }, |
| | | label: { |
| | | show: true, |
| | | formatter: "{b}: {d}%", |
| | | color: "#606266", |
| | | }, |
| | | labelLine: { |
| | | show: true, |
| | | lineStyle: { color: "#dcdfe6" }, |
| | | }, |
| | | }, |
| | | ], |
| | | color: ["#409EFF", "#67C23A"], |
| | | }; |
| | | purposeChartInstance.setOption(option); |
| | | }; |
| | | |
| | | // æ´æ°è½èå价对æ¯å¾ |
| | | const updatePriceChart = () => { |
| | | const data = tableData.value; |
| | | const priceData = {}; |
| | | |
| | | data.forEach(item => { |
| | | if (!priceData[item.energyType]) { |
| | | priceData[item.energyType] = { |
| | | ç产: 0, |
| | | åå
¬: 0, |
| | | }; |
| | | } |
| | | if (priceData[item.energyType].hasOwnProperty(item.energyPurpose)) { |
| | | priceData[item.energyType][item.energyPurpose] = parseFloat(item.price); |
| | | } |
| | | }); |
| | | |
| | | const energyTypes = Object.keys(priceData); |
| | | const productionPrices = energyTypes.map(type => priceData[type].ç产); |
| | | const officePrices = energyTypes.map(type => priceData[type].åå
¬); |
| | | |
| | | const option = { |
| | | tooltip: { |
| | | trigger: "axis", |
| | | axisPointer: { type: "shadow" }, |
| | | backgroundColor: "rgba(255, 255, 255, 0.95)", |
| | | borderColor: "#409EFF", |
| | | borderWidth: 1, |
| | | textStyle: { color: "#303133" }, |
| | | }, |
| | | legend: { |
| | | data: ["ç产è½èåä»·", "åå
¬è½èåä»·"], |
| | | top: 0, |
| | | right: 10, |
| | | textStyle: { color: "#606266" }, |
| | | }, |
| | | grid: { |
| | | left: "3%", |
| | | right: "4%", |
| | | bottom: "10%", |
| | | top: "15%", |
| | | containLabel: true, |
| | | }, |
| | | xAxis: { |
| | | type: "category", |
| | | data: energyTypes, |
| | | axisLabel: { color: "#606266" }, |
| | | axisLine: { lineStyle: { color: "#ebeef5" } }, |
| | | splitLine: { show: false }, |
| | | }, |
| | | yAxis: { |
| | | type: "value", |
| | | name: "åä»·(å
)", |
| | | nameTextStyle: { color: "#606266" }, |
| | | axisLabel: { color: "#606266" }, |
| | | axisLine: { show: false }, |
| | | splitLine: { lineStyle: { color: "#f0f2f5" } }, |
| | | }, |
| | | series: [ |
| | | { |
| | | name: "ç产è½èåä»·", |
| | | type: "bar", |
| | | data: productionPrices, |
| | | itemStyle: { |
| | | color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ |
| | | { offset: 0, color: "#409EFF" }, |
| | | { offset: 1, color: "#66b1ff" }, |
| | | ]), |
| | | borderRadius: [4, 4, 0, 0], |
| | | }, |
| | | }, |
| | | { |
| | | name: "åå
¬è½èåä»·", |
| | | type: "bar", |
| | | data: officePrices, |
| | | itemStyle: { |
| | | color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ |
| | | { offset: 0, color: "#67C23A" }, |
| | | { offset: 1, color: "#85ce61" }, |
| | | ]), |
| | | borderRadius: [4, 4, 0, 0], |
| | | }, |
| | | }, |
| | | ], |
| | | }; |
| | | priceChartInstance.setOption(option); |
| | | }; |
| | | |
| | | // ç»è®¡ç»´åº¦åæ¢ |
| | | const handleTypeChange = () => { |
| | | // éç½®æ¶é´èå´ |
| | | if (statisticsType.value === "day") { |
| | | const end = new Date(); |
| | | const start = new Date(); |
| | | start.setDate(start.getDate() - 6); |
| | | searchForm.dateRange = [ |
| | | start.toISOString().split("T")[0], |
| | | end.toISOString().split("T")[0], |
| | | ]; |
| | | } else { |
| | | const end = new Date(); |
| | | const start = new Date(); |
| | | start.setMonth(start.getMonth() - 2); |
| | | searchForm.monthRange = [ |
| | | start.toISOString().slice(0, 7), |
| | | end.toISOString().slice(0, 7), |
| | | ]; |
| | | } |
| | | page.current = 1; |
| | | handleQuery(); |
| | | }; |
| | | |
| | | // æ¥è¯¢ |
| | | const handleQuery = () => { |
| | | tableLoading.value = true; |
| | | |
| | | // æé 请æ±åæ° |
| | | const params = { |
| | | type: statisticsType.value, |
| | | energyType: searchForm.energyType || undefined, |
| | | energyPurpose: searchForm.energyPurpose || undefined, |
| | | }; |
| | | |
| | | if (statisticsType.value === "day") { |
| | | if (searchForm.dateRange && searchForm.dateRange.length === 2) { |
| | | params.startDate = searchForm.dateRange[0]; |
| | | params.endDate = searchForm.dateRange[1]; |
| | | } |
| | | } else { |
| | | if (searchForm.monthRange && searchForm.monthRange.length === 2) { |
| | | params.startDate = searchForm.monthRange[0] + "-01"; |
| | | params.endDate = searchForm.monthRange[1] + "-01"; |
| | | } |
| | | } |
| | | |
| | | // è°ç¨æ¥å£è·åæ°æ® |
| | | energyCostStatistics(params) |
| | | .then(res => { |
| | | if (res.code === 200) { |
| | | tableData.value = res.data.records || []; |
| | | page.total = res.data.total || 0; |
| | | |
| | | // æ´æ°ç»è®¡æ¦è§æ°æ® |
| | | if (res.data.overview) { |
| | | overview.totalCost = res.data.overview.totalCost || "0.00"; |
| | | overview.productionCost = res.data.overview.productionCost || "0.00"; |
| | | overview.officeCost = res.data.overview.officeCost || "0.00"; |
| | | overview.avgCost = res.data.overview.avgCost || "0.00"; |
| | | } |
| | | } else { |
| | | ElMessage.error(res.message || "è·åæ°æ®å¤±è´¥"); |
| | | tableData.value = []; |
| | | page.total = 0; |
| | | } |
| | | }) |
| | | .catch(err => { |
| | | console.error("è·åæ°æ®å¼å¸¸ï¼", err); |
| | | // çæåæ°æ® |
| | | generateMockData(); |
| | | }) |
| | | .finally(() => { |
| | | tableLoading.value = false; |
| | | updateCharts(); |
| | | }); |
| | | }; |
| | | |
| | | // çæåæ°æ® |
| | | const generateMockData = () => { |
| | | if (statisticsType.value === "day") { |
| | | // çææè¿7天çåæ°æ® |
| | | const mockData = []; |
| | | const today = new Date(); |
| | | |
| | | for (let i = 6; i >= 0; i--) { |
| | | const date = new Date(today); |
| | | date.setDate(date.getDate() - i); |
| | | const dateStr = date.toISOString().split("T")[0]; |
| | | |
| | | // ç产è½èæ°æ® |
| | | mockData.push({ |
| | | timePeriod: dateStr, |
| | | energyType: "çµ", |
| | | energyPurpose: "ç产", |
| | | consumption: (Math.random() * 1000 + 500).toFixed(2), |
| | | unit: "kWh", |
| | | price: "0.85", |
| | | cost: (Math.random() * 850 + 425).toFixed(2), |
| | | }); |
| | | mockData.push({ |
| | | timePeriod: dateStr, |
| | | energyType: "æ°´", |
| | | energyPurpose: "ç产", |
| | | consumption: (Math.random() * 500 + 200).toFixed(2), |
| | | unit: "m³", |
| | | price: "3.50", |
| | | cost: (Math.random() * 1750 + 700).toFixed(2), |
| | | }); |
| | | mockData.push({ |
| | | timePeriod: dateStr, |
| | | energyType: "æ°", |
| | | energyPurpose: "ç产", |
| | | consumption: (Math.random() * 300 + 100).toFixed(2), |
| | | unit: "m³", |
| | | price: "2.80", |
| | | cost: (Math.random() * 840 + 280).toFixed(2), |
| | | }); |
| | | |
| | | // åå
¬è½èæ°æ® |
| | | mockData.push({ |
| | | timePeriod: dateStr, |
| | | energyType: "çµ", |
| | | energyPurpose: "åå
¬", |
| | | consumption: (Math.random() * 200 + 100).toFixed(2), |
| | | unit: "kWh", |
| | | price: "0.85", |
| | | cost: (Math.random() * 170 + 85).toFixed(2), |
| | | }); |
| | | mockData.push({ |
| | | timePeriod: dateStr, |
| | | energyType: "æ°´", |
| | | energyPurpose: "åå
¬", |
| | | consumption: (Math.random() * 50 + 20).toFixed(2), |
| | | unit: "m³", |
| | | price: "3.50", |
| | | cost: (Math.random() * 175 + 70).toFixed(2), |
| | | }); |
| | | } |
| | | |
| | | tableData.value = mockData; |
| | | page.total = mockData.length; |
| | | } else { |
| | | // çææè¿3个æçåæ°æ® |
| | | const mockData = []; |
| | | const today = new Date(); |
| | | |
| | | for (let i = 2; i >= 0; i--) { |
| | | const date = new Date(today); |
| | | date.setMonth(date.getMonth() - i); |
| | | const monthStr = date.toISOString().slice(0, 7); |
| | | |
| | | // ç产è½èæ°æ® |
| | | mockData.push({ |
| | | timePeriod: monthStr, |
| | | energyType: "çµ", |
| | | energyPurpose: "ç产", |
| | | consumption: (Math.random() * 30000 + 15000).toFixed(2), |
| | | unit: "kWh", |
| | | price: "0.85", |
| | | cost: (Math.random() * 25500 + 12750).toFixed(2), |
| | | }); |
| | | mockData.push({ |
| | | timePeriod: monthStr, |
| | | energyType: "æ°´", |
| | | energyPurpose: "ç产", |
| | | consumption: (Math.random() * 15000 + 6000).toFixed(2), |
| | | unit: "m³", |
| | | price: "3.50", |
| | | cost: (Math.random() * 52500 + 21000).toFixed(2), |
| | | }); |
| | | mockData.push({ |
| | | timePeriod: monthStr, |
| | | energyType: "æ°", |
| | | energyPurpose: "ç产", |
| | | consumption: (Math.random() * 9000 + 3000).toFixed(2), |
| | | unit: "m³", |
| | | price: "2.80", |
| | | cost: (Math.random() * 25200 + 8400).toFixed(2), |
| | | }); |
| | | |
| | | // åå
¬è½èæ°æ® |
| | | mockData.push({ |
| | | timePeriod: monthStr, |
| | | energyType: "çµ", |
| | | energyPurpose: "åå
¬", |
| | | consumption: (Math.random() * 6000 + 3000).toFixed(2), |
| | | unit: "kWh", |
| | | price: "0.85", |
| | | cost: (Math.random() * 5100 + 2550).toFixed(2), |
| | | }); |
| | | mockData.push({ |
| | | timePeriod: monthStr, |
| | | energyType: "æ°´", |
| | | energyPurpose: "åå
¬", |
| | | consumption: (Math.random() * 1500 + 600).toFixed(2), |
| | | unit: "m³", |
| | | price: "3.50", |
| | | cost: (Math.random() * 5250 + 2100).toFixed(2), |
| | | }); |
| | | } |
| | | |
| | | tableData.value = mockData; |
| | | page.total = mockData.length; |
| | | } |
| | | |
| | | // æ´æ°ç»è®¡æ¦è§æ°æ® |
| | | calculateOverview(); |
| | | }; |
| | | |
| | | // 计ç®ç»è®¡æ¦è§æ°æ® |
| | | const calculateOverview = () => { |
| | | let totalCost = 0; |
| | | let productionCost = 0; |
| | | let officeCost = 0; |
| | | |
| | | tableData.value.forEach(item => { |
| | | const cost = parseFloat(item.cost); |
| | | totalCost += cost; |
| | | if (item.energyPurpose === "ç产") { |
| | | productionCost += cost; |
| | | } else if (item.energyPurpose === "åå
¬") { |
| | | officeCost += cost; |
| | | } |
| | | }); |
| | | |
| | | overview.totalCost = totalCost.toFixed(2); |
| | | overview.productionCost = productionCost.toFixed(2); |
| | | overview.officeCost = officeCost.toFixed(2); |
| | | overview.avgCost = (totalCost / tableData.value.length).toFixed(2); |
| | | }; |
| | | |
| | | // æ´æ°ææå¾è¡¨ |
| | | const updateCharts = () => { |
| | | nextTick(() => { |
| | | if (costChartInstance) updateCostChart(); |
| | | if (typeChartInstance) updateTypeChart(); |
| | | if (purposeChartInstance) updatePurposeChart(); |
| | | if (priceChartInstance) updatePriceChart(); |
| | | }); |
| | | }; |
| | | |
| | | // éç½® |
| | | const handleReset = () => { |
| | | searchForm.energyType = ""; |
| | | searchForm.energyPurpose = ""; |
| | | if (statisticsType.value === "day") { |
| | | const end = new Date(); |
| | | const start = new Date(); |
| | | start.setDate(start.getDate() - 6); |
| | | searchForm.dateRange = [ |
| | | start.toISOString().split("T")[0], |
| | | end.toISOString().split("T")[0], |
| | | ]; |
| | | } else { |
| | | const end = new Date(); |
| | | const start = new Date(); |
| | | start.setMonth(start.getMonth() - 2); |
| | | searchForm.monthRange = [ |
| | | start.toISOString().slice(0, 7), |
| | | end.toISOString().slice(0, 7), |
| | | ]; |
| | | } |
| | | page.current = 1; |
| | | handleQuery(); |
| | | }; |
| | | |
| | | // å¯¼åº |
| | | const handleExport = () => { |
| | | ElMessage.success("æ¥è¡¨å¯¼åºæå"); |
| | | }; |
| | | |
| | | // å页大å°åå |
| | | const handleSizeChange = val => { |
| | | page.size = val; |
| | | }; |
| | | |
| | | // 页ç åå |
| | | const handleCurrentChange = val => { |
| | | page.current = val; |
| | | }; |
| | | |
| | | // çªå£å¤§å°ååæ¶éæ°æ¸²æå¾è¡¨ |
| | | const handleResize = () => { |
| | | costChartInstance && costChartInstance.resize(); |
| | | typeChartInstance && typeChartInstance.resize(); |
| | | purposeChartInstance && purposeChartInstance.resize(); |
| | | priceChartInstance && priceChartInstance.resize(); |
| | | }; |
| | | |
| | | onMounted(() => { |
| | | handleQuery(); |
| | | initCharts(); |
| | | window.addEventListener("resize", handleResize); |
| | | }); |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | .app-container { |
| | | padding: 20px; |
| | | } |
| | | |
| | | .search_form { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | margin-bottom: 20px; |
| | | padding: 15px; |
| | | background-color: #f5f7fa; |
| | | border-radius: 8px; |
| | | } |
| | | |
| | | .statistics-overview { |
| | | margin-bottom: 30px; |
| | | } |
| | | |
| | | .charts-container { |
| | | margin-bottom: 30px; |
| | | } |
| | | |
| | | .table-section { |
| | | margin-bottom: 20px; |
| | | } |
| | | |
| | | .section-header { |
| | | display: flex; |
| | | align-items: center; |
| | | font-size: 18px; |
| | | font-weight: bold; |
| | | color: #303133; |
| | | margin-bottom: 15px; |
| | | padding-left: 10px; |
| | | border-left: 3px solid #409eff; |
| | | |
| | | .header-icon { |
| | | margin-right: 8px; |
| | | color: #409eff; |
| | | } |
| | | } |
| | | |
| | | .overview-card { |
| | | display: flex; |
| | | align-items: center; |
| | | padding: 20px; |
| | | border-radius: 4px; |
| | | background: #fff; |
| | | border: 1px solid #ebeef5; |
| | | |
| | | &.blue-card { |
| | | background-color: #ecf5ff; |
| | | } |
| | | |
| | | &.green-card { |
| | | background-color: #f0f9eb; |
| | | } |
| | | |
| | | &.purple-card { |
| | | background-color: #f3f0ff; |
| | | } |
| | | |
| | | &.gray-card { |
| | | background-color: #f5f7fa; |
| | | } |
| | | |
| | | .overview-icon { |
| | | width: 40px; |
| | | height: 40px; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | border-radius: 50%; |
| | | margin-right: 15px; |
| | | |
| | | &.blue-icon { |
| | | background-color: #409eff; |
| | | color: #fff; |
| | | } |
| | | |
| | | &.green-icon { |
| | | background-color: #67c23a; |
| | | color: #fff; |
| | | } |
| | | |
| | | &.purple-icon { |
| | | background-color: #909399; |
| | | color: #fff; |
| | | } |
| | | |
| | | &.gray-icon { |
| | | background-color: #909399; |
| | | color: #fff; |
| | | } |
| | | |
| | | .el-icon { |
| | | font-size: 20px; |
| | | } |
| | | } |
| | | |
| | | .overview-info { |
| | | flex: 1; |
| | | |
| | | .overview-label { |
| | | font-size: 14px; |
| | | color: #606266; |
| | | margin-bottom: 5px; |
| | | } |
| | | |
| | | .overview-value { |
| | | font-size: 20px; |
| | | font-weight: bold; |
| | | color: #303133; |
| | | |
| | | .unit { |
| | | font-size: 12px; |
| | | font-weight: normal; |
| | | color: #909399; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | .chart-card { |
| | | background: #fff; |
| | | border-radius: 4px; |
| | | border: 1px solid #ebeef5; |
| | | padding: 20px; |
| | | |
| | | .chart-title { |
| | | font-size: 14px; |
| | | font-weight: bold; |
| | | color: #303133; |
| | | margin-bottom: 15px; |
| | | padding-bottom: 10px; |
| | | border-bottom: 1px solid #ebeef5; |
| | | } |
| | | |
| | | .chart-content { |
| | | height: 300px; |
| | | } |
| | | } |
| | | |
| | | .consumption-value { |
| | | font-weight: bold; |
| | | color: #409eff; |
| | | } |
| | | |
| | | .consumption-unit { |
| | | font-size: 12px; |
| | | color: #909399; |
| | | margin-left: 2px; |
| | | } |
| | | |
| | | .price-value { |
| | | font-weight: bold; |
| | | color: #67c23a; |
| | | } |
| | | |
| | | .cost-value { |
| | | font-weight: bold; |
| | | color: #f56c6c; |
| | | } |
| | | |
| | | .pagination-container { |
| | | display: flex; |
| | | justify-content: flex-end; |
| | | } |
| | | </style> |
| | |
| | | ArrowDown, |
| | | } from "@element-plus/icons-vue"; |
| | | import * as echarts from "echarts"; |
| | | import { energyConsumptionDetailStatistics } from "@/api/energyManagement/energyType"; |
| | | |
| | | // ç»è®¡ç»´åº¦ï¼day-ææ¥ï¼month-ææï¼year-æå¹´ |
| | | const statisticsType = ref("day"); |
| | | |
| | | // æç´¢è¡¨å |
| | | const searchForm = reactive({ |
| | | energyType: "", |
| | | dateRange: [], |
| | | monthRange: [], |
| | | energyType: "å
¨é¨", |
| | | dateRange: (() => { |
| | | // é»è®¤æè¿7天 |
| | | const end = new Date(); |
| | | const start = new Date(); |
| | | start.setDate(start.getDate() - 6); |
| | | return [start.toISOString().split("T")[0], end.toISOString().split("T")[0]]; |
| | | })(), |
| | | monthRange: (() => { |
| | | // é»è®¤æè¿3个æ |
| | | const end = new Date(); |
| | | const start = new Date(); |
| | | start.setMonth(start.getMonth() - 2); |
| | | return [start.toISOString().slice(0, 7), end.toISOString().slice(0, 7)]; |
| | | })(), |
| | | year: new Date().getFullYear(), |
| | | }); |
| | | |
| | |
| | | // æ¥è¯¢ |
| | | const handleQuery = () => { |
| | | tableLoading.value = true; |
| | | setTimeout(() => { |
| | | const data = generateMockData(); |
| | | tableData.value = data; |
| | | page.total = data.length; |
| | | const params = { |
| | | type: "", |
| | | }; |
| | | |
| | | // æé 请æ±åæ° |
| | | if (searchForm.energyType != "å
¨é¨") { |
| | | params.type = searchForm.energyType; |
| | | } |
| | | |
| | | if (statisticsType.value === "day") { |
| | | if (searchForm.dateRange && searchForm.dateRange.length === 2) { |
| | | params.startDate = searchForm.dateRange[0]; |
| | | params.endDate = searchForm.dateRange[1]; |
| | | // 计ç®å¤©æ° |
| | | const start = new Date(searchForm.dateRange[0]); |
| | | const end = new Date(searchForm.dateRange[1]); |
| | | params.days = Math.ceil((end - start) / (1000 * 60 * 60 * 24)) + 1; |
| | | } |
| | | } else if (statisticsType.value === "month") { |
| | | if (searchForm.monthRange && searchForm.monthRange.length === 2) { |
| | | params.startDate = searchForm.monthRange[0] + "-01"; |
| | | params.endDate = searchForm.monthRange[1] + "-01"; |
| | | // è®¡ç®ææ° |
| | | const start = new Date(searchForm.monthRange[0] + "-01"); |
| | | const end = new Date(searchForm.monthRange[1] + "-01"); |
| | | params.days = |
| | | (end.getFullYear() - start.getFullYear()) * 12 + |
| | | (end.getMonth() - start.getMonth()) + |
| | | 1; |
| | | } |
| | | } else if (statisticsType.value === "year") { |
| | | params.startDate = searchForm.year + "-01-01"; |
| | | params.endDate = searchForm.year + "-12-31"; |
| | | params.days = 365; |
| | | } |
| | | |
| | | // è°ç¨æ¥å£è·åæ°æ® |
| | | energyConsumptionDetailStatistics(params) |
| | | .then(res => { |
| | | if (res.code === 200) { |
| | | const data = res.data; |
| | | |
| | | // æ´æ°ç»è®¡æ¦è§æ°æ® |
| | | overview.totalConsumption = data.totalEnergyConsumption || "0"; |
| | | overview.totalAmount = data.totalEnergyCost || "0"; |
| | | overview.avgConsumption = data.averageConsumption || "0"; |
| | | overview.compareRate = data.changeVite || 0; |
| | | |
| | | // å¤çè¡¨æ ¼æ°æ® |
| | | tableData.value = data.energyCostDtos || []; |
| | | page.total = tableData.value.length || 0; |
| | | } else { |
| | | ElMessage.error(res.message || "è·åæ°æ®å¤±è´¥"); |
| | | tableData.value = []; |
| | | page.total = 0; |
| | | } |
| | | }) |
| | | .catch(err => { |
| | | console.error("è·åæ°æ®å¼å¸¸ï¼", err); |
| | | ElMessage.error("ç³»ç»å¼å¸¸ï¼è·åæ°æ®å¤±è´¥"); |
| | | tableData.value = []; |
| | | page.total = 0; |
| | | }) |
| | | .finally(() => { |
| | | tableLoading.value = false; |
| | | updateCharts(); |
| | | }, 300); |
| | | }); |
| | | }; |
| | | |
| | | // æ´æ°ææå¾è¡¨ |
| | |
| | | |
| | | // éç½® |
| | | const handleReset = () => { |
| | | searchForm.energyType = ""; |
| | | searchForm.dateRange = []; |
| | | searchForm.monthRange = []; |
| | | searchForm.energyType = "å
¨é¨"; |
| | | // é置为é»è®¤æ¶é´èå´ |
| | | const end = new Date(); |
| | | const start = new Date(); |
| | | |
| | | // é»è®¤æè¿7天 |
| | | start.setDate(start.getDate() - 6); |
| | | searchForm.dateRange = [ |
| | | start.toISOString().split("T")[0], |
| | | end.toISOString().split("T")[0], |
| | | ]; |
| | | |
| | | // é»è®¤æè¿3个æ |
| | | start.setMonth(start.getMonth() - 2); |
| | | searchForm.monthRange = [ |
| | | start.toISOString().slice(0, 7), |
| | | end.toISOString().slice(0, 7), |
| | | ]; |
| | | |
| | | // é»è®¤å½å年份 |
| | | searchForm.year = new Date().getFullYear(); |
| | | |
| | | page.current = 1; |
| | | handleQuery(); |
| | | }; |
| | |
| | | @keyup.enter="handleQuery" /> |
| | | </el-form-item> |
| | | <el-form-item label="产åè§æ ¼:"> |
| | | <el-input v-model="searchForm.productSpec" |
| | | <el-input v-model="searchForm.specification" |
| | | placeholder="请è¾å
¥" |
| | | clearable |
| | | style="width: 160px;" |
| | |
| | | <el-row :gutter="20"> |
| | | <el-col :span="10"> |
| | | <el-form-item label="产åè§æ ¼"> |
| | | <div class="info-display">{{ mergeForm.productSpec || '-' }}</div> |
| | | <div class="info-display">{{ mergeForm.specification || '-' }}</div> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="10"> |
| | |
| | | placeholder="请è¾å
¥äº§ååç§°" /> |
| | | </el-form-item> |
| | | <el-form-item label="产åè§æ ¼" |
| | | prop="productSpec"> |
| | | <el-input v-model="form.productSpec" |
| | | prop="specification"> |
| | | <el-input v-model="form.specification" |
| | | placeholder="请è¾å
¥äº§åè§æ ¼" /> |
| | | </el-form-item> |
| | | <el-form-item label="ç©æç¼ç " |
| | |
| | | }, |
| | | { |
| | | label: "产åè§æ ¼", |
| | | prop: "productSpec", |
| | | prop: "specification", |
| | | width: "150px", |
| | | className: "spec-cell", |
| | | }, |
| | |
| | | // è®¾ç½®è¡¨åæ°æ® |
| | | mergeForm.materialCode = row.materialCode; |
| | | mergeForm.productName = row.productName || ""; |
| | | mergeForm.productSpec = row.productSpec || ""; |
| | | mergeForm.specification = row.specification || ""; |
| | | mergeForm.length = row.length || 0; |
| | | mergeForm.width = row.width || 0; |
| | | mergeForm.height = row.height || 0; |
| | |
| | | const mergeForm = reactive({ |
| | | materialCode: "", |
| | | productName: "", |
| | | productSpec: "", |
| | | specification: "", |
| | | length: 0, |
| | | width: 0, |
| | | height: 0, |
| | |
| | | applyNo: "", |
| | | customerName: "", |
| | | productName: "", |
| | | productSpec: "", |
| | | specification: "", |
| | | materialCode: "", |
| | | quantity: 0, |
| | | volume: 0, |
| | |
| | | { required: true, message: "请è¾å
¥å®¢æ·åç§°", trigger: "blur" }, |
| | | ], |
| | | productName: [{ required: true, message: "请è¾å
¥äº§ååç§°", trigger: "blur" }], |
| | | productSpec: [{ required: true, message: "请è¾å
¥äº§åè§æ ¼", trigger: "blur" }], |
| | | specification: [ |
| | | { required: true, message: "请è¾å
¥äº§åè§æ ¼", trigger: "blur" }, |
| | | ], |
| | | materialCode: [ |
| | | { required: true, message: "请è¾å
¥ç©æç¼ç ", trigger: "blur" }, |
| | | ], |
| | |
| | | searchForm: { |
| | | customerName: "", |
| | | productName: "", |
| | | productSpec: "", |
| | | specification: "", |
| | | materialCode: "", |
| | | applyNo: "", |
| | | dateRange: [], |
| | |
| | | Object.assign(searchForm.value, { |
| | | customerName: "", |
| | | productName: "", |
| | | productSpec: "", |
| | | specification: "", |
| | | materialCode: "", |
| | | applyNo: "", |
| | | dateRange: [], |
| | |
| | | const firstRow = selectedRows.value[0]; |
| | | mergeForm.materialCode = selectedserialNo.value; |
| | | mergeForm.productName = firstRow.productName || ""; |
| | | mergeForm.productSpec = firstRow.productSpec || ""; |
| | | mergeForm.specification = firstRow.specification || ""; |
| | | mergeForm.length = firstRow.length || 0; |
| | | mergeForm.width = firstRow.width || 0; |
| | | mergeForm.height = firstRow.height || 0; |
| | |
| | | applyNo: "", |
| | | customerName: "", |
| | | productName: "", |
| | | productSpec: "", |
| | | specification: "", |
| | | materialCode: "", |
| | | quantity: 0, |
| | | volume: 0, |
| | |
| | | applyNo: row.applyNo || "", |
| | | customerName: row.customerName || "", |
| | | productName: row.productName || "", |
| | | productSpec: row.productSpec || "", |
| | | specification: row.specification || "", |
| | | materialCode: row.materialCode || "", |
| | | quantity: row.quantity || 0, |
| | | volume: row.volume || 0, |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <!-- æç´¢åºå --> |
| | | <div class="search_form"> |
| | | <el-form :model="searchForm" |
| | | :inline="true"> |
| | | <el-form-item label="年份:"> |
| | | <el-select v-model="searchForm.year" |
| | | placeholder="è¯·éæ©å¹´ä»½" |
| | | style="width: 120px;" |
| | | @change="handleQuery"> |
| | | <el-option v-for="year in years" |
| | | :key="year" |
| | | :label="year + 'å¹´'" |
| | | :value="year" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="è½èç±»å:"> |
| | | <el-select v-model="searchForm.energyType" |
| | | placeholder="å
¨é¨" |
| | | clearable |
| | | style="width: 140px;" |
| | | @change="handleQuery"> |
| | | <el-option label="å
¨é¨" |
| | | value="å
¨é¨" /> |
| | | <el-option label="æ°´" |
| | | value="æ°´" /> |
| | | <el-option label="çµ" |
| | | value="çµ" /> |
| | | <el-option label="è¸æ±½" |
| | | value="è¸æ±½" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" |
| | | @click="handleQuery">æ¥è¯¢</el-button> |
| | | <el-button @click="handleReset">éç½®</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | <div> |
| | | <el-button type="success" |
| | | @click="handleExport">å¯¼åºæ¥è¡¨</el-button> |
| | | </div> |
| | | </div> |
| | | <!-- å¾è¡¨åºå --> |
| | | <div class="chart-section"> |
| | | <h2 class="section-header"> |
| | | <el-icon class="header-icon"> |
| | | <TrendCharts /> |
| | | </el-icon> |
| | | è½èåèè¶å¿ |
| | | </h2> |
| | | <div class="chart-card"> |
| | | <div ref="consumptionChart" |
| | | class="chart-content"></div> |
| | | </div> |
| | | </div> |
| | | <!-- æ°æ®è¡¨æ ¼ --> |
| | | <div class="table-section"> |
| | | <h2 class="section-header"> |
| | | <el-icon class="header-icon"> |
| | | <List /> |
| | | </el-icon> |
| | | è½èåèæ°æ® |
| | | </h2> |
| | | <el-table :data="tableData" |
| | | v-loading="tableLoading" |
| | | border> |
| | | <el-table-column prop="energyType" |
| | | label="è½è" |
| | | width="100" |
| | | align="center"> |
| | | <template #default="scope"> |
| | | <el-tag :type="getEnergyTypeType(scope.row.energyType)"> |
| | | {{ scope.row.energyType }} |
| | | </el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="unit" |
| | | label="åä½" |
| | | width="120" |
| | | align="center" /> |
| | | <el-table-column label="æåº¦æ°æ®"> |
| | | <el-table-column prop="monthlyUnitConsumption" |
| | | label="æåº¦ç´¯è®¡åè" |
| | | align="right"> |
| | | <template #default="scope"> |
| | | <span class="data-value">{{ scope.row.monthlyUnitConsumption }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="monthlyConsumption" |
| | | label="æåº¦ç´¯è®¡ç¨é/æåº¦ç´¯è®¡äº§é" |
| | | align="right"> |
| | | <template #default="scope"> |
| | | <span class="data-value">{{ scope.row.monthlyConsumption }}/{{ scope.row.monthlyProduction }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table-column> |
| | | <el-table-column label="å¹´åº¦æ°æ®"> |
| | | <el-table-column prop="annualUnitConsumption" |
| | | label="年度累计åè" |
| | | align="right"> |
| | | <template #default="scope"> |
| | | <span class="data-value">{{ scope.row.annualUnitConsumption }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="annualConsumption" |
| | | label="年度累计ç¨é/年度累计产é" |
| | | align="right"> |
| | | <template #default="scope"> |
| | | <span class="data-value">{{ scope.row.annualConsumption }}/{{ scope.row.annualProduction }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table-column> |
| | | </el-table> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, reactive, onMounted, nextTick } from "vue"; |
| | | import { ElMessage } from "element-plus"; |
| | | import { TrendCharts, List } from "@element-plus/icons-vue"; |
| | | import * as echarts from "echarts"; |
| | | |
| | | // æç´¢è¡¨å |
| | | const searchForm = reactive({ |
| | | year: new Date().getFullYear(), |
| | | energyType: "", |
| | | }); |
| | | |
| | | // çæå¹´ä»½é项 |
| | | const years = []; |
| | | const currentYear = new Date().getFullYear(); |
| | | for (let i = currentYear - 5; i <= currentYear; i++) { |
| | | years.push(i); |
| | | } |
| | | |
| | | // è¡¨æ ¼æ°æ® |
| | | const tableData = ref([]); |
| | | const tableLoading = ref(false); |
| | | |
| | | // å¾è¡¨å¼ç¨ |
| | | const consumptionChart = ref(null); |
| | | let consumptionChartInstance = null; |
| | | |
| | | // è·åè½èç±»åæ ç¾ç±»å |
| | | const getEnergyTypeType = type => { |
| | | const typeMap = { |
| | | æ°´: "primary", |
| | | çµ: "warning", |
| | | è¸æ±½: "success", |
| | | }; |
| | | return typeMap[type] || "info"; |
| | | }; |
| | | |
| | | // åå§åå¾è¡¨ |
| | | const initChart = () => { |
| | | nextTick(() => { |
| | | if (consumptionChart.value) { |
| | | consumptionChartInstance = echarts.init(consumptionChart.value); |
| | | updateChart(); |
| | | } |
| | | }); |
| | | }; |
| | | |
| | | // æ´æ°å¾è¡¨ |
| | | const updateChart = () => { |
| | | const data = tableData.value; |
| | | const months = [ |
| | | "1æ", |
| | | "2æ", |
| | | "3æ", |
| | | "4æ", |
| | | "5æ", |
| | | "6æ", |
| | | "7æ", |
| | | "8æ", |
| | | "9æ", |
| | | "10æ", |
| | | "11æ", |
| | | "12æ", |
| | | ]; |
| | | |
| | | // åå¤å¾è¡¨æ°æ® |
| | | const series = []; |
| | | const energyTypes = ["æ°´", "çµ", "è¸æ±½"]; |
| | | |
| | | energyTypes.forEach(type => { |
| | | const typeData = data.find(item => item.energyType === type); |
| | | if (typeData && typeData.monthlyData) { |
| | | series.push({ |
| | | name: type, |
| | | type: "line", |
| | | data: typeData.monthlyData.map(item => item.unitConsumption), |
| | | smooth: true, |
| | | symbol: "circle", |
| | | symbolSize: 8, |
| | | lineStyle: { |
| | | width: 3, |
| | | }, |
| | | itemStyle: { |
| | | color: |
| | | getEnergyTypeType(type) === "primary" |
| | | ? "#409EFF" |
| | | : getEnergyTypeType(type) === "warning" |
| | | ? "#E6A23C" |
| | | : "#67C23A", |
| | | }, |
| | | }); |
| | | } |
| | | }); |
| | | |
| | | const option = { |
| | | tooltip: { |
| | | trigger: "axis", |
| | | backgroundColor: "rgba(255, 255, 255, 0.95)", |
| | | borderColor: "#409EFF", |
| | | borderWidth: 1, |
| | | textStyle: { color: "#303133" }, |
| | | }, |
| | | legend: { |
| | | data: energyTypes, |
| | | top: 0, |
| | | right: 10, |
| | | textStyle: { color: "#606266" }, |
| | | }, |
| | | grid: { |
| | | left: "3%", |
| | | right: "4%", |
| | | bottom: "10%", |
| | | top: "15%", |
| | | containLabel: true, |
| | | }, |
| | | xAxis: { |
| | | type: "category", |
| | | data: months, |
| | | axisLabel: { color: "#606266" }, |
| | | axisLine: { lineStyle: { color: "#ebeef5" } }, |
| | | splitLine: { show: false }, |
| | | }, |
| | | yAxis: { |
| | | type: "value", |
| | | name: "åè", |
| | | nameTextStyle: { color: "#606266" }, |
| | | axisLabel: { color: "#606266" }, |
| | | axisLine: { show: false }, |
| | | splitLine: { lineStyle: { color: "#f0f2f5" } }, |
| | | }, |
| | | series: series, |
| | | }; |
| | | |
| | | consumptionChartInstance.setOption(option); |
| | | }; |
| | | |
| | | // æ¥è¯¢ |
| | | const handleQuery = () => { |
| | | tableLoading.value = true; |
| | | |
| | | // æ¨¡ææ¥å£è°ç¨ |
| | | setTimeout(() => { |
| | | generateMockData(); |
| | | tableLoading.value = false; |
| | | updateChart(); |
| | | }, 500); |
| | | }; |
| | | |
| | | // éç½® |
| | | const handleReset = () => { |
| | | searchForm.year = new Date().getFullYear(); |
| | | searchForm.energyType = ""; |
| | | handleQuery(); |
| | | }; |
| | | |
| | | // å¯¼åº |
| | | const handleExport = () => { |
| | | ElMessage.success("æ¥è¡¨å¯¼åºæå"); |
| | | }; |
| | | |
| | | // çæåæ°æ® |
| | | const generateMockData = () => { |
| | | const energyTypes = [ |
| | | { |
| | | energyType: "æ°´", |
| | | unit: "å¨/ç«æ¹ç±³", |
| | | monthlyUnitConsumption: (Math.random() * 0.5 + 0.8).toFixed(4), |
| | | monthlyConsumption: Math.floor(Math.random() * 5000 + 10000), |
| | | monthlyProduction: Math.floor(Math.random() * 10000 + 20000), |
| | | annualUnitConsumption: (Math.random() * 0.3 + 0.9).toFixed(4), |
| | | annualConsumption: Math.floor(Math.random() * 60000 + 120000), |
| | | annualProduction: Math.floor(Math.random() * 120000 + 240000), |
| | | monthlyData: generateMonthlyData(0.8, 1.3), |
| | | }, |
| | | { |
| | | energyType: "çµ", |
| | | unit: "度/ç«æ¹ç±³", |
| | | monthlyUnitConsumption: (Math.random() * 2 + 5).toFixed(4), |
| | | monthlyConsumption: Math.floor(Math.random() * 50000 + 100000), |
| | | monthlyProduction: Math.floor(Math.random() * 10000 + 20000), |
| | | annualUnitConsumption: (Math.random() * 1.5 + 5.5).toFixed(4), |
| | | annualConsumption: Math.floor(Math.random() * 600000 + 1200000), |
| | | annualProduction: Math.floor(Math.random() * 120000 + 240000), |
| | | monthlyData: generateMonthlyData(5, 7), |
| | | }, |
| | | { |
| | | energyType: "è¸æ±½", |
| | | unit: "å¨/ç«æ¹ç±³", |
| | | monthlyUnitConsumption: (Math.random() * 0.3 + 0.5).toFixed(4), |
| | | monthlyConsumption: Math.floor(Math.random() * 3000 + 6000), |
| | | monthlyProduction: Math.floor(Math.random() * 10000 + 20000), |
| | | annualUnitConsumption: (Math.random() * 0.2 + 0.55).toFixed(4), |
| | | annualConsumption: Math.floor(Math.random() * 36000 + 72000), |
| | | annualProduction: Math.floor(Math.random() * 120000 + 240000), |
| | | monthlyData: generateMonthlyData(0.5, 0.8), |
| | | }, |
| | | ]; |
| | | |
| | | if (searchForm.energyType && searchForm.energyType !== "å
¨é¨") { |
| | | tableData.value = energyTypes.filter( |
| | | item => item.energyType === searchForm.energyType |
| | | ); |
| | | } else { |
| | | tableData.value = energyTypes; |
| | | } |
| | | }; |
| | | |
| | | // çææåº¦æ°æ® |
| | | const generateMonthlyData = (min, max) => { |
| | | const data = []; |
| | | for (let i = 1; i <= 12; i++) { |
| | | data.push({ |
| | | month: i, |
| | | unitConsumption: (Math.random() * (max - min) + min).toFixed(4), |
| | | }); |
| | | } |
| | | return data; |
| | | }; |
| | | |
| | | // çªå£å¤§å°ååæ¶éæ°æ¸²æå¾è¡¨ |
| | | const handleResize = () => { |
| | | consumptionChartInstance && consumptionChartInstance.resize(); |
| | | }; |
| | | |
| | | onMounted(() => { |
| | | handleQuery(); |
| | | initChart(); |
| | | window.addEventListener("resize", handleResize); |
| | | }); |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | .app-container { |
| | | padding: 20px; |
| | | } |
| | | |
| | | .search_form { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | margin-bottom: 20px; |
| | | padding: 15px; |
| | | background-color: #f5f7fa; |
| | | border-radius: 8px; |
| | | } |
| | | |
| | | .chart-section { |
| | | margin-bottom: 30px; |
| | | } |
| | | |
| | | .table-section { |
| | | margin-bottom: 20px; |
| | | } |
| | | |
| | | .section-header { |
| | | display: flex; |
| | | align-items: center; |
| | | font-size: 18px; |
| | | font-weight: bold; |
| | | color: #303133; |
| | | margin-bottom: 15px; |
| | | padding-left: 10px; |
| | | border-left: 3px solid #409eff; |
| | | |
| | | .header-icon { |
| | | margin-right: 8px; |
| | | color: #409eff; |
| | | } |
| | | } |
| | | |
| | | .chart-card { |
| | | background: #fff; |
| | | border-radius: 4px; |
| | | border: 1px solid #ebeef5; |
| | | padding: 20px; |
| | | |
| | | .chart-content { |
| | | height: 400px; |
| | | } |
| | | } |
| | | |
| | | .data-value { |
| | | font-weight: bold; |
| | | color: #409eff; |
| | | } |
| | | </style> |