diff --git a/package.json b/package.json index 06b3e52..cf21d7a 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "dependencies": { "@dcloudio/uni-app": "^3.0.0-4080420251103001", "@dcloudio/uni-app-plus": "^3.0.0-4080420251103001", + "pinia": "^3.0.4", "vue": "^3.4.27" }, "devDependencies": { diff --git a/src/api.js b/src/api.js new file mode 100644 index 0000000..2d48c08 --- /dev/null +++ b/src/api.js @@ -0,0 +1,184 @@ +let BASE_URL = "https://apitest.shelingxingqiu.com/api/shoot"; // 默认正式版 + +function request(method, url, data = {}) { + const token = uni.getStorageSync("token"); + const header = {}; + if (token) header.Authorization = `Bearer ${token || ""}`; + return new Promise((resolve, reject) => { + uni.request({ + url: `${BASE_URL}${url}`, + method, + header, + data, + timeout: 10000, + success: (res) => { + if (res.data) { + const { code, data, message } = res.data; + if (code === 0) resolve(data); + else if (message) { + if (message.indexOf("登录身份已失效") !== -1) { + uni.removeStorageSync("token"); + } + if (message === "ROOM_FULL") { + resolve({ full: true }); + return; + } + if (message === "ERROR_ROOM_GAME_START") { + resolve({ started: true }); + return; + } + if (url.indexOf("/user/room") !== -1 && method === "GET") { + resolve({}); + return; + } + if (message === "ERROR_BATTLE_GAMING") { + resolve({}); + return; + } + if (message === "BIND_DEVICE") { + resolve({ binded: true }); + return; + } + if (message === "ERROR_ORDER_UNPAY") { + uni.showToast({ + title: "当前有未支付订单", + icon: "none", + }); + resolve({}); + return; + } + if (message === "ROOM_EMPTY") { + return uni.showToast({ + title: "房间已过期", + icon: "none", + }); + } + uni.showToast({ + title: message, + icon: "none", + }); + } + reject(""); + } + }, + fail: (err) => { + handleRequestError(err, url); + reject(err); + }, + }); + }); +} + +// 统一的错误处理函数 +function handleRequestError(err, url) { + console.log("请求失败:", { err, url }); + + // 根据错误类型显示不同提示 + if (err.errMsg) { + if (err.errMsg.includes("timeout")) { + showCustomToast("请求超时,请稍后重试", "timeout"); + } else if (err.errMsg.includes("fail")) { + // 检查网络状态 + uni.getNetworkType({ + success: (res) => { + if (res.networkType === "none") { + showCustomToast("网络连接已断开,请检查网络设置", "network"); + } else { + showCustomToast("服务器连接失败,请稍后重试", "server"); + } + }, + fail: () => { + showCustomToast("网络异常,请检查网络连接", "unknown"); + }, + }); + } else { + showCustomToast("请求失败,请稍后重试", "general"); + } + } else { + showCustomToast("网络异常,请稍后重试", "unknown"); + } +} + +// 自定义提示函数 +function showCustomToast(message, type) { + const config = { + title: message, + icon: "none", + duration: 3000, + }; + + // 根据错误类型可以添加不同的处理逻辑 + switch (type) { + case "timeout": + config.duration = 4000; // 超时提示显示更久 + break; + case "network": + config.duration = 5000; // 网络问题提示显示更久 + break; + default: + break; + } + + uni.showToast(config); +} + +export const getHomeData = (seasonId) => { + return request("GET", `/user/myHome?seasonId=${seasonId}`); +}; + +export const getPointBookConfigAPI = async () => { + return request("GET", "/user/score/sheet/option"); +}; + +export const getPointBookListAPI = async ( + page = 1, + bowType, + distance, + targetType +) => { + let url = `/user/score/sheet/list?pageNum=${page}&pageSize=10`; + if (bowType) url += `&bowType=${bowType}`; + if (distance) url += `&distance=${distance}`; + if (targetType) url += `&targetType=${targetType}`; + const result = await request("GET", url); + return result.list || []; +}; + +export const getPointBookStatisticsAPI = async () => { + return request("GET", `/v2/user/score/sheet/statistics`); +}; + +export const removePointRecord = async (id) => { + return request("DELETE", `/user/score/sheet/delete?id=${id}`); +}; + +export const getPointBookDetailAPI = async (id) => { + return request("GET", `/user/score/sheet/detail?id=${id}`); +}; + +export const addNoteAPI = async (id, remark) => { + return request("POST", "/user/score/sheet/remark", { id, remark }); +}; + +export const savePointBookAPI = async ( + bowType, + distance, + targetType, + groups, + arrows, + data = [] +) => { + return request("POST", "/user/score/sheet/report", { + bowType, + distance, + targetType, + groups, + arrows, + group_data: data.map((item) => + item.map((i) => ({ + ...i, + ring: i.ring === "M" ? -1 : i.ring === "X" ? 0 : Number(i.ring), + })) + ), + }); +}; diff --git a/src/components/AppBackground.vue b/src/components/AppBackground.vue new file mode 100644 index 0000000..3095318 --- /dev/null +++ b/src/components/AppBackground.vue @@ -0,0 +1,65 @@ + + + + + diff --git a/src/components/Avatar.vue b/src/components/Avatar.vue new file mode 100644 index 0000000..b8a5111 --- /dev/null +++ b/src/components/Avatar.vue @@ -0,0 +1,49 @@ + + + + + diff --git a/src/components/BowTargetEdit.vue b/src/components/BowTargetEdit.vue new file mode 100644 index 0000000..0af60ae --- /dev/null +++ b/src/components/BowTargetEdit.vue @@ -0,0 +1,349 @@ + + + + + diff --git a/src/components/Container.vue b/src/components/Container.vue new file mode 100644 index 0000000..5b3cfe4 --- /dev/null +++ b/src/components/Container.vue @@ -0,0 +1,73 @@ + + + + + diff --git a/src/components/EditOption.vue b/src/components/EditOption.vue new file mode 100644 index 0000000..a0c2772 --- /dev/null +++ b/src/components/EditOption.vue @@ -0,0 +1,452 @@ + + + + + diff --git a/src/components/Header.vue b/src/components/Header.vue new file mode 100644 index 0000000..53e5865 --- /dev/null +++ b/src/components/Header.vue @@ -0,0 +1,202 @@ + + + + + diff --git a/src/components/IconButton.vue b/src/components/IconButton.vue new file mode 100644 index 0000000..bc466dd --- /dev/null +++ b/src/components/IconButton.vue @@ -0,0 +1,39 @@ + + + + diff --git a/src/components/InputRow.vue b/src/components/InputRow.vue new file mode 100644 index 0000000..24ef818 --- /dev/null +++ b/src/components/InputRow.vue @@ -0,0 +1,84 @@ + + + + + diff --git a/src/components/PointRecord.vue b/src/components/PointRecord.vue new file mode 100644 index 0000000..0e9810d --- /dev/null +++ b/src/components/PointRecord.vue @@ -0,0 +1,141 @@ + + + + + diff --git a/src/components/RingBarChart.vue b/src/components/RingBarChart.vue new file mode 100644 index 0000000..6e14673 --- /dev/null +++ b/src/components/RingBarChart.vue @@ -0,0 +1,105 @@ + + + + + diff --git a/src/components/SButton.vue b/src/components/SButton.vue new file mode 100644 index 0000000..822ac9b --- /dev/null +++ b/src/components/SButton.vue @@ -0,0 +1,96 @@ + + + + + diff --git a/src/components/SModal.vue b/src/components/SModal.vue new file mode 100644 index 0000000..e963ec5 --- /dev/null +++ b/src/components/SModal.vue @@ -0,0 +1,107 @@ + + + + + diff --git a/src/components/ScreenHint.vue b/src/components/ScreenHint.vue new file mode 100644 index 0000000..333fe52 --- /dev/null +++ b/src/components/ScreenHint.vue @@ -0,0 +1,67 @@ + + + + + diff --git a/src/components/ScrollList.vue b/src/components/ScrollList.vue new file mode 100644 index 0000000..1ea4474 --- /dev/null +++ b/src/components/ScrollList.vue @@ -0,0 +1,96 @@ + + + + + diff --git a/src/heatmap.js b/src/heatmap.js new file mode 100644 index 0000000..e69de29 diff --git a/src/main.js b/src/main.js index f2a35f1..d42ca05 100644 --- a/src/main.js +++ b/src/main.js @@ -1,10 +1,12 @@ -import { createSSRApp } from 'vue' -import App from './App.vue' +import { createSSRApp } from "vue"; +import { createPinia } from "pinia"; +import App from "./App.vue"; export function createApp() { - const app = createSSRApp(App) + const app = createSSRApp(App); + const pinia = createPinia(); + app.use(pinia); return { - app - } + app, + }; } - diff --git a/src/manifest.json b/src/manifest.json index f03cf61..a774564 100644 --- a/src/manifest.json +++ b/src/manifest.json @@ -38,16 +38,16 @@ "ios" : { "appid" : "com.shelingxingqiu.arcx", "devices" : "iphone", - "deploymentTarget" : "13.0", - "mobileprovision" : "/Users/makaihong/Projects/point-book-app/DistributeProfile.mobileprovision", - "p12" : "/Users/makaihong/Projects/point-book-app/Distribute_pwd_123456.p12", - "password" : "123456", - "urltypes" : [ - { - "urlschemes" : [ "pointbook" ], - "id" : "com.pointbook.scheme" - } - ], + // "deploymentTarget" : "13.0", + // "mobileprovision" : "/Users/makaihong/Projects/point-book-app/DistributeProfile.mobileprovision", + // "p12" : "/Users/makaihong/Projects/point-book-app/Distribute_pwd_123456.p12", + // "password" : "123456", + // "urltypes" : [ + // { + // "urlschemes" : [ "pointbook" ], + // "id" : "com.pointbook.scheme" + // } + // ], "privacyDescription" : { "NSCameraUsageDescription" : "Camera access is required for taking photos and scanning", "NSMicrophoneUsageDescription" : "Microphone access is required for recording and calls", diff --git a/src/pages.json b/src/pages.json index 59019a2..e951881 100644 --- a/src/pages.json +++ b/src/pages.json @@ -1,16 +1,41 @@ { "pages": [ { - "path": "pages/index", - "style": { - "navigationBarTitleText": "ARCX" - } + "path": "pages/index" + }, + { + "path": "pages/create" + }, + { + "path": "pages/detail" + }, + { + "path": "pages/edit" + }, + { + "path": "pages/list" + }, + { + "path": "pages/profile" + }, + { + "path": "pages/reset-pwd" + }, + { + "path": "pages/signin" + }, + { + "path": "pages/signup" + }, + { + "path": "pages/edit-profile" } ], "globalStyle": { "navigationBarTextStyle": "white", "navigationBarBackgroundColor": "#2c3e50", - "backgroundColor": "#ffffff" + "backgroundColor": "#ffffff", + "navigationStyle": "custom" }, "condition": { "current": 0, diff --git a/src/pages/create.vue b/src/pages/create.vue new file mode 100644 index 0000000..41c01b9 --- /dev/null +++ b/src/pages/create.vue @@ -0,0 +1,152 @@ + + + + + diff --git a/src/pages/detail.vue b/src/pages/detail.vue new file mode 100644 index 0000000..66c131e --- /dev/null +++ b/src/pages/detail.vue @@ -0,0 +1,467 @@ + + +