diff --git a/apps/admin-web/src/lib/storeCreate.ts b/apps/admin-web/src/lib/storeCreate.ts index 0536a38..9a4aee7 100644 --- a/apps/admin-web/src/lib/storeCreate.ts +++ b/apps/admin-web/src/lib/storeCreate.ts @@ -8,7 +8,6 @@ export type StoreCreateForm = { districtCode?: string; name: string; phone: string; - smsCode: string; address: string; intro?: string; coverUrl?: string; @@ -23,7 +22,7 @@ const PHONE_RE = /^1\d{10}$/; const BANK_RE = /^\d{16,19}$/; export function validateStoreCreateStep1( - form: Pick, + form: Pick, ): string | null { if (!form.partnerId) return '请选择开城合伙人'; if (!form.regionCodes || form.regionCodes.length < 3) return '请选择省 / 市 / 区县'; @@ -31,7 +30,6 @@ export function validateStoreCreateStep1( if (!form.name?.trim()) return '请填写门店名称'; if (!form.phone?.trim()) return '请填写门店手机号'; if (!PHONE_RE.test(form.phone.trim())) return '门店手机号须为11位手机号'; - if (!form.smsCode?.trim()) return '请填写短信验证码'; if (!form.address?.trim()) return '请填写详细地址'; if (form.intro?.trim()) { const len = form.intro.trim().length; diff --git a/apps/admin-web/src/pages/StoresPage.tsx b/apps/admin-web/src/pages/StoresPage.tsx index caffa5e..7e43603 100644 --- a/apps/admin-web/src/pages/StoresPage.tsx +++ b/apps/admin-web/src/pages/StoresPage.tsx @@ -83,7 +83,6 @@ export default function StoresPage() { const [createOpen, setCreateOpen] = useState(false); const [createStep, setCreateStep] = useState(0); const [createError, setCreateError] = useState(''); - const [smsCooldown, setSmsCooldown] = useState(0); const [partners, setPartners] = useState([]); const [cities, setCities] = useState([]); const [optionsLoading, setOptionsLoading] = useState(false); @@ -141,38 +140,9 @@ export default function StoresPage() { setCreateOpen(false); setCreateStep(0); setCreateError(''); - setSmsCooldown(0); createForm.resetFields(); } - async function sendCreateSms() { - const phone = String(createForm.getFieldValue('phone') ?? '').trim(); - if (!/^1\d{10}$/.test(phone)) { - message.error('请先填写正确的11位门店手机号'); - return; - } - if (smsCooldown > 0) return; - try { - await request('/admin/stores/phone/sms/send', { - method: 'POST', - body: JSON.stringify({ phone }), - }); - message.success('验证码已发送'); - setSmsCooldown(60); - const timer = setInterval(() => { - setSmsCooldown((s) => { - if (s <= 1) { - clearInterval(timer); - return 0; - } - return s - 1; - }); - }, 1000); - } catch (e) { - message.error(e instanceof Error ? e.message : '发送失败'); - } - } - function openCreateModal() { void loadOptions(); createForm.setFieldsValue({ @@ -192,7 +162,7 @@ export default function StoresPage() { return; } try { - await createForm.validateFields(['partnerId', 'regionCodes', 'cityId', 'name', 'phone', 'smsCode', 'address']); + await createForm.validateFields(['partnerId', 'regionCodes', 'cityId', 'name', 'phone', 'address']); } catch { return; } @@ -220,7 +190,6 @@ export default function StoresPage() { city: values.city, name: values.name.trim(), phone: values.phone.trim(), - smsCode: values.smsCode.trim(), district: values.district.trim(), address: values.address.trim(), intro: values.intro?.trim() || undefined, @@ -239,7 +208,7 @@ export default function StoresPage() { if (e && typeof e === 'object' && 'errorFields' in e) { const fields = e as { errorFields?: Array<{ name: string[] }> }; const first = fields.errorFields?.[0]?.name?.[0]; - if (first === 'partnerId' || first === 'cityId' || first === 'regionCodes' || first === 'name' || first === 'phone' || first === 'smsCode') { + if (first === 'partnerId' || first === 'cityId' || first === 'regionCodes' || first === 'name' || first === 'phone') { setCreateStep(0); } return; @@ -409,16 +378,6 @@ export default function StoresPage() { - - - - - - - - diff --git a/scripts/test-shop-auth.mjs b/scripts/test-shop-auth.mjs index ce0c69a..f5e02d6 100644 --- a/scripts/test-shop-auth.mjs +++ b/scripts/test-shop-auth.mjs @@ -57,7 +57,7 @@ async function main() { }); if (!refreshed.accessToken) throw new Error('refresh failed'); - console.log('4. STORE_ACCOUNT_OPEN occupied phone'); + console.log('4. Admin create store rejects occupied phone'); await req('HQ_WEB', '/admin/auth/sms/send', { method: 'POST', body: JSON.stringify({ phone: '13600000001', scene: 'HQ_LOGIN' }), @@ -66,10 +66,17 @@ async function main() { method: 'POST', body: JSON.stringify({ phone: '13600000001', code: MOCK_SMS_CODE }), }); - const occupied = await expectFail('HQ_WEB', '/admin/stores/phone/sms/send', { + const occupied = await expectFail('HQ_WEB', '/admin/stores', { method: 'POST', token: admin.accessToken, - body: JSON.stringify({ phone: '13910000001' }), + body: JSON.stringify({ + partnerId: '1', + cityId: '1', + name: '重复手机号测试店', + phone: '13910000001', + district: '测试区', + address: '测试地址1号', + }), }); if (!occupied.includes('已绑定')) throw new Error(`unexpected: ${occupied}`); diff --git a/server/dukang-api/src/modules/ops/admin-stores.controller.ts b/server/dukang-api/src/modules/ops/admin-stores.controller.ts index 4341045..9c0762d 100644 --- a/server/dukang-api/src/modules/ops/admin-stores.controller.ts +++ b/server/dukang-api/src/modules/ops/admin-stores.controller.ts @@ -28,11 +28,6 @@ export class AdminStoresController { return this.service.listStores(query); } - @Post('phone/sms/send') - sendOpenSms(@Body() body: { phone: string }) { - return this.service.sendStoreOpenSms(body.phone); - } - @Get(':id') detail(@Param('id') id: string) { return this.service.detailStore(BigInt(id)); diff --git a/server/dukang-api/src/modules/ops/admin-stores.service.ts b/server/dukang-api/src/modules/ops/admin-stores.service.ts index 2881d97..52575b5 100644 --- a/server/dukang-api/src/modules/ops/admin-stores.service.ts +++ b/server/dukang-api/src/modules/ops/admin-stores.service.ts @@ -1,10 +1,8 @@ import { BadRequestException, Injectable, NotFoundException } from '@nestjs/common'; import { Prisma } from '@prisma/client'; -import { ClientApp, SmsScene } from '@dukang/shared-types'; import { PrismaService } from '../../common/prisma/prisma.module'; import { serializeBigInt } from '../../common/decorators/current-user.decorator'; import { mapStoreCompat } from '../../common/compat/v31-compat'; -import { AuthService } from '../iam/auth.service'; import type { AdminStoreAccountsQueryDto, AdminStoreMediaQueryDto, AdminStoresQueryDto } from './dto/admin-query.dto'; import type { CreateStoreAccountDto, @@ -18,16 +16,7 @@ import type { @Injectable() export class AdminStoresService { - constructor( - private readonly prisma: PrismaService, - private readonly authService: AuthService, - ) {} - - async sendStoreOpenSms(phone: string) { - return this.authService.sendSms(phone, SmsScene.STORE_ACCOUNT_OPEN, { - clientApp: ClientApp.HQ_WEB, - }); - } + constructor(private readonly prisma: PrismaService) {} async listStores(query: AdminStoresQueryDto) { const page = query.page ?? 1; @@ -168,7 +157,6 @@ export class AdminStoresService { if (!/^1[3-9]\d{9}$/.test(normalizedPhone)) { throw new BadRequestException('请输入正确的手机号码'); } - await this.authService.verifySmsCode(normalizedPhone, dto.smsCode, SmsScene.STORE_ACCOUNT_OPEN); const existingAccount = await this.prisma.storeAccount.findUnique({ where: { phone: normalizedPhone }, }); diff --git a/server/dukang-api/src/modules/ops/dto/admin-mutate.dto.ts b/server/dukang-api/src/modules/ops/dto/admin-mutate.dto.ts index 6c2b944..90b3573 100644 --- a/server/dukang-api/src/modules/ops/dto/admin-mutate.dto.ts +++ b/server/dukang-api/src/modules/ops/dto/admin-mutate.dto.ts @@ -24,10 +24,6 @@ export class CreateStoreDto { @IsNotEmpty() phone: string; - @IsString() - @IsNotEmpty() - smsCode: string; - @IsOptional() @IsString() categoryId?: string;