feat: 添加签到页面,整合用户选择和日期选择功能,支持数据过滤
This commit is contained in:
@@ -40,7 +40,7 @@ export type TableFilterColumn = {
|
|||||||
key: string;
|
key: string;
|
||||||
title: string;
|
title: string;
|
||||||
component?: Component | VNode;
|
component?: Component | VNode;
|
||||||
componentProps?: Record<string, any>;
|
componentProps?: Record<string, any> | ((form: Record<string, any>) => Record<string, any>);
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TableFilterColumns = Array<TableFilterColumn>;
|
export type TableFilterColumns = Array<TableFilterColumn>;
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ const props = withDefaults(
|
|||||||
{
|
{
|
||||||
title: '',
|
title: '',
|
||||||
showHeaderOperation: true,
|
showHeaderOperation: true,
|
||||||
|
filterColumnsCount: 4,
|
||||||
filterColumns: () => [],
|
filterColumns: () => [],
|
||||||
headerOperations: () => ({
|
headerOperations: () => ({
|
||||||
add: true,
|
add: true,
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { onMounted, ref } from 'vue';
|
import { onMounted, ref } from 'vue';
|
||||||
import { NInput } from 'naive-ui';
|
import { NInput } from 'naive-ui';
|
||||||
import type { TableFilterColumns } from '.';
|
import type { TableFilterColumn, TableFilterColumns } from '.';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
columns?: TableFilterColumns;
|
columns?: TableFilterColumns;
|
||||||
@@ -15,8 +15,22 @@ const inlineForm: Record<string, any> = {};
|
|||||||
|
|
||||||
const form = ref<Record<string, any>>({});
|
const form = ref<Record<string, any>>({});
|
||||||
|
|
||||||
|
function transformProps(col: TableFilterColumn) {
|
||||||
|
if (typeof col.componentProps === 'object') {
|
||||||
|
return col.componentProps;
|
||||||
|
} else if (typeof col.componentProps === 'function') {
|
||||||
|
return col.componentProps(form.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
props.columns?.forEach(col => {
|
props.columns?.forEach(col => {
|
||||||
|
if (col.key.includes(',')) {
|
||||||
|
col.key.split(',').forEach(k => {
|
||||||
|
inlineForm[k] = null;
|
||||||
|
form.value[k] = null;
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
inlineForm[col.key] = null;
|
inlineForm[col.key] = null;
|
||||||
form.value[col.key] = null;
|
form.value[col.key] = null;
|
||||||
});
|
});
|
||||||
@@ -41,7 +55,7 @@ function handleConfirm() {
|
|||||||
<component
|
<component
|
||||||
:is="col.component || NInput"
|
:is="col.component || NInput"
|
||||||
:value="form[col.key]"
|
:value="form[col.key]"
|
||||||
v-bind="col.componentProps"
|
v-bind="transformProps(col)"
|
||||||
@update:value="(val: any) => (form[col.key] = val)"
|
@update:value="(val: any) => (form[col.key] = val)"
|
||||||
/>
|
/>
|
||||||
</NFormItem>
|
</NFormItem>
|
||||||
|
|||||||
@@ -234,7 +234,8 @@ const local: App.I18n.Schema = {
|
|||||||
news: 'News',
|
news: 'News',
|
||||||
withdraw: 'Withdraw',
|
withdraw: 'Withdraw',
|
||||||
wallet: 'Wallet',
|
wallet: 'Wallet',
|
||||||
kyc: 'KYC'
|
kyc: 'KYC',
|
||||||
|
check: 'CheckIn'
|
||||||
},
|
},
|
||||||
page: {
|
page: {
|
||||||
login: {
|
login: {
|
||||||
|
|||||||
@@ -230,7 +230,8 @@ const local: App.I18n.Schema = {
|
|||||||
news: '新闻管理',
|
news: '新闻管理',
|
||||||
withdraw: '提现管理',
|
withdraw: '提现管理',
|
||||||
wallet: '钱包管理',
|
wallet: '钱包管理',
|
||||||
kyc: '实名管理'
|
kyc: '实名管理',
|
||||||
|
check: '签到管理'
|
||||||
},
|
},
|
||||||
page: {
|
page: {
|
||||||
login: {
|
login: {
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ export const views: Record<LastLevelRouteKey, RouteComponent | (() => Promise<Ro
|
|||||||
500: () => import("@/views/_builtin/500/index.vue"),
|
500: () => import("@/views/_builtin/500/index.vue"),
|
||||||
"iframe-page": () => import("@/views/_builtin/iframe-page/[url].vue"),
|
"iframe-page": () => import("@/views/_builtin/iframe-page/[url].vue"),
|
||||||
login: () => import("@/views/_builtin/login/index.vue"),
|
login: () => import("@/views/_builtin/login/index.vue"),
|
||||||
|
check: () => import("@/views/check/index.vue"),
|
||||||
home: () => import("@/views/home/index.vue"),
|
home: () => import("@/views/home/index.vue"),
|
||||||
kyc: () => import("@/views/kyc/index.vue"),
|
kyc: () => import("@/views/kyc/index.vue"),
|
||||||
news: () => import("@/views/news/index.vue"),
|
news: () => import("@/views/news/index.vue"),
|
||||||
|
|||||||
@@ -39,6 +39,15 @@ export const generatedRoutes: GeneratedRoute[] = [
|
|||||||
hideInMenu: true
|
hideInMenu: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'check',
|
||||||
|
path: '/check',
|
||||||
|
component: 'layout.base$view.check',
|
||||||
|
meta: {
|
||||||
|
title: 'check',
|
||||||
|
i18nKey: 'route.check'
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'home',
|
name: 'home',
|
||||||
path: '/home',
|
path: '/home',
|
||||||
|
|||||||
@@ -166,6 +166,7 @@ const routeMap: RouteMap = {
|
|||||||
"403": "/403",
|
"403": "/403",
|
||||||
"404": "/404",
|
"404": "/404",
|
||||||
"500": "/500",
|
"500": "/500",
|
||||||
|
"check": "/check",
|
||||||
"home": "/home",
|
"home": "/home",
|
||||||
"iframe-page": "/iframe-page/:url",
|
"iframe-page": "/iframe-page/:url",
|
||||||
"kyc": "/kyc",
|
"kyc": "/kyc",
|
||||||
|
|||||||
3
src/typings/elegant-router.d.ts
vendored
3
src/typings/elegant-router.d.ts
vendored
@@ -20,6 +20,7 @@ declare module "@elegant-router/types" {
|
|||||||
"403": "/403";
|
"403": "/403";
|
||||||
"404": "/404";
|
"404": "/404";
|
||||||
"500": "/500";
|
"500": "/500";
|
||||||
|
"check": "/check";
|
||||||
"home": "/home";
|
"home": "/home";
|
||||||
"iframe-page": "/iframe-page/:url";
|
"iframe-page": "/iframe-page/:url";
|
||||||
"kyc": "/kyc";
|
"kyc": "/kyc";
|
||||||
@@ -63,6 +64,7 @@ declare module "@elegant-router/types" {
|
|||||||
| "403"
|
| "403"
|
||||||
| "404"
|
| "404"
|
||||||
| "500"
|
| "500"
|
||||||
|
| "check"
|
||||||
| "home"
|
| "home"
|
||||||
| "iframe-page"
|
| "iframe-page"
|
||||||
| "kyc"
|
| "kyc"
|
||||||
@@ -93,6 +95,7 @@ declare module "@elegant-router/types" {
|
|||||||
| "500"
|
| "500"
|
||||||
| "iframe-page"
|
| "iframe-page"
|
||||||
| "login"
|
| "login"
|
||||||
|
| "check"
|
||||||
| "home"
|
| "home"
|
||||||
| "kyc"
|
| "kyc"
|
||||||
| "news"
|
| "news"
|
||||||
|
|||||||
87
src/views/check/index.vue
Normal file
87
src/views/check/index.vue
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
import { useTemplateRef } from 'vue';
|
||||||
|
import { NDatePicker } from 'naive-ui';
|
||||||
|
import dayjs from 'dayjs';
|
||||||
|
import { client, safeClient } from '@/service/api';
|
||||||
|
import type { TableBaseColumns, TableFetchData, TableFilterColumns, TableInst } from '@/components/table';
|
||||||
|
import UserSelect from '@/components/common/user-select.vue';
|
||||||
|
|
||||||
|
defineOptions({
|
||||||
|
name: 'CheckInPage'
|
||||||
|
});
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
userId: string;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const tableInst = useTemplateRef<TableInst>('tableInst');
|
||||||
|
|
||||||
|
const fetchData: TableFetchData = ({ pagination, filter }) => {
|
||||||
|
return safeClient(() => client.api.admin.checkIns.get({ query: { userId: props.userId, ...pagination, ...filter } }));
|
||||||
|
};
|
||||||
|
|
||||||
|
const columns: TableBaseColumns = [
|
||||||
|
{
|
||||||
|
key: 'userId',
|
||||||
|
title: '用户ID'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'checkInAt',
|
||||||
|
title: '签到时间',
|
||||||
|
render: (row: any) => {
|
||||||
|
return dayjs(row.checkInAt).format('YYYY-MM-DD HH:mm:ss');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
const filterColumns: TableFilterColumns = [
|
||||||
|
{
|
||||||
|
key: 'userId',
|
||||||
|
title: '用户',
|
||||||
|
component: UserSelect
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'startDate',
|
||||||
|
title: '开始日期',
|
||||||
|
component: NDatePicker,
|
||||||
|
componentProps: form => ({
|
||||||
|
clearable: true,
|
||||||
|
valueFormat: 'yyyy-MM-dd',
|
||||||
|
formattedValue: form.startDate,
|
||||||
|
onUpdateFormattedValue: val => {
|
||||||
|
form.startDate = val;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'endDate',
|
||||||
|
title: '结束日期',
|
||||||
|
component: NDatePicker,
|
||||||
|
componentProps: form => ({
|
||||||
|
clearable: true,
|
||||||
|
valueFormat: 'yyyy-MM-dd',
|
||||||
|
formattedValue: form.endDate,
|
||||||
|
onUpdateFormattedValue: val => {
|
||||||
|
form.endDate = val;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
];
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<TableBase
|
||||||
|
ref="tableInst"
|
||||||
|
:fetch-data="fetchData"
|
||||||
|
:columns="columns"
|
||||||
|
:filter-columns="filterColumns"
|
||||||
|
:scroll-x="800"
|
||||||
|
:header-operations="{
|
||||||
|
add: false,
|
||||||
|
refresh: true,
|
||||||
|
columns: true
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="css" scoped></style>
|
||||||
@@ -13,7 +13,9 @@ const props = defineProps<{
|
|||||||
|
|
||||||
const tableInst = useTemplateRef<TableInst>('tableInst');
|
const tableInst = useTemplateRef<TableInst>('tableInst');
|
||||||
const fetchData: TableFetchData = ({ pagination, filter }) => {
|
const fetchData: TableFetchData = ({ pagination, filter }) => {
|
||||||
return safeClient(() => client.api.admin.wallet.wallets.get({ query: { userId: props.userId } }));
|
return safeClient(() =>
|
||||||
|
client.api.admin.wallet.wallets.get({ query: { userId: props.userId, ...pagination, ...filter } })
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const columns: TableBaseColumns = [
|
const columns: TableBaseColumns = [
|
||||||
|
|||||||
Reference in New Issue
Block a user