daShangDao_psiWebApp/backups/EmployeeAdd.vue.bak
97694731 0543936df8
Some checks failed
CI / build (20.x) (push) Waiting to run
CI / lint (push) Waiting to run
CI / test (push) Waiting to run
CI / deploy-preview (push) Blocked by required conditions
CI / security (push) Waiting to run
CI / build (18.x) (push) Has been cancelled
change store
2026-06-04 11:18:46 +08:00

384 lines
11 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="employee-add">
<el-card>
<template>
<div class="card-header">
<span>添加代理</span>
<el-button @click="$router.push('/admin/employees')">
<el-icon>
<Back />
</el-icon>
</el-button>
</div>
</template>
<el-steps :active="activeStep" finish-status="success" simple class="steps">
<el-step title="填写信息" />
<el-step title="确认信息" />
<el-step title="完成" />
</el-steps>
<!-- 第一步填写信息 -->
<div v-if="activeStep === 1" class="step-content">
<el-form ref="formRef" :model="form" :rules="rules" label-width="100px" class="add-form">
<el-form-item label="姓名" prop="name">
<el-input v-model="form.name" placeholder="请输入代理姓名" :prefix-icon="User" clearable />
</el-form-item>
<el-form-item label="密码" prop="password">
<el-input v-model="form.password" type="password" placeholder="请输入密码至少6位" :prefix-icon="Lock"
show-password clearable />
</el-form-item>
<el-form-item label="确认密码" prop="confirmPassword">
<el-input v-model="form.confirmPassword" type="password" placeholder="请再次输入密码" :prefix-icon="Lock"
show-password clearable />
</el-form-item>
<el-form-item label="手机号" prop="phone">
<el-input v-model="form.phone" placeholder="请输入手机号" :prefix-icon="Lock" maxlength="11" clearable
show-word-limit />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="nextStep" :loading="checking">
下一步,确认信息
</el-button>
</el-form-item>
</el-form>
<!-- 工号预览(动态生成) -->
<el-card shadow="never" class="preview-card">
<template #header>
<span>工号预览</span>
</template>
<div class="preview-content">
<div class="preview-item">
<span class="label">工号格式:</span>
<span class="value">5位数字自动生成</span>
</div>
<div class="preview-item">
<span class="label">账号格式:</span>
<span class="value">dl_ + 工号(如 dl_00001</span>
</div>
<div class="preview-item">
<span class="label">示例工号:</span>
<el-tag size="small">{{ previewEmployeeId }}</el-tag>
</div>
<div class="preview-item">
<span class="label">示例账号:</span>
<el-tag size="small" type="success">{{ previewUsername }}</el-tag>
</div>
</div>
</el-card>
</div>
<!-- 第二步:确认信息 -->
<div v-if="activeStep === 2" class="step-content">
<el-descriptions :column="1" border class="confirm-info">
<el-descriptions-item label="姓名">{{ form.name }}</el-descriptions-item>
<el-descriptions-item label="工号">{{ previewEmployeeId }}</el-descriptions-item>
<el-descriptions-item label="登录账号">{{ previewUsername }}</el-descriptions-item>
<el-descriptions-item label="手机号">{{ form.phone }}</el-descriptions-item>
<el-descriptions-item label="初始积分">0</el-descriptions-item>
<el-descriptions-item label="角色">代理</el-descriptions-item>
<el-descriptions-item label="状态">正常</el-descriptions-item>
</el-descriptions>
<div class="step-actions">
<el-button @click="prevStep">上一步</el-button>
<el-button type="primary" @click="submitForm" :loading="submitting">
确认添加
</el-button>
</div>
</div>
<!-- 第三步完成 -->
<div v-if="activeStep === 3" class="step-content result">
<el-result icon="success" :title="`添加成功`" :sub-title="`代理 ${resultData?.name} (${resultData?.username}) 已添加`">
<template #extra>
<div class="result-info" ref="resultInfoRef">
<el-alert type="info" :closable="false" show-icon>
<p class="title-center">进销存系统</p>
<p>登录网址https://psi.buzhiyushu.cn/</p>
<p>工号:{{ resultData?.employee_id }}</p>
<p>账号:{{ resultData?.username }}</p>
<p>初始密码:{{ form.password }}</p>
<p>手机号:{{ form.phone }}</p>
<p style="color: #f56c6c; margin-top: 10px;">请妥善保管账号信息!</p>
</el-alert>
</div>
<div class="result-actions">
<el-button type="primary" @click="resetForm">继续添加</el-button>
<el-button @click="$router.push('/admin/employees')">查看列表</el-button>
<el-button type="success" @click="copyResultInfo">
<el-icon>
<DocumentCopy />
</el-icon>
一键复制
</el-button>
</div>
</template>
</el-result>
</div>
</el-card>
</div>
</template>
<script setup>
import { ref, reactive, computed, onMounted } from 'vue'
import { useRouter } from 'vue-router'
import { ElMessage } from 'element-plus'
import { User, Lock, Back, DocumentCopy } from '@element-plus/icons-vue'
import request from '@/utils/request'
import { copyToClipboard } from '@/utils/clipboard'
import { useUserStore } from '@/store/user'
const router = useRouter()
const userStore = useUserStore()
const activeStep = ref(1)
const checking = ref(false)
const submitting = ref(false)
const formRef = ref(null)
const resultData = ref(null)
const resultInfoRef = ref(null)
// 表单数据
const form = reactive({
name: '',
password: '',
confirmPassword: '',
phone: ''
})
// 表单验证规则
const validatePass = (rule, value, callback) => {
if (value === '') {
callback(new Error('请输入密码'))
} else if (value.length < 6) {
callback(new Error('密码长度不能小于6位'))
} else {
if (form.confirmPassword !== '') {
formRef.value?.validateField('confirmPassword')
}
callback()
}
}
const validatePass2 = (rule, value, callback) => {
if (value === '') {
callback(new Error('请再次输入密码'))
} else if (value !== form.password) {
callback(new Error('两次输入密码不一致'))
} else {
callback()
}
}
const rules = {
name: [
{ required: true, message: '请输入代理姓名', trigger: 'blur' },
{ min: 2, max: 20, message: '姓名长度应为2-20个字符', trigger: 'blur' }
],
password: [
{ validator: validatePass, trigger: 'blur' }
],
confirmPassword: [
{ validator: validatePass2, trigger: 'blur' }
],
phone: [
{ required: true, message: '请输入手机号', trigger: 'blur' },
{ pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号', trigger: 'blur' }
]
}
// 预览工号和账号(模拟)
const previewEmployeeId = ref('00001')
const previewUsername = computed(() => `dl_${previewEmployeeId.value}`)
// 获取下一个可用工号
const fetchNextEmployeeId = async () => {
try {
// 这里可以调用接口获取下一个工号
// 如果没有接口,使用模拟数据
const res = await request.get('/admin/employee/list', { params: { page: 1, page_size: 1 } })
if (res.code === 200 && res.data.list.length > 0) {
const lastId = res.data.list[0].employee_id
const seq = parseInt(lastId) + 1
previewEmployeeId.value = String(seq).padStart(5, '0')
}
} catch (error) {
// console.error('获取工号失败:', error)
// 使用模拟数据
previewEmployeeId.value = String(Math.floor(Math.random() * 90000 + 10000)).padStart(5, '0')
}
}
// 下一步
const nextStep = async () => {
if (!formRef.value) return
await formRef.value.validate()
activeStep.value = 2
}
// 上一步
const prevStep = () => {
activeStep.value = 1
}
// 提交表单
const submitForm = async () => {
submitting.value = true
try {
// 动态构建请求参数fid 来自 login 响应的 idabout_id 来自 login 响应的 about_id
const currentInfo = userStore.getAdminInfo()
const params = {
name: form.name,
password: form.password,
phone: form.phone,
}
if (currentInfo?.id) {
params.fid = currentInfo.id
}
if (currentInfo?.about_id) {
params.about_id = currentInfo.about_id
}
const res = await request.post('/admin/employee/add', params)
if (res.code === 200) {
resultData.value = res.data
activeStep.value = 3
ElMessage.success('添加成功')
}
} catch (error) {
// console.error('添加代理失败:', error)
ElMessage.error('添加失败,请重试')
} finally {
submitting.value = false
}
}
// 重置表单
const resetForm = () => {
form.name = ''
form.password = ''
form.confirmPassword = ''
form.phone = ''
activeStep.value = 1
resultData.value = null
fetchNextEmployeeId()
}
// 一键复制结果信息
const copyResultInfo = async () => {
if (!resultData.value) return
const text = `书海寻源代理系统
登录网址https://wallet.buzhiyushu.cn/
工号:${resultData.value.employee_id}
账号:${resultData.value.username}
初始密码:${form.password}
手机号:${form.phone}
请妥善保管账号信息!`
await copyToClipboard(text, '账号信息已复制到剪贴板')
}
// 初始化
onMounted(() => {
fetchNextEmployeeId()
})
</script>
<style scoped>
.employee-add {
padding: 0;
}
.card-header {
display: flex;
justify-content: space-between;
align-items: center;
font-size: 16px;
font-weight: 600;
color: #303133;
}
.steps {
margin: 20px 0 40px;
}
.step-content {
min-height: 300px;
padding: 20px 0;
}
.add-form {
width: 500px;
margin: 0 auto;
}
.preview-card {
width: 500px;
margin: 30px auto 0;
background-color: #f8f9fa;
}
.preview-content {
padding: 10px;
}
.preview-item {
margin-bottom: 10px;
display: flex;
align-items: center;
}
.preview-item .label {
width: 80px;
color: #666;
font-size: 13px;
}
.preview-item .value {
color: #333;
font-size: 13px;
}
.confirm-info {
width: 500px;
margin: 0 auto;
}
.step-actions {
margin-top: 30px;
text-align: center;
}
.result {
display: flex;
justify-content: center;
}
.result-info {
margin: 20px 0;
text-align: left;
}
.result-actions {
margin-top: 20px;
display: flex;
gap: 10px;
justify-content: center;
}
:deep(.el-descriptions__label) {
width: 120px;
}
.title-center {
text-align: center;
font-weight: bold;
font-size: 16px;
margin-bottom: 10px;
}
</style>