完善企业编辑页面并修复采购建单重试
This commit is contained in:
@@ -0,0 +1,113 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, onMounted, reactive, ref, watch } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { ElMessage, type FormInstance, type FormRules } from 'element-plus'
|
||||
import { useTenantAdministrationStore } from '../store/tenantAdministration'
|
||||
import { useAuthStore } from '@/modules/auth/public'
|
||||
|
||||
const props = withDefaults(defineProps<{ memberId?: string }>(), { memberId: '' })
|
||||
const router = useRouter()
|
||||
const store = useTenantAdministrationStore()
|
||||
const auth = useAuthStore()
|
||||
const editingId = computed(() => props.memberId)
|
||||
const title = computed(() => editingId.value ? '编辑成员' : '新增成员')
|
||||
const canGrantMemberRole = computed(() => auth.hasPermission('company:member:grant-role'))
|
||||
const canSave = computed(() => auth.hasPermission(editingId.value ? 'company:member:edit' : 'company:member:create'))
|
||||
const loading = ref(false)
|
||||
const loadError = ref('')
|
||||
const saving = ref(false)
|
||||
const formRef = ref<FormInstance>()
|
||||
const form = reactive({ name: '', account: '', password: '', phone: '', email: '', roleIds: [] as string[] })
|
||||
const memberRules: FormRules = {
|
||||
name: [{ required: true, whitespace: true, message: '请输入成员姓名', trigger: 'blur' }],
|
||||
account: [
|
||||
{ required: true, message: '请输入登录账号', trigger: 'blur' },
|
||||
{ pattern: /^[A-Za-z0-9_.@-]{4,64}$/, message: '账号需为 4–64 位字母、数字或 _ . @ -', trigger: 'blur' },
|
||||
],
|
||||
password: [
|
||||
{ required: true, message: '请输入初始密码', trigger: 'blur' },
|
||||
{ pattern: /^(?=.*[A-Za-z])(?=.*\d).{8,64}$/, message: '密码需为 8–64 位,并同时包含字母和数字', trigger: 'blur' },
|
||||
],
|
||||
phone: [{ pattern: /^1[3-9]\d{9}$/, message: '请输入有效的中国大陆登录手机号', trigger: 'blur' }],
|
||||
email: [{ type: 'email', message: '请输入正确的邮箱地址', trigger: 'blur' }],
|
||||
roleIds: [{ type: 'array', required: true, min: 1, message: '请至少选择一个成员角色', trigger: 'change' }],
|
||||
}
|
||||
let loadVersion = 0
|
||||
async function loadEditor() {
|
||||
const version = ++loadVersion
|
||||
loading.value = true
|
||||
loadError.value = ''
|
||||
Object.assign(form, { name: '', account: '', password: '', phone: '', email: '', roleIds: [] })
|
||||
try {
|
||||
await Promise.all([store.loadRoles(), ...(editingId.value ? [store.loadMembers()] : [])])
|
||||
if (version !== loadVersion) return
|
||||
if (editingId.value) {
|
||||
const member = store.members.find(item => item.id === editingId.value)
|
||||
if (!member) throw new Error('该成员不存在或已不可访问,请返回成员列表重新选择')
|
||||
Object.assign(form, { name: member.name, account: member.account, phone: member.phone, email: member.email, roleIds: [...member.roleIds] })
|
||||
}
|
||||
formRef.value?.clearValidate()
|
||||
} catch (error) {
|
||||
if (version === loadVersion) loadError.value = error instanceof Error ? error.message : '成员资料加载失败'
|
||||
} finally {
|
||||
if (version === loadVersion) loading.value = false
|
||||
}
|
||||
}
|
||||
onMounted(() => void loadEditor())
|
||||
watch(() => props.memberId, () => void loadEditor())
|
||||
function returnToList() { void router.push({ name: 'members' }) }
|
||||
async function saveMember() {
|
||||
if (saving.value || loading.value || loadError.value || !canSave.value) return
|
||||
form.name = form.name.trim()
|
||||
form.account = form.account.trim()
|
||||
form.phone = form.phone.trim()
|
||||
form.email = form.email.trim()
|
||||
const valid = editingId.value
|
||||
? await formRef.value?.validateField(['name', 'account', 'phone', 'email', 'roleIds']).then(() => true).catch(() => false)
|
||||
: await formRef.value?.validate().catch(() => false)
|
||||
if (!valid) return
|
||||
saving.value = true
|
||||
try {
|
||||
if (editingId.value) {
|
||||
await store.updateMember(editingId.value, { name: form.name, memberNo: form.account, phone: form.phone, email: form.email, roleIds: [...form.roleIds] })
|
||||
ElMessage.success('成员信息已更新')
|
||||
} else {
|
||||
await store.createMember({ ...form, memberNo: form.account, roleIds: [...form.roleIds] })
|
||||
ElMessage.success('成员已新增')
|
||||
}
|
||||
form.password = ''
|
||||
await router.push({ name: 'members' })
|
||||
} catch (error) {
|
||||
ElMessage.error(error instanceof Error ? error.message : '成员保存失败,请重试')
|
||||
} finally { saving.value = false }
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section v-loading="loading" class="company-editor client-ui" :aria-busy="loading">
|
||||
<header class="company-editor-heading"><h2>{{ title }}</h2><el-button :disabled="saving" @click="returnToList">返回列表</el-button></header>
|
||||
<el-alert v-if="loadError" type="error" :closable="false" :title="loadError"><el-button @click="loadEditor">重新加载</el-button></el-alert>
|
||||
<el-form v-else ref="formRef" :model="form" :rules="memberRules" label-position="top" :disabled="saving || loading || !canSave" scroll-to-error @submit.prevent="saveMember">
|
||||
<section class="company-editor-section">
|
||||
<h3>账号信息</h3>
|
||||
<div class="company-editor-grid">
|
||||
<el-form-item label="成员姓名" prop="name" required><el-input v-model="form.name" maxlength="64" placeholder="请输入成员姓名" /></el-form-item>
|
||||
<el-form-item label="登录账号" prop="account" required><el-input v-model="form.account" :disabled="Boolean(editingId)" maxlength="64" placeholder="4–64 位字母、数字或 _ . @ -" /></el-form-item>
|
||||
<el-form-item v-if="!editingId" label="初始密码" prop="password" required><el-input v-model="form.password" type="password" show-password autocomplete="new-password" maxlength="64" placeholder="8–64 位,同时包含字母和数字" /></el-form-item>
|
||||
</div>
|
||||
</section>
|
||||
<section class="company-editor-section">
|
||||
<h3>联系信息与角色</h3>
|
||||
<div class="company-editor-grid">
|
||||
<el-form-item label="登录手机号" prop="phone"><el-input v-model="form.phone" maxlength="11" inputmode="tel" autocomplete="tel" placeholder="请输入登录手机号(选填)" /><span class="company-editor-help">用于该成员手机号登录;修改后会同步认证账号并退出该成员现有会话。</span></el-form-item>
|
||||
<el-form-item label="邮箱" prop="email"><el-input v-model="form.email" maxlength="128" placeholder="请输入邮箱(选填)" /></el-form-item>
|
||||
<el-form-item label="成员角色" prop="roleIds" required><el-select v-model="form.roleIds" multiple :disabled="Boolean(editingId) && !canGrantMemberRole" placeholder="请选择角色" popper-class="company-editor-popper"><el-option v-for="role in store.roles.filter((item) => item.status === 'ACTIVE' && (!item.builtin || form.roleIds.includes(item.id)))" :key="role.id" :label="role.name" :value="role.id" :disabled="role.builtin" /></el-select></el-form-item>
|
||||
</div>
|
||||
</section>
|
||||
<p v-if="!editingId" class="company-editor-help">请通过安全渠道将初始密码交给成员;前端不会保存或再次展示该密码。</p>
|
||||
<footer class="company-editor-actions"><el-button :disabled="saving" @click="returnToList">返回列表</el-button><el-button v-if="canSave" type="primary" native-type="submit" :loading="saving">{{ editingId ? '保存修改' : '新增成员' }}</el-button></footer>
|
||||
</el-form>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<style scoped src="./companyEditor.css"></style>
|
||||
Reference in New Issue
Block a user