计分本细节更新
This commit is contained in:
@@ -510,3 +510,11 @@ export const laserCloseAPI = async () => {
|
||||
export const getDeviceBatteryAPI = async () => {
|
||||
return request("GET", "/user/device/battery");
|
||||
};
|
||||
|
||||
export const addNoteAPI = async (id, remark) => {
|
||||
return request("POST", "/user/score/sheet/remark", { id, remark });
|
||||
};
|
||||
|
||||
export const removePointRecord = async (id) => {
|
||||
return request("DELETE", `/user/score/sheet/delete?id=${id}`);
|
||||
};
|
||||
|
||||
@@ -215,6 +215,8 @@ class AudioManager {
|
||||
|
||||
// 播放指定音频
|
||||
play(key) {
|
||||
const pages = getCurrentPages();
|
||||
if (pages.length <= 1) return;
|
||||
// 如果有正在播放的音频,先停止
|
||||
if (this.currentPlayingKey) {
|
||||
this.stop(this.currentPlayingKey);
|
||||
@@ -222,6 +224,7 @@ class AudioManager {
|
||||
|
||||
const audio = this.audioMap.get(key);
|
||||
if (audio) {
|
||||
console.log("播放音频:", key);
|
||||
audio.play();
|
||||
this.currentPlayingKey = key;
|
||||
} else {
|
||||
|
||||
@@ -63,6 +63,30 @@ const onMeterChange = (e) => {
|
||||
meter.value = e.detail.value;
|
||||
props.onSelect(props.itemIndex, e.detail.value);
|
||||
};
|
||||
const sets = ref(null);
|
||||
const onSetsChange = (e) => {
|
||||
sets.value = e.detail.value;
|
||||
if (!sets.value) return;
|
||||
if (arrowAmount.value || groupArrows[secondSelectIndex.value]) {
|
||||
props.onSelect(
|
||||
props.itemIndex,
|
||||
`${e.detail.value}/${
|
||||
arrowAmount.value || groupArrows[secondSelectIndex.value]
|
||||
}`
|
||||
);
|
||||
}
|
||||
};
|
||||
const arrowAmount = ref("");
|
||||
const onArrowAmountChange = (e) => {
|
||||
arrowAmount.value = e.detail.value;
|
||||
if (!arrowAmount.value) return;
|
||||
if (sets.value || selectedIndex.value !== -1) {
|
||||
props.onSelect(
|
||||
props.itemIndex,
|
||||
`${sets.value || selectedIndex.value}/${e.detail.value}`
|
||||
);
|
||||
}
|
||||
};
|
||||
watch(
|
||||
() => props.value,
|
||||
(newValue) => {
|
||||
@@ -219,7 +243,7 @@ onMounted(async () => {
|
||||
<view v-if="itemIndex === 3">
|
||||
<view class="amount-items">
|
||||
<view
|
||||
v-for="i in 12"
|
||||
v-for="i in 4"
|
||||
:key="i"
|
||||
:style="{
|
||||
borderColor: selectedIndex === i ? '#fed847' : '#eeeeee',
|
||||
@@ -229,6 +253,21 @@ onMounted(async () => {
|
||||
<text>{{ i }}</text>
|
||||
<text>组</text>
|
||||
</view>
|
||||
<view
|
||||
:style="{
|
||||
borderColor: selectedIndex === 5 ? '#fed847' : '#eeeeee',
|
||||
}"
|
||||
>
|
||||
<input
|
||||
v-model="sets"
|
||||
placeholder="自定义"
|
||||
type="number"
|
||||
placeholder-style="color: #DDDDDD"
|
||||
@focus="() => (selectedIndex = 5)"
|
||||
@change="onSetsChange"
|
||||
/>
|
||||
<text>组</text>
|
||||
</view>
|
||||
</view>
|
||||
<view
|
||||
:style="{ marginTop: '5px', marginBottom: '10px', color: '#999999' }"
|
||||
@@ -246,6 +285,21 @@ onMounted(async () => {
|
||||
<text>{{ item }}</text>
|
||||
<text>箭</text>
|
||||
</view>
|
||||
<view
|
||||
:style="{
|
||||
borderColor: secondSelectIndex === 4 ? '#fed847' : '#eeeeee',
|
||||
}"
|
||||
>
|
||||
<input
|
||||
v-model="arrowAmount"
|
||||
placeholder="自定义"
|
||||
type="number"
|
||||
placeholder-style="color: #DDDDDD"
|
||||
@focus="() => (secondSelectIndex = 4)"
|
||||
@change="onArrowAmountChange"
|
||||
/>
|
||||
<text>箭</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@@ -352,4 +406,12 @@ onMounted(async () => {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
.amount-items > view:last-child {
|
||||
grid-column: 1 / -1;
|
||||
width: 100%;
|
||||
}
|
||||
.amount-items > view:last-child > input {
|
||||
width: 85%;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -6,6 +6,10 @@ const props = defineProps({
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
longPress: {
|
||||
type: Function,
|
||||
default: () => {},
|
||||
},
|
||||
});
|
||||
const bowOptions = ref({});
|
||||
const targetOptions = ref({});
|
||||
@@ -28,7 +32,7 @@ onMounted(() => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<view class="container" @click="toDetailPage">
|
||||
<view class="container" @click="toDetailPage" @longpress="longPress(props.data)">
|
||||
<view>
|
||||
<view class="labels">
|
||||
<view></view>
|
||||
@@ -54,9 +58,9 @@ onMounted(() => {
|
||||
<view>
|
||||
<image src="../static/bow-target.png" mode="widthFix" />
|
||||
<view class="arrow-amount">
|
||||
<text>共</text>
|
||||
<text>{{ data.arrows * data.groups }}</text>
|
||||
<text>箭</text>
|
||||
<text>{{ data.actualTotalRing }}</text>
|
||||
<text>/</text>
|
||||
<text>{{ data.totalRing }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@@ -124,19 +128,18 @@ onMounted(() => {
|
||||
.arrow-amount {
|
||||
position: absolute;
|
||||
background-color: #0009;
|
||||
border-radius: 10px;
|
||||
border-radius: 12px;
|
||||
color: #fffc;
|
||||
font-size: 12px;
|
||||
line-height: 22px;
|
||||
width: 60px;
|
||||
font-size: 24rpx;
|
||||
line-height: 26px;
|
||||
width: 64px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
top: calc(50% - 13px);
|
||||
left: calc(50% - 30px);
|
||||
top: calc(50% - 15px);
|
||||
left: calc(50% - 32px);
|
||||
}
|
||||
.arrow-amount > text:nth-child(2) {
|
||||
.arrow-amount > text:nth-child(1) {
|
||||
font-size: 30rpx;
|
||||
color: #fff;
|
||||
font-size: 14px;
|
||||
margin: 0 3px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -61,6 +61,7 @@ const ringText = (ring) => {
|
||||
{{ b && b.ring !== undefined ? b.ring : "" }}
|
||||
</text>
|
||||
</view>
|
||||
<text>环值</text>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
@@ -70,9 +71,18 @@ const ringText = (ring) => {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-end;
|
||||
position: relative;
|
||||
}
|
||||
.container > text {
|
||||
position: absolute;
|
||||
bottom: 2rpx;
|
||||
left: 0;
|
||||
font-size: 18rpx;
|
||||
color: #999999;
|
||||
}
|
||||
.container > view {
|
||||
padding: 0 10rpx;
|
||||
padding-left: 40rpx;
|
||||
padding-right: 10rpx;
|
||||
}
|
||||
.container > view:first-child {
|
||||
display: flex;
|
||||
@@ -93,14 +103,15 @@ const ringText = (ring) => {
|
||||
transition: all 0.3s ease;
|
||||
height: 0;
|
||||
}
|
||||
.container > view:last-child {
|
||||
.container > view:nth-child(2) {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(12, 1fr);
|
||||
border-top: 1rpx solid #333;
|
||||
font-size: 22rpx;
|
||||
color: #333333;
|
||||
padding-top: 2rpx;
|
||||
}
|
||||
.container > view:last-child > text {
|
||||
.container > view:nth-child(2) > text {
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -7,25 +7,40 @@ import ScreenHint2 from "@/components/ScreenHint2.vue";
|
||||
import SButton from "@/components/SButton.vue";
|
||||
import RingBarChart from "@/components/RingBarChart.vue";
|
||||
|
||||
import { getPointBookDetailAPI } from "@/apis";
|
||||
import { getPointBookDetailAPI, addNoteAPI } from "@/apis";
|
||||
|
||||
const selectedIndex = ref(0);
|
||||
const showTip = ref(false);
|
||||
const showTip2 = ref(false);
|
||||
const showTip3 = ref(false);
|
||||
const groups = ref([]);
|
||||
const data = ref({});
|
||||
const targetId = ref(0);
|
||||
const targetSrc = ref("");
|
||||
const arrows = ref([]);
|
||||
const notes = ref("");
|
||||
const draftNotes = ref("");
|
||||
const recordId = ref("");
|
||||
|
||||
const openTip = (index) => {
|
||||
if (index === 1) showTip.value = true;
|
||||
else if (index === 2) showTip2.value = true;
|
||||
else if (index === 3) showTip3.value = true;
|
||||
};
|
||||
|
||||
const closeTip = () => {
|
||||
showTip.value = false;
|
||||
showTip2.value = false;
|
||||
showTip3.value = false;
|
||||
};
|
||||
|
||||
const saveNote = async () => {
|
||||
notes.value = draftNotes.value;
|
||||
draftNotes.value = "";
|
||||
showTip3.value = false;
|
||||
if (recordId.value) {
|
||||
await addNoteAPI(recordId.value, notes.value);
|
||||
}
|
||||
};
|
||||
|
||||
const onSelect = (index) => {
|
||||
@@ -54,6 +69,8 @@ const ringRates = computed(() => {
|
||||
onLoad(async (options) => {
|
||||
if (options.id) {
|
||||
const result = await getPointBookDetailAPI(options.id || 164);
|
||||
recordId.value = result.id;
|
||||
notes.value = result.remark || "";
|
||||
const config = uni.getStorageSync("point-book-config");
|
||||
config.targetOption.some((item) => {
|
||||
if (item.id === result.targetType) {
|
||||
@@ -132,6 +149,10 @@ onLoad(async (options) => {
|
||||
<view>总环数</view>
|
||||
<text>{{ data.userTotalRing }}/{{ data.totalRing }}</text>
|
||||
</view>
|
||||
<button hover-class="none" @click="() => openTip(3)">
|
||||
<image src="../static/edit.png" mode="widthFix" />
|
||||
<text>备注</text>
|
||||
</button>
|
||||
</view>
|
||||
<view class="title-bar">
|
||||
<view />
|
||||
@@ -168,14 +189,21 @@ onLoad(async (options) => {
|
||||
</view>
|
||||
<view class="ring-text-groups">
|
||||
<view v-for="(item, index) in groups" :key="index">
|
||||
<text v-if="selectedIndex === 0 && index !== 0">{{
|
||||
`第${index}组`
|
||||
<view v-if="selectedIndex === 0 && index !== 0">
|
||||
<text>{{ index }}:</text>
|
||||
<text>{{
|
||||
item.list.reduce((acc, cur) => acc + cur.ring, 0)
|
||||
}}</text>
|
||||
<text>环</text>
|
||||
</view>
|
||||
<view
|
||||
v-if="
|
||||
(selectedIndex === 0 && index !== 0) ||
|
||||
(selectedIndex !== 0 && index === selectedIndex)
|
||||
"
|
||||
:style="{
|
||||
marginLeft: selectedIndex === 0 && index !== 0 ? '20rpx' : '0',
|
||||
}"
|
||||
>
|
||||
<text
|
||||
v-for="(arrow, index2) in item.list"
|
||||
@@ -186,11 +214,7 @@ onLoad(async (options) => {
|
||||
}"
|
||||
>
|
||||
{{
|
||||
arrow.ring === 0
|
||||
? "X"
|
||||
: arrow.ring === -1
|
||||
? "M"
|
||||
: arrow.ring + "环"
|
||||
arrow.ring === 0 ? "X" : arrow.ring === -1 ? "M" : arrow.ring
|
||||
}}
|
||||
</text>
|
||||
</view>
|
||||
@@ -200,7 +224,10 @@ onLoad(async (options) => {
|
||||
<SButton :onClick="goBack" :rounded="50">关闭</SButton>
|
||||
</view>
|
||||
</view>
|
||||
<ScreenHint2 :show="showTip || showTip2" :onClose="closeTip">
|
||||
<ScreenHint2
|
||||
:show="showTip || showTip2 || showTip3"
|
||||
:onClose="!notes && showTip3 ? null : closeTip"
|
||||
>
|
||||
<view class="tip-content">
|
||||
<block v-if="showTip">
|
||||
<text>落点稳定性说明</text>
|
||||
@@ -212,6 +239,22 @@ onLoad(async (options) => {
|
||||
<text>落点分布说明</text>
|
||||
<text>展示用户某次练习中射箭的点位</text>
|
||||
</block>
|
||||
<block v-if="showTip3">
|
||||
<text>笔记</text>
|
||||
<text v-if="notes">{{ notes }}</text>
|
||||
<textarea
|
||||
v-if="!notes"
|
||||
v-model="draftNotes"
|
||||
rows="4"
|
||||
class="notes-input"
|
||||
placeholder="写下本次射箭的补充信息与心得"
|
||||
placeholder-style="color: #ccc;"
|
||||
/>
|
||||
<view v-if="!notes">
|
||||
<button hover-class="none" @click="showTip3 = false">取消</button>
|
||||
<button hover-class="none" @click="saveNote">保存备注</button>
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
</ScreenHint2>
|
||||
</view>
|
||||
@@ -265,7 +308,8 @@ onLoad(async (options) => {
|
||||
column-gap: 3vw;
|
||||
margin: 10rpx 30rpx;
|
||||
}
|
||||
.detail-data > view {
|
||||
.detail-data > view,
|
||||
.detail-data > button {
|
||||
border-radius: 10px;
|
||||
background-color: #fff;
|
||||
margin-bottom: 20rpx;
|
||||
@@ -283,6 +327,18 @@ onLoad(async (options) => {
|
||||
font-weight: 500;
|
||||
color: #000;
|
||||
}
|
||||
.detail-data > button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 26rpx;
|
||||
color: #999999;
|
||||
}
|
||||
.detail-data > button > image {
|
||||
width: 28rpx;
|
||||
height: 28rpx;
|
||||
margin-right: 10rpx;
|
||||
margin-left: 20rpx;
|
||||
}
|
||||
.question-mark {
|
||||
width: 28rpx;
|
||||
height: 28rpx;
|
||||
@@ -326,6 +382,33 @@ onLoad(async (options) => {
|
||||
margin-top: 20px;
|
||||
opacity: 0.8;
|
||||
}
|
||||
.tip-content > view {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.tip-content > view > input {
|
||||
width: 80%;
|
||||
height: 44px;
|
||||
border-radius: 22px;
|
||||
border: 1px solid #eeeeee;
|
||||
padding: 0 12px;
|
||||
font-size: 14px;
|
||||
color: #000;
|
||||
}
|
||||
.tip-content > view > button {
|
||||
width: 48%;
|
||||
background: linear-gradient(180deg, #fbfbfb 0%, #f5f5f5 100%);
|
||||
border-radius: 22px;
|
||||
border: 1px solid #eeeeee;
|
||||
padding: 12px 0;
|
||||
font-size: 14px;
|
||||
color: #000;
|
||||
}
|
||||
.tip-content > view > button:last-child {
|
||||
background: #fed847;
|
||||
}
|
||||
.ring-text-groups {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -338,22 +421,43 @@ onLoad(async (options) => {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
.ring-text-groups > view > text {
|
||||
.ring-text-groups > view > view:first-child:nth-last-child(2) {
|
||||
width: 82rpx;
|
||||
text-align: center;
|
||||
font-size: 27rpx;
|
||||
font-size: 20rpx;
|
||||
display: flex;
|
||||
color: #999;
|
||||
}
|
||||
.ring-text-groups > view > view {
|
||||
.ring-text-groups > view > view:first-child:nth-last-child(2) > text {
|
||||
line-height: 30rpx;
|
||||
}
|
||||
.ring-text-groups
|
||||
> view
|
||||
> view:first-child:nth-last-child(2)
|
||||
> text:nth-child(2) {
|
||||
font-size: 40rpx;
|
||||
color: #666;
|
||||
margin-right: 6rpx;
|
||||
}
|
||||
.ring-text-groups > view > view:last-child {
|
||||
flex: 1;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(6, auto);
|
||||
grid-gap: 10rpx;
|
||||
margin-bottom: 30rpx;
|
||||
margin-left: 20rpx;
|
||||
}
|
||||
.ring-text-groups > view > view > text {
|
||||
.ring-text-groups > view > view:last-child > text {
|
||||
width: 1fr;
|
||||
text-align: center;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
.notes-input {
|
||||
width: calc(100% - 40rpx);
|
||||
margin: 25rpx 0;
|
||||
border: 1px solid #eee;
|
||||
border-radius: 5px;
|
||||
padding: 5px;
|
||||
color: #000;
|
||||
padding: 20rpx;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -5,14 +5,17 @@ import SModal from "@/components/SModal.vue";
|
||||
import EditOption from "@/components/EditOption.vue";
|
||||
import PointRecord from "@/components/PointRecord.vue";
|
||||
import ScrollList from "@/components/ScrollList.vue";
|
||||
import { getPointBookListAPI } from "@/apis";
|
||||
import ScreenHint2 from "@/components/ScreenHint2.vue";
|
||||
import { getPointBookListAPI, removePointRecord } from "@/apis";
|
||||
|
||||
const showTip = ref(false);
|
||||
const bowType = ref({});
|
||||
const distance = ref(0);
|
||||
const bowtargetType = ref({});
|
||||
const showModal = ref(false);
|
||||
const selectorIndex = ref(0);
|
||||
const list = ref([]);
|
||||
const removeId = ref("");
|
||||
|
||||
const onListLoading = async (page) => {
|
||||
const result = await getPointBookListAPI(
|
||||
@@ -34,6 +37,22 @@ const openSelector = (index) => {
|
||||
showModal.value = true;
|
||||
};
|
||||
|
||||
const onLongPress = (item) => {
|
||||
removeId.value = item.id;
|
||||
showTip.value = true;
|
||||
};
|
||||
|
||||
const confirmRemove = async () => {
|
||||
try {
|
||||
showTip.value = false;
|
||||
await removePointRecord(removeId.value);
|
||||
list.value = list.value.filter((it) => it.id !== removeId.value);
|
||||
uni.showToast({ title: "已删除", icon: "none" });
|
||||
} catch (e) {
|
||||
uni.showToast({ title: "删除失败,请重试", icon: "none" });
|
||||
}
|
||||
};
|
||||
|
||||
const onSelectOption = (itemIndex, value) => {
|
||||
if (itemIndex === 0) {
|
||||
bowType.value = value.name === bowType.value.name ? {} : value;
|
||||
@@ -78,7 +97,7 @@ const onSelectOption = (itemIndex, value) => {
|
||||
<view class="point-records">
|
||||
<ScrollList :onLoading="onListLoading">
|
||||
<view v-for="(item, index) in list" :key="index">
|
||||
<PointRecord :data="item" />
|
||||
<PointRecord :data="item" :longPress="onLongPress" />
|
||||
</view>
|
||||
<view class="no-data" v-if="list.length === 0">暂无数据</view>
|
||||
</ScrollList>
|
||||
@@ -119,6 +138,15 @@ const onSelectOption = (itemIndex, value) => {
|
||||
/>
|
||||
</view>
|
||||
</SModal>
|
||||
<ScreenHint2 :show="showTip">
|
||||
<view class="tip-content">
|
||||
<text>确认删除该记录吗</text>
|
||||
<view>
|
||||
<button hover-class="none" @click="showTip = false">取消</button>
|
||||
<button hover-class="none" @click="confirmRemove">确认</button>
|
||||
</view>
|
||||
</view>
|
||||
</ScreenHint2>
|
||||
</view>
|
||||
</Container>
|
||||
</template>
|
||||
@@ -186,4 +214,34 @@ const onSelectOption = (itemIndex, value) => {
|
||||
color: #999999;
|
||||
font-size: 14px;
|
||||
}
|
||||
.tip-content {
|
||||
width: 100%;
|
||||
padding: 25px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
color: #000;
|
||||
}
|
||||
.tip-content > text {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
font-size: 14px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
.tip-content > view {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-top: 20px;
|
||||
}
|
||||
.tip-content > view > button {
|
||||
width: 48%;
|
||||
background: linear-gradient(180deg, #fbfbfb 0%, #f5f5f5 100%);
|
||||
border-radius: 22px;
|
||||
border: 1px solid #eeeeee;
|
||||
padding: 12px 0;
|
||||
font-size: 14px;
|
||||
color: #000;
|
||||
}
|
||||
.tip-content > view > button:last-child {
|
||||
background: #fed847;
|
||||
}
|
||||
</style>
|
||||
|
||||
BIN
src/static/edit.png
Normal file
BIN
src/static/edit.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 363 B |
Reference in New Issue
Block a user