447 lines
11 KiB
Vue
447 lines
11 KiB
Vue
<template>
|
||
<div>
|
||
<!-- 搜索 -->
|
||
<CustomerListSearch
|
||
:search-form="searchForm"
|
||
:search-options="searchOptions"
|
||
@search="handleSearch"
|
||
@reset="handleReset"
|
||
></CustomerListSearch>
|
||
<!-- 表格 -->
|
||
<CustomerListTable
|
||
:table-data="tableTree"
|
||
:columns="tableColumnsOptions"
|
||
row-key="userId"
|
||
:default-sort="{ prop: 'createTime', order: 'descending' }"
|
||
@expand-change="handleGetSubList"
|
||
>
|
||
<template #marginRatio="{ row }">
|
||
<el-button
|
||
v-if="row.role_id === 5"
|
||
type="primary"
|
||
size="small"
|
||
v-auth="'agent_getSelfVarietyPointDiffConfig'"
|
||
@click="handleMarginRatio(row)"
|
||
>
|
||
修改
|
||
</el-button>
|
||
</template>
|
||
<template #commissionRatio="{ row }">
|
||
{{ row.commissionRatio }}
|
||
<el-button
|
||
v-if="row.role_id === 5"
|
||
type="primary"
|
||
size="small"
|
||
@click="handleCommissionRatio(row)"
|
||
v-auth="'agent_editAgent'"
|
||
>
|
||
修改
|
||
</el-button>
|
||
</template>
|
||
<template #action="{ row }">
|
||
<el-button link type="primary" size="small" @click="handleDetail(row)" v-if="row.userId">
|
||
查看详情
|
||
</el-button>
|
||
</template>
|
||
</CustomerListTable>
|
||
<!-- 分页 -->
|
||
<CustomerListPagination
|
||
v-model="currentPage"
|
||
v-model:pageSizeValue="pageSize"
|
||
:total="total"
|
||
@pagination-change="handlePaginationChange"
|
||
/>
|
||
<!-- dialog -->
|
||
<CustomerListDialog
|
||
:visible="dialogVisible"
|
||
:title="dialogTitle"
|
||
:type="dialogType"
|
||
:fullscreen="dialogFullscreen"
|
||
:show-footer="dialogType !== 'view'"
|
||
@confirm="handleSubmit"
|
||
@cancel="handleCancel"
|
||
@close="handleClose"
|
||
>
|
||
<CustomerListTable
|
||
:table-data="marginRatioTree"
|
||
:columns="marginRatioTableColumnsOptions"
|
||
row-key="id"
|
||
v-if="dialogType === 'editMarginRatio'"
|
||
style="height: 500px"
|
||
>
|
||
<template #assignedPointDiff="{ row }">
|
||
<el-form
|
||
:model="row"
|
||
:rules="marginRatioRules(row)"
|
||
:ref="(el) => setFormRef(el, row.id)"
|
||
>
|
||
<el-form-item prop="assignedPointDifference">
|
||
<el-input
|
||
v-model="row.assignedPointDifference"
|
||
size="small"
|
||
placeholder="请输入点差"
|
||
/>
|
||
</el-form-item>
|
||
</el-form>
|
||
</template>
|
||
</CustomerListTable>
|
||
<CustomerListForm
|
||
:form-data="commissionRatioForm"
|
||
:form-rules="commissionRatioFormRules"
|
||
:form-items="commissionRatioFormItemOptions"
|
||
ref="commissionRatioFormRef"
|
||
v-if="dialogType === 'editCommissionRatio'"
|
||
></CustomerListForm>
|
||
</CustomerListDialog>
|
||
<!-- dialog表格 -->
|
||
</div>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
|
||
defineOptions({
|
||
name: 'Agent'
|
||
})
|
||
// 组件
|
||
import CustomerListSearch from '@/components/common/Search.vue'
|
||
import CustomerListTable from '@/components/common/Table.vue'
|
||
import CustomerListPagination from '@/components/common/Pagination.vue'
|
||
import CustomerListDialog from '@/components/common/Dialog.vue'
|
||
import CustomerListForm from '@/components/common/Form.vue'
|
||
// 配置以及表单验证
|
||
import { search, tableColumns, marginRatioTableColumns, commissionRatioFormItem } from './options'
|
||
|
||
// 接口
|
||
import { getSelfVarietyPointDiffConfigApi, editCustomerApi } from '@/api/modules/agent/customerList'
|
||
import { getAgentListApi } from '@/api/modules/profile/agent.ts'
|
||
|
||
// 公用方法
|
||
import { getStorage } from '@/utils/storage'
|
||
const router = useRouter()
|
||
/**
|
||
* @description: 获取用户id
|
||
*/
|
||
const userInfo: any = getStorage('userInfo')
|
||
const userId = ref(userInfo?.id || '')
|
||
|
||
/**
|
||
* @description: 定义搜索数据
|
||
*/
|
||
const searchForm = ref({
|
||
accountName: '',
|
||
startTime: '',
|
||
endTime: '',
|
||
status: '',
|
||
})
|
||
const searchOptions = ref(search)
|
||
const tableColumnsOptions = ref(tableColumns)
|
||
|
||
/**
|
||
* @description: 定义表格数据
|
||
*/
|
||
const tableTree = ref([])
|
||
const treeProps = { children: 'children', hasChildren: 'hasChildren' }
|
||
|
||
/**
|
||
* @description: 定义分页数据
|
||
*/
|
||
const total = ref(0)
|
||
const currentPage = ref(1)
|
||
const pageSize = ref(10)
|
||
|
||
/**
|
||
* @description: 定义弹窗数据
|
||
*/
|
||
const dialogVisible = ref<boolean>(false)
|
||
const dialogTitle = ref<string>('')
|
||
const dialogType = ref<string>('')
|
||
const dialogFullscreen = ref(false)
|
||
|
||
/**
|
||
* @description: 定义点差表格数据
|
||
*/
|
||
const marginRatioTree = ref([])
|
||
const marginRatioTableColumnsOptions = ref(marginRatioTableColumns)
|
||
// 存储所有行的表单
|
||
const formRefs: any = ref({})
|
||
|
||
// 动态存储每行表单
|
||
const setFormRef = (el: any, id: any) => {
|
||
if (el) formRefs.value[id] = el
|
||
}
|
||
// 点差验证规则
|
||
const marginRatioRules = (row: any) => {
|
||
return {
|
||
assignedPointDifference: [
|
||
{ required: true, message: '请输入数字', trigger: ['blur', 'change'] },
|
||
{
|
||
pattern: /^\d+(\.\d+)?$/,
|
||
message: '只能输入数字(可带小数)',
|
||
trigger: ['blur', 'change'],
|
||
},
|
||
{
|
||
validator: (rule: any, value: any, callback: any) => {
|
||
const inputVal = Number(value || 0)
|
||
const maxVal = Number(row.pointDifference || 0)
|
||
|
||
if (inputVal > maxVal) {
|
||
callback(new Error('不能大于可分配点数'))
|
||
} else {
|
||
callback()
|
||
}
|
||
},
|
||
trigger: ['blur', 'change'],
|
||
},
|
||
],
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @description: 定义手续费form数据
|
||
*/
|
||
const commissionRatioForm = ref({
|
||
commissionRatio: '',
|
||
})
|
||
const commissionRatioFormRef = ref()
|
||
const commissionRatioFormRules = {
|
||
commissionRatio: [
|
||
{ required: true, message: '请输入手续费分成比例', trigger: ['blur', 'change'] },
|
||
{ pattern: /^\d+(\.\d+)?$/, message: '只能输入数字(可带小数)', trigger: ['blur', 'change'] },
|
||
],
|
||
}
|
||
const commissionRatioFormItemOptions = ref(commissionRatioFormItem)
|
||
const selectId = ref('')
|
||
|
||
/**
|
||
* @description: 角色映射方法
|
||
*/
|
||
const roleMap: any = {
|
||
1: '平台',
|
||
2: '承包商',
|
||
3: '特殊做市商',
|
||
4: '普通做市商',
|
||
5: '代理',
|
||
6: '用户',
|
||
}
|
||
|
||
/**
|
||
* @description: 定义公共请求数据方法
|
||
*/
|
||
// 获取客户列表
|
||
const getCustomerList = async () => {
|
||
const params = {
|
||
page: currentPage.value,
|
||
page_size: pageSize.value,
|
||
user_name: searchForm.value.accountName,
|
||
reg_start_time: searchForm.value.startTime,
|
||
reg_end_time: searchForm.value.endTime,
|
||
status: searchForm.value.status,
|
||
}
|
||
const data: any = await getAgentListApi(params)
|
||
|
||
tableTree.value = data.data.map((item: any) => ({
|
||
...item,
|
||
accountName: item.username,
|
||
userId: item.id,
|
||
status: item.status === 1 ? '正常' : '禁用',
|
||
role: item.role.title || '未知',
|
||
accountQty: item.son_user[0]?.son_user_count,
|
||
commissionRatio: item?.wallet_capital?.fee_handling_percent,
|
||
createTime: item.created_at,
|
||
role_id: item.role_id,
|
||
}))
|
||
|
||
//分页数据
|
||
total.value = data.total
|
||
currentPage.value = data.current_page
|
||
pageSize.value = Number(data.per_page)
|
||
}
|
||
|
||
//获取代理点差数据
|
||
const getSelfVarietyPointDiffConfig = async (id: string) => {
|
||
const params = {
|
||
user_id: id,
|
||
}
|
||
const data: any = await getSelfVarietyPointDiffConfigApi(params)
|
||
marginRatioTree.value = data.map((item: any) => ({
|
||
id: item.id,
|
||
varietyName: item.name,
|
||
varietyCode: item.code,
|
||
pointDifference: item.point_diff,
|
||
assignedPointDifference: item.target_point_diff,
|
||
}))
|
||
}
|
||
|
||
/**
|
||
* @description: 页面加载完成需要请求的数据
|
||
*/
|
||
onMounted(() => {
|
||
getCustomerList()
|
||
})
|
||
|
||
/**
|
||
* @description: 定义搜索方法
|
||
*/
|
||
const handleSearch = async () => {
|
||
getCustomerList()
|
||
}
|
||
const handleReset = () => {
|
||
searchForm.value = {
|
||
accountName: '',
|
||
startTime: '',
|
||
endTime: '',
|
||
status: '',
|
||
}
|
||
getCustomerList()
|
||
}
|
||
|
||
/**
|
||
* @description: 定义表格方法
|
||
*/
|
||
const handleDetail = (row: any) => {
|
||
console.log('查看详情', row)
|
||
router.push(`/agent/customerDetail/${row.userId}`)
|
||
}
|
||
|
||
// 修改点差
|
||
const handleMarginRatio = (row: any) => {
|
||
getSelfVarietyPointDiffConfig(row.userId)
|
||
console.log('修改点差', row)
|
||
dialogVisible.value = true
|
||
dialogTitle.value = '修改点差'
|
||
dialogType.value = 'editMarginRatio'
|
||
selectId.value = row.userId
|
||
}
|
||
|
||
// 修改手续费比例
|
||
const handleCommissionRatio = (row: any) => {
|
||
console.log('修改手续费比例', row)
|
||
dialogVisible.value = true
|
||
dialogTitle.value = '修改手续费'
|
||
dialogType.value = 'editCommissionRatio'
|
||
selectId.value = row.userId
|
||
commissionRatioForm.value.commissionRatio = row.commissionRatio
|
||
}
|
||
|
||
// 获取子列表
|
||
const handleGetSubList = async (row: any) => {
|
||
const params = {
|
||
user_name: '',
|
||
user_id: row.userId,
|
||
page: currentPage.value,
|
||
page_size: pageSize.value,
|
||
reg_start_time: '',
|
||
reg_end_time: '',
|
||
status: '',
|
||
}
|
||
const data: any = await getAgentListApi(params)
|
||
if (data.data.length === 0) {
|
||
ElMessage({
|
||
message: '暂无数据',
|
||
type: 'error',
|
||
})
|
||
row.children = []
|
||
return
|
||
}
|
||
row.children = data.data.map((item: any) => ({
|
||
accountName: item.username,
|
||
userId: item.id,
|
||
status: item.status === 1 ? '正常' : '禁用',
|
||
role: roleMap[item.role_id] || '未知',
|
||
accountQty: item.account[0].account_count,
|
||
commissionRatio: item.wallet_capital.fee_handling_percent,
|
||
createTime: item.created_at,
|
||
role_id: item.role_id,
|
||
children:
|
||
item.role_id === 5
|
||
? [
|
||
{
|
||
hasChildren: true,
|
||
},
|
||
]
|
||
: undefined,
|
||
}))
|
||
}
|
||
|
||
/**
|
||
* @description: 定义分页方法
|
||
*/
|
||
const handlePaginationChange = (page: { currentPage: number; size: number }) => {
|
||
currentPage.value = page.currentPage
|
||
getCustomerList()
|
||
}
|
||
|
||
/**
|
||
* @description: 定义弹窗方法
|
||
*/
|
||
//提交
|
||
const handleSubmit = async () => {
|
||
const params = {
|
||
user_id: selectId.value,
|
||
toucun_percent: '',
|
||
point_diffs_json: '',
|
||
fee_handling_percent: '',
|
||
fee_setting_id: '',
|
||
risk_control_id: '',
|
||
}
|
||
if (dialogType.value === 'editMarginRatio') {
|
||
// 逐行验证
|
||
for (const row of marginRatioTree.value) {
|
||
const form = formRefs.value[(row as any).id]
|
||
if (!form) continue
|
||
try {
|
||
await form.validate()
|
||
} catch (err) {
|
||
console.error(`第 ${(row as any).id} 行验证不通过,请检查`)
|
||
return
|
||
}
|
||
}
|
||
//转换为接口需要的格式 { id: assignedPointDifference }
|
||
const marginRatioJSON = marginRatioTree.value.reduce((acc: any, cur: any) => {
|
||
acc[cur.id] = cur.assignedPointDifference * 1
|
||
return acc
|
||
}, {})
|
||
|
||
// 调用接口
|
||
try {
|
||
await editCustomerApi({ ...params, point_diffs_json: JSON.stringify(marginRatioJSON) })
|
||
dialogVisible.value = false
|
||
} catch (err) {
|
||
console.log('提交失败:', err)
|
||
}
|
||
}
|
||
if (dialogType.value === 'editCommissionRatio') {
|
||
await commissionRatioFormRef.value.validate()
|
||
try {
|
||
await editCustomerApi({
|
||
...params,
|
||
fee_handling_percent: commissionRatioForm.value.commissionRatio,
|
||
})
|
||
dialogVisible.value = false
|
||
await getCustomerList()
|
||
} catch (err) {
|
||
console.log('提交失败:', err)
|
||
}
|
||
}
|
||
}
|
||
// 取消
|
||
const handleCancel = () => {
|
||
dialogVisible.value = false
|
||
}
|
||
// 关闭
|
||
const handleClose = () => {
|
||
dialogVisible.value = false
|
||
}
|
||
/**
|
||
* @description: 定义弹窗表格方法
|
||
*/
|
||
</script>
|
||
|
||
<style scoped lang="scss">
|
||
:deep(.placeholder-row) {
|
||
text-align: center;
|
||
color: #909399;
|
||
/* 灰色,和Element空状态颜色一致 */
|
||
}
|
||
</style>
|