Browse Source

feat: Add 新增产品离线、返线、返工返修

master
TengXF 7 months ago
parent
commit
0fa228f07b
  1. 21
      src/api/mes/dict/dictApi.ts
  2. 15
      src/api/mes/productBackline/productBacklineApi.ts
  3. 23
      src/api/mes/productOffline/productOfflineApi.ts
  4. 15
      src/api/mes/reworkBatch/reworkBatchApi.ts
  5. 15
      src/api/mes/reworkSingle/reworkSingleApi.ts
  6. 78
      src/pages.json
  7. 229
      src/pages/mes/productBackline/createProductBackline.vue
  8. 319
      src/pages/mes/productBackline/detail.vue
  9. 339
      src/pages/mes/productBackline/handle.vue
  10. 210
      src/pages/mes/productBackline/index.vue
  11. 244
      src/pages/mes/productOffline/createProductOffline.vue
  12. 311
      src/pages/mes/productOffline/detail.vue
  13. 373
      src/pages/mes/productOffline/handle.vue
  14. 279
      src/pages/mes/productOffline/index.vue
  15. 267
      src/pages/mes/reworkBatch/create.vue
  16. 326
      src/pages/mes/reworkBatch/index.vue
  17. 303
      src/pages/mes/reworkSingle/create.vue
  18. 349
      src/pages/mes/reworkSingle/handle.vue
  19. 320
      src/pages/mes/reworkSingle/index.vue
  20. 1
      src/static/menus/mes/reworkSingle.svg

21
src/api/mes/dict/dictApi.ts

@ -0,0 +1,21 @@
import http from '../../http'
// 获取字典
export function getDictList(type) {
return http.get('/system/dict-data/queryByDictType?dictType=' + type)
}
export async function getDict(type) {
let data =[]
await getDictList(type).then((res) => {
if (res.code == 0) {
data = res.data.map(item=>{
return {
label:item.label,
value:item.value,
}
})
} else {}
}).catch((err) => {})
return data
}

15
src/api/mes/productBackline/productBacklineApi.ts

@ -0,0 +1,15 @@
import http from '../../http'
// 产品离线登记列表
export function getPage(params) {
return http.get('/mes/product-backline/page',{params})
}
export function changeStatus(data) {
return http.put('/mes/product-backline/update',data)
}
export function create(data) {
return http.post('/mes/product-backline/create',data)
}

23
src/api/mes/productOffline/productOfflineApi.ts

@ -0,0 +1,23 @@
import http from '../../http'
// 产品离线登记列表
export function getPage(params) {
return http.get('/mes/product-offline/page',{params})
}
export function changeStatus(data) {
return http.put('/mes/product-offline/update',data)
}
export function create(data) {
return http.post('/mes/product-offline/create',data)
}
export function getPageChildren(params) {
return http.get('/wms/team/getPageChildren',{params})
}
export function getworkSchedulingPage(params) {
return http.get('/mes/work-scheduling/page',{params})
}

15
src/api/mes/reworkBatch/reworkBatchApi.ts

@ -0,0 +1,15 @@
import http from '../../http'
// 产品离线登记列表
export function getPage(params) {
return http.get('/mes/rework-batch/page',{params})
}
export function update(data) {
return http.put('/mes/rework-batch/update',data)
}
export function create(data) {
return http.post('/mes/rework-batch/create',data)
}

15
src/api/mes/reworkSingle/reworkSingleApi.ts

@ -0,0 +1,15 @@
import http from '../../http'
// 产品离线登记列表
export function getPage(params) {
return http.get('/mes/rework-single/page',{params})
}
export function update(data) {
return http.put('/mes/rework-single/update',data)
}
export function create(data) {
return http.post('/mes/rework-single/create',data)
}

78
src/pages.json

@ -1955,9 +1955,87 @@
"navigationBarTitleText": "工序报工", "navigationBarTitleText": "工序报工",
"enablePullDownRefresh": true "enablePullDownRefresh": true
} }
},
{
"path": "pages/mes/productOffline/index",
"style": {
"navigationBarTitleText": "产品离线登记",
"enablePullDownRefresh": true
}
},
{
"path": "pages/mes/productOffline/handle",
"style": {
"navigationBarTitleText": "处理产品离线登记",
"enablePullDownRefresh": true
}
},
{
"path": "pages/mes/productOffline/createProductOffline",
"style": {
"navigationBarTitleText": "创建产品离线登记",
"enablePullDownRefresh": true
}
},
{
"path": "pages/mes/productBackline/index",
"style": {
"navigationBarTitleText": "产品返线登记",
"enablePullDownRefresh": true
}
},
{
"path": "pages/mes/productBackline/detail",
"style": {
"navigationBarTitleText": "产品返线登记详情",
"enablePullDownRefresh": true
}
},
{
"path": "pages/mes/productBackline/handle",
"style": {
"navigationBarTitleText": "处理产品返线登记",
"enablePullDownRefresh": true
}
},
{
"path": "pages/mes/productBackline/createProductBackline",
"style": {
"navigationBarTitleText": "创建产品返线登记",
"enablePullDownRefresh": true
}
},
{
"path": "pages/mes/reworkSingle/index",
"style": {
"navigationBarTitleText": "返工返修单件管理",
"enablePullDownRefresh": true
}
},
{
"path": "pages/mes/reworkSingle/create",
"style": {
"navigationBarTitleText": "创建返工返修登记",
"enablePullDownRefresh": true
}
},
{
"path": "pages/mes/reworkBatch/index",
"style": {
"navigationBarTitleText": "返工返修批量管理",
"enablePullDownRefresh": true
}
},
{
"path": "pages/mes/reworkBatch/create",
"style": {
"navigationBarTitleText": "批量创建返工返修登记",
"enablePullDownRefresh": true
}
} }
], ],
"globalStyle": { "globalStyle": {
"navigationBarTextStyle": "white", "navigationBarTextStyle": "white",

229
src/pages/mes/productBackline/createProductBackline.vue

@ -0,0 +1,229 @@
<template>
<!-- 列表展示标准模版 -->
<view>
<u-form :model="form">
<view>
<u-form-item label="离线编码" prop="offlineCode">
<view>
<!-- <u-input v-model="form.offlineCode" type="select" @click="showBackProduct = true" placeholder="请选择离线编码"/> -->
<u-input v-model="form.offlineCode" disabled="true"/>
</view>
</u-form-item>
</view>
<view>
<u-form-item label="产品编码" prop="productCode">
<view>
<u-input v-model="form.productCode" disabled="true"/>
</view>
</u-form-item>
</view>
<view>
<u-form-item label="工单编码" prop="workBillno">
<view>
<u-input v-model="form.workBillno" disabled="true"/>
</view>
</u-form-item>
</view>
<view>
<u-form-item label="计划编码" prop="planCode">
<view>
<u-input v-model="form.planCode" disabled="true"/>
</view>
</u-form-item>
</view>
<view>
<u-form-item label="工序编码" prop="processCode">
<view>
<u-input v-model="form.processCode" disabled="true"/>
</view>
</u-form-item>
</view>
<view>
<u-form-item label="工位编码" prop="stationCode">
<view>
<u-input v-model="form.stationCode" disabled="true"/>
</view>
</u-form-item>
</view>
<view>
<u-form-item label="加工人员" prop="operCode">
<view>
<u-input v-model="form.operCode" />
</view>
</u-form-item>
</view>
</u-form>
<view class="footer">
<view class="btns">
<button class="sure" @click="handleSubmit" :loading='loading' :disabled='loading'>提交处理</button>
</view>
<view style="height: constant(safe-area-inset-bottom); height: env(safe-area-inset-bottom);"></view>
</view>
<view style="height: constant(safe-area-inset-bottom); height: env(safe-area-inset-bottom);"></view>
</view>
<u-select v-model="showBackProduct" :list="backProductList" @confirm="selectProduct"></u-select>
</template>
<script setup lang="ts">
import requestButton from '@/mycomponents/button/requestButton.vue'
/*初始化*/
import {
onLoad,
onShow,
onReachBottom
} from '@dcloudio/uni-app'
import {
ref,
getCurrentInstance
} from 'vue'
/*引入API*/
import * as productBacklineApi from "@/api/mes/productBackline/productBacklineApi.ts"
import * as productOfflineApi from "@/api/mes/productOffline/productOfflineApi.ts"
const { proxy } = getCurrentInstance()
const paramData = ref()
const loading = ref(false)
/*列表数据集*/
const list = ref([])
const productItem = ref()
const showBackProduct = ref(false)
const backProductList = ref([{label:'产品1',value: '111',name:'产品'},{label:'产品2',value: '222',name:'产品'}])
const form = ref({
offlineCode:'',
workBillno:'',
planCode:'',
processCode:'',
productCode:'',
stationCode:'',
operCode:'',
name:'',
})
/*分页参数*/
const params = ref({
pageNo: 1,
pageSize: 50,
status:2
})
//
function handleSubmit(){
if(form.value.productCode!=''){
proxy.$modal.confirm('确定提交处理吗').then(() => {
proxy.$modal.loading('加载中')
loading.value = true
productBacklineApi.create(form.value).then((res) => {
proxy.$modal.closeLoading()
if (res.data) {
proxy.$modal.showToast('成功')
setTimeout(() => {
proxy.$tab.navigateBack()
loading.value = false
}, 1500)
} else {
proxy.$modal.showToast('失败')
loading.value = false
}
}).catch(() => {
proxy.$modal.closeLoading()
loading.value = false
})
})
}
else{
proxy.$modal.showToast('请先选择离线编码')
}
}
//
function selectProduct(index){
form.value.productCode = index[0].value
findProductByCode(index[0].value);
showBackProduct.value = false
}
// 线
function getproductOfflinePage() {
proxy.$modal.loading('加载中')
productOfflineApi.getPage(params.value).then((res) => {
proxy.$modal.closeLoading()
if (res.data.list.length > 0) {
list.value = res.data.list
backProductList.value = transList(res.data.list)
} else {
proxy.$modal.closeLoading()
}
}).catch(() => {
proxy.$modal.closeLoading()
})
}
//
function transList(data) {
const backProductList = data.map(item => {
return {
"label": item.productName,
"value": item.productCode
};
});
return backProductList;
}
//
function findProductByCode(productCode) {
productItem.value = list.value.find(item => item.productCode === productCode);
form.value.offlineCode = productItem.value.offlineCode
form.value.workBillno = productItem.value.workBillno
form.value.planCode = productItem.value.planCode
form.value.processCode = productItem.value.processCode
form.value.stationCode = productItem.value.stationCode
}
/*通用方法*/
onLoad((option) => {
if (option.obj) {
paramData.value = JSON.parse(decodeURIComponent(option.obj)); // paramData
console.log(paramData.value)
form.value.offlineCode = paramData.value.offlineCode
form.value.workBillno = paramData.value.workBillno
form.value.planCode = paramData.value.planCode
form.value.processCode = paramData.value.processCode
form.value.stationCode = paramData.value.stationCode
form.value.productCode = paramData.value.productCode
}
})
onShow(() => {
getproductOfflinePage()
})
onReachBottom(() => {
})
</script>
<style lang="scss" scoped>
.footer {
position: fixed;
bottom: 0px;
left: 0px;
width: 100%;
z-index: 22;
}
.btns {
display: flex;
button {
flex: 1;
}
.sure {
background: #409eff;
color: white;
border-radius: 0px;
&::after {
border: 1px solid #409eff;
border-radius: 0px;
}
}
.reset {
background: #ff7a45;
border-radius: 0px;
&::after {
border-radius: 0px;
}
}
}
</style>

319
src/pages/mes/productBackline/detail.vue

@ -0,0 +1,319 @@
<template>
<!-- 详情 -->
<view class="detail-container">
<view class="info">
<view class="title">
<view>产品返线登记详情</view>
</view>
<!-- 主数据 -->
<view class="dec">
<view class="dec-item">
<view>返线编码</view>
<view>{{paramData.backlineBillno}}</view>
</view>
<view class="dec-item">
<view>离线编码</view>
<view>{{paramData.offlineCode}}</view>
</view>
<view class="dec-item">
<view>计划编码</view>
<view>{{paramData.planCode}}</view>
</view>
<view class="dec-item">
<view>工单编码</view>
<view>{{paramData.workBillno}}</view>
</view>
<view class="dec-item">
<view>产品编码</view>
<view>{{paramData.productCode}}</view>
</view>
<view class="dec-item">
<view>工序编码</view>
<view>{{paramData.processCode}}</view>
</view>
<view class="dec-item">
<view>工位编码</view>
<view>{{paramData.stationCode}}</view>
</view>
<view class="dec-item">
<view>离线原因</view>
<view>{{paramData.offlineReson}}</view>
</view>
<view class="dec-item">
<view>质检人员</view>
<view>{{paramData.checkPersonCode}}</view>
</view>
</view>
</view>
<view class="footer">
<view class="btns">
<button class="reset" @click="reject">驳回</button>
<button class="sure" @click="submitForm" :loading='loading' :disabled='loading'>提交</button>
</view>
<view style="height: constant(safe-area-inset-bottom); height: env(safe-area-inset-bottom);"></view>
</view>
<view style="height: constant(safe-area-inset-bottom); height: env(safe-area-inset-bottom);"></view>
</view>
</template>
<script setup lang="ts">
import {
onLoad,
onShow
} from '@dcloudio/uni-app'
import {
ref,
getCurrentInstance
} from 'vue'
import * as productOfflineApi from "@/api/mes/productBackline/productBacklineApi.ts"
const { proxy } = getCurrentInstance()
const paramData = ref()
const data = ref({})
const subList = ref([])
const loading = ref(false)
const from = ref()//13
function getShowDetail() {
productOfflineApi.orderDayPage().then((res) => {
subList.value = res.data.list
}).catch(() => { })
}
//
function submitForm() {
proxy.$modal.confirm('确定提交吗').then(() => {
proxy.$modal.loading('加载中')
loading.value = true
productOfflineApi.orderDayPage().then((res) => {
proxy.$modal.closeLoading()
if (res.data) {
proxy.$modal.showToast('成功')
setTimeout(() => {
proxy.$tab.navigateBack()
loading.value = false
}, 1500)
} else {
proxy.$modal.showToast('失败')
loading.value = false
}
}).catch(() => {
proxy.$modal.closeLoading()
loading.value = false
})
})
}
//
function reject(item) {
proxy.$modal.confirm('确定驳回申请吗?').then(() => {
proxy.$modal.loading('加载中')
loading.value = true
orderDayPlan.orderDayPage().then(async (res) => {
if (res.data) {
proxy.$modal.showToast('成功')
setTimeout(() => {
proxy.$tab.navigateBack()
loading.value = false
}, 1500)
} else {
proxy.$modal.showToast('失败')
loading.value = false
}
}).catch(() => {
proxy.$modal.closeLoading()
loading.value = false
})
})
}
onLoad((option) => {
if (option.obj) {
paramData.value = JSON.parse(option.obj); // paramData
}
if (option.type) type.value = option.type;
if (option.from) from.value = option.from;
if (option.number) {
number.value = option.number;
}
console.log(paramData.value)
})
onShow(() => {
getShowDetail()
})
</script>
<style lang="scss" scoped>
.detail-container {
min-height: 100vh;
background: white;
}
.line {
background: #f5f5f5;
height: 20rpx;
}
.info {
background: white;
}
.tab {
border-bottom: 1px solid #e4e4e4;
}
.title {
display: flex;
align-items: center;
padding: 20rpx 30rpx;
border-bottom: 1px solid #e4e4e4;
view {
&:nth-child(1) {
flex: 1;
border-left: 10rpx solid #409eff;
padding-left: 20rpx;
font-weight: bold;
}
}
}
.dec {
padding: 30rpx;
.dec-item {
padding-bottom: 30rpx;
display: flex;
view {
&:nth-child(1) {
width: 160rpx;
}
&:nth-child(2) {
color: #888888;
flex: 1;
width: 0px;
word-wrap: break-word;
}
}
}
}
.dec2 {
padding: 10rpx 30rpx;
display: flex;
view {
&:nth-child(1) {
width: 180rpx;
}
&:nth-child(2) {
color: #888888;
flex: 1;
width: 0px;
word-wrap: break-word;
}
}
}
.items {
border-radius: 12rpx;
background: #F5F5F5;
padding-bottom: 20rpx;
.items-name {
padding: 20rpx;
border-bottom: 1px solid #dedede;
}
.items-dec {
padding: 0px 20rpx;
margin-top: 20rpx;
}
}
.list {
padding: 20rpx;
.item {
display: flex;
margin-bottom: 20rpx;
.item-box {
border-radius: 12rpx;
border: 1px solid #dedede;
border-radius: 12rpx;
flex: 1;
width: 0rpx;
}
.spare-title {
padding: 20rpx 30rpx;
border-bottom: 1px solid #e4e4e4;
display: flex;
.title-txt {
color: #409eff;
font-size: 30rpx;
font-weight: bold;
flex: 1;
}
}
.dec {
color: #9c9c9c;
padding: 0rpx 30rpx 20rpx;
}
}
}
.add-btn {
display: flex;
justify-content: flex-start;
align-items: center;
}
.footer {
position: fixed;
bottom: 0px;
left: 0px;
width: 100%;
z-index: 22;
}
.btns {
display: flex;
button {
flex: 1;
}
.sure {
background: #409eff;
color: white;
border-radius: 0px;
&::after {
border: 1px solid #409eff;
border-radius: 0px;
}
}
.reset {
// background: #F5F5F5;
background: #ff7a45; /* 使用浅蓝色作为背景色 */
border-radius: 0px;
&::after {
border-radius: 0px;
}
}
}
</style>

339
src/pages/mes/productBackline/handle.vue

@ -0,0 +1,339 @@
<template>
<!-- 详情 -->
<view class="detail-container">
<view class="info">
<view class="title">
<view>处理产品返线登记</view>
</view>
<!-- 主数据 -->
<view class="dec">
<!-- <view class="dec-item" @click="selectType">
<view>处理类型</view>
<view>{{handleType.label}}</view>
</view> -->
<view class="dec-item" @click="selectWorker" >
<view>处理人员</view>
<view>{{handleWorker.label}}</view>
</view>
<view class="dec-item">
<view>处理结果</view>
<view><u-input v-model="handleResult" placeholder="请输入结果" /></view>
</view>
</view>
</view>
<view class="footer">
<view class="btns">
<button class="sure" @click="handleSubmit" :loading='loading' :disabled='loading'>提交处理</button>
</view>
<view style="height: constant(safe-area-inset-bottom); height: env(safe-area-inset-bottom);"></view>
</view>
<view style="height: constant(safe-area-inset-bottom); height: env(safe-area-inset-bottom);"></view>
</view>
<u-popup v-model="showWorker" mode="bottom" border-radius="14" length="50%">
<view>
<u-select v-model="showWorker" mode="mutil-column-auto" :list="workerList" @confirm="confirmSelectWorker"></u-select>
</view>
</u-popup>
<u-popup v-model="showType" mode="bottom" border-radius="14" length="50%">
<view>
<u-select v-model="showType" :list="typeList" @confirm="confirmSelectType"></u-select>
</view>
</u-popup>
</template>
<script setup lang="ts">
import {
onLoad,
onShow
} from '@dcloudio/uni-app'
import {
ref,
getCurrentInstance
} from 'vue'
import * as productBacklineApi from "@/api/mes/productBackline/productBacklineApi.ts"
import * as productOfflineApi from "@/api/mes/productOffline/productOfflineApi.ts"
import * as dictApi from "@/api/mes/dict/dictApi.ts"
const { proxy } = getCurrentInstance()
const params = ref({
pageNo: 1,
pageSize: 10,
})
const paramData = ref()
const handleResult = ref()
const loading = ref(false)
const showWorker = ref(false)
const showType = ref(false)
const handleWorker = ref({})
const workerList = ref([])
const handleType = ref({})
const typeList = ref([])
//
async function getDictInfo(){
await dictApi.getDict("basic_team_type").then((res) => {
proxy.$modal.closeLoading()
if (res) {
console.log(typeList.value)
typeList.value = res
} else {
}
}).catch(() => {
})
}
//
function submitData(){
proxy.$modal.loading('加载中')
loading.value = true
productBacklineApi.changeStatus(paramData.value).then((res) => {
proxy.$modal.closeLoading()
if (res.data) {
proxy.$modal.showToast('成功')
setTimeout(() => {
proxy.$tab.navigateBack()
loading.value = false
}, 1500)
} else {
proxy.$modal.showToast('失败')
loading.value = false
}
}).catch(() => {
proxy.$modal.closeLoading()
loading.value = false
})
}
//
function selectWorker() {
showWorker.value = true
}
//
function selectType() {
showType.value = true
}
//
function confirmSelectWorker(val){
console.log(val)
handleWorker.value = val[1]
}
//
function confirmSelectType(val){
console.log(val)
handleType.value = val[0]
}
//
function handleSubmit(){
proxy.$modal.confirm('确定提交处理吗').then(() => {
paramData.value.status = 2
paramData.value.checkPersonCode = handleWorker.value.value
paramData.value.handleResult = handleResult.value.value
submitData()
})
}
onLoad((option) => {
if (option.obj) {
paramData.value = JSON.parse(decodeURIComponent(option.obj)); // paramData
}
if (option.type) type.value = option.type;
if (option.from) from.value = option.from;
if (option.number) {
number.value = option.number;
}
})
onShow(() => {
// getShowDetail()
getDictInfo()
getPageChildren()
})
//
function getPageChildren(){
productOfflineApi.getPageChildren(params.value).then((res) => {
console.log(res)
if (res.data) {
console.log(res.data)
workerList.value = res.data
} else {
}
}).catch(() => {
})
}
</script>
<style lang="scss" scoped>
.detail-container {
min-height: 100vh;
background: white;
}
.line {
background: #f5f5f5;
height: 20rpx;
}
.info {
background: white;
}
.tab {
border-bottom: 1px solid #e4e4e4;
}
.title {
display: flex;
align-items: center;
padding: 20rpx 30rpx;
border-bottom: 1px solid #e4e4e4;
view {
&:nth-child(1) {
flex: 1;
border-left: 10rpx solid #409eff;
padding-left: 20rpx;
font-weight: bold;
}
}
}
.dec {
padding: 30rpx;
.dec-item {
padding-bottom: 30rpx;
display: flex;
view {
&:nth-child(1) {
width: 180rpx;
}
&:nth-child(2) {
color: #888888;
flex: 1;
width: 0px;
word-wrap: break-word;
}
}
}
}
.dec2 {
padding: 10rpx 30rpx;
display: flex;
view {
&:nth-child(1) {
width: 180rpx;
}
&:nth-child(2) {
color: #888888;
flex: 1;
width: 0px;
word-wrap: break-word;
}
}
}
.items {
border-radius: 12rpx;
background: #F5F5F5;
padding-bottom: 20rpx;
.items-name {
padding: 20rpx;
border-bottom: 1px solid #dedede;
}
.items-dec {
padding: 0px 20rpx;
margin-top: 20rpx;
}
}
.list {
padding: 20rpx;
.item {
display: flex;
margin-bottom: 20rpx;
.item-box {
border-radius: 12rpx;
border: 1px solid #dedede;
border-radius: 12rpx;
flex: 1;
width: 0rpx;
}
.spare-title {
padding: 20rpx 30rpx;
border-bottom: 1px solid #e4e4e4;
display: flex;
.title-txt {
color: #409eff;
font-size: 30rpx;
font-weight: bold;
flex: 1;
}
}
.dec {
color: #9c9c9c;
padding: 0rpx 30rpx 20rpx;
}
}
}
.add-btn {
display: flex;
justify-content: flex-start;
align-items: center;
}
.footer {
position: fixed;
bottom: 0px;
left: 0px;
width: 100%;
z-index: 22;
}
.btns {
display: flex;
button {
flex: 1;
}
.sure {
background: #409eff;
color: white;
border-radius: 0px;
&::after {
border: 1px solid #409eff;
border-radius: 0px;
}
}
.reset {
background: #ff7a45;
border-radius: 0px;
&::after {
border-radius: 0px;
}
}
}
</style>

210
src/pages/mes/productBackline/index.vue

@ -0,0 +1,210 @@
<template>
<!-- 列表展示标准模版 -->
<view class="container">
<view>
<u-subsection :list="tabsList" v-model="current" @change="tabsChange"></u-subsection>
</view>
<view class="list">
<view class="item" v-for="(item,index) in list" :key="index" @click="openDetail(item)">
<view class="title">
<view class="title-txt">
{{item.offlineCode}}
</view>
<view class="time">
{{`${$time.formatDate(item.createTime)}`}}
</view>
</view>
<view class="dec">
<view>登记状态</view>
<view>
<u-tag text="待处理" type="warning" mode="light" shape="circle" v-if="item.status==1" :style="{ width: '65px' }" />
<u-tag text="已处理" type="success" mode="light" shape="circle" v-if="item.status==2" :style="{ width: '65px' }" />
</view>
</view>
<view class="dec">
<view>计划编码</view><view>{{item.planCode}}</view>
</view>
<view class="dec">
<view>工单编码</view><view>{{item.workBillno}}</view>
</view>
<view class="dec">
<view>产品编码</view><view>{{item.productCode}}</view>
</view>
<view class="dec">
<view>工序编码</view><view>{{item.processCode}}</view>
</view>
<view class="dec">
<view>工位编码</view><view>{{item.stationCode}}</view>
</view>
<view class="dec">
<view>
<u-button v-if="item.status==1" size="medium" type="success" @click="handleItem(item)" >去处理</u-button>
</view>
</view>
</view>
<view style="height: 94rpx;padding-top: 30rpx;">
<u-loadmore :status="status" v-if="status != 'loadmore'" />
</view>
</view>
<view style="height: constant(safe-area-inset-bottom); height: env(safe-area-inset-bottom);"></view>
<requestButton @goScan='openScanDetailPopup'></requestButton>
</view>
</template>
<script setup lang="ts">
import requestButton from '@/mycomponents/button/requestButton.vue'
/*初始化*/
import {
onLoad,
onShow,
onReachBottom
} from '@dcloudio/uni-app'
import {
ref,
getCurrentInstance
} from 'vue'
/*引入API*/
import * as productBacklineApi from "@/api/mes/productBackline/productBacklineApi.ts"
const { proxy } = getCurrentInstance()
const tabsList = ref([{name:'待处理'},{name:'已处理'}])
const current = ref(0)
/*分页参数*/
const params = ref({
pageNo: 1,
pageSize: 10,
flag:null,
status: 1
})
/*是否显示"没有更多了"*/
const status = ref('loadmore')
/*列表数据集*/
const list = ref([])
/*列表调用API方法*/
async function getList() {
if (status.value == 'nomore') return;
status.value = 'loading';
proxy.$modal.loading('加载中')
await productBacklineApi.getPage(params.value).then((res) => {
proxy.$modal.closeLoading()
if (res.data.list.length > 0) {
list.value = list.value.concat(res.data.list);
params.value.pageNo++;
status.value = 'loadmore'
} else {
status.value = 'nomore'
}
}).catch(() => {
proxy.$modal.closeLoading()
})
}
//
function openScanDetailPopup() {
proxy.$tab.navigateTo(`/pages/mes/productBackline/createProductBackline`)
proxy.$modal.loading('加载中')
setTimeout(function() {
proxy.$modal.closeLoading();
}, 500);
}
//
function handleItem(index){
const objString = JSON.stringify(index);
proxy.$tab.navigateTo(`/pages/mes/productBackline/handle?obj=${encodeURIComponent(objString)}`)
proxy.$modal.loading('正在打开详情页')
setTimeout(function() {
proxy.$modal.closeLoading();
}, 500);
}
/*打开详情页*/
function openDetail(item) {
if(item.ststus==2){
console.log(item)
const objString = JSON.stringify(item);
proxy.$tab.navigateTo(`/pages/mes/productBackline/detail?obj=${objString}`)
proxy.$modal.loading('正在打开详情页')
setTimeout(function() {
proxy.$modal.closeLoading();
}, 500);
}
}
// tab
function tabsChange(curr){
current.value = curr
params.value.status = (curr + 1)
params.value.pageNo = 1
params.value.pageSize = 5
list.value = []
status.value = 'loadmore'
getList();
}
/*通用方法*/
onShow(() => {
params.value.pageNo = 1
list.value = []
status.value = 'loadmore'
getList()
})
onReachBottom(() => {
getList()
})
</script>
<style lang="scss" scoped>
.container{
background: #f5f5f5;
min-height: 100vh;
}
.list {
background: #f5f5f5;
margin-top: 20rpx;
.item {
padding: 30rpx 30rpx 0px 30rpx;
margin-top: 20rpx;
background: white;
position: relative;
.title {
display: flex;
align-items: center;
padding-bottom: 20rpx;
.title-txt {
color: #409eff;
font-weight: bold;
font-size: 36rpx;
width: 0px;
flex: 1;
word-wrap: break-word;
}
.time {
color: #919191;
}
}
.dec {
padding-bottom: 20rpx;
display: flex;
align-items: center;
view {
&:nth-child(1){
width: 160rpx;;
}
&:nth-child(2){
color: #999999;
flex: 1;
width: 0px;
word-wrap: break-word;
}
}
}
.last {
padding-bottom: 30rpx;
}
.bottom {
display: flex;
justify-content: space-between;
align-items: center;
border-top: 1px solid #E4E4E4;
padding: 20rpx 0px;
height: 90rpx;
}
}
}
</style>

244
src/pages/mes/productOffline/createProductOffline.vue

@ -0,0 +1,244 @@
<template>
<!-- 列表展示标准模版 -->
<view>
<u-form :model="form">
<view>
<u-form-item label="产品编码" prop="productCode">
<view>
<u-input v-model="form.productCode" type="select" @click="showProduct = true" placeholder="请选择产品编码"/>
<!-- <u-input v-model="form.productCode" disabled="true"/> -->
</view>
</u-form-item>
</view>
<view>
<u-form-item label="工单编码" prop="workBillno">
<view>
<u-input v-model="form.workBillno" disabled="true"/>
</view>
</u-form-item>
</view>
<view>
<u-form-item label="计划编码" prop="planCode">
<view>
<u-input v-model="form.planCode" disabled="true"/>
</view>
</u-form-item>
</view>
<view>
<u-form-item label="工序编码" prop="processCode">
<view>
<u-input v-model="form.processCode" disabled="true"/>
</view>
</u-form-item>
</view>
<view>
<u-form-item label="工位编码" prop="stationCode">
<view>
<u-input v-model="form.stationCode" disabled="true"/>
</view>
</u-form-item>
</view>
<view>
<u-form-item label="产品去向" prop="productDestination">
<view>
<u-input v-model="form.productDestination" />
</view>
</u-form-item>
</view>
<view>
<u-form-item label="离线原因" prop="offlineReson">
<view>
<u-input v-model="form.offlineReson" />
</view>
</u-form-item>
</view>
</u-form>
<view class="footer">
<view class="btns">
<button class="sure" @click="handleSubmit" :loading='loading' :disabled='loading'>提交处理</button>
</view>
<view style="height: constant(safe-area-inset-bottom); height: env(safe-area-inset-bottom);"></view>
</view>
<view style="height: constant(safe-area-inset-bottom); height: env(safe-area-inset-bottom);"></view>
</view>
<u-select v-model="showProduct" :list="productList" @confirm="selectProduct"></u-select>
</template>
<script setup lang="ts">
import requestButton from '@/mycomponents/button/requestButton.vue'
/*初始化*/
import {
onLoad,
onShow,
onReachBottom
} from '@dcloudio/uni-app'
import {
ref,
getCurrentInstance
} from 'vue'
/*引入API*/
import * as productOfflineApi from "@/api/mes/productOffline/productOfflineApi.ts"
const { proxy } = getCurrentInstance()
const loading = ref(false)
/*列表数据集*/
const list = ref([])
const productItem = ref()
const showProduct = ref(false)
const paramData = ref()
const productList = ref([{label:'产品1',value: '111',name:'产品'},{label:'产品2',value: '222',name:'产品'}])
const form = ref({
workBillno:'',
planCode:'',
processCode:'',
productCode:'',
stationCode:'',
offlineReson:'',
productDestination:'',
name:'',
})
/*分页参数*/
const params = ref({
pageNo: 1,
pageSize: 50,
flagDo:3
})
//
function handleSubmit(){
if(form.value.productCode!=''){
proxy.$modal.confirm('确定提交处理吗').then(() => {
proxy.$modal.loading('加载中')
loading.value = true
productOfflineApi.create(form.value).then((res) => {
proxy.$modal.closeLoading()
if (res.data) {
proxy.$modal.showToast('成功')
setTimeout(() => {
proxy.$tab.navigateBack()
loading.value = false
}, 1500)
} else {
proxy.$modal.showToast('失败')
loading.value = false
}
}).catch(() => {
proxy.$modal.closeLoading()
loading.value = false
})
})
}
else{
proxy.$modal.showToast('请先选择产品编码')
}
}
//
function selectProduct(index){
form.value.productCode = index[0].value
findProductByCode(index[0].value);
showProduct.value = false
}
//
function getworkSchedulingPage() {
proxy.$modal.loading('加载中')
productOfflineApi.getworkSchedulingPage(params.value).then((res) => {
proxy.$modal.closeLoading()
if (res.data.list.length > 0) {
list.value = res.data.list
productList.value = transList(res.data.list)
} else {
}
}).catch(() => {
proxy.$modal.closeLoading()
})
}
//
function transList(data) {
const productList = data.map(item => {
return {
"label": item.productName,
"value": item.productCode
};
});
return productList;
}
//
function findProductByCode(productCode) {
productItem.value = list.value.find(item => item.productCode === productCode);
form.value.workBillno = productItem.value.schedulingCode
form.value.planCode = productItem.value.planMaserCode
form.value.processCode = productItem.value.workingNode
form.value.stationCode = productItem.value.currentWorkstation
}
/*是否显示"没有更多了"*/
// const status = ref('loadmore')
/*通用方法*/
onLoad((option) => {
if (option.obj) {
paramData.value = JSON.parse(decodeURIComponent(option.obj)); // paramData
form.value.workBillno = paramData.value.schedulingCode
form.value.planCode = paramData.value.planMaserCode
form.value.processCode = paramData.value.workingNode
form.value.stationCode = paramData.value.currentWorkstation
form.value.productCode = paramData.value.currentWorkstation
}
})
onShow(() => {
// params.value.pageNo = 1
// list.value = []
// status.value = 'loadmore'
getworkSchedulingPage()
})
onReachBottom(() => {
// getList()
})
</script>
<style lang="scss" scoped>
.footer {
position: fixed;
bottom: 0px;
left: 0px;
width: 100%;
z-index: 22;
}
.btns {
display: flex;
button {
flex: 1;
}
.sure {
background: #409eff;
color: white;
border-radius: 0px;
&::after {
border: 1px solid #409eff;
border-radius: 0px;
}
}
.reset {
background: #ff7a45;
border-radius: 0px;
&::after {
border-radius: 0px;
}
}
}
</style>

311
src/pages/mes/productOffline/detail.vue

@ -0,0 +1,311 @@
<template>
<!-- 详情 -->
<view class="detail-container">
<view class="info">
<view class="title">
<view>产品离线登记详情</view>
</view>
<!-- 主数据 -->
<view class="dec">
<view class="dec-item">
<view>离线编码</view>
<view>{{paramData.offlineCode}}</view>
</view>
<view class="dec-item">
<view>计划编码</view>
<view>{{paramData.planCode}}</view>
</view>
<view class="dec-item">
<view>工单编码</view>
<view>{{paramData.workBillno}}</view>
</view>
<view class="dec-item">
<view>产品编码</view>
<view>{{paramData.productCode}}</view>
</view>
<view class="dec-item">
<view>工序编码</view>
<view>{{paramData.processCode}}</view>
</view>
<view class="dec-item">
<view>工位编码</view>
<view>{{paramData.stationCode}}</view>
</view>
<view class="dec-item">
<view>离线原因</view>
<view>{{paramData.offlineReson}}</view>
</view>
<view class="dec-item">
<view>质检人员</view>
<view>{{paramData.checkPersonCode}}</view>
</view>
</view>
</view>
<view class="footer">
<!-- <view class="btns">
<button v-if="paramData.status==2 || paramData.status==3" class="reset" @click="reject">驳回</button>
<button v-if="paramData.status==1" class="sure" @click="changeStatus" :loading='loading' :disabled='loading'>提交处理</button>
<button v-if="paramData.status==2" class="sure" @click="changeStatus" :loading='loading' :disabled='loading'>处理完成</button>
</view> -->
<view style="height: constant(safe-area-inset-bottom); height: env(safe-area-inset-bottom);"></view>
</view>
<view style="height: constant(safe-area-inset-bottom); height: env(safe-area-inset-bottom);"></view>
</view>
</template>
<script setup lang="ts">
import {
onLoad,
onShow
} from '@dcloudio/uni-app'
import {
ref,
getCurrentInstance
} from 'vue'
import * as productOfflineApi from "@/api/mes/productOffline/productOfflineApi.ts"
const { proxy } = getCurrentInstance()
const paramData = ref()
const data = ref({})
const subList = ref([])
const loading = ref(false)
const from = ref()//13
function getShowDetail() {
productOfflineApi.orderDayPage().then((res) => {
subList.value = res.data.list
}).catch(() => { })
}
function changeStatus(){
proxy.$modal.confirm('确定继续操作吗').then(() => {
console.log(paramData.value.status)
// if(paramData.value.status ==1){
// paramData.value = 2
// }else{
// paramData.value = 3
// }
paramData.value.status = Number(paramData.value.status); //
paramData.value.status += 1; // 1 2
submitData()
})
}
//
function submitData(){
proxy.$modal.loading('加载中')
loading.value = true
productOfflineApi.changeStatus(paramData.value).then((res) => {
proxy.$modal.closeLoading()
if (res.data) {
proxy.$modal.showToast('成功')
setTimeout(() => {
proxy.$tab.navigateBack()
loading.value = false
}, 1500)
} else {
proxy.$modal.showToast('失败')
loading.value = false
}
}).catch(() => {
proxy.$modal.closeLoading()
loading.value = false
})
}
//
function reject(item) {
proxy.$modal.confirm('确定继续操作吗').then(() => {
paramData.value.status = Number(paramData.value.status);
paramData.value.status -= 1;
submitData()
})
}
onLoad((option) => {
if (option.obj) {
paramData.value = JSON.parse(decodeURIComponent(option.obj)); // paramData
}
if (option.type) type.value = option.type;
if (option.from) from.value = option.from;
if (option.number) {
number.value = option.number;
}
})
onShow(() => {
// getShowDetail()
})
</script>
<style lang="scss" scoped>
.detail-container {
min-height: 100vh;
background: white;
}
.line {
background: #f5f5f5;
height: 20rpx;
}
.info {
background: white;
}
.tab {
border-bottom: 1px solid #e4e4e4;
}
.title {
display: flex;
align-items: center;
padding: 20rpx 30rpx;
border-bottom: 1px solid #e4e4e4;
view {
&:nth-child(1) {
flex: 1;
border-left: 10rpx solid #409eff;
padding-left: 20rpx;
font-weight: bold;
}
}
}
.dec {
padding: 30rpx;
.dec-item {
padding-bottom: 30rpx;
display: flex;
view {
&:nth-child(1) {
width: 160rpx;
}
&:nth-child(2) {
color: #888888;
flex: 1;
width: 0px;
word-wrap: break-word;
}
}
}
}
.dec2 {
padding: 10rpx 30rpx;
display: flex;
view {
&:nth-child(1) {
width: 180rpx;
}
&:nth-child(2) {
color: #888888;
flex: 1;
width: 0px;
word-wrap: break-word;
}
}
}
.items {
border-radius: 12rpx;
background: #F5F5F5;
padding-bottom: 20rpx;
.items-name {
padding: 20rpx;
border-bottom: 1px solid #dedede;
}
.items-dec {
padding: 0px 20rpx;
margin-top: 20rpx;
}
}
.list {
padding: 20rpx;
.item {
display: flex;
margin-bottom: 20rpx;
.item-box {
border-radius: 12rpx;
border: 1px solid #dedede;
border-radius: 12rpx;
flex: 1;
width: 0rpx;
}
.spare-title {
padding: 20rpx 30rpx;
border-bottom: 1px solid #e4e4e4;
display: flex;
.title-txt {
color: #409eff;
font-size: 30rpx;
font-weight: bold;
flex: 1;
}
}
.dec {
color: #9c9c9c;
padding: 0rpx 30rpx 20rpx;
}
}
}
.add-btn {
display: flex;
justify-content: flex-start;
align-items: center;
}
.footer {
position: fixed;
bottom: 0px;
left: 0px;
width: 100%;
z-index: 22;
}
.btns {
display: flex;
button {
flex: 1;
}
.sure {
background: #409eff;
color: white;
border-radius: 0px;
&::after {
border: 1px solid #409eff;
border-radius: 0px;
}
}
.reset {
background: #ff7a45;
border-radius: 0px;
&::after {
border-radius: 0px;
}
}
}
</style>

373
src/pages/mes/productOffline/handle.vue

@ -0,0 +1,373 @@
<template>
<!-- 详情 -->
<view class="detail-container">
<view class="info">
<view class="title">
<view>处理产品离线登记</view>
</view>
<!-- 主数据 -->
<view class="dec">
<view class="dec-item" @click="selectType">
<view>处理类型</view>
<view>{{handleType.label}}</view>
</view>
<view class="dec-item" @click="selectWorker" >
<view>处理人员</view>
<view>{{handleWorker.label}}</view>
</view>
<view class="dec-item" @click="selectReson" >
<view>处理结果</view>
<!-- <view>{{handleOfflineReson.label}}</view> -->
<view><u-input v-model="handleResult" placeholder="请输入结果" /></view>
</view>
</view>
</view>
<view class="footer">
<view class="btns">
<button class="sure" @click="handleSubmit" :loading='loading' :disabled='loading'>提交处理</button>
</view>
<view style="height: constant(safe-area-inset-bottom); height: env(safe-area-inset-bottom);"></view>
</view>
<view style="height: constant(safe-area-inset-bottom); height: env(safe-area-inset-bottom);"></view>
</view>
<!-- 离线登记人员 弹出层-->
<u-popup v-model="showWorker" mode="bottom" border-radius="14" length="30%">
<view>
<u-select v-model="showWorker" mode="mutil-column-auto" :list="workerList" @confirm="confirmSelectWorker"></u-select>
</view>
</u-popup>
<!-- 离线登记类型 弹出层-->
<u-popup v-model="showType" mode="bottom" border-radius="14" length="30%">
<view>
<u-select v-model="showType" :list="typeList" @confirm="confirmSelectType"></u-select>
</view>
</u-popup>
<!-- 离线登记原因 弹出层-->
<u-popup v-model="showReason" mode="bottom" border-radius="14" length="30%">
<view>
<u-select v-model="showReason" :list="offlineResonList" @confirm="confirmSelectReson"></u-select>
</view>
</u-popup>
</template>
<script setup lang="ts">
import {
onLoad,
onShow
} from '@dcloudio/uni-app'
import {
ref,
getCurrentInstance
} from 'vue'
import * as productOfflineApi from "@/api/mes/productOffline/productOfflineApi.ts"
import * as dictApi from "@/api/mes/dict/dictApi.ts"
const { proxy } = getCurrentInstance()
const paramData = ref()
const params = ref({
pageNo: 1,
pageSize: 10,
})
const loading = ref(false)
const handleResult = ref()
//
const showWorker = ref(false)
const showType = ref(false)
const showReason = ref(false)
const handleWorker = ref({})
const workerList = ref([])
const handleType = ref({})
const typeList = ref([])
const handleOfflineReson = ref({})
const offlineResonList = ref([])
//
function submitData(){
proxy.$modal.loading('加载中')
loading.value = true
productOfflineApi.changeStatus(paramData.value).then((res) => {
proxy.$modal.closeLoading()
if (res.data) {
proxy.$modal.showToast('成功')
setTimeout(() => {
proxy.$tab.navigateBack()
loading.value = false
}, 1500)
} else {
proxy.$modal.showToast('失败')
loading.value = false
}
}).catch(() => {
proxy.$modal.closeLoading()
loading.value = false
})
}
//
function selectWorker() {
showWorker.value = true
}
//
function selectType() {
showType.value = true
}
//
function selectReson() {
showReason.value = true
}
//
function confirmSelectWorker(val){
console.log(val)
handleWorker.value = val[1]
}
//
function confirmSelectType(val){
console.log(val)
handleType.value = val[0]
}
//
function confirmSelectReson(val){
console.log(val)
handleOfflineReson.value = val[0]
}
//
function handleSubmit(){
proxy.$modal.confirm('确定提交处理吗').then(() => {
paramData.value.status = 2
paramData.value.checkPersonCode = handleWorker.value.value//
paramData.value.handleResult = handleResult.value.value//
paramData.value.handleType = handleType.value.value//
submitData()
})
}
onLoad((option) => {
if (option.obj) {
paramData.value = JSON.parse(decodeURIComponent(option.obj)); // paramData
}
if (option.type) type.value = option.type;
if (option.from) from.value = option.from;
if (option.number) {
number.value = option.number;
}
})
onShow(() => {
getPageChildren()
getDictReson()
getDictType()
})
//
async function getDictType(){
await dictApi.getDict("offline_handle_type").then((res) => {
proxy.$modal.closeLoading()
if (res) {
console.log(typeList.value)
typeList.value = res
} else {
}
}).catch(() => {
})
}
//
async function getDictReson(){
await dictApi.getDict("offline_reason").then((res) => {
proxy.$modal.closeLoading()
if (res) {
offlineResonList.value = res
} else {
}
}).catch(() => {
})
}
//
function getPageChildren(){
productOfflineApi.getPageChildren(params.value).then((res) => {
console.log(res)
if (res.data) {
console.log(res.data)
workerList.value = res.data
} else {
}
}).catch(() => {
})
}
</script>
<style lang="scss" scoped>
.detail-container {
min-height: 100vh;
background: white;
}
.line {
background: #f5f5f5;
height: 20rpx;
}
.info {
background: white;
}
.tab {
border-bottom: 1px solid #e4e4e4;
}
.title {
display: flex;
align-items: center;
padding: 20rpx 30rpx;
border-bottom: 1px solid #e4e4e4;
view {
&:nth-child(1) {
flex: 1;
border-left: 10rpx solid #409eff;
padding-left: 20rpx;
font-weight: bold;
}
}
}
.dec {
padding: 30rpx;
.dec-item {
padding-bottom: 30rpx;
display: flex;
view {
&:nth-child(1) {
width: 180rpx;
}
&:nth-child(2) {
color: #888888;
flex: 1;
width: 0px;
word-wrap: break-word;
}
}
}
}
.dec2 {
padding: 10rpx 30rpx;
display: flex;
view {
&:nth-child(1) {
width: 180rpx;
}
&:nth-child(2) {
color: #888888;
flex: 1;
width: 0px;
word-wrap: break-word;
}
}
}
.items {
border-radius: 12rpx;
background: #F5F5F5;
padding-bottom: 20rpx;
.items-name {
padding: 20rpx;
border-bottom: 1px solid #dedede;
}
.items-dec {
padding: 0px 20rpx;
margin-top: 20rpx;
}
}
.list {
padding: 20rpx;
.item {
display: flex;
margin-bottom: 20rpx;
.item-box {
border-radius: 12rpx;
border: 1px solid #dedede;
border-radius: 12rpx;
flex: 1;
width: 0rpx;
}
.spare-title {
padding: 20rpx 30rpx;
border-bottom: 1px solid #e4e4e4;
display: flex;
.title-txt {
color: #409eff;
font-size: 30rpx;
font-weight: bold;
flex: 1;
}
}
.dec {
color: #9c9c9c;
padding: 0rpx 30rpx 20rpx;
}
}
}
.add-btn {
display: flex;
justify-content: flex-start;
align-items: center;
}
.footer {
position: fixed;
bottom: 0px;
left: 0px;
width: 100%;
z-index: 22;
}
.btns {
display: flex;
button {
flex: 1;
}
.sure {
background: #409eff;
color: white;
border-radius: 0px;
&::after {
border: 1px solid #409eff;
border-radius: 0px;
}
}
.reset {
background: #ff7a45;
border-radius: 0px;
&::after {
border-radius: 0px;
}
}
}
</style>

279
src/pages/mes/productOffline/index.vue

@ -0,0 +1,279 @@
<template>
<!-- 列表展示标准模版 -->
<view class="container">
<view>
<u-subsection :list="tabsList" v-model="current" @change="tabsChange"></u-subsection>
</view>
<view class="list">
<view class="item" v-for="(item,index) in list" :key="index" @click="openDetail(item)">
<view class="title">
<view class="title-txt">
{{item.offlineCode}}
</view>
<view class="time">
{{`${$time.formatDate(item.createTime)}`}}
</view>
</view>
<view class="dec">
<view>登记状态</view>
<view>
<u-tag text="待处理" type="warning" mode="light" shape="circle" v-if="item.status==1" :style="{ width: '62px' }" />
<u-tag text="已处理" type="success" mode="light" shape="circle" v-if="item.status==2" :style="{ width: '62px' }" />
</view>
</view>
<view class="dec">
<view>计划编码</view><view>{{item.planCode}}</view>
</view>
<view class="dec">
<view>工单编码</view><view>{{item.workBillno}}</view>
</view>
<view class="dec">
<view>产品编码</view><view>{{item.productCode}}</view>
</view>
<view class="dec">
<view>工序编码</view><view>{{item.processCode}}</view>
</view>
<view class="dec">
<view>工位编码</view><view>{{item.stationCode}}</view>
</view>
<view class="dec">
<view v-if="item.status==1">
<u-button size="medium" type="warning" @click="handleItem(item)" >去处理</u-button>
</view>
<view v-if="item.status==2">
<u-button size="medium" type="success" @click="backProduct(item)" >返线处理</u-button>
</view>
</view>
</view>
<view style="height: 94rpx;padding-top: 30rpx;">
<u-loadmore :status="status" v-if="status != 'loadmore'" />
</view>
</view>
<view style="height: constant(safe-area-inset-bottom); height: env(safe-area-inset-bottom);"></view>
<requestButton @goScan='openScanDetailPopup'></requestButton>
</view>
<u-popup v-model="showWorker" mode="bottom" border-radius="14" length="30%">
<view>
<u-select v-model="showWorker" mode="mutil-column-auto" :list="workerList" @confirm="confirmSelectWorker"></u-select>
</view>
</u-popup>
</template>
<script setup lang="ts">
import requestButton from '@/mycomponents/button/requestButton.vue'
/*初始化*/
import {
onLoad,
onShow,
onReachBottom
} from '@dcloudio/uni-app'
import {
ref,
getCurrentInstance
} from 'vue'
/*引入API*/
import * as productOfflineApi from "@/api/mes/productOffline/productOfflineApi.ts"
const { proxy } = getCurrentInstance()
const tabsList = ref([{name:'待处理'},{name:'已处理'}])
const showWorker = ref(false)
const workerList = ref([])
const current = ref(0)
/*分页参数*/
const params = ref({
pageNo: 1,
pageSize: 10,
flag:null,
status: 1
})
const backlineItem = ref({
offlineCode:'',
workBillno:'',
planCode:'',
processCode:'',
productCode:'',
stationCode:'',
operCode:'',
})
/*是否显示"没有更多了"*/
const status = ref('loadmore')
/*列表数据集*/
const list = ref([])
/*列表调用API方法*/
async function getList() {
if (status.value == 'nomore') return;
status.value = 'loading';
proxy.$modal.loading('加载中')
await productOfflineApi.getPage(params.value).then((res) => {
proxy.$modal.closeLoading()
if (res.data.list.length > 0) {
list.value = list.value.concat(res.data.list);
params.value.pageNo++;
status.value = 'loadmore'
} else {
status.value = 'nomore'
}
}).catch(() => {
proxy.$modal.closeLoading()
})
}
//
function handleItem(index){
const objString = JSON.stringify(index);
proxy.$tab.navigateTo(`/pages/mes/productOffline/handle?obj=${encodeURIComponent(objString)}`)
proxy.$modal.loading('正在打开详情页')
setTimeout(function() {
proxy.$modal.closeLoading();
}, 500);
}
// 线
function backProduct(index){
console.log(index.offlineCode)
backlineItem.value.offlineCode = index.offlineCode
backlineItem.value.workBillno = index.workBillno
backlineItem.value.planCode = index.planCode
backlineItem.value.processCode = index.processCode
backlineItem.value.stationCode = index.stationCode
backlineItem.value.productCode = index.productCode
showWorker.value = true
}
// tabs
function tabsChange(curr){
current.value = curr
params.value.status = (curr + 1)
params.value.pageNo = 1
params.value.pageSize = 5
list.value = []
status.value = 'loadmore'
getList();
}
/*打开详情页*/
function openDetail(item) {
if(item.ststus==2){
const objString = JSON.stringify(item);
proxy.$tab.navigateTo(`/pages/mes/productOffline/detail?obj=${encodeURIComponent(objString)}`)
proxy.$modal.loading('正在打开详情页')
setTimeout(function() {
proxy.$modal.closeLoading();
}, 500);
}
}
//
function openScanDetailPopup() {
proxy.$tab.navigateTo(`/pages/mes/productOffline/createProductOffline`)
proxy.$modal.loading('正在打开')
setTimeout(function() {
proxy.$modal.closeLoading();
}, 500);
}
/*通用方法*/
onShow(() => {
params.value.pageNo = 1
list.value = []
status.value = 'loadmore'
getList()
getPageChildren()
})
onReachBottom(() => {
getList()
})
//
function getPageChildren(){
productOfflineApi.getPageChildren(params.value).then((res) => {
console.log(res)
if (res.data) {
console.log(res.data)
workerList.value = res.data
} else {
}
}).catch(() => {
})
}
//
function confirmSelectWorker(val){
console.log(val)
backlineItem.value.operCode = val[1].value
console.log(backlineItem.value)
//
// handleBackline()
}
//
function handleBackline(){
proxy.$modal.loading('加载中')
productOfflineApi.create(backlineItem.value).then((res) => {
proxy.$modal.closeLoading()
if (res.data) {
proxy.$modal.showToast('成功')
setTimeout(() => {
proxy.$tab.navigateBack()
}, 1500)
} else {
proxy.$modal.showToast('失败')
}
}).catch(() => {
proxy.$modal.closeLoading()
})
}
</script>
<style lang="scss" scoped>
.container{
background: #f5f5f5;
min-height: 100vh;
}
.list {
background: #f5f5f5;
margin-top: 20rpx;
.item {
padding: 30rpx 30rpx 0px 30rpx;
margin-top: 20rpx;
background: white;
position: relative;
.title {
display: flex;
align-items: center;
padding-bottom: 20rpx;
.title-txt {
color: #409eff;
font-weight: bold;
font-size: 36rpx;
width: 0px;
flex: 1;
word-wrap: break-word;
}
.time {
color: #919191;
}
}
.dec {
padding-bottom: 20rpx;
display: flex;
align-items: center;
view {
&:nth-child(1){
width: 160rpx;;
}
&:nth-child(2){
color: #999999;
flex: 1;
width: 0px;
word-wrap: break-word;
}
}
}
.last {
padding-bottom: 30rpx;
}
.bottom {
display: flex;
justify-content: space-between;
align-items: center;
border-top: 1px solid #E4E4E4;
padding: 20rpx 0px;
height: 90rpx;
}
}
}
</style>

267
src/pages/mes/reworkBatch/create.vue

@ -0,0 +1,267 @@
<template>
<!-- 列表展示标准模版 -->
<view>
<u-form :model="form">
<view>
<u-form-item label="批次号" prop="batchNo">
<view>
<u-input v-model="form.batchNo" placeholder="请输入批次号"/>
</view>
</u-form-item>
</view>
<view>
<u-form-item label="产品编码" prop="productionCode">
<view>
<!-- <u-input v-model="form.productName" type="select" @click="showProduct = true" placeholder="请选择产品编码"/> -->
<u-input v-model="form.productionCode" placeholder="请输入批次号"/>
</view>
</u-form-item>
</view>
<view>
<u-form-item label="产品数量" prop="productionCount">
<view>
<!-- <u-input v-model="form.productName" type="select" @click="showProduct = true" placeholder="请选择产品编码"/> -->
<u-input v-model="form.productionCount" type="number" placeholder="请输入数量"/>
</view>
</u-form-item>
</view>
<view>
<u-form-item label="工作类型" prop="reworkTypeName">
<view>
<u-input v-model="form.reworkTypeName" type="select" @click="showReworkType = true" placeholder="请选择工作类型"/>
</view>
</u-form-item>
</view>
<view>
<u-form-item label="是否替换" prop="replaceFlagName">
<view>
<u-input v-model="form.replaceFlagName" type="select" @click="showReplaceFlag = true" placeholder="请选择是否有替换件"/>
<!-- <u-input v-model="form.productCode" disabled="true"/> -->
</view>
</u-form-item>
</view>
<view>
<u-form-item label="返修动作" prop="reworkAction">
<view>
<u-input v-model="form.reworkAction" placeholder="请输入返修动作"/>
</view>
</u-form-item>
</view>
<view>
<u-form-item label="返修人员" prop="reworkPersoncode">
<view>
<u-input v-model="form.reworkPersoncode" placeholder="请输入返修人员"/>
</view>
</u-form-item>
</view>
<view>
<u-form-item label="返修时间" prop="reworkStr" >
<view>
<u-input v-model="form.reworkStr" type="select" @click="showReworkTime = true" placeholder="请选择返修时间"/>
</view>
</u-form-item>
</view>
</u-form>
<view class="footer">
<view class="btns">
<button class="sure" @click="handleSubmit" :loading='loading' :disabled='loading'>提交处理</button>
</view>
<view style="height: constant(safe-area-inset-bottom); height: env(safe-area-inset-bottom);"></view>
</view>
<view style="height: constant(safe-area-inset-bottom); height: env(safe-area-inset-bottom);"></view>
</view>
<view>
<u-select v-model="showProduct" :list="productList" @confirm="selectProduct"></u-select>
</view>
<view>
<u-select v-model="showReworkType" :list="reworkTypeList" @confirm="selectReworkType"></u-select>
</view>
<view>
<u-select v-model="showReplaceFlag" :list="replaceFlagList" @confirm="selectReplaceFlag"></u-select>
</view>
<view>
<u-picker v-model="showReworkTime" mode="time" :params="reworkTimeParams" @confirm="selectReworkTime"></u-picker>
</view>
</template>
<script setup lang="ts">
/*初始化*/
import {
onLoad,
onShow,
onReachBottom
} from '@dcloudio/uni-app'
import {
ref,
getCurrentInstance
} from 'vue'
/*引入API*/
import * as reworkBatchApi from "@/api/mes/reworkBatch/reworkBatchApi.ts"
const { proxy } = getCurrentInstance()
const loading = ref(false)
const showProduct = ref(false)
const showReworkType = ref(false)
const showReplaceFlag = ref(false)
const showReworkTime = ref(false)
const paramData = ref()
const productList = ref([{label:'产品1',value: '111',name:'产品'},{label:'产品2',value: '222',name:'产品'}])
const reworkTypeList = ref([{label:'返工',value: '1'},{label:'返修',value: '2'}])
const replaceFlagList = ref([{label:'是',value: '1'},{label:'否',value: '2'}])
const reworkTimeParams =ref({
year: true,
month: true,
day: true,
hour: false,
minute: false,
second: false,
timestamp: true,
})
const form = ref({
reworkAction:'',
reworkPersoncode:'',
processCode:'',
productionCode:'',
productName:'',
stationCode:'',
offlineReson:'',
productDestination:'',
reworkType:'',
reworkTypeName:'',
replaceFlag:'',
replaceFlagName:'',
reworkTime:'',
reworkStr:'',
batchNo:'',
productionCount:''
})
//
function handleSubmit(){
//
if(form.value.productionCode=='' && form.value.productionCode.trim() == ''){
proxy.$modal.showToast('请先选择产品')
return
}
if(form.value.reworkType=='' && form.value.reworkType.trim() == ''){
proxy.$modal.showToast('请先选择工作类型')
return
}
if(form.value.replaceFlag =='' && form.value.replaceFlag.trim() == ''){
proxy.$modal.showToast('请先选择是否有替换件')
return
}
//
proxy.$modal.confirm('确定提交处理吗').then(() => {
proxy.$modal.loading('加载中')
loading.value = true
reworkBatchApi.create(form.value).then((res) => {
proxy.$modal.closeLoading()
if (res.data) {
proxy.$modal.showToast('成功')
setTimeout(() => {
proxy.$tab.navigateBack()
loading.value = false
proxy.$modal.closeLoading()
}, 1000)
} else {
proxy.$modal.showToast('失败')
loading.value = false
proxy.$modal.closeLoading()
}
}).catch(() => {
proxy.$modal.closeLoading()
loading.value = false
})
})
}
//
function selectProduct(index){
form.value.productionCode = index[0].value
form.value.productName = index[0].label
showProduct.value = false
}
//
function selectReworkType(index){
form.value.reworkType = index[0].value
form.value.reworkTypeName = index[0].label
showReworkType.value = false
}
//
function selectReplaceFlag(index){
form.value.replaceFlag = index[0].value
form.value.replaceFlagName = index[0].label
showReplaceFlag.value = false
}
//
function selectReworkTime(index){
const dateStr = `${index.year}-${index.month}-${index.day}`
form.value.reworkStr = dateStr
form.value.reworkTime = index.timestamp
console.log(form.value.reworkTime)
showReworkTime.value = false
}
/*通用方法*/
onLoad((option) => {
if (option.obj) {
paramData.value = JSON.parse(decodeURIComponent(option.obj)); // paramData
form.value.processCode = paramData.value.workingNode
form.value.stationCode = paramData.value.currentWorkstation
form.value.productionCode = paramData.value.currentWorkstation
}
})
onShow(() => {
// params.value.pageNo = 1
// list.value = []
// status.value = 'loadmore'
})
onReachBottom(() => {
// getList()
})
</script>
<style lang="scss" scoped>
.footer {
position: fixed;
bottom: 0px;
left: 0px;
width: 100%;
z-index: 22;
}
.btns {
display: flex;
button {
flex: 1;
}
.sure {
background: #409eff;
color: white;
border-radius: 0px;
&::after {
border: 1px solid #409eff;
border-radius: 0px;
}
}
.reset {
background: #ff7a45;
border-radius: 0px;
&::after {
border-radius: 0px;
}
}
}
</style>

326
src/pages/mes/reworkBatch/index.vue

@ -0,0 +1,326 @@
<template>
<!-- 列表展示标准模版 -->
<view class="container">
<view>
<u-subsection :list="tabsList" v-model="current" @change="tabsChange"></u-subsection>
<!-- <u-tabs-swiper :list="tabsList" :is-scroll="true" :current="current" @change="tabsChange"></u-tabs-swiper> -->
</view>
<view class="list">
<view class="item" v-for="(item,index) in list" :key="index" @click="openDetail(item)">
<view class="title">
<view class="title-txt">
{{item.reworkbillNo}}
</view>
<view class="time">
{{`${$time.formatDate(item.createTime)}`}}
</view>
</view>
<view class="dec">
<view>处理状态</view>
<view>
<u-tag text="待处理" type="warning" mode="light" shape="circle" v-if="item.status==1" :style="{ width: '65px' }" />
<!-- <u-tag text="处理中" type="primary" mode="light" shape="circle" v-if="item.status==2" :style="{ width: '65px' }" /> -->
<u-tag text="已完成" type="success" mode="light" shape="circle" v-if="item.status==2" :style="{ width: '65px' }" />
</view>
</view>
<view class="dec">
<view>批次号</view><view>{{item.batchNo}}</view>
</view>
<view class="dec">
<view>产品编码</view><view>{{item.productionCode}}</view>
</view>
<view class="dec">
<view>产品数量</view><view>{{item.productionCount}}</view>
</view>
<view class="dec">
<view>工作类型</view><view>{{item.status == '1'?'返工' :'返修'}}</view>
</view>
<view class="dec">
<view>是否有替换件</view><view>{{item.replaceFlag == 'TRUE'?'是' :'否'}}</view>
</view>
<view class="dec">
<view>返修人员</view><view>{{item.reworkPersoncode}}</view>
</view>
<view class="dec" v-if="item.status!=1">
<view>返修时间</view><view> {{`${$time.formatDate(item.reworkTime)}`}}</view>
</view>
<view class="dec" v-if="item.status==3">
<view>返修结果</view><view>{{item.reworkResult}}</view>
</view>
<view class="dec">
<view v-if="item.status==1">
<u-button size="medium" type="primary" @click="handleItem(item)" >去处理</u-button>
</view>
<view v-if="item.status==2">
<u-button size="medium" type="error" @click="handleRefuse(item)" >退回</u-button>
<!-- <u-button size="medium" type="warning" @click="handleSuspend(item)" >终止</u-button>
<u-button size="medium" type="success" @click="handleSuccess(item)" >完成</u-button> -->
</view>
<view v-if="item.status==3">
<u-button size="medium" type="error" @click="handleRefuse(item)" >退回</u-button>
</view>
</view>
</view>
<view style="height: 94rpx;padding-top: 30rpx;">
<u-loadmore :status="status" v-if="status != 'loadmore'" />
</view>
</view>
<view style="height: constant(safe-area-inset-bottom); height: env(safe-area-inset-bottom);"></view>
<requestButton @goScan='openScanDetailPopup'></requestButton>
</view>
<u-popup v-model="showType" mode="bottom" border-radius="14" length="30%">
<view style="margin-top: 30px; margin-left: 30px;">
<u-input v-model="reworkPersoncode" placeholder="请输入返工返修人员" />
</view>
<view class="btns">
<u-button class="sure" @click="handleReceive">确定</u-button>
</view>
</u-popup>
</template>
<script setup lang="ts">
import requestButton from '@/mycomponents/button/requestButton.vue'
/*初始化*/
import {
onLoad,
onShow,
onReachBottom
} from '@dcloudio/uni-app'
import {
ref,
getCurrentInstance
} from 'vue'
/*引入API*/
import * as reworkBatchApi from "@/api/mes/reworkBatch/reworkBatchApi.ts"
const { proxy } = getCurrentInstance()
const paramData = ref()
// const tabsList = ref([{name:''},{name:''},{name:''}])
const tabsList = ref([{name:'待处理'},{name:'已完成'}])
const reworkPersoncode = ref()
const showType = ref(false)
const current = ref(0)
/*分页参数*/
const params = ref({
pageNo: 1,
pageSize: 10,
status: 1
})
/*是否显示"没有更多了"*/
const status = ref('loadmore')
/*列表数据集*/
const list = ref([])
/*列表调用API方法*/
async function getList() {
if (status.value == 'nomore') return;
status.value = 'loading';
proxy.$modal.loading('加载中')
await reworkBatchApi.getPage(params.value).then((res) => {
proxy.$modal.closeLoading()
if (res.data.list.length > 0) {
list.value = list.value.concat(res.data.list);
params.value.pageNo++;
status.value = 'loadmore'
} else {
status.value = 'nomore'
}
}).catch(() => {
proxy.$modal.closeLoading()
})
}
//
function handleItem(index){
reworkPersoncode.value = null
paramData.value = index
showType.value = true
}
//
function handleReceive(){
if(reworkPersoncode.value != '' && reworkPersoncode.value.trim() != ''){
paramData.value.reworkPersoncode=reworkPersoncode.value
changeStatus(2)
showType.value = false
}
else{
proxy.$modal.showToast('请输入返修人员')
reworkPersoncode.value = null
}
}
//
function handleSuspend(index){
proxy.$modal.confirm('确定提交吗').then(() => {
paramData.value = index
changeStatus(1)
})
}
//
function handleSuccess(index){
proxy.$modal.confirm('确定提交吗').then(() => {
paramData.value = index
changeStatus(3)
})
}
//
function handleRefuse(index){
proxy.$modal.confirm('确定提交吗').then(() => {
paramData.value = index
changeStatus(1)
})
}
//
function changeStatus(val){
paramData.value.status = val
proxy.$modal.loading('加载中')
reworkBatchApi.update(paramData.value).then((res) => {
proxy.$modal.closeLoading()
if (res.data) {
list.value=[]
proxy.$modal.showToast('成功')
setTimeout(() => {
proxy.$modal.closeLoading()
params.value.pageNo = 1
params.value.pageSize = 5
getList();
}, 500)
} else {
proxy.$modal.showToast('失败')
proxy.$modal.closeLoading()
}
}).catch(() => {
proxy.$modal.closeLoading()
})
}
function tabsChange(curr){
current.value = curr
params.value.status = (curr + 1)
params.value.pageNo = 1
params.value.pageSize = 5
list.value = []
status.value = 'loadmore'
getList();
}
/*打开详情页*/
function openDetail(item) {
if(item.ststus==3){
// const objString = JSON.stringify(item);
// proxy.$tab.navigateTo(`/pages/mes/reworkSingle/detail?obj=${encodeURIComponent(objString)}`)
// proxy.$modal.loading('')
// setTimeout(function() {
// proxy.$modal.closeLoading();
// }, 500);
}
}
function openScanDetailPopup() {
proxy.$tab.navigateTo(`/pages/mes/reworkBatch/create`)
proxy.$modal.loading('正在打开')
setTimeout(function() {
proxy.$modal.closeLoading();
}, 500);
}
/*通用方法*/
onShow(() => {
params.value.pageNo = 1
list.value = []
status.value = 'loadmore'
getList()
})
onReachBottom(() => {
getList()
})
</script>
<style lang="scss" scoped>
.container{
background: #f5f5f5;
min-height: 100vh;
}
.list {
background: #f5f5f5;
margin-top: 20rpx;
.item {
padding: 30rpx 30rpx 0px 30rpx;
margin-top: 20rpx;
background: white;
position: relative;
.title {
display: flex;
align-items: center;
padding-bottom: 20rpx;
.title-txt {
color: #409eff;
font-weight: bold;
font-size: 36rpx;
width: 0px;
flex: 1;
word-wrap: break-word;
}
.time {
color: #919191;
}
}
.dec {
padding-bottom: 20rpx;
display: flex;
align-items: center;
view {
&:nth-child(1){
width: 160rpx;;
}
&:nth-child(2){
color: #999999;
flex: 1;
width: 0px;
word-wrap: break-word;
}
}
}
.last {
padding-bottom: 30rpx;
}
.bottom {
display: flex;
justify-content: space-between;
align-items: center;
border-top: 1px solid #E4E4E4;
padding: 20rpx 0px;
height: 90rpx;
}
}
}
.btns {
display: flex;
button {
flex: 1;
}
.sure {
background: #409eff;
color: white;
border-radius: 0px;
margin-top: 60px;
&::after {
border: 1px solid #409eff;
border-radius: 0px;
}
}
.reset {
background: #ff7a45;
border-radius: 0px;
&::after {
border-radius: 0px;
}
}
}
</style>

303
src/pages/mes/reworkSingle/create.vue

@ -0,0 +1,303 @@
<template>
<!-- 列表展示标准模版 -->
<view>
<u-form :model="form">
<view>
<u-form-item label="产品编码" prop="productCode">
<view>
<!-- <u-input v-model="form.productName" type="select" @click="showProduct = true" placeholder="请选择产品编码"/> -->
<u-input v-model="form.productCode" />
</view>
</u-form-item>
</view>
<view>
<u-form-item label="工作类型" prop="reworkTypeName">
<view>
<u-input v-model="form.reworkTypeName" type="select" @click="showReworkType = true" placeholder="请选择工作类型"/>
</view>
</u-form-item>
</view>
<view>
<u-form-item label="是否替换" prop="replaceFlagName">
<view>
<u-input v-model="form.replaceFlagName" type="select" @click="showReplaceFlag = true" placeholder="请选择是否有替换件"/>
</view>
</u-form-item>
</view>
<view>
<u-form-item label="返修动作" prop="reworkAction">
<view>
<u-input v-model="form.reworkAction" placeholder="请输入返修动作"/>
</view>
</u-form-item>
</view>
<view>
<u-form-item label="返修人员" prop="reworkPersoncode">
<view>
<u-input v-model="form.reworkPersoncode" placeholder="请输入返修人员"/>
</view>
</u-form-item>
</view>
<view>
<u-form-item label="返修时间" prop="reworkStr" >
<view>
<u-input v-model="form.reworkStr" type="select" @click="showReworkTime = true" placeholder="请选择返修时间"/>
</view>
</u-form-item>
</view>
</u-form>
<view class="footer">
<view class="btns">
<button class="sure" @click="handleSubmit" :loading='loading' :disabled='loading'>提交处理</button>
</view>
<view style="height: constant(safe-area-inset-bottom); height: env(safe-area-inset-bottom);"></view>
</view>
<view style="height: constant(safe-area-inset-bottom); height: env(safe-area-inset-bottom);"></view>
</view>
<view>
<u-select v-model="showProduct" :list="productList" @confirm="selectProduct"></u-select>
</view>
<view>
<u-select v-model="showReworkType" :list="reworkTypeList" @confirm="selectReworkType"></u-select>
</view>
<view>
<u-select v-model="showReplaceFlag" :list="replaceFlagList" @confirm="selectReplaceFlag"></u-select>
</view>
<view>
<u-picker v-model="showReworkTime" mode="time" :params="reworkTimeParams" @confirm="selectReworkTime"></u-picker>
</view>
</template>
<script setup lang="ts">
import requestButton from '@/mycomponents/button/requestButton.vue'
/*初始化*/
import {
onLoad,
onShow,
onReachBottom
} from '@dcloudio/uni-app'
import {
ref,
getCurrentInstance
} from 'vue'
/*引入API*/
import * as reworkSingleApi from "@/api/mes/reworkSingle/reworkSingleApi.ts"
const { proxy } = getCurrentInstance()
const loading = ref(false)
/*列表数据集*/
const list = ref([])
const productItem = ref()
const showProduct = ref(false)
const showReworkType = ref(false)
const showReplaceFlag = ref(false)
const showReworkTime = ref(false)
const paramData = ref()
const productList = ref([{label:'产品1',value: '111',name:'产品'},{label:'产品2',value: '222',name:'产品'}])
const reworkTypeList = ref([{label:'返工',value: '1'},{label:'返修',value: '2'}])
const replaceFlagList = ref([{label:'是',value: '1'},{label:'否',value: '2'}])
const reworkTimeParams =ref({
year: true,
month: true,
day: true,
hour: false,
minute: false,
second: false,
timestamp: true,
})
const form = ref({
reworkAction:'',
reworkPersoncode:'',
processCode:'',
productCode:'',
productName:'',
stationCode:'',
offlineReson:'',
productDestination:'',
reworkType:'',
reworkTypeName:'',
replaceFlag:'',
replaceFlagName:'',
reworkTime:'',
reworkStr:''
})
/*分页参数*/
const params = ref({
pageNo: 1,
pageSize: 50,
flagDo:3
})
//
function handleSubmit(){
//
if(form.value.productCode=='' && form.value.productCode.trim() == ''){
proxy.$modal.showToast('请先选择产品')
return
}
if(form.value.reworkType=='' && form.value.reworkType.trim() == ''){
proxy.$modal.showToast('请先选择工作类型')
return
}
if(form.value.replaceFlag =='' && form.value.replaceFlag.trim() == ''){
proxy.$modal.showToast('请先选择是否有替换件')
return
}
//
proxy.$modal.confirm('确定提交处理吗').then(() => {
proxy.$modal.loading('加载中')
loading.value = true
reworkSingleApi.create(form.value).then((res) => {
proxy.$modal.closeLoading()
if (res.data) {
proxy.$modal.showToast('成功')
setTimeout(() => {
proxy.$tab.navigateBack()
loading.value = false
proxy.$modal.closeLoading()
}, 1000)
} else {
proxy.$modal.showToast('失败')
loading.value = false
proxy.$modal.closeLoading()
}
}).catch(() => {
proxy.$modal.closeLoading()
loading.value = false
})
})
}
//
function selectProduct(index){
form.value.productCode = index[0].value
form.value.productName = index[0].label
showProduct.value = false
}
//
function selectReworkType(index){
form.value.reworkType = index[0].value
form.value.reworkTypeName = index[0].label
showReworkType.value = false
}
//
function selectReplaceFlag(index){
form.value.replaceFlag = index[0].value
form.value.replaceFlagName = index[0].label
showReplaceFlag.value = false
}
//
function selectReworkTime(index){
const dateStr = `${index.year}-${index.month}-${index.day}`
form.value.reworkStr = dateStr
form.value.reworkTime = index.timestamp
console.log(form.value.reworkTime)
showReworkTime.value = false
}
function getworkSchedulingPage() {
reworkSingleApi.getworkSchedulingPage(params.value).then((res) => {
proxy.$modal.closeLoading()
if (res.data.list.length > 0) {
list.value = res.data.list
productList.value = transList(res.data.list)
} else {
proxy.$modal.closeLoading()
}
}).catch(() => {
proxy.$modal.closeLoading()
})
}
function transList(data) {
const productList = data.map(item => {
return {
"label": item.productName,
"value": item.productCode
};
});
return productList;
}
function findProductByCode(productCode) {
productItem.value = list.value.find(item => item.productCode === productCode);
form.value.workBillno = productItem.value.schedulingCode
form.value.planCode = productItem.value.planMaserCode
form.value.processCode = productItem.value.workingNode
form.value.stationCode = productItem.value.currentWorkstation
}
/*是否显示"没有更多了"*/
// const status = ref('loadmore')
/*通用方法*/
onLoad((option) => {
if (option.obj) {
paramData.value = JSON.parse(decodeURIComponent(option.obj)); // paramData
form.value.workBillno = paramData.value.schedulingCode
form.value.planCode = paramData.value.planMaserCode
form.value.processCode = paramData.value.workingNode
form.value.stationCode = paramData.value.currentWorkstation
form.value.productCode = paramData.value.currentWorkstation
}
})
onShow(() => {
// params.value.pageNo = 1
// list.value = []
// status.value = 'loadmore'
// getworkSchedulingPage()
})
onReachBottom(() => {
// getList()
})
</script>
<style lang="scss" scoped>
.footer {
position: fixed;
bottom: 0px;
left: 0px;
width: 100%;
z-index: 22;
}
.btns {
display: flex;
button {
flex: 1;
}
.sure {
background: #409eff;
color: white;
border-radius: 0px;
&::after {
border: 1px solid #409eff;
border-radius: 0px;
}
}
.reset {
background: #ff7a45;
border-radius: 0px;
&::after {
border-radius: 0px;
}
}
}
</style>

349
src/pages/mes/reworkSingle/handle.vue

@ -0,0 +1,349 @@
<template>
<!-- 详情 -->
<view class="detail-container">
<view class="info">
<view class="title">
<view>领取</view>
</view>
<!-- 主数据 -->
<view class="dec">
<view class="dec-item" @click="selectType">
<view>工作类型</view>
<view>{{reworkType.label}}</view>
</view>
<view class="dec-item" @click="selectWorker" >
<view>返修人员</view>
<view>{{handleWorker.label}}</view>
</view>
<view class="dec-item" >
<view>返修人员</view>
<!-- <view>{{handleOfflineReson.label}}</view> -->
<view><u-input v-model="reworkPersoncode" placeholder="请输入返修人员" /></view>
</view>
</view>
</view>
<view class="footer">
<view class="btns">
<button class="sure" @click="handleSubmit" :loading='loading' :disabled='loading'>确定领取</button>
</view>
<view style="height: constant(safe-area-inset-bottom); height: env(safe-area-inset-bottom);"></view>
</view>
<view style="height: constant(safe-area-inset-bottom); height: env(safe-area-inset-bottom);"></view>
</view>
<!-- 离线登记人员 弹出层-->
<u-popup v-model="showWorker" mode="bottom" border-radius="14" length="30%">
<view>
<u-select v-model="showWorker" mode="mutil-column-auto" :list="workerList" @confirm="confirmSelectWorker"></u-select>
</view>
</u-popup>
<!-- 工作类型 弹出层-->
<u-popup v-model="showType" mode="bottom" border-radius="14" length="50%">
<view>
<u-select v-model="showType" :list="typeList" @confirm="confirmSelectType"></u-select>
</view>
</u-popup>
</template>
<script setup lang="ts">
import {
onLoad,
onShow
} from '@dcloudio/uni-app'
import {
ref,
getCurrentInstance
} from 'vue'
import * as reworkSingleApi from "@/api/mes/reworkSingle/reworkSingleApi.ts"
import * as dictApi from "@/api/mes/dict/dictApi.ts"
const { proxy } = getCurrentInstance()
const paramData = ref()
const params = ref({
pageNo: 1,
pageSize: 10,
})
const loading = ref(false)
const reworkPersoncode = ref()
//
const showWorker = ref(false)
const showType = ref(false)
const handleWorker = ref({})
const workerList = ref([])
const reworkType = ref({})
const typeList = ref([])
const handleOfflineReson = ref({})
const offlineResonList = ref([])
//
function submitData(){
proxy.$modal.loading('加载中')
loading.value = true
reworkSingleApi.update(paramData.value).then((res) => {
proxy.$modal.closeLoading()
if (res.data) {
proxy.$modal.showToast('成功')
setTimeout(() => {
proxy.$tab.navigateBack()
loading.value = false
}, 1500)
} else {
proxy.$modal.showToast('失败')
loading.value = false
}
}).catch(() => {
proxy.$modal.closeLoading()
loading.value = false
})
}
//
function selectWorker() {
showWorker.value = true
}
function selectType() {
showType.value = true
}
//
function confirmSelectWorker(val){
handleWorker.value = val[1]
}
function confirmSelectType(val){
reworkType.value = val[0]
}
function handleSubmit(){
proxy.$modal.confirm('确定提交吗').then(() => {
paramData.value.status = 2
paramData.value.reworkPersoncode = reworkPersoncode.value.value//
paramData.value.reworkType = reworkType.value.value//
submitData()
})
}
onLoad((option) => {
if (option.obj) {
paramData.value = JSON.parse(decodeURIComponent(option.obj)); // paramData
}
if (option.type) type.value = option.type;
if (option.from) from.value = option.from;
if (option.number) {
number.value = option.number;
}
})
onShow(() => {
getPageChildren()
getDictReson()
getDictType()
})
async function getDictType(){
await dictApi.getDict("rework_type").then((res) => {
proxy.$modal.closeLoading()
if (res) {
console.log(typeList.value)
typeList.value = res
} else {
}
}).catch(() => {
})
}
async function getDictReson(){
await dictApi.getDict("offline_reason").then((res) => {
proxy.$modal.closeLoading()
if (res) {
offlineResonList.value = res
} else {
}
}).catch(() => {
})
}
function getPageChildren(){
productOfflineApi.getPageChildren(params.value).then((res) => {
console.log(res)
if (res.data) {
console.log(res.data)
workerList.value = res.data
} else {
}
}).catch(() => {
})
}
</script>
<style lang="scss" scoped>
.detail-container {
min-height: 100vh;
background: white;
}
.line {
background: #f5f5f5;
height: 20rpx;
}
.info {
background: white;
}
.tab {
border-bottom: 1px solid #e4e4e4;
}
.title {
display: flex;
align-items: center;
padding: 20rpx 30rpx;
border-bottom: 1px solid #e4e4e4;
view {
&:nth-child(1) {
flex: 1;
border-left: 10rpx solid #409eff;
padding-left: 20rpx;
font-weight: bold;
}
}
}
.dec {
padding: 30rpx;
.dec-item {
padding-bottom: 30rpx;
display: flex;
view {
&:nth-child(1) {
width: 180rpx;
}
&:nth-child(2) {
color: #888888;
flex: 1;
width: 0px;
word-wrap: break-word;
}
}
}
}
.dec2 {
padding: 10rpx 30rpx;
display: flex;
view {
&:nth-child(1) {
width: 180rpx;
}
&:nth-child(2) {
color: #888888;
flex: 1;
width: 0px;
word-wrap: break-word;
}
}
}
.items {
border-radius: 12rpx;
background: #F5F5F5;
padding-bottom: 20rpx;
.items-name {
padding: 20rpx;
border-bottom: 1px solid #dedede;
}
.items-dec {
padding: 0px 20rpx;
margin-top: 20rpx;
}
}
.list {
padding: 20rpx;
.item {
display: flex;
margin-bottom: 20rpx;
.item-box {
border-radius: 12rpx;
border: 1px solid #dedede;
border-radius: 12rpx;
flex: 1;
width: 0rpx;
}
.spare-title {
padding: 20rpx 30rpx;
border-bottom: 1px solid #e4e4e4;
display: flex;
.title-txt {
color: #409eff;
font-size: 30rpx;
font-weight: bold;
flex: 1;
}
}
.dec {
color: #9c9c9c;
padding: 0rpx 30rpx 20rpx;
}
}
}
.add-btn {
display: flex;
justify-content: flex-start;
align-items: center;
}
.footer {
position: fixed;
bottom: 0px;
left: 0px;
width: 100%;
z-index: 22;
}
.btns {
display: flex;
button {
flex: 1;
}
.sure {
background: #409eff;
color: white;
border-radius: 0px;
&::after {
border: 1px solid #409eff;
border-radius: 0px;
}
}
.reset {
background: #ff7a45;
border-radius: 0px;
&::after {
border-radius: 0px;
}
}
}
</style>

320
src/pages/mes/reworkSingle/index.vue

@ -0,0 +1,320 @@
<template>
<!-- 列表展示标准模版 -->
<view class="container">
<view>
<u-subsection :list="tabsList" v-model="current" @change="tabsChange"></u-subsection>
<!-- <u-tabs-swiper :list="tabsList" :is-scroll="true" :current="current" @change="tabsChange"></u-tabs-swiper> -->
</view>
<view class="list">
<view class="item" v-for="(item,index) in list" :key="index" @click="openDetail(item)">
<view class="title">
<view class="title-txt">
{{item.reworkbillNo}}
</view>
<view class="time">
{{`${$time.formatDate(item.createTime)}`}}
</view>
</view>
<view class="dec">
<view>处理状态</view>
<view>
<u-tag text="待处理" type="warning" mode="light" shape="circle" v-if="item.status==1" :style="{ width: '65px' }" />
<!-- <u-tag text="处理中" type="primary" mode="light" shape="circle" v-if="item.status==2" :style="{ width: '65px' }" /> -->
<u-tag text="已完成" type="success" mode="light" shape="circle" v-if="item.status==2" :style="{ width: '65px' }" />
</view>
</view>
<view class="dec">
<view>产品编码</view><view>{{item.productionCode}}</view>
</view>
<view class="dec">
<view>工作类型</view><view>{{item.status == '1'?'返工' :'返修'}}</view>
</view>
<view class="dec">
<view>是否有替换件</view><view>{{item.replaceFlag == 'TRUE'?'是' :'否'}}</view>
</view>
<view class="dec">
<view>返修人员</view><view>{{item.reworkPersoncode}}</view>
</view>
<view class="dec" v-if="item.status!=1">
<view>返修时间</view><view>{{`${$time.formatDate(item.reworkTime)}`}}</view>
</view>
<view class="dec" v-if="item.status==3">
<view>返修结果</view><view>{{item.reworkResult}}</view>
</view>
<view class="dec">
<view v-if="item.status==1">
<u-button size="medium" type="primary" @click="handleItem(item)" >去处理</u-button>
</view>
<view v-if="item.status==2">
<u-button size="medium" type="error" @click="handleRefuse(item)" >退回</u-button>
<!-- <u-button size="medium" type="warning" @click="handleSuspend(item)" >终止</u-button>
<u-button size="medium" type="success" @click="handleSuccess(item)" >完成</u-button> -->
</view>
<view v-if="item.status==3">
<u-button size="medium" type="error" @click="handleRefuse(item)" >退回</u-button>
</view>
</view>
</view>
<view style="height: 94rpx;padding-top: 30rpx;">
<u-loadmore :status="status" v-if="status != 'loadmore'" />
</view>
</view>
<view style="height: constant(safe-area-inset-bottom); height: env(safe-area-inset-bottom);"></view>
<requestButton @goScan='openScanDetailPopup'></requestButton>
</view>
<u-popup v-model="showType" mode="bottom" border-radius="14" length="30%">
<view style="margin-top: 30px; margin-left: 30px;">
<u-input v-model="reworkPersoncode" placeholder="请输入返工返修人员" />
</view>
<view class="btns">
<u-button class="sure" @click="handleReceive">确定</u-button>
</view>
</u-popup>
</template>
<script setup lang="ts">
import requestButton from '@/mycomponents/button/requestButton.vue'
/*初始化*/
import {
onLoad,
onShow,
onReachBottom
} from '@dcloudio/uni-app'
import {
ref,
getCurrentInstance
} from 'vue'
/*引入API*/
import * as reworkSingleApi from "@/api/mes/reworkSingle/reworkSingleApi.ts"
const { proxy } = getCurrentInstance()
const paramData = ref()
// const tabsList = ref([{name:''},{name:''},{name:''}])
const tabsList = ref([{name:'待处理'},{name:'已完成'}])
const reworkPersoncode = ref()
const showType = ref(false)
const current = ref(0)
/*分页参数*/
const params = ref({
pageNo: 1,
pageSize: 10,
status: 1
})
/*是否显示"没有更多了"*/
const status = ref('loadmore')
/*列表数据集*/
const list = ref([])
/*列表调用API方法*/
async function getList() {
if (status.value == 'nomore') return;
status.value = 'loading';
proxy.$modal.loading('加载中')
await reworkSingleApi.getPage(params.value).then((res) => {
proxy.$modal.closeLoading()
if (res.data.list.length > 0) {
list.value = list.value.concat(res.data.list);
params.value.pageNo++;
status.value = 'loadmore'
} else {
status.value = 'nomore'
}
}).catch(() => {
proxy.$modal.closeLoading()
})
}
//
function handleItem(index){
reworkPersoncode.value = null
paramData.value = index
showType.value = true
}
//
function handleReceive(){
if(reworkPersoncode.value != '' && reworkPersoncode.value.trim() != ''){
paramData.value.reworkPersoncode=reworkPersoncode.value
changeStatus(2)
showType.value = false
}
else{
proxy.$modal.showToast('请输入返修人员')
reworkPersoncode.value = null
}
}
//
function handleSuspend(index){
proxy.$modal.confirm('确定提交吗').then(() => {
paramData.value = index
changeStatus(1)
})
}
//
function handleSuccess(index){
proxy.$modal.confirm('确定提交吗').then(() => {
paramData.value = index
changeStatus(3)
})
}
//
function handleRefuse(index){
proxy.$modal.confirm('确定提交吗').then(() => {
paramData.value = index
changeStatus(1)
})
}
//
function changeStatus(val){
paramData.value.status = val
proxy.$modal.loading('加载中')
reworkSingleApi.update(paramData.value).then((res) => {
proxy.$modal.closeLoading()
if (res.data) {
list.value=[]
proxy.$modal.showToast('成功')
setTimeout(() => {
proxy.$modal.closeLoading()
params.value.pageNo = 1
params.value.pageSize = 5
getList();
}, 500)
} else {
proxy.$modal.showToast('失败')
proxy.$modal.closeLoading()
}
}).catch(() => {
proxy.$modal.closeLoading()
})
}
function tabsChange(curr){
current.value = curr
params.value.status = (curr + 1)
params.value.pageNo = 1
params.value.pageSize = 5
list.value = []
status.value = 'loadmore'
getList();
}
/*打开详情页*/
function openDetail(item) {
if(item.ststus==3){
// const objString = JSON.stringify(item);
// proxy.$tab.navigateTo(`/pages/mes/reworkSingle/detail?obj=${encodeURIComponent(objString)}`)
// proxy.$modal.loading('')
// setTimeout(function() {
// proxy.$modal.closeLoading();
// }, 500);
}
}
function openScanDetailPopup() {
proxy.$tab.navigateTo(`/pages/mes/reworkSingle/create`)
proxy.$modal.loading('正在打开')
setTimeout(function() {
proxy.$modal.closeLoading();
}, 500);
}
/*通用方法*/
onShow(() => {
params.value.pageNo = 1
list.value = []
status.value = 'loadmore'
getList()
})
onReachBottom(() => {
getList()
})
</script>
<style lang="scss" scoped>
.container{
background: #f5f5f5;
min-height: 100vh;
}
.list {
background: #f5f5f5;
margin-top: 20rpx;
.item {
padding: 30rpx 30rpx 0px 30rpx;
margin-top: 20rpx;
background: white;
position: relative;
.title {
display: flex;
align-items: center;
padding-bottom: 20rpx;
.title-txt {
color: #409eff;
font-weight: bold;
font-size: 36rpx;
width: 0px;
flex: 1;
word-wrap: break-word;
}
.time {
color: #919191;
}
}
.dec {
padding-bottom: 20rpx;
display: flex;
align-items: center;
view {
&:nth-child(1){
width: 160rpx;;
}
&:nth-child(2){
color: #999999;
flex: 1;
width: 0px;
word-wrap: break-word;
}
}
}
.last {
padding-bottom: 30rpx;
}
.bottom {
display: flex;
justify-content: space-between;
align-items: center;
border-top: 1px solid #E4E4E4;
padding: 20rpx 0px;
height: 90rpx;
}
}
}
.btns {
display: flex;
button {
flex: 1;
}
.sure {
background: #409eff;
color: white;
border-radius: 0px;
margin-top: 60px;
&::after {
border: 1px solid #409eff;
border-radius: 0px;
}
}
.reset {
background: #ff7a45;
border-radius: 0px;
&::after {
border-radius: 0px;
}
}
}
</style>

1
src/static/menus/mes/reworkSingle.svg

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1703490945534" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="24847" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><path d="M64 464a34.08 34.08 0 0 1 8-21.44 50.24 50.24 0 0 0-8 26.4z" fill="#3c9cff" p-id="24848"></path><path d="M937.44 288L849.28 100.8A64 64 0 0 0 791.36 64H232.64a64 64 0 0 0-57.92 36.8L86.56 288l-16 35.04A64.96 64.96 0 0 0 64 350.4V896a64 64 0 0 0 64 64h768a64 64 0 0 0 64-64V350.4a64 64 0 0 0-6.08-27.2zM848 912H176a64 64 0 0 1-64-64V361.12a64 64 0 0 1 6.08-27.2l11.84-25.28 75.2-160A64 64 0 0 1 263.04 112h497.92a64 64 0 0 1 57.92 36.8l75.04 160 12 25.28a64 64 0 0 1 6.08 27.2V848a64 64 0 0 1-64 64z" fill="#3c9cff" p-id="24849"></path><path d="M339.2 752l64-80h-128z m266.4-265.44l7.2 4.16-23.68 23.68a66.56 66.56 0 0 0-7.52-3.84A160 160 0 0 0 355.2 656a88.64 88.64 0 0 0 0.96 16h-32a133.92 133.92 0 0 1-0.8-16 192 192 0 0 1 282.24-169.44zM684.8 544l-64 80h128zM418.4 809.44l-7.2-4.16 23.68-23.68a66.56 66.56 0 0 0 7.52 3.84A160 160 0 0 0 668.8 640a88.64 88.64 0 0 0-0.96-16h32a133.44 133.44 0 0 1 0 16 192 192 0 0 1-281.44 169.44z" fill="#3c9cff" p-id="24850"></path><path d="M64 336.16h896v48H64v-48z" fill="#3c9cff" p-id="24851"></path></svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

Loading…
Cancel
Save