Files
HTFX-CRM-APP/pages/components/reportTable/index.vue
2025-07-07 15:55:44 +08:00

407 lines
13 KiB
Vue

<template>
<view class="tableContainer">
<view v-if="showSearch" class="searchSection">
<slot name="customSearch" :searchFormData="searchFormData" :handleSearch="handleSearchSubmit"></slot>
<view v-if="searchFormRenderColumns?.length">
<slot name="default" :showSearchDialog="showSearchDialog" :searchFormData="searchFormData" :handleSearch="handleSearchSubmit"></slot>
</view>
<uni-popup ref="alertDialog" mask-background-color="transparent" :isMaskClick="false">
<view class="searchFormDialog">
<view class="searchForm">
<uni-forms ref="searchForm" :modelValue="searchFormData">
<uni-row>
<uni-col v-show="searchFormVisible" v-for="item in searchFormRenderColumns" :key="item.field" :span="item.span ?? 24">
<uni-forms-item :label="item.title">
<uni-easyinput primaryColor="#29BBE4" v-if="getTypeByfield(item.field) === 'text'" v-model="searchFormData[item.field]" />
<uni-data-select
v-if="item.field === 'mt4_group' && getTypeByfield(item.field) === 'select' && url == '/app/report/getReport40'"
:localdata="mtGroupOptions"
v-model="searchFormData[item.field]"
:placeholder="$t('form.pleaseSelect')"
:emptyTips="$t('common.empty')"
></uni-data-select>
<uni-data-select
v-else-if="item.field === 'mt4_leverage' && getTypeByfield(item.field) === 'select' && url == '/app/report/getReport40'"
:localdata="leverageList"
v-model="searchFormData[item.field]"
:placeholder="$t('form.pleaseSelect')"
:emptyTips="$t('common.empty')"
></uni-data-select>
<uni-data-select
v-else-if="item.field === 'user_type' && getTypeByfield(item.field) === 'select' && url == '/app/report/getReport40'"
:localdata="[{text: $t('form.userType.ib'), value: 1}, {text: $t('form.userType.customer'), value: 2}]"
v-model="searchFormData[item.field]"
:placeholder="$t('form.pleaseSelect')"
:emptyTips="$t('common.empty')"
></uni-data-select>
<uni-data-select
:clear="url !== '/app/report/getReport26'"
v-else-if="getTypeByfield(item.field) === 'select'"
:localdata="selectFieldsMap[item.field]"
v-model="searchFormData[item.field]"
:placeholder="$t('form.pleaseSelect')"
:emptyTips="$t('common.empty')"
@change="handleSelectChange($event, item.field)"
></uni-data-select>
<uni-datetime-picker
v-if="getTypeByfield(item.field) === 'dateRange'"
type="daterange"
v-model="timeRangeData[item.field]"
@change="(e) => handleDateRangeChange(e, item.field)"
/>
</uni-forms-item>
</uni-col>
</uni-row>
</uni-forms>
<view class="submitter">
<view class="confirmBtn" @click="handleSearchSubmit">{{ $t('common.okText') }}</view>
<view class="cancelBtn" @click="closeSearchDialog">{{ $t('common.cancelText') }}</view>
</view>
</view>
</view>
</uni-popup>
<view v-if="showTimeRangeSelector">
<uni-data-checkbox
v-model="daterangePreset"
:localdata="daterangePresets"
@change="handlePresetChange"
selectedColor="#29BBE4"
class="datePreset"
></uni-data-checkbox>
<uni-datetime-picker type="daterange" v-model="timeRangeData[defaultDateRangeKey]" @change="(e) => handleDateRangeChange(e, defaultDateRangeKey)" />
</view>
</view>
<view class="tableSection">
<uni-table :emptyText="$t('common.empty')" v-if="!tableLoading">
<!-- 表头行 -->
<uni-tr class="tableTh">
<uni-th v-for="item in columns" :key="item.field" :width="getWidthByfield(item.field)" align="center" class="columnItem">
{{ item.title }}
</uni-th>
</uni-tr>
<!-- 表格数据行 -->
<uni-tr v-for="row in tableData" :key="row.rowKey ?? row.id" class="rowItem">
<uni-td v-for="(item, index) in columns" :key="item.rowKey ?? item.id" align="center" class="columnItem">
<view v-if="item.field === 'operate'">
<slot name="operationRender" :row="row"></slot>
</view>
<view v-else-if="item.field === 'status'">
{{ getStatus(row?.[item.field]) }}
</view>
<view v-else-if="item.field == 'currency_type'">
{{ row['currency_type_text'] }}
</view>
<view v-else-if="item.field == 'user_type'">
{{ userTypeOptions?.[row?.[item.field]] }}
</view>
<view v-else-if="item.field == 'mt4_server'">
{{ row['mt4_server_name'] ?? row['mt4_server'] ?? '-' }}
</view>
<view v-else>
{{ row?.[item.field] ?? '-' }}
</view>
</uni-td>
</uni-tr>
</uni-table>
<Spin v-show="tableLoading" />
<view><uni-pagination show-icon :page-size="searchFormData.page_size" :current="searchFormData.curr_page" :total="total" @change="change" /></view>
</view>
</view>
</template>
<script>
import dayjs from 'dayjs';
import mockdata from '@/pages/report/mock';
import { UserLanguage } from '@/utils/const';
import { depositStatusOptions, withdrawStatusOptions, transferStatusOptions, fundOutStatusOptions, fundTransferStatusOptions, userTypeOptions } from '@/utils/options.ts';
import { getTableData } from '@/services/report/report.ts';
import { getMtServers, getMtGroup, getDictByCode } from '@/services/common.ts';
export default {
props: {
title: {
type: String,
required: false,
default: ''
},
url: {
type: String,
required: true,
default: undefined
},
showSearch: {
type: Boolean,
required: false,
default: true
},
showTimeRangeSelector: {
type: Boolean,
required: false,
default: true
},
defaultDateRangeKey: {
type: String,
required: false,
default: 'apply_time'
},
timeRangeStart: {
type: String,
required: false,
default: 'apply_time_start'
},
timeRangeEnd: {
type: String,
required: false,
default: 'apply_time_end'
},
// statusOptions: {
// type: Array,
// required: false,
// default: () => []
// },
visible: {
type: Boolean,
required: true,
default: true
},
queryParams: {
type: Object,
default: null
}
},
data() {
return {
currentReportUrl: '',
searchFormData: {
curr_page: 1,
page_size: 10
},
searchFormVisible: true,
daterangePreset: undefined,
daterangePresets: [
{ text: this.$t('common.yesterday'), value: 1 },
{ text: this.$t('common.threeDays'), value: 2 },
{ text: this.$t('common.7Days'), value: 6 },
{ text: this.$t('common.30Days'), value: 29 }
],
userTypeOptions: userTypeOptions,
mtServerOptions: [],
mtGroupOptions: [],
statusOptionsMap: {
'/app/capital/queryMyGoldInList': depositStatusOptions,
'/app/capital/queryMyGoldOutList': withdrawStatusOptions,
'/app/capital/queryMyTransferList': transferStatusOptions,
'/app/capital/queryMyFundOutList': fundOutStatusOptions,
'/app/capital/queryMyFundTransferList': fundTransferStatusOptions
},
mtServerFields: ['mt4_server'],
timeRangeData: {},
tableLoading: true,
tableData: [],
total: 0,
columns: [],
CURRENT: 1,
PAGESIZE: 10,
leverageList: []
};
},
computed: {
searchFormRenderColumns() {
return this.columns.filter((item) => item.ifFilter);
},
selectFieldsMap() {
return { mt4_server: this.mtServerOptions };
},
// dateRangeFieldsMap() {
// return { '/app/report/getReport17': { apply_time: ['apply_time_start', 'apply_time_end'], audit_time: ['audit_time_start', 'audit_time_end'] } };
// },
dateRangeFieldsMap() {
// 配置是时间范围类型字段对应的起始、结束时间字段名
return {
apply_time: { default: ['apply_time_start', 'apply_time_end'] },
audit_time: { default: ['audit_time_start', 'audit_time_end'] },
close: { default: ['close_start', 'close_end'] },
open_time: { default: ['open_time_start', 'open_time_end'] },
close_time: { default: ['close_time_start', 'close_time_end'] },
create_time: { default: ['create_time_start', 'create_time_end'] },
date_1: { default: ['date_1_start', 'date_1_end'] },
regdate: { default: ['regdate_start', 'regdate_end'] },
lastdate: { default: ['lastdate_start', 'lastdate_end'] }
};
}
},
methods: {
showSearchDialog() {
this.$refs.alertDialog.open();
},
closeSearchDialog() {
this.$refs.alertDialog.close();
},
getTypeByfield(field) {
if (('mt4_group' === field || 'mt4_leverage' === field || 'user_type' === field) && this.url === '/app/report/getReport40') {
return 'select';
}
if (Object.keys(this.selectFieldsMap).includes(field)) {
return 'select';
} else if (Object.keys(this.dateRangeFieldsMap).includes(field)) {
return 'dateRange';
} else {
return 'text';
}
},
getWidthByfield(field) {
if (field.includes('time')) {
return 230;
} else if (field.includes('email')) {
return 150;
} else {
return 110;
}
},
getStatus(key) {
return this.statusOptionsMap[this.url]?.[key];
},
handleDateRangeChange(val, dateRangeKey = 'default_date_range') {
if (!val.length) {
this.timeRangeData[dateRangeKey] = null;
}
this.daterangePreset = undefined;
if (this.timeRangeData[dateRangeKey]) {
this.searchFormData[this.dateRangeFieldsMap[dateRangeKey].default[0] ?? this.timeRangeStart] = this.timeRangeData[dateRangeKey][0];
this.searchFormData[this.dateRangeFieldsMap[dateRangeKey].default[1] ?? this.timeRangeEnd] = this.timeRangeData[dateRangeKey][1];
} else {
delete this.searchFormData[this.dateRangeFieldsMap[dateRangeKey]?.default[0] ?? this.timeRangeStart];
delete this.searchFormData[this.dateRangeFieldsMap[dateRangeKey]?.default[1] ?? this.timeRangeEnd];
}
this.handleSearchSubmit();
},
handlePresetChange(e) {
this.timeRangeData[this.defaultDateRangeKey] = [dayjs().subtract(Number(e.detail.value), 'day').format('YYYY-MM-DD'), dayjs().format('YYYY-MM-DD')];
if (this.timeRangeData[this.defaultDateRangeKey]) {
this.searchFormData[this.dateRangeFieldsMap[this.defaultDateRangeKey].default[0] ?? this.timeRangeStart] = this.timeRangeData[this.defaultDateRangeKey][0];
this.searchFormData[this.dateRangeFieldsMap[this.defaultDateRangeKey].default[1] ?? this.timeRangeEnd] = this.timeRangeData[this.defaultDateRangeKey][1];
} else {
delete this.searchFormData[this.timeRangeStart];
delete this.searchFormData[this.timeRangeEnd];
}
this.handleSearchSubmit();
},
async getMtServerOptions() {
const res = await getMtServers({ qcc_language: UserLanguage, server_type: 'live' });
if (res && res.code === 0) {
this.mtServerOptions = res.data?.map((item) => ({
text: item.server_name,
value: item.id
}));
}
},
async getTableDataByUrl() {
this.tableLoading = true;
this.tableData = [];
const params = {
...this.searchFormData,
qcc_language: UserLanguage
};
if (this.url === '/app/report/getReport26') {
await this.getMtServerOptions();
this.mtServerOptions.push({ text: 'PAMM', value: 99 });
if (!params.mt4_server) {
this.searchFormData.mt4_server = this.mtServerOptions[0]?.value;
params.mt4_server = this.mtServerOptions[0]?.value;
}
}
const res = await getTableData(this.url, params);
if (res && res.code === 0) {
if (this.url === '/app/report/getReport40') {
if (res.data.records && res.data.records.length) {
res.data.records.pop()
}
}
this.tableData = res.data.records ?? [];
this.columns = res.data.columns ?? [];
this.total = res.data.totalRecords;
}
res.data.columns.find((item) => {
if (item.ifFilter === true && this.mtServerFields.includes(item.field)) {
if (!this.mtServerOptions.length) {
this.getMtServerOptions();
}
return true;
} else {
return false;
}
});
this.tableLoading = false;
},
// 分页触发
change(e) {
this.searchFormData.curr_page = e.current;
this.getTableDataByUrl();
},
handleSearchSubmit() {
this.getTableDataByUrl();
this.closeSearchDialog();
},
loadMtGroupList(serverCode) {
getMtGroup({
qcc_mt_server: serverCode
}).then(resp => {
if (resp.data) {
this.mtGroupOptions = resp.data.map(i => ({text: i.mt_group, value: i.mt_group}))
}
})
},
handleSelectChange(e, field) {
if ('mt4_server' === field && this.url === '/app/report/getReport40') {
this.searchFormData['mt4_group'] = undefined
this.mtGroupOptions = []
if (e) {
this.loadMtGroupList(e)
}
}
}
},
watch: {
url(newValue, oldValue) {
this.timeRangeData = {}
this.searchFormData.timeRange = null;
this.daterangePreset = undefined;
Object.keys(this.searchFormData).forEach((key) => {
delete this.searchFormData[key];
});
this.searchFormData.curr_page = this.CURRENT;
this.searchFormData.page_size = this.PAGESIZE;
this.total = 0;
this.getTableDataByUrl();
if (newValue == '/app/report/getReport40') {
getDictByCode('leverage').then(resp => {
this.leverageList = resp.data.map(i => {
return { text: i.fun_item_text, value: i.fun_item_code }
})
})
}
},
visible(newValue, oldValue) {
if (newValue) {
this.getTableDataByUrl();
}
}
},
mounted() {
if (this.queryParams) {
Object.assign(this.searchFormData, this.queryParams)
}
if (this.visible) {
this.getTableDataByUrl();
}
},
onReady() {}
};
</script>
<style lang="scss" scoped>
@import './index.scss';
</style>