Compare commits
No commits in common. "master" and "3.1.2026071608" have entirely different histories.
master
...
3.1.202607
31
changelog.md
31
changelog.md
|
|
@ -1,34 +1,3 @@
|
||||||
## 3.1.2026072315
|
|
||||||
|
|
||||||
- fix: 问题修复
|
|
||||||
- 工艺路线表单残留问题根治:xtSelect外部清空值时同步清空显示文字(残留主因);画布/右侧新增弹框加key每次打开强制重建实例;route_form编辑时sort不再被count+1覆盖;无routeId不再全量拉辅料 [caoqianming]
|
|
||||||
## 3.1.2026072314
|
|
||||||
|
|
||||||
- fix: 问题修复
|
|
||||||
- 弹框表单残留上次内容问题一批:route_form open时主动resetForm不再依赖父级v-if销毁(关闭动画期间重开复用实例致残留);riskpoint新增未重置saveForm且RiskForm常驻挂载补destroy-on-close;algo页弹框v-model改v-if与algo2对齐;mroom/plat_record新增未重置表单 [caoqianming]
|
|
||||||
- 工作流配置四页(字段/工作流/流转/状态)新增弹框未重置表单,先编辑再新增会残留上一条内容;默认值提为defaultForm常量供data与新增共用 [caoqianming]
|
|
||||||
- 禅道458 [shijing]
|
|
||||||
- 陶瓷日志中设备为可选 [shijing]
|
|
||||||
## 3.1.2026072309
|
|
||||||
|
|
||||||
- feat: 新增功能
|
|
||||||
- 工艺画布scFlow更名xtFlow;工艺包产品常驻画布为终点节点可直接连线;节点按物料真实类型着色;fix:拖线新增setData覆盖params_json致排一次棒表单报错;perf:vue-flow分包prefetch预取+查看器合并重复布局;style:route_show查看页卡片化紧凑布局 [caoqianming]
|
|
||||||
- 物料表单新增入库检验方式,入库明细未检免检物料显示免检标识;fix:其他配置页提交未实现导致保存无效 [caoqianming]
|
|
||||||
- 工艺路线新增可视化流程编辑器scFlowEditor(Vue Flow+dagre异步分包); 编辑工艺抽屉压缩布局留白 [caoqianming]
|
|
||||||
- 禅道444扭转工序,快速报工,扫码框后面加数字识别功能 [shijing]
|
|
||||||
- 禅道446深加工统计里加工装tab页面 [shijing]
|
|
||||||
- 销售发货批次选择隐藏可发数量为0的批次 [caoqianming]
|
|
||||||
- 合格B类字段文案改为记为合格更准确表达 [caoqianming]
|
|
||||||
- fix: 问题修复
|
|
||||||
- 抽屉内打开的el-dialog统一加append-to-body(24文件28处),避免被pages.scss抽屉工作流表单样式误伤成卡片/灰底/底部留白 [caoqianming]
|
|
||||||
- 抽屉内el-main/el-aside恢复nopadding约定优先级; route_form弹窗加append-to-body避免被抽屉工作流表单样式误伤成卡片 [caoqianming]
|
|
||||||
- 分检加人员筛选不生效修改 [shijing]
|
|
||||||
- table下的tr补上tbody包裹,消除vue3.5模板编译的HTML嵌套规范警告 [caoqianming]
|
|
||||||
- scScanner内置扫码枪输入框改为opt-in(默认隐藏),消除与调用页自有输入框重复 [caoqianming]
|
|
||||||
- 禅道452综合查询界面棒数据未显示发货数 [shijing]
|
|
||||||
- 禅道452综合查询界面棒数据未显示发货数 [shijing]
|
|
||||||
- 禅道452综合查询界面棒数据未显示发货数 [shijing]
|
|
||||||
- 出入库记录及明细表单新增时清空,避免上次保存数据残留导致"物料找不到" [caoqianming]
|
|
||||||
## 3.1.2026071608
|
## 3.1.2026071608
|
||||||
|
|
||||||
- feat: 新增功能
|
- feat: 新增功能
|
||||||
|
|
|
||||||
28
package.json
28
package.json
|
|
@ -7,14 +7,11 @@
|
||||||
"build": "vue-cli-service build --report"
|
"build": "vue-cli-service build --report"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@element-plus/icons-vue": "^2.3.2",
|
"@element-plus/icons-vue": "2.0.10",
|
||||||
"@kjgl77/datav-vue3": "^1.7.1",
|
"@kjgl77/datav-vue3": "^1.7.1",
|
||||||
"@tinymce/tinymce-vue": "5.0.0",
|
"@tinymce/tinymce-vue": "5.0.0",
|
||||||
"@vue-flow/background": "^1.3.2",
|
|
||||||
"@vue-flow/controls": "^1.1.3",
|
|
||||||
"@vue-flow/core": "^1.48.2",
|
|
||||||
"animate.css": "^4.1.1",
|
"animate.css": "^4.1.1",
|
||||||
"axios": "^1.18.1",
|
"axios": "1.3.4",
|
||||||
"babylonjs": "^6.46.0",
|
"babylonjs": "^6.46.0",
|
||||||
"babylonjs-gui": "^6.46.0",
|
"babylonjs-gui": "^6.46.0",
|
||||||
"babylonjs-loaders": "^6.46.0",
|
"babylonjs-loaders": "^6.46.0",
|
||||||
|
|
@ -22,27 +19,26 @@
|
||||||
"codemirror": "^5.65.17",
|
"codemirror": "^5.65.17",
|
||||||
"codemirror-editor-vue3": "^2.7.0",
|
"codemirror-editor-vue3": "^2.7.0",
|
||||||
"copy-webpack-plugin": "^12.0.2",
|
"copy-webpack-plugin": "^12.0.2",
|
||||||
"core-js": "^3.49.0",
|
"core-js": "3.29.0",
|
||||||
"cropperjs": "1.5.13",
|
"cropperjs": "1.5.13",
|
||||||
"crypto-browserify": "^3.12.0",
|
"crypto-browserify": "^3.12.0",
|
||||||
"crypto-js": "^4.2.0",
|
"crypto-js": "4.1.1",
|
||||||
"d3": "^7.6.1",
|
"d3": "^7.6.1",
|
||||||
"dagre": "^0.8.5",
|
|
||||||
"dagre-d3": "^0.6.4",
|
"dagre-d3": "^0.6.4",
|
||||||
"dhtmlx-gantt": "^8.0.6",
|
"dhtmlx-gantt": "^8.0.6",
|
||||||
"echarts": "^5.5.1",
|
"echarts": "^5.5.1",
|
||||||
"element-plus": "^2.14.3",
|
"element-plus": "^2.8.4",
|
||||||
"html2canvas": "^1.4.1",
|
"html2canvas": "^1.4.1",
|
||||||
"json-editor-vue3": "^1.0.6",
|
"json-editor-vue3": "^1.0.6",
|
||||||
"jspdf": "^2.5.1",
|
"jspdf": "^2.5.1",
|
||||||
"node-polyfill-webpack-plugin": "^4.0.0",
|
"node-polyfill-webpack-plugin": "^4.0.0",
|
||||||
"nprogress": "0.2.0",
|
"nprogress": "0.2.0",
|
||||||
"qrcodejs2": "0.0.2",
|
"qrcodejs2": "0.0.2",
|
||||||
"sortablejs": "^1.15.7",
|
"sortablejs": "1.15.0",
|
||||||
"tinymce": "6.3.2",
|
"tinymce": "6.3.2",
|
||||||
"vue": "^3.5.40",
|
"vue": "3.2.47",
|
||||||
"vue-i18n": "^11.4.7",
|
"vue-i18n": "9.2.2",
|
||||||
"vue-router": "^4.6.4",
|
"vue-router": "4.1.6",
|
||||||
"vuedraggable": "4.0.3",
|
"vuedraggable": "4.0.3",
|
||||||
"vuex": "4.1.0",
|
"vuex": "4.1.0",
|
||||||
"xgplayer": "2.32.2",
|
"xgplayer": "2.32.2",
|
||||||
|
|
@ -52,9 +48,9 @@
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "7.21.00",
|
"@babel/core": "7.21.00",
|
||||||
"@vue/cli-plugin-babel": "^5.0.9",
|
"@vue/cli-plugin-babel": "5.0.8",
|
||||||
"@vue/cli-service": "^5.0.9",
|
"@vue/cli-service": "5.0.8",
|
||||||
"sass": "^1.101.0",
|
"sass": "1.58.3",
|
||||||
"sass-loader": "10.1.1"
|
"sass-loader": "10.1.1"
|
||||||
},
|
},
|
||||||
"browserslist": [
|
"browserslist": [
|
||||||
|
|
|
||||||
|
|
@ -516,12 +516,6 @@ export default {
|
||||||
return await http.get(`${config.API_URL}/mtm/routepack/${id}/final_materials/`);
|
return await http.get(`${config.API_URL}/mtm/routepack/${id}/final_materials/`);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
validate: {
|
|
||||||
name: "校验工艺图",
|
|
||||||
req: async function (id) {
|
|
||||||
return await http.get(`${config.API_URL}/mtm/routepack/${id}/validate/`);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
update: {
|
update: {
|
||||||
name: "更新",
|
name: "更新",
|
||||||
req: async function (id, data) {
|
req: async function (id, data) {
|
||||||
|
|
|
||||||
|
|
@ -1,106 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="mnode" :class="'mnode--' + (data.kind || 'mid')">
|
|
||||||
<Handle type="target" :position="Position.Top" class="mnode__handle" />
|
|
||||||
<span class="mnode__tag">{{ kindLabel }}</span>
|
|
||||||
<div class="mnode__name" :title="data.label">{{ data.label }}</div>
|
|
||||||
<Handle type="source" :position="Position.Bottom" class="mnode__handle" />
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { Handle, Position } from "@vue-flow/core";
|
|
||||||
|
|
||||||
// 物料节点卡片:xtFlowEditor(编辑)与 xtFlowViewer(查看)共用,保证两端视觉一致
|
|
||||||
export default {
|
|
||||||
name: "MaterialNode",
|
|
||||||
components: { Handle },
|
|
||||||
props: {
|
|
||||||
// { label, kind: raw|mid|final }
|
|
||||||
data: { type: Object, default: () => ({}) },
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return { Position };
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
kindLabel() {
|
|
||||||
return { raw: "原料", final: "成品", mid: "半成品" }[this.data.kind] || "半成品";
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.mnode {
|
|
||||||
position: relative;
|
|
||||||
width: 150px;
|
|
||||||
padding: 6px 10px 8px;
|
|
||||||
border-radius: 8px;
|
|
||||||
border: 1px solid #dcdfe6;
|
|
||||||
background: #fff;
|
|
||||||
box-shadow: 0 2px 8px rgba(31, 45, 61, 0.08);
|
|
||||||
text-align: center;
|
|
||||||
transition: box-shadow 0.15s, transform 0.15s;
|
|
||||||
}
|
|
||||||
.mnode:hover {
|
|
||||||
box-shadow: 0 4px 14px rgba(31, 45, 61, 0.16);
|
|
||||||
transform: translateY(-1px);
|
|
||||||
}
|
|
||||||
.mnode__tag {
|
|
||||||
display: inline-block;
|
|
||||||
font-size: 11px;
|
|
||||||
line-height: 1;
|
|
||||||
padding: 2px 6px;
|
|
||||||
border-radius: 8px;
|
|
||||||
margin-bottom: 5px;
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
.mnode__name {
|
|
||||||
font-size: 12px;
|
|
||||||
line-height: 1.3;
|
|
||||||
color: #303133;
|
|
||||||
word-break: break-all;
|
|
||||||
display: -webkit-box;
|
|
||||||
-webkit-line-clamp: 2;
|
|
||||||
-webkit-box-orient: vertical;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
.mnode--raw {
|
|
||||||
border-color: #f0c78a;
|
|
||||||
background: #fffaf2;
|
|
||||||
}
|
|
||||||
.mnode--raw .mnode__tag {
|
|
||||||
background: #e6a23c;
|
|
||||||
}
|
|
||||||
.mnode--mid {
|
|
||||||
border-color: #a3d0ff;
|
|
||||||
background: #f5faff;
|
|
||||||
}
|
|
||||||
.mnode--mid .mnode__tag {
|
|
||||||
background: #409eff;
|
|
||||||
}
|
|
||||||
.mnode--final {
|
|
||||||
border-color: #a4da89;
|
|
||||||
background: #f6fcf1;
|
|
||||||
}
|
|
||||||
.mnode--final .mnode__tag {
|
|
||||||
background: #67c23a;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
/* Vue Flow 内部元素(非 scoped) */
|
|
||||||
.vue-flow__node-material {
|
|
||||||
background: transparent;
|
|
||||||
border: none;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
.vue-flow__handle {
|
|
||||||
width: 9px;
|
|
||||||
height: 9px;
|
|
||||||
background: #fff;
|
|
||||||
border: 2px solid #409eff;
|
|
||||||
}
|
|
||||||
.vue-flow__handle:hover {
|
|
||||||
background: #409eff;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
||||||
import dagre from "dagre";
|
|
||||||
|
|
||||||
export const NODE_W = 150;
|
|
||||||
export const NODE_H = 54;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* dagre 自动布局,返回带 position 的 nodes
|
|
||||||
* @param {Array} nodes Vue Flow 节点(id 必须为字符串)
|
|
||||||
* @param {Array} edges Vue Flow 边
|
|
||||||
* @param {Object} opts { rankdir: TB|BT|LR|RL, nodeW, nodeH }
|
|
||||||
*/
|
|
||||||
export function layoutGraph(nodes, edges, opts = {}) {
|
|
||||||
const { rankdir = "TB", nodeW = NODE_W, nodeH = NODE_H } = opts;
|
|
||||||
const g = new dagre.graphlib.Graph();
|
|
||||||
g.setGraph({ rankdir, nodesep: 30, ranksep: 56, marginx: 20, marginy: 20 });
|
|
||||||
g.setDefaultEdgeLabel(() => ({}));
|
|
||||||
nodes.forEach((n) => g.setNode(n.id, { width: nodeW, height: nodeH }));
|
|
||||||
edges.forEach((e) => g.setEdge(e.source, e.target));
|
|
||||||
dagre.layout(g);
|
|
||||||
return nodes.map((n) => {
|
|
||||||
const gn = g.node(n.id);
|
|
||||||
return { ...n, position: { x: gn.x - nodeW / 2, y: gn.y - nodeH / 2 } };
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<el-dialog append-to-body
|
<el-dialog
|
||||||
title="绑定定位卡"
|
title="绑定定位卡"
|
||||||
destroy-on-close
|
destroy-on-close
|
||||||
v-model="pageShow"
|
v-model="pageShow"
|
||||||
|
|
|
||||||
|
|
@ -155,7 +155,6 @@
|
||||||
</el-card>
|
</el-card>
|
||||||
<p class="tables-title">作业人员</p>
|
<p class="tables-title">作业人员</p>
|
||||||
<table class="tables" cellspacing="0">
|
<table class="tables" cellspacing="0">
|
||||||
<tbody>
|
|
||||||
<tr class="tableTh tableThS">
|
<tr class="tableTh tableThS">
|
||||||
<td class="tableTd">序号</td>
|
<td class="tableTd">序号</td>
|
||||||
<td class="tableTd" style="width:100px">姓名</td>
|
<td class="tableTd" style="width:100px">姓名</td>
|
||||||
|
|
@ -173,11 +172,9 @@
|
||||||
</td>
|
</td>
|
||||||
<td class="tableTd" style="width:180px">{{ item.create_time }}</td>
|
<td class="tableTd" style="width:180px">{{ item.create_time }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
|
||||||
</table>
|
</table>
|
||||||
<p class="tables-title">气体检测记录</p>
|
<p class="tables-title">气体检测记录</p>
|
||||||
<table class="tables" cellspacing="0">
|
<table class="tables" cellspacing="0">
|
||||||
<tbody>
|
|
||||||
<tr class="tableTh tableThS">
|
<tr class="tableTh tableThS">
|
||||||
<td class="tableTd">序号</td>
|
<td class="tableTd">序号</td>
|
||||||
<td class="tableTd">检测部位</td>
|
<td class="tableTd">检测部位</td>
|
||||||
|
|
@ -201,11 +198,9 @@
|
||||||
<td class="tableTd">{{ item.check_time }}</td>
|
<td class="tableTd">{{ item.check_time }}</td>
|
||||||
<td class="tableTd">{{ item.create_time }}</td>
|
<td class="tableTd">{{ item.create_time }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
|
||||||
</table>
|
</table>
|
||||||
<p class="tables-title">处理日志</p>
|
<p class="tables-title">处理日志</p>
|
||||||
<table class="tables" cellspacing="0">
|
<table class="tables" cellspacing="0">
|
||||||
<tbody>
|
|
||||||
<tr class="tableTh">
|
<tr class="tableTh">
|
||||||
<td class="tableTd">进行状态</td>
|
<td class="tableTd">进行状态</td>
|
||||||
<td class="tableTd attributeTd">操作类型</td>
|
<td class="tableTd attributeTd">操作类型</td>
|
||||||
|
|
@ -233,7 +228,6 @@
|
||||||
</td>
|
</td>
|
||||||
<td class="tableTd" v-if="item.participant_str==null">{{ item.update_time }}</td>
|
<td class="tableTd" v-if="item.participant_str==null">{{ item.update_time }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,7 @@
|
||||||
<template>
|
<template>
|
||||||
<span class="sc-scanner" style="display:inline-flex;align-items:center;gap:4px;vertical-align:middle;">
|
<span class="sc-scanner" style="display:inline-flex;align-items:center;gap:4px;vertical-align:middle;">
|
||||||
<!-- 扫码枪(蓝牙/USB HID):聚焦后扫码即输入,回车触发。平板蓝牙枪、PC USB枪都走这里 -->
|
<!-- 扫码枪(蓝牙/USB HID):聚焦后扫码即输入,回车触发。平板蓝牙枪、PC USB枪都走这里 -->
|
||||||
<!-- 默认隐藏:多数调用页已自带扫码输入框,避免重复;需集中式扫码框时传 :showInput="true" -->
|
|
||||||
<el-input
|
<el-input
|
||||||
v-if="showInput"
|
|
||||||
ref="gunInput"
|
ref="gunInput"
|
||||||
v-model="gunValue"
|
v-model="gunValue"
|
||||||
:placeholder="placeholder"
|
:placeholder="placeholder"
|
||||||
|
|
@ -23,9 +21,6 @@ export default {
|
||||||
labeltext: { type: String, default: "扫码" },
|
labeltext: { type: String, default: "扫码" },
|
||||||
placeholder: { type: String, default: "扫码枪扫描" },
|
placeholder: { type: String, default: "扫码枪扫描" },
|
||||||
gunWidth: { type: String, default: "180px" },
|
gunWidth: { type: String, default: "180px" },
|
||||||
// 是否显示组件自带的扫码枪输入框。默认 false:调用页通常已有自己的扫码输入框,
|
|
||||||
// 显示会重复;需要 scScanner 作为独立集中式扫码入口时传 true。
|
|
||||||
showInput: { type: Boolean, default: false },
|
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
|
|
||||||
|
|
@ -9,13 +9,11 @@
|
||||||
@mouseout="mouseOut"
|
@mouseout="mouseOut"
|
||||||
>
|
>
|
||||||
<table class="totall">
|
<table class="totall">
|
||||||
<tbody>
|
|
||||||
<tr class="title">
|
<tr class="title">
|
||||||
<th v-for="itemx in titleData" :key="itemx">
|
<th v-for="itemx in titleData" :key="itemx">
|
||||||
{{ itemx }}
|
{{ itemx }}
|
||||||
</th>
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
|
||||||
</table>
|
</table>
|
||||||
<div
|
<div
|
||||||
:id="refValue"
|
:id="refValue"
|
||||||
|
|
@ -24,7 +22,6 @@
|
||||||
>
|
>
|
||||||
<div :id="'scrollBody' + refValue">
|
<div :id="'scrollBody' + refValue">
|
||||||
<table :class="{ marquee_top: animate }">
|
<table :class="{ marquee_top: animate }">
|
||||||
<tbody>
|
|
||||||
<tr
|
<tr
|
||||||
v-for="(itemy, index) in rowData"
|
v-for="(itemy, index) in rowData"
|
||||||
class="rollData"
|
class="rollData"
|
||||||
|
|
@ -50,13 +47,11 @@
|
||||||
<span v-else>{{ itemz.value }}</span>
|
<span v-else>{{ itemz.value }}</span>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
|
||||||
</table>
|
</table>
|
||||||
<table
|
<table
|
||||||
:class="{ marquee_top: animate }"
|
:class="{ marquee_top: animate }"
|
||||||
v-show="scrollVivible"
|
v-show="scrollVivible"
|
||||||
>
|
>
|
||||||
<tbody>
|
|
||||||
<tr
|
<tr
|
||||||
v-for="(itemy, index) in rowData"
|
v-for="(itemy, index) in rowData"
|
||||||
class="rollData"
|
class="rollData"
|
||||||
|
|
@ -86,7 +81,6 @@
|
||||||
<span v-else>{{ itemz.value }}</span>
|
<span v-else>{{ itemz.value }}</span>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,717 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="flow-editor" v-loading="loading">
|
|
||||||
<!-- 顶部工具栏 -->
|
|
||||||
<div class="flow-toolbar">
|
|
||||||
<div class="flow-toolbar__left">
|
|
||||||
<el-button v-if="!readonly" type="primary" icon="el-icon-plus" size="small" round @click="addStep">新增工序</el-button>
|
|
||||||
<el-button icon="el-icon-magic-stick" size="small" round @click="relayout">自动布局</el-button>
|
|
||||||
<el-button icon="el-icon-full-screen" size="small" round @click="doFit">适应画布</el-button>
|
|
||||||
<el-button icon="el-icon-circle-check" size="small" round @click="doValidate" :loading="validating">校验</el-button>
|
|
||||||
</div>
|
|
||||||
<div class="flow-legend">
|
|
||||||
<span class="lg lg--raw">原料</span>
|
|
||||||
<span class="lg lg--mid">半成品</span>
|
|
||||||
<span class="lg lg--final">成品</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="flow-tip" v-if="!readonly">
|
|
||||||
从左侧拖入原料作为起点 → 节点间拉线新建工序,拉到空白处自动生成半成品,连到产品节点收尾;单击线条编辑,右键线条删工序 / 右键节点移除物料
|
|
||||||
</div>
|
|
||||||
<div class="flow-tip flow-tip--ro" v-else>当前状态不可编辑(仅创建中的工艺可编辑)</div>
|
|
||||||
|
|
||||||
<div class="flow-body">
|
|
||||||
<!-- 左侧物料面板:拖入画布作为节点 -->
|
|
||||||
<div class="flow-palette" v-if="!readonly">
|
|
||||||
<div class="palette-head">
|
|
||||||
<div class="palette-title">物料库</div>
|
|
||||||
<el-select v-model="matType" size="small" @change="loadMaterials" style="width: 100%">
|
|
||||||
<el-option label="主要原料" value="30"></el-option>
|
|
||||||
<el-option label="成品" value="10"></el-option>
|
|
||||||
<el-option label="半成品" value="20"></el-option>
|
|
||||||
</el-select>
|
|
||||||
<el-input
|
|
||||||
v-model="matKeyword"
|
|
||||||
size="small"
|
|
||||||
clearable
|
|
||||||
prefix-icon="el-icon-search"
|
|
||||||
placeholder="搜索物料"
|
|
||||||
style="margin-top: 6px"
|
|
||||||
></el-input>
|
|
||||||
</div>
|
|
||||||
<div class="palette-list" v-loading="matLoading">
|
|
||||||
<div
|
|
||||||
v-for="m in filteredMaterials"
|
|
||||||
:key="m.id"
|
|
||||||
class="palette-item"
|
|
||||||
:draggable="true"
|
|
||||||
@dragstart="onDragStart($event, m)"
|
|
||||||
:title="m.full_name"
|
|
||||||
>
|
|
||||||
<i class="el-icon-rank palette-item__grip"></i>
|
|
||||||
<span class="palette-item__txt">{{ m.full_name }}</span>
|
|
||||||
</div>
|
|
||||||
<div v-if="!matLoading && filteredMaterials.length === 0" class="palette-empty">无匹配物料</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 画布 -->
|
|
||||||
<div class="flow-canvas" @drop="onDrop" @dragover.prevent>
|
|
||||||
<VueFlow
|
|
||||||
:id="flowId"
|
|
||||||
:default-viewport="{ zoom: 0.9 }"
|
|
||||||
:min-zoom="0.2"
|
|
||||||
:max-zoom="2"
|
|
||||||
:connection-radius="8"
|
|
||||||
:connect-on-click="false"
|
|
||||||
:nodes-draggable="true"
|
|
||||||
:nodes-connectable="!readonly"
|
|
||||||
:elements-selectable="true"
|
|
||||||
@nodes-initialized="onNodesInit"
|
|
||||||
@connect-start="onConnectStart"
|
|
||||||
@connect="onConnect"
|
|
||||||
@connect-end="onConnectEnd"
|
|
||||||
@edge-click="onEdgeClick"
|
|
||||||
@edge-context-menu="onEdgeContextMenu"
|
|
||||||
@node-context-menu="onNodeContextMenu"
|
|
||||||
>
|
|
||||||
<!-- 自定义物料节点(与 xtFlowViewer 共用) -->
|
|
||||||
<template #node-material="{ data }">
|
|
||||||
<material-node :data="data" />
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<Background :gap="18" pattern-color="#e6e9ef" />
|
|
||||||
<Controls :show-interactive="false" />
|
|
||||||
</VueFlow>
|
|
||||||
<div v-if="!loading && nodes.length === 0" class="flow-empty">
|
|
||||||
<i class="el-icon-position flow-empty__icon"></i>
|
|
||||||
<div>从左侧把「原料」拖到这里开始搭建工艺路线</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 复用现有单步表单:新增/编辑一条 Route;key 随每次打开递增强制重建实例,预填走 prop 在挂载时即确定 -->
|
|
||||||
<route-form
|
|
||||||
v-if="dialogVisible"
|
|
||||||
:key="dialogSeq"
|
|
||||||
ref="routeForm"
|
|
||||||
:count="count"
|
|
||||||
:routepack="routepack"
|
|
||||||
:prefill="formPrefill"
|
|
||||||
@success="onFormSuccess"
|
|
||||||
@closed="dialogVisible = false"
|
|
||||||
></route-form>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { VueFlow, useVueFlow } from "@vue-flow/core";
|
|
||||||
import { Background } from "@vue-flow/background";
|
|
||||||
import { Controls } from "@vue-flow/controls";
|
|
||||||
import routeForm from "@/views/mtm/route_form.vue";
|
|
||||||
import MaterialNode from "./flow/MaterialNode.vue";
|
|
||||||
import { layoutGraph } from "./flow/dagreLayout";
|
|
||||||
import "@vue-flow/core/dist/style.css";
|
|
||||||
import "@vue-flow/core/dist/theme-default.css";
|
|
||||||
import "@vue-flow/controls/dist/style.css";
|
|
||||||
|
|
||||||
// 每个编辑器实例分配唯一 flowId,避免 Vue Flow 全局 store 按固定 id 缓存导致跨次残留
|
|
||||||
let flowSeq = 0;
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "xtFlowEditor",
|
|
||||||
components: { VueFlow, Background, Controls, routeForm, MaterialNode },
|
|
||||||
props: {
|
|
||||||
// 工艺包 id
|
|
||||||
routepack: { type: String, default: "" },
|
|
||||||
// 工艺包产品:常驻画布作为终点节点,可从其他节点拉线连入
|
|
||||||
productId: { type: [String, Number], default: "" },
|
|
||||||
productName: { type: String, default: "" },
|
|
||||||
// 是否只读(非“创建中”状态)
|
|
||||||
readonly: { type: Boolean, default: false },
|
|
||||||
},
|
|
||||||
emits: ["changed"],
|
|
||||||
setup() {
|
|
||||||
const flowId = "route-flow-editor-" + ++flowSeq;
|
|
||||||
const { fitView, screenToFlowCoordinate, project, setNodes, setEdges, addNodes, removeNodes } =
|
|
||||||
useVueFlow(flowId);
|
|
||||||
return { flowId, fitView, screenToFlowCoordinate, project, setNodes, setEdges, addNodes, removeNodes };
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
loading: false,
|
|
||||||
validating: false,
|
|
||||||
routes: [],
|
|
||||||
nodes: [],
|
|
||||||
edges: [],
|
|
||||||
count: 0,
|
|
||||||
dialogVisible: false,
|
|
||||||
dialogSeq: 0,
|
|
||||||
formPrefill: null,
|
|
||||||
// 左侧物料面板
|
|
||||||
matType: "30",
|
|
||||||
matKeyword: "",
|
|
||||||
materials: [],
|
|
||||||
matLoading: false,
|
|
||||||
// 客户端临时种子节点(尚未挂到任何 Route 上)
|
|
||||||
seedNodes: [],
|
|
||||||
// 连线手势内部状态
|
|
||||||
connectSource: null,
|
|
||||||
connectMade: false,
|
|
||||||
connectStartPos: null,
|
|
||||||
// 仅初次加载自动适配一次,避免编辑时视图跳动
|
|
||||||
hasFitted: false,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
filteredMaterials() {
|
|
||||||
const kw = (this.matKeyword || "").trim().toLowerCase();
|
|
||||||
if (!kw) return this.materials;
|
|
||||||
return this.materials.filter((m) => (m.full_name || "").toLowerCase().includes(kw));
|
|
||||||
},
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
routepack() {
|
|
||||||
this.reload();
|
|
||||||
},
|
|
||||||
productId() {
|
|
||||||
if (this.routepack) this.reload();
|
|
||||||
},
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
this.loadMaterials();
|
|
||||||
if (this.routepack) this.reload();
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
/** 加载左侧物料面板列表 */
|
|
||||||
loadMaterials() {
|
|
||||||
this.matLoading = true;
|
|
||||||
this.$API.mtm.material.list
|
|
||||||
.req({ page: 0, type__in: this.matType, is_hidden: false, query: "{full_name,id}" })
|
|
||||||
.then((res) => {
|
|
||||||
this.materials = Array.isArray(res) ? res : res.results || [];
|
|
||||||
})
|
|
||||||
.finally(() => {
|
|
||||||
this.matLoading = false;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
/** 重新拉取路线并重建图 */
|
|
||||||
reload() {
|
|
||||||
if (!this.routepack) return;
|
|
||||||
this.loading = true;
|
|
||||||
this.$API.mtm.route.list
|
|
||||||
.req({ page: 0, routepack: this.routepack })
|
|
||||||
.then((res) => {
|
|
||||||
this.routes = Array.isArray(res) ? res : res.results || [];
|
|
||||||
this.count = this.routes.length;
|
|
||||||
this.buildGraph();
|
|
||||||
})
|
|
||||||
.finally(() => {
|
|
||||||
this.loading = false;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
/** 物料真实类型 → 节点配色:10成品 30原料 其余半成品 */
|
|
||||||
kindOfType(t) {
|
|
||||||
const s = String(t);
|
|
||||||
if (s === "10") return "final";
|
|
||||||
if (s === "30") return "raw";
|
|
||||||
return "mid";
|
|
||||||
},
|
|
||||||
|
|
||||||
/** 拓扑推断兜底(后端未返回物料类型时用):起点原料 / 终点成品 / 中间半成品 */
|
|
||||||
kindOf(id, targetIds) {
|
|
||||||
const isSrc = this.routes.some((r) => String(r.material_in) === id);
|
|
||||||
const isTgt = targetIds.has(id);
|
|
||||||
if (isTgt && !isSrc) return "final";
|
|
||||||
if (!isTgt && isSrc) return "raw";
|
|
||||||
return "mid";
|
|
||||||
},
|
|
||||||
|
|
||||||
/** 由 routes 构建 物料节点 + 工序边,并用 dagre 自动布局;合并未落库的种子节点 */
|
|
||||||
buildGraph() {
|
|
||||||
const matMap = {};
|
|
||||||
const matKind = {};
|
|
||||||
const targetIds = new Set();
|
|
||||||
const edges = [];
|
|
||||||
|
|
||||||
this.routes.forEach((r) => {
|
|
||||||
if (r.material_in == null || r.material_out == null) return;
|
|
||||||
const sid = String(r.material_in);
|
|
||||||
const tid = String(r.material_out);
|
|
||||||
if (!matMap[sid]) matMap[sid] = r.material_in_name || sid;
|
|
||||||
if (!matMap[tid]) matMap[tid] = r.material_out_name || tid;
|
|
||||||
if (r.material_in_type != null) matKind[sid] = this.kindOfType(r.material_in_type);
|
|
||||||
if (r.material_out_type != null) matKind[tid] = this.kindOfType(r.material_out_type);
|
|
||||||
targetIds.add(tid);
|
|
||||||
|
|
||||||
const locked = !!r.from_route;
|
|
||||||
edges.push({
|
|
||||||
id: String(r.id),
|
|
||||||
source: sid,
|
|
||||||
target: tid,
|
|
||||||
label: (r.process_name || "") + (locked ? " 🔒" : ""),
|
|
||||||
data: { route: r, locked },
|
|
||||||
type: "smoothstep",
|
|
||||||
markerEnd: "arrowclosed",
|
|
||||||
style: {
|
|
||||||
stroke: locked ? "#c0c4cc" : "#409eff",
|
|
||||||
strokeWidth: locked ? 1.5 : 2,
|
|
||||||
strokeDasharray: locked ? "5 4" : undefined,
|
|
||||||
},
|
|
||||||
labelStyle: { fill: "#5b6370", fontSize: "12px", fontWeight: 500 },
|
|
||||||
labelBgStyle: { fill: "#ffffff", stroke: "#e4e7ed", strokeWidth: 1 },
|
|
||||||
labelBgPadding: [7, 4],
|
|
||||||
labelBgBorderRadius: 6,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
const routeNodes = Object.keys(matMap).map((id) => ({
|
|
||||||
id,
|
|
||||||
type: "material",
|
|
||||||
data: { label: matMap[id], kind: matKind[id] || this.kindOf(id, targetIds) },
|
|
||||||
position: { x: 0, y: 0 },
|
|
||||||
}));
|
|
||||||
|
|
||||||
// 工艺包产品常驻画布作为终点节点(尚未被任何工序引用时也显示)
|
|
||||||
const pid = this.productId ? String(this.productId) : "";
|
|
||||||
if (pid && !matMap[pid]) {
|
|
||||||
routeNodes.push({
|
|
||||||
id: pid,
|
|
||||||
type: "material",
|
|
||||||
data: { label: this.productName || "产品", kind: "final" },
|
|
||||||
position: { x: 0, y: 0 },
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// 已落库的物料从种子集合中剔除,其余种子保留在画布上
|
|
||||||
const routeNodeIds = new Set(Object.keys(matMap));
|
|
||||||
if (pid) routeNodeIds.add(pid);
|
|
||||||
this.seedNodes = this.seedNodes.filter((s) => !routeNodeIds.has(s.id));
|
|
||||||
|
|
||||||
const prevCount = this.nodes.length;
|
|
||||||
this.edges = edges;
|
|
||||||
this.nodes = layoutGraph(routeNodes.concat(this.seedNodes), edges);
|
|
||||||
this.syncStore();
|
|
||||||
// 节点增减后 dagre 会整体重排,重新适配视野,避免“看着是空白其实有节点”导致拉线误吸附
|
|
||||||
if (this.hasFitted && this.nodes.length !== prevCount) this.doFit();
|
|
||||||
},
|
|
||||||
|
|
||||||
/** 把本地 nodes/edges 命令式同步到 Vue Flow store(先节点后边,避免边找不到端点) */
|
|
||||||
syncStore() {
|
|
||||||
this.setEdges([]);
|
|
||||||
this.setNodes(this.nodes);
|
|
||||||
this.setEdges(this.edges);
|
|
||||||
},
|
|
||||||
|
|
||||||
/** 重新布局并适应画布 */
|
|
||||||
relayout() {
|
|
||||||
this.nodes = layoutGraph([...this.nodes], this.edges);
|
|
||||||
this.setNodes(this.nodes);
|
|
||||||
this.doFit();
|
|
||||||
},
|
|
||||||
|
|
||||||
doFit() {
|
|
||||||
this.$nextTick(() => {
|
|
||||||
try {
|
|
||||||
this.fitView({ padding: 0.25, maxZoom: 1, duration: 300 });
|
|
||||||
} catch (e) {
|
|
||||||
/* noop */
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
/** VueFlow 节点尺寸测量完成:仅首次自动适配一次 */
|
|
||||||
onNodesInit() {
|
|
||||||
if (this.hasFitted) return;
|
|
||||||
if (this.nodes.length === 0) return;
|
|
||||||
this.hasFitted = true;
|
|
||||||
this.doFit();
|
|
||||||
},
|
|
||||||
|
|
||||||
/* ============ 左侧面板拖拽入画布 ============ */
|
|
||||||
onDragStart(evt, mat) {
|
|
||||||
evt.dataTransfer.setData(
|
|
||||||
"application/xtflow",
|
|
||||||
JSON.stringify({ id: mat.id, name: mat.full_name, type: this.matType })
|
|
||||||
);
|
|
||||||
evt.dataTransfer.effectAllowed = "move";
|
|
||||||
},
|
|
||||||
onDrop(evt) {
|
|
||||||
if (this.readonly) return;
|
|
||||||
const raw = evt.dataTransfer.getData("application/xtflow");
|
|
||||||
if (!raw) return;
|
|
||||||
let mat;
|
|
||||||
try {
|
|
||||||
mat = JSON.parse(raw);
|
|
||||||
} catch (e) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const pos = this.toFlowPos(evt.clientX, evt.clientY);
|
|
||||||
this.addSeed(mat, pos);
|
|
||||||
},
|
|
||||||
toFlowPos(clientX, clientY) {
|
|
||||||
if (typeof this.screenToFlowCoordinate === "function") {
|
|
||||||
return this.screenToFlowCoordinate({ x: clientX, y: clientY });
|
|
||||||
}
|
|
||||||
if (typeof this.project === "function") {
|
|
||||||
return this.project({ x: clientX, y: clientY });
|
|
||||||
}
|
|
||||||
return { x: clientX, y: clientY };
|
|
||||||
},
|
|
||||||
addSeed(mat, position) {
|
|
||||||
const id = String(mat.id);
|
|
||||||
if (this.nodes.some((n) => n.id === id)) {
|
|
||||||
const inUse = this.routes.some(
|
|
||||||
(r) => String(r.material_in) === id || String(r.material_out) === id
|
|
||||||
);
|
|
||||||
this.$message.info(inUse ? "该物料已在工序中使用" : "该物料已在画布中(右键节点可移除)");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const node = {
|
|
||||||
id,
|
|
||||||
type: "material",
|
|
||||||
data: { label: mat.name, kind: this.kindOfType(mat.type) },
|
|
||||||
position,
|
|
||||||
};
|
|
||||||
this.seedNodes.push(node);
|
|
||||||
this.nodes = [...this.nodes, node];
|
|
||||||
// 命令式加入 store:先注册再渲染 Handle,避免 dimensions 竞态
|
|
||||||
this.addNodes([node]);
|
|
||||||
},
|
|
||||||
|
|
||||||
/* ============ 连线手势 ============ */
|
|
||||||
onConnectStart(params) {
|
|
||||||
this.connectSource = (params && (params.nodeId || params.source)) || null;
|
|
||||||
this.connectMade = false;
|
|
||||||
const oe = params && params.event;
|
|
||||||
this.connectStartPos = oe && oe.clientX != null ? { x: oe.clientX, y: oe.clientY } : null;
|
|
||||||
},
|
|
||||||
/** 连到已有节点:新建一条 Route,预填输入/输出物料 */
|
|
||||||
onConnect(conn) {
|
|
||||||
this.connectMade = true;
|
|
||||||
if (this.readonly) return;
|
|
||||||
// 误吸附保护:吸回起点自身或目标无效时,按“拉到空白”处理,只带输入
|
|
||||||
if (!conn.target || conn.target === conn.source) {
|
|
||||||
this.openAddFrom(conn.source);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const src = this.nodes.find((n) => n.id === conn.source);
|
|
||||||
const tgt = this.nodes.find((n) => n.id === conn.target);
|
|
||||||
// 注意:id 为雪花大整数,必须保持字符串,切勿 Number() 否则精度丢失
|
|
||||||
this.openForm("add", {
|
|
||||||
material_in: conn.source,
|
|
||||||
material_in_name: src ? src.data.label : "",
|
|
||||||
material_out: conn.target,
|
|
||||||
material_out_name: tgt ? tgt.data.label : "",
|
|
||||||
});
|
|
||||||
},
|
|
||||||
/** 拉线到空白处:新建工序,输出物料留空由后端自动生成下一节点 */
|
|
||||||
onConnectEnd(evt) {
|
|
||||||
const src = this.connectSource;
|
|
||||||
const made = this.connectMade;
|
|
||||||
const startPos = this.connectStartPos;
|
|
||||||
this.connectSource = null;
|
|
||||||
this.connectMade = false;
|
|
||||||
this.connectStartPos = null;
|
|
||||||
if (this.readonly || made || !src) return;
|
|
||||||
// 单纯点击手柄(几乎无位移)不算拉线,不弹新增表单
|
|
||||||
const oe = evt && evt.clientX != null ? evt : evt && evt.event;
|
|
||||||
if (startPos && oe && oe.clientX != null) {
|
|
||||||
const dist = Math.hypot(oe.clientX - startPos.x, oe.clientY - startPos.y);
|
|
||||||
if (dist < 8) return;
|
|
||||||
}
|
|
||||||
this.openAddFrom(src);
|
|
||||||
},
|
|
||||||
/** 以某节点为输入新建工序:只带输入物料,其余字段一律默认值 */
|
|
||||||
openAddFrom(srcId) {
|
|
||||||
const node = this.nodes.find((n) => n.id === srcId);
|
|
||||||
// id 为雪花大整数,保持字符串
|
|
||||||
this.openForm("add", {
|
|
||||||
material_in: srcId,
|
|
||||||
material_in_name: node ? node.data.label : "",
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
/** 单击边 => 编辑对应 Route(复用 route_form) */
|
|
||||||
onEdgeClick(evt) {
|
|
||||||
const edge = evt.edge || evt;
|
|
||||||
const route = edge.data && edge.data.route;
|
|
||||||
if (!route) return;
|
|
||||||
if (this.readonly) {
|
|
||||||
this.$message.info("当前状态不可编辑");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (edge.data.locked) {
|
|
||||||
this.$message.warning("该工序引用了其他步骤,无法编辑");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.openForm("edit", route);
|
|
||||||
},
|
|
||||||
|
|
||||||
/** 右键边 => 删除对应 Route */
|
|
||||||
onEdgeContextMenu(evt) {
|
|
||||||
const oe = evt.event || evt;
|
|
||||||
if (oe && oe.preventDefault) oe.preventDefault();
|
|
||||||
if (this.readonly) return;
|
|
||||||
const edge = evt.edge || evt;
|
|
||||||
const route = edge.data && edge.data.route;
|
|
||||||
if (!route) return;
|
|
||||||
if (edge.data.locked) {
|
|
||||||
this.$message.warning("该工序被其他步骤引用,无法删除");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.$confirm(`确定删除工序「${route.process_name || ""}」吗?`, "提示", {
|
|
||||||
type: "warning",
|
|
||||||
})
|
|
||||||
.then(() => {
|
|
||||||
this.$API.mtm.route.delete.req(route.id).then(() => {
|
|
||||||
this.$message.success("删除成功");
|
|
||||||
this.reload();
|
|
||||||
this.$emit("changed");
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.catch(() => {});
|
|
||||||
},
|
|
||||||
|
|
||||||
/** 右键节点 => 移除未落库的种子节点(已用于工序的物料需删对应工序) */
|
|
||||||
onNodeContextMenu(evt) {
|
|
||||||
const oe = evt.event || evt;
|
|
||||||
if (oe && oe.preventDefault) oe.preventDefault();
|
|
||||||
if (this.readonly) return;
|
|
||||||
const node = evt.node || evt;
|
|
||||||
const nid = node.id;
|
|
||||||
if (this.productId && nid === String(this.productId)) {
|
|
||||||
this.$message.warning("产品节点为工艺终点,不可移除");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const inUse = this.routes.some(
|
|
||||||
(r) => String(r.material_in) === nid || String(r.material_out) === nid
|
|
||||||
);
|
|
||||||
if (inUse) {
|
|
||||||
this.$message.warning("该物料已用于工序,请删除对应工序");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const label = (node.data && node.data.label) || "";
|
|
||||||
this.$confirm(`从画布移除「${label}」?`, "提示", { type: "warning" })
|
|
||||||
.then(() => {
|
|
||||||
this.seedNodes = this.seedNodes.filter((s) => s.id !== nid);
|
|
||||||
this.nodes = this.nodes.filter((n) => n.id !== nid);
|
|
||||||
this.removeNodes([nid]);
|
|
||||||
})
|
|
||||||
.catch(() => {});
|
|
||||||
},
|
|
||||||
|
|
||||||
addStep() {
|
|
||||||
this.openForm("add", null);
|
|
||||||
},
|
|
||||||
|
|
||||||
/** 打开单步表单;prefill 为 null 表示纯新增。预填经 prop 传入,在表单挂载 open 时一次性应用 */
|
|
||||||
openForm(mode, prefill) {
|
|
||||||
this.dialogSeq += 1;
|
|
||||||
this.formPrefill = prefill || null;
|
|
||||||
this.dialogVisible = true;
|
|
||||||
this.$nextTick(() => {
|
|
||||||
this.$refs.routeForm.open(mode);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
onFormSuccess() {
|
|
||||||
this.dialogVisible = false;
|
|
||||||
this.reload();
|
|
||||||
this.$emit("changed");
|
|
||||||
},
|
|
||||||
|
|
||||||
/** 调后端 validate 接口,实时反馈 DAG 是否合法 */
|
|
||||||
doValidate() {
|
|
||||||
if (!this.routepack) return;
|
|
||||||
this.validating = true;
|
|
||||||
this.$API.mtm.routepack.validate
|
|
||||||
.req(this.routepack)
|
|
||||||
.then((res) => {
|
|
||||||
if (res && res.valid) {
|
|
||||||
this.$message.success("工艺图校验通过");
|
|
||||||
} else {
|
|
||||||
this.$message.error("校验未通过:" + (res ? res.error : "未知错误"));
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.finally(() => {
|
|
||||||
this.validating = false;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.flow-editor {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
min-height: 480px;
|
|
||||||
}
|
|
||||||
.flow-toolbar {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
gap: 8px;
|
|
||||||
padding: 4px 8px;
|
|
||||||
background: #f7f9fc;
|
|
||||||
border: 1px solid #eef1f6;
|
|
||||||
border-radius: 8px;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
}
|
|
||||||
.flow-toolbar__left {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 8px;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
}
|
|
||||||
.flow-legend {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 12px;
|
|
||||||
}
|
|
||||||
.lg {
|
|
||||||
position: relative;
|
|
||||||
padding-left: 16px;
|
|
||||||
font-size: 12px;
|
|
||||||
color: #606266;
|
|
||||||
}
|
|
||||||
.lg::before {
|
|
||||||
content: "";
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
top: 50%;
|
|
||||||
transform: translateY(-50%);
|
|
||||||
width: 10px;
|
|
||||||
height: 10px;
|
|
||||||
border-radius: 3px;
|
|
||||||
border: 1px solid;
|
|
||||||
}
|
|
||||||
.lg--raw::before {
|
|
||||||
background: #fdf6ec;
|
|
||||||
border-color: #e6a23c;
|
|
||||||
}
|
|
||||||
.lg--mid::before {
|
|
||||||
background: #ecf5ff;
|
|
||||||
border-color: #409eff;
|
|
||||||
}
|
|
||||||
.lg--final::before {
|
|
||||||
background: #f0f9eb;
|
|
||||||
border-color: #67c23a;
|
|
||||||
}
|
|
||||||
.flow-tip {
|
|
||||||
color: #909399;
|
|
||||||
font-size: 12px;
|
|
||||||
padding: 3px 2px 4px;
|
|
||||||
}
|
|
||||||
.flow-tip--ro {
|
|
||||||
color: #e6a23c;
|
|
||||||
}
|
|
||||||
.flow-body {
|
|
||||||
display: flex;
|
|
||||||
flex: 1;
|
|
||||||
min-height: 420px;
|
|
||||||
gap: 6px;
|
|
||||||
}
|
|
||||||
.flow-palette {
|
|
||||||
width: 190px;
|
|
||||||
flex: 0 0 190px;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
border: 1px solid #eef1f6;
|
|
||||||
border-radius: 8px;
|
|
||||||
overflow: hidden;
|
|
||||||
background: #fff;
|
|
||||||
}
|
|
||||||
.palette-head {
|
|
||||||
padding: 8px;
|
|
||||||
border-bottom: 1px solid #f0f2f5;
|
|
||||||
background: #fafbfd;
|
|
||||||
}
|
|
||||||
.palette-title {
|
|
||||||
font-size: 13px;
|
|
||||||
font-weight: 600;
|
|
||||||
color: #303133;
|
|
||||||
margin-bottom: 8px;
|
|
||||||
}
|
|
||||||
.palette-list {
|
|
||||||
flex: 1;
|
|
||||||
overflow-y: auto;
|
|
||||||
padding: 8px;
|
|
||||||
}
|
|
||||||
.palette-item {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 6px;
|
|
||||||
padding: 7px 9px;
|
|
||||||
margin-bottom: 6px;
|
|
||||||
border: 1px solid #ebeef5;
|
|
||||||
border-radius: 6px;
|
|
||||||
background: #fff;
|
|
||||||
cursor: grab;
|
|
||||||
font-size: 12px;
|
|
||||||
color: #303133;
|
|
||||||
transition: all 0.15s;
|
|
||||||
}
|
|
||||||
.palette-item:hover {
|
|
||||||
border-color: #409eff;
|
|
||||||
background: #ecf5ff;
|
|
||||||
box-shadow: 0 2px 6px rgba(64, 158, 255, 0.15);
|
|
||||||
transform: translateY(-1px);
|
|
||||||
}
|
|
||||||
.palette-item:active {
|
|
||||||
cursor: grabbing;
|
|
||||||
}
|
|
||||||
.palette-item__grip {
|
|
||||||
color: #c0c4cc;
|
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
|
||||||
.palette-item__txt {
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
.palette-empty {
|
|
||||||
color: #909399;
|
|
||||||
font-size: 12px;
|
|
||||||
text-align: center;
|
|
||||||
padding: 16px 0;
|
|
||||||
}
|
|
||||||
.flow-canvas {
|
|
||||||
position: relative;
|
|
||||||
flex: 1;
|
|
||||||
min-height: 420px;
|
|
||||||
border: 1px solid #eef1f6;
|
|
||||||
border-radius: 8px;
|
|
||||||
overflow: hidden;
|
|
||||||
background: #fbfcfe;
|
|
||||||
}
|
|
||||||
.flow-empty {
|
|
||||||
position: absolute;
|
|
||||||
top: 50%;
|
|
||||||
left: 50%;
|
|
||||||
transform: translate(-50%, -50%);
|
|
||||||
color: #a8abb2;
|
|
||||||
font-size: 13px;
|
|
||||||
text-align: center;
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
.flow-empty__icon {
|
|
||||||
font-size: 34px;
|
|
||||||
color: #c8ccd4;
|
|
||||||
display: block;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
</style>
|
|
||||||
<style>
|
|
||||||
/* Vue Flow 内部元素(非 scoped);物料节点样式在 flow/MaterialNode.vue */
|
|
||||||
.vue-flow__controls {
|
|
||||||
box-shadow: 0 2px 10px rgba(31, 45, 61, 0.12);
|
|
||||||
border-radius: 6px;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
@ -1,261 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="xt-flow-viewer">
|
|
||||||
<!-- 顶部工具栏:与 xtFlowEditor 视觉一致 -->
|
|
||||||
<div class="flow-toolbar">
|
|
||||||
<div class="flow-toolbar__left">
|
|
||||||
<el-button icon="el-icon-full-screen" size="small" round @click="doFit">适应画布</el-button>
|
|
||||||
</div>
|
|
||||||
<div class="flow-legend">
|
|
||||||
<span class="lg lg--raw">原料</span>
|
|
||||||
<span class="lg lg--mid">半成品</span>
|
|
||||||
<span class="lg lg--final">成品</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="flow-canvas">
|
|
||||||
<VueFlow
|
|
||||||
:id="flowId"
|
|
||||||
:min-zoom="0.2"
|
|
||||||
:max-zoom="2"
|
|
||||||
:nodes-draggable="false"
|
|
||||||
:nodes-connectable="false"
|
|
||||||
:elements-selectable="false"
|
|
||||||
@nodes-initialized="onNodesInit"
|
|
||||||
>
|
|
||||||
<template #node-material="{ data }">
|
|
||||||
<material-node :data="data" />
|
|
||||||
</template>
|
|
||||||
<Background :gap="18" pattern-color="#e6e9ef" />
|
|
||||||
<Controls :show-interactive="false" />
|
|
||||||
</VueFlow>
|
|
||||||
<div v-if="isEmpty" class="flow-empty">
|
|
||||||
<i class="el-icon-warning-outline flow-empty__icon"></i>
|
|
||||||
<div>暂无工艺图数据</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { VueFlow, useVueFlow } from "@vue-flow/core";
|
|
||||||
import { Background } from "@vue-flow/background";
|
|
||||||
import { Controls } from "@vue-flow/controls";
|
|
||||||
import MaterialNode from "./flow/MaterialNode.vue";
|
|
||||||
import { layoutGraph } from "./flow/dagreLayout";
|
|
||||||
import "@vue-flow/core/dist/style.css";
|
|
||||||
import "@vue-flow/core/dist/theme-default.css";
|
|
||||||
import "@vue-flow/controls/dist/style.css";
|
|
||||||
|
|
||||||
// 每个实例分配唯一 flowId,避免 Vue Flow 全局 store 按固定 id 缓存导致多实例互相覆盖
|
|
||||||
let viewerSeq = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 工艺路线只读流程图(Vue Flow 版),与 xtFlowEditor 共用节点样式与布局。
|
|
||||||
* props 与 scDegra 对齐:nodes [{id,label}]、edges [{id,source,target,label}]
|
|
||||||
*/
|
|
||||||
export default {
|
|
||||||
name: "xtFlowViewer",
|
|
||||||
components: { VueFlow, Background, Controls, MaterialNode },
|
|
||||||
props: {
|
|
||||||
nodes: { type: Array, default: () => [] },
|
|
||||||
edges: { type: Array, default: () => [] },
|
|
||||||
rankdir: { type: String, default: "TB" },
|
|
||||||
},
|
|
||||||
setup() {
|
|
||||||
const flowId = "xt-flow-viewer-" + ++viewerSeq;
|
|
||||||
const { fitView, setNodes, setEdges } = useVueFlow(flowId);
|
|
||||||
return { flowId, fitView, setNodes, setEdges };
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
// 首次 fit 不带动画,避免打开时视图跳动
|
|
||||||
hasFitted: false,
|
|
||||||
rebuildPending: false,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
isEmpty() {
|
|
||||||
return !(this.nodes || []).length;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
nodes() {
|
|
||||||
this.scheduleRebuild();
|
|
||||||
},
|
|
||||||
edges() {
|
|
||||||
this.scheduleRebuild();
|
|
||||||
},
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
this.rebuild();
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
/** nodes/edges 通常被先后赋值,用微任务合并成一次 rebuild,避免双次 dagre 布局 */
|
|
||||||
scheduleRebuild() {
|
|
||||||
if (this.rebuildPending) return;
|
|
||||||
this.rebuildPending = true;
|
|
||||||
Promise.resolve().then(() => {
|
|
||||||
this.rebuildPending = false;
|
|
||||||
this.rebuild();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
/** nodes/edges -> Vue Flow 图;节点类型按出入度推断(无入边=原料,无出边=成品) */
|
|
||||||
rebuild() {
|
|
||||||
const sourceIds = new Set();
|
|
||||||
const targetIds = new Set();
|
|
||||||
const rawEdges = (this.edges || [])
|
|
||||||
.filter((e) => e.source != null && e.target != null)
|
|
||||||
.map((e) => {
|
|
||||||
const sid = String(e.source);
|
|
||||||
const tid = String(e.target);
|
|
||||||
sourceIds.add(sid);
|
|
||||||
targetIds.add(tid);
|
|
||||||
return {
|
|
||||||
id: e.id != null ? String(e.id) : sid + "-" + tid,
|
|
||||||
source: sid,
|
|
||||||
target: tid,
|
|
||||||
label: e.label || "",
|
|
||||||
type: "smoothstep",
|
|
||||||
markerEnd: "arrowclosed",
|
|
||||||
style: { stroke: "#409eff", strokeWidth: 2 },
|
|
||||||
labelStyle: { fill: "#5b6370", fontSize: "12px", fontWeight: 500 },
|
|
||||||
labelBgStyle: { fill: "#ffffff", stroke: "#e4e7ed", strokeWidth: 1 },
|
|
||||||
labelBgPadding: [7, 4],
|
|
||||||
labelBgBorderRadius: 6,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
const vNodes = (this.nodes || [])
|
|
||||||
.filter((n) => n.id != null && n.label)
|
|
||||||
.map((n) => {
|
|
||||||
const id = String(n.id);
|
|
||||||
const isSrc = sourceIds.has(id);
|
|
||||||
const isTgt = targetIds.has(id);
|
|
||||||
let kind = "mid";
|
|
||||||
if (isTgt && !isSrc) kind = "final";
|
|
||||||
else if (isSrc && !isTgt) kind = "raw";
|
|
||||||
return { id, type: "material", data: { label: n.label, kind }, position: { x: 0, y: 0 } };
|
|
||||||
});
|
|
||||||
const nodeIds = new Set(vNodes.map((n) => n.id));
|
|
||||||
const vEdges = rawEdges.filter((e) => nodeIds.has(e.source) && nodeIds.has(e.target));
|
|
||||||
|
|
||||||
this.setEdges([]);
|
|
||||||
this.setNodes(layoutGraph(vNodes, vEdges, { rankdir: this.rankdir }));
|
|
||||||
this.setEdges(vEdges);
|
|
||||||
// 首次挂载交给 nodes-initialized(尺寸测量完成)再 fit;数据更新时尺寸已就绪,直接 fit
|
|
||||||
if (this.hasFitted) this.doFit();
|
|
||||||
},
|
|
||||||
onNodesInit() {
|
|
||||||
this.doFit();
|
|
||||||
},
|
|
||||||
doFit() {
|
|
||||||
this.$nextTick(() => {
|
|
||||||
try {
|
|
||||||
this.fitView({ padding: 0.2, maxZoom: 1, duration: this.hasFitted ? 200 : 0 });
|
|
||||||
this.hasFitted = true;
|
|
||||||
} catch (e) {
|
|
||||||
/* noop */
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.xt-flow-viewer {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
min-height: 320px;
|
|
||||||
gap: 6px;
|
|
||||||
}
|
|
||||||
.flow-toolbar {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
gap: 8px;
|
|
||||||
padding: 4px 8px;
|
|
||||||
background: #f7f9fc;
|
|
||||||
border: 1px solid #eef1f6;
|
|
||||||
border-radius: 8px;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
}
|
|
||||||
.flow-toolbar__left {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 8px;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
}
|
|
||||||
.flow-legend {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 12px;
|
|
||||||
}
|
|
||||||
.lg {
|
|
||||||
position: relative;
|
|
||||||
padding-left: 16px;
|
|
||||||
font-size: 12px;
|
|
||||||
color: #606266;
|
|
||||||
}
|
|
||||||
.lg::before {
|
|
||||||
content: "";
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
top: 50%;
|
|
||||||
transform: translateY(-50%);
|
|
||||||
width: 10px;
|
|
||||||
height: 10px;
|
|
||||||
border-radius: 3px;
|
|
||||||
border: 1px solid;
|
|
||||||
}
|
|
||||||
.lg--raw::before {
|
|
||||||
background: #fdf6ec;
|
|
||||||
border-color: #e6a23c;
|
|
||||||
}
|
|
||||||
.lg--mid::before {
|
|
||||||
background: #ecf5ff;
|
|
||||||
border-color: #409eff;
|
|
||||||
}
|
|
||||||
.lg--final::before {
|
|
||||||
background: #f0f9eb;
|
|
||||||
border-color: #67c23a;
|
|
||||||
}
|
|
||||||
.flow-canvas {
|
|
||||||
position: relative;
|
|
||||||
flex: 1;
|
|
||||||
min-height: 280px;
|
|
||||||
border: 1px solid #eef1f6;
|
|
||||||
border-radius: 8px;
|
|
||||||
overflow: hidden;
|
|
||||||
background: #fbfcfe;
|
|
||||||
}
|
|
||||||
.flow-empty {
|
|
||||||
position: absolute;
|
|
||||||
top: 50%;
|
|
||||||
left: 50%;
|
|
||||||
transform: translate(-50%, -50%);
|
|
||||||
color: #a8abb2;
|
|
||||||
font-size: 13px;
|
|
||||||
text-align: center;
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
.flow-empty__icon {
|
|
||||||
font-size: 34px;
|
|
||||||
color: #c8ccd4;
|
|
||||||
display: block;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
}
|
|
||||||
/* 只读视图:隐藏连接点 */
|
|
||||||
.xt-flow-viewer :deep(.vue-flow__handle) {
|
|
||||||
opacity: 0;
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.xt-flow-viewer .vue-flow__controls {
|
|
||||||
box-shadow: 0 2px 10px rgba(31, 45, 61, 0.12);
|
|
||||||
border-radius: 6px;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
@ -123,18 +123,8 @@ onMounted(() => {
|
||||||
const init = () => {
|
const init = () => {
|
||||||
if (props.label) {
|
if (props.label) {
|
||||||
selectLabel.value = props.label;
|
selectLabel.value = props.label;
|
||||||
return;
|
} else {
|
||||||
}
|
if (props.multiple) {
|
||||||
// 外部把值清空(表单重置/实例复用)时同步清空显示文字,否则输入框会残留上次选择的内容
|
|
||||||
const emptyVal =
|
|
||||||
props.modelValue == null ||
|
|
||||||
props.modelValue === "" ||
|
|
||||||
(Array.isArray(props.modelValue) && props.modelValue.length === 0);
|
|
||||||
if (emptyVal) {
|
|
||||||
selectLabel.value = "";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (props.multiple) {
|
|
||||||
if (isFixOptions.value) {
|
if (isFixOptions.value) {
|
||||||
selectLabel.value = props.options
|
selectLabel.value = props.options
|
||||||
.filter((item) =>
|
.filter((item) =>
|
||||||
|
|
@ -159,6 +149,7 @@ const init = () => {
|
||||||
selectLabel.value = props.obj[props.labelField];
|
selectLabel.value = props.obj[props.labelField];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const isFixOptions = ref(false);
|
const isFixOptions = ref(false);
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ const DEFAULT_CONFIG = {
|
||||||
DASHBOARD_URL: "/dashboard",
|
DASHBOARD_URL: "/dashboard",
|
||||||
|
|
||||||
//版本号
|
//版本号
|
||||||
APP_VER: "3.1.2026072315",
|
APP_VER: "3.1.2026071608",
|
||||||
|
|
||||||
//内核版本号
|
//内核版本号
|
||||||
CORE_VER: "1.6.9",
|
CORE_VER: "1.6.9",
|
||||||
|
|
|
||||||
|
|
@ -62,11 +62,6 @@
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 显式声明 nopadding 的区域不受上面默认内边距影响 */
|
|
||||||
.el-main.nopadding {
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 表单卡片化 */
|
/* 表单卡片化 */
|
||||||
.el-main > .el-form {
|
.el-main > .el-form {
|
||||||
background: var(--el-bg-color);
|
background: var(--el-bg-color);
|
||||||
|
|
@ -164,11 +159,6 @@
|
||||||
padding: 14px 10px 14px 14px;
|
padding: 14px 10px 14px 14px;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
.el-aside.nopadding {
|
|
||||||
background: transparent;
|
|
||||||
border-left: 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================================
|
/* ============================================================
|
||||||
|
|
|
||||||
|
|
@ -356,7 +356,7 @@
|
||||||
<el-dialog v-model="choseMyScheduleDialog" title="选择策略">
|
<el-dialog v-model="choseMyScheduleDialog" title="选择策略">
|
||||||
<MySchedule @scheduleChose="scheduleChose"></MySchedule>
|
<MySchedule @scheduleChose="scheduleChose"></MySchedule>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
<el-dialog v-model="riskDialog" title="新增/编辑" width="90%" destroy-on-close>
|
<el-dialog v-model="riskDialog" title="新增/编辑" width="90%">
|
||||||
<RiskForm ref="riskForm" :riskpoint="rowData.id" @riskConfirm="riskConfirm"></RiskForm>
|
<RiskForm ref="riskForm" :riskpoint="rowData.id" @riskConfirm="riskConfirm"></RiskForm>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</el-container>
|
</el-container>
|
||||||
|
|
@ -444,7 +444,6 @@ export default {
|
||||||
this.$refs.table.queryData(this.query);
|
this.$refs.table.queryData(this.query);
|
||||||
},
|
},
|
||||||
table_add() {
|
table_add() {
|
||||||
this.saveForm = Object.assign({}, defaultForm);
|
|
||||||
this.saveDialog = true;
|
this.saveDialog = true;
|
||||||
},
|
},
|
||||||
table_edit(row) {
|
table_edit(row) {
|
||||||
|
|
|
||||||
|
|
@ -128,13 +128,13 @@
|
||||||
</el-container>
|
</el-container>
|
||||||
</el-container>
|
</el-container>
|
||||||
<save-dialog
|
<save-dialog
|
||||||
v-if="dialog.save"
|
v-model="dialog.save"
|
||||||
ref="saveDialog"
|
ref="saveDialog"
|
||||||
@success="handleSaveSuccessss"
|
@success="handleSaveSuccessss"
|
||||||
@closed="dialog.save = false"
|
@closed="dialog.save = false"
|
||||||
></save-dialog>
|
></save-dialog>
|
||||||
<algo-dialog
|
<algo-dialog
|
||||||
v-if="dialog.algos"
|
v-model="dialog.algos"
|
||||||
ref="algoDialog"
|
ref="algoDialog"
|
||||||
@success="handleSaveSuccessss"
|
@success="handleSaveSuccessss"
|
||||||
@closed="dialog.algos = false"
|
@closed="dialog.algos = false"
|
||||||
|
|
|
||||||
|
|
@ -208,7 +208,7 @@
|
||||||
>保 存</el-button
|
>保 存</el-button
|
||||||
>
|
>
|
||||||
</el-footer>
|
</el-footer>
|
||||||
<el-dialog append-to-body title="选择题目" v-model="questionCVisible" width="90%">
|
<el-dialog title="选择题目" v-model="questionCVisible" width="90%">
|
||||||
<Question
|
<Question
|
||||||
style="height: 500px"
|
style="height: 500px"
|
||||||
ref="QuestionChoseRef"
|
ref="QuestionChoseRef"
|
||||||
|
|
@ -219,7 +219,7 @@
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
<!-- <el-button type="primary" @click="handleChoose1" icon="el-icon-plus" style="margin-right: 10px;">上传试题</el-button> -->
|
<!-- <el-button type="primary" @click="handleChoose1" icon="el-icon-plus" style="margin-right: 10px;">上传试题</el-button> -->
|
||||||
<el-dialog append-to-body
|
<el-dialog
|
||||||
v-model="impDialogVisible"
|
v-model="impDialogVisible"
|
||||||
title="上传试题"
|
title="上传试题"
|
||||||
:left="'200px'"
|
:left="'200px'"
|
||||||
|
|
|
||||||
|
|
@ -1,22 +1,18 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="wrapper" @mouseover="mouseOver" @mouseout="mouseOut">
|
<div class="wrapper" @mouseover="mouseOver" @mouseout="mouseOut">
|
||||||
<table class="totall">
|
<table class="totall">
|
||||||
<tbody>
|
|
||||||
<tr class="title">
|
<tr class="title">
|
||||||
<th v-for="itemx in liData" :key="itemx">{{ itemx }}</th>
|
<th v-for="itemx in liData" :key="itemx">{{ itemx }}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
|
||||||
</table>
|
</table>
|
||||||
<div ref="moocBox" class="wrapper2">
|
<div ref="moocBox" class="wrapper2">
|
||||||
<table :class="{ marquee_top: animate }">
|
<table :class="{ marquee_top: animate }">
|
||||||
<tbody>
|
|
||||||
<tr v-for="itemy in listData" class="rollData" ref="con1" :key="itemy">
|
<tr v-for="itemy in listData" class="rollData" ref="con1" :key="itemy">
|
||||||
<td v-for="itemz in itemy" :key="itemz">{{ itemz }}</td>
|
<td v-for="itemz in itemy" :key="itemz">{{ itemz }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr v-for="itemy in listData" class="rollData" ref="con2" :key="itemy">
|
<tr v-for="itemy in listData" class="rollData" ref="con2" :key="itemy">
|
||||||
<td v-for="itemz in itemy" :key="itemz">{{ itemz }}</td>
|
<td v-for="itemz in itemy" :key="itemz">{{ itemz }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -326,17 +326,10 @@ export default {
|
||||||
// console.log('userOption',userOption);
|
// console.log('userOption',userOption);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
//新增时清空表单,避免上次保存的数据残留(与mioitem_form一致,防v-if未及时重建时复用旧实例)
|
|
||||||
resetForm() {
|
|
||||||
this.form = { state: 10, inout_date: this.$TOOL.dateFormat2(new Date()) };
|
|
||||||
},
|
|
||||||
//显示
|
//显示
|
||||||
open(mode = "add", type = "",htype="") {
|
open(mode = "add", type = "",htype="") {
|
||||||
this.mode = mode;
|
this.mode = mode;
|
||||||
this.htype = htype;
|
this.htype = htype;
|
||||||
if (mode == "add") {
|
|
||||||
this.resetForm();
|
|
||||||
}
|
|
||||||
this.form.type = type;
|
this.form.type = type;
|
||||||
this.init();
|
this.init();
|
||||||
this.visible = true;
|
this.visible = true;
|
||||||
|
|
|
||||||
|
|
@ -149,9 +149,8 @@
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="检验提交" prop="count_tested" v-if="cate=='mainso'&&(type == 'pur_in' ||type == 'do_in' ||type == 'other_in')">
|
<el-table-column label="检验提交" prop="count_tested" v-if="cate=='mainso'&&(type == 'pur_in' ||type == 'do_in' ||type == 'other_in')">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-tag v-if="scope.row.test_date !== null" type="success">是</el-tag>
|
<el-tag v-if="scope.row.test_date == null" type="warning">否</el-tag>
|
||||||
<el-tag v-else-if="scope.row.material_&&scope.row.material_.test_mode_in==10" type="info">免检</el-tag>
|
<el-tag v-else type="success">是</el-tag>
|
||||||
<el-tag v-else type="warning">否</el-tag>
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="不合格数量" prop="count_notok" v-if="cate!=='helpso'">
|
<el-table-column label="不合格数量" prop="count_notok" v-if="cate!=='helpso'">
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<el-dialog append-to-body
|
<el-dialog
|
||||||
title="检验"
|
title="检验"
|
||||||
v-model="visible"
|
v-model="visible"
|
||||||
:size="1200"
|
:size="1200"
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<el-dialog append-to-body
|
<el-dialog
|
||||||
:title="titleMap[form.type]"
|
:title="titleMap[form.type]"
|
||||||
v-model="visible"
|
v-model="visible"
|
||||||
:size="1000"
|
:size="1000"
|
||||||
|
|
@ -272,7 +272,7 @@
|
||||||
<el-button @click="visible = false">取消</el-button>
|
<el-button @click="visible = false">取消</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
<el-dialog append-to-body title="设置发货流水位数" v-model="showDigit">
|
<el-dialog title="设置发货流水位数" v-model="showDigit">
|
||||||
<h4>没有找到该前缀的发货编号,请完善发货流水号位数(填整数)</h4>
|
<h4>没有找到该前缀的发货编号,请完善发货流水号位数(填整数)</h4>
|
||||||
<el-form :model="wprParams" label-width="80px">
|
<el-form :model="wprParams" label-width="80px">
|
||||||
<el-form-item label="流水位数">
|
<el-form-item label="流水位数">
|
||||||
|
|
@ -507,8 +507,7 @@ export default {
|
||||||
// orderitem_material__order: this.mioObj.order,
|
// orderitem_material__order: this.mioObj.order,
|
||||||
type:10,
|
type:10,
|
||||||
// material__type: 10
|
// material__type: 10
|
||||||
// 只展示可发数量(存量-在途出入库)大于0的批次
|
count__gte: 1,
|
||||||
count_canmio__gt: 0,
|
|
||||||
|
|
||||||
};
|
};
|
||||||
this.inputBatchDisable = true;
|
this.inputBatchDisable = true;
|
||||||
|
|
@ -736,35 +735,11 @@ export default {
|
||||||
this.form.warehouse = "";
|
this.form.warehouse = "";
|
||||||
this.inputBatchDisable = false;
|
this.inputBatchDisable = false;
|
||||||
},
|
},
|
||||||
//新增时清空表单,避免上次保存的数据残留导致"物料找不到"等错误
|
|
||||||
resetForm() {
|
|
||||||
this.form = { count: 1, note: '', pack_index: 1 };
|
|
||||||
this.selectObj = null;
|
|
||||||
this.selectBatch = null;
|
|
||||||
this.mioitems = [''];
|
|
||||||
this.mioitemw = [];
|
|
||||||
this.wprList = [];
|
|
||||||
this.wbatchOptions = [];
|
|
||||||
this.batchOptions = [];
|
|
||||||
this.batchOptions_o = [];
|
|
||||||
this.components = [];
|
|
||||||
this.assembShow = false;
|
|
||||||
this.batchcount = null;
|
|
||||||
this.mTracking = 10;
|
|
||||||
this.prefix = '';
|
|
||||||
this.halfgoodprefix = '';
|
|
||||||
this.digitNum = null;
|
|
||||||
this.count_send_yp = 0;
|
|
||||||
this.inputBatchDisable = false;
|
|
||||||
},
|
|
||||||
//显示
|
//显示
|
||||||
open(mode = "add", type = "",mtype) {
|
open(mode = "add", type = "",mtype) {
|
||||||
let that = this;
|
let that = this;
|
||||||
this.mode = mode;
|
this.mode = mode;
|
||||||
this.mtype = mtype?mtype:null;
|
this.mtype = mtype?mtype:null;
|
||||||
if (mode == "add") {
|
|
||||||
this.resetForm();
|
|
||||||
}
|
|
||||||
this.form.type = this.type = type;
|
this.form.type = this.type = type;
|
||||||
if (mode == "add") {
|
if (mode == "add") {
|
||||||
this.init();
|
this.init();
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<el-dialog append-to-body
|
<el-dialog
|
||||||
title="标签信息"
|
title="标签信息"
|
||||||
v-model="visible"
|
v-model="visible"
|
||||||
:size="1000"
|
:size="1000"
|
||||||
|
|
|
||||||
|
|
@ -132,18 +132,6 @@
|
||||||
<el-switch v-model="form.is_hidden" />
|
<el-switch v-model="form.is_hidden" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :md="12" :sm="24">
|
|
||||||
<el-form-item label="入库检验方式" prop="test_mode_in">
|
|
||||||
<el-select
|
|
||||||
v-model="form.test_mode_in"
|
|
||||||
placeholder="入库检验方式"
|
|
||||||
style="width: 100%"
|
|
||||||
>
|
|
||||||
<el-option label="免检" :value="10"></el-option>
|
|
||||||
<el-option label="必检" :value="20"></el-option>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :md="12" :sm="24">
|
<el-col :md="12" :sm="24">
|
||||||
<el-form-item label="安全库存下限" prop="count_safe">
|
<el-form-item label="安全库存下限" prop="count_safe">
|
||||||
<el-input-number
|
<el-input-number
|
||||||
|
|
@ -243,7 +231,7 @@ export default {
|
||||||
show: "查看物料",
|
show: "查看物料",
|
||||||
},
|
},
|
||||||
brothers: [],
|
brothers: [],
|
||||||
form: { test_mode_in: 20 },
|
form: {},
|
||||||
rules: {
|
rules: {
|
||||||
name: [
|
name: [
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -157,18 +157,6 @@
|
||||||
<el-switch v-model="form.is_hidden" />
|
<el-switch v-model="form.is_hidden" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :md="12" :sm="24">
|
|
||||||
<el-form-item label="入库检验方式" prop="test_mode_in">
|
|
||||||
<el-select
|
|
||||||
v-model="form.test_mode_in"
|
|
||||||
placeholder="入库检验方式"
|
|
||||||
style="width: 100%"
|
|
||||||
>
|
|
||||||
<el-option label="免检" :value="10"></el-option>
|
|
||||||
<el-option label="必检" :value="20"></el-option>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :md="12" :sm="24" v-if="form.type == 40">
|
<el-col :md="12" :sm="24" v-if="form.type == 40">
|
||||||
<el-form-item label="是否进入车间库存">
|
<el-form-item label="是否进入车间库存">
|
||||||
<el-switch v-model="form.into_wm" />
|
<el-switch v-model="form.into_wm" />
|
||||||
|
|
@ -219,7 +207,7 @@ export default {
|
||||||
edit: "编辑物料",
|
edit: "编辑物料",
|
||||||
show: "查看物料",
|
show: "查看物料",
|
||||||
},
|
},
|
||||||
form: { test_mode_in: 20 },
|
form: {},
|
||||||
rules: {
|
rules: {
|
||||||
name: [
|
name: [
|
||||||
{
|
{
|
||||||
|
|
@ -365,7 +353,6 @@ export default {
|
||||||
that.form.unit = data.unit;
|
that.form.unit = data.unit;
|
||||||
that.form.process = data.process;
|
that.form.process = data.process;
|
||||||
that.form.tracking = data.tracking;
|
that.form.tracking = data.tracking;
|
||||||
that.form.test_mode_in = data.test_mode_in;
|
|
||||||
that.form.count_safe = data.count_safe;
|
that.form.count_safe = data.count_safe;
|
||||||
that.form.count_safe_upper = data.count_safe_upper;
|
that.form.count_safe_upper = data.count_safe_upper;
|
||||||
that.form.is_hidden = data.is_hidden;
|
that.form.is_hidden = data.is_hidden;
|
||||||
|
|
|
||||||
|
|
@ -98,7 +98,7 @@
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="合格B类默认记合格">
|
<el-form-item label="合批清除缺陷">
|
||||||
<el-switch
|
<el-switch
|
||||||
v-model="form.clear_defect"
|
v-model="form.clear_defect"
|
||||||
></el-switch>
|
></el-switch>
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,14 @@
|
||||||
</div>
|
</div>
|
||||||
</el-header>
|
</el-header>
|
||||||
<el-main class="nopadding">
|
<el-main class="nopadding">
|
||||||
<xtFlowViewer :nodes="nodes" :edges="edges"></xtFlowViewer>
|
<scDegra
|
||||||
|
style="margin-top: 50px;"
|
||||||
|
ref="degraDialogs"
|
||||||
|
:nodes="nodes"
|
||||||
|
:edges="edges"
|
||||||
|
:rankdir="'DL'"
|
||||||
|
>
|
||||||
|
</scDegra>
|
||||||
</el-main>
|
</el-main>
|
||||||
</el-container>
|
</el-container>
|
||||||
</el-aside>
|
</el-aside>
|
||||||
|
|
@ -123,9 +130,6 @@
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import { defineAsyncComponent } from "vue";
|
|
||||||
// 异步加载:Vue Flow 单独分包
|
|
||||||
const xtFlowViewer = defineAsyncComponent(() => import(/* webpackPrefetch: true */ "@/components/xtFlowViewer.vue"));
|
|
||||||
const defaultForm = {
|
const defaultForm = {
|
||||||
process: null,
|
process: null,
|
||||||
sort: 1,
|
sort: 1,
|
||||||
|
|
@ -135,7 +139,7 @@ const defaultForm = {
|
||||||
};
|
};
|
||||||
export default {
|
export default {
|
||||||
name: "route",
|
name: "route",
|
||||||
components: { xtFlowViewer },
|
components: {},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
apiObj: null,
|
apiObj: null,
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@
|
||||||
:title="titleMap[mode]"
|
:title="titleMap[mode]"
|
||||||
v-model="visible"
|
v-model="visible"
|
||||||
:size="1000"
|
:size="1000"
|
||||||
append-to-body
|
|
||||||
destroy-on-close
|
destroy-on-close
|
||||||
@closed="$emit('closed')"
|
@closed="$emit('closed')"
|
||||||
>
|
>
|
||||||
|
|
@ -305,8 +304,6 @@ export default {
|
||||||
props: {
|
props: {
|
||||||
count: { type: Number, default : 0 },
|
count: { type: Number, default : 0 },
|
||||||
routepack: { type: String, default: "" },
|
routepack: { type: String, default: "" },
|
||||||
// 打开时的预填数据(画布拉线传入):挂载即确定,避免事后setData在任何时序下带入脏数据
|
|
||||||
prefill: { type: Object, default: null },
|
|
||||||
},
|
},
|
||||||
emits: ["success", "closed"],
|
emits: ["success", "closed"],
|
||||||
data() {
|
data() {
|
||||||
|
|
@ -399,11 +396,6 @@ export default {
|
||||||
},
|
},
|
||||||
getroutemats(){
|
getroutemats(){
|
||||||
let that = this;
|
let that = this;
|
||||||
// 无 routeId(画布拉线预填等新增场景)时不请求,避免拉回全量辅料
|
|
||||||
if (!that.routeId) {
|
|
||||||
that.routemats = [];
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
that.$API.mtm.routemat.list.req({ route: that.routeId,page: 0}).then((res) => {
|
that.$API.mtm.routemat.list.req({ route: that.routeId,page: 0}).then((res) => {
|
||||||
that.routemats = res;
|
that.routemats = res;
|
||||||
});
|
});
|
||||||
|
|
@ -474,45 +466,15 @@ export default {
|
||||||
that.paramsJsonFileurl = list1;
|
that.paramsJsonFileurl = list1;
|
||||||
that.params_json.fileurl = JSON.stringify(that.paramsJsonFileurl);
|
that.params_json.fileurl = JSON.stringify(that.paramsJsonFileurl);
|
||||||
},
|
},
|
||||||
//重置表单状态:open时主动清空,不依赖父级v-if销毁组件(关闭动画期间重开会复用实例导致残留上次内容)
|
|
||||||
resetForm() {
|
|
||||||
this.form = Object.assign({}, defaultForm);
|
|
||||||
this.form.routepack = this.routepack;
|
|
||||||
if (this.project_code == "bxerp" || this.project_code == "tcerp") {
|
|
||||||
this.form.material_out_tracking = 20;
|
|
||||||
}
|
|
||||||
this.params_json = {
|
|
||||||
duibian1: 0,
|
|
||||||
duibian2: 0,
|
|
||||||
changdu1: 0,
|
|
||||||
changdu2: 0,
|
|
||||||
pbnum: 0,
|
|
||||||
pbsigao: 0,
|
|
||||||
pbbb: "是",
|
|
||||||
};
|
|
||||||
this.params_json2 = { dscd: 0, sijing: 0 };
|
|
||||||
this.fileIds = [];
|
|
||||||
this.fileurl = [];
|
|
||||||
this.fileurl_form = [];
|
|
||||||
this.paramsJsonFileurl = [];
|
|
||||||
this.routemats = [];
|
|
||||||
this.routeId = "";
|
|
||||||
this.processName = "";
|
|
||||||
this.divDisable = false;
|
|
||||||
},
|
|
||||||
//显示
|
//显示
|
||||||
open(mode = "add") {
|
open(mode = "add") {
|
||||||
let that = this;
|
let that = this;
|
||||||
that.mode = mode;
|
that.mode = mode;
|
||||||
that.resetForm();
|
|
||||||
if (that.prefill) that.setData(that.prefill);
|
|
||||||
that.visible = true;
|
that.visible = true;
|
||||||
that.$nextTick(() => {
|
that.$nextTick(() => {
|
||||||
// 仅新增时按现有数量预填排序;编辑时保留 setData 带入的原 sort
|
if(that.count){
|
||||||
if(that.count && mode === "add"){
|
|
||||||
that.form.sort = that.count+1;
|
that.form.sort = that.count+1;
|
||||||
}
|
}
|
||||||
that.$refs.dialogForm && that.$refs.dialogForm.clearValidate();
|
|
||||||
})
|
})
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
|
|
@ -522,18 +484,16 @@ export default {
|
||||||
Object.assign(that.form, data);
|
Object.assign(that.form, data);
|
||||||
that.routeId = data.id;
|
that.routeId = data.id;
|
||||||
that.addTemplate.route = data.id;
|
that.addTemplate.route = data.id;
|
||||||
// 画布拖线新增(prefill)或后端数据无params_json时保留默认值,避免undefined导致模板取值报错
|
that.params_json=that.form.params_json;
|
||||||
if (that.form.params_json) {
|
|
||||||
that.params_json = Object.assign({}, that.params_json, that.form.params_json);
|
|
||||||
}
|
|
||||||
if((this.project_code=='bxerp'||this.project_code=='tcerp')&&this.form.material_out_tracking==null){
|
if((this.project_code=='bxerp'||this.project_code=='tcerp')&&this.form.material_out_tracking==null){
|
||||||
this.form.material_out_tracking = 20;
|
this.form.material_out_tracking = 20;
|
||||||
}
|
}
|
||||||
if(data.process_name=='捆棒'&&that.form.params_json){
|
if(data.process_name=='捆棒'){
|
||||||
that.params_json2 = Object.assign({}, that.params_json2, that.form.params_json);
|
that.params_json2=that.form.params_json;
|
||||||
}
|
}
|
||||||
if(data.process_name=='排一次棒'){
|
if(data.process_name=='排一次棒'){
|
||||||
that.fileIds= [];
|
that.fileIds= [];
|
||||||
|
that.params_json=that.form.params_json;
|
||||||
if(that.params_json.fileurl&&that.params_json.fileurl!=="[]"){
|
if(that.params_json.fileurl&&that.params_json.fileurl!=="[]"){
|
||||||
let fileurl = JSON.parse(that.params_json.fileurl);
|
let fileurl = JSON.parse(that.params_json.fileurl);
|
||||||
fileurl.forEach((item)=>{
|
fileurl.forEach((item)=>{
|
||||||
|
|
|
||||||
|
|
@ -1,81 +1,79 @@
|
||||||
<template>
|
<template>
|
||||||
<el-container class="rs-page" v-loading="loading">
|
<el-container v-loading="loading">
|
||||||
<el-main class="nopadding rs-main">
|
|
||||||
<!-- 基本信息条 -->
|
|
||||||
<div class="rs-card rs-head">
|
|
||||||
<div class="rs-card__title">基本信息</div>
|
|
||||||
<div class="rs-head__items">
|
|
||||||
<div class="rs-head__item">
|
|
||||||
<span class="rs-lbl">工艺名称</span>
|
|
||||||
<span class="rs-val">{{ form.name || "-" }}</span>
|
|
||||||
</div>
|
|
||||||
<div class="rs-head__item">
|
|
||||||
<span class="rs-lbl">物料名称</span>
|
|
||||||
<span class="rs-val">{{ form.material_name || "-" }}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="rs-body">
|
<el-main class="nopadding" style="padding-right: 1px;">
|
||||||
<!-- 流程图卡 -->
|
<el-container>
|
||||||
<div class="rs-card rs-flow">
|
<el-header style="height: 80px;display: block;padding:0">
|
||||||
<div class="rs-card__title">工艺路线流程图</div>
|
<el-card shadow="hover">
|
||||||
<el-tabs v-if="tabsTitle.length > 1" v-model="activeName" class="rs-tabs"
|
<el-descriptions :column="3" title="基本信息">
|
||||||
@tab-click="tabshandleClick">
|
<el-descriptions-item label="工艺名称:">{{
|
||||||
<el-tab-pane :label="item" v-for="item in tabsTitle" :key="item"></el-tab-pane>
|
form.name
|
||||||
</el-tabs>
|
}}</el-descriptions-item>
|
||||||
<xtFlowViewer v-if="limitedWatch" :nodes="nodes" :edges="edges" class="rs-flow__canvas"
|
<el-descriptions-item label="物料名称:">{{
|
||||||
style="min-height: 0">
|
form.material_name
|
||||||
</xtFlowViewer>
|
}}</el-descriptions-item>
|
||||||
</div>
|
</el-descriptions>
|
||||||
|
</el-card>
|
||||||
|
</el-header>
|
||||||
|
<el-main>
|
||||||
|
<el-container>
|
||||||
|
<el-aside style="width: 50%;overflow: scroll;">
|
||||||
|
<div
|
||||||
|
style="font-weight: 600;color: #303133;font-size: 16px;padding: 10px 0;position: fixed;">
|
||||||
|
工艺路线流程图</div>
|
||||||
|
<el-tabs v-if="tabsTitle.length > 1" v-model="activeName" :tab-position="'left'"
|
||||||
|
style="flex-direction: row;" @tab-click="tabshandleClick">
|
||||||
|
<el-tab-pane :label="item" v-for="item in tabsTitle" :key="item"></el-tab-pane>
|
||||||
|
</el-tabs>
|
||||||
|
<scDegra style="margin-top: 50px;" v-if="limitedWatch" ref="degraDialogs" :nodes="nodes"
|
||||||
|
:edges="edges" :rankdir="'DL'" @closeDialog="limitedWatch = false">
|
||||||
|
</scDegra>
|
||||||
|
</el-aside>
|
||||||
|
<el-main class="padding: 1px">
|
||||||
|
<scTable ref="tables" :data="tableData" row-key="id" hidePagination hideDo stripe border>
|
||||||
|
<el-table-column label="排序" prop="sort" width="50">
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="工序" prop="process_name">
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="输入" prop="material_in_name">
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="输出" prop="material_out_name">
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="追踪方式">
|
||||||
|
<template #default="scope">
|
||||||
|
<span>{{ tracking_[scope.row.material_out_tracking] }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="出材率" prop="out_rate">
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="切分融合数量" prop="div_number">
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="工时" prop="hour_work">
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="批次校验" v-if="project_code !== 'bxerp'">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-tag v-if="scope.row.batch_bind" type="success">是</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</scTable>
|
||||||
|
</el-main>
|
||||||
|
</el-container>
|
||||||
|
|
||||||
<!-- 工序表格卡 -->
|
</el-main>
|
||||||
<div class="rs-card rs-steps">
|
|
||||||
<div class="rs-card__title">工序步骤</div>
|
|
||||||
<div class="rs-steps__table">
|
</el-container>
|
||||||
<scTable ref="tables" :data="tableData" row-key="id" hidePagination hideDo stripe border>
|
|
||||||
<el-table-column label="排序" prop="sort" width="50">
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="工序" prop="process_name">
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="输入" prop="material_in_name">
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="输出" prop="material_out_name">
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="追踪方式" width="80">
|
|
||||||
<template #default="scope">
|
|
||||||
<span>{{ tracking_[scope.row.material_out_tracking] }}</span>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="出材率" prop="out_rate" width="70">
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="切分融合数量" prop="div_number" width="80">
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="工时" prop="hour_work" width="60">
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="批次校验" width="80" v-if="project_code !== 'bxerp'">
|
|
||||||
<template #default="scope">
|
|
||||||
<el-tag v-if="scope.row.batch_bind" type="success">是</el-tag>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</scTable>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</el-main>
|
</el-main>
|
||||||
<el-aside width="20%" v-if="form.ticket" class="rs-aside">
|
<el-aside width="20%" v-if="form.ticket">
|
||||||
<ticketd :ticket_="form.ticket_"></ticketd>
|
<ticketd :ticket_="form.ticket_"></ticketd>
|
||||||
</el-aside>
|
</el-aside>
|
||||||
</el-container>
|
</el-container>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import { defineAsyncComponent } from "vue";
|
|
||||||
import ticketd from '@/views/wf/ticketd.vue'
|
import ticketd from '@/views/wf/ticketd.vue'
|
||||||
// 异步加载:Vue Flow 单独分包,仅打开详情时才下载
|
|
||||||
const xtFlowViewer = defineAsyncComponent(() => import(/* webpackPrefetch: true */ "@/components/xtFlowViewer.vue"));
|
|
||||||
export default {
|
export default {
|
||||||
emits: ["success", "closed"],
|
emits: ["success", "closed"],
|
||||||
components: { ticketd, xtFlowViewer },
|
components: { ticketd },
|
||||||
props: {
|
props: {
|
||||||
t_id: { type: String, default: null },
|
t_id: { type: String, default: null },
|
||||||
},
|
},
|
||||||
|
|
@ -180,99 +178,7 @@ export default {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
/* 页面底色:浅灰承托白卡 */
|
.el-transfer {
|
||||||
.rs-page {
|
--el-transfer-panel-width: 345px !important;
|
||||||
height: 100%;
|
|
||||||
background: #f5f7fa;
|
|
||||||
}
|
|
||||||
.rs-main {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 10px;
|
|
||||||
padding: 10px;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
/* 统一卡片语言 */
|
|
||||||
.rs-card {
|
|
||||||
background: #fff;
|
|
||||||
border: 1px solid #ebeef5;
|
|
||||||
border-radius: 10px;
|
|
||||||
box-shadow: 0 1px 2px rgba(31, 45, 61, 0.04);
|
|
||||||
padding: 12px 14px;
|
|
||||||
}
|
|
||||||
.rs-card__title {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 8px;
|
|
||||||
font-size: 15px;
|
|
||||||
font-weight: 600;
|
|
||||||
color: #303133;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
}
|
|
||||||
.rs-card__title::before {
|
|
||||||
content: "";
|
|
||||||
width: 3px;
|
|
||||||
height: 14px;
|
|
||||||
border-radius: 2px;
|
|
||||||
background: var(--el-color-primary, #409eff);
|
|
||||||
}
|
|
||||||
/* 基本信息条:单行轻量 */
|
|
||||||
.rs-head {
|
|
||||||
flex-shrink: 0;
|
|
||||||
padding-bottom: 10px;
|
|
||||||
}
|
|
||||||
.rs-head .rs-card__title {
|
|
||||||
margin-bottom: 8px;
|
|
||||||
}
|
|
||||||
.rs-head__items {
|
|
||||||
display: flex;
|
|
||||||
gap: 48px;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
}
|
|
||||||
.rs-lbl {
|
|
||||||
color: #909399;
|
|
||||||
font-size: 13px;
|
|
||||||
margin-right: 10px;
|
|
||||||
}
|
|
||||||
.rs-val {
|
|
||||||
color: #303133;
|
|
||||||
font-size: 13px;
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
/* 主体:流程图 + 工序表 两卡并排 */
|
|
||||||
.rs-body {
|
|
||||||
flex: 1;
|
|
||||||
min-height: 0;
|
|
||||||
display: flex;
|
|
||||||
gap: 10px;
|
|
||||||
}
|
|
||||||
.rs-flow {
|
|
||||||
width: 50%;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
.rs-flow__canvas {
|
|
||||||
flex: 1;
|
|
||||||
min-height: 0;
|
|
||||||
}
|
|
||||||
.rs-tabs :deep(.el-tabs__header) {
|
|
||||||
margin: 0 0 8px;
|
|
||||||
}
|
|
||||||
.rs-steps {
|
|
||||||
flex: 1;
|
|
||||||
min-width: 0;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
.rs-steps__table {
|
|
||||||
flex: 1;
|
|
||||||
min-height: 0;
|
|
||||||
}
|
|
||||||
/* 右侧工单/审批面板:与主体同底色,间距交给 ticketd 自身的内边距 */
|
|
||||||
.rs-aside {
|
|
||||||
background: #f5f7fa;
|
|
||||||
padding: 0;
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
@closed="$emit('closed')"
|
@closed="$emit('closed')"
|
||||||
>
|
>
|
||||||
<el-container>
|
<el-container>
|
||||||
<el-header style="height: auto; padding: 6px 20px 0">
|
<el-header>
|
||||||
<el-steps
|
<el-steps
|
||||||
:active="active"
|
:active="active"
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
|
|
@ -93,29 +93,30 @@
|
||||||
<!--工序!-->
|
<!--工序!-->
|
||||||
<el-main class="nopadding" v-if="active === 1">
|
<el-main class="nopadding" v-if="active === 1">
|
||||||
<el-container>
|
<el-container>
|
||||||
<el-aside class="nopadding" style="width: 55%;overflow: hidden;padding-right: 6px;">
|
<el-aside style="width: 50%;overflow: scroll;">
|
||||||
<xtFlowEditor
|
<div style="font-weight: 600;color: #303133;font-size: 16px;padding: 10px 0;position: fixed;width: 30px;">工艺路线流程图</div>
|
||||||
ref="flowEditor"
|
<scDegra
|
||||||
:routepack="routepack"
|
style="margin-top: 50px;"
|
||||||
:product-id="form.material || ''"
|
v-if="limitedWatch"
|
||||||
:product-name="form.material_name || ''"
|
ref="degraDialogs"
|
||||||
:readonly="!!(form.state && form.state !== 10)"
|
:nodes="nodes"
|
||||||
@changed="handleEditorChanged"
|
:edges="edges"
|
||||||
></xtFlowEditor>
|
:rankdir="'DL'"
|
||||||
|
>
|
||||||
|
</scDegra>
|
||||||
</el-aside>
|
</el-aside>
|
||||||
<el-main class="nopadding" style="width: 45%;overflow: auto;">
|
<el-main style="width: 50%;overflow: scroll;">
|
||||||
<el-container>
|
<el-container>
|
||||||
<el-header style="height: auto; padding: 4px 0">
|
<el-header>
|
||||||
<div class="left-panel">
|
<div class="left-panel" style="margin: 10px">
|
||||||
<el-button
|
<el-button
|
||||||
type="primary"
|
type="primary"
|
||||||
icon="el-icon-plus"
|
icon="el-icon-plus"
|
||||||
size="small"
|
|
||||||
@click="table_add"
|
@click="table_add"
|
||||||
></el-button>
|
></el-button>
|
||||||
</div>
|
</div>
|
||||||
</el-header>
|
</el-header>
|
||||||
<el-main class="nopadding">
|
<el-main>
|
||||||
<scTable
|
<scTable
|
||||||
ref="tables"
|
ref="tables"
|
||||||
:apiObj="apiObj"
|
:apiObj="apiObj"
|
||||||
|
|
@ -175,7 +176,7 @@
|
||||||
</el-main>
|
</el-main>
|
||||||
</el-container>
|
</el-container>
|
||||||
</el-main>
|
</el-main>
|
||||||
<el-footer v-if="active === 1" style="height: 44px; display: flex; align-items: center; justify-content: center; gap: 8px;">
|
<el-footer v-if="active === 1" style="text-align: center">
|
||||||
<el-button @click="handleLastStep" style="margin-right: 4px">上一步</el-button>
|
<el-button @click="handleLastStep" style="margin-right: 4px">上一步</el-button>
|
||||||
<ticketd_b :workflow_key="'routepack'" :title="form.name" :t_id="form.id" :ticket_="form.ticket_"
|
<ticketd_b :workflow_key="'routepack'" :title="form.name" :t_id="form.id" :ticket_="form.ticket_"
|
||||||
@success="$emit('closed')"></ticketd_b>
|
@success="$emit('closed')"></ticketd_b>
|
||||||
|
|
@ -184,7 +185,6 @@
|
||||||
</el-container>
|
</el-container>
|
||||||
<save-dialog
|
<save-dialog
|
||||||
v-if="dialog.save"
|
v-if="dialog.save"
|
||||||
:key="dialogSeq"
|
|
||||||
ref="saveDialog"
|
ref="saveDialog"
|
||||||
:count = "count"
|
:count = "count"
|
||||||
:routepack="routepack"
|
:routepack="routepack"
|
||||||
|
|
@ -194,14 +194,11 @@
|
||||||
</el-drawer>
|
</el-drawer>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import { defineAsyncComponent } from "vue";
|
|
||||||
import saveDialog from "./route_form.vue";
|
import saveDialog from "./route_form.vue";
|
||||||
import ticketd_b from "@/views/wf/ticketd_b.vue";
|
import ticketd_b from "@/views/wf/ticketd_b.vue";
|
||||||
// 异步加载:Vue Flow + dagre 单独分包,仅打开工艺编辑器时才下载,首屏零影响
|
|
||||||
const xtFlowEditor = defineAsyncComponent(() => import(/* webpackPrefetch: true */ "@/components/xtFlowEditor.vue"));
|
|
||||||
export default {
|
export default {
|
||||||
name: "routepack_form",
|
name: "routepack_form",
|
||||||
components: { saveDialog, ticketd_b, xtFlowEditor },
|
components: { saveDialog, ticketd_b },
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
active: 0,
|
active: 0,
|
||||||
|
|
@ -218,7 +215,6 @@ export default {
|
||||||
dialog: {
|
dialog: {
|
||||||
save: false,
|
save: false,
|
||||||
},
|
},
|
||||||
dialogSeq: 0,
|
|
||||||
fileList:[],
|
fileList:[],
|
||||||
form: {
|
form: {
|
||||||
name: "",
|
name: "",
|
||||||
|
|
@ -343,14 +339,13 @@ export default {
|
||||||
table_add() {
|
table_add() {
|
||||||
let that = this;
|
let that = this;
|
||||||
that.count = this.$refs.tables.tableData.length;
|
that.count = this.$refs.tables.tableData.length;
|
||||||
this.dialogSeq += 1;
|
console.log("count",that.count);
|
||||||
this.dialog.save = true;
|
this.dialog.save = true;
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
this.$refs.saveDialog.open("add");
|
this.$refs.saveDialog.open("add");
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
table_edit(row) {
|
table_edit(row) {
|
||||||
this.dialogSeq += 1;
|
|
||||||
this.dialog.save = true;
|
this.dialog.save = true;
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
this.$refs.saveDialog.open("edit").setData(row);
|
this.$refs.saveDialog.open("edit").setData(row);
|
||||||
|
|
@ -374,7 +369,7 @@ export default {
|
||||||
let that = this;
|
let that = this;
|
||||||
that.$API.mtm.route.delete.req(row.id).then((res) => {
|
that.$API.mtm.route.delete.req(row.id).then((res) => {
|
||||||
that.$message.success("工序步骤删除成功");
|
that.$message.success("工序步骤删除成功");
|
||||||
that.$refs.flowEditor && that.$refs.flowEditor.reload();
|
that.getDEGdatas();
|
||||||
that.$refs.tables.refresh();
|
that.$refs.tables.refresh();
|
||||||
return res;
|
return res;
|
||||||
}).catch((err) => {
|
}).catch((err) => {
|
||||||
|
|
@ -383,13 +378,10 @@ export default {
|
||||||
},
|
},
|
||||||
//本地更新数据
|
//本地更新数据
|
||||||
handleSaveSuccess() {
|
handleSaveSuccess() {
|
||||||
|
console.log("handleSaveSuccess");
|
||||||
let that = this;
|
let that = this;
|
||||||
that.$refs.tables.refresh();
|
that.$refs.tables.refresh();
|
||||||
that.$refs.flowEditor && that.$refs.flowEditor.reload();
|
that.getDEGdatas();
|
||||||
},
|
|
||||||
//画布内发生增删改 -> 同步刷新右侧表格
|
|
||||||
handleEditorChanged() {
|
|
||||||
this.$refs.tables && this.$refs.tables.refresh();
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -99,11 +99,6 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
const defaultForm = {
|
|
||||||
name: "",
|
|
||||||
location: "",
|
|
||||||
capacity: "",
|
|
||||||
};
|
|
||||||
export default {
|
export default {
|
||||||
name: "mroom",
|
name: "mroom",
|
||||||
data() {
|
data() {
|
||||||
|
|
@ -119,7 +114,11 @@ export default {
|
||||||
edit: "编辑",
|
edit: "编辑",
|
||||||
show: "查看",
|
show: "查看",
|
||||||
},
|
},
|
||||||
addForm: Object.assign({}, defaultForm),
|
addForm: {
|
||||||
|
name: "",
|
||||||
|
location: "",
|
||||||
|
capacity: "",
|
||||||
|
},
|
||||||
rules: {
|
rules: {
|
||||||
name: [{ required: true, message: "请输入会议室名称", trigger: "blur" }],
|
name: [{ required: true, message: "请输入会议室名称", trigger: "blur" }],
|
||||||
location: [{ required: true, message: "请输入地点", trigger: "blur" }],
|
location: [{ required: true, message: "请输入地点", trigger: "blur" }],
|
||||||
|
|
@ -128,10 +127,9 @@ export default {
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
//添加会议室
|
//添加工作流
|
||||||
handleAdd() {
|
handleAdd() {
|
||||||
this.type = "add";
|
this.type = "add";
|
||||||
this.addForm = Object.assign({}, defaultForm);
|
|
||||||
this.limitedVisible = true;
|
this.limitedVisible = true;
|
||||||
},
|
},
|
||||||
handleCancel() {
|
handleCancel() {
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
label-width="auto"
|
label-width="auto"
|
||||||
style="margin-top: 20px"
|
style="margin-top: 20px"
|
||||||
>
|
>
|
||||||
<el-form-item label="领料时校验是否检验(总开关,物料可单独设为免检)">
|
<el-form-item label="领料时校验是否检验">
|
||||||
<el-switch v-model="form.mes.check_test_when_do_out"></el-switch>
|
<el-switch v-model="form.mes.check_test_when_do_out"></el-switch>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-divider />
|
<el-divider />
|
||||||
|
|
@ -51,16 +51,7 @@ export default {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
submitForm() {
|
submitForm() {
|
||||||
this.saveLoading = true;
|
|
||||||
this.$API.system.config.updateInfo.req({
|
|
||||||
mes: this.form.mes,
|
|
||||||
sms: this.form.sms
|
|
||||||
}).then(() => {
|
|
||||||
this.$message.success("保存成功");
|
|
||||||
this.saveLoading = false;
|
|
||||||
}).catch(() => {
|
|
||||||
this.saveLoading = false;
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -100,7 +100,7 @@
|
||||||
</el-main>
|
</el-main>
|
||||||
<ScBind v-model="showBindBlt" :bindBtl="bindBtl" :bindType="bindType" :bindName="bindName"
|
<ScBind v-model="showBindBlt" :bindBtl="bindBtl" :bindType="bindType" :bindName="bindName"
|
||||||
:bindEmployee="bindEmployee" @success="showBindBltSuccess" @closed="showBindBltClose"></ScBind>
|
:bindEmployee="bindEmployee" @success="showBindBltSuccess" @closed="showBindBltClose"></ScBind>
|
||||||
<el-dialog append-to-body title="提前离厂" v-model="leaveVisible" width="30%">
|
<el-dialog title="提前离厂" v-model="leaveVisible" width="30%">
|
||||||
<el-form ref="dialogForm" label-width="80px">
|
<el-form ref="dialogForm" label-width="80px">
|
||||||
<el-form-item label="离厂原因">
|
<el-form-item label="离厂原因">
|
||||||
<el-input v-model="reason" type="text" clearable></el-input>
|
<el-input v-model="reason" type="text" clearable></el-input>
|
||||||
|
|
@ -112,7 +112,7 @@
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
<!-- 人员添加编辑 -->
|
<!-- 人员添加编辑 -->
|
||||||
<el-dialog append-to-body v-model="workerVisible" :title="workDialogTitle">
|
<el-dialog v-model="workerVisible" :title="workDialogTitle">
|
||||||
<el-form ref="workerForm" :model="formworker" label-width="120px">
|
<el-form ref="workerForm" :model="formworker" label-width="120px">
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :md="24" :sm="12" :xs="24">
|
<el-col :md="24" :sm="12" :xs="24">
|
||||||
|
|
|
||||||
|
|
@ -245,7 +245,6 @@ export default {
|
||||||
methods: {
|
methods: {
|
||||||
handleAdd() {
|
handleAdd() {
|
||||||
this.type = "add";
|
this.type = "add";
|
||||||
this.addForm = {};
|
|
||||||
this.limitedVisible = true;
|
this.limitedVisible = true;
|
||||||
},
|
},
|
||||||
handleCancel() {
|
handleCancel() {
|
||||||
|
|
|
||||||
|
|
@ -179,9 +179,8 @@ export default {
|
||||||
},
|
},
|
||||||
handleQuery(){
|
handleQuery(){
|
||||||
let that = this;
|
let that = this;
|
||||||
let querys0 = [{field:"wm",value:false,compare:"isnull"},{field:"data__分检_日期",compare:"isnull",value:false},{field:"data__has_key",compare:"",value:"分检_批次号"}];
|
|
||||||
let querys = [[{field:"wm",value:false,compare:"isnull"},{field:"data__分检_日期",compare:"isnull",value:false},{field:"data__has_key",compare:"",value:"分检_批次号"}]];
|
let querys = [[{field:"wm",value:false,compare:"isnull"},{field:"data__分检_日期",compare:"isnull",value:false},{field:"data__has_key",compare:"",value:"分检_批次号"}]];
|
||||||
let obj = {},obj1 = {},obj2 = {},obj3 = {},obj4 = {},obj5 = {},obj6 = {},obj7 = {};
|
let obj = {},obj1 = {},obj2 = {},obj3 = {},obj4 = {},obj5 = {};
|
||||||
obj.field = 'data__分检_批次号';
|
obj.field = 'data__分检_批次号';
|
||||||
obj.value = that.query.batch__contains;
|
obj.value = that.query.batch__contains;
|
||||||
obj.compare = '';
|
obj.compare = '';
|
||||||
|
|
@ -202,58 +201,27 @@ export default {
|
||||||
obj4.value = that.query.number__contains;
|
obj4.value = that.query.number__contains;
|
||||||
obj4.compare = 'contains';
|
obj4.compare = 'contains';
|
||||||
|
|
||||||
obj5.field = 'data__喷码_一体刀_操作人';
|
obj5.field = 'data__分检_操作人';
|
||||||
obj5.value = that.query.handler;
|
obj5.value = that.query.handler;
|
||||||
obj5.compare = '';
|
obj5.compare = '';
|
||||||
|
|
||||||
obj6.field = 'data__喷码_磨床开台_操作人';
|
|
||||||
obj6.value = that.query.handler;
|
|
||||||
obj6.compare = '';
|
|
||||||
|
|
||||||
obj7.field = 'data__光锥一体刀_操作人';
|
|
||||||
obj7.value = that.query.handler;
|
|
||||||
obj7.compare = '';
|
|
||||||
if(that.query.handler!==''&&that.query.handler!==null){
|
|
||||||
querys[1]=querys0;
|
|
||||||
querys[2]=querys0;
|
|
||||||
querys[0].push(obj5);
|
|
||||||
querys[1].push(obj6);
|
|
||||||
querys[2].push(obj7);
|
|
||||||
}
|
|
||||||
if(that.query.batch__contains!==''&&that.query.batch__contains!==null){
|
if(that.query.batch__contains!==''&&that.query.batch__contains!==null){
|
||||||
querys[0].push(obj);
|
querys[0].push(obj);
|
||||||
if(that.query.handler!==''&&that.query.handler!==null){
|
|
||||||
querys[1].push(obj);
|
|
||||||
querys[2].push(obj);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if(that.query.last_time__gte!==''&&that.query.last_time__gte!==null){
|
if(that.query.last_time__gte!==''&&that.query.last_time__gte!==null){
|
||||||
querys[0].push(obj1);
|
querys[0].push(obj1);
|
||||||
if(that.query.handler!==''&&that.query.handler!==null){
|
|
||||||
querys[1].push(obj1);
|
|
||||||
querys[2].push(obj1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if(that.query.last_time__lte!==''&&that.query.last_time__lte!==null){
|
if(that.query.last_time__lte!==''&&that.query.last_time__lte!==null){
|
||||||
querys[0].push(obj2);
|
querys[0].push(obj2);
|
||||||
if(that.query.handler!==''&&that.query.handler!==null){
|
|
||||||
querys[1].push(obj2);
|
|
||||||
querys[2].push(obj2);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if(that.query.name__contains!==''&&that.query.name__contains!==null){
|
if(that.query.name__contains!==''&&that.query.name__contains!==null){
|
||||||
querys[0].push(obj3);
|
querys[0].push(obj3);
|
||||||
if(that.query.handler!==''&&that.query.handler!==null){
|
|
||||||
querys[1].push(obj3);
|
|
||||||
querys[2].push(obj3);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if(that.query.number__contains!==''&&that.query.number__contains!==null){
|
if(that.query.number__contains!==''&&that.query.number__contains!==null){
|
||||||
querys[0].push(obj4);
|
querys[0].push(obj4);
|
||||||
if(that.query.handler!==''&&that.query.handler!==null){
|
}
|
||||||
querys[1].push(obj4);
|
if(that.query.handler!==''&&that.query.handler!==null){
|
||||||
querys[2].push(obj4);
|
querys[0].push(obj5);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
that.params.querys = querys;
|
that.params.querys = querys;
|
||||||
this.$refs.table.queryData(that.params);
|
this.$refs.table.queryData(that.params);
|
||||||
|
|
|
||||||
|
|
@ -195,7 +195,7 @@
|
||||||
</el-container>
|
</el-container>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="jsx">
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: "statistics_guan",
|
name: "statistics_guan",
|
||||||
data() {
|
data() {
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@
|
||||||
<div class="left-panel"></div>
|
<div class="left-panel"></div>
|
||||||
<div class="right-panel">
|
<div class="right-panel">
|
||||||
<xtSelect
|
<xtSelect
|
||||||
v-if="activeName=='shengchan'"
|
|
||||||
:apiObj="apiObj"
|
:apiObj="apiObj"
|
||||||
v-model="query.user_name"
|
v-model="query.user_name"
|
||||||
:valueField="'name'"
|
:valueField="'name'"
|
||||||
|
|
@ -37,189 +36,50 @@
|
||||||
</div>
|
</div>
|
||||||
</el-header>
|
</el-header>
|
||||||
<el-main class="nopadding">
|
<el-main class="nopadding">
|
||||||
<el-tabs type="border-card" v-model="activeName" @tab-click="tabsClick" style="height: 100%;" lazy>
|
<scTable
|
||||||
<el-tab-pane name="shengchan" label="生产统计" style="height: 100%;" key="shengchan">
|
ref="table"
|
||||||
<el-container v-if="activeName=='shengchan'">
|
:data="tableData"
|
||||||
<el-main>
|
id="exportDiv"
|
||||||
<scTable
|
row-key="id"
|
||||||
ref="table"
|
hidePagination
|
||||||
:data="tableData"
|
hideDo
|
||||||
id="exportDiv"
|
stripe
|
||||||
row-key="id"
|
|
||||||
hidePagination
|
|
||||||
stripe
|
|
||||||
>
|
|
||||||
<el-table-column label="日期" prop="日期" width="100" fixed="left">
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="操作人" prop="操作人" width="100" fixed="left">
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column v-for="item in lists" :key="item" :label="item.text" align="center">
|
|
||||||
<el-table-column v-for="item1 in item.value" :key="item1" :label="item1">
|
|
||||||
<template #default="scope">
|
|
||||||
<el-input v-if="scope.row.indexs==0&&scope.row" v-model="scope.row[item.text+'_'+item1]" @change="xishuChange"></el-input>
|
|
||||||
<span v-if="scope.row.indexs!==0&&scope.row">{{ scope.row[item.text+'_'+item1] }}</span>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="其它工时" prop="其它工时">
|
|
||||||
<template #default="scope">
|
|
||||||
<el-input v-if="scope.row.indexs!==0&&scope.row" v-model="scope.row.time_other" @change="xishuChange"></el-input>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="总工时" prop="总工时">
|
|
||||||
<template #default="scope">
|
|
||||||
<el-input v-if="scope.row.indexs!==0&&scope.row" v-model="scope.row.time_all"></el-input>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="备注" prop="备注">
|
|
||||||
<template #default="scope">
|
|
||||||
<el-input v-if="scope.row.indexs!==0&&scope.row" v-model="scope.row.note"></el-input>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</scTable>
|
|
||||||
|
|
||||||
<el-drawer v-model="visible" :title="userName+'板段列表'" size="50%" direction="rtl" append-to-body destroy-on-close>
|
|
||||||
<el-card shadow="never">
|
|
||||||
<div v-for="(item,index) in detailRow" :key="item" style="height:22px;border-bottom: 1px solid #efefef;">
|
|
||||||
<span style="margin-right:10px;width: 18px;display: inline-block;">{{ index+1 }} </span>
|
|
||||||
{{ item }}
|
|
||||||
</div>
|
|
||||||
</el-card>
|
|
||||||
</el-drawer>
|
|
||||||
</el-main>
|
|
||||||
</el-container>
|
|
||||||
</el-tab-pane>
|
|
||||||
<el-tab-pane name="gongzhuang" label="工装统计" style="height: 100%;" key="gongzhuang">
|
|
||||||
<el-container v-if="activeName=='gongzhuang'">
|
|
||||||
<el-main>
|
|
||||||
<scTable
|
|
||||||
ref="table"
|
|
||||||
:data="tableData"
|
|
||||||
id="exportDiv"
|
|
||||||
row-key="id"
|
|
||||||
hidePagination
|
|
||||||
stripe
|
|
||||||
>
|
|
||||||
<el-table-column type="index" width="50" fixed="left"/>
|
|
||||||
<el-table-column label="工装编号" prop="工装编号" :filters="userFilters" :filter-method="filterUser" filter-placement="bottom-end">
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="物料名" prop="物料名" :filters="nameFilters" :filter-method="filterName" filter-placement="bottom-end">
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="总数">
|
|
||||||
<template #default="scope">
|
|
||||||
<span @click="handleClick(scope.row)" style="color:#0052d9;">{{ scope.row.总切片数 }}</span>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</scTable>
|
|
||||||
</el-main>
|
|
||||||
</el-container>
|
|
||||||
</el-tab-pane>
|
|
||||||
<el-tab-pane name="renyuan" label="开台人员统计" style="height: 100%;" key="renyuan">
|
|
||||||
<el-container v-if="activeName=='renyuan'">
|
|
||||||
<el-main>
|
|
||||||
<scTable
|
|
||||||
ref="table"
|
|
||||||
:data="tableData"
|
|
||||||
id="exportDiv"
|
|
||||||
row-key="id"
|
|
||||||
hidePagination
|
|
||||||
stripe
|
|
||||||
>
|
|
||||||
<el-table-column type="index" width="50" fixed="left"/>
|
|
||||||
<el-table-column label="开台人" prop="开台人员姓名" :filters="userFilters" :filter-method="filterUser3" filter-placement="bottom-end">
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="物料名" prop="物料名" :filters="nameFilters" :filter-method="filterName" filter-placement="bottom-end">
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="总数" prop="总切片数">
|
|
||||||
<template #default="scope">
|
|
||||||
<span @click="handleClick(scope.row)" style="color:#0052d9;">{{ scope.row.总切片数 }}</span>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</scTable>
|
|
||||||
</el-main>
|
|
||||||
</el-container>
|
|
||||||
</el-tab-pane>
|
|
||||||
</el-tabs>
|
|
||||||
<el-drawer
|
|
||||||
v-model="boardVisible"
|
|
||||||
:title="boardTitle"
|
|
||||||
size="80%"
|
|
||||||
direction="rtl"
|
|
||||||
append-to-body
|
|
||||||
destroy-on-close
|
|
||||||
>
|
>
|
||||||
<div class="board-drawer-body">
|
<el-table-column label="日期" prop="日期" width="100" fixed="left">
|
||||||
<div class="board-drawer-table">
|
</el-table-column>
|
||||||
<el-table :data="boardList" border stripe height="100%" style="width: 100%;">
|
<el-table-column label="操作人" prop="操作人" width="100" fixed="left">
|
||||||
<el-table-column type="index" label="序号" width="60" />
|
</el-table-column>
|
||||||
<el-table-column label="板段号" prop="板段号" />
|
<el-table-column v-for="item in lists" :key="item" :label="item.text" align="center">
|
||||||
<el-table-column label="像位移" prop="像位移" />
|
<el-table-column v-for="item1 in item.value" :key="item1" :label="item1">
|
||||||
</el-table>
|
<template #default="scope">
|
||||||
</div>
|
<el-input v-if="scope.row.indexs==0&&scope.row" v-model="scope.row[item.text+'_'+item1]" @change="xishuChange"></el-input>
|
||||||
<div class="board-drawer-chart">
|
<span v-if="scope.row.indexs!==0&&scope.row">{{ scope.row[item.text+'_'+item1] }}</span>
|
||||||
<div class="board-chart-scroll">
|
</template>
|
||||||
<scEcharts
|
</el-table-column>
|
||||||
:option="chartOption"
|
</el-table-column>
|
||||||
:style="{ width: chartWidth + 'px', height: '100%' }"
|
<el-table-column label="其它工时" prop="其它工时">
|
||||||
/>
|
<template #default="scope">
|
||||||
</div>
|
<el-input v-if="scope.row.indexs!==0&&scope.row" v-model="scope.row.time_other" @change="xishuChange"></el-input>
|
||||||
</div>
|
</template>
|
||||||
</div>
|
</el-table-column>
|
||||||
</el-drawer>
|
<el-table-column label="总工时" prop="总工时">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-input v-if="scope.row.indexs!==0&&scope.row" v-model="scope.row.time_all"></el-input>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="备注" prop="备注">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-input v-if="scope.row.indexs!==0&&scope.row" v-model="scope.row.note"></el-input>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</scTable>
|
||||||
</el-main>
|
</el-main>
|
||||||
</el-container>
|
</el-container>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import scEcharts from "@/components/scEcharts";
|
|
||||||
export default {
|
export default {
|
||||||
name: "workerTimes",
|
name: "workerTimes",
|
||||||
components: { scEcharts },
|
|
||||||
computed: {
|
|
||||||
chartWidth() {
|
|
||||||
const perPoint = 22;
|
|
||||||
const minWidth = 600;
|
|
||||||
return Math.max(minWidth, (this.boardList.length || 1) * perPoint);
|
|
||||||
},
|
|
||||||
chartOption() {
|
|
||||||
const xs = this.boardList.map(i => i.板段号);
|
|
||||||
const ys = this.boardList.map(i => (i.像位移 == null ? null : Number(i.像位移)));
|
|
||||||
return {
|
|
||||||
tooltip: { trigger: 'axis' },
|
|
||||||
grid: { left: 50, right: 20, top: 30, bottom: 100 },
|
|
||||||
xAxis: {
|
|
||||||
type: 'category',
|
|
||||||
data: xs,
|
|
||||||
axisLabel: { rotate: 85, interval: 0, fontSize: 11 }
|
|
||||||
},
|
|
||||||
yAxis: { type: 'value', name: '像位移' },
|
|
||||||
series: [{
|
|
||||||
name: '像位移',
|
|
||||||
type: 'line',
|
|
||||||
data: ys,
|
|
||||||
connectNulls: false,
|
|
||||||
symbol: 'circle',
|
|
||||||
symbolSize: 6,
|
|
||||||
markLine: {
|
|
||||||
symbol: 'none',
|
|
||||||
silent: true,
|
|
||||||
data: [
|
|
||||||
{
|
|
||||||
yAxis: 100,
|
|
||||||
lineStyle: { color: '#f5a623', width: 1.5, type: 'dashed' },
|
|
||||||
label: { formatter: '标准 100', position: 'insideEndTop', color: '#f5a623' }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
yAxis: 200,
|
|
||||||
lineStyle: { color: '#f5222d', width: 1.5, type: 'dashed' },
|
|
||||||
label: { formatter: '标准 200', position: 'insideEndTop', color: '#f5222d' }
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
};
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
query:{
|
query:{
|
||||||
|
|
@ -233,17 +93,6 @@ export default {
|
||||||
lists:[],
|
lists:[],
|
||||||
mgruops:[],
|
mgruops:[],
|
||||||
tableData:[],
|
tableData:[],
|
||||||
userFilters:[],
|
|
||||||
filterUsers:[],
|
|
||||||
nameFilters:[],
|
|
||||||
filterNames:[],
|
|
||||||
visible:false,
|
|
||||||
userName:'',
|
|
||||||
boardVisible:false,
|
|
||||||
boardTitle:'',
|
|
||||||
boardList:[],
|
|
||||||
code:'lineDay_p',
|
|
||||||
activeName:'shengchan',
|
|
||||||
apiObj: this.$API.system.user.list,
|
apiObj: this.$API.system.user.list,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
@ -255,12 +104,6 @@ export default {
|
||||||
that.getData();
|
that.getData();
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
tabsClick(){
|
|
||||||
let that = this;
|
|
||||||
that.$nextTick(()=>{
|
|
||||||
that.getData();
|
|
||||||
})
|
|
||||||
},
|
|
||||||
getData(){
|
getData(){
|
||||||
let that = this;
|
let that = this;
|
||||||
that.lists = [];
|
that.lists = [];
|
||||||
|
|
@ -270,85 +113,51 @@ export default {
|
||||||
that.coefficient = [];
|
that.coefficient = [];
|
||||||
let params = {};
|
let params = {};
|
||||||
params.query = that.query;
|
params.query = that.query;
|
||||||
let code = that.activeName=='shengchan'?'lineDay_p':that.activeName=='gongzhuang'?'product_toolings':'product_kaitairen';
|
that.$API.bi.dataset.exec.req('lineDay_p', params).then((res) => {
|
||||||
that.$API.bi.dataset.exec.req(code, params).then((res) => {
|
|
||||||
let data = res.data2.ds0;
|
let data = res.data2.ds0;
|
||||||
let coefficient = [];
|
let coefficient = [];
|
||||||
if(data.length>0){
|
if(data.length>0){
|
||||||
if(that.activeName=='shengchan'){
|
|
||||||
data.forEach(item=>{
|
|
||||||
let obj = item.工序物料生产数?JSON.parse(item.工序物料生产数):{};
|
|
||||||
for(let key in obj){
|
|
||||||
if(coefficient.indexOf(key)<0){
|
|
||||||
coefficient.push(key);
|
|
||||||
}
|
|
||||||
let mgroup = key.split('_')[0];
|
|
||||||
let pname = key.split('_')[1];
|
|
||||||
if(that.mgruops.indexOf(mgroup)<0){
|
|
||||||
that.mgruops.push(mgroup);
|
|
||||||
that.lists.push({text:mgroup,value:[pname]});
|
|
||||||
}else{
|
|
||||||
var index = that.mgruops.indexOf(mgroup);
|
|
||||||
if(that.lists[index].value.indexOf(pname)<0){
|
|
||||||
that.lists[index].value.push(pname);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
item[key]= obj[key];
|
|
||||||
item[pname]= obj[key];
|
|
||||||
}
|
|
||||||
})
|
|
||||||
that.coefficient = coefficient;
|
|
||||||
let item0 = {日期:'系数',操作人:'',indexs:0};
|
|
||||||
coefficient.forEach(cof=>{
|
|
||||||
item0[cof]= 1;
|
|
||||||
})
|
|
||||||
data.unshift(item0);
|
|
||||||
data.forEach(item1 => {
|
|
||||||
item1.time_other=0;
|
|
||||||
let all = 0;
|
|
||||||
coefficient.forEach(item2 => {
|
|
||||||
if(item1[item2]){
|
|
||||||
all = all+ Number(item1[item2])
|
|
||||||
}
|
|
||||||
})
|
|
||||||
item1.time_all = all;
|
|
||||||
})
|
|
||||||
}
|
|
||||||
let userList = [],users = [];
|
|
||||||
let nameList = [],names = [];
|
|
||||||
data.forEach(item=>{
|
data.forEach(item=>{
|
||||||
if(that.activeName=='gongzhuang'){
|
let obj = item.工序物料生产数?JSON.parse(item.工序物料生产数):{};
|
||||||
if(users.indexOf(item.工装编号)>-1){}else{
|
for(let key in obj){
|
||||||
users.push(item.工装编号);
|
if(coefficient.indexOf(key)<0){
|
||||||
userList.push({text:item.工装编号,value:item.工装编号})
|
coefficient.push(key);
|
||||||
}
|
}
|
||||||
}else if(that.activeName=='renyuan'){
|
let mgroup = key.split('_')[0];
|
||||||
if(users.indexOf(item.开台人员姓名)>-1){}else{
|
let pname = key.split('_')[1];
|
||||||
users.push(item.开台人员姓名);
|
if(that.mgruops.indexOf(mgroup)<0){
|
||||||
userList.push({text:item.开台人员姓名,value:item.开台人员姓名})
|
that.mgruops.push(mgroup);
|
||||||
|
that.lists.push({text:mgroup,value:[pname]});
|
||||||
|
}else{
|
||||||
|
var index = that.mgruops.indexOf(mgroup);
|
||||||
|
if(that.lists[index].value.indexOf(pname)<0){
|
||||||
|
that.lists[index].value.push(pname);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
item[key]= obj[key];
|
||||||
|
item[pname]= obj[key];
|
||||||
}
|
}
|
||||||
if(names.indexOf(item.物料名)>-1){}else{
|
})
|
||||||
names.push(item.物料名);
|
that.coefficient = coefficient;
|
||||||
nameList.push({text:item.物料名,value:item.物料名})
|
let item0 = {日期:'系数',操作人:'',indexs:0};
|
||||||
}
|
coefficient.forEach(cof=>{
|
||||||
that.userFilters = userList;
|
item0[cof]= 1;
|
||||||
that.nameFilters = nameList;
|
})
|
||||||
|
data.unshift(item0);
|
||||||
|
data.forEach(item1 => {
|
||||||
|
item1.time_other=0;
|
||||||
|
let all = 0;
|
||||||
|
coefficient.forEach(item2 => {
|
||||||
|
if(item1[item2]){
|
||||||
|
all = all+ Number(item1[item2])
|
||||||
|
}
|
||||||
|
})
|
||||||
|
item1.time_all = all;
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
that.tableData = data;
|
that.tableData = data;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
filterUser(value, row) {
|
|
||||||
return row.工装编号 == value;
|
|
||||||
},
|
|
||||||
filterUser3(value, row) {
|
|
||||||
return row.开台人员姓名 == value;
|
|
||||||
},
|
|
||||||
filterName(value, row) {
|
|
||||||
return row.物料名 == value;
|
|
||||||
},
|
|
||||||
|
|
||||||
xishuChange(){
|
xishuChange(){
|
||||||
let that = this;
|
let that = this;
|
||||||
that.tableData.forEach((item1,index1) => {
|
that.tableData.forEach((item1,index1) => {
|
||||||
|
|
@ -377,16 +186,6 @@ export default {
|
||||||
deptChange(){
|
deptChange(){
|
||||||
this.getData();
|
this.getData();
|
||||||
},
|
},
|
||||||
handleClick(row){
|
|
||||||
let that = this;
|
|
||||||
let detail = row.板段明细;
|
|
||||||
if(typeof detail === 'string'){
|
|
||||||
try{ detail = JSON.parse(detail); }catch(e){ detail = []; }
|
|
||||||
}
|
|
||||||
that.boardList = Array.isArray(detail) ? detail : [];
|
|
||||||
that.boardTitle = (row.工装编号 || row.开台人员姓名 || '') + ' 板段列表';
|
|
||||||
that.boardVisible = true;
|
|
||||||
},
|
|
||||||
handleQuery(){
|
handleQuery(){
|
||||||
let that = this;
|
let that = this;
|
||||||
that.getData();
|
that.getData();
|
||||||
|
|
@ -396,26 +195,4 @@ export default {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.board-drawer-body {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
height: 100%;
|
|
||||||
gap: 8px;
|
|
||||||
}
|
|
||||||
.board-drawer-table {
|
|
||||||
flex: 0 0 60%;
|
|
||||||
min-height: 0;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
.board-drawer-chart {
|
|
||||||
flex: 0 0 40%;
|
|
||||||
min-height: 0;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
.board-chart-scroll {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
overflow-x: auto;
|
|
||||||
overflow-y: hidden;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -327,7 +327,7 @@
|
||||||
</el-container>
|
</el-container>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="jsx">
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: "statistics_guan",
|
name: "statistics_guan",
|
||||||
data() {
|
data() {
|
||||||
|
|
|
||||||
|
|
@ -1,72 +0,0 @@
|
||||||
<!--
|
|
||||||
物料仓库合格库存统计
|
|
||||||
数据来源: BI 数据集 code=materialCount2 (POST api/bi/dataset/{code}/exec)
|
|
||||||
抽自 factory_web/src/views/inm/good.vue 的"物料仓库合格库存统计"抽屉内容
|
|
||||||
-->
|
|
||||||
<template>
|
|
||||||
<el-container v-loading="loading">
|
|
||||||
<el-header style="display: flex; align-items: center;">
|
|
||||||
<span style="font-weight: 600;">物料仓库合格库存统计</span>
|
|
||||||
<el-text style="margin-left: 16px;">仓库总数:{{ totalCount }}</el-text>
|
|
||||||
<el-button type="primary" icon="el-icon-refresh" @click="getProductCount" :loading="loading" style="margin-left: auto;">刷新</el-button>
|
|
||||||
</el-header>
|
|
||||||
<el-container>
|
|
||||||
<el-header style="height: 40%;">
|
|
||||||
<scTable :data="tableData" hideDo hidePagination row-key="material_name" style="width: 100%;">
|
|
||||||
<el-table-column label="物料名" prop="material_name"></el-table-column>
|
|
||||||
<el-table-column label="数量" prop="count"></el-table-column>
|
|
||||||
</scTable>
|
|
||||||
</el-header>
|
|
||||||
<el-main>
|
|
||||||
<scEcharts :option="echartsOptions" height="100%"></scEcharts>
|
|
||||||
</el-main>
|
|
||||||
</el-container>
|
|
||||||
</el-container>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import scEcharts from "@/components/scEcharts/index.vue";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "goodStatistic",
|
|
||||||
components: { scEcharts },
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
loading: false,
|
|
||||||
tableData: [],
|
|
||||||
totalCount: 0,
|
|
||||||
echartsOptions: {},
|
|
||||||
};
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
this.getProductCount();
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
getProductCount() {
|
|
||||||
let that = this;
|
|
||||||
let query = {
|
|
||||||
material_types: "10",
|
|
||||||
select_material: "material.name as material_name",
|
|
||||||
groupby_material: "material.name",
|
|
||||||
};
|
|
||||||
that.loading = true;
|
|
||||||
that.$API.bi.dataset.exec
|
|
||||||
.req("materialCount2", { query: query })
|
|
||||||
.then((res) => {
|
|
||||||
let data = (that.tableData = res.data2.ds0 || []);
|
|
||||||
let totalCount = 0;
|
|
||||||
data.forEach((item) => {
|
|
||||||
totalCount += Number(item.count) || 0;
|
|
||||||
});
|
|
||||||
that.totalCount = totalCount;
|
|
||||||
if (res.echart_options) {
|
|
||||||
that.echartsOptions = JSON.parse(res.echart_options);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.finally(() => {
|
|
||||||
that.loading = false;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
<!--
|
<!--
|
||||||
物料保障车间-仓库数量汇总表
|
物料保障车间-仓库数量汇总表
|
||||||
数据来源: BI 数据集 code=wh_material_summary (POST api/bi/dataset/{code}/exec)
|
数据来源: BI 数据集 code=wh_material_summary (POST api/bi/dataset/{code}/exec)
|
||||||
返回 res.data2.ds0~ds4, 分组维度为 material.model(型号)
|
返回 res.data2.ds0~ds3, 分组维度为 material.model(型号)
|
||||||
菜单/路由由后端下发, component 填 statistics/material_wh_summary
|
菜单/路由由后端下发, component 填 statistics/material_wh_summary
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
|
|
@ -25,13 +25,15 @@
|
||||||
|
|
||||||
<el-main id="elMain" v-loading="loading">
|
<el-main id="elMain" v-loading="loading">
|
||||||
<!-- KPI 概览 -->
|
<!-- KPI 概览 -->
|
||||||
<div class="kpi-grid">
|
<el-row :gutter="15" style="margin-bottom: 15px;">
|
||||||
<el-card v-for="k in kpiList" :key="k.label" shadow="hover" class="kpi-card" :style="{ borderLeft: '4px solid ' + k.color }">
|
<el-col :md="6" :sm="12" v-for="k in kpiList" :key="k.label">
|
||||||
<div class="kpi-label">{{ k.label }} · 现有库存合计</div>
|
<el-card shadow="hover" class="kpi-card" :style="{ borderLeft: '4px solid ' + k.color }">
|
||||||
<div class="kpi-value" :style="{ color: k.color }">{{ fmtNum(k.total) }}</div>
|
<div class="kpi-label">{{ k.label }} · 现有库存合计</div>
|
||||||
<div class="kpi-sub">覆盖 {{ k.count }} 个型号</div>
|
<div class="kpi-value" :style="{ color: k.color }">{{ fmtNum(k.total) }}</div>
|
||||||
</el-card>
|
<div class="kpi-sub">覆盖 {{ k.count }} 个型号</div>
|
||||||
</div>
|
</el-card>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
<!-- 库存量对比图 -->
|
<!-- 库存量对比图 -->
|
||||||
<el-card shadow="never" style="margin-bottom: 15px;">
|
<el-card shadow="never" style="margin-bottom: 15px;">
|
||||||
|
|
@ -101,18 +103,6 @@
|
||||||
</el-table>
|
</el-table>
|
||||||
</el-card>
|
</el-card>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
<el-col :lg="12">
|
|
||||||
<el-card shadow="never" class="rpt-card">
|
|
||||||
<template #header><b>半成品库周数据</b><span class="hd-tip">(入库=采购入库+生产入库 / 出库=生产领料)</span></template>
|
|
||||||
<el-table :data="ds4" border stripe size="small" show-summary :summary-method="sumRow">
|
|
||||||
<el-table-column label="型号" prop="型号" width="110" />
|
|
||||||
<el-table-column label="入库数据" prop="入库数据" align="right" :formatter="numCell" />
|
|
||||||
<el-table-column label="出库数据" prop="出库数据" align="right" :formatter="numCell" />
|
|
||||||
<el-table-column label="现有库存" prop="现有库存" align="right" :formatter="numCell" />
|
|
||||||
</el-table>
|
|
||||||
</el-card>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
<!-- 设置安全库存上下限 -->
|
<!-- 设置安全库存上下限 -->
|
||||||
|
|
@ -146,7 +136,6 @@ import scEcharts from "@/components/scEcharts/index.vue";
|
||||||
const BLOCKS = [
|
const BLOCKS = [
|
||||||
{ key: "原料", color: "#409EFF" },
|
{ key: "原料", color: "#409EFF" },
|
||||||
{ key: "成品", color: "#67C23A" },
|
{ key: "成品", color: "#67C23A" },
|
||||||
{ key: "半成品", color: "#B37FEB" },
|
|
||||||
{ key: "白玻", color: "#E6A23C" },
|
{ key: "白玻", color: "#E6A23C" },
|
||||||
{ key: "黑玻", color: "#909399" },
|
{ key: "黑玻", color: "#909399" },
|
||||||
];
|
];
|
||||||
|
|
@ -162,7 +151,6 @@ export default {
|
||||||
ds1: [],
|
ds1: [],
|
||||||
ds2: [],
|
ds2: [],
|
||||||
ds3: [],
|
ds3: [],
|
||||||
ds4: [],
|
|
||||||
safeDialog: {
|
safeDialog: {
|
||||||
visible: false,
|
visible: false,
|
||||||
saving: false,
|
saving: false,
|
||||||
|
|
@ -279,7 +267,6 @@ export default {
|
||||||
this.ds1 = d.ds1 || [];
|
this.ds1 = d.ds1 || [];
|
||||||
this.ds2 = d.ds2 || [];
|
this.ds2 = d.ds2 || [];
|
||||||
this.ds3 = d.ds3 || [];
|
this.ds3 = d.ds3 || [];
|
||||||
this.ds4 = d.ds4 || [];
|
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
|
|
@ -348,19 +335,8 @@ export default {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.kpi-grid {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(5, 1fr);
|
|
||||||
gap: 15px;
|
|
||||||
margin-bottom: 15px;
|
|
||||||
}
|
|
||||||
@media (max-width: 992px) {
|
|
||||||
.kpi-grid {
|
|
||||||
grid-template-columns: repeat(2, 1fr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.kpi-card {
|
.kpi-card {
|
||||||
margin-bottom: 0;
|
margin-bottom: 8px;
|
||||||
}
|
}
|
||||||
.kpi-label {
|
.kpi-label {
|
||||||
color: #909399;
|
color: #909399;
|
||||||
|
|
@ -37,7 +37,6 @@
|
||||||
<el-main id="elMain">
|
<el-main id="elMain">
|
||||||
<el-row :gutter="15">
|
<el-row :gutter="15">
|
||||||
<table class="tables" border="1" cellspacing="0">
|
<table class="tables" border="1" cellspacing="0">
|
||||||
<tbody>
|
|
||||||
<tr>
|
<tr>
|
||||||
<th class="tableTh tableHead" colspan="15">库存统计</th>
|
<th class="tableTh tableHead" colspan="15">库存统计</th>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
@ -205,12 +204,10 @@
|
||||||
<td class="tableTd">外扫未抛光</td>
|
<td class="tableTd">外扫未抛光</td>
|
||||||
<td class="tableTd"></td>
|
<td class="tableTd"></td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
|
||||||
</table>
|
</table>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-row :gutter="15">
|
<el-row :gutter="15">
|
||||||
<table class="tables" border="1" cellspacing="0">
|
<table class="tables" border="1" cellspacing="0">
|
||||||
<tbody>
|
|
||||||
<tr>
|
<tr>
|
||||||
<th class="tableTh tableHead" colspan="15">扫边车间数据汇总</th>
|
<th class="tableTh tableHead" colspan="15">扫边车间数据汇总</th>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
@ -361,7 +358,6 @@
|
||||||
<td class="tableTd">外扫未抛光</td>
|
<td class="tableTd">外扫未抛光</td>
|
||||||
<td class="tableTd"></td>
|
<td class="tableTd"></td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
|
||||||
</table>
|
</table>
|
||||||
</el-row>
|
</el-row>
|
||||||
</el-main>
|
</el-main>
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<span
|
<span
|
||||||
v-if="scope.row.week_esitimate_consume && scope.row.week_esitimate_consume !== null">
|
v-if="scope.row.week_esitimate_consume && scope.row.week_esitimate_consume !== null">
|
||||||
{{ Math.floor(scope.row.count / scope.row.week_esitimate_consume) * 7 }}
|
{{ Math.floor(scope.row.count_mb / scope.row.week_esitimate_consume) * 7 }}
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
@ -337,20 +337,12 @@ export default {
|
||||||
this.echartsOptions = JSON.parse(res.echart_options);
|
this.echartsOptions = JSON.parse(res.echart_options);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}else if(that.params.type==30){
|
|
||||||
this.$API.bi.dataset.exec.req("materialCount2", {query:query2 }).then((res) => {
|
|
||||||
if (res.echart_options) {
|
|
||||||
this.echartsOptions = JSON.parse(res.echart_options);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}else if(that.params.type==40){
|
}else if(that.params.type==40){
|
||||||
this.$API.bi.dataset.exec.req("helpso_cate", {}).then((res) => {
|
this.$API.bi.dataset.exec.req("helpso_cate", {}).then((res) => {
|
||||||
if (res.echart_options) {
|
if (res.echart_options) {
|
||||||
this.echartsOptions = JSON.parse(res.echart_options);
|
this.echartsOptions = JSON.parse(res.echart_options);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}else{
|
|
||||||
that.echartsOptions = null;
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
//更改周预估用量
|
//更改周预估用量
|
||||||
|
|
|
||||||
|
|
@ -33,11 +33,17 @@
|
||||||
<el-table-column label="版型" prop="版型">
|
<el-table-column label="版型" prop="版型">
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="7号">
|
<el-table-column label="7号">
|
||||||
<el-table-column label="合格数" prop="合格数">
|
<el-table-column
|
||||||
|
label="合格数"
|
||||||
|
prop="合格数"
|
||||||
|
>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="8号">
|
<el-table-column label="8号">
|
||||||
<el-table-column label="仓库库存" prop="仓库库存">
|
<el-table-column
|
||||||
|
label="仓库库存"
|
||||||
|
prop="仓库库存"
|
||||||
|
>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="6号">
|
<el-table-column label="6号">
|
||||||
|
|
@ -47,7 +53,10 @@
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="粘头" prop="粘头">
|
<el-table-column label="粘头" prop="粘头">
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="粗中细" prop="粗中细">
|
<el-table-column
|
||||||
|
label="粗中细"
|
||||||
|
prop="粗中细"
|
||||||
|
>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="抛光" prop="抛光">
|
<el-table-column label="抛光" prop="抛光">
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
@ -84,12 +93,18 @@
|
||||||
<el-table-column label="规格" prop="规格">
|
<el-table-column label="规格" prop="规格">
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="10号">
|
<el-table-column label="10号">
|
||||||
<el-table-column label="合格数" prop="合格数">
|
<el-table-column
|
||||||
|
label="合格数"
|
||||||
|
prop="合格数"
|
||||||
|
>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="8号">
|
<el-table-column label="8号">
|
||||||
<!-- 仓库库存加车间未退火数 -->
|
<!-- 仓库库存加车间未退火数 -->
|
||||||
<el-table-column label="库存" prop="仓库库存">
|
<el-table-column
|
||||||
|
label="库存"
|
||||||
|
prop="仓库库存"
|
||||||
|
>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="退火" prop="退火">
|
<el-table-column label="退火" prop="退火">
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
@ -266,7 +281,6 @@ export default {
|
||||||
//棒数据
|
//棒数据
|
||||||
getDataB(data,saleData) {
|
getDataB(data,saleData) {
|
||||||
let that = this;
|
let that = this;
|
||||||
that.tableData11 = [];
|
|
||||||
let models = [],dataArr = [];
|
let models = [],dataArr = [];
|
||||||
//按版型(型号)分组
|
//按版型(型号)分组
|
||||||
data.forEach((item) => {
|
data.forEach((item) => {
|
||||||
|
|
@ -348,46 +362,14 @@ export default {
|
||||||
obj.成品库;
|
obj.成品库;
|
||||||
that.tableData11[index] = obj;
|
that.tableData11[index] = obj;
|
||||||
});
|
});
|
||||||
saleData.forEach((item) => {
|
|
||||||
let model = "";
|
|
||||||
if (item.型号.indexOf("+") > -1) {
|
|
||||||
model = item.型号.split("+")[0];
|
|
||||||
} else {
|
|
||||||
model = item.型号;
|
|
||||||
}
|
|
||||||
let index = models.indexOf(model);
|
|
||||||
if (index > -1) {
|
|
||||||
that.tableData11[index].检验合格数 += item.数量;
|
|
||||||
} else {
|
|
||||||
models.push(model);
|
|
||||||
that.tableData11.push({
|
|
||||||
版型: model,
|
|
||||||
合格数: 0,
|
|
||||||
仓库库存: 0,
|
|
||||||
库存: 0,
|
|
||||||
平头: 0,
|
|
||||||
粘头: 0,
|
|
||||||
粗中细: 0,
|
|
||||||
抛光: 0,
|
|
||||||
开槽: 0,
|
|
||||||
配管: 0,
|
|
||||||
成品库: 0,
|
|
||||||
合计: 0,
|
|
||||||
中检合格数: 0,
|
|
||||||
检验合格数: item.数量,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
})
|
|
||||||
that.models_b = models;
|
that.models_b = models;
|
||||||
that.getCountOk('b',models);
|
that.getCountOk('b',models);
|
||||||
},
|
},
|
||||||
//管数据
|
//管数据
|
||||||
getDataG(data,saleData) {
|
getDataG(data,saleData) {
|
||||||
let that = this;
|
let that = this;
|
||||||
that.tableData22 = [];
|
|
||||||
let models = [],
|
let models = [],
|
||||||
modelArr = [];
|
modelArr = [];
|
||||||
let modelsspec = [];
|
|
||||||
//modelArr按型号分组
|
//modelArr按型号分组
|
||||||
data.forEach((item) => {
|
data.forEach((item) => {
|
||||||
let index = 0;
|
let index = 0;
|
||||||
|
|
@ -435,6 +417,7 @@ export default {
|
||||||
});
|
});
|
||||||
//specArr已将同型号的数组中按规格分组
|
//specArr已将同型号的数组中按规格分组
|
||||||
specArr.forEach((item3, index3) => {
|
specArr.forEach((item3, index3) => {
|
||||||
|
let modelsspec = [];
|
||||||
item3.forEach((item4) => {
|
item3.forEach((item4) => {
|
||||||
let obj = {
|
let obj = {
|
||||||
版型: "",
|
版型: "",
|
||||||
|
|
@ -499,42 +482,19 @@ export default {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
saleData.forEach((item) => {
|
saleData.forEach((item) => {
|
||||||
let model = "", spec = "";
|
let index = 0;
|
||||||
if (item.型号 && item.型号.indexOf("+") > -1) {
|
if (item.型号.indexOf("+") > -1) {
|
||||||
model = item.型号.split("+")[1];
|
let model = item.型号.split("+")[1];
|
||||||
|
index = models.indexOf(model);
|
||||||
} else {
|
} else {
|
||||||
model = item.型号 || "";
|
index = models.indexOf(item.型号);
|
||||||
}
|
}
|
||||||
if (item.规格 && item.规格.indexOf("+") > -1) {
|
|
||||||
spec = item.规格.split("+")[1];
|
|
||||||
} else {
|
|
||||||
spec = item.规格 || "";
|
|
||||||
}
|
|
||||||
let msitem = model + spec;
|
|
||||||
let index = modelsspec.indexOf(msitem);
|
|
||||||
if (index > -1) {
|
if (index > -1) {
|
||||||
that.tableData22[index].检验合格数 += item.数量;
|
that.tableData22[index].检验合格数=item.数量;
|
||||||
} else {
|
|
||||||
modelsspec.push(msitem);
|
|
||||||
that.tableData22.push({
|
|
||||||
版型: model,
|
|
||||||
规格: spec,
|
|
||||||
合格数: 0,
|
|
||||||
仓库库存: 0,
|
|
||||||
退火: 0,
|
|
||||||
库存: 0,
|
|
||||||
开槽: 0,
|
|
||||||
倒角: 0,
|
|
||||||
配棒: 0,
|
|
||||||
成品库: 0,
|
|
||||||
合计: 0,
|
|
||||||
中检合格数: 0,
|
|
||||||
检验合格数: item.数量,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
that.models_g = modelsspec;
|
that.models_g = models;
|
||||||
that.getCountOk('g',modelsspec);
|
that.getCountOk('g',models);
|
||||||
},
|
},
|
||||||
getSaleOutData(data_b, data_g){
|
getSaleOutData(data_b, data_g){
|
||||||
let that = this;
|
let that = this;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<el-dialog append-to-body
|
<el-dialog
|
||||||
title="打印物料标签"
|
title="打印物料标签"
|
||||||
v-model="visible"
|
v-model="visible"
|
||||||
destroy-on-close
|
destroy-on-close
|
||||||
|
|
|
||||||
|
|
@ -117,18 +117,6 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
const defaultForm = {
|
|
||||||
field_key: '',
|
|
||||||
field_name: '',
|
|
||||||
placeholder: '',
|
|
||||||
field_type: '',
|
|
||||||
sort: '',
|
|
||||||
label: 'name',
|
|
||||||
default_value: '',
|
|
||||||
field_template: '',
|
|
||||||
field_choice: [],
|
|
||||||
is_hidden: false,
|
|
||||||
};
|
|
||||||
export default {
|
export default {
|
||||||
name: "field",
|
name: "field",
|
||||||
data() {
|
data() {
|
||||||
|
|
@ -142,7 +130,18 @@
|
||||||
show: '查看'
|
show: '查看'
|
||||||
},
|
},
|
||||||
//表单数据
|
//表单数据
|
||||||
addForm: Object.assign({}, defaultForm, {field_choice: []}),
|
addForm: {
|
||||||
|
field_key: '',
|
||||||
|
field_name: '',
|
||||||
|
placeholder: '',
|
||||||
|
field_type: '',
|
||||||
|
sort: '',
|
||||||
|
label: 'name',
|
||||||
|
default_value: '',
|
||||||
|
field_template: '',
|
||||||
|
field_choice: [],
|
||||||
|
is_hidden: false,
|
||||||
|
},
|
||||||
//验证规则
|
//验证规则
|
||||||
rules: {
|
rules: {
|
||||||
name: [
|
name: [
|
||||||
|
|
@ -206,8 +205,6 @@
|
||||||
},
|
},
|
||||||
handleAdd() {
|
handleAdd() {
|
||||||
this.type = 'add';
|
this.type = 'add';
|
||||||
this.addForm = Object.assign({}, defaultForm, {field_choice: []});
|
|
||||||
this.choiceOption = [{id: null, name: ""}];
|
|
||||||
this.dialogVisible = true;
|
this.dialogVisible = true;
|
||||||
},
|
},
|
||||||
submitHandle() {
|
submitHandle() {
|
||||||
|
|
|
||||||
|
|
@ -391,15 +391,6 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
const defaultForm = {
|
|
||||||
name: "",
|
|
||||||
is_hidden: false,
|
|
||||||
sort: "",
|
|
||||||
type: "",
|
|
||||||
enable_retreat: false,
|
|
||||||
participant_type: 0,
|
|
||||||
distribute_type: 2, //分发类型
|
|
||||||
};
|
|
||||||
export default {
|
export default {
|
||||||
name: "state",
|
name: "state",
|
||||||
data() {
|
data() {
|
||||||
|
|
@ -421,10 +412,17 @@ export default {
|
||||||
stateChange: [],
|
stateChange: [],
|
||||||
fieldList: [],
|
fieldList: [],
|
||||||
//表单数据
|
//表单数据
|
||||||
addForm: Object.assign({}, defaultForm, {
|
addForm: {
|
||||||
|
name: "",
|
||||||
|
is_hidden: false,
|
||||||
|
sort: "",
|
||||||
|
type: "",
|
||||||
participant_cc: [],
|
participant_cc: [],
|
||||||
|
enable_retreat: false,
|
||||||
|
participant_type: 0,
|
||||||
|
distribute_type: 2, //分发类型
|
||||||
state_fields: {}, //字段状态是否可写
|
state_fields: {}, //字段状态是否可写
|
||||||
}),
|
},
|
||||||
//验证规则
|
//验证规则
|
||||||
rules: {
|
rules: {
|
||||||
name: [{ required: true, message: "请输入工作流名称" }],
|
name: [{ required: true, message: "请输入工作流名称" }],
|
||||||
|
|
@ -570,11 +568,6 @@ export default {
|
||||||
handleAdd() {
|
handleAdd() {
|
||||||
this.getField();
|
this.getField();
|
||||||
this.type = "add";
|
this.type = "add";
|
||||||
this.addForm = Object.assign({}, defaultForm, {
|
|
||||||
participant_cc: [],
|
|
||||||
state_fields: {},
|
|
||||||
});
|
|
||||||
this.stateChange = [];
|
|
||||||
this.dialogVisible = true;
|
this.dialogVisible = true;
|
||||||
// if(this.dialogInitNum === 0){
|
// if(this.dialogInitNum === 0){
|
||||||
// this.getUsers();
|
// this.getUsers();
|
||||||
|
|
|
||||||
|
|
@ -142,13 +142,6 @@
|
||||||
<script>
|
<script>
|
||||||
// import vueJsonEditor from 'vue-json-editor'
|
// import vueJsonEditor from 'vue-json-editor'
|
||||||
import JsonEditorVue from 'json-editor-vue3'
|
import JsonEditorVue from 'json-editor-vue3'
|
||||||
const defaultForm = {
|
|
||||||
name: '',
|
|
||||||
timer: 0,
|
|
||||||
source_state: '',
|
|
||||||
destination_state: '',
|
|
||||||
field_require_check: false,
|
|
||||||
};
|
|
||||||
export default {
|
export default {
|
||||||
name: "transform",
|
name: "transform",
|
||||||
components: { JsonEditorVue },
|
components: { JsonEditorVue },
|
||||||
|
|
@ -172,7 +165,14 @@
|
||||||
value: 3,
|
value: 3,
|
||||||
label: '其他'
|
label: '其他'
|
||||||
}],
|
}],
|
||||||
addForm: Object.assign({}, defaultForm, {condition_expression: {}}),
|
addForm: {
|
||||||
|
name: '',
|
||||||
|
timer: 0,
|
||||||
|
source_state: '',
|
||||||
|
destination_state: '',
|
||||||
|
condition_expression: {},
|
||||||
|
field_require_check: false,
|
||||||
|
},
|
||||||
stateList: [],
|
stateList: [],
|
||||||
dialogVisible: false,
|
dialogVisible: false,
|
||||||
}
|
}
|
||||||
|
|
@ -200,7 +200,6 @@
|
||||||
handleAdd() {
|
handleAdd() {
|
||||||
this.getStateList();
|
this.getStateList();
|
||||||
this.type = 'add';
|
this.type = 'add';
|
||||||
this.addForm = Object.assign({}, defaultForm, {condition_expression: {}});
|
|
||||||
this.dialogVisible = true;
|
this.dialogVisible = true;
|
||||||
},
|
},
|
||||||
handleEdit(row) {
|
handleEdit(row) {
|
||||||
|
|
|
||||||
|
|
@ -207,15 +207,6 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import degraDialog from "./degraD3_2.vue";
|
import degraDialog from "./degraD3_2.vue";
|
||||||
const defaultForm = {
|
|
||||||
name: "",
|
|
||||||
sn_prefix: "",
|
|
||||||
description: "",
|
|
||||||
view_permission_check: true,
|
|
||||||
display_form_str: [],
|
|
||||||
title_template: "",
|
|
||||||
content_template: "",
|
|
||||||
};
|
|
||||||
export default {
|
export default {
|
||||||
name: "index",
|
name: "index",
|
||||||
components: {
|
components: {
|
||||||
|
|
@ -242,7 +233,15 @@ export default {
|
||||||
},
|
},
|
||||||
wfCateOptions: [],
|
wfCateOptions: [],
|
||||||
//表单数据
|
//表单数据
|
||||||
addForm: Object.assign({}, defaultForm, { display_form_str: [] }),
|
addForm: {
|
||||||
|
name: "",
|
||||||
|
sn_prefix: "",
|
||||||
|
description: "",
|
||||||
|
view_permission_check: true,
|
||||||
|
display_form_str: [],
|
||||||
|
title_template: "",
|
||||||
|
content_template: "",
|
||||||
|
},
|
||||||
//验证规则
|
//验证规则
|
||||||
rules: {
|
rules: {
|
||||||
name: [{ required: true, message: "请输入工作流名称" }],
|
name: [{ required: true, message: "请输入工作流名称" }],
|
||||||
|
|
@ -265,7 +264,6 @@ export default {
|
||||||
//添加工作流
|
//添加工作流
|
||||||
handleAdd() {
|
handleAdd() {
|
||||||
this.type = "add";
|
this.type = "add";
|
||||||
this.addForm = Object.assign({}, defaultForm, { display_form_str: [] });
|
|
||||||
this.limitedVisible = true;
|
this.limitedVisible = true;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -915,7 +915,6 @@ export default {
|
||||||
this.imputDisable = true;
|
this.imputDisable = true;
|
||||||
await this.getInputText(data);
|
await this.getInputText(data);
|
||||||
this.imputDisable = false;
|
this.imputDisable = false;
|
||||||
await this.$nextTick();
|
|
||||||
this.$refs.codeInput.focus();
|
this.$refs.codeInput.focus();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -286,7 +286,7 @@
|
||||||
@success="handleSaveSuccess"
|
@success="handleSaveSuccess"
|
||||||
@closed="dialog.save = false"
|
@closed="dialog.save = false"
|
||||||
></save-dialog>
|
></save-dialog>
|
||||||
<el-dialog append-to-body v-model="printVisible" width="1200px">
|
<el-dialog v-model="printVisible" width="1200px">
|
||||||
<print :baseData="form" :tableData="tableData" :type="form.type" mtype="20" @closePrint="printVisible=false"/>
|
<print :baseData="form" :tableData="tableData" :type="form.type" mtype="20" @closePrint="printVisible=false"/>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
<print-dialog
|
<print-dialog
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<el-dialog append-to-body
|
<el-dialog
|
||||||
:title="titleMap[form.type]"
|
:title="titleMap[form.type]"
|
||||||
v-model="visible"
|
v-model="visible"
|
||||||
:size="1000"
|
:size="1000"
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@
|
||||||
</el-descriptions>
|
</el-descriptions>
|
||||||
<div style="padding: 5px 10px;display: flex;justify-content: end;align-items: center;">
|
<div style="padding: 5px 10px;display: flex;justify-content: end;align-items: center;">
|
||||||
<div v-if="mlogItem.submit_time == null && hasOkBDefect" style="margin-right: 16px;display:flex;align-items:center;">
|
<div v-if="mlogItem.submit_time == null && hasOkBDefect" style="margin-right: 16px;display:flex;align-items:center;">
|
||||||
<span style="margin-right: 6px;">合格B类记为合格</span>
|
<span style="margin-right: 6px;">合格B类不拆批</span>
|
||||||
<el-switch v-model="mlogItem.clear_defect"></el-switch>
|
<el-switch v-model="mlogItem.clear_defect"></el-switch>
|
||||||
</div>
|
</div>
|
||||||
<el-button
|
<el-button
|
||||||
|
|
@ -276,7 +276,7 @@
|
||||||
</scTable>
|
</scTable>
|
||||||
</el-card>
|
</el-card>
|
||||||
<!-- 输入物料编辑 -->
|
<!-- 输入物料编辑 -->
|
||||||
<el-dialog append-to-body v-model="saveInDialog" title="编辑">
|
<el-dialog v-model="saveInDialog" title="编辑">
|
||||||
<el-form
|
<el-form
|
||||||
:model="saveInForm"
|
:model="saveInForm"
|
||||||
:rules="rules"
|
:rules="rules"
|
||||||
|
|
@ -444,7 +444,7 @@
|
||||||
@closed="dialog.edit = false"
|
@closed="dialog.edit = false"
|
||||||
>
|
>
|
||||||
</edit-dialog>
|
</edit-dialog>
|
||||||
<el-dialog append-to-body v-model="printVisible" width="1200px">
|
<el-dialog v-model="printVisible" width="1200px">
|
||||||
<print :baseData="mlogItem" :tableData="tableData" :tableData2="tableData2" type="102" @closePrint="printVisible=false"/>
|
<print :baseData="mlogItem" :tableData="tableData" :tableData2="tableData2" type="102" @closePrint="printVisible=false"/>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<el-dialog append-to-body
|
<el-dialog
|
||||||
:title="titleMap[mode]"
|
:title="titleMap[mode]"
|
||||||
v-model="visible"
|
v-model="visible"
|
||||||
style="width: 80%;"
|
style="width: 80%;"
|
||||||
|
|
@ -60,8 +60,8 @@
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :md="12" :sm="12" :xs="24" v-if="base_code=='tcerp'||route_code=='ladansi'||route_code=='yicifusi'||route_code=='ercifusi'||route_code=='zlybcl'||route_code=='djg'||route_code=='cnc'">
|
<el-col :md="12" :sm="12" :xs="24" v-if="route_code=='ladansi'||route_code=='yicifusi'||route_code=='ercifusi'||route_code=='zlybcl'||route_code=='djg'||route_code=='cnc'">
|
||||||
<el-form-item label="生产设备" :prop="base_code!=='tcerp' ? 'equipment' : null">
|
<el-form-item label="生产设备" prop="equipment">
|
||||||
<el-select
|
<el-select
|
||||||
v-model="form.equipment"
|
v-model="form.equipment"
|
||||||
placeholder="生产设备"
|
placeholder="生产设备"
|
||||||
|
|
@ -315,7 +315,6 @@ export default {
|
||||||
mtaskOptions:[],
|
mtaskOptions:[],
|
||||||
supplierOptions: [],
|
supplierOptions: [],
|
||||||
setFiltersVisible: false,
|
setFiltersVisible: false,
|
||||||
base_code: this.$TOOL.data.get('BASE_INFO').base.base_code,
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@
|
||||||
style="padding: 0 10px"
|
style="padding: 0 10px"
|
||||||
>
|
>
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :span="scanColSpan">
|
<el-col :span="project_code!=='bxerp'?22:24">
|
||||||
<el-form-item label="扫码:">
|
<el-form-item label="扫码:">
|
||||||
<el-input
|
<el-input
|
||||||
class="inputWrap"
|
class="inputWrap"
|
||||||
|
|
@ -34,9 +34,6 @@
|
||||||
<el-col :span="2" v-if="project_code!=='bxerp'">
|
<el-col :span="2" v-if="project_code!=='bxerp'">
|
||||||
<scScanner style="top: -7px" @scanResult="codeTextChange"></scScanner>
|
<scScanner style="top: -7px" @scanResult="codeTextChange"></scScanner>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="4" v-if="route_code=='niuzhuan'">
|
|
||||||
<el-button type="success" @click="digital" style="margin-top: 3px;margin-left: 5px;">数字识别</el-button>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :md="12" :sm="12" :xs="24">
|
<el-col :md="12" :sm="12" :xs="24">
|
||||||
|
|
@ -66,8 +63,8 @@
|
||||||
<el-input-number v-model="form.count_use" :disabled="materialTracking==20" style="width: 100%;"></el-input-number>
|
<el-input-number v-model="form.count_use" :disabled="materialTracking==20" style="width: 100%;"></el-input-number>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :md="12" :sm="12" :xs="24" v-if="base_code=='tcerp'||route_code=='ladansi'||route_code=='yicifusi'||route_code=='ercifusi'||route_code=='zlybcl'||route_code=='djg'||route_code=='cnc'">
|
<el-col :md="12" :sm="12" :xs="24" v-if="route_code=='ladansi'||route_code=='yicifusi'||route_code=='ercifusi'||route_code=='zlybcl'||route_code=='djg'||route_code=='cnc'">
|
||||||
<el-form-item label="生产设备" :prop="base_code!=='tcerp' ? 'equipment' : null">
|
<el-form-item label="生产设备" prop="equipment">
|
||||||
<el-select
|
<el-select
|
||||||
v-model="form.equipment"
|
v-model="form.equipment"
|
||||||
placeholder="生产设备"
|
placeholder="生产设备"
|
||||||
|
|
@ -233,15 +230,7 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
emits: ["success", "closed"],
|
emits: ["success", "closed"],
|
||||||
computed: {
|
|
||||||
scanColSpan(){
|
|
||||||
let span = this.project_code!=='bxerp' ? 22 : 24;
|
|
||||||
if(this.route_code=='niuzhuan'){
|
|
||||||
span -= 4;
|
|
||||||
}
|
|
||||||
return span;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
loading: false,
|
loading: false,
|
||||||
|
|
@ -277,9 +266,6 @@ export default {
|
||||||
imageUrl:'',
|
imageUrl:'',
|
||||||
test_file:'',
|
test_file:'',
|
||||||
project_code:'',
|
project_code:'',
|
||||||
ocr_ip:"",
|
|
||||||
ocr_port:"",
|
|
||||||
ocr_unit:"",
|
|
||||||
visible: false,
|
visible: false,
|
||||||
isSaveing: false,
|
isSaveing: false,
|
||||||
batchCountCando:0,
|
batchCountCando:0,
|
||||||
|
|
@ -292,7 +278,6 @@ export default {
|
||||||
routeOptions: [],
|
routeOptions: [],
|
||||||
materialOptions: [],
|
materialOptions: [],
|
||||||
routeOriginOptions: [],
|
routeOriginOptions: [],
|
||||||
base_code: this.$TOOL.data.get('BASE_INFO').base.base_code,
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
|
@ -324,9 +309,6 @@ export default {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},500)
|
},500)
|
||||||
that.ocr_ip = localStorage.getItem("ocr_ip") || "";
|
|
||||||
that.ocr_port = localStorage.getItem("ocr_port") || "";
|
|
||||||
that.ocr_unit = localStorage.getItem("ocr_unit") || "";
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
//获取工艺步骤
|
//获取工艺步骤
|
||||||
|
|
@ -369,29 +351,6 @@ export default {
|
||||||
this.wm_in = text;
|
this.wm_in = text;
|
||||||
this.formWminChange(text);
|
this.formWminChange(text);
|
||||||
},
|
},
|
||||||
digital(){
|
|
||||||
let that = this;
|
|
||||||
if(!that.ocr_ip || !that.ocr_port || !that.ocr_unit){
|
|
||||||
that.$message.warning('请先在右上角"数字识别设置"配置IP、端口号和位号');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
that.$API.em.equipment.get_svs_char.req({
|
|
||||||
host: that.ocr_ip,
|
|
||||||
port: that.ocr_port,
|
|
||||||
flow_unit: that.ocr_unit
|
|
||||||
}).then((res) => {
|
|
||||||
if(res.char){
|
|
||||||
that.wm_in = res.char;
|
|
||||||
that.formWminChange(res.char);
|
|
||||||
}
|
|
||||||
}).catch((err) => {
|
|
||||||
that.$notify.error({
|
|
||||||
title: '数字识别获取失败',
|
|
||||||
message: err.data
|
|
||||||
})
|
|
||||||
return err;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
//显示
|
//显示
|
||||||
open(mode = "add") {
|
open(mode = "add") {
|
||||||
let that = this;
|
let that = this;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<el-dialog append-to-body
|
<el-dialog
|
||||||
title="过程检验"
|
title="过程检验"
|
||||||
v-model="visible"
|
v-model="visible"
|
||||||
:size="1000"
|
:size="1000"
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
<!-- 新增mlogbIn -->
|
<!-- 新增mlogbIn -->
|
||||||
<template>
|
<template>
|
||||||
<el-dialog append-to-body
|
<el-dialog
|
||||||
title="添加日志详情"
|
title="添加日志详情"
|
||||||
v-model="visible"
|
v-model="visible"
|
||||||
:size="1000"
|
:size="1000"
|
||||||
|
|
|
||||||
|
|
@ -274,7 +274,7 @@
|
||||||
</sc-form-table>
|
</sc-form-table>
|
||||||
</el-main>
|
</el-main>
|
||||||
</el-container>
|
</el-container>
|
||||||
<el-dialog append-to-body
|
<el-dialog
|
||||||
title="检验"
|
title="检验"
|
||||||
v-model="checkVisible"
|
v-model="checkVisible"
|
||||||
destroy-on-close
|
destroy-on-close
|
||||||
|
|
@ -378,7 +378,7 @@
|
||||||
</el-main>
|
</el-main>
|
||||||
</el-container>
|
</el-container>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
<el-dialog append-to-body
|
<el-dialog
|
||||||
title="批量检验"
|
title="批量检验"
|
||||||
v-model="setVisible"
|
v-model="setVisible"
|
||||||
destroy-on-close
|
destroy-on-close
|
||||||
|
|
|
||||||
|
|
@ -68,7 +68,7 @@
|
||||||
<el-button type="primary" @click="mtaskb_submit">提交</el-button>
|
<el-button type="primary" @click="mtaskb_submit">提交</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<el-dialog append-to-body v-model="printVisible" width="1200px">
|
<el-dialog v-model="printVisible" width="1200px">
|
||||||
<print :baseData="mtaskObj" type="mtask" @closePrint="printVisible=false"/>
|
<print :baseData="mtaskObj" type="mtask" @closePrint="printVisible=false"/>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</el-drawer>
|
</el-drawer>
|
||||||
|
|
|
||||||
|
|
@ -87,21 +87,12 @@
|
||||||
>
|
>
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-button
|
<el-button
|
||||||
v-if="scope.row.submit_time!==null"
|
|
||||||
link size="small"
|
link size="small"
|
||||||
@click="check_revert(scope.row)"
|
@click="check_revert(scope.row)"
|
||||||
v-auth="'ftestwork.create'"
|
v-auth="'ftestwork.create'"
|
||||||
type="primary"
|
type="primary"
|
||||||
>撤回
|
>撤回
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button
|
|
||||||
v-else
|
|
||||||
link size="small"
|
|
||||||
@click="check_delete(scope.row)"
|
|
||||||
v-auth="'ftestwork.create'"
|
|
||||||
type="danger"
|
|
||||||
>删除
|
|
||||||
</el-button>
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</scTable>
|
</scTable>
|
||||||
|
|
@ -168,17 +159,7 @@ export default {
|
||||||
});
|
});
|
||||||
}).catch(() => {});
|
}).catch(() => {});
|
||||||
},
|
},
|
||||||
check_delete(row){
|
|
||||||
let that = this;
|
|
||||||
this.$confirm(`确定删除该检验吗?`, "提示", {
|
|
||||||
type: "warning",
|
|
||||||
}).then(() => {
|
|
||||||
that.$API.qm.ftestwork.delete.req(row.id).then((res) => {
|
|
||||||
this.$refs.table.refresh();
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
},
|
|
||||||
handleQuery() {
|
handleQuery() {
|
||||||
this.$refs.table.queryData(this.query);
|
this.$refs.table.queryData(this.query);
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<el-dialog append-to-body
|
<el-dialog
|
||||||
:title="titleMap[mode]"
|
:title="titleMap[mode]"
|
||||||
v-model="visible"
|
v-model="visible"
|
||||||
destroy-on-close
|
destroy-on-close
|
||||||
|
|
|
||||||
|
|
@ -116,7 +116,7 @@
|
||||||
@closed="dialog.check = false"
|
@closed="dialog.check = false"
|
||||||
>
|
>
|
||||||
</check-dialog>
|
</check-dialog>
|
||||||
<el-dialog append-to-body v-model="printVisible" width="1200px">
|
<el-dialog v-model="printVisible" width="1200px">
|
||||||
<print :baseData="fmlogItem" :tableData="tableData" type="101" @closePrint="printVisible=false"/>
|
<print :baseData="fmlogItem" :tableData="tableData" type="101" @closePrint="printVisible=false"/>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -310,7 +310,7 @@
|
||||||
@success="handleSaveSuccess"
|
@success="handleSaveSuccess"
|
||||||
@closed="dialog.save = false"
|
@closed="dialog.save = false"
|
||||||
></save-dialog>
|
></save-dialog>
|
||||||
<el-dialog append-to-body v-model="printVisible" width="1200px">
|
<el-dialog v-model="printVisible" width="1200px">
|
||||||
<print :baseData="form" :tableData="tableData" :type="form.type" mtype="20" @closePrint="printVisible=false"/>
|
<print :baseData="form" :tableData="tableData" :type="form.type" mtype="20" @closePrint="printVisible=false"/>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
<print-dialog
|
<print-dialog
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<el-dialog append-to-body
|
<el-dialog
|
||||||
:title="titleMap[form.type]"
|
:title="titleMap[form.type]"
|
||||||
v-model="visible"
|
v-model="visible"
|
||||||
style="width: 80%;"
|
style="width: 80%;"
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,7 @@
|
||||||
<div style="padding: 5px 10px;display: flex;justify-content: end;align-items: center;">
|
<div style="padding: 5px 10px;display: flex;justify-content: end;align-items: center;">
|
||||||
<!-- hasOkBDefect -->
|
<!-- hasOkBDefect -->
|
||||||
<div v-if="mlogItem.submit_time == null" style="margin-right: 16px;display:flex;align-items:center;">
|
<div v-if="mlogItem.submit_time == null" style="margin-right: 16px;display:flex;align-items:center;">
|
||||||
<span style="margin-right: 6px;">合格B类记为合格</span>
|
<span style="margin-right: 6px;">合格B类不拆批</span>
|
||||||
<el-switch v-model="mlogItem.clear_defect"></el-switch>
|
<el-switch v-model="mlogItem.clear_defect"></el-switch>
|
||||||
</div>
|
</div>
|
||||||
<el-button
|
<el-button
|
||||||
|
|
@ -168,7 +168,7 @@
|
||||||
</scTable>
|
</scTable>
|
||||||
</el-card>
|
</el-card>
|
||||||
<!-- 输入物料编辑 -->
|
<!-- 输入物料编辑 -->
|
||||||
<el-dialog append-to-body v-model="saveInDialog" title="编辑">
|
<el-dialog v-model="saveInDialog" title="编辑">
|
||||||
<el-form
|
<el-form
|
||||||
:model="saveInForm"
|
:model="saveInForm"
|
||||||
:rules="rules"
|
:rules="rules"
|
||||||
|
|
@ -359,7 +359,7 @@
|
||||||
@closed="dialog.edit = false"
|
@closed="dialog.edit = false"
|
||||||
>
|
>
|
||||||
</edit-dialog>
|
</edit-dialog>
|
||||||
<el-dialog append-to-body v-model="printVisible" width="1200px">
|
<el-dialog v-model="printVisible" width="1200px">
|
||||||
<print :baseData="mlogItem" :tableData="tableData" :tableData2="tableData2" type="102" @closePrint="printVisible=false"/>
|
<print :baseData="mlogItem" :tableData="tableData" :tableData2="tableData2" type="102" @closePrint="printVisible=false"/>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
<print-dialog
|
<print-dialog
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<el-dialog append-to-body
|
<el-dialog
|
||||||
:title="titleMap[mode]"
|
:title="titleMap[mode]"
|
||||||
v-model="visible"
|
v-model="visible"
|
||||||
destroy-on-close
|
destroy-on-close
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<el-dialog append-to-body
|
<el-dialog
|
||||||
title="过程检验"
|
title="过程检验"
|
||||||
v-model="visible"
|
v-model="visible"
|
||||||
style="width: 80%;"
|
style="width: 80%;"
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<el-dialog append-to-body
|
<el-dialog
|
||||||
:title="titleMap[mode]"
|
:title="titleMap[mode]"
|
||||||
v-model="visible"
|
v-model="visible"
|
||||||
style="width: 80%;"
|
style="width: 80%;"
|
||||||
|
|
|
||||||
|
|
@ -68,7 +68,7 @@
|
||||||
<el-button type="primary" @click="mtaskb_submit">提交</el-button>
|
<el-button type="primary" @click="mtaskb_submit">提交</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<el-dialog append-to-body v-model="printVisible" width="1200px">
|
<el-dialog v-model="printVisible" width="1200px">
|
||||||
<print :baseData="mtaskObj" type="mtask" @closePrint="printVisible=false"/>
|
<print :baseData="mtaskObj" type="mtask" @closePrint="printVisible=false"/>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</el-drawer>
|
</el-drawer>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue