Files
shoot-miniprograms/src/pages/point-book-list.vue
2025-11-27 12:02:57 +08:00

373 lines
9.6 KiB
Vue

<script setup>
import { ref } from "vue";
import { onShow } from "@dcloudio/uni-app";
import Container from "@/components/Container.vue";
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 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 pointDraft = ref(null);
const onListLoading = async (page) => {
const result = await getPointBookListAPI(
page,
bowType.value.id,
distance.value,
bowtargetType.value.id
);
if (page === 1) {
list.value = result;
} else {
list.value = list.value.concat(result);
}
return result.length;
};
const openSelector = (index) => {
selectorIndex.value = index;
showModal.value = true;
};
const onRemoveRecord = (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;
} else if (itemIndex === 1) {
distance.value = value === distance.value ? 0 : value;
} else if (itemIndex === 2) {
bowtargetType.value = value.name === bowtargetType.value.name ? {} : value;
}
showModal.value = false;
onListLoading(1);
};
const onRemoveDraft = () => {
pointDraft.value = null;
uni.removeStorageSync("last-point-record");
};
const toEditPage = () => {
uni.navigateTo({
url: "/pages/point-book-edit?withDraft=true",
});
};
onShow(() => {
const draft = uni.getStorageSync("last-point-record");
pointDraft.value = draft ? uni.getStorageSync("last-point-book") : null;
});
</script>
<template>
<Container
:bgType="2"
bgColor="#F5F5F5"
:whiteBackArrow="false"
title="计分记录"
>
<view class="container">
<view class="selectors">
<view @click="() => openSelector(0)">
<text :style="{ color: bowType.name ? '#000' : '#999' }">{{
bowType.name || "请选择"
}}</text>
<image src="../static/arrow-grey.png" mode="widthFix" />
</view>
<view @click="() => openSelector(1)">
<text :style="{ color: distance ? '#000' : '#999' }">{{
distance ? distance + " 米" : "请选择"
}}</text>
<image src="../static/arrow-grey.png" mode="widthFix" />
</view>
<view @click="() => openSelector(2)">
<text :style="{ color: bowtargetType.name ? '#000' : '#999' }">{{
bowtargetType.name || "请选择"
}}</text>
<image src="../static/arrow-grey.png" mode="widthFix" />
</view>
</view>
<view class="point-records">
<ScrollList :onLoading="onListLoading">
<uni-swipe-action>
<block v-if="pointDraft">
<uni-swipe-action-item>
<template v-slot:right>
<view class="swipe-right" @click="onRemoveDraft">
<image
class="swipe-icon"
src="../static/delete-white.png"
mode="widthFix"
/>
</view>
</template>
<view class="point-draft" v-if="pointDraft" @click="toEditPage">
<text>{{ pointDraft.bowType.name }}</text>
<text>{{ pointDraft.distance }}</text>
<text>{{ pointDraft.bowtargetType.name }}</text>
<view>
<image src="../static/draft-icon.png" mode="widthFix" />
<text>本地草稿</text>
<view>
<text>计分待完成</text>
<image src="../static/back.png" mode="widthFix" />
</view>
</view>
</view>
</uni-swipe-action-item>
<view :style="{ height: '25rpx' }" />
</block>
<block v-for="(item, index) in list" :key="item.id">
<uni-swipe-action-item>
<template v-slot:right>
<view class="swipe-right" @click="onRemoveRecord(item)">
<image
class="swipe-icon"
src="../static/delete-white.png"
mode="widthFix"
/>
</view>
</template>
<PointRecord :data="item" />
</uni-swipe-action-item>
<view
v-if="index < list.length - 1"
:style="{ height: '25rpx' }"
/>
</block>
</uni-swipe-action>
<view class="no-data" v-if="list.length === 0">暂无数据</view>
</ScrollList>
</view>
<SModal
:show="showModal"
:noBg="true"
height="auto"
:onClose="() => (showModal = false)"
>
<view class="selector">
<button hover-class="none" @click="() => (showModal = false)">
<image src="../static/close-grey.png" mode="widthFix" />
</button>
<EditOption
v-show="selectorIndex === 0"
:itemIndex="0"
:expand="true"
:noArrow="true"
:onSelect="onSelectOption"
:value="bowType.name"
/>
<EditOption
v-show="selectorIndex === 1"
:itemIndex="1"
:expand="true"
:noArrow="true"
:onSelect="onSelectOption"
:value="distance + ''"
/>
<EditOption
v-show="selectorIndex === 2"
:itemIndex="2"
:expand="true"
:noArrow="true"
:onSelect="onSelectOption"
:value="bowtargetType.name"
/>
</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>
<style scoped>
.container {
width: 100%;
height: 100%;
}
.selectors {
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 15px;
margin-top: 10px;
}
.selectors > view {
display: flex;
align-items: center;
justify-content: space-between;
background-color: #fff;
height: 55px;
border-radius: 12px;
color: #333;
font-size: 13px;
width: 26vw;
}
.selectors > view:last-child {
width: 34vw;
}
.selectors > view > text {
width: calc(100% - 11vw);
text-align: center;
margin-left: 3vw;
}
.selectors > view > image {
width: 5vw;
margin-right: 3vw;
}
.selector {
padding: 10px;
background-color: #fff;
border-radius: 10px;
position: relative;
}
.selector > button {
position: absolute;
top: 0;
right: 0;
}
.selector > button > image {
width: 40px;
}
.point-records {
margin: 0 15px;
margin-top: 10px;
height: calc(100% - 80px);
}
.no-data {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
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;
}
/* 右侧滑动按钮(自定义宽度与图标) */
.swipe-right {
width: 120rpx; /* 这里可按需调整按钮宽度 */
height: 100%;
background-color: #ff7c7c;
display: flex;
align-items: center;
justify-content: center;
}
.swipe-icon {
width: 44rpx;
height: 44rpx;
}
.point-draft {
height: 200rpx;
border-radius: 25rpx;
position: relative;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
}
.point-draft > text {
font-weight: 500;
font-size: 40rpx;
color: #333333;
margin: 0 20rpx;
}
.point-draft > view:last-child {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
background: #000000b3;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.point-draft > view:last-child > image {
width: 46rpx;
height: 38rpx;
margin-bottom: 10rpx;
}
.point-draft > view:last-child > text {
font-weight: 500;
font-size: 26rpx;
color: #ffffff;
}
.point-draft > view:last-child > view {
display: flex;
align-items: center;
justify-content: center;
font-size: 22rpx;
color: #ffffff;
transform: translateX(8rpx);
}
.point-draft > view:last-child > view > image {
width: 30rpx;
height: 30rpx;
transform: rotate(180deg);
}
</style>