@@ -1,41 +1,31 @@ | |||
<template> | |||
<el-dialog | |||
class="dialog-with-menu" | |||
style="padding: 40px" | |||
style="padding: 32px" | |||
:fullscreen="fullscreen" | |||
:visible="visible" | |||
@close="handleClose" | |||
:destroy-on-close="false" | |||
:close-on-click-modal="configs.clickModalToClose ?? true" | |||
> | |||
<!-- <el-button type="text" icon="el-icon-close" style="position: absolute; z-index: 100; top: 0; right: 18px" @click="handleClose">关闭</el-button> --> | |||
<el-tabs v-model="activeTab" type="card" @tab-click="handleTabClick"> | |||
<el-tab-pane name="sub" label="子订单进度"> | |||
<SubOrderDetail v-if="order !== null" :order="order" /> | |||
</el-tab-pane> | |||
<el-tab-pane name="car" label="窑车详情"> | |||
<CarDetail v-if="order !== null" :order-id="order.id" :table-layout="carLayoutKey" /> | |||
</el-tab-pane> | |||
<el-tab-pane name="tray" label="托盘详情"> | |||
<TrayDetail /> | |||
</el-tab-pane> | |||
<el-tab-pane name="order" label="订单详情"> | |||
<OrderDetail ref="order-detail-tag" :configs="configs" /> | |||
</el-tab-pane> | |||
</el-tabs> | |||
<!-- | |||
<div style="width: 100%; height: 76px; position: absolute; z-index: 100; bottom: 0; text-align: right;"> | |||
<el-button type="" plain @click="handleClose" style="margin-right: 18px; margin-top: 18px;">关闭</el-button> | |||
</div> --> | |||
:close-on-click-modal="configs.clickModalToClose ?? true"> | |||
<div slot="title" style="background: #eee; padding: 8px; text-align: center; border-bottom: 1px solid #ccc"> | |||
<el-checkbox-group v-model="activeTab" @change="handleTabClick"> | |||
<el-checkbox-button :true-label="1">子订单进度</el-checkbox-button> | |||
<el-checkbox-button :true-label="2">窑车详情</el-checkbox-button> | |||
<el-checkbox-button :true-label="3">托盘详情</el-checkbox-button> | |||
<el-checkbox-button :true-label="4">订单详情</el-checkbox-button> | |||
</el-checkbox-group> | |||
</div> | |||
<!-- <transition mode="out-in" :name="toLeft ? 'fade-left' : 'fade-right'"> --> | |||
<transition mode="out-in" name="fade-left"> | |||
<SubOrderDetail v-if="activeTab === 1 && order !== null" :order="order" /> | |||
<CarDetail v-if="activeTab === 2 && order !== null" :order-id="order.id" :table-layout="carLayoutKey" /> | |||
<TrayDetail v-if="activeTab === 3" /> | |||
<OrderDetailWrapper v-if="activeTab === 4" :order="order" :order-detail-configs="configs" /> | |||
</transition> | |||
<!-- footer --> | |||
<div slot="footer" style=""> | |||
<!-- <template v-for="(operate, index) in configs.form.operations"> | |||
<el-button v-if="showButton(operate)" :key="'operation_' + index" :type="operate.type" @click="handleBtnClick(operate)">{{ | |||
operate.label | |||
}}</el-button> | |||
</template> --> | |||
<div slot="footer" style="background: #eee; padding: 10px 20px"> | |||
<el-button @click="handleClose">取消</el-button> | |||
</div> | |||
</el-dialog> | |||
@@ -43,13 +33,13 @@ | |||
<script> | |||
import CarDetail from "./tabs/carDetail.vue"; | |||
import OrderDetail from "./tabs/orderDetail.vue"; | |||
import OrderDetailWrapper from "./tabs/orderDetailWrapper.vue"; | |||
import SubOrderDetail from "./tabs/subOrderDetail.vue"; | |||
import TrayDetail from "./tabs/trayDetail.vue"; | |||
export default { | |||
name: "DialogWithMenu--OrderVersion", | |||
components: { CarDetail, OrderDetail, SubOrderDetail, TrayDetail }, | |||
components: { CarDetail, OrderDetailWrapper, SubOrderDetail, TrayDetail }, | |||
props: { | |||
configs: { | |||
type: Object, | |||
@@ -57,7 +47,7 @@ export default { | |||
}, | |||
fullscreen: { | |||
type: Boolean, | |||
default: false, | |||
default: true, | |||
}, | |||
}, | |||
inject: ["urls"], | |||
@@ -65,26 +55,41 @@ export default { | |||
return { | |||
detailMode: false, | |||
visible: false, | |||
activeTab: "sub", | |||
activeTab: 1, | |||
oldActiveTab: 1, | |||
order: null, | |||
carLayoutKey: 0, | |||
toLeft: true, | |||
orderNotReady: true | |||
}; | |||
}, | |||
mounted() { | |||
document.body.style.overflow = "hidden"; | |||
}, | |||
beforeDestroy() { | |||
document.body.style.overflow = "unset"; | |||
}, | |||
methods: { | |||
handleTabClick(tab, event) { | |||
console.log("handle tab click", tab, event); | |||
switch (tab.label) { | |||
case "子订单进度": | |||
handleTabClick(tab) { | |||
console.log("handle tab click", tab); | |||
if (tab > this.oldActiveTab) this.toLeft = true; | |||
else this.toLeft = false; | |||
switch (tab) { | |||
case 1: | |||
// 子订单进度 | |||
break; | |||
case "窑车详情": | |||
case 2: | |||
// "窑车详情": | |||
this.carLayoutKey = Math.random(); | |||
break; | |||
case "托盘详情": | |||
case 3: | |||
// "托盘详情": | |||
break; | |||
case "订单详情": | |||
case 4: | |||
// "订单详情": | |||
break; | |||
} | |||
this.oldActiveTab = tab; | |||
}, | |||
/** init **/ | |||
@@ -93,10 +98,6 @@ export default { | |||
this.order = order; | |||
this.detailMode = detailMode ?? false; | |||
this.visible = true; | |||
this.$nextTick(() => { | |||
this.$refs["order-detail-tag"].init(this.order.id, this.detailMode); | |||
}); | |||
}, | |||
handleClose() { | |||
@@ -104,8 +105,6 @@ export default { | |||
setTimeout(() => { | |||
this.$emit("destroy-dialog"); | |||
// this.resetForm(); | |||
// this.$emit("update:dialogVisible", false); | |||
}, 200); | |||
}, | |||
}, | |||
@@ -116,12 +115,6 @@ export default { | |||
.dialog-with-menu >>> .el-dialog__body { | |||
padding-top: 40px !important; | |||
padding-bottom: 40px !important; | |||
/* padding-top: 0 !important; | |||
padding-bottom: 0 !important; | |||
padding-left: 0 !important; | |||
padding-right: 0 !important; | |||
height: 100%; */ | |||
} | |||
.el-select, | |||
@@ -130,12 +123,26 @@ export default { | |||
width: 100% !important; | |||
} | |||
.dialog-with-menu >>> .el-dialog { | |||
border-radius: 8px; | |||
display: flex; | |||
flex-direction: column; | |||
} | |||
.dialog-with-menu >>> .el-dialog__header { | |||
padding: 0; | |||
/* background: linear-gradient(to bottom, rgba(0, 0, 0, 0.25), white); */ | |||
} | |||
.dialog-with-menu >>> .el-dialog__body { | |||
height: calc(100% - 72px); | |||
/* height: calc(100% - 72px); */ | |||
height: 1px; | |||
flex: 1; | |||
/* padding-bottom: 10px; */ | |||
overflow-y: auto; | |||
} | |||
.dialog-with-menu >>> .el-dialog__footer { | |||
padding: 0; | |||
} | |||
.dialog-with-menu >>> .el-tabs__content { | |||
@@ -152,4 +159,44 @@ export default { | |||
height: 0; | |||
width: 0; | |||
} | |||
.fade-left-enter { | |||
transform: translateX(10px); | |||
opacity: 0; | |||
} | |||
.fade-left-enter-active, | |||
.fade-left-leave-active { | |||
transition: transform 0.3s ease-out, opacity 0.3s ease-out; | |||
} | |||
.fade-left-enter-to, | |||
.fade-left-leave { | |||
transform: translate(0); | |||
} | |||
.fade-left-leave-to { | |||
transform: translateX(-10px); | |||
opacity: 0; | |||
} | |||
.fade-right-enter { | |||
transform: translateX(-10px); | |||
opacity: 0; | |||
} | |||
.fade-right-leave-to { | |||
transform: translateX(10px); | |||
opacity: 0; | |||
} | |||
.fade-right-enter-active, | |||
.fade-right-leave-active { | |||
transition: transform 0.3s ease-out, opacity 0.3s ease-out; | |||
} | |||
.fade-right-enter-to, | |||
.fade-right-leave { | |||
transform: translateX(0); | |||
} | |||
</style> |
@@ -408,7 +408,6 @@ export default { | |||
openMenuDialog(row, detail) { | |||
this.renderMenuDialog = true; | |||
console.log("this.renderMenuDialog = true;", row, detail); | |||
this.$nextTick(() => { | |||
this.$refs["menu-dialog"].init(/** some args... */ row, detail); | |||
}); | |||
@@ -0,0 +1,44 @@ | |||
<template> | |||
<div class="inputs-area"> | |||
<div class="inputs-area__title">{{ title }}</div> | |||
<div class="inputs-area__main"> | |||
<slot /> | |||
</div> | |||
</div> | |||
</template> | |||
<script> | |||
export default { | |||
name: "InputsArea", | |||
props: { | |||
title: { | |||
type: String, | |||
default: '' | |||
} | |||
}, | |||
}; | |||
</script> | |||
<style scoped> | |||
.inputs-area { | |||
/* background: #ccc3; */ | |||
position: relative; | |||
border: 1px solid #ccc; | |||
margin-bottom: 24px; | |||
} | |||
.inputs-area__title { | |||
position: absolute; | |||
top: -12px; | |||
left: 20px; | |||
padding: 0 12px; | |||
line-height: 24px; | |||
min-width: 12px; | |||
background: white; | |||
user-select: none; | |||
} | |||
.inputs-area__main { | |||
padding: 16px; | |||
} | |||
</style> |
@@ -24,19 +24,27 @@ | |||
:dialog-visible.sync="carPayloadDialogVisible" | |||
:configs="carPayloadDialogConfigs" /> | |||
<!-- @refreshDataList="getList" --> | |||
<TemperatureDialog | |||
ref="temperature-dialog" | |||
v-if="!!temperatureDialogVisible" | |||
:dialog-visible.sync="temperatureDialogVisible" | |||
@refreshDataList="getAList" /> | |||
</div> | |||
</template> | |||
<script> | |||
import BaseListTable from "../BaseListTable.vue"; | |||
import BaseListTable from "@/components/BaseListTable.vue"; | |||
import TableOperaionComponent from "@/components/noTemplateComponents/operationComponent"; | |||
// import StateSelect from '@/components/StateSelect.vue'; | |||
import { timeFilter } from "@/utils/filters"; | |||
import { timeFilter, dictFilter } from "@/utils/filters"; | |||
import TemperatureDialog from "./temperatureDialog.vue"; | |||
import DialogCarPayload from "@/components/DialogCarPayload.vue"; | |||
export default { | |||
name: "CarDetailTag", | |||
components: { BaseListTable, DialogCarPayload }, | |||
components: { BaseListTable, DialogCarPayload, TemperatureDialog }, | |||
props: { | |||
orderId: { | |||
type: String, | |||
@@ -44,8 +52,8 @@ export default { | |||
}, | |||
tableLayout: { | |||
type: Number, | |||
default: 0 | |||
} | |||
default: 0, | |||
}, | |||
}, | |||
data() { | |||
return { | |||
@@ -54,7 +62,7 @@ export default { | |||
{ type: "index", label: "序号" }, | |||
// { prop: "createTime", label: "添加时间", filter: timeFilter }, | |||
{ prop: "code", label: "窑车号" }, | |||
{ prop: "stateDictValue", label: "状态" }, // , subcomponent: StateSelect }, | |||
{ prop: "stateDictValue", label: "状态", filter: dictFilter("car_state") }, // , subcomponent: StateSelect }, | |||
// { prop: "stateDictValue", label: "状态", filter: v => (v !== null && v !== undefined) ? ['没有数据', '正常', '判废', '过渡'][v] : '-' }, // subcomponent | |||
// { prop: "orderCode", label: "订单号" }, | |||
{ prop: "posCode", label: "位置" }, | |||
@@ -67,6 +75,7 @@ export default { | |||
width: 90, | |||
subcomponent: TableOperaionComponent, | |||
options: [ | |||
{ name: "temperature", label: "烧制温度", icon: "odometer", color: '#ff4d00' }, | |||
{ name: "to-car-payload", label: "装载详情", icon: "shopping-cart-full" }, // or el-icon-box | |||
// { name: "delete", label: "删除", icon: "delete", emitFull: true, promptField: "code" }, | |||
], | |||
@@ -99,6 +108,7 @@ export default { | |||
], | |||
}, | |||
}, | |||
temperatureDialogVisible: false, | |||
}; | |||
}, | |||
watch: { | |||
@@ -112,8 +122,8 @@ export default { | |||
immediate: true, | |||
}, | |||
tableLayout() { | |||
this.doLayout() | |||
} | |||
this.doLayout(); | |||
}, | |||
}, | |||
// activated() { | |||
// console.log("hhh"); | |||
@@ -178,10 +188,22 @@ export default { | |||
case "to-car-payload": { | |||
// open dialog instead of redirect to a new page | |||
this.openCarPayloadDialog(data); | |||
break; | |||
} | |||
case "temperature": { | |||
this.openTemperatureDialog(data); | |||
break; | |||
} | |||
} | |||
}, | |||
openTemperatureDialog(id) { | |||
this.temperatureDialogVisible = true; | |||
this.$nextTick(() => { | |||
this.$refs["temperature-dialog"].init(id); | |||
}); | |||
}, | |||
openCarPayloadDialog(id) { | |||
this.carPayloadDialogVisible = true; | |||
this.$nextTick(() => { | |||
@@ -0,0 +1,70 @@ | |||
const colors = { | |||
line: '#555' | |||
} | |||
export default (x_data, y_data) => ({ | |||
title: { | |||
text: "窑车温度", | |||
}, | |||
grid: { | |||
show: true, | |||
top: 96, | |||
left: 52, | |||
right: 32, | |||
bottom: 24, | |||
}, | |||
xAxis: { | |||
type: "category", | |||
data: Array(65) | |||
.fill(1) | |||
.map((val, index) => { | |||
return val + index; | |||
}), | |||
axisLine: { | |||
lineStyle: { | |||
color: colors.line | |||
}, | |||
}, | |||
}, | |||
yAxis: { | |||
type: "value", | |||
name: "温度", | |||
nameTextStyle: { | |||
fontSize: 18, | |||
align: "right", | |||
verticalAlign: "bottom", | |||
lineHeight: 36, | |||
padding: 10, | |||
}, | |||
axisLine: { | |||
show: true, | |||
lineStyle: { | |||
color: colors.line, | |||
}, | |||
}, | |||
axisLabel: { | |||
formatter: '{value} ℃' | |||
}, | |||
splitLine: { | |||
lineStyle: { | |||
color: '#ddd' | |||
} | |||
}, | |||
}, | |||
tooltip: { | |||
trigger: 'axis', | |||
formatter: '<strong style="font-size: 16px">位置</strong> ({b}) <span style="font-size: 16px; font-weight: bold;">{c}</span> ℃' | |||
}, | |||
dataZoom: { | |||
type: 'inside' | |||
}, | |||
series: [ | |||
{ | |||
data: y_data, | |||
// data: Array(65) | |||
// .fill(1) | |||
// .map((val) => Math.floor(Math.random() * 1000)), | |||
type: "line", | |||
}, | |||
], | |||
}) |
@@ -0,0 +1,26 @@ | |||
import { timeFilter } from '@/utils/filters' | |||
export default [ | |||
// { type: 'index', label: '序号' }, | |||
// { prop: "createTime", label: "添加时间", filter: timeFilter }, | |||
// { prop: "stateDictValue", label: "状态", filter: v => (v !== null && v !== undefined) ? ['没有数据', '正常', '判废', '过渡'][v] : '-' }, // subcomponent | |||
// { prop: "stateDictValue", label: "温度", subcomponent: StateSelect }, | |||
{ width: 60, prop: "code", label: "位置" }, | |||
{ width: 60, prop: "temp1", label: "温度" }, | |||
{ width: 80, prop: "press1", label: "窑内压力" }, | |||
{ width: 80, prop: "press2", label: "车下压力" }, | |||
{ prop: "createTime", label: "时间", filter: timeFilter }, | |||
// { prop: "endTime", label: "结束时间", filter: timeFilter }, | |||
// { | |||
// prop: "operations", | |||
// name: "操作", | |||
// fixed: "right", | |||
// width: 150, | |||
// subcomponent: TableOperaionComponent, | |||
// options: [ | |||
// { name: "temperature", label: "烧制温度", }, | |||
// { name: "to-car-payload", label: "装载详情", icon: 'document' }, | |||
// { name: "delete", label: "删除", icon: 'delete', emitFull: true, promptField: 'code' } | |||
// ], | |||
// }, | |||
]; |
@@ -1,47 +1,71 @@ | |||
<template> | |||
<div class="order-detail"> | |||
<el-form ref="dataForm" :model="dataForm" v-loading="loadingStatus" style="padding: 0 40px"> | |||
<el-row v-for="(row, rowIndex) in configs.form.rows" :key="'row_' + rowIndex" :gutter="20"> | |||
<el-col v-for="(col, colIndex) in row" :key="colIndex" :span="24 / row.length" :class="{ h0: col.hidden }"> | |||
<!-- 通过多个 col === null 可以控制更灵活的 span 大小 --> | |||
<el-form-item v-if="col !== null" :label="col.label" :prop="col.prop" :rules="col.rules || null"> | |||
<el-input v-if="col.input" v-model="dataForm[col.prop]" clearable :disabled="detailMode" v-bind="col.elparams" /> | |||
<el-cascader | |||
v-if="col.cascader" | |||
v-model="dataForm[col.prop]" | |||
:options="col.options" | |||
:disabled="detailMode" | |||
v-bind="col.elparams" | |||
></el-cascader> | |||
<el-select v-if="col.select" v-model="dataForm[col.prop]" clearable :disabled="detailMode" v-bind="col.elparams"> | |||
<el-option v-for="(opt, optIdx) in col.options" :key="'option_' + optIdx" :label="opt.label" :value="opt.value" /> | |||
</el-select> | |||
<el-switch | |||
v-if="col.switch" | |||
v-model="dataForm[col.prop]" | |||
:active-value="col.activeValue ?? 1" | |||
:inactive-value="col.activeValue ?? 0" | |||
@change="handleSwitchChange" | |||
:disabled="detailMode" | |||
/> | |||
<el-input v-if="col.textarea" type="textarea" v-model="dataForm[col.prop]" :disabled="detailMode" v-bind="col.elparams" /> | |||
<el-date-picker v-if="col.datetime" v-model="dataForm[col.prop]" :disabled="detailMode" v-bind="col.elparams" /> | |||
<div class="order-detail" style="padding-bottom: 6px;"> | |||
<el-skeleton v-if="loadingStatus" /> | |||
<el-form ref="dataForm" :model="dataForm" v-else size="small" style="padding: 0"> | |||
<!-- <el-form ref="dataForm" :model="dataForm" v-loading="loadingStatus" size="small" style="padding:0 "> --> | |||
<InputsArea v-for="field in configs.form.field" :key="field.title" :title="field.title"> | |||
<el-row v-for="(row, rowIndex) in field.rows" :key="'row_' + rowIndex" :gutter="20"> | |||
<el-col v-for="(col, colIndex) in row" :key="colIndex" :span="24 / row.length" :class="{ h0: col.hidden }"> | |||
<!-- 通过多个 col === null 可以控制更灵活的 span 大小 --> | |||
<el-form-item v-if="col !== null" :label="col.label" :prop="col.prop" :rules="col.rules || null"> | |||
<el-input | |||
v-if="col.input" | |||
v-model="dataForm[col.prop]" | |||
clearable | |||
:disabled="detailMode" | |||
v-bind="col.elparams" /> | |||
<el-cascader | |||
v-if="col.cascader" | |||
v-model="dataForm[col.prop]" | |||
:options="col.options" | |||
:disabled="detailMode" | |||
v-bind="col.elparams"></el-cascader> | |||
<el-select | |||
v-if="col.select" | |||
v-model="dataForm[col.prop]" | |||
clearable | |||
:disabled="detailMode" | |||
v-bind="col.elparams"> | |||
<el-option | |||
v-for="(opt, optIdx) in col.options" | |||
:key="'option_' + optIdx" | |||
:label="opt.label" | |||
:value="opt.value" /> | |||
</el-select> | |||
<el-switch | |||
v-if="col.switch" | |||
v-model="dataForm[col.prop]" | |||
:active-value="col.activeValue ?? 1" | |||
:inactive-value="col.activeValue ?? 0" | |||
@change="handleSwitchChange" | |||
:disabled="detailMode" /> | |||
<el-input | |||
v-if="col.textarea" | |||
type="textarea" | |||
v-model="dataForm[col.prop]" | |||
:disabled="detailMode" | |||
v-bind="col.elparams" /> | |||
<el-date-picker | |||
v-if="col.datetime" | |||
v-model="dataForm[col.prop]" | |||
:disabled="detailMode" | |||
v-bind="col.elparams" /> | |||
<div class="" v-if="col.component" style="margin: 42px 0 0"> | |||
<!-- 下面这个 component 几乎是为 富文本 quill 定制的了... TODO:后续可能会根据业务需求创建新的版本 --> | |||
<component | |||
:is="col.component" | |||
:key="'component_' + col.prop" | |||
@update:modelValue="handleComponentModelUpdate(col.prop, $event)" | |||
:modelValue="dataForm[col.prop] ?? ''" | |||
:mode="detailMode ? 'detail' : dataForm.id ? 'edit' : 'create'" | |||
v-bind="col.bind" | |||
/> | |||
</div> | |||
<!-- add more... --> | |||
</el-form-item> | |||
</el-col> | |||
</el-row> | |||
<div class="" v-if="col.component" style="margin: 32px 0 0"> | |||
<!-- 下面这个 component 几乎是为 富文本 quill 定制的了... TODO:后续可能会根据业务需求创建新的版本 --> | |||
<component | |||
:is="col.component" | |||
:key="'component_' + col.prop" | |||
@update:modelValue="handleComponentModelUpdate(col.prop, $event)" | |||
:modelValue="dataForm[col.prop] ?? ''" | |||
:mode="detailMode ? 'detail' : dataForm.id ? 'edit' : 'create'" | |||
v-bind="col.bind" /> | |||
</div> | |||
<!-- add more... --> | |||
</el-form-item> | |||
</el-col> | |||
</el-row> | |||
</InputsArea> | |||
</el-form> | |||
</div> | |||
</template> | |||
@@ -50,9 +74,11 @@ | |||
// import textOnlyComponent from "@/components/noTemplateComponents/textOnlyComponent.js"; | |||
import moment from "moment"; | |||
import { pick as __pick } from "@/utils/filters"; | |||
import InputsArea from "./InputsArea.vue"; | |||
export default { | |||
name: "OrderDetailTag", | |||
components: { InputsArea }, | |||
props: { | |||
configs: { | |||
type: Object, | |||
@@ -68,45 +94,60 @@ export default { | |||
const watchList = []; | |||
const cachedList = {}; | |||
this.configs.form.rows.forEach((row) => { | |||
row.forEach((col) => { | |||
dataForm[col.prop] = col.default ?? null; | |||
this.configs.form.field.forEach((field) => { | |||
field.rows.forEach((row) => { | |||
row.forEach((col) => { | |||
if (!col.prop) return; | |||
if (col.fetchData) | |||
col.fetchData().then(({ data: res }) => { | |||
if (res.code === 0 && res.data.list) { | |||
if ("injectTo" in col) { | |||
// 保存完整的数据列表 | |||
cachedList[col.prop] = res.data.list; | |||
} | |||
dataForm[col.prop] = col.default ?? null; | |||
this.$set( | |||
col, | |||
"options", | |||
res.data.list.map((i) => ({ | |||
label: col.optionLabel ? i[col.optionLabel] : i.name, | |||
value: col.optionValue ? i[col.optionValue] : i.id, | |||
})) | |||
); | |||
} else { | |||
col.options.splice(0); | |||
} | |||
}); | |||
else if (col.fetchTreeData) { | |||
// 获取设备类型时触发的,用于前端构建属性结构,约定,parentId 为0时是顶级节点 | |||
col.fetchTreeData().then(({ data: res }) => { | |||
// console.log("[DialogJustForm fetchTreeData -->]", res.data); | |||
if (res.code === 0 && res.data) { | |||
if ("list" in res.data) { | |||
this.$set(col, "options", res.data.list); | |||
} else if (Array.isArray(res.data)) { | |||
this.$set(col, "options", res.data); | |||
if (col.fetchData) | |||
col.fetchData().then(({ data: res }) => { | |||
if (res.code === 0) { | |||
if (typeof res.data === "object" && "list" in res.data) { | |||
if ("injectTo" in col) { | |||
// 保存完整的数据列表,用于自动更新关联字段 | |||
cachedList[col.prop] = res.data.list; | |||
} | |||
this.$set( | |||
col, | |||
"options", | |||
res.data.list.map((i) => ({ | |||
label: col.optionLabel ? i[col.optionLabel] : i.name, | |||
value: col.optionValue ? i[col.optionValue] : i.id, | |||
})) | |||
); | |||
} else if (Array.isArray(res.data)) { | |||
this.$set( | |||
col, | |||
"options", | |||
res.data.map((i) => ({ | |||
label: col.optionLabel ? i[col.optionLabel] : i.name, | |||
value: col.optionValue ? i[col.optionValue] : i.id, | |||
})) | |||
); | |||
} | |||
} else { | |||
// error 静默失败 | |||
col.options.splice(0); | |||
} | |||
} else { | |||
col.options.splice(0); | |||
} | |||
}); | |||
} | |||
}); | |||
else if (col.fetchTreeData) { | |||
// 获取设备类型时触发的,用于前端构建属性结构,约定,parentId 为0时是顶级节点 | |||
col.fetchTreeData().then(({ data: res }) => { | |||
// console.log("[DialogJustForm fetchTreeData -->]", res.data); | |||
if (res.code === 0 && res.data) { | |||
if ("list" in res.data) { | |||
this.$set(col, "options", res.data.list); | |||
} else if (Array.isArray(res.data)) { | |||
this.$set(col, "options", res.data); | |||
} | |||
} else { | |||
col.options.splice(0); | |||
} | |||
}); | |||
} | |||
}); | |||
}); | |||
}); | |||
@@ -120,25 +161,30 @@ export default { | |||
}, | |||
mounted() { | |||
/** 处理 injectTo 选项 */ | |||
this.configs.form.rows.forEach((row) => { | |||
row.forEach((col) => { | |||
if ("injectTo" in col && Array.isArray(col.injectTo)) { | |||
col.injectTo.map((item) => { | |||
const unwatch = this.$watch( | |||
() => this.dataForm[col.prop], | |||
(newVal) => { | |||
const chosenObject = this.cachedList[col.prop]?.find((i) => i.id === newVal); | |||
if (chosenObject) { | |||
this.$set(this.dataForm, item[0], chosenObject[item[1]]); | |||
this.configs.form.field.forEach((field) => { | |||
field.rows.forEach((row) => { | |||
row.forEach((col) => { | |||
if (!col.prop) return; | |||
if ("injectTo" in col && Array.isArray(col.injectTo)) { | |||
// console.log("watching options ..... ", col); | |||
col.injectTo.map((item) => { | |||
const unwatch = this.$watch( | |||
() => this.dataForm[col.prop], | |||
(newVal) => { | |||
const chosenObject = this.cachedList[col.prop].find((i) => i.id === newVal); | |||
if (chosenObject) { | |||
// 如果找到了 | |||
this.$set(this.dataForm, item[0], chosenObject[item[1]]); | |||
} | |||
}, | |||
{ | |||
immediate: false, | |||
} | |||
}, | |||
{ | |||
immediate: false, | |||
} | |||
); | |||
this.watchList.push(unwatch); | |||
}); | |||
} | |||
); | |||
this.watchList.push(unwatch); | |||
}); | |||
} | |||
}); | |||
}); | |||
}); | |||
}, | |||
@@ -200,7 +246,9 @@ export default { | |||
const { startTime, endTime } = this.dataForm; | |||
httpPayload = { | |||
...httpPayload, | |||
startTime: startTime ? moment(startTime).format("YYYY-MM-DDTHH:mm:ss") : moment().format("YYYY-MM-DDTHH:mm:ss"), | |||
startTime: startTime | |||
? moment(startTime).format("YYYY-MM-DDTHH:mm:ss") | |||
: moment().format("YYYY-MM-DDTHH:mm:ss"), | |||
endTime: endTime ? moment(endTime).format("YYYY-MM-DDTHH:mm:ss") : moment().format("YYYY-MM-DDTHH:mm:ss"), | |||
}; | |||
} | |||
@@ -288,6 +336,9 @@ export default { | |||
this.$http | |||
.get(this.urls.base + `/${this.dataForm.id}`) | |||
.then(({ data: res }) => { | |||
// 特供 emit | |||
this.$emit("detail-loaded"); | |||
if (res && res.code === 0) { | |||
this.dataForm = __pick(res.data, Object.keys(this.dataForm)); | |||
/** 格式化文件上传列表 */ | |||
@@ -0,0 +1,41 @@ | |||
<template> | |||
<div style="height: 100%;"> | |||
<el-skeleton v-show="orderNotReady" /> | |||
<OrderDetail v-show="!orderNotReady" ref="order-detail-tag" :configs="orderDetailConfigs" @detail-loaded="orderNotReady = false" /> | |||
</div> | |||
</template> | |||
<script> | |||
import OrderDetail from './orderDetail.vue'; | |||
export default { | |||
name: "OrderDetailWrapper", | |||
components: { OrderDetail }, | |||
props: { | |||
orderDetailConfigs: { | |||
type: Object, | |||
default: () => null, | |||
}, | |||
order: { | |||
type: Object, | |||
default: () => null | |||
} | |||
}, | |||
data() { | |||
return { | |||
detailMode: true, | |||
orderNotReady: true | |||
}; | |||
}, | |||
created() { }, | |||
mounted() { | |||
console.log('this.order', this.order) | |||
this.$nextTick(() => { | |||
this.$refs["order-detail-tag"].init(this.order.id, this.detailMode); | |||
}); | |||
}, | |||
methods: {}, | |||
}; | |||
</script> | |||
<style scoped></style> |
@@ -0,0 +1,164 @@ | |||
<template> | |||
<el-dialog | |||
:visible="visible" | |||
title="烧制温度" | |||
class="temperature-dialog" | |||
width="80%" | |||
@close="handleClose" | |||
:append-to-body="true" | |||
:destroy-on-close="false"> | |||
<div class="data-list"> | |||
<BaseListTable | |||
v-loading="tableLoading" | |||
style="height: 85%" | |||
:table-config="{ height: '100%' }" | |||
:column-config="tableConfig" | |||
:table-data="dataList" | |||
@operate-event="handleOperate" | |||
:current-page="page" | |||
:current-size="size" | |||
:refresh-layout-key="refreshLayoutKey" /> | |||
<el-pagination | |||
class="" | |||
style="position: absolute; bottom: 0; left: 50%; transform: translateX(-50%)" | |||
@size-change="handleSizeChange" | |||
@current-change="handlePageChange" | |||
:current-page.sync="page" | |||
:page-sizes="[20, 50, 100]" | |||
:page-size="size" | |||
:total="totalPage" | |||
layout="total, sizes, prev, pager, next, jumper"></el-pagination> | |||
</div> | |||
<div class="temp-chart" style="height: 300px;"> | |||
<div id="temp-chart" class="temp-chart__inner" style="height: 100%;" /> | |||
</div> | |||
</el-dialog> | |||
</template> | |||
<script> | |||
import BaseListTable from "@/components/BaseListTable.vue"; | |||
import loadChartConfig from "./configs/chart"; | |||
import tableConfig from "./configs/tableProps"; | |||
import * as echarts from "echarts"; | |||
export default { | |||
name: "TemperatureDialog", | |||
components: { BaseListTable }, | |||
props: {}, | |||
data() { | |||
return { | |||
visible: false, | |||
hisId: null, | |||
tableConfig, | |||
chart: null, | |||
dataList: [], | |||
page: 1, | |||
size: 100, | |||
tableLoading: false, | |||
refreshLayoutKey: 0, | |||
totalPage: 0, | |||
}; | |||
}, | |||
activated() { | |||
this.refreshLayoutKey = Math.random(); | |||
}, | |||
mounted() {}, | |||
watch: { | |||
dataList: { | |||
handler: function (val) { | |||
this.drawChart(val); | |||
}, | |||
}, | |||
}, | |||
methods: { | |||
init(id) { | |||
this.hisId = id; | |||
this.visible = true; | |||
this.$nextTick(() => { | |||
this.getList(); | |||
}); | |||
}, | |||
getList() { | |||
this.tableLoading = true; | |||
this.$http | |||
.post("/pms/kilnPosHistory/pageView", { | |||
page: this.page, | |||
limit: this.size, | |||
hisId: this.hisId, | |||
}) | |||
.then(({ data: res }) => { | |||
console.log("temp dialog res", res); | |||
this.tableLoading = false; | |||
if (res.code === 0) { | |||
if ("list" in res.data) { | |||
this.dataList = res.data.list; | |||
} else if (Array.isArray(res.data)) { | |||
this.dataList = res.data; | |||
} // else ... | |||
} else { | |||
this.dataList.splice(0); | |||
} | |||
// this.dataList = [ | |||
// { id: 1, code: 1, press1: 1, press2: 1, createTime: "2023-4-21 01:00:00", temp1: 1000 }, | |||
// { id: 2, code: 2, press1: 2, press2: 2, createTime: "2023-4-21 02:00:00", temp1: 2000 }, | |||
// { id: 3, code: 3, press1: 3, press2: 3, createTime: "2023-4-21 03:00:00", temp1: 3000 }, | |||
// { id: 4, code: 4, press1: 4, press2: 4, createTime: "2023-4-21 04:00:00", temp1: 4000 }, | |||
// { id: 5, code: 5, press1: 5, press2: 5, createTime: "2023-4-21 05:00:00", temp1: 5000 }, | |||
// { id: 6, code: 6, press1: 6, press2: 6, createTime: "2023-4-21 06:00:00", temp1: 6000 }, | |||
// { id: 7, code: 7, press1: 7, press2: 7, createTime: "2023-4-21 07:00:00", temp1: 7000 }, | |||
// { id: 8, code: 8, press1: 8, press2: 8, createTime: "2023-4-21 08:00:00", temp1: 8000 }, | |||
// { id: 9, code: 9, press1: 9, press2: 9, createTime: "2023-4-21 09:00:00", temp1: 9000 }, | |||
// { id: 10, code: 10, press1: 10, press2: 10, createTime: "2023-4-21 10:00:00", temp1: 10000 }, | |||
// { id: 11, code: 11, press1: 11, press2: 11, createTime: "2023-4-21 11:00:00", temp1: 11000 }, | |||
// { id: 12, code: 12, press1: 12, press2: 12, createTime: "2023-4-21 12:00:00", temp1: 12000 }, | |||
// ]; | |||
}); | |||
}, | |||
drawChart() { | |||
// 根据 dataList 绘制折线图 | |||
if (!this.chart) this.chart = echarts.init(document.getElementById("temp-chart")); | |||
// const y_data = Array(65).fill(0) | |||
this.chart.setOption(loadChartConfig(null, this.dataList.map(i => i.temp1))); | |||
}, | |||
handleOperate() {}, | |||
handlePageChange(page) { | |||
this.page = page; | |||
this.getList(); | |||
}, | |||
handleSizeChange(size) { | |||
this.size = size; | |||
this.getList(); | |||
}, | |||
handleClose() { | |||
setTimeout(() => { | |||
this.$emit("destroy-dialog"); | |||
}, 300); | |||
this.visible = false; | |||
}, | |||
}, | |||
}; | |||
</script> | |||
<style scoped> | |||
.temperature-dialog >>> .el-dialog__body { | |||
height: 70vh; | |||
display: flex; | |||
} | |||
.data-list, | |||
.temp-chart { | |||
/* border: 1px solid #ccc; */ | |||
width: 35%; | |||
overflow-y: auto; | |||
position: relative; | |||
} | |||
.temp-chart { | |||
flex: 1; | |||
/* margin-left: 18px; */ | |||
padding-left: 10px; | |||
margin-left: 10px; | |||
/* border-left: 1px solid #ccc; */ | |||
/* background-color: lightblue; */ | |||
} | |||
</style> |