计分本配置接口接入

This commit is contained in:
kron
2025-08-04 16:28:34 +08:00
parent 54a51d2a28
commit 97d23aa731
9 changed files with 181 additions and 129 deletions

View File

@@ -15,7 +15,7 @@ function request(method, url, data = {}) {
if (res.data) {
const { code, data, message } = res.data;
if (code === 0) resolve(data);
else {
else if (message) {
if (message.indexOf("登录身份已失效") !== -1) {
uni.removeStorageSync("token");
}
@@ -38,7 +38,6 @@ function request(method, url, data = {}) {
if (message === "BIND_DEVICE") {
resolve({ binded: true });
return;
}
if (message === "ERROR_ORDER_UNPAY") {
uni.showToast({
@@ -65,17 +64,17 @@ function request(method, url, data = {}) {
// 统一的错误处理函数
function handleRequestError(err, url) {
console.log('请求失败:', { err, url });
console.log("请求失败:", { err, url });
// 根据错误类型显示不同提示
if (err.errMsg) {
if (err.errMsg.includes('timeout')) {
if (err.errMsg.includes("timeout")) {
showCustomToast("请求超时,请稍后重试", "timeout");
} else if (err.errMsg.includes('fail')) {
} else if (err.errMsg.includes("fail")) {
// 检查网络状态
uni.getNetworkType({
success: (res) => {
if (res.networkType === 'none') {
if (res.networkType === "none") {
showCustomToast("网络连接已断开,请检查网络设置", "network");
} else {
showCustomToast("服务器连接失败,请稍后重试", "server");
@@ -83,7 +82,7 @@ function handleRequestError(err, url) {
},
fail: () => {
showCustomToast("网络异常,请检查网络连接", "unknown");
}
},
});
} else {
showCustomToast("请求失败,请稍后重试", "general");
@@ -98,21 +97,21 @@ function showCustomToast(message, type) {
const config = {
title: message,
icon: "none",
duration: 3000
duration: 3000,
};
// 根据错误类型可以添加不同的处理逻辑
switch (type) {
case 'timeout':
case "timeout":
config.duration = 4000; // 超时提示显示更久
break;
case 'network':
case "network":
config.duration = 5000; // 网络问题提示显示更久
break;
default:
break;
}
uni.showToast(config);
}
@@ -364,3 +363,14 @@ export const getCurrentGameAPI = async () => {
const result = await request("GET", "/user/join/battle");
return result.currentGame || {};
};
export const getPointBookConfigAPI = async () => {
return request("GET", "/user/score/sheet/option");
};
export const getPointBookListAPI = async (page = 1, size = 10) => {
return request(
"GET",
`/user/score/sheet/list?pageNum=${page}&pageSize=${size}`
);
};

View File

@@ -3,6 +3,14 @@ import { ref, onMounted } from "vue";
import { getElementRect, calcRing } from "@/util";
const props = defineProps({
id: {
type: Number,
default: 0,
},
src: {
type: String,
default: "",
},
arrows: {
type: Array,
default: () => [],
@@ -26,6 +34,7 @@ const onClick = async (e) => {
y: e.detail.y - rect.value.top - 10,
};
newArrow.ring = calcRing(
props.id,
newArrow.x,
newArrow.y,
rect.value.width * 0.9,
@@ -72,7 +81,13 @@ const onDrag = async (e) => {
// 更新坐标
arrow.value.x = Math.max(0, Math.min(width, arrow.value.x + deltaX));
arrow.value.y = Math.max(0, Math.min(height, arrow.value.y + deltaY));
arrow.value.ring = calcRing(arrow.value.x, arrow.value.y, width, height);
arrow.value.ring = calcRing(
props.id,
arrow.value.x,
arrow.value.y,
width,
height
);
// 更新拖拽起始位置
dragStartPos.value = { x: clientX, y: clientY };
@@ -96,7 +111,7 @@ onMounted(async () => {
@touchmove="onDrag"
@touchend="endDrag"
>
<image src="../static/bow-target.png" mode="widthFix" />
<image :src="src" mode="widthFix" />
<view
v-for="(arrow, index) in arrows"
:key="index"

View File

@@ -26,59 +26,21 @@ const props = defineProps({
default: "",
},
});
const bowTypes = [
{
name: "反曲弓",
image:
"https://api.shelingxingqiu.com/attachment/2025-07-28/dbnincayxdzicpeidq.png",
},
{
name: "复合弓",
image:
"https://api.shelingxingqiu.com/attachment/2025-07-28/dbnincawegb0dhs0sw.png",
},
{
name: "美洲猎弓",
image:
"https://api.shelingxingqiu.com/attachment/2025-07-28/dbnincaxxeqlufc3nl.png",
},
{
name: "传统弓",
image:
"https://api.shelingxingqiu.com/attachment/2025-07-28/dbnincastq3c3xkzdu.png",
},
{
name: "光弓",
image:
"https://api.shelingxingqiu.com/attachment/2025-07-28/dbnincaur573p7lxh7.png",
},
];
const itemTexts = ["选择弓种", "选择练习距离", "选择靶纸", "选择组/箭数"];
const distances = [5, 8, 10, 18, 25, 30, 50, 60, 70];
const bowtargetTypes = [
"40全环靶",
"80全环靶",
"122全环靶",
"40半环靶",
"60半环靶",
"80半环靶",
"三连靶",
"品字靶",
"复合三连靶",
"复合品字靶",
];
const groupArrows = [3, 6, 12, 18];
const data = ref([]);
const selectedIndex = ref(-1);
const secondSelectIndex = ref(-1);
const onSelectItem = (index) => {
selectedIndex.value = index;
if (props.itemIndex === 0) {
props.onSelect(props.itemIndex, bowTypes[index].name);
props.onSelect(props.itemIndex, data.value[index]);
} else if (props.itemIndex === 1) {
props.onSelect(props.itemIndex, distances[index]);
} else if (props.itemIndex === 2) {
props.onSelect(props.itemIndex, bowtargetTypes[index]);
props.onSelect(props.itemIndex, data.value[index]);
} else if (props.itemIndex === 3 && secondSelectIndex.value !== -1) {
props.onSelect(
props.itemIndex,
@@ -104,8 +66,8 @@ watch(
() => props.value,
(newValue) => {
if (!newValue) return;
if (props.itemIndex === 0) {
bowTypes.forEach((item, index) => {
if (props.itemIndex === 0 || props.itemIndex === 2) {
data.value.forEach((item, index) => {
if (item.name === newValue) {
selectedIndex.value = index;
}
@@ -121,15 +83,19 @@ watch(
}
});
}
if (props.itemIndex === 2) {
bowtargetTypes.forEach((item, index) => {
if (item === newValue) {
selectedIndex.value = index;
}
});
}
}
);
onMounted(() => {
const config = uni.getStorageSync("point-book-config");
if (config) {
if (props.itemIndex === 0) {
data.value = config.bowOption;
} else if (props.itemIndex === 2) {
data.value = config.targetOption;
}
// props.onSelect(props.itemIndex, config[props.itemIndex]);
}
});
</script>
<template>
@@ -171,14 +137,14 @@ watch(
</view>
<view v-if="itemIndex === 0" class="bow-items">
<view
v-for="(item, index) in bowTypes"
v-for="(item, index) in data"
:key="index"
:style="{
borderColor: selectedIndex === index ? '#fed847' : '#eeeeee',
}"
@click="onSelectItem(index)"
>
<image :src="item.image" mode="widthFix" />
<image :src="item.icon" mode="widthFix" />
<text>{{ item.name }}</text>
</view>
</view>
@@ -211,15 +177,15 @@ watch(
</view>
<view v-if="itemIndex === 2" class="bowtarget-items">
<view
v-for="(item, index) in bowtargetTypes"
v-for="(item, index) in data"
:key="index"
:style="{
borderColor: selectedIndex === index ? '#fed847' : '#eeeeee',
}"
@click="onSelectItem(index)"
>
<text>{{ item.substring(0, item.length - 3) }}</text>
<text>{{ item.substring(item.length - 3) }}</text>
<text>{{ item.name.substring(0, item.name.length - 3) }}</text>
<text>{{ item.name.substring(item.name.length - 3) }}</text>
</view>
</view>
<view v-if="itemIndex === 3">
@@ -236,7 +202,8 @@ watch(
<text></text>
</view>
</view>
<view :style="{ marginTop: '5px', marginBottom: '10px' }"
<view
:style="{ marginTop: '5px', marginBottom: '10px', color: '#999999' }"
>选择每组的箭数</view
>
<view class="amount-items">

View File

@@ -97,17 +97,17 @@ onUnmounted(() => {
class="loading"
/>
<view v-if="pointBook" class="point-book-info">
<text>{{ pointBook.bowType }}</text>
<text>{{ pointBook.bowType.name }}</text>
<text>{{ pointBook.distance }} </text>
<text
>{{
pointBook.bowtargetType.substring(
pointBook.bowtargetType.name.substring(
0,
pointBook.bowtargetType.length - 3
pointBook.bowtargetType.name.length - 3
)
}}
{{
pointBook.bowtargetType.substring(pointBook.bowtargetType.length - 3)
pointBook.bowtargetType.name.substring(pointBook.bowtargetType.name.length - 3)
}}</text
>
</view>

View File

@@ -3,15 +3,23 @@ import { ref, onMounted, onUnmounted } from "vue";
import Container from "@/components/Container.vue";
import EditOption from "@/components/EditOption.vue";
import SButton from "@/components/SButton.vue";
import { getPointBookConfigAPI } from "@/apis";
const clickable = ref(false);
const expandIndex = ref(-1);
const bowType = ref("");
const bowType = ref({});
const distance = ref(0);
const bowtargetType = ref("");
const amountGroup = ref("");
const onExpandChange = (index, expand) => {
expandIndex.value = !expand ? -1 : index;
if (expandIndex.value !== -1) {
expandIndex.value = -1;
setTimeout(() => {
expandIndex.value = !expand ? -1 : index;
}, 100);
} else {
expandIndex.value = !expand ? -1 : index;
}
};
const toListPage = () => {
@@ -41,11 +49,16 @@ const onSelect = (itemIndex, value) => {
}
};
const toEditPage = () => {
expandIndex.value = -1;
uni.navigateTo({
url: "/pages/point-book-edit",
});
};
onMounted(() => {
onMounted(async () => {
const config = await getPointBookConfigAPI();
if (config) {
uni.setStorageSync("point-book-config", config);
}
const pointBook = uni.getStorageSync("point-book");
if (pointBook) {
bowType.value = pointBook.bowType;
@@ -73,7 +86,7 @@ onMounted(() => {
:expand="expandIndex === 0"
:onExpand="onExpandChange"
:onSelect="onSelect"
:value="bowType"
:value="bowType.name"
/>
<EditOption
:itemIndex="1"
@@ -87,7 +100,7 @@ onMounted(() => {
:expand="expandIndex === 2"
:onExpand="onExpandChange"
:onSelect="onSelect"
:value="bowtargetType"
:value="bowtargetType.name"
/>
<EditOption
:itemIndex="3"

View File

@@ -12,17 +12,20 @@ const amount = ref(0);
const currentGroup = ref(1);
const currentArrow = ref(0);
const arrowGroups = ref({});
const ringColors = [
"#FADB80",
"#FADB80",
"#FADB80",
"#F97E81",
"#F97E81",
"#7AC7FF",
"#7AC7FF",
"#9B9B9B",
"#9B9B9B",
];
const bowtarget = ref({});
const ringTypes = ref([
{ ring: "X", color: "#FADB80" },
{ ring: "10", color: "#FADB80" },
{ ring: "9", color: "#FADB80" },
{ ring: "8", color: "#F97E81" },
{ ring: "7", color: "#F97E81" },
{ ring: "6", color: "#7AC7FF" },
{ ring: "5", color: "#7AC7FF" },
{ ring: "4", color: "#9B9B9B" },
{ ring: "3", color: "#9B9B9B" },
{ ring: "2", color: "#d8d8d8" },
{ ring: "1", color: "#d8d8d8" },
]);
const onEdit = (arrows) => {
arrowGroups.value[currentGroup.value][currentArrow.value] = { ring };
@@ -61,6 +64,15 @@ const onEditDone = (arrow) => {
onMounted(() => {
const pointBook = uni.getStorageSync("point-book");
if (pointBook.bowtargetType) {
bowtarget.value = pointBook.bowtargetType;
if (bowtarget.value.id > 3) {
ringTypes.value = ringTypes.value.slice(0, 6);
if (bowtarget.value.id > 8) {
ringTypes.value = ringTypes.value.slice(1);
}
}
}
if (pointBook.amountGroup) {
groups.value = Number(pointBook.amountGroup.split("/")[0]);
amount.value = Number(pointBook.amountGroup.split("/")[1]);
@@ -82,6 +94,8 @@ onMounted(() => {
<BowTargetEdit
:onChange="onEditDone"
:arrows="arrowGroups[currentGroup]"
:id="bowtarget.id"
:src="bowtarget.icon"
/>
<view class="title-bar">
<view>
@@ -114,15 +128,18 @@ onMounted(() => {
</view>
<text>输入分值的情况下系统不提供落点稳定性分</text>
<view class="bow-rings">
<view @click="() => onClickRing('X')">X</view>
<view
v-for="i in 10"
:key="i"
@click="() => onClickRing(11 - i)"
:style="{ backgroundColor: ringColors[i] || '#d8d8d8' }"
>{{ 11 - i }}</view
v-for="(item, index) in ringTypes"
:key="index"
@click="() => onClickRing(item.ring)"
:style="{ backgroundColor: item.color }"
>{{ item.ring }}</view
>
<view
:style="{ backgroundColor: '#d8d8d8' }"
@click="() => onClickRing('M')"
>M</view
>
<view @click="() => onClickRing('M')">M</view>
</view>
<ScreenHint2 :show="showTip">
<view class="tip-content">
@@ -188,9 +205,6 @@ onMounted(() => {
color: #fff;
background-color: #d8d8d8;
}
.bow-rings > view:first-child {
background-color: #fadb80;
}
.tip-content {
width: 100%;
padding: 25px;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

View File

@@ -296,7 +296,7 @@ export const getElementRect = () => {
});
};
export const calcRing = (x, y, targetWidth, targetHeight) => {
const calcNormalBowTarget = (x, y, targetWidth, targetHeight) => {
// 计算靶心坐标(靶纸中心)
const centerX = targetWidth / 2;
const centerY = targetHeight / 2;
@@ -318,7 +318,8 @@ export const calcRing = (x, y, targetWidth, targetHeight) => {
// 全环靶有10个环每个环占半径的10%
// 从外到内1环到10环
// 距离越近靶心,环数越高
if (relativeDistance <= 0.1) return 10; // 靶心区域
if (relativeDistance <= 0.05) return "X";
if (relativeDistance <= 0.1) return 10;
if (relativeDistance <= 0.2) return 9;
if (relativeDistance <= 0.3) return 8;
if (relativeDistance <= 0.4) return 7;
@@ -332,7 +333,7 @@ export const calcRing = (x, y, targetWidth, targetHeight) => {
return 0; // 脱靶
};
const calcSmallBowTarget = (x, y, side) => {
const calcHalfBowTarget = (x, y, side, noX = false) => {
// 计算靶心坐标(靶纸中心)
const centerX = side / 2;
const centerY = side / 2;
@@ -350,8 +351,8 @@ const calcSmallBowTarget = (x, y, side) => {
// 计算相对距离0-1之间
const relativeDistance = distance / targetRadius;
if (relativeDistance <= 0.1) return "X"; // 靶心区域
if (relativeDistance <= 0.2) return 10;
if (relativeDistance <= 0.1) return noX ? 10 : "X";
if (relativeDistance <= 0.2) return noX ? 9 : 10;
if (relativeDistance <= 0.4) return 9;
if (relativeDistance <= 0.6) return 8;
if (relativeDistance <= 0.8) return 7;
@@ -360,44 +361,76 @@ const calcSmallBowTarget = (x, y, side) => {
return 0; // 脱靶
};
export const calcRing2 = (x, y, targetWidth, targetHeight) => {
export const calcTripleBowTarget = (
x,
y,
targetWidth,
targetHeight,
noX = false
) => {
const side = targetWidth * 0.325;
if (x / targetWidth >= 0.337 && x / targetWidth <= 0.663) {
if (y / targetHeight <= 0.325) {
return calcHalfBowTarget(x - targetWidth * 0.337, y, side, noX);
} else if (y / targetHeight >= 0.335 && y / targetHeight <= 0.662) {
return calcHalfBowTarget(
x - targetWidth * 0.337,
y - targetHeight * 0.335,
side,
noX
);
} else if (y / targetHeight >= 0.674) {
return calcHalfBowTarget(
x - targetWidth * 0.337,
y - targetHeight * 0.674,
side,
noX
);
}
}
return 0;
};
export const calcPinBowTarget = (
x,
y,
targetWidth,
targetHeight,
noX = false
) => {
const side = targetWidth * 0.48;
if (
x / targetWidth >= 0.26 &&
x / targetWidth <= 0.74 &&
y / targetHeight <= 0.48
) {
return calcSmallBowTarget(x - targetWidth * 0.26, y, side);
return calcHalfBowTarget(x - targetWidth * 0.26, y, side, noX);
} else if (x / targetHeight <= 0.48 && y / targetHeight >= 0.456) {
return calcSmallBowTarget(x, y - targetHeight * 0.456, side);
return calcHalfBowTarget(x, y - targetHeight * 0.456, side, noX);
} else if (x / targetHeight >= 0.52 && y / targetHeight >= 0.456) {
return calcSmallBowTarget(
return calcHalfBowTarget(
x - targetWidth * 0.52,
y - targetHeight * 0.456,
side
side,
noX
);
}
return 0;
};
export const calcRing3 = (x, y, targetWidth, targetHeight) => {
const side = targetWidth * 0.325;
if (x / targetWidth >= 0.337 && x / targetWidth <= 0.663) {
if (y / targetHeight <= 0.325) {
return calcSmallBowTarget(x - targetWidth * 0.337, y, side);
} else if (y / targetHeight >= 0.335 && y / targetHeight <= 0.662) {
return calcSmallBowTarget(
x - targetWidth * 0.337,
y - targetHeight * 0.335,
side
);
} else if (y / targetHeight >= 0.674) {
return calcSmallBowTarget(
x - targetWidth * 0.337,
y - targetHeight * 0.674,
side
);
}
export const calcRing = (bowtargetId, x, y, targetWidth, targetHeight) => {
if (bowtargetId < 4) {
return calcNormalBowTarget(x, y, targetWidth, targetHeight);
} else if (bowtargetId < 7) {
return calcHalfBowTarget(x, y, targetWidth);
} else if (bowtargetId === 7) {
return calcTripleBowTarget(x, y, targetWidth, targetHeight);
} else if (bowtargetId === 8) {
return calcPinBowTarget(x, y, targetWidth, targetHeight);
} else if (bowtargetId === 9) {
return calcTripleBowTarget(x, y, targetWidth, targetHeight, true);
} else if (bowtargetId === 10) {
return calcPinBowTarget(x, y, targetWidth, targetHeight, true);
}
return 0;
};