feat: tag样式优化
This commit is contained in:
@@ -0,0 +1,123 @@
|
|||||||
|
.statusTag {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 5px;
|
||||||
|
padding: 1px 8px;
|
||||||
|
border-radius: 6px;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 500;
|
||||||
|
line-height: 20px;
|
||||||
|
white-space: nowrap;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
letter-spacing: 0.2px;
|
||||||
|
|
||||||
|
&.dimmed {
|
||||||
|
opacity: 0.55;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dot {
|
||||||
|
width: 6px;
|
||||||
|
height: 6px;
|
||||||
|
border-radius: 50%;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.primary {
|
||||||
|
color: #1677ff;
|
||||||
|
background: rgba(22, 119, 255, 0.08);
|
||||||
|
border-color: rgba(22, 119, 255, 0.18);
|
||||||
|
|
||||||
|
.dot {
|
||||||
|
background: #1677ff;
|
||||||
|
box-shadow: 0 0 0 2px rgba(22, 119, 255, 0.15);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.success {
|
||||||
|
color: #389e0d;
|
||||||
|
background: rgba(82, 196, 26, 0.1);
|
||||||
|
border-color: rgba(82, 196, 26, 0.22);
|
||||||
|
|
||||||
|
.dot {
|
||||||
|
background: #52c41a;
|
||||||
|
box-shadow: 0 0 0 2px rgba(82, 196, 26, 0.15);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.warning {
|
||||||
|
color: #d48806;
|
||||||
|
background: rgba(250, 173, 20, 0.12);
|
||||||
|
border-color: rgba(250, 173, 20, 0.28);
|
||||||
|
|
||||||
|
.dot {
|
||||||
|
background: #faad14;
|
||||||
|
box-shadow: 0 0 0 2px rgba(250, 173, 20, 0.18);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.danger {
|
||||||
|
color: #cf1322;
|
||||||
|
background: rgba(255, 77, 79, 0.08);
|
||||||
|
border-color: rgba(255, 77, 79, 0.2);
|
||||||
|
|
||||||
|
.dot {
|
||||||
|
background: #ff4d4f;
|
||||||
|
box-shadow: 0 0 0 2px rgba(255, 77, 79, 0.15);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.orange {
|
||||||
|
color: #d46b08;
|
||||||
|
background: rgba(250, 140, 22, 0.1);
|
||||||
|
border-color: rgba(250, 140, 22, 0.22);
|
||||||
|
|
||||||
|
.dot {
|
||||||
|
background: #fa8c16;
|
||||||
|
box-shadow: 0 0 0 2px rgba(250, 140, 22, 0.15);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.cyan {
|
||||||
|
color: #08979c;
|
||||||
|
background: rgba(19, 194, 194, 0.1);
|
||||||
|
border-color: rgba(19, 194, 194, 0.22);
|
||||||
|
|
||||||
|
.dot {
|
||||||
|
background: #13c2c2;
|
||||||
|
box-shadow: 0 0 0 2px rgba(19, 194, 194, 0.15);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.purple {
|
||||||
|
color: #531dab;
|
||||||
|
background: rgba(114, 46, 209, 0.08);
|
||||||
|
border-color: rgba(114, 46, 209, 0.2);
|
||||||
|
|
||||||
|
.dot {
|
||||||
|
background: #722ed1;
|
||||||
|
box-shadow: 0 0 0 2px rgba(114, 46, 209, 0.15);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.neutral {
|
||||||
|
color: rgba(0, 0, 0, 0.55);
|
||||||
|
background: rgba(0, 0, 0, 0.04);
|
||||||
|
border-color: rgba(0, 0, 0, 0.08);
|
||||||
|
|
||||||
|
.dot {
|
||||||
|
background: rgba(0, 0, 0, 0.25);
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.default {
|
||||||
|
color: rgba(0, 0, 0, 0.65);
|
||||||
|
background: #fafafa;
|
||||||
|
border-color: #f0f0f0;
|
||||||
|
|
||||||
|
.dot {
|
||||||
|
background: rgba(0, 0, 0, 0.2);
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
import { defineComponent, type PropType } from 'vue';
|
||||||
|
import styles from './StatusTag.module.less';
|
||||||
|
|
||||||
|
export type StatusTagTone =
|
||||||
|
| 'primary'
|
||||||
|
| 'success'
|
||||||
|
| 'warning'
|
||||||
|
| 'danger'
|
||||||
|
| 'orange'
|
||||||
|
| 'cyan'
|
||||||
|
| 'purple'
|
||||||
|
| 'neutral'
|
||||||
|
| 'default';
|
||||||
|
|
||||||
|
const StatusTag = defineComponent({
|
||||||
|
name: 'StatusTag',
|
||||||
|
props: {
|
||||||
|
label: { type: String, required: true },
|
||||||
|
tone: { type: String as PropType<StatusTagTone>, default: 'default' },
|
||||||
|
showDot: { type: Boolean, default: true },
|
||||||
|
dimmed: { type: Boolean, default: false },
|
||||||
|
},
|
||||||
|
setup(props) {
|
||||||
|
return () => (
|
||||||
|
<span
|
||||||
|
class={[styles.statusTag, styles[props.tone], props.dimmed && styles.dimmed]
|
||||||
|
.filter(Boolean)
|
||||||
|
.join(' ')}
|
||||||
|
>
|
||||||
|
{props.showDot ? <span class={styles.dot} /> : null}
|
||||||
|
<span>{props.label}</span>
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default StatusTag;
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
export { default as StatusTag } from './StatusTag';
|
||||||
|
export type { StatusTagTone } from './StatusTag';
|
||||||
@@ -4,4 +4,6 @@
|
|||||||
*/
|
*/
|
||||||
export { default as HelloWorld } from './HelloWorld';
|
export { default as HelloWorld } from './HelloWorld';
|
||||||
export { default as ChangePasswordModal } from './ChangePasswordModal';
|
export { default as ChangePasswordModal } from './ChangePasswordModal';
|
||||||
export { default as PageTabs } from './pageTabs/PageTabs';
|
export { default as PageTabs } from './PageTabs/PageTabs';
|
||||||
|
export { StatusTag } from './StatusTag';
|
||||||
|
export type { StatusTagTone } from './StatusTag';
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ function renderBodyCell({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 跳转类型列:彩色 Tag
|
// 跳转类型列:StatusTag
|
||||||
if (column.dataIndex === 'jumpType') {
|
if (column.dataIndex === 'jumpType') {
|
||||||
return renderJumpType(text);
|
return renderJumpType(text);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { computed, reactive, toRef, Ref, h } from 'vue';
|
import { computed, reactive, toRef, Ref, h } from 'vue';
|
||||||
import { message, Tag } from 'ant-design-vue';
|
import { message } from 'ant-design-vue';
|
||||||
|
import { StatusTag, type StatusTagTone } from '@/components';
|
||||||
import { useState, useDebounce, useThrottleFn } from '@/hooks';
|
import { useState, useDebounce, useThrottleFn } from '@/hooks';
|
||||||
|
|
||||||
// ============================================================
|
// ============================================================
|
||||||
@@ -21,18 +22,18 @@ export const JUMP_TYPE_OPTIONS = [
|
|||||||
{ value: 'none', label: '无链接' },
|
{ value: 'none', label: '无链接' },
|
||||||
] as const;
|
] as const;
|
||||||
|
|
||||||
/** 跳转类型映射(用于表格 Tag 渲染) */
|
/** 跳转类型映射(用于表格 StatusTag 渲染) */
|
||||||
const JUMP_TYPE_MAP: Record<string, { label: string; color: string }> = {
|
const JUMP_TYPE_MAP: Record<string, { label: string; tone: StatusTagTone }> = {
|
||||||
event_detail: { label: '赛事详情页', color: 'blue' },
|
event_detail: { label: '赛事详情页', tone: 'primary' },
|
||||||
miniprogram_page: { label: '小程序页面', color: 'cyan' },
|
miniprogram_page: { label: '小程序页面', tone: 'cyan' },
|
||||||
custom_link: { label: '自定义链接', color: 'purple' },
|
custom_link: { label: '自定义链接', tone: 'purple' },
|
||||||
none: { label: '无链接', color: 'default' },
|
none: { label: '无链接', tone: 'default' },
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Banner 状态映射 */
|
/** Banner 状态映射 */
|
||||||
const STATUS_MAP: Record<string, { label: string; color: string }> = {
|
const STATUS_MAP: Record<string, { label: string; tone: StatusTagTone; dimmed?: boolean }> = {
|
||||||
enabled: { label: '启用中', color: 'green' },
|
enabled: { label: '启用中', tone: 'success' },
|
||||||
disabled: { label: '已禁用', color: 'default' },
|
disabled: { label: '已禁用', tone: 'default', dimmed: true },
|
||||||
};
|
};
|
||||||
|
|
||||||
/** 关联赛事选项(mock) */
|
/** 关联赛事选项(mock) */
|
||||||
@@ -153,7 +154,6 @@ export function useBannerModel() {
|
|||||||
dataIndex: 'jumpType',
|
dataIndex: 'jumpType',
|
||||||
key: 'jumpType',
|
key: 'jumpType',
|
||||||
width: 120,
|
width: 120,
|
||||||
align: 'center' as const,
|
|
||||||
},
|
},
|
||||||
{ title: '关联赛事', dataIndex: 'relatedEvent', key: 'relatedEvent', width: 200 },
|
{ title: '关联赛事', dataIndex: 'relatedEvent', key: 'relatedEvent', width: 200 },
|
||||||
{ title: '所属区域', key: 'region', width: 140 },
|
{ title: '所属区域', key: 'region', width: 140 },
|
||||||
@@ -282,18 +282,17 @@ export function useBannerModel() {
|
|||||||
|
|
||||||
// ===== 供页面 bodyCell 使用的渲染工具 =====
|
// ===== 供页面 bodyCell 使用的渲染工具 =====
|
||||||
const renderJumpType = (type: string) => {
|
const renderJumpType = (type: string) => {
|
||||||
const info = JUMP_TYPE_MAP[type] || { label: type || '-', color: 'default' };
|
const info = JUMP_TYPE_MAP[type] || { label: type || '-', tone: 'default' as const };
|
||||||
return h(Tag, { color: info.color }, () => info.label);
|
return h(StatusTag, { label: info.label, tone: info.tone });
|
||||||
};
|
};
|
||||||
|
|
||||||
const renderStatus = (status: string) => {
|
const renderStatus = (status: string) => {
|
||||||
const info = STATUS_MAP[status] || { label: status || '-', color: 'default' };
|
const info = STATUS_MAP[status] || { label: status || '-', tone: 'default' as const };
|
||||||
const tagProps: any = { color: info.color };
|
return h(StatusTag, {
|
||||||
// 已禁用状态添加半透明样式
|
label: info.label,
|
||||||
if (status === 'disabled') {
|
tone: info.tone,
|
||||||
tagProps.style = { opacity: 0.5 };
|
dimmed: info.dimmed,
|
||||||
}
|
});
|
||||||
return h(Tag, tagProps, () => info.label);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { computed, reactive, toRef, Ref, h } from 'vue';
|
import { computed, reactive, toRef, Ref, h } from 'vue';
|
||||||
import { message, Tag } from 'ant-design-vue';
|
import { message } from 'ant-design-vue';
|
||||||
|
import { StatusTag, type StatusTagTone } from '@/components';
|
||||||
import { useState, useDebounce, useThrottleFn } from '@/hooks';
|
import { useState, useDebounce, useThrottleFn } from '@/hooks';
|
||||||
|
|
||||||
// ============================================================
|
// ============================================================
|
||||||
@@ -67,12 +68,12 @@ const MOCK_DATA = Array.from({ length: 12 }, (_, i) => ({
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
/** 状态标签映射 */
|
/** 状态标签映射 */
|
||||||
const STATUS_MAP: Record<string, { label: string; color: string }> = {
|
const STATUS_MAP: Record<string, { label: string; tone: StatusTagTone }> = {
|
||||||
pending: { label: '待审核', color: 'gold' },
|
pending: { label: '待审核', tone: 'warning' },
|
||||||
enrolling: { label: '报名中', color: 'blue' },
|
enrolling: { label: '报名中', tone: 'primary' },
|
||||||
deleted: { label: '已删除', color: 'red' },
|
deleted: { label: '已删除', tone: 'neutral' },
|
||||||
removed: { label: '已下架', color: 'orange' },
|
removed: { label: '已下架', tone: 'orange' },
|
||||||
rejected: { label: '审核不通过', color: 'volcano' },
|
rejected: { label: '审核不通过', tone: 'danger' },
|
||||||
};
|
};
|
||||||
|
|
||||||
// ============================================================
|
// ============================================================
|
||||||
@@ -169,9 +170,10 @@ export function useEventListModel() {
|
|||||||
dataIndex: 'status',
|
dataIndex: 'status',
|
||||||
key: 'status',
|
key: 'status',
|
||||||
width: 90,
|
width: 90,
|
||||||
|
align: 'center' as const,
|
||||||
customRender: ({ text }: { text: string }) => {
|
customRender: ({ text }: { text: string }) => {
|
||||||
const info = STATUS_MAP[text] || { label: text, color: 'default' };
|
const info = STATUS_MAP[text] || { label: text, tone: 'default' as const };
|
||||||
return h(Tag, { color: info.color }, () => info.label);
|
return h(StatusTag, { label: info.label, tone: info.tone });
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{ title: '报名人数', dataIndex: 'enrolledCount', key: 'enrolledCount', width: 90 },
|
{ title: '报名人数', dataIndex: 'enrolledCount', key: 'enrolledCount', width: 90 },
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { defineComponent, ref, computed } from 'vue';
|
import { defineComponent, ref, computed } from 'vue';
|
||||||
import { Modal, Table, Button, Tag, Pagination, Image, Space } from 'ant-design-vue';
|
import { Modal, Table, Button, Pagination, Image, Space } from 'ant-design-vue';
|
||||||
|
import { StatusTag, type StatusTagTone } from '@/components';
|
||||||
import styles from './OrderDetailModal.module.less';
|
import styles from './OrderDetailModal.module.less';
|
||||||
|
|
||||||
interface OrderDetailModalProps {
|
interface OrderDetailModalProps {
|
||||||
@@ -69,9 +70,9 @@ const PLAYER_COLUMNS = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const REFUND_STATUS_MAP: Record<string, { label: string; color: string }> = {
|
const REFUND_STATUS_MAP: Record<string, { label: string; tone: StatusTagTone }> = {
|
||||||
success: { label: '退款成功', color: 'green' },
|
success: { label: '退款成功', tone: 'success' },
|
||||||
failed: { label: '退款失败', color: 'red' },
|
failed: { label: '退款失败', tone: 'danger' },
|
||||||
};
|
};
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
@@ -203,14 +204,14 @@ export default defineComponent({
|
|||||||
{pagedRefunds.value.map((r, idx) => {
|
{pagedRefunds.value.map((r, idx) => {
|
||||||
const statusInfo = REFUND_STATUS_MAP[r.status] || {
|
const statusInfo = REFUND_STATUS_MAP[r.status] || {
|
||||||
label: '-',
|
label: '-',
|
||||||
color: 'default',
|
tone: 'default' as const,
|
||||||
};
|
};
|
||||||
const realIdx = (refundPage.value - 1) * refundPageSize.value + idx + 1;
|
const realIdx = (refundPage.value - 1) * refundPageSize.value + idx + 1;
|
||||||
return (
|
return (
|
||||||
<div key={r.key} class={styles.refundCard}>
|
<div key={r.key} class={styles.refundCard}>
|
||||||
<div class={styles.refundCardHeader}>
|
<div class={styles.refundCardHeader}>
|
||||||
<span class={styles.refundIndex}>第{realIdx}次退款</span>
|
<span class={styles.refundIndex}>第{realIdx}次退款</span>
|
||||||
<Tag color={statusInfo.color}>{statusInfo.label}</Tag>
|
<StatusTag label={statusInfo.label} tone={statusInfo.tone} />
|
||||||
</div>
|
</div>
|
||||||
<div class={styles.refundCardBody}>
|
<div class={styles.refundCardBody}>
|
||||||
<div class={styles.refundCol}>
|
<div class={styles.refundCol}>
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { computed, reactive, toRef, Ref, h } from 'vue';
|
import { computed, reactive, toRef, Ref, h } from 'vue';
|
||||||
import { message, Tag } from 'ant-design-vue';
|
import { message } from 'ant-design-vue';
|
||||||
|
import { StatusTag, type StatusTagTone } from '@/components';
|
||||||
import { useState, useDebounce, useThrottleFn } from '@/hooks';
|
import { useState, useDebounce, useThrottleFn } from '@/hooks';
|
||||||
|
|
||||||
// ============================================================
|
// ============================================================
|
||||||
@@ -22,18 +23,18 @@ export const REFUND_STATUS_OPTIONS = [
|
|||||||
{ value: 'refund_failed', label: '退款失败' },
|
{ value: 'refund_failed', label: '退款失败' },
|
||||||
] as const;
|
] as const;
|
||||||
|
|
||||||
/** 订单状态 Tag 映射 */
|
/** 订单状态 StatusTag 映射 */
|
||||||
const ORDER_STATUS_MAP: Record<string, { label: string; color: string }> = {
|
const ORDER_STATUS_MAP: Record<string, { label: string; tone: StatusTagTone }> = {
|
||||||
paid: { label: '已支付', color: 'green' },
|
paid: { label: '已支付', tone: 'success' },
|
||||||
partial_refund: { label: '部分退款', color: 'orange' },
|
partial_refund: { label: '部分退款', tone: 'orange' },
|
||||||
full_refund: { label: '全部退款', color: 'blue' },
|
full_refund: { label: '全部退款', tone: 'primary' },
|
||||||
closed: { label: '已关闭', color: 'default' },
|
closed: { label: '已关闭', tone: 'default' },
|
||||||
};
|
};
|
||||||
|
|
||||||
/** 退款状态 Tag 映射 */
|
/** 退款状态 StatusTag 映射 */
|
||||||
const REFUND_STATUS_MAP: Record<string, { label: string; color: string }> = {
|
const REFUND_STATUS_MAP: Record<string, { label: string; tone: StatusTagTone }> = {
|
||||||
refund_success: { label: '退款成功', color: 'green' },
|
refund_success: { label: '退款成功', tone: 'success' },
|
||||||
refund_failed: { label: '退款失败', color: 'red' },
|
refund_failed: { label: '退款失败', tone: 'danger' },
|
||||||
};
|
};
|
||||||
|
|
||||||
// ============================================================
|
// ============================================================
|
||||||
@@ -254,8 +255,8 @@ export function useOrderModel() {
|
|||||||
width: 100,
|
width: 100,
|
||||||
align: 'center' as const,
|
align: 'center' as const,
|
||||||
customRender: ({ text }: { text: string }) => {
|
customRender: ({ text }: { text: string }) => {
|
||||||
const info = ORDER_STATUS_MAP[text] || { label: text || '-', color: 'default' };
|
const info = ORDER_STATUS_MAP[text] || { label: text || '-', tone: 'default' as const };
|
||||||
return h(Tag, { color: info.color }, () => info.label);
|
return h(StatusTag, { label: info.label, tone: info.tone });
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -266,8 +267,8 @@ export function useOrderModel() {
|
|||||||
align: 'center' as const,
|
align: 'center' as const,
|
||||||
customRender: ({ text }: { text: string }) => {
|
customRender: ({ text }: { text: string }) => {
|
||||||
if (!text) return h('span', '-');
|
if (!text) return h('span', '-');
|
||||||
const info = REFUND_STATUS_MAP[text] || { label: text, color: 'default' };
|
const info = REFUND_STATUS_MAP[text] || { label: text, tone: 'default' as const };
|
||||||
return h(Tag, { color: info.color }, () => info.label);
|
return h(StatusTag, { label: info.label, tone: info.tone });
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { computed, reactive, toRef, Ref, h } from 'vue';
|
import { computed, reactive, toRef, Ref, h } from 'vue';
|
||||||
import { message, Tag } from 'ant-design-vue';
|
import { message } from 'ant-design-vue';
|
||||||
|
import { StatusTag, type StatusTagTone } from '@/components';
|
||||||
import { useState, useDebounce, useThrottleFn } from '@/hooks';
|
import { useState, useDebounce, useThrottleFn } from '@/hooks';
|
||||||
|
|
||||||
// ============================================================
|
// ============================================================
|
||||||
@@ -13,10 +14,10 @@ export const USER_STATUS_OPTIONS = [
|
|||||||
{ value: 'disabled', label: '禁用' },
|
{ value: 'disabled', label: '禁用' },
|
||||||
] as const;
|
] as const;
|
||||||
|
|
||||||
/** 用户状态 Tag 映射 */
|
/** 用户状态 StatusTag 映射 */
|
||||||
const USER_STATUS_MAP: Record<string, { label: string; color: string }> = {
|
const USER_STATUS_MAP: Record<string, { label: string; tone: StatusTagTone }> = {
|
||||||
active: { label: '正常', color: 'green' },
|
active: { label: '正常', tone: 'success' },
|
||||||
disabled: { label: '禁用', color: 'red' },
|
disabled: { label: '禁用', tone: 'danger' },
|
||||||
};
|
};
|
||||||
|
|
||||||
// ============================================================
|
// ============================================================
|
||||||
@@ -94,8 +95,8 @@ export function useUserModel() {
|
|||||||
width: 90,
|
width: 90,
|
||||||
align: 'center' as const,
|
align: 'center' as const,
|
||||||
customRender: ({ text }: { text: string }) => {
|
customRender: ({ text }: { text: string }) => {
|
||||||
const info = USER_STATUS_MAP[text] || { label: text, color: 'default' };
|
const info = USER_STATUS_MAP[text] || { label: text, tone: 'default' as const };
|
||||||
return h(Tag, { color: info.color }, () => info.label);
|
return h(StatusTag, { label: info.label, tone: info.tone });
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{ title: '登录时间', dataIndex: 'loginTime', key: 'loginTime', width: 170 },
|
{ title: '登录时间', dataIndex: 'loginTime', key: 'loginTime', width: 170 },
|
||||||
|
|||||||
@@ -170,7 +170,7 @@ export default defineComponent({
|
|||||||
value={range.value}
|
value={range.value}
|
||||||
onUpdate:value={(val: string) => handleRangeChange(val)}
|
onUpdate:value={(val: string) => handleRangeChange(val)}
|
||||||
options={[...RANGE_OPTIONS]}
|
options={[...RANGE_OPTIONS]}
|
||||||
style={{ width: 120 }}
|
style={{ width: '120px' }}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { computed, reactive, toRef, Ref, h } from 'vue';
|
import { computed, reactive, toRef, Ref, h } from 'vue';
|
||||||
import { message, Tag } from 'ant-design-vue';
|
import { message } from 'ant-design-vue';
|
||||||
|
import { StatusTag, type StatusTagTone } from '@/components';
|
||||||
import { useState, useDebounce, useThrottleFn } from '@/hooks';
|
import { useState, useDebounce, useThrottleFn } from '@/hooks';
|
||||||
|
|
||||||
// ============================================================
|
// ============================================================
|
||||||
@@ -22,11 +23,11 @@ export const TRANSACTION_STATUS_OPTIONS = [
|
|||||||
{ value: '已解冻', label: '已解冻' },
|
{ value: '已解冻', label: '已解冻' },
|
||||||
] as const;
|
] as const;
|
||||||
|
|
||||||
/** 明细状态映射(用于表格 Tag 渲染) */
|
/** 明细状态映射(用于表格 StatusTag 渲染) */
|
||||||
const TRANSACTION_STATUS_MAP: Record<string, { label: string; color: string }> = {
|
const TRANSACTION_STATUS_MAP: Record<string, { label: string; tone: StatusTagTone }> = {
|
||||||
正常: { label: '正常', color: 'blue' },
|
正常: { label: '正常', tone: 'primary' },
|
||||||
冻结中: { label: '冻结中', color: 'orange' },
|
冻结中: { label: '冻结中', tone: 'orange' },
|
||||||
已解冻: { label: '已解冻', color: 'green' },
|
已解冻: { label: '已解冻', tone: 'success' },
|
||||||
};
|
};
|
||||||
|
|
||||||
// ============================================================
|
// ============================================================
|
||||||
@@ -319,10 +320,13 @@ export function useWalletModel() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/** 渲染交易状态 Tag */
|
/** 渲染交易状态 StatusTag */
|
||||||
const renderTransactionStatus = (status: string) => {
|
const renderTransactionStatus = (status: string) => {
|
||||||
const info = TRANSACTION_STATUS_MAP[status] || { label: status || '-', color: 'default' };
|
const info = TRANSACTION_STATUS_MAP[status] || {
|
||||||
return h(Tag, { color: info.color }, () => info.label);
|
label: status || '-',
|
||||||
|
tone: 'default' as const,
|
||||||
|
};
|
||||||
|
return h(StatusTag, { label: info.label, tone: info.tone });
|
||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { computed, reactive, toRef, Ref, h } from 'vue';
|
import { computed, reactive, toRef, Ref, h } from 'vue';
|
||||||
import { message, Tag } from 'ant-design-vue';
|
import { message } from 'ant-design-vue';
|
||||||
|
import { StatusTag, type StatusTagTone } from '@/components';
|
||||||
import { useState, useDebounce, useThrottleFn } from '@/hooks';
|
import { useState, useDebounce, useThrottleFn } from '@/hooks';
|
||||||
|
|
||||||
// ============================================================
|
// ============================================================
|
||||||
@@ -132,9 +133,9 @@ const MOCK_USERS: Record<string, any[]> = {
|
|||||||
// ============================================================
|
// ============================================================
|
||||||
// 状态文本/颜色映射
|
// 状态文本/颜色映射
|
||||||
// ============================================================
|
// ============================================================
|
||||||
const STATUS_MAP: Record<string, { label: string; color: string }> = {
|
const STATUS_MAP: Record<string, { label: string; tone: StatusTagTone }> = {
|
||||||
active: { label: '正常', color: 'green' },
|
active: { label: '正常', tone: 'success' },
|
||||||
disabled: { label: '禁用', color: 'red' },
|
disabled: { label: '禁用', tone: 'danger' },
|
||||||
};
|
};
|
||||||
|
|
||||||
// ============================================================
|
// ============================================================
|
||||||
@@ -288,10 +289,10 @@ export function useRoleModel() {
|
|||||||
/** 根据 roleId 获取该角色下的用户列表 */
|
/** 根据 roleId 获取该角色下的用户列表 */
|
||||||
const getRoleUsers = (roleId: string) => MOCK_USERS[roleId] || [];
|
const getRoleUsers = (roleId: string) => MOCK_USERS[roleId] || [];
|
||||||
|
|
||||||
/** 状态 Tag 渲染 */
|
/** 状态 StatusTag 渲染 */
|
||||||
const renderStatus = (status: string) => {
|
const renderStatus = (status: string) => {
|
||||||
const info = STATUS_MAP[status] || { label: status || '-', color: 'default' };
|
const info = STATUS_MAP[status] || { label: status || '-', tone: 'default' as const };
|
||||||
return h(Tag, { color: info.color }, () => info.label);
|
return h(StatusTag, { label: info.label, tone: info.tone });
|
||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { computed, reactive, toRef, Ref, h } from 'vue';
|
import { computed, reactive, toRef, Ref, h } from 'vue';
|
||||||
import { message, Tag } from 'ant-design-vue';
|
import { message } from 'ant-design-vue';
|
||||||
|
import { StatusTag, type StatusTagTone } from '@/components';
|
||||||
import { useState, useDebounce, useThrottleFn } from '@/hooks';
|
import { useState, useDebounce, useThrottleFn } from '@/hooks';
|
||||||
|
|
||||||
// ============================================================
|
// ============================================================
|
||||||
@@ -19,17 +20,17 @@ export const USER_STATUS_OPTIONS = [
|
|||||||
{ value: 'disabled', label: '禁用' },
|
{ value: 'disabled', label: '禁用' },
|
||||||
] as const;
|
] as const;
|
||||||
|
|
||||||
/** 角色文本/颜色映射(表格渲染) */
|
/** 角色文本/色调映射(表格渲染) */
|
||||||
const ROLE_MAP: Record<string, { label: string; color: string }> = {
|
const ROLE_MAP: Record<string, { label: string; tone: StatusTagTone }> = {
|
||||||
admin: { label: '管理员', color: 'blue' },
|
admin: { label: '管理员', tone: 'primary' },
|
||||||
operator: { label: '运营人员', color: 'cyan' },
|
operator: { label: '运营人员', tone: 'cyan' },
|
||||||
auditor: { label: '审核人员', color: 'purple' },
|
auditor: { label: '审核人员', tone: 'purple' },
|
||||||
};
|
};
|
||||||
|
|
||||||
/** 状态文本/颜色映射 */
|
/** 状态文本/色调映射 */
|
||||||
const STATUS_MAP: Record<string, { label: string; color: string }> = {
|
const STATUS_MAP: Record<string, { label: string; tone: StatusTagTone }> = {
|
||||||
active: { label: '正常', color: 'green' },
|
active: { label: '正常', tone: 'success' },
|
||||||
disabled: { label: '禁用', color: 'red' },
|
disabled: { label: '禁用', tone: 'danger' },
|
||||||
};
|
};
|
||||||
|
|
||||||
// ============================================================
|
// ============================================================
|
||||||
@@ -103,10 +104,9 @@ export function useUserModel() {
|
|||||||
dataIndex: 'role',
|
dataIndex: 'role',
|
||||||
key: 'role',
|
key: 'role',
|
||||||
width: 120,
|
width: 120,
|
||||||
align: 'center' as const,
|
|
||||||
customRender: ({ text }: { text: string }) => {
|
customRender: ({ text }: { text: string }) => {
|
||||||
const info = ROLE_MAP[text] || { label: text || '-', color: 'default' };
|
const info = ROLE_MAP[text] || { label: text || '-', tone: 'default' as const };
|
||||||
return h(Tag, { color: info.color }, () => info.label);
|
return h(StatusTag, { label: info.label, tone: info.tone });
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -116,8 +116,8 @@ export function useUserModel() {
|
|||||||
width: 100,
|
width: 100,
|
||||||
align: 'center' as const,
|
align: 'center' as const,
|
||||||
customRender: ({ text }: { text: string }) => {
|
customRender: ({ text }: { text: string }) => {
|
||||||
const info = STATUS_MAP[text] || { label: text || '-', color: 'default' };
|
const info = STATUS_MAP[text] || { label: text || '-', tone: 'default' as const };
|
||||||
return h(Tag, { color: info.color }, () => info.label);
|
return h(StatusTag, { label: info.label, tone: info.tone });
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{ title: '创建时间', dataIndex: 'createTime', key: 'createTime', width: 180 },
|
{ title: '创建时间', dataIndex: 'createTime', key: 'createTime', width: 180 },
|
||||||
|
|||||||
Reference in New Issue
Block a user