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