| | |
| | | }) |
| | | } |
| | | |
| | | // 查询过程检列表 |
| | | export function qualityInspectProcessPage(query) { |
| | | return request({ |
| | | url: '/quality/qualityInspect/processPage', |
| | | method: 'get', |
| | | params: query, |
| | | }) |
| | | } |
| | |
| | | <div class="search_form"> |
| | | <div> |
| | | <span class="search_title">工序:</span> |
| | | <el-input |
| | | v-model="searchForm.process" |
| | | <el-input v-model="searchForm.process" |
| | | style="width: 240px" |
| | | placeholder="请输入工序搜索" |
| | | @change="handleQuery" |
| | | clearable |
| | | :prefix-icon="Search" |
| | | /> |
| | | <span style="margin-left: 10px" class="search_title">检测日期:</span> |
| | | <el-date-picker v-model="searchForm.entryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="daterange" |
| | | placeholder="请选择" clearable @change="changeDaterange" /> |
| | | <el-button type="primary" @click="handleQuery" style="margin-left: 10px" |
| | | >搜索</el-button |
| | | > |
| | | :prefix-icon="Search" /> |
| | | <span style="margin-left: 10px" |
| | | class="search_title">日期:</span> |
| | | <el-date-picker v-model="searchForm.entryDate" |
| | | value-format="YYYY-MM-DD" |
| | | format="YYYY-MM-DD" |
| | | type="daterange" |
| | | placeholder="请选择" |
| | | clearable |
| | | @change="changeDaterange" /> |
| | | <el-button type="primary" |
| | | @click="handleQuery" |
| | | style="margin-left: 10px">搜索</el-button> |
| | | <el-button type="info" |
| | | @click="resetForm" |
| | | style="margin-left: 10px">重置</el-button> |
| | | </div> |
| | | <div> |
| | | <el-button type="primary" @click="openForm('add')">新增</el-button> |
| | | <!-- <el-button type="primary" |
| | | @click="openForm('add')">新增</el-button> |
| | | <el-button @click="handleOut">导出</el-button> |
| | | <el-button type="danger" plain @click="handleDelete">删除</el-button> |
| | | <el-button type="danger" |
| | | plain |
| | | @click="handleDelete">删除</el-button> --> |
| | | </div> |
| | | </div> |
| | | <div class="table_list"> |
| | | <PIMTable |
| | | rowKey="id" |
| | | <PIMTable rowKey="id" |
| | | :column="tableColumn" |
| | | :tableData="tableData" |
| | | :page="page" |
| | | :isSelection="true" |
| | | @selection-change="handleSelectionChange" |
| | | :tableLoading="tableLoading" |
| | | @pagination="pagination" |
| | | :total="page.total" |
| | | ></PIMTable> |
| | | :total="page.total"> |
| | | <template #qualifiedQuantity="{ row }"> |
| | | <span style="font-weight: bold;color: #409eff;">{{ row.qualifiedQuantity }}</span><span style="margin-left: 5px;color: #909399;">方</span> |
| | | </template> |
| | | <template #unqualifiedQuantity="{ row }"> |
| | | <span style="font-weight: bold;color: #b43434;">{{ row.unqualifiedQuantity }}</span><span style="margin-left: 5px;color: #909399;">方</span> |
| | | </template> |
| | | <template #quantity="{ row }"> |
| | | <span style="font-weight: bold;color: #28e431;">{{ row.quantity }}</span><span style="margin-left: 5px;color: #909399;">方</span> |
| | | </template> |
| | | </PIMTable> |
| | | </div> |
| | | <InspectionFormDia ref="inspectionFormDia" @close="handleQuery"></InspectionFormDia> |
| | | <FormDia ref="formDia" @close="handleQuery"></FormDia> |
| | | <files-dia ref="filesDia" @close="handleQuery"></files-dia> |
| | | <el-dialog v-model="dialogFormVisible" title="编辑检验员" width="30%" |
| | | <InspectionFormDia ref="inspectionFormDia" |
| | | @close="handleQuery"></InspectionFormDia> |
| | | <FormDia ref="formDia" |
| | | @close="handleQuery"></FormDia> |
| | | <files-dia ref="filesDia" |
| | | @close="handleQuery"></files-dia> |
| | | <el-dialog v-model="dialogFormVisible" |
| | | title="编辑检验员" |
| | | width="30%" |
| | | @close="closeDia"> |
| | | <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef"> |
| | | <el-form-item label="检验员:" prop="checkName"> |
| | | <el-select v-model="form.checkName" placeholder="请选择" clearable> |
| | | <el-option v-for="item in userList" :key="item.nickName" :label="item.nickName" |
| | | <el-form :model="form" |
| | | label-width="140px" |
| | | label-position="top" |
| | | :rules="rules" |
| | | ref="formRef"> |
| | | <el-form-item label="检验员:" |
| | | prop="checkName"> |
| | | <el-select v-model="form.checkName" |
| | | placeholder="请选择" |
| | | clearable> |
| | | <el-option v-for="item in userList" |
| | | :key="item.nickName" |
| | | :label="item.nickName" |
| | | :value="item.nickName"/> |
| | | </el-select> |
| | | </el-form-item> |
| | | </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="closeDia">取消</el-button> |
| | | </div> |
| | | </template> |
| | |
| | | |
| | | <script setup> |
| | | import { Search } from "@element-plus/icons-vue"; |
| | | import {onMounted, ref, reactive, toRefs, getCurrentInstance, nextTick} from "vue"; |
| | | import { |
| | | onMounted, |
| | | ref, |
| | | reactive, |
| | | toRefs, |
| | | getCurrentInstance, |
| | | nextTick, |
| | | } from "vue"; |
| | | import InspectionFormDia from "@/views/qualityManagement/processInspection/components/inspectionFormDia.vue"; |
| | | import FormDia from "@/views/qualityManagement/processInspection/components/formDia.vue"; |
| | | import {ElMessageBox} from "element-plus"; |
| | | import { |
| | | downloadQualityInspect, |
| | | qualityInspectDel, |
| | | qualityInspectListPage, qualityInspectUpdate, |
| | | submitQualityInspect |
| | | qualityInspectListPage, |
| | | qualityInspectUpdate, |
| | | submitQualityInspect, |
| | | qualityInspectProcessPage, |
| | | } from "@/api/qualityManagement/rawMaterialInspection.js"; |
| | | import FilesDia from "@/views/qualityManagement/processInspection/components/filesDia.vue"; |
| | | import dayjs from "dayjs"; |
| | |
| | | searchForm: { |
| | | process: "", |
| | | entryDate: undefined, // 录入日期 |
| | | entryDateStart: undefined, |
| | | entryDateEnd: undefined, |
| | | startTime: undefined, |
| | | endTime: undefined, |
| | | }, |
| | | rules: { |
| | | checkName: [{required: true, message: "请选择", trigger: "change"}], |
| | |
| | | const { searchForm } = toRefs(data); |
| | | const tableColumn = ref([ |
| | | { |
| | | label: "检测日期", |
| | | prop: "checkTime", |
| | | width: 120 |
| | | label: "日期", |
| | | prop: "createTime", |
| | | width: "130", |
| | | formatData: val => { |
| | | return dayjs(val).format("YYYY-MM-DD"); |
| | | }, |
| | | }, |
| | | { |
| | | label: "生产工单号", |
| | | prop: "workOrderNo", |
| | | width: 120 |
| | | label: "生产订单号", |
| | | prop: "npsNo", |
| | | width: "130", |
| | | }, |
| | | { |
| | | label: "工序", |
| | | prop: "process", |
| | | width: 230 |
| | | }, |
| | | { |
| | | label: "检验员", |
| | | prop: "checkName", |
| | | }, |
| | | { |
| | | label: "产品名称", |
| | | prop: "productName", |
| | | }, |
| | | { |
| | | label: "规格型号", |
| | | prop: "model", |
| | | }, |
| | | { |
| | | label: "单位", |
| | | prop: "unit", |
| | | }, |
| | | { |
| | | label: "数量", |
| | | prop: "quantity", |
| | | width: 100 |
| | | }, |
| | | { |
| | | label: "检测单位", |
| | | prop: "checkCompany", |
| | | width: 120 |
| | | }, |
| | | { |
| | | label: "检测结果", |
| | | prop: "checkResult", |
| | | dataType: "tag", |
| | | formatType: (params) => { |
| | | if (params == '不合格') { |
| | | return "danger"; |
| | | } else if (params == '合格') { |
| | | }, |
| | | { |
| | | label: "产品编码", |
| | | prop: "materialCode", |
| | | width: "130", |
| | | }, |
| | | { |
| | | label: "产品类型", |
| | | prop: "strength", |
| | | dataType: "tag", |
| | | formatType: params => { |
| | | if (params == "A3.5") { |
| | | return "success"; |
| | | } else if (params == "A4.5") { |
| | | return "warning"; |
| | | } else { |
| | | return null; |
| | | } |
| | | }, |
| | | }, |
| | | { |
| | | label: "提交状态", |
| | | prop: "inspectState", |
| | | formatData: (params) => { |
| | | if (params) { |
| | | return "已提交"; |
| | | label: "产品名称", |
| | | prop: "productName", |
| | | }, |
| | | { |
| | | label: "规格", |
| | | prop: "model", |
| | | width: "130", |
| | | }, |
| | | { |
| | | label: "班次", |
| | | prop: "schedule", |
| | | dataType: "tag", |
| | | formatType: params => { |
| | | if (params == "白班") { |
| | | return "primary"; |
| | | } else if (params == "夜班") { |
| | | return "warning"; |
| | | } else { |
| | | return "未提交"; |
| | | return null; |
| | | } |
| | | }, |
| | | }, |
| | | { |
| | | dataType: "action", |
| | | label: "操作", |
| | | align: "center", |
| | | fixed: "right", |
| | | width: 280, |
| | | operation: [ |
| | | { |
| | | name: "编辑", |
| | | type: "text", |
| | | clickFun: (row) => { |
| | | openForm("edit", row); |
| | | }, |
| | | disabled: (row) => { |
| | | // 已提交则禁用 |
| | | if (row.inspectState == 1) return true; |
| | | // 如果检验员有值,只有当前登录用户能编辑 |
| | | if (row.checkName) { |
| | | return row.checkName !== userStore.nickName; |
| | | } |
| | | return false; |
| | | } |
| | | label: "岗位人员", |
| | | prop: "postName", |
| | | }, |
| | | { |
| | | name: "附件", |
| | | type: "text", |
| | | clickFun: (row) => { |
| | | openFilesFormDia(row); |
| | | }, |
| | | label: "报工单号", |
| | | prop: "productionProductRouteItemId", |
| | | }, |
| | | { |
| | | name: "提交", |
| | | type: "text", |
| | | clickFun: (row) => { |
| | | submit(row.id); |
| | | }, |
| | | disabled: (row) => { |
| | | // 已提交则禁用 |
| | | if (row.inspectState == 1) return true; |
| | | // 如果检验员有值,只有当前登录用户能提交 |
| | | if (row.checkName) { |
| | | return row.checkName !== userStore.nickName; |
| | | } |
| | | return false; |
| | | } |
| | | label: "产出数量", |
| | | prop: "quantity", |
| | | dataType: "slot", |
| | | slot: "quantity", |
| | | }, |
| | | { |
| | | name: "分配检验员", |
| | | type: "text", |
| | | clickFun: (row) => { |
| | | if (!row.checkName) { |
| | | open(row) |
| | | } else { |
| | | proxy.$modal.msgError("检验员已存在"); |
| | | } |
| | | }, |
| | | disabled: (row) => { |
| | | return row.inspectState == 1 || row.checkName; |
| | | } |
| | | label: "合格数量", |
| | | prop: "qualifiedQuantity", |
| | | dataType: "slot", |
| | | slot: "qualifiedQuantity", |
| | | }, |
| | | { |
| | | name: "下载", |
| | | type: "text", |
| | | clickFun: (row) => { |
| | | downLoadFile(row); |
| | | label: "不合格数量", |
| | | prop: "unqualifiedQuantity", |
| | | dataType: "slot", |
| | | slot: "unqualifiedQuantity", |
| | | }, |
| | | }, |
| | | ], |
| | | }, |
| | | |
| | | // { |
| | | // dataType: "action", |
| | | // label: "操作", |
| | | // align: "center", |
| | | // fixed: "right", |
| | | // width: 280, |
| | | // operation: [ |
| | | // { |
| | | // name: "编辑", |
| | | // type: "text", |
| | | // clickFun: row => { |
| | | // openForm("edit", row); |
| | | // }, |
| | | // disabled: row => { |
| | | // // 已提交则禁用 |
| | | // if (row.inspectState == 1) return true; |
| | | // // 如果检验员有值,只有当前登录用户能编辑 |
| | | // if (row.checkName) { |
| | | // return row.checkName !== userStore.nickName; |
| | | // } |
| | | // return false; |
| | | // }, |
| | | // }, |
| | | // { |
| | | // name: "附件", |
| | | // type: "text", |
| | | // clickFun: row => { |
| | | // openFilesFormDia(row); |
| | | // }, |
| | | // }, |
| | | // { |
| | | // name: "提交", |
| | | // type: "text", |
| | | // clickFun: row => { |
| | | // submit(row.id); |
| | | // }, |
| | | // disabled: row => { |
| | | // // 已提交则禁用 |
| | | // if (row.inspectState == 1) return true; |
| | | // // 如果检验员有值,只有当前登录用户能提交 |
| | | // if (row.checkName) { |
| | | // return row.checkName !== userStore.nickName; |
| | | // } |
| | | // return false; |
| | | // }, |
| | | // }, |
| | | // { |
| | | // name: "分配检验员", |
| | | // type: "text", |
| | | // clickFun: row => { |
| | | // if (!row.checkName) { |
| | | // open(row); |
| | | // } else { |
| | | // proxy.$modal.msgError("检验员已存在"); |
| | | // } |
| | | // }, |
| | | // disabled: row => { |
| | | // return row.inspectState == 1 || row.checkName; |
| | | // }, |
| | | // }, |
| | | // { |
| | | // name: "下载", |
| | | // type: "text", |
| | | // clickFun: row => { |
| | | // downLoadFile(row); |
| | | // }, |
| | | // }, |
| | | // ], |
| | | // }, |
| | | ]); |
| | | const userList = ref([]); |
| | | const currentRow = ref(null) |
| | | const currentRow = ref(null); |
| | | const tableData = ref([]); |
| | | const selectedRows = ref([]); |
| | | const tableLoading = ref(false); |
| | | const dialogFormVisible = ref(false); |
| | | const form = ref({ |
| | | checkName: "" |
| | | checkName: "", |
| | | }); |
| | | const page = reactive({ |
| | | current: 1, |
| | | size: 100, |
| | | total: 0 |
| | | total: 0, |
| | | }); |
| | | const formDia = ref() |
| | | const filesDia = ref() |
| | | const inspectionFormDia = ref() |
| | | const { proxy } = getCurrentInstance() |
| | | const userStore = useUserStore() |
| | | const changeDaterange = (value) => { |
| | | searchForm.value.entryDateStart = undefined; |
| | | searchForm.value.entryDateEnd = undefined; |
| | | const formDia = ref(); |
| | | const filesDia = ref(); |
| | | const inspectionFormDia = ref(); |
| | | const { proxy } = getCurrentInstance(); |
| | | const userStore = useUserStore(); |
| | | const changeDaterange = value => { |
| | | searchForm.value.startTime = undefined; |
| | | searchForm.value.endTime = undefined; |
| | | if (value) { |
| | | searchForm.value.entryDateStart = dayjs(value[0]).format("YYYY-MM-DD"); |
| | | searchForm.value.entryDateEnd = dayjs(value[1]).format("YYYY-MM-DD"); |
| | | searchForm.value.startTime = dayjs(value[0]).format("YYYY-MM-DD"); |
| | | searchForm.value.endTime = dayjs(value[1]).format("YYYY-MM-DD"); |
| | | } |
| | | getList(); |
| | | }; |
| | |
| | | page.current = 1; |
| | | getList(); |
| | | }; |
| | | const pagination = (obj) => { |
| | | /** 重置按钮操作 */ |
| | | const resetForm = () => { |
| | | searchForm.value = { |
| | | checkName: "", |
| | | entryDate: undefined, |
| | | startTime: undefined, |
| | | endTime: undefined, |
| | | }; |
| | | getList(); |
| | | }; |
| | | const pagination = obj => { |
| | | page.current = obj.page; |
| | | page.size = obj.limit; |
| | | getList(); |
| | |
| | | const getList = () => { |
| | | tableLoading.value = true; |
| | | const params = { ...searchForm.value, ...page }; |
| | | params.entryDate = undefined |
| | | qualityInspectListPage({...params, inspectType: 1}).then(res => { |
| | | params.entryDate = undefined; |
| | | qualityInspectProcessPage({ ...params, inspectType: 1 }) |
| | | .then(res => { |
| | | tableLoading.value = false; |
| | | tableData.value = res.data.records |
| | | tableData.value = res.data.records; |
| | | page.total = res.data.total; |
| | | }).catch(err => { |
| | | tableLoading.value = false; |
| | | }) |
| | | .catch(err => { |
| | | tableLoading.value = false; |
| | | }); |
| | | }; |
| | | // 表格选择数据 |
| | | const handleSelectionChange = (selection) => { |
| | | const handleSelectionChange = selection => { |
| | | selectedRows.value = selection; |
| | | }; |
| | | |
| | | // 打开弹框 |
| | | const openForm = (type, row) => { |
| | | nextTick(() => { |
| | | formDia.value?.openDialog(type, row) |
| | | }) |
| | | formDia.value?.openDialog(type, row); |
| | | }); |
| | | }; |
| | | // 打开新增检验弹框 |
| | | const openInspectionForm = (type, row) => { |
| | | nextTick(() => { |
| | | inspectionFormDia.value?.openDialog(type, row) |
| | | }) |
| | | inspectionFormDia.value?.openDialog(type, row); |
| | | }); |
| | | }; |
| | | // 打开附件弹框 |
| | | const openFilesFormDia = (type, row) => { |
| | | nextTick(() => { |
| | | filesDia.value?.openDialog(type, row) |
| | | }) |
| | | filesDia.value?.openDialog(type, row); |
| | | }); |
| | | }; |
| | | // 提价 |
| | | const submit = async (id) => { |
| | | const res = await submitQualityInspect({id: id}) |
| | | const submit = async id => { |
| | | const res = await submitQualityInspect({ id: id }); |
| | | if (res.code === 200) { |
| | | proxy.$modal.msgSuccess("提交成功"); |
| | | getList(); |
| | | } |
| | | } |
| | | const open = async (row) => { |
| | | }; |
| | | const open = async row => { |
| | | let userLists = await userListNoPage(); |
| | | userList.value = userLists.data; |
| | | currentRow.value = row |
| | | dialogFormVisible.value = true |
| | | } |
| | | currentRow.value = row; |
| | | dialogFormVisible.value = true; |
| | | }; |
| | | // 关闭弹框 |
| | | const closeDia = () => { |
| | | proxy.resetForm("formRef"); |
| | |
| | | if (currentRow.value) { |
| | | const data = { |
| | | ...form.value, |
| | | id: currentRow.value.id |
| | | } |
| | | id: currentRow.value.id, |
| | | }; |
| | | qualityInspectUpdate(data).then(res => { |
| | | proxy.$modal.msgSuccess("提交成功"); |
| | | closeDia(); |
| | | getList(); |
| | | }) |
| | | }); |
| | | } |
| | | }; |
| | | |
| | |
| | | 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; |
| | |
| | | type: "warning", |
| | | }) |
| | | .then(() => { |
| | | qualityInspectDel(ids).then((res) => { |
| | | qualityInspectDel(ids).then(res => { |
| | | proxy.$modal.msgSuccess("删除成功"); |
| | | getList(); |
| | | }); |
| | |
| | | proxy.$modal.msg("已取消"); |
| | | }); |
| | | }; |
| | | const downLoadFile = (row) => { |
| | | downloadQualityInspect({ id: row.id }).then((blobData) => { |
| | | const downLoadFile = row => { |
| | | downloadQualityInspect({ id: row.id }).then(blobData => { |
| | | const blob = new Blob([blobData], { |
| | | type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', |
| | | }) |
| | | const downloadUrl = window.URL.createObjectURL(blob) |
| | | type: "application/vnd.openxmlformats-officedocument.wordprocessingml.document", |
| | | }); |
| | | const downloadUrl = window.URL.createObjectURL(blob); |
| | | |
| | | const link = document.createElement('a') |
| | | link.href = downloadUrl |
| | | link.download = '过程检验报告.docx' |
| | | document.body.appendChild(link) |
| | | link.click() |
| | | const link = document.createElement("a"); |
| | | link.href = downloadUrl; |
| | | link.download = "过程检验报告.docx"; |
| | | document.body.appendChild(link); |
| | | link.click(); |
| | | |
| | | document.body.removeChild(link) |
| | | window.URL.revokeObjectURL(downloadUrl) |
| | | }) |
| | | document.body.removeChild(link); |
| | | window.URL.revokeObjectURL(downloadUrl); |
| | | }); |
| | | }; |
| | | // 导出 |
| | | const handleOut = () => { |
| | |
| | | type: "warning", |
| | | }) |
| | | .then(() => { |
| | | proxy.download("/quality/qualityInspect/export", {inspectType: 1}, "过程检验.xlsx"); |
| | | proxy.download( |
| | | "/quality/qualityInspect/export", |
| | | { inspectType: 1 }, |
| | | "过程检验.xlsx" |
| | | ); |
| | | }) |
| | | .catch(() => { |
| | | proxy.$modal.msg("已取消"); |
| | |
| | | </div> |
| | | <div class="material-info-card"> |
| | | <div class="material-icon"> |
| | | <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> |
| | | <svg width="24" |
| | | height="24" |
| | | viewBox="0 0 24 24" |
| | | fill="none" |
| | | stroke="currentColor" |
| | | stroke-width="2"> |
| | | <path d="M20 7h-4V4c0-1.1-.9-2-2-2h-4c-1.1 0-2 .9-2 2v3H4c-1.1 0-2 .9-2 2v11c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V9c0-1.1-.9-2-2-2z" /> |
| | | <polyline points="22,7 12,13 2,7" /> |
| | | </svg> |
| | |
| | | </div> |
| | | <div class="material-info-card"> |
| | | <div class="material-icon"> |
| | | <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> |
| | | <svg width="24" |
| | | height="24" |
| | | viewBox="0 0 24 24" |
| | | fill="none" |
| | | stroke="currentColor" |
| | | stroke-width="2"> |
| | | <path d="M20 7h-4V4c0-1.1-.9-2-2-2h-4c-1.1 0-2 .9-2 2v3H4c-1.1 0-2 .9-2 2v11c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V9c0-1.1-.9-2-2-2z" /> |
| | | <polyline points="22,7 12,13 2,7" /> |
| | | </svg> |
| | |
| | | <!-- 右下:销量排名分析 --> |
| | | <div class="bi-panel bi-panel-bottom-right"> |
| | | <PanelHeader :isFullscreen="true" |
| | | title="物料生产量统计" /> |
| | | title="能耗统计" /> |
| | | <div class="panel-tabs"> |
| | | <span class="tab-item" |
| | | :class="{ active: salesTimeDimension === 'year' }" |
| | |
| | | @click="handleSalesTimeDimensionChange('month')">月</span> |
| | | </div> |
| | | <div class="bi-panel-body"> |
| | | <!-- <div class="chart-filter-tabs"> |
| | | <span v-for="area in salesAreas" |
| | | :key="area" |
| | | class="cf-tab" |
| | | :class="{ active: selectedArea === area }" |
| | | @click="handleAreaChange(area)">{{ area }}</span> |
| | | </div> |
| | | <div ref="salesRankingChart" |
| | | class="echart-fill"></div> --> |
| | | class="echart-fill"></div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | |
| | | // 板材单耗图表配置 |
| | | const boardCostChartOption = computed(() => { |
| | | const materials = ["消耗量"]; |
| | | const colors = ["#00A4ED", "#34D8F7", "#4A8BFF", "#8A6BFF", "#C8C447", "#FF6B6B"]; |
| | | const colors = [ |
| | | "#00A4ED", |
| | | "#34D8F7", |
| | | "#4A8BFF", |
| | | "#8A6BFF", |
| | | "#C8C447", |
| | | "#FF6B6B", |
| | | ]; |
| | | const year = 2024; |
| | | const periodType = boardTimeDimension.value; |
| | | |
| | |
| | | // 产量分析图表配置 |
| | | const productionChartOption = computed(() => { |
| | | const salesAreas = ["全部", "砌块", "板材"]; |
| | | const colors = ["#00A4ED", "#34D8F7", "#4A8BFF", "#8A6BFF", "#C8C447", "#FF6B6B"]; |
| | | const colors = [ |
| | | "#00A4ED", |
| | | "#34D8F7", |
| | | "#4A8BFF", |
| | | "#8A6BFF", |
| | | "#C8C447", |
| | | "#FF6B6B", |
| | | ]; |
| | | const year = 2024; |
| | | const periodType = productionTimeDimension.value; |
| | | |
| | |
| | | }; |
| | | }); |
| | | |
| | | // 销量排名分析图表配置 |
| | | // 能耗统计图表配置 |
| | | const salesRankingChartOption = computed(() => { |
| | | const customers = ["客户BB", "客户AA", "客户CC", "客户DD", "客户DD", "客户DD"]; |
| | | const values = [130, 120, 102, 90, 90, 70]; |
| | | const barColors = [ |
| | | "#34D8F7", |
| | | "#4A8BFF", |
| | | "#8A6BFF", |
| | | "#C8C447", |
| | | "#C8C447", |
| | | "#C8C447", |
| | | const energyTypes = ["水", "电", "蒸汽"]; |
| | | const colors = ["#00A4ED", "#AC43C2", "#F5BC4A"]; |
| | | const year = 2024; |
| | | const periodType = salesTimeDimension.value; |
| | | |
| | | // 生成时间段 |
| | | let periods = []; |
| | | if (periodType === "year") { |
| | | // 年度数据:6个月 |
| | | for (let month = 9; month <= 12; month++) { |
| | | periods.push(`${month}/${year.toString().slice(2)}`); |
| | | } |
| | | for (let month = 1; month <= 3; month++) { |
| | | periods.push(`${month}/${(year + 1).toString().slice(2)}`); |
| | | } |
| | | } else { |
| | | // 月度数据:7天 |
| | | const month = 1; |
| | | for (let day = 1; day <= 7; day++) { |
| | | periods.push(`${month}/${day}`); |
| | | } |
| | | } |
| | | |
| | | // 为每种能源类型生成数据 |
| | | const waterData = periods.map(() => { |
| | | return periodType === "year" |
| | | ? Math.floor(Math.random() * 300) + 400 |
| | | : Math.floor(Math.random() * 30) + 40; |
| | | }); |
| | | const steamData = periods.map(() => { |
| | | return periodType === "year" |
| | | ? Math.floor(Math.random() * 400) + 500 |
| | | : Math.floor(Math.random() * 40) + 50; |
| | | }); |
| | | const electricityData = periods.map(() => { |
| | | return periodType === "year" |
| | | ? Math.floor(Math.random() * 200) + 300 |
| | | : Math.floor(Math.random() * 20) + 30; |
| | | }); |
| | | |
| | | const series = [ |
| | | { |
| | | name: "水", |
| | | type: "bar", |
| | | data: waterData, |
| | | itemStyle: { |
| | | color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ |
| | | { offset: 0, color: "#00A4ED" }, |
| | | { offset: 1, color: "#0F285A" }, |
| | | ]), |
| | | borderRadius: [getResponsiveValue(4), getResponsiveValue(4), 0, 0], |
| | | }, |
| | | barWidth: getResponsiveValue(6), |
| | | }, |
| | | { |
| | | name: "电", |
| | | type: "line", |
| | | data: electricityData, |
| | | itemStyle: { |
| | | color: "#AC43C2", |
| | | }, |
| | | lineStyle: { |
| | | width: getResponsiveValue(1), |
| | | color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [ |
| | | { offset: 0, color: "#AC43C2" }, |
| | | { offset: 1, color: "#AC43C2" }, |
| | | ]), |
| | | }, |
| | | symbol: "circle", |
| | | symbolSize: getResponsiveValue(8), |
| | | areaStyle: { |
| | | color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ |
| | | { offset: 0, color: "#AC43C250" }, |
| | | { offset: 1, color: "#AC43C203" }, |
| | | ]), |
| | | }, |
| | | }, |
| | | { |
| | | name: "蒸汽", |
| | | type: "bar", |
| | | data: steamData, |
| | | itemStyle: { |
| | | color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ |
| | | { offset: 0, color: "#F5BC4A" }, |
| | | { offset: 1, color: "#591C22" }, |
| | | ]), |
| | | borderRadius: [getResponsiveValue(4), getResponsiveValue(4), 0, 0], |
| | | }, |
| | | barWidth: getResponsiveValue(6), |
| | | }, |
| | | ]; |
| | | |
| | | return { |
| | | backgroundColor: "transparent", |
| | | tooltip: { |
| | | trigger: "axis", |
| | | axisPointer: { type: "shadow" }, |
| | | backgroundColor: "rgba(0,0,0,0.55)", |
| | | borderColor: "rgba(64,158,255,0.25)", |
| | | axisPointer: { type: "cross" }, |
| | | backgroundColor: "rgba(0,0,0,0.7)", |
| | | borderColor: "rgba(64,158,255,0.5)", |
| | | borderWidth: getResponsiveValue(1), |
| | | textStyle: { color: "#B8C8E0", fontSize: getResponsiveValue(11) }, |
| | | formatter: "{b}: {c} 立方米", |
| | | textStyle: { color: "#B8C8E0", fontSize: getResponsiveValue(12) }, |
| | | formatter: function (params) { |
| | | let result = params[0].name + "<br/>"; |
| | | params.forEach(param => { |
| | | const unit = param.seriesName === "电" ? "度" : "吨"; |
| | | result += `${param.marker}${param.seriesName}: ${param.value} ${unit}<br/>`; |
| | | }); |
| | | return result; |
| | | }, |
| | | }, |
| | | legend: { |
| | | data: energyTypes, |
| | | top: "5%", |
| | | right: "1%", |
| | | textStyle: { |
| | | color: "#B8C8E0", |
| | | fontSize: getResponsiveValue(10), |
| | | }, |
| | | itemWidth: getResponsiveValue(12), |
| | | itemHeight: getResponsiveValue(12), |
| | | itemGap: getResponsiveValue(15), |
| | | }, |
| | | grid: { |
| | | left: "14%", |
| | | right: "6%", |
| | | top: "16%", |
| | | bottom: "8%", |
| | | left: "1%", |
| | | right: "1%", |
| | | top: "25%", |
| | | bottom: "0%", |
| | | containLabel: true, |
| | | }, |
| | | xAxis: { |
| | | type: "value", |
| | | axisLine: { show: false }, |
| | | axisLabel: { color: "#B8C8E0", fontSize: getResponsiveValue(11) }, |
| | | splitLine: { lineStyle: { color: "rgba(184,200,224,0.12)" } }, |
| | | type: "category", |
| | | data: periods, |
| | | axisLabel: { |
| | | fontSize: getResponsiveValue(11), |
| | | color: "#93B9FF", |
| | | interval: 0, |
| | | rotate: periodType === "month" ? 45 : 0, |
| | | }, |
| | | axisLine: { |
| | | show: true, |
| | | lineStyle: { |
| | | width: getResponsiveValue(1), |
| | | color: "#305B9A", |
| | | }, |
| | | }, |
| | | axisTick: { |
| | | show: false, |
| | | }, |
| | | }, |
| | | yAxis: { |
| | | type: "category", |
| | | data: customers, |
| | | axisTick: { show: false }, |
| | | axisLine: { show: false }, |
| | | type: "value", |
| | | axisLabel: { |
| | | color: "#B8C8E0", |
| | | fontSize: getResponsiveValue(11), |
| | | margin: getResponsiveValue(8), |
| | | color: "#93B9FF", |
| | | formatter: function (value) { |
| | | return value; |
| | | }, |
| | | }, |
| | | series: [ |
| | | { |
| | | name: "销量(立方米)", |
| | | type: "bar", |
| | | barWidth: getResponsiveValue(14), |
| | | data: values, |
| | | itemStyle: { |
| | | color: params => barColors[params.dataIndex] || "#00A4ED", |
| | | borderRadius: [ |
| | | getResponsiveValue(6), |
| | | getResponsiveValue(6), |
| | | getResponsiveValue(6), |
| | | getResponsiveValue(6), |
| | | ], |
| | | axisLine: { |
| | | show: true, |
| | | lineStyle: { |
| | | color: "#305B9A", |
| | | }, |
| | | }, |
| | | ], |
| | | splitLine: { |
| | | lineStyle: { |
| | | color: "#0F2E60", |
| | | type: "dashed", |
| | | }, |
| | | }, |
| | | }, |
| | | series: series, |
| | | }; |
| | | }); |
| | | |
| | |
| | | height: 24vh; |
| | | } |
| | | |
| | | |
| | | .bi-panel-bottom-right .echart-fill { |
| | | height: calc(100% - 2.8vh); |
| | | } |
| | |
| | | font-size: 1vh; |
| | | opacity: 0.7; |
| | | } |
| | | |
| | | </style> |