当前位置: 首页 > article >正文

uni-app vue3 常用页面 组合式api方式

全局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>


http://www.kler.cn/a/509699.html

相关文章:

  • 彻底讲清楚 单体架构、集群架构、分布式架构及扩展架构
  • 设计模式-单例模式
  • leetcode707-设计链表
  • AI 大爆发时代,音视频未来路在何方?
  • Formality:参考设计/实现设计以及顶层设计
  • js基础---var与let的区别以及const的使用
  • PyTorch深度学习实践【刘二大人】之卷积神经网络
  • 网络互联(软件路由器)实验
  • 如何禁用 PySpark 在运行时打印信息
  • Spring Cloud与Spring Boot的关系
  • 【AI论文】Diffusion模型的推理时缩放:超越降噪步骤的缩放策略
  • postman接口请求-post登陆接口+x-www-form-urlencoded
  • 【PyCharm】连接 Git
  • uniapp 地图(map)加载大量自定义坐标卡顿优化
  • 意图颠覆电影行业的视频生成模型:Runway的Gen系列
  • ubuntu 在mongodb启动的情况下无法进入shell
  • 【redis】键的全局命令
  • RabbitMQ--延迟队列
  • opencv3.4 ffmpeg3.4 arm-linux 交叉编译
  • 02UML图(D1_结构图)
  • 【Python项目】基于深度学习的开放领域时间抽取系统
  • 【机器学习:二十、拆分原始训练集】
  • 【数据分析】coco格式数据生成yolo数据可视化
  • 11.在 Vue 3 中使用 ECharts 实现树状图
  • vue中的那些事(刷新+key+v-if,v-for)
  • Python制作简易PDF查看工具PDFViewerV1.0