feat(api): 添加电子围栏功能并重构仓库模块
- 新增 shopStoreFence 模块,包含完整的CRUD接口和数据模型 - 将 shopWarehouse 重命名为 shopStoreWarehouse 并更新相关接口 - 配置文件中切换API_BASE_URL到生产环境地址 - 地址管理页面标题从"地址管理"改为"配送管理" - 配送员页面收益描述从"工资收入"改为"本月配送佣金" - 用户地址列表增加每月修改次数限制逻辑 - 更新地址数据模型增加updateTime字段 - 页面组件中的收货地址文案统一改为配送地址 - 移除用户优惠券页面中不必要的导航链接
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
export default definePageConfig({
|
||||
navigationBarTitleText: '地址管理',
|
||||
navigationBarTitleText: '配送管理',
|
||||
navigationBarTextStyle: 'black'
|
||||
})
|
||||
|
||||
@@ -6,11 +6,40 @@ import {View} from '@tarojs/components'
|
||||
import {ShopUserAddress} from "@/api/shop/shopUserAddress/model";
|
||||
import {listShopUserAddress, removeShopUserAddress, updateShopUserAddress} from "@/api/shop/shopUserAddress";
|
||||
import FixedButton from "@/components/FixedButton";
|
||||
import dayjs from "dayjs";
|
||||
|
||||
const Address = () => {
|
||||
const [list, setList] = useState<ShopUserAddress[]>([])
|
||||
const [address, setAddress] = useState<ShopUserAddress>()
|
||||
|
||||
const parseTime = (raw?: unknown) => {
|
||||
if (raw === undefined || raw === null || raw === '') return null;
|
||||
// 兼容秒/毫秒时间戳
|
||||
if (typeof raw === 'number' || (typeof raw === 'string' && /^\d+$/.test(raw))) {
|
||||
const n = Number(raw);
|
||||
return dayjs(Number.isFinite(n) ? (n < 1e12 ? n * 1000 : n) : raw as any);
|
||||
}
|
||||
return dayjs(raw as any);
|
||||
}
|
||||
|
||||
const canModifyOncePerMonth = (item: ShopUserAddress) => {
|
||||
const lastUpdate = parseTime(item.updateTime);
|
||||
if (!lastUpdate || !lastUpdate.isValid()) return { ok: true as const };
|
||||
|
||||
// 若 updateTime 与 createTime 基本一致,则视为“未修改过”,不做限制
|
||||
const createdAt = parseTime(item.createTime);
|
||||
if (createdAt && createdAt.isValid() && Math.abs(lastUpdate.diff(createdAt, 'minute')) < 1) {
|
||||
return { ok: true as const };
|
||||
}
|
||||
|
||||
const nextAllowed = lastUpdate.add(1, 'month');
|
||||
const now = dayjs();
|
||||
if (now.isBefore(nextAllowed)) {
|
||||
return { ok: false as const, nextAllowed: nextAllowed.format('YYYY-MM-DD HH:mm') };
|
||||
}
|
||||
return { ok: true as const };
|
||||
}
|
||||
|
||||
const reload = () => {
|
||||
listShopUserAddress({
|
||||
userId: Taro.getStorageSync('UserId')
|
||||
@@ -137,7 +166,17 @@ const Address = () => {
|
||||
</View>
|
||||
<Divider direction={'vertical'}/>
|
||||
<View className={'text-gray-400'}
|
||||
onClick={() => Taro.navigateTo({url: '/user/address/add?id=' + item.id})}>
|
||||
onClick={() => {
|
||||
const { ok, nextAllowed } = canModifyOncePerMonth(item);
|
||||
if (!ok) {
|
||||
Taro.showToast({
|
||||
title: `一个月只能修改一次${nextAllowed ? ',' + nextAllowed + ' 后可再次修改' : ''}`,
|
||||
icon: 'none',
|
||||
});
|
||||
return;
|
||||
}
|
||||
Taro.navigateTo({url: '/user/address/add?id=' + item.id})
|
||||
}}>
|
||||
修改
|
||||
</View>
|
||||
</>
|
||||
|
||||
@@ -375,7 +375,7 @@ const OrderConfirm = () => {
|
||||
<CellGroup>
|
||||
{
|
||||
address && (
|
||||
<Cell className={'address-bottom-line'} onClick={() => Taro.navigateTo({url: '/user/address/index'})}>
|
||||
<Cell className={'address-bottom-line'}>
|
||||
<Space>
|
||||
<Location className={'text-gray-500'}/>
|
||||
<View className={'flex flex-col w-full justify-between items-start'}>
|
||||
|
||||
Reference in New Issue
Block a user