mirror of
https://github.com/yangjian102621/geekai.git
synced 2025-09-17 16:56:38 +08:00
feat(ui): 新增弹窗及时间格式化
This commit is contained in:
parent
eb2658a91c
commit
ecc5a52232
@ -3,3 +3,55 @@ import { v4 as uuidV4 } from "uuid";
|
|||||||
export const getUUID = () => {
|
export const getUUID = () => {
|
||||||
return uuidV4();
|
return uuidV4();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 格式化日期
|
||||||
|
export function dateFormat(timestamp: number, format?: string) {
|
||||||
|
if (!timestamp) {
|
||||||
|
return '';
|
||||||
|
} else if (timestamp < 9680917502) {
|
||||||
|
timestamp = timestamp * 1000;
|
||||||
|
}
|
||||||
|
let year, month, day, HH, mm, ss;
|
||||||
|
let time = new Date(timestamp);
|
||||||
|
let timeDate;
|
||||||
|
year = time.getFullYear(); // 年
|
||||||
|
month = time.getMonth() + 1; // 月
|
||||||
|
day = time.getDate(); // 日
|
||||||
|
HH = time.getHours(); // 时
|
||||||
|
mm = time.getMinutes(); // 分
|
||||||
|
ss = time.getSeconds(); // 秒
|
||||||
|
|
||||||
|
month = month < 10 ? '0' + month : month;
|
||||||
|
day = day < 10 ? '0' + day : day;
|
||||||
|
HH = HH < 10 ? '0' + HH : HH; // 时
|
||||||
|
mm = mm < 10 ? '0' + mm : mm; // 分
|
||||||
|
ss = ss < 10 ? '0' + ss : ss; // 秒
|
||||||
|
|
||||||
|
switch (format) {
|
||||||
|
case 'yyyy':
|
||||||
|
timeDate = String(year);
|
||||||
|
break;
|
||||||
|
case 'yyyy-MM':
|
||||||
|
timeDate = year + '-' + month;
|
||||||
|
break;
|
||||||
|
case 'yyyy-MM-dd':
|
||||||
|
timeDate = year + '-' + month + '-' + day;
|
||||||
|
break;
|
||||||
|
case 'yyyy/MM/dd':
|
||||||
|
timeDate = year + '/' + month + '/' + day;
|
||||||
|
break;
|
||||||
|
case 'yyyy-MM-dd HH:mm:ss':
|
||||||
|
timeDate = year + '-' + month + '-' + day + ' ' + HH + ':' + mm + ':' + ss;
|
||||||
|
break;
|
||||||
|
case 'HH:mm:ss':
|
||||||
|
timeDate = HH + ':' + mm + ':' + ss;
|
||||||
|
break;
|
||||||
|
case 'MM':
|
||||||
|
timeDate = String(month);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
timeDate = year + '-' + month + '-' + day + ' ' + HH + ':' + mm + ':' + ss;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return timeDate;
|
||||||
|
}
|
@ -46,7 +46,7 @@ function useAsyncTable<T extends Record<string, unknown>>(
|
|||||||
const { data } = await request({
|
const { data } = await request({
|
||||||
...unref(params ?? {}),
|
...unref(params ?? {}),
|
||||||
page: paginationState.current,
|
page: paginationState.current,
|
||||||
pageSize: paginationState.pageSize,
|
page_size: paginationState.pageSize,
|
||||||
});
|
});
|
||||||
tableState.data = (data as any)?.items;
|
tableState.data = (data as any)?.items;
|
||||||
paginationState.total = (data as any)?.total;
|
paginationState.total = (data as any)?.total;
|
||||||
|
@ -5,9 +5,9 @@ import { useTableScroll } from "@/components/SearchTable/utils";
|
|||||||
import { Message } from "@arco-design/web-vue";
|
import { Message } from "@arco-design/web-vue";
|
||||||
import type { TableRequest, TableOriginalProps } from "./useAsyncTable";
|
import type { TableRequest, TableOriginalProps } from "./useAsyncTable";
|
||||||
|
|
||||||
export interface SimpleTable extends TableOriginalProps {
|
export interface SimpleTable extends /* @vue-ignore */ TableOriginalProps {
|
||||||
request: TableRequest<Record<string, unknown>>;
|
request: TableRequest<Record<string, unknown>>;
|
||||||
params: Record<string, unknown>;
|
params?: Record<string, unknown>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = defineProps<SimpleTable>();
|
const props = defineProps<SimpleTable>();
|
||||||
|
37
gpt-vue/projects/vue-admin/src/composables/usePopup.ts
Normal file
37
gpt-vue/projects/vue-admin/src/composables/usePopup.ts
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
import { h } from "vue";
|
||||||
|
import type { Component, ComponentInternalInstance } from "vue";
|
||||||
|
import { Modal, Drawer } from "@arco-design/web-vue";
|
||||||
|
import type { ModalConfig, DrawerConfig } from "@arco-design/web-vue";
|
||||||
|
import app from "@/main";
|
||||||
|
|
||||||
|
interface Config {
|
||||||
|
nodeProps?: (...arg: any) => Record<string, any>;
|
||||||
|
popupProps?: (
|
||||||
|
arg: any[],
|
||||||
|
exposed: () => ComponentInternalInstance["exposed"]
|
||||||
|
) => Omit<ModalConfig | DrawerConfig, "content"> & {
|
||||||
|
[key: string]: any;
|
||||||
|
};
|
||||||
|
type?: "drawer" | "modal";
|
||||||
|
}
|
||||||
|
|
||||||
|
const component = {
|
||||||
|
modal: Modal,
|
||||||
|
drawer: Drawer,
|
||||||
|
};
|
||||||
|
function usePopup(node: Component, config: Config) {
|
||||||
|
const { nodeProps, popupProps, type = "modal" } = config;
|
||||||
|
|
||||||
|
return (...arg: any[]) => {
|
||||||
|
const content = h(node, nodeProps ? nodeProps(arg) : {});
|
||||||
|
const popupNode = component[type];
|
||||||
|
// 获取全局组件的上下文
|
||||||
|
popupNode._context = app._context;
|
||||||
|
popupNode.open({
|
||||||
|
content: () => content,
|
||||||
|
...popupProps?.(arg, () => content?.component?.exposed as any),
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default usePopup;
|
@ -25,3 +25,11 @@ export const getSession = () => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
export const loginLog = (params?: Record<string, unknown>) => {
|
||||||
|
return http({
|
||||||
|
url: "/api/admin/user/loginLog",
|
||||||
|
method: "get",
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
@ -2,6 +2,7 @@ import {
|
|||||||
IconUser,
|
IconUser,
|
||||||
IconDashboard,
|
IconDashboard,
|
||||||
IconOrderedList,
|
IconOrderedList,
|
||||||
|
IconCalendar,
|
||||||
} from "@arco-design/web-vue/es/icon";
|
} from "@arco-design/web-vue/es/icon";
|
||||||
|
|
||||||
const menu = [
|
const menu = [
|
||||||
@ -32,6 +33,24 @@ const menu = [
|
|||||||
},
|
},
|
||||||
component: () => import('@/views/Order/OrderContainer.vue')
|
component: () => import('@/views/Order/OrderContainer.vue')
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/reward',
|
||||||
|
name: 'Reward',
|
||||||
|
meta: {
|
||||||
|
title: "众筹管理",
|
||||||
|
icon: IconCalendar,
|
||||||
|
},
|
||||||
|
component: () => import('@/views/Reward/RewardContainer.vue')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/loginLog',
|
||||||
|
name: 'LoginLog',
|
||||||
|
meta: {
|
||||||
|
title: "登录日志",
|
||||||
|
icon: IconCalendar,
|
||||||
|
},
|
||||||
|
component: () => import('@/views/LoginLog.vue')
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
export default menu;
|
export default menu;
|
||||||
|
29
gpt-vue/projects/vue-admin/src/views/LoginLog.vue
Normal file
29
gpt-vue/projects/vue-admin/src/views/LoginLog.vue
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
import { dateFormat } from "@gpt-vue/packages/utils";
|
||||||
|
import SearchTable from "@/components/SearchTable/SearchTable.vue";
|
||||||
|
import type { SearchTableColumns } from "@/components/SearchTable/type";
|
||||||
|
import { loginLog } from "@/http/login";
|
||||||
|
|
||||||
|
const columns: SearchTableColumns[] = [
|
||||||
|
{
|
||||||
|
dataIndex: "username",
|
||||||
|
title: "用户名",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: "login_ip",
|
||||||
|
title: "登录IP",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: "login_address",
|
||||||
|
title: "登录地址",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: "created_at",
|
||||||
|
title: "登陆时间",
|
||||||
|
render: ({ record }) => dateFormat(record.created_at),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
</script>
|
||||||
|
<template>
|
||||||
|
<SearchTable :request="loginLog" :columns="columns" />
|
||||||
|
</template>
|
@ -0,0 +1,59 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
import type { TableColumnData } from "@arco-design/web-vue";
|
||||||
|
import { dateFormat } from "@gpt-vue/packages/utils";
|
||||||
|
import SimpleTable from "@/components/SimpleTable/SimpleTable.vue";
|
||||||
|
import { getList } from "./api";
|
||||||
|
|
||||||
|
const columns: TableColumnData[] = [
|
||||||
|
{
|
||||||
|
dataIndex: "username",
|
||||||
|
title: "用户",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: "tx_id",
|
||||||
|
title: "转账单号",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: "amount",
|
||||||
|
title: "转账金额",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: "remark",
|
||||||
|
title: "备注",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: "created_at",
|
||||||
|
title: "转账时间",
|
||||||
|
render: ({ record }) => dateFormat(record.created_at),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "核销时间",
|
||||||
|
slotName: "updated_at",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "兑换详情",
|
||||||
|
slotName: "exchange",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "操作",
|
||||||
|
slotName: "actions",
|
||||||
|
fixed: "right",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
</script>
|
||||||
|
<template>
|
||||||
|
<SimpleTable :request="getList" :columns="columns">
|
||||||
|
<template #updated_at="{ record }">
|
||||||
|
<span v-if="record.status">{{ dateFormat(record.updated_at) }}</span>
|
||||||
|
<a-tag v-else>未核销</a-tag>
|
||||||
|
</template>
|
||||||
|
<template #exchange="{ record }">
|
||||||
|
<a-tag v-if="record.exchange.calls > 0"
|
||||||
|
>聊天{{ record.exchange.calls }}次</a-tag
|
||||||
|
>
|
||||||
|
<a-tag v-else-if="record.exchange.img_calls > 0"
|
||||||
|
>绘图{{ record.exchange.img_calls }}次</a-tag
|
||||||
|
>
|
||||||
|
</template>
|
||||||
|
</SimpleTable>
|
||||||
|
</template>
|
9
gpt-vue/projects/vue-admin/src/views/Reward/api.ts
Normal file
9
gpt-vue/projects/vue-admin/src/views/Reward/api.ts
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import http from "@/http/config";
|
||||||
|
|
||||||
|
export const getList = (params?: Record<string, unknown>) => {
|
||||||
|
return http({
|
||||||
|
url: "/api/admin/reward/list",
|
||||||
|
method: "get",
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user