全局api请求封装 utils/request.js
import config from '@/utils/config';
// 统一 POST 请求方法示例
const post = (url, data, options = {}) => {
url = config.url + url;
console.log("uni.getStorageSync('token')==========", uni.getStorageSync('token'));
const defaultOptions = {
method: 'POST',
header: {
'Content-Type': 'application/json'
// ,'token': `${uni.getStorageSync('token')}`
}
};
const finalOptions = { ...defaultOptions, ...options };
// 如果服务器需要 token,可以在这里添加 Authorization 头部
if (!finalOptions.header['token'] && uni.getStorageSync('token')) {
finalOptions.header['token'] = `${uni.getStorageSync('token')}`;
}
// if (!finalOptions.header['Authorization'] && uni.getStorageSync('token')) {
// finalOptions.header['Authorization'] = `Bearer ${uni.getStorageSync('token')}`;
// }
console.log('POST 请求参数=====', JSON.stringify(data));
console.log('POST 请求header=====', finalOptions);
console.log('POST url=====', url);
return new Promise((resolve, reject) => {
uni.request({
...finalOptions,
url: url,
data: data,
success: (res) => {
console.log('请示结果=============', res);
if (res.statusCode === 200) {
resolve(res.data);
} else {
reject(new Error(`POST请求失败,状态码:${res.statusCode}`));
uni.showToast({
icon: 'none',
title: `POST请求失败,状态码:${res.statusCode}`
});
}
},
fail: (err) => {
reject(err);
// 网络错误或其他请求失败的情况
uni.showToast({
icon: 'none',
title: 'POST系统异常,请稍后再试'
});
}
});
});
};
// 统一 GET 请求方法示例
const get = (url, data, options = {}) => {
url = config.url + url;
console.log("uni.getStorageSync('token')==========", uni.getStorageSync('token'));
const defaultOptions = {
method: 'GET',
header: {
'Content-Type': 'application/json'
// ,'token': `${uni.getStorageSync('token')}`
}
};
const finalOptions = { ...defaultOptions, ...options };
// 如果服务器需要 token,可以在这里添加 Authorization 头部
if (!finalOptions.header['token'] && uni.getStorageSync('token')) {
finalOptions.header['token'] = `${uni.getStorageSync('token')}`;
}
// if (!finalOptions.header['Authorization'] && uni.getStorageSync('token')) {
// finalOptions.header['Authorization'] = `Bearer ${uni.getStorageSync('token')}`;
// }
console.log('GET 请求header=====', finalOptions);
console.log('GET url=====', url);
console.log('GET 请求参数=====', data);
return new Promise((resolve, reject) => {
uni.request({
...finalOptions,
url: url,
data: data,
success: (res) => {
console.log('GET请示结果=============', res);
if (res.statusCode === 200) {
resolve(res.data);
} else {
reject(new Error(`GET请求失败,状态码:${res.statusCode}`));
uni.showToast({
icon: 'none',
title: `GET请求失败,状态码:${res.statusCode}`
});
}
},
fail: (err) => {
reject(err);
// 网络错误或其他请求失败的情况
uni.showToast({
icon: 'none',
title: 'GET系统异常,请稍后再试'
});
}
});
});
};
export const request = {
post,
get
};
全局变量配置 main.js
import App from './App';
import store from './store';
import request from '@/http/request.js';
// #ifndef VUE3
import Vue from 'vue';
Vue.config.productionTip = false;
Vue.prototype.$store = store;
Vue.prototype.$adpid = '1111111111';
Vue.prototype.$backgroundAudioData = {
playing: false,
playTime: 0,
formatedPlayTime: '00:00:00'
};
Vue.prototype.$request = request;
// 设置全局变量和函数(Vue 2)
Vue.prototype.$globalData = null;
Vue.prototype.$setGlobalData = (data) => {
Vue.prototype.$globalData = data;
};
Vue.prototype.$getGlobalData = () => {
return Vue.prototype.$globalData;
};
Vue.prototype.$globalData2 = null;
Vue.prototype.$setGlobalData2 = (data) => {
Vue.prototype.$globalData2 = data;
};
Vue.prototype.$getGlobalData2 = () => {
return Vue.prototype.$globalData2;
};
Vue.prototype.$globalData3 = null;
Vue.prototype.$setGlobalData3 = (data) => {
Vue.prototype.$globalData3 = data;
};
Vue.prototype.$getGlobalData3 = () => {
return Vue.prototype.$globalData3;
};
App.mpType = 'app';
const app = new Vue({
store,
...App
});
app.$mount();
// #endif
// #ifdef VUE3
import { createSSRApp } from 'vue';
export function createApp() {
const app = createSSRApp(App);
app.use(store);
app.config.globalProperties.$adpid = '1111111111';
app.config.globalProperties.$backgroundAudioData = {
playing: false,
playTime: 0,
formatedPlayTime: '00:00:00'
};
app.config.globalProperties.$request = request;
// 注意:在 Vue 3 中,全局变量和函数应该直接设置在 app.config.globalProperties 上,
// 而不是像 Vue 2 那样通过 Vue.prototype。但是,为了保持一致性,并且能够在组件中
// 通过 this.$xxx 的方式访问,我们仍然可以在这里设置它们。
// 不过,通常建议通过组合式 API 的 getCurrentInstance 来访问这些全局属性。
app.config.globalProperties.$globalData = null;
app.config.globalProperties.$setGlobalData = (data) => {
app.config.globalProperties.$globalData = data;
};
app.config.globalProperties.$getGlobalData = () => {
return app.config.globalProperties.$globalData;
};
app.config.globalProperties.$globalData2 = null;
app.config.globalProperties.$setGlobalData2 = (data) => {
app.config.globalProperties.$globalData2 = data;
};
app.config.globalProperties.$getGlobalData2 = () => {
return app.config.globalProperties.$globalData2;
};
app.config.globalProperties.$globalData3 = null;
app.config.globalProperties.$setGlobalData3 = (data) => {
app.config.globalProperties.$globalData3 = data;
};
app.config.globalProperties.$getGlobalData3 = () => {
return app.config.globalProperties.$globalData3;
};
return {
app
};
}
// #endif
页面级api封装
user.ts
import { request } from '@/utils/request.js';
//1.登录得到code
const LoginByOauth = (data) => {
return request.post('/levault/usrsvr/Usr/LoginByOauth', data);
};
//2.通过code获取Token
const GetTokenFromCode = (data) => {
return request.post('/levault/usrsvr/Usr/GetTokenFromCode', data);
};
export const userApi = {
LoginByOauth,
GetTokenFromCode
};
receiptList.ts
import { request } from '@/utils/request.js';
import config from '@/utils/config';
//收货单分页查询
export const queryPage = (data) => {
return request.post(config.baseUrl + '/ReceiveOrder/queryPage', data);
};
//收货单行查询
export const receiveJobTaskSeach = (data) => {
return request.post(config.baseUrl + '/Tj0ReceiveJobTask/receiveJobTaskSeach', data);
};
//收货异常数量提报
export const receiveAbnormal = (data) => {
return request.post(config.baseUrl + '/Tj0ReceiveJobTask/receiveAbnormal', data);
};
//收货单提交
export const receiveSubmit = (data) => {
return request.post(config.baseUrl + '/Tj0ReceiveJobTask/receiveSubmit', data);
};
vue页面
登录页面vue
<template>
<view>
<view class="uni-common-mt">
<view class="uni-flex uni-column">
<view class="flex-item flex-item-V">
<view class="logo">
<image src="/static/image/uniui-logo.png" style="height:90px;display: none;"></image>
</view>
<view class="logoHead">欢迎使用WMS</view>
</view>
<view class="flex-item flex-item-V">
</view>
<view class="flex-item flex-item-V form">
<form ref="myForm" @submit="formSubmit">
<view class="uni-form-item uni-column">
<uni-easyinput name="loginName" placeholder="请输入账号" prefixIcon="person" value="">
</uni-easyinput>
</view>
<view class="uni-form-item uni-column">
<uni-easyinput name="password" type="password" placeholder="请输入密码" prefixIcon="locked"
value="" @confirm="handlePasswordConfirm ">
</uni-easyinput>
</view>
<view class="uni-btn-v loginBtn">
<button form-type="submit" type="primary" :loading="loginLoading">登 录</button>
</view>
</form>
</view>
</view>
</view>
</view>
</template>
<script setup>
import {
nextTick,
onMounted,
ref
} from 'vue';
import {
userApi
} from "@/api/user";
import graceChecker from "@/common/graceChecker.js";
import CryptoJS from 'crypto-js';
import G from '@/utils/global.js'
const loginLoading = ref(false);
const myForm = ref();
const handlePasswordConfirm = () => {
// myForm.value.submit();
};
const formSubmit = (e) => {
console.log('form发生了submit事件,携带数据为:' + JSON.stringify(e.detail.value))
//定义表单规则
var rule = [{
name: "loginName",
checkType: "string",
checkRule: "1,10",
errorMsg: "请输入1-10位的账号"
},
{
name: "password",
checkType: "string",
checkRule: "3,15",
errorMsg: "请输入3-15密码"
}
];
//进行表单检查
var formData = e.detail.value;
var checkRes = graceChecker.check(formData, rule);
if (checkRes) {
//登录信息
formData.tenantId = "1867144130501541888";
formData.lang = "zh_cn";
formData.industry = null;
formData.password = CryptoJS.SHA256(formData.password).toString(CryptoJS.enc.Hex);
let thisObj = {
"thisObj": formData
};
loginLoading.value = true;
uni.setStorageSync('token', null);
//1.登录得到code
userApi.LoginByOauth(thisObj).then(loginRes => {
console.log('loginRes========', JSON.stringify(loginRes));
if (loginRes.mfail != '0' || loginRes.data == null) {
loginLoading.value = false;
uni.showToast({
icon: 'none',
duration: G.ShowPopTime,
title: `登录异常,code获取异常:${loginRes.msg}`
});
return;
} else {
//2.通过code获取Token
let postData = {
code: loginRes.data.code
};
//获取token
userApi.GetTokenFromCode(postData).then(tokenRes => {
console.log('Token========', JSON.stringify(tokenRes));
if (tokenRes.mfail != '0' || tokenRes.data == null) {
loginLoading.value = false;
uni.showToast({
icon: 'none',
duration: G.ShowPopTime,
title: `登录异常,token获取异常:${res.msg}`
});
return;
}
//登录成功后,将token写入全局变量
uni.setStorageSync('token', tokenRes.data.token);
//跳转到首页
nextTick(() => {
uni.reLaunch({
animationType: 'zoom-out',
animationDuration: 200,
url: "/pages/index/index"
});
});
}).catch(error => {
uni.setStorageSync('token', null);
loginLoading.value = false;
uni.showToast({
icon: 'none',
duration: G.ShowPopTime,
title: `访问失败,请联系管理员!:${res.msg}`
});
});
}
}).catch(error => {
uni.setStorageSync('token', null);
loginLoading.value = false;
uni.showToast({
icon: 'none',
duration: G.ShowPopTime,
title: `访问失败,请联系管理员!:${res.msg}`
});
});
} else {
loginLoading.value = false;
uni.showToast({
title: graceChecker.error,
icon: "none",
duration: G.ShowPopTime
});
}
}
onMounted(() => {
//uni.setStorageSync('token', null);
});
</script>
<style scoped lang="scss">
view {
box-sizing: border-box;
}
.uni-common-mt {
margin: 0;
}
.flex-item:nth-child(1) {
display: flex;
flex-flow: column;
justify-content: center;
align-content: center;
}
.flex-item:nth-child(2) {
height: 120rpx;
background: url("/static/login-style.png") round space;
}
.logo {
min-height: 100rpx;
padding-left: 10px;
margin-top: 100rpx;
}
.logoHead {
font-family: 'Microsoft YaHei', sans-serif;
text-align: center;
color: darkblue;
font-size: 58rpx;
font-weight: bold;
text-shadow: 1px 1px rgba(0, 0, 0, .3);
padding-bottom: 40rpx;
}
.loginBtn {
padding-top: 40rpx;
}
.form {
padding: 0px 40px;
}
</style>
主页面VUE
<template>
<view class="container">
<uni-nav-bar dark :fixed="true" shadow background-color="#007AFF" status-bar left-icon="left" right-icon="home" left-text="退出"
title="主页面" @clickLeft="back" />
<uni-section title="菜单" type="line" padding>
<uni-grid :column="3" :show-border="false" :square="false" :highlight="true" @change="gotoPage">
<uni-grid-item v-for="(item ,index) in list" :index="index" :key="index">
<view class="grid-item-box">
<image :src="item.imgUrl" class="image" mode="aspectFill" />
<!-- <uni-icons type="image" size="64" color="#0573f9"></uni-icons> -->
<text class="text">{
{ item.text }}</text>
</view>
</uni-grid-item>
</uni-grid>
</uni-section>
</view>
<view>
<!-- 提示窗示例 -->
<uni-popup ref="alertDialog" type="dialog">
<uni-popup-dialog :type="msgType" cancelText="关闭" confirmText="确定" title="提示" content="确定退出登录吗?"
@confirm="dialogConfirm"></uni-popup-dialog>
</uni-popup>
</view>
</template>
<script setup>
import {
nextTick,
onMounted,
reactive,
ref
} from 'vue';
const alertDialog = ref();
const msgType = ref("error");
const props = reactive({
hasLeftWin: {
type: Boolean
},
leftWinActive: {
type: String
}
});
const goto = (url) => {
uni.navigateTo({
url: url
})
};
const dynamicList = reactive([]);
// const dynamicList = reactive([]);
const list = reactive([{
url: '/pages/receiptConfirm/index',
imgUrl: '/static/image/cart2.png',
text: '收货确认',
badge: '0',
type: "primary"
},
{
url: '/pages/receiptList/index',
imgUrl: '/static/image/cart3.png',
text: '收货任务',
badge: '1',
type: "success"
},
{
url: '/pages/stocktaking/index',
imgUrl: '/static/image/cart2.png',
text: '盘点',
badge: '99',
type: "warning"
},
{
url: '/pages/intelligentLibraryTray/index',
imgUrl: '/static/image/cart3.png',
text: '智能库托盘',
badge: '2',
type: "error"
},
{
url: '/pages/loadingTask/index',
imgUrl: '/static/image/cart2.png',
text: '上架任务',
badge: '2',
type: "error"
},
{
url: '/pages/inventoryQuery/index',
imgUrl: '/static/image/cart3.png',
text: '库存查询',
badge: '2',
type: "error"
},
{
url: '/pages/pickingTask/index',
imgUrl: '/static/image/cart2.png',
text: '拣货任务',
badge: '2',
type: "error"
},
{
url: '/pages/unpacking/index',
imgUrl: '/static/image/cart3.png',
text: '拆包'
},
{
url: '/pages/reprintRawMaterial/index',
imgUrl: '/static/image/cart2.png',
text: '原材料补打'
},
{
url: '/pages/moveInventory/index',
imgUrl: '/static/image/cart3.png',
text: '移库'
},
{
url: '/pages/MESMaterialDistribution/index',
imgUrl: '/static/image/cart2.png',
text: '物料配送'
}
]);
const gotoPage = (e) => {
let {
index
} = e.detail;
console.log(e.detail, list[index].url);
if (list[index]) { //页面跳转
nextTick(() => {
uni.navigateTo({
url: list[index].url,
animationType: 'zoom-out',
animationDuration: 200
});
});
// uni.showToast({
// title: `点击第${index + 1}个宫格`,
// icon: 'none'
// })
}
};
//退出系统
const dialogConfirm = () => {
uni.reLaunch({
animationType: 'zoom-out',
animationDuration: 200,
url: "/pages/login/index"
});
};
//退出系统事件
const back = () => {
msgType.value = "error";
alertDialog.value.open();
};
// const add = () => {
// if (dynamicList.length < 9) {
// dynamicList.push({
// url: `/static/c${dynamicList.length + 1}.png`,
// text: `Grid ${dynamicList.length + 1}`,
// color: dynamicList.length % 2 === 0 ? '#f5f5f5' : "#fff"
// })
// } else {
// uni.showToast({
// title: '最多添加9个',
// icon: 'none'
// });
// }
// };
// const del = () => {
// dynamicList.splice(dynamicList.length - 1, 1)
// };
onMounted(() => {
});
</script>
<script>
export default {
onNavigationBarButtonTap(e) {
if (e.index === 0) {
//dialogToggle("error");
this.msgType = "error";
this.$refs.alertDialog.open();
}
}
}
</script>
<style scoped lang="scss">
view {
box-sizing: border-box;
}
.image {
width: 48px;
height: 48px;
}
.text {
font-size: 14px;
margin-top: 5px;
}
.example-body {
/* #ifndef APP-NVUE */
// display: block;
/* #endif */
}
.grid-dynamic-box {
margin-bottom: 15px;
}
.grid-item-box {
flex: 1;
// position: relative;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
align-items: center;
justify-content: center;
padding: 15px 0;
}
.grid-item-box-row {
flex: 1;
// position: relative;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
align-items: center;
justify-content: center;
padding: 15px 0;
}
.grid-dot {
position: absolute;
top: 5px;
right: 15px;
}
.swiper {
height: 420px;
}
/* #ifdef H5 */
@media screen and (min-width: 768px) and (max-width: 1425px) {
.swiper {
height: 630px;
}
}
@media screen and (min-width: 1425px) {
.swiper {
height: 830px;
}
}
/* #endif */
</style>
receiptList/index.vue
<template>
<z-paging ref="paging" v-model="dataList" @query="queryList">
<template #top>
<uni-group class="searchForm">
<uni-easyinput v-model="orderNumber" placeholder="请输入或扫描送货单号" prefixIcon="scan" @confirm="onInput">
</uni-easyinput>
</uni-group>
<view style="margin: 0 5px;">
<uni-segmented-control :current="current" :values="items" @clickItem="onClickItem" styleType="button">
</uni-segmented-control>
</view>
</template>
<view class="content">
<view class="itemCard" v-for="(item,index) in dataList" :key="index" @click="itemClick(item)">
<view class="item">
<view class="example-body">
<uni-row class="demo-uni-row">
<uni-col :span="24">
<view class="listItme">
<view class="listTitle blueBar">送货单号</view>
<view class="listContent">{
{item.orderNumber}}</view>
</view>
</uni-col>
<uni-col :span="24">
<view class="listItme">
<view class="listTitle">关联单号</view>
<view>{
{item.relatedOrderNumber}}</view>
</view>
</uni-col>
<uni-col :span="24">
<view class="listItme">
<view class="listTitle">单据来源</view>
<view class="listContent">{
{item.orderSource}}</view>
</view>
</uni-col>
<uni-col :span="24">
<view class="listItme">
<view class="listTitle">开始时间</view>
<view class="listContent">{
{item.planStartTime}}</view>
</view>
</uni-col>
<uni-col :span="24">
<view class="listItme">
<view class="listTitle">结束时间</view>
<view class="listContent">{
{item.planEndTime}}</view>
</view>
</uni-col>
<uni-col :span="24">
<view class="listItme">
<view class="listTitle">收货人</view>
<view class="listContent">{
{item.responsiblePerson}}</view>
</view>
</uni-col>
</uni-row>
</view>
<view class="item-arrow">
<uni-icons type="right" size="25" color="grey"></uni-icons>
</view>
</view>
</view>
</view>
</z-paging>
</template>
<script setup>
import {
onMounted,
reactive,
ref,
getCurrentInstance
} from 'vue';
import {
queryPage
} from "@/api/receiptList";
const instance = getCurrentInstance();
const paging = ref(null);
const focus = reactive(true);
const dataList = ref([]);
const items = ['收货中', '待收货', '已收货'];
const current = ref(0); // 当前选中的选项卡,默认为第一个选项卡
const orderNumber = ref("");
//查询
const onInput = (e) => {
paging.value.reload();
};
const onClickItem = (e) => {
current.value = e.currentIndex; // 获取当前选中的索引
paging.value.reload();
};
// @query所绑定的方法不要自己调用!!需要刷新列表数据时,只需要调用paging.value.reload()即可
const queryList = (pageNo, pageSize) => {
// 组件加载时会自动触发此方法,因此默认页面加载时会自动触发,无需手动调用
// 这里的pageNo和pageSize会自动计算好,直接传给服务器即可
// 模拟请求服务器获取分页数据,请替换成自己的网络请求
const params = {
"attrSet": [],
"condition": [],
"sorts": [{
"name": "createAt",
"sort": "desc"
}],
"page": {
"pageNo": pageNo,
"pageSize": pageSize
}
};
if (orderNumber.value != '') {
params.condition.push({
"compare": "LIKE",
"field": "orderNumber",
"value": orderNumber.value
});
}
if (current.value == 0) {
//收货中
params.condition.push({
"compare": "EQUAL",
"field": "orderStatus",
"value": 'Created'
});
} else if (current.value == 1) {
//待收货
params.condition.push({
"compare": "EQUAL",
"field": "orderStatus",
"value": 'SH'
});
}
if (current.value == 2) {
//已收货
params.condition.push({
"compare": "EQUAL",
"field": "orderStatus",
"value": 'SHWC'
});
}
queryPage(params).then(res => {
console.log("============", JSON.stringify(res));
if (res.code == 0) {
// 将请求的结果数组传递给z-paging
paging.value.complete(res.data);
} else { //异常信息
paging.value.complete(false);
uni.showToast({
title: res.msg
});
}
}).catch(res => {
// 如果请求失败写paging.value.complete(false);
// 注意,每次都需要在catch中写这句话很麻烦,z-paging提供了方案可以全局统一处理
// 在底层的网络请求抛出异常时,写uni.$emit('z-paging-error-emit');即可
paging.value.complete(false);
});
};
const itemClick = (item) => {
instance.appContext.config.globalProperties.$setGlobalData(item);
uni.navigateTo({
url: '/pages/receiptList/confirm'
});
// let infoData = JSON.stringify(item)
// let newStr = encodeURIComponent(infoData);
// uni.navigateTo({
// url: '/pages/receiptList/confirm?data=' + newStr
// });
// console.log('点击了', item);
};
onMounted(() => {
console.log("加載成功。。。");
});
</script>
<style scoped lang="scss">
view {
box-sizing: border-box;
color: $uni-text-color;
}
button {
font-size: $uni-btn-font-size !important;
}
.searchForm {
margin-top: 0 !important;
}
.content {
margin: 0;
}
.itemCard {
padding: 10rpx 10rpx 10rpx 15rpx;
z-index: 1;
border: 1px solid #ddd;
border-radius: 6px;
background-color: $uni-bg-color;
margin: 8rpx 8rpx 0px 8rpx !important;
}
.item {
z-index: 1;
position: relative;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0;
}
.item-line {
position: absolute;
bottom: 0rpx;
left: 0rpx;
height: 1px;
}
.listItme {
display: flex;
justify-content: row;
line-height: 55rpx;
}
.listTitle {
padding-left: 20rpx;
font-weight: bold;
min-width: 120rpx;
padding-right: 10rpx;
white-space: nowrap;
/* 禁止换行 */
overflow: hidden;
}
.listTitle::after {
white-space: pre;
content: " ";
}
.listContent {
min-width: 120rpx;
margin-right: 10rpx;
white-space: nowrap;
/* 禁止换行 */
overflow: hidden;
/* 隐藏溢出内容 */
text-overflow: ellipsis;
/* 使用省略号表示溢出 */
}
//蓝色条块
.blueBar {
margin-left: -22rpx;
}
.blueBar::before {
white-space: pre;
content: " ";
background-color: $uni-border-bar-color; // $uni-color-primary ;
width: 4px;
/* 竖块的宽度 */
height: 12px;
border-radius: 10px;
margin-right: 15rpx;
}
</style>
receiptList/confirm.vue
<template>
<z-paging ref="paging" v-model="dataList" @query="queryList">
<!-- 需要固定在顶部不滚动的view放在slot="top"的view中,如果需要跟着滚动,则不要设置slot="top" -->
<!-- 注意!此处的z-tabs为独立的组件,可替换为第三方的tabs,若需要使用z-tabs,请在插件市场搜索z-tabs并引入,否则会报插件找不到的错误 -->
<template #top>
<view class="searchForm">
<view>
<uni-easyinput name="userName" placeholder="请扫描物料二维码" prefixIcon="scan" @confirm="onInput">
</uni-easyinput>
</view>
<view class="example-body searchFormList">
<uni-row class="demo-uni-row">
<uni-col :span="15">
<view class="listItme">
<view class="listTitle">送货单号</view>
<view class="listContent">{
{selectItem.orderNumber}}</view>
</view>
</uni-col>
<uni-col :span="9">
<view class="listItme">
<view class="listTitle">总件数</view>
<view class="listContent">2000</view>
</view>
</uni-col>
<uni-col :span="15">
<view class="listItme">
<view class="listTitle">已收数量</view>
<view class="listContent">5000</view>
</view>
</uni-col>
<uni-col :span="9">
<view class="listItme">
<view class="listTitle">待收数量</view>
<view class="listContent">200</view>
</view>
</uni-col>
</uni-row>
</view>
<view class="btnList2">
<view>
<button type="primary" :loading="loginLoading" @click="submitOrder">提 交</button>
</view>
<view>
<button type="primary" plain="true">条码补打</button>
</view>
</view>
</view>
</template>
<!-- 如果希望其他view跟着页面滚动,可以放在z-paging标签内 -->
<view>
<view class="itemCard" v-for="(item,index) in dataList" :key="index">
<view class="example-body">
<uni-row class="demo-uni-row">
<uni-col :span="24">
<view class="listItme">
<view class="listTitle blueBar">物料号</view>
<view class="listContent">{
{item.materialDepict}} {
{item.materialCode}}</view>
</view>
</uni-col>
<uni-col :span="10">
<view class="listItme">
<view class="listTitle">箱号</view>
<view class="listContent">{
{item.consumablesCode}}</view>
</view>
</uni-col>
<uni-col :span="14">
<view class="listItme">
<view class="listTitle">是否检验</view>
<view class="listContent">{
{item.qualityInspection}}</view>
</view>
</uni-col>
<uni-col :span="10">
<view class="listItme">
<view class="listTitle">收货状态</view>
<view class="listContent">{
{item.taskStatus}}</view>
</view>
</uni-col>
<uni-col :span="14">
<view class="listItme">
<view class="listTitle">送货数量</view>
<view class="listContent">{
{item.taskQuantity}}</view>
</view>
</uni-col>
<uni-col :span="10">
<view class="listItme">
<view class="listTitle">清点数量</view>
<view class="listContent">
<input class="uniInput" type="number" maxlength="10" placeholder="输入数量"
v-model="item.actualOperateQuantity" />
</view>
</view>
</uni-col>
<uni-col :span="14">
<view class="listItme">
<view class="listTitle">智库物料</view>
<view class="listContent">{
{item.materialCode}}</view>
</view>
</uni-col>
<uni-col :span="10">
<view class="listItme">
<view class="listTitle">行号</view>
<view class="listContent">{
{item.tj0receiveLineNumber}}</view>
</view>
</uni-col>
<uni-col :span="10">
<view class="listItme">
<view class="listContent2">
<button type="warn" @click="toggle(item)" size="mini">收货异常</button>
</view>
</view>
</uni-col>
</uni-row>
</view>
<view>
<uni-collapse accordion>
<uni-collapse-item title="物料明细">
<view class="collapseBody">
<uni-row class="demo-uni-row" v-for="(citem,index) in item.serialNumberOutVOList"
:key="index">
<uni-col :span="24">
<view class="item_line"></view>
</uni-col>
<uni-col :span="24">
<view class="listItme">
<view class="listTitle">SN/序列号</view>
<view class="listContent">{
{citem.serialNum}}</view>
</view>
</uni-col>
<uni-col :span="24">
<view class="listItme">
<view class="listTitle">批次号</view>
<view class="listContent">{
{citem.batchNumber}}</view>
</view>
</uni-col>
<uni-col :span="12">
<view class="listItme">
<view class="listTitle">数 量</view>
<view class="listContent">{
{citem.actualOperateQuantity}}</view>
</view>
</uni-col>
</uni-row>
</view>
</uni-collapse-item>
</uni-collapse>
</view>
</view>
</view>
</z-paging>
<view>
<!-- 普通弹窗 -->
<uni-popup ref="refPopup" background-color="#fff" @change="change">
<view class="popup-content">
<uni-section title="收货异常" type="line">
<view class="example">
<!-- 基础表单校验 -->
<uni-forms ref="formRef" :rules="customRules" :model="valiFormData" labelWidth="80px">
<uni-forms-item label="物料编码" name="materialCode">
<uni-easyinput disabled v-model="valiFormData.materialCode" placeholder="" />
</uni-forms-item>
<uni-forms-item label=" 送货数量" name="taskQuantity">
<uni-easyinput type="number" disabled v-model="valiFormData.taskQuantity"
placeholder="" />
</uni-forms-item>
<uni-forms-item label="清点数量" required name="actualOperateQuantity">
<uni-easyinput type="number" v-model="valiFormData.actualOperateQuantity" maxlength="10"
placeholder="输入数量" />
</uni-forms-item>
<uni-forms-item label="损坏数量" required name="tj0damagedQuantity">
<uni-easyinput type="number" v-model="valiFormData.tj0damagedQuantity" maxlength="10"
placeholder="输入数量" />
</uni-forms-item>
<uni-forms-item label="破损数量" required name="tj0wornQuantity">
<uni-easyinput type="number" v-model="valiFormData.tj0wornQuantity" maxlength="10"
placeholder="输入数量" />
</uni-forms-item>
</uni-forms>
<button type="primary" @click="submit('valiForm')">保 存</button>
</view>
</uni-section>
</view>
</uni-popup>
</view>
</template>
<script setup>
import {
onMounted,
reactive,
ref,
getCurrentInstance
} from 'vue';
import {
receiveJobTaskSeach,
receiveAbnormal,
receiveSubmit
} from "@/api/receiptList";
const instance = getCurrentInstance();
const loginLoading = ref(false);
const formRef = ref();
const baseFormData = reactive({});
const selectItem = ref({});
const popupType = reactive("bottom");
const refPopup = ref();
var itemValue = {};
//提交
const submitOrder = () => {
let params = selectItem.value;
params.taskList = dataList.value;
console.log("params============", JSON.stringify(params));
loginLoading.value = true;
receiveSubmit(params).then(res => {
loginLoading.value = false;
if (res.code == 0) {
refPopup.value.close();
uni.showToast({
title: `保存成功`,
icon: 'success',
duration: 3000
});
} else { //异常信息
uni.showToast({
title: res.msg
});
}
}).catch(res => {
loginLoading.value = false;
paging.value.complete(false);
});
};
const valiFormData = reactive({});
// 自定义表单校验规则
const customRules = reactive({
actualOperateQuantity: {
rules: [{
required: true,
errorMessage: '清点数量,不能为空'
}]
},
tj0damagedQuantity: {
rules: [{
required: true,
errorMessage: '损坏数量,不能为空'
}]
},
tj0wornQuantity: {
rules: [{
required: true,
errorMessage: '破损数量,不能为空'
}]
}
});
const paging = ref(null);
const dataList = ref([]);
// @query所绑定的方法不要自己调用!!需要刷新列表数据时,只需要调用paging.value.reload()即可
const queryList = (pageNo, pageSize) => {
// 组件加载时会自动触发此方法,因此默认页面加载时会自动触发,无需手动调用
// 这里的pageNo和pageSize会自动计算好,直接传给服务器即可
// 模拟请求服务器获取分页数据,请替换成自己的网络请求
const params = {
"attrSet": [],
"condition": [],
"sorts": [{
"name": "createAt",
"sort": "desc"
}],
"page": {
"pageNo": pageNo,
"pageSize": pageSize
}
};
params.condition.push({
"compare": "EQUAL",
"field": "mainId",
"value": selectItem.value.objId
});
receiveJobTaskSeach(params).then(res => {
console.log("============", JSON.stringify(res));
if (res.code == 0) {
// 将请求的结果数组传递给z-paging
res.data.forEach(i => {
if (i.taskQuantity != null && i.taskQuantity != "" && i.taskQuantity !=
0)
i.actualOperateQuantity = i.taskQuantity;
});
paging.value.complete(res.data);
} else { //异常信息
paging.value.complete(false);
uni.showToast({
title: res.msg
});
}
}).catch(res => {
// 如果请求失败写paging.value.complete(false);
// 注意,每次都需要在catch中写这句话很麻烦,z-paging提供了方案可以全局统一处理
// 在底层的网络请求抛出异常时,写uni.$emit('z-paging-error-emit');即可
paging.value.complete(false);
});
};
const itemClick = (item) => {
let infoData = JSON.stringify(item)
let newStr = infoData.replace(/%/g, '%25');
uni.navigateTo({
url: '/pages/receiptConfirm/confirm?data=' + encodeURIComponent(newStr)
})
// console.log('点击了', item);
};
//收货异常
const toggle = (item) => {
itemValue = item;
valiFormData.objId = item.objId;
valiFormData.materialCode = item.materialCode;
valiFormData.taskQuantity = item.taskQuantity;
valiFormData.actualOperateQuantity = item.actualOperateQuantity;
valiFormData.tj0damagedQuantity = item.tj0damagedQuantity;
valiFormData.tj0wornQuantity = item.tj0wornQuantity;
// open 方法传入参数 等同在 uni-popup 组件上绑定 type属性
refPopup.value.open(popupType);
//console.log('item', JSON.stringify(item));
};
//收货异常提交
const submit = async (ref) => {
console.log("baseFormData====", JSON.stringify(baseFormData));
await formRef?.value?.validate();
// formRef.value.validate().then(res => {
// loginLoading.value = true;
// console.log('success', res);
// uni.showToast({
// title: `校验通过`
// })
// }).catch(err => {
// console.log('err', err);
// });
itemValue.actualOperateQuantity = valiFormData.actualOperateQuantity;
itemValue.tj0damagedQuantity = valiFormData.tj0damagedQuantity;
itemValue.tj0wornQuantity = valiFormData.tj0wornQuantity;
refPopup.value.close();
uni.showToast({
title: `保存成功`,
icon: 'success',
duration: 2000
});
/*
receiveAbnormal(valiFormData).then(res => {
loginLoading.value = false;
console.log("============", JSON.stringify(res));
if (res.code == 0) {
refPopup.value.close();
valiFormData.actualOperateQuantity = "";
valiFormData.tj0damagedQuantity = "";
valiFormData.tj0wornQuantity = "";
uni.showToast({
title: `保存成功`,
icon: 'success',
duration: 3000
});
} else { //异常信息
uni.showToast({
title: res.msg
});
}
}).catch(res => {
loginLoading.value = false;
paging.value.complete(false);
});*/
};
onMounted(() => {
const pages = getCurrentPages();
const currentPage = pages[pages.length - 1]; // 当前页面
//取全局变量参数
const globalData = instance.appContext.config.globalProperties.$getGlobalData();
selectItem.value = globalData;
// //父页面data参数
// if (currentPage.options && currentPage.options.data) {
// let infoData = decodeURIComponent(currentPage.options.data);
// // console.log("infoData----------", JSON.stringify(infoData))
// selectItem.value = JSON.parse(infoData);
// }
console.log("onReady====", selectItem.value.orderNumber);
});
</script>
<style scoped lang="scss">
view {
box-sizing: border-box;
color: $uni-text-color;
}
button {
font-size: 13px !important;
}
.uniInput {
border-bottom: 1px solid $uni-border-bar-color;
border-radius: 0px;
width: 60px;
padding: 3px 3px;
font-size: 13px;
}
.searchForm {
background-color: $uni-bg-color;
padding: 15rpx 0rpx;
}
.searchForm>view:nth-child(1) {
padding: 0 7px;
}
.searchFormList {
font-weight: bold !important;
}
.btnList2 {
display: flex;
flex-flow: row wrap;
justify-content: space-between;
align-content: space-between;
}
.btnList2>view {
flex: 1;
padding: 8rpx;
}
.btnList {
display: flex;
flex-flow: row wrap;
justify-content: space-between;
align-content: space-between;
}
.btnList>view {
flex: 33%;
padding: 8rpx;
}
.example-body {
margin-top: 10rpx;
}
.itemCard {
padding-left: 15rpx;
z-index: 1;
border: 1px solid $uni-border-color;
border-radius: 6px;
background-color: white;
margin: 8rpx 8rpx 0px 8rpx;
}
.listItme {
display: flex;
justify-content: row;
line-height: 55rpx;
}
.listTitle {
font-weight: bold;
padding-left: 20rpx;
min-width: 120rpx;
padding-right: 10rpx;
white-space: nowrap;
/* 禁止换行 */
overflow: hidden;
}
.listTitle::after {
white-space: pre;
content: "";
}
.listContent2 {
display: flex;
padding-left: 12px;
}
.listContent2>button {
width: 140px !important;
font-size: 11px !important;
}
.listContent {
min-width: 120rpx;
margin-right: 10rpx;
white-space: nowrap;
/* 禁止换行 */
overflow: hidden;
/* 隐藏溢出内容 */
text-overflow: ellipsis;
/* 使用省略号表示溢出 */
}
.item_line {
height: 1rpx;
width: 100%;
background-color: #eeeeee;
margin: 10rpx 0;
}
.collapseBody {
padding: 0 40rpx;
}
.popup-content {
margin: 0rpx 40rpx 40rpx 40rpx;
background-color: #fff;
}
//蓝色条块
.blueBar {
margin-left: -22rpx;
}
.blueBar::before {
white-space: pre;
content: " ";
background-color: $uni-border-bar-color; // $uni-color-primary ;
width: 4px;
/* 竖块的宽度 */
height: 12px;
border-radius: 10px;
margin-right: 15rpx;
}
</style>