Compare commits

...

12 Commits

Author SHA1 Message Date
lb
e153d7e077 update 流程图 2023-10-24 17:07:32 +08:00
lb
3c31e5d63a done 新建工序 2023-10-24 15:56:15 +08:00
lb
6006ae13d9 update flow 2023-10-24 11:17:07 +08:00
lb
106d0ed89c merge server 2023-10-20 17:03:06 +08:00
lb
cfbd00b560 update process 2023-10-20 17:00:49 +08:00
lb
a787935263 add process flow and process node 2023-10-20 16:03:40 +08:00
lb
15da20fac7 add 添加一个缓存方案 2023-10-20 14:22:46 +08:00
lb
6b4e906e75 update process flow 2023-10-19 16:40:36 +08:00
lb
d121e408af add 工艺流程列表 2023-10-19 11:13:37 +08:00
lb
f8baaa8955 update ui 2023-10-17 17:02:53 +08:00
lb
416d4bb390 update 2023-10-17 15:27:08 +08:00
lb
fe7821cbd8 update 核心模块-厂务-设备 2023-10-17 15:22:17 +08:00
32 changed files with 10484 additions and 8258 deletions

View File

@@ -12,10 +12,8 @@ ENV = 'development'
VUE_APP_TITLE = 产线监控系统
# 芋道管理系统/开发环境
# VUE_APP_BASE_API = 'http://192.168.1.49:48080'
# VUE_APP_BASE_API = 'http://192.168.1.8:48080'
VUE_APP_BASE_API = 'http://192.168.0.33:48080'
# VUE_APP_BASE_API = 'http://192.168.1.188:48080'
# VUE_APP_BASE_API = 'http://192.168.1.8:48082'
VUE_APP_BASE_API = 'http://192.168.0.33:48082'
# 路由懒加载
VUE_CLI_BABEL_TRANSPILE_MODULES = true

View File

@@ -41,6 +41,7 @@
"url": "https://github.com/YunaiV/ruoyi-vue-pro"
},
"dependencies": {
"@antv/x6": "^2.15.3",
"@babel/parser": "7.18.4",
"@riophae/vue-treeselect": "0.4.0",
"axios": "0.27.2",

View File

@@ -3,7 +3,7 @@ import request from '@/utils/request'
// 创建设备
export function createEquipment(data) {
return request({
url: '/base/equipment/create',
url: '/base/core-equipment/create',
method: 'post',
data: data
})
@@ -12,7 +12,7 @@ export function createEquipment(data) {
// 更新设备
export function updateEquipment(data) {
return request({
url: '/base/equipment/update',
url: '/base/core-equipment/update',
method: 'put',
data: data
})
@@ -21,7 +21,7 @@ export function updateEquipment(data) {
// 删除设备
export function deleteEquipment(id) {
return request({
url: '/base/equipment/delete?id=' + id,
url: '/base/core-equipment/delete?id=' + id,
method: 'delete'
})
}
@@ -29,7 +29,7 @@ export function deleteEquipment(id) {
// 获得设备
export function getEquipment(id) {
return request({
url: '/base/equipment/get?id=' + id,
url: '/base/core-equipment/get?id=' + id,
method: 'get'
})
}
@@ -37,7 +37,7 @@ export function getEquipment(id) {
// 获得设备分页
export function getEquipmentPage(query) {
return request({
url: '/base/equipment/page',
url: '/base/core-equipment/page',
method: 'get',
params: query
})
@@ -46,7 +46,7 @@ export function getEquipmentPage(query) {
// 导出设备 Excel
export function exportEquipmentExcel(query) {
return request({
url: '/base/equipment/export-excel',
url: '/base/core-equipment/export-excel',
method: 'get',
params: query,
responseType: 'blob'
@@ -55,7 +55,7 @@ export function exportEquipmentExcel(query) {
// 获得所有设备列表
export function getEquipmentAll() {
return request({
url: '/base/equipment/listAll',
url: '/base/core-equipment/listAll',
method: 'get'
})
}

View File

@@ -3,7 +3,7 @@ import request from '@/utils/request'
// 创建设备类型
export function createEquipmentType(data) {
return request({
url: '/base/equipment-type/create',
url: '/base/core-equipment-type/create',
method: 'post',
data: data
})
@@ -12,7 +12,7 @@ export function createEquipmentType(data) {
// 更新设备类型
export function updateEquipmentType(data) {
return request({
url: '/base/equipment-type/update',
url: '/base/core-equipment-type/update',
method: 'put',
data: data
})
@@ -21,7 +21,7 @@ export function updateEquipmentType(data) {
// 删除设备类型
export function deleteEquipmentType(id) {
return request({
url: '/base/equipment-type/delete?id=' + id,
url: '/base/core-equipment-type/delete?id=' + id,
method: 'delete'
})
}
@@ -29,7 +29,7 @@ export function deleteEquipmentType(id) {
// 获得设备类型
export function getEquipmentType(id) {
return request({
url: '/base/equipment-type/get?id=' + id,
url: '/base/core-equipment-type/get?id=' + id,
method: 'get'
})
}
@@ -37,7 +37,7 @@ export function getEquipmentType(id) {
// 获得设备类型分页
export function getEquipmentTypePage(query) {
return request({
url: '/base/equipment-type/page',
url: '/base/core-equipment-type/page',
method: 'get',
params: query
})
@@ -46,7 +46,7 @@ export function getEquipmentTypePage(query) {
// 导出设备类型 Excel
export function exportEquipmentTypeExcel(query) {
return request({
url: '/base/equipment-type/export-excel',
url: '/base/core-equipment-type/export-excel',
method: 'get',
params: query,
responseType: 'blob'

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="14px" height="14px" viewBox="0 0 14 14" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>上传</title>
<g id="组件" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" opacity="0.65">
<g id="上传_Resources/Button" transform="translate(-12.000000, -9.000000)">
<g id="上传" transform="translate(12.000000, 9.000000)">
<g id="upload" transform="translate(0.875000, 0.875000)" fill="currentColor" fill-rule="nonzero">
<path d="M5.80371094,0.138085937 C5.8953125,0.046484375 6.01699219,0 6.13867188,0 C6.26035156,0 6.38066406,0.046484375 6.47363281,0.138085937 L8.60371094,2.26953125 C8.78828125,2.45410156 8.78828125,2.75351562 8.60371094,2.93808594 C8.51484375,3.02695312 8.39589844,3.07617188 8.27011719,3.07617188 C8.14433594,3.07617188 8.02539062,3.02695312 7.93652344,2.93808594 L6.61171875,1.61328125 L6.61171875,9.51289062 C6.61171875,9.77402344 6.39980469,9.9859375 6.13867188,9.9859375 C5.87753906,9.9859375 5.665625,9.77402344 5.665625,9.51289062 L5.665625,1.61328125 L4.34082031,2.93808594 C4.15625,3.12265625 3.85683594,3.12265625 3.67363281,2.93808594 C3.4890625,2.75351562 3.4890625,2.45410156 3.67226563,2.26953125 L5.80371094,0.138085937 Z M11.7769531,7.88046875 C11.5158203,7.88046875 11.3039063,8.09238281 11.3039063,8.35351563 L11.3039063,11.025 C11.3039063,11.1794922 11.178125,11.3066406 11.0222656,11.3066406 L1.22636719,11.3066406 C1.071875,11.3066406 0.944726562,11.1808594 0.944726562,11.025 L0.944726562,8.35214844 C0.944726562,8.09101563 0.7328125,7.87910156 0.471679688,7.87910156 C0.210546875,7.87910156 0,8.09238281 0,8.35214844 L0,11.3996094 C0,11.8685547 0.381445313,12.2486328 0.849023437,12.2486328 L11.4009766,12.2486328 C11.8699219,12.2486328 12.25,11.8671875 12.25,11.3996094 L12.25,8.35214844 C12.25,8.09238281 12.0380859,7.88046875 11.7769531,7.88046875 Z" id="Shape"></path>
</g>
<rect id="Rectangle-49" x="0" y="0" width="14" height="14"></rect>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@@ -83,6 +83,9 @@
:on-success="handleUploadSuccess"
v-bind="col.bind">
<el-button size="mini" :disabled="col.bind?.disabled || false">
<svg-icon
icon-class="icon-upload"
style="color: inherit"></svg-icon>
上传文件
</el-button>
<div class="el-upload__tip" slot="tip" v-if="col.uploadTips">
@@ -94,6 +97,7 @@
class="file"
v-for="file in form[col.prop] || []"
:file="file"
:key="file.fileUrl"
@delete="handleDeleteFile(file)" />
</div>
</el-form-item>
@@ -105,6 +109,7 @@
<script>
import { getAccessToken } from '@/utils/auth';
import tupleImg from '@/assets/images/tuple.png';
import cache from '@/utils/cache';
/**
* 找到最长的label
@@ -132,7 +137,6 @@ const uploadedFile = {
},
methods: {
handleDelete() {
console.log('emit delete event')
this.$emit('delete', this.file);
},
},
@@ -187,6 +191,10 @@ export default {
type: Boolean,
default: false,
},
hasFiles: {
type: Boolean,
default: false,
},
labelPosition: {
type: String,
default: 'right',
@@ -219,7 +227,6 @@ export default {
watch: {
rows: {
handler() {
console.log('watch triggered!');
this.$nextTick(() => {
this.handleOptions('watch');
});
@@ -230,6 +237,9 @@ export default {
dataForm: {
handler(val) {
this.form = JSON.parse(JSON.stringify(val));
if (this.hasFiles) {
this.form.files = this.form.files ?? [];
}
},
deep: true,
immediate: true,
@@ -308,6 +318,11 @@ export default {
'list' in response.data
? response.data.list
: response.data;
if (opt.cache) {
cache.store(opt.cache, list);
}
this.$set(
this.optionListOf,
opt.prop,
@@ -367,7 +382,9 @@ export default {
},
handleDeleteFile(file) {
this.form.files = this.form.files.filter(item => item.fileUrl != file.fileUrl);
this.form.files = this.form.files.filter(
(item) => item.fileUrl != file.fileUrl
);
this.$emit('update', this.form);
},
},

View File

@@ -28,10 +28,37 @@ export default {
// tableBtn: [], // 占位
// searchBarFormConfig: [], // 占位
// // 弹窗表单配置
// dialogFormConfig: [], // 占位
// dialogFormConfig: [], //
updateUrl: '',
addUrl: '',
pageUrl: '',
form: {}
};
},
methods: {
// utils
http(url, method, payload) {
return this.$axios({
url,
method,
params: method === 'get' ? payload : null,
data: method !== 'get' ? payload : null,
})
},
put(payload) {
return this.http(this.updateUrl, 'put', payload);
},
post(payload) {
return this.http(this.addUrl, 'post', payload);
},
recv(payload) {
return this.http(this.pageUrl, 'get', payload);
},
info(payload) {
return this.http(this.infoUrl, 'get', payload);
},
// 过滤后端传回的详情数据
filterData(data, keys) {
const obj = {};

View File

@@ -72,15 +72,15 @@ export const constantRoutes = [
{
path: '/',
component: Layout,
redirect: 'core/base/factory',
// children: [{
// path: 'index',
// redirect: 'core/base/factory',
// component: (resolve) => require(['@/views/index'], resolve),
// name: '首页',
// meta: { title: '首页', icon: 'dashboard', affix: true }
// }
// ]
// redirect: 'core/base/factory',
children: [{
path: 'index',
// redirect: 'core/base/factory',
component: (resolve) => require(['@/views/index'], resolve),
name: '首页',
meta: { title: '首页', icon: 'dashboard', affix: true }
}
]
},
{
path: '/user',

53
src/utils/cache.js Normal file
View File

@@ -0,0 +1,53 @@
let timers = [];
export default {
exists(key) {
const _ = localStorage.getItem('stored_keys');
return _ ? _.split(',')?.indexOf(key) != -1 : false;
},
store(key, value, duration = null) {
if (!localStorage.getItem('stored_keys')) localStorage.setItem('stored_keys', key);
else localStorage.setItem('stored_keys', localStorage.getItem('stored_keys') + ',' + key);
localStorage.setItem(key, JSON.stringify(value));
console.log('store duration', duration)
if (duration) {
if (timers[key]) clearTimeout(timers[key]);
timers[key] = setTimeout(() => {
console.log("clear cache", key)
this.clear([key]);
}, duration * 1000);
}
},
/**
*
* @param {*} key
* @param {*} cb
* @param {*} param2 force 强制更新调用cb
* @returns
*/
async getList(key, cb = null, { force = false, duration = null } = {}) {
if (this.exists(key) && !force) {
return JSON.parse(localStorage.getItem(key))
} else {
const list = await cb();
this.store(key, list, duration);
return list;
}
},
clear(keys) {
if (keys && keys.length) {
let stored_keys = localStorage.getItem('stored_keys').split(',');
keys.forEach((key) => {
stored_keys = stored_keys.filter((item) => item != key);
});
localStorage.setItem('stored_keys', stored_keys);
return;
}
localStorage.removeItem('stored_keys');
},
}

View File

@@ -217,7 +217,7 @@ export function getTime(type) {
export function debounce(func, wait, immediate) {
let timeout, args, context, timestamp, result
const later = function() {
const later = function () {
// 据上一次触发时间间隔
const last = +new Date() - timestamp
@@ -234,7 +234,7 @@ export function debounce(func, wait, immediate) {
}
}
return function(...args) {
return function (...args) {
context = this
timestamp = +new Date()
const callNow = immediate && !timeout
@@ -438,3 +438,7 @@ export function toCamelCase(str, upperCaseFirst) {
return str;
}
export function IdToName(targetId, source, prop = 'name') {
return source.find(item => item.id === targetId)?.[prop]
}

View File

@@ -219,7 +219,7 @@ export default {
{
select: true,
label: '设备',
url: '/base/equipment/page?pageNo=1&pageSize=100',
url: '/base/core-equipment/page?pageNo=1&pageSize=100',
prop: 'equipmentId',
bind: {
filterable: true,
@@ -278,7 +278,7 @@ export default {
input: true,
label: '设备分组编码',
prop: 'code',
// url: '/base/equipment/getCode',
// url: '/base/core-equipment/getCode',
},
],
],

View File

@@ -191,7 +191,7 @@ export default {
// 获取设备列表
async getEquipmentList() {
const response = await this.$axios(
'/base/equipment/page?pageNo=1&pageSize=100'
'/base/core-equipment/page?pageNo=1&pageSize=100'
);
this.equipmentList = response.data.list.map((item) => ({
label: item.name,

View File

@@ -192,7 +192,7 @@ export default {
{
select: true,
label: '设备',
url: '/base/equipment/page?pageNo=1&pageSize=100',
url: '/base/core-equipment/page?pageNo=1&pageSize=100',
prop: 'equipmentId',
rules: [{ required: true, message: '不能为空', trigger: 'blur' }],
},

View File

@@ -192,7 +192,7 @@ export default {
input: true,
label: '设备分组编码',
prop: 'code',
// url: '/base/equipment/getCode',
// url: '/base/core-equipment/getCode',
}
]
],

View File

@@ -247,7 +247,7 @@ export default {
select: true,
label: '设备',
prop: 'equipmentId',
url: '/base/equipment/page?pageNo=1&pageSize=99',
url: '/base/core-equipment/page?pageNo=1&pageSize=99',
rules: [{ required: true, message: '不能为空', trigger: 'blur' }],
bind: {
filterable: true,
@@ -283,7 +283,7 @@ export default {
input: true,
label: '关联表名',
prop: 'plcTableName',
// url: '/base/equipment/getCode',
// url: '/base/core-equipment/getCode',
},
],
],
@@ -320,7 +320,7 @@ export default {
methods: {
async getEquipmentOptions() {
const res = await this.$axios({
url: '/base/equipment/listAll',
url: '/base/core-equipment/listAll',
method: 'get',
});
return res.data;

View File

@@ -18,7 +18,13 @@
预览
</div> -->
</section>
<section class="file-area">
<section
class="file-area"
:style="{
height: expand ? 'auto' : isPicMode ? '180px' : '152px',
gap: isPicMode ? '0 24px' : '24px',
gridAutoRows: isPicMode ? '180px' : '152px',
}">
<el-upload
class="equipment-upload"
:disabled="disabled"
@@ -56,7 +62,6 @@
v-for="(file, index) in files"
:key="file.fileName"
:style="{
display: index > 3 && !expand ? 'none' : 'block',
background: isPicMode
? `url(${file.fileUrl}) no-repeat`
: `url(${defaultBg}) no-repeat`,
@@ -226,7 +231,7 @@ export default {
clearTimeout(this.updateTimer);
}
this.updateTimer = setTimeout(() => {
console.log('[AssetsUpload] 更新上传列表');
// console.log('[AssetsUpload] 更新上传列表');
this.emitFilelist();
clearTimeout(this.updateTimer);
this.updateTimer = null;
@@ -314,7 +319,6 @@ export default {
}
:deep(.equipment-upload) {
background: #ccc4;
.el-upload-dragger {
width: 188px;
height: 128px;
@@ -346,6 +350,10 @@ export default {
}
}
.equipment-upload {
margin-bottom: 24px;
}
.file-list {
padding: 12px;
border: 1px solid #ccc;
@@ -354,13 +362,14 @@ export default {
// custom
.file-area {
display: grid;
grid-template-columns: repeat(5, 188px);
grid-auto-rows: 128px;
gap: 24px 18px;
place-content: center;
grid-template-columns: repeat(auto-fill, 188px);
grid-auto-rows: 152px;
gap: 48px 24px;
overflow: hidden;
}
.file-list__item {
height: 128px;
background-color: #fff;
border: 1px dashed #d9d9d9;
border-radius: 6px;

View File

@@ -1,32 +0,0 @@
<!--
filename: EquipmentAssets.vue
author: liubin
date: 2023-08-22 11:11:18
description: 设备资产
-->
<template>
<div class="equipment-assets"></div>
</template>
<script>
export default {
name: "EquipmentAssets",
components: {},
props: {},
data() {
return {}
},
computed: {},
methods: {},
}
</script>
<style scoped lang="scss">
.equipment-assets {
background: #f1f1f1;
padding: 12px;
min-height: 128px;
margin-top: 8px;
}
</style>

View File

@@ -283,7 +283,7 @@ export default {
async getEqTypeList() {
this.formLoading = true;
const { code, data } = await this.$axios(
'/base/equipment-type/page?pageNo=1&pageSize=100'
'/base/core-equipment-type/page?pageNo=1&pageSize=100'
);
// debugger;
if (code == 0) {

View File

@@ -1,111 +0,0 @@
<!--
filename: EquipmentPics.vue
author: liubin
date: 2023-08-18 16:29:39
description:
-->
<template>
<div class="equipment-pics">
<div v-for="(url, idx) in images" :key="url">
<img :src="url" :alt="url" />
<figure class="big-img" :style="inlineStyle">
<img :src="url" :alt="url" />
<figcaption>{{ desc[idx] }}</figcaption>
</figure>
</div>
</div>
</template>
<script>
export default {
name: 'EquipmentPics',
components: {},
props: {
inlineStyle: {
type: Object,
default: () => ({}),
},
},
data() {
return {
desc: [
'车间设备 - 1',
'车间设备 - 2',
'车间设备 - 3',
'车间设备 - 4',
'车间设备 - 5',
'车间设备 - 6',
'车间设备 - 7',
'车间设备 - 8',
'车间设备 - 9',
'车间设备 - 10',
'车间设备 - 11',
'车间设备 - 12',
],
images: Array(10)
.fill(1)
.map((_, index) => require(`../assets/eq${index + 1}.jpg`)),
};
},
methods: {},
};
</script>
<style scoped lang="scss">
.equipment-pics {
// background: #cfcfcf;
padding: 12px;
// margin: 8px;
display: flex;
overflow-x: auto;
}
.equipment-pics > div {
height: 100px;
position: relative;
cursor: pointer;
}
.equipment-pics > div:not(:last-child) {
margin-right: 12px;
}
.equipment-pics > div > img {
height: 95%;
}
.equipment-pics > div > figure {
display: none;
position: fixed;
// inset: 0;
// margin: auto;
top: 0;
right: 0;
// width: 640px;
// height: 480px;
background: #000;
overflow: hidden;
padding: 8px 8px 0;
}
.equipment-pics > div:hover > figure {
margin: 0;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.equipment-pics > div > figure > img {
flex: 1;
}
.equipment-pics > div > figure > figcaption {
height: 24px;
margin-top: 8px;
font-size: 18px;
line-height: 1;
color: #fff;
}
</style>

View File

@@ -60,9 +60,9 @@
name: '基本信息',
key: 'base',
rows: computedRows,
url: '/base/equipment/get',
urlUpdate: '/base/equipment/update',
urlCreate: '/base/equipment/create',
url: '/base/core-equipment/get',
urlUpdate: '/base/core-equipment/update',
urlCreate: '/base/core-equipment/create',
queryParams: { id: form.id },
},
{
@@ -105,9 +105,6 @@
<script>
import moment from 'moment';
import basicPageMixin from '@/mixins/lb/basicPageMixin';
import { getAccessToken } from '@/utils/auth';
import EquipmentPics from './components/EquipmentPics';
import EquipmentAssets from './components/EquipmentAssets';
import EquipmentDrawer from './components/EquipmentDrawer';
import {
@@ -132,6 +129,12 @@ export default {
return {
searchBarKeys: ['name', 'code'],
tableBtn: [
this.$auth.hasPermi(`base:equipment:update`)
? {
type: 'detail',
btnName: '详情',
}
: undefined,
this.$auth.hasPermi('base:equipment:update')
? {
type: 'edit',
@@ -144,12 +147,6 @@ export default {
btnName: '删除',
}
: undefined,
this.$auth.hasPermi(`base:equipment:update`)
? {
type: 'detail',
btnName: '详情',
}
: undefined,
].filter((v) => v),
tableProps: [
{
@@ -213,6 +210,13 @@ export default {
{
type: 'separate',
},
{
type: this.$auth.hasPermi('base:equipment:export') ? 'button' : '',
btnName: '导出',
name: 'export',
plain: true,
color: 'primary',
},
{
type: this.$auth.hasPermi('base:equipment:create') ? 'button' : '',
btnName: '新增',
@@ -220,12 +224,6 @@ export default {
plain: true,
color: 'success',
},
{
type: this.$auth.hasPermi('base:equipment:export') ? 'button' : '',
btnName: '导出',
name: 'export',
color: 'warning',
},
],
rows: [
[
@@ -242,7 +240,7 @@ export default {
input: true,
label: '设备编码',
prop: 'code',
url: '/base/equipment/getCode',
url: '/base/core-equipment/getCode',
},
{
input: true,
@@ -269,7 +267,7 @@ export default {
select: true,
label: '设备类型',
prop: 'equipmentTypeId',
url: '/base/equipment-type/page?pageNo=1&pageSize=100',
url: '/base/core-equipment-type/page?pageNo=1&pageSize=100',
bind: {
filterable: true,
},

View File

@@ -37,7 +37,12 @@
@close="cancel"
@cancel="cancel"
@confirm="submitForm">
<DialogForm v-if="open" ref="form" v-model="form" :rows="rows" />
<DialogForm
v-if="open"
ref="form"
v-model="form"
:has-files="true"
:rows="rows" />
</base-dialog>
</div>
</template>
@@ -139,7 +144,7 @@ export default {
input: true,
label: '设备类型编码',
prop: 'code',
url: '/base/equipment-type/getCode',
url: '/base/core-equipment-type/getCode',
},
],
[
@@ -147,7 +152,7 @@ export default {
select: true,
label: '父类',
prop: 'parentId',
url: '/base/equipment-type/page?pageNo=1&pageSize=100',
url: '/base/core-equipment-type/page?pageNo=1&pageSize=100',
},
{},
],
@@ -207,8 +212,6 @@ export default {
name: undefined,
parentId: undefined,
remark: undefined,
fileNames: [],
fileUrls: [],
};
this.resetForm('form');
},

View File

@@ -416,7 +416,7 @@ export default {
/** 准备设备数据 */
async initEquipment() {
const { code, data } = await this.$axios({
url: '/base/equipment/listAll',
url: '/base/core-equipment/listAll',
method: 'get',
});
if (code == 0) {

View File

@@ -223,7 +223,7 @@ export default {
/** 准备设备数据 */
async initEquipment() {
const { code, data } = await this.$axios({
url: '/base/equipment/listAll',
url: '/base/core-equipment/listAll',
method: 'get',
});
if (code == 0) {

View File

@@ -0,0 +1,367 @@
<!--
filename: index.vue
author: liubin
date: 2023-10-19 10:03:42
description:
-->
<template>
<div class="app-container">
<!-- 搜索工作栏 -->
<SearchBar :formConfigs="searchBarFormConfig" ref="search-bar" />
<section class="process-flow">
<el-button class="process-item__add-btn" @click="handleAdd">
+ 新增工艺
</el-button>
<ProcessItem
v-for="item in list"
:key="item.id"
:id="item.id"
:name="item.name"
:line="item.lineName"
:desc="item.remark"
:isActive="item.enabled"
@edit="handleUpdate" />
</section>
<base-dialog
:dialogTitle="title"
:dialogVisible="open"
@close="cancel"
@cancel="cancel"
width="45%"
@confirm="submitForm">
<DialogForm
v-if="open"
key="index-dialog-form"
ref="form"
v-model="form"
:rows="rows" />
</base-dialog>
</div>
</template>
<script>
import basicPageMixin from '@/mixins/lb/basicPageMixin';
// import cache from '@/utils/cache';
const ProcessItem = {
name: 'ProcessItem',
components: {},
props: ['id', 'name', 'line', 'desc', 'isActive'],
data() {
return {};
},
computed: {},
methods: {
handleEdit() {
this.$emit('edit', this.id);
},
handleViewDetail(e) {
this.$router.push({
name: 'ProcessFlowView',
params: {
id: this.id,
},
});
},
},
render: function (h) {
return (
<div
class={'process-item' + (this.isActive ? ' active' : '')}
style="display: flex; flex-direction: column; position: relative;">
<div
class="process-item__content"
style="flex: 1; display: flex; align-items: center; cursor: pointer;"
title="点击查看详细工序列表"
onClick={this.handleViewDetail}>
{this.isActive ? (
<span style="display: inline-block; width: 10px; height: 10px; border-radius: 100%; background: #0ebe3a; position: absolute; top: 20px; right: 20px;" />
) : (
''
)}
<svg-icon
icon-class="tree-table"
style="margin-left: 12px; width: 48px; height: 48px; color: #0858ff33"
/>
<div
class="info"
style="margin-left: 12px; display: flex; flex-direction: column;">
<h2 style="margin: 20px 0 0; font-weight: 600; font-size: 18px; ">
{this.name}
</h2>
<h3 style="margin: 0; font-weight: 400; font-size: 14px; line-height: 2; color: #888;">
{this.line || '/'}
</h3>
<p style="margin: 0; text-overflow: ellipse; white-space: nowrap; font-weight: 400; font-size: 14px; line-height: 1.25; color: #888;">
{this.desc}
</p>
</div>
</div>
<div
class="process-item__footer"
style="background: #f7f9fa; border-top: 1px solid #0001;">
<el-row gutter={20}>
<el-col
span={8}
style="text-align: center; border-right: 1px solid #0001">
<el-button
type="text"
style="color: #0007; line-height: 1.75"
onClick={this.handleEdit}>
编辑
</el-button>
</el-col>
<el-col
span={8}
style="text-align: center; border-right: 1px solid #0001">
<el-button type="text" style="color: #0007; line-height: 1.75">
复制
</el-button>
</el-col>
<el-col span={8} style="text-align: center;">
<el-button type="text" style="color: #0007; line-height: 1.75">
删除
</el-button>
</el-col>
</el-row>
</div>
</div>
);
},
};
export default {
name: 'ProcessFlow',
components: { ProcessItem },
mixins: [basicPageMixin],
props: {},
data() {
return {
updateUrl: '/extend/process-flow/update',
addUrl: '/extend/process-flow/create',
pageUrl: '/extend/process-flow/page',
infoUrl: '/extend/process-flow/get',
searchBarKeys: ['name', 'code', 'lineId', 'productId'],
searchBarFormConfig: [
{
label: '工艺流程列表',
},
],
queryParams: {
pageNo: 1,
pageSize: 10,
code: null,
name: null,
productId: null,
lineId: null,
},
lineList: null,
list: [],
rows: [
[
{
input: true,
label: '工艺名称',
prop: 'name',
rules: [{ required: true, message: '不能为空', trigger: 'blur' }],
// bind: {
// disabled: this.editMode == 'detail', // some condition, like detail mode...
// }
},
{
input: true,
label: '工艺编码',
prop: 'code',
// url: '/base/core-equipment/getCode',
},
],
[
{
select: true,
label: '产线',
prop: 'lineId',
// cache: 'processFlow::lineList',
url: '/base/core-production-line/listAll',
bind: {
filterable: true,
},
},
{
switch: true,
label: '是否启用',
prop: 'enabled',
bind: {
'active-value': 1,
'inactive-value': 0,
},
},
],
[
{
textarea: true,
label: '功能描述',
prop: 'remark',
},
],
],
form: {
id: null,
code: null,
name: null,
productId: null,
lineId: null,
enabled: 1,
remark: null,
externalCode: null,
},
};
},
computed: {},
mounted() {
this.getList();
},
methods: {
cancel() {
this.open = false;
this.reset();
},
reset() {
this.form = {
id: null,
code: null,
name: null,
productId: null,
lineId: null,
enabled: 1,
remark: null,
externalCode: null,
};
this.resetForm('form');
},
handleAdd() {
this.reset();
this.open = true;
this.showUploadComponents = false;
this.title = '添加工艺';
},
async handleUpdate(id) {
this.reset();
const { data } = await this.info({ id });
this.form = data;
this.open = true;
this.title = '修改工艺';
},
submitForm() {
this.$refs['form'].validate((valid) => {
if (!valid) {
return;
}
// 修改的提交
if (this.form.id != null) {
this.put(this.form).then((response) => {
this.$modal.msgSuccess('修改成功');
this.open = false;
this.getList();
});
return;
}
// 添加的提交
this.post(this.form).then((response) => {
this.$modal.msgSuccess('新增成功');
this.open = false;
this.getList();
});
});
},
async getList() {
this.loading = true;
const { code, data } = await this.recv(this.queryParams);
if (code == 0) {
this.list = data.list;
this.total = data.total;
this.loading = false;
return;
}
this.loading = false;
},
// async getList() {
// this.loading = true;
// const { code, data } = await this.recv(this.queryParams);
// if (code == 0) {
// const list = [];
// for (const item of data.list) {
// const newItem = await this.itemAttachName(item);
// list.push(newItem);
// }
// this.list = list;
// this.total = data.total;
// this.loading = false;
// return;
// }
// this.loading = false;
// },
// async itemAttachName(item) {
// if (!this.lineList) {
// this.lineList = await cache.getList(
// 'processFlow::lineList',
// async () => {
// const { code, data } = await this.$axios(
// '/base/core-production-line/listAll'
// );
// if (code == 0) {
// return data;
// }
// }
// );
// }
// return {
// ...item,
// lineName: this.lineList.find((line) => line.id == item.lineId)?.name,
// };
// },
},
};
</script>
<style scoped lang="scss">
.process-flow {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
grid-auto-rows: 200px;
gap: 24px;
}
.process-item__add-btn {
display: grid;
border: 1px solid #ccc;
font-size: 20px;
color: #ccc;
border-style: dashed;
border-radius: 6px;
place-items: center;
cursor: pointer;
transition: all 0.2s ease-in;
&:hover {
color: #555;
border-color: #555;
}
}
.process-item {
border-radius: 4px;
box-shadow: 0 0 6px 1px #ccc;
overflow: hidden;
// &.active {
// box-shadow: 0 0 6px 1px #18c8bf66;
// }
}
</style>

View File

@@ -0,0 +1,104 @@
<!--
filename: ProcessBomList.vue
author: liubin
date: 2023-10-20 15:00:58
description:
-->
<template>
<section class="process-bom">
<SearchBar :formConfigs="searchBarFormConfig" ref="search-bar" />
<div
class="btns"
style="
text-align: right;
position: absolute;
top: 20px;
right: 20px;
display: flex;
">
<el-button type="primary" plain class="btn-create" icon="el-icon-plus">
分配设备
</el-button>
<el-input
icon="el-icon-search"
placeholder="搜索"
style="margin-left: 20px">
<i slot="prefix" class="el-input__icon el-icon-search"></i>
</el-input>
</div>
<!-- 列表 -->
<base-table
:table-props="tableProps"
:page="queryParams.pageNo"
:limit="queryParams.pageSize"
:table-data="list"
@emitFun="handleEmitFun">
<method-btn
v-if="tableBtn.length"
slot="handleBtn"
label="操作"
:width="120"
:method-list="tableBtn"
@clickBtn="handleTableBtnClick" />
</base-table>
<!-- 分页组件 -->
<pagination
v-show="total > 0"
:total="total"
:page.sync="queryParams.pageNo"
:limit.sync="queryParams.pageSize"
@pagination="getList" />
</section>
</template>
<script>
export default {
name: 'ProcessBom',
components: {},
props: {},
data() {
return {
searchBarFormConfig: [{ label: '工序下设备' }],
tableProps: [
// {
// prop: 'createTime',
// label: '添加时间',
// fixed: true,
// width: 180,
// filter: (val) => moment(val).format('yyyy-MM-DD HH:mm:ss'),
// },
{ prop: 'name', label: '设备名称' },
{ prop: 'code', label: '物料BOM' },
{ prop: 'remark', label: '参数BOM' },
],
list: [],
total: 0,
tableBtn: [],
queryParams: {
pageNo: 1,
pageSize: 10,
},
};
},
computed: {},
methods: {
handleEmitFun() {},
handleTableBtnClick() {},
getList() {},
},
};
</script>
<style scoped lang="scss">
.process-bom {
position: relative;
flex: 1;
padding: 12px 20px;
background: #fff;
border-radius: 8px;
}
</style>

View File

@@ -0,0 +1,504 @@
<!--
filename: ProcessGraph.vue
author: liubin
date: 2023-10-20 15:00:58
description:
-->
<template>
<section class="process-graph">
<SearchBar :formConfigs="searchBarFormConfig" ref="search-bar" />
<div class="btns" style="text-align: right; position: absolute; top: 20px; right: 20px">
<el-button type="warning" @click="undo" plain v-if="allowUndo" :disabled="!allowUndo" icon="el-icon-back">
撤销
</el-button>
<el-button type="warning" @click="redo" plain v-if="allowRedo" :disabled="!allowRedo">
下一步
<i class="el-icon-right el-icon--right"></i>
</el-button>
<el-button class="btn-refresh" @click="handleUpdateLayout" icon="el-icon-refresh">
刷新布局</el-button>
<el-button type="primary" plain class="btn-create" icon="el-icon-plus" @click="handleAdd">
新建工序
</el-button>
<el-button class="btn-serialize" @click="handleToJson">序列化</el-button>
<el-button class="btn-antiserialize" @click="handleLoadJson">
反序列化
</el-button>
<el-button class="btn-edit" @click="handleEdit">编辑</el-button>
<el-button type="error" class="btn-delete" @click="handleDelete">
删除
</el-button>
</div>
<div class="process-graph__panel" ref="panel"></div>
<!-- 对话框(添加 / 修改) -->
<base-dialog :dialogTitle="title" :dialogVisible="open" width="35%" @close="cancel" @cancel="cancel"
@confirm="submitForm">
<DialogForm v-if="open" ref="form" v-model="form" :rows="rows" />
</base-dialog>
</section>
</template>
<script>
import { Graph } from '@antv/x6';
import ProcessNode, { createProcessNode, CACHE_NAME } from './ProcessNode';
import DialogForm from '@/components/DialogForm';
// import { IdToName } from '@/utils'
Graph.registerNode('process-node', ProcessNode);
export default {
name: 'ProcessGraph',
components: { DialogForm },
props: {},
inject: ['getFlowId'],
data() {
return {
allowRedo: false,
allowUndo: false,
graph: null,
searchBarFormConfig: [{ label: '工序列表' }],
title: '',
open: false,
form: {
name: '', // 工序名称
sectionId: '', // 工段id
remark: '', // 描述
},
rows: [
[
{
input: true,
label: '工序名称',
prop: 'name',
rules: [{ required: true, message: '不能为空', trigger: 'blur' }],
},
],
[
{
select: true,
label: '工段',
prop: 'sectionId',
url: '/base/core-workshop-section/listAll',
rules: [{ required: true, message: '不能为空', trigger: 'blur' }],
bind: {
filterable: true,
},
cache: CACHE_NAME
},
],
[
{
textarea: true,
label: '工序说明',
prop: 'remark',
},
],
],
updateUrl: '/extend/process-flow-view/update',
addUrl: '/extend/process-flow-view/create',
// pageUrl: '/extend/process-flow-det/get',
infoUrl: '/extend/process-flow-view/get',
layout: {
id: null,
flowId: null,
content: '',
createTime: null
},
};
},
watch: {
'form.sectionId': {
handler(id) {
// const { form } = this;
// const { sectionId } = form;
// if (sectionId) {
// const { label } = this.$refs['form'].getSelectItem(
// 'sectionId',
// sectionId
// );
// form.workshopName = label;
// }
},
immediate: false,
},
},
activated() {
this.loadLayout().then(json => {
this.initGraph(json)
})
// const pn1 = graph.addNode({
// shape: 'process-node',
// x: 30,
// y: 30,
// processName: '工序00A',
// workshopName: '工段1',
// processDesc: 'test test test',
// processId: '1',
// tools: [{ name: 'button-remove' }],
// });
// const pn2 = graph.addNode({
// shape: 'process-node',
// x: 240,
// y: 30,
// processName: '工序00B',
// workshopName: '工段1',
// processDesc: 'test test test',
// processId: '1',
// });
// const pn3 = graph.addNode({
// shape: 'process-node',
// x: 360,
// y: 30,
// processName: '工序00C',
// workshopName: '工段1',
// processDesc: 'test test test',
// processId: '1',
// });
// const pn4 = graph.addNode({
// shape: 'process-node',
// x: 360,
// y: 120,
// processName: '工序00D',
// workshopName: '工段1',
// processDesc: 'test test test',
// processId: '1',
// });
// const pn5 = graph.addNode({
// shape: 'process-node',
// x: 500,
// y: 30,
// processName: '工序00E',
// workshopName: '工段1',
// processDesc: 'test test test',
// processId: '1',
// });
// graph.addEdge({
// source: pn1,
// target: pn2,
// router: {
// name: 'er',
// },
// attrs: {
// line: {
// stroke: '#0b58ff',
// strokeWidth: 1,
// targetMarker: {
// // name: 'classic',
// // name: 'async',
// size: 0,
// },
// },
// },
// });
// graph.addEdge({
// source: pn2,
// target: pn3,
// router: {
// name: 'er',
// },
// attrs: {
// line: {
// stroke: '#0b58ff',
// strokeWidth: 1,
// targetMarker: {
// // name: 'classic',
// // name: 'async',
// size: 0,
// },
// },
// },
// });
// graph.addEdge({
// source: pn2,
// target: pn4,
// router: {
// name: 'er',
// },
// attrs: {
// line: {
// stroke: '#0b58ff',
// strokeWidth: 1,
// targetMarker: {
// // name: 'classic',
// // name: 'async',
// size: 0,
// },
// },
// },
// });
// graph.addEdge({
// source: pn3,
// target: pn5,
// router: {
// name: 'er',
// },
// attrs: {
// line: {
// stroke: '#0b58ff',
// strokeWidth: 1,
// targetMarker: {
// // name: 'classic',
// // name: 'async',
// size: 0,
// },
// },
// },
// });
// graph.addEdge({
// source: pn4,
// target: pn5,
// router: {
// name: 'er',
// },
// attrs: {
// line: {
// stroke: '#0b58ff',
// strokeWidth: 1,
// targetMarker: {
// // name: 'classic',
// // name: 'async',
// size: 0,
// },
// },
// },
// });
// const pn1 = graph.addNode({
// shape: 'process-node',
// x: 0,
// y: 0,
// detName: '测试工序', // 工序名称
// sectionName: 'default', // 工段
// detDesc: 'loremakdfkd...', // 工序说明
// processId: 'p-1', // 工艺ID
// detId: 'det-id-1', // 工序ID
// tools: [{ name: 'button-remove' }],
// });
// const htmlNode = graph.addNode({
// x: 0,
// y: 0,
// width: 200,
// height: 100,
// shape: 'html',
// html() {
// const ctn = document.createElement('div');
// ctn.style.width = '100%';
// ctn.style.height = '100%';
// ctn.style.border = '1px solid #ccc';
// ctn.style.background = '#fff';
// ctn.innerText = 'hello';
// return ctn;
// },
// });
},
computed: {},
methods: {
initGraph(json) {
const graph = new Graph({
container: this.$refs.panel,
grid: {
size: 10,
visible: true,
},
history: true
});
graph.fromJSON(json)
this.graph = graph;
},
resetLayout() {
this.layout = {
id: null,
flowId: null,
content: '',
createTime: null
}
},
async loadLayout() {
const flowId = this.$route.params.id;
if (!flowId) return { cells: [] }
const { code, data } = await this.info({ id: flowId });
if (code == 0) {
if (data) {
this.layout = data;
return JSON.parse(data?.content) || { cells: [] };
}
return { cells: [] };
}
this.resetLayout();
return Promise.reject(this.infoUrl + ' 接口出错!');
},
handleToJson() { },
handleLoadJson() { },
handleDumpJson() {
if (this.graph) {
console.log(JSON.stringify(this.graph.toJSON(), null, 2));
}
},
async handleUpdateLayout() {
this.layout.content = JSON.stringify(this.graph.toJSON());
let code, data;
// 手动刷新布局
if (this.layout.id) {
({ code, data } = await this.put(this.layout));
} else {
this.layout.flowId = this.$route.params.id;
({ code, data } = await this.post(this.layout));
}
if (code == 0) {
this.$modal.msgSuccess('布局已刷新!')
}
},
reset() {
this.form = {
name: '', // 工序名称
sectionId: '', // 工段id
remark: '', // 描述
};
this.resetForm('form');
},
/** 取消按钮 */
cancel() {
this.open = false;
this.reset();
},
handleAdd() {
this.reset();
this.open = true;
this.title = '添加工序';
},
handleEdit() {
this.open = true;
this.title = '编辑工序';
},
handleDelete(id) { },
/** 提交按钮 */
submitForm() {
this.$refs['form'].validate((valid) => {
if (!valid) {
return;
}
// 修改的提交
if (this.form.id != null) {
this.updateProcess();
return;
}
const flowId = this.getFlowId();
this.createProcess()
.then(({ id, name, sectionId, remark }) => {
if (!id || !flowId) return null;
return createProcessNode({
flowId: flowId,
name, sectionId, remark,
id,
})
}
).then(node => {
if (!node) {
this.$modal.msgError('创建节点失败');
return;
};
this.graph.addNode(node);
});
});
},
updateProcess() {
return updateEquipmentType(this.form).then((response) => {
this.$modal.msgSuccess('修改成功');
this.open = false;
// this.getList();
});
},
createProcess() {
// const flowId = this.$route.params.id;
const flowId = this.getFlowId(); // it also works
if (!flowId) {
this.$modal.msgError('工艺ID不能为空');
return Promise.reject(null);
}
console.log('create process', this.form)
// 添加的提交
return this.post({ flowId: this.flowId, ...this.form }).then(
({ code, data }) => {
this.$modal.msgSuccess('新增成功');
this.open = false;
// this.getList();
return {
id: data, // 服务器返回的新建的工段id
...this.form, // 保存一份 this.form 副本,当 open->false 时 this.form 里的信息就清空了
};
}
);
},
put(payload) {
return this.http(this.updateUrl, 'put', payload);
},
post(payload) {
return this.http(this.addUrl, 'post', payload);
},
recv(payload) {
return this.http(this.pageUrl, 'get', payload);
},
info(payload) {
return this.http(this.infoUrl, 'get', payload);
},
http(url, method, payload) {
return this.$axios({
url,
method,
params: method === 'get' ? payload : null,
data: method !== 'get' ? payload : null,
})
},
},
};
</script>
<style scoped lang="scss">
.process-graph {
padding: 12px 20px 20px;
background: #fff;
border-radius: 8px;
position: relative;
}
.process-graph__panel {
height: 300px;
}
</style>
<style>
.x6-widget-selection-selected {
border: 1px solid red;
}
</style>

View File

@@ -0,0 +1,133 @@
<!--
filename: ProcessInfo.vue
author: liubin
date: 2023-10-20 15:00:58
description:
-->
<template>
<section class="process-info">
<SearchBar :formConfigs="searchBarFormConfig" ref="search-bar" />
<el-row :gutter="20">
<el-col :span="6">
<InfoItem label="工艺名称" :value="form.name" />
</el-col>
<el-col :span="6">
<InfoItem label="产线" :value="form.lineName" />
</el-col>
<el-col :span="12">
<InfoItem label="工艺描述" :value="form.remark" />
</el-col>
</el-row>
<el-row :gutter="20" style="margin-top: 12px;">
<el-col :span="6">
<!-- <InfoItem label="创建人" value="xxse" /> -->
</el-col>
<el-col :span="6">
<InfoItem label="创建时间" :value="form.createTime" />
</el-col>
<el-col :span="6">
<!-- <InfoItem label="更新人" value="xxse" /> -->
</el-col>
<el-col :span="6">
<!-- <InfoItem label="更新时间" value="2023-10-22 10:11:00" /> -->
</el-col>
</el-row>
</section>
</template>
<script>
const InfoItem = {
name: 'InfoItem',
components: {},
props: ['label', 'value'],
data() {
return {};
},
computed: {},
methods: {},
render: function (h) {
return (
<div style="display: flex; align-items: center; font-size: 14px; line-height: 1.5">
<span style="width: 100px; text-align: left; font-weight: 700">{this.label}:</span>
<span style="width: 200px; text-align: left; text-overflow: ellipse; white-space: nowrap">
{this.value}
</span>
</div>
);
},
};
export default {
name: 'ProcessInfo',
components: { InfoItem },
props: {},
inject: ['getFlowId'],
data() {
return {
infoUrl: '/extend/process-flow/get',
searchBarFormConfig: [{ label: '工艺详情' }],
form: {
id: null,
name: null,
lineName: null,
createTime: null,
remark: null,
enable: null,
code: null
},
};
},
activated() {
this.getInfo()
},
computed: {},
methods: {
// utils
http(url, method, payload) {
return this.$axios({
url,
method,
params: method === 'get' ? payload : null,
data: method !== 'get' ? payload : null,
})
},
put(payload) {
return this.http(this.updateUrl, 'put', payload);
},
post(payload) {
return this.http(this.addUrl, 'post', payload);
},
recv(payload) {
return this.http(this.pageUrl, 'get', payload);
},
info(payload) {
return this.http(this.infoUrl, 'get', payload);
},
async getInfo() {
const flowId = this.$route.params.id;
if (!flowId) this.$router.go(-1);
const { code, data } = await this.info({ id: flowId });
// debugger;
if (code == 0) {
this.form = {
...data
};
} else {
this.$modal.msgError('工艺信息获取失败')
}
}
},
};
</script>
<style scoped lang="scss">
.process-info {
padding: 12px 20px 20px;
background: #fff;
border-radius: 8px;
}
</style>

View File

@@ -0,0 +1,116 @@
import { Node, ObjectExt } from '@antv/x6';
import { IdToName } from '@/utils'
import cache from '@/utils/cache'
import axios from '@/utils/request'
export default class ProcessNode extends Node { }
ProcessNode.config({
width: 240,
height: 100,
markup: [
{
tagName: 'rect',
selector: 'container',
attrs: {
x: 0,
y: 0,
width: 200,
height: 100,
fill: 'transparent',
stroke: '#ccc'
},
},
{
tagName: 'rect',
attrs: {
x: 0,
y: 0,
width: 200,
height: 50,
fill: '#ffffff',
},
},
{
tagName: 'rect',
attrs: {
x: 0,
y: 50,
width: 200,
height: 50,
fill: '#f8f8f8',
},
},
{
tagName: 'text',
selector: 'detName',
attrs: {
x: 20,
y: 30,
},
},
{
tagName: 'text',
selector: 'sectionName',
attrs: {
x: 115,
y: 30,
},
},
{
tagName: 'text',
selector: 'detDesc',
attrs: {
x: 26,
y: 80,
fill: '#777',
fontSize: 14,
fill: '#1a90fc',
},
},
],
propHooks(metadata) {
const { detId, detName, detDesc, sectionName, processId, ...others } = metadata;
// debugger;
if (detName) ObjectExt.setByPath(others, 'attrs/detName/text', detName);
if (detDesc) ObjectExt.setByPath(others, 'attrs/detDesc/text', detDesc);
if (sectionName) ObjectExt.setByPath(others, 'attrs/sectionName/text', sectionName);
if (detId) ObjectExt.setByPath(others, 'attrs/detId/text', detId);
if (processId) ObjectExt.setByPath(others, 'attrs/processId/text', processId);
return others;
}
});
export const CACHE_NAME = 'ProcessDetail::section';
async function getSectionFrom(sectionId) {
const sectionList = await cache.getList(
CACHE_NAME,
async () => {
const { code, data } = await axios(
'/base/core-production-line/listAll'
);
if (code == 0) {
return data;
}
}
);
debugger;
return IdToName(sectionId, sectionList);
}
export async function createProcessNode({ flowId, id, name, sectionId, remark }) {
const sectionName = await getSectionFrom(sectionId);
return {
shape: 'process-node',
x: 0,
y: 0,
detName: name, // 工序名称
sectionName, // 工段
detDesc: remark, // 工序说明
processId: flowId, // 工艺ID
detId: id, // 工序ID
tools: [{ name: 'button-remove' }],
};
}
export async function createEdge(src, dest) { }

View File

@@ -0,0 +1,55 @@
<!--
filename: index.vue
author: liubin
date: 2023-10-18 12:25:46
description:
-->
<template>
<div class="app-container process-flow-view">
<ProcessInfo />
<ProcessDetail style="margin-top: 16px" />
<ProcessBomList style="margin-top: 16px" />
</div>
</template>
<script>
import ProcessInfo from './components/ProcessInfo.vue';
import ProcessBomList from './components/ProcessBomList.vue';
import ProcessDetail from './components/ProcessDetail.vue';
export default {
name: 'ProcessFlowView',
components: { ProcessInfo, ProcessDetail, ProcessBomList },
props: {},
data() {
return {
flowId: null,
};
},
provide() {
const that = this;
return {
getFlowId() {
return that.flowId;
},
};
},
activated() {
console.log('activated...', this.$route.params);
this.flowId = this.$route.params.id;
},
computed: {},
methods: {},
};
</script>
<style scoped lang="scss">
.process-flow-view {
padding: 8px;
flex: 1;
background: #f2f4f9;
display: flex;
flex-direction: column;
}
</style>

View File

@@ -117,6 +117,7 @@ export default {
{
_action: 'params-monitor',
label: '操作',
width: 56,
subcomponent: {
props: ['injectData'],
render: function (h) {
@@ -124,10 +125,10 @@ export default {
return h(
'el-button',
{
class: 'iconfont icon-detail',
props: { type: 'text' },
on: {
click: function () {
console.log('inejctdata', _this.injectData);
_this.$emit('emitData', {
action: _this.injectData._action,
// value: _this.injectData.id,
@@ -135,8 +136,8 @@ export default {
});
},
},
},
'查看详情'
}
// '查看详情'
);
},
},
@@ -215,7 +216,7 @@ export default {
/** 根据产线获取设备 */
async getEquipmentList(id) {
const { data } = await this.$axios({
url: '/base/equipment/listByLine',
url: '/base/core-equipment/listByLine',
method: 'get',
params: { id },
});

View File

@@ -64,6 +64,7 @@ export default {
name: item.inspectionContent,
type: 'bar',
barCategoryGap: 12,
barWidth: 20,
data: [],
};

17034
yarn.lock

File diff suppressed because it is too large Load Diff