shinnosuke
2026-08-04 5fb3b1311dda70a44ecbf76923b440913a735e6a
fix: validate scenic merchant creation fields
2个文件已修改
40 ■■■■■ 已修改文件
talent-card-admin/src/views/MerchantCreateView.vue 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
talent-card-server/src/main/java/com/talentcard/server/business/admin/AdminBusinessService.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
talent-card-admin/src/views/MerchantCreateView.vue
@@ -60,6 +60,10 @@
const normalizedMerchantType = computed(() => String(form.merchantType || '').trim())
const isFoodMerchant = computed(() => normalizedMerchantType.value === '餐饮服务')
const isServiceMerchant = computed(() => isFoodMerchant.value || normalizedMerchantType.value === '景区服务')
const requiresMerchantOperator = computed(() => !isEditMode.value && (
  normalizedMerchantType.value === '景区服务'
  || (isFoodMerchant.value && Number(form.canLoginMerchantApp) === 1)
))
function queryString(key: string, fallback = '') {
  const value = route.query[key]
@@ -110,7 +114,7 @@
}
async function checkLoginAccountAvailable() {
  if (isEditMode.value || !isFoodMerchant.value || Number(form.canLoginMerchantApp) !== 1) return true
  if (!requiresMerchantOperator.value) return true
  if (!/^[A-Za-z0-9]{1,32}$/.test(accountForm.loginAccount)) return false
  accountChecking.value = true
  try {
@@ -1012,14 +1016,26 @@
        ElMessage.warning('请输入排序')
        return
    }
    if (!isEditMode.value && isServiceMerchant.value && Number(form.canLoginMerchantApp) === 1) {
    if (requiresMerchantOperator.value) {
        if (!accountForm.loginAccount.trim()) {
            ElMessage.warning('请输入登录账号')
            return
        }
        if (!/^[A-Za-z0-9]{1,32}$/.test(accountForm.loginAccount)) {
            ElMessage.warning('登录账号仅支持英文和数字,长度不超过32位')
            return
        }
        if (!(await checkLoginAccountAvailable())) return
        if (!accountForm.loginPassword) {
            ElMessage.warning('请输入登录密码')
            return
        }
        if (accountForm.loginPassword.length < 6 || accountForm.loginPassword.length > 64) {
            ElMessage.warning('登录密码长度须为6至64位')
            return
        }
        if (!accountForm.confirmPassword) {
            ElMessage.warning('请输入确认密码')
            return
        }
    }
@@ -1040,7 +1056,7 @@
      businessStatus: form.businessStatus,
        longitude: Number(form.longitude || 0) || undefined,
        latitude: Number(form.latitude || 0) || undefined,
        canLoginMerchantApp: Number(form.canLoginMerchantApp ?? 1),
        canLoginMerchantApp: requiresMerchantOperator.value ? 1 : Number(form.canLoginMerchantApp ?? 1),
        loginAccount: !isEditMode.value ? accountForm.loginAccount : undefined,
        loginPassword: !isEditMode.value ? accountForm.loginPassword : undefined,
        groupBuyingEnabled: form.groupBuyingEnabled,
talent-card-server/src/main/java/com/talentcard/server/business/admin/AdminBusinessService.java
@@ -317,6 +317,7 @@
    @Transactional
    public Map<String, Object> createMerchant(MerchantCreateRequest request) {
        validateScenicMerchantCreate(request);
        jdbcTemplate.update("""
                insert into merchant(merchant_name, merchant_type, contact_name, contact_mobile, address,
                                         logo_url, cover_url, business_status, longitude, latitude, can_login_merchant_app, group_buying_enabled,
@@ -367,6 +368,23 @@
                && (request.canLoginMerchantApp() == null || request.canLoginMerchantApp() == 1);
    }
    private void validateScenicMerchantCreate(MerchantCreateRequest request) {
        if (!"景区服务".equals(request.merchantType())) {
            return;
        }
        if (request.businessHours() == null || request.businessHours().isEmpty()
                || request.businessHours().stream().anyMatch(item -> item.startTime() == null || item.endTime() == null
                        || item.startTime().isBlank() || item.endTime().isBlank() || item.startTime().equals(item.endTime()))) {
            throw new BusinessException(ErrorCode.BAD_REQUEST, "请选择有效的营业时间");
        }
        if (request.loginAccount() == null || !request.loginAccount().trim().matches("^[A-Za-z0-9]{1,32}$")) {
            throw new BusinessException(ErrorCode.BAD_REQUEST, "商户登录账号只能包含英文字母和数字");
        }
        if (request.loginPassword() == null || request.loginPassword().length() < 6 || request.loginPassword().length() > 64) {
            throw new BusinessException(ErrorCode.BAD_REQUEST, "商户登录密码长度须为6至64位");
        }
    }
    private Long createDefaultStore(Long merchantId, String merchantName, String address) {
        jdbcTemplate.update("insert into merchant_store(merchant_id, store_name, address, status) values (?, ?, ?, 1)",
                merchantId, merchantName.trim(), address);