mirror of
				https://github.com/yangjian102621/geekai.git
				synced 2025-11-04 16:23:42 +08:00 
			
		
		
		
	feat(ui): 新增弹窗及时间格式化
This commit is contained in:
		@@ -2,4 +2,56 @@ import { v4 as uuidV4 } from "uuid";
 | 
			
		||||
 | 
			
		||||
export const getUUID = () => {
 | 
			
		||||
  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({
 | 
			
		||||
        ...unref(params ?? {}),
 | 
			
		||||
        page: paginationState.current,
 | 
			
		||||
        pageSize: paginationState.pageSize,
 | 
			
		||||
        page_size: paginationState.pageSize,
 | 
			
		||||
      });
 | 
			
		||||
      tableState.data = (data as any)?.items;
 | 
			
		||||
      paginationState.total = (data as any)?.total;
 | 
			
		||||
 
 | 
			
		||||
@@ -5,9 +5,9 @@ import { useTableScroll } from "@/components/SearchTable/utils";
 | 
			
		||||
import { Message } from "@arco-design/web-vue";
 | 
			
		||||
import type { TableRequest, TableOriginalProps } from "./useAsyncTable";
 | 
			
		||||
 | 
			
		||||
export interface SimpleTable extends TableOriginalProps {
 | 
			
		||||
export interface SimpleTable extends /* @vue-ignore */ TableOriginalProps {
 | 
			
		||||
  request: TableRequest<Record<string, unknown>>;
 | 
			
		||||
  params: Record<string, unknown>;
 | 
			
		||||
  params?: Record<string, unknown>;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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,
 | 
			
		||||
  IconDashboard,
 | 
			
		||||
  IconOrderedList,
 | 
			
		||||
  IconCalendar,
 | 
			
		||||
} from "@arco-design/web-vue/es/icon";
 | 
			
		||||
 | 
			
		||||
const menu = [
 | 
			
		||||
@@ -32,6 +33,24 @@ const menu = [
 | 
			
		||||
    },
 | 
			
		||||
    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;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										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
 | 
			
		||||
  })
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user