修复bug

This commit is contained in:
2026-04-15 09:29:11 +08:00
parent 7fb650e3a4
commit b452cb2b50
9 changed files with 250 additions and 133 deletions
+2 -2
View File
@@ -5,7 +5,7 @@ VITE_DELETE_CONSOLE=false
#本地环境 #本地环境
#VITE_SERVER_BASEURL=http://liuyao.nat100.top/meiguowaimai #VITE_SERVER_BASEURL=http://liuyao.nat100.top/meiguowaimai
#VITE_SERVER_BASEURL=http://192.168.5.58:8080 VITE_SERVER_BASEURL=http://192.168.5.4:8080
VITE_SERVER_BASEURL=https://howhowfresh.com/prod-api #VITE_SERVER_BASEURL=https://howhowfresh.com/prod-api
#VITE_SERVER_BASEURL=http://192.168.1.8:8811 #VITE_SERVER_BASEURL=http://192.168.1.8:8811
#VITE_SERVER_BASEURL=http://mifengchuantou.natapp1.cc/meiguowaimai #VITE_SERVER_BASEURL=http://mifengchuantou.natapp1.cc/meiguowaimai
+13 -8
View File
@@ -317,6 +317,10 @@
"discountedPrice": "Actual selling price:", "discountedPrice": "Actual selling price:",
"enterPlaceholder": "Enter", "enterPlaceholder": "Enter",
"frequentlyBoughtTogether": "Frequently Bought Together", "frequentlyBoughtTogether": "Frequently Bought Together",
"specManagement": "Specification Management",
"priceAutoFillTip": "Price is auto-filled from the first specification",
"originalPriceAutoFillTip": "Auto-filled from the first specification's list price",
"discountPriceAutoFillTip": "Auto-filled from the first specification's member price",
"itemActiveDesc": "Customers can view and order this dish", "itemActiveDesc": "Customers can view and order this dish",
"itemIsActive": "Item is Active", "itemIsActive": "Item is Active",
"itemIsNot": "The dish is not activated", "itemIsNot": "The dish is not activated",
@@ -346,19 +350,20 @@
}, },
"add-item": { "add-item": {
"add": "Add", "add": "Add",
"addSideDishes": "+ Add Side Dishes",
"enterPlaceholder": "Enter", "enterPlaceholder": "Enter",
"isRequired": "Is Required", "isRequired": "Is Required",
"name": "Name", "name": "Name",
"price": "Price($)", "price": "Price($)",
"sideDish": "Side Dish", "memberPrice": "Member price($)",
"sideDishesFlavorValue": "Side Dishes/Flavor Value:", "actualSalePrice": "Actual sale price($)",
"title": "Add Side Dish", "spec": "Specification",
"typeOfSideDishes": "Type of Side Dishes/Flavor:", "specValue": "Specification Value:",
"title": "Add Specification",
"specType": "Specification Type:",
"validation": { "validation": {
"addAtLeastOne": "Please add at least one side dish", "addAtLeastOne": "Please add at least one specification",
"completeAllFields": "Please complete all fields for side dish {index}", "completeAllFields": "Please complete all fields for specification {index}",
"enterSideDishName": "Please enter side dish name for item {index}", "enterSpecName": "Please enter specification name for item {index}",
"submittedSuccessfully": "Submitted successfully" "submittedSuccessfully": "Submitted successfully"
}, },
"value": "Value" "value": "Value"
+13 -8
View File
@@ -317,6 +317,10 @@
"discountedPrice": "实际销售价格:", "discountedPrice": "实际销售价格:",
"enterPlaceholder": "输入", "enterPlaceholder": "输入",
"frequentlyBoughtTogether": "经常一起购买", "frequentlyBoughtTogether": "经常一起购买",
"specManagement": "规格管理",
"priceAutoFillTip": "价格由第一项规格自动填充",
"originalPriceAutoFillTip": "由第一项规格中的「价格」自动填充",
"discountPriceAutoFillTip": "由第一项规格中的「会员价」自动填充",
"itemActiveDesc": "客户可以查看并订购此菜品", "itemActiveDesc": "客户可以查看并订购此菜品",
"itemIsActive": "菜品已激活", "itemIsActive": "菜品已激活",
"itemIsNot": "菜品未激活", "itemIsNot": "菜品未激活",
@@ -346,19 +350,20 @@
}, },
"add-item": { "add-item": {
"add": "添加", "add": "添加",
"addSideDishes": "+ 添加配菜",
"enterPlaceholder": "输入", "enterPlaceholder": "输入",
"isRequired": "是否必选", "isRequired": "是否必选",
"name": "名称", "name": "名称",
"price": "价格($)", "price": "价格($)",
"sideDish": "配菜", "memberPrice": "会员价($)",
"sideDishesFlavorValue": "配菜/口味值:", "actualSalePrice": "实际支付价格($)",
"title": "添加配菜", "spec": "规格",
"typeOfSideDishes": "配菜类型/口味", "specValue": "规格值",
"title": "添加规格",
"specType": "规格类型:",
"validation": { "validation": {
"addAtLeastOne": "请至少添加一个配菜", "addAtLeastOne": "请至少添加一个规格",
"completeAllFields": "请完成配菜 {index} 的所有字段", "completeAllFields": "请完成规格 {index} 的所有字段",
"enterSideDishName": "请输入配菜 {index} 的配菜名称", "enterSpecName": "请输入规格 {index} 的规格名称",
"submittedSuccessfully": "提交成功" "submittedSuccessfully": "提交成功"
}, },
"value": "值" "value": "值"
+2 -2
View File
@@ -2,8 +2,8 @@
"name" : "CHEFLINK Merchant", "name" : "CHEFLINK Merchant",
"appid" : "__UNI__BB8E3C9", "appid" : "__UNI__BB8E3C9",
"description" : "美国外卖商户端", "description" : "美国外卖商户端",
"versionName" : "2.0.1", "versionName" : "3.0.0",
"versionCode" : 201, "versionCode" : 300,
"transformPx" : false, "transformPx" : false,
/* 5+App */ /* 5+App */
"app-plus" : { "app-plus" : {
+17 -8
View File
@@ -80,15 +80,24 @@ const btnLoading = ref(false)
function codeSubmit() { function codeSubmit() {
// console.log(data) // console.log(data)
btnLoading.value = true btnLoading.value = true
const body: Record<string, any> = {
...logicStore.registerForm,
phone: logicStore.registerForm.phone,
areaCode: areaCode.value,
// captcha: data.code,
// uuid: data.uuid,
userPort: 2, // 登录端口2 商户端
}
if (!body.email) {
delete body.email
delete body.confirmEmail
}
if (logicStore.registerForm.type === 'email' && !String(body.phone ?? '').trim()) {
delete body.phone
delete body.areaCode
}
appUserRegisterPost({ appUserRegisterPost({
body: { body
...logicStore.registerForm,
phone: logicStore.registerForm.phone,
areaCode: areaCode.value,
// captcha: data.code,
// uuid: data.uuid,
userPort: 2, // 登录端口2 商户端
}
}).then((res) => { }).then((res) => {
;(userStore as any).token = (res as any).data?.token; ;(userStore as any).token = (res as any).data?.token;
logicStore.reset() logicStore.reset()
+59 -30
View File
@@ -45,16 +45,12 @@ const FormSchema = z.object({
}, },
{message: t('pages-user.food.add-food.schema.discountPricePositive') ?? '折扣价必须大于0'}, {message: t('pages-user.food.add-food.schema.discountPricePositive') ?? '折扣价必须大于0'},
), ),
// dishImage: z.array(z.string()).min(1, t('pages-user.food.add-food.schema.dishImage')),
stock: z.string() stock: z.string()
.min(1, t('pages-user.food.add-food.stockRequired')) .min(1, t('pages-user.food.add-food.stockRequired'))
.refine( .refine(
(val) => { (val) => {
// 检查是否为空字符串或仅包含空格
const trimmed = val.trim() const trimmed = val.trim()
if (trimmed === '') return false if (trimmed === '') return false
// 检查是否为整数
const num = Number(trimmed) const num = Number(trimmed)
return Number.isInteger(num) return Number.isInteger(num)
}, },
@@ -68,12 +64,9 @@ const FormSchema = z.object({
{message: t('pages-user.food.add-food.stockMustBeNonNegative')} {message: t('pages-user.food.add-food.stockMustBeNonNegative')}
) )
}).refine((data) => { }).refine((data) => {
// 验证折扣价不能高于原价
if (data.discountPrice && data.discountPrice.trim() !== '') { if (data.discountPrice && data.discountPrice.trim() !== '') {
const originalPrice = parseFloat(data.originalPrice) const originalPrice = parseFloat(data.originalPrice)
const discountPrice = parseFloat(data.discountPrice) const discountPrice = parseFloat(data.discountPrice)
// 检查是否为有效数字
if (!isNaN(originalPrice) && !isNaN(discountPrice)) { if (!isNaN(originalPrice) && !isNaN(discountPrice)) {
return discountPrice <= originalPrice return discountPrice <= originalPrice
} }
@@ -99,9 +92,56 @@ const removeImage = (index: number) => {
formData.value.dishImage.splice(index, 1) formData.value.dishImage.splice(index, 1)
} }
// 配菜数据
const merchantSideDishVoList = ref([]) const merchantSideDishVoList = ref([])
function syncPriceFromSpec() {
const specList = merchantSideDishVoList.value.merchantSideDishBoList
if (specList && specList.length > 0) {
const firstGroup = specList[0]
const items = firstGroup.merchantSideDishItemBoList
if (items && items.length > 0) {
const first = items[0] as { price?: string; memberPrice?: string }
const listPrice = first.price != null && String(first.price).trim() !== '' ? String(first.price).trim() : ''
const memberPrice =
first.memberPrice != null && String(first.memberPrice).trim() !== '' ? String(first.memberPrice).trim() : ''
if (listPrice) {
formData.value.originalPrice = listPrice
}
if (memberPrice) {
formData.value.discountPrice = memberPrice
}
}
}
}
/** 提交用:保持规格完整传递(包含第一项) */
function buildMerchantSideDishBoListForSubmit() {
const raw = merchantSideDishVoList.value.merchantSideDishBoList
if (!raw || !Array.isArray(raw) || raw.length === 0) {
return raw || []
}
return JSON.parse(JSON.stringify(raw)) as any[]
}
/** 保存/编辑请求体:去掉详情里的 Vo 列表与旧 Bo 列表,只传去重后的 merchantSideDishBoList,避免修改时重复提交 */
function buildDishSaveBody(stockValue: number) {
const fd = formData.value as Record<string, unknown>
const {
merchantSideDishVoList: _vo,
merchantSideDishBoList: _bo,
dishImage: _dishImgArr,
...rest
} = fd
return {
...rest,
tax: Number(formData.value.tax) / 100 || 0,
stock: stockValue,
merchantSideDishBoList: buildMerchantSideDishBoListForSubmit(),
dishImage: formData.value.dishImage.join(','),
delFlag: formData.value.isActive ? 1 : 3
}
}
function navigateTo(url: string) { function navigateTo(url: string) {
uni.navigateTo({ uni.navigateTo({
url, url,
@@ -110,11 +150,11 @@ function navigateTo(url: string) {
console.log(data) console.log(data)
if (data) { if (data) {
merchantSideDishVoList.value = data merchantSideDishVoList.value = data
syncPriceFromSpec()
} }
}, },
}, },
success: function (res) { success: function (res) {
// 通过eventChannel向被打开页面传送数据
res.eventChannel.emit('acceptDataFromOpenerPage', {data: merchantSideDishVoList.value.merchantSideDishBoList || []}) res.eventChannel.emit('acceptDataFromOpenerPage', {data: merchantSideDishVoList.value.merchantSideDishBoList || []})
} }
}) })
@@ -297,17 +337,11 @@ function saveDish() {
// 安全处理库存值 // 安全处理库存值
const stockValue = formData.value.stock ? Number(formData.value.stock.trim()) : 0 const stockValue = formData.value.stock ? Number(formData.value.stock.trim()) : 0
const body = buildDishSaveBody(stockValue)
if (formData.value.id) { if (formData.value.id) {
appMerchantDishEditDishPost({ appMerchantDishEditDishPost({
body: { body
...formData.value,
tax: Number(formData.value.tax) / 100 || 0,
stock: stockValue,
merchantSideDishBoList: merchantSideDishVoList.value.merchantSideDishBoList,
dishImage: formData.value.dishImage.join(','),
delFlag: formData.value.isActive ? 1 : 3
}
}).then(() => { }).then(() => {
uni.showToast({ uni.showToast({
title: t('toast.submitSuccess'), title: t('toast.submitSuccess'),
@@ -317,14 +351,7 @@ function saveDish() {
}) })
} else { } else {
appMerchantDishAddDishPost({ appMerchantDishAddDishPost({
body: { body
...formData.value,
tax: Number(formData.value.tax) / 100 || 0,
stock: stockValue,
merchantSideDishBoList: merchantSideDishVoList.value.merchantSideDishBoList,
dishImage: formData.value.dishImage.join(','),
delFlag: formData.value.isActive ? 1 : 3
}
}).then(() => { }).then(() => {
uni.showToast({ uni.showToast({
title: t('toast.submitSuccess'), title: t('toast.submitSuccess'),
@@ -455,7 +482,7 @@ function saveDish() {
</view> </view>
</view> </view>
<!-- 价格输入 --> <!-- 价格自动从第一项规格填充只读 -->
<view class="form-item mb-52rpx"> <view class="form-item mb-52rpx">
<text class="label text-36rpx lh-36rpx text-#333 mb-20rpx block font-500">{{ <text class="label text-36rpx lh-36rpx text-#333 mb-20rpx block font-500">{{
t('pages-user.food.add-food.price') t('pages-user.food.add-food.price')
@@ -466,8 +493,8 @@ function saveDish() {
<wd-input <wd-input
v-model="formData.originalPrice" v-model="formData.originalPrice"
:focus-when-clear="false" :focus-when-clear="false"
clearable
custom-class="!text-30rpx !bg-transparent flex-1" custom-class="!text-30rpx !bg-transparent flex-1"
disabled
no-border no-border
placeholder="0.00" placeholder="0.00"
placeholderStyle="font-size: 30rpx;color: #999;" placeholderStyle="font-size: 30rpx;color: #999;"
@@ -475,9 +502,10 @@ function saveDish() {
> >
</wd-input> </wd-input>
</view> </view>
<text class="text-24rpx text-#999 mt-10rpx block">{{ t('pages-user.food.add-food.originalPriceAutoFillTip') }}</text>
</view> </view>
<!-- 折扣价输入 --> <!-- 实际销售价格自动从第一项规格会员价填充只读 -->
<view class="form-item mb-52rpx"> <view class="form-item mb-52rpx">
<text class="label text-36rpx lh-36rpx text-#333 mb-20rpx block font-500"> <text class="label text-36rpx lh-36rpx text-#333 mb-20rpx block font-500">
{{ t('pages-user.food.add-food.discountedPrice') }} {{ t('pages-user.food.add-food.discountedPrice') }}
@@ -487,8 +515,8 @@ function saveDish() {
<wd-input <wd-input
v-model="formData.discountPrice" v-model="formData.discountPrice"
:focus-when-clear="false" :focus-when-clear="false"
clearable
custom-class="!text-30rpx !bg-transparent flex-1" custom-class="!text-30rpx !bg-transparent flex-1"
disabled
no-border no-border
placeholder="0.00" placeholder="0.00"
placeholderStyle="font-size: 30rpx;color: #999;" placeholderStyle="font-size: 30rpx;color: #999;"
@@ -496,6 +524,7 @@ function saveDish() {
> >
</wd-input> </wd-input>
</view> </view>
<text class="text-24rpx text-#999 mt-10rpx block">{{ t('pages-user.food.add-food.discountPriceAutoFillTip') }}</text>
</view> </view>
<!-- 重量: --> <!-- 重量: -->
@@ -580,7 +609,7 @@ function saveDish() {
<view class="form-item mb-52rpx"> <view class="form-item mb-52rpx">
<view class="flex-center-sb"> <view class="flex-center-sb">
<text class="text-36rpx lh-36rpx text-#333 mb-20rpx block font-500"> <text class="text-36rpx lh-36rpx text-#333 mb-20rpx block font-500">
{{ t('pages-user.food.add-food.frequentlyBoughtTogether') }} {{ t('pages-user.food.add-food.specManagement') }}
</text> </text>
<view class="bg-#F2F2F2 rounded-32rpx w-158rpx h-64rpx center font-500 text-26rpx text-#333" <view class="bg-#F2F2F2 rounded-32rpx w-158rpx h-64rpx center font-500 text-26rpx text-#333"
@click="navigateTo('/pages-user/pages/food/add-item')"> @click="navigateTo('/pages-user/pages/food/add-item')">
+81 -60
View File
@@ -1,68 +1,65 @@
<script lang="ts" setup> <script lang="ts" setup>
const {t} = useI18n() const {t} = useI18n()
// 配菜值的类型定义 interface SpecValue {
interface SideDishValue {
name: string name: string
price: string price: string
memberPrice: string
actualSalePrice: string
} }
// 配菜组的类型定义 interface SpecGroup {
interface SideDishGroup {
sideDishName: string sideDishName: string
isRequired: 1 | 2, // 是否必选,1表示必选 2非必选 isRequired: 1 | 2,
merchantSideDishItemBoList: SideDishValue[] merchantSideDishItemBoList: SpecValue[]
} }
// 表单数据
const formData = reactive({ const formData = reactive({
merchantSideDishBoList: [] as SideDishGroup[] merchantSideDishBoList: [] as SpecGroup[]
}) })
// 添加配菜组 const addSpecGroup = () => {
const addSideDishGroup = () => { const newGroup: SpecGroup = {
const newGroup: SideDishGroup = {
sideDishName: '', sideDishName: '',
isRequired: 1, isRequired: 1,
merchantSideDishItemBoList: [ merchantSideDishItemBoList: [
{ {
name: '', name: '',
price: '' price: '',
memberPrice: '',
actualSalePrice: ''
} }
] ]
} }
formData.merchantSideDishBoList.push(newGroup) formData.merchantSideDishBoList.push(newGroup)
} }
// 删除配菜组 const removeSpecGroup = (groupIndex: number) => {
const removeSideDishGroup = (groupIndex: number) => {
formData.merchantSideDishBoList.splice(groupIndex, 1) formData.merchantSideDishBoList.splice(groupIndex, 1)
} }
// 添加配菜值 const addSpecValue = (groupIndex: number) => {
const addSideDishValue = (groupIndex: number) => { const newValue: SpecValue = {
const newValue: SideDishValue = {
name: '', name: '',
price: '' price: '',
memberPrice: '',
actualSalePrice: ''
} }
formData.merchantSideDishBoList[groupIndex].merchantSideDishItemBoList.push(newValue) formData.merchantSideDishBoList[groupIndex].merchantSideDishItemBoList.push(newValue)
} }
// 删除配菜值 const removeSpecValue = (groupIndex: number, valueIndex: number) => {
const removeSideDishValue = (groupIndex: number, valueIndex: number) => {
if (formData.merchantSideDishBoList[groupIndex].merchantSideDishItemBoList.length > 1) { if (formData.merchantSideDishBoList[groupIndex].merchantSideDishItemBoList.length > 1) {
formData.merchantSideDishBoList[groupIndex].merchantSideDishItemBoList.splice(valueIndex, 1) formData.merchantSideDishBoList[groupIndex].merchantSideDishItemBoList.splice(valueIndex, 1)
} }
} }
// 提交表单
const submitForm = () => { const submitForm = () => {
// 验证表单
for (let i = 0; i < formData.merchantSideDishBoList.length; i++) { for (let i = 0; i < formData.merchantSideDishBoList.length; i++) {
const group = formData.merchantSideDishBoList[i] const group = formData.merchantSideDishBoList[i]
if (!group.sideDishName.trim()) { if (!group.sideDishName.trim()) {
uni.showToast({ uni.showToast({
title: t('pages-user.food.add-item.validation.enterSideDishName', {index: i + 1}), title: t('pages-user.food.add-item.validation.enterSpecName', {index: i + 1}),
icon: 'none' icon: 'none'
}) })
return return
@@ -70,7 +67,7 @@ const submitForm = () => {
for (let j = 0; j < group.merchantSideDishItemBoList.length; j++) { for (let j = 0; j < group.merchantSideDishItemBoList.length; j++) {
const value = group.merchantSideDishItemBoList[j] const value = group.merchantSideDishItemBoList[j]
if (!value.name.trim() || !value.price.trim()) { if (!value.name.trim() || !value.price.trim() || !value.memberPrice.trim() || !value.actualSalePrice.trim()) {
uni.showToast({ uni.showToast({
title: t('pages-user.food.add-item.validation.completeAllFields', {index: i + 1}), title: t('pages-user.food.add-item.validation.completeAllFields', {index: i + 1}),
icon: 'none' icon: 'none'
@@ -88,7 +85,6 @@ const submitForm = () => {
return return
} }
// 这里可以调用API提交数据
console.log('Submit form:', formData) console.log('Submit form:', formData)
uni.showToast({ uni.showToast({
@@ -108,7 +104,20 @@ onMounted(() => {
eventChannel.on('acceptDataFromOpenerPage', function (data) { eventChannel.on('acceptDataFromOpenerPage', function (data) {
console.log('acceptDataFromOpenerPage', data.data) console.log('acceptDataFromOpenerPage', data.data)
if (data.data && data.data.length > 0) { if (data.data && data.data.length > 0) {
formData.merchantSideDishBoList = data.data formData.merchantSideDishBoList = data.data.map((group: SpecGroup) => ({
...group,
merchantSideDishItemBoList: (group.merchantSideDishItemBoList || []).map((item) => ({
...item,
memberPrice:
item.memberPrice !== undefined && item.memberPrice !== null && String(item.memberPrice) !== ''
? String(item.memberPrice)
: '',
actualSalePrice:
item.actualSalePrice !== undefined && item.actualSalePrice !== null && String(item.actualSalePrice) !== ''
? String(item.actualSalePrice)
: ''
}))
}))
} }
}) })
}) })
@@ -117,10 +126,9 @@ onUnload(() => {
eventChannel = null eventChannel = null
}) })
// 初始化一个配菜组 addSpecGroup()
addSideDishGroup()
function handleClickItem(group: SideDishGroup) { function handleClickItem(group: SpecGroup) {
group.isRequired = group.isRequired === 1 ? 2 : 1 group.isRequired = group.isRequired === 1 ? 2 : 1
} }
</script> </script>
@@ -132,33 +140,28 @@ function handleClickItem(group: SideDishGroup) {
<!-- 页面内容 --> <!-- 页面内容 -->
<view class="content px-30rpx pt-40rpx pb-200rpx"> <view class="content px-30rpx pt-40rpx pb-200rpx">
<!-- 配菜组列表 -->
<view <view
v-for="(group, groupIndex) in formData.merchantSideDishBoList" v-for="(group, groupIndex) in formData.merchantSideDishBoList"
:key="groupIndex" :key="groupIndex"
class="side-dish-group mb-40rpx" class="spec-group mb-40rpx"
> >
<!-- 配菜组容器 -->
<view class="flex-center-sb mb-26rpx"> <view class="flex-center-sb mb-26rpx">
<!-- 配菜组标题 --> <text class="text-28rpx text-#999 block">{{ t('pages-user.food.add-item.spec') }} {{
<text class="text-28rpx text-#999 block">{{ t('pages-user.food.add-item.sideDish') }} {{
groupIndex + 1 groupIndex + 1
}}: }}:
</text> </text>
<!-- 删除配菜组按钮 -->
<view <view
class="w-48rpx h-48rpx" class="w-48rpx h-48rpx"
@tap="removeSideDishGroup(groupIndex)" @tap="removeSpecGroup(groupIndex)"
> >
<image class="w-48rpx h-48rpx" src="@img/chef/190.png"></image> <image class="w-48rpx h-48rpx" src="@img/chef/190.png"></image>
</view> </view>
</view> </view>
<view class="bg-white rounded-20rpx px-20rpx py-30rpx relative"> <view class="bg-white rounded-20rpx px-20rpx py-30rpx relative">
<!-- 配菜类型输入 -->
<view class="mb-20rpx"> <view class="mb-20rpx">
<text class="text-36rpx text-#333 font-500 mb-20rpx block">{{ <text class="text-36rpx text-#333 font-500 mb-20rpx block">{{
t('pages-user.food.add-item.typeOfSideDishes') t('pages-user.food.add-item.specType')
}} }}
</text> </text>
<view class="bg-#F6F6F6 rounded-16rpx h-98rpx px-24rpx flex items-center"> <view class="bg-#F6F6F6 rounded-16rpx h-98rpx px-24rpx flex items-center">
@@ -177,13 +180,11 @@ function handleClickItem(group: SideDishGroup) {
</view> </view>
</view> </view>
<!-- 配菜组必选状态 -->
<view class="mb-44rpx flex-center-sb"> <view class="mb-44rpx flex-center-sb">
<text class="text-36rpx text-#333 font-500 mb-20rpx block"> <text class="text-36rpx text-#333 font-500 mb-20rpx block">
{{ t('pages-user.food.add-item.isRequired') }} {{ t('pages-user.food.add-item.isRequired') }}
</text> </text>
<view class="shrink-0" @click="handleClickItem(group)"> <view class="shrink-0" @click="handleClickItem(group)">
<!-- 单选按钮 -->
<image <image
:src=" :src="
group.isRequired === 1 group.isRequired === 1
@@ -196,35 +197,29 @@ function handleClickItem(group: SideDishGroup) {
</view> </view>
</view> </view>
<!-- 配菜值标题 -->
<text class="text-36rpx text-#333 font-500 mb-30rpx block"> <text class="text-36rpx text-#333 font-500 mb-30rpx block">
{{ t('pages-user.food.add-item.sideDishesFlavorValue') }} {{ t('pages-user.food.add-item.specValue') }}
</text> </text>
<!-- 配菜值列表 -->
<view class="values-list"> <view class="values-list">
<view <view
v-for="(value, valueIndex) in group.merchantSideDishItemBoList" v-for="(value, valueIndex) in group.merchantSideDishItemBoList"
:key="valueIndex" :key="valueIndex"
class="mb-10rpx last:mb-0" class="mb-10rpx last:mb-0"
> >
<!-- 配菜值容器 -->
<view class="bg-white py-28rpx border-2rpx border-solid border-#DFDFDF rounded-16rpx px-20rpx"> <view class="bg-white py-28rpx border-2rpx border-solid border-#DFDFDF rounded-16rpx px-20rpx">
<view class="flex-center-sb mb-26rpx"> <view class="flex-center-sb mb-26rpx">
<!-- 配菜组标题 -->
<text class="text-26rpx text-#333 font-500 block">{{ t('pages-user.food.add-item.value') }} <text class="text-26rpx text-#333 font-500 block">{{ t('pages-user.food.add-item.value') }}
{{ valueIndex + 1 }}: {{ valueIndex + 1 }}:
</text> </text>
<!-- 删除配菜组按钮 -->
<view <view
class="w-48rpx h-48rpx" class="w-48rpx h-48rpx"
@click="removeSideDishValue(groupIndex, valueIndex)" @click="removeSpecValue(groupIndex, valueIndex)"
> >
<image class="w-48rpx h-48rpx" src="@img/chef/190.png"></image> <image class="w-48rpx h-48rpx" src="@img/chef/190.png"></image>
</view> </view>
</view> </view>
<!-- 名称输入 -->
<view class="form-row flex items-center mb-24rpx"> <view class="form-row flex items-center mb-24rpx">
<text class="label text-28rpx text-#333 w-120rpx">{{ t('pages-user.food.add-item.name') }}</text> <text class="label text-28rpx text-#333 w-120rpx">{{ t('pages-user.food.add-item.name') }}</text>
<view class="bg-#F6F6F6 rounded-16rpx h-88rpx px-20rpx flex-1 flex items-center"> <view class="bg-#F6F6F6 rounded-16rpx h-88rpx px-20rpx flex-1 flex items-center">
@@ -243,8 +238,7 @@ function handleClickItem(group: SideDishGroup) {
</view> </view>
</view> </view>
<!-- 价格输入 --> <view class="form-row flex items-center mb-24rpx">
<view class="form-row flex items-center">
<text class="label text-28rpx text-#333 w-120rpx">{{ t('pages-user.food.add-item.price') }}</text> <text class="label text-28rpx text-#333 w-120rpx">{{ t('pages-user.food.add-item.price') }}</text>
<view class="bg-#F6F6F6 rounded-16rpx h-88rpx px-20rpx flex-1 flex items-center"> <view class="bg-#F6F6F6 rounded-16rpx h-88rpx px-20rpx flex-1 flex items-center">
<wd-input <wd-input
@@ -261,27 +255,54 @@ function handleClickItem(group: SideDishGroup) {
</wd-input> </wd-input>
</view> </view>
</view> </view>
<view class="form-row flex items-center mb-24rpx">
<text class="label text-28rpx text-#333 w-120rpx">{{ t('pages-user.food.add-item.memberPrice') }}</text>
<view class="bg-#F6F6F6 rounded-16rpx h-88rpx px-20rpx flex-1 flex items-center">
<wd-input
v-model="value.memberPrice"
:focus-when-clear="false"
:placeholder="t('pages-user.food.add-item.enterPlaceholder')"
clearable
confirm-type="search"
custom-class="!text-30rpx !bg-transparent flex-1"
no-border
placeholderStyle="font-size: 30rpx;color: #999;"
use-prefix-slot
>
</wd-input>
</view>
</view>
<view class="form-row flex items-center">
<text class="label text-28rpx text-#333 w-120rpx">{{ t('pages-user.food.add-item.actualSalePrice') }}</text>
<view class="bg-#F6F6F6 rounded-16rpx h-88rpx px-20rpx flex-1 flex items-center">
<wd-input
v-model="value.actualSalePrice"
:focus-when-clear="false"
:placeholder="t('pages-user.food.add-item.enterPlaceholder')"
clearable
confirm-type="search"
custom-class="!text-30rpx !bg-transparent flex-1"
no-border
placeholderStyle="font-size: 30rpx;color: #999;"
use-prefix-slot
>
</wd-input>
</view>
</view>
</view> </view>
</view> </view>
</view> </view>
<!-- 添加配菜值按钮 -->
<view <view
class="bg-#F2F2F2 rounded-20rpx h-88rpx center mt-24rpx" class="bg-#F2F2F2 rounded-20rpx h-88rpx center mt-24rpx"
@click="addSideDishValue(groupIndex)" @click="addSpecValue(groupIndex)"
> >
<text class="text-30rpx text-#333 font-500">+ {{ t('pages-user.food.add-item.add') }}</text> <text class="text-30rpx text-#333 font-500">+ {{ t('pages-user.food.add-item.add') }}</text>
</view> </view>
</view> </view>
</view> </view>
<!-- 添加配菜组按钮 -->
<view
class="bg-#F6F6F6 border-2rpx border-solid border-#333 rounded-16rpx h-88rpx flex items-center justify-center mb-40rpx"
@click="addSideDishGroup"
>
<text class="text-30rpx text-#333 font-500">{{ t('pages-user.food.add-item.addSideDishes') }}</text>
</view>
</view> </view>
<!-- 底部提交按钮 --> <!-- 底部提交按钮 -->
@@ -211,6 +211,14 @@ function getStock(item: any) {
return Number(stock).toFixed(0) return Number(stock).toFixed(0)
} }
/** 已售完:有明确库存且数量 <= 0(未返回 stock 时不视为售完,避免误盖) */
function isSoldOut(item: any) {
const stock = (item as any)?.stock
if (stock === undefined || stock === null || stock === '') return false
const n = Number(stock)
return !Number.isNaN(n) && n <= 0
}
function initData() { function initData() {
console.log('页面回来的时候获取最新的数据', props.currentIndex) console.log('页面回来的时候获取最新的数据', props.currentIndex)
if (+props.currentIndex === +props.tabIndex) { if (+props.currentIndex === +props.tabIndex) {
@@ -382,11 +390,21 @@ const isMerchant = computed(() => {
<template v-for="(item, index) in searchResult" :key="item.item.id || index"> <template v-for="(item, index) in searchResult" :key="item.item.id || index">
<view :class="[index === 0 ? '' : 'mt-46rpx']" @click="handleClickDish(item.item)"> <view :class="[index === 0 ? '' : 'mt-46rpx']" @click="handleClickDish(item.item)">
<view class="flex-center-sb"> <view class="flex-center-sb">
<image <view
:src="item.item.dishImage" class="relative w-176rpx h-176rpx mr-28rpx shrink-0 rounded-24rpx overflow-hidden"
class="w-176rpx h-176rpx mr-28rpx shrink-0 rounded-24rpx" >
mode="aspectFill" <image
></image> :src="item.item.dishImage"
class="w-full h-full block"
mode="aspectFill"
></image>
<image
v-if="isSoldOut(item.item)"
class="sold-out-cover"
mode="aspectFill"
src="/static/app/images/SoldOut.png"
></image>
</view>
<view class="flex-1 h-176rpx"> <view class="flex-1 h-176rpx">
<view class="text-33rpx lh-34rpx text-#333 font-500 mb-22rpx line-clamp-1 tracking-[.04em]"> <view class="text-33rpx lh-34rpx text-#333 font-500 mb-22rpx line-clamp-1 tracking-[.04em]">
{{ item.item.dishName }} {{ item.item.dishName }}
@@ -414,11 +432,21 @@ const isMerchant = computed(() => {
<view :class="[index === 0 ? '' : 'mt-46rpx']"> <view :class="[index === 0 ? '' : 'mt-46rpx']">
<wd-swipe-action v-model="swipeActionValue"> <wd-swipe-action v-model="swipeActionValue">
<view class="flex-center-sb" @click="handleClickDish(item)"> <view class="flex-center-sb" @click="handleClickDish(item)">
<image <view
:src="item.dishImage ? item.dishImage.split(',')[0] : ''" class="relative w-176rpx h-176rpx mr-28rpx shrink-0 rounded-24rpx overflow-hidden"
class="w-176rpx h-176rpx mr-28rpx shrink-0 rounded-24rpx" >
mode="aspectFill" <image
></image> :src="item.dishImage ? item.dishImage.split(',')[0] : ''"
class="w-full h-full block"
mode="aspectFill"
></image>
<image
v-if="isSoldOut(item)"
class="sold-out-cover"
mode="aspectFill"
src="/static/app/images/SoldOut.png"
></image>
</view>
<view class="flex-1 h-176rpx"> <view class="flex-1 h-176rpx">
<view class="text-33rpx lh-34rpx text-#333 font-500 mb-22rpx line-clamp-1 tracking-[.04em]"> <view class="text-33rpx lh-34rpx text-#333 font-500 mb-22rpx line-clamp-1 tracking-[.04em]">
{{ item.dishName }} {{ item.dishName }}
@@ -495,11 +523,21 @@ const isMerchant = computed(() => {
</view> </view>
<template v-for="(item, index) in dataList" :key="item.id || index"> <template v-for="(item, index) in dataList" :key="item.id || index">
<view :class="[index === 0 ? '' : 'mt-46rpx']" class="flex-center-sb" @click="handleClickDish(item)"> <view :class="[index === 0 ? '' : 'mt-46rpx']" class="flex-center-sb" @click="handleClickDish(item)">
<image <view
:src="item.dishImage ? item.dishImage.split(',')[0] : ''" class="relative w-176rpx h-176rpx mr-28rpx shrink-0 rounded-24rpx overflow-hidden bg-common"
class="w-176rpx h-176rpx mr-28rpx shrink-0 rounded-24rpx bg-common" >
mode="aspectFill" <image
></image> :src="item.dishImage ? item.dishImage.split(',')[0] : ''"
class="w-full h-full block"
mode="aspectFill"
></image>
<image
v-if="isSoldOut(item)"
class="sold-out-cover"
mode="aspectFill"
src="/static/app/images/SoldOut.png"
></image>
</view>
<view class="flex-1 h-176rpx"> <view class="flex-1 h-176rpx">
<view class="text-33rpx lh-34rpx text-#333 font-500 mb-22rpx line-clamp-1 tracking-[.04em]"> <view class="text-33rpx lh-34rpx text-#333 font-500 mb-22rpx line-clamp-1 tracking-[.04em]">
{{ item.dishName }} {{ item.dishName }}
@@ -533,6 +571,16 @@ const isMerchant = computed(() => {
</template> </template>
<style lang="scss" scoped> <style lang="scss" scoped>
.sold-out-cover {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
z-index: 2;
pointer-events: none;
}
:deep(.wd-input__clear) { :deep(.wd-input__clear) {
background-color: transparent !important; background-color: transparent !important;
} }
Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB