docs(deployment): 更新部署文档并添加自动化部署脚本
- 更新了 DEPLOYMENT.md 文档,增加了更多部署细节和说明 - 添加了 Linux 和 Windows 平台的自动化部署脚本 - 更新了 README.md,增加了部署相关说明 - 调整了 .env 文件配置,以适应新的部署流程 - 移除了部分不必要的代码和配置
This commit is contained in:
@@ -1,13 +1,11 @@
|
||||
# 生产环境配置
|
||||
NODE_ENV=production
|
||||
VITE_APP_NAME=结伴客后台管理系统
|
||||
VITE_APP_VERSION=1.0.0
|
||||
|
||||
# API配置
|
||||
VITE_API_BASE_URL=https://api.jiebanke.com/api/v1
|
||||
VITE_API_TIMEOUT=15000
|
||||
VITE_API_BASE_URL=https://api.jiebanke.com/api
|
||||
VITE_API_TIMEOUT=10000
|
||||
|
||||
# 功能开关
|
||||
VITE_FEATURE_ANALYTICS=true
|
||||
VITE_FEATURE_DEBUG=false
|
||||
|
||||
# 性能优化
|
||||
VITE_COMPRESSION=true
|
||||
VITE_FEATURE_DEBUG=false
|
||||
@@ -1,11 +1,16 @@
|
||||
import axios from 'axios'
|
||||
import { message } from 'ant-design-vue'
|
||||
import type { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios'
|
||||
import { mockAPI } from './mockData'
|
||||
import { createMockWrapper } from '@/config/mock'
|
||||
|
||||
// API基础配置
|
||||
const baseURL = import.meta.env.VITE_API_BASE_URL || 'http://localhost:3100/api'
|
||||
const timeout = parseInt(import.meta.env.VITE_API_TIMEOUT || '10000')
|
||||
|
||||
// 检查是否使用模拟数据(注释掉未使用的变量)
|
||||
// const useMock = import.meta.env.VITE_USE_MOCK === 'true' || (!baseURL || baseURL.includes('localhost')) && import.meta.env.DEV
|
||||
|
||||
// 创建axios实例
|
||||
const api: AxiosInstance = axios.create({
|
||||
baseURL,
|
||||
@@ -116,8 +121,8 @@ export const request = {
|
||||
api.patch(url, data, config).then(res => res.data)
|
||||
}
|
||||
|
||||
// 认证相关API
|
||||
export const authAPI = {
|
||||
// 认证相关API(开发环境使用模拟数据)
|
||||
export const authAPI = createMockWrapper({
|
||||
// 管理员登录
|
||||
login: (credentials: { username: string; password: string }) =>
|
||||
request.post<{
|
||||
@@ -149,15 +154,7 @@ export const authAPI = {
|
||||
// 退出登录
|
||||
logout: () =>
|
||||
request.post('/auth/logout')
|
||||
}
|
||||
|
||||
export * from './user'
|
||||
export * from './merchant'
|
||||
export * from './travel'
|
||||
export * from './animal'
|
||||
export * from './order'
|
||||
export * from './promotion'
|
||||
export * from './system'
|
||||
}, mockAPI.auth)
|
||||
|
||||
// 为避免命名冲突,单独导出模块
|
||||
export { default as userAPI } from './user'
|
||||
@@ -168,4 +165,13 @@ export { default as orderAPI } from './order'
|
||||
export { default as promotionAPI } from './promotion'
|
||||
export { default as systemAPI } from './system'
|
||||
|
||||
// 重新导出特定类型以避免冲突
|
||||
export type { ApiResponse } from './user'
|
||||
export type { Merchant } from './merchant'
|
||||
export type { Travel } from './travel'
|
||||
export type { Animal } from './animal'
|
||||
export type { Order } from './order'
|
||||
export type { Promotion } from './promotion'
|
||||
export type { SystemStats } from './system'
|
||||
|
||||
export default api
|
||||
187
admin-system/src/api/mockData.ts
Normal file
187
admin-system/src/api/mockData.ts
Normal file
@@ -0,0 +1,187 @@
|
||||
// 模拟数据服务
|
||||
import { message } from 'ant-design-vue'
|
||||
|
||||
// 模拟延迟
|
||||
const delay = (ms: number) => new Promise(resolve => setTimeout(resolve, ms))
|
||||
|
||||
// 模拟用户数据
|
||||
const mockUsers = [
|
||||
{ id: 1, username: 'admin', nickname: '系统管理员', role: 'admin', status: 'active', createdAt: '2024-01-01' },
|
||||
{ id: 2, username: 'user1', nickname: '旅行爱好者', role: 'user', status: 'active', createdAt: '2024-01-02' },
|
||||
{ id: 3, username: 'merchant1', nickname: '花店老板', role: 'merchant', status: 'active', createdAt: '2024-01-03' }
|
||||
]
|
||||
|
||||
// 模拟商家数据
|
||||
const mockMerchants = [
|
||||
{ id: 1, name: '鲜花坊', type: 'flower', status: 'approved', contact: '13800138001', createdAt: '2024-01-05' },
|
||||
{ id: 2, name: '快乐农场', type: 'farm', status: 'approved', contact: '13800138002', createdAt: '2024-01-06' }
|
||||
]
|
||||
|
||||
// 模拟旅行数据
|
||||
const mockTravels = [
|
||||
{ id: 1, userId: 2, destination: '西藏', startDate: '2024-06-01', endDate: '2024-06-10', status: 'active', createdAt: '2024-01-10' },
|
||||
{ id: 2, userId: 2, destination: '云南', startDate: '2024-07-01', endDate: '2024-07-07', status: 'active', createdAt: '2024-01-11' }
|
||||
]
|
||||
|
||||
// 模拟动物数据
|
||||
const mockAnimals = [
|
||||
{ id: 1, name: '小白', type: 'sheep', merchantId: 2, status: 'available', price: 500, createdAt: '2024-01-15' },
|
||||
{ id: 2, name: '小花', type: 'cow', merchantId: 2, status: 'claimed', price: 1000, createdAt: '2024-01-16' }
|
||||
]
|
||||
|
||||
// 模拟订单数据
|
||||
const mockOrders = [
|
||||
{ id: 1, userId: 2, merchantId: 1, amount: 199, status: 'completed', createdAt: '2024-01-20' },
|
||||
{ id: 2, userId: 2, merchantId: 1, amount: 299, status: 'pending', createdAt: '2024-01-21' }
|
||||
]
|
||||
|
||||
// 模拟API响应格式
|
||||
const createSuccessResponse = (data: any) => ({
|
||||
success: true,
|
||||
data,
|
||||
message: '操作成功'
|
||||
})
|
||||
|
||||
// 模拟分页响应
|
||||
const createPaginatedResponse = (data: any[], page: number, pageSize: number, total: number) => ({
|
||||
success: true,
|
||||
data: {
|
||||
list: data,
|
||||
pagination: {
|
||||
current: page,
|
||||
pageSize,
|
||||
total,
|
||||
totalPages: Math.ceil(total / pageSize)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// 模拟认证API
|
||||
export const mockAuthAPI = {
|
||||
login: async (credentials: { username: string; password: string }) => {
|
||||
await delay(1000)
|
||||
|
||||
if (credentials.username === 'admin' && credentials.password === 'admin123') {
|
||||
const adminUser = mockUsers.find(u => u.username === 'admin')
|
||||
return createSuccessResponse({
|
||||
token: 'mock-jwt-token-for-admin',
|
||||
admin: adminUser
|
||||
})
|
||||
}
|
||||
|
||||
message.error('用户名或密码错误')
|
||||
throw new Error('登录失败')
|
||||
},
|
||||
|
||||
getCurrentUser: async () => {
|
||||
await delay(500)
|
||||
const adminUser = mockUsers.find(u => u.username === 'admin')
|
||||
return createSuccessResponse({
|
||||
admin: adminUser
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 模拟用户API
|
||||
export const mockUserAPI = {
|
||||
getUsers: async (params: any = {}) => {
|
||||
await delay(800)
|
||||
const { page = 1, pageSize = 10 } = params
|
||||
const start = (page - 1) * pageSize
|
||||
const end = start + pageSize
|
||||
const paginatedData = mockUsers.slice(start, end)
|
||||
|
||||
return createPaginatedResponse(paginatedData, page, pageSize, mockUsers.length)
|
||||
},
|
||||
|
||||
getUserById: async (id: number) => {
|
||||
await delay(500)
|
||||
const user = mockUsers.find(u => u.id === id)
|
||||
if (user) {
|
||||
return createSuccessResponse(user)
|
||||
}
|
||||
message.error('用户不存在')
|
||||
throw new Error('用户不存在')
|
||||
}
|
||||
}
|
||||
|
||||
// 模拟商家API
|
||||
export const mockMerchantAPI = {
|
||||
getMerchants: async (params: any = {}) => {
|
||||
await delay(800)
|
||||
const { page = 1, limit = 10 } = params
|
||||
const start = (page - 1) * limit
|
||||
const end = start + limit
|
||||
const paginatedData = mockMerchants.slice(start, end)
|
||||
|
||||
return createPaginatedResponse(paginatedData, page, limit, mockMerchants.length)
|
||||
}
|
||||
}
|
||||
|
||||
// 模拟旅行API
|
||||
export const mockTravelAPI = {
|
||||
getTravels: async (params: any = {}) => {
|
||||
await delay(800)
|
||||
const { page = 1, limit = 10 } = params
|
||||
const start = (page - 1) * limit
|
||||
const end = start + limit
|
||||
const paginatedData = mockTravels.slice(start, end)
|
||||
|
||||
return createPaginatedResponse(paginatedData, page, limit, mockTravels.length)
|
||||
}
|
||||
}
|
||||
|
||||
// 模拟动物API
|
||||
export const mockAnimalAPI = {
|
||||
getAnimals: async (params: any = {}) => {
|
||||
await delay(800)
|
||||
const { page = 1, limit = 10 } = params
|
||||
const start = (page - 1) * limit
|
||||
const end = start + limit
|
||||
const paginatedData = mockAnimals.slice(start, end)
|
||||
|
||||
return createPaginatedResponse(paginatedData, page, limit, mockAnimals.length)
|
||||
}
|
||||
}
|
||||
|
||||
// 模拟订单API
|
||||
export const mockOrderAPI = {
|
||||
getOrders: async (params: any = {}) => {
|
||||
await delay(800)
|
||||
const { page = 1, limit = 10 } = params
|
||||
const start = (page - 1) * limit
|
||||
const end = start + limit
|
||||
const paginatedData = mockOrders.slice(start, end)
|
||||
|
||||
return createPaginatedResponse(paginatedData, page, limit, mockOrders.length)
|
||||
}
|
||||
}
|
||||
|
||||
// 模拟系统统计API
|
||||
export const mockSystemAPI = {
|
||||
getSystemStats: async () => {
|
||||
await delay(600)
|
||||
return createSuccessResponse({
|
||||
userCount: mockUsers.length,
|
||||
merchantCount: mockMerchants.length,
|
||||
travelCount: mockTravels.length,
|
||||
animalCount: mockAnimals.length,
|
||||
orderCount: mockOrders.length,
|
||||
todayUserCount: 5,
|
||||
todayOrderCount: 3
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 导出所有模拟API
|
||||
export const mockAPI = {
|
||||
auth: mockAuthAPI,
|
||||
user: mockUserAPI,
|
||||
merchant: mockMerchantAPI,
|
||||
travel: mockTravelAPI,
|
||||
animal: mockAnimalAPI,
|
||||
order: mockOrderAPI,
|
||||
system: mockSystemAPI
|
||||
}
|
||||
|
||||
export default mockAPI
|
||||
@@ -1,4 +1,6 @@
|
||||
import { request } from '.'
|
||||
import { mockSystemAPI } from './mockData'
|
||||
import { createMockWrapper } from '@/config/mock'
|
||||
|
||||
// 服务类型
|
||||
export type ServiceType = 'database' | 'cache' | 'mq'
|
||||
@@ -88,9 +90,20 @@ export const getSystemConfigs = (params?: SystemConfigQueryParams) =>
|
||||
export const updateSystemConfig = (id: string, data: SystemConfigUpdateData) =>
|
||||
request.put<{ success: boolean; code: number; message: string }>(`/admin/system-configs/${id}`, data)
|
||||
|
||||
// 定义系统统计数据类型
|
||||
export interface SystemStats {
|
||||
userCount: number
|
||||
merchantCount: number
|
||||
travelCount: number
|
||||
animalCount: number
|
||||
orderCount: number
|
||||
todayUserCount: number
|
||||
todayOrderCount: number
|
||||
}
|
||||
|
||||
// 获取系统统计信息
|
||||
export const getSystemStats = () =>
|
||||
request.get<{ success: boolean; code: number; message: string; data: any }>('/admin/system/stats')
|
||||
request.get<{ success: boolean; code: number; message: string; data: SystemStats }>('/admin/system/stats')
|
||||
|
||||
// 获取系统日志
|
||||
export const getSystemLogs = (params?: { page?: number; limit?: number; level?: string }) =>
|
||||
@@ -104,7 +117,8 @@ export const getSystemSettings = () =>
|
||||
export const updateSystemSettings = (data: any) =>
|
||||
request.put<{ success: boolean; code: number; message: string }>(`/admin/system/settings`, data)
|
||||
|
||||
export default {
|
||||
// 开发环境使用模拟数据
|
||||
const systemAPI = createMockWrapper({
|
||||
getServices,
|
||||
updateServiceStatus,
|
||||
startService,
|
||||
@@ -118,4 +132,6 @@ export default {
|
||||
getSystemLogs,
|
||||
getSystemSettings,
|
||||
updateSystemSettings
|
||||
}
|
||||
}, mockSystemAPI)
|
||||
|
||||
export default systemAPI
|
||||
@@ -1,4 +1,6 @@
|
||||
import { request } from '.'
|
||||
import { mockUserAPI } from './mockData'
|
||||
import { createMockWrapper } from '@/config/mock'
|
||||
|
||||
// 定义用户相关类型
|
||||
export interface User {
|
||||
@@ -101,11 +103,14 @@ export const updateUserStatus = (id: number, status: string) =>
|
||||
request.put<ApiResponse<User>>(`/users/${id}/status`, { status })
|
||||
|
||||
|
||||
export default {
|
||||
// 开发环境使用模拟数据
|
||||
const userAPI = createMockWrapper({
|
||||
getUsers,
|
||||
getUser,
|
||||
createUser,
|
||||
updateUser,
|
||||
deleteUser,
|
||||
batchUpdateUserStatus
|
||||
}
|
||||
}, mockUserAPI)
|
||||
|
||||
export default userAPI
|
||||
28
admin-system/src/config/mock.ts
Normal file
28
admin-system/src/config/mock.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
// 模拟数据配置
|
||||
import { mockAPI } from '@/api/mockData'
|
||||
|
||||
// 检查是否启用模拟模式
|
||||
const isMockMode = import.meta.env.VITE_USE_MOCK === 'true' || !import.meta.env.VITE_API_BASE_URL
|
||||
|
||||
// 模拟API包装器
|
||||
export const createMockWrapper = (realAPI: any, mockAPI: any) => {
|
||||
if (isMockMode) {
|
||||
console.log('🔧 使用模拟数据模式')
|
||||
return mockAPI
|
||||
}
|
||||
return realAPI
|
||||
}
|
||||
|
||||
// 替换真实API为模拟API(开发环境)
|
||||
if (isMockMode && import.meta.env.DEV) {
|
||||
console.log('🚀 开发环境启用模拟数据')
|
||||
|
||||
// 重写全局API对象
|
||||
const globalAPI = (window as any).$api = (window as any).$api || {}
|
||||
Object.assign(globalAPI, mockAPI)
|
||||
}
|
||||
|
||||
export default {
|
||||
isMockMode,
|
||||
mockAPI
|
||||
}
|
||||
44
admin-system/test-mock.js
Normal file
44
admin-system/test-mock.js
Normal file
@@ -0,0 +1,44 @@
|
||||
// 测试模拟数据功能
|
||||
const mockAPI = require('./src/api/mockData.ts')
|
||||
|
||||
console.log('🧪 测试模拟数据API...')
|
||||
|
||||
// 测试登录功能
|
||||
console.log('\n1. 测试登录功能')
|
||||
mockAPI.mockAuthAPI.login({ username: 'admin', password: 'admin123' })
|
||||
.then(response => {
|
||||
console.log('✅ 登录成功:', response.data.admin.username)
|
||||
return mockAPI.mockAuthAPI.getCurrentUser()
|
||||
})
|
||||
.then(response => {
|
||||
console.log('✅ 获取当前用户成功:', response.data.admin.nickname)
|
||||
})
|
||||
.catch(error => {
|
||||
console.log('❌ 登录测试失败:', error.message)
|
||||
})
|
||||
|
||||
// 测试用户列表
|
||||
console.log('\n2. 测试用户列表')
|
||||
mockAPI.mockUserAPI.getUsers({ page: 1, pageSize: 5 })
|
||||
.then(response => {
|
||||
console.log('✅ 获取用户列表成功:', response.data.list.length + '个用户')
|
||||
})
|
||||
.catch(error => {
|
||||
console.log('❌ 用户列表测试失败:', error.message)
|
||||
})
|
||||
|
||||
// 测试系统统计
|
||||
console.log('\n3. 测试系统统计')
|
||||
mockAPI.mockSystemAPI.getSystemStats()
|
||||
.then(response => {
|
||||
console.log('✅ 获取系统统计成功:')
|
||||
console.log(' - 用户数:', response.data.userCount)
|
||||
console.log(' - 商家数:', response.data.merchantCount)
|
||||
console.log(' - 旅行数:', response.data.travelCount)
|
||||
console.log(' - 动物数:', response.data.animalCount)
|
||||
})
|
||||
.catch(error => {
|
||||
console.log('❌ 系统统计测试失败:', error.message)
|
||||
})
|
||||
|
||||
console.log('\n🎉 模拟数据测试完成!')
|
||||
Reference in New Issue
Block a user