初始化参股

This commit is contained in:
2026-01-27 18:06:04 +08:00
commit 2774a539bf
254 changed files with 33255 additions and 0 deletions

57
前端/utils/api-test.uts Normal file
View File

@@ -0,0 +1,57 @@
/**
* API测试文件 - 测试前后端对接
*/
import { getCaseList, getBanners, getActiveServices } from '@/api/index.uts'
// 测试案例列表API
export const testCaseListAPI = async () => {
try {
console.log('测试案例列表API...')
const res = await getCaseList()
console.log('案例列表API响应:', res)
return res
} catch (error) {
console.error('案例列表API错误:', error)
throw error
}
}
// 测试轮播图API
export const testBannersAPI = async () => {
try {
console.log('测试轮播图API...')
const res = await getBanners()
console.log('轮播图API响应:', res)
return res
} catch (error) {
console.error('轮播图API错误:', error)
throw error
}
}
// 测试服务列表API
export const testServicesAPI = async () => {
try {
console.log('测试服务列表API...')
const res = await getActiveServices()
console.log('服务列表API响应:', res)
return res
} catch (error) {
console.error('服务列表API错误:', error)
throw error
}
}
// 运行所有测试
export const runAllTests = async () => {
console.log('开始API对接测试...')
try {
await testBannersAPI()
await testCaseListAPI()
await testServicesAPI()
console.log('所有API测试完成')
} catch (error) {
console.error('API测试失败:', error)
}
}

73
前端/utils/config.uts Normal file
View File

@@ -0,0 +1,73 @@
/**
* 项目配置文件
*/
// 环境配置
export const ENV = {
// 开发环境
development: {
baseUrl: 'http://localhost:3000/api',
imageBaseUrl: 'http://localhost:3000'
},
// 生产环境
production: {
baseUrl: 'https://api.youyijia.com/api',
imageBaseUrl: 'https://api.youyijia.com'
}
}
// 当前环境 - 切换为 'production' 上线
export const currentEnv = 'development'
// 获取当前环境配置
export const getEnvConfig = () : UTSJSONObject => {
if (currentEnv == 'production') {
return {
baseUrl: ENV.production.baseUrl,
imageBaseUrl: ENV.production.imageBaseUrl
} as UTSJSONObject
}
return {
baseUrl: ENV.development.baseUrl,
imageBaseUrl: ENV.development.imageBaseUrl
} as UTSJSONObject
}
// 是否使用Mock数据 - 已关闭,对接真实后端
export const useMock = false
// 分页配置
export const PAGE_SIZE = 10
// 图片上传配置
export const UPLOAD_CONFIG = {
maxSize: 5 * 1024 * 1024, // 5MB
maxCount: 9,
accept: ['image/jpeg', 'image/png', 'image/gif']
}
// 缓存Key
export const STORAGE_KEYS = {
TOKEN: 'user_token',
USER_INFO: 'user_info',
FAVORITES: 'user_favorites',
SEARCH_HISTORY: 'search_history'
}
// 沙发分类
export const SOFA_CATEGORIES = [
{ id: 'all', name: '全部' },
{ id: 'leather', name: '皮沙发' },
{ id: 'fabric', name: '布艺沙发' },
{ id: 'functional', name: '功能沙发' },
{ id: 'antique', name: '古典沙发' },
{ id: 'office', name: '办公沙发' }
]
// 翻新服务类型
export const SERVICE_TYPES = [
{ id: 'repair', name: '局部修复', icon: '/static/icons/repair.png' },
{ id: 'recolor', name: '改色翻新', icon: '/static/icons/recolor.png' },
{ id: 'refurbish', name: '整体翻新', icon: '/static/icons/refurbish.png' },
{ id: 'custom', name: '定制换皮', icon: '/static/icons/custom.png' }
]

249
前端/utils/mock.uts Normal file
View File

@@ -0,0 +1,249 @@
/**
* Mock数据 - 开发阶段使用
* 后端开发完成后可关闭
*/
// 轮播图数据
const bannerList = [
{
id: '1',
image: '/static/mock/banner1.svg',
title: '专业沙发翻新服务',
link: '/pages/service/index'
},
{
id: '2',
image: '/static/mock/banner2.svg',
title: '十年品质保证',
link: '/pages/about/index'
},
{
id: '3',
image: '/static/mock/banner3.svg',
title: '免费上门评估',
link: '/pages/booking/index'
}
]
// 案例数据
const caseList = [
{
id: '1',
title: '欧式真皮沙发翻新',
category: 'leather',
categoryName: '皮沙发',
beforeImages: ['/static/mock/case1-before.svg'],
afterImages: ['/static/mock/case1-after.svg'],
coverImage: '/static/mock/case1-after.svg',
description: '这款欧式真皮沙发使用多年后出现皮面老化、褪色问题,经过我们专业的翻新处理,焕然一新。采用进口头层牛皮,色泽均匀,手感细腻。',
material: '进口头层牛皮',
duration: '7天',
price: '¥3800',
views: 1256,
likes: 89,
createTime: '2026-01-15'
},
{
id: '2',
title: '现代简约布艺沙发翻新',
category: 'fabric',
categoryName: '布艺沙发',
beforeImages: ['/static/mock/case2-before.svg'],
afterImages: ['/static/mock/case2-after.svg'],
coverImage: '/static/mock/case2-after.svg',
description: '布艺沙发使用时间长了容易脏污、起球,这款沙发经过整体换布处理,选用高品质科技布,防水防污,易于打理。',
material: '高品质科技布',
duration: '5天',
price: '¥2200',
views: 986,
likes: 67,
createTime: '2026-01-12'
},
{
id: '3',
title: '美式复古沙发改色翻新',
category: 'leather',
categoryName: '皮沙发',
beforeImages: ['/static/mock/case3-before.svg'],
afterImages: ['/static/mock/case3-after.svg'],
coverImage: '/static/mock/case3-after.svg',
description: '客户希望将原本深棕色的沙发改为更现代的米白色,我们采用专业改色工艺,色泽持久不脱落,触感保持柔软。',
material: '专业皮革改色',
duration: '6天',
price: '¥2800',
views: 756,
likes: 45,
createTime: '2026-01-10'
},
{
id: '4',
title: '功能沙发维修翻新',
category: 'functional',
categoryName: '功能沙发',
beforeImages: ['/static/mock/case4-before.svg'],
afterImages: ['/static/mock/case4-after.svg'],
coverImage: '/static/mock/case4-after.svg',
description: '功能沙发的电动机构出现故障,同时皮面也有磨损。我们更换了电机和控制系统,并对皮面进行了局部修复。',
material: '原装配件+局部修复',
duration: '4天',
price: '¥1800',
views: 623,
likes: 38,
createTime: '2026-01-08'
},
{
id: '5',
title: '中式红木沙发垫翻新',
category: 'antique',
categoryName: '古典沙发',
beforeImages: ['/static/mock/case5-before.svg'],
afterImages: ['/static/mock/case5-after.svg'],
coverImage: '/static/mock/case5-after.svg',
description: '红木沙发的坐垫和靠垫使用多年已经塌陷变形,我们重新填充高密度海绵,并更换了丝绸面料,古典韵味十足。',
material: '高密度海绵+丝绸面料',
duration: '5天',
price: '¥2500',
views: 512,
likes: 32,
createTime: '2026-01-05'
},
{
id: '6',
title: '办公室皮沙发组合翻新',
category: 'office',
categoryName: '办公沙发',
beforeImages: ['/static/mock/case6-before.svg'],
afterImages: ['/static/mock/case6-after.svg'],
coverImage: '/static/mock/case6-after.svg',
description: '企业办公室的沙发组合整体翻新包括一套3+1+1沙发。采用耐磨商务皮革简约大气提升企业形象。',
material: '商务耐磨皮革',
duration: '10天',
price: '¥8800',
views: 445,
likes: 28,
createTime: '2026-01-02'
}
]
// 服务流程数据
const serviceProcess = [
{
step: 1,
title: '在线预约',
description: '通过小程序或电话预约上门服务',
icon: '/static/icons/step1.png'
},
{
step: 2,
title: '上门评估',
description: '专业师傅免费上门查看沙发状况',
icon: '/static/icons/step2.png'
},
{
step: 3,
title: '方案报价',
description: '根据沙发情况提供翻新方案和报价',
icon: '/static/icons/step3.png'
},
{
step: 4,
title: '确认订单',
description: '确认方案后签订服务合同',
icon: '/static/icons/step4.png'
},
{
step: 5,
title: '专业翻新',
description: '工厂或上门进行专业翻新作业',
icon: '/static/icons/step5.png'
},
{
step: 6,
title: '验收交付',
description: '翻新完成后客户验收,满意付款',
icon: '/static/icons/step6.png'
}
]
// 公司信息
const companyInfo = {
name: '优艺家沙发翻新',
slogan: '让旧沙发焕发新生',
description: '优艺家是一家专业从事沙发翻新、维修、改色的服务公司,拥有十余年行业经验。我们秉承"品质至上、客户第一"的服务理念,为千家万户提供专业的沙发翻新服务。',
phone: '400-888-8888',
wechat: 'youyijia2026',
address: '上海市浦东新区张江高科技园区',
workTime: '周一至周日 9:00-18:00',
features: [
{ title: '专业团队', desc: '10年+从业经验' },
{ title: '品质保证', desc: '质保期内免费维护' },
{ title: '上门服务', desc: '免费上门评估' },
{ title: '价格透明', desc: '无隐形消费' }
]
}
/**
* 获取Mock数据
*/
export const getMockData = (url : string, method : string, params ?: UTSJSONObject | null) : any | null => {
// 轮播图
if (url == '/banners') {
return bannerList
}
// 案例列表
if (url == '/cases' && method == 'GET') {
const category = params?.['category'] as string | null
const page = (params?.['page'] ?? 1) as number
const pageSize = (params?.['pageSize'] ?? 10) as number
let filteredList = caseList
if (category != null && category != '' && category != 'all') {
filteredList = caseList.filter((item) : boolean => item.category == category)
}
const start = (page - 1) * pageSize
const end = start + pageSize
const list = filteredList.slice(start, end)
return {
list: list,
total: filteredList.length,
page: page,
pageSize: pageSize
}
}
// 案例详情
if (url.startsWith('/cases/') && method == 'GET') {
const id = url.replace('/cases/', '')
const caseItem = caseList.find((item) : boolean => item.id == id)
return caseItem
}
// 热门案例
if (url == '/cases/hot') {
return caseList.slice(0, 4)
}
// 服务流程
if (url == '/service/process') {
return serviceProcess
}
// 公司信息
if (url == '/company/info') {
return companyInfo
}
// 提交预约
if (url == '/booking' && method == 'POST') {
return {
bookingId: 'BK' + Date.now().toString(),
status: 'pending',
message: '预约成功,我们会尽快与您联系'
}
}
return null
}

174
前端/utils/request.uts Normal file
View File

@@ -0,0 +1,174 @@
/**
* 网络请求封装
* 预留后端接口对接
*/
import { getEnvConfig, useMock, STORAGE_KEYS } from './config.uts'
import { getMockData } from './mock.uts'
// 请求配置类型
type RequestOptions = {
url : string
method ?: 'GET' | 'POST' | 'PUT' | 'DELETE'
data ?: UTSJSONObject | null
header ?: UTSJSONObject | null
showLoading ?: boolean
loadingText ?: string
}
// 响应数据类型
type ResponseData = {
code : number
message : string
data : any
}
/**
* 请求拦截器
*/
const requestInterceptor = (options : RequestOptions) : RequestOptions => {
// 添加token
const token = uni.getStorageSync(STORAGE_KEYS.TOKEN) as string
if (token != '') {
if (options.header == null) {
options.header = {} as UTSJSONObject
}
options.header!['Authorization'] = `Bearer ${token}`
}
return options
}
/**
* 响应拦截器
*/
const responseInterceptor = (response : UTSJSONObject) : ResponseData => {
const statusCode = response['statusCode'] as number
const data = response['data'] as UTSJSONObject
if (statusCode == 200) {
const code = (data['code'] ?? 0) as number
if (code == 0 || code == 200) {
return {
code: 0,
message: 'success',
data: data['data']
} as ResponseData
} else if (code == 401) {
// token过期,跳转登录
uni.removeStorageSync(STORAGE_KEYS.TOKEN)
uni.showToast({
title: '请重新登录',
icon: 'none'
})
return {
code: code,
message: (data['message'] ?? '请重新登录') as string,
data: null
} as ResponseData
} else {
return {
code: code,
message: (data['message'] ?? '请求失败') as string,
data: null
} as ResponseData
}
} else {
return {
code: statusCode,
message: '网络请求失败',
data: null
} as ResponseData
}
}
/**
* 统一请求方法
*/
export const request = (options : RequestOptions) : Promise<ResponseData> => {
return new Promise((resolve, reject) => {
// 使用Mock数据
if (useMock) {
const mockData = getMockData(options.url, options.method ?? 'GET', options.data)
if (mockData != null) {
setTimeout(() => {
resolve({
code: 0,
message: 'success',
data: mockData
} as ResponseData)
}, 300) // 模拟网络延迟
return
}
}
// 请求拦截
const finalOptions = requestInterceptor(options)
// 显示loading
if (finalOptions.showLoading == true) {
uni.showLoading({
title: finalOptions.loadingText ?? '加载中...'
})
}
const config = getEnvConfig()
const baseUrl = config['baseUrl'] as string
uni.request({
url: baseUrl + finalOptions.url,
method: finalOptions.method ?? 'GET',
data: finalOptions.data as UTSJSONObject | null,
header: finalOptions.header as UTSJSONObject | null,
success: (res) => {
if (finalOptions.showLoading == true) {
uni.hideLoading()
}
const result = responseInterceptor(res as UTSJSONObject)
if (result.code == 0) {
resolve(result)
} else {
uni.showToast({
title: result.message,
icon: 'none'
})
reject(result)
}
},
fail: (err) => {
if (finalOptions.showLoading == true) {
uni.hideLoading()
}
uni.showToast({
title: '网络连接失败',
icon: 'none'
})
reject({
code: -1,
message: '网络连接失败',
data: null
} as ResponseData)
}
})
})
}
/**
* GET请求
*/
export const get = (url : string, data ?: UTSJSONObject | null) : Promise<ResponseData> => {
return request({
url: url,
method: 'GET',
data: data
} as RequestOptions)
}
/**
* POST请求
*/
export const post = (url : string, data ?: UTSJSONObject | null) : Promise<ResponseData> => {
return request({
url: url,
method: 'POST',
data: data
} as RequestOptions)
}