Merge branch 'master' of http://gitea.xxhhcty.xyz:8080/zcdsj/factory_web
This commit is contained in:
commit
02f3d3e3dd
|
|
@ -21,8 +21,11 @@ VUE_APP_PJ = 'gx'
|
|||
|
||||
# VUE_APP_BASEURL = http://10.50.211.228:2250/
|
||||
|
||||
VUE_APP_API_BASEURL = http://127.0.0.1:2226/api
|
||||
VUE_APP_BASEURL = http://127.0.0.1:2226
|
||||
# VUE_APP_API_BASEURL = http://127.0.0.1:2226/api
|
||||
# VUE_APP_BASEURL = http://127.0.0.1:2226
|
||||
|
||||
VUE_APP_API_BASEURL = http://10.0.11.51:2250/api
|
||||
VUE_APP_BASEURL = http://10.0.11.51:2250
|
||||
|
||||
# 托克逊
|
||||
# VUE_APP_API_BASEURL = http://10.50.211.228:2250/api
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@ node_modules
|
|||
/public/glb/
|
||||
/dist
|
||||
.VSCodeCounter/
|
||||
.claude/
|
||||
.codex/
|
||||
|
||||
# local env files
|
||||
.env.local
|
||||
|
|
@ -14,6 +16,7 @@ node_modules
|
|||
.env.production
|
||||
.env.development
|
||||
|
||||
|
||||
# Log files
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
|
|
@ -28,5 +31,7 @@ pnpm-debug.log*
|
|||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
*.bat
|
||||
|
||||
/package-lock.json
|
||||
/vue.config.js
|
||||
|
|
|
|||
|
|
@ -101,6 +101,14 @@ export default {
|
|||
`${config.API_URL}/cm/labeltemplate/${id}/send_to_coder/`,
|
||||
data);
|
||||
}
|
||||
},
|
||||
sendToHanslaser:{
|
||||
name: "下发到激光",
|
||||
req: async function(id, data){
|
||||
return await http.post(
|
||||
`${config.API_URL}/cm/labeltemplate/${id}/send_to_hanslaser/`,
|
||||
data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -126,6 +126,14 @@ export default {
|
|||
data);
|
||||
}
|
||||
},
|
||||
get_svs_char: {
|
||||
name: "获取数据识别",
|
||||
req: async function(data){
|
||||
return await http.get(
|
||||
`${config.API_URL}/em/equipment/get_svs_char/`,
|
||||
data);
|
||||
}
|
||||
}
|
||||
},
|
||||
//巡检记录
|
||||
einspect: {
|
||||
|
|
|
|||
|
|
@ -6,11 +6,24 @@ export default {
|
|||
name: "列表",
|
||||
req: async function(data){
|
||||
return await http.post(
|
||||
`${config.HOST_URL}/hfnf_api/mplogx/`,
|
||||
// 同源路径,由 nginx(/factory_api/) 反向代理到统计服务 10.0.11.52:5800
|
||||
`${config.HOST_URL}/factory_api/mplogx/`,
|
||||
// "http://10.0.11.52:5800/mplogx/",
|
||||
data
|
||||
);
|
||||
}
|
||||
},
|
||||
},
|
||||
stats: {
|
||||
list: {
|
||||
name: "数据统计",
|
||||
req: async function(params){
|
||||
return await http.get(
|
||||
// 同源路径,由 nginx(/factory_api/) 反向代理到统计服务 10.0.11.52:5800
|
||||
`${config.HOST_URL}/factory_api/stats`,
|
||||
params
|
||||
);
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
@ -127,6 +127,7 @@ const routes = [
|
|||
name: "cement_data_template",
|
||||
path: "/cement_data_template",
|
||||
meta: {
|
||||
hidden: true,
|
||||
title: "数据模板",
|
||||
},
|
||||
component: "home/cement_data_template",
|
||||
|
|
@ -3528,6 +3529,7 @@ const routes = [
|
|||
path: "/statistic/task_rate",
|
||||
meta: {
|
||||
title: "任务进度",
|
||||
hidden: true,
|
||||
// icon: "el-icon-DataAnalysis",
|
||||
perms: ["statistic_wpm"],
|
||||
},
|
||||
|
|
@ -3595,6 +3597,7 @@ const routes = [
|
|||
name: "user_statistics",
|
||||
meta: {
|
||||
title: "绩效统计",
|
||||
hidden: true,
|
||||
icon: "el-icon-trend-charts",
|
||||
perms: ["statistic_kpi"],
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,13 +1,39 @@
|
|||
<template>
|
||||
<div class="user-bar">
|
||||
<div class="screen panel-item" @click="printerSetting">
|
||||
<el-dropdown
|
||||
class="screen panel-item"
|
||||
trigger="click"
|
||||
@command="handleSettingCommand"
|
||||
>
|
||||
<div class="setting-trigger" title="设置">
|
||||
<el-icon>
|
||||
<el-icon-printer :size="26"/>
|
||||
<el-icon-setting color="#fff" :size="26"/>
|
||||
</el-icon>
|
||||
</div>
|
||||
<div class="screen panel-item" @click="coderSetting" title="喷码设置">
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item command="printer">
|
||||
<el-icon><el-icon-printer/></el-icon>
|
||||
<span style="margin-left:6px">打印设置</span>
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item command="coder">
|
||||
<el-icon><el-icon-postcard/></el-icon>
|
||||
<span style="margin-left:6px">喷码设置</span>
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item command="ocr">
|
||||
<el-icon><el-icon-view/></el-icon>
|
||||
<span style="margin-left:6px">数字识别设置</span>
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item command="marker">
|
||||
<el-icon><el-icon-edit-pen/></el-icon>
|
||||
<span style="margin-left:6px">打码设置</span>
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
<div class="screen panel-item" @click="openAddCoder" title="补喷码">
|
||||
<el-icon>
|
||||
<el-icon-postcard :size="26"/>
|
||||
<el-icon-brush :size="26"/>
|
||||
</el-icon>
|
||||
</div>
|
||||
<scan-dialog ref="scanDialog" :type="'info'" @closed="scanClose"> </scan-dialog>
|
||||
|
|
@ -134,6 +160,38 @@
|
|||
<el-button type="primary" @click="saveCoder">保存</el-button>
|
||||
</el-footer>
|
||||
</el-dialog>
|
||||
<el-dialog title="数字识别设置" v-model="setOcrVisible" width="600px">
|
||||
<el-form label-width="140px">
|
||||
<el-form-item label="IP">
|
||||
<el-input v-model="ocr_ip" placeholder="IP"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="Port">
|
||||
<el-input v-model="ocr_port" placeholder="端口号"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="unit">
|
||||
<el-input v-model="ocr_unit" placeholder="位号"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-footer>
|
||||
<el-button type="primary" @click="saveOcr">保存</el-button>
|
||||
</el-footer>
|
||||
</el-dialog>
|
||||
<el-dialog title="打码设置" v-model="setMarkerVisible" width="600px">
|
||||
<el-form label-width="140px">
|
||||
<el-form-item label="打码IP">
|
||||
<el-input v-model="marker_ip" placeholder="打码机器分配的IP地址"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="打码端口">
|
||||
<el-input v-model="marker_port" placeholder="打码机器分配的端口号"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="数字码模板名">
|
||||
<el-input v-model="marker_jobname" placeholder="打码机信息模板名, 如 Barcode"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-footer>
|
||||
<el-button type="primary" @click="saveMarker">保存</el-button>
|
||||
</el-footer>
|
||||
</el-dialog>
|
||||
<el-dialog
|
||||
v-model="searchVisible"
|
||||
:width="700"
|
||||
|
|
@ -145,6 +203,41 @@
|
|||
<search @success="searchVisible = false"></search>
|
||||
</el-dialog>
|
||||
<scan-detail ref="scanDetails" v-if="scanVisible" :mlogId="scanId"></scan-detail>
|
||||
|
||||
<!-- 补喷码弹窗 -->
|
||||
<el-dialog title="补喷码" v-model="addCoderVisible" width="720px" destroy-on-close>
|
||||
<div style="display:flex;gap:8px;margin-bottom:16px">
|
||||
<el-input
|
||||
v-model="addCoderSearch"
|
||||
placeholder="输入板号搜索"
|
||||
clearable
|
||||
style="width:320px"
|
||||
@keyup.enter="searchWpr"
|
||||
/>
|
||||
<el-button type="primary" :loading="addCoderSearching" @click="searchWpr">搜索</el-button>
|
||||
</div>
|
||||
<el-table :data="wprList" v-loading="addCoderSearching" border size="small">
|
||||
<el-table-column label="板号" prop="number" min-width="120" />
|
||||
<el-table-column label="物料名称" min-width="160" show-overflow-tooltip>
|
||||
<template #default="scope">{{ (scope.row.material_name || '').split('|')[0] }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="批次号" prop="wm_batch" min-width="130" />
|
||||
<el-table-column label="操作" width="180" align="center">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
type="success" size="small"
|
||||
:loading="!!addCoderLoadingMap[scope.row.id + '_1']"
|
||||
@click="addCoderSend(scope.row, 'coder_jobname', 'coder_field', '1')"
|
||||
>喷数字</el-button>
|
||||
<el-button
|
||||
type="primary" size="small"
|
||||
:loading="!!addCoderLoadingMap[scope.row.id + '_2']"
|
||||
@click="addCoderSend(scope.row, 'coder_jobname2', 'coder_field2', '2')"
|
||||
>喷二维码</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
|
@ -162,6 +255,8 @@ export default {
|
|||
visible:false,
|
||||
setNameVisible:false,
|
||||
setCoderVisible:false,
|
||||
setOcrVisible:false,
|
||||
setMarkerVisible:false,
|
||||
searchVisible: false,
|
||||
msg: false,
|
||||
msgList: {},
|
||||
|
|
@ -181,7 +276,18 @@ export default {
|
|||
coder_field2:'',
|
||||
coder_jobname:'',
|
||||
coder_jobname2:'',
|
||||
ocr_ip:'192.168.1.231',
|
||||
ocr_port:'80',
|
||||
ocr_unit:'',
|
||||
marker_ip:'',
|
||||
marker_port:'',
|
||||
marker_jobname:'',
|
||||
scanVisible:false,
|
||||
addCoderVisible: false,
|
||||
addCoderSearch: '',
|
||||
addCoderSearching: false,
|
||||
wprList: [],
|
||||
addCoderLoadingMap: {},
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
|
|
@ -207,6 +313,12 @@ export default {
|
|||
this.coder_field2 = localStorage.getItem("coder_field2") || "";
|
||||
this.coder_jobname = localStorage.getItem("coder_jobname") || "";
|
||||
this.coder_jobname2 = localStorage.getItem("coder_jobname2") || "";
|
||||
this.ocr_ip = localStorage.getItem("ocr_ip") || "";
|
||||
this.ocr_port = localStorage.getItem("ocr_port") || "";
|
||||
this.ocr_unit = localStorage.getItem("ocr_unit") || "";
|
||||
this.marker_ip = localStorage.getItem("marker_ip") || "";
|
||||
this.marker_port = localStorage.getItem("marker_port") || "";
|
||||
this.marker_jobname = localStorage.getItem("marker_jobname") || "";
|
||||
},
|
||||
methods: {
|
||||
openBook() {
|
||||
|
|
@ -296,6 +408,12 @@ export default {
|
|||
var element = document.documentElement;
|
||||
this.$TOOL.screen(element);
|
||||
},
|
||||
handleSettingCommand(command){
|
||||
if(command === 'printer') this.printerSetting();
|
||||
else if(command === 'coder') this.coderSetting();
|
||||
else if(command === 'ocr') this.ocrSetting();
|
||||
else if(command === 'marker') this.markerSetting();
|
||||
},
|
||||
printerSetting(){
|
||||
this.setNameVisible=true;
|
||||
},
|
||||
|
|
@ -320,6 +438,28 @@ export default {
|
|||
});
|
||||
this.setCoderVisible=false;
|
||||
},
|
||||
ocrSetting(){
|
||||
this.setOcrVisible=true;
|
||||
},
|
||||
saveOcr(){
|
||||
this.$TOOL.setOcr({
|
||||
"ocr_ip":this.ocr_ip,
|
||||
"ocr_port":this.ocr_port,
|
||||
"ocr_unit":this.ocr_unit
|
||||
});
|
||||
this.setOcrVisible=false;
|
||||
},
|
||||
markerSetting(){
|
||||
this.setMarkerVisible=true;
|
||||
},
|
||||
saveMarker(){
|
||||
this.$TOOL.setMarker({
|
||||
"marker_ip":this.marker_ip,
|
||||
"marker_port":this.marker_port,
|
||||
"marker_jobname":this.marker_jobname
|
||||
});
|
||||
this.setMarkerVisible=false;
|
||||
},
|
||||
//显示短消息
|
||||
showMsg() {
|
||||
this.msg = true;
|
||||
|
|
@ -333,6 +473,67 @@ export default {
|
|||
search() {
|
||||
this.searchVisible = true;
|
||||
},
|
||||
openAddCoder() {
|
||||
this.addCoderVisible = true;
|
||||
this.addCoderSearch = '';
|
||||
this.wprList = [];
|
||||
},
|
||||
async searchWpr() {
|
||||
const kw = this.addCoderSearch.trim();
|
||||
if (!kw) { this.$message.warning('请输入板号'); return; }
|
||||
this.addCoderSearching = true;
|
||||
try {
|
||||
const res = await this.$API.wpm.wpr.list.req({ number: kw, page: 0 });
|
||||
const list = Array.isArray(res) ? res : (res && res.results) || [];
|
||||
this.wprList = list;
|
||||
if (!list.length) this.$message.warning('未找到相关板号');
|
||||
} finally {
|
||||
this.addCoderSearching = false;
|
||||
}
|
||||
},
|
||||
addCoderSend(row, coderJobNameKey, coderFieldKey, suffix) {
|
||||
const that = this;
|
||||
const key = row.id + '_' + suffix;
|
||||
if (that.addCoderLoadingMap[key]) return;
|
||||
const coder_ip = localStorage.getItem('coder_ip') || '';
|
||||
if (!coder_ip) {
|
||||
that.$message.error('请先在右上角"喷码设置"配置喷码IP');
|
||||
return;
|
||||
}
|
||||
that.addCoderLoadingMap = { ...that.addCoderLoadingMap, [key]: true };
|
||||
const release = () => {
|
||||
const m = { ...that.addCoderLoadingMap };
|
||||
delete m[key];
|
||||
that.addCoderLoadingMap = m;
|
||||
};
|
||||
const coder_port = localStorage.getItem('coder_port') || '';
|
||||
const coder_field = localStorage.getItem(coderFieldKey) || '';
|
||||
const templateName = '喷码模板';
|
||||
const tdata = {
|
||||
number: row.number,
|
||||
name: (row.material_name || '').split('|')[0],
|
||||
ofrom_name: row.wm_material_ofrom_name || '',
|
||||
ofrom_batch: row.wm_batch || '',
|
||||
};
|
||||
that.$API.cm.labeltemplate.list.req({ name: templateName, page: 0 }).then(res => {
|
||||
const list = Array.isArray(res) ? res : (res && res.results) || [];
|
||||
const template = list.find(t => t.name === templateName);
|
||||
if (!template) {
|
||||
that.$message.error(`未找到标签模板: ${templateName}`);
|
||||
return Promise.reject(new Error('no_template'));
|
||||
}
|
||||
const body = { tdata_list: [tdata], coder_ip };
|
||||
if (coder_port) body.coder_port = Number(coder_port);
|
||||
if (coder_field) body.coder_field = coder_field;
|
||||
const coder_jobname = localStorage.getItem(coderJobNameKey) || '';
|
||||
if (coder_jobname) body.coder_jobname = coder_jobname;
|
||||
return that.$API.cm.labeltemplate.sendToCoder.req(template.id, body);
|
||||
}).then(() => {
|
||||
that.$message.success('喷码下发成功');
|
||||
}).catch(e => {
|
||||
if (e && e.message !== 'no_template') that.$message.error('喷码下发失败');
|
||||
}).finally(release);
|
||||
},
|
||||
scanClose(data){
|
||||
|
||||
let that = this;
|
||||
|
|
|
|||
|
|
@ -414,8 +414,8 @@ export default {
|
|||
}
|
||||
this.pmenu = this.$route.meta.breadcrumb
|
||||
? this.$route.meta.breadcrumb[0]
|
||||
: {};
|
||||
let lists = this.pmenu.children;
|
||||
: { meta: {}, children: [] };
|
||||
let lists = this.pmenu.children || [];
|
||||
let perms = this.$TOOL.data.get("PERMISSIONS") || [];
|
||||
for (var i = 0; i < lists.length; i++) {
|
||||
if (lists[i].meta && lists[i].meta.perms) {
|
||||
|
|
|
|||
11
src/main.js
11
src/main.js
|
|
@ -55,7 +55,14 @@ const _ResizeObserver = window.ResizeObserver;
|
|||
|
||||
window.ResizeObserver = class ResizeObserver extends _ResizeObserver {
|
||||
constructor(callback) {
|
||||
callback = debounce(callback, 16);
|
||||
super(callback);
|
||||
// 先包 try/catch 再 debounce:debounce 用 setTimeout 延迟执行,
|
||||
// 必须让真正执行回调时也在 try/catch 内,否则元素卸载瞬间
|
||||
// getComputedStyle 拿到非 Element 的错误会逃出 setTimeout 成为未捕获异常
|
||||
const safe = (entries, observer) => {
|
||||
try {
|
||||
callback(entries, observer);
|
||||
} catch (e) {}
|
||||
};
|
||||
super(debounce(safe, 16));
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -7,7 +7,21 @@ const routes = [
|
|||
path: "/",
|
||||
component: () => import(/* webpackChunkName: "layout" */ '@/layout'),
|
||||
redirect: config.DASHBOARD_URL || getBaseDashboard(),
|
||||
children: []
|
||||
//固定页:通过按钮跳转、不依赖菜单(动态/静态)的页面
|
||||
children: [
|
||||
{
|
||||
name: "hfnf_mplogx",
|
||||
path: "/hfnf_mplogx",
|
||||
meta: { title: "测点数据明细", hidden: true },
|
||||
component: () => import('@/views/fac_cal/hfnf_mplogx'),
|
||||
},
|
||||
{
|
||||
name: "cement_data_template",
|
||||
path: "/cement_data_template",
|
||||
meta: { title: "数据模板", hidden: true },
|
||||
component: () => import('@/views/fac_cal/cement_data_template'),
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
path: "/login",
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@ axios.interceptors.request.use(
|
|||
let token = tool.data.get("TOKEN");
|
||||
if(token){
|
||||
config.headers[sysConfig.TOKEN_NAME] = sysConfig.TOKEN_PREFIX + token
|
||||
// 记录本次请求实际使用的 token,用于 401 时判断是否已被并发刷新过
|
||||
config._tokenUsed = token;
|
||||
}
|
||||
if(!sysConfig.REQUEST_CACHE && config.method == 'get'){
|
||||
config.params = config.params || {};
|
||||
|
|
@ -49,13 +51,43 @@ axios.interceptors.response.use(
|
|||
});
|
||||
}else{
|
||||
if (error.config.url.indexOf('auth/token/refresh/') != -1) {
|
||||
// 刷新接口自身 401:refresh token 已失效,清除登录态并跳登录
|
||||
isRefreshing = false;
|
||||
requests = [];
|
||||
tool.data.remove("TOKEN");
|
||||
tool.data.remove("TOKEN_REFRESH");
|
||||
console.warn('[auth] refresh token 失效,跳转登录页');
|
||||
router.push('/login');
|
||||
return
|
||||
return Promise.reject(error.response);
|
||||
}
|
||||
const currentToken = tool.data.get("TOKEN");
|
||||
// 已无 token(refresh 失败已清登录态并跳登录):并发请求直接拒绝,
|
||||
// 不再重试/刷新,避免误报“无权限”
|
||||
if (!currentToken) {
|
||||
return Promise.reject(error.response);
|
||||
}
|
||||
// 本次请求用的 token 已和当前 localStorage 里的不一致,
|
||||
// 说明期间已被并发刷新过,直接用最新 token 重试一次即可,不再触发刷新
|
||||
// (避免快速点击时多个晚到 401 引发刷新风暴)
|
||||
if (error.config._tokenUsed && error.config._tokenUsed !== currentToken && !error.config._retriedAfterRefresh) {
|
||||
error.config._tokenUsed = currentToken;
|
||||
error.config._retriedAfterRefresh = true;
|
||||
return axios(error.config);
|
||||
}
|
||||
// 已刷新过 token 仍然 401:说明不是 token 过期,而是无权限/持久 401。
|
||||
// 不再刷新、不跳登录,只提示无权限,避免刷新循环把会话耗到失效。
|
||||
if (error.config._retriedAfterRefresh) {
|
||||
console.warn('[auth] 刷新后仍 401,判定为无权限,不跳登录', error.config.url);
|
||||
ElNotification.warning({
|
||||
title: '无权限',
|
||||
message: (error.response.data && error.response.data.err_msg) || '当前账号无权限访问该资源'
|
||||
});
|
||||
return Promise.reject(error.response);
|
||||
}
|
||||
if (!isRefreshing) {
|
||||
isRefreshing = true;
|
||||
// 必须 return 刷新 Promise,否则即便刷新成功,原始请求也会被 reject,重试结果被丢弃
|
||||
return new Promise((resolve, reject) => {
|
||||
axios({
|
||||
method: 'post',
|
||||
url: sysConfig.API_URL+'/auth/token/refresh/',
|
||||
|
|
@ -67,17 +99,34 @@ axios.interceptors.response.use(
|
|||
// 替换本地的token
|
||||
tool.data.set("TOKEN", res.data.access);
|
||||
tool.data.set("TOKEN_TIME", new Date().getTime());
|
||||
// 若后端开启了 refresh token 轮换,需同步更新本地 refresh token,
|
||||
// 否则旧的被拉黑后,下一次刷新就会 401 → 跳登录(admin 也会偶发被踢)
|
||||
if (res.data && res.data.refresh) {
|
||||
tool.data.set("TOKEN_REFRESH", res.data.refresh);
|
||||
}
|
||||
error.config.headers[sysConfig.TOKEN_NAME] = sysConfig.TOKEN_PREFIX + res.data.access;
|
||||
error.config._retriedAfterRefresh = true; // 标记:重试后若仍 401 则视为无权限
|
||||
isRefreshing = false;
|
||||
requests.forEach(cb => cb())
|
||||
//发起后将requests置空
|
||||
const queue = requests; requests = [];
|
||||
queue.forEach(cb => cb())
|
||||
resolve(axios(error.config))
|
||||
}).catch(err=>{
|
||||
// 刷新失败:复位状态,清登录态,跳登录
|
||||
isRefreshing = false;
|
||||
requests = [];
|
||||
return axios(error.config)
|
||||
tool.data.remove("TOKEN");
|
||||
tool.data.remove("TOKEN_REFRESH");
|
||||
console.warn('[auth] token 刷新失败,跳转登录页', err);
|
||||
router.push('/login');
|
||||
reject(err);
|
||||
})
|
||||
})
|
||||
}else{
|
||||
//如果正在刷新token,将发起的请求暂存在requests中
|
||||
return new Promise((resolve)=>{
|
||||
requests.push(()=>{
|
||||
error.config._retriedAfterRefresh = true;
|
||||
resolve(axios(error.config));
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -155,6 +155,16 @@ tool.setCoder = function (val) {
|
|||
localStorage.setItem('coder_jobname', val.coder_jobname || '')
|
||||
localStorage.setItem('coder_jobname2', val.coder_jobname2 || '')
|
||||
}
|
||||
tool.setOcr = function (val) {
|
||||
localStorage.setItem('ocr_ip', val.ocr_ip || '')
|
||||
localStorage.setItem('ocr_port', val.ocr_port || '')
|
||||
localStorage.setItem('ocr_unit', val.ocr_unit || '')
|
||||
}
|
||||
tool.setMarker = function (val) {
|
||||
localStorage.setItem('marker_ip', val.marker_ip || '')
|
||||
localStorage.setItem('marker_port', val.marker_port || '')
|
||||
localStorage.setItem('marker_jobname', val.marker_jobname || '')
|
||||
}
|
||||
/* 复制对象 */
|
||||
tool.objCopy = function (obj) {
|
||||
return JSON.parse(JSON.stringify(obj));
|
||||
|
|
|
|||
|
|
@ -0,0 +1,969 @@
|
|||
<template>
|
||||
<el-container class="dashboard">
|
||||
<!-- Header -->
|
||||
<el-header class="dash-header">
|
||||
<div class="dash-header-side dash-header-left">
|
||||
<span class="header-tag">PHOTON · {{ mgroupName }}</span>
|
||||
<span class="header-status"><i class="led-dot"></i>实时数据</span>
|
||||
</div>
|
||||
<div class="dash-header-center">
|
||||
<div class="dash-title">{{ mgroupName }}工段生产数据看板</div>
|
||||
<div class="dash-title-deco"><span></span><i></i><span></span></div>
|
||||
</div>
|
||||
<div class="dash-header-side dash-header-right">
|
||||
<div class="dash-day">{{ currentDay }}</div>
|
||||
<div class="dash-time">{{ currentTime }}</div>
|
||||
</div>
|
||||
</el-header>
|
||||
|
||||
<el-main class="dash-main">
|
||||
<!-- KPI Cards -->
|
||||
<div class="kpi-row">
|
||||
<div class="kpi-card kpi-c2">
|
||||
<div class="kpi-meta">
|
||||
<div class="kpi-label">昨日流转量</div>
|
||||
<div class="kpi-sub">PROCESSED</div>
|
||||
</div>
|
||||
<div class="kpi-value">{{ sctj.rjgs }}</div>
|
||||
<div class="kpi-bar"></div>
|
||||
</div>
|
||||
<div class="kpi-card kpi-c3">
|
||||
<div class="kpi-meta">
|
||||
<div class="kpi-label">昨日加工前不良</div>
|
||||
<div class="kpi-sub">PRE-DEFECT</div>
|
||||
</div>
|
||||
<div class="kpi-value">{{ sctj.rjgqbls }}</div>
|
||||
<div class="kpi-bar"></div>
|
||||
</div>
|
||||
<div class="kpi-card kpi-c4">
|
||||
<div class="kpi-meta">
|
||||
<div class="kpi-label">昨日合格数</div>
|
||||
<div class="kpi-sub">QUALIFIED</div>
|
||||
</div>
|
||||
<div class="kpi-value">{{ sctj.rhgs }}</div>
|
||||
<div class="kpi-bar"></div>
|
||||
</div>
|
||||
<div class="kpi-card kpi-c5">
|
||||
<div class="kpi-meta">
|
||||
<div class="kpi-label">昨日不合格数</div>
|
||||
<div class="kpi-sub">REJECTED</div>
|
||||
</div>
|
||||
<div class="kpi-value">{{ sctj.rbhgs }}</div>
|
||||
<div class="kpi-bar"></div>
|
||||
</div>
|
||||
<div class="kpi-card kpi-c1">
|
||||
<div class="kpi-meta">
|
||||
<div class="kpi-label">昨日合格率</div>
|
||||
<div class="kpi-sub">DAILY QUALITY RATE</div>
|
||||
</div>
|
||||
<div class="kpi-value">{{ sctj.rhgl }}</div>
|
||||
<div class="kpi-bar"></div>
|
||||
</div>
|
||||
<div class="kpi-card kpi-c1">
|
||||
<div class="kpi-meta">
|
||||
<div class="kpi-label">昨日生产直通率</div>
|
||||
<div class="kpi-sub">DAILY QUALITY RATE</div>
|
||||
</div>
|
||||
<div class="kpi-value">{{ sctj.rztls }}</div>
|
||||
<div class="kpi-bar"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Top row: 2 panels -->
|
||||
<el-row :gutter="12" type="flex" class="row-top">
|
||||
<el-col :span="12" class="col-full">
|
||||
<div class="panel">
|
||||
<div class="panel-head">
|
||||
<span class="panel-title">设备状态</span>
|
||||
<div class="panel-states">
|
||||
<span class="state-chip s-run"><i></i>运行<em>{{ hh.yx }}</em></span>
|
||||
<span class="state-chip s-idle"><i></i>未运行<em>{{ hh.wyx }}</em></span>
|
||||
<span class="state-chip s-err"><i></i>故障<em>{{ hh.gz }}</em></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel-body" id="scrollContainer">
|
||||
<dv-scroll-board :config="configDataEq" class="board" />
|
||||
</div>
|
||||
<i class="corner tl"></i><i class="corner tr"></i>
|
||||
<i class="corner bl"></i><i class="corner br"></i>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="4" class="col-full">
|
||||
<div class="panel">
|
||||
<div class="panel-head">
|
||||
<span class="panel-title">工序余料</span>
|
||||
</div>
|
||||
<div class="panel-body" ref="processBox">
|
||||
<dv-scroll-board :config="configDataProcess" class="board" />
|
||||
</div>
|
||||
<i class="corner tl"></i><i class="corner tr"></i>
|
||||
<i class="corner bl"></i><i class="corner br"></i>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="8" class="col-full">
|
||||
<div class="panel">
|
||||
<div class="panel-head">
|
||||
<span class="panel-title">昨日损耗分析</span>
|
||||
</div>
|
||||
<div class="panel-body chart-body" id="chart2"></div>
|
||||
<i class="corner tl"></i><i class="corner tr"></i>
|
||||
<i class="corner bl"></i><i class="corner br"></i>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<!-- Bottom row: 2 panels -->
|
||||
<el-row :gutter="12" type="flex" class="row-bottom">
|
||||
<el-col :span="12" class="col-full">
|
||||
<div class="panel">
|
||||
<div class="panel-head">
|
||||
<span class="panel-title">生产统计</span>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<dv-scroll-board :config="configDatas" class="board" />
|
||||
</div>
|
||||
<i class="corner tl"></i><i class="corner tr"></i>
|
||||
<i class="corner bl"></i><i class="corner br"></i>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="12" class="col-full">
|
||||
<div class="panel">
|
||||
<div class="panel-head">
|
||||
<span class="panel-title">车间库存</span>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<dv-scroll-board :config="configDataInm" class="board" />
|
||||
</div>
|
||||
<i class="corner tl"></i><i class="corner tr"></i>
|
||||
<i class="corner bl"></i><i class="corner br"></i>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-main>
|
||||
</el-container>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as echarts from "echarts";
|
||||
import scScrollTavle from "@/components/scScrollTable.vue";
|
||||
function deepCopy(obj) {
|
||||
return JSON.parse(JSON.stringify(obj));
|
||||
}
|
||||
export default {
|
||||
components: { scScrollTavle },
|
||||
data() {
|
||||
return {
|
||||
pieOption: {
|
||||
backgroundColor: "",
|
||||
tooltip: { trigger: 'item' },
|
||||
legend: {
|
||||
icon: "stack",
|
||||
right: 10,
|
||||
orient: 'vertical',
|
||||
itemWidth: 10,
|
||||
itemHeight: 10,
|
||||
textStyle: { color: '#c8f2ff', fontSize: 11 },
|
||||
},
|
||||
series: {
|
||||
name: '不合格占比',
|
||||
type: 'pie',
|
||||
radius: ['35%', '65%'],
|
||||
center: ['38%', '52%'],
|
||||
itemStyle: {
|
||||
borderColor: 'rgba(3, 22, 26, 0.8)',
|
||||
borderWidth: 2,
|
||||
},
|
||||
label: { show: false },
|
||||
labelLine: { show: false },
|
||||
data: []
|
||||
}
|
||||
},
|
||||
tableHeight: 100,
|
||||
speed: 2000,
|
||||
time: null,
|
||||
hh: {
|
||||
yx: 0,
|
||||
wyx: 0,
|
||||
gz: 0,
|
||||
},
|
||||
sctj: {
|
||||
rjgs: 0,
|
||||
rjgqbls: 0,
|
||||
rhgs: 0,
|
||||
rbhgs: 0,
|
||||
rhgl: 0,
|
||||
rztls: 0,
|
||||
rlzls: 0,
|
||||
},
|
||||
dayInterval: null,
|
||||
chartInterval2: null,
|
||||
//库存
|
||||
configDataInm: {
|
||||
header: ['物料名称', '批次号', '数量', '生产中'],
|
||||
headerBGC: 'rgba(0, 229, 255, 0.16)',
|
||||
oddRowBGC: 'rgba(0, 229, 255, 0.04)',
|
||||
evenRowBGC: 'rgba(0, 229, 255, 0.10)',
|
||||
headerHeight: 38,
|
||||
rowNum: 8,
|
||||
align: 'center',
|
||||
data: [],
|
||||
waitTime: 1500,
|
||||
},
|
||||
configDataProcess: {
|
||||
headerBGC: 'rgba(0, 229, 255, 0.16)',
|
||||
oddRowBGC: 'rgba(0, 229, 255, 0.04)',
|
||||
evenRowBGC: 'rgba(0, 229, 255, 0.10)',
|
||||
header: ['物料名', '数量(个)'],
|
||||
headerHeight: 38,
|
||||
rowNum: 8,
|
||||
align: 'center',
|
||||
columnWidth: [],
|
||||
data: []
|
||||
},
|
||||
//设备
|
||||
configDataEq: {
|
||||
headerBGC: 'rgba(0, 229, 255, 0.16)',
|
||||
oddRowBGC: 'rgba(0, 229, 255, 0.04)',
|
||||
evenRowBGC: 'rgba(0, 229, 255, 0.10)',
|
||||
header: ['设备名称', '设备编号', '设备状态', '日加工量', '累计加工量'],
|
||||
headerHeight: 38,
|
||||
rowNum: 8,
|
||||
align: 'center',
|
||||
data: []
|
||||
},
|
||||
//生产统计
|
||||
configDatas: {
|
||||
headerBGC: 'rgba(0, 229, 255, 0.16)',
|
||||
oddRowBGC: 'rgba(0, 229, 255, 0.04)',
|
||||
evenRowBGC: 'rgba(0, 229, 255, 0.10)',
|
||||
header: ['日期', '物料名', '接收数', '合格数', '不合格数', '交送数'],
|
||||
headerHeight: 38,
|
||||
rowNum: 7,
|
||||
align: 'center',
|
||||
data: []
|
||||
},
|
||||
page: 1,
|
||||
currentTime: "",
|
||||
currentDay: "",
|
||||
mgroupName: "",
|
||||
mgroupId: "",
|
||||
today: "",
|
||||
end_time: '',
|
||||
start_time: '',
|
||||
daysList: [],
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
let that = this;
|
||||
let arr = this.$route.path.split("/");
|
||||
that.mgroup_code = arr[2];
|
||||
that.page = 1;
|
||||
that.getMgroups(this.mgroup_code);
|
||||
that.configDataInm.data = [];
|
||||
//表格table的高度
|
||||
this.tableHeight = document.getElementById("scrollContainer").clientHeight;
|
||||
this.$nextTick(() => {
|
||||
const box = this.$refs.processBox;
|
||||
if (box) {
|
||||
const w = box.clientWidth - 16;
|
||||
this.configDataProcess.columnWidth = [Math.max(50, w - 100), 100];
|
||||
}
|
||||
});
|
||||
this.showTime();
|
||||
this.dayInterval = setInterval(() => {
|
||||
this.showTime();
|
||||
}, 1000);
|
||||
//近七天的日期数组
|
||||
let daysArr = this.getMondayOfCurrentWeek();
|
||||
this.daysArr = daysArr;
|
||||
let xAxisData = [];
|
||||
daysArr.forEach((item) => {
|
||||
let dates = item.split('-');
|
||||
let obj = dates[1] + '-' + dates[2];
|
||||
xAxisData.push(obj);
|
||||
let dayitem = Number(dates[2]);
|
||||
that.daysList.push(dayitem);
|
||||
})
|
||||
that.today = new Date().toISOString().split('T')[0];
|
||||
that.yesterday =that.$TOOL.dateFormat2(new Date().getTime() - 24 * 60 * 60 * 1000);;
|
||||
this.xAxisData = xAxisData;
|
||||
let startDate = new Date(daysArr[0]).getTime() - (1000 * 60 * 60 * 24);
|
||||
let endDate = new Date(daysArr[6]).getTime() + (1000 * 60 * 60 * 24);
|
||||
let start_time = this.$TOOL.dateFormat(new Date(startDate), "yyyy-MM-dd");
|
||||
let end_time = this.$TOOL.dateFormat(new Date(endDate), "yyyy-MM-dd");
|
||||
this.start_time = start_time;
|
||||
this.end_time = end_time;
|
||||
},
|
||||
beforeDestroy() {
|
||||
if (this.dayInterval) clearInterval(this.dayInterval);
|
||||
if (this.chartInterval2) clearInterval(this.chartInterval2);
|
||||
},
|
||||
methods: {
|
||||
getMgroups(code){
|
||||
let that = this;
|
||||
that.$API.mtm.mgroup.list.req({page:0,code}).then((res) => {
|
||||
that.mgroupName = res[0].name;
|
||||
that.mgroupId = res[0].id;
|
||||
this.$nextTick(() => {
|
||||
that.getEqState(that.mgroupId);
|
||||
this.getMaterials(that.page);
|
||||
this.getProductLine();
|
||||
this.getCountnotok();
|
||||
this.getProcessLeft();
|
||||
})
|
||||
});
|
||||
},
|
||||
getMondayOfCurrentWeek() {
|
||||
let today = new Date();
|
||||
let days = [];
|
||||
for (let i = 6; i >= 0; i--) {
|
||||
let date = new Date(today);
|
||||
date.setDate(today.getDate() - i);
|
||||
days.push(date.toISOString().split('T')[0]);
|
||||
}
|
||||
return days;
|
||||
},
|
||||
//时间
|
||||
showTime() {
|
||||
this.currentTime = this.$TOOL.dateFormat(new Date(), "hh:mm:ss");
|
||||
this.currentDay = this.$TOOL.dateFormat(
|
||||
new Date(),
|
||||
"yyyy年MM月dd日"
|
||||
);
|
||||
},
|
||||
setChart(name, option = null) {
|
||||
let dom = document.getElementById(name);
|
||||
if (!dom) return null;
|
||||
var myChart = echarts.getInstanceByDom(dom);
|
||||
if (myChart == undefined) {
|
||||
myChart = echarts.init(dom, "dark", {
|
||||
renderer: "svg",
|
||||
});
|
||||
}
|
||||
if (option == null) {
|
||||
option = Object.assign({}, this.barOption);
|
||||
}
|
||||
setTimeout(() => {
|
||||
try {
|
||||
myChart.setOption(option);
|
||||
} catch (error) { }
|
||||
}, 500);
|
||||
return myChart;
|
||||
},
|
||||
getProcessLeft() {
|
||||
let that = this;
|
||||
let obj = {
|
||||
query: { mgroup_name: that.mgroupName },
|
||||
};
|
||||
that.$API.bi.dataset.exec.req("mgroup_yuliao", obj).then((res) => {
|
||||
let list = res.data2.ds0;
|
||||
if (list.length > 0) {
|
||||
list.forEach((item) => {
|
||||
if(item.状态=='合格'&&(item.物料名.indexOf('QS')>-1||item.物料名.indexOf('32.2')>-1||item.物料名.indexOf('3D')>-1||item.物料名.indexOf('2.5D')>-1)){
|
||||
let arr = [];
|
||||
arr[0] = item.物料名+'('+item.状态+')';
|
||||
arr[1] = item.数量;
|
||||
that.configDataProcess.data.push(arr);
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
//生产统计
|
||||
getProductLine() {
|
||||
let that = this;
|
||||
let obj = {
|
||||
query: { start_date: that.start_time, end_date: that.end_time, mgroup_name: that.mgroupName },
|
||||
};
|
||||
that.$API.bi.dataset.exec.req("lineDay", obj).then((res) => {
|
||||
let list = res.data2.ds0;
|
||||
if (list.length > 0) {
|
||||
list.forEach((item) => {
|
||||
let dateYes = that.yesterday.split('-')[2];
|
||||
if (item.日 == dateYes) {
|
||||
that.sctj.rjgs += item.生产数;
|
||||
that.sctj.rjgqbls += item.加工前不良;
|
||||
that.sctj.rhgs += item.合格数;
|
||||
that.sctj.rbhgs += item.不合格数;
|
||||
}
|
||||
let arr = [];
|
||||
arr[0] = item.年 + '-' + item.月 + '-' + item.日;
|
||||
arr[1] = item.物料名;
|
||||
arr[2] = item.接收数;
|
||||
arr[3] = item.生产数;
|
||||
arr[4] = item.合格数;
|
||||
arr[5] = item.交送数;
|
||||
that.configDatas.data.push(arr);
|
||||
});
|
||||
that.sctj.rhgl = Number((that.sctj.rhgs / that.sctj.rjgs * 100).toFixed(2));
|
||||
let total = that.sctj.rjgs+that.sctj.rjgqbls;
|
||||
that.sctj.rztls = Number((that.sctj.rhgs / total * 100).toFixed(2));
|
||||
}
|
||||
});
|
||||
},
|
||||
//不合格分布
|
||||
getCountnotok() {
|
||||
let that = this;
|
||||
let obj = {
|
||||
query: { start_date: that.yesterday, end_date: that.yesterday,mgroup_name:that.mgroupName }
|
||||
};
|
||||
that.$API.bi.dataset.exec.req('notok_dis', obj).then((res) => {
|
||||
let seriesData = [];
|
||||
if (res.data2.ds0) {
|
||||
res.data2.ds0.forEach((item) => {
|
||||
let obj = {};
|
||||
obj.name = item.不合格项;
|
||||
obj.value = item.数量;
|
||||
seriesData.push(obj);
|
||||
})
|
||||
}
|
||||
that.pieOption.series.data = seriesData;
|
||||
let index2 = 0;
|
||||
let chart2 = this.setChart("chart2", that.pieOption);
|
||||
if (!chart2) return;
|
||||
this.chartInterval2 = setInterval(function () {
|
||||
if (index2 < seriesData.length) {
|
||||
chart2.dispatchAction({ type: "downplay", seriesIndex: 0 });
|
||||
chart2.dispatchAction({ type: "highlight", seriesIndex: 0, dataIndex: index2 });
|
||||
chart2.dispatchAction({ type: "showTip", seriesIndex: 0, dataIndex: index2 });
|
||||
index2++;
|
||||
} else {
|
||||
index2 = 0;
|
||||
}
|
||||
}, 3000);
|
||||
})
|
||||
},
|
||||
//设备状态
|
||||
getEqState() {
|
||||
let that = this;
|
||||
let obj = {
|
||||
query: { query_date: that.today, mgroup_name: that.mgroupName },
|
||||
};
|
||||
that.$API.wpm.ana.equipLastMlog.req({ mgroup: that.mgroupId }).then((res) => {
|
||||
that.hh.yx = res.运行;
|
||||
that.hh.wyx = res.未运行;
|
||||
that.hh.gz = res.故障;
|
||||
});
|
||||
that.$API.bi.dataset.exec.req("equit_static", obj).then((res) => {
|
||||
let list = res.data2.ds0;
|
||||
if (list.length > 0) {
|
||||
list.forEach((item) => {
|
||||
let arr = [];
|
||||
arr[0] = item.设备名称;
|
||||
arr[1] = item.设备编号;
|
||||
if (item.运行状态 == '运行') {
|
||||
arr[2] = '<span style="color:#00e5ff">● 运行</span>';
|
||||
} else if (item.运行状态 == '待机') {
|
||||
arr[2] = '<span style="color:#45b076">● 待机</span>';
|
||||
} else if (item.运行状态 == '停机') {
|
||||
arr[2] = '<span style="color:#de3c36">● 停机</span>';
|
||||
}else if (item.运行状态 == '故障') {
|
||||
arr[2] = '<span style="color:#de3c36">● 故障</span>';
|
||||
}else if (item.运行状态 == '离线') {
|
||||
arr[2] = '<span style="color:#de3c36">● 离线</span>';
|
||||
}
|
||||
arr[3] = item.当日加工量 ? item.当日加工量 : 0;
|
||||
arr[4] = item.累计总加工量 ? item.累计总加工量 : 0;
|
||||
that.configDataEq.data.push(arr);
|
||||
});
|
||||
}
|
||||
})
|
||||
},
|
||||
//库存统计列表
|
||||
getMaterials(page) {
|
||||
let that = this;
|
||||
let query = '{ material_name, batch, count, count_working }';
|
||||
that.$API.wpm.wmaterial.list.req({ page: page, page_size: 100, mgroup: that.mgroupId, query: query }).then((res) => {
|
||||
if (res.results.length > 0) {
|
||||
res.results.forEach((item) => {
|
||||
let arr = [];
|
||||
arr[0] = item.material_name;
|
||||
arr[1] = item.batch;
|
||||
arr[2] = item.count;
|
||||
arr[3] = item.count_working;
|
||||
that.configDataInm.data.push(arr);
|
||||
})
|
||||
if(that.configDataInm.data.length<res.count){
|
||||
that.getMaterials(page+1);
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
@font-face {
|
||||
font-family: "myfont";
|
||||
src: url("../../../utils/youShe.ttf");
|
||||
}
|
||||
|
||||
.dashboard,
|
||||
.dashboard * {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.dashboard {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
overflow: hidden;
|
||||
background: #00181c url("/public/img/photon_bg.png") center / cover no-repeat;
|
||||
color: #fff;
|
||||
font-family: "Microsoft Yahei" !important;
|
||||
}
|
||||
|
||||
.dashboard::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background:
|
||||
radial-gradient(ellipse at 20% 0%, rgba(0, 229, 255, 0.10), transparent 55%),
|
||||
radial-gradient(ellipse at 80% 100%, rgba(0, 122, 153, 0.18), transparent 55%);
|
||||
pointer-events: none;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
/* ============= Header ============= */
|
||||
.dash-header {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
flex: 0 0 72px !important;
|
||||
height: 72px !important;
|
||||
padding: 0 24px !important;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
background: url("/public/img/photon_header.png") center / 100% 100% no-repeat;
|
||||
}
|
||||
|
||||
.dash-header-side {
|
||||
flex: 0 0 280px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 14px;
|
||||
}
|
||||
|
||||
.dash-header-right {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.dash-header-center {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.dash-title {
|
||||
font-family: "myfont", "Microsoft Yahei";
|
||||
font-size: 30px;
|
||||
font-weight: bold;
|
||||
letter-spacing: 8px;
|
||||
background: linear-gradient(180deg, #ffffff 0%, #b9fbff 55%, #00d4ff 100%);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
text-shadow: 0 0 22px rgba(0, 212, 255, 0.45);
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.dash-title-deco {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 10px;
|
||||
margin-top: 6px;
|
||||
}
|
||||
|
||||
.dash-title-deco span {
|
||||
display: inline-block;
|
||||
width: 90px;
|
||||
height: 1px;
|
||||
background: linear-gradient(90deg, transparent, rgba(0, 229, 255, 0.7), transparent);
|
||||
}
|
||||
|
||||
.dash-title-deco i {
|
||||
display: inline-block;
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
background: #00e5ff;
|
||||
transform: rotate(45deg);
|
||||
box-shadow: 0 0 8px #00e5ff;
|
||||
}
|
||||
|
||||
.header-tag {
|
||||
font-size: 12px;
|
||||
letter-spacing: 2px;
|
||||
padding: 4px 10px;
|
||||
border: 1px solid rgba(0, 229, 255, 0.45);
|
||||
color: #95ffff;
|
||||
background: rgba(0, 229, 255, 0.06);
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.header-status {
|
||||
font-size: 13px;
|
||||
color: #95ffff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.led-dot {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 50%;
|
||||
background: #18f1a4;
|
||||
box-shadow: 0 0 8px #18f1a4;
|
||||
animation: led-pulse 1.4s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes led-pulse {
|
||||
|
||||
0%,
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
50% {
|
||||
opacity: 0.35;
|
||||
}
|
||||
}
|
||||
|
||||
.dash-day {
|
||||
font-size: 14px;
|
||||
color: #c8f2ff;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
|
||||
.dash-time {
|
||||
font-family: "myfont", "Microsoft Yahei";
|
||||
font-size: 22px;
|
||||
color: #fff;
|
||||
letter-spacing: 3px;
|
||||
text-shadow: 0 0 12px rgba(0, 229, 255, 0.55);
|
||||
}
|
||||
|
||||
/* ============= Main ============= */
|
||||
.dash-main {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
flex: 1 1 0 !important;
|
||||
min-height: 0;
|
||||
padding: 10px !important;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* ============= KPI Strip ============= */
|
||||
.kpi-row {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(6, 1fr);
|
||||
gap: 10px;
|
||||
flex: 0 0 92px;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.kpi-card {
|
||||
position: relative;
|
||||
padding: 10px 16px;
|
||||
background: linear-gradient(135deg, rgba(0, 60, 80, 0.55) 0%, rgba(3, 22, 26, 0.7) 100%);
|
||||
border: 1px solid rgba(0, 229, 255, 0.22);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.kpi-card::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: radial-gradient(circle at 100% 0%, rgba(0, 229, 255, 0.16), transparent 60%);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.kpi-card::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 3px;
|
||||
height: 100%;
|
||||
background: #00e5ff;
|
||||
box-shadow: 0 0 10px #00e5ff;
|
||||
}
|
||||
|
||||
.kpi-meta {
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.kpi-label {
|
||||
font-size: 15px;
|
||||
letter-spacing: 2px;
|
||||
color: #d8f6ff;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.kpi-sub {
|
||||
font-size: 10px;
|
||||
letter-spacing: 2px;
|
||||
color: rgba(149, 255, 255, 0.45);
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.kpi-value {
|
||||
font-family: "myfont", "Microsoft Yahei";
|
||||
font-size: 34px;
|
||||
font-weight: bold;
|
||||
letter-spacing: 1px;
|
||||
z-index: 1;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.kpi-bar {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
height: 2px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.kpi-c1 .kpi-value {
|
||||
color: #95ffff;
|
||||
text-shadow: 0 0 14px rgba(0, 229, 255, 0.55);
|
||||
}
|
||||
|
||||
.kpi-c1::after {
|
||||
background: #00e5ff;
|
||||
box-shadow: 0 0 10px #00e5ff;
|
||||
}
|
||||
|
||||
.kpi-c1 .kpi-bar {
|
||||
background: linear-gradient(90deg, #00e5ff, transparent);
|
||||
}
|
||||
|
||||
.kpi-c2 .kpi-value {
|
||||
color: #c5ff7a;
|
||||
text-shadow: 0 0 14px rgba(170, 255, 102, 0.55);
|
||||
}
|
||||
|
||||
.kpi-c2::after {
|
||||
background: #aaff66;
|
||||
box-shadow: 0 0 10px #aaff66;
|
||||
}
|
||||
|
||||
.kpi-c2 .kpi-bar {
|
||||
background: linear-gradient(90deg, #aaff66, transparent);
|
||||
}
|
||||
|
||||
.kpi-c3 .kpi-value {
|
||||
color: #ffd87a;
|
||||
text-shadow: 0 0 14px rgba(255, 200, 80, 0.55);
|
||||
}
|
||||
|
||||
.kpi-c3::after {
|
||||
background: #ffb74d;
|
||||
box-shadow: 0 0 10px #ffb74d;
|
||||
}
|
||||
|
||||
.kpi-c3 .kpi-bar {
|
||||
background: linear-gradient(90deg, #ffb74d, transparent);
|
||||
}
|
||||
|
||||
.kpi-c4 .kpi-value {
|
||||
color: #7af0a8;
|
||||
text-shadow: 0 0 14px rgba(45, 210, 140, 0.55);
|
||||
}
|
||||
|
||||
.kpi-c4::after {
|
||||
background: #2dd28c;
|
||||
box-shadow: 0 0 10px #2dd28c;
|
||||
}
|
||||
|
||||
.kpi-c4 .kpi-bar {
|
||||
background: linear-gradient(90deg, #2dd28c, transparent);
|
||||
}
|
||||
|
||||
.kpi-c5 .kpi-value {
|
||||
color: #ff8a8a;
|
||||
text-shadow: 0 0 14px rgba(255, 107, 107, 0.55);
|
||||
}
|
||||
|
||||
.kpi-c5::after {
|
||||
background: #ff6b6b;
|
||||
box-shadow: 0 0 10px #ff6b6b;
|
||||
}
|
||||
|
||||
.kpi-c5 .kpi-bar {
|
||||
background: linear-gradient(90deg, #ff6b6b, transparent);
|
||||
}
|
||||
|
||||
/* ============= Content Rows ============= */
|
||||
.row-top,
|
||||
.row-bottom {
|
||||
display: flex;
|
||||
min-height: 0;
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
.row-top {
|
||||
flex: 1.15 1 0;
|
||||
}
|
||||
|
||||
.row-bottom {
|
||||
flex: 1 1 0;
|
||||
}
|
||||
|
||||
.col-full {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
/* ============= Panel ============= */
|
||||
.panel {
|
||||
position: relative;
|
||||
height: 100%;
|
||||
background: linear-gradient(180deg, rgba(10, 63, 68, 0.45) 0%, rgba(3, 22, 26, 0.65) 100%);
|
||||
border: 1px solid rgba(0, 229, 255, 0.18);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.panel-head {
|
||||
position: relative;
|
||||
height: 36px;
|
||||
flex: 0 0 36px;
|
||||
padding: 0 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
background: linear-gradient(90deg, rgba(0, 229, 255, 0.16) 0%, rgba(0, 229, 255, 0.02) 60%, rgba(0, 229, 255, 0.08) 100%);
|
||||
border-bottom: 1px solid rgba(0, 229, 255, 0.18);
|
||||
}
|
||||
|
||||
.panel-head::before {
|
||||
content: "";
|
||||
width: 4px;
|
||||
height: 16px;
|
||||
background: linear-gradient(180deg, #00e5ff, #007a99);
|
||||
box-shadow: 0 0 6px rgba(0, 229, 255, 0.6);
|
||||
}
|
||||
|
||||
.panel-title {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
letter-spacing: 2px;
|
||||
}
|
||||
|
||||
.panel-sub {
|
||||
font-size: 11px;
|
||||
letter-spacing: 2px;
|
||||
color: rgba(149, 255, 255, 0.5);
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
.panel-states {
|
||||
margin-left: auto;
|
||||
display: flex;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.state-chip {
|
||||
font-size: 12px;
|
||||
padding: 2px 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
background: rgba(255, 255, 255, 0.04);
|
||||
border: 1px solid rgba(255, 255, 255, 0.08);
|
||||
color: #d8f6ff;
|
||||
}
|
||||
|
||||
.state-chip i {
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
border-radius: 50%;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.state-chip em {
|
||||
font-style: normal;
|
||||
font-weight: bold;
|
||||
color: #fff;
|
||||
margin-left: 3px;
|
||||
}
|
||||
|
||||
.s-run i {
|
||||
background: #00a3f5;
|
||||
box-shadow: 0 0 6px #00a3f5;
|
||||
}
|
||||
|
||||
.s-idle i {
|
||||
background: #45b076;
|
||||
box-shadow: 0 0 6px #45b076;
|
||||
}
|
||||
|
||||
.s-err i {
|
||||
background: #de3c36;
|
||||
box-shadow: 0 0 6px #de3c36;
|
||||
}
|
||||
|
||||
.panel-body {
|
||||
flex: 1 1 0;
|
||||
min-height: 0;
|
||||
padding: 8px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.chart-body {
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
.board {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
/* ============= Corner brackets ============= */
|
||||
.corner {
|
||||
position: absolute;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
border-color: #00e5ff;
|
||||
border-style: solid;
|
||||
pointer-events: none;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.corner.tl {
|
||||
top: -1px;
|
||||
left: -1px;
|
||||
border-width: 2px 0 0 2px;
|
||||
}
|
||||
|
||||
.corner.tr {
|
||||
top: -1px;
|
||||
right: -1px;
|
||||
border-width: 2px 2px 0 0;
|
||||
}
|
||||
|
||||
.corner.bl {
|
||||
bottom: -1px;
|
||||
left: -1px;
|
||||
border-width: 0 0 2px 2px;
|
||||
}
|
||||
|
||||
.corner.br {
|
||||
bottom: -1px;
|
||||
right: -1px;
|
||||
border-width: 0 2px 2px 0;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -132,7 +132,7 @@
|
|||
id="dashbordProcess"
|
||||
>
|
||||
<span class="percentage-value" style="font-size: 16px"
|
||||
>{{ dialogData.percentage }}%</span
|
||||
>{{ dialogData.percentage }}</span
|
||||
>
|
||||
</el-progress>
|
||||
<span>完成进度</span>
|
||||
|
|
@ -216,7 +216,7 @@
|
|||
id="dashbordProcess"
|
||||
>
|
||||
<span class="percentage-value" style="font-size: 16px"
|
||||
>{{ currentData.percentage }}%</span
|
||||
>{{ currentData.percentage }}</span
|
||||
>
|
||||
</el-progress>
|
||||
<p style="text-align: center">完成进度</p>
|
||||
|
|
@ -444,29 +444,40 @@ export default {
|
|||
yesterday: "",
|
||||
dept6Obj: {
|
||||
deptName: "光学精密加工车间",
|
||||
percentage: 100,
|
||||
percentage: "100%",
|
||||
count_bang: 0,
|
||||
count_guan: 0,
|
||||
},
|
||||
dept7Obj: {
|
||||
deptName: "光纤预制棒生产车间",
|
||||
percentage: 100,
|
||||
percentage: "100%",
|
||||
count_bang: 0,
|
||||
},
|
||||
dept8Obj: {
|
||||
deptName: "玻璃配合料制备车间",
|
||||
percentage: 100,
|
||||
percentage: "100%",
|
||||
count: 0,
|
||||
},
|
||||
dept10Obj: {
|
||||
deptName: "光纤预制管生产车间",
|
||||
percentage: 100,
|
||||
percentage: "100%",
|
||||
count_guan: 0,
|
||||
},
|
||||
isUnmounted: false,
|
||||
pieChart: null,
|
||||
line1Chart: null,
|
||||
line2Chart: null,
|
||||
line3Chart: null,
|
||||
bar1Chart: null,
|
||||
onResize: null,
|
||||
onCanvasMouseMove: null,
|
||||
onCanvasClick: null,
|
||||
canvasEl: null,
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
loadBabylon().then(() => {
|
||||
if (this.isUnmounted) return;
|
||||
this.initView();
|
||||
})
|
||||
},
|
||||
|
|
@ -536,27 +547,22 @@ export default {
|
|||
that.showTime();
|
||||
}, 1000);
|
||||
that.notokTimer = setInterval(() => {
|
||||
if (that.isUnmounted) return;
|
||||
let pieDom = document.getElementById("pie");
|
||||
if (pieDom) {
|
||||
if (!pieDom) return;
|
||||
if (that.deptName == "10车间") {
|
||||
that.deptName = "7车间";
|
||||
} else {
|
||||
that.deptName = "10车间";
|
||||
}
|
||||
let deptData = [];
|
||||
if (that.deptName == "7车间") {
|
||||
deptData = that.dept7Data;
|
||||
} else {
|
||||
deptData = that.dept10Data;
|
||||
}
|
||||
let deptData =
|
||||
that.deptName == "7车间" ? that.dept7Data : that.dept10Data;
|
||||
that.pieoption.series.data = deptData;
|
||||
let pieoption = that.pieoption;
|
||||
|
||||
let pieChart = echarts.init(pieDom);
|
||||
pieChart.clear();
|
||||
pieChart.setOption(pieoption, true);
|
||||
if (!that.pieChart || that.pieChart.isDisposed()) {
|
||||
that.pieChart = echarts.init(pieDom);
|
||||
}
|
||||
}, 5000);
|
||||
that.pieChart.setOption(that.pieoption, true);
|
||||
}, 60000);
|
||||
that.timerData = setInterval(() => {
|
||||
that.getDeptDetail();
|
||||
}, 60000);
|
||||
|
|
@ -592,8 +598,12 @@ export default {
|
|||
that.getCountDept7();
|
||||
//左1---本周交付数
|
||||
let chartDom = document.getElementById("line1");
|
||||
if (!chartDom) return;
|
||||
chartDom.style.height = this.blockHeight;
|
||||
let myChart = echarts.init(chartDom);
|
||||
if (!that.line1Chart || that.line1Chart.isDisposed()) {
|
||||
that.line1Chart = echarts.init(chartDom);
|
||||
}
|
||||
let myChart = that.line1Chart;
|
||||
let option = {
|
||||
tooltip: {
|
||||
trigger: "axis",
|
||||
|
|
@ -862,8 +872,12 @@ export default {
|
|||
}
|
||||
//柱状图折线
|
||||
let line3Dom = document.getElementById("line3");
|
||||
if (!line3Dom) return;
|
||||
line3Dom.style.height = this.blockHeight;
|
||||
let line3Chart = echarts.init(line3Dom);
|
||||
if (!that.line3Chart || that.line3Chart.isDisposed()) {
|
||||
that.line3Chart = echarts.init(line3Dom);
|
||||
}
|
||||
let line3Chart = that.line3Chart;
|
||||
let line3option = {
|
||||
tooltip: {
|
||||
trigger: "axis",
|
||||
|
|
@ -980,12 +994,19 @@ export default {
|
|||
that.$API.bi.dataset.exec.req("materialCount", obj).then((res) => {
|
||||
let data = [];
|
||||
let list = res.data2.ds0;
|
||||
let names = [];
|
||||
if (list.length > 0) {
|
||||
list.forEach((item) => {
|
||||
let indexes = names.indexOf(item.material_name);
|
||||
if(indexes === -1){
|
||||
names.push(item.material_name);
|
||||
let arr = [];
|
||||
arr[0] = item.material_name ;
|
||||
arr[1] = item.count;
|
||||
data.push(arr);
|
||||
}else{
|
||||
data[indexes][1] = data[indexes][1] + item.count;
|
||||
}
|
||||
});
|
||||
}
|
||||
that.taskBoard.data = data;
|
||||
|
|
@ -1217,7 +1238,7 @@ export default {
|
|||
// 添加抓取事件
|
||||
const hl1 = new BABYLON.HighlightLayer("hl1", scene);
|
||||
const hl1Click = new BABYLON.HighlightLayer("hl1Click", scene);
|
||||
canvas.addEventListener("mousemove", (event) => {
|
||||
that.onCanvasMouseMove = (event) => {
|
||||
// 使用 scene.pick 检测鼠标拾取
|
||||
const pickResult = scene.pick(
|
||||
scene.pointerX,
|
||||
|
|
@ -1292,8 +1313,9 @@ export default {
|
|||
} else {
|
||||
that.infoVisibel = false;
|
||||
}
|
||||
});
|
||||
canvas.addEventListener("click", (event) => {
|
||||
};
|
||||
canvas.addEventListener("mousemove", that.onCanvasMouseMove);
|
||||
that.onCanvasClick = (event) => {
|
||||
// 使用 scene.pick 检测鼠标拾取
|
||||
const pickResult = scene.pick(
|
||||
scene.pointerX,
|
||||
|
|
@ -1364,7 +1386,8 @@ export default {
|
|||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
canvas.addEventListener("click", that.onCanvasClick);
|
||||
return scene;
|
||||
};
|
||||
const scene = createScene(); //Call the createScene function
|
||||
|
|
@ -1374,9 +1397,9 @@ export default {
|
|||
});
|
||||
this.engine = engine;
|
||||
this.scene = scene;
|
||||
window.addEventListener("resize", function () {
|
||||
engine.resize();
|
||||
});
|
||||
this.canvasEl = canvas;
|
||||
this.onResize = () => engine.resize();
|
||||
window.addEventListener("resize", this.onResize);
|
||||
},
|
||||
getDeptData(name) {
|
||||
this.infoVisibel = true;
|
||||
|
|
@ -1505,8 +1528,12 @@ export default {
|
|||
let that = this;
|
||||
//左边2
|
||||
let bar1 = document.getElementById("bar1");
|
||||
if (!bar1) return;
|
||||
bar1.style.height = this.blockHeight;
|
||||
let bar1Chart = echarts.init(bar1);
|
||||
if (!that.bar1Chart || that.bar1Chart.isDisposed()) {
|
||||
that.bar1Chart = echarts.init(bar1);
|
||||
}
|
||||
let bar1Chart = that.bar1Chart;
|
||||
let bar1option = {
|
||||
tooltip: {
|
||||
trigger: "axis",
|
||||
|
|
@ -1655,8 +1682,12 @@ export default {
|
|||
bar1Chart.setOption(bar1option);
|
||||
//左3
|
||||
let line2Dom = document.getElementById("line2");
|
||||
if (!line2Dom) return;
|
||||
line2Dom.style.height = this.blockHeight;
|
||||
let line2Chart = echarts.init(line2Dom);
|
||||
if (!that.line2Chart || that.line2Chart.isDisposed()) {
|
||||
that.line2Chart = echarts.init(line2Dom);
|
||||
}
|
||||
let line2Chart = that.line2Chart;
|
||||
let line2option = {
|
||||
tooltip: {
|
||||
trigger: "axis",
|
||||
|
|
@ -1845,8 +1876,12 @@ export default {
|
|||
line2Chart.setOption(line2option);
|
||||
//饼状图
|
||||
let pieDom = document.getElementById("pie");
|
||||
if (!pieDom) return;
|
||||
pieDom.style.height = this.blockHeight;
|
||||
let pieChart = echarts.init(pieDom);
|
||||
if (!that.pieChart || that.pieChart.isDisposed()) {
|
||||
that.pieChart = echarts.init(pieDom);
|
||||
}
|
||||
let pieChart = that.pieChart;
|
||||
let pieoption = {
|
||||
color: [
|
||||
"rgb(237,224,45)",
|
||||
|
|
@ -1914,22 +1949,53 @@ export default {
|
|||
},
|
||||
},
|
||||
beforeUnmount() {
|
||||
let that = this;
|
||||
clearInterval(that.timerTime);
|
||||
clearInterval(that.timerData);
|
||||
clearInterval(that.notokTimer);
|
||||
that.timerTime = null;
|
||||
that.timerData = null;
|
||||
that.notokTimer = null;
|
||||
},
|
||||
beforeDestoryed() {
|
||||
let that = this;
|
||||
clearInterval(that.timerTime);
|
||||
clearInterval(that.timerData);
|
||||
clearInterval(that.notokTimer);
|
||||
that.timerTime = null;
|
||||
that.timerData = null;
|
||||
that.notokTimer = null;
|
||||
this.isUnmounted = true;
|
||||
// 定时器
|
||||
clearInterval(this.timerTime);
|
||||
clearInterval(this.timerData);
|
||||
clearInterval(this.notokTimer);
|
||||
clearInterval(this.heightTimer);
|
||||
this.timerTime = null;
|
||||
this.timerData = null;
|
||||
this.notokTimer = null;
|
||||
this.heightTimer = null;
|
||||
// echarts 实例
|
||||
[
|
||||
this.pieChart,
|
||||
this.line1Chart,
|
||||
this.line2Chart,
|
||||
this.line3Chart,
|
||||
this.bar1Chart,
|
||||
].forEach((c) => {
|
||||
if (c && !c.isDisposed()) c.dispose();
|
||||
});
|
||||
this.pieChart = this.line1Chart = this.line2Chart = this.line3Chart = this.bar1Chart = null;
|
||||
// 事件监听器
|
||||
if (this.onResize) {
|
||||
window.removeEventListener("resize", this.onResize);
|
||||
this.onResize = null;
|
||||
}
|
||||
if (this.canvasEl) {
|
||||
if (this.onCanvasMouseMove) {
|
||||
this.canvasEl.removeEventListener("mousemove", this.onCanvasMouseMove);
|
||||
}
|
||||
if (this.onCanvasClick) {
|
||||
this.canvasEl.removeEventListener("click", this.onCanvasClick);
|
||||
}
|
||||
this.canvasEl = null;
|
||||
}
|
||||
this.onCanvasMouseMove = null;
|
||||
this.onCanvasClick = null;
|
||||
// babylon 引擎
|
||||
if (this.scene) {
|
||||
try { this.scene.dispose(); } catch (e) {}
|
||||
this.scene = null;
|
||||
}
|
||||
if (this.engine) {
|
||||
try { this.engine.stopRenderLoop(); } catch (e) {}
|
||||
try { this.engine.dispose(); } catch (e) {}
|
||||
this.engine = null;
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -7,8 +7,11 @@
|
|||
</div>
|
||||
<div class="right-panel">
|
||||
<el-cascader v-model="query.belong_dept" :options="group" :props="groupsProps" clearable placeholder="所在车间"
|
||||
:show-all-levels="false" @change="handleQuery">
|
||||
:show-all-levels="false" @change="handleQuery" style="width:180px">
|
||||
</el-cascader>
|
||||
<el-select v-model="query.cate" placeholder="设备分类" clearable style="width:180px">
|
||||
<el-option v-for="item in cateOptions" :key="item.id" :label="item.name" :value="item.id"></el-option>
|
||||
</el-select>
|
||||
<el-input v-model="query.search" placeholder="设备名称/编号" clearable style="width:200px"></el-input>
|
||||
<el-button type="primary" icon="el-icon-search" @click="handleQuery"></el-button>
|
||||
</div>
|
||||
|
|
@ -38,7 +41,7 @@
|
|||
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="购置日期" prop="buy_date">
|
||||
<el-table-column label="购置日期" prop="buy_date" width="90">
|
||||
</el-table-column>
|
||||
<el-table-column label="运行规则" prop="indicate_mgroup_running" width="100">
|
||||
</el-table-column>
|
||||
|
|
@ -195,6 +198,7 @@ export default {
|
|||
data() {
|
||||
return {
|
||||
runningStateEnum,
|
||||
cateOptions:[],
|
||||
deptOptions: [],
|
||||
dialog: {
|
||||
save: false,
|
||||
|
|
@ -247,9 +251,16 @@ export default {
|
|||
};
|
||||
},
|
||||
mounted() {
|
||||
this.getDept()
|
||||
this.getDept();
|
||||
this.getCateOptions();
|
||||
},
|
||||
methods: {
|
||||
getCateOptions() {
|
||||
let that = this;
|
||||
that.$API.em.ecate.list.req({page:0,type:10}).then(res => {
|
||||
that.cateOptions = res;
|
||||
})
|
||||
},
|
||||
//表格选择后回调事件
|
||||
selectionChange(selection) {
|
||||
this.selectiones = selection;
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
<!-- 工厂数据卡片 -->
|
||||
<el-row :gutter="16" class="factory-row">
|
||||
<el-col :xs="24" :sm="12" :md="6" v-for="(item, index) in factories" :key="item.name">
|
||||
<div class="factory-card" :style="{ borderTopColor: item.color }" @click="goDetail">
|
||||
<div class="factory-card" :style="{ borderTopColor: item.color }">
|
||||
<div class="card-header">
|
||||
<div class="card-icon" :style="{ backgroundColor: item.bgColor }">
|
||||
<el-icon :size="24" :color="item.color"><OfficeBuilding /></el-icon>
|
||||
|
|
@ -193,30 +193,32 @@ let pieChart = null
|
|||
const colors = ['#409eff', '#67c23a', '#e6a23c', '#f56c6c']
|
||||
const bgColors = ['#ecf5ff', '#f0f9eb', '#fdf6ec', '#fef0f0']
|
||||
|
||||
// 各工厂基础比例
|
||||
const baseFactories = [
|
||||
{ name: '合肥南方', ratio: 0.4382 },
|
||||
{ name: '中联万吨', ratio: 0.3081 },
|
||||
{ name: '铜梁水泥', ratio: 0.1424 },
|
||||
{ name: '槐坎南方水泥', ratio: 0.1113 },
|
||||
// 各工厂与数据表的映射关系
|
||||
const factoryDefs = [
|
||||
{ name: '合肥南方', match: (t) => t === 'mplogx' }, // 合肥南方
|
||||
{ name: '中联万吨', match: (t) => t === 'mplogx_xzzl' }, // 中联万吨
|
||||
{ name: '铜梁水泥', match: (t) => t === 'mplogx_tlxn' }, // 铜梁水泥
|
||||
{ name: '槐坎南方水泥', match: (t) => t.startsWith('mplogx_hknf') }, // 槁坎南方水泥
|
||||
]
|
||||
|
||||
const totalCount = ref(0)
|
||||
const tables = ref([])
|
||||
|
||||
const factories = computed(() => {
|
||||
const total = totalCount.value
|
||||
// 前3个按比例取整,最后一个用总量减去前3个保证总和精确
|
||||
const counts = baseFactories.map(f => Math.round(total * f.ratio))
|
||||
const sumFirst3 = counts[0] + counts[1] + counts[2]
|
||||
counts[3] = total - sumFirst3
|
||||
|
||||
return baseFactories.map((f, i) => ({
|
||||
return factoryDefs.map((f, i) => {
|
||||
// 同一工厂可能对应多张数据表,按表名匹配后累加行数
|
||||
const count = tables.value
|
||||
.filter((t) => f.match(t.table_name))
|
||||
.reduce((sum, t) => sum + (t.approximate_row_count || 0), 0)
|
||||
return {
|
||||
name: f.name,
|
||||
count: counts[i],
|
||||
count,
|
||||
color: colors[i],
|
||||
bgColor: bgColors[i],
|
||||
percentage: total > 0 ? (counts[i] / total) * 100 : 0,
|
||||
}))
|
||||
percentage: total > 0 ? (count / total) * 100 : 0,
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
const maxFactory = computed(() => {
|
||||
|
|
@ -336,19 +338,29 @@ const handleResize = () => {
|
|||
pieChart?.resize()
|
||||
}
|
||||
|
||||
// 拦截浏览器后退:在大屏页按“返回”时跳转到数据模板页
|
||||
const handlePopState = () => {
|
||||
router.push('/cement_data_template')
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
API.hfnf.mplogx.list.req({ page: 1, page_size: 1 }).then(res => {
|
||||
totalCount.value = res.count
|
||||
API.hfnf.stats.list.req().then(res => {
|
||||
tables.value = res.tables || []
|
||||
totalCount.value = res.summary?.approximate_row_count_total || 0
|
||||
nextTick(() => {
|
||||
initBarChart()
|
||||
initPieChart()
|
||||
})
|
||||
})
|
||||
window.addEventListener('resize', handleResize)
|
||||
// 多压一条相同的历史记录,使浏览器后退可被 popstate 拦截
|
||||
history.pushState(null, '', location.href)
|
||||
window.addEventListener('popstate', handlePopState)
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
window.removeEventListener('resize', handleResize)
|
||||
window.removeEventListener('popstate', handlePopState)
|
||||
barChart?.dispose()
|
||||
pieChart?.dispose()
|
||||
})
|
||||
|
|
|
|||
|
|
@ -183,7 +183,7 @@
|
|||
></el-table-column>
|
||||
<el-table-column
|
||||
prop="dept_name"
|
||||
label="完成车间"
|
||||
label="所在车间"
|
||||
></el-table-column>
|
||||
<el-table-column
|
||||
prop="count"
|
||||
|
|
@ -351,7 +351,7 @@
|
|||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="dept_name"
|
||||
label="完成车间"
|
||||
label="所在车间"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="count"
|
||||
|
|
|
|||
|
|
@ -90,6 +90,7 @@
|
|||
v-model="selectBatch"
|
||||
value-key="id"
|
||||
clearable
|
||||
:multiple="project_code=='gz'&&form.type == 'sale_out'"
|
||||
filterable
|
||||
remote = "true"
|
||||
:style="divStyle"
|
||||
|
|
@ -581,6 +582,13 @@ export default {
|
|||
that.form.count = Number(that.selectObj.count_canmio);
|
||||
that.mTracking = that.selectObj.material_.tracking;
|
||||
that.selectBatchChange(that.selectObj)
|
||||
}else if(that.type == "sale_out"&&that.project_code=='gz'){
|
||||
that.form.material = that.selectObj.id;
|
||||
that.form.unit = that.selectObj.unit;
|
||||
that.form.unit_price = that.selectObj.unit_price;
|
||||
that.mTracking = that.selectObj.tracking;
|
||||
that.selectBatch = [];
|
||||
that.getBatchOptions();
|
||||
}else{
|
||||
var type = this.form.type;
|
||||
that.form.material = that.selectObj.id;
|
||||
|
|
@ -616,6 +624,26 @@ export default {
|
|||
let that = this;
|
||||
that.wprList = [];
|
||||
that.mioitems = [];
|
||||
// gz 销售发货:多选批次
|
||||
if(that.form.type == 'sale_out' && that.project_code == 'gz' && Array.isArray(items)){
|
||||
if(items.length === 0){
|
||||
that.form.batch = "";
|
||||
that.form.mb = "";
|
||||
that.form.count = 0;
|
||||
that.batchcount = 0;
|
||||
that.form.warehouse = "";
|
||||
that.inputBatchDisable = false;
|
||||
return;
|
||||
}
|
||||
let totalCount = items.reduce((sum, it) => sum + Number(it.count_canmio || 0), 0);
|
||||
that.form.batch = items.map(it => it.batch).join(',');
|
||||
that.form.mb = items.map(it => it.id).join(',');
|
||||
that.form.count = totalCount;
|
||||
that.batchcount = totalCount;
|
||||
that.form.warehouse = items[0].warehouse;
|
||||
that.inputBatchDisable = true;
|
||||
return;
|
||||
}
|
||||
if(items){
|
||||
if(that.form.type == 'sale_out'&&that.project_code=='bxerp'){
|
||||
let count = 0;
|
||||
|
|
@ -876,7 +904,21 @@ export default {
|
|||
try {
|
||||
let res;
|
||||
if (that.mode == "add") {
|
||||
if(that.form.type == 'sale_out' && that.project_code == 'gz' && Array.isArray(that.selectBatch) && that.selectBatch.length > 0){
|
||||
let payload = that.selectBatch.map(b => ({
|
||||
mio: that.mioId,
|
||||
material: that.form.material,
|
||||
batch: b.batch,
|
||||
mb: b.id,
|
||||
count: Number(b.count_canmio),
|
||||
warehouse: b.warehouse,
|
||||
unit_price: that.form.unit_price,
|
||||
note: that.form.note || ''
|
||||
}));
|
||||
res = await that.$API.inm.mioitem.create.req(payload);
|
||||
} else {
|
||||
res = await that.$API.inm.mioitem.create.req(that.form);
|
||||
}
|
||||
} else if (that.mode == "edit") {
|
||||
res = await that.$API.inm.mioitem.update.req(that.form.id,that.form);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,6 +31,11 @@
|
|||
clearable
|
||||
style="width: 200px;"
|
||||
></el-input>
|
||||
<el-input v-model="query.handler"
|
||||
placeholder="操作人"
|
||||
clearable
|
||||
style="width: 200px;"
|
||||
></el-input>
|
||||
<el-button
|
||||
type="primary"
|
||||
icon="el-icon-search"
|
||||
|
|
@ -110,13 +115,24 @@
|
|||
<span>{{scope.row.data.分检_缺陷项_扭转角不合格?scope.row.data.分检_缺陷项_扭转角不合格:0}}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="开台人" align="center" class-name="colorheader7">
|
||||
<el-table-column label="工装" align="center" class-name="colorheader7">
|
||||
<template #default="scope">
|
||||
<span>{{toolList[scope.row.pre_info.tooling]}}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="开台人" align="center" class-name="colorheader1">
|
||||
<template #default="scope">
|
||||
<span v-if="scope.row.data.喷码_一体刀_操作人">{{scope.row.data.喷码_一体刀_操作人}}</span>
|
||||
<span v-if="scope.row.data.喷码_磨床开台_操作人">{{scope.row.data.喷码_磨床开台_操作人}}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="备注" align="center" class-name="colorheader1">
|
||||
<el-table-column label="开台设备" align="center" class-name="colorheader2">
|
||||
<template #default="scope">
|
||||
<span v-if="scope.row.data.喷码_一体刀_使用设备">{{scope.row.data.喷码_一体刀_使用设备}}</span>
|
||||
<span v-if="scope.row.data.喷码_磨床开台_使用设备">{{scope.row.data.喷码_磨床开台_使用设备}}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="备注" align="center" class-name="colorheader3">
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.data.分检_缺陷项_备注 }}</span>
|
||||
</template>
|
||||
|
|
@ -141,17 +157,30 @@ export default {
|
|||
batch__contains:'',
|
||||
last_time__gte:'',
|
||||
last_time__lte:'',
|
||||
handler:''
|
||||
},
|
||||
apiObj: this.$API.wpm.wpr.query,
|
||||
options:[],
|
||||
tableData:[],
|
||||
toolList:{},
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.getToolings();
|
||||
},
|
||||
methods: {
|
||||
getToolings(){
|
||||
let that = this;
|
||||
that.$API.em.equipment.list.req({ page: 0,type:10,cate__code:'7'}).then((res) => {
|
||||
res.forEach((item) => {
|
||||
that.toolList[item.id] = item.number;
|
||||
});
|
||||
});
|
||||
},
|
||||
handleQuery(){
|
||||
let that = this;
|
||||
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 = {};
|
||||
let obj = {},obj1 = {},obj2 = {},obj3 = {},obj4 = {},obj5 = {};
|
||||
obj.field = 'data__分检_批次号';
|
||||
obj.value = that.query.batch__contains;
|
||||
obj.compare = '';
|
||||
|
|
@ -172,6 +201,10 @@ export default {
|
|||
obj4.value = that.query.number__contains;
|
||||
obj4.compare = 'contains';
|
||||
|
||||
obj5.field = 'data__分检_操作人';
|
||||
obj5.value = that.query.handler;
|
||||
obj5.compare = '';
|
||||
|
||||
if(that.query.batch__contains!==''&&that.query.batch__contains!==null){
|
||||
querys[0].push(obj);
|
||||
}
|
||||
|
|
@ -187,6 +220,9 @@ export default {
|
|||
if(that.query.number__contains!==''&&that.query.number__contains!==null){
|
||||
querys[0].push(obj4);
|
||||
}
|
||||
if(that.query.handler!==''&&that.query.handler!==null){
|
||||
querys[0].push(obj5);
|
||||
}
|
||||
that.params.querys = querys;
|
||||
this.$refs.table.queryData(that.params);
|
||||
},
|
||||
|
|
|
|||
|
|
@ -51,7 +51,11 @@
|
|||
stripe
|
||||
>
|
||||
<el-table-column type="index" width="50" fixed="left"/>
|
||||
<el-table-column label="工段名" prop="工段名" fixed="left">
|
||||
<el-table-column label="工段" prop="工段名" fixed="left">
|
||||
</el-table-column>
|
||||
<el-table-column label="工序" prop="工序" fixed="left">
|
||||
</el-table-column>
|
||||
<el-table-column label="库存数" prop="物料数量" fixed="left">
|
||||
</el-table-column>
|
||||
<el-table-column label="生产数" prop="生产数" fixed="left">
|
||||
</el-table-column>
|
||||
|
|
@ -133,7 +137,7 @@ export default {
|
|||
sums[index] = "合计";
|
||||
return;
|
||||
}
|
||||
if (index <total && (index!==0||index!==1||index!==5)) {
|
||||
if (index <total && (index!==0||index!==1||index!==2||index!==7)) {
|
||||
const values = data.map((item) =>
|
||||
Number(item[column.property])
|
||||
);
|
||||
|
|
@ -151,8 +155,8 @@ export default {
|
|||
}, 0);
|
||||
}
|
||||
}
|
||||
if(index==5){
|
||||
sums[index] = ((sums[3]/sums[2])*100).toFixed(2) + '%';
|
||||
if(index==7){
|
||||
sums[index] = ((sums[5]/sums[4])*100).toFixed(2) + '%';
|
||||
}
|
||||
});
|
||||
return sums;
|
||||
|
|
|
|||
|
|
@ -17,6 +17,16 @@
|
|||
placeholder="结束时间"
|
||||
style="margin-left: 2px; width: 150px"
|
||||
/>
|
||||
<el-input v-model="query.material_name"
|
||||
placeholder="产品名称"
|
||||
clearable
|
||||
style="width: 200px;"
|
||||
></el-input>
|
||||
<el-input v-model="query.batch"
|
||||
placeholder="批次号"
|
||||
clearable
|
||||
style="width: 200px;"
|
||||
></el-input>
|
||||
<el-button
|
||||
type="primary"
|
||||
icon="el-icon-search"
|
||||
|
|
@ -226,6 +236,8 @@ export default {
|
|||
select_cols: "",
|
||||
mgroup_name: "扭转",
|
||||
testmgroup_name: "扭后检测",
|
||||
material_name: "",
|
||||
batch: "",
|
||||
},
|
||||
end_date:'',
|
||||
start_date:'',
|
||||
|
|
@ -257,6 +269,16 @@ export default {
|
|||
}else{
|
||||
query.end_date = that.query.end_date;
|
||||
}
|
||||
if(that.query.material_name==''||that.query.material_name==null){
|
||||
delete query.material_name;
|
||||
}else{
|
||||
query.material_name = that.query.material_name;
|
||||
}
|
||||
if(that.query.batch==''||that.query.batch==null){
|
||||
delete query.batch;
|
||||
}else{
|
||||
query.batch = that.query.batch;
|
||||
}
|
||||
params.query = query;
|
||||
if(that.activeName=='product'){
|
||||
biStr = 'product_defect_pb_m';
|
||||
|
|
|
|||
|
|
@ -63,6 +63,12 @@
|
|||
placeholder="结束时间"
|
||||
style="margin-left: 2px; width: 150px"
|
||||
/>
|
||||
<el-input
|
||||
v-model="query.material_name"
|
||||
placeholder="物料名"
|
||||
clearable
|
||||
style="width: 200px; margin-left: 2px;"
|
||||
/>
|
||||
<el-button
|
||||
type="primary"
|
||||
icon="el-icon-search"
|
||||
|
|
@ -96,6 +102,8 @@
|
|||
<span>{{ scope.row.data.装炉压板出炉_装炉_日期?scope.row.data.装炉压板出炉_装炉_日期:'' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="物料名称" prop="material_name" fixed="left">
|
||||
</el-table-column>
|
||||
<el-table-column label="板号" prop="number" fixed="left">
|
||||
</el-table-column>
|
||||
<el-table-column label="压前对边" align="center">
|
||||
|
|
@ -201,6 +209,8 @@
|
|||
<el-table-column label="序号" type="index" width="50" fixed="left"/>
|
||||
<el-table-column label="板号" prop="number" fixed="left">
|
||||
</el-table-column>
|
||||
<el-table-column label="物料名称" prop="material_name" fixed="left">
|
||||
</el-table-column>
|
||||
<el-table-column label="炉号" fixed="left">
|
||||
<template #default="scope">
|
||||
<span v-if="scope.row.data.装炉压板出炉_设备编号">{{ scope.row.data.装炉压板出炉_设备编号 }}</span>
|
||||
|
|
@ -372,6 +382,8 @@
|
|||
<el-table-column type="index" width="50" fixed="left"/>
|
||||
<el-table-column label="设备编号" prop="设备编号">
|
||||
</el-table-column>
|
||||
<el-table-column label="物料名" prop="物料名">
|
||||
</el-table-column>
|
||||
<el-table-column label="总数">
|
||||
<template #default="scope">
|
||||
<span v-if="scope.row.总切片数" @click="handleNumClick(scope.row)" style="color:#0052d9;">{{ scope.row.总切片数 }}</span>
|
||||
|
|
@ -425,6 +437,8 @@
|
|||
<span v-if="scope.row.横压!==null">{{scope.row.横压}}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="物料名" prop="物料名">
|
||||
</el-table-column>
|
||||
<el-table-column label="总数" prop="总切片数">
|
||||
</el-table-column>
|
||||
<el-table-column label="长点">
|
||||
|
|
@ -470,6 +484,8 @@
|
|||
<el-table-column type="index" width="50" fixed="left"/>
|
||||
<el-table-column label="操作人" prop="员工">
|
||||
</el-table-column>
|
||||
<el-table-column label="物料名" prop="物料名">
|
||||
</el-table-column>
|
||||
<el-table-column label="总数" prop="总切片数">
|
||||
</el-table-column>
|
||||
<el-table-column label="长点">
|
||||
|
|
@ -515,6 +531,8 @@
|
|||
<el-table-column type="index" width="50" fixed="left"/>
|
||||
<el-table-column label="丝高" prop="丝高">
|
||||
</el-table-column>
|
||||
<el-table-column label="物料名" prop="物料名">
|
||||
</el-table-column>
|
||||
<el-table-column label="总数" prop="总切片数">
|
||||
</el-table-column>
|
||||
<el-table-column label="长点">
|
||||
|
|
@ -629,6 +647,9 @@ export default {
|
|||
}else{
|
||||
query.end_date = that.query.end_date;
|
||||
}
|
||||
if(that.query.material_name!=''&&that.query.material_name!=null){
|
||||
query.material_name = that.query.material_name;
|
||||
}
|
||||
if(that.activeName=='luhao'){
|
||||
query.select_cols = that.query.select_cols;
|
||||
params.query = query;
|
||||
|
|
|
|||
|
|
@ -31,6 +31,12 @@
|
|||
placeholder="结束时间"
|
||||
style="margin-left: 2px; width: 150px"
|
||||
/>
|
||||
<el-input
|
||||
v-model="query.material_name"
|
||||
placeholder="物料名"
|
||||
clearable
|
||||
style="width: 200px; margin-left: 2px;"
|
||||
/>
|
||||
<el-button
|
||||
type="primary"
|
||||
icon="el-icon-search"
|
||||
|
|
@ -55,6 +61,8 @@
|
|||
<el-table-column type="index" width="50" fixed="left"/>
|
||||
<el-table-column label="炉号" prop="设备编号">
|
||||
</el-table-column>
|
||||
<el-table-column label="物料名" prop="物料名">
|
||||
</el-table-column>
|
||||
<el-table-column label="总数">
|
||||
<template #default="scope">
|
||||
<!-- @click="handleNumClick(scope.row)" -->
|
||||
|
|
@ -133,6 +141,8 @@
|
|||
<span v-if="scope.row.横压!==null">{{scope.row.横压}}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="物料名" prop="物料名">
|
||||
</el-table-column>
|
||||
<el-table-column label="总数" prop="总切片数">
|
||||
</el-table-column>
|
||||
<el-table-column label="黑网重">
|
||||
|
|
@ -202,6 +212,8 @@
|
|||
<el-table-column type="index" width="50" fixed="left"/>
|
||||
<el-table-column label="操作人" prop="员工">
|
||||
</el-table-column>
|
||||
<el-table-column label="物料名" prop="物料名">
|
||||
</el-table-column>
|
||||
<el-table-column label="总数" prop="总切片数">
|
||||
</el-table-column>
|
||||
<el-table-column label="黑网重">
|
||||
|
|
@ -271,6 +283,8 @@
|
|||
<el-table-column type="index" width="50" fixed="left"/>
|
||||
<el-table-column label="丝高" prop="丝高">
|
||||
</el-table-column>
|
||||
<el-table-column label="物料名" prop="物料名">
|
||||
</el-table-column>
|
||||
<el-table-column label="总数" prop="总切片数">
|
||||
</el-table-column>
|
||||
<el-table-column label="黑网重">
|
||||
|
|
@ -352,7 +366,8 @@ export default {
|
|||
query:{
|
||||
end_date:'',
|
||||
start_date:'',
|
||||
select_cols: ""
|
||||
select_cols: "",
|
||||
material_name:'',
|
||||
},
|
||||
end_date:'',
|
||||
start_date:'',
|
||||
|
|
@ -384,6 +399,9 @@ export default {
|
|||
}else{
|
||||
query.end_date = that.query.end_date;
|
||||
}
|
||||
if(that.query.material_name!=''&&that.query.material_name!=null){
|
||||
query.material_name = that.query.material_name;
|
||||
}
|
||||
if(that.activeName=='luhao'){
|
||||
query.select_cols = that.query.select_cols;
|
||||
query.mgroup_name = '装炉压板出炉';
|
||||
|
|
|
|||
|
|
@ -20,7 +20,9 @@
|
|||
<el-row :gutter="10">
|
||||
<el-col :lg="11">
|
||||
<el-card shadow="never">
|
||||
<div class="chart-scroll" ref="chartScroll">
|
||||
<div id="bachart1" style="width:100%;height:300px;"></div>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :lg="13">
|
||||
|
|
@ -100,11 +102,15 @@ export default {
|
|||
text: '',
|
||||
},
|
||||
grid: {
|
||||
top: '80px'
|
||||
top: '150px'
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis'
|
||||
},
|
||||
legend: {
|
||||
top: 30,
|
||||
left: 10,
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: []
|
||||
|
|
@ -112,7 +118,6 @@ export default {
|
|||
yAxis: {
|
||||
type: 'value'
|
||||
},
|
||||
lenged: [],
|
||||
series: [{
|
||||
data: [0, 0, 0, 0, 0, 0, 0],
|
||||
stack: 'Ad',
|
||||
|
|
@ -146,13 +151,11 @@ export default {
|
|||
that.start_date = year + '-' + month + '-01';
|
||||
that.end_date = year + '-' + month + '-' + days;
|
||||
that.queryDate = year + '-' + month;
|
||||
let duration = that.endWeekNum - that.firstWeekNum + 1;
|
||||
for (let i = 1; i <= duration; i++) {
|
||||
for (let i = that.firstWeekNum; i <= that.endWeekNum; i++) {
|
||||
that.xAxisOrigin.push('第' + i + '周');
|
||||
}
|
||||
that.xAxisData = that.xAxisOrigin;
|
||||
let height = document.getElementById('mainDom').clientHeight;
|
||||
console.log('height',height);
|
||||
height= height-60;
|
||||
that.tableHeight = height;
|
||||
document.getElementById('bachart1').style.height = height + 'px';
|
||||
|
|
@ -170,12 +173,12 @@ export default {
|
|||
}
|
||||
setTimeout(() => {
|
||||
try {
|
||||
myChart.setOption(option);
|
||||
myChart.clear();
|
||||
myChart.setOption(option, true);
|
||||
} catch (error) { }
|
||||
}, 500)
|
||||
},
|
||||
queryTypeChange(value) {
|
||||
console.log(value)
|
||||
this.queryDate = '';
|
||||
},
|
||||
getWeekOfYear(a,b,c) {
|
||||
|
|
@ -197,19 +200,18 @@ export default {
|
|||
query: { start_date: that.start_date, end_date: that.end_date, mgroup_name: "混料", is_count_utask: -1 },
|
||||
};
|
||||
let option = deepCopy(that.basicOption);
|
||||
option.xAxis.data = that.xAxisData;
|
||||
option.title.text = '混料统计';
|
||||
let dateLabels = that.xAxisData;
|
||||
let exec = that.queryType == '月' ? 'lineWeek' : 'lineMonth';
|
||||
that.$API.bi.dataset.exec.req(exec, obj).then((res) => {
|
||||
let dataList = res.data2.ds0 ? res.data2.ds0 : [];
|
||||
that.dataList = dataList;
|
||||
if (dataList.length > 0) {
|
||||
option.series = [];
|
||||
let seriesData = [], nameList = [];
|
||||
let nameList = [];
|
||||
dataList.forEach(ite => {
|
||||
if (nameList.indexOf(ite.物料名) > -1) { } else {
|
||||
nameList.push(ite.物料名);
|
||||
seriesData.push([0,0,0,0,0,0,0,0,0,0,0,0])
|
||||
let obj = {};
|
||||
obj.text = ite.物料名;
|
||||
obj.value = ite.物料名;
|
||||
|
|
@ -230,11 +232,15 @@ export default {
|
|||
that.specsFilters.push(obj3);
|
||||
}
|
||||
})
|
||||
let seriesData = [];
|
||||
for (let i = 0; i < dateLabels.length; i++) {
|
||||
seriesData.push(new Array(modelList.length).fill(0));
|
||||
}
|
||||
dataList.forEach(item => {
|
||||
let indexX = 0, indexY = 0;
|
||||
if (that.queryType == '月') {
|
||||
indexX = nameList.indexOf(item.物料名);
|
||||
indexY = item.周 - that.firstWeekNum;
|
||||
indexX = item.周 - that.firstWeekNum;
|
||||
indexY = modelList.indexOf(item.型号);
|
||||
if(dateList.indexOf(item.周)>-1){}else{
|
||||
dateList.push(item.周);
|
||||
let obj = {};
|
||||
|
|
@ -244,22 +250,33 @@ export default {
|
|||
}
|
||||
} else {
|
||||
that.dateFilters = [1,2,3,4,5,6,7,8,9,10,11,12];
|
||||
indexX = nameList.indexOf(item.物料名);
|
||||
indexY = item.月 - 1;
|
||||
indexX = item.月 - 1;
|
||||
indexY = modelList.indexOf(item.型号);
|
||||
}
|
||||
if (indexX >= 0 && indexX < seriesData.length && indexY >= 0) {
|
||||
seriesData[indexX][indexY] += item.合格数;
|
||||
}
|
||||
});
|
||||
option.xAxis.data = modelList;
|
||||
for (let n = 0; n < seriesData.length; n++) {
|
||||
let obj = {};
|
||||
obj.name = nameList[n];
|
||||
obj.stack = 'Ad';
|
||||
obj.name = dateLabels[n];
|
||||
obj.type = 'bar';
|
||||
obj.barWidth = '15px';
|
||||
obj.barWidth = '10px';
|
||||
obj.data = seriesData[n];
|
||||
option.series.push(obj)
|
||||
}
|
||||
let chartDom = document.getElementById('bachart1');
|
||||
if (chartDom) {
|
||||
let parentWidth = that.$refs.chartScroll ? that.$refs.chartScroll.clientWidth : chartDom.parentElement.clientWidth;
|
||||
let needWidth = modelList.length * dateLabels.length * 15;
|
||||
chartDom.style.width = Math.max(parentWidth, needWidth) + 'px';
|
||||
let inst = echarts.getInstanceByDom(chartDom);
|
||||
if (inst) inst.resize();
|
||||
}
|
||||
that.setChart("bachart1", option);
|
||||
} else {
|
||||
option.xAxis.data = [];
|
||||
that.setChart("bachart1", option);
|
||||
}
|
||||
});
|
||||
|
|
@ -361,4 +378,8 @@ export default {
|
|||
right: 8px;
|
||||
z-index: 10;
|
||||
}
|
||||
.chart-scroll {
|
||||
width: 100%;
|
||||
overflow-x: auto;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
<el-container>
|
||||
<el-header>
|
||||
<div class="right-panel">
|
||||
<el-select v-model="queryType" @change="queryTypeChange">
|
||||
<el-select v-model="queryType" @change="queryTypeChange" style="width: 150px">
|
||||
<el-option
|
||||
v-for="item in typeOptions"
|
||||
:key="item"
|
||||
|
|
@ -17,7 +17,7 @@
|
|||
type="month"
|
||||
placeholder="查询月期"
|
||||
value-format="YYYY-MM"
|
||||
style="width: 100%"
|
||||
style="width: 150px"
|
||||
>
|
||||
</el-date-picker>
|
||||
<el-date-picker
|
||||
|
|
@ -26,7 +26,7 @@
|
|||
type="year"
|
||||
placeholder="查询年份"
|
||||
value-format="YYYY"
|
||||
style="width: 100%"
|
||||
style="width: 150px"
|
||||
>
|
||||
</el-date-picker>
|
||||
<el-button
|
||||
|
|
@ -41,7 +41,9 @@
|
|||
<el-row :gutter="10">
|
||||
<el-col :lg="12">
|
||||
<el-card shadow="never">
|
||||
<div class="chart-scroll">
|
||||
<div id="bachart1"></div>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :lg="12">
|
||||
|
|
@ -55,7 +57,7 @@
|
|||
<el-table
|
||||
:data="tableData7"
|
||||
id="exportDiv7"
|
||||
:height="300"
|
||||
:height="500"
|
||||
:summary-method="getSummaries"
|
||||
show-summary
|
||||
>
|
||||
|
|
@ -107,7 +109,9 @@
|
|||
<el-row :gutter="10">
|
||||
<el-col :lg="12">
|
||||
<el-card shadow="never">
|
||||
<div class="chart-scroll">
|
||||
<div id="bachart2"></div>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :lg="12">
|
||||
|
|
@ -121,7 +125,7 @@
|
|||
<el-table
|
||||
:data="tableData10"
|
||||
id="exportDiv10"
|
||||
:height="300"
|
||||
:height="500"
|
||||
:summary-method="getSummaries"
|
||||
show-summary
|
||||
>
|
||||
|
|
@ -173,7 +177,9 @@
|
|||
<el-row :gutter="10">
|
||||
<el-col :lg="12">
|
||||
<el-card shadow="never">
|
||||
<div class="chart-scroll">
|
||||
<div id="bachart3"></div>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :lg="12">
|
||||
|
|
@ -187,7 +193,7 @@
|
|||
<el-table
|
||||
:data="tableData6"
|
||||
id="exportDiv6"
|
||||
:height="300"
|
||||
:height="500"
|
||||
:summary-method="getSummaries2"
|
||||
show-summary
|
||||
>
|
||||
|
|
@ -278,6 +284,9 @@ export default {
|
|||
tooltip: {
|
||||
trigger: "axis",
|
||||
},
|
||||
legend: {
|
||||
top: 30,
|
||||
},
|
||||
xAxis: {
|
||||
type: "category",
|
||||
data: [],
|
||||
|
|
@ -285,13 +294,10 @@ export default {
|
|||
yAxis: {
|
||||
type: "value",
|
||||
},
|
||||
lenged: [],
|
||||
series: [
|
||||
{
|
||||
data: [0, 0, 0, 0, 0, 0, 0],
|
||||
stack: "Ad",
|
||||
type: "bar",
|
||||
barWidth: "15px",
|
||||
},
|
||||
],
|
||||
},
|
||||
|
|
@ -343,8 +349,7 @@ export default {
|
|||
that.start_date = year + "-" + month + "-01";
|
||||
that.end_date =year + "-" + month + "-" + days;
|
||||
that.queryDate = year + "-" + month;
|
||||
let duration = that.endWeekNum - that.firstWeekNum + 1;
|
||||
for (let i = 1; i <= duration; i++) {
|
||||
for (let i = that.firstWeekNum; i <= that.endWeekNum; i++) {
|
||||
that.xAxisOrigin.push("第" + i + "周");
|
||||
}
|
||||
that.xAxisData = that.xAxisOrigin;
|
||||
|
|
@ -366,6 +371,7 @@ export default {
|
|||
}
|
||||
setTimeout(() => {
|
||||
try {
|
||||
myChart.resize();
|
||||
myChart.setOption(option);
|
||||
} catch (error) {}
|
||||
}, 500);
|
||||
|
|
@ -391,8 +397,8 @@ export default {
|
|||
that.modelFilters6 = [];
|
||||
that.specsFilters6 = [];
|
||||
let option = deepCopy(that.basicOption);
|
||||
option.xAxis.data = that.xAxisData;
|
||||
option.title.text = "6车间";
|
||||
let dateLabels = that.xAxisData;
|
||||
let exec = that.queryType == "月" ? "lineWeek" : "lineMonth";
|
||||
let obj = {
|
||||
query: {
|
||||
|
|
@ -406,12 +412,11 @@ export default {
|
|||
that.tableData6 = tableData6;
|
||||
if (tableData6.length > 0) {
|
||||
option.series = [];
|
||||
let seriesData = [],nameList = [];
|
||||
let nameList = [];
|
||||
tableData6.forEach((ite) => {
|
||||
if (nameList.indexOf(ite.物料名) > -1) {
|
||||
}else {
|
||||
nameList.push(ite.物料名);
|
||||
seriesData.push([]);
|
||||
let obj = {};
|
||||
obj.text = ite.物料名;
|
||||
obj.value = ite.物料名;
|
||||
|
|
@ -439,15 +444,19 @@ export default {
|
|||
that.modelFilters6.push(obj4);
|
||||
}
|
||||
});
|
||||
let seriesData = [];
|
||||
let prodData = [];
|
||||
for (let i = 0; i < dateLabels.length; i++) {
|
||||
seriesData.push(new Array(nameList.length).fill(0));
|
||||
prodData.push(new Array(nameList.length).fill(0));
|
||||
}
|
||||
if (that.queryType == "月") {
|
||||
tableData6.forEach((item) => {
|
||||
let indexX = nameList.indexOf(item.物料名);
|
||||
let indexY = item.周 - that.firstWeekNum;
|
||||
if(seriesData[indexX][indexY]){
|
||||
seriesData[indexX][indexY] += item.合格数;
|
||||
}else{
|
||||
seriesData[indexX][indexY] =0;
|
||||
let indexX = item.周 - that.firstWeekNum;
|
||||
let indexY = nameList.indexOf(item.物料名);
|
||||
if (indexX >= 0 && indexX < seriesData.length && indexY >= 0) {
|
||||
seriesData[indexX][indexY] += item.合格数;
|
||||
prodData[indexX][indexY] += Number(item.生产数) || 0;
|
||||
}
|
||||
if(dateList.indexOf(item.周)>-1){}else{
|
||||
dateList.push(item.周);
|
||||
|
|
@ -460,27 +469,105 @@ export default {
|
|||
} else {
|
||||
that.dateFilters6 = [1,2,3,4,5,6,7,8,9,10,11,12];
|
||||
tableData6.forEach((item) => {
|
||||
let indexX = nameList.indexOf(item.物料名);
|
||||
let indexY = item.month - 1;
|
||||
if(seriesData[indexX][indexY]){
|
||||
seriesData[indexX][indexY] += item.合格数;
|
||||
}else{
|
||||
seriesData[indexX][indexY] =0;
|
||||
let indexX = item.月 - 1;
|
||||
let indexY = nameList.indexOf(item.物料名);
|
||||
if (indexX >= 0 && indexX < seriesData.length && indexY >= 0) {
|
||||
seriesData[indexX][indexY] += item.合格数;
|
||||
prodData[indexX][indexY] += Number(item.生产数) || 0;
|
||||
}
|
||||
});
|
||||
}
|
||||
option.xAxis = { type: "category", data: nameList };
|
||||
option.yAxis = [
|
||||
{ type: "value" },
|
||||
{ type: "value", min: -233.33, max: 100, show: false }
|
||||
];
|
||||
option.legend = { top: 30, data: dateLabels };
|
||||
let barWidth = 10;
|
||||
let barGap = 0;
|
||||
let chartDom = document.getElementById("bachart3");
|
||||
if (chartDom) {
|
||||
chartDom.style.width = (nameList.length * dateLabels.length * 15) + "px";
|
||||
}
|
||||
for (let n = 0; n < seriesData.length; n++) {
|
||||
let obj = {};
|
||||
obj.name = nameList[n];
|
||||
obj.stack = "Ad";
|
||||
obj.name = dateLabels[n];
|
||||
obj.type = "bar";
|
||||
obj.barWidth = "15px";
|
||||
obj.barWidth = barWidth;
|
||||
obj.barGap = "0%";
|
||||
obj.data = seriesData[n];
|
||||
option.series.push(obj);
|
||||
}
|
||||
let totalSeries = seriesData.length;
|
||||
let curveData = [];
|
||||
let ratesByMat = [];
|
||||
for (let mat = 0; mat < nameList.length; mat++) {
|
||||
let rates = [];
|
||||
for (let s = 0; s < totalSeries; s++) {
|
||||
let pass = seriesData[s][mat];
|
||||
let prod = prodData[s][mat];
|
||||
rates.push(prod > 0 ? Math.round((pass / prod) * 100) : null);
|
||||
}
|
||||
curveData.push({ value: [mat].concat(rates) });
|
||||
ratesByMat.push(rates);
|
||||
}
|
||||
option.tooltip = {
|
||||
trigger: "axis",
|
||||
formatter: function (params) {
|
||||
if (!params || params.length === 0) return "";
|
||||
let cat = params[0].axisValueLabel;
|
||||
let matIdx = params[0].dataIndex;
|
||||
let rates = ratesByMat[matIdx] || [];
|
||||
let html = '<div style="font-weight:bold">' + cat + '</div>';
|
||||
let barIdx = 0;
|
||||
params.forEach(function (p) {
|
||||
if (p.seriesType !== "bar") return;
|
||||
let rate = rates[barIdx];
|
||||
let rateStr = (rate !== null && rate !== undefined) ? rate + "%" : "-";
|
||||
html += '<div>' +
|
||||
'<span style="display:inline-block;width:10px;height:10px;background:' + p.color + ';border-radius:50%;margin-right:5px;vertical-align:middle"></span>' +
|
||||
p.seriesName + ': ' + p.value + ' 合格率 ' + rateStr +
|
||||
'</div>';
|
||||
barIdx++;
|
||||
});
|
||||
return html;
|
||||
}
|
||||
};
|
||||
option.series.push({
|
||||
name: "合格率",
|
||||
type: "custom",
|
||||
xAxisIndex: 0,
|
||||
yAxisIndex: 1,
|
||||
silent: true,
|
||||
z: 5,
|
||||
data: curveData,
|
||||
renderItem: function (params, api) {
|
||||
let materialIdx = api.value(0);
|
||||
let centerX = api.coord([materialIdx, 0])[0];
|
||||
let groupWidth = totalSeries * barWidth + (totalSeries - 1) * barGap;
|
||||
let halfGroup = groupWidth / 2;
|
||||
let slotWidth = barWidth + barGap;
|
||||
let pts = [];
|
||||
for (let s = 0; s < totalSeries; s++) {
|
||||
let rate = api.value(s + 1);
|
||||
if (rate === null || rate === undefined) continue;
|
||||
let xPx = centerX - halfGroup + barWidth / 2 + s * slotWidth;
|
||||
let yPx = api.coord([0, rate])[1];
|
||||
pts.push([xPx, yPx]);
|
||||
}
|
||||
if (pts.length < 2) return null;
|
||||
return {
|
||||
type: "polyline",
|
||||
shape: { points: pts, smooth: 0.3 },
|
||||
style: { stroke: "#333", lineWidth: 1.5, fill: "none" }
|
||||
};
|
||||
}
|
||||
});
|
||||
that.setChart("bachart3", option);
|
||||
} else {
|
||||
option.xAxis.data = [];
|
||||
let chartDom = document.getElementById("bachart3");
|
||||
if (chartDom) chartDom.style.width = "100%";
|
||||
that.setChart("bachart3", option);
|
||||
}
|
||||
});
|
||||
|
|
@ -500,8 +587,8 @@ export default {
|
|||
},
|
||||
};
|
||||
let option = deepCopy(that.basicOption);
|
||||
option.xAxis.data = that.xAxisData;
|
||||
option.title.text = "预制棒(7车间)";
|
||||
let dateLabels = that.xAxisData;
|
||||
let exec = that.queryType == "月" ? "lineWeek" : "lineMonth";
|
||||
that.$API.bi.dataset.exec.req(exec, obj).then((res) => {
|
||||
console.log("7生产车间统计:", res);
|
||||
|
|
@ -509,13 +596,11 @@ export default {
|
|||
that.tableData7 = tableData7;
|
||||
if (tableData7.length > 0) {
|
||||
option.series = [];
|
||||
let seriesData = [],
|
||||
nameList = [];
|
||||
let nameList = [];
|
||||
tableData7.forEach((ite) => {
|
||||
if (nameList.indexOf(ite.物料名) > -1) {
|
||||
} else {
|
||||
nameList.push(ite.物料名);
|
||||
seriesData.push([]);
|
||||
let obj = {};
|
||||
obj.text = ite.物料名;
|
||||
obj.value = ite.物料名;
|
||||
|
|
@ -536,12 +621,18 @@ export default {
|
|||
that.specsFilters7.push(obj3);
|
||||
}
|
||||
});
|
||||
let seriesData = [];
|
||||
let prodData = [];
|
||||
for (let i = 0; i < dateLabels.length; i++) {
|
||||
seriesData.push(new Array(nameList.length).fill(0));
|
||||
prodData.push(new Array(nameList.length).fill(0));
|
||||
}
|
||||
tableData7.forEach((item) => {
|
||||
let indexX = 0,
|
||||
indexY = 0;
|
||||
if (that.queryType == "月") {
|
||||
indexX = nameList.indexOf(item.物料名);
|
||||
indexY = item.周 - that.firstWeekNum;
|
||||
indexX = item.周 - that.firstWeekNum;
|
||||
indexY = nameList.indexOf(item.物料名);
|
||||
if(dateList.indexOf(item.周)>-1){}else{
|
||||
dateList.push(item.周);
|
||||
let obj = {};
|
||||
|
|
@ -551,27 +642,105 @@ export default {
|
|||
}
|
||||
} else {
|
||||
that.dateFilters7 = [1,2,3,4,5,6,7,8,9,10,11,12];
|
||||
indexX = nameList.indexOf(item.物料名);
|
||||
indexY = item.月 - 1;
|
||||
indexX = item.月 - 1;
|
||||
indexY = nameList.indexOf(item.物料名);
|
||||
}
|
||||
if(seriesData[indexX][indexY]){
|
||||
seriesData[indexX][indexY] += item.合格数;
|
||||
}else{
|
||||
seriesData[indexX][indexY] =0;
|
||||
if (indexX >= 0 && indexX < seriesData.length && indexY >= 0) {
|
||||
seriesData[indexX][indexY] += item.合格数;
|
||||
prodData[indexX][indexY] += Number(item.生产数) || 0;
|
||||
}
|
||||
});
|
||||
option.xAxis = { type: "category", data: nameList };
|
||||
option.yAxis = [
|
||||
{ type: "value" },
|
||||
{ type: "value", min: -233.33, max: 100, show: false }
|
||||
];
|
||||
option.legend = { top: 30, data: dateLabels };
|
||||
let barWidth = 10;
|
||||
let barGap = 0;
|
||||
let chartDom = document.getElementById("bachart1");
|
||||
if (chartDom) {
|
||||
chartDom.style.width = (nameList.length * dateLabels.length * 15) + "px";
|
||||
}
|
||||
for (let n = 0; n < seriesData.length; n++) {
|
||||
let obj = {};
|
||||
obj.name = nameList[n];
|
||||
obj.stack = "Ad";
|
||||
obj.name = dateLabels[n];
|
||||
obj.type = "bar";
|
||||
obj.barWidth = "15px";
|
||||
obj.barWidth = barWidth;
|
||||
obj.barGap = "0%";
|
||||
obj.data = seriesData[n];
|
||||
option.series.push(obj);
|
||||
}
|
||||
let totalSeries = seriesData.length;
|
||||
let curveData = [];
|
||||
let ratesByMat = [];
|
||||
for (let mat = 0; mat < nameList.length; mat++) {
|
||||
let rates = [];
|
||||
for (let s = 0; s < totalSeries; s++) {
|
||||
let pass = seriesData[s][mat];
|
||||
let prod = prodData[s][mat];
|
||||
rates.push(prod > 0 ? Math.round((pass / prod) * 100) : null);
|
||||
}
|
||||
curveData.push({ value: [mat].concat(rates) });
|
||||
ratesByMat.push(rates);
|
||||
}
|
||||
option.tooltip = {
|
||||
trigger: "axis",
|
||||
formatter: function (params) {
|
||||
if (!params || params.length === 0) return "";
|
||||
let cat = params[0].axisValueLabel;
|
||||
let matIdx = params[0].dataIndex;
|
||||
let rates = ratesByMat[matIdx] || [];
|
||||
let html = '<div style="font-weight:bold">' + cat + '</div>';
|
||||
let barIdx = 0;
|
||||
params.forEach(function (p) {
|
||||
if (p.seriesType !== "bar") return;
|
||||
let rate = rates[barIdx];
|
||||
let rateStr = (rate !== null && rate !== undefined) ? rate + "%" : "-";
|
||||
html += '<div>' +
|
||||
'<span style="display:inline-block;width:10px;height:10px;background:' + p.color + ';border-radius:50%;margin-right:5px;vertical-align:middle"></span>' +
|
||||
p.seriesName + ': ' + p.value + ' 合格率 ' + rateStr +
|
||||
'</div>';
|
||||
barIdx++;
|
||||
});
|
||||
return html;
|
||||
}
|
||||
};
|
||||
option.series.push({
|
||||
name: "合格率",
|
||||
type: "custom",
|
||||
xAxisIndex: 0,
|
||||
yAxisIndex: 1,
|
||||
silent: true,
|
||||
z: 5,
|
||||
data: curveData,
|
||||
renderItem: function (params, api) {
|
||||
let materialIdx = api.value(0);
|
||||
let centerX = api.coord([materialIdx, 0])[0];
|
||||
let groupWidth = totalSeries * barWidth + (totalSeries - 1) * barGap;
|
||||
let halfGroup = groupWidth / 2;
|
||||
let slotWidth = barWidth + barGap;
|
||||
let pts = [];
|
||||
for (let s = 0; s < totalSeries; s++) {
|
||||
let rate = api.value(s + 1);
|
||||
if (rate === null || rate === undefined) continue;
|
||||
let xPx = centerX - halfGroup + barWidth / 2 + s * slotWidth;
|
||||
let yPx = api.coord([0, rate])[1];
|
||||
pts.push([xPx, yPx]);
|
||||
}
|
||||
if (pts.length < 2) return null;
|
||||
return {
|
||||
type: "polyline",
|
||||
shape: { points: pts, smooth: 0.3 },
|
||||
style: { stroke: "#333", lineWidth: 1.5, fill: "none" }
|
||||
};
|
||||
}
|
||||
});
|
||||
that.setChart("bachart1", option);
|
||||
} else {
|
||||
option.xAxis.data = [];
|
||||
let chartDom = document.getElementById("bachart1");
|
||||
if (chartDom) chartDom.style.width = "100%";
|
||||
that.setChart("bachart1", option);
|
||||
}
|
||||
});
|
||||
|
|
@ -584,8 +753,8 @@ export default {
|
|||
that.modelFilters = [];
|
||||
that.specsFilters = [];
|
||||
let option = deepCopy(that.basicOption);
|
||||
option.xAxis.data = that.xAxisData;
|
||||
option.title.text = "预制管(10车间)";
|
||||
let dateLabels = that.xAxisData;
|
||||
let obj = {
|
||||
query: {
|
||||
start_date: that.start_date,
|
||||
|
|
@ -599,13 +768,11 @@ export default {
|
|||
that.tableData10 = tableData10;
|
||||
if (tableData10.length > 0) {
|
||||
option.series = [];
|
||||
let seriesData = [],
|
||||
nameList = [];
|
||||
let nameList = [];
|
||||
tableData10.forEach((ite) => {
|
||||
if (nameList.indexOf(ite.物料名) > -1) {
|
||||
} else {
|
||||
nameList.push(ite.物料名);
|
||||
seriesData.push([]);
|
||||
let obj = {};
|
||||
obj.text = ite.物料名;
|
||||
obj.value = ite.物料名;
|
||||
|
|
@ -626,12 +793,18 @@ export default {
|
|||
that.specsFilters.push(obj3);
|
||||
}
|
||||
});
|
||||
let seriesData = [];
|
||||
let prodData = [];
|
||||
for (let i = 0; i < dateLabels.length; i++) {
|
||||
seriesData.push(new Array(nameList.length).fill(0));
|
||||
prodData.push(new Array(nameList.length).fill(0));
|
||||
}
|
||||
tableData10.forEach((item) => {
|
||||
let indexX = 0,
|
||||
indexY = 0;
|
||||
if (that.queryType == "月") {
|
||||
indexX = nameList.indexOf(item.物料名);
|
||||
indexY = item.周 - that.firstWeekNum;
|
||||
indexX = item.周 - that.firstWeekNum;
|
||||
indexY = nameList.indexOf(item.物料名);
|
||||
if(dateList.indexOf(item.周)>-1){}else{
|
||||
dateList.push(item.周);
|
||||
let obj = {};
|
||||
|
|
@ -641,27 +814,105 @@ export default {
|
|||
}
|
||||
} else {
|
||||
that.dateFilters = [1,2,3,4,5,6,7,8,9,10,11,12];
|
||||
indexX = nameList.indexOf(item.物料名);
|
||||
indexY = item.月 - 1;
|
||||
indexX = item.月 - 1;
|
||||
indexY = nameList.indexOf(item.物料名);
|
||||
}
|
||||
if(seriesData[indexX][indexY]){
|
||||
seriesData[indexX][indexY] += item.合格数;
|
||||
}else{
|
||||
seriesData[indexX][indexY] =0;
|
||||
if (indexX >= 0 && indexX < seriesData.length && indexY >= 0) {
|
||||
seriesData[indexX][indexY] += item.合格数;
|
||||
prodData[indexX][indexY] += Number(item.生产数) || 0;
|
||||
}
|
||||
});
|
||||
option.xAxis = { type: "category", data: nameList };
|
||||
option.yAxis = [
|
||||
{ type: "value" },
|
||||
{ type: "value", min: -233.33, max: 100, show: false }
|
||||
];
|
||||
option.legend = { top: 30, data: dateLabels };
|
||||
let barWidth = 10;
|
||||
let barGap = 0;
|
||||
let chartDom = document.getElementById("bachart2");
|
||||
if (chartDom) {
|
||||
chartDom.style.width = (nameList.length * dateLabels.length * 15) + "px";
|
||||
}
|
||||
for (let n = 0; n < seriesData.length; n++) {
|
||||
let obj = {};
|
||||
obj.name = nameList[n];
|
||||
obj.stack = "Ad";
|
||||
obj.name = dateLabels[n];
|
||||
obj.type = "bar";
|
||||
obj.barWidth = "15px";
|
||||
obj.barWidth = barWidth;
|
||||
obj.barGap = "0%";
|
||||
obj.data = seriesData[n];
|
||||
option.series.push(obj);
|
||||
}
|
||||
let totalSeries = seriesData.length;
|
||||
let curveData = [];
|
||||
let ratesByMat = [];
|
||||
for (let mat = 0; mat < nameList.length; mat++) {
|
||||
let rates = [];
|
||||
for (let s = 0; s < totalSeries; s++) {
|
||||
let pass = seriesData[s][mat];
|
||||
let prod = prodData[s][mat];
|
||||
rates.push(prod > 0 ? Math.round((pass / prod) * 100) : null);
|
||||
}
|
||||
curveData.push({ value: [mat].concat(rates) });
|
||||
ratesByMat.push(rates);
|
||||
}
|
||||
option.tooltip = {
|
||||
trigger: "axis",
|
||||
formatter: function (params) {
|
||||
if (!params || params.length === 0) return "";
|
||||
let cat = params[0].axisValueLabel;
|
||||
let matIdx = params[0].dataIndex;
|
||||
let rates = ratesByMat[matIdx] || [];
|
||||
let html = '<div style="font-weight:bold">' + cat + '</div>';
|
||||
let barIdx = 0;
|
||||
params.forEach(function (p) {
|
||||
if (p.seriesType !== "bar") return;
|
||||
let rate = rates[barIdx];
|
||||
let rateStr = (rate !== null && rate !== undefined) ? rate + "%" : "-";
|
||||
html += '<div>' +
|
||||
'<span style="display:inline-block;width:10px;height:10px;background:' + p.color + ';border-radius:50%;margin-right:5px;vertical-align:middle"></span>' +
|
||||
p.seriesName + ': ' + p.value + ' 合格率 ' + rateStr +
|
||||
'</div>';
|
||||
barIdx++;
|
||||
});
|
||||
return html;
|
||||
}
|
||||
};
|
||||
option.series.push({
|
||||
name: "合格率",
|
||||
type: "custom",
|
||||
xAxisIndex: 0,
|
||||
yAxisIndex: 1,
|
||||
silent: true,
|
||||
z: 5,
|
||||
data: curveData,
|
||||
renderItem: function (params, api) {
|
||||
let materialIdx = api.value(0);
|
||||
let centerX = api.coord([materialIdx, 0])[0];
|
||||
let groupWidth = totalSeries * barWidth + (totalSeries - 1) * barGap;
|
||||
let halfGroup = groupWidth / 2;
|
||||
let slotWidth = barWidth + barGap;
|
||||
let pts = [];
|
||||
for (let s = 0; s < totalSeries; s++) {
|
||||
let rate = api.value(s + 1);
|
||||
if (rate === null || rate === undefined) continue;
|
||||
let xPx = centerX - halfGroup + barWidth / 2 + s * slotWidth;
|
||||
let yPx = api.coord([0, rate])[1];
|
||||
pts.push([xPx, yPx]);
|
||||
}
|
||||
if (pts.length < 2) return null;
|
||||
return {
|
||||
type: "polyline",
|
||||
shape: { points: pts, smooth: 0.3 },
|
||||
style: { stroke: "#333", lineWidth: 1.5, fill: "none" }
|
||||
};
|
||||
}
|
||||
});
|
||||
that.setChart("bachart2", option);
|
||||
} else {
|
||||
option.xAxis.data = [];
|
||||
let chartDom = document.getElementById("bachart2");
|
||||
if (chartDom) chartDom.style.width = "100%";
|
||||
that.setChart("bachart2", option);
|
||||
}
|
||||
});
|
||||
|
|
@ -734,9 +985,8 @@ export default {
|
|||
that.end_date =that.queryDate +"-" +days;
|
||||
that.firstWeekNum = that.getWeekOfYear(year,month,1);
|
||||
that.endWeekNum = that.getWeekOfYear(year,month,days);
|
||||
let duration = that.endWeekNum - that.firstWeekNum + 1;
|
||||
let xAxisData = [];
|
||||
for (let i = 1; i <= duration; i++) {
|
||||
for (let i = that.firstWeekNum; i <= that.endWeekNum; i++) {
|
||||
xAxisData.push("第" + i + "周");
|
||||
}
|
||||
that.xAxisData = xAxisData;
|
||||
|
|
@ -828,12 +1078,17 @@ export default {
|
|||
</script>
|
||||
|
||||
<style scoped>
|
||||
.chart-scroll {
|
||||
width: 100%;
|
||||
overflow-x: auto;
|
||||
}
|
||||
#bachart1,
|
||||
#bachart2,
|
||||
#bachart3,
|
||||
#bachart4 {
|
||||
width: 100%;
|
||||
height: 300px;
|
||||
min-width: 100%;
|
||||
height: 500px;
|
||||
}
|
||||
.tables {
|
||||
position: absolute;
|
||||
|
|
|
|||
|
|
@ -40,7 +40,9 @@
|
|||
<el-row :gutter="10">
|
||||
<el-col :lg="12">
|
||||
<el-card shadow="never">
|
||||
<scEcharts id="bachart1" height="300px" :option="option"></scEcharts>
|
||||
<div class="echarts-scroll">
|
||||
<scEcharts ref="echarts1" id="bachart1" height="300px" :option="option"></scEcharts>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :lg="12">
|
||||
|
|
@ -128,9 +130,21 @@ export default {
|
|||
type: "category",
|
||||
data: [],
|
||||
},
|
||||
yAxis: {
|
||||
yAxis: [
|
||||
{
|
||||
type: "value",
|
||||
name: "数量",
|
||||
},
|
||||
{
|
||||
type: "value",
|
||||
name: "合格率",
|
||||
min: 0,
|
||||
max: 100,
|
||||
axisLabel: {
|
||||
formatter: "{value}%",
|
||||
},
|
||||
},
|
||||
],
|
||||
series: [],
|
||||
},
|
||||
nameFilters: [],
|
||||
|
|
@ -189,48 +203,92 @@ export default {
|
|||
obj.query.order_bys_date = ", 月";
|
||||
}
|
||||
let xAxisData = [],nameData=[],seriesData=[];
|
||||
let colorPalette = ['#5470c6', '#91cc75', '#fac858', '#ee6666', '#73c0de', '#3ba272', '#fc8452', '#9a60b4', '#ea7ccc'];
|
||||
that.$API.bi.dataset.exec.req("lineWeek", obj).then((res) => {
|
||||
let data = res.data2.ds0;
|
||||
that.tableData = data;
|
||||
data.forEach((item) => {
|
||||
if (xAxisData.indexOf(item.工段) > -1) {
|
||||
} else {
|
||||
if (xAxisData.indexOf(item.工段) === -1) {
|
||||
xAxisData.push(item.工段);
|
||||
let obj = {};
|
||||
obj.text = item.工段;
|
||||
obj.value = item.工段;
|
||||
that.mgroupFilters.push(obj);
|
||||
that.mgroupFilters.push({ text: item.工段, value: item.工段 });
|
||||
}
|
||||
if (nameData.indexOf(item.物料名) > -1) {
|
||||
} else {
|
||||
let obj0 = {};
|
||||
obj0.text = item.物料名;
|
||||
obj0.value = item.物料名;
|
||||
that.nameFilters.push(obj0);
|
||||
if (nameData.indexOf(item.物料名) === -1) {
|
||||
nameData.push(item.物料名);
|
||||
let obj = {
|
||||
name:'',
|
||||
that.nameFilters.push({ text: item.物料名, value: item.物料名 });
|
||||
}
|
||||
});
|
||||
nameData.forEach((materialName, idx) => {
|
||||
let color = colorPalette[idx % colorPalette.length];
|
||||
let barData = xAxisData.map((mgroup) => {
|
||||
let qualified = 0;
|
||||
data.forEach((item) => {
|
||||
if (item.工段 === mgroup && item.物料名 === materialName) {
|
||||
qualified += Number(item.合格数) || 0;
|
||||
}
|
||||
});
|
||||
return qualified;
|
||||
});
|
||||
let passRateData = xAxisData.map((mgroup) => {
|
||||
let qualified = 0;
|
||||
let produced = 0;
|
||||
data.forEach((item) => {
|
||||
if (item.工段 === mgroup && item.物料名 === materialName) {
|
||||
qualified += Number(item.合格数) || 0;
|
||||
produced += Number(item.生产数) || 0;
|
||||
}
|
||||
});
|
||||
return produced > 0
|
||||
? Number(((qualified / produced) * 100).toFixed(2))
|
||||
: null;
|
||||
});
|
||||
seriesData.push({
|
||||
name: materialName,
|
||||
type: "bar",
|
||||
yAxisIndex: 0,
|
||||
itemStyle: { color },
|
||||
label: {
|
||||
show: true,
|
||||
position: "top",
|
||||
formatter: "{c}",
|
||||
color: "rgb(64,158,255)",
|
||||
color: color,
|
||||
},
|
||||
barWidth: "15px",
|
||||
data:[0, 0, 0, 0, 0, 0, 0, 0],
|
||||
};
|
||||
obj.name=item.物料名,
|
||||
seriesData.push(obj);
|
||||
}
|
||||
let index = xAxisData.indexOf(item.工段);
|
||||
let indexY = nameData.indexOf(item.物料名);
|
||||
seriesData[indexY].data[index] += item.合格数;
|
||||
data: barData,
|
||||
});
|
||||
seriesData.push({
|
||||
name: materialName + " 合格率",
|
||||
type: "line",
|
||||
yAxisIndex: 1,
|
||||
smooth: true,
|
||||
data: passRateData,
|
||||
label: {
|
||||
show: true,
|
||||
position: "top",
|
||||
formatter: "{c}%",
|
||||
color: color,
|
||||
},
|
||||
lineStyle: { color },
|
||||
itemStyle: { color },
|
||||
});
|
||||
});
|
||||
that.xAxisData = xAxisData;
|
||||
that.option.xAxis.data = that.xAxisData;
|
||||
that.option.series = seriesData;
|
||||
that.$nextTick(() => {
|
||||
that.resizeChart(xAxisData.length, nameData.length);
|
||||
});
|
||||
});
|
||||
},
|
||||
resizeChart(xCount, materialCount) {
|
||||
let chartDiv = document.getElementById("bachart1");
|
||||
if (!chartDiv) return;
|
||||
let wrapper = chartDiv.parentElement;
|
||||
let parentWidth = wrapper.clientWidth;
|
||||
let groupWidth = Math.max(60, materialCount * 25 + 30);
|
||||
let neededWidth = xCount * groupWidth + 80;
|
||||
chartDiv.style.width = Math.max(parentWidth, neededWidth) + "px";
|
||||
let inst = this.$refs.echarts1 && this.$refs.echarts1.myChart;
|
||||
if (inst) inst.resize();
|
||||
},
|
||||
handleQuery() {
|
||||
if (this.queryDate !== "" && this.queryDate !== null) {
|
||||
|
|
@ -313,4 +371,12 @@ export default {
|
|||
left: 4px;
|
||||
z-index: 10;
|
||||
}
|
||||
.echarts-scroll {
|
||||
width: 100%;
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
}
|
||||
.echarts-scroll > :deep(#bachart1) {
|
||||
min-width: 100%;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@
|
|||
:filter-method="filterModel1" filter-placement="bottom-end" />
|
||||
<el-table-column label="规格" prop="material_specification" :filters="specsFilters1"
|
||||
:filter-method="filterSpecs1" filter-placement="bottom-end" />
|
||||
<el-table-column prop="dept_name" label="完成车间" :filters="deptFilters1"
|
||||
<el-table-column prop="dept_name" label="所在车间/仓库" :filters="deptFilters1"
|
||||
:filter-method="filterDept1" filter-placement="bottom-end" />
|
||||
<el-table-column label="库存合格品数" prop="count" />
|
||||
</scTable>
|
||||
|
|
|
|||
|
|
@ -540,7 +540,7 @@ export default {
|
|||
let that = this;
|
||||
var req = {
|
||||
page: 0,
|
||||
state:10,
|
||||
state__in:'10,34',
|
||||
tag:that.tag,
|
||||
mgroupx:that.mgroupId
|
||||
};
|
||||
|
|
@ -556,6 +556,7 @@ export default {
|
|||
let that = this;
|
||||
that.materialOptions = [];
|
||||
var req = {
|
||||
tag:that.tag,
|
||||
mgroupx: that.mgroupId,
|
||||
page: 0
|
||||
};
|
||||
|
|
@ -665,7 +666,16 @@ export default {
|
|||
});
|
||||
},
|
||||
addMaterial(){
|
||||
this.addShow = true;
|
||||
let that = this;
|
||||
that.addShow = true;
|
||||
// 将已扫板段对应的批次预填入多选,避免手动添加把扫描数据顶掉
|
||||
if(that.form.handoverb && that.form.handoverb.length > 0){
|
||||
that.form.handoverb.forEach(item => {
|
||||
if(item.wm && that.selectItems.indexOf(item.wm) === -1){
|
||||
that.selectItems.push(item.wm);
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
delMaterial(index){
|
||||
this.selectItems.splice(index,1);
|
||||
|
|
@ -715,6 +725,15 @@ export default {
|
|||
},
|
||||
materialChange() {
|
||||
let that = this;
|
||||
// shangpaipingmo:先缓存已扫板段数据,重建后保留
|
||||
let scannedMap = {};
|
||||
if(that.route_code == 'shangpaipingmo'){
|
||||
(that.form.handoverb || []).forEach(h => {
|
||||
if(h.wm && h.handoverbw && h.handoverbw.length > 0){
|
||||
scannedMap[h.wm] = h;
|
||||
}
|
||||
});
|
||||
}
|
||||
that.form.new_batch = that.route_code=='shangpaipingmo'?that.form.new_batch:"";
|
||||
let totalCount = 0,data = [];
|
||||
if(that.selectItems.length>0){
|
||||
|
|
@ -755,15 +774,31 @@ export default {
|
|||
}
|
||||
data.forEach((item,index)=>{
|
||||
item.wm = item.id;
|
||||
item.count = item.count_canhandover;
|
||||
totalCount += Number(item.count_canhandover);
|
||||
item.tracking = item.material_.tracking;
|
||||
if(item.material_.process_name){
|
||||
item.process = item.material_.process_name;
|
||||
}
|
||||
let scanned = scannedMap[item.id];
|
||||
if(scanned){
|
||||
// 保留已扫板段的 handoverbw 和数量
|
||||
item.handoverbw = scanned.handoverbw;
|
||||
item.count = scanned.count;
|
||||
totalCount += Number(scanned.count);
|
||||
} else {
|
||||
item.count = item.count_canhandover;
|
||||
totalCount += Number(item.count_canhandover);
|
||||
item.handoverbw = [];
|
||||
that.getWprList(item.id,index);
|
||||
}
|
||||
})
|
||||
// 同步 checkedStatus:全选状态由各批次 handoverbw 实际勾选情况决定
|
||||
that.checkedStatus = data.map(item => {
|
||||
let scanned = scannedMap[item.id];
|
||||
if(scanned && scanned.handoverbw && scanned.handoverbw.length > 0){
|
||||
return scanned.handoverbw.every(w => w.checked !== false);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
that.totalCount = totalCount;
|
||||
that.form.handoverb = data;
|
||||
|
|
@ -1049,16 +1084,22 @@ export default {
|
|||
let obj1 = {};
|
||||
obj1.wpr = res[0].id;
|
||||
obj1.number = res[0].number;
|
||||
obj1.checked = true;
|
||||
that.form.handoverb[indexs].count+=1;
|
||||
that.form.handoverb[indexs].handoverbw.push(obj1);
|
||||
that.checkedStatus.push(true)
|
||||
that.selectItems.push(res[0].id)
|
||||
}
|
||||
}else{
|
||||
that.form.handoverb[indexs].handoverbw = [];
|
||||
let obj1 = {};
|
||||
obj1.wpr = res[0].id;
|
||||
obj1.checked = true;
|
||||
obj1.number = res[0].number;
|
||||
that.form.handoverb[indexs].count=1;
|
||||
that.form.handoverb[indexs].handoverbw.push(obj1);
|
||||
that.checkedStatus.push(true)
|
||||
that.selectItems.push(res[0].id)
|
||||
}
|
||||
}else{//handoverb里没有有这个物料批次
|
||||
if(that.new_wm==''){
|
||||
|
|
@ -1082,9 +1123,12 @@ export default {
|
|||
obj2.count = 1;
|
||||
let obj3 = {};
|
||||
obj3.wpr = res[0].id;
|
||||
obj3.checked = true;
|
||||
obj3.number = res[0].number;
|
||||
obj2.handoverbw.push(obj3);
|
||||
that.form.handoverb.push(obj2);
|
||||
that.checkedStatus.push(true)
|
||||
that.selectItems.push(res[0].id)
|
||||
}
|
||||
})
|
||||
}else{
|
||||
|
|
@ -1097,9 +1141,12 @@ export default {
|
|||
obj2.count = 1;
|
||||
let obj3 = {};
|
||||
obj3.wpr = res[0].id;
|
||||
obj3.checked = true;
|
||||
obj3.number = res[0].number;
|
||||
obj2.handoverbw.push(obj3);
|
||||
that.form.handoverb.push(obj2);
|
||||
that.checkedStatus.push(true)
|
||||
that.selectItems.push(res[0].id)
|
||||
}
|
||||
}
|
||||
}else{
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
<div class="left-panel">
|
||||
<el-button type="primary" @click="tomio('do_out')" v-auth="'mio.do'" v-if="route_code=='qingxi'">领料</el-button>
|
||||
<el-button type="primary" v-auth="'wmaterial.create'" @click="table_create()">来料</el-button>
|
||||
<el-button type="primary" v-auth="'handover.create'" @click="table_add(40)">报废</el-button>
|
||||
<el-button type="primary" v-auth="'handover.create'" @click="table_add(40,'todo')">报废</el-button>
|
||||
<el-button type="primary" v-auth="'handover.create'" @click="batchConcat()">合批</el-button>
|
||||
</div>
|
||||
<div class="right-panel">
|
||||
|
|
@ -512,9 +512,10 @@ export default {
|
|||
}
|
||||
},
|
||||
//添加报废
|
||||
table_add(type) {
|
||||
table_add(type,tag) {
|
||||
this.dialog.scrap = true;
|
||||
this.type = type;
|
||||
this.tag = tag;
|
||||
this.$nextTick(() => {
|
||||
this.$refs.scrapDialog.open("add");
|
||||
});
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
<el-header>
|
||||
<div class="left-panel">
|
||||
<el-button type="primary" @click="tomio('do_out')" v-auth="'mio.do'" v-if="route_code=='qingxi'">领料</el-button>
|
||||
<el-button type="primary" v-auth="'handover.create'" @click="table_add(40)">报废</el-button>
|
||||
<el-button type="primary" v-auth="'handover.create'" @click="table_add(40,'done')">报废</el-button>
|
||||
<el-button type="primary" v-auth="'handover.create'" @click="batchConcat()">合批</el-button>
|
||||
<el-button type="primary" @click="tomio('do_in')" v-auth="'mio.doin'">入库</el-button>
|
||||
</div>
|
||||
|
|
@ -255,6 +255,7 @@
|
|||
v-if="dialog.scrap"
|
||||
ref="scrapDialog"
|
||||
:type="type"
|
||||
:tag="tag"
|
||||
:wmItem="wmItem"
|
||||
:mgroupName="mgroup_name"
|
||||
:mgroupId="mgroupId"
|
||||
|
|
@ -501,9 +502,10 @@ export default {
|
|||
}
|
||||
},
|
||||
//添加报废
|
||||
table_add(type) {
|
||||
table_add(type,tag) {
|
||||
this.dialog.scrap = true;
|
||||
this.type = type;
|
||||
this.tag = tag;
|
||||
this.$nextTick(() => {
|
||||
this.$refs.scrapDialog.open("add");
|
||||
});
|
||||
|
|
|
|||
|
|
@ -364,7 +364,13 @@
|
|||
</scTable>
|
||||
</el-card>
|
||||
<!-- 输出物料 输出物料追踪类型为单个-->
|
||||
<el-card v-else style="width: 100%;margin-bottom:1vh" header="输出物料" shadow="never">
|
||||
<el-card v-else style="width: 100%;margin-bottom:1vh" shadow="never">
|
||||
<template #header>
|
||||
<div style="display:flex;align-items:center;justify-content:space-between;">
|
||||
<span>输出物料</span>
|
||||
<el-button size="small" v-if="checkTableShow" @click="$refs.checkTable.openColumnSetting()">列设置</el-button>
|
||||
</div>
|
||||
</template>
|
||||
<check-table
|
||||
v-if="checkTableShow"
|
||||
ref="checkTable"
|
||||
|
|
@ -386,6 +392,7 @@
|
|||
style="width: 100%;height: 500px;"
|
||||
></check-table>
|
||||
</el-card>
|
||||
<div style="height: 100px;"></div>
|
||||
<save-dialog
|
||||
v-if="dialog.save"
|
||||
ref="saveDialog"
|
||||
|
|
@ -670,11 +677,18 @@ export default {
|
|||
}
|
||||
that.materialIn = res.material_in!==null?res.material_in:res.mlogb_full[0]?res.mlogb_full[0].material_in:null;
|
||||
that.deptId = res.belong_dept;
|
||||
that.checkTableShow = true;
|
||||
that.apiObjWm = that.$API.wpm.wmaterial.list;
|
||||
that.$API.wpm.mlogb.list.req(that.paramsOut).then((res) => {
|
||||
that.tableData2 = res;
|
||||
if(res.qct!==null){
|
||||
that.checkTableShow = true;
|
||||
}else{
|
||||
that.$API.wpm.mlogb.list.req(that.paramsOut).then((res_out) => {
|
||||
that.tableData2 = res_out;
|
||||
if(res.is_fix&&res_out[0].qct!==null){
|
||||
that.mlogItem.qct = res_out[0].qct;
|
||||
}
|
||||
that.checkTableShow = true;
|
||||
})
|
||||
}
|
||||
if(!res.is_fix){
|
||||
that.getcutCount(res.material_in);
|
||||
that.$API.mtm.routepack.list.req({page:0,search:res.routepack_name}).then((res) => {
|
||||
|
|
@ -700,8 +714,13 @@ export default {
|
|||
},
|
||||
getEquipment(){
|
||||
let that = this;
|
||||
that.equipmentOtions = [];
|
||||
that.$API.em.equipment.list.req({page:0,belong_dept:that.dept}).then((res) => {
|
||||
that.equipmentOtions = res;
|
||||
res.forEach((item) => {
|
||||
if(item.cate_name!=="工装"||item.cate_name==null){
|
||||
that.equipmentOtions.push(item);
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
//获取指定工序的切分数量
|
||||
|
|
|
|||
|
|
@ -7,8 +7,7 @@
|
|||
destroy-on-close
|
||||
@closed="$emit('closed')"
|
||||
>
|
||||
<el-container v-loading="loading">
|
||||
<el-main style="padding: 0">
|
||||
<el-container v-loading="loading" style="background: none;">
|
||||
<el-form
|
||||
ref="dialogForm"
|
||||
:model="form"
|
||||
|
|
@ -115,7 +114,6 @@
|
|||
<el-button type="primary" :loading="isSaveing" @click="submit">提交</el-button>
|
||||
<el-button @click="visible = false">取消</el-button>
|
||||
</el-footer>
|
||||
</el-main>
|
||||
</el-container>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -620,6 +620,13 @@ export default {
|
|||
that.testitems.push(obj)
|
||||
}
|
||||
})
|
||||
res.qct_defects.forEach((item) => {
|
||||
that.addTemplate[item.defect_name] = false;
|
||||
let obj = Object.assign({}, item);
|
||||
obj.canEdit = that.processType=='20'?false:true;
|
||||
that.qct_defects.push(obj);
|
||||
})
|
||||
that.qct_defects_origin = that.qct_defects;
|
||||
that.getList();
|
||||
});
|
||||
},
|
||||
|
|
|
|||
|
|
@ -22,8 +22,9 @@
|
|||
<el-button type="primary" v-if="!isSubmit&&processType=='20'" @click="check_start">检验</el-button>
|
||||
<el-button type="primary" v-if="multipleSet" @click="check_set" style="position: absolute;left: 210px;">批量操作</el-button>
|
||||
<el-input v-if="multipleSet" v-model="wprInputText" @change="wprinputChange" style="width:200px;position: absolute;left: 308px;"></el-input>
|
||||
<div style="width:fit-content;position: absolute;right: 40px;display: inline-block;">
|
||||
<div style="display: flex;">
|
||||
<el-button v-if="!isSubmit" type="success" @click="digital ">数字识别</el-button>
|
||||
<div style="width:fit-content;position: absolute;right: 0;display: inline-block;">
|
||||
<div style="display: flex;align-items: center;gap: 8px;">
|
||||
<el-link v-if="test_file!==''" :href="test_file" target="_blank">{{ test_file_name }}</el-linK>
|
||||
<scFileImport
|
||||
v-if="project_code=='tcerp'&&processType=='20'&&!isSubmit"
|
||||
|
|
@ -34,6 +35,14 @@
|
|||
></scFileImport><!-- :templateUrl="checkTemplate" -->
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="columnSettingVisible" class="col-setting-float-panel" @click.stop>
|
||||
<div v-for="col in allColumnOptions" :key="col.key" class="col-setting-item">
|
||||
<el-checkbox
|
||||
:model-value="isColVisible(col.key)"
|
||||
@change="toggleColumn(col.key)"
|
||||
>{{ col.label }}</el-checkbox>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-scroll">
|
||||
<table id="mlogbwlist" class="tables">
|
||||
|
|
@ -45,11 +54,15 @@
|
|||
<th class="w_50 sticky-cell sticky-left-index">序号</th>
|
||||
<th class="w_140 sticky-cell sticky-left-batch">物料批次</th>
|
||||
<th class="w_140 sticky-cell sticky-left-number">物料编号</th>
|
||||
<th class="w_150" v-if="route_code=='niuzhuan'">生产设备</th>
|
||||
<th class="w_180" v-if="route_code=='niuzhuan'">扭转日期</th>
|
||||
<th class="w_80" v-for="item in qct_testitems" :key="item.id">{{ item.testitem_name }}</th>
|
||||
<th class="w_80" v-for="item in qct_defects" :key="item.id">{{ item.defect_name }}</th>
|
||||
<th class="w_80">备注</th>
|
||||
<th class="w_150" v-if="route_code=='niuzhuan'" v-show="isColVisible('equip')">生产设备</th>
|
||||
<th class="w_180" v-if="route_code=='niuzhuan'" v-show="isColVisible('time')">扭转日期</th>
|
||||
<th class="w_150" v-if="mgroupName=='喷码'" v-show="isColVisible('tooling')">工装</th>
|
||||
<th class="w_80" v-for="item in qct_testitems" :key="item.id" v-show="isColVisible('testitem_'+item.id)">{{ item.testitem_name }}</th>
|
||||
<th class="w_80" v-for="item in qct_defects" :key="item.id" v-show="isColVisible('defect_'+item.id)">
|
||||
{{ item.defect_name }}
|
||||
<span style="color:#f56c6c;">{{ getDefectCount(item.defect_name) }}</span>
|
||||
</th>
|
||||
<th class="w_80" v-show="isColVisible('note')">备注</th>
|
||||
<th class="w_150 sticky-cell sticky-right-action" v-if="!isSubmit">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
|
@ -70,7 +83,7 @@
|
|||
<span v-else>{{ row.number }}</span>
|
||||
<span v-if="row.wpr_number_out !== null && row.wpr_number_out !== undefined">——{{ row.wpr_number_out }}</span>
|
||||
</td>
|
||||
<td class="w_150 " v-if="route_code=='niuzhuan'">
|
||||
<td class="w_150 " v-if="route_code=='niuzhuan'" v-show="isColVisible('equip')">
|
||||
<select name="pets" id="pet-select" v-if="row.isEdit" style="width: 100%;" v-model="row.equip" :value="row.equip">
|
||||
<option v-for="item in optionsEq" :key="item.id" :value="item.id">
|
||||
{{ item.number }}
|
||||
|
|
@ -78,13 +91,21 @@
|
|||
</select>
|
||||
<span v-else>{{ row.equip_name }}<span v-if="row.equip_number&&row.equip_number!=null">{{ row.equip_number }}</span></span>
|
||||
</td>
|
||||
<td class="w_180 " v-if="route_code=='niuzhuan'">
|
||||
<td class="w_180 " v-if="route_code=='niuzhuan'" v-show="isColVisible('time')">
|
||||
<input v-if="row.isEdit" type="datetime-local" id="datetime" v-model="row.work_start_time" @change = "timeChange(row)">
|
||||
<div v-else>
|
||||
<span v-if="row.work_start_time!==null">{{ row.work_start_time}}</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="w_80 " v-for="item in qct_testitems" :key="item.id">
|
||||
<td class="w_150 " v-if="mgroupName=='喷码'" v-show="isColVisible('tooling')">
|
||||
<select name="tooling" id="tooling-select" v-if="row.isEdit" style="width: 100%;" v-model="row.tooling" :value="row.tooling">
|
||||
<option v-for="item in optionsTooling" :key="item.id" :value="item.id">
|
||||
{{ item.name }}
|
||||
</option>
|
||||
</select>
|
||||
<span v-else>{{ getToolingName(row.wpr_pre_info?.tooling) || row.tooling_name }}</span>
|
||||
</td>
|
||||
<td class="w_80 " v-for="item in qct_testitems" :key="item.id" v-show="isColVisible('testitem_'+item.id)">
|
||||
<span v-if="!row.isEdit || !item.canEdit">{{ row[item.testitem_name] }}</span>
|
||||
<input v-if="item.testitem_field_type == 'input-number' && row.isEdit && item.canEdit"
|
||||
type="number" v-model="row[item.testitem_name]" @change="defectCountSun(row)">
|
||||
|
|
@ -101,10 +122,10 @@
|
|||
<option v-for="item0 in item.testitem_choices" :key="item0" :value="item0">{{ item0 }}</option>
|
||||
</select>
|
||||
</td>
|
||||
<td class="w_80 padding_4 defectBlock" v-for="item in qct_defects" :key="item.id">
|
||||
<td class="w_80 padding_4 defectBlock" v-for="item in qct_defects" :key="item.id" v-show="isColVisible('defect_'+item.id)">
|
||||
<input type="checkbox" class="checkboxInput" :disabled="!row.isEdit || !item.canEdit" v-model="row[item.defect_name]" @change="switchChange(row, item,index)">
|
||||
</td>
|
||||
<td class="w_80 ">
|
||||
<td class="w_80 " v-show="isColVisible('note')">
|
||||
<input v-if="row.isEdit" v-model="row.note" placeholder="备注">
|
||||
<span v-else style="width: 100%;height: 100%;display: inline-block;">{{ row.note }}</span>
|
||||
</td>
|
||||
|
|
@ -394,10 +415,15 @@ export default {
|
|||
wprInputText:"",
|
||||
project_code:"",
|
||||
test_file_name:"",
|
||||
ocr_ip:"",
|
||||
ocr_port:"",
|
||||
ocr_unit:"",
|
||||
canMultiple:false,
|
||||
selectedAll:false,
|
||||
checkAll: false,
|
||||
hideAdd: false,
|
||||
hiddenColumns: [],
|
||||
columnSettingVisible: false,
|
||||
visible: false,
|
||||
isSaveing:false,
|
||||
setVisible:false,
|
||||
|
|
@ -432,6 +458,7 @@ export default {
|
|||
|
||||
},
|
||||
optionsEq:[],
|
||||
optionsTooling:[],
|
||||
defectlists:[],
|
||||
testitemlists:[],
|
||||
selectWprList:[],
|
||||
|
|
@ -445,6 +472,26 @@ export default {
|
|||
};
|
||||
},
|
||||
watch: {},
|
||||
computed: {
|
||||
allColumnOptions() {
|
||||
const cols = [];
|
||||
if (this.route_code === 'niuzhuan') {
|
||||
cols.push({ key: 'equip', label: '生产设备' });
|
||||
cols.push({ key: 'time', label: '扭转日期' });
|
||||
}
|
||||
if (this.mgroupName === '喷码') {
|
||||
cols.push({ key: 'tooling', label: '工装' });
|
||||
}
|
||||
this.qct_testitems.forEach(item => {
|
||||
cols.push({ key: 'testitem_' + item.id, label: item.testitem_name });
|
||||
});
|
||||
this.qct_defects.forEach(item => {
|
||||
cols.push({ key: 'defect_' + item.id, label: item.defect_name });
|
||||
});
|
||||
cols.push({ key: 'note', label: '备注' });
|
||||
return cols;
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
let that = this;
|
||||
if(that.test_file!==''&&that.test_file!==null){
|
||||
|
|
@ -460,6 +507,9 @@ export default {
|
|||
if(that.route_code=='niuzhuan'){
|
||||
that.getEquipment4();
|
||||
}
|
||||
if(that.mgroupName=='喷码'){
|
||||
that.getToolings();
|
||||
}
|
||||
if(that.qct!==''&&that.qct!==null){//输出
|
||||
that.getdefects();
|
||||
}else{
|
||||
|
|
@ -486,6 +536,8 @@ export default {
|
|||
}).catch(()=>{
|
||||
that.getList();
|
||||
})
|
||||
}else{
|
||||
that.getList();
|
||||
}
|
||||
}
|
||||
that.visible = true;
|
||||
|
|
@ -494,6 +546,9 @@ export default {
|
|||
},500)
|
||||
that.actionMenuClickHandler = (event) => that.handleDocumentClick(event);
|
||||
document.addEventListener("click", that.actionMenuClickHandler, true);
|
||||
that.ocr_ip = localStorage.getItem("ocr_ip") || "";
|
||||
that.ocr_port = localStorage.getItem("ocr_port") || "";
|
||||
that.ocr_unit = localStorage.getItem("ocr_unit") || "";
|
||||
|
||||
},
|
||||
beforeUnmount() {
|
||||
|
|
@ -502,6 +557,17 @@ export default {
|
|||
}
|
||||
},
|
||||
methods: {
|
||||
isColVisible(key) {
|
||||
return !this.hiddenColumns.includes(key);
|
||||
},
|
||||
toggleColumn(key) {
|
||||
const idx = this.hiddenColumns.indexOf(key);
|
||||
if (idx > -1) {
|
||||
this.hiddenColumns.splice(idx, 1);
|
||||
} else {
|
||||
this.hiddenColumns.push(key);
|
||||
}
|
||||
},
|
||||
refreshfun(){
|
||||
this.getList();
|
||||
},
|
||||
|
|
@ -515,7 +581,14 @@ export default {
|
|||
if (event.target && event.target.closest(".action-more")) {
|
||||
return;
|
||||
}
|
||||
if (event.target && event.target.closest(".col-setting-float-panel")) {
|
||||
return;
|
||||
}
|
||||
this.openedActionMenu = null;
|
||||
this.columnSettingVisible = false;
|
||||
},
|
||||
openColumnSetting() {
|
||||
this.columnSettingVisible = !this.columnSettingVisible;
|
||||
},
|
||||
check_add(){
|
||||
let that = this;
|
||||
|
|
@ -551,6 +624,31 @@ export default {
|
|||
that.optionsEq = res.reverse();
|
||||
})
|
||||
},
|
||||
getToolings() {
|
||||
let that = this;
|
||||
that.$API.em.equipment.list.req({page:0,type:10,cate__code:"7",query:"{id,name,number}"}).then((res) => {
|
||||
that.optionsTooling = Array.isArray(res) ? res : (res.results || []);
|
||||
})
|
||||
},
|
||||
getToolingName(id) {
|
||||
if (!id) return '';
|
||||
const item = this.optionsTooling.find(t => t.id == id);
|
||||
return item ? item.name : id;
|
||||
},
|
||||
autoSyncTooling() {
|
||||
const that = this;
|
||||
if (that.mgroupName !== '喷码') return;
|
||||
that.mlogbwlist.forEach((row) => {
|
||||
const wprTooling = row.wpr_pre_info?.tooling;
|
||||
if (wprTooling && row.tooling != wprTooling && row.id) {
|
||||
that.$API.wpm.mlogbw.update.req(row.id, { tooling: wprTooling,number:row.number,mlogb:row.mlogb }).then((res) => {
|
||||
row.tooling = res.tooling;
|
||||
row.tooling_name = res.tooling_name;
|
||||
row.tooling_number = res.tooling_number;
|
||||
}).catch(() => {});
|
||||
}
|
||||
});
|
||||
},
|
||||
getEquipments(){
|
||||
let that = this;
|
||||
that.$API.em.equipment.list.req({page:0,cate__code:"6"}).then((res) => {
|
||||
|
|
@ -608,7 +706,6 @@ export default {
|
|||
},
|
||||
timeChange(row){
|
||||
let that = this;
|
||||
console.log('row',row)
|
||||
let index = that.mlogbwlist.indexOf(row);
|
||||
if(row.work_start_time!==''&&row.work_start_time!==null&&row.work_start_time!==undefined){
|
||||
let waveNum = 1;
|
||||
|
|
@ -690,6 +787,9 @@ export default {
|
|||
that.mlogbwlist.push(obj);
|
||||
})
|
||||
}
|
||||
that.$nextTick(() => {
|
||||
that.autoSyncTooling();
|
||||
});
|
||||
})
|
||||
},
|
||||
widthFun(item){
|
||||
|
|
@ -719,6 +819,9 @@ export default {
|
|||
if(row.equip){
|
||||
obj.equip = row.equip;
|
||||
}
|
||||
if(row.tooling){
|
||||
obj.tooling = row.tooling;
|
||||
}
|
||||
//qct不为空,有检验表
|
||||
if((that.qct!==''&&that.qct!==null)||(that.qctId!==''&&that.qctId!==null)){
|
||||
obj.ftest = {};
|
||||
|
|
@ -762,6 +865,8 @@ export default {
|
|||
that.mlogbwlist[editIndex].isEdit = false;
|
||||
that.mlogbwlist[editIndex].equip_name = res.equip_name;
|
||||
that.mlogbwlist[editIndex].equip_number = res.equip_number;
|
||||
that.mlogbwlist[editIndex].tooling_name = res.tooling_name;
|
||||
that.mlogbwlist[editIndex].tooling_number = res.tooling_number;
|
||||
that.mlogbwlist[editIndex].work_start_time = res.work_start_time;
|
||||
// that.getList();
|
||||
return res;
|
||||
|
|
@ -778,6 +883,8 @@ export default {
|
|||
that.mlogbwlist[editIndex].isEdit = false;
|
||||
that.mlogbwlist[editIndex].equip_name = res.equip_name;
|
||||
that.mlogbwlist[editIndex].equip_number = res.equip_number;
|
||||
that.mlogbwlist[editIndex].tooling_name = res.tooling_name;
|
||||
that.mlogbwlist[editIndex].tooling_number = res.tooling_number;
|
||||
that.mlogbwlist[editIndex].work_start_time = res.work_start_time;
|
||||
// that.getList();
|
||||
return res;
|
||||
|
|
@ -796,6 +903,12 @@ export default {
|
|||
formTableEdit(index) {
|
||||
let that = this;
|
||||
that.mlogbwlist[index].isEdit = true;
|
||||
if(that.mgroupName=='喷码'){
|
||||
const wprTooling = that.mlogbwlist[index].wpr_pre_info?.tooling;
|
||||
if(wprTooling && that.mlogbwlist[index].tooling != wprTooling){
|
||||
that.mlogbwlist[index].tooling = wprTooling;
|
||||
}
|
||||
}
|
||||
let date = new Date();
|
||||
if(that.mlogbwlist[index].work_start_time==''||that.mlogbwlist[index].work_start_time==null){
|
||||
that.mlogbwlist[index].work_start_time = that.$TOOL.dateFormat(date, 'yyyy-MM-dd hh:mm:ss');
|
||||
|
|
@ -1013,6 +1126,93 @@ that.$API.wpm.prints.req(printer_ip, obj).then((response) => {
|
|||
that.wprNumber = "";
|
||||
that.setVisible=true;
|
||||
},
|
||||
|
||||
|
||||
//扫描这里更新:添加数字化识别,调用一个接口,并且返回number和设备数据,然后根据number将这一行放到第一行并编辑这一行,并且把设备数据放到对应位置
|
||||
digital(){
|
||||
let that = this;
|
||||
//第一步:调用接口获取数字识别设备返回的number
|
||||
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.mlogbwlist.forEach((item,index) => {
|
||||
if(item.number==res.char){
|
||||
let obj = Object.assign({},item);S
|
||||
obj.isEdit = true;
|
||||
that.mlogbwlist.splice(index,1);
|
||||
that.wprInputText = "";
|
||||
that.mlogbwlist.unshift(obj);
|
||||
that.$nextTick(() => {
|
||||
that.selectedindexes.push(obj.id);
|
||||
that.selectWprList.push(item);
|
||||
})
|
||||
//第二步:获取投影仪设备的监测数据
|
||||
//先判断是否有需要检测设备的检测项,若有,赋值,若无,跳过
|
||||
if(that.qct_testitems.length>0 && !!that.setForm.cd_req_addr){
|
||||
that.$API.em.cd.req({method:that.setForm.cd_req_addr}).then((res) => {
|
||||
that.qct_testitems.forEach(item0 => {
|
||||
if(item0.testitem_cd_expr!=null){
|
||||
that.mlogbwlist[0][item0.testitem_name]= eval(item0.testitem_cd_expr);
|
||||
item0.cd_expr = true;
|
||||
that.qct_defects.forEach(item => {
|
||||
if(item.rule_expression!==''&&item.rule_expression!==undefined&&item.rule_expression!==null){
|
||||
let str = item.rule_expression.replace(/`/g, '');
|
||||
str = str.replace(/\${(.*?)}/g, 'row.\$1');
|
||||
let judge = false;
|
||||
try {
|
||||
judge = eval(str);
|
||||
that.mlogbwlist[0][item.defect_name] = judge;
|
||||
}catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
}else{
|
||||
that.mlogbwlist[0][item.defect_name] = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
})
|
||||
let arrs= that.qct_testitems.filter(item => item.testitem_cd_expr!=null)
|
||||
if(arrs.length>0){
|
||||
that.seveAuto(0);
|
||||
}
|
||||
}).catch((err) => {
|
||||
this.$notify.error({
|
||||
title: '获取数据失败',
|
||||
message: err.data
|
||||
})
|
||||
return err;
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}).catch((err) => {
|
||||
that.$notify.error({
|
||||
title: '数字识别获取失败',
|
||||
message: err.data
|
||||
})
|
||||
return err;
|
||||
});
|
||||
},
|
||||
seveAuto(index){
|
||||
let that= this;
|
||||
let arr2 = that.mlogbwlist.filter(item => item.cd_expr==true);
|
||||
if(arr2.length>0){
|
||||
that.formTableSave(that.mlogbwlist[index],index);
|
||||
}else{
|
||||
setTimeout(() => {
|
||||
that.seveAuto(index);
|
||||
}, 500);
|
||||
}
|
||||
},
|
||||
|
||||
//扫描物料将这一行放到第一行并编辑这一行
|
||||
wprinputChange(){
|
||||
let that = this;
|
||||
|
|
@ -1050,6 +1250,7 @@ that.$API.wpm.prints.req(printer_ip, obj).then((response) => {
|
|||
that.qct_testitems.forEach(item0 => {
|
||||
if(item0.testitem_cd_expr!=null){
|
||||
that.mlogbwlist[index][item0.testitem_name]= eval(item0.testitem_cd_expr);
|
||||
that.mlogbwlist[index].cd_expr = true;
|
||||
that.qct_defects.forEach(item => {
|
||||
if(item.rule_expression!==''&&item.rule_expression!==undefined&&item.rule_expression!==null){
|
||||
let str = item.rule_expression.replace(/`/g, '');
|
||||
|
|
@ -1067,6 +1268,10 @@ that.$API.wpm.prints.req(printer_ip, obj).then((response) => {
|
|||
});
|
||||
}
|
||||
})
|
||||
let arrs= that.qct_testitems.filter(item => {return item.testitem_cd_expr!=null;})
|
||||
if(arrs.length>0){
|
||||
that.seveAuto(index);
|
||||
}
|
||||
}).catch((err) => {
|
||||
this.$notify.error({
|
||||
title: '获取数据失败',
|
||||
|
|
@ -1149,7 +1354,6 @@ that.$API.wpm.prints.req(printer_ip, obj).then((response) => {
|
|||
fullscreen: true,
|
||||
text: "解析中...请稍等",
|
||||
});
|
||||
console.log(res);
|
||||
this.$API.wpm.mlog.change.req(that.mlogId,{ test_file: res.path }).then((res) => {
|
||||
loading.close();
|
||||
this.$message.success("导入成功");
|
||||
|
|
@ -1159,6 +1363,15 @@ that.$API.wpm.prints.req(printer_ip, obj).then((response) => {
|
|||
this.$message.error("导入失败,请重新尝试");
|
||||
});
|
||||
},
|
||||
getDefectCount(defectName){
|
||||
let count = 0;
|
||||
this.mlogbwlist.forEach(row => {
|
||||
if(row[defectName]){
|
||||
count++;
|
||||
}
|
||||
});
|
||||
return count;
|
||||
},
|
||||
hasNull(){
|
||||
let that = this;
|
||||
let canSubmit = true;
|
||||
|
|
@ -1363,6 +1576,24 @@ tbody tr:nth-child(odd) .sticky-cell{
|
|||
.more-menu-btn:hover{
|
||||
background: #fef0f0;
|
||||
}
|
||||
.col-setting-float-panel{
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 35px;
|
||||
z-index: 100;
|
||||
background: #fff;
|
||||
border: 1px solid #ebeef5;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 2px 12px rgba(0,0,0,0.12);
|
||||
padding: 8px 12px;
|
||||
min-width: 150px;
|
||||
max-height: 300px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.col-setting-item{
|
||||
padding: 4px 0;
|
||||
line-height: 1.6;
|
||||
}
|
||||
.btn{
|
||||
margin:0 5px;
|
||||
border: none;
|
||||
|
|
|
|||
|
|
@ -15,14 +15,14 @@
|
|||
<el-button
|
||||
v-if="mgroupName=='喷码'"
|
||||
type="success"
|
||||
:disabled="selectedRows.length === 0"
|
||||
:disabled="selectedRows.length === 0||batchCoderLoading2"
|
||||
:loading="batchCoderLoading"
|
||||
@click="batchSendToCoder"
|
||||
>批量喷数字码</el-button>
|
||||
<el-button
|
||||
v-if="mgroupName=='喷码'"
|
||||
type="primary"
|
||||
:disabled="selectedRows.length === 0"
|
||||
:disabled="selectedRows.length === 0||batchCoderLoading"
|
||||
:loading="batchCoderLoading2"
|
||||
@click="batchSendToCoder2"
|
||||
>批量喷二维码</el-button>
|
||||
|
|
@ -49,6 +49,26 @@
|
|||
<el-table-column label="对外编号" prop="number_out" min-width="100px"
|
||||
v-if="mgroupName=='成品内外初检'||mgroupName=='成品内质复检'||mgroupName=='成品性能检测'||mgroupName=='成品尺寸检测'||mgroupName=='成品外观复检一'||mgroupName=='成品外观复检二'"
|
||||
></el-table-column>
|
||||
<el-table-column label="工装" min-width="100px" v-if="mgroupName=='喷码'">
|
||||
<template #default="scope">
|
||||
<el-select
|
||||
v-model="scope.row.pre_info.tooling"
|
||||
placeholder="选择工装"
|
||||
clearable
|
||||
filterable
|
||||
size="small"
|
||||
style="width:100%"
|
||||
@change="handleToolingChange(scope.row)"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in toolingOptions"
|
||||
:key="item.id"
|
||||
:label="item.name"
|
||||
:value="item.id"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="记录数据" prop="oinfo">
|
||||
<template #default="scope">
|
||||
<div v-for="(item,index) in scope.row.oinfo" :key="item.id">
|
||||
|
|
@ -66,25 +86,7 @@
|
|||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="工装" min-width="80px" v-if="mgroupName=='喷码'">
|
||||
<template #default="scope">
|
||||
<el-select
|
||||
v-model="scope.row.tooling"
|
||||
placeholder="选择工装"
|
||||
clearable
|
||||
size="small"
|
||||
style="width:100%"
|
||||
@change="handleToolingChange(scope.row)"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in toolingOptions"
|
||||
:key="item.id"
|
||||
:label="item.name"
|
||||
:value="item.id"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
label="操作"
|
||||
fixed="right"
|
||||
|
|
@ -93,7 +95,9 @@
|
|||
>
|
||||
<template #default="scope">
|
||||
<el-button v-if="mode=='ins'&&mgroupName=='毛坯检测后打码'" @click="QRCode(scope.row)" type="success">二维码</el-button>
|
||||
<el-button @click="printMaterial(scope.row)" type="primary" v-if="mode==!'ins'&&mgroupName!=='喷码'">打签</el-button>
|
||||
<el-button v-if="mode=='ins'&&mgroupName=='毛坯检测'" @click="sendToMarker(scope.row)" type="success" :loading="!!markerLoadingIds[scope.row.id]" :disabled="!!markerLoadingIds[scope.row.id]">打码</el-button>
|
||||
<span v-if="mode=='ins'&&mgroupName=='喷码'"></span>
|
||||
<el-button v-else @click="printMaterial(scope.row)" type="primary">打签</el-button>
|
||||
<el-button @click="sendToCoder(scope.row,'coder_jobname','coder_field')" type="success" v-if="mode=='ins'&&mgroupName=='喷码'" :loading="!!coderLoadingIds[scope.row.id]" :disabled="!!coderLoadingIds[scope.row.id]">喷数字码</el-button>
|
||||
<el-button @click="sendToCoder(scope.row,'coder_jobname2','coder_field2')" type="primary" v-if="mode=='ins'&&mgroupName=='喷码'" :loading="!!coderLoadingIds[scope.row.id]" :disabled="!!coderLoadingIds[scope.row.id]">喷二维码</el-button>
|
||||
</template>
|
||||
|
|
@ -179,6 +183,7 @@ export default {
|
|||
printer_name:localStorage.getItem("printer_name"),
|
||||
apiObjPrint:this.$API.cm.labelmat.fromWm,
|
||||
coderLoadingIds:{},
|
||||
markerLoadingIds:{},
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
|
|
@ -195,7 +200,7 @@ export default {
|
|||
this.params.wm = this.wm;
|
||||
this.visible = true;
|
||||
this.getRowWpr();
|
||||
// this.getToolingOptions();
|
||||
this.getToolingOptions();
|
||||
that.$nextTick(() => {
|
||||
let heights = document.getElementsByClassName("el-drawer__body")[0].clientHeight;
|
||||
that.wprTableHeight = heights-20;
|
||||
|
|
@ -205,18 +210,21 @@ export default {
|
|||
getRowWpr(){
|
||||
let that = this;
|
||||
that.$API.wpm.wpr.list.req(that.params).then((res) => {
|
||||
that.wprList = res;
|
||||
that.wprList = (Array.isArray(res) ? res : []).map(row => ({
|
||||
...row,
|
||||
pre_info: row.pre_info || {},
|
||||
}));
|
||||
})
|
||||
},
|
||||
getToolingOptions(){
|
||||
let that = this;
|
||||
that.$API.mtm.tooling.list.req({ page: 0}).then((res) => {
|
||||
that.$API.em.equipment.list.req({ page: 0,type:10,cate__code:'7'}).then((res) => {
|
||||
that.toolingOptions = Array.isArray(res) ? res : (res.results || []);
|
||||
});
|
||||
},
|
||||
handleToolingChange(row){
|
||||
let that = this;
|
||||
that.$API.wpm.wpr.update.req(row.id,{tooling:row.tooling}).then(() => {
|
||||
that.$API.wpm.wpr.update.req(row.id,{pre_info:{tooling:row.pre_info.tooling}}).then(() => {
|
||||
that.$message.success("工装更新成功");
|
||||
});
|
||||
},
|
||||
|
|
@ -386,7 +394,7 @@ that.$API.wpm.prints.req(printer_ip, obj).then((response) => {
|
|||
params.data = data;
|
||||
}else{
|
||||
params.label_template_name = '单件打印模板';
|
||||
params.data = {number:row.number,name:name};
|
||||
params.data = {number:row.number,name:name,oname:that.ofromName};
|
||||
}
|
||||
that.$API.cm.labeltemplate.commands.req(params).then((res) => {
|
||||
let obj = {};
|
||||
|
|
@ -474,6 +482,41 @@ that.$API.wpm.prints.req(printer_ip, obj).then((response) => {
|
|||
return that.$API.cm.labeltemplate.sendToCoder.req(template.id, body);
|
||||
});
|
||||
},
|
||||
//下发打码: 单行入队 1 条
|
||||
sendToMarker(row){
|
||||
let that = this;
|
||||
if (that.markerLoadingIds[row.id]) return;
|
||||
let marker_ip = localStorage.getItem('marker_ip') || '';
|
||||
if (!marker_ip) {
|
||||
that.$message.error('请先在右上角"打码设置"配置打码IP');
|
||||
return;
|
||||
}
|
||||
let release = () => {
|
||||
let map = { ...that.markerLoadingIds };
|
||||
delete map[row.id];
|
||||
that.markerLoadingIds = map;
|
||||
};
|
||||
that.markerLoadingIds = { ...that.markerLoadingIds, [row.id]: true };
|
||||
let templateName = '打码模板';
|
||||
that.$API.cm.labeltemplate.list.req({name: templateName, page: 0}).then((res) => {
|
||||
let list = Array.isArray(res) ? res : (res && res.results) || [];
|
||||
let template = list.find(t => t.name === templateName);
|
||||
if (!template) {
|
||||
that.$message.error(`未找到标签模板: ${templateName}`);
|
||||
return Promise.reject(new Error('no template'));
|
||||
}
|
||||
let body = { tdata_list: [{number: row.number}], coder_ip: marker_ip,coder_port:null };
|
||||
let marker_port = localStorage.getItem('marker_port') || '';
|
||||
let marker_jobname = localStorage.getItem('marker_jobname') || '';
|
||||
if (marker_port) body.coder_port = Number(marker_port);
|
||||
if (marker_jobname) body.coder_jobname = marker_jobname;
|
||||
return that.$API.cm.labeltemplate.sendToHanslaser.req(template.id, body);
|
||||
}).then(() => {
|
||||
that.$message.success('打码下发成功');
|
||||
}).catch(e => {
|
||||
if (e && e.message !== 'no template') that.$message.error('打码下发失败');
|
||||
}).finally(release);
|
||||
},
|
||||
openSplit() {
|
||||
let that = this;
|
||||
let data = {
|
||||
|
|
|
|||
|
|
@ -6,8 +6,6 @@
|
|||
style="width: 90%;"
|
||||
@closed="$emit('closed')"
|
||||
>
|
||||
<el-container v-loading="loading">
|
||||
<el-main style="padding: 0">
|
||||
<el-form
|
||||
ref="dialogForm"
|
||||
:model="form"
|
||||
|
|
@ -328,14 +326,12 @@
|
|||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</el-main>
|
||||
<el-footer>
|
||||
<el-button type="primary" :loading="isSaveing" @click="submit"
|
||||
>保存</el-button
|
||||
>
|
||||
<el-button @click="visible = false">取消</el-button>
|
||||
</el-footer>
|
||||
</el-container>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
|
|
|
|||
|
|
@ -6,8 +6,6 @@
|
|||
style="width: 80%;"
|
||||
@closed="$emit('closed')"
|
||||
>
|
||||
<el-container v-loading="loading">
|
||||
<el-main style="padding: 0 20px 20px 20px">
|
||||
<el-form
|
||||
ref="dialogForm"
|
||||
:model="form"
|
||||
|
|
@ -259,12 +257,10 @@
|
|||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</el-main>
|
||||
<el-footer>
|
||||
<el-button type="primary" :loading="isSaveing" @click="submit">保存</el-button>
|
||||
<el-button @click="visible = false">取消</el-button>
|
||||
</el-footer>
|
||||
</el-container>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
|
|
|
|||
|
|
@ -6,8 +6,6 @@
|
|||
destroy-on-close
|
||||
@closed="$emit('closed')"
|
||||
>
|
||||
<el-container v-loading="loading">
|
||||
<el-main style="padding: 0 0 20px 0">
|
||||
<el-form
|
||||
ref="dialogForm"
|
||||
:model="form"
|
||||
|
|
@ -179,12 +177,10 @@
|
|||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</el-main>
|
||||
<el-footer>
|
||||
<el-button type="primary" :loading="isSaveing" @click="submit">保存</el-button>
|
||||
<el-button @click="visible = false">取消</el-button>
|
||||
</el-footer>
|
||||
</el-container>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue