This commit is contained in:
李远 2026-03-16 18:32:34 +08:00
parent 05650ed956
commit 08cc5486dc
1 changed files with 0 additions and 398 deletions

View File

@ -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>