init: CATL电池线PAD Web首次入库
This commit is contained in:
248
src/views/404.vue
Normal file
248
src/views/404.vue
Normal file
@@ -0,0 +1,248 @@
|
||||
<template>
|
||||
<div class="wscn-http404-container">
|
||||
<div class="wscn-http404">
|
||||
<div class="pic-404">
|
||||
<img
|
||||
class="pic-404__parent"
|
||||
src="@/assets/404_images/404.png"
|
||||
alt="404"
|
||||
/>
|
||||
<img
|
||||
class="pic-404__child left"
|
||||
src="@/assets/404_images/404_cloud.png"
|
||||
alt="404"
|
||||
/>
|
||||
<img
|
||||
class="pic-404__child mid"
|
||||
src="@/assets/404_images/404_cloud.png"
|
||||
alt="404"
|
||||
/>
|
||||
<img
|
||||
class="pic-404__child right"
|
||||
src="@/assets/404_images/404_cloud.png"
|
||||
alt="404"
|
||||
/>
|
||||
</div>
|
||||
<div class="bullshit">
|
||||
<div class="bullshit__oops">OOPS!</div>
|
||||
<div class="bullshit__info">
|
||||
版权所有
|
||||
<a class="link-type" href="https://wallstreetcn.com" target="_blank"
|
||||
>华尔街见闻</a
|
||||
>
|
||||
</div>
|
||||
<div class="bullshit__headline">{{ message }}</div>
|
||||
<div class="bullshit__info">
|
||||
请检查您输入的网址是否正确,请点击以下按钮返回主页或者发送错误报告
|
||||
</div>
|
||||
<a href="/" class="bullshit__return-home">返回首页</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "Page404",
|
||||
computed: {
|
||||
message() {
|
||||
return "网管说这个页面你不能进......";
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style rel="stylesheet/scss" lang="scss" scoped>
|
||||
.wscn-http404-container {
|
||||
transform: translate(-50%, -50%);
|
||||
position: absolute;
|
||||
top: 40%;
|
||||
left: 50%;
|
||||
}
|
||||
.wscn-http404 {
|
||||
position: relative;
|
||||
width: 1200px;
|
||||
padding: 0 50px;
|
||||
overflow: hidden;
|
||||
.pic-404 {
|
||||
position: relative;
|
||||
float: left;
|
||||
width: 600px;
|
||||
overflow: hidden;
|
||||
&__parent {
|
||||
width: 100%;
|
||||
}
|
||||
&__child {
|
||||
position: absolute;
|
||||
&.left {
|
||||
width: 80px;
|
||||
top: 17px;
|
||||
left: 220px;
|
||||
opacity: 0;
|
||||
animation-name: cloudLeft;
|
||||
animation-duration: 2s;
|
||||
animation-timing-function: linear;
|
||||
animation-fill-mode: forwards;
|
||||
animation-delay: 1s;
|
||||
}
|
||||
&.mid {
|
||||
width: 46px;
|
||||
top: 10px;
|
||||
left: 420px;
|
||||
opacity: 0;
|
||||
animation-name: cloudMid;
|
||||
animation-duration: 2s;
|
||||
animation-timing-function: linear;
|
||||
animation-fill-mode: forwards;
|
||||
animation-delay: 1.2s;
|
||||
}
|
||||
&.right {
|
||||
width: 62px;
|
||||
top: 100px;
|
||||
left: 500px;
|
||||
opacity: 0;
|
||||
animation-name: cloudRight;
|
||||
animation-duration: 2s;
|
||||
animation-timing-function: linear;
|
||||
animation-fill-mode: forwards;
|
||||
animation-delay: 1s;
|
||||
}
|
||||
@keyframes cloudLeft {
|
||||
0% {
|
||||
top: 17px;
|
||||
left: 220px;
|
||||
opacity: 0;
|
||||
}
|
||||
20% {
|
||||
top: 33px;
|
||||
left: 188px;
|
||||
opacity: 1;
|
||||
}
|
||||
80% {
|
||||
top: 81px;
|
||||
left: 92px;
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
top: 97px;
|
||||
left: 60px;
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@keyframes cloudMid {
|
||||
0% {
|
||||
top: 10px;
|
||||
left: 420px;
|
||||
opacity: 0;
|
||||
}
|
||||
20% {
|
||||
top: 40px;
|
||||
left: 360px;
|
||||
opacity: 1;
|
||||
}
|
||||
70% {
|
||||
top: 130px;
|
||||
left: 180px;
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
top: 160px;
|
||||
left: 120px;
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@keyframes cloudRight {
|
||||
0% {
|
||||
top: 100px;
|
||||
left: 500px;
|
||||
opacity: 0;
|
||||
}
|
||||
20% {
|
||||
top: 120px;
|
||||
left: 460px;
|
||||
opacity: 1;
|
||||
}
|
||||
80% {
|
||||
top: 180px;
|
||||
left: 340px;
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
top: 200px;
|
||||
left: 300px;
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.bullshit {
|
||||
position: relative;
|
||||
float: left;
|
||||
width: 300px;
|
||||
padding: 30px 0;
|
||||
overflow: hidden;
|
||||
&__oops {
|
||||
font-size: 32px;
|
||||
font-weight: bold;
|
||||
line-height: 40px;
|
||||
color: #1482f0;
|
||||
opacity: 0;
|
||||
margin-bottom: 20px;
|
||||
animation-name: slideUp;
|
||||
animation-duration: 0.5s;
|
||||
animation-fill-mode: forwards;
|
||||
}
|
||||
&__headline {
|
||||
font-size: 20px;
|
||||
line-height: 24px;
|
||||
color: #222;
|
||||
font-weight: bold;
|
||||
opacity: 0;
|
||||
margin-bottom: 10px;
|
||||
animation-name: slideUp;
|
||||
animation-duration: 0.5s;
|
||||
animation-delay: 0.1s;
|
||||
animation-fill-mode: forwards;
|
||||
}
|
||||
&__info {
|
||||
font-size: 13px;
|
||||
line-height: 21px;
|
||||
color: grey;
|
||||
opacity: 0;
|
||||
margin-bottom: 30px;
|
||||
animation-name: slideUp;
|
||||
animation-duration: 0.5s;
|
||||
animation-delay: 0.2s;
|
||||
animation-fill-mode: forwards;
|
||||
}
|
||||
&__return-home {
|
||||
display: block;
|
||||
float: left;
|
||||
width: 110px;
|
||||
height: 36px;
|
||||
background: #1482f0;
|
||||
border-radius: 100px;
|
||||
text-align: center;
|
||||
color: #ffffff;
|
||||
opacity: 0;
|
||||
font-size: 14px;
|
||||
line-height: 36px;
|
||||
cursor: pointer;
|
||||
animation-name: slideUp;
|
||||
animation-duration: 0.5s;
|
||||
animation-delay: 0.3s;
|
||||
animation-fill-mode: forwards;
|
||||
}
|
||||
@keyframes slideUp {
|
||||
0% {
|
||||
transform: translateY(60px);
|
||||
opacity: 0;
|
||||
}
|
||||
100% {
|
||||
transform: translateY(0);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
124
src/views/CallMaterials/index.vue
Normal file
124
src/views/CallMaterials/index.vue
Normal file
@@ -0,0 +1,124 @@
|
||||
<template>
|
||||
<div class="card">
|
||||
<van-steps :active="callActive" active-color="#23d96e">
|
||||
<van-step>选择物料</van-step>
|
||||
<van-step>AGV送料中</van-step>
|
||||
<van-step>物料验证</van-step>
|
||||
</van-steps>
|
||||
<el-tabs type="border-card" v-model="callActive" style="margin-top: 5vh;">
|
||||
<el-tab-pane :disabled="callActive != 0" :name="0" label="选择物料">
|
||||
<van-dropdown-menu>
|
||||
<van-field v-model="materials" is-link readonly name="picker" label="叫料图号" placeholder="选择物料图号"
|
||||
@click="isShowMaterialsPicker = true" />
|
||||
<van-popup :show="isShowMaterialsPicker" destroy-on-close position="bottom">
|
||||
<van-picker :columns="materialsList" :model-value="carValue" @confirm="materialsOnConfirm"
|
||||
@cancel="isShowMaterialsPicker = false" />
|
||||
</van-popup>
|
||||
<van-field v-model="carPos" is-link readonly name="picker" label="叫料库位" placeholder="选择库位"
|
||||
@click="isShowCarPosPicker = true" />
|
||||
<van-popup :show="isShowCarPosPicker" destroy-on-close position="bottom">
|
||||
<van-picker :columns="carPosList" :model-value="materialsValue" @confirm="carPosOnConfirm"
|
||||
@cancel="isShowCarPosPicker = false" />
|
||||
</van-popup>
|
||||
</van-dropdown-menu>
|
||||
<el-button icon="ShoppingCartFull" type="primary" @click="CallMaterials" style="margin-top: 5vh;">请求叫料</el-button>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :disabled="callActive != 1" :name="1" label="AGV送料中">
|
||||
<van-cell-group>
|
||||
<van-cell title="叫料时间" value="2025-03-25 10:00:00" />
|
||||
<van-cell title="叫料图号" :value="materials" />
|
||||
<van-cell title="叫料库位" :value="carPos" />
|
||||
</van-cell-group>
|
||||
<el-button icon="FolderChecked" type="primary" @click="handHandle" style="margin-top: 2vh;">已到达,手动确认</el-button>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :disabled="callActive != 2" :name="2" label="物料验证">
|
||||
<van-cell-group>
|
||||
<van-cell title="计划订单" value="TestOrder1" />
|
||||
<van-cell title="工件编号" value="DES1235123" />
|
||||
<van-cell title="物料型号" value="DES" />
|
||||
<van-cell title="叫料时间" value="2025-03-25 10:00:00" />
|
||||
<van-cell title="叫料图号" :value="materials" />
|
||||
<van-cell title="叫料库位" :value="carPos" />
|
||||
<van-field value="物料码值" label="码值" right-icon="scan" :right-icon-size="19" />
|
||||
</van-cell-group>
|
||||
<el-button icon="FullScreen" type="primary" @click="verifyCode" style="margin-top: 5vh;">校验物料</el-button>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ElMessageBox } from 'element-plus'
|
||||
import { inject, onMounted, onUnmounted, reactive, ref } from 'vue'
|
||||
// import { showSuccessToast, showFailToast } from 'vant';
|
||||
|
||||
const ExecDatabaseByParam = inject('ExecDatabaseByParam')
|
||||
|
||||
const callActive = ref(0)
|
||||
|
||||
// 缓存库下拉
|
||||
const carPos = ref()
|
||||
const carValue = ref()
|
||||
const isShowCarPosPicker = ref(false)
|
||||
const carPosList = reactive([
|
||||
{ text: '缓存库位1', value: '缓存库位1' },
|
||||
{ text: '缓存库位2', value: '缓存库位2' },
|
||||
{ text: '缓存库位3', value: '缓存库位3' },
|
||||
])
|
||||
|
||||
// 选择物料下拉
|
||||
const materials = ref()
|
||||
const materialsValue = ref()
|
||||
const isShowMaterialsPicker = ref(false)
|
||||
const materialsList = reactive([
|
||||
{ text: 'MaterialsType1', value: 'MaterialsType1' },
|
||||
{ text: 'MaterialsType2', value: 'MaterialsType2' },
|
||||
{ text: 'MaterialsType3', value: 'MaterialsType3' },
|
||||
])
|
||||
|
||||
|
||||
onMounted(() => {
|
||||
})
|
||||
|
||||
const nextTo = () => {
|
||||
if (callActive.value == 2) {
|
||||
callActive.value = 0
|
||||
} else {
|
||||
callActive.value++
|
||||
}
|
||||
}
|
||||
|
||||
const carPosOnConfirm = (selectedValues, eslectedOptions) => {
|
||||
carPos.value = selectedValues?.text;
|
||||
isShowCarPosPicker.value = false;
|
||||
};
|
||||
|
||||
const materialsOnConfirm = (selectedValues, eslectedOptions) => {
|
||||
materials.value = selectedValues?.text;
|
||||
isShowMaterialsPicker.value = false;
|
||||
setTimeout(() => {
|
||||
if (carPos.value == undefined) {
|
||||
carPos.value = carPosList[2].text
|
||||
}
|
||||
}, 1000);
|
||||
};
|
||||
|
||||
const CallMaterials = () => {
|
||||
ElMessage.success('物料呼叫成功!等待送达')
|
||||
nextTo()
|
||||
}
|
||||
|
||||
const handHandle = () => {
|
||||
ElMessage.success('手动确认到达,请扫码校验物料')
|
||||
nextTo()
|
||||
}
|
||||
const verifyCode = () => {
|
||||
ElMessage.success('物料验证成功!送料结束')
|
||||
carPos.value = ''
|
||||
materials.value = ''
|
||||
nextTo()
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
167
src/views/CallMaterialsSearch/index.vue
Normal file
167
src/views/CallMaterialsSearch/index.vue
Normal file
@@ -0,0 +1,167 @@
|
||||
<template>
|
||||
<div class="card">
|
||||
<div class="dataList">
|
||||
<div class="item">
|
||||
<div class="tItem">
|
||||
<div class="name">叫料时间:</div>
|
||||
<div class="value">2025-03-22 13:04:21</div>
|
||||
</div>
|
||||
<div class="tItem">
|
||||
<div class="name">到料时间:</div>
|
||||
<div class="value">2025-03-22 13:05:12</div>
|
||||
</div>
|
||||
<div class="tItem">
|
||||
<div class="name">绑定工件:</div>
|
||||
<div class="value">DES1235123</div>
|
||||
</div>
|
||||
<div class="tItem">
|
||||
<div class="name">物料名称:</div>
|
||||
<div class="value">断路器总成</div>
|
||||
</div>
|
||||
<div class="tItem">
|
||||
<div class="name">物料编号:</div>
|
||||
<div class="value">MaterialsNo1</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="tItem">
|
||||
<div class="name">叫料时间:</div>
|
||||
<div class="value">2025-03-22 13:18:21</div>
|
||||
</div>
|
||||
<div class="tItem">
|
||||
<div class="name">到料时间:</div>
|
||||
<div class="value">2025-03-22 13:22:12</div>
|
||||
</div>
|
||||
<div class="tItem">
|
||||
<div class="name">绑定工件:</div>
|
||||
<div class="value">DES1235124</div>
|
||||
</div>
|
||||
<div class="tItem">
|
||||
<div class="name">物料名称:</div>
|
||||
<div class="value">断路器总成</div>
|
||||
</div>
|
||||
<div class="tItem">
|
||||
<div class="name">物料编号:</div>
|
||||
<div class="value">MaterialsNo2</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="tItem">
|
||||
<div class="name">叫料时间:</div>
|
||||
<div class="value">2025-03-22 13:18:21</div>
|
||||
</div>
|
||||
<div class="tItem">
|
||||
<div class="name">到料时间:</div>
|
||||
<div class="value">2025-03-22 13:22:12</div>
|
||||
</div>
|
||||
<div class="tItem">
|
||||
<div class="name">绑定工件:</div>
|
||||
<div class="value">DES1235124</div>
|
||||
</div>
|
||||
<div class="tItem">
|
||||
<div class="name">物料名称:</div>
|
||||
<div class="value">断路器总成</div>
|
||||
</div>
|
||||
<div class="tItem">
|
||||
<div class="name">物料编号:</div>
|
||||
<div class="value">MaterialsNo2</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="tItem">
|
||||
<div class="name">叫料时间:</div>
|
||||
<div class="value">2025-03-22 13:18:21</div>
|
||||
</div>
|
||||
<div class="tItem">
|
||||
<div class="name">到料时间:</div>
|
||||
<div class="value">2025-03-22 13:22:12</div>
|
||||
</div>
|
||||
<div class="tItem">
|
||||
<div class="name">绑定工件:</div>
|
||||
<div class="value">DES1235124</div>
|
||||
</div>
|
||||
<div class="tItem">
|
||||
<div class="name">物料名称:</div>
|
||||
<div class="value">断路器总成</div>
|
||||
</div>
|
||||
<div class="tItem">
|
||||
<div class="name">物料编号:</div>
|
||||
<div class="value">MaterialsNo2</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="tItem">
|
||||
<div class="name">叫料时间:</div>
|
||||
<div class="value">2025-03-22 13:18:21</div>
|
||||
</div>
|
||||
<div class="tItem">
|
||||
<div class="name">到料时间:</div>
|
||||
<div class="value">2025-03-22 13:22:12</div>
|
||||
</div>
|
||||
<div class="tItem">
|
||||
<div class="name">绑定工件:</div>
|
||||
<div class="value">DES1235124</div>
|
||||
</div>
|
||||
<div class="tItem">
|
||||
<div class="name">物料名称:</div>
|
||||
<div class="value">断路器总成</div>
|
||||
</div>
|
||||
<div class="tItem">
|
||||
<div class="name">物料编号:</div>
|
||||
<div class="value">MaterialsNo2</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="tItem">
|
||||
<div class="name">叫料时间:</div>
|
||||
<div class="value">2025-03-22 13:18:21</div>
|
||||
</div>
|
||||
<div class="tItem">
|
||||
<div class="name">到料时间:</div>
|
||||
<div class="value">2025-03-22 13:22:12</div>
|
||||
</div>
|
||||
<div class="tItem">
|
||||
<div class="name">绑定工件:</div>
|
||||
<div class="value">DES1235124</div>
|
||||
</div>
|
||||
<div class="tItem">
|
||||
<div class="name">物料名称:</div>
|
||||
<div class="value">断路器总成</div>
|
||||
</div>
|
||||
<div class="tItem">
|
||||
<div class="name">物料编号:</div>
|
||||
<div class="value">MaterialsNo2</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { inject, onMounted, onUnmounted, reactive, ref } from 'vue'
|
||||
|
||||
onMounted(() => {
|
||||
})
|
||||
|
||||
// 离开网页 删除定时器
|
||||
onUnmounted(() => {
|
||||
})
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.dataList {
|
||||
.item {
|
||||
border: 2px solid #ccc;
|
||||
padding: 10px 10px;
|
||||
// 圆角 阴影
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
|
||||
margin: 10px 0;
|
||||
.tItem {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
109
src/views/CarMaterialsBind/index.vue
Normal file
109
src/views/CarMaterialsBind/index.vue
Normal file
@@ -0,0 +1,109 @@
|
||||
<template>
|
||||
<div class="main">
|
||||
<div class="card">
|
||||
<van-cell-group>
|
||||
<van-field v-model="carBigPos" is-link readonly label="选择库位" placeholder="请选库位号"
|
||||
@click="isShowCarBigPosPicker = true" />
|
||||
<van-popup :show="isShowCarBigPosPicker" round position="bottom">
|
||||
<van-cascader v-model="carBigPosValue" title="请选库位号" :options="carBigPosList"
|
||||
@close="isShowCarBigPosPicker = false" @finish="carBigPosFinish" />
|
||||
</van-popup>
|
||||
</van-cell-group>
|
||||
|
||||
</div>
|
||||
<div class="card" v-if="carStatus == 1">
|
||||
<van-cell-group inset>
|
||||
库位绑定信息
|
||||
<van-cell title="物料名称" value="断路器总成" />
|
||||
<van-cell title="物料图号" value="DESA" />
|
||||
<van-cell title="物料编号" value="DESA1235123" />
|
||||
<van-cell title="订单号" value="Order001" />
|
||||
<van-cell title="入库时间" value="2025-03-22" />
|
||||
</van-cell-group>
|
||||
<van-button icon="replay" type="primary" size="large">库位解绑</van-button>
|
||||
</div>
|
||||
<div class="card" v-if="carStatus == 2">
|
||||
<van-cell-group inset>
|
||||
空库位绑定
|
||||
<!-- <van-field label="物料名称" v-model="bindMaterialsData.materialName" right-icon="browsing-history-o"
|
||||
:right-icon-size="19" /> -->
|
||||
<van-field v-model="bindMaterialsData.materialName" is-link readonly name="picker" label="物料名称" placeholder="选择物料"
|
||||
@click="isShowMaterialsPicker = true" />
|
||||
<van-popup :show="isShowMaterialsPicker" destroy-on-close position="bottom">
|
||||
<van-picker :columns="materialsList" :model-value="bindMaterialsData.materialCode" @confirm="bindMaterialsOnConfirm"
|
||||
@cancel="isShowMaterialsPicker = false" />
|
||||
</van-popup>
|
||||
<van-cell title="物料图号" :value="bindMaterialsData.materialCode" right-icon="more-o" :right-icon-size="19" />
|
||||
<!-- <van-field label="物料号" v-model="bindMaterialsData.materialCode" right-icon="more-o" :right-icon-size="19" /> -->
|
||||
<van-field label="物料编号" v-model="bindMaterialsData.materialNo" right-icon="scan" :right-icon-size="19" />
|
||||
<van-field label="订单号" v-model="bindMaterialsData.orderNo" right-icon="newspaper-o" :right-icon-size="19" />
|
||||
<van-button icon="back-top" type="primary" size="large">绑定库位信息</van-button>
|
||||
</van-cell-group>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { inject, onMounted, onUnmounted, reactive, ref } from 'vue'
|
||||
const ExecDatabaseByParam = inject('ExecDatabaseByParam')
|
||||
|
||||
const carStatus = ref(0)
|
||||
|
||||
// 选择库位 下拉
|
||||
const carBigPos = ref()
|
||||
const carBigPosValue = ref()
|
||||
const isShowCarBigPosPicker = ref(false)
|
||||
const carBigPosList = reactive([
|
||||
{
|
||||
text: '缓存库1',
|
||||
value: '缓存库1',
|
||||
children: [{ text: '1-1', value: '1-1' }, { text: '1-2', value: '1-2' }, { text: '1-3', value: '1-3' }],
|
||||
},
|
||||
{
|
||||
text: '缓存库2',
|
||||
value: '缓存库2',
|
||||
children: [{ text: '2-1', value: '2-1' }, { text: '2-2', value: '2-2' }, { text: '3-3', value: '3-3' }],
|
||||
},
|
||||
])
|
||||
|
||||
// 选择物料种类 下拉
|
||||
const isShowMaterialsPicker = ref(false)
|
||||
const materialsList = reactive([
|
||||
{ text: '测试物料1', value: 'MaterialsType1' },
|
||||
{ text: '测试物料2', value: 'MaterialsType2' },
|
||||
{ text: '测试物料3', value: 'MaterialsType3' },
|
||||
])
|
||||
const bindMaterialsData = reactive({
|
||||
materialName: '',
|
||||
materialNo: '',
|
||||
materialCode: '',
|
||||
orderNo: '',
|
||||
inTime: '',
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
})
|
||||
|
||||
// 全部选项选择完毕后,会触发 finish 事件
|
||||
const carBigPosFinish = (selectedOptions) => {
|
||||
console.log(selectedOptions, selectedOptions.selectedOptions);
|
||||
if(selectedOptions.selectedOptions[0].text == '缓存库1') {
|
||||
carStatus.value = 1
|
||||
} else {
|
||||
carStatus.value = 2
|
||||
}
|
||||
carBigPos.value = selectedOptions.selectedOptions.map((option) => option.text).join(' / ');
|
||||
isShowCarBigPosPicker.value = false;
|
||||
|
||||
console.log(carStatus)
|
||||
};
|
||||
|
||||
const bindMaterialsOnConfirm = (selectedValues, eslectedOptions) => {
|
||||
bindMaterialsData.materialName = selectedValues?.text;
|
||||
bindMaterialsData.materialCode = selectedValues?.value;
|
||||
isShowMaterialsPicker.value = false;
|
||||
};
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
123
src/views/CarMaterialsBindSearch/index.vue
Normal file
123
src/views/CarMaterialsBindSearch/index.vue
Normal file
@@ -0,0 +1,123 @@
|
||||
<template>
|
||||
<div class="card">
|
||||
<div class="dataList">
|
||||
<div class="item">
|
||||
<div class="tItem">
|
||||
<div class="name">操作时间:</div>
|
||||
<div class="value">2025-03-22 13:04:21</div>
|
||||
</div>
|
||||
<div class="tItem">
|
||||
<div class="name">操作类型:</div>
|
||||
<van-tag class="value" type="success">库位绑定</van-tag>
|
||||
</div>
|
||||
<div class="tItem">
|
||||
<div class="name">操作库位:</div>
|
||||
<div class="value">缓存库2 / 1-1</div>
|
||||
</div>
|
||||
<div class="tItem">
|
||||
<div class="name">物料名称:</div>
|
||||
<div class="value">断路器壳体</div>
|
||||
</div>
|
||||
<div class="tItem">
|
||||
<div class="name">物料编号:</div>
|
||||
<div class="value">MaterialsNo1</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="tItem">
|
||||
<div class="name">操作时间:</div>
|
||||
<div class="value">2025-03-22 13:04:21</div>
|
||||
</div>
|
||||
<div class="tItem">
|
||||
<div class="name">操作类型:</div>
|
||||
<van-tag class="value" type="warning">库位解绑</van-tag>
|
||||
</div>
|
||||
<div class="tItem">
|
||||
<div class="name">操作库位:</div>
|
||||
<div class="value">缓存库2 / 1-1</div>
|
||||
</div>
|
||||
<div class="tItem">
|
||||
<div class="name">物料名称:</div>
|
||||
<div class="value">断路器壳体</div>
|
||||
</div>
|
||||
<div class="tItem">
|
||||
<div class="name">物料编号:</div>
|
||||
<div class="value">MaterialsNo1</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="tItem">
|
||||
<div class="name">操作时间:</div>
|
||||
<div class="value">2025-03-22 13:04:21</div>
|
||||
</div>
|
||||
<div class="tItem">
|
||||
<div class="name">操作类型:</div>
|
||||
<van-tag class="value" type="warning">库位解绑</van-tag>
|
||||
</div>
|
||||
<div class="tItem">
|
||||
<div class="name">操作库位:</div>
|
||||
<div class="value">缓存库2 / 1-1</div>
|
||||
</div>
|
||||
<div class="tItem">
|
||||
<div class="name">物料名称:</div>
|
||||
<div class="value">断路器壳体</div>
|
||||
</div>
|
||||
<div class="tItem">
|
||||
<div class="name">物料编号:</div>
|
||||
<div class="value">MaterialsNo1</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="tItem">
|
||||
<div class="name">操作时间:</div>
|
||||
<div class="value">2025-03-22 13:04:21</div>
|
||||
</div>
|
||||
<div class="tItem">
|
||||
<div class="name">操作类型:</div>
|
||||
<van-tag class="value" type="success">库位绑定</van-tag>
|
||||
</div>
|
||||
<div class="tItem">
|
||||
<div class="name">操作库位:</div>
|
||||
<div class="value">缓存库2 / 1-1</div>
|
||||
</div>
|
||||
<div class="tItem">
|
||||
<div class="name">物料名称:</div>
|
||||
<div class="value">断路器壳体</div>
|
||||
</div>
|
||||
<div class="tItem">
|
||||
<div class="name">物料编号:</div>
|
||||
<div class="value">MaterialsNo1</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { inject, onMounted, onUnmounted, reactive, ref } from 'vue'
|
||||
|
||||
onMounted(() => {
|
||||
})
|
||||
|
||||
// 离开网页 删除定时器
|
||||
onUnmounted(() => {
|
||||
})
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.dataList {
|
||||
.item {
|
||||
border: 2px solid #ccc;
|
||||
padding: 10px 10px;
|
||||
// 圆角 阴影
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
|
||||
margin: 10px 0;
|
||||
.tItem {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
206
src/views/Layout/index.vue
Normal file
206
src/views/Layout/index.vue
Normal file
@@ -0,0 +1,206 @@
|
||||
<template>
|
||||
<div class="main">
|
||||
<router-view />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { inject, onMounted, ref } from 'vue'
|
||||
import { useAppStore } from '@/store/app.js'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { addDynamicRoutes } from '@/router/index.js'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { useRouter } from 'vue-router'
|
||||
import Cookies from 'js-cookie'
|
||||
|
||||
const router = useRouter()
|
||||
const store = useAppStore()
|
||||
const CreateData = inject('CreateData')
|
||||
const ExecDatabase = inject('ExecDatabase')
|
||||
// storeToRefs 响应式解构赋值 pinia
|
||||
const { user, isLoading, routerData } = storeToRefs(store)
|
||||
|
||||
const menuValue = ref('')
|
||||
const date = ref('')
|
||||
const time = ref('')
|
||||
const nowWeek = ref('')
|
||||
const week = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六']
|
||||
const now = new Date()
|
||||
|
||||
onMounted(() => {
|
||||
setTimeout(() => {
|
||||
if (!store.user.AID) {
|
||||
if (Cookies.get('AID')) {
|
||||
user.value.token = Cookies.get('token')
|
||||
user.value.AID = Cookies.get('AID')
|
||||
user.value.name = Cookies.get('name')
|
||||
user.value.role = Cookies.get('role')
|
||||
user.value.userName = Cookies.get('userName')
|
||||
user.value.opName = Cookies.get('opName')
|
||||
user.value.opNameText = Cookies.get('opNameText')
|
||||
} else {
|
||||
console.log('store.user.AID为空,返回主页!')
|
||||
ElMessage.warning('用户信息过期,请重新登陆!')
|
||||
router.push({ path: '/login' })
|
||||
}
|
||||
} else {
|
||||
// 获取当前实时日期时间 与星期几
|
||||
// setInterval(() => {
|
||||
// date.value = now.toLocaleDateString()
|
||||
// time.value = now.toLocaleTimeString()
|
||||
// nowWeek.value = week[now.getDay()]
|
||||
// }, 1000)
|
||||
}
|
||||
}, 200)
|
||||
})
|
||||
|
||||
// 获取权限列表
|
||||
const getRouter = async () => {
|
||||
// 获取权限列表
|
||||
var param = []
|
||||
param[0] = ['userId', store.user.AID]
|
||||
var Data = CreateData('11', 'PDA_基础表_权限模块_查询', param)
|
||||
ExecDatabase(Data).then(response => {
|
||||
if (response.data.length > 0) {
|
||||
for (let item of response.data) {
|
||||
item.selected = false
|
||||
}
|
||||
response.data[0].selected = true
|
||||
routerData.value.userRouterList = response.data
|
||||
initRouter()
|
||||
} else {
|
||||
ElMessage.warning('该角色未分配角色模块,请先进行分配!')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const initRouter = async () => {
|
||||
// 动态添加路由
|
||||
await addDynamicRoutes(routerData.value.userRouterList).then(() => {
|
||||
menuValue.value = routerData.value.userRouterList[0].path
|
||||
routerData.nowRouterPath = routerData.value.userRouterList[0].path
|
||||
routerData.nowRouterTitle = routerData.value.userRouterList[0].权限模块
|
||||
router.push({ path: '/' + routerData.value.userRouterList[0].path })
|
||||
store.isLoading = false
|
||||
})
|
||||
}
|
||||
|
||||
const routerTo = (item) => {
|
||||
const targetRoute = routerData.value.userRouterList.find(r => r.path === item.path)
|
||||
if (targetRoute) {
|
||||
routerData.nowRouterPath = targetRoute.path
|
||||
routerData.nowRouterTitle = targetRoute.权限模块
|
||||
routerData.selected = true
|
||||
router.push({ path: '/' + targetRoute.path })
|
||||
}
|
||||
}
|
||||
|
||||
const logout = () => {
|
||||
ElMessage.warning('退出登录成功!')
|
||||
store.$reset() // 重置pinia数据
|
||||
router.push('/login')
|
||||
// var param = []
|
||||
// param[0] = ['userId', user.AID]
|
||||
// param[1] = ['opName', user.opName]
|
||||
// var Data = CreateData('11', '基础表_用户角色_退出登录', param)
|
||||
// ExecDatabase(Data).then(response => {
|
||||
// if (response.data.length > 0) {
|
||||
// ElMessage.warning('退出登录成功!')
|
||||
// store.$reset() // 重置pinia数据
|
||||
// router.push('/login')
|
||||
// } else {
|
||||
// ElMessage.warning('退出登录失败,数据未清空!')
|
||||
// }
|
||||
// })
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.topBar {
|
||||
width: 100vw;
|
||||
overflow: hidden;
|
||||
|
||||
.logo {
|
||||
width: 20vw;
|
||||
height: 10vh;
|
||||
background-image: url("/public/TopLogo.png");
|
||||
background-size: 100% 100%;
|
||||
}
|
||||
|
||||
.dateTime {
|
||||
font-size: .8vw;
|
||||
float: right;
|
||||
width: 10vw;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
|
||||
div {
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 主内容窗体大小
|
||||
.main {
|
||||
height: 92vh;
|
||||
width: 100vw;
|
||||
overflow: auto;
|
||||
background-color: #f0f3f6;
|
||||
}
|
||||
|
||||
// .t-menu__operations {
|
||||
// .t-button {
|
||||
// margin-left: 8px;
|
||||
// }
|
||||
// }
|
||||
|
||||
.t-demo-menu--dark {
|
||||
.t-button {
|
||||
color: #fff;
|
||||
|
||||
&:hover {
|
||||
background-color: #4b4b4b;
|
||||
border-color: transparent;
|
||||
--ripple-color: #383838;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// logo 两旁留空
|
||||
::v-deep() .t-head-menu .t-menu__logo:not(:empty) {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
::v-deep() .t-menu__logo>* {
|
||||
margin-left: 0 !important;
|
||||
}
|
||||
|
||||
// 顶部栏高度
|
||||
::v-deep() .t-head-menu__inner{
|
||||
height: 8vh;
|
||||
}
|
||||
|
||||
/* 滚动条样式 */
|
||||
::-webkit-scrollbar {
|
||||
width: 4px;
|
||||
/* 设置纵轴(y轴)轴滚动条 */
|
||||
height: 4px;
|
||||
/* 设置横轴(x轴)轴滚动条 */
|
||||
}
|
||||
|
||||
/* 滚动条滑块(里面小方块) */
|
||||
::-webkit-scrollbar-thumb {
|
||||
border-radius: 10px;
|
||||
box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
|
||||
background: #7ba2cc;
|
||||
}
|
||||
|
||||
/* 滚动条轨道 */
|
||||
::-webkit-scrollbar-track {
|
||||
border-radius: 0;
|
||||
box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
|
||||
background: #fff;
|
||||
}
|
||||
</style>
|
||||
238
src/views/Login/index.vue
Normal file
238
src/views/Login/index.vue
Normal file
@@ -0,0 +1,238 @@
|
||||
<template>
|
||||
<div class="main">
|
||||
<div class="login">
|
||||
<div class="title">AMES 工位登录</div>
|
||||
<div class="login-form">
|
||||
<div class="form-item">
|
||||
<el-input v-model="userform.userName" :prefix-icon="User" clearable placeholder="请输入用户名" size="large"
|
||||
class="login-input" />
|
||||
</div>
|
||||
<div class="form-item">
|
||||
<el-input v-model="userform.password" :prefix-icon="Lock" clearable placeholder="请输入密码" show-password
|
||||
size="large" class="login-input" @keyup.enter="login" />
|
||||
</div>
|
||||
<div class="form-item">
|
||||
<el-select v-model="userform.opName" placeholder="请选择台位号" size="large" class="login-select">
|
||||
<el-option v-for="item in opNameList" :key="item.工位号" :label="item.工位号" :value="item.工位号" />
|
||||
</el-select>
|
||||
</div>
|
||||
<div class="form-item">
|
||||
<el-button type="danger" size="large" class="login-button" @click="login">
|
||||
登 录
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { inject, onMounted, reactive } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { useAppStore } from "@/store/app.js";
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { encrypt, cryptoDecrypt, generateSalt } from "../../utils/AES-Pkcs7";
|
||||
import Cookies from 'js-cookie'
|
||||
|
||||
const router = useRouter()
|
||||
const CreateData = inject('CreateData')
|
||||
const ExecDatabase = inject('ExecDatabase')
|
||||
const store = useAppStore();
|
||||
// storeToRefs 响应式解构赋值 pinia
|
||||
const { user, isLoading } = storeToRefs(store);
|
||||
|
||||
const opNameList = reactive([])
|
||||
const userform = reactive({
|
||||
userName: '',
|
||||
password: '',
|
||||
opName: '',
|
||||
opNameText: ''
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
getOpName()
|
||||
})
|
||||
|
||||
const getOpName = () => {
|
||||
opNameList.length = 0
|
||||
// 获取当前操作员名称
|
||||
var param = []
|
||||
var Data = CreateData('11', 'MES_计划BOM_工位与名称_PDA用_查询', param)
|
||||
ExecDatabase(Data).then(response => {
|
||||
if (response.data.length > 0) {
|
||||
opNameList.push(...response.data)
|
||||
// 获取上次登录的工位号
|
||||
const lastOpName = Cookies.get('lastOpName')
|
||||
if (lastOpName && opNameList.some(op => op.工位号 === lastOpName)) {
|
||||
userform.opName = lastOpName
|
||||
userform.opNameText = opNameList.find(op => op.工位号 === lastOpName).工位名称
|
||||
} else {
|
||||
userform.opName = opNameList[0].工位号
|
||||
userform.opNameText = opNameList[0].工位名称
|
||||
}
|
||||
}
|
||||
console.log(response)
|
||||
})
|
||||
}
|
||||
|
||||
const login = () => {
|
||||
console.log(user)
|
||||
var param = []
|
||||
param.push(['用户名', userform.userName])
|
||||
param.push(['密码', userform.password])
|
||||
param.push(['功能类型', 0])
|
||||
var Data = CreateData('11', '菜单模块系统_用户名密码_查询数据_改造新增', param)
|
||||
ExecDatabase(Data).then(response => {
|
||||
const data = response.data
|
||||
if (data.length === 0 || data.result === '0' || data[0].result === '0') {
|
||||
ElMessage.warning('账号或密码错误,请重试!')
|
||||
} else {
|
||||
const param2 = []
|
||||
param2[0] = ['工位号', userform.opName]
|
||||
param2[1] = ['操作者工号', userform.userName]
|
||||
param2[2] = ['班次名称', 'A'] // this.loginForm.class]
|
||||
const Data = CreateData('12', '测量数据工位_监控系统_操作者工号_增加', param2)
|
||||
ExecDatabase(Data).then(() => { })
|
||||
|
||||
// 存储当前工位号到 cookie
|
||||
Cookies.set('lastOpName', userform.opName, { expires: 365 }) // 保存一年
|
||||
|
||||
Cookies.set('AID', data[0].人员编号, { expires: 1 })
|
||||
Cookies.set('name', data[0].姓名, { expires: 1 })
|
||||
Cookies.set('role', data[0].角色编号, { expires: 1 })
|
||||
Cookies.set('userName', data[0].考勤编号, { expires: 1 })
|
||||
Cookies.set('opName', userform.opName, { expires: 1 })
|
||||
Cookies.set('opNameText', userform.opNameText, { expires: 1 })
|
||||
|
||||
user.value.AID = response.data[0].人员编号
|
||||
user.value.name = response.data[0].姓名
|
||||
user.value.role = response.data[0].角色编号
|
||||
user.value.userName = response.data[0].考勤编号
|
||||
user.value.opName = userform.opName
|
||||
user.value.opNameText = userform.opNameText
|
||||
ElMessage.success('登录成功')
|
||||
store.isLoading = true
|
||||
router.push('/')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.main {
|
||||
position: relative;
|
||||
height: 100vh;
|
||||
width: 100vw;
|
||||
background-image: url("/public/login.png");
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.login {
|
||||
width: 85vw;
|
||||
padding: 40px 20px;
|
||||
background-color: rgba(255, 255, 255, 0.8);
|
||||
border: 2px solid #730215;
|
||||
border-radius: 16px;
|
||||
box-shadow: 0 0 20px rgba(0, 0, 0, 0.8);
|
||||
|
||||
.title {
|
||||
color: #e43852;
|
||||
font-size: 42px;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
.login-form {
|
||||
width: 90%;
|
||||
margin: 0 auto;
|
||||
|
||||
.form-item {
|
||||
margin-bottom: 24px;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
margin-top: 40px;
|
||||
}
|
||||
|
||||
.login-input {
|
||||
height: 50px;
|
||||
font-size: 16px;
|
||||
|
||||
:deep(.el-input__wrapper) {
|
||||
background-color: rgba(255, 255, 255, 0.9);
|
||||
border-radius: 8px;
|
||||
padding: 0 15px;
|
||||
backdrop-filter: blur(5px);
|
||||
}
|
||||
|
||||
:deep(.el-input__inner) {
|
||||
height: 50px;
|
||||
}
|
||||
}
|
||||
|
||||
.login-select {
|
||||
width: 100%;
|
||||
height: 50px;
|
||||
|
||||
:deep(.el-input__wrapper) {
|
||||
background-color: rgba(255, 255, 255, 0.9);
|
||||
border-radius: 8px;
|
||||
padding: 0 15px;
|
||||
backdrop-filter: blur(5px);
|
||||
}
|
||||
|
||||
:deep(.el-input__inner) {
|
||||
height: 50px;
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.login-button {
|
||||
width: 100%;
|
||||
height: 50px;
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
border-radius: 8px;
|
||||
background-color: #e43852;
|
||||
border: none;
|
||||
|
||||
&:hover {
|
||||
background-color: darken(#e43852, 10%);
|
||||
}
|
||||
|
||||
&:active {
|
||||
background-color: darken(#e43852, 20%);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 适配不同屏幕尺寸
|
||||
@media screen and (min-width: 768px) {
|
||||
.main {
|
||||
.login {
|
||||
width: 70vw;
|
||||
max-width: 600px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 767px) {
|
||||
.main {
|
||||
.login {
|
||||
width: 90vw;
|
||||
|
||||
.title {
|
||||
font-size: 36px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
642
src/views/OpStatus/index.vue
Normal file
642
src/views/OpStatus/index.vue
Normal file
@@ -0,0 +1,642 @@
|
||||
<template>
|
||||
<div class="container">
|
||||
<!-- 数据栏 -->
|
||||
<div class="data-section">
|
||||
<div class="data-grid">
|
||||
<div class="data-item">
|
||||
<span class="label">工位名称:</span>
|
||||
<span class="value">{{ user.opNameText }}</span>
|
||||
</div>
|
||||
<div class="data-item">
|
||||
<span class="label">工位编号:</span>
|
||||
<span class="value">{{ user.opName }}</span>
|
||||
</div>
|
||||
<div class="data-item">
|
||||
<span class="label">操作者:</span>
|
||||
<span class="value">{{ user.name }}</span>
|
||||
</div>
|
||||
<div class="data-item">
|
||||
<span class="label">产品编号:</span>
|
||||
<span class="value long-text">{{ opSatus.productNumber }}</span>
|
||||
</div>
|
||||
<div class="data-item">
|
||||
<span class="label">产品型号:</span>
|
||||
<span class="value">{{ opSatus.productModel }}</span>
|
||||
</div>
|
||||
<div class="data-item">
|
||||
<span class="label">订单号:</span>
|
||||
<span class="value">{{ opSatus.orderNumber }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="data-item chassis-item">
|
||||
<span class="label">底盘编号:</span>
|
||||
<span class="value">{{ opSatus.chassisNumber }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 功能按钮 -->
|
||||
<div class="button-section">
|
||||
<el-button type="primary" class="action-button" @click="showScanDialog">
|
||||
产品进站
|
||||
</el-button>
|
||||
<el-button type="warning" class="action-button" @click="handleProblemReport">
|
||||
检查项确认
|
||||
</el-button>
|
||||
<el-button type="success" class="action-button" @click="handleProcessComplete">
|
||||
装配完成
|
||||
</el-button>
|
||||
<el-button type="danger" class="action-button" @click="handleLogout">
|
||||
退出登录
|
||||
</el-button>
|
||||
</div>
|
||||
|
||||
<!-- 扫码弹窗 -->
|
||||
<el-dialog v-model="scanDialogVisible" title="扫码" width="80%" :close-on-click-modal="false"
|
||||
:close-on-press-escape="false" :show-close="false">
|
||||
<div class="scan-dialog-content">
|
||||
<el-input v-model="scanCode" placeholder="请扫描或输入随车码" size="large" @keyup.enter="submitScanCode" />
|
||||
</div>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="closeScanDialog">取消</el-button>
|
||||
<el-button type="primary" @click="submitScanCode">
|
||||
提交码值
|
||||
</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 装配完成弹窗 -->
|
||||
<el-dialog v-model="workFinishDialogVisible" title="装配完成" width="80%" :close-on-click-modal="false"
|
||||
:close-on-press-escape="false" :show-close="false">
|
||||
<div class="work-finish-dialog-content">
|
||||
<el-form :model="workFinishForm" :rules="workFinishFormRules" ref="workFinishFormRef">
|
||||
<el-form-item label="订单号:" prop="orderCode">
|
||||
<el-input v-model="workFinishForm.orderCode" readonly />
|
||||
</el-form-item>
|
||||
<el-form-item label="产品编号:" prop="productNumber">
|
||||
<el-input v-model="workFinishForm.productNumber" readonly />
|
||||
</el-form-item>
|
||||
<el-form-item label="产品型号:" prop="productModel">
|
||||
<el-input v-model="workFinishForm.productModel" readonly />
|
||||
</el-form-item>
|
||||
<el-form-item label="底盘编号:" prop="chassisNumber">
|
||||
<el-input v-model="workFinishForm.chassisNumber" readonly />
|
||||
</el-form-item>
|
||||
<el-form-item label="结果:" prop="isOk">
|
||||
<el-select v-model="workFinishForm.isOk" placeholder="请选择结果">
|
||||
<el-option label="通过" value="1" />
|
||||
<el-option label="未通过" value="0" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="workFinishDialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="finishWorkSubmit">
|
||||
提交
|
||||
</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 检查项弹窗 -->
|
||||
<el-dialog v-model="checkItemsDialogVisible" title="检查项确认" :top="'10vh'" width="100%"
|
||||
:close-on-click-modal="false" :close-on-press-escape="false" :show-close="false">
|
||||
<div v-loading="checkItemsLoading" class="check-items-dialog-content">
|
||||
<el-table :data="checkItemsList" border style="width: 100%" max-height="400px">
|
||||
<el-table-column prop="排序" label="序号" width="60" align="center" />
|
||||
<el-table-column prop="检查内容" label="检查内容" min-width="120">
|
||||
<template #default="scope">
|
||||
<div class="multiline-cell">{{ scope.row.检查内容 }}</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="检查要求" label="检查要求" min-width="180">
|
||||
<template #default="scope">
|
||||
<div class="multiline-cell">{{ scope.row.检查要求 }}</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="状态" width="120" align="center">
|
||||
<template #default="scope">
|
||||
<el-tag v-if="scope.row.检查结果 === '0'" type="warning">未确认</el-tag>
|
||||
<el-tag v-else-if="scope.row.检查结果 === '1'" type="success">OK</el-tag>
|
||||
<el-tag v-else-if="scope.row.检查结果 === '2'" type="danger">NOK</el-tag>
|
||||
<span v-else>{{ scope.row.检查结果 }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="200" align="center">
|
||||
<template #default="scope">
|
||||
<div v-if="scope.row.检查结果 === '0'">
|
||||
<el-button type="success" size="mini" @click="handleCheckResult(scope.row, '1')">OK</el-button>
|
||||
<el-button type="danger" size="mini" @click="handleCheckResult(scope.row, '2')">NOK</el-button>
|
||||
</div>
|
||||
<div v-else>
|
||||
<el-button type="info" size="mini" disabled>已确认</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="检查备注" label="备注" min-width="120">
|
||||
<template #default="scope">
|
||||
<span v-if="scope.row.检查结果 !== '0'">{{ scope.row.检查备注 || '-' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="checkItemsDialogVisible = false">关闭</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<!-- NOK备注弹窗 -->
|
||||
<el-dialog v-model="nokRemarkDialogVisible" title="NOK备注" width="500px" :append-to-body="true">
|
||||
<el-form :model="nokRemarkForm" ref="nokRemarkFormRef" :rules="nokRemarkRules">
|
||||
<el-form-item label="NOK原因" prop="remark" label-width="80px">
|
||||
<el-input v-model="nokRemarkForm.remark" type="textarea" :rows="3" placeholder="请输入NOK原因">
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="nokRemarkDialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="confirmNokRemark">确认</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { inject, onMounted, onUnmounted, reactive, ref } from 'vue'
|
||||
import { useAppStore } from '@/store/app.js'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
|
||||
const router = useRouter()
|
||||
const store = useAppStore()
|
||||
const { user, isLoading, routerData } = storeToRefs(store)
|
||||
|
||||
const ExecDatabaseByParam = inject('ExecDatabaseByParam')
|
||||
|
||||
const isEnableUI = ref(false)
|
||||
|
||||
const carSectionList = reactive([])
|
||||
const opSatus = reactive({
|
||||
workstationName: '',
|
||||
workstationCode: '',
|
||||
operator: '',
|
||||
productNumber: '',
|
||||
productModel: '',
|
||||
orderNumber: '',
|
||||
chassisNumber: '',
|
||||
})
|
||||
|
||||
const nowStatus = reactive({
|
||||
isPeople: false,
|
||||
isCarArrive: false,
|
||||
isRgvShipping: false,
|
||||
})
|
||||
|
||||
var timer1 = null
|
||||
|
||||
// 扫码相关
|
||||
const scanDialogVisible = ref(false)
|
||||
const scanCode = ref('')
|
||||
|
||||
// 装配完成相关
|
||||
const workFinishDialogVisible = ref(false)
|
||||
const workFinishForm = reactive({
|
||||
orderCode: '',
|
||||
productNumber: '',
|
||||
productModel: '',
|
||||
chassisNumber: '',
|
||||
isOk: '1'
|
||||
})
|
||||
const workFinishFormRef = ref(null)
|
||||
const workFinishFormRules = {
|
||||
orderCode: [
|
||||
{ required: true, message: '请输入订单号', trigger: 'blur' },
|
||||
{ min: 2, max: 50, message: '长度在2到50个字符之间', trigger: 'blur' }
|
||||
],
|
||||
productNumber: [
|
||||
{ required: true, message: '请输入产品编号', trigger: 'blur' },
|
||||
{ min: 2, max: 50, message: '长度在2到50个字符之间', trigger: 'blur' }
|
||||
],
|
||||
productModel: [
|
||||
{ required: true, message: '请输入产品型号', trigger: 'blur' },
|
||||
{ min: 0, max: 50, message: '长度在2到50个字符之间', trigger: 'blur' }
|
||||
],
|
||||
chassisNumber: [
|
||||
{ required: true, message: '请输入底盘编号', trigger: 'blur' },
|
||||
{ min: 2, max: 50, message: '长度在2到50个字符之间', trigger: 'blur' }
|
||||
],
|
||||
isOk: [
|
||||
{ required: true, message: '请选择结果', trigger: 'change' }
|
||||
]
|
||||
}
|
||||
|
||||
// 检查项相关
|
||||
const checkItemsDialogVisible = ref(false)
|
||||
const checkItemsLoading = ref(false)
|
||||
const checkItemsList = ref([])
|
||||
const nokRemarkDialogVisible = ref(false)
|
||||
const nokRemarkForm = reactive({
|
||||
id: null,
|
||||
remark: '',
|
||||
resultType: ''
|
||||
})
|
||||
const nokRemarkRules = {
|
||||
remark: [
|
||||
{ required: true, message: '请输入NOK原因', trigger: 'blur' },
|
||||
{ min: 2, max: 50, message: '长度在2到50个字符之间', trigger: 'blur' }
|
||||
]
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
setTimeout(() => {
|
||||
getOpMoby()
|
||||
}, 1000)
|
||||
store.isLoading = false
|
||||
})
|
||||
|
||||
// 离开网页 删除定时器
|
||||
onUnmounted(() => {
|
||||
clearInterval(timer1)
|
||||
})
|
||||
|
||||
// 显示扫码弹窗
|
||||
const showScanDialog = async () => {
|
||||
await getOpMoby()
|
||||
if (opSatus.productNumber != '') {
|
||||
ElMessage.warning('当前工件未离站 不可重新进站')
|
||||
return
|
||||
}
|
||||
|
||||
scanCode.value = ''
|
||||
scanDialogVisible.value = true
|
||||
}
|
||||
|
||||
// 关闭扫码弹窗
|
||||
const closeScanDialog = () => {
|
||||
scanDialogVisible.value = false
|
||||
scanCode.value = ''
|
||||
}
|
||||
|
||||
// 提交扫码数据
|
||||
const submitScanCode = async () => {
|
||||
if (!scanCode.value) {
|
||||
ElMessage.warning('请输入随车码')
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
const param = []
|
||||
param[0] = ['工位号', user.value.opName]
|
||||
param[1] = ['产品编码', scanCode.value]
|
||||
param[2] = ['操作者', user.value.name]
|
||||
let response = await ExecDatabaseByParam('11', 'CATL_测量数据车体MOBY_车体进站', param)
|
||||
if (response.data.length > 0) {
|
||||
const isOk = response.data[0].是否合格
|
||||
const msg = response.data[0].msg
|
||||
if (isOk === 1) {
|
||||
ElMessage.success(msg || '产品进站成功')
|
||||
closeScanDialog()
|
||||
getOpMoby()
|
||||
} else {
|
||||
ElMessage.error(msg || '产品进站失败')
|
||||
}
|
||||
} else {
|
||||
ElMessage.error('产品进站失败!')
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('提交失败:', error)
|
||||
ElMessage.error('系统错误,请重试')
|
||||
}
|
||||
}
|
||||
|
||||
// 获取工位数据
|
||||
const getOpMoby = async () => {
|
||||
let param = []
|
||||
console.log(store.user.opName)
|
||||
param[0] = ['工位号', store.user.opName]
|
||||
let response = await ExecDatabaseByParam('11', 'CATL_测量数据工位MOBY_详细信息_查询', param)
|
||||
if (response.data.length > 0) {
|
||||
opSatus.workstationName = response.data[0].工位名称
|
||||
opSatus.workstationCode = response.data[0].工位编号
|
||||
opSatus.operator = response.data[0].操作者
|
||||
opSatus.productNumber = response.data[0].Last_发动机号
|
||||
opSatus.productModel = response.data[0].Last_机型号
|
||||
opSatus.orderNumber = response.data[0].Last_工单号
|
||||
opSatus.chassisNumber = response.data[0].车体二维码
|
||||
} else {
|
||||
opSatus.workstationName = ''
|
||||
opSatus.workstationCode = ''
|
||||
opSatus.productNumber = ''
|
||||
opSatus.productModel = ''
|
||||
opSatus.orderNumber = ''
|
||||
opSatus.chassisNumber = ''
|
||||
}
|
||||
}
|
||||
|
||||
// 装配完成前检查
|
||||
const handleProcessComplete = async () => {
|
||||
if (!opSatus.productNumber) {
|
||||
ElMessage.error('工位未在工作!')
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
let param = []
|
||||
param[0] = ['产品编码', opSatus.productNumber]
|
||||
let response = await ExecDatabaseByParam('11', 'CATL_测量数据_出站前检查', param)
|
||||
|
||||
if (response.data.length > 0) {
|
||||
const isOk = response.data[0].是否合格
|
||||
const msg = response.data[0].msg
|
||||
if (isOk === 1) {
|
||||
showFinishDialog()
|
||||
} else {
|
||||
ElMessage.error(msg || '出站检查未通过')
|
||||
}
|
||||
} else {
|
||||
ElMessage.error('产品出站失败!')
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('出站检查失败:', error)
|
||||
ElMessage.error('系统错误,请重试')
|
||||
}
|
||||
}
|
||||
|
||||
// 显示装配完成弹窗
|
||||
const showFinishDialog = () => {
|
||||
workFinishForm.orderCode = opSatus.orderNumber
|
||||
workFinishForm.productNumber = opSatus.productNumber
|
||||
workFinishForm.productModel = opSatus.productModel
|
||||
workFinishForm.chassisNumber = opSatus.chassisNumber
|
||||
workFinishForm.isOk = '1'
|
||||
workFinishDialogVisible.value = true
|
||||
}
|
||||
|
||||
// 装配完成提交
|
||||
const finishWorkSubmit = async () => {
|
||||
try {
|
||||
let param = []
|
||||
param[0] = ['发动机流水号', workFinishForm.productNumber]
|
||||
param[1] = ['工位编码', user.value.opName]
|
||||
param[2] = ['托盘号', 1]
|
||||
param[3] = ['过点属性', 1]
|
||||
param[4] = ['采集时间', '']
|
||||
param[5] = ['操作者', user.value.name]
|
||||
param[6] = ['合格标志', workFinishForm.isOk]
|
||||
param[7] = ['过站状态', 1]
|
||||
param[8] = ['岔道上下件', 1]
|
||||
param[9] = ['重量', '0']
|
||||
param[10] = ['操作标记', 1]
|
||||
param[11] = ['车体二维码', workFinishForm.chassisNumber]
|
||||
let response = await ExecDatabaseByParam('12', 'Event_MOM_过点数据', param)
|
||||
if (response.data.length > 0 && response.data[0].result == "1") {
|
||||
ElMessage.success('装配完成')
|
||||
workFinishDialogVisible.value = false
|
||||
getOpMoby() // 刷新数据
|
||||
} else {
|
||||
ElMessage.error(response.data[0]?.msg || '装配完成失败')
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('装配完成失败:', error)
|
||||
ElMessage.error('系统错误,请重试')
|
||||
}
|
||||
}
|
||||
|
||||
// 检查项相关
|
||||
const handleProblemReport = async () => {
|
||||
if (!opSatus.productNumber) {
|
||||
ElMessage.error('工位未在工作!')
|
||||
return
|
||||
}
|
||||
|
||||
checkItemsDialogVisible.value = true
|
||||
loadCheckItems()
|
||||
}
|
||||
|
||||
// 加载检查项列表
|
||||
const loadCheckItems = async () => {
|
||||
checkItemsLoading.value = true
|
||||
try {
|
||||
let param = []
|
||||
param[0] = ['工位号', user.value.opName]
|
||||
param[1] = ['工件编号', opSatus.productNumber]
|
||||
|
||||
let response = await ExecDatabaseByParam('11', 'CATL_工位检查项_记录表_工位查询', param)
|
||||
checkItemsList.value = response.data || []
|
||||
} catch (error) {
|
||||
console.error('加载检查项失败:', error)
|
||||
ElMessage.error('加载检查项失败')
|
||||
} finally {
|
||||
checkItemsLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 处理检查结果
|
||||
const handleCheckResult = (row, resultType) => {
|
||||
if (resultType === '2') {
|
||||
// NOK需要填写备注
|
||||
nokRemarkForm.id = row.ID
|
||||
nokRemarkForm.resultType = resultType
|
||||
nokRemarkForm.remark = ''
|
||||
nokRemarkDialogVisible.value = true
|
||||
} else {
|
||||
// OK直接提交
|
||||
submitCheckResult(row.ID, resultType, '')
|
||||
}
|
||||
}
|
||||
|
||||
// 确认NOK备注
|
||||
const confirmNokRemark = () => {
|
||||
if (!nokRemarkForm.remark) {
|
||||
ElMessage.warning('请输入NOK原因')
|
||||
return
|
||||
}
|
||||
submitCheckResult(nokRemarkForm.id, nokRemarkForm.resultType, nokRemarkForm.remark)
|
||||
nokRemarkDialogVisible.value = false
|
||||
}
|
||||
|
||||
// 提交检查结果
|
||||
const submitCheckResult = async (id, resultType, remark) => {
|
||||
try {
|
||||
let param = []
|
||||
param[0] = ['ID', id]
|
||||
param[1] = ['操作者', user.value.name]
|
||||
param[2] = ['检查结果', resultType]
|
||||
param[3] = ['检查备注', remark]
|
||||
|
||||
let response = await ExecDatabaseByParam('12', 'CATL_工位检查项_记录表_工位检查确认', param)
|
||||
|
||||
if (response.data?.[0]?.result === '1') {
|
||||
ElMessage.success(resultType === '1' ? '检查项确认OK' : '检查项确认NOK')
|
||||
loadCheckItems() // 刷新列表
|
||||
} else {
|
||||
ElMessage.error('提交失败')
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('提交检查结果失败:', error)
|
||||
ElMessage.error('提交失败')
|
||||
}
|
||||
}
|
||||
|
||||
// 退出登录
|
||||
const handleLogout = () => {
|
||||
ElMessageBox.confirm('确定要退出登录吗?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
ElMessage.warning('退出登录成功!')
|
||||
store.$reset() // 重置pinia数据
|
||||
router.push('/login')
|
||||
}).catch(() => { })
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.container {
|
||||
height: 80vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 20px;
|
||||
background-color: #f5f7fa;
|
||||
}
|
||||
|
||||
.data-section {
|
||||
flex: 1;
|
||||
background-color: white;
|
||||
border-radius: 12px;
|
||||
padding: 20px;
|
||||
margin-bottom: 20px;
|
||||
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.data-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 15px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.data-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 1.2rem;
|
||||
padding: 10px;
|
||||
border-bottom: 1px solid #ebeef5;
|
||||
|
||||
.label {
|
||||
width: 120px;
|
||||
color: #606266;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.value {
|
||||
flex: 1;
|
||||
color: #303133;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.long-text {
|
||||
font-size: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
.chassis-item {
|
||||
grid-column: 1 / -1;
|
||||
border-top: 2px solid #dcdfe6;
|
||||
margin-top: 10px;
|
||||
padding-top: 15px;
|
||||
}
|
||||
|
||||
.button-section {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 15px;
|
||||
padding: 20px;
|
||||
background-color: white;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.action-button {
|
||||
height: 60px;
|
||||
font-size: 1.2rem;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.el-button+.el-button {
|
||||
margin-left: 0px;
|
||||
}
|
||||
|
||||
// 响应式调整
|
||||
@media screen and (max-width: 1024px) {
|
||||
.data-item {
|
||||
font-size: 1rem;
|
||||
|
||||
.label {
|
||||
width: 100px;
|
||||
}
|
||||
}
|
||||
|
||||
.action-button {
|
||||
height: 50px;
|
||||
font-size: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
.scan-dialog-content {
|
||||
padding: 20px;
|
||||
|
||||
.el-input {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.dialog-footer {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
// 调整按钮样式
|
||||
.button-section {
|
||||
.el-button--danger {
|
||||
background-color: #f56c6c;
|
||||
border-color: #f56c6c;
|
||||
|
||||
&:hover {
|
||||
background-color: #f78989;
|
||||
border-color: #f78989;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.work-finish-dialog-content {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.check-items-dialog-content {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.nok-remark-dialog-content {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.multiline-cell {
|
||||
white-space: pre-wrap;
|
||||
word-break: break-all;
|
||||
line-height: 1.5;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user