From 1ce6381248c97098502b0ebf6f3d986d0efb39b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B5=B5=E5=BF=A0=E6=9E=97?= <170083662@qq.com> Date: Sat, 7 Feb 2026 18:52:35 +0800 Subject: [PATCH] =?UTF-8?q?feat(api):=20=E6=B7=BB=E5=8A=A0=E7=94=B5?= =?UTF-8?q?=E5=AD=90=E5=9B=B4=E6=A0=8F=E5=8A=9F=E8=83=BD=E5=B9=B6=E9=87=8D?= =?UTF-8?q?=E6=9E=84=E4=BB=93=E5=BA=93=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 shopStoreFence 模块,包含完整的CRUD接口和数据模型 - 将 shopWarehouse 重命名为 shopStoreWarehouse 并更新相关接口 - 配置文件中切换API_BASE_URL到生产环境地址 - 地址管理页面标题从"地址管理"改为"配送管理" - 配送员页面收益描述从"工资收入"改为"本月配送佣金" - 用户地址列表增加每月修改次数限制逻辑 - 更新地址数据模型增加updateTime字段 - 页面组件中的收货地址文案统一改为配送地址 - 移除用户优惠券页面中不必要的导航链接 --- config/env.ts | 4 +- src/api/shop/shopStoreFence/index.ts | 101 ++++++++++++++++++ src/api/shop/shopStoreFence/model/index.ts | 43 ++++++++ .../index.ts | 38 +++---- .../model/index.ts | 18 ++-- src/api/shop/shopUserAddress/model/index.ts | 2 + src/pages/user/components/UserCell.tsx | 2 +- src/pages/user/components/UserGrid.tsx | 2 +- src/rider/index.tsx | 2 +- src/user/address/index.config.ts | 2 +- src/user/address/index.tsx | 41 ++++++- src/user/ticket/use.tsx | 2 +- 12 files changed, 220 insertions(+), 37 deletions(-) create mode 100644 src/api/shop/shopStoreFence/index.ts create mode 100644 src/api/shop/shopStoreFence/model/index.ts rename src/api/shop/{shopWarehouse => shopStoreWarehouse}/index.ts (53%) rename src/api/shop/{shopWarehouse => shopStoreWarehouse}/model/index.ts (74%) diff --git a/config/env.ts b/config/env.ts index 78c1e6e..f630969 100644 --- a/config/env.ts +++ b/config/env.ts @@ -2,8 +2,8 @@ export const ENV_CONFIG = { // 开发环境 development: { - API_BASE_URL: 'http://127.0.0.1:9200/api', - // API_BASE_URL: 'https://mp-api.websoft.top/api', + // API_BASE_URL: 'http://127.0.0.1:9200/api', + API_BASE_URL: 'https://mp-api.websoft.top/api', APP_NAME: '开发环境', DEBUG: 'true', }, diff --git a/src/api/shop/shopStoreFence/index.ts b/src/api/shop/shopStoreFence/index.ts new file mode 100644 index 0000000..609defa --- /dev/null +++ b/src/api/shop/shopStoreFence/index.ts @@ -0,0 +1,101 @@ +import request from '@/utils/request'; +import type { ApiResult, PageResult } from '@/api/index'; +import type { ShopStoreFence, ShopStoreFenceParam } from './model'; + +/** + * 分页查询黄家明_电子围栏 + */ +export async function pageShopStoreFence(params: ShopStoreFenceParam) { + const res = await request.get>>( + '/shop/shop-store-fence/page', + params + ); + if (res.code === 0) { + return res.data; + } + return Promise.reject(new Error(res.message)); +} + +/** + * 查询黄家明_电子围栏列表 + */ +export async function listShopStoreFence(params?: ShopStoreFenceParam) { + const res = await request.get>( + '/shop/shop-store-fence', + params + ); + if (res.code === 0 && res.data) { + return res.data; + } + return Promise.reject(new Error(res.message)); +} + +/** + * 添加黄家明_电子围栏 + */ +export async function addShopStoreFence(data: ShopStoreFence) { + const res = await request.post>( + '/shop/shop-store-fence', + data + ); + if (res.code === 0) { + return res.message; + } + return Promise.reject(new Error(res.message)); +} + +/** + * 修改黄家明_电子围栏 + */ +export async function updateShopStoreFence(data: ShopStoreFence) { + const res = await request.put>( + '/shop/shop-store-fence', + data + ); + if (res.code === 0) { + return res.message; + } + return Promise.reject(new Error(res.message)); +} + +/** + * 删除黄家明_电子围栏 + */ +export async function removeShopStoreFence(id?: number) { + const res = await request.del>( + '/shop/shop-store-fence/' + id + ); + if (res.code === 0) { + return res.message; + } + return Promise.reject(new Error(res.message)); +} + +/** + * 批量删除黄家明_电子围栏 + */ +export async function removeBatchShopStoreFence(data: (number | undefined)[]) { + const res = await request.del>( + '/shop/shop-store-fence/batch', + { + data + } + ); + if (res.code === 0) { + return res.message; + } + return Promise.reject(new Error(res.message)); +} + +/** + * 根据id查询黄家明_电子围栏 + */ +export async function getShopStoreFence(id: number) { + const res = await request.get>( + '/shop/shop-store-fence/' + id + ); + if (res.code === 0 && res.data) { + return res.data; + } + return Promise.reject(new Error(res.message)); +} diff --git a/src/api/shop/shopStoreFence/model/index.ts b/src/api/shop/shopStoreFence/model/index.ts new file mode 100644 index 0000000..99c20dd --- /dev/null +++ b/src/api/shop/shopStoreFence/model/index.ts @@ -0,0 +1,43 @@ +import type { PageParam } from '@/api/index'; + +/** + * 黄家明_电子围栏 + */ +export interface ShopStoreFence { + // 自增ID + id?: number; + // 围栏名称 + name?: string; + // 类型 0圆形 1方形 + type?: number; + // 定位 + location?: string; + // 经度 + longitude?: string; + // 纬度 + latitude?: string; + // 区域 + district?: string; + // 电子围栏轮廓 + points?: string; + // 排序(数字越小越靠前) + sortNumber?: number; + // 备注 + comments?: string; + // 状态, 0正常, 1冻结 + status?: number; + // 租户id + tenantId?: number; + // 创建时间 + createTime?: string; + // 修改时间 + updateTime?: string; +} + +/** + * 黄家明_电子围栏搜索条件 + */ +export interface ShopStoreFenceParam extends PageParam { + id?: number; + keywords?: string; +} diff --git a/src/api/shop/shopWarehouse/index.ts b/src/api/shop/shopStoreWarehouse/index.ts similarity index 53% rename from src/api/shop/shopWarehouse/index.ts rename to src/api/shop/shopStoreWarehouse/index.ts index 59a5f6e..898e7b9 100644 --- a/src/api/shop/shopWarehouse/index.ts +++ b/src/api/shop/shopStoreWarehouse/index.ts @@ -1,13 +1,13 @@ import request from '@/utils/request'; -import type { ApiResult, PageResult } from '@/api'; -import type { ShopWarehouse, ShopWarehouseParam } from './model'; +import type { ApiResult, PageResult } from '@/api/index'; +import type { ShopStoreWarehouse, ShopStoreWarehouseParam } from './model'; /** * 分页查询仓库 */ -export async function pageShopWarehouse(params: ShopWarehouseParam) { - const res = await request.get>>( - '/shop/shop-warehouse/page', +export async function pageShopStoreWarehouse(params: ShopStoreWarehouseParam) { + const res = await request.get>>( + '/shop/shop-store-warehouse/page', params ); if (res.code === 0) { @@ -19,9 +19,9 @@ export async function pageShopWarehouse(params: ShopWarehouseParam) { /** * 查询仓库列表 */ -export async function listShopWarehouse(params?: ShopWarehouseParam) { - const res = await request.get>( - '/shop/shop-warehouse', +export async function listShopStoreWarehouse(params?: ShopStoreWarehouseParam) { + const res = await request.get>( + '/shop/shop-store-warehouse', params ); if (res.code === 0 && res.data) { @@ -33,9 +33,9 @@ export async function listShopWarehouse(params?: ShopWarehouseParam) { /** * 添加仓库 */ -export async function addShopWarehouse(data: ShopWarehouse) { +export async function addShopStoreWarehouse(data: ShopStoreWarehouse) { const res = await request.post>( - '/shop/shop-warehouse', + '/shop/shop-store-warehouse', data ); if (res.code === 0) { @@ -47,9 +47,9 @@ export async function addShopWarehouse(data: ShopWarehouse) { /** * 修改仓库 */ -export async function updateShopWarehouse(data: ShopWarehouse) { +export async function updateShopStoreWarehouse(data: ShopStoreWarehouse) { const res = await request.put>( - '/shop/shop-warehouse', + '/shop/shop-store-warehouse', data ); if (res.code === 0) { @@ -61,9 +61,9 @@ export async function updateShopWarehouse(data: ShopWarehouse) { /** * 删除仓库 */ -export async function removeShopWarehouse(id?: number) { +export async function removeShopStoreWarehouse(id?: number) { const res = await request.del>( - '/shop/shop-warehouse/' + id + '/shop/shop-store-warehouse/' + id ); if (res.code === 0) { return res.message; @@ -74,9 +74,9 @@ export async function removeShopWarehouse(id?: number) { /** * 批量删除仓库 */ -export async function removeBatchShopWarehouse(data: (number | undefined)[]) { +export async function removeBatchShopStoreWarehouse(data: (number | undefined)[]) { const res = await request.del>( - '/shop/shop-warehouse/batch', + '/shop/shop-store-warehouse/batch', { data } @@ -90,9 +90,9 @@ export async function removeBatchShopWarehouse(data: (number | undefined)[]) { /** * 根据id查询仓库 */ -export async function getShopWarehouse(id: number) { - const res = await request.get>( - '/shop/shop-warehouse/' + id +export async function getShopStoreWarehouse(id: number) { + const res = await request.get>( + '/shop/shop-store-warehouse/' + id ); if (res.code === 0 && res.data) { return res.data; diff --git a/src/api/shop/shopWarehouse/model/index.ts b/src/api/shop/shopStoreWarehouse/model/index.ts similarity index 74% rename from src/api/shop/shopWarehouse/model/index.ts rename to src/api/shop/shopStoreWarehouse/model/index.ts index 4b96a81..8dc7421 100644 --- a/src/api/shop/shopWarehouse/model/index.ts +++ b/src/api/shop/shopStoreWarehouse/model/index.ts @@ -1,9 +1,9 @@ -import type { PageParam } from '@/api'; +import type { PageParam } from '@/api/index'; /** * 仓库 */ -export interface ShopWarehouse { +export interface ShopStoreWarehouse { // 自增ID id?: number; // 仓库名称 @@ -18,12 +18,12 @@ export interface ShopWarehouse { realName?: string; // 联系电话 phone?: string; - // 省份 + // 所在省份 province?: string; - // 城市 - city: undefined, - // 区域 - region: undefined, + // 所在城市 + city?: string; + // 所在辖区 + region?: string; // 经纬度 lngAndLat?: string; // 用户ID @@ -34,8 +34,6 @@ export interface ShopWarehouse { sortNumber?: number; // 是否删除 isDelete?: number; - // 状态 - status?: number; // 租户id tenantId?: number; // 创建时间 @@ -47,7 +45,7 @@ export interface ShopWarehouse { /** * 仓库搜索条件 */ -export interface ShopWarehouseParam extends PageParam { +export interface ShopStoreWarehouseParam extends PageParam { id?: number; keywords?: string; } diff --git a/src/api/shop/shopUserAddress/model/index.ts b/src/api/shop/shopUserAddress/model/index.ts index 9bf7f50..85696b9 100644 --- a/src/api/shop/shopUserAddress/model/index.ts +++ b/src/api/shop/shopUserAddress/model/index.ts @@ -38,6 +38,8 @@ export interface ShopUserAddress { tenantId?: number; // 注册时间 createTime?: string; + // 更新时间 + updateTime?: string; } /** diff --git a/src/pages/user/components/UserCell.tsx b/src/pages/user/components/UserCell.tsx index 46a0882..9354b40 100644 --- a/src/pages/user/components/UserCell.tsx +++ b/src/pages/user/components/UserCell.tsx @@ -55,7 +55,7 @@ const UserCell = () => { title={ - 收货地址 + 配送地址 } align="center" diff --git a/src/pages/user/components/UserGrid.tsx b/src/pages/user/components/UserGrid.tsx index 54b6577..059ac15 100644 --- a/src/pages/user/components/UserGrid.tsx +++ b/src/pages/user/components/UserGrid.tsx @@ -81,7 +81,7 @@ const UserCell = () => { )} - navTo('/user/address/index', true)}> + navTo('/user/address/index', true)}> diff --git a/src/rider/index.tsx b/src/rider/index.tsx index b8d59c4..665800e 100644 --- a/src/rider/index.tsx +++ b/src/rider/index.tsx @@ -139,7 +139,7 @@ const DealerIndex: React.FC = () => { {formatMoney(dealerUser.money)} - 工资收入 + 本月配送佣金 { const [list, setList] = useState([]) const [address, setAddress] = useState() + 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 = () => { 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}) + }}> 修改 diff --git a/src/user/ticket/use.tsx b/src/user/ticket/use.tsx index 22ef5ca..02e0b13 100644 --- a/src/user/ticket/use.tsx +++ b/src/user/ticket/use.tsx @@ -375,7 +375,7 @@ const OrderConfirm = () => { { address && ( - Taro.navigateTo({url: '/user/address/index'})}> +