完成ios首页改造
This commit is contained in:
@@ -27,7 +27,7 @@ const props = defineProps({
|
||||
default: "",
|
||||
},
|
||||
});
|
||||
const itemTexts = ["选择弓种", "选择练习距离", "选择靶纸", "选择组/箭数"];
|
||||
const itemTexts = ["Bow Type", "Distance", "Target Type", "Sets/Arrows"];
|
||||
const distances = [5, 8, 10, 18, 25, 30, 50, 60, 70];
|
||||
const groupArrows = [3, 6, 12, 18];
|
||||
|
||||
@@ -135,22 +135,22 @@ onMounted(async () => {
|
||||
}"
|
||||
>
|
||||
<view @click="() => onExpand(itemIndex, !expand)">
|
||||
<text :style="{ opacity: expand ? 1 : 0 }">{{
|
||||
itemIndex !== 3 ? itemTexts[itemIndex] : "选择组"
|
||||
<text :style="{ opacity: expand ? 1 : 0 }">{{
|
||||
itemIndex !== 3 ? itemTexts[itemIndex] : "Select Sets"
|
||||
}}</text>
|
||||
<block>
|
||||
<text :style="{ opacity: expand ? 0 : 1 }" v-if="itemIndex === 0">{{
|
||||
<text :style="{ opacity: expand ? 0 : 1 }" v-if="itemIndex === 0">{{
|
||||
value || itemTexts[itemIndex]
|
||||
}}</text>
|
||||
<text :style="{ opacity: expand ? 0 : 1 }" v-if="itemIndex === 1">{{
|
||||
value && value > 0 ? value + "米" : itemTexts[itemIndex]
|
||||
<text :style="{ opacity: expand ? 0 : 1 }" v-if="itemIndex === 1">{{
|
||||
value && value > 0 ? value + "m" : itemTexts[itemIndex]
|
||||
}}</text>
|
||||
<text :style="{ opacity: expand ? 0 : 1 }" v-if="itemIndex === 2">{{
|
||||
<text :style="{ opacity: expand ? 0 : 1 }" v-if="itemIndex === 2">{{
|
||||
value || itemTexts[itemIndex]
|
||||
}}</text>
|
||||
<text :style="{ opacity: expand ? 0 : 1 }" v-if="itemIndex === 3">{{
|
||||
<text :style="{ opacity: expand ? 0 : 1 }" v-if="itemIndex === 3">{{
|
||||
selectedIndex !== -1 && secondSelectIndex !== -1
|
||||
? `${selectedIndex}组/${groupArrows[secondSelectIndex]}箭`
|
||||
? `${selectedIndex}sets/${groupArrows[secondSelectIndex]}arrows`
|
||||
: itemTexts[itemIndex]
|
||||
}}</text>
|
||||
</block>
|
||||
@@ -186,7 +186,7 @@ onMounted(async () => {
|
||||
@click="onSelectItem(index)"
|
||||
>
|
||||
<text>{{ item }}</text>
|
||||
<text>米</text>
|
||||
<text>m</text>
|
||||
</view>
|
||||
<view
|
||||
:style="{
|
||||
@@ -195,12 +195,12 @@ onMounted(async () => {
|
||||
>
|
||||
<input
|
||||
v-model="meter"
|
||||
placeholder="自定义"
|
||||
placeholder="custom"
|
||||
placeholder-style="color: #DDDDDD"
|
||||
@focus="() => (selectedIndex = 9)"
|
||||
@change="onMeterChange"
|
||||
/>
|
||||
<text>米</text>
|
||||
<text>m</text>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="itemIndex === 2" class="bowtarget-items">
|
||||
@@ -227,12 +227,12 @@ onMounted(async () => {
|
||||
@click="onSelectItem(i)"
|
||||
>
|
||||
<text>{{ i }}</text>
|
||||
<text>组</text>
|
||||
<text>sets</text>
|
||||
</view>
|
||||
</view>
|
||||
<view
|
||||
:style="{ marginTop: '5px', marginBottom: '10px', color: '#999999' }"
|
||||
>选择每组的箭数</view
|
||||
>Select arrows per set</view
|
||||
>
|
||||
<view class="amount-items">
|
||||
<view
|
||||
@@ -244,7 +244,7 @@ onMounted(async () => {
|
||||
@click="onSelectSecondItem(index)"
|
||||
>
|
||||
<text>{{ item }}</text>
|
||||
<text>箭</text>
|
||||
<text>arrows</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
@@ -68,7 +68,6 @@ onMounted(() => {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border-radius: 25rpx;
|
||||
margin-bottom: 25rpx;
|
||||
height: 200rpx;
|
||||
border: 2rpx solid #fed848;
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import { ref, computed } from "vue";
|
||||
const props = defineProps({
|
||||
data: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
default: Array,
|
||||
},
|
||||
total: {
|
||||
type: Number,
|
||||
@@ -69,6 +69,7 @@ const ringText = (ring) => {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-end;
|
||||
margin-top: -30rpx;
|
||||
}
|
||||
.container > view {
|
||||
padding: 0 10rpx;
|
||||
|
||||
@@ -59,6 +59,7 @@ onShow(async () => {
|
||||
<scroll-view
|
||||
class="scroll-list"
|
||||
scroll-y
|
||||
enable-flex="true"
|
||||
:show-scrollbar="false"
|
||||
enhanced="true"
|
||||
:bounces="false"
|
||||
@@ -73,8 +74,8 @@ onShow(async () => {
|
||||
>
|
||||
<slot></slot>
|
||||
<view class="tips">
|
||||
<text v-if="loading">加载中...</text>
|
||||
<text v-if="noMore">{{ count === 0 ? "暂无数据" : "没有更多了" }}</text>
|
||||
<text v-if="loading">Loading...</text>
|
||||
<text v-if="noMore">{{ count === 0 ? "No data" : "That‘s all" }}</text>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</template>
|
||||
@@ -83,9 +84,7 @@ onShow(async () => {
|
||||
.scroll-list {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.tips {
|
||||
height: 50rpx;
|
||||
flex-direction: column;
|
||||
}
|
||||
.tips > text {
|
||||
color: #d0d0d0;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
<script setup>
|
||||
import { ref, computed, onMounted, watch } from "vue";
|
||||
import { onShow } from "@dcloudio/uni-app";
|
||||
import Container from "@/components/Container.vue";
|
||||
import PointRecord from "@/components/PointRecord.vue";
|
||||
import RingBarChart from "@/components/RingBarChart.vue";
|
||||
|
||||
@@ -22,6 +21,7 @@ const isIOS = computed(() => {
|
||||
const loadImage = ref(false);
|
||||
const data = ref({
|
||||
weeksCheckIn: [],
|
||||
ringRate: [],
|
||||
});
|
||||
|
||||
const bowTargetSrc = ref("");
|
||||
@@ -48,6 +48,7 @@ const loadData = async () => {
|
||||
else if (result.checkInCount >= 5) hot = 3;
|
||||
else if (result.checkInCount === 7) hot = 4;
|
||||
uni.$emit("update-hot", hot);
|
||||
return;
|
||||
loadImage.value = true;
|
||||
const generateHeatmapAsync = async () => {
|
||||
const weekArrows = result.weekArrows
|
||||
@@ -115,146 +116,142 @@ onShow(async () => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Container :bgType="4" bgColor="#F5F5F5" :whiteBackArrow="false" title="">
|
||||
<view class="container">
|
||||
<view class="daily-signin">
|
||||
<view>
|
||||
<image src="../static/week-check.png" />
|
||||
</view>
|
||||
<view :class="data.weeksCheckIn[0] ? 'checked' : ''">
|
||||
<image
|
||||
v-if="data.weeksCheckIn[0]"
|
||||
src="../static/checked-green2.png"
|
||||
mode="widthFix"
|
||||
/>
|
||||
<view v-else></view>
|
||||
<text>周一</text>
|
||||
</view>
|
||||
<view :class="data.weeksCheckIn[1] ? 'checked' : ''">
|
||||
<image
|
||||
v-if="data.weeksCheckIn[1]"
|
||||
src="../static/checked-green2.png"
|
||||
mode="widthFix"
|
||||
/>
|
||||
<view v-else></view>
|
||||
<text>周二</text>
|
||||
</view>
|
||||
<view :class="data.weeksCheckIn[2] ? 'checked' : ''">
|
||||
<image
|
||||
v-if="data.weeksCheckIn[2]"
|
||||
src="../static/checked-green2.png"
|
||||
mode="widthFix"
|
||||
/>
|
||||
<view v-else></view>
|
||||
<text>周三</text>
|
||||
</view>
|
||||
<view :class="data.weeksCheckIn[3] ? 'checked' : ''">
|
||||
<image
|
||||
v-if="data.weeksCheckIn[3]"
|
||||
src="../static/checked-green2.png"
|
||||
mode="widthFix"
|
||||
/>
|
||||
<view v-else></view>
|
||||
<text>周四</text>
|
||||
</view>
|
||||
<view :class="data.weeksCheckIn[4] ? 'checked' : ''">
|
||||
<image
|
||||
v-if="data.weeksCheckIn[4]"
|
||||
src="../static/checked-green2.png"
|
||||
mode="widthFix"
|
||||
/>
|
||||
<view v-else></view>
|
||||
<text>周五</text>
|
||||
</view>
|
||||
<view :class="data.weeksCheckIn[5] ? 'checked' : ''">
|
||||
<image
|
||||
v-if="data.weeksCheckIn[5]"
|
||||
src="../static/checked-green2.png"
|
||||
mode="widthFix"
|
||||
/>
|
||||
<view v-else></view>
|
||||
<text>周六</text>
|
||||
</view>
|
||||
<view :class="data.weeksCheckIn[6] ? 'checked' : ''">
|
||||
<image
|
||||
v-if="data.weeksCheckIn[6]"
|
||||
src="../static/checked-green2.png"
|
||||
mode="widthFix"
|
||||
/>
|
||||
<view v-else></view>
|
||||
<text>周日</text>
|
||||
</view>
|
||||
<view class="container">
|
||||
<view class="daily-signin">
|
||||
<view>
|
||||
<image src="../static/week-check.png" />
|
||||
</view>
|
||||
<view class="statistics">
|
||||
<view>
|
||||
<text>{{ data.todayTotalArrow || "-" }}</text>
|
||||
<text>今日射箭(箭)</text>
|
||||
</view>
|
||||
<view>
|
||||
<text>{{ data.totalArrow || "-" }}</text>
|
||||
<text>累计射箭(箭)</text>
|
||||
</view>
|
||||
<view>
|
||||
<text>{{ data.totalDay || "-" }}</text>
|
||||
<text>已训练天数(天)</text>
|
||||
</view>
|
||||
<view>
|
||||
<text>{{ data.averageRing || "-" }}</text>
|
||||
<text>平均环数(箭)</text>
|
||||
</view>
|
||||
<view>
|
||||
<text>{{
|
||||
data.yellowRate !== undefined
|
||||
? Number((data.yellowRate * 100).toFixed(2)) + "%"
|
||||
: "-"
|
||||
}}</text>
|
||||
<text>黄心率</text>
|
||||
</view>
|
||||
<view>
|
||||
<button hover-class="none" @click="startScoring">
|
||||
<image src="../static/start-scoring.png" mode="widthFix" />
|
||||
</button>
|
||||
</view>
|
||||
</view>
|
||||
<view class="title" :style="{ marginBottom: 0 }">
|
||||
<image src="../static/point-book-title1.png" mode="widthFix" />
|
||||
</view>
|
||||
<view class="heat-map">
|
||||
<view :class="data.weeksCheckIn[0] ? 'checked' : ''">
|
||||
<image
|
||||
:src="bowTargetSrc || '../static/bow-target.png'"
|
||||
v-if="data.weeksCheckIn[0]"
|
||||
src="../static/checked-green2.png"
|
||||
mode="widthFix"
|
||||
/>
|
||||
<image
|
||||
v-if="heatMapImageSrc"
|
||||
:src="heatMapImageSrc"
|
||||
mode="aspectFill"
|
||||
/>
|
||||
<view v-if="loadImage" class="load-image">
|
||||
<text>生成中...</text>
|
||||
</view>
|
||||
<canvas
|
||||
id="heatMapCanvas"
|
||||
canvas-id="heatMapCanvas"
|
||||
type="2d"
|
||||
style="
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
top: -1000px;
|
||||
left: 0;
|
||||
z-index: 2;
|
||||
"
|
||||
/>
|
||||
<view v-else></view>
|
||||
<text>Mon</text>
|
||||
</view>
|
||||
<view :class="data.weeksCheckIn[1] ? 'checked' : ''">
|
||||
<image
|
||||
v-if="data.weeksCheckIn[1]"
|
||||
src="../static/checked-green2.png"
|
||||
mode="widthFix"
|
||||
/>
|
||||
<view v-else></view>
|
||||
<text>Tue</text>
|
||||
</view>
|
||||
<view :class="data.weeksCheckIn[2] ? 'checked' : ''">
|
||||
<image
|
||||
v-if="data.weeksCheckIn[2]"
|
||||
src="../static/checked-green2.png"
|
||||
mode="widthFix"
|
||||
/>
|
||||
<view v-else></view>
|
||||
<text>Wed</text>
|
||||
</view>
|
||||
<view :class="data.weeksCheckIn[3] ? 'checked' : ''">
|
||||
<image
|
||||
v-if="data.weeksCheckIn[3]"
|
||||
src="../static/checked-green2.png"
|
||||
mode="widthFix"
|
||||
/>
|
||||
<view v-else></view>
|
||||
<text>Thu</text>
|
||||
</view>
|
||||
<view :class="data.weeksCheckIn[4] ? 'checked' : ''">
|
||||
<image
|
||||
v-if="data.weeksCheckIn[4]"
|
||||
src="../static/checked-green2.png"
|
||||
mode="widthFix"
|
||||
/>
|
||||
<view v-else></view>
|
||||
<text>Fri</text>
|
||||
</view>
|
||||
<view :class="data.weeksCheckIn[5] ? 'checked' : ''">
|
||||
<image
|
||||
v-if="data.weeksCheckIn[5]"
|
||||
src="../static/checked-green2.png"
|
||||
mode="widthFix"
|
||||
/>
|
||||
<view v-else></view>
|
||||
<text>Sat</text>
|
||||
</view>
|
||||
<view :class="data.weeksCheckIn[6] ? 'checked' : ''">
|
||||
<image
|
||||
v-if="data.weeksCheckIn[6]"
|
||||
src="../static/checked-green2.png"
|
||||
mode="widthFix"
|
||||
/>
|
||||
<view v-else></view>
|
||||
<text>Sun</text>
|
||||
</view>
|
||||
<RingBarChart :data="data.ringRate" v-if="user.id" />
|
||||
</view>
|
||||
</Container>
|
||||
<view class="statistics">
|
||||
<view>
|
||||
<text>{{ data.todayTotalArrow || "-" }}</text>
|
||||
<text>Today's Arrows</text>
|
||||
</view>
|
||||
<view>
|
||||
<text>{{ data.totalArrow || "-" }}</text>
|
||||
<text>Total Arrows</text>
|
||||
</view>
|
||||
<view>
|
||||
<text>{{ data.totalDay || "-" }}</text>
|
||||
<text>Training Days</text>
|
||||
</view>
|
||||
<view>
|
||||
<text>{{ data.averageRing || "-" }}</text>
|
||||
<text>Avg Score</text>
|
||||
</view>
|
||||
<view>
|
||||
<text>{{
|
||||
data.yellowRate !== undefined
|
||||
? Number((data.yellowRate * 100).toFixed(2)) + "%"
|
||||
: "-"
|
||||
}}</text>
|
||||
<text>X-Ring Rate</text>
|
||||
</view>
|
||||
<view>
|
||||
<button hover-class="none" @click="startScoring">
|
||||
<image src="../static/start-scoring.png" mode="widthFix" />
|
||||
</button>
|
||||
</view>
|
||||
</view>
|
||||
<view class="title" :style="{ marginBottom: 0 }">
|
||||
<image src="../static/point-book-title1.png" mode="widthFix" />
|
||||
</view>
|
||||
<view class="heat-map">
|
||||
<image
|
||||
:src="bowTargetSrc || '../static/bow-target.png'"
|
||||
mode="widthFix"
|
||||
/>
|
||||
<image v-if="heatMapImageSrc" :src="heatMapImageSrc" mode="aspectFill" />
|
||||
<view v-if="loadImage" class="load-image">
|
||||
<text>Generating...</text>
|
||||
</view>
|
||||
<canvas
|
||||
id="heatMapCanvas"
|
||||
canvas-id="heatMapCanvas"
|
||||
type="2d"
|
||||
style="
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
top: -1000px;
|
||||
left: 0;
|
||||
z-index: 2;
|
||||
"
|
||||
/>
|
||||
</view>
|
||||
<RingBarChart :data="data.ringRate" />
|
||||
<view :style="{ height: '25rpx' }" />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.container {
|
||||
width: calc(100% - 50rpx);
|
||||
padding: 25rpx;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
}
|
||||
.statistics {
|
||||
border-radius: 25rpx;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
<script setup>
|
||||
import { ref, onMounted } from "vue";
|
||||
import Container from "@/components/Container.vue";
|
||||
import SModal from "@/components/SModal.vue";
|
||||
import EditOption from "@/components/EditOption.vue";
|
||||
import PointRecord from "@/components/PointRecord.vue";
|
||||
@@ -48,79 +47,72 @@ const onSelectOption = (itemIndex, value) => {
|
||||
</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 class="container">
|
||||
<view class="selectors">
|
||||
<view @click="() => openSelector(0)">
|
||||
<text :style="{ color: bowType.name ? '#000' : '#999' }">{{
|
||||
bowType.name || "Bow Type"
|
||||
}}</text>
|
||||
<image src="../static/arrow-grey.png" mode="widthFix" />
|
||||
</view>
|
||||
<view class="point-records">
|
||||
<ScrollList :onLoading="onListLoading">
|
||||
<view v-for="(item, index) in list" :key="index">
|
||||
<PointRecord :data="item" />
|
||||
</view>
|
||||
<view class="no-data" v-if="list.length === 0">暂无数据</view>
|
||||
</ScrollList>
|
||||
<view @click="() => openSelector(1)">
|
||||
<text :style="{ color: distance ? '#000' : '#999' }">{{
|
||||
distance ? distance + " m" : "Distance"
|
||||
}}</text>
|
||||
<image src="../static/arrow-grey.png" mode="widthFix" />
|
||||
</view>
|
||||
<view @click="() => openSelector(2)">
|
||||
<text :style="{ color: bowtargetType.name ? '#000' : '#999' }">{{
|
||||
bowtargetType.name || "Target Type"
|
||||
}}</text>
|
||||
<image src="../static/arrow-grey.png" mode="widthFix" />
|
||||
</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>
|
||||
</view>
|
||||
</Container>
|
||||
<view class="point-records">
|
||||
<ScrollList :onLoading="onListLoading">
|
||||
<view v-for="(item, index) in list" :key="index">
|
||||
<view v-if="index > 0" :style="{ height: '25rpx' }" />
|
||||
<PointRecord :data="item" />
|
||||
</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>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
@@ -132,15 +124,13 @@ const onSelectOption = (itemIndex, value) => {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0 15px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
.selectors > view {
|
||||
height: 110rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
background-color: #fff;
|
||||
height: 55px;
|
||||
border-radius: 12px;
|
||||
color: #333;
|
||||
font-size: 13px;
|
||||
@@ -150,7 +140,7 @@ const onSelectOption = (itemIndex, value) => {
|
||||
width: 34vw;
|
||||
}
|
||||
.selectors > view > text {
|
||||
width: calc(100% - 11vw);
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
margin-left: 3vw;
|
||||
}
|
||||
@@ -173,17 +163,8 @@ const onSelectOption = (itemIndex, value) => {
|
||||
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;
|
||||
height: calc(100% - 130rpx);
|
||||
overflow: auto;
|
||||
}
|
||||
</style>
|
||||
|
||||
114
src/pages/point-book-profile.vue
Normal file
114
src/pages/point-book-profile.vue
Normal file
@@ -0,0 +1,114 @@
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import Avatar from "@/components/Avatar.vue";
|
||||
|
||||
import useStore from "@/store";
|
||||
import { storeToRefs } from "pinia";
|
||||
const store = useStore();
|
||||
const { user } = storeToRefs(store);
|
||||
|
||||
const toEditPage = () => {
|
||||
uni.navigateTo({
|
||||
url: "/pages/point-book-edit",
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<view class="container">
|
||||
<view class="header">
|
||||
<image :src="user.avatar" mode="widthFix" />
|
||||
<button hover-class="none" @click="toEditPage">
|
||||
<image src="../static/pen-yellow.png" mode="widthFix" />
|
||||
</button>
|
||||
</view>
|
||||
<view class="body">
|
||||
<view>
|
||||
<button hover-class="none">
|
||||
<image src="../static/user-yellow.png" mode="widthFix" />
|
||||
<text>Name</text>
|
||||
<image src="../static/back-grey.png" mode="widthFix" />
|
||||
</button>
|
||||
<button hover-class="none">
|
||||
<image src="../static/email-yellow.png" mode="widthFix" />
|
||||
<text>Email</text>
|
||||
<image src="../static/back-grey.png" mode="widthFix" />
|
||||
</button>
|
||||
<button hover-class="none">
|
||||
<image src="../static/password-yellow.png" mode="widthFix" />
|
||||
<text>Password</text>
|
||||
<image src="../static/back-grey.png" mode="widthFix" />
|
||||
</button>
|
||||
</view>
|
||||
<button hover-class="none">Log out</button>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
.header {
|
||||
position: relative;
|
||||
margin-top: -120rpx;
|
||||
}
|
||||
.header > image {
|
||||
width: 180rpx;
|
||||
height: 180rpx;
|
||||
border-radius: 50%;
|
||||
border: 4rpx solid #fff;
|
||||
}
|
||||
.header > button {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
.header > button > image {
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
}
|
||||
.body {
|
||||
width: 100%;
|
||||
margin-top: 20rpx;
|
||||
}
|
||||
.body > view {
|
||||
background-color: $uni-bg-color;
|
||||
border-radius: 25px;
|
||||
padding: 0 20px;
|
||||
}
|
||||
.body > view > button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 20px 0;
|
||||
}
|
||||
.body > view > button:not(:last-child) {
|
||||
border-bottom: 1rpx solid #e3e3e3;
|
||||
}
|
||||
.body > view > button > image:first-child {
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
}
|
||||
.body > view > button > text {
|
||||
flex: 1;
|
||||
font-size: 26rpx;
|
||||
color: #333333;
|
||||
text-align: left;
|
||||
padding-left: 20rpx;
|
||||
}
|
||||
.body > view > button > image:last-child {
|
||||
width: 28rpx;
|
||||
height: 28rpx;
|
||||
}
|
||||
.body > button:last-child {
|
||||
margin-top: 24rpx;
|
||||
background: $uni-bg-color;
|
||||
border-radius: 24rpx;
|
||||
font-size: 26rpx;
|
||||
color: $uni-link-color;
|
||||
text-align: center;
|
||||
padding: 20px 0;
|
||||
}
|
||||
</style>
|
||||
@@ -1,6 +1,9 @@
|
||||
<script setup>
|
||||
import { ref, computed, onMounted, onBeforeUnmount, watch } from "vue";
|
||||
import Container from "@/components/Container.vue";
|
||||
import Home from "@/pages/point-book-home.vue";
|
||||
import History from "@/pages/point-book-list.vue";
|
||||
import Profile from "@/pages/point-book-profile.vue";
|
||||
import Avatar from "@/components/Avatar.vue";
|
||||
|
||||
import { getHomeData } from "@/apis";
|
||||
|
||||
@@ -11,18 +14,28 @@ const { updateUser } = store;
|
||||
const { user } = storeToRefs(store);
|
||||
|
||||
const activeTab = ref(0);
|
||||
const heat = ref(0);
|
||||
|
||||
const isIOS = computed(() => {
|
||||
const systemInfo = uni.getDeviceInfo();
|
||||
return systemInfo.osName === "ios";
|
||||
});
|
||||
|
||||
const capsuleHeight = computed(() => {
|
||||
const menuBtnInfo = uni.getMenuButtonBoundingClientRect();
|
||||
return menuBtnInfo.top - 9;
|
||||
});
|
||||
|
||||
const goSignIn = () => {
|
||||
uni.navigateTo({
|
||||
url: "/pages/sign-in",
|
||||
});
|
||||
};
|
||||
|
||||
const onClickTab = (index) => {
|
||||
if (index > 0 && !user.value.id) {
|
||||
return uni.navigateTo({
|
||||
url: "/pages/sign-in",
|
||||
});
|
||||
}
|
||||
// if (index > 0 && !user.value.id) {
|
||||
// return goSignIn();
|
||||
// }
|
||||
activeTab.value = index;
|
||||
};
|
||||
|
||||
@@ -36,6 +49,10 @@ watch(
|
||||
}
|
||||
);
|
||||
|
||||
const updateHot = (value) => {
|
||||
heat.value = value;
|
||||
};
|
||||
|
||||
onMounted(async () => {
|
||||
const token = uni.getStorageSync(
|
||||
`${uni.getAccountInfoSync().miniProgram.envVersion}_token`
|
||||
@@ -44,12 +61,55 @@ onMounted(async () => {
|
||||
const data = await getHomeData();
|
||||
if (data.user) updateUser(data.user);
|
||||
}
|
||||
uni.$on("update-hot", updateHot);
|
||||
});
|
||||
onBeforeUnmount(() => {
|
||||
uni.$off("update-hot", updateHot);
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Container :bgType="4" bgColor="#F5F5F5" :whiteBackArrow="false" title="">
|
||||
<view class="container"> </view>
|
||||
<view class="container">
|
||||
<view
|
||||
class="header"
|
||||
:style="{
|
||||
paddingTop: capsuleHeight + 'px',
|
||||
overflow: activeTab === 1 ? 'hidden' : 'unset',
|
||||
}"
|
||||
>
|
||||
<image
|
||||
class="bg-image"
|
||||
:src="`../static/app-bg${activeTab === 2 ? 6 : 5}.png`"
|
||||
mode="widthFix"
|
||||
/>
|
||||
<view v-if="activeTab === 0" class="user-header" @click="goSignIn">
|
||||
<block v-if="user.id">
|
||||
<Avatar :src="user.avatar" :size="40" borderColor="#333" />
|
||||
<text class="truncate">{{ user.nickName }}</text>
|
||||
<image
|
||||
v-if="heat"
|
||||
:src="`../static/hot${heat}.png`"
|
||||
mode="widthFix"
|
||||
/>
|
||||
</block>
|
||||
<block v-else>
|
||||
<image src="../static/user-icon.png" mode="widthFix" />
|
||||
<text>新来的弓箭手你好呀~</text>
|
||||
</block>
|
||||
</view>
|
||||
<view v-if="activeTab === 1" class="title">History</view>
|
||||
</view>
|
||||
<view
|
||||
class="body"
|
||||
:style="{
|
||||
height: 'calc(100% - 50px - ' + capsuleHeight + 'px - 160rpx - 25rpx)',
|
||||
overflowY: activeTab === 2 ? 'unset' : 'hidden',
|
||||
}"
|
||||
>
|
||||
<Home v-show="activeTab === 0" />
|
||||
<History v-show="activeTab === 1" />
|
||||
<Profile v-show="activeTab === 2" />
|
||||
</view>
|
||||
<view class="tabbar">
|
||||
<button hover-class="none" @click="onClickTab(0)">
|
||||
<image
|
||||
@@ -77,14 +137,64 @@ onMounted(async () => {
|
||||
>
|
||||
</button>
|
||||
</view>
|
||||
</Container>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.container {
|
||||
width: calc(100% - 50rpx);
|
||||
height: 100%;
|
||||
padding: 25rpx;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
background: #f5f5f5;
|
||||
}
|
||||
.header {
|
||||
height: 50px;
|
||||
position: relative;
|
||||
font-weight: 500;
|
||||
font-size: 30rpx;
|
||||
color: #333333;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
z-index: 1;
|
||||
}
|
||||
.title {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
.header > image {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
}
|
||||
.user-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
position: relative;
|
||||
margin-left: 30rpx;
|
||||
}
|
||||
.user-header > image:first-child {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 50%;
|
||||
border: 2rpx solid #333;
|
||||
}
|
||||
.user-header > image:last-child {
|
||||
width: 36rpx;
|
||||
height: 36rpx;
|
||||
}
|
||||
.user-header > text:nth-child(2) {
|
||||
font-weight: 500;
|
||||
font-size: 30rpx;
|
||||
color: #333333;
|
||||
margin: 0 20rpx;
|
||||
max-width: 300rpx;
|
||||
}
|
||||
.body {
|
||||
position: relative;
|
||||
padding: 25rpx 25rpx 0rpx 25rpx;
|
||||
z-index: 2;
|
||||
}
|
||||
.tabbar {
|
||||
width: 100%;
|
||||
|
||||
BIN
src/static/app-bg6.png
Normal file
BIN
src/static/app-bg6.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 8.5 KiB |
BIN
src/static/back-grey.png
Normal file
BIN
src/static/back-grey.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 273 B |
BIN
src/static/email-yellow.png
Normal file
BIN
src/static/email-yellow.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
BIN
src/static/password-yellow.png
Normal file
BIN
src/static/password-yellow.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 687 B |
BIN
src/static/pen-yellow.png
Normal file
BIN
src/static/pen-yellow.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.3 KiB |
BIN
src/static/user-yellow.png
Normal file
BIN
src/static/user-yellow.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 877 B |
@@ -74,3 +74,5 @@ $uni-color-subtitle: #555; // 二级标题颜色
|
||||
$uni-font-size-subtitle: 18px;
|
||||
$uni-color-paragraph: #3f536e; // 文章段落颜色
|
||||
$uni-font-size-paragraph: 15px;
|
||||
|
||||
$uni-link-color: #287fff;
|
||||
|
||||
Reference in New Issue
Block a user