|
|
@@ -2,85 +2,87 @@
|
|
|
<view class="page-container">
|
|
|
<u-navbar title="新建团餐" :autoBack="true" :placeholder="true"></u-navbar>
|
|
|
|
|
|
- <u-collapse ref="collapseRef"
|
|
|
- :value="activeNames"
|
|
|
- @change="onCollapseChange">
|
|
|
- <u-collapse-item
|
|
|
- :class="{
|
|
|
- active: activeNames == category.id
|
|
|
- }"
|
|
|
- v-for="(category, index) in dishCategories"
|
|
|
- :key="category.id"
|
|
|
- :name="category.id"
|
|
|
- @click="onClick"
|
|
|
- >
|
|
|
- <view slot="title" class="collapse-title">
|
|
|
- <text>{{ category.name }}</text>
|
|
|
- <u-switch
|
|
|
- v-if="false"
|
|
|
- size="20"
|
|
|
- activeColor="#3c9cff"
|
|
|
- :value="category.isActive"
|
|
|
- @change="onSwitchChange($event, category.id)"
|
|
|
- ></u-switch>
|
|
|
- </view>
|
|
|
-
|
|
|
- <view class="collapse-content">
|
|
|
- <view class="dish-item" v-for="(dish, dishIndex) in category.items" :key="dish.id">
|
|
|
- <view class="dish-header">
|
|
|
- <view class="dish-title">
|
|
|
- <u-image width="32rpx" height="32rpx" src="/static/icon/icon_edit.png"></u-image>
|
|
|
- <text>{{ category.name }}{{ dishIndex + 1 }}</text>
|
|
|
+ <u-form :model="form" :rules="rules" ref="formRef" :error-type="['toast', 'border-bottom']">
|
|
|
+ <u-collapse ref="collapseRef"
|
|
|
+ :value="activeNames"
|
|
|
+ @change="onCollapseChange">
|
|
|
+ <u-collapse-item
|
|
|
+ :class="{
|
|
|
+ active: activeNames == category.id
|
|
|
+ }"
|
|
|
+ v-for="(category, catIndex) in form.dishCategories"
|
|
|
+ :key="category.id"
|
|
|
+ :name="category.id"
|
|
|
+ @click="onClick"
|
|
|
+ >
|
|
|
+ <view slot="title" class="collapse-title">
|
|
|
+ <text>{{ category.name }}</text>
|
|
|
+ <u-switch
|
|
|
+ v-if="false"
|
|
|
+ size="20"
|
|
|
+ activeColor="#3c9cff"
|
|
|
+ :value="category.isActive"
|
|
|
+ @change="onSwitchChange($event, category.id)"
|
|
|
+ ></u-switch>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <view class="collapse-content">
|
|
|
+ <view class="dish-item" v-for="(dish, dishIndex) in category.items" :key="dish.id">
|
|
|
+ <view class="dish-header">
|
|
|
+ <view class="dish-title">
|
|
|
+ <u-image width="32rpx" height="32rpx" src="/static/icon/icon_edit.png"></u-image>
|
|
|
+ <text>{{ category.name }}{{ dishIndex + 1 }}</text>
|
|
|
+ </view>
|
|
|
+ <view class="dish-actions">
|
|
|
+ <u-button v-if="dishIndex === category.items.length - 1"
|
|
|
+ type="primary" size="mini"
|
|
|
+ hover-class="none"
|
|
|
+ :custom-style="{
|
|
|
+ color: '#2D88F4',
|
|
|
+ border: '1rpx solid #2D88F4',
|
|
|
+ background: 'rgba(45,136,244,0.1)',
|
|
|
+ }"
|
|
|
+ @click="addDish(category.id)"
|
|
|
+ >
|
|
|
+ <view class="text">
|
|
|
+ <u-image width="32rpx" height="32rpx" src="/static/icon/icon_plus.png"></u-image>
|
|
|
+ <text>添加</text>
|
|
|
+ </view>
|
|
|
+ </u-button>
|
|
|
+ <u-button v-if="category.items.length > 1"
|
|
|
+ type="error" size="mini"
|
|
|
+ hover-class="none"
|
|
|
+ :custom-style="{
|
|
|
+ color: '#FF6067',
|
|
|
+ border: '1rpx solid #FF6067',
|
|
|
+ background: 'rgba(255,96,103,0.1)',
|
|
|
+ }"
|
|
|
+ @click="removeDish(category.id, dish.id)"
|
|
|
+ >
|
|
|
+ <view class="text">
|
|
|
+ <u-image width="32rpx" height="32rpx" src="/static/icon/icon_del.png"></u-image>
|
|
|
+ <text>删除</text>
|
|
|
+ </view>
|
|
|
+ </u-button>
|
|
|
+ </view>
|
|
|
</view>
|
|
|
- <view class="dish-actions">
|
|
|
- <u-button v-if="dishIndex === category.items.length - 1"
|
|
|
- type="primary" size="mini"
|
|
|
- hover-class="none"
|
|
|
- :custom-style="{
|
|
|
- color: '#2D88F4',
|
|
|
- border: '1rpx solid #2D88F4',
|
|
|
- background: 'rgba(45,136,244,0.1)',
|
|
|
- }"
|
|
|
- @click="addDish(category.id)"
|
|
|
- >
|
|
|
- <view class="text">
|
|
|
- <u-image width="32rpx" height="32rpx" src="/static/icon/icon_plus.png"></u-image>
|
|
|
- <text>添加</text>
|
|
|
- </view>
|
|
|
- </u-button>
|
|
|
- <u-button v-if="category.items.length > 1"
|
|
|
- type="error" size="mini"
|
|
|
- hover-class="none"
|
|
|
- :custom-style="{
|
|
|
- color: '#FF6067',
|
|
|
- border: '1rpx solid #FF6067',
|
|
|
- background: 'rgba(255,96,103,0.1)',
|
|
|
- }"
|
|
|
- @click="removeDish(category.id, dish.id)"
|
|
|
- >
|
|
|
- <view class="text">
|
|
|
- <u-image width="32rpx" height="32rpx" src="/static/icon/icon_del.png"></u-image>
|
|
|
- <text>删除</text>
|
|
|
- </view>
|
|
|
- </u-button>
|
|
|
+ <view class="dish-form">
|
|
|
+ <u-form-item label="名称" :prop="`dishCategories.${catIndex}.items.${dishIndex}.name`" :required="isEdited(dish)">
|
|
|
+ <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>
|
|
|
+ <text slot="right" style="color: #333333;">元</text>
|
|
|
+ </u-form-item>
|
|
|
+ <u-form-item label="描述" :prop="`dishCategories.${catIndex}.items.${dishIndex}.description`" :required="isEdited(dish)">
|
|
|
+ <u-input v-model="dish.description" height="41" placeholder="请描述菜品的使用素材" inputAlign="right"></u-input>
|
|
|
+ </u-form-item>
|
|
|
</view>
|
|
|
</view>
|
|
|
- <view class="dish-form">
|
|
|
- <u-form-item label="名称">
|
|
|
- <u-input v-model="dish.name" height="41" placeholder="请输入" inputAlign="right"></u-input>
|
|
|
- </u-form-item>
|
|
|
- <u-form-item label="价格">
|
|
|
- <u-input v-model="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="描述" :borderBottom="false">
|
|
|
- <u-input v-model="dish.description" height="41" placeholder="请描述菜品的使用素材" inputAlign="right"></u-input>
|
|
|
- </u-form-item>
|
|
|
- </view>
|
|
|
</view>
|
|
|
- </view>
|
|
|
- </u-collapse-item>
|
|
|
- </u-collapse>
|
|
|
+ </u-collapse-item>
|
|
|
+ </u-collapse>
|
|
|
+ </u-form>
|
|
|
|
|
|
<view class="footer-bar">
|
|
|
<u-button
|
|
|
@@ -113,61 +115,97 @@ let dishIdCounter = 100; // 简单的唯一ID生成器
|
|
|
export default {
|
|
|
data() {
|
|
|
return {
|
|
|
- // 模拟菜品分类和菜品数据
|
|
|
- dishCategories: [
|
|
|
- {
|
|
|
- id: 1,
|
|
|
- name: '荤菜',
|
|
|
- isActive: false,
|
|
|
- items: [{ id: dishIdCounter++, name: '', price: '', description: '' }]
|
|
|
- },
|
|
|
- {
|
|
|
- id: 2,
|
|
|
- name: '素菜',
|
|
|
- isActive: false,
|
|
|
- items: [{ id: dishIdCounter++, name: '', price: '', description: '' }]
|
|
|
- },
|
|
|
- {
|
|
|
- id: 3,
|
|
|
- name: '主食',
|
|
|
- isActive: false,
|
|
|
- items: [{ id: dishIdCounter++, name: '', price: '', description: '' }]
|
|
|
- },
|
|
|
- {
|
|
|
- id: 4,
|
|
|
- name: '汤',
|
|
|
- isActive: false,
|
|
|
- items: [{ id: dishIdCounter++, name: '', price: '', description: '' }]
|
|
|
- },
|
|
|
- {
|
|
|
- id: 5,
|
|
|
- name: '其他',
|
|
|
- isActive: false,
|
|
|
- items: [{ id: dishIdCounter++, name: '', price: '', description: '' }]
|
|
|
- }
|
|
|
- ],
|
|
|
+ // 数据
|
|
|
+ form: {
|
|
|
+ dishCategories: [
|
|
|
+ {
|
|
|
+ id: 1,
|
|
|
+ name: '荤菜',
|
|
|
+ isActive: false,
|
|
|
+ items: [{ id: dishIdCounter++, name: '', price: '', description: '' }]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: 2,
|
|
|
+ name: '素菜',
|
|
|
+ isActive: false,
|
|
|
+ items: [{ id: dishIdCounter++, name: '', price: '', description: '' }]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: 3,
|
|
|
+ name: '主食',
|
|
|
+ isActive: false,
|
|
|
+ items: [{ id: dishIdCounter++, name: '', price: '', description: '' }]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: 4,
|
|
|
+ name: '汤',
|
|
|
+ isActive: false,
|
|
|
+ items: [{ id: dishIdCounter++, name: '', price: '', description: '' }]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: 5,
|
|
|
+ name: '其他',
|
|
|
+ isActive: false,
|
|
|
+ items: [{ id: dishIdCounter++, name: '', price: '', description: '' }]
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ },
|
|
|
+ rules: {},
|
|
|
activeNames: [1], // 控制折叠面板展开的name数组
|
|
|
};
|
|
|
},
|
|
|
+ watch: {
|
|
|
+ 'form.dishCategories': {
|
|
|
+ handler() {
|
|
|
+ this.$nextTick(() => {
|
|
|
+ this.updateValidationRules();
|
|
|
+ });
|
|
|
+ },
|
|
|
+ deep: true
|
|
|
+ }
|
|
|
+ },
|
|
|
+ mounted() {
|
|
|
+ this.$nextTick(() => {
|
|
|
+ this.$refs.formRef.setRules(this.rules);
|
|
|
+ });
|
|
|
+ },
|
|
|
methods: {
|
|
|
+ // 判断一个菜品是否被编辑过
|
|
|
+ isEdited(dish) {
|
|
|
+ return !!(dish.name || dish.price || dish.description);
|
|
|
+ },
|
|
|
+ updateValidationRules() {
|
|
|
+ if (!this.$refs.formRef) return;
|
|
|
+
|
|
|
+ const newRules = {};
|
|
|
+ this.form.dishCategories.forEach((category, catIndex) => {
|
|
|
+ category.items.forEach((dish, dishIndex) => {
|
|
|
+ if (this.isEdited(dish)) {
|
|
|
+ // 如果菜品的任一字段被填写,则所有字段都变为必填
|
|
|
+ const nameProp = `dishCategories.${catIndex}.items.${dishIndex}.name`;
|
|
|
+ const priceProp = `dishCategories.${catIndex}.items.${dishIndex}.price`;
|
|
|
+ const descProp = `dishCategories.${catIndex}.items.${dishIndex}.description`;
|
|
|
+
|
|
|
+ newRules[nameProp] = [{ required: true, message: '请输入名称', trigger: ['blur', 'change'] }];
|
|
|
+ newRules[priceProp] = [{ required: true, message: '请输入价格', trigger: ['blur', 'change'] }];
|
|
|
+ newRules[descProp] = [{ required: true, message: '请输入描述', trigger: ['blur', 'change'] }];
|
|
|
+ }
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ this.rules = newRules;
|
|
|
+ this.$refs.formRef.setRules(this.rules);
|
|
|
+ },
|
|
|
// Switch开关状态变化
|
|
|
onSwitchChange(isActive, categoryId) {
|
|
|
- const category = this.dishCategories.find(c => c.id === categoryId);
|
|
|
- if (category) {
|
|
|
- category.isActive = isActive;
|
|
|
-
|
|
|
- // 联动折叠面板
|
|
|
- if (isActive) {
|
|
|
- // 如果是打开,且当前未展开,则添加到activeNames
|
|
|
- if (!this.activeNames.includes(categoryId)) {
|
|
|
- this.activeNames.push(categoryId);
|
|
|
- }
|
|
|
- } else {
|
|
|
- // 如果是关闭,从activeNames中移除
|
|
|
- const index = this.activeNames.indexOf(categoryId);
|
|
|
- if (index > -1) {
|
|
|
- this.activeNames.splice(index, 1);
|
|
|
- }
|
|
|
+ const index = this.activeNames.indexOf(categoryId);
|
|
|
+ if (isActive) {
|
|
|
+ if (index === -1) {
|
|
|
+ this.activeNames.push(categoryId);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (index > -1) {
|
|
|
+ this.activeNames.splice(index, 1);
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
@@ -175,14 +213,10 @@ export default {
|
|
|
onCollapseChange(names) {
|
|
|
console.log(names)
|
|
|
this.activeNames = names;
|
|
|
- // 反向联动Switch
|
|
|
- // this.dishCategories.forEach(category => {
|
|
|
- // category.isActive = names.includes(category.id);
|
|
|
- // });
|
|
|
},
|
|
|
// 添加菜品
|
|
|
addDish(categoryId) {
|
|
|
- const category = this.dishCategories.find(c => c.id === categoryId);
|
|
|
+ const category = this.form.dishCategories.find(c => c.id === categoryId);
|
|
|
if (category) {
|
|
|
category.items.push({
|
|
|
id: dishIdCounter++,
|
|
|
@@ -194,7 +228,7 @@ export default {
|
|
|
},
|
|
|
// 删除菜品
|
|
|
removeDish(categoryId, dishId) {
|
|
|
- const category = this.dishCategories.find(c => c.id === categoryId);
|
|
|
+ const category = this.form.dishCategories.find(c => c.id === categoryId);
|
|
|
if (category && category.items.length > 1) {
|
|
|
const index = category.items.findIndex(d => d.id === dishId);
|
|
|
if (index > -1) {
|
|
|
@@ -208,9 +242,12 @@ export default {
|
|
|
},
|
|
|
// 提交审核
|
|
|
submit() {
|
|
|
- const activeCategories = this.dishCategories.filter(c => c);
|
|
|
- console.log('提交的数据:', activeCategories);
|
|
|
- uni.showToast({ title: '提交成功', icon: 'success' });
|
|
|
+ this.$refs.formRef.validate().then(res => {
|
|
|
+ const activeCategories = this.form.dishCategories.filter(c => c.items.some(this.isDishEdited));
|
|
|
+ console.log('表单校验成功, 提交的数据:', activeCategories);
|
|
|
+ }).catch(errors => {
|
|
|
+ console.log('校验失败', errors);
|
|
|
+ });
|
|
|
}
|
|
|
}
|
|
|
};
|
|
|
@@ -280,7 +317,7 @@ export default {
|
|
|
}
|
|
|
}
|
|
|
.dish-form {
|
|
|
- padding: 0 16rpx;
|
|
|
+ padding: 6rpx 16rpx;
|
|
|
border-radius: 8rpx;
|
|
|
background: #F7F8FC;
|
|
|
}
|