task-92(店铺中心): 实现编辑店铺表单

新增 shop-manage-edit-form.ts(店铺行预填编辑字段,密码掩码不回填需重录),
补充 toShopManageUpdateRequest(不含 createdById),并在 shop-manage-api.ts 增加
submitUpdateShopManage(PUT /api/admin/shop-manages/{id})。

TDD: task-92.test.ts 8 用例先 RED 后 GREEN。
This commit is contained in:
2026-09-05 16:47:01 +08:00
parent 58ea911d66
commit 813ab5db7b
4 changed files with 165 additions and 4 deletions
@@ -13,6 +13,7 @@ import {
} from './shop-dto.ts'
import {
toShopManageCreateRequest,
toShopManageUpdateRequest,
validateShopManageForm,
type ShopManageFormValues,
} from './shop-manage-form-model.ts'
@@ -46,3 +47,17 @@ export async function submitCreateShopManage(form: ShopManageFormValues, created
}
return item
}
/** 提交编辑店铺:先校验(失败抛首条错误不发请求)PUT /api/admin/shop-manages/{id}。 */
export async function submitUpdateShopManage(id: number, form: ShopManageFormValues): Promise<ShopSummary> {
const { valid, errors } = validateShopManageForm(form)
if (!valid) {
throw new Error(Object.values(errors)[0] || '店铺表单校验未通过')
}
const { data } = await http.put<unknown>(`${SHOP_MANAGE_ENDPOINT}/${id}`, toShopManageUpdateRequest(form))
const item = toShopSummary(unwrap<unknown>(data))
if (!item) {
throw new Error('更新店铺响应异常:未返回有效记录')
}
return item
}
@@ -0,0 +1,31 @@
/** 店铺编辑表单模型(任务 92):由店铺行预填可编辑字段(分组/名称/账号),纯逻辑。 */
import type { ShopSummary } from './shop-dto.ts'
import type { ShopManageFormValues } from './shop-manage-form-model.ts'
function finiteId(value: unknown): number | null {
return typeof value === 'number' && Number.isFinite(value) && value >= 1 ? Math.floor(value) : null
}
function groupIdOr(item: ShopSummary): number | null {
return typeof item.groupId === 'number' && Number.isFinite(item.groupId) && item.groupId >= 1
? Math.floor(item.groupId)
: null
}
function textField(value: unknown): string {
return typeof value === 'string' ? value : ''
}
/** 由店铺行预填编辑表单:密码掩码不回填明文,需保存时重新录入(后端更新要求必填)。 */
export function buildShopManageEditForm(item: ShopSummary | null | undefined): ShopManageFormValues | null {
if (!item || typeof item !== 'object') return null
if (finiteId(item.id) === null) return null
return {
groupId: groupIdOr(item),
shopName: textField(item.shopName),
mallName: textField(item.mallName),
znUsername: textField(item.znUsername),
account: textField(item.account),
password: '',
}
}
@@ -33,6 +33,16 @@ export interface ShopManageCreatePayload {
znUsername?: string
}
/** 发送 PUT /api/admin/shop-manages/{id} 的请求体(与 Java ShopManageUpdateRequest camelCase 对齐)。 */
export interface ShopManageUpdatePayload {
groupId: number
shopName: string
mallName: string
account: string
password: string
znUsername?: string
}
export function emptyShopManageForm(): ShopManageFormValues {
return { groupId: null, shopName: '', mallName: '', znUsername: '', account: '', password: '' }
}
@@ -66,8 +76,18 @@ export function validateShopManageForm(form: ShopManageFormValues): { valid: boo
return { valid: Object.keys(errors).length === 0, errors }
}
/** 新增表单 → 创建请求体;缺有效分组/必填时抛可操作错误(调用前应先校验)。 */
export function toShopManageCreateRequest(form: ShopManageFormValues, createdById: number): ShopManageCreatePayload {
/** 新增/更新共用的必填业务段。 */
interface ManagePayloadBase {
groupId: number
shopName: string
mallName: string
account: string
password: string
znUsername?: string
}
/** 通用必填段(校验 + 归一);缺有效分组/必填时抛可操作错误(调用前应先校验)。 */
function requiredBase(form: ShopManageFormValues): ManagePayloadBase {
const groupId = positiveGroupId(form.groupId)
if (groupId === null) {
throw new Error('分组不能为空')
@@ -76,15 +96,24 @@ export function toShopManageCreateRequest(form: ShopManageFormValues, createdByI
if (!errorText(form.mallName)) throw new Error('商城名称不能为空')
if (!errorText(form.account)) throw new Error('账号不能为空')
if (!errorText(form.password)) throw new Error('密码不能为空')
const payload: ShopManageCreatePayload = {
const payload: ManagePayloadBase = {
groupId,
shopName: errorText(form.shopName),
mallName: errorText(form.mallName),
account: errorText(form.account),
password: errorText(form.password),
createdById,
}
const znUsername = (form.znUsername || '').trim()
if (znUsername) payload.znUsername = znUsername
return payload
}
/** 新增表单 → 创建请求体(含 createdById)。 */
export function toShopManageCreateRequest(form: ShopManageFormValues, createdById: number): ShopManageCreatePayload {
return { ...requiredBase(form), createdById }
}
/** 编辑表单 → 更新请求体(与新增同字段,不含 createdById)。 */
export function toShopManageUpdateRequest(form: ShopManageFormValues): ShopManageUpdatePayload {
return requiredBase(form)
}