调整表格滚动条

This commit is contained in:
2026-05-11 11:00:24 +08:00
parent f76e890ab2
commit 022c18c6be
8 changed files with 155 additions and 140 deletions

View File

@ -0,0 +1,8 @@
.el-drawer__body {
display: flex;
flex-direction: column;
padding: 20px;
overflow: hidden;
height: 100%;
max-height: 100%;
}

View File

@ -1,5 +1,6 @@
@use './user.scss'; @use './user.scss';
@use './system.scss'; @use './system.scss';
@use './element.scss';
* { * {
margin: 0; margin: 0;

View File

@ -142,7 +142,7 @@ defineExpose({
<style scoped lang="scss"> <style scoped lang="scss">
.table-container { .table-container {
width: 100%; width: 100%;
height: calc(100vh - 180px); height: 100%;
overflow: hidden; // overflow: hidden;
} }
</style> </style>

View File

@ -21,8 +21,8 @@
<!-- 用户信息下拉菜单 --> <!-- 用户信息下拉菜单 -->
<el-dropdown @command="handleCommand" class="user-dropdown"> <el-dropdown @command="handleCommand" class="user-dropdown">
<div class="user-info"> <div class="user-info">
<el-avatar :size="32" :src="userAvatar" class="user-avatar"> <el-avatar :size="32" class="user-avatar">
<el-icon><User /></el-icon> <el-icon :size="20"><User /></el-icon>
</el-avatar> </el-avatar>
<span class="username">{{ activeUserName }}</span> <span class="username">{{ activeUserName }}</span>
<el-icon class="dropdown-icon"><ArrowDown /></el-icon> <el-icon class="dropdown-icon"><ArrowDown /></el-icon>
@ -49,6 +49,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { computed } from 'vue'
import { import {
Bell, Bell,
Sunny, Sunny,
@ -69,10 +70,8 @@ const router = useRouter()
const userStore = useUserStore() const userStore = useUserStore()
const languageStore = useLanguageStore() const languageStore = useLanguageStore()
// // - 使 userStore
const userInfo = getStorage<any>('userInfo') const activeUserName = computed(() => userStore.userInfo?.username || '-')
const activeUserName = ref(userInfo?.username || 'Admin')
const userAvatar = ref(userInfo?.avatar || '')
const unreadCount = ref(3) // const unreadCount = ref(3) //
// //

View File

@ -165,6 +165,19 @@ const switchAccount = async () => {
clearUserInfo(); clearUserInfo();
router.push('/user/login'); router.push('/user/login');
}; };
/**
*
* @param data
*/
const updateUserInfo = (data: Partial<UserInfo>) => {
if (userInfo.value) {
// 合并更新用户信息
userInfo.value = { ...userInfo.value, ...data };
// 更新本地存储
setStorage('userInfo', userInfo.value);
}
};
return { return {
// 状态 // 状态
token, token,
@ -182,6 +195,7 @@ return {
forgotPassword, forgotPassword,
changePassword, changePassword,
sendCode, sendCode,
switchAccount switchAccount,
updateUserInfo
}; };
}); });

View File

@ -27,13 +27,13 @@ export const tableColumns = [
// 账号数量 // 账号数量
{ prop: 'accountQty', label: '账号数量', width: 100 }, { prop: 'accountQty', label: '账号数量', width: 100 },
// 点差分配比例 // 点差分配比例
{ prop: 'marginRatio', label: '点差分配比例', slotName: 'marginRatio' , minWidth: 140}, { prop: 'marginRatio', label: '点差分配比例', slotName: 'marginRatio' , width: 140},
// 手续费分成比例 // 手续费分成比例
{ prop: 'commissionRatio', label: '手续费分成比例', slotName: 'commissionRatio' , minWidth: 140}, { prop: 'commissionRatio', label: '手续费分成比例', slotName: 'commissionRatio' , width: 140},
// 注册时间 // 注册时间
{ prop: 'createTime', label: '注册时间', sortable: true , minWidth: 180}, { prop: 'createTime', label: '注册时间', sortable: true , minWidth: 180},
// 操作 // 操作
{ label: '操作', slotName: 'action', minWidth: 200} { label: '操作', slotName: 'action', width: 200}
] ]
// 点差表格配置 // 点差表格配置

View File

@ -1,35 +1,21 @@
<template> <template>
<div class="market"> <div class="market">
<!-- 搜索 --> <!-- 搜索 -->
<MarketSearch <MarketSearch :search-form="marketSearchForm" :search-options="marketSearchOptions" @search="handleSearch"
:search-form="marketSearchForm" @reset="handleReset">
:search-options="marketSearchOptions"
@search="handleSearch"
@reset="handleReset"
>
<template #button="{ form }"> <template #button="{ form }">
<el-button type="primary" @click="handleAddMarket()" v-auth="'agent_createAgent'"> <el-button type="primary" @click="handleAddMarket()" v-auth="'agent_createAgent'">
添加 添加
</el-button> </el-button>
<el-button <el-button type="primary" :disabled="!selectedRow" v-auth="'agent_editAgent'" @click="handleEditMarket()">
type="primary"
:disabled="!selectedRow"
v-auth="'agent_editAgent'"
@click="handleEditMarket()"
>
编辑 编辑
</el-button> </el-button>
</template> </template>
</MarketSearch> </MarketSearch>
<!-- 表格 --> <!-- 表格 -->
<MarketTable <MarketTable :table-data="marketTree" :columns="marketTableColumnsOptions" row-key="id" @row-click="handleRowClick"
:table-data="marketTree" @row-contextmenu="handleRowContextMenu">
:columns="marketTableColumnsOptions"
row-key="id"
@row-click="handleRowClick"
@row-contextmenu="handleRowContextMenu"
>
<template #pointSpread="{ row }"> <template #pointSpread="{ row }">
<el-button type="primary" size="small" @click="handleViewPointDiff(row)"> 查看 </el-button> <el-button type="primary" size="small" @click="handleViewPointDiff(row)"> 查看 </el-button>
</template> </template>
@ -44,107 +30,80 @@
</context-menu> </context-menu>
<!-- 分页 --> <!-- 分页 -->
<MarketPagination <MarketPagination v-model="currentPage" v-model:pageSizeValue="pageSize" :total="total"
v-model="currentPage" @pagination-change="handlePaginationChange" />
v-model:pageSizeValue="pageSize"
:total="total"
@pagination-change="handlePaginationChange"
/>
</div> </div>
<!-- dialog --> <!-- 抽屉 -->
<MarketDialog <el-drawer class="my-drawer" :append-to-body="false" v-model="dialogVisible" :title="dialogTitle"
:visible="dialogVisible" :size="dialogType === 'view' ? '60%' : '50%'" :destroy-on-close="true">
:title="dialogTitle"
:type="dialogType"
:fullscreen="dialogFullscreen"
:show-footer="dialogType !== 'view'"
@confirm="handleSubmit"
@cancel="handleCancel"
@close="handleClose"
>
<!-- 表单 --> <!-- 表单 -->
<MarketForm <div v-if="dialogType !== 'view'" class="drawer-form">
:form-data="marketForm" <MarketForm :form-data="marketForm" :form-rules="marketFormRules" :form-items="marketFormItemOptions"
:form-rules="marketFormRules" :options-map="marketFormOptionsMap" ref="marketFormRef">
:form-items="marketFormItemOptions" <template #phoneOrEmail="{ formData }" v-if="dialogType === 'add'">
:options-map="marketFormOptionsMap" <div class="phone-email">
ref="marketFormRef" <div class="tab-btn">
v-if="dialogType !== 'view'" <el-button :type="activeTab === 'email' ? 'primary' : 'default'" size="small"
> @click="activeTab = 'email'">
<template #phoneOrEmail="{ formData }" v-if="dialogType === 'add'"> 邮箱
<div class="phone-email"> </el-button>
<div class="tab-btn"> <el-button :type="activeTab === 'phone' ? 'primary' : 'default'" size="small"
<el-button @click="activeTab = 'phone'">
:type="activeTab === 'email' ? 'primary' : 'default'" 手机号
size="small" </el-button>
@click="activeTab = 'email'" </div>
> <div class="group">
邮箱 <el-form-item prop="email" v-if="activeTab === 'email'">
</el-button> <el-input v-model="marketForm.email" placeholder="请输入邮箱" />
<el-button </el-form-item>
:type="activeTab === 'phone' ? 'primary' : 'default'" <el-form-item prop="phone" class="phone-item" v-if="activeTab === 'phone'">
size="small" <el-select v-model="marketForm.countryCode" placeholder="请选择国家区号">
@click="activeTab = 'phone'" <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>
</el-button> <span class="country-code">{{ item.code }}</span>
</div>
</el-option>
</el-select>
<el-input v-model="marketForm.phone" placeholder="请输入手机号" />
</el-form-item>
</div>
</div> </div>
<div class="group"> </template>
<el-form-item prop="email" v-if="activeTab === 'email'"> </MarketForm>
<el-input v-model="marketForm.email" placeholder="请输入邮箱" /> </div>
</el-form-item>
<el-form-item prop="phone" class="phone-item" v-if="activeTab === 'phone'">
<el-select v-model="marketForm.countryCode" placeholder="请选择国家区号">
<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="marketForm.phone" placeholder="请输入手机号" />
</el-form-item>
</div>
</div>
</template>
</MarketForm>
<!-- 点差表格 --> <!-- 点差表格 -->
<MarketTable <div class="drawer-table">
:table-data="marketPointTree" <div class="table-header" v-if="dialogType !== 'view'">点差配置</div>
:columns="marketPointTableColumnsOptions" <div class="table-wrapper">
row-key="id" <MarketTable :table-data="marketPointTree" :columns="marketPointTableColumnsOptions" row-key="id">
style="height: 300px" <template #assignedPointDiff="{ row }">
> <el-form :model="row" :rules="rules(marketForm, row)">
<template #assignedPointDiff="{ row }"> <el-form-item prop="pointDifference">
<el-form :model="row" :rules="rules(marketForm, row)"> <el-input v-model="row.pointDifference" size="small" placeholder="请输入点差" />
<el-form-item prop="pointDifference"> </el-form-item>
<el-input v-model="row.pointDifference" size="small" placeholder="请输入点差" /> </el-form>
</el-form-item> </template>
</el-form> </MarketTable>
</template> </div>
</MarketTable> </div>
</MarketDialog>
<MarketDialog <!-- 底部按钮 -->
:visible="rightClickDialogVisible" <template #footer v-if="dialogType !== 'view'">
:title="rightClickDialogTitleEnum[rightClickDialogType]" <div class="drawer-footer">
@confirm="handleRightClickDialogSubmit" <el-button @click="handleCancel">取消</el-button>
@cancel="handleRightClickDialogCancel" <el-button type="primary" @click="handleSubmit">确定</el-button>
@close="handleRightClickDialogClose" </div>
> </template>
</el-drawer>
<MarketDialog :visible="rightClickDialogVisible" :title="rightClickDialogTitleEnum[rightClickDialogType]"
@confirm="handleRightClickDialogSubmit" @cancel="handleRightClickDialogCancel" @close="handleRightClickDialogClose">
<!-- 'account' | 'acceptOrders' | 'transfer' | 'deposit' | 'withdraw' --> <!-- 'account' | 'acceptOrders' | 'transfer' | 'deposit' | 'withdraw' -->
<MarketForm <MarketForm :marketForm="rightClickMarketForm" :form-rules="rightClickMarketFormRules"
:marketForm="rightClickMarketForm" :form-items="rightClickMarketFormItemOptions"></MarketForm>
:form-rules="rightClickMarketFormRules"
:form-items="rightClickMarketFormItemOptions"
></MarketForm>
</MarketDialog> </MarketDialog>
</template> </template>
@ -157,7 +116,6 @@ defineOptions({
import MarketSearch from '@/components/common/Search.vue' import MarketSearch from '@/components/common/Search.vue'
import MarketTable from '@/components/common/Table.vue' import MarketTable from '@/components/common/Table.vue'
import MarketPagination from '@/components/common/Pagination.vue' import MarketPagination from '@/components/common/Pagination.vue'
import MarketDialog from '@/components/common/Dialog.vue'
import MarketForm from '@/components/common/Form.vue' import MarketForm from '@/components/common/Form.vue'
// //
import { import {
@ -168,7 +126,7 @@ import {
countryOptions, countryOptions,
viewMarketPointTableColumns, viewMarketPointTableColumns,
} from './options' } from './options'
import {useUserStore} from '@/stores/modules/user.ts' import { useUserStore } from '@/stores/modules/user.ts'
import { rules } from './rules' import { rules } from './rules'
// //
@ -211,7 +169,6 @@ const currentPage = ref(1)
const dialogVisible = ref<boolean>(false) const dialogVisible = ref<boolean>(false)
const dialogTitle = ref<string>('') const dialogTitle = ref<string>('')
const dialogType = ref<string>('add') const dialogType = ref<string>('add')
const dialogFullscreen = ref(false)
/** /**
* @description 定义dialog表单数据 * @description 定义dialog表单数据
@ -318,7 +275,7 @@ const handleAction = (key: 'account' | 'acceptOrders' | 'transfer' | 'deposit' |
rightClickDialogVisible.value = true rightClickDialogVisible.value = true
} }
const handleRightClickDialogSubmit = () => {} const handleRightClickDialogSubmit = () => { }
const handleRightClickDialogCancel = () => { const handleRightClickDialogCancel = () => {
rightClickDialogVisible.value = false rightClickDialogVisible.value = false
@ -533,7 +490,6 @@ const handleAddMarket = async () => {
dialogType.value = 'add' dialogType.value = 'add'
// 2. // 2.
marketForm.value = { ...initMarketForm } marketForm.value = { ...initMarketForm }
dialogFullscreen.value = false
} }
// //
@ -585,11 +541,10 @@ const handleEditMarket = async () => {
})) }))
} }
// //
dialogVisible.value = true dialogVisible.value = true
dialogTitle.value = '编辑' dialogTitle.value = '编辑'
dialogType.value = 'edit' dialogType.value = 'edit'
dialogFullscreen.value = false
} catch (error) { } catch (error) {
console.error('编辑数据加载失败:', error) console.error('编辑数据加载失败:', error)
} }
@ -610,11 +565,10 @@ const handleViewPointDiff = async (row: any) => {
assignedPointDifference: item.target_point_diff || '', assignedPointDifference: item.target_point_diff || '',
})) }))
// //
dialogVisible.value = true dialogVisible.value = true
dialogTitle.value = '查看点差' dialogTitle.value = '查看点差'
dialogType.value = 'view' dialogType.value = 'view'
dialogFullscreen.value = true
} catch (error) { } catch (error) {
console.error('加载点差数据失败:', error) console.error('加载点差数据失败:', error)
} }
@ -721,13 +675,7 @@ const handleSubmit = async () => {
// //
const handleCancel = async () => { const handleCancel = async () => {
dialogVisible.value = false dialogVisible.value = false
// dialog // drawer
}
//
const handleClose = async () => {
dialogVisible.value = false
// dialog
} }
</script> </script>
@ -735,6 +683,7 @@ const handleClose = async () => {
:deep(.el-form-item__content) { :deep(.el-form-item__content) {
margin-left: 0 !important; margin-left: 0 !important;
} }
.market { .market {
.search-container { .search-container {
:deep(.el-form) { :deep(.el-form) {
@ -778,7 +727,49 @@ const handleClose = async () => {
} }
} }
} }
.table-container { .table-container {
max-width: 100%; max-width: 100%;
} }
//
.drawer-form {
flex-shrink: 0;
margin-bottom: 20px;
padding-bottom: 20px;
border-bottom: 1px solid #ebeef5;
}
.drawer-table {
flex: 1;
display: flex;
flex-direction: column;
overflow: hidden;
min-height: 0;
max-height: 100%;
.table-header {
flex-shrink: 0;
font-size: 16px;
font-weight: 500;
color: #303133;
margin-bottom: 16px;
padding-bottom: 8px;
border-bottom: 1px solid #ebeef5;
}
.table-wrapper {
flex: 1;
min-height: 0;
}
}
.drawer-footer {
flex-shrink: 0;
display: flex;
justify-content: flex-end;
gap: 10px;
padding-top: 20px;
border-top: 1px solid #ebeef5;
}
</style> </style>

View File

@ -377,6 +377,8 @@ const handleEditConfirm = async () => {
const params: EditUsernameParams = { username: editForm.value }; const params: EditUsernameParams = { username: editForm.value };
await editUsernameApi(params); await editUsernameApi(params);
userInfo.username = editForm.value; userInfo.username = editForm.value;
//
userStore.updateUserInfo({ username: editForm.value });
} }
if (editField.value === 'mobile') { if (editField.value === 'mobile') {
const mobile = editForm.countryCode + editForm.value; const mobile = editForm.countryCode + editForm.value;