Bladeren bron

团餐商品对接增删改查、上下架接口;

郭鹏飞 10 maanden geleden
bovenliggende
commit
6e7f169068

+ 28 - 18
components/list-scroll-view/index.vue

@@ -22,8 +22,9 @@ export default {
 	props: {
 		// 数据接口
 		api: {
-			type: Function,
-			default: () => {}
+			type: Object,
+			required: true,
+			default: null
 		},
 		// 初始参数
 		init: {
@@ -110,31 +111,40 @@ export default {
 				this.mescroll.endErr();
 				return;
 			}
-			let params = {
+			let options = {}, params = {
 				pageNo: e.num,
 				pageSize: e.size,
 				...this.init,
 				...this.params
 			};
+			// request底层问题
+			if (this.api.method === 'POST') {
+				options.data = params;
+			} else if (this.api.method === 'GET') {
+				options.params = params;
+			}
 			// 置空
 			if(e.num == 1) this.dataList = []; 
 			// 请求
-			this.api(params).then(res => {
-				// 无分页处理,用于那些需要下拉和空列表的地方
-				if (this.noPage) {
-					res = {
-						...res,
-						result: {
-							records: res.result,
-							total: res.result.length
-						}
-					};
+			this.$http.request({
+				...this.api,
+				...options
+			}).then(res => {
+				if (res.data.code === 200) {
+					let r = res.data.result;
+					// 无分页处理,用于那些需要下拉和空列表的地方
+					if (this.noPage) {
+						r = {
+							records: r,
+							total: r.length
+						};
+					}
+					let result = r || {}, records = r[this.keyName] || [];
+					this.$emit('afterFetch', result);
+					// 数据
+					this.dataList = this.dataList.concat(records);
+					this.mescroll.endBySize(records.length, result.total || result[this.keyName].total);
 				}
-				let result = res.result || {}, records = result[this.keyName].records || result[this.keyName] || [];
-				this.$emit('afterFetch', result);
-				// 数据
-				this.dataList = this.dataList.concat(records);
-				this.mescroll.endBySize(records.length, result.total || result[this.keyName].total);
 			}).catch(e => {
 				this.mescroll.endErr();
 			});

+ 6 - 1
components/modal/index.vue

@@ -74,7 +74,8 @@ export default {
 	data() {
 		return {
 			show: false,
-			timer: null
+			timer: null,
+			callback: null
 		};
 	},
 	mounted() {
@@ -92,12 +93,16 @@ export default {
 					callback && callback();
 				}, duration);
 			}
+			if (!duration && callback) {
+				this.callback = callback;
+			}
 		},
 		onCancel() {
 			this.$emit('cancel');
 			this.show = false;
 		},
 		onSubmit() {
+			this.callback && this.callback();
 			this.$emit('confirm');
 			this.show = false;
 		},

+ 105 - 0
components/upload/index.vue

@@ -0,0 +1,105 @@
+<template>
+	<u-upload :action="action" :fileList="fileListData" 
+		v-bind="$attrs" 
+		@on-remove="onRemove"
+		@on-success="afterRead"
+		@on-list-change="onListChange">
+		<slot></slot>
+	</u-upload>
+</template>
+
+<script>
+import configService from '@/common/service/config.service';
+export default {
+	name: "",
+	props: {
+		api: {
+			type: String,
+			default: '/sys/common/upload'
+		},
+		fileList: {
+			type: Array,
+			default: () => []
+		},
+	},
+	data() {
+		return {
+			fileListData: [],
+		};
+	},
+	watch: {
+		fileList: {
+			immediate: true,
+			handler(n) {
+				if (n.length > 0) {
+					this.fileListData = n;
+				}
+			}
+		}
+	},
+	computed: {
+		action() {
+			return configService.apiUrl + this.api
+		}
+	},
+	mounted() {
+		
+	},
+	beforeDestroy() {
+		
+	},
+	methods: {
+		afterRead(event, index, list) {
+			// url是组件的固定字段
+			this.fileListData[index] = {
+				...event,
+				url: list[index].url
+			};
+			this.$emit('update:fileList', this.fileListData);
+			this.$emit('complete', this.fileListData);
+		},
+		onRemove(index, lists) {
+			this.fileListData.splice(index, 1);
+			this.$emit('update:fileList', this.fileListData);
+			this.$emit('complete', this.fileListData);
+		},
+		// onListChange早于onSuccess
+		onListChange(lists) {
+			// this.$emit('complete', lists);
+		},
+		// 手动上传
+		uploadFilePromise(url) {
+			return new Promise((resolve, reject) => {
+				let a = uni.uploadFile({
+					url: this.action,
+					name: "file",
+					header:{
+						'AppType': '5',
+						'X-Access-Token': uni.getStorageSync('token'),
+					},
+					filePath: url,
+					// formData: {
+					// 	user: "test",
+					// },
+					success: (res) => {
+						uni.hideLoading();
+						let data = JSON.parse(res.data);
+						if (data.success) {
+							resolve(data);
+						} else {
+							uni.showToast({
+								icon: 'none',
+								title: data.message || '文件导入失败',
+							});
+						}
+					},
+				});
+			});
+		},
+	}
+}
+</script>
+
+<style lang="scss" scoped>
+
+</style>

+ 123 - 43
pages/groupMeal/goods/form-step1.vue

@@ -9,7 +9,7 @@
 				:error-type="['toast', 'border-bottom']"
 			> 
 				<u-form-item prop="category" label="商品分类" required borderBottom>
-					<u-input v-model="form.category" placeholder="去设置" height="41" inputAlign="right" @click="show = true"></u-input>
+					<u-input v-model="form.categoryName" placeholder="去设置" height="41" inputAlign="right" @click="show = true"></u-input>
 					<u-icon slot="right" name="arrow-right" color="#C7C6CA"></u-icon>
 				</u-form-item>
 				
@@ -17,47 +17,43 @@
 					<u-input v-model="form.name" placeholder="输入商品名称" height="41" inputAlign="right"></u-input>
 				</u-form-item>
 
-				<u-form-item prop="coverImages" label="商品封面图" required labelPosition="top">
+				<u-form-item prop="productImage" label="商品封面图" required labelPosition="top">
 					<view class="upload-content">
-						<view class="upload-tip">支持jpg、png格式,建议尺寸为300px*300px,上传1-4张</view>
-						<u-upload
-							name="cover"
+						<view class="upload-tip">支持jpg、png格式,建议尺寸为750px*750px,上传1-4张</view>
+						<Upload
 							width="140"
 							height="140"
-							multiple
 							:maxCount="4"
-							:fileList="fileList.cover"
+							:multiple="true"
+							:fileList.sync="fileList.cover"
 							:previewFullImage="true"
-							@afterRead="afterRead($event, 'cover')"
-							@delete="deletePic($event, 'cover')"
-						></u-upload>
+							@complete="onUpload($event, 'cover')"
+						/>
 					</view>
 				</u-form-item>
 
 				<u-form-item prop="detailImages" label="商品详情图" required borderBottom labelPosition="top">
 					<view class="upload-content">
-						<view class="upload-tip">支持jpg、png格式,建议尺寸为300px*300px,最多20张</view>
-						<u-upload
-							name="detail"
+						<view class="upload-tip">支持jpg、png格式,最多20张</view>
+						<Upload
 							width="140"
 							height="140"
-							multiple
 							:maxCount="20"
-							:fileList="fileList.detail"
+							:multiple="true"
+							:fileList.sync="fileList.detail"
 							:previewFullImage="true"
-							@afterRead="afterRead($event, 'detail')"
-							@delete="deletePic($event, 'detail')"
-						></u-upload>
+							@complete="onUpload($event, 'detail')"
+						/>
 					</view>
 				</u-form-item>
 
-				<u-form-item prop="groupPrice" label="团餐价" required borderBottom>
-					<u-input v-model="form.groupPrice" type="digit" height="41" :clearable="false" placeholder="请输入团餐价" inputAlign="right"></u-input>
+				<u-form-item prop="price" label="团餐价" required borderBottom>
+					<u-input v-model.number="form.price" type="digit" height="41" :clearable="false" placeholder="请输入团餐价" inputAlign="right"></u-input>
 					<text slot="right" class="input-suffix">元</text>
 				</u-form-item>
 				
-				<u-form-item prop="salePrice" label="售价" required :borderBottom="false">
-					<u-input v-model="form.salePrice" type="digit" height="41" :clearable="false" placeholder="商品售价" inputAlign="right"></u-input>
+				<u-form-item prop="sellingPrice" label="售价" required :borderBottom="false">
+					<u-input v-model.number="form.sellingPrice" type="digit" height="41" :clearable="false" placeholder="商品售价" inputAlign="right"></u-input>
 					<text slot="right" class="input-suffix">元</text>
 				</u-form-item>
 			</u-form>
@@ -72,31 +68,40 @@
 </template>
 
 <script>
+import Upload from '@/components/upload/index.vue';
+import configService from '@/common/service/config.service';
 export default {
+	components: {
+		Upload,
+	},
 	data() {
 		return {
 			show: false,
 			form: {
 				name: '',
 				category: '',
-				coverImages: [],
-				detailImages: [],
-				groupPrice: '',
-				salePrice: '',
+				productImage: '',
+				detailImages: '',
+				price: '',
+				sellingPrice: '',
 			},
+			query: {},
 			fileList: {
 				cover: [],
 				detail: [],
 			},
 			actionSheetList: [
 				{
-					text: '早餐'
+					text: '早餐',
+					value: '1'
 				},
 				{
-					text: '午餐'
+					text: '午餐',
+					value: '2'
 				},
 				{
-					text: '晚餐'
+					text: '晚餐',
+					value: '3'
 				}
 			],
 			rules: {
@@ -113,34 +118,109 @@ export default {
 						message: '请选择分类',
 						trigger: ['blur', 'change']
 					}
-				]
+				],
+				price: [
+					{
+						required: true,
+						type: 'number',
+						message: '请输入团餐价格',
+						trigger: ['blur', 'change']
+					}
+				],
+				sellingPrice: [
+					{
+						required: true,
+						type: 'number',
+						message: '请输入商品售价',
+						trigger: ['blur', 'change']
+					}
+				],
+				productImage: [
+					{
+						required: true,
+						message: '请上传商品封面图',
+						trigger: ['blur', 'change']
+					}
+				],
+				detailImages: [
+					{
+						required: true,
+						message: '请上传商品详情图片',
+						trigger: ['blur', 'change']
+					}
+				],
 			}
 		};
 	},
+	onLoad(query) {
+		if (query.id) {
+			this.query = query;
+			this.getData();
+		}
+		// 清除
+		uni.removeStorageSync('gm_goods');
+		// 获取餐品分类
+		this.getClassData();
+	},
 	onReady() {
 		this.$refs.uForm.setRules(this.rules);
 	},
 	methods: {
-		// 分类选择,打开弹窗
-		actionSheetCallback(index) {
-			this.form.category = this.actionSheetList[index].text;
+		// 编辑数据
+		getData() {
+			this.$http.get('/groupmeal/gmCustomerPackage/queryById', { params: { id: this.query.id } }).then(res => {
+				if (res.data.code === 200) {
+					let data = res.data.result;
+					this.form = {
+						...data,
+						categoryName: this.actionSheetList.find(item => item.value == data.category).text
+					};
+					this.fileList = {
+						cover: data.productImage.split(',').map(item => {
+							return {
+								url: configService.apiUrl + '/' + item
+							}
+						}),
+						detail: data.detailImages.split(',').map(item => {
+							return {
+								url: configService.apiUrl + '/' + item
+							}
+						}),
+					};
+				}
+			});
 		},
-		// 图片上传处理
-		async afterRead(event, type) {
-			let lists = [].concat(event.file);
-			this.fileList[type].push(...lists);
-			// 上传逻辑
-			this.form[type === 'cover' ? 'coverImages' : 'detailImages'] = this.fileList[type].map(f => f.url);
+		// 餐品分类
+		getClassData() {
+			this.$http.get('/groupmeal/gmMerchantPackage/getGroupMealCategory', {}).then(res => {
+				if (res.data.code === 200) {
+					this.actionSheetList = res.data.result.map(item => {
+						return {
+							text: item.name,
+							value: item.code
+						}
+					})
+				}
+			});
+		},
+		// 分类选择,打开弹窗
+		actionSheetCallback(e) {
+			this.form.category = e.value;
+			this.form.categoryName = e.text;
 		},
-		deletePic(event, type) {
-			this.fileList[type].splice(event.index, 1);
-			this.form[type === 'cover' ? 'coverImages' : 'detailImages'] = this.fileList[type].map(f => f.url);
+		// 图片处理
+		onUpload(event, type) {
+			this.fileList[type] = event;
+			this.form[type === 'cover' ? 'productImage' : 'detailImages'] = this.fileList[type].map(f => f.message).join();
 		},
+		// 下一步
 		goNextStep() {
 			// 表单校验
 			this.$refs.uForm.validate(valid => {
 				if (valid) {
-					console.log('Form Data:', this.form);
+					console.log('Form Data:', this.form, this.fileList);
+					const { categoryName, ...form } = this.form;
+					uni.setStorageSync('gm_goods', form);
 					uni.navigateTo({
 						url: '/pages/groupMeal/goods/form-step2'
 					});

+ 50 - 5
pages/groupMeal/goods/form-step2.vue

@@ -17,6 +17,7 @@
 				>
 					<view slot="title" class="collapse-title">
 						<text>{{ category.name }}</text>
+						<text class="num" v-if="isEditedShow(category)">({{ category.items.length }})</text>
 						<u-switch 
 							v-if="false"
 							size="20"
@@ -71,7 +72,7 @@
 									<u-input v-model="dish.name" height="41" placeholder="请输入" inputAlign="right"></u-input>
 								</u-form-item>
 								<u-form-item label="价格" :prop="`dishCategories.${catIndex}.items.${dishIndex}.price`" :required="isEdited(dish)">
-									<u-input v-model="dish.price" type="digit" height="41" placeholder="输入金额" :clearable="false" inputAlign="right"></u-input>
+									<u-input v-model.number="dish.price" type="digit" height="41" placeholder="输入金额" :clearable="false" inputAlign="right"></u-input>
 									<text slot="right" style="color: #333333;">元</text>
 								</u-form-item>
 								<u-form-item label="描述" :prop="`dishCategories.${catIndex}.items.${dishIndex}.description`" :required="isEdited(dish)">
@@ -164,6 +165,15 @@ export default {
 			deep: true
 		}
 	},
+	onLoad() {
+		const goods = uni.getStorageSync('gm_goods');
+		if (goods.gmMerchantPackageDetails && goods.gmMerchantPackageDetails.length > 0) {
+			this.form.dishCategories.map(a => {
+				let items = goods.gmMerchantPackageDetails.filter(b => b.category == a.id);
+				if (items.length > 0) a.items = items;
+			});
+		}
+	},
 	mounted() {
 		this.$nextTick(() => {
 			this.$refs.formRef.setRules(this.rules);
@@ -174,6 +184,10 @@ export default {
 		isEdited(dish) {
 			return !!(dish.name || dish.price || dish.description);
 		},
+		isEditedShow(e) {
+			const goods = uni.getStorageSync('gm_goods');
+			return goods.gmMerchantPackageDetails && goods.gmMerchantPackageDetails.length > 0 && goods.gmMerchantPackageDetails.some(b => b.category == e.id);;
+		},
 		updateValidationRules() {
 			if (!this.$refs.formRef) return;
 			
@@ -187,7 +201,7 @@ export default {
 						const descProp = `dishCategories.${catIndex}.items.${dishIndex}.description`;
 						
 						newRules[nameProp] = [{ required: true, message: '请输入名称', trigger: ['blur', 'change'] }];
-						newRules[priceProp] = [{ required: true, message: '请输入价格', trigger: ['blur', 'change'] }];
+						newRules[priceProp] = [{ required: true, type: 'number', message: '请输入价格', trigger: ['blur', 'change'] }];
 						newRules[descProp] = [{ required: true, message: '请输入描述', trigger: ['blur', 'change'] }];
 					}
 				});
@@ -245,13 +259,41 @@ export default {
 		// 提交审核
 		submit() {
 			this.$refs.formRef.validate().then(res => {
-				const activeCategories = this.form.dishCategories.filter(c => c.items.some(this.isDishEdited));
+				const goods = uni.getStorageSync('gm_goods');
+				const activeCategories = this.form.dishCategories.filter(c => c.items.some(this.isEdited));
+				const details = [];
+				// 遍历一级分类
+				activeCategories.forEach(category => {
+					// 检查是否有items属性且为数组
+					if (category.items && Array.isArray(category.items)) {
+						// 遍历二级菜品
+						category.items.forEach(item => {
+							// 创建新对象,只保留需要的属性
+							details.push({
+								category: category.id,
+								name: item.name,
+								price: item.price,
+								description: item.description
+							});
+						});
+					}
+				});
 				let params = {
-					gmMerchantPackageDetails: [...activeCategories]
+					...goods,
+					gmMerchantPackageDetails: [...details]
 				};
 				console.log('表单校验成功, 提交的数据:', activeCategories, params);
 				this.$http.post('/groupmeal/gmMerchantPackage/submit', params).then(res => {
-					if (res.data.code === 200) {}
+					let type = res.data.code === 200 ? 'success' : 'error';
+					this.$tip[type](res.data.message);
+					if (res.data.code === 200) {
+						// 清除
+						uni.removeStorageSync('gm_goods');
+						// 返回列表
+						uni.navigateBack({
+							delta: 2
+						});
+					}
 				});
 			}).catch(errors => {
 				console.log('校验失败', errors);
@@ -287,6 +329,9 @@ export default {
 		display: flex;
 		align-items: center;
 		justify-content: space-between;
+		.num {
+			padding: 0 10rpx;
+		}
 	}
 	.collapse-content {
 		.dish-item {

+ 117 - 35
pages/groupMeal/goods/list.vue

@@ -25,6 +25,7 @@
 		<!-- 一级分类Tabs -->
 		<u-tabs :list="statusTabs" 
 			:current="currentStatusTab" 
+			font-size="30"
 			inactive-color="#666666"
 			:bar-style="{
 				bottom: '20rpx',
@@ -67,11 +68,11 @@
 							<u-image width="120rpx" height="120rpx" border-radius="12rpx" :src="goods.image" mode="aspectFill"></u-image>
 							<view class="goods-info">
 								<view class="goods-name">{{ goods.name }}</view>
-								<view class="goods-desc">{{ goods.description }}</view>
+								<view class="goods-desc">{{ goods.dishName || goods.description }}</view>
 								<view class="goods-sales">销量:{{ goods.sales }}</view>
 								<view class="goods-price-line">
 									<text class="price"><text class="unit">¥</text>{{ goods.price }}</text>
-									<text class="original-price">¥{{ goods.originalPrice }}</text>
+									<text class="original-price">¥{{ goods.sellingPrice }}</text>
 								</view>
 							</view>
 							<!-- 根据模式和状态显示不同操作 -->
@@ -81,7 +82,7 @@
 									type="primary" plain
 									@click="editGoods(goods)"
 								>编辑</u-button>
-								<u-checkbox v-if="isManaging" :name="goods.id" shape="circle" v-model="goods.checked"></u-checkbox>
+								<u-checkbox v-if="isManaging" :name="goods.id" shape="circle" v-model="goods.checked" @change="onSelect"></u-checkbox>
 							</view>
 						</view>
 					</u-checkbox-group>
@@ -89,10 +90,18 @@
 			</scroll-view>
 		</view>
 
+		<!-- <ListScrollView ref="listScroll0" 
+			:api="api"
+			:init="{
+				...initParams,
+			}">
+			<template v-slot:list="{ data }"></template>
+		</ListScrollView> -->
+
 		<!-- 批量管理底部操作栏 -->
 		<view class="footer-bar" v-if="isManaging">
 			<u-checkbox-group v-model="isAllSelected" placement="row">
-				<u-checkbox name="all" shape="circle" v-model="isAllSelected" @change="selectAll">全选</u-checkbox>
+				<u-checkbox name="all" shape="circle" v-model="isAllSelected" @change="onSelectAll">全选</u-checkbox>
 			</u-checkbox-group>
 			
 			<view class="action-buttons">
@@ -110,7 +119,6 @@
 		<Modal ref="myModal"
 			:title="modalText.title" 
 			:content="modalText.content" 
-			:showCancelButton="false"
 		/>
 	</view>
 </template>
@@ -118,29 +126,30 @@
 <script>
 import Modal from '@/components/modal/index.vue';
 import Tabbar from '@/pages/groupMeal/tabbar/index.vue';
+import configService from '@/common/service/config.service';
+import ListScrollView from '@/components/list-scroll-view/index.vue';
 export default {
 	components: {
 		Modal,
-		Tabbar
+		Tabbar,
+		ListScrollView
 	},
 	data() {
 		return {
-			isManaging: false, // 是否处于批量管理模式
+			api: {
+				url: '/groupmeal/gmMerchantPackage/pageList',
+				method: 'POST',
+			},
+			// 是否处于批量管理模式
+			isManaging: false, 
 			// 一级分类
 			statusTabs: [{ name: '售卖中' }, { name: '审核中' }, { name: '未上架' }],
 			currentStatusTab: 0,
 			// 二级分类
 			categoryTabs: [{ name: '早餐' }, { name: '午餐' }, { name: '晚餐' }],
 			currentCategoryTab: 0,
-			// 所有商品数据 (模拟)
-			allGoods: [
-				{ id: 1, categoryId: 0, status: 0, name: '套餐名称套餐名称套餐名称套餐名称', sales: 1255, price: 10.8, originalPrice: 12, description: '米饭, 鱼香肉丝, 宫保鸡丁', image: '/static/demo/goods1.png' },
-				{ id: 2, categoryId: 0, status: 0, name: '套餐名称套餐名称', sales: 1255, price: 14.8, originalPrice: 16, description: '米饭, 红烧排骨', image: '/static/demo/goods2.png' },
-				{ id: 3, categoryId: 1, status: 0, name: '套餐名称套餐名称', sales: 1255, price: 13.1, originalPrice: 15.0, description: '米饭, 糖醋里脊', image: '/static/demo/goods3.png' },
-				{ id: 4, categoryId: 0, status: 1, name: '审核中套餐', sales: 0, price: 20, originalPrice: 25, description: '审核中商品描述', image: '/static/demo/goods1.png' },
-				{ id: 5, categoryId: 0, status: 2, name: '未上架早餐', sales: 0, price: 15, originalPrice: 18, description: '未上架商品描述', image: '/static/demo/goods2.png' },
-				{ id: 6, categoryId: 1, status: 2, name: '未上架午餐', sales: 0, price: 25, originalPrice: 30, description: '未上架商品描述', image: '/static/demo/goods3.png' },
-			],
+			// 所有商品数据
+			allGoods: [],
 			selectedGoods: [], // 已选中的商品ID
 			isAllSelected: false, // 用于全选checkbox的状态绑定
 			// 联动功能相关数据
@@ -151,20 +160,18 @@ export default {
 			modalText: {
 				title: '提示',
 				btntext: '确定',
-				// 是否将所选商品上架?
 				// 所选商品有未通过审核商品无法批量操作上架
-				// 是否将所选商品删除?删除后需重新添加品牌标配
-				content: '报名成功,请等待平台审核'
+				content: '是否将所选商品上架?'
 			},
 		};
 	},
 	computed: {
 		// 根据一、二级分类筛选商品
 		filteredGoods() {
-			const filteredByCategory = this.allGoods.filter(goods => goods.status === this.currentStatusTab);
+			const filteredByCategory = this.allGoods;
 			const grouped = [];
 			this.categoryTabs.forEach((category, index) => {
-				const items = filteredByCategory.filter(goods => goods.categoryId === index);
+				const items = filteredByCategory.filter(goods => goods.category == (index + 1));
 				if (items.length > 0) {
 					grouped.push({
 						id: index,
@@ -180,6 +187,35 @@ export default {
 				this.calculateCategoryOffsets();
 			});
 			return grouped;
+		},
+		// 数据参数
+		initParams() {
+			let params = {
+				// 商品状态: 0 未上架, 1 已上架
+				status: 0,
+				// 审核状态: 0 审核中, 1 已审核
+				// reviewStatus: 0,
+			}
+			// 售卖中
+			if (this.currentStatusTab == 0) {
+				params = {
+					status: 1,
+				}
+			}
+			// 审核中 
+			else if (this.currentStatusTab == 1) {
+				params = {
+					status: 0,
+					reviewStatus: 0,
+				}
+			}
+			// 未上架
+			else if (this.currentStatusTab == 2) {
+				params = {
+					status: 0,
+				}
+			}
+			return params;
 		}
 	},
 	onLoad() {
@@ -187,19 +223,24 @@ export default {
 		this.getData();
 		// 获取餐品分类
 		this.getClassData();
-		// this.$refs.myModal.onOpen();
 	},
 	methods: {
 		// 商品数据
 		getData() {
 			let params = {
-				status: 0,
-				reviewStatus: 1,
 				pageNo: 1,
-				pageSize: 10
+				pageSize: 10,
+				...this.initParams
 			};
 			this.$http.post('/groupmeal/gmMerchantPackage/pageList', params).then(res => {
-				if (res.data.code === 200) {}
+				if (res.data.code === 200) {
+					this.allGoods = res.data.result.records.map(item => {
+						return {
+							...item,
+							image: configService.apiUrl + '/' + item.productImage.split(',')[0]
+						}
+					});
+				}
 			});
 		},
 		// 餐品分类
@@ -213,12 +254,19 @@ export default {
 			this.isManaging = !this.isManaging;
 			this.selectedGoods = []; // 切换模式时清空选择
 			this.isAllSelected = false;
+			if (!this.isManaging) {
+				this.filteredGoods.flatMap(category => category.items.forEach(item => {
+					item.checked = false;
+				}));
+			}
 		},
 		// 主分类事件
 		onTabChange(e) {
 			this.currentStatusTab = e;
 			this.selectedGoods = []; // 切换Tab时清空选择
 			this.isAllSelected = false;
+			// 列表数据
+			this.getData();
 			// 切换 Tab 后,重置左侧分类高亮到第一个
 			// this.currentCategoryTab = 0; 
 			// this.$nextTick(() => {
@@ -234,13 +282,22 @@ export default {
 		},
 		// 编辑商品
 		editGoods(goods) {
-			console.log('编辑商品:', goods);
 			uni.navigateTo({
 				url: '/pages/groupMeal/goods/form-step1?id=' + goods.id
 			});
 		},
+		// 单选
+		onSelect(e) {
+			if (e.value) {
+				this.selectedGoods.push(e.name);
+			} else {
+				let i = this.selectedGoods.indexOf(e.name);
+				this.selectedGoods.splice(i, 1);
+			}
+			this.isAllSelected = this.selectedGoods.length === this.allGoods.length;
+		},
 		// 全选事件
-		selectAll(e) {
+		onSelectAll(e) {
 			if (e.value) {
 				// 全选
 				this.selectedGoods = this.filteredGoods.flatMap(category => category.items.map(item => item.id));
@@ -258,18 +315,42 @@ export default {
 				uni.showToast({ title: '请先选择商品', icon: 'none' });
 				return;
 			}
+			let content = '';
 			if (action === 'delete') {
-
+				content = '是否将所选商品删除?';
+			} else {
+				content = `是否将所选商品${action === 'publish' ? '上架' : '下架'}?`;
+			}
+			this.modalText.content = content;
+			this.$refs.myModal.onOpen(false, () => {
+				this.onConfirm(action);
+			});
+			console.log(`执行批量操作: ${action}`, this.selectedGoods);
+		},
+		// 弹窗确认事件
+		onConfirm(action) {
+			if (action === 'delete') {
+				// 单删接口
+				// this.$http.get('/groupmeal/gmMerchantPackage/delete');
+				// 多删接口
+				this.$http.delete('/groupmeal/gmMerchantPackage/deleteBatch', {}, {
+					params: { ids: this.selectedGoods.join() }
+				}).then(res => {
+					if (res.data.code === 200) {}
+					this.$tip.toast(res.data.message);
+				});
 			} else {
-				this.$http.post('/groupmeal/gmMerchantPackage/launch', {
-					id: '',
-					status: action === 'publish' ? 1 : 0 
+				// 单个接口
+				// this.$http.post('/groupmeal/gmMerchantPackage/launch');
+				// 多选接口
+				this.$http.post('/groupmeal/gmMerchantPackage/batchLaunch', {
+					ids: this.selectedGoods,
+					status: this.currentStatusTab == 2 ? 1 : 0 
 				}).then(res => {
 					if (res.data.code === 200) {}
+					this.$tip.toast(res.data.message);
 				});
 			}
-			console.log(`执行批量操作: ${action}`, this.selectedGoods);
-			uni.showToast({ title: '操作成功', icon: 'success' });
 		},
 		// 核心功能 1: 点击左侧二级分类,右侧商品列表滚动到对应位置
 		onCategoryTabChange(index) {
@@ -406,11 +487,12 @@ export default {
 		flex: 1;
 		height: 100%;
 		background-color: #fff;
-		padding: 20rpx 24rpx;
+		padding: 0 24rpx 20rpx;
 		.category-title {
 			font-weight: 500;
 			font-size: 26rpx;
 			color: #000000;
+			padding-top: 20rpx;
 		}
 		.u-checkbox-group {
 			width: 100%;

+ 1 - 1
plugin/uni-simple-router/vueRouter/init.js

@@ -40,7 +40,7 @@ const rewriteUniFun = function (Router) {
     uni.navigateBack = function (delta) {
         let backLayer = delta;
         if (delta && delta.constructor === Object) { // 这种可能就只是uni-app自带的返回按钮,还有种可能就是开发者另类传递的
-            backLayer = 1;
+            backLayer = delta.delta || 1;
         }
         Router.back(backLayer, delta);
     };

+ 1 - 1
uni_modules/uview-ui/components/u-action-sheet/u-action-sheet.vue

@@ -145,7 +145,7 @@
 			itemClick(item, index) {
 				// disabled的项禁止点击
 				if(this.list[index].disabled) return;
-				this.$emit('click', { name: item.text, index });
+				this.$emit('click', { ...item, index });
 				this.$emit('input', false);
 			}
 		}