feat(api): 添加电子围栏功能并重构仓库模块
- 新增 shopStoreFence 模块,包含完整的CRUD接口和数据模型 - 将 shopWarehouse 重命名为 shopStoreWarehouse 并更新相关接口 - 配置文件中切换API_BASE_URL到生产环境地址 - 地址管理页面标题从"地址管理"改为"配送管理" - 配送员页面收益描述从"工资收入"改为"本月配送佣金" - 用户地址列表增加每月修改次数限制逻辑 - 更新地址数据模型增加updateTime字段 - 页面组件中的收货地址文案统一改为配送地址 - 移除用户优惠券页面中不必要的导航链接
This commit is contained in:
@@ -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',
|
||||
},
|
||||
|
||||
101
src/api/shop/shopStoreFence/index.ts
Normal file
101
src/api/shop/shopStoreFence/index.ts
Normal file
@@ -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<ApiResult<PageResult<ShopStoreFence>>>(
|
||||
'/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<ApiResult<ShopStoreFence[]>>(
|
||||
'/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<ApiResult<unknown>>(
|
||||
'/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<ApiResult<unknown>>(
|
||||
'/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<ApiResult<unknown>>(
|
||||
'/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<ApiResult<unknown>>(
|
||||
'/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<ApiResult<ShopStoreFence>>(
|
||||
'/shop/shop-store-fence/' + id
|
||||
);
|
||||
if (res.code === 0 && res.data) {
|
||||
return res.data;
|
||||
}
|
||||
return Promise.reject(new Error(res.message));
|
||||
}
|
||||
43
src/api/shop/shopStoreFence/model/index.ts
Normal file
43
src/api/shop/shopStoreFence/model/index.ts
Normal file
@@ -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;
|
||||
}
|
||||
@@ -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<ApiResult<PageResult<ShopWarehouse>>>(
|
||||
'/shop/shop-warehouse/page',
|
||||
export async function pageShopStoreWarehouse(params: ShopStoreWarehouseParam) {
|
||||
const res = await request.get<ApiResult<PageResult<ShopStoreWarehouse>>>(
|
||||
'/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<ApiResult<ShopWarehouse[]>>(
|
||||
'/shop/shop-warehouse',
|
||||
export async function listShopStoreWarehouse(params?: ShopStoreWarehouseParam) {
|
||||
const res = await request.get<ApiResult<ShopStoreWarehouse[]>>(
|
||||
'/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<ApiResult<unknown>>(
|
||||
'/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<ApiResult<unknown>>(
|
||||
'/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<ApiResult<unknown>>(
|
||||
'/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<ApiResult<unknown>>(
|
||||
'/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<ApiResult<ShopWarehouse>>(
|
||||
'/shop/shop-warehouse/' + id
|
||||
export async function getShopStoreWarehouse(id: number) {
|
||||
const res = await request.get<ApiResult<ShopStoreWarehouse>>(
|
||||
'/shop/shop-store-warehouse/' + id
|
||||
);
|
||||
if (res.code === 0 && res.data) {
|
||||
return res.data;
|
||||
@@ -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;
|
||||
}
|
||||
@@ -38,6 +38,8 @@ export interface ShopUserAddress {
|
||||
tenantId?: number;
|
||||
// 注册时间
|
||||
createTime?: string;
|
||||
// 更新时间
|
||||
updateTime?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -55,7 +55,7 @@ const UserCell = () => {
|
||||
title={
|
||||
<View style={{display: 'inline-flex', alignItems: 'center'}}>
|
||||
<Location size={16}/>
|
||||
<Text className={'pl-3 text-sm'}>收货地址</Text>
|
||||
<Text className={'pl-3 text-sm'}>配送地址</Text>
|
||||
</View>
|
||||
}
|
||||
align="center"
|
||||
|
||||
@@ -81,7 +81,7 @@ const UserCell = () => {
|
||||
</Grid.Item>
|
||||
)}
|
||||
|
||||
<Grid.Item text="收货地址" onClick={() => navTo('/user/address/index', true)}>
|
||||
<Grid.Item text="配送地址" onClick={() => navTo('/user/address/index', true)}>
|
||||
<View className="text-center">
|
||||
<View className="w-12 h-12 bg-emerald-50 rounded-xl flex items-center justify-center mx-auto mb-2">
|
||||
<Location color="#3b82f6" size="20"/>
|
||||
|
||||
@@ -139,7 +139,7 @@ const DealerIndex: React.FC = () => {
|
||||
<Text className="text-lg font-bold mb-1 text-white">
|
||||
{formatMoney(dealerUser.money)}
|
||||
</Text>
|
||||
<Text className="text-xs" style={{ color: 'rgba(255, 255, 255, 0.9)' }}>工资收入</Text>
|
||||
<Text className="text-xs" style={{ color: 'rgba(255, 255, 255, 0.9)' }}>本月配送佣金</Text>
|
||||
</View>
|
||||
<View className="text-center p-3 rounded-lg flex flex-col" style={{
|
||||
background: businessGradients.money.frozen
|
||||
|
||||
@@ -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