feat(admin): link city-partner store count; fix benefitUsageRule null string
CI / verify (pull_request) Has been cancelled
CI / verify (pull_request) Has been cancelled
City partner storeCount jumps to /stores?partnerId=; normalize empty/null text so usage rule is not saved as literal "null. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -17,6 +17,14 @@ import type {
|
||||
UpdateStoreStatusDto,
|
||||
} from './dto/admin-mutate.dto';
|
||||
|
||||
/** 选填文案:空 / null / "null" 一律存库为 null,避免 String(null)==="null" */
|
||||
function normalizeStoreOptionalText(value: unknown): string | null {
|
||||
if (value == null) return null;
|
||||
const s = String(value).trim();
|
||||
if (!s || /^null$/i.test(s) || /^undefined$/i.test(s)) return null;
|
||||
return s;
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class AdminStoresService {
|
||||
constructor(
|
||||
@@ -286,7 +294,7 @@ export class AdminStoresService {
|
||||
...(normalizedPhone !== undefined ? { phone: normalizedPhone } : {}),
|
||||
...(dto.intro !== undefined ? { intro: dto.intro } : {}),
|
||||
...(dto.benefitUsageRule !== undefined
|
||||
? { benefitUsageRule: String(dto.benefitUsageRule).trim() || null }
|
||||
? { benefitUsageRule: normalizeStoreOptionalText(dto.benefitUsageRule) }
|
||||
: {}),
|
||||
...(dto.address !== undefined ? { address: dto.address.trim() } : {}),
|
||||
...(dto.province !== undefined ? { province: dto.province.trim() } : {}),
|
||||
@@ -417,7 +425,7 @@ export class AdminStoresService {
|
||||
if (intro && (intro.length < 2 || intro.length > 500)) {
|
||||
throw new BadRequestException('门店简介须为 2~500 字');
|
||||
}
|
||||
const benefitUsageRule = dto.benefitUsageRule?.trim() || null;
|
||||
const benefitUsageRule = normalizeStoreOptionalText(dto.benefitUsageRule);
|
||||
if (benefitUsageRule && benefitUsageRule.length > 1000) {
|
||||
throw new BadRequestException('好客权益券使用规则最多 1000 字');
|
||||
}
|
||||
|
||||
@@ -28,6 +28,14 @@ function haversineMeters(lat1: number, lng1: number, lat2: number, lng2: number)
|
||||
return 2 * R * Math.asin(Math.min(1, Math.sqrt(a)));
|
||||
}
|
||||
|
||||
/** 选填文案:空 / null / "null" 存库为 null,避免 String(null)==="null" */
|
||||
function normalizeOptionalTextField(value: unknown): string | null {
|
||||
if (value == null) return null;
|
||||
const s = String(value).trim();
|
||||
if (!s || /^null$/i.test(s) || /^undefined$/i.test(s)) return null;
|
||||
return s;
|
||||
}
|
||||
|
||||
function parseOptionalCoord(value: unknown, kind: 'lat' | 'lng' = 'lng'): number | null {
|
||||
if (value == null || value === '') return null;
|
||||
const n = typeof value === 'number' ? value : Number(value);
|
||||
@@ -301,9 +309,8 @@ export class StoreService {
|
||||
if (introRaw && (introRaw.length < 2 || introRaw.length > 500)) {
|
||||
throw new BadRequestException('门店简介须为 2~500 字');
|
||||
}
|
||||
const benefitUsageRuleRaw =
|
||||
body.benefitUsageRule != null ? String(body.benefitUsageRule).trim() : '';
|
||||
if (benefitUsageRuleRaw.length > 1000) {
|
||||
const benefitUsageRuleRaw = normalizeOptionalTextField(body.benefitUsageRule);
|
||||
if (benefitUsageRuleRaw && benefitUsageRuleRaw.length > 1000) {
|
||||
throw new BadRequestException('好客权益券使用规则最多 1000 字');
|
||||
}
|
||||
|
||||
@@ -325,7 +332,7 @@ export class StoreService {
|
||||
district: String(body.district ?? ''),
|
||||
address: String(body.address),
|
||||
intro: introRaw || null,
|
||||
benefitUsageRule: benefitUsageRuleRaw || null,
|
||||
benefitUsageRule: benefitUsageRuleRaw,
|
||||
avgPrice: avgPriceRaw,
|
||||
openTime,
|
||||
closeTime,
|
||||
@@ -522,7 +529,9 @@ export class StoreService {
|
||||
const address = body.address !== undefined ? String(body.address).trim() : undefined;
|
||||
const introRaw = body.intro !== undefined ? String(body.intro).trim() : undefined;
|
||||
const benefitUsageRuleRaw =
|
||||
body.benefitUsageRule !== undefined ? String(body.benefitUsageRule).trim() : undefined;
|
||||
body.benefitUsageRule !== undefined
|
||||
? normalizeOptionalTextField(body.benefitUsageRule)
|
||||
: undefined;
|
||||
const latitude =
|
||||
body.latitude !== undefined ? parseOptionalCoord(body.latitude, 'lat') : undefined;
|
||||
const longitude =
|
||||
@@ -536,7 +545,7 @@ export class StoreService {
|
||||
if (introRaw && (introRaw.length < 2 || introRaw.length > 500)) {
|
||||
throw new BadRequestException('门店简介须为 2~500 字');
|
||||
}
|
||||
if (benefitUsageRuleRaw !== undefined && benefitUsageRuleRaw.length > 1000) {
|
||||
if (benefitUsageRuleRaw != null && benefitUsageRuleRaw.length > 1000) {
|
||||
throw new BadRequestException('好客权益券使用规则最多 1000 字');
|
||||
}
|
||||
if (
|
||||
@@ -561,7 +570,7 @@ export class StoreService {
|
||||
...(hasCoordsUpdate ? { latitude, longitude } : {}),
|
||||
...(introRaw !== undefined ? { intro: introRaw || null } : {}),
|
||||
...(benefitUsageRuleRaw !== undefined
|
||||
? { benefitUsageRule: benefitUsageRuleRaw || null }
|
||||
? { benefitUsageRule: benefitUsageRuleRaw }
|
||||
: {}),
|
||||
...(resubmitAudit
|
||||
? {
|
||||
|
||||
Reference in New Issue
Block a user