Compare commits
2 Commits
bf3f380ba8
...
1251a0be83
| Author | SHA1 | Date | |
|---|---|---|---|
| 1251a0be83 | |||
| 7cc56af0d5 |
@@ -5,16 +5,27 @@
|
||||
import { get } from '@/utils/request';
|
||||
import { USE_MOCK, MOCK_DELAY } from '@/config/mock';
|
||||
import { buildMockPaymentFlowPage } from '@/config/mock/paymentFlow';
|
||||
import type { PaymentFlowQueryParams, PaymentFlowVO, PageData, ApiResult } from './types';
|
||||
import type {
|
||||
PaymentFlowQueryParams,
|
||||
PaymentFlowVO,
|
||||
PaymentFlowPageData,
|
||||
ApiResult,
|
||||
} from './types';
|
||||
|
||||
export type { PaymentFlowVO, PaymentFlowQueryParams, PageData, ApiResult } from './types';
|
||||
export type {
|
||||
PaymentFlowVO,
|
||||
PaymentFlowQueryParams,
|
||||
PaymentFlowPageData,
|
||||
PaymentFlowExData,
|
||||
ApiResult,
|
||||
} from './types';
|
||||
|
||||
const delay = (ms: number) => new Promise<void>((r) => setTimeout(r, ms));
|
||||
|
||||
/** GET /admin/finance/paymentFlow/page — 支付流水分页 */
|
||||
export async function getPaymentFlowList(
|
||||
params: PaymentFlowQueryParams,
|
||||
): Promise<ApiResult<PageData<PaymentFlowVO>>> {
|
||||
): Promise<ApiResult<PaymentFlowPageData>> {
|
||||
if (USE_MOCK) {
|
||||
await delay(MOCK_DELAY);
|
||||
const page = Number(params.page) || 1;
|
||||
|
||||
@@ -41,6 +41,22 @@ export interface PageData<T> {
|
||||
total: number;
|
||||
list: T[];
|
||||
}
|
||||
|
||||
/** 支付流水分页扩展汇总(与 total 同级) */
|
||||
export interface PaymentFlowExData {
|
||||
/** 总支付金额 */
|
||||
totalAmount: string;
|
||||
/** 总退款金额 */
|
||||
totalRefundAmount: string;
|
||||
}
|
||||
|
||||
/** 支付流水分页响应 */
|
||||
export interface PaymentFlowPageData {
|
||||
total: number;
|
||||
list: PaymentFlowVO[];
|
||||
exData: PaymentFlowExData;
|
||||
}
|
||||
|
||||
export interface ApiResult<T> {
|
||||
code: number;
|
||||
msg: string;
|
||||
|
||||
@@ -41,6 +41,19 @@ export interface RoleUsageUserQueryParams {
|
||||
roleId?: string;
|
||||
}
|
||||
|
||||
/** 保存角色 — POST /admin/sys/role/save */
|
||||
export interface RoleSaveParams {
|
||||
name: string;
|
||||
menuIds: string[];
|
||||
}
|
||||
|
||||
/** 更新角色 — POST /admin/sys/role/update */
|
||||
export interface RoleUpdateParams {
|
||||
id: string;
|
||||
name: string;
|
||||
menuIds: string[];
|
||||
}
|
||||
|
||||
export interface PageData<T> {
|
||||
total: number;
|
||||
list: T[];
|
||||
|
||||
@@ -28,7 +28,7 @@ export type {
|
||||
|
||||
const delay = (ms: number) => new Promise<void>((r) => setTimeout(r, ms));
|
||||
|
||||
/** GET /sys/user/page — 用户分页 */
|
||||
/** GET /admin/sys/user/page — 用户分页 */
|
||||
export async function getUserList(
|
||||
params: UserListQueryParams,
|
||||
): Promise<ApiResult<PageData<TournamentAdminUserVO>>> {
|
||||
@@ -38,7 +38,7 @@ export async function getUserList(
|
||||
const limit = Number(params.limit) || 10;
|
||||
return { code: 200, msg: 'success', data: buildMockUserListPage(page, limit) };
|
||||
}
|
||||
return get('/sys/user/page', params as Record<string, any>);
|
||||
return get('/admin/sys/user/page', params as Record<string, any>);
|
||||
}
|
||||
|
||||
/** POST /sys/user/save — 新增用户 */
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* 支付流水假数据
|
||||
* 对应接口:GET /admin/finance/paymentFlow/page
|
||||
*/
|
||||
import type { PaymentFlowVO, PaymentFlowQueryParams, PageData } from '@/api/payments';
|
||||
import type { PaymentFlowVO, PaymentFlowQueryParams, PaymentFlowPageData } from '@/api/payments';
|
||||
|
||||
const MOCK_LIST: PaymentFlowVO[] = [
|
||||
{
|
||||
@@ -127,7 +127,7 @@ export function buildMockPaymentFlowPage(
|
||||
page: number,
|
||||
limit: number,
|
||||
params: PaymentFlowQueryParams,
|
||||
): PageData<PaymentFlowVO> {
|
||||
): PaymentFlowPageData {
|
||||
let filtered = [...MOCK_LIST];
|
||||
|
||||
if (params.nickname) {
|
||||
@@ -143,7 +143,22 @@ export function buildMockPaymentFlowPage(
|
||||
inDateRange(item.createDate, params.createDateBegin, params.createDateEnd),
|
||||
);
|
||||
|
||||
let totalAmount = 0;
|
||||
let totalRefundAmount = 0;
|
||||
for (const item of filtered) {
|
||||
const amt = Number(item.amount) || 0;
|
||||
if (item.type === 1) totalAmount += amt;
|
||||
else if (item.type === 2) totalRefundAmount += amt;
|
||||
}
|
||||
|
||||
const total = filtered.length;
|
||||
const start = (page - 1) * limit;
|
||||
return { total, list: filtered.slice(start, start + limit) };
|
||||
return {
|
||||
total,
|
||||
list: filtered.slice(start, start + limit),
|
||||
exData: {
|
||||
totalAmount: totalAmount.toFixed(2),
|
||||
totalRefundAmount: totalRefundAmount.toFixed(2),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -83,11 +83,11 @@ export default defineComponent({
|
||||
<div class={pageStyles.summary}>
|
||||
<span class={pageStyles.summaryItem}>
|
||||
<span class={pageStyles.summaryLabel}>总支付金额:</span>
|
||||
<span class={pageStyles.summaryValue}>{summary.value.totalPay}元</span>
|
||||
<span class={pageStyles.summaryValue}>{summary.value.totalAmount}元</span>
|
||||
</span>
|
||||
<span class={pageStyles.summaryItem}>
|
||||
<span class={pageStyles.summaryLabel}>总退款金额:</span>
|
||||
<span class={pageStyles.summaryValue}>{summary.value.totalRefund}元</span>
|
||||
<span class={pageStyles.summaryValue}>{summary.value.totalRefundAmount}元</span>
|
||||
</span>
|
||||
</div>
|
||||
<div ref={containerRef} class={pageStyles.tableBody}>
|
||||
|
||||
@@ -8,21 +8,22 @@ import { buildMockPaymentFlowPage } from '@/config/mock/paymentFlow';
|
||||
import type {
|
||||
PaymentFlowQueryParams,
|
||||
PaymentFlowVO,
|
||||
PageData,
|
||||
PaymentFlowPageData,
|
||||
ApiResult,
|
||||
} from '@/api/payments/types';
|
||||
|
||||
export type {
|
||||
PaymentFlowVO,
|
||||
PaymentFlowQueryParams,
|
||||
PageData,
|
||||
PaymentFlowPageData,
|
||||
PaymentFlowExData,
|
||||
ApiResult,
|
||||
} from '@/api/payments/types';
|
||||
|
||||
// ============================================================
|
||||
// URL 常量
|
||||
// ============================================================
|
||||
const paymentFlowList = '/finance/paymentFlow/page';
|
||||
const paymentFlowList = '/admin/finance/paymentFlow/page';
|
||||
|
||||
const delay = (ms: number) => new Promise<void>((r) => setTimeout(r, ms));
|
||||
|
||||
@@ -33,7 +34,7 @@ const delay = (ms: number) => new Promise<void>((r) => setTimeout(r, ms));
|
||||
/** 支付流水分页 */
|
||||
export async function getPaymentFlowList(
|
||||
params: PaymentFlowQueryParams,
|
||||
): Promise<ApiResult<PageData<PaymentFlowVO>>> {
|
||||
): Promise<ApiResult<PaymentFlowPageData>> {
|
||||
if (USE_MOCK) {
|
||||
await delay(MOCK_DELAY);
|
||||
const page = Number(params.page) || 1;
|
||||
|
||||
@@ -41,7 +41,7 @@ export function usePaymentsModel() {
|
||||
);
|
||||
|
||||
// ===== 汇总 =====
|
||||
const [summary, setSummary] = useState({ totalPay: '0.00', totalRefund: '0.00' });
|
||||
const [summary, setSummary] = useState({ totalAmount: '0.00', totalRefundAmount: '0.00' });
|
||||
|
||||
// ===== 表格状态 =====
|
||||
const [loading, setLoading] = useState<boolean>(false);
|
||||
@@ -104,21 +104,14 @@ export function usePaymentsModel() {
|
||||
setLoading(true);
|
||||
try {
|
||||
const queryParams = buildQueryParams();
|
||||
console.log('支付流水查询参数:', queryParams);
|
||||
const res = await getPaymentFlowList(queryParams);
|
||||
if (res.code == 200) {
|
||||
console.log('支付流水查询结果:', { total: res.data.total, count: res.data.list.length });
|
||||
setDataSource(res.data.list);
|
||||
setPagination({ ...pagination.value, total: res.data.total });
|
||||
// 汇总:type=1 金额为收入,type=2 金额为退款
|
||||
let totalPay = 0;
|
||||
let totalRefund = 0;
|
||||
for (const item of res.data.list) {
|
||||
const amt = Number(item.amount) || 0;
|
||||
if (item.type === 1) totalPay += amt;
|
||||
else if (item.type === 2) totalRefund += amt;
|
||||
}
|
||||
setSummary({ totalPay: totalPay.toFixed(2), totalRefund: totalRefund.toFixed(2) });
|
||||
setSummary({
|
||||
totalAmount: res.data.exData?.totalAmount ?? '0.00',
|
||||
totalRefundAmount: res.data.exData?.totalRefundAmount ?? '0.00',
|
||||
});
|
||||
}
|
||||
} catch {
|
||||
// 网络层已统一提示
|
||||
@@ -134,7 +127,7 @@ export function usePaymentsModel() {
|
||||
filterForm.type = '';
|
||||
setPagination({ current: 1, pageSize: 10, total: 0 });
|
||||
setDataSource([]);
|
||||
setSummary({ totalPay: '0.00', totalRefund: '0.00' });
|
||||
setSummary({ totalAmount: '0.00', totalRefundAmount: '0.00' });
|
||||
setTimeout(() => handleSearch(), 350);
|
||||
}, 500);
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import { defineComponent, reactive, ref, watch } from 'vue';
|
||||
import { Modal, Radio, Input, Button, Upload, Image, Spin, message } from 'ant-design-vue';
|
||||
import { PlusOutlined } from '@ant-design/icons-vue';
|
||||
import { getWithdrawInfo, postWithdrawAudit, type WithdrawInfoVO } from '../model/services';
|
||||
import { AUDIT_STATUS_MAP, PAY_STATUS_MAP } from '../model/useWithdrawModel';
|
||||
import { getAuditStatusText, getPayStatusText } from '../model/useWithdrawModel';
|
||||
import styles from './WithdrawDetailModal.module.less';
|
||||
|
||||
const { TextArea } = Input;
|
||||
@@ -135,8 +135,8 @@ export default defineComponent({
|
||||
{renderItem('费率:', `${(Number(d.feeRate) * 100).toFixed(2)}%`)}
|
||||
{renderItem('手续费:', `¥${d.feeAmount}`)}
|
||||
{renderItem('到账金额:', `¥${d.receivedAmount}`, true)}
|
||||
{renderItem('审核状态:', AUDIT_STATUS_MAP[d.auditStatus] ?? '-', true)}
|
||||
{renderItem('列账状态:', PAY_STATUS_MAP[d.payStatus] ?? '-')}
|
||||
{renderItem('审核状态:', getAuditStatusText(d.auditStatus), true)}
|
||||
{renderItem('列账状态:', getPayStatusText(d.payStatus))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { defineComponent, onMounted } from 'vue';
|
||||
import { Button, Input, Table, Form, Space, Pagination, Select } from 'ant-design-vue';
|
||||
import { useWithdrawModel, AUDIT_STATUS_MAP, PAY_STATUS_MAP } from './model/useWithdrawModel';
|
||||
import { useWithdrawModel, renderAuditStatus, renderPayStatus } from './model/useWithdrawModel';
|
||||
import { useContainerSize } from '@/hooks';
|
||||
import WithdrawDetailModal from './components/WithdrawDetailModal';
|
||||
import pageStyles from '@/assets/styles/pageLayout.module.less';
|
||||
@@ -21,10 +21,10 @@ function renderBodyCell({
|
||||
onView: (record: any) => void;
|
||||
}) {
|
||||
if (column.key === 'auditStatus') {
|
||||
return <span>{AUDIT_STATUS_MAP[record.auditStatus] || record.auditStatus || '-'}</span>;
|
||||
return renderAuditStatus(record.auditStatus);
|
||||
}
|
||||
if (column.key === 'payStatus') {
|
||||
return <span>{PAY_STATUS_MAP[record.payStatus] ?? '-'}</span>;
|
||||
return renderPayStatus(record.payStatus);
|
||||
}
|
||||
if (column.key === 'action') {
|
||||
// auditStatus=0(待审核)→ 显示「审核」,其他 → 显示「查看」
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { computed, reactive, toRef, Ref } from 'vue';
|
||||
import { computed, reactive, toRef, Ref, h } from 'vue';
|
||||
import { StatusTag, type StatusTagTone } from '@/components';
|
||||
import { useState, useDebounce, useThrottleFn } from '@/hooks';
|
||||
import { getWithdrawList, type WithdrawVO, type WithdrawQueryParams } from './services';
|
||||
|
||||
@@ -22,20 +23,45 @@ export const PAY_STATUS_OPTIONS = [
|
||||
{ value: '2', label: '支付失败' },
|
||||
] as const;
|
||||
|
||||
/** 审核状态文案映射 */
|
||||
export const AUDIT_STATUS_MAP: Record<number, string> = {
|
||||
0: '待审核',
|
||||
1: '审核通过',
|
||||
2: '审核驳回',
|
||||
/** 审核状态文案 + 色调映射 */
|
||||
const AUDIT_STATUS_MAP: Record<number, { label: string; tone: StatusTagTone }> = {
|
||||
0: { label: '待审核', tone: 'warning' },
|
||||
1: { label: '审核通过', tone: 'success' },
|
||||
2: { label: '审核驳回', tone: 'danger' },
|
||||
};
|
||||
|
||||
/** 到账状态文案映射 */
|
||||
export const PAY_STATUS_MAP: Record<number, string> = {
|
||||
0: '未支付',
|
||||
1: '支付成功',
|
||||
2: '支付失败',
|
||||
/** 到账状态文案 + 色调映射 */
|
||||
const PAY_STATUS_MAP: Record<number, { label: string; tone: StatusTagTone }> = {
|
||||
0: { label: '未支付', tone: 'default' },
|
||||
1: { label: '支付成功', tone: 'success' },
|
||||
2: { label: '支付失败', tone: 'danger' },
|
||||
};
|
||||
|
||||
/** 渲染审核状态 StatusTag */
|
||||
export function renderAuditStatus(status: number) {
|
||||
const info = AUDIT_STATUS_MAP[status] || {
|
||||
label: String(status ?? '-'),
|
||||
tone: 'default' as const,
|
||||
};
|
||||
return h(StatusTag, { label: info.label, tone: info.tone });
|
||||
}
|
||||
|
||||
/** 渲染到账状态 StatusTag */
|
||||
export function renderPayStatus(status: number) {
|
||||
const info = PAY_STATUS_MAP[status] || { label: String(status ?? '-'), tone: 'default' as const };
|
||||
return h(StatusTag, { label: info.label, tone: info.tone });
|
||||
}
|
||||
|
||||
/** 获取审核状态纯文本(详情弹窗用) */
|
||||
export function getAuditStatusText(status: number): string {
|
||||
return AUDIT_STATUS_MAP[status]?.label ?? String(status ?? '-');
|
||||
}
|
||||
|
||||
/** 获取到账状态纯文本(详情弹窗用) */
|
||||
export function getPayStatusText(status: number): string {
|
||||
return PAY_STATUS_MAP[status]?.label ?? String(status ?? '-');
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// Model
|
||||
// ============================================================
|
||||
|
||||
@@ -22,7 +22,7 @@ export type {
|
||||
// ============================================================
|
||||
// URL 常量
|
||||
// ============================================================
|
||||
const operationLogList = '/sys/operation/page';
|
||||
const operationLogList = '/admin/sys/operation/page';
|
||||
|
||||
const delay = (ms: number) => new Promise<void>((r) => setTimeout(r, ms));
|
||||
|
||||
|
||||
@@ -2,12 +2,7 @@ import { defineComponent, ref, reactive, watch } from 'vue';
|
||||
import { Modal, Form, Input, Tree, Button, Spin, message } from 'ant-design-vue';
|
||||
import type { TreeProps } from 'ant-design-vue';
|
||||
import { getPermissionTree, type PermissionTreeNode } from '../model/services';
|
||||
import {
|
||||
roleNameRules,
|
||||
buildTreeData,
|
||||
extractLeafPermissions,
|
||||
type AntdTreeNode,
|
||||
} from '../controller';
|
||||
import { roleNameRules, buildTreeData, type AntdTreeNode } from '../controller';
|
||||
import styles from './RoleFormModal.module.less';
|
||||
|
||||
interface RoleFormModalProps {
|
||||
@@ -110,18 +105,26 @@ export default defineComponent({
|
||||
return;
|
||||
}
|
||||
|
||||
const isEdit = !!props.record;
|
||||
// 仅提取叶节点 { id, selected } 传给后端
|
||||
const leafPermissions = extractLeafPermissions(rawApiTree.value);
|
||||
// 从原始权限树中收集所有叶节点 ID(children 为空或不存在)
|
||||
const leafNodeIds = new Set<string>();
|
||||
const collectLeafIds = (nodes: PermissionTreeNode[]) => {
|
||||
for (const node of nodes) {
|
||||
if (!node.children || node.children.length === 0) {
|
||||
leafNodeIds.add(String(node.id));
|
||||
} else {
|
||||
collectLeafIds(node.children);
|
||||
}
|
||||
}
|
||||
};
|
||||
collectLeafIds(rawApiTree.value);
|
||||
|
||||
// 从用户当前勾选的 checkedKeys 中只取叶节点 ID
|
||||
const menuIds = formData.checkedKeys.filter((key: string) => leafNodeIds.has(key));
|
||||
|
||||
props.onSave({
|
||||
roleName: formData.roleName,
|
||||
roleId: props.record?.roleId,
|
||||
// 完整选中 key 列表(含父节点),供向后兼容
|
||||
permissions: formData.checkedKeys,
|
||||
// 仅叶节点数据,后端实际需要的格式
|
||||
leafPermissions,
|
||||
isEdit,
|
||||
menuIds,
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -66,33 +66,3 @@ export function buildTreeData(apiTree: PermissionTreeNode[]): {
|
||||
const treeData = apiTree.map((node) => convertNode(node, leafKeys));
|
||||
return { treeData, checkedKeys: Array.from(leafKeys) };
|
||||
}
|
||||
|
||||
/**
|
||||
* 从后端权限树中提取叶节点数据,整理为提交格式。
|
||||
*
|
||||
* 只返回叶节点,格式为 `{ id, selected }` 数组。
|
||||
* 父节点的勾选状态由后端根据叶节点数据推导,前端不传父节点。
|
||||
*/
|
||||
export function extractLeafPermissions(
|
||||
apiTree: PermissionTreeNode[],
|
||||
): { id: number; selected: boolean }[] {
|
||||
const result: { id: number; selected: boolean }[] = [];
|
||||
|
||||
const walk = (nodes: PermissionTreeNode[]) => {
|
||||
for (const node of nodes) {
|
||||
const isLeaf = !node.children || node.children.length === 0;
|
||||
if (isLeaf) {
|
||||
result.push({
|
||||
id: node.id,
|
||||
// null 视为 false,即未授权
|
||||
selected: node.selected === true,
|
||||
});
|
||||
} else {
|
||||
walk(node.children!);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
walk(apiTree);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -3,13 +3,11 @@
|
||||
* 该页面使用的所有接口集中管理
|
||||
*/
|
||||
import { get, post } from '@/utils/request';
|
||||
import { USE_MOCK, MOCK_DELAY } from '@/config/mock';
|
||||
import { buildMockRoleListPage } from '@/config/mock/roleList';
|
||||
import { buildMockRoleUsageUserPage } from '@/config/mock/roleUsageUser';
|
||||
import { buildMockPermissionTree } from '@/config/mock/permissionTree';
|
||||
import type {
|
||||
RoleListQueryParams,
|
||||
RoleUsageUserQueryParams,
|
||||
RoleSaveParams,
|
||||
RoleUpdateParams,
|
||||
TournamentAdminRolePageVO,
|
||||
RoleUsageUserVO,
|
||||
PermissionTreeNode,
|
||||
@@ -22,6 +20,8 @@ export type {
|
||||
RoleUsageUserVO,
|
||||
RoleListQueryParams,
|
||||
RoleUsageUserQueryParams,
|
||||
RoleSaveParams,
|
||||
RoleUpdateParams,
|
||||
PermissionTreeNode,
|
||||
PageData,
|
||||
ApiResult,
|
||||
@@ -30,56 +30,49 @@ export type {
|
||||
// ============================================================
|
||||
// URL 常量
|
||||
// ============================================================
|
||||
const roleList = '/sys/role/page';
|
||||
const roleUsageUserList = '/sys/role/usageUserPage';
|
||||
const rolePermissionList = '/sys/role/permissionList';
|
||||
const roleDelete = '/sys/role/del';
|
||||
|
||||
const delay = (ms: number) => new Promise<void>((r) => setTimeout(r, ms));
|
||||
const roleList = '/admin/sys/role/page';
|
||||
const roleSave = '/admin/sys/role/save';
|
||||
const roleUpdate = '/admin/sys/role/update';
|
||||
const roleUsageUserList = '/admin/sys/role/usageUserPage';
|
||||
const rolePermissionList = '/admin/sys/role/permissionList';
|
||||
const roleDelete = '/admin/sys/role/del';
|
||||
|
||||
// ============================================================
|
||||
// API 函数
|
||||
// ============================================================
|
||||
|
||||
/** 角色列表分页 */
|
||||
export async function getRoleList(
|
||||
/** 角色列表分页 — GET /admin/sys/role/page */
|
||||
export function getRoleList(
|
||||
params: RoleListQueryParams,
|
||||
): Promise<ApiResult<PageData<TournamentAdminRolePageVO>>> {
|
||||
if (USE_MOCK) {
|
||||
await delay(MOCK_DELAY);
|
||||
const page = Number(params.page) || 1;
|
||||
const limit = Number(params.limit) || 10;
|
||||
return { code: 200, msg: 'success', data: buildMockRoleListPage(page, limit) };
|
||||
}
|
||||
return get(roleList, params as Record<string, any>);
|
||||
}
|
||||
|
||||
/** 角色下用户列表分页 */
|
||||
export async function getRoleUsageUserList(
|
||||
/** 新增角色 — POST /admin/sys/role/save */
|
||||
export function saveRole(params: RoleSaveParams): Promise<ApiResult<Record<string, never>>> {
|
||||
return post(roleSave, params);
|
||||
}
|
||||
|
||||
/** 更新角色 — POST /admin/sys/role/update */
|
||||
export function updateRole(params: RoleUpdateParams): Promise<ApiResult<Record<string, never>>> {
|
||||
return post(roleUpdate, params);
|
||||
}
|
||||
|
||||
/** 角色下用户列表分页 — GET /admin/sys/role/usageUserPage */
|
||||
export function getRoleUsageUserList(
|
||||
params: RoleUsageUserQueryParams,
|
||||
): Promise<ApiResult<PageData<RoleUsageUserVO>>> {
|
||||
if (USE_MOCK) {
|
||||
await delay(MOCK_DELAY);
|
||||
const page = Number(params.page) || 1;
|
||||
const limit = Number(params.limit) || 10;
|
||||
return { code: 200, msg: 'success', data: buildMockRoleUsageUserPage(page, limit) };
|
||||
}
|
||||
return get(roleUsageUserList, params as Record<string, any>);
|
||||
}
|
||||
|
||||
/** 角色权限树 */
|
||||
export async function getPermissionTree(
|
||||
/** 角色权限树 — GET /admin/sys/role/permissionList */
|
||||
export function getPermissionTree(
|
||||
roleId: number | string,
|
||||
): Promise<ApiResult<PermissionTreeNode[]>> {
|
||||
if (USE_MOCK) {
|
||||
await delay(MOCK_DELAY);
|
||||
const id = Number(roleId) || 0;
|
||||
return { code: 200, msg: 'success', data: buildMockPermissionTree(id) };
|
||||
}
|
||||
return get(rolePermissionList, { roleId: String(roleId) });
|
||||
}
|
||||
|
||||
/** 删除角色 */
|
||||
/** 删除角色 — POST /admin/sys/role/del */
|
||||
export function deleteRole(id: number): Promise<ApiResult<null>> {
|
||||
return post(roleDelete, { id });
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@ import { message } from 'ant-design-vue';
|
||||
import { useState, useDebounce, useThrottleFn } from '@/hooks';
|
||||
import {
|
||||
getRoleList,
|
||||
saveRole,
|
||||
updateRole,
|
||||
deleteRole,
|
||||
type TournamentAdminRolePageVO,
|
||||
type RoleListQueryParams,
|
||||
@@ -125,11 +127,29 @@ export function useRoleModel() {
|
||||
if (formSubmitting.value) return;
|
||||
setFormSubmitting(true);
|
||||
try {
|
||||
console.log(isEdit.value ? '编辑角色' : '新增角色', formPayload);
|
||||
// TODO: 替换为真实 API 调用(/sys/role/save、/sys/role/update)
|
||||
message.success(isEdit.value ? '编辑成功' : '新增成功');
|
||||
handleCloseForm();
|
||||
handleSearch();
|
||||
// menuIds 由 RoleFormModal 从用户勾选的 checkedKeys 中过滤叶节点后传入
|
||||
const menuIds: string[] = formPayload.menuIds || [];
|
||||
|
||||
let res: any;
|
||||
if (isEdit.value) {
|
||||
res = await updateRole({
|
||||
id: String(formPayload.roleId),
|
||||
name: formPayload.roleName,
|
||||
menuIds,
|
||||
});
|
||||
} else {
|
||||
res = await saveRole({
|
||||
name: formPayload.roleName,
|
||||
menuIds,
|
||||
});
|
||||
}
|
||||
if (res.code == 200) {
|
||||
message.success(isEdit.value ? '编辑成功' : '新增成功');
|
||||
handleCloseForm();
|
||||
handleSearch();
|
||||
} else {
|
||||
message.error(res.msg || '操作失败');
|
||||
}
|
||||
} catch {
|
||||
// 网络层已统一提示,不再重复 message.error
|
||||
} finally {
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
* 该页面使用的所有接口集中管理
|
||||
*/
|
||||
import { get, post } from '@/utils/request';
|
||||
import { fetchPermissions } from '@/api/menu';
|
||||
import type {
|
||||
UserListQueryParams,
|
||||
UserSaveParams,
|
||||
@@ -29,6 +28,7 @@ export type {
|
||||
// ============================================================
|
||||
// URL 常量
|
||||
// ============================================================
|
||||
const userPage = '/admin/sys/user/page';
|
||||
const userSave = '/sys/user/save';
|
||||
const userUpdate = '/sys/user/update';
|
||||
const userActive = '/sys/user/active';
|
||||
@@ -39,47 +39,14 @@ const userUpdatePwd = '/sys/user/updatepwd';
|
||||
// ============================================================
|
||||
|
||||
/**
|
||||
* 用户列表 - 通过 fetchPermissions 接口获取用户权限列表
|
||||
* 接口: GET /admin/sys/role/permissionList
|
||||
* 返回权限编码列表,前端做分页处理
|
||||
* 用户列表分页
|
||||
* 接口: GET /admin/sys/user/page
|
||||
* 参数: page, limit, text(姓名/手机号), roleId(角色ID), status(0=停用,1=正常)
|
||||
*/
|
||||
export async function getUserList(
|
||||
_params: UserListQueryParams,
|
||||
export function getUserList(
|
||||
params: UserListQueryParams,
|
||||
): Promise<ApiResult<PageData<TournamentAdminUserVO>>> {
|
||||
// 调用 fetchPermissions 获取用户权限数据
|
||||
const list = await fetchPermissions();
|
||||
|
||||
// 将权限编码字符串转为类用户列表格式,支持分页
|
||||
const page = Number(_params.page) || 1;
|
||||
const limit = Number(_params.limit) || 10;
|
||||
const start = (page - 1) * limit;
|
||||
const end = start + limit;
|
||||
const pagedList = list.slice(start, end);
|
||||
|
||||
// 将权限编码映射为用户 VO 格式(后端返回的权限码可能包含用户信息)
|
||||
const userListData: TournamentAdminUserVO[] = pagedList.map((item, index) => {
|
||||
// 如果 item 是对象则直接使用,如果是字符串则构造基本结构
|
||||
if (typeof item === 'object' && item !== null) {
|
||||
return item as unknown as TournamentAdminUserVO;
|
||||
}
|
||||
return {
|
||||
id: String(start + index + 1),
|
||||
realName: String(item),
|
||||
phone: '',
|
||||
roleName: '',
|
||||
status: '1',
|
||||
createTime: '',
|
||||
} as TournamentAdminUserVO;
|
||||
});
|
||||
|
||||
return {
|
||||
code: 200,
|
||||
msg: 'success',
|
||||
data: {
|
||||
total: list.length,
|
||||
list: userListData,
|
||||
},
|
||||
};
|
||||
return get(userPage, params as Record<string, any>);
|
||||
}
|
||||
|
||||
/** 新增用户 */
|
||||
|
||||
Reference in New Issue
Block a user