This commit is contained in:
hzz 2024-04-15 18:47:14 +08:00
parent 73344175a8
commit 640ad55aa2
10 changed files with 370 additions and 51 deletions

View File

@ -32,9 +32,9 @@ export function getBaseInfoNew() {
})
}
//首页 产量堆叠图
export function qualitynewDeviceOutputQuality() {
export function halfHourOutputPassInfo() {
return request({
url: '/casm/quality/newDeviceOutputQuality',
url: '/casm/quality/halfHourOutputPassInfo',
method: 'get'
})
}
@ -46,5 +46,12 @@ export function getNewestFiveInfo() {
method: 'get'
})
}
//首页 张力值
export function getTensionInfo() {
return request({
url: '/casm/quality/getTensionInfo',
method: 'get'
})
}

View File

@ -21,14 +21,14 @@
</el-upload>
<!-- 上传提示 -->
<div class="el-upload__tip" v-if="showTip">
请上传
{{tLang('tip','请上传')}}
<template v-if="fileSize">
大小不超过 <b style="color: #f56c6c">{{ fileSize }}MB</b>
{{tLang('tip','大小不超过')}} <b style="color: #f56c6c">{{ fileSize }}MB </b>
</template>
<template v-if="fileType">
格式为 <b style="color: #f56c6c">{{ fileType.join("/") }}</b>
{{tLang('tip','格式为')}} <b style="color: #f56c6c">{{ fileType.join("/") }}</b>
</template>
的文件
{{tLang('tip','的文件')}}
</div>
<el-dialog

View File

@ -0,0 +1,255 @@
<!--
* @Author: wei
* @description: 大屏自适应容器组件
* @LastEditTime: 2023-04-20 11:20:03
-->
<template>
<!-- <section class="screen-box" :style="boxStyle"> -->
<div class="screen-wrapper" ref="screenWrapper" :style="wrapperStyle">
<slot></slot>
</div>
<!-- </section> -->
</template>
<script>
/**
* 防抖函数
* @param {T} fn
* @param {number} delay
* @return
*/
function debounce(fn, delay) {
let timer = null;
return function (...args) {
timer = setTimeout(
() => {
typeof fn === "function" && fn.apply(null, args);
clearTimeout(timer);
},
delay > 0 ? delay : 100
);
};
}
export default {
name: "VScaleScreen",
props: {
width: {
type: [String, Number],
default: 1920,
},
height: {
type: [String, Number],
default: 1080,
},
fullScreen: {
type: Boolean,
default: false,
},
autoScale: {
type: [Object, Boolean],
default: true,
},
selfAdaption: {
type: Boolean,
default: true,
},
delay: {
type: Number,
default: 500,
},
boxStyle: {
type: Object,
default: () => ({}),
},
wrapperStyle: {
type: Object,
default: () => ({}),
},
},
data() {
return {
currentWidth: 0,
currentHeight: 0,
originalWidth: 0,
originalHeight: 0,
onResize: null,
observer: null,
};
},
watch: {
selfAdaption(val) {
if (val) {
this.resize();
this.addListener();
} else {
this.clearListener();
this.clearStyle();
}
},
},
computed: {
screenWrapper() {
return this.$refs["screenWrapper"];
},
},
methods: {
initSize() {
return new Promise((resolve, reject) => {
// console.log("");
// overflow:hidden
if (this.screenWrapper.parentNode) {
this.screenWrapper.parentNode.style.overflow = "hidden";
this.screenWrapper.parentNode.scrollLeft = 0;
this.screenWrapper.parentNode.scrollTop = 0;
}
this.$nextTick(() => {
// region
if (this.width && this.height) {
this.currentWidth = this.width;
this.currentHeight = this.height;
} else {
this.currentWidth = this.screenWrapper.clientWidth;
this.currentHeight = this.screenWrapper.clientHeight;
}
// endregion
// region
if (!this.originalHeight || !this.originalWidth) {
this.originalWidth = window.screen.width;
this.originalHeight = window.screen.height;
}
// endregion
resolve();
});
});
},
updateSize() {
if (this.currentWidth && this.currentHeight) {
this.screenWrapper.style.width = `${this.currentWidth}px`;
this.screenWrapper.style.height = `${this.currentHeight}px`;
} else {
this.screenWrapper.style.width = `${this.originalWidth}px`;
this.screenWrapper.style.height = `${this.originalHeight}px`;
}
},
handleAutoScale(scale) {
if (!this.autoScale) return;
const screenWrapper = this.screenWrapper;
const domWidth = screenWrapper.clientWidth;
const domHeight = screenWrapper.clientHeight;
const currentWidth = document.body.clientWidth;
const currentHeight = document.body.clientHeight;
screenWrapper.style.transform = `scale(${scale},${scale}) `;
let mx = Math.max((currentWidth - domWidth * scale) / 2, 0);
let my = Math.max((currentHeight - domHeight * scale) / 2, 0);
if (typeof this.autoScale === "object") {
// @ts-ignore
!this.autoScale.x && (mx = 0);
// @ts-ignore
!this.autoScale.y && (my = 0);
}
// console.log({
// mx,
// my,
// currentWidth,
// currentHeight,
// domWidth,
// domHeight,
// scale,
// });
this.screenWrapper.style.margin = `${my}px ${mx}px`;
},
updateScale() {
const screenWrapper = this.screenWrapper;
//
const currentWidth = document.body.clientWidth;
const currentHeight = document.body.clientHeight;
// onResize
const realWidth = this.currentWidth || this.originalWidth;
const realHeight = this.currentHeight || this.originalHeight;
//
const widthScale = currentWidth / realWidth;
const heightScale = currentHeight / realHeight;
// console.log({currentWidth, currentHeight,realWidth,realHeight});
//
if (this.fullScreen) {
screenWrapper.style.transform = `scale(${widthScale},${heightScale})`;
return false;
}
//
const scale = Math.min(widthScale, heightScale);
this.handleAutoScale(scale);
},
initMutationObserver() {
const screenWrapper = this.screenWrapper;
const observer = (this.observer = new MutationObserver(() => {
this.onResize();
}));
observer.observe(screenWrapper, {
attributes: true,
attributeFilter: ["style"],
attributeOldValue: true,
});
},
clearListener() {
window.removeEventListener("resize", this.onResize);
},
addListener() {
window.addEventListener("resize", this.onResize);
},
clearStyle() {
// console.log("");
const screenWrapper = this.screenWrapper;
screenWrapper.parentNode.style.overflow = "auto";
screenWrapper.style = "";
},
async resize() {
if (!this.selfAdaption) {
return;
}
await this.initSize();
this.updateSize();
this.updateScale();
},
},
mounted() {
this.onResize = debounce(() => {
this.resize();
}, this.delay);
this.$nextTick(() => {
if (this.selfAdaption) {
this.resize();
this.addListener();
}
});
},
beforeDestroy() {
this.clearListener();
// this.observer.disconnect()
},
};
//
</script>
<style scoped>
.screen-box {
overflow: hidden;
background-size: 100% 100%;
background: #000;
width: 100vw;
height: 100vh;
}
.screen-wrapper {
transition-property: all;
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
transition-duration: 500ms;
position: relative;
overflow: hidden;
z-index: 100;
transform-origin: left top;
}
</style>

View File

@ -79,6 +79,10 @@ export default {
},
"tip": {
"确定删除选中记录?": "Are you sure to delete the selected record?",
"请上传": "Please upload",
"大小不超过": "Size is not more than",
"格式为": "Format is",
"的文件": "file",
},
"login": {
"标题": "CASM Sewing Management System",
@ -129,12 +133,16 @@ export default {
"张力值": "Tension Value",
"张力": "Tension",
'针数': 'Needle',
"针1": "Needle1",
"针2": "Needle2",
},
"user":{
'人员信息': 'User Info',
'操作员': 'Operator',
'人员ID': 'Staff ID',
'员工姓名': 'Staff Name',
'员工编号': 'Staff Code',
},
"device": {
"设备信息": "Device Info",

View File

@ -80,6 +80,10 @@ export default {
},
"tip": {
"确定删除选中记录?": "确定删除选中记录?",
"请上传": "请上传",
"大小不超过": "大小不超过",
"格式为": "格式为",
"的文件": "的文件",
},
"login": {
"标题": "智能缝纫管理系统",
@ -130,12 +134,15 @@ export default {
"张力值": "张力值",
"张力": "张力",
'针数': '针数',
"针1": "针1",
"针2": "针2",
},
"user":{
'人员信息': '人员信息',
'操作员': '操作员',
'人员ID': '人员ID',
'员工姓名': '员工姓名',
'员工编号': '员工编号',
},
"device": {
"设备信息": "设备信息",

View File

@ -14,10 +14,10 @@
</el-row>
<div class="chart-content">
<div class="chart-content-card">
<v-chart class="line-chart" :option="line_option" />
<v-chart ref="lineChartRef" class="line-chart" :option="line_option" />
</div>
<div class="chart-content-card">
<v-chart class="line-chart" :option="pie_option" />
<v-chart ref="pieChartRef" class="line-chart" :option="pie_option" />
</div>
<div class="right-content-card">
<div>{{ deviceState.on + tLang('home', '台') }}/{{ deviceState.total + tLang('home', '台') }}</div>
@ -87,6 +87,12 @@ let item_color = {
4: '#CCCCCC',
}
let lineChartRef = ref(null);
let pieChartRef = ref(null);
window.onresize = () => {
lineChartRef.value.resize();
pieChartRef.value.resize();
}
const line_option = ref({
title: {

View File

@ -30,7 +30,6 @@
style="width: 100px; height: 100px; margin-right: 10px; margin-bottom: 10px"
@click="dialogImageUrl = item; dialogVisible = true"></el-image>
</div>
</el-descriptions-item>
</el-descriptions>
</el-dialog>

View File

@ -18,7 +18,7 @@
</el-row>
<el-row>
<el-col :span="12">{{ tLang('device', '运行时长') }}</el-col>
<el-col :span="12">{{ info.runTime||0 + tLang('common','分钟') }}</el-col>
<el-col :span="12">{{ info.runTime || 0 + tLang('common', '分钟') }}</el-col>
</el-row>
</div>
</div>
@ -46,36 +46,42 @@
</div>
<div class="info-content">
<el-row justify="space-evenly">
<el-col :span="12">操作员</el-col>
<el-col :span="12">张一一</el-col>
<el-col :span="6">{{ tLang('product', '产品名称') }}</el-col>
<el-col :span="6">{{ info.productionName }}</el-col>
<el-col :span="6">{{ tLang('product', '产品编码') }}</el-col>
<el-col :span="6">{{ info.productionCode }}</el-col>
</el-row>
<el-row>
<el-col :span="12">人员ID</el-col>
<el-col :span="12">11</el-col>
<el-row v-for="item in info.info">
<el-col :span="4">{{ tLang('product', '面线信息') }}</el-col>
<el-col :span="4">{{ item.surfacelineCode }}</el-col>
<el-col :span="4">{{ tLang('product', '底线信息') }}</el-col>
<el-col :span="4">{{ item.bottomlineCode }}</el-col>
<el-col :span="4">{{ tLang('product', '梭芯信息') }}</el-col>
<el-col :span="4">{{ item.shuttlecoreCode }}</el-col>
</el-row>
</div>
</div>
<div class="barchart">
<v-chart class="chart-class" :option="bar_option" />
<v-chart ref="barChart" class="chart-class" :option="bar_option" />
</div>
</div>
<div class="right-content">
<div class="zhangli">
<v-chart class="chart-class" :option="line_option" />
<v-chart ref="lineChart" class="chart-class" :option="line_option" />
</div>
<div class="table">
<el-table :data="qualityList" stripe style="width: 100%">
<el-table-column type="index" :label="tLang('common', '序号')" align="center" width="60" />
<el-table-column :label="tLang('quality', '产品序列号')" align="center" prop="serialNumber" />
<el-table-column :label="tLang('quality', '开始时间')" align="center" prop="starttime">
<template #default="scope">
<!-- <template #default="scope">
<span>{{ parseTime(scope.row.starttime, '{y}-{m}-{d} {hh}:{mm}:{ss}') }}</span>
</template>
</template> -->
</el-table-column>
<el-table-column :label="tLang('quality', '完成时间')" align="center" prop="endtime">
<template #default="scope">
<!-- <template #default="scope">
<span>{{ parseTime(scope.row.endtime, '{y}-{m}-{d} {hh}:{mm}:{ss}') }}</span>
</template>
</template> -->
</el-table-column>
<el-table-column :label="tLang('product', '底线编码')" align="center" prop="bottomlineCode" />
<el-table-column :label="tLang('product', '面线编码')" align="center" prop="surfacelineCode" />
@ -86,7 +92,7 @@
<el-tag type="success" size="mini" v-if="scope.row.state === '0'">{{ tLang('common', '合格') }}</el-tag>
<el-tag type="danger" size="mini" v-else-if="scope.row.state === '1'">{{ tLang('common', '不合格')
}}</el-tag>
<el-tag type="error" size="mini" v-else>{{ tLang('common', '未完成') }}</el-tag>
<el-tag type="warning" size="mini" v-else>{{ tLang('common', '未完成') }}</el-tag>
</div>
</template>
</el-table-column>
@ -97,7 +103,8 @@
</template>
<script setup>
import { getBaseInfoNew, qualitynewDeviceOutputQuality, getNewestFiveInfo } from "@/api/home";
import { getBaseInfoNew, halfHourOutputPassInfo, getNewestFiveInfo,getTensionInfo } from "@/api/home";
import { getCurrentInstance } from "vue";
@ -106,7 +113,7 @@ let pass = ref([0]);
let noPass = ref([0]);
let bar_option = ref({
title: {
text: proxy.tLang('home','产量'),
text: proxy.tLang('home', '产量'),
textStyle: {
color: '#797979'
},
@ -118,7 +125,7 @@ let bar_option = ref({
}
},
legend: {
data: [proxy.tLang('common','合格'), proxy.tLang('common','不合格')],
data: [proxy.tLang('common', '合格'), proxy.tLang('common', '不合格')],
textStyle: {
color: '#797979'
},
@ -156,7 +163,7 @@ let bar_option = ref({
],
series: [
{
name: proxy.tLang('common','合格'),
name: proxy.tLang('common', '合格'),
type: 'bar',
stack: 'Ad',
shape: 'circle',
@ -169,7 +176,7 @@ let bar_option = ref({
data: [0]
},
{
name: proxy.tLang('common','不合格'),
name: proxy.tLang('common', '不合格'),
type: 'bar',
stack: 'Ad',
shape: 'circle',
@ -177,7 +184,7 @@ let bar_option = ref({
focus: 'series'
},
itemStyle: {
color: '#5470c6'
color: '#c81623'
},
data: [0],
label: {
@ -195,32 +202,49 @@ let bar_option = ref({
let line_option = ref({
title: {
text: proxy.tLang('home','张力值'),
text: proxy.tLang('home', '张力值'),
left: '0',
textStyle: {
color: '#000'
}
},
xAxis: {
name: proxy.tLang('home','针数'),
name: proxy.tLang('home', '针数'),
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
data: [1],
boundaryGap: false,
axisLine: {
onZero: false //-----------
}
},
yAxis: {
name: proxy.tLang('home','张力'),
type: 'value'
name: proxy.tLang('home', '张力'),
type: 'value',
min: -10,
max: 10
},
series: [
{
data: [820, 932, 901, 934, 1290, 1330, 1320],
name: proxy.tLang('home', '针1'),
data: [0],
type: 'line',
smooth: true
},
{
name: proxy.tLang('home', '针2'),
data: [0],
type: 'line',
smooth: true
}
]
})
let timer = null;
let info = ref({});
let qualityList = ref([]);
let barChart = ref(null);
let lineChart = ref(null);
function getData() {
getNewestFiveInfo().then(res => {
qualityList.value = res.data;
@ -228,12 +252,25 @@ function getData() {
getBaseInfoNew().then(res => {
info.value = res.data;
});
qualitynewDeviceOutputQuality().then(res => {
getTensionInfo().then(res => {
let round = [];
let one = [];
let two = [];
res.data.forEach(item => {
round.push(item.round);
one.push(...item.one);
two.push(...item.two);
});
line_option.value.xAxis.data = one.map((item, index) => index + 1);
line_option.value.series[0].data = one;
line_option.value.series[1].data = two;
})
halfHourOutputPassInfo().then(res => {
pass.value = res.data.pass;
noPass.value = res.data.noPass;
bar_option.value.series[0].data = res.data.pass;
bar_option.value.series[1].data = res.data.noPass;
bar_option.value.xAxis[0].data = res.data.time;
bar_option.value.xAxis[0].data = res.data.timePass;
});
}

View File

@ -36,7 +36,7 @@
value-format="YYYY-MM-DD hh:mm:ss" :placeholder="tLang('common', '请选择') + tLang('produce', '结束时间')">
</el-date-picker>
</el-form-item>
<el-form-item label="tLang('produce','批次')" prop="batch">
<el-form-item :label="tLang('produce','批次')" prop="batch">
<el-input v-model="queryParams.batch" :placeholder="tLang('common', '请输入') + tLang('produce', '批次')"
clearable @keyup.enter="handleQuery" />
</el-form-item>

View File

@ -1,26 +1,26 @@
<template>
<el-dialog v-model="props.modelValue" title="设备详情" @close="close" width="800">
<el-descriptions title="" column="2">
<el-descriptions-item label="产品名称">{{ props.info.productionName }}</el-descriptions-item>
<el-descriptions-item label="产品编码">{{ props.info.productionCode }}</el-descriptions-item>
<el-descriptions-item label="产品类型">{{ props.info.type }}</el-descriptions-item>
<el-descriptions-item :label="tLang('product','产品名称')">{{ props.info.productionName }}</el-descriptions-item>
<el-descriptions-item :label="tLang('product','产品编码')">{{ props.info.productionCode }}</el-descriptions-item>
<el-descriptions-item :label="tLang('product','产品类型')">{{ props.info.type }}</el-descriptions-item>
<el-descriptions-item label="设备名称">{{ props.info.deviceName }}</el-descriptions-item>
<el-descriptions-item label="设备编码">{{ props.info.deviceCode }}</el-descriptions-item>
<el-descriptions-item :label="tLang('device','设备名称')">{{ props.info.deviceName }}</el-descriptions-item>
<el-descriptions-item :label="tLang('device','设备编码')">{{ props.info.deviceCode }}</el-descriptions-item>
<el-descriptions-item label="员工姓名">{{ props.info.userName }}</el-descriptions-item>
<el-descriptions-item label="员工编码">{{ props.info.userCode }}</el-descriptions-item>
<el-descriptions-item label="目标产量">{{ props.info.planOutput }}</el-descriptions-item>
<el-descriptions-item label="实时产量">{{ props.info.output }}</el-descriptions-item>
<el-descriptions-item :label="tLang('user','员工姓名')">{{ props.info.userName }}</el-descriptions-item>
<el-descriptions-item :label="tLang('produce','员工编号')">{{ props.info.userCode }}</el-descriptions-item>
<el-descriptions-item :label="tLang('produce','目标产量')">{{ props.info.planOutput }}</el-descriptions-item>
<el-descriptions-item :label="tLang('produce','当前产量')">{{ props.info.output }}</el-descriptions-item>
<el-descriptions-item label="开始时间">{{ props.info.starttime }}</el-descriptions-item>
<el-descriptions-item label="结束时间">{{ props.info.endtime }}</el-descriptions-item>
<el-descriptions-item :label="tLang('produce','开始时间')">{{ props.info.starttime }}</el-descriptions-item>
<el-descriptions-item :label="tLang('produce','结束时间')">{{ props.info.endtime }}</el-descriptions-item>
</el-descriptions>
<el-descriptions title="" column="1">
<el-descriptions-item label="备注信息">{{ props.info.remark }}</el-descriptions-item>
<el-descriptions-item :label="tLang('produce','备注')">{{ props.info.remark }}</el-descriptions-item>
</el-descriptions>
<el-descriptions title="" column="">
<el-descriptions-item label="设备图片">
<el-descriptions-item :label="tLang('product','图片')">
<div v-if="props.info.file && props.info.file.length > 0" style="width: 100%;display: flex;flex-direction: row;justify-content: center;">
<el-image v-for="(item, index) in props.info?.file.split(',')" :key="index" :src="baseUrl + item"
style="width: 100px; height: 100px; margin-right: 10px; margin-bottom: 10px"