diff --git a/env/.env.development b/env/.env.development index 0817bf7..bf1327c 100644 --- a/env/.env.development +++ b/env/.env.development @@ -5,7 +5,7 @@ VITE_DELETE_CONSOLE=false #本地环境 #VITE_SERVER_BASEURL=http://liuyao.nat100.top/meiguowaimai -VITE_SERVER_BASEURL=http://192.168.5.23:8889 -#VITE_SERVER_BASEURL=https://howhowfresh.com/prod-api +#VITE_SERVER_BASEURL=http://192.168.5.64:8080 +VITE_SERVER_BASEURL=https://howhowfresh.com/prod-api #VITE_SERVER_BASEURL=http://192.168.1.8:8811 #VITE_SERVER_BASEURL=http://mifengchuantou.natapp1.cc/meiguowaimai diff --git a/src/locale/en.json b/src/locale/en.json index 595ec83..dceb1cc 100644 --- a/src/locale/en.json +++ b/src/locale/en.json @@ -428,7 +428,9 @@ "name": "name:", "nameRequired": "Name is required", "setDefaultDays": "Set the default days and times this menu will be available", - "submit": "submit" + "submit": "submit", + "sort": "Sort position", + "sortPlaceholder": "Please enter sort number" }, "message": { "readAll": "One-click read", diff --git a/src/locale/zh-Hans.json b/src/locale/zh-Hans.json index 07e8b44..248c9cf 100644 --- a/src/locale/zh-Hans.json +++ b/src/locale/zh-Hans.json @@ -428,7 +428,9 @@ "name": "名称:", "nameRequired": "名称不能为空", "setDefaultDays": "设置此菜单可用的默认天数和时间", - "submit": "提交" + "submit": "提交", + "sort": "排序位置", + "sortPlaceholder": "请输入排序数字" }, "message": { "readAll": "一键已读", diff --git a/src/manifest.json b/src/manifest.json index d4f8ea1..5d95e61 100644 --- a/src/manifest.json +++ b/src/manifest.json @@ -2,8 +2,8 @@ "name" : "CHEFLINK Merchant", "appid" : "__UNI__BB8E3C9", "description" : "美国外卖商户端", - "versionName" : "1.0.13", - "versionCode" : 113, + "versionName" : "1.0.16", + "versionCode" : 116, "transformPx" : false, /* 5+App特有相关 */ "app-plus" : { diff --git a/src/pages-user/pages/food/add-food.vue b/src/pages-user/pages/food/add-food.vue index 63664ce..a6e3fd5 100644 --- a/src/pages-user/pages/food/add-food.vue +++ b/src/pages-user/pages/food/add-food.vue @@ -130,28 +130,49 @@ onLoad((options) => { getMenuListByMerchant() }) -const menuList = ref([]) +// 默认分页配置(避免一次请求 1000 条) +const DEFAULT_PAGE_SIZE = 10; +const DEFAULT_PAGE_NUM = 1; -function getMenuListByMerchant() { - appMerchantMenuMenuListByMerchantPost({ - params: { - pageSize: 1000, - pageNum: 1 - } - }).then(res => { - menuList.value = res.rows - selectedMenu.value = menuList.value[0].id +const menuList = ref([]) - if (res.rows.length === 0) { - uni.showToast({ - title: t('pages-user.food.add-food.tips'), - icon: 'none' - }) - } else { - // 回显menu - formData.value.menu = menuList.value.find(item => item.id === formData.value.menuId)?.menuName +async function getMenuListByMerchant() { + const allRows: any[] = [] + let pageNum = DEFAULT_PAGE_NUM + + while (true) { + const res = await appMerchantMenuMenuListByMerchantPost({ + params: { + pageSize: DEFAULT_PAGE_SIZE, + pageNum + } + }) + + const rows = res.rows || [] + allRows.push(...rows) + + if ((typeof res.total === 'number' && allRows.length >= res.total) || rows.length < DEFAULT_PAGE_SIZE) { + break } - }) + + pageNum += 1 + if (pageNum > 200) break + } + + menuList.value = allRows + + if (menuList.value.length === 0) { + uni.showToast({ + title: t('pages-user.food.add-food.tips'), + icon: 'none' + }) + return + } + + selectedMenu.value = menuList.value[0]?.id + + // 回显 menu + formData.value.menu = menuList.value.find(item => item.id === formData.value.menuId)?.menuName } // 获取菜品详情 diff --git a/src/pages-user/pages/menu/index.vue b/src/pages-user/pages/menu/index.vue index c13c033..1e5a243 100644 --- a/src/pages-user/pages/menu/index.vue +++ b/src/pages-user/pages/menu/index.vue @@ -17,6 +17,8 @@ const formData = reactive({ id: '', menuName: '', scheduleTimes: '', + // 排序 + sort: 0, isActive: true }) // 提交表单 @@ -94,6 +96,8 @@ function getMenuDetail() { formData.menuName = res.data.menuName formData.scheduleTimes = res.data.scheduleTimes formData.isActive = +res.data.delFlag === 1 + // 排序 + formData.sort = res.data.sort ?? 0 }) } @@ -152,6 +156,28 @@ function deleteMenu() { + + + + {{ t('pages-user.menu.sort') }} + + + + + + + diff --git a/src/pages/home/components/tabbar-menu/components/menu-swiper-list/menu-swiper-list.vue b/src/pages/home/components/tabbar-menu/components/menu-swiper-list/menu-swiper-list.vue index b8b4ed7..b220a7e 100644 --- a/src/pages/home/components/tabbar-menu/components/menu-swiper-list/menu-swiper-list.vue +++ b/src/pages/home/components/tabbar-menu/components/menu-swiper-list/menu-swiper-list.vue @@ -15,6 +15,10 @@ const {t} = useI18n() const message = useMessage(); +// 默认分页配置(菜单相关接口仍然依赖) +const DEFAULT_PAGE_SIZE = 10; +const DEFAULT_PAGE_NUM = 1; + const props = defineProps<{ tabIndex: number | string currentIndex: number | string @@ -25,46 +29,76 @@ function changeMenu() { emits('changeMenu') } -watch(() => props.currentIndex, (newVal) => { - console.log('111', newVal, props.tabIndex) - if (+newVal === props.tabIndex && +props.tabIndex === 1) { - getMenuListByMerchant() - } - if (+newVal === props.tabIndex && +props.tabIndex === 2) { - getMenuListByMerchant() - } else if (+newVal === props.tabIndex && +props.tabIndex === 3) { - // 获取菜品列表 - console.log('获取菜品列表') - getDishList() - } -}, {immediate: true}) +const tabIndexNum = computed(() => +props.tabIndex) -const paging = ref(null) -const dataList = ref([]) -const queryList = (pageNo, pageSize) => { - return new Promise((resolve, reject) => { - paging.value.complete([ - { - title: '订单1' +watch( + () => props.currentIndex, + (newVal) => { + console.log('111', newVal, props.tabIndex) + if (+newVal === props.tabIndex) { + // 切换到当前tab,触发分页加载(pageNum会由z-paging自动递增) + paging.value?.reload() + } + }, + {immediate: true}, +) + +// 分页数据源:tab1=菜单详情内dishList(本地分页),tab2=菜单列表(后端分页),tab3=菜品列表(后端分页) +function queryByTab(pageNum: number, pageSize: number) { + // tab1:菜单概览-菜单下菜品(本地分页) + if (tabIndexNum.value === 1) { + return new Promise>(async (resolve) => { + await ensureMenuListLoaded() + await ensureMenuDetailLoaded() + const all = menuDishListData.value || [] + const start = (pageNum - 1) * pageSize + resolve({ + rows: all.slice(start, start + pageSize), + total: all.length, + } as any) + }) + } + + // tab2:周菜单管理-菜单列表(后端分页) + if (tabIndexNum.value === 2) { + return new Promise>((resolve) => { + if (!userStore.isLogin) return resolve({rows: [], total: 0} as any) + appMerchantMenuMenuListByMerchantPost({ + params: { + pageNum, + pageSize, + }, + }).then((res: any) => { + resolve({ + ...(res as any), + rows: (res as any).rows || [], + total: (res as any).total || 0, + }) + }) + }) + } + + // tab3:菜品列表(后端分页) + return new Promise>((resolve) => { + if (!userStore.isLogin) return resolve({rows: [], total: 0} as any) + appMerchantDishListPost({ + params: { + pageNum, + pageSize, }, - { - title: '订单2' - }, - { - title: '订单3' - }, - ]); + // @ts-ignore 后端 body 暂无筛选条件,这里传空对象 + body: {}, + }).then((res: any) => { + resolve({ + ...(res as any), + rows: (res as any).rows || [], + total: (res as any).total || 0, + }) + }) }) } -// 加载状态 -const loading = ref(true) -// 模拟数据加载 -onMounted(() => { - loading.value = true - setTimeout(() => { - loading.value = false - }, 300) -}) + +const {paging, dataList, loading, queryList} = usePage(queryByTab) function navigateTo(url: string) { uni.navigateTo({url}) @@ -72,76 +106,85 @@ function navigateTo(url: string) { // 获取当前商户的菜单列表 -const menuList = ref([]) +const menuList = ref([]) // 当前选中的菜单索引 const currentMenuIndex = ref(0) // 当前选中的菜单数据 const currentMenu = computed(() => { - return menuList.value[currentMenuIndex.value] + return menuList.value[currentMenuIndex.value] || {} }) -function getMenuListByMerchant() { +async function ensureMenuListLoaded() { + // 仅tab1需要完整menuList用于头部展示 & indexChangeMenu定位 + if (tabIndexNum.value !== 1) return if (!userStore.isLogin) return - appMerchantMenuMenuListByMerchantPost({ - params: { - pageSize: 1000, - pageNum: 1 + if (menuList.value.length > 0) return + + const allRows: any[] = [] + let pageNum = DEFAULT_PAGE_NUM + + while (true) { + const res: any = await appMerchantMenuMenuListByMerchantPost({ + params: { + pageSize: DEFAULT_PAGE_SIZE, + pageNum, + }, + }) + + const rows = res.rows || [] + allRows.push(...rows) + + if ((typeof res.total === 'number' && allRows.length >= res.total) || rows.length < DEFAULT_PAGE_SIZE) { + break } - }).then(res => { - menuList.value = res.rows || [] - if (res.rows && res.rows.length > 0) { - // 设置当前选中的菜单索引 - currentMenuIndex.value = 0 - if (+props.currentIndex === 1) { - // 获取菜单详情 - getMenuDetail() - } - } - }) + + pageNum += 1 + if (pageNum > 200) break + } + + menuList.value = allRows + if (menuList.value.length > 0) { + currentMenuIndex.value = 0 + } } -const findIndexById = (array, targetId) => - array.findIndex(item => item.id === targetId); +const findIndexById = (array: any[], targetId: string | number) => + array.findIndex((item) => item.id === targetId); function indexChangeMenu(id: string) { // 最新的菜单ID console.log('indexChangeMenu', id) currentMenuIndex.value = findIndexById(menuList.value, id) console.log('当前选中的菜单索引', currentMenuIndex.value) - getMenuDetail() + getMenuDetail().then(() => { + paging.value?.reload() + }) } -// 菜单下面的菜品数据 +// 菜单下面的菜品数据(完整数据,用于tab1本地分页与搜索) const menuDishListData = ref([]) -function getMenuDetail() { - appMerchantMenuMenuDetailPost({ +async function getMenuDetail() { + return appMerchantMenuMenuDetailPost({ params: { recipeId: currentMenu.value.id || '' } - }).then(res => { + }).then((res: any) => { console.log('获取菜单详情', res) - if (res.data && res.data.dishList) { - menuDishListData.value = res.data.dishList || [] + if (res.data && (res.data as any).dishList) { + menuDishListData.value = (res.data as any).dishList || [] } }).catch(err => { console.error('获取菜单详情失败', err) }) } -const dishList = ref([]) - -function getDishList() { - appMerchantDishListPost({ - params: { - pageSize: 1000, - pageNum: 1 - } - }).then(res => { - console.log('res', res) - dishList.value = res.rows - console.log('dishList', dishList.value) - }) +async function ensureMenuDetailLoaded() { + if (tabIndexNum.value !== 1) return + if (!currentMenu.value?.id) return + // 没有数据时才请求,避免每次上拉都重复打接口 + if (menuDishListData.value.length > 0) return + await getMenuDetail() } function handleClickMenu(item: any) { @@ -157,12 +200,21 @@ function handleClickDish(item: MerchantDishVo) { }) } +// 库存文案相关辅助方法 +function hasStock(item: any) { + return !!(item as any)?.stock +} + +function getStock(item: any) { + const stock = (item as any)?.stock + if (stock === undefined || stock === null) return '' + return Number(stock).toFixed(0) +} + function initData() { console.log('页面回来的时候获取最新的数据', props.currentIndex) - if (+props.currentIndex === 2 || +props.currentIndex === 1) { - getMenuListByMerchant() - } else if (+props.currentIndex === 3) { - getDishList() + if (+props.currentIndex === +props.tabIndex) { + paging.value?.reload() } } @@ -182,11 +234,14 @@ function handleSearch() { isShowSearch.value = true } -const searchResult = ref([]); +type DishSearchResult = { + item: MerchantDishVo +} +const searchResult = ref([]); function handleConfirmSearch() { console.log('handleConfirmSearch', keyword.value) - const fuse = new Fuse(menuDishListData.value, { + const fuse = new Fuse(menuDishListData.value, { threshold: 0.2, keys: ["dishName", "dishDescription"], }); @@ -199,7 +254,7 @@ function inputClear() { } // 删除菜品 -function deleteRecipe(item) { +function deleteRecipe(item: MerchantDishVo) { message .confirm({ title: t("common.prompt.system-prompt"), @@ -217,7 +272,7 @@ function deleteRecipe(item) { }) .then(async () => { appMerchantDishRemovePost({ - body: [item.id] + body: [item.id as number], }).then((res) => { uni.showToast({ title: t('toast.deleteSuccess'), @@ -324,7 +379,7 @@ const isMerchant = computed(() => {