杂项配置面板管理本地Mock自定义店铺支持增删改名
This commit is contained in:
@@ -2,10 +2,12 @@ import { Router } from 'express'
|
||||
|
||||
import {
|
||||
acceptAdminWorkOrders,
|
||||
addAdminMockCustomShop,
|
||||
assignAdminWorkOrderToWorker,
|
||||
cancelAdminWorkOrder,
|
||||
confirmAdminWorkOrderFriendAdded,
|
||||
createAdminMockWorkOrder,
|
||||
deleteAdminMockCustomShop,
|
||||
deleteAdminWorkOrder,
|
||||
getAdminWorkOrderEvents,
|
||||
getAdminWorkOrderSharing,
|
||||
@@ -13,6 +15,7 @@ import {
|
||||
listAdminWorkOrders,
|
||||
pinAdminWorkOrder,
|
||||
publishAdminWorkOrder,
|
||||
renameAdminMockCustomShop,
|
||||
reopenAdminCancelledWorkOrder,
|
||||
reprocessAdminKuaishouSendCodeWorkOrders,
|
||||
resetAdminWorkOrderGiftMaterial,
|
||||
@@ -46,6 +49,61 @@ router.get(
|
||||
}),
|
||||
)
|
||||
|
||||
router.post(
|
||||
'/worker-platform/orders/mock/custom-shops',
|
||||
requireAdminRoles(['admin']),
|
||||
createJsonHandler((req) => addAdminMockCustomShop(String(req.body?.name || '')), {
|
||||
successMessage: '自定义店铺已新增',
|
||||
errorMessage: '新增自定义店铺失败',
|
||||
scope: '[admin/worker-platform/orders/mock/custom-shops]',
|
||||
audit: (req) => ({
|
||||
action: 'mock_custom_shop_added',
|
||||
targetType: 'mock_custom_shop',
|
||||
targetId: String(req.body?.name || ''),
|
||||
data: {},
|
||||
}),
|
||||
}),
|
||||
)
|
||||
|
||||
router.put(
|
||||
'/worker-platform/orders/mock/custom-shops',
|
||||
requireAdminRoles(['admin']),
|
||||
createJsonHandler(
|
||||
(req) =>
|
||||
renameAdminMockCustomShop(
|
||||
String(req.body?.name || ''),
|
||||
String(req.body?.newName || req.body?.nextName || ''),
|
||||
),
|
||||
{
|
||||
successMessage: '自定义店铺已重命名',
|
||||
errorMessage: '重命名自定义店铺失败',
|
||||
scope: '[admin/worker-platform/orders/mock/custom-shops]',
|
||||
audit: (req) => ({
|
||||
action: 'mock_custom_shop_renamed',
|
||||
targetType: 'mock_custom_shop',
|
||||
targetId: String(req.body?.name || ''),
|
||||
data: { newName: String(req.body?.newName || '') },
|
||||
}),
|
||||
},
|
||||
),
|
||||
)
|
||||
|
||||
router.delete(
|
||||
'/worker-platform/orders/mock/custom-shops',
|
||||
requireAdminRoles(['admin']),
|
||||
createJsonHandler((req) => deleteAdminMockCustomShop(String(req.query?.name || '')), {
|
||||
successMessage: '自定义店铺已删除',
|
||||
errorMessage: '删除自定义店铺失败',
|
||||
scope: '[admin/worker-platform/orders/mock/custom-shops]',
|
||||
audit: (req) => ({
|
||||
action: 'mock_custom_shop_deleted',
|
||||
targetType: 'mock_custom_shop',
|
||||
targetId: String(req.query?.name || ''),
|
||||
data: {},
|
||||
}),
|
||||
}),
|
||||
)
|
||||
|
||||
router.post(
|
||||
'/worker-platform/orders/mock',
|
||||
requireAdminRoles(['admin', 'operator', 'support']),
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { APP_CONFIG_KEYS } from '../../config/app-config-keys.js'
|
||||
import { createHttpError } from '../../utils/http.js'
|
||||
import { readAppConfigEntry, saveAppConfigEntry } from '../config/app-config-store.js'
|
||||
|
||||
/** 记忆的自定义店铺上限,超出后淘汰最早录入的。 */
|
||||
@@ -24,12 +25,49 @@ export async function rememberAdminMockCustomShop(shopName: string): Promise<str
|
||||
0,
|
||||
MAX_CUSTOM_SHOPS,
|
||||
)
|
||||
const saved = await saveAppConfigEntry({
|
||||
configKey: APP_CONFIG_KEYS.workerMockShops,
|
||||
value: { shops: nextShops },
|
||||
normalize: normalizeMockCustomShops,
|
||||
})
|
||||
return saved.shops
|
||||
return saveMockCustomShops(nextShops)
|
||||
}
|
||||
|
||||
/** 手动新增自定义店铺,重名时视为成功(幂等)。 */
|
||||
export async function addAdminMockCustomShop(shopName: string): Promise<string[]> {
|
||||
const name = requireShopName(shopName, '新增')
|
||||
return saveMockCustomShops([name, ...listAdminMockCustomShops().filter((item) => item !== name)])
|
||||
}
|
||||
|
||||
/** 重命名自定义店铺;新名称已存在时合并(移除旧名称)。 */
|
||||
export async function renameAdminMockCustomShop(
|
||||
oldName: string,
|
||||
nextName: string,
|
||||
): Promise<string[]> {
|
||||
const currentShops = listAdminMockCustomShops()
|
||||
const from = requireShopName(oldName, '重命名')
|
||||
const to = requireShopName(nextName, '重命名为')
|
||||
if (!currentShops.includes(from)) {
|
||||
throw createHttpError('该自定义店铺不存在', {
|
||||
statusCode: 404,
|
||||
errorCode: 'mock_custom_shop_not_found',
|
||||
})
|
||||
}
|
||||
return saveMockCustomShops(
|
||||
currentShops.flatMap((item) => {
|
||||
if (item === from) return [to]
|
||||
if (item === to) return [] // 新名称原本已存在时合并,避免重复
|
||||
return [item]
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
/** 删除自定义店铺,不影响已用它生成的工单。 */
|
||||
export async function deleteAdminMockCustomShop(shopName: string): Promise<string[]> {
|
||||
const currentShops = listAdminMockCustomShops()
|
||||
const name = normalizeShopName(shopName)
|
||||
if (!name || !currentShops.includes(name)) {
|
||||
throw createHttpError('该自定义店铺不存在', {
|
||||
statusCode: 404,
|
||||
errorCode: 'mock_custom_shop_not_found',
|
||||
})
|
||||
}
|
||||
return saveMockCustomShops(currentShops.filter((item) => item !== name))
|
||||
}
|
||||
|
||||
export function normalizeMockCustomShops(rawValue: unknown): MockCustomShopsConfig {
|
||||
@@ -40,6 +78,26 @@ export function normalizeMockCustomShops(rawValue: unknown): MockCustomShopsConf
|
||||
return { shops: normalized.slice(0, MAX_CUSTOM_SHOPS) }
|
||||
}
|
||||
|
||||
async function saveMockCustomShops(shops: string[]): Promise<string[]> {
|
||||
const saved = await saveAppConfigEntry({
|
||||
configKey: APP_CONFIG_KEYS.workerMockShops,
|
||||
value: { shops },
|
||||
normalize: normalizeMockCustomShops,
|
||||
})
|
||||
return saved.shops
|
||||
}
|
||||
|
||||
function requireShopName(value: unknown, action: string): string {
|
||||
const name = normalizeShopName(value)
|
||||
if (!name) {
|
||||
throw createHttpError(`请填写要${action}的店铺名称`, {
|
||||
statusCode: 400,
|
||||
errorCode: 'mock_custom_shop_name_required',
|
||||
})
|
||||
}
|
||||
return name
|
||||
}
|
||||
|
||||
function createDefaultMockCustomShops(): MockCustomShopsConfig {
|
||||
return { shops: [] }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user