Initial commit: Monisuo - 虚拟货币模拟交易平台

功能模块:
- 用户注册/登录/KYC
- 资金账户/交易账户
- 实时行情/币种管理
- 即时交易/充提审核
- 管理后台

技术栈:
- 后端: SpringBoot 2.2.4 + MyBatis Plus
- 前端: uni-app x (Vue3 + UTS)
- 数据库: MySQL

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
sion
2026-03-21 20:52:33 +08:00
commit 7694a34ade
108 changed files with 12563 additions and 0 deletions

43
app/api/asset.uts Normal file
View File

@@ -0,0 +1,43 @@
/**
* 资产API
*/
import { get, post } from './request.uts'
/**
* 获取资产总览
*/
export func getAssetOverview (): Promise<any> {
return get('/api/asset/overview', null)
}
/**
* 获取资金账户
*/
export func getFundAccount (): Promise<any> {
return get('/api/asset/fund', null)
}
/**
* 获取交易账户
*/
export func getTradeAccounts (): Promise<any> {
return get('/api/asset/trade', null)
}
/**
* 资金划转
*/
export func transfer (direction: number, amount: string): Promise<any> {
return post('/api/asset/transfer', { direction, amount } as UTSJSONObject)
}
/**
* 获取资金流水
*/
export func getFlows (flowType: number | null, pageNum: number, pageSize: number): Promise<any> {
const params: UTSJSONObject = { pageNum: pageNum, pageSize: pageSize }
if (flowType !== null) {
params['flowType'] = flowType
}
return get('/api/asset/flow', params)
}

36
app/api/fund.uts Normal file
View File

@@ -0,0 +1,36 @@
/**
* 充提API
*/
import { get, post } from './request.uts'
/**
* 申请充值
*/
export func deposit (amount: string, remark: string | null): Promise<any> {
return post('/api/fund/deposit', { amount, remark } as UTSJSONObject)
}
/**
* 申请提现
*/
export func withdraw (amount: string, remark: string | null): Promise<any> {
return post('/api/fund/withdraw', { amount, remark } as UTSJSONObject)
}
/**
* 取消订单
*/
export func cancelOrder (orderNo: string): Promise<any> {
return post('/api/fund/cancel', { orderNo } as UTSJSONObject)
}
/**
* 获取充提记录
*/
export func getOrders (type: number | null, pageNum: number, pageSize: number): Promise<any> {
const params: UTSJSONObject = { pageNum: pageNum, pageSize: pageSize }
if (type !== null) {
params['type'] = type
}
return get('/api/fund/orders', params)
}

9
app/api/index.uts Normal file
View File

@@ -0,0 +1,9 @@
/**
* API 统一导出
*/
export * from './request.uts'
export * from './user.uts'
export * from './market.uts'
export * from './asset.uts'
export * from './trade.uts'
export * from './fund.uts'

25
app/api/market.uts Normal file
View File

@@ -0,0 +1,25 @@
/**
* 行情API
*/
import { get } from './request.uts'
/**
* 获取币种列表
*/
export func getCoinList (): Promise<any> {
return get('/api/market/list', null)
}
/**
* 获取币种详情
*/
export func getCoinDetail (code: string): Promise<any> {
return get('/api/market/detail', { code } as UTSJSONObject)
}
/**
* 搜索币种
*/
export func searchCoins (keyword: string): Promise<any> {
return get('/api/market/search', { keyword } as UTSJSONObject)
}

130
app/api/request.uts Normal file
View File

@@ -0,0 +1,130 @@
/**
* 网络请求封装 - 模拟所APP
*/
// API 基础地址(生产环境服务器地址)
const BASE_URL: string = 'http://8.155.172.147:5010'
// 请求超时时间
const TIMEOUT: number = 30000
// 响应数据类型
type ResponseData = {
code: string
msg: string
data: any
}
// 请求配置类型
type RequestOptions = {
url: string
method?: string
data?: UTSJSONObject | null
header?: UTSJSONObject | null
timeout?: number
loading?: boolean
loadingText?: string
}
/**
* 请求拦截器
*/
func requestInterceptor (config: RequestOptions): RequestOptions {
const token = uni.getStorageSync('token') as string
if (token !== null && token !== '') {
config.header = {
...config.header,
'Authorization': `Bearer ${token}`
} as UTSJSONObject
}
config.header = {
'Content-Type': 'application/json',
...config.header
} as UTSJSONObject
return config
}
/**
* 响应拦截器
*/
func responseInterceptor (response: UniRequestSuccessCallbackResult): Promise<ResponseData> {
const statusCode: number = response.statusCode
const data = response.data as ResponseData
if (statusCode === 200) {
if (data.code === '0000') {
return Promise.resolve(data)
} else if (data.code === '0002') {
uni.removeStorageSync('token')
uni.reLaunch({ url: '/pages/login/login' })
return Promise.reject(new Error(data.msg || '请重新登录'))
} else {
uni.showToast({ title: data.msg || '请求失败', icon: 'none', duration: 2000 })
return Promise.reject(new Error(data.msg))
}
} else if (statusCode === 401) {
uni.removeStorageSync('token')
uni.reLaunch({ url: '/pages/login/login' })
return Promise.reject(new Error('未授权'))
} else {
return Promise.reject(new Error(`网络错误: ${statusCode}`))
}
}
/**
* 通用请求方法
*/
func request (options: RequestOptions): Promise<ResponseData> {
let config: RequestOptions = {
url: options.url.startsWith('http') ? options.url : BASE_URL + options.url,
method: options.method || 'GET',
data: options.data || null,
header: options.header || null,
timeout: options.timeout || TIMEOUT
}
config = requestInterceptor(config)
const showLoading = options.loading !== false
if (showLoading) {
uni.showLoading({ title: options.loadingText || '加载中...', mask: true })
}
return new Promise((resolve, reject) => {
uni.request({
url: config.url,
method: config.method as UniRequestMethod,
data: config.data,
header: config.header,
timeout: config.timeout,
success: (response: UniRequestSuccessCallbackResult) => {
responseInterceptor(response).then(resolve).catch(reject)
},
fail: (error: UniRequestFailCallbackResult) => {
uni.showToast({ title: error.errMsg || '网络请求失败', icon: 'none', duration: 2000 })
reject(new Error(error.errMsg))
},
complete: () => {
if (showLoading) uni.hideLoading()
}
})
})
}
/**
* GET 请求
*/
export func get (url: string, params: UTSJSONObject | null = null): Promise<ResponseData> {
return request({ url, method: 'GET', data: params })
}
/**
* POST 请求
*/
export func post (url: string, data: UTSJSONObject | null = null): Promise<ResponseData> {
return request({ url, method: 'POST', data: data })
}
export const config = { BASE_URL, TIMEOUT }

39
app/api/trade.uts Normal file
View File

@@ -0,0 +1,39 @@
/**
* 交易API
*/
import { get, post } from './request.uts'
/**
* 买入
*/
export func buy (coinCode: string, price: string, quantity: string): Promise<any> {
return post('/api/trade/buy', { coinCode, price, quantity } as UTSJSONObject)
}
/**
* 卖出
*/
export func sell (coinCode: string, price: string, quantity: string): Promise<any> {
return post('/api/trade/sell', { coinCode, price, quantity } as UTSJSONObject)
}
/**
* 获取交易记录
*/
export func getOrders (coinCode: string | null, direction: number | null, pageNum: number, pageSize: number): Promise<any> {
const params: UTSJSONObject = { pageNum: pageNum, pageSize: pageSize }
if (coinCode !== null) {
params['coinCode'] = coinCode
}
if (direction !== null) {
params['direction'] = direction
}
return get('/api/trade/orders', params)
}
/**
* 获取订单详情
*/
export func getOrderDetail (orderNo: string): Promise<any> {
return get('/api/trade/order/detail', { orderNo } as UTSJSONObject)
}

39
app/api/user.uts Normal file
View File

@@ -0,0 +1,39 @@
/**
* 用户API
*/
import { get, post } from './request.uts'
/**
* 用户登录
*/
export func login (username: string, password: string): Promise<any> {
return post('/api/user/login', { username, password } as UTSJSONObject)
}
/**
* 用户注册
*/
export func register (username: string, password: string): Promise<any> {
return post('/api/user/register', { username, password } as UTSJSONObject)
}
/**
* 获取用户信息
*/
export func getUserInfo (): Promise<any> {
return get('/api/user/info', null)
}
/**
* 上传KYC资料
*/
export func uploadKyc (idCardFront: string, idCardBack: string): Promise<any> {
return post('/api/user/kyc', { idCardFront, idCardBack } as UTSJSONObject)
}
/**
* 退出登录
*/
export func logout (): Promise<any> {
return post('/api/user/logout', null)
}