mirror of
https://github.com/pure-admin/pure-admin-thin.git
synced 2025-04-25 16:07:19 +08:00
feat: 搜索用户和用户详情 搭建
This commit is contained in:
parent
bd060e3b15
commit
f888fe65fe
@ -1,33 +1,33 @@
|
|||||||
import { cdn } from "./cdn";
|
import { cdn } from './cdn'
|
||||||
import { resolve } from "path";
|
import { resolve } from 'path'
|
||||||
import vue from "@vitejs/plugin-vue";
|
import vue from '@vitejs/plugin-vue'
|
||||||
import { viteBuildInfo } from "./info";
|
import { viteBuildInfo } from './info'
|
||||||
import svgLoader from "vite-svg-loader";
|
import svgLoader from 'vite-svg-loader'
|
||||||
import vueJsx from "@vitejs/plugin-vue-jsx";
|
import vueJsx from '@vitejs/plugin-vue-jsx'
|
||||||
import { viteMockServe } from "vite-plugin-mock";
|
// import { viteMockServe } from 'vite-plugin-mock'
|
||||||
import { configCompressPlugin } from "./compress";
|
import { configCompressPlugin } from './compress'
|
||||||
// import ElementPlus from "unplugin-element-plus/vite";
|
// import ElementPlus from "unplugin-element-plus/vite";
|
||||||
import { visualizer } from "rollup-plugin-visualizer";
|
import { visualizer } from 'rollup-plugin-visualizer'
|
||||||
import removeConsole from "vite-plugin-remove-console";
|
import removeConsole from 'vite-plugin-remove-console'
|
||||||
import themePreprocessorPlugin from "@pureadmin/theme";
|
import themePreprocessorPlugin from '@pureadmin/theme'
|
||||||
import VueI18nPlugin from "@intlify/unplugin-vue-i18n/vite";
|
import VueI18nPlugin from '@intlify/unplugin-vue-i18n/vite'
|
||||||
import DefineOptions from "unplugin-vue-define-options/vite";
|
import DefineOptions from 'unplugin-vue-define-options/vite'
|
||||||
import { genScssMultipleScopeVars } from "../src/layout/theme";
|
import { genScssMultipleScopeVars } from '../src/layout/theme'
|
||||||
|
|
||||||
export function getPluginsList(
|
export function getPluginsList(
|
||||||
command: string,
|
command: string,
|
||||||
VITE_CDN: boolean,
|
VITE_CDN: boolean,
|
||||||
VITE_COMPRESSION: ViteCompression
|
VITE_COMPRESSION: ViteCompression
|
||||||
) {
|
) {
|
||||||
const prodMock = true;
|
const prodMock = true
|
||||||
const lifecycle = process.env.npm_lifecycle_event;
|
const lifecycle = process.env.npm_lifecycle_event
|
||||||
return [
|
return [
|
||||||
vue(),
|
vue(),
|
||||||
// https://github.com/intlify/bundle-tools/tree/main/packages/vite-plugin-vue-i18n
|
// https://github.com/intlify/bundle-tools/tree/main/packages/vite-plugin-vue-i18n
|
||||||
VueI18nPlugin({
|
VueI18nPlugin({
|
||||||
runtimeOnly: true,
|
runtimeOnly: true,
|
||||||
compositionOnly: true,
|
compositionOnly: true,
|
||||||
include: [resolve("locales/**")]
|
include: [resolve('locales/**')]
|
||||||
}),
|
}),
|
||||||
// jsx、tsx语法支持
|
// jsx、tsx语法支持
|
||||||
vueJsx(),
|
vueJsx(),
|
||||||
@ -35,7 +35,7 @@ export function getPluginsList(
|
|||||||
configCompressPlugin(VITE_COMPRESSION),
|
configCompressPlugin(VITE_COMPRESSION),
|
||||||
DefineOptions(),
|
DefineOptions(),
|
||||||
// 线上环境删除console
|
// 线上环境删除console
|
||||||
removeConsole({ external: ["src/assets/iconfont/iconfont.js"] }),
|
removeConsole({ external: ['src/assets/iconfont/iconfont.js'] }),
|
||||||
viteBuildInfo(),
|
viteBuildInfo(),
|
||||||
// 自定义主题
|
// 自定义主题
|
||||||
themePreprocessorPlugin({
|
themePreprocessorPlugin({
|
||||||
@ -48,19 +48,19 @@ export function getPluginsList(
|
|||||||
svgLoader(),
|
svgLoader(),
|
||||||
// ElementPlus({}),
|
// ElementPlus({}),
|
||||||
// mock支持
|
// mock支持
|
||||||
viteMockServe({
|
// viteMockServe({
|
||||||
mockPath: "mock",
|
// mockPath: 'mock',
|
||||||
localEnabled: command === "serve",
|
// localEnabled: command === 'serve',
|
||||||
prodEnabled: command !== "serve" && prodMock,
|
// prodEnabled: command !== 'serve' && prodMock,
|
||||||
injectCode: `
|
// injectCode: `
|
||||||
import { setupProdMockServer } from './mockProdServer';
|
// import { setupProdMockServer } from './mockProdServer';
|
||||||
setupProdMockServer();
|
// setupProdMockServer();
|
||||||
`,
|
// `,
|
||||||
logger: false
|
// logger: false
|
||||||
}),
|
// }),
|
||||||
// 打包分析
|
// 打包分析
|
||||||
lifecycle === "report"
|
lifecycle === 'report'
|
||||||
? visualizer({ open: true, brotliSize: true, filename: "report.html" })
|
? visualizer({ open: true, brotliSize: true, filename: 'report.html' })
|
||||||
: null
|
: null
|
||||||
];
|
]
|
||||||
}
|
}
|
||||||
|
@ -1,36 +1,36 @@
|
|||||||
// 根据角色动态生成路由
|
// 根据角色动态生成路由
|
||||||
import { MockMethod } from "vite-plugin-mock";
|
import { MockMethod } from 'vite-plugin-mock'
|
||||||
|
|
||||||
export default [
|
export default [
|
||||||
{
|
{
|
||||||
url: "/login",
|
url: '/login',
|
||||||
method: "post",
|
method: 'post',
|
||||||
response: ({ body }) => {
|
response: ({ body }) => {
|
||||||
if (body.username === "admin") {
|
if (body.username === 'admin') {
|
||||||
return {
|
return {
|
||||||
success: true,
|
success: true,
|
||||||
data: {
|
data: {
|
||||||
username: "admin",
|
username: 'admin',
|
||||||
// 一个用户可能有多个角色
|
// 一个用户可能有多个角色
|
||||||
roles: ["admin"],
|
roles: ['admin'],
|
||||||
accessToken: "eyJhbGciOiJIUzUxMiJ9.admin",
|
accessToken: 'eyJhbGciOiJIUzUxMiJ9.admin',
|
||||||
refreshToken: "eyJhbGciOiJIUzUxMiJ9.adminRefresh",
|
refreshToken: 'eyJhbGciOiJIUzUxMiJ9.adminRefresh',
|
||||||
expires: "2023/10/30 00:00:00"
|
expires: '2023/10/30 00:00:00'
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
} else {
|
} else {
|
||||||
return {
|
return {
|
||||||
success: true,
|
success: true,
|
||||||
data: {
|
data: {
|
||||||
username: "common",
|
username: 'common',
|
||||||
// 一个用户可能有多个角色
|
// 一个用户可能有多个角色
|
||||||
roles: ["common"],
|
roles: ['common'],
|
||||||
accessToken: "eyJhbGciOiJIUzUxMiJ9.common",
|
accessToken: 'eyJhbGciOiJIUzUxMiJ9.common',
|
||||||
refreshToken: "eyJhbGciOiJIUzUxMiJ9.commonRefresh",
|
refreshToken: 'eyJhbGciOiJIUzUxMiJ9.commonRefresh',
|
||||||
expires: "2023/10/30 00:00:00"
|
expires: '2023/10/30 00:00:00'
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
] as MockMethod[];
|
] as MockMethod[]
|
||||||
|
78
mock/playerData.ts
Normal file
78
mock/playerData.ts
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
import { MockMethod } from 'vite-plugin-mock'
|
||||||
|
|
||||||
|
export default [
|
||||||
|
{
|
||||||
|
url: '/dev-api/getCurrentDayData',
|
||||||
|
method: 'post',
|
||||||
|
response: () => {
|
||||||
|
return {
|
||||||
|
success: true,
|
||||||
|
data: [
|
||||||
|
{
|
||||||
|
active_count: 12398,
|
||||||
|
play_count: 123,
|
||||||
|
register_count: 222,
|
||||||
|
channel: 'PC',
|
||||||
|
nlh_player: 98,
|
||||||
|
plo4_player: 715,
|
||||||
|
plo5_player: 123,
|
||||||
|
plo6_player: 123
|
||||||
|
},
|
||||||
|
{
|
||||||
|
active_count: 23,
|
||||||
|
play_count: 212,
|
||||||
|
register_count: 253,
|
||||||
|
channel: 'IOS',
|
||||||
|
nlh_player: 254,
|
||||||
|
plo4_player: 2213,
|
||||||
|
plo5_player: 2123,
|
||||||
|
plo6_player: 512
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
url: '/getHistoricalData',
|
||||||
|
method: 'post',
|
||||||
|
response: () => {
|
||||||
|
return {
|
||||||
|
success: true,
|
||||||
|
data: [
|
||||||
|
{
|
||||||
|
play_account: 2132,
|
||||||
|
register_account: 232,
|
||||||
|
active_account: 2123,
|
||||||
|
channel: 'PC'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
play_account: 21232,
|
||||||
|
register_account: 12313,
|
||||||
|
active_account: 67123,
|
||||||
|
channel: 'IOS'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
url: '/snow/getUserData',
|
||||||
|
method: 'post',
|
||||||
|
response: () => {
|
||||||
|
return {
|
||||||
|
success: true,
|
||||||
|
data: [
|
||||||
|
{
|
||||||
|
username: 2132,
|
||||||
|
club_name: '12123',
|
||||||
|
channel: 'PC',
|
||||||
|
mobile: 'P123123213123',
|
||||||
|
area: 'beijing',
|
||||||
|
last_login_date: '2023/12/12',
|
||||||
|
last_area: 'beijing'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
] as MockMethod[]
|
@ -1,27 +1,27 @@
|
|||||||
import { MockMethod } from "vite-plugin-mock";
|
import { MockMethod } from 'vite-plugin-mock'
|
||||||
|
|
||||||
// 模拟刷新token接口
|
// 模拟刷新token接口
|
||||||
export default [
|
export default [
|
||||||
{
|
{
|
||||||
url: "/refreshToken",
|
url: '/refreshToken',
|
||||||
method: "post",
|
method: 'post',
|
||||||
response: ({ body }) => {
|
response: ({ body }) => {
|
||||||
if (body.refreshToken) {
|
if (body.refreshToken) {
|
||||||
return {
|
return {
|
||||||
success: true,
|
success: true,
|
||||||
data: {
|
data: {
|
||||||
accessToken: "eyJhbGciOiJIUzUxMiJ9.newAdmin",
|
accessToken: 'eyJhbGciOiJIUzUxMiJ9.newAdmin',
|
||||||
refreshToken: "eyJhbGciOiJIUzUxMiJ9.newAdminRefresh",
|
refreshToken: 'eyJhbGciOiJIUzUxMiJ9.newAdminRefresh',
|
||||||
// `expires`选择这种日期格式是为了方便调试,后端直接设置时间戳或许更方便(每次都应该递增)。如果后端返回的是时间戳格式,前端开发请来到这个目录`src/utils/auth.ts`,把第`38`行的代码换成expires = data.expires即可。
|
// `expires`选择这种日期格式是为了方便调试,后端直接设置时间戳或许更方便(每次都应该递增)。如果后端返回的是时间戳格式,前端开发请来到这个目录`src/utils/auth.ts`,把第`38`行的代码换成expires = data.expires即可。
|
||||||
expires: "2023/10/30 23:59:59"
|
expires: '2023/10/30 23:59:59'
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
} else {
|
} else {
|
||||||
return {
|
return {
|
||||||
success: false,
|
success: false,
|
||||||
data: {}
|
data: {}
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
] as MockMethod[];
|
] as MockMethod[]
|
||||||
|
1335
pnpm-lock.yaml
generated
1335
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
77
src/api/basic.ts
Normal file
77
src/api/basic.ts
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
import { http } from '@/utils/http'
|
||||||
|
import { baseUrlApi } from './utils'
|
||||||
|
|
||||||
|
export type UserResult = {
|
||||||
|
success: boolean
|
||||||
|
data: {
|
||||||
|
/** 用户名 */
|
||||||
|
username: string
|
||||||
|
/** 当前登陆用户的角色 */
|
||||||
|
roles: Array<string>
|
||||||
|
/** `token` */
|
||||||
|
accessToken: string
|
||||||
|
/** 用于调用刷新`accessToken`的接口时所需的`token` */
|
||||||
|
refreshToken: string
|
||||||
|
/** `accessToken`的过期时间(格式'xxxx/xx/xx xx:xx:xx') */
|
||||||
|
expires: Date
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 不同渠道下的各维度数据
|
||||||
|
interface dailyData {
|
||||||
|
active_count: number
|
||||||
|
play_count: number
|
||||||
|
register_count: number
|
||||||
|
channel: string
|
||||||
|
nlh_player: number
|
||||||
|
plo4_player: number
|
||||||
|
plo5_player: number
|
||||||
|
plo6_player: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export type CurrentDayData = {
|
||||||
|
success: boolean
|
||||||
|
data: Array<dailyData>
|
||||||
|
}
|
||||||
|
|
||||||
|
interface OHistoricalData {
|
||||||
|
play_account: number
|
||||||
|
register_account: number
|
||||||
|
active_account: number
|
||||||
|
channel: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type HistoricalData = {
|
||||||
|
success: boolean
|
||||||
|
data: Array<OHistoricalData>
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 当日用户数据 */
|
||||||
|
// export const getCurrentDayData = (data?: object) => {
|
||||||
|
// return http.request<CurrentDayData>('post', '/getCurrentDayData', { data })
|
||||||
|
// }
|
||||||
|
|
||||||
|
export const getCurrentDayData = (data?: object) => {
|
||||||
|
return http.request<any>('post', baseUrlApi('/cms/user/dataset/today'), {
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 历史用户数据 */
|
||||||
|
export const getHistoricalData = (data?: object) => {
|
||||||
|
console.log('api', data)
|
||||||
|
return http.request<HistoricalData>(
|
||||||
|
'post',
|
||||||
|
baseUrlApi('/cms/user/dataset/history'),
|
||||||
|
{
|
||||||
|
data
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 搜索用户 */
|
||||||
|
export const getUserData = (data?: object) => {
|
||||||
|
return http.request<HistoricalData>('post', baseUrlApi('/cms/user/list'), {
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
1
src/api/utils.ts
Normal file
1
src/api/utils.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export const baseUrlApi = (url: string) => `/dev-api${url}`
|
11
src/main.ts
11
src/main.ts
@ -9,7 +9,7 @@ import { MotionPlugin } from '@vueuse/motion'
|
|||||||
// import { useEcharts } from "@/plugins/echarts";
|
// import { useEcharts } from "@/plugins/echarts";
|
||||||
import { injectResponsiveStorage } from '@/utils/responsive'
|
import { injectResponsiveStorage } from '@/utils/responsive'
|
||||||
|
|
||||||
// import Table from "@pureadmin/table";
|
import Table from '@pureadmin/table'
|
||||||
// import PureDescriptions from "@pureadmin/descriptions";
|
// import PureDescriptions from "@pureadmin/descriptions";
|
||||||
|
|
||||||
// 引入重置样式
|
// 引入重置样式
|
||||||
@ -50,9 +50,12 @@ getServerConfig(app).then(async config => {
|
|||||||
await router.isReady()
|
await router.isReady()
|
||||||
injectResponsiveStorage(app, config)
|
injectResponsiveStorage(app, config)
|
||||||
setupStore(app)
|
setupStore(app)
|
||||||
app.use(MotionPlugin).use(useI18n).use(ElementPlus)
|
app
|
||||||
// .use(useEcharts);
|
.use(MotionPlugin)
|
||||||
// .use(Table);
|
.use(useI18n)
|
||||||
|
.use(ElementPlus)
|
||||||
|
// .use(useEcharts);
|
||||||
|
.use(Table)
|
||||||
// .use(PureDescriptions);
|
// .use(PureDescriptions);
|
||||||
app.mount('#app')
|
app.mount('#app')
|
||||||
})
|
})
|
||||||
|
@ -6,47 +6,58 @@ export default {
|
|||||||
redirect: '/basic/liveData',
|
redirect: '/basic/liveData',
|
||||||
meta: {
|
meta: {
|
||||||
title: $t('menus.basicData'),
|
title: $t('menus.basicData'),
|
||||||
icon: 'lineChartLine'
|
icon: 'lineChartLine',
|
||||||
|
rank: 6
|
||||||
},
|
},
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: '/basic/liveData',
|
path: '/basic/liveData',
|
||||||
name: 'LiveData',
|
name: 'LiveData',
|
||||||
component: () => import('@/views/basicData/LiveData.vue'),
|
component: () => import('@/views/basic/LiveData.vue'),
|
||||||
meta: {
|
meta: {
|
||||||
title: $t('menus.liveData'),
|
title: $t('menus.liveData'),
|
||||||
roles: ['admin']
|
roles: ['admin']
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
path: '/basic/liveData2',
|
|
||||||
name: 'LiveData2',
|
|
||||||
component: () => import('@/views/basicData/LiveData.vue'),
|
|
||||||
meta: {
|
|
||||||
title: '测试2',
|
|
||||||
roles: ['admin1']
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
path: '/basic/userData',
|
path: '/basic/userData',
|
||||||
name: 'UserData',
|
name: 'UserData',
|
||||||
component: () => import('@/views/basicData/queryUser/index.vue'),
|
component: () => import('@/views/basic/queryUser/index.vue'),
|
||||||
meta: {
|
meta: {
|
||||||
title: $t('menus.userData')
|
title: $t('menus.userData')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
path: '/basic/queryUser',
|
path: '/basic/queryUser',
|
||||||
name: 'QueryUser',
|
name: 'QueryUser',
|
||||||
component: () => import('@/views/basicData/queryUser/queryUser.vue'),
|
component: () => import('@/views/basic/queryUser/queryUser.vue'),
|
||||||
meta: {
|
meta: {
|
||||||
title: $t('menus.searchUser')
|
title: $t('menus.searchUser')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/basic/queryUser/users/:id',
|
||||||
|
name: 'UserInfo',
|
||||||
|
component: () => import('@/views/basic/queryUser/user/index.vue'),
|
||||||
|
meta: {
|
||||||
|
title: '用户信息',
|
||||||
|
showLink: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/basic/queryUser/users/:id/basicInfo',
|
||||||
|
name: 'UserBasicInfo',
|
||||||
|
component: () => import('@/views/basic/queryUser/user/basicInfo.vue'),
|
||||||
|
meta: {
|
||||||
|
title: '基础信息',
|
||||||
|
showLink: false
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '/basic/gameData',
|
path: '/basic/gameData',
|
||||||
name: 'GameData',
|
name: 'GameData',
|
||||||
component: () => import('@/views/basicData/GameData.vue'),
|
component: () => import('@/views/basic/GameData.vue'),
|
||||||
meta: {
|
meta: {
|
||||||
title: $t('menus.gameData')
|
title: $t('menus.gameData')
|
||||||
}
|
}
|
||||||
@ -54,7 +65,7 @@ export default {
|
|||||||
{
|
{
|
||||||
path: '/basic/clubData',
|
path: '/basic/clubData',
|
||||||
name: 'ClubData',
|
name: 'ClubData',
|
||||||
component: () => import('@/views/basicData/queryClub/index.vue'),
|
component: () => import('@/views/basic/queryClub/index.vue'),
|
||||||
meta: {
|
meta: {
|
||||||
title: $t('menus.clubData')
|
title: $t('menus.clubData')
|
||||||
}
|
}
|
||||||
@ -62,7 +73,7 @@ export default {
|
|||||||
{
|
{
|
||||||
path: '/basic/queryClub',
|
path: '/basic/queryClub',
|
||||||
name: 'QueryData',
|
name: 'QueryData',
|
||||||
component: () => import('@/views/basicData/queryClub/queryClub.vue'),
|
component: () => import('@/views/basic/queryClub/queryClub.vue'),
|
||||||
meta: {
|
meta: {
|
||||||
title: $t('menus.searchClub')
|
title: $t('menus.searchClub')
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,58 @@ const IFrame = () => import('@/layout/frameView.vue')
|
|||||||
const modulesRoutes = import.meta.glob('/src/views/**/*.{vue,tsx}')
|
const modulesRoutes = import.meta.glob('/src/views/**/*.{vue,tsx}')
|
||||||
|
|
||||||
// 动态路由
|
// 动态路由
|
||||||
import { getAsyncRoutes, getAsyncPath } from '@/api/routes'
|
// import { getAsyncRoutes, getAsyncPath } from '@/api/routes'
|
||||||
|
|
||||||
|
// start 只使用静态路由
|
||||||
|
const permissionRouter = {
|
||||||
|
path: '/permission',
|
||||||
|
meta: {
|
||||||
|
title: 'menus.permission',
|
||||||
|
icon: 'informationLine',
|
||||||
|
rank: 99
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: '/permission/page/index',
|
||||||
|
name: 'PermissionPage',
|
||||||
|
meta: {
|
||||||
|
title: 'menus.permissionPage',
|
||||||
|
roles: ['admin', 'common']
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/permission/button/index',
|
||||||
|
name: 'PermissionButton',
|
||||||
|
meta: {
|
||||||
|
title: 'menus.permissionButton',
|
||||||
|
roles: ['admin', 'common'],
|
||||||
|
auths: ['btn_add', 'btn_edit', 'btn_delete']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
const permissionPath = {
|
||||||
|
page: [
|
||||||
|
'/permission',
|
||||||
|
'/permission/page/index',
|
||||||
|
'/permission/button/index',
|
||||||
|
|
||||||
|
'/finance',
|
||||||
|
'/finance/diamondData'
|
||||||
|
],
|
||||||
|
btn: ['btn-edit', 'edit-create']
|
||||||
|
}
|
||||||
|
function getAsyncRoutes() {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
resolve({ data: [permissionRouter] })
|
||||||
|
})
|
||||||
|
}
|
||||||
|
function getAsyncPath() {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
resolve({ data: permissionPath })
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// end 只使用静态路由
|
||||||
|
|
||||||
// 本地fake的动态路由
|
// 本地fake的动态路由
|
||||||
import localFullRouter from './localRouter'
|
import localFullRouter from './localRouter'
|
||||||
@ -390,6 +441,10 @@ function hasAuth(value: string | Array<string>): boolean {
|
|||||||
: isIncludeAllChildren(value, metaAuths)
|
: isIncludeAllChildren(value, metaAuths)
|
||||||
return isAuths ? true : false
|
return isAuths ? true : false
|
||||||
}
|
}
|
||||||
|
export const baseUrlApi = (url: string) =>
|
||||||
|
process.env.NODE_ENV === 'development'
|
||||||
|
? `/api/${url}`
|
||||||
|
: `http://192.168.100.87:8000/${url}`
|
||||||
|
|
||||||
export {
|
export {
|
||||||
hasAuth,
|
hasAuth,
|
||||||
|
@ -3,24 +3,81 @@ import Axios, {
|
|||||||
AxiosRequestConfig,
|
AxiosRequestConfig,
|
||||||
CustomParamsSerializer
|
CustomParamsSerializer
|
||||||
} from 'axios'
|
} from 'axios'
|
||||||
|
import Qs from 'qs'
|
||||||
import {
|
import {
|
||||||
PureHttpError,
|
PureHttpError,
|
||||||
RequestMethods,
|
RequestMethods,
|
||||||
PureHttpResponse,
|
PureHttpResponse,
|
||||||
PureHttpRequestConfig
|
PureHttpRequestConfig
|
||||||
} from './types.d'
|
} from './types.d'
|
||||||
import { stringify } from 'qs'
|
|
||||||
import NProgress from '../progress'
|
import NProgress from '../progress'
|
||||||
import { getToken, formatToken } from '@/utils/auth'
|
import { getToken, formatToken } from '@/utils/auth'
|
||||||
import { useUserStoreHook } from '@/store/modules/user'
|
import { useUserStoreHook } from '@/store/modules/user'
|
||||||
|
|
||||||
|
function urlEncodeString(data) {
|
||||||
|
let str = data
|
||||||
|
if (
|
||||||
|
data.indexOf('#') != -1 ||
|
||||||
|
data.indexOf('+') != -1 ||
|
||||||
|
data.indexOf('/') != -1 ||
|
||||||
|
data.indexOf('?') != -1 ||
|
||||||
|
data.indexOf('%') != -1 ||
|
||||||
|
data.indexOf('&') != -1 ||
|
||||||
|
data.indexOf('=') != -1
|
||||||
|
) {
|
||||||
|
str = data.replace(/([\#|\+|\/|\?|\%|\#|\&|\=])/g, $1 => {
|
||||||
|
return encodeURIComponent($1)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return str
|
||||||
|
}
|
||||||
|
function stringify(data) {
|
||||||
|
let ret = ''
|
||||||
|
for (const it in data) {
|
||||||
|
ret += encodeURIComponent(it) + '=' + encodeURIComponent(data[it]) + '&'
|
||||||
|
}
|
||||||
|
ret = ret.substring(0, ret.lastIndexOf('&'))
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
// 相关配置请参考:www.axios-js.com/zh-cn/docs/#axios-request-config-1
|
// 相关配置请参考:www.axios-js.com/zh-cn/docs/#axios-request-config-1
|
||||||
const defaultConfig: AxiosRequestConfig = {
|
const defaultConfig: AxiosRequestConfig = {
|
||||||
|
transformRequest: [
|
||||||
|
function (data) {
|
||||||
|
// 对 data 进行任意转换处理
|
||||||
|
// data = http.getPostData(data)
|
||||||
|
data = {
|
||||||
|
sig: '681d66eda1b3df8b7b6641e4864452d7',
|
||||||
|
accesstoken: '',
|
||||||
|
cmd_id: 0,
|
||||||
|
extend: {
|
||||||
|
net: 'wifi',
|
||||||
|
device: 'huaweiP10',
|
||||||
|
macid: '12bb540d5f56add5c7a176c36b339ed7',
|
||||||
|
tz_name: 'Asia%2FShanghai',
|
||||||
|
tz_delta: 'GMT%2B8'
|
||||||
|
},
|
||||||
|
request: { method: 'sysversion%23getsysversion' },
|
||||||
|
public: {
|
||||||
|
channel: 'POKIO_H5_NORMAL',
|
||||||
|
version: 1311,
|
||||||
|
packid: 200,
|
||||||
|
lang: 'tw'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
data = { postdata: urlEncodeString(JSON.stringify(data)) }
|
||||||
|
// data = { postdata: JSON.stringify(data) }
|
||||||
|
|
||||||
|
return Qs.stringify(data)
|
||||||
|
// return stringify(data)
|
||||||
|
}
|
||||||
|
],
|
||||||
// 请求超时时间
|
// 请求超时时间
|
||||||
timeout: 10000,
|
timeout: 10000,
|
||||||
headers: {
|
headers: {
|
||||||
Accept: 'application/json, text/plain, */*',
|
Accept: 'application/json, text/plain, */*',
|
||||||
'Content-Type': 'application/json',
|
// 'Content-Type': 'application/json',
|
||||||
'X-Requested-With': 'XMLHttpRequest'
|
'X-Requested-With': 'XMLHttpRequest'
|
||||||
},
|
},
|
||||||
// 数组格式参数序列化(https://github.com/axios/axios/issues/5142)
|
// 数组格式参数序列化(https://github.com/axios/axios/issues/5142)
|
||||||
|
@ -1,10 +1,67 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import { useRenderIcon } from '@/components/ReIcon/src/hooks'
|
||||||
|
import Search from '@iconify-icons/ep/search'
|
||||||
|
// import Refresh from '@iconify-icons/ep/refresh'
|
||||||
|
import { useUser } from './indexHook'
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
// name 作为一种规范最好必须写上并且和路由的name保持一致
|
// name 作为一种规范最好必须写上并且和路由的name保持一致
|
||||||
name: 'UserData'
|
name: 'UserData'
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const formRef = ref()
|
||||||
|
const {
|
||||||
|
form,
|
||||||
|
currentDayData,
|
||||||
|
historicalData,
|
||||||
|
currentDayColumns,
|
||||||
|
historicalColumns,
|
||||||
|
loading,
|
||||||
|
onSearchHistory
|
||||||
|
} = useUser()
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<h1>用户数据</h1>
|
<el-card shadow="never" class="card1">
|
||||||
|
<template #header>
|
||||||
|
<div class="card-header">
|
||||||
|
<span class="font-medium"> 今日数据 </span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<pure-table :data="currentDayData" :columns="currentDayColumns" border />
|
||||||
|
<el-divider />
|
||||||
|
<p class="card-header font-bold pb-5">历史数据</p>
|
||||||
|
<div class="w-[81%]">
|
||||||
|
<el-form
|
||||||
|
ref="formRef"
|
||||||
|
:inline="true"
|
||||||
|
:model="form"
|
||||||
|
class="bg-bg_color w-[99/100]"
|
||||||
|
>
|
||||||
|
<el-form-item prop="date">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="form.dateRange"
|
||||||
|
type="daterange"
|
||||||
|
range-separator="To"
|
||||||
|
start-placeholder="Start date"
|
||||||
|
end-placeholder="End date"
|
||||||
|
format="YYYY/MM/DD"
|
||||||
|
value-format="x"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
:icon="useRenderIcon(Search)"
|
||||||
|
:loading="loading"
|
||||||
|
@click="onSearchHistory"
|
||||||
|
>
|
||||||
|
搜索
|
||||||
|
</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</div>
|
||||||
|
<pure-table :data="historicalData" :columns="historicalColumns" border />
|
||||||
|
</el-card>
|
||||||
</template>
|
</template>
|
||||||
|
105
src/views/basic/queryUser/indexHook.ts
Normal file
105
src/views/basic/queryUser/indexHook.ts
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
import { ref, reactive, onMounted } from 'vue'
|
||||||
|
|
||||||
|
import { getCurrentDayData, getHistoricalData } from '@/api/basic'
|
||||||
|
|
||||||
|
export function useUser() {
|
||||||
|
const currentDayColumns: TableColumnList = [
|
||||||
|
{
|
||||||
|
label: '渠道',
|
||||||
|
prop: 'channel'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '在线用户数量',
|
||||||
|
prop: 'active_count'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '在玩用户数量',
|
||||||
|
prop: 'play_count'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '当日注册',
|
||||||
|
prop: 'register_count'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'NLH在玩',
|
||||||
|
prop: 'nlh_player'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'PLO4',
|
||||||
|
prop: 'nlh_player'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'PLO4',
|
||||||
|
prop: 'nlh_player'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'PLO4',
|
||||||
|
prop: 'nlh_player'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
const historicalColumns: TableColumnList = [
|
||||||
|
{
|
||||||
|
label: '渠道',
|
||||||
|
prop: 'channel'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '在线用户数量',
|
||||||
|
prop: 'active_count'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '在玩用户数量',
|
||||||
|
prop: 'play_count'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '当日注册',
|
||||||
|
prop: 'register_count'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
const form = reactive({
|
||||||
|
dateRange: ''
|
||||||
|
})
|
||||||
|
|
||||||
|
const currentDayData = ref([])
|
||||||
|
const historicalData = ref([])
|
||||||
|
const loading = ref(true)
|
||||||
|
|
||||||
|
function onSearchToday() {
|
||||||
|
getCurrentDayData().then(res => {
|
||||||
|
currentDayData.value = res.data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
function onSearchHistory() {
|
||||||
|
console.log('onSearchHistory1', form.dateRange)
|
||||||
|
console.log('onSearchHistory2', form.dateRange[0])
|
||||||
|
getHistoricalData({
|
||||||
|
start_date: form.dateRange[0],
|
||||||
|
end_date: form.dateRange[1]
|
||||||
|
}).then(res => {
|
||||||
|
historicalData.value = res.data
|
||||||
|
loading.value = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// const resetHistoryForm = formEl => {
|
||||||
|
// if (!formEl) return
|
||||||
|
// formEl.resetFields()
|
||||||
|
// onSearchHistory()
|
||||||
|
// }
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
onSearchToday()
|
||||||
|
onSearchHistory()
|
||||||
|
})
|
||||||
|
|
||||||
|
return {
|
||||||
|
form,
|
||||||
|
currentDayData,
|
||||||
|
historicalData,
|
||||||
|
currentDayColumns,
|
||||||
|
historicalColumns,
|
||||||
|
loading,
|
||||||
|
onSearchHistory
|
||||||
|
// resetHistoryForm
|
||||||
|
}
|
||||||
|
}
|
54
src/views/basic/queryUser/infoHook.ts
Normal file
54
src/views/basic/queryUser/infoHook.ts
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
import { useMultiTagsStoreHook } from '@/store/modules/multiTags'
|
||||||
|
import { useRouter, useRoute } from 'vue-router'
|
||||||
|
import { onBeforeMount } from 'vue'
|
||||||
|
|
||||||
|
export function useDetail() {
|
||||||
|
const route = useRoute()
|
||||||
|
const router = useRouter()
|
||||||
|
const id = route.query?.id ? route.query?.id : route.params?.id
|
||||||
|
|
||||||
|
function toDetail(
|
||||||
|
index: number | string | string[] | number[],
|
||||||
|
model: string
|
||||||
|
) {
|
||||||
|
if (model === 'query') {
|
||||||
|
// 保存信息到标签页
|
||||||
|
useMultiTagsStoreHook().handleTags('push', {
|
||||||
|
path: `/basic/queryUser/users/`,
|
||||||
|
name: 'UserInfo',
|
||||||
|
query: { id: String(index) },
|
||||||
|
meta: {
|
||||||
|
title: {
|
||||||
|
zh: `No.${index} - 详情信息`,
|
||||||
|
en: `No.${index} - DetailInfo`
|
||||||
|
},
|
||||||
|
// 最大打开标签数
|
||||||
|
dynamicLevel: 3
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// 路由跳转
|
||||||
|
router.push({ name: 'TabQueryDetail', query: { id: String(index) } })
|
||||||
|
} else {
|
||||||
|
useMultiTagsStoreHook().handleTags('push', {
|
||||||
|
path: `/basic/queryUser/users/:id`,
|
||||||
|
name: 'UserInfo',
|
||||||
|
params: { id: String(index) },
|
||||||
|
meta: {
|
||||||
|
title: {
|
||||||
|
zh: `No.${index} - 详情信息`,
|
||||||
|
en: `No.${index} - DetailInfo`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
router.push({ name: 'UserInfo', params: { id: String(index) } })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function initToDetail(model) {
|
||||||
|
onBeforeMount(() => {
|
||||||
|
if (id) toDetail(id, model)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return { toDetail, initToDetail, id, router }
|
||||||
|
}
|
@ -1,10 +1,100 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import { useRenderIcon } from '@/components/ReIcon/src/hooks'
|
||||||
|
import Search from '@iconify-icons/ep/search'
|
||||||
|
// import Refresh from '@iconify-icons/ep/refresh'
|
||||||
|
import { useUser } from './queryUserHook'
|
||||||
|
import { useDetail } from './infoHook'
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
// name 作为一种规范最好必须写上并且和路由的name保持一致
|
// name 作为一种规范最好必须写上并且和路由的name保持一致
|
||||||
name: 'QueryUser'
|
name: 'QueryUser'
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const { toDetail, router } = useDetail()
|
||||||
|
|
||||||
|
const formRef = ref()
|
||||||
|
const { form, historicalData, historicalColumns, loading, onSearchUser } =
|
||||||
|
useUser()
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<h1>查询用户</h1>
|
<el-card shadow="never" class="card1">
|
||||||
|
<template #header>
|
||||||
|
<div class="card-header">
|
||||||
|
<span class="font-medium"> 搜索用户 </span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<div>
|
||||||
|
<el-form
|
||||||
|
ref="formRef"
|
||||||
|
:inline="true"
|
||||||
|
:model="form"
|
||||||
|
class="bg-bg_color w-[99/100]"
|
||||||
|
>
|
||||||
|
<el-form-item prop="username">
|
||||||
|
<el-input
|
||||||
|
v-model="form.username"
|
||||||
|
placeholder="用户名"
|
||||||
|
clearable
|
||||||
|
class="!w-[160px]"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item prop="mobile">
|
||||||
|
<el-input
|
||||||
|
v-model="form.mobile"
|
||||||
|
placeholder="手机号码"
|
||||||
|
clearable
|
||||||
|
class="!w-[160px]"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item prop="email">
|
||||||
|
<el-input
|
||||||
|
v-model="form.email"
|
||||||
|
placeholder="邮箱"
|
||||||
|
clearable
|
||||||
|
class="!w-[200px]"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item prop="dateRange">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="form.dateRange"
|
||||||
|
type="daterange"
|
||||||
|
range-separator="To"
|
||||||
|
start-placeholder="Start date"
|
||||||
|
end-placeholder="End date"
|
||||||
|
format="YYYY/MM/DD"
|
||||||
|
value-format="YYYY-MM-DD"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
:icon="useRenderIcon(Search)"
|
||||||
|
:loading="loading"
|
||||||
|
@click="onSearchUser"
|
||||||
|
>
|
||||||
|
搜索
|
||||||
|
</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</div>
|
||||||
|
<pure-table :data="historicalData" :columns="historicalColumns" border />
|
||||||
|
<!-- <el-button>
|
||||||
|
<router-link :to="{ name: 'UserInfo', params: { id: 12318 } }"
|
||||||
|
>User</router-link
|
||||||
|
>
|
||||||
|
</el-button> -->
|
||||||
|
<div class="flex flex-wrap items-center">
|
||||||
|
<p>params传参模式:</p>
|
||||||
|
<el-button
|
||||||
|
class="m-2"
|
||||||
|
v-for="index in 6"
|
||||||
|
:key="index"
|
||||||
|
@click="toDetail(index, 'params')"
|
||||||
|
>
|
||||||
|
打开{{ index }}详情页
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</el-card>
|
||||||
</template>
|
</template>
|
||||||
|
74
src/views/basic/queryUser/queryUserHook.ts
Normal file
74
src/views/basic/queryUser/queryUserHook.ts
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
import { ref, reactive, onMounted } from 'vue'
|
||||||
|
|
||||||
|
import { getUserData } from '@/api/basic'
|
||||||
|
|
||||||
|
export function useUser() {
|
||||||
|
const historicalColumns: TableColumnList = [
|
||||||
|
{
|
||||||
|
label: '用户名',
|
||||||
|
prop: 'user_name'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '所属俱乐部',
|
||||||
|
prop: 'club_name'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '注册渠道',
|
||||||
|
prop: 'register_channel'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '绑定手机/邮箱',
|
||||||
|
prop: 'mobile'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '注册IP及归属地',
|
||||||
|
prop: 'reg_ip'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '最后登录',
|
||||||
|
prop: 'last_login_date'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '最后登录IP及归属地',
|
||||||
|
prop: 'last_area'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
const form = reactive({
|
||||||
|
username: '',
|
||||||
|
mobile: '',
|
||||||
|
email: '',
|
||||||
|
dateRange: ''
|
||||||
|
})
|
||||||
|
|
||||||
|
const historicalData = ref([])
|
||||||
|
const loading = ref(true)
|
||||||
|
|
||||||
|
function onSearchUser() {
|
||||||
|
console.log(form.dateRange)
|
||||||
|
console.log(form.dateRange[0])
|
||||||
|
getUserData({ date: form }).then(res => {
|
||||||
|
historicalData.value = res.data
|
||||||
|
loading.value = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// const resetHistoryForm = formEl => {
|
||||||
|
// if (!formEl) return
|
||||||
|
// formEl.resetFields()
|
||||||
|
// onSearchUser()
|
||||||
|
// }
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
onSearchUser()
|
||||||
|
})
|
||||||
|
|
||||||
|
return {
|
||||||
|
form,
|
||||||
|
historicalData,
|
||||||
|
historicalColumns,
|
||||||
|
loading,
|
||||||
|
onSearchUser
|
||||||
|
// resetHistoryForm
|
||||||
|
}
|
||||||
|
}
|
20
src/views/basic/queryUser/user/BasicInfo.vue
Normal file
20
src/views/basic/queryUser/user/BasicInfo.vue
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<template>
|
||||||
|
<div>基础信息-{{ id }}-{{ props.uid }}</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { useRoute } from 'vue-router'
|
||||||
|
|
||||||
|
defineOptions({
|
||||||
|
// name 作为一种规范最好必须写上并且和路由的name保持一致
|
||||||
|
name: 'BasicInfo'
|
||||||
|
})
|
||||||
|
|
||||||
|
const props = defineProps(['uid'])
|
||||||
|
|
||||||
|
const route = useRoute()
|
||||||
|
// const router = useRouter()
|
||||||
|
const id = route.query?.id ? route.query?.id : route.params?.id
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped></style>
|
20
src/views/basic/queryUser/user/GameRecord.vue
Normal file
20
src/views/basic/queryUser/user/GameRecord.vue
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<template>
|
||||||
|
<div>游戏记录-{{ id }}-{{ props.uid }}</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { useRoute } from 'vue-router'
|
||||||
|
|
||||||
|
defineOptions({
|
||||||
|
// name 作为一种规范最好必须写上并且和路由的name保持一致
|
||||||
|
name: 'GameRecord'
|
||||||
|
})
|
||||||
|
|
||||||
|
const props = defineProps(['uid'])
|
||||||
|
|
||||||
|
const route = useRoute()
|
||||||
|
// const router = useRouter()
|
||||||
|
const id = route.query?.id ? route.query?.id : route.params?.id
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped></style>
|
20
src/views/basic/queryUser/user/chatRecord.vue
Normal file
20
src/views/basic/queryUser/user/chatRecord.vue
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<template>
|
||||||
|
<div>聊天记录-{{ id }}-{{ props.uid }}</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { useRoute } from 'vue-router'
|
||||||
|
|
||||||
|
defineOptions({
|
||||||
|
// name 作为一种规范最好必须写上并且和路由的name保持一致
|
||||||
|
name: 'ChatRecord'
|
||||||
|
})
|
||||||
|
|
||||||
|
const props = defineProps(['uid'])
|
||||||
|
|
||||||
|
const route = useRoute()
|
||||||
|
// const router = useRouter()
|
||||||
|
const id = route.query?.id ? route.query?.id : route.params?.id
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped></style>
|
20
src/views/basic/queryUser/user/diamondRecord.vue
Normal file
20
src/views/basic/queryUser/user/diamondRecord.vue
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<template>
|
||||||
|
<div>钻石记录-{{ id }}-{{ props.uid }}</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { useRoute } from 'vue-router'
|
||||||
|
|
||||||
|
defineOptions({
|
||||||
|
// name 作为一种规范最好必须写上并且和路由的name保持一致
|
||||||
|
name: 'DiamondRecord'
|
||||||
|
})
|
||||||
|
|
||||||
|
const props = defineProps(['uid'])
|
||||||
|
|
||||||
|
const route = useRoute()
|
||||||
|
// const router = useRouter()
|
||||||
|
const id = route.query?.id ? route.query?.id : route.params?.id
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped></style>
|
67
src/views/basic/queryUser/user/index.vue
Normal file
67
src/views/basic/queryUser/user/index.vue
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
<template>
|
||||||
|
<el-card>
|
||||||
|
<div>用户信息 列表页面</div>
|
||||||
|
<div>{{ id }} - 详情页内容在此(params传参)</div>
|
||||||
|
<el-tabs v-model="activeName" type="border-card">
|
||||||
|
<el-tab-pane
|
||||||
|
v-for="(_, tab) in tabsMap"
|
||||||
|
:key="tabsMap[tab].name"
|
||||||
|
:name="tabsMap[tab].name"
|
||||||
|
:label="tabsMap[tab].label"
|
||||||
|
/>
|
||||||
|
<component :is="tabsMap[activeName].component" :uid="id" />
|
||||||
|
</el-tabs>
|
||||||
|
</el-card>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref } from 'vue'
|
||||||
|
|
||||||
|
import { useDetail } from '../infoHook'
|
||||||
|
import basicInfo from './basicInfo.vue'
|
||||||
|
import gameRecord from './gameRecord.vue'
|
||||||
|
import diamondRecord from './diamondRecord.vue'
|
||||||
|
import loginRecord from './loginRecord.vue'
|
||||||
|
import chatRecord from './chatRecord.vue'
|
||||||
|
|
||||||
|
defineOptions({
|
||||||
|
// name 作为一种规范最好必须写上并且和路由的name保持一致
|
||||||
|
name: 'UserInformation'
|
||||||
|
})
|
||||||
|
|
||||||
|
const { initToDetail, id } = useDetail()
|
||||||
|
|
||||||
|
initToDetail('params')
|
||||||
|
|
||||||
|
const activeName = ref('basicInfo')
|
||||||
|
|
||||||
|
const tabsMap = {
|
||||||
|
basicInfo: {
|
||||||
|
name: 'basicInfo',
|
||||||
|
label: '用户信息',
|
||||||
|
component: basicInfo
|
||||||
|
},
|
||||||
|
gameRecord: {
|
||||||
|
name: 'gameRecord',
|
||||||
|
label: '游戏记录',
|
||||||
|
component: gameRecord
|
||||||
|
},
|
||||||
|
diamondRecord: {
|
||||||
|
name: 'diamondRecord',
|
||||||
|
label: '钻石记录',
|
||||||
|
component: diamondRecord
|
||||||
|
},
|
||||||
|
loginRecord: {
|
||||||
|
name: 'loginRecord',
|
||||||
|
label: '登录记录',
|
||||||
|
component: loginRecord
|
||||||
|
},
|
||||||
|
chatRecord: {
|
||||||
|
name: 'chatRecord',
|
||||||
|
label: '聊天记录',
|
||||||
|
component: chatRecord
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped></style>
|
20
src/views/basic/queryUser/user/loginRecord.vue
Normal file
20
src/views/basic/queryUser/user/loginRecord.vue
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<template>
|
||||||
|
<div>登录记录-{{ id }}-{{ props.uid }}</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { useRoute } from 'vue-router'
|
||||||
|
|
||||||
|
defineOptions({
|
||||||
|
// name 作为一种规范最好必须写上并且和路由的name保持一致
|
||||||
|
name: 'LoginRecord'
|
||||||
|
})
|
||||||
|
|
||||||
|
const props = defineProps(['uid'])
|
||||||
|
|
||||||
|
const route = useRoute()
|
||||||
|
// const router = useRouter()
|
||||||
|
const id = route.query?.id ? route.query?.id : route.params?.id
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped></style>
|
@ -23,6 +23,11 @@ import Lock from '@iconify-icons/ri/lock-fill'
|
|||||||
import Check from '@iconify-icons/ep/check'
|
import Check from '@iconify-icons/ep/check'
|
||||||
import User from '@iconify-icons/ri/user-3-fill'
|
import User from '@iconify-icons/ri/user-3-fill'
|
||||||
|
|
||||||
|
// 只要静态路由
|
||||||
|
import { setToken } from '@/utils/auth'
|
||||||
|
import { addPathMatch } from '@/router/utils'
|
||||||
|
import { usePermissionStoreHook } from '@/store/modules/permission'
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'Login'
|
name: 'Login'
|
||||||
})
|
})
|
||||||
@ -44,22 +49,43 @@ const ruleForm = reactive({
|
|||||||
password: 'admin123'
|
password: 'admin123'
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// const onLogin = async (formEl: FormInstance | undefined) => {
|
||||||
|
// loading.value = true
|
||||||
|
// if (!formEl) return
|
||||||
|
// await formEl.validate((valid, fields) => {
|
||||||
|
// if (valid) {
|
||||||
|
// useUserStoreHook()
|
||||||
|
// .loginByUsername({ username: ruleForm.username, password: 'admin123' })
|
||||||
|
// .then(res => {
|
||||||
|
// if (res.success) {
|
||||||
|
// // 获取后端路由
|
||||||
|
// initRouter().then(() => {
|
||||||
|
// router.push('/')
|
||||||
|
// message('登录成功', { type: 'success' })
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
// } else {
|
||||||
|
// loading.value = false
|
||||||
|
// return fields
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
// }
|
||||||
const onLogin = async (formEl: FormInstance | undefined) => {
|
const onLogin = async (formEl: FormInstance | undefined) => {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
if (!formEl) return
|
if (!formEl) return
|
||||||
await formEl.validate((valid, fields) => {
|
await formEl.validate((valid, fields) => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
useUserStoreHook()
|
// 全部采取静态路由模式
|
||||||
.loginByUsername({ username: ruleForm.username, password: 'admin123' })
|
usePermissionStoreHook().handleWholeMenus([])
|
||||||
.then(res => {
|
addPathMatch()
|
||||||
if (res.success) {
|
setToken({
|
||||||
// 获取后端路由
|
username: 'admin',
|
||||||
initRouter().then(() => {
|
roles: ['admin'],
|
||||||
router.push('/')
|
accessToken: 'eyJhbGciOiJIUzUxMiJ9.admin'
|
||||||
message('登录成功', { type: 'success' })
|
} as any)
|
||||||
})
|
router.push('/')
|
||||||
}
|
message('登录成功', { type: 'success' })
|
||||||
})
|
|
||||||
} else {
|
} else {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
return fields
|
return fields
|
||||||
|
@ -1,34 +1,34 @@
|
|||||||
import dayjs from "dayjs";
|
import dayjs from 'dayjs'
|
||||||
import { resolve } from "path";
|
import { resolve } from 'path'
|
||||||
import pkg from "./package.json";
|
import pkg from './package.json'
|
||||||
import { warpperEnv } from "./build";
|
import { warpperEnv } from './build'
|
||||||
import { getPluginsList } from "./build/plugins";
|
import { getPluginsList } from './build/plugins'
|
||||||
import { include, exclude } from "./build/optimize";
|
import { include, exclude } from './build/optimize'
|
||||||
import { UserConfigExport, ConfigEnv, loadEnv } from "vite";
|
import { UserConfigExport, ConfigEnv, loadEnv } from 'vite'
|
||||||
|
|
||||||
/** 当前执行node命令时文件夹的地址(工作目录) */
|
/** 当前执行node命令时文件夹的地址(工作目录) */
|
||||||
const root: string = process.cwd();
|
const root: string = process.cwd()
|
||||||
|
|
||||||
/** 路径查找 */
|
/** 路径查找 */
|
||||||
const pathResolve = (dir: string): string => {
|
const pathResolve = (dir: string): string => {
|
||||||
return resolve(__dirname, ".", dir);
|
return resolve(__dirname, '.', dir)
|
||||||
};
|
}
|
||||||
|
|
||||||
/** 设置别名 */
|
/** 设置别名 */
|
||||||
const alias: Record<string, string> = {
|
const alias: Record<string, string> = {
|
||||||
"@": pathResolve("src"),
|
'@': pathResolve('src'),
|
||||||
"@build": pathResolve("build")
|
'@build': pathResolve('build')
|
||||||
};
|
}
|
||||||
|
|
||||||
const { dependencies, devDependencies, name, version } = pkg;
|
const { dependencies, devDependencies, name, version } = pkg
|
||||||
const __APP_INFO__ = {
|
const __APP_INFO__ = {
|
||||||
pkg: { dependencies, devDependencies, name, version },
|
pkg: { dependencies, devDependencies, name, version },
|
||||||
lastBuildTime: dayjs(new Date()).format("YYYY-MM-DD HH:mm:ss")
|
lastBuildTime: dayjs(new Date()).format('YYYY-MM-DD HH:mm:ss')
|
||||||
};
|
}
|
||||||
|
|
||||||
export default ({ command, mode }: ConfigEnv): UserConfigExport => {
|
export default ({ command, mode }: ConfigEnv): UserConfigExport => {
|
||||||
const { VITE_CDN, VITE_PORT, VITE_COMPRESSION, VITE_PUBLIC_PATH } =
|
const { VITE_CDN, VITE_PORT, VITE_COMPRESSION, VITE_PUBLIC_PATH } =
|
||||||
warpperEnv(loadEnv(mode, root));
|
warpperEnv(loadEnv(mode, root))
|
||||||
return {
|
return {
|
||||||
base: VITE_PUBLIC_PATH,
|
base: VITE_PUBLIC_PATH,
|
||||||
root,
|
root,
|
||||||
@ -41,9 +41,16 @@ export default ({ command, mode }: ConfigEnv): UserConfigExport => {
|
|||||||
https: false,
|
https: false,
|
||||||
// 端口号
|
// 端口号
|
||||||
port: VITE_PORT,
|
port: VITE_PORT,
|
||||||
host: "0.0.0.0",
|
host: '0.0.0.0',
|
||||||
// 本地跨域代理 https://cn.vitejs.dev/config/server-options.html#server-proxy
|
// 本地跨域代理 https://cn.vitejs.dev/config/server-options.html#server-proxy
|
||||||
proxy: {}
|
proxy: {
|
||||||
|
'^/dev-api/.*': {
|
||||||
|
// 这里填写后端地址
|
||||||
|
target: 'http://192.168.100.87:8000',
|
||||||
|
changeOrigin: true,
|
||||||
|
rewrite: path => path.replace(/^\/dev-api/, '')
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
plugins: getPluginsList(command, VITE_CDN, VITE_COMPRESSION),
|
plugins: getPluginsList(command, VITE_CDN, VITE_COMPRESSION),
|
||||||
// https://cn.vitejs.dev/config/dep-optimization-options.html#dep-optimization-options
|
// https://cn.vitejs.dev/config/dep-optimization-options.html#dep-optimization-options
|
||||||
@ -57,13 +64,13 @@ export default ({ command, mode }: ConfigEnv): UserConfigExport => {
|
|||||||
chunkSizeWarningLimit: 4000,
|
chunkSizeWarningLimit: 4000,
|
||||||
rollupOptions: {
|
rollupOptions: {
|
||||||
input: {
|
input: {
|
||||||
index: pathResolve("index.html")
|
index: pathResolve('index.html')
|
||||||
},
|
},
|
||||||
// 静态资源分类打包
|
// 静态资源分类打包
|
||||||
output: {
|
output: {
|
||||||
chunkFileNames: "static/js/[name]-[hash].js",
|
chunkFileNames: 'static/js/[name]-[hash].js',
|
||||||
entryFileNames: "static/js/[name]-[hash].js",
|
entryFileNames: 'static/js/[name]-[hash].js',
|
||||||
assetFileNames: "static/[ext]/[name]-[hash].[ext]"
|
assetFileNames: 'static/[ext]/[name]-[hash].[ext]'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -71,5 +78,5 @@ export default ({ command, mode }: ConfigEnv): UserConfigExport => {
|
|||||||
__INTLIFY_PROD_DEVTOOLS__: false,
|
__INTLIFY_PROD_DEVTOOLS__: false,
|
||||||
__APP_INFO__: JSON.stringify(__APP_INFO__)
|
__APP_INFO__: JSON.stringify(__APP_INFO__)
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
};
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user