shinnosuke
2026-09-10 65b57875700bf42ebd17eafa01a265e5690ce271
talent-card-admin/src/views/MerchantCreateView.vue
@@ -79,6 +79,8 @@
const hasValidMerchantId = computed(() => /^\d+$/.test(queryString('merchantId')))
const isEditMode = computed(() => route.query.mode === 'edit' && hasValidMerchantId.value)
const hasExistingMerchant = computed(() => isEditMode.value)
const merchantDetailLoaded = ref(!isEditMode.value)
const originalMerchantLoginAccount = ref('')
const normalizedMerchantType = computed(() => String(form.merchantType || '').trim())
const merchantTypeAliases: Record<string, string> = {
  '餐饮服务': 'food', food: 'food',
@@ -346,11 +348,26 @@
}
async function checkLoginAccountAvailable() {
  if (!requiresMerchantOperator.value) return true
  if (!/^[A-Za-z0-9]{1,32}$/.test(accountForm.loginAccount)) return false
  // Loading an edit record programmatically updates and may blur this field.
  // Do not validate until its current operator account has been identified.
  if (isEditMode.value && !merchantDetailLoaded.value) return true
  const normalizedAccount = accountForm.loginAccount.trim()
  if (isEditMode.value && originalMerchantLoginAccount.value !== ''
      && normalizedAccount === originalMerchantLoginAccount.value) {
    accountTaken.value = false
    return true
  }
  // An existing merchant keeps its owner account; it must not be checked
  // against itself, and any stale validation message should be cleared.
  if (!requiresMerchantOperator.value) {
    accountTaken.value = false
    return true
  }
  if (!/^[A-Za-z0-9]{1,32}$/.test(normalizedAccount)) return false
  accountChecking.value = true
  try {
    const result = await checkMerchantLoginAccount(accountForm.loginAccount)
    const currentMerchantId = isEditMode.value ? queryString('merchantId') : undefined
    const result = await checkMerchantLoginAccount(normalizedAccount, currentMerchantId)
    accountTaken.value = !result.available
    if (accountTaken.value) ElMessage.warning('登录账号已存在,请更换')
    return result.available
@@ -2404,6 +2421,10 @@
  if (isCarWashMerchant.value) syncCarWashJumpMeta()
})
watch(requiresMerchantOperator, (required) => {
  if (!required) accountTaken.value = false
})
// The create page is reused when the service type changes, so reset these
// create-only defaults from the current route instead of retaining old values.
watch(() => [route.query.mode, route.query.merchantType], applyNewMerchantDefaults, { immediate: true })
@@ -2419,7 +2440,9 @@
         form.canLoginMerchantApp = Number(merchant.canLoginMerchantApp ?? 1)
         form.recommend = Number(merchant.isRecommend ?? 0)
         accountForm.loginAccount = merchant.loginAccount || ''
         originalMerchantLoginAccount.value = String(merchant.loginAccount || '').trim()
         merchantHasLoginAccount.value = Boolean(String(merchant.loginAccount || '').trim())
         accountTaken.value = false
      if (isParkingMerchant.value) {
        parkingAddresses.value = parseJsonValue<ParkingAddress[]>(merchant.usageInstructions, [])
      } else if (isFuelMerchant.value) {
@@ -2440,6 +2463,8 @@
         resetBusinessHours(merchant.businessHours)
         resetMerchantRights(merchant.merchantRightsConfig)
      resetCarWashJumpFromMerchant(merchant as Record<string, any>)
      }).finally(() => {
         merchantDetailLoaded.value = true
      })
   }
  if (activeTab.value === 'products') {
@@ -2589,7 +2614,7 @@
          <el-form-item v-if="supportsMerchantAppLogin" class="merchant-account-login-toggle" label="登录商户端" label-width="100px">
            <el-switch v-model="form.canLoginMerchantApp" :active-value="1" :inactive-value="0" />
          </el-form-item>
          <el-form-item class="merchant-account-field" label="登录账号" prop="loginAccount" :required="merchantOperatorEnabled" :error="accountTaken ? '登录账号已存在,请更换' : ''">
          <el-form-item class="merchant-account-field" label="登录账号" prop="loginAccount" :required="merchantOperatorEnabled" :error="requiresMerchantOperator && accountTaken ? '登录账号已存在,请更换' : ''">
            <el-input v-model="accountForm.loginAccount" maxlength="32" :disabled="isEditMode && merchantHasLoginAccount" :placeholder="isEditMode && !merchantHasLoginAccount ? '请输入登录账号' : (isEditMode ? '已配置登录账号' : '仅支持英文和数字')" @input="normalizeLoginAccount" @blur="checkLoginAccountAvailable" />
          </el-form-item>
          <el-form-item class="merchant-account-field" label="登录密码" prop="loginPassword" :required="merchantOperatorEnabled">