| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345 |
- <template>
- <view class="page-container">
- <u-navbar title="新建团餐" :autoBack="true" :placeholder="true"></u-navbar>
-
- <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-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>
- </u-collapse-item>
- </u-collapse>
- </u-form>
- <view class="footer-bar">
- <u-button
- :custom-style="{
- width: '205rpx',
- fontWeight: '400',
- fontSize: '28rpx',
- color: '#449AFF',
- border: '1rpx solid #449AFF',
- background: '#fff',
- marginRight: '24rpx'
- }"
- @click="goBack"
- >上一步</u-button>
- <u-button
- :custom-style="{
- fontWeight: '400',
- fontSize: '28rpx',
- color: '#FFFFFF',
- background: 'linear-gradient(90deg, #77B6FF 0%, #449AFF 100%)',
- }"
- @click="submit"
- >提交审核</u-button>
- </view>
- </view>
- </template>
- <script>
- let dishIdCounter = 100; // 简单的唯一ID生成器
- export default {
- data() {
- return {
- // 数据
- 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 index = this.activeNames.indexOf(categoryId);
- if (isActive) {
- if (index === -1) {
- this.activeNames.push(categoryId);
- }
- } else {
- if (index > -1) {
- this.activeNames.splice(index, 1);
- }
- }
- },
- // 折叠面板状态变化
- onCollapseChange(names) {
- console.log(names)
- this.activeNames = names;
- },
- // 添加菜品
- addDish(categoryId) {
- const category = this.form.dishCategories.find(c => c.id === categoryId);
- if (category) {
- category.items.push({
- id: dishIdCounter++,
- name: '',
- price: '',
- description: ''
- });
- }
- },
- // 删除菜品
- removeDish(categoryId, dishId) {
- 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) {
- category.items.splice(index, 1);
- }
- }
- },
- // 上一步
- goBack() {
- uni.navigateBack();
- },
- // 提交审核
- submit() {
- 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);
- });
- }
- }
- };
- </script>
- <style lang="scss" scoped>
- .page-container {
- min-height: 100vh;
- background-color: #f5f5f5;
- padding-bottom: 160rpx;
- ::v-deep .u-collapse-item {
- margin-bottom: 16rpx;
- .u-collapse-head {
- padding: 20rpx 32rpx;
- background-color: #fff;
- }
- &.active {
- .u-collapse-body {
- height: auto !important;
- }
- }
- }
- .collapse-title {
- font-weight: 500;
- font-size: 32rpx;
- color: #333333;
- display: flex;
- align-items: center;
- justify-content: space-between;
- }
- .collapse-content {
- .dish-item {
- margin-top: 16rpx;
- padding: 20rpx 32rpx;
- background: #FFFFFF;
- box-shadow: 0 2rpx 8rpx 0 rgba(214,225,237,0.1);
- border: 1rpx solid #F0F3F5;
- border-radius: 16rpx;
- .dish-header {
- margin-bottom: 20rpx;
- display: flex;
- align-items: center;
- justify-content: space-between;
- .dish-title {
- font-size: 28rpx;
- color: #333333;
- display: flex;
- align-items: center;
- }
- .dish-actions {
- display: flex;
- gap: 16rpx;
- ::v-deep .u-btn {
- font-weight: 400;
- font-size: 22rpx;
- }
- .text {
- display: flex;
- align-items: center;
- text {
- line-height: 1;
- margin-left: 4rpx;
- }
- }
- }
- }
- .dish-form {
- padding: 6rpx 16rpx;
- border-radius: 8rpx;
- background: #F7F8FC;
- }
- ::v-deep .u-form-item {
- padding: 16rpx 0;
- line-height: 1;
- .u-form-item--left__content {
- flex: none;
- }
- }
- }
- }
- }
- .footer-bar {
- ::v-deep .u-btn {
- width: 100%;
- height: 76rpx;
- border-radius: 54rpx;
- &::after {
- display: none;
- }
- }
- }
- </style>
|