This commit is contained in:
parent
05650ed956
commit
08cc5486dc
|
|
@ -1,398 +0,0 @@
|
|||
<template>
|
||||
<div class="client">
|
||||
<!-- 搜索组件 -->
|
||||
<ClientSearch :search-form="clientSearchForm" :search-options="clientSearchOptions" @search="handleSearch"
|
||||
@reset="handleReset">
|
||||
<template #button="{ form }">
|
||||
<el-button type="primary" @click="handleAdd()">
|
||||
添加客户
|
||||
</el-button>
|
||||
</template>
|
||||
</ClientSearch>
|
||||
<ClientTable :table-data="clientTree" :columns="clientTableColumns" row-key="id" :tree-props="treeProps">
|
||||
<template #status="{ row }">
|
||||
<el-switch :model-value="row.status === 1" :active-value="true" :inactive-value="false" active-text="启用"
|
||||
inactive-text="禁用" />
|
||||
</template>
|
||||
<template #action="{ row }">
|
||||
<el-button type="primary" size="small" @click="handleChange(row)">
|
||||
修改
|
||||
</el-button>
|
||||
</template>
|
||||
</ClientTable>
|
||||
<ClientPagination :modelValue="clientSearchForm.currentPage" :pageSizeValue="clientSearchForm.pageSize"
|
||||
:total="total" @pagination-change="handlePaginationChange" />
|
||||
</div>
|
||||
<!-- 客户弹窗 -->
|
||||
<ClientDialog :visible="dialogVisible" :title="dialogTitle" :type="dialogType" @confirm="handleSubmit"
|
||||
@cancel="handleCancel" @close="handleClose">
|
||||
<ClientForm :form-data="clientForm" :form-rules="clientFormRules" :form-items="clientFormOptions"
|
||||
:options-map="clientFormOptionsMap" ref="clientFormRef">
|
||||
<template #phoneOrEmail="{ formData }">
|
||||
<div class="phone-email">
|
||||
<div class="tab-btn">
|
||||
<el-button type="primary" size="small" :class="{ 'active': activeTab === 'email' }"
|
||||
@click="activeTab = 'email'">
|
||||
邮箱
|
||||
</el-button>
|
||||
<el-button type="primary" class="phone" size="small"
|
||||
:class="{ 'active': activeTab === 'phone' }" @click="activeTab = 'phone'">
|
||||
手机号
|
||||
</el-button>
|
||||
</div>
|
||||
<el-form-item prop="email" v-if="activeTab === 'email'" class="email-item">
|
||||
<el-input v-model="formData.email" placeholder="请输入邮箱"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="phone" v-else class="phone-item">
|
||||
<el-select v-model="formData.countryCode" :teleported="false" value-key="code" placeholder="国家"
|
||||
class="country-select">
|
||||
<el-option v-for="item in countryOptions" :key="item.code" :label="item.code"
|
||||
:value="item.code">
|
||||
<div class="country-option">
|
||||
<span class="country-name">{{ item.name }}</span>
|
||||
<span class="country-code">{{ item.code }}</span>
|
||||
</div>
|
||||
</el-option>
|
||||
</el-select>
|
||||
<el-input v-model="formData.phone" placeholder="请输入手机号" clearable />
|
||||
</el-form-item>
|
||||
</div>
|
||||
</template>
|
||||
</ClientForm>
|
||||
</ClientDialog>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
// 组件
|
||||
import ClientSearch from '@/components/common/Search.vue'
|
||||
import ClientTable from '@/components/common/Table.vue'
|
||||
import ClientPagination from '@/components/common/Pagination.vue'
|
||||
import ClientDialog from '@/components/common/Dialog.vue'
|
||||
import ClientForm from '@/components/common/Form.vue'
|
||||
// 接口
|
||||
import { getClientListApi, getFeeTemplateOptionsApi, getRiskTemplateOptionsApi, getAgentOptionsApi, createClientApi, editClientApi } from '@/api/modules/account/client'
|
||||
|
||||
// 配置
|
||||
import { clientSearch, clientAddFormItem, clientChangeFormItem, countryOptions, clientTableColumns } from './options'
|
||||
import { rules } from './rules'
|
||||
|
||||
//定义客户搜索表单配置
|
||||
const clientSearchOptions = ref(clientSearch)
|
||||
const clientSearchForm = ref({
|
||||
currentPage: 1,
|
||||
pageSize: 1,
|
||||
username: '',
|
||||
status: '正常',
|
||||
startDateTime: '',
|
||||
endDateTime: '',
|
||||
})
|
||||
|
||||
//定义表格配置
|
||||
const clientTree = ref<any[]>([])
|
||||
const treeProps = ref({
|
||||
children: 'parent',
|
||||
label: 'username'
|
||||
})
|
||||
|
||||
// 定义分页配置
|
||||
const total = ref(0)
|
||||
|
||||
// 定义dialog配置
|
||||
const dialogTitle = ref('')
|
||||
const dialogVisible = ref(false)
|
||||
const dialogType = ref('add')
|
||||
const clientForm = ref({
|
||||
//手续费模板
|
||||
feeTemplate: '',
|
||||
//风控模板
|
||||
riskTemplate: '',
|
||||
//所属上级名
|
||||
agentUsername: '',
|
||||
email: '',
|
||||
phone: '',
|
||||
countryCode: '+86',
|
||||
//是否升级
|
||||
isUpgrade: 1,
|
||||
//是否变更客户名
|
||||
userName: '',
|
||||
status: 1,
|
||||
id: '',
|
||||
})
|
||||
|
||||
// 定义客户表单配置
|
||||
const clientFormRef = ref()
|
||||
const clientFormRules = ref(rules())
|
||||
const clientFormOptions = ref<any[]>(clientAddFormItem)
|
||||
// 定义客户表单选项切换
|
||||
const activeTab = ref('email')
|
||||
// 定义客户表单选项类型
|
||||
interface FormOption {
|
||||
label: string;
|
||||
value: string | number;
|
||||
}
|
||||
interface ClientFormOptionsMap {
|
||||
feeTemplate: FormOption[];
|
||||
riskTemplate: FormOption[];
|
||||
agentUsername: FormOption[];
|
||||
isUpgrade: FormOption[];
|
||||
status: FormOption[];
|
||||
}
|
||||
const clientFormOptionsMap = ref<ClientFormOptionsMap>({
|
||||
feeTemplate: [],
|
||||
riskTemplate: [],
|
||||
agentUsername: [],
|
||||
isUpgrade: [
|
||||
{ label: '是', value: 1 },
|
||||
{ label: '否', value: 2 }
|
||||
],
|
||||
status: [
|
||||
{ label: '正常', value: 1 },
|
||||
{ label: '禁用', value: 2 }
|
||||
],
|
||||
})
|
||||
|
||||
// 获取账户列表
|
||||
const fetchClientList = async () => {
|
||||
const params = {
|
||||
page: clientSearchForm.value.currentPage,
|
||||
page_size: clientSearchForm.value.pageSize,
|
||||
username: clientSearchForm.value.username,
|
||||
status: clientSearchForm.value.status === '正常' ? 1 : 2,
|
||||
reg_start_time: clientSearchForm.value.startDateTime.length > 0 ? `${clientSearchForm.value.startDateTime} 0:00:00` : '',
|
||||
reg_end_time: clientSearchForm.value.endDateTime.length > 0 ? `${clientSearchForm.value.endDateTime} 23:59:59` : '',
|
||||
}
|
||||
const data = await getClientListApi(params)
|
||||
clientTree.value = data.data.map(item => ({
|
||||
...item,
|
||||
// 映射所属代理用户名
|
||||
agentUsername: item.par_uid === item.parent?.id ? item.parent?.username : '',
|
||||
}));
|
||||
//把接口返回的分页字段赋值给分页组件
|
||||
total.value = Number(data.total)
|
||||
clientSearchForm.value.currentPage = Number(data.current_page)
|
||||
clientSearchForm.value.pageSize = Number(data.per_page)
|
||||
}
|
||||
onMounted(async () => {
|
||||
await fetchClientList()
|
||||
})
|
||||
/**
|
||||
* @description: 搜索事件
|
||||
*/
|
||||
|
||||
// 搜索
|
||||
const handleSearch = async () => {
|
||||
try {
|
||||
await fetchClientList()
|
||||
} catch (err) {
|
||||
console.error('获取客户列表失败', err)
|
||||
}
|
||||
}
|
||||
|
||||
// 搜索重置
|
||||
const handleReset = () => {
|
||||
clientSearchForm.value = {
|
||||
currentPage: 1,
|
||||
pageSize: 1,
|
||||
username: '',
|
||||
status: '正常',
|
||||
startDateTime: '',
|
||||
endDateTime: '',
|
||||
}
|
||||
fetchClientList() // 重置后自动刷新列表
|
||||
}
|
||||
|
||||
// 客户表单选项切换
|
||||
const handleDialogType = (type: string) => {
|
||||
clientFormOptions.value = type === 'add' ? clientAddFormItem : clientChangeFormItem
|
||||
}
|
||||
|
||||
// 映射对象为数组通用方法
|
||||
const mapObjectToOptions = (obj: Record<string, string>) => {
|
||||
return Object.entries(obj).map(([label, value]) => ({
|
||||
label, // 模板/代理名称
|
||||
value // 模板/代理ID
|
||||
}))
|
||||
}
|
||||
|
||||
//统一获取表单选项
|
||||
const optionsFetched = ref(false)
|
||||
const getOptions = async () => {
|
||||
// 已获取过选项则直接返回,避免重复请求
|
||||
if (optionsFetched.value) return
|
||||
|
||||
try {
|
||||
const [agentRes, feeTemplateRes, riskTemplateRes] = await Promise.all([
|
||||
getAgentOptionsApi(),
|
||||
getFeeTemplateOptionsApi(),
|
||||
getRiskTemplateOptionsApi()
|
||||
])
|
||||
|
||||
// 修正映射:label=名称,value=ID
|
||||
clientFormOptionsMap.value.agentUsername = mapObjectToOptions(agentRes as Record<string, string>)
|
||||
clientFormOptionsMap.value.feeTemplate = mapObjectToOptions(feeTemplateRes as Record<string, string>)
|
||||
clientFormOptionsMap.value.riskTemplate = mapObjectToOptions(riskTemplateRes as Record<string, string>)
|
||||
|
||||
optionsFetched.value = true // 标记已获取
|
||||
} catch (error) {
|
||||
console.error('获取表单选项失败:', error)
|
||||
ElMessage.error('获取表单选项失败,请稍后重试')
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: 表格修改事件
|
||||
*/
|
||||
|
||||
const handleChange = async (row: any) => {
|
||||
dialogVisible.value = true
|
||||
dialogTitle.value = '修改客户'
|
||||
dialogType.value = 'edit'
|
||||
handleDialogType(dialogType.value)
|
||||
//获取表单选项
|
||||
await getOptions()
|
||||
// 核心:将选中行的数值赋值给表单,尤其是id
|
||||
clientForm.value = {
|
||||
id: row.id, // 关键:传递用户ID
|
||||
feeTemplate: row.feeTemplate || '', // 回显手续费模板
|
||||
riskTemplate: row.riskTemplate || '', // 回显风控模板
|
||||
agentUsername: row.agentUsername || '', // 回显所属上级
|
||||
email: row.email || '', // 回显邮箱
|
||||
phone: row.phone || '', // 回显手机号
|
||||
countryCode: row.countryCode || '+86', // 回显国家码
|
||||
isUpgrade: row.isUpgrade || 1, // 回显是否升级
|
||||
userName: row.username || '', // 回显用户名
|
||||
status: row.status || 1, // 回显状态
|
||||
}
|
||||
}
|
||||
|
||||
// 分页事件
|
||||
const handlePaginationChange = (page: { currentPage: number, pageSize: number }) => {
|
||||
clientSearchForm.value.currentPage = page.currentPage
|
||||
clientSearchForm.value.pageSize = page.pageSize
|
||||
handleSearch()
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: dialog事件
|
||||
*/
|
||||
|
||||
// 客户添加
|
||||
const handleAdd = async () => {
|
||||
dialogVisible.value = true
|
||||
dialogType.value = 'add'
|
||||
dialogTitle.value = '添加客户'
|
||||
handleDialogType(dialogType.value)
|
||||
//获取表单选项
|
||||
await getOptions()
|
||||
}
|
||||
|
||||
const handleSubmit = async () => {
|
||||
try {
|
||||
await clientFormRef.value?.validate()
|
||||
if (dialogType.value === 'add') {
|
||||
const params = {
|
||||
reg_type: activeTab.value === 'email' ? 1 : 2,
|
||||
email: clientForm.value.email,
|
||||
mobile: clientForm.value.phone,
|
||||
parent_id: clientForm.value.agentUsername,
|
||||
risk_control_id: clientForm.value.riskTemplate,
|
||||
fee_setting_id: clientForm.value.feeTemplate,
|
||||
}
|
||||
await createClientApi(params)
|
||||
await fetchClientList()
|
||||
dialogVisible.value = false
|
||||
} else {
|
||||
const params = {
|
||||
user_id: clientForm.value.id,
|
||||
risk_control_id: clientForm.value.riskTemplate,
|
||||
fee_setting_id: clientForm.value.feeTemplate,
|
||||
username: clientForm.value.userName,
|
||||
is_levelup: clientForm.value.isUpgrade,
|
||||
status: clientForm.value.status,
|
||||
}
|
||||
await editClientApi(params)
|
||||
await fetchClientList()
|
||||
dialogVisible.value = false
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('客户表单验证失败', err)
|
||||
}
|
||||
}
|
||||
|
||||
const resetForm = () => {
|
||||
clientForm.value = {
|
||||
//手续费模板
|
||||
feeTemplate: '',
|
||||
//风控模板
|
||||
riskTemplate: '',
|
||||
//所属上级
|
||||
agentUsername: '',
|
||||
email: '',
|
||||
phone: '',
|
||||
countryCode: '+86',
|
||||
//是否升级
|
||||
isUpgrade: 1,
|
||||
//是否变更客户名
|
||||
userName: '',
|
||||
status: 1,
|
||||
id: '',
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// 弹窗取消
|
||||
const handleCancel = () => {
|
||||
dialogVisible.value = false
|
||||
dialogType.value = 'add'
|
||||
resetForm()
|
||||
}
|
||||
|
||||
// 弹窗关闭
|
||||
const handleClose = () => {
|
||||
dialogVisible.value = false
|
||||
dialogType.value = 'add'
|
||||
resetForm()
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.phone-email {
|
||||
display: flex;
|
||||
|
||||
:deep(.el-form-item__content) {
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
|
||||
.tab-btn {
|
||||
display: flex;
|
||||
margin-right: 10px;
|
||||
|
||||
.el-button {
|
||||
margin-left: 0;
|
||||
background-color: transparent;
|
||||
border: 1px solid #DCDFE6;
|
||||
color: #303133;
|
||||
height: 32px;
|
||||
|
||||
}
|
||||
|
||||
.active {
|
||||
background-color: #409EFF;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
.email-item {
|
||||
.el-input {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.phone-item {
|
||||
.el-select {
|
||||
width: 120px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Loading…
Reference in New Issue