init
This commit is contained in:
+3
-3
@@ -4,13 +4,13 @@ VITE_APP_TITLE = 'Portal 管理后台'
|
|||||||
# 部署基础路径
|
# 部署基础路径
|
||||||
VITE_APP_BASE_URL = '/'
|
VITE_APP_BASE_URL = '/'
|
||||||
|
|
||||||
# 接口前缀(本地走 Vite proxy)
|
# 接口前缀留空:请求直接以 /api/... 发起,由 Vite proxy 的 /api 规则转发到后端
|
||||||
VITE_APP_BASE_API = '/'
|
VITE_APP_BASE_API = ''
|
||||||
|
|
||||||
# 后端真实地址
|
# 后端真实地址
|
||||||
VITE_APP_API_URL = 'http://localhost:8080'
|
VITE_APP_API_URL = 'http://localhost:8080'
|
||||||
|
|
||||||
# 是否启用本地 mock(true 时拦截全部 /api/v1 请求;false 时仅命中标记 alwaysMock 的接口)
|
# 是否启用本地 mock(true 时拦截 /api 请求)
|
||||||
VITE_USE_MOCK = 'false'
|
VITE_USE_MOCK = 'false'
|
||||||
|
|
||||||
# 开发端口
|
# 开发端口
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
VITE_APP_TITLE = 'Portal 管理后台'
|
VITE_APP_TITLE = 'Portal 管理后台'
|
||||||
VITE_APP_BASE_URL = '/'
|
VITE_APP_BASE_URL = '/'
|
||||||
VITE_APP_BASE_API = '/api/v1'
|
VITE_APP_BASE_API = ''
|
||||||
VITE_APP_API_URL = 'https://api.example.com'
|
VITE_APP_API_URL = 'https://api.example.com'
|
||||||
VITE_USE_MOCK = 'false'
|
VITE_USE_MOCK = 'false'
|
||||||
VITE_APP_PORT = '3000'
|
VITE_APP_PORT = '3000'
|
||||||
|
|||||||
+19
-19
@@ -33,7 +33,7 @@ const pickString = (value: unknown, fallback = '') => (typeof value === 'string'
|
|||||||
export const mockRules: MockRule[] = [
|
export const mockRules: MockRule[] = [
|
||||||
{
|
{
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
pattern: /^\/api\/v1\/auth\/login$/,
|
pattern: /^\/api\/auth\/login$/,
|
||||||
handler: (ctx) => ({
|
handler: (ctx) => ({
|
||||||
accessToken: 'mock-access-token',
|
accessToken: 'mock-access-token',
|
||||||
refreshToken: 'mock-refresh-token',
|
refreshToken: 'mock-refresh-token',
|
||||||
@@ -44,12 +44,12 @@ export const mockRules: MockRule[] = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
pattern: /^\/api\/v1\/auth\/logout$/,
|
pattern: /^\/api\/auth\/logout$/,
|
||||||
handler: () => true,
|
handler: () => true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
pattern: /^\/api\/v1\/auth\/me$/,
|
pattern: /^\/api\/auth\/me$/,
|
||||||
handler: () => ({
|
handler: () => ({
|
||||||
userId: 1,
|
userId: 1,
|
||||||
username: 'admin',
|
username: 'admin',
|
||||||
@@ -70,12 +70,12 @@ export const mockRules: MockRule[] = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
pattern: /^\/api\/v1\/auth\/routes$/,
|
pattern: /^\/api\/auth\/routes$/,
|
||||||
handler: () => menuRoutes,
|
handler: () => menuRoutes,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
pattern: /^\/api\/v1\/api\/admin\/users$/,
|
pattern: /^\/api\/api\/admin\/users$/,
|
||||||
handler: (ctx) => {
|
handler: (ctx) => {
|
||||||
const page = toNumber(ctx.query.page, 1)
|
const page = toNumber(ctx.query.page, 1)
|
||||||
const size = toNumber(ctx.query.size, 20)
|
const size = toNumber(ctx.query.size, 20)
|
||||||
@@ -94,12 +94,12 @@ export const mockRules: MockRule[] = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
pattern: /^\/api\/v1\/api\/admin\/users\/(\d+)$/,
|
pattern: /^\/api\/api\/admin\/users\/(\d+)$/,
|
||||||
handler: (ctx) => users.find((item) => item.id === toNumber(ctx.params[0])) ?? null,
|
handler: (ctx) => users.find((item) => item.id === toNumber(ctx.params[0])) ?? null,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
method: 'PUT',
|
method: 'PUT',
|
||||||
pattern: /^\/api\/v1\/api\/admin\/users\/(\d+)$/,
|
pattern: /^\/api\/api\/admin\/users\/(\d+)$/,
|
||||||
handler: (ctx) => {
|
handler: (ctx) => {
|
||||||
const target = users.find((item) => item.id === toNumber(ctx.params[0]))
|
const target = users.find((item) => item.id === toNumber(ctx.params[0]))
|
||||||
if (!target) return false
|
if (!target) return false
|
||||||
@@ -113,7 +113,7 @@ export const mockRules: MockRule[] = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
pattern: /^\/api\/v1\/api\/admin\/users\/(\d+)\/status$/,
|
pattern: /^\/api\/api\/admin\/users\/(\d+)\/status$/,
|
||||||
handler: (ctx) => {
|
handler: (ctx) => {
|
||||||
const target = users.find((item) => item.id === toNumber(ctx.params[0]))
|
const target = users.find((item) => item.id === toNumber(ctx.params[0]))
|
||||||
if (!target) return false
|
if (!target) return false
|
||||||
@@ -125,7 +125,7 @@ export const mockRules: MockRule[] = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
pattern: /^\/api\/v1\/api\/admin\/miniapps$/,
|
pattern: /^\/api\/api\/admin\/miniapps$/,
|
||||||
handler: (ctx) => {
|
handler: (ctx) => {
|
||||||
const { status } = ctx.query
|
const { status } = ctx.query
|
||||||
const pageNum = toNumber(ctx.query.pageNum, 1)
|
const pageNum = toNumber(ctx.query.pageNum, 1)
|
||||||
@@ -142,7 +142,7 @@ export const mockRules: MockRule[] = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
pattern: /^\/api\/v1\/api\/admin\/miniapps\/(\d+)$/,
|
pattern: /^\/api\/api\/admin\/miniapps\/(\d+)$/,
|
||||||
handler: (ctx) => {
|
handler: (ctx) => {
|
||||||
const target = miniApps.find((item) => item.id === toNumber(ctx.params[0]))
|
const target = miniApps.find((item) => item.id === toNumber(ctx.params[0]))
|
||||||
if (!target) return null
|
if (!target) return null
|
||||||
@@ -152,7 +152,7 @@ export const mockRules: MockRule[] = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
pattern: /^\/api\/v1\/api\/admin\/miniapps$/,
|
pattern: /^\/api\/api\/admin\/miniapps$/,
|
||||||
handler: (ctx) => {
|
handler: (ctx) => {
|
||||||
const id = miniApps.length + 1
|
const id = miniApps.length + 1
|
||||||
const created: MockMiniApp = {
|
const created: MockMiniApp = {
|
||||||
@@ -172,7 +172,7 @@ export const mockRules: MockRule[] = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
method: 'PUT',
|
method: 'PUT',
|
||||||
pattern: /^\/api\/v1\/api\/admin\/miniapps\/(\d+)$/,
|
pattern: /^\/api\/api\/admin\/miniapps\/(\d+)$/,
|
||||||
handler: (ctx) => {
|
handler: (ctx) => {
|
||||||
const target = miniApps.find((item) => item.id === toNumber(ctx.params[0]))
|
const target = miniApps.find((item) => item.id === toNumber(ctx.params[0]))
|
||||||
if (!target) return false
|
if (!target) return false
|
||||||
@@ -189,7 +189,7 @@ export const mockRules: MockRule[] = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
pattern: /^\/api\/v1\/api\/admin\/miniapps\/([\d,]+)$/,
|
pattern: /^\/api\/api\/admin\/miniapps\/([\d,]+)$/,
|
||||||
handler: (ctx) => {
|
handler: (ctx) => {
|
||||||
const ids = ctx.params[0].split(',').map((id) => toNumber(id))
|
const ids = ctx.params[0].split(',').map((id) => toNumber(id))
|
||||||
ids.forEach((id) => {
|
ids.forEach((id) => {
|
||||||
@@ -201,7 +201,7 @@ export const mockRules: MockRule[] = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
pattern: /^\/api\/v1\/api\/admin\/files$/,
|
pattern: /^\/api\/api\/admin\/files$/,
|
||||||
handler: (ctx) => {
|
handler: (ctx) => {
|
||||||
const { keyword, uploader_type, page, size } = ctx.query
|
const { keyword, uploader_type, page, size } = ctx.query
|
||||||
const pageNum = toNumber(page, 1)
|
const pageNum = toNumber(page, 1)
|
||||||
@@ -221,7 +221,7 @@ export const mockRules: MockRule[] = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
pattern: /^\/api\/v1\/api\/admin\/files\/upload$/,
|
pattern: /^\/api\/api\/admin\/files\/upload$/,
|
||||||
handler: () => {
|
handler: () => {
|
||||||
const id = files.length + 1
|
const id = files.length + 1
|
||||||
const rand = Math.random().toString(36).slice(2, 10)
|
const rand = Math.random().toString(36).slice(2, 10)
|
||||||
@@ -251,7 +251,7 @@ export const mockRules: MockRule[] = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
pattern: /^\/api\/v1\/api\/admin\/files\/(\d+)$/,
|
pattern: /^\/api\/api\/admin\/files\/(\d+)$/,
|
||||||
handler: (ctx) => {
|
handler: (ctx) => {
|
||||||
const id = toNumber(ctx.params[0])
|
const id = toNumber(ctx.params[0])
|
||||||
const index = files.findIndex((item) => item.id === id)
|
const index = files.findIndex((item) => item.id === id)
|
||||||
@@ -262,7 +262,7 @@ export const mockRules: MockRule[] = [
|
|||||||
{
|
{
|
||||||
// 统计每个小程序的用户数(有真实用户的取真实值,其余返回稳定模拟值)
|
// 统计每个小程序的用户数(有真实用户的取真实值,其余返回稳定模拟值)
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
pattern: /^\/api\/v1\/api\/admin\/dashboard\/user-count-by-miniapp$/,
|
pattern: /^\/api\/api\/admin\/dashboard\/user-count-by-miniapp$/,
|
||||||
alwaysMock: true,
|
alwaysMock: true,
|
||||||
handler: () =>
|
handler: () =>
|
||||||
miniApps.map((app) => {
|
miniApps.map((app) => {
|
||||||
@@ -276,7 +276,7 @@ export const mockRules: MockRule[] = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
pattern: /^\/api\/v1\/api\/admin\/monitor\/server-info$/,
|
pattern: /^\/api\/api\/admin\/monitor\/server-info$/,
|
||||||
alwaysMock: true,
|
alwaysMock: true,
|
||||||
handler: () => ({
|
handler: () => ({
|
||||||
hostname: 'portal-server-01',
|
hostname: 'portal-server-01',
|
||||||
@@ -293,7 +293,7 @@ export const mockRules: MockRule[] = [
|
|||||||
{
|
{
|
||||||
// 实时状态:每次请求生成浮动指标,模拟监控采集中
|
// 实时状态:每次请求生成浮动指标,模拟监控采集中
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
pattern: /^\/api\/v1\/api\/admin\/monitor\/server-status$/,
|
pattern: /^\/api\/api\/admin\/monitor\/server-status$/,
|
||||||
alwaysMock: true,
|
alwaysMock: true,
|
||||||
handler: () => {
|
handler: () => {
|
||||||
const cpuUsage = Math.round((20 + Math.random() * 60) * 10) / 10
|
const cpuUsage = Math.round((20 + Math.random() * 60) * 10) / 10
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
import type { Plugin } from 'vite'
|
import type { Plugin } from 'vite'
|
||||||
import { mockRules, type MockContext } from './index'
|
import { mockRules, type MockContext } from './index'
|
||||||
|
|
||||||
const MOCK_PREFIX = '/api/v1'
|
const MOCK_PREFIX = '/api'
|
||||||
|
|
||||||
function readBody(req: NodeJS.ReadableStream): Promise<string> {
|
function readBody(req: NodeJS.ReadableStream): Promise<string> {
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import type { LoginForm, LoginResult, UserInfo } from '@/types/auth'
|
|||||||
import type { RouteVO } from '@/types/router'
|
import type { RouteVO } from '@/types/router'
|
||||||
import { staticMenuRoutes } from '@/config/static-routes'
|
import { staticMenuRoutes } from '@/config/static-routes'
|
||||||
|
|
||||||
// 叠加在 VITE_APP_BASE_API(/api/v1) 之上,经 Vite proxy 剥离 /api/v1 后命中后端 /api/admin
|
// 请求直接以 /api/admin 发起,由 Vite proxy 的 /api 规则转发到后端
|
||||||
const ADMIN_BASE = '/api/admin'
|
const ADMIN_BASE = '/api/admin'
|
||||||
|
|
||||||
export const AuthAPI = {
|
export const AuthAPI = {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import request from '@/utils/request'
|
|||||||
import type { PageResult } from '@/types/common'
|
import type { PageResult } from '@/types/common'
|
||||||
import type { FileQuery, FileUploadVO, FileVO } from '@/types/file'
|
import type { FileQuery, FileUploadVO, FileVO } from '@/types/file'
|
||||||
|
|
||||||
// 叠加在 VITE_APP_BASE_API(/api/v1) 之上,经 Vite proxy 剥离 /api/v1 后命中后端 /api/admin/files
|
// 请求直接以 /api/admin/files 发起,由 Vite proxy 的 /api 规则转发到后端
|
||||||
const BASE_URL = '/api/admin/files'
|
const BASE_URL = '/api/admin/files'
|
||||||
|
|
||||||
export const FileAPI = {
|
export const FileAPI = {
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ import request from '@/utils/request'
|
|||||||
import type { PageResult } from '@/types/common'
|
import type { PageResult } from '@/types/common'
|
||||||
import type { MiniAppForm, MiniAppQuery, MiniAppStatus, MiniAppVO } from '@/types/miniapp'
|
import type { MiniAppForm, MiniAppQuery, MiniAppStatus, MiniAppVO } from '@/types/miniapp'
|
||||||
|
|
||||||
// 前端基础路径 VITE_APP_BASE_API 为 /api/v1,经 Vite proxy 整体剥离后转发到 Go 后端;
|
// 请求直接以 /api/admin/miniapps 发起,由 Vite proxy 的 /api 规则转发到 Go 后端;
|
||||||
// 此处拼接 /api/admin/miniapps,剥离 /api/v1 后即可精确命中后端 /api/admin/miniapps
|
// 精确命中后端 /api/admin/miniapps
|
||||||
const BASE_URL = '/api/admin/miniapps'
|
const BASE_URL = '/api/admin/miniapps'
|
||||||
|
|
||||||
export const MiniAppAPI = {
|
export const MiniAppAPI = {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import request from '@/utils/request'
|
|||||||
import type { PageResult } from '@/types/common'
|
import type { PageResult } from '@/types/common'
|
||||||
import type { UserForm, UserQuery, UserStatus, UserVO } from '@/types/system/user'
|
import type { UserForm, UserQuery, UserStatus, UserVO } from '@/types/system/user'
|
||||||
|
|
||||||
// 叠加在 VITE_APP_BASE_API(/api/v1) 上,经 Vite proxy 剥离 /api/v1 后命中后端 /api/admin/users
|
// 请求直接以 /api/admin/users 发起,由 Vite proxy 的 /api 规则转发到后端
|
||||||
const BASE_URL = '/api/admin/users'
|
const BASE_URL = '/api/admin/users'
|
||||||
|
|
||||||
export const UserAPI = {
|
export const UserAPI = {
|
||||||
|
|||||||
@@ -8,9 +8,6 @@
|
|||||||
|
|
||||||
defineOptions({ name: 'File' })
|
defineOptions({ name: 'File' })
|
||||||
|
|
||||||
/** 经 Vite proxy 拼接前缀,使本地静态访问也走后端代理(避免硬编码域名/端口) */
|
|
||||||
const previewUrl = (url: string) => `${import.meta.env.VITE_APP_BASE_API}${url}`
|
|
||||||
|
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
const total = ref(0)
|
const total = ref(0)
|
||||||
const list = ref<FileVO[]>([])
|
const list = ref<FileVO[]>([])
|
||||||
@@ -79,12 +76,12 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function handlePreview(row: FileVO) {
|
function handlePreview(row: FileVO) {
|
||||||
window.open(previewUrl(row.url), '_blank')
|
window.open(row.url, '_blank')
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleDownload(row: FileVO) {
|
function handleDownload(row: FileVO) {
|
||||||
const link = document.createElement('a')
|
const link = document.createElement('a')
|
||||||
link.href = previewUrl(row.url)
|
link.href = row.url
|
||||||
link.download = row.origin_name || row.filename
|
link.download = row.origin_name || row.filename
|
||||||
link.click()
|
link.click()
|
||||||
}
|
}
|
||||||
@@ -163,8 +160,8 @@
|
|||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-image
|
<el-image
|
||||||
v-if="isImage(row as FileVO)"
|
v-if="isImage(row as FileVO)"
|
||||||
:src="previewUrl((row as FileVO).url)"
|
:src="(row as FileVO).url"
|
||||||
:preview-src-list="[previewUrl((row as FileVO).url)]"
|
:preview-src-list="[(row as FileVO).url]"
|
||||||
:initial-index="0"
|
:initial-index="0"
|
||||||
fit="cover"
|
fit="cover"
|
||||||
class="thumb"
|
class="thumb"
|
||||||
|
|||||||
+7
-2
@@ -43,10 +43,15 @@ export default defineConfig(({ mode }) => {
|
|||||||
port: Number(env.VITE_APP_PORT) || 3000,
|
port: Number(env.VITE_APP_PORT) || 3000,
|
||||||
open: true,
|
open: true,
|
||||||
proxy: {
|
proxy: {
|
||||||
[env.VITE_APP_BASE_API]: {
|
// 接口:请求以 /api/... 发起,直接转发到后端(后端以 /api 提供服务,无需重写路径)
|
||||||
|
'/api': {
|
||||||
|
target: env.VITE_APP_API_URL,
|
||||||
|
changeOrigin: true,
|
||||||
|
},
|
||||||
|
// 文件静态资源由后端 r.Static 提供,dev 下直连后端
|
||||||
|
'/files': {
|
||||||
target: env.VITE_APP_API_URL,
|
target: env.VITE_APP_API_URL,
|
||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
rewrite: (path: string) => path.replace(new RegExp(`^${env.VITE_APP_BASE_API}`), ''),
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user