UI优化
This commit is contained in:
@@ -194,4 +194,10 @@ button::after {
|
||||
font-size: 14px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.truncate {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -18,7 +18,7 @@ const tabs = [
|
||||
];
|
||||
|
||||
function handleTabClick(index) {
|
||||
if (index !== 0 && !user.value.id) return props.signin();
|
||||
if (index === 1 && !user.value.id) return props.signin();
|
||||
if (index === 0) {
|
||||
uni.navigateTo({
|
||||
url: "/pages/be-vip",
|
||||
|
||||
@@ -52,6 +52,8 @@ const props = defineProps({
|
||||
:rowCount="arrows.length === 12 ? 6 : 9"
|
||||
:total="arrows.length"
|
||||
:scores="arrows.map((a) => a.ring)"
|
||||
:margin="arrows.length === 12 ? 4 : 1"
|
||||
:fontSize="arrows.length === 12 ? 25 : 22"
|
||||
/>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
<script setup>
|
||||
import { ref, watch } from "vue";
|
||||
import BowPower from "@/components/BowPower.vue";
|
||||
import { simulShootAPI } from "@/apis";
|
||||
import useStore from "@/store";
|
||||
import { storeToRefs } from "pinia";
|
||||
const store = useStore();
|
||||
const { device } = storeToRefs(store);
|
||||
|
||||
const props = defineProps({
|
||||
totalRound: {
|
||||
type: Number,
|
||||
@@ -38,6 +44,10 @@ const props = defineProps({
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
start: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
showE: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
@@ -73,6 +83,9 @@ function calcRealY(num) {
|
||||
const len = num < 0 ? Math.abs(num) + 20 : 20 - num;
|
||||
return `calc(${(len / 40) * 100}% - 10px)`;
|
||||
}
|
||||
const simulShoot = async () => {
|
||||
if (device.value.deviceId) await simulShootAPI(device.value.deviceId);
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -90,8 +103,9 @@ function calcRealY(num) {
|
||||
<view
|
||||
v-if="scores.length && showRoundTips && showLatestArrow && showE"
|
||||
class="e-value fade-in"
|
||||
>经验 +1</view
|
||||
>
|
||||
经验 +1
|
||||
</view>
|
||||
<view
|
||||
v-if="scores.length && showRoundTips && showLatestArrow"
|
||||
class="round-tip fade-in"
|
||||
@@ -133,6 +147,9 @@ function calcRealY(num) {
|
||||
<image :src="avatar" mode="widthFix" />
|
||||
</view>
|
||||
<text v-if="tips">{{ tips }}</text>
|
||||
<view class="simul" @click="simulShoot" :style="{ color: '#fff' }">
|
||||
模拟射箭
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
@@ -141,9 +158,11 @@ function calcRealY(num) {
|
||||
width: calc(100% - 30px);
|
||||
padding: 15px;
|
||||
/* overflow: hidden; */
|
||||
position: relative;
|
||||
}
|
||||
.target {
|
||||
position: relative;
|
||||
padding: 5px;
|
||||
}
|
||||
.e-value {
|
||||
position: absolute;
|
||||
@@ -166,7 +185,7 @@ function calcRealY(num) {
|
||||
z-index: 2;
|
||||
}
|
||||
.round-tip > text {
|
||||
font-size: 18px;
|
||||
font-size: 24px;
|
||||
margin-left: 5px;
|
||||
}
|
||||
.target > image:last-child {
|
||||
@@ -217,4 +236,11 @@ function calcRealY(num) {
|
||||
display: block;
|
||||
margin-top: 20px;
|
||||
}
|
||||
.simul {
|
||||
position: absolute;
|
||||
bottom: 20px;
|
||||
right: 20px;
|
||||
color: #fff;
|
||||
margin-left: 20px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,14 +1,19 @@
|
||||
<script setup>
|
||||
defineProps({
|
||||
tall: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
noBg: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
type: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
});
|
||||
const bubbleTypes = [
|
||||
"../static/long-bubble.png",
|
||||
"../static/long-bubble-middle.png",
|
||||
"../static/long-bubble-tall.png",
|
||||
];
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -17,10 +22,8 @@ defineProps({
|
||||
<view>
|
||||
<image
|
||||
v-if="!noBg"
|
||||
:src="
|
||||
tall ? '../static/long-bubble-tall.png' : '../static/long-bubble.png'
|
||||
"
|
||||
:style="{ top: tall ? '-6%' : '-12%' }"
|
||||
:src="bubbleTypes[type]"
|
||||
:style="{ top: type === 2 ? '-5%' : '-12%' }"
|
||||
mode="widthFix"
|
||||
/>
|
||||
<slot />
|
||||
|
||||
@@ -1,10 +1,5 @@
|
||||
<script setup>
|
||||
import { ref, onMounted } from "vue";
|
||||
import useStore from "@/store";
|
||||
import { simulShootAPI } from "@/apis";
|
||||
import { storeToRefs } from "pinia";
|
||||
const store = useStore();
|
||||
const { device } = storeToRefs(store);
|
||||
const isIos = ref(true);
|
||||
|
||||
const props = defineProps({
|
||||
@@ -18,12 +13,6 @@ const props = defineProps({
|
||||
},
|
||||
});
|
||||
|
||||
const simulShoot = async () => {
|
||||
if (device.value.deviceId) {
|
||||
await simulShootAPI(device.value.deviceId);
|
||||
}
|
||||
};
|
||||
|
||||
const onClick = () => {
|
||||
if (props.onBack) props.onBack();
|
||||
else uni.navigateBack();
|
||||
@@ -41,7 +30,6 @@ onMounted(() => {
|
||||
<image src="../static/back.png" mode="widthFix" />
|
||||
</view>
|
||||
<text>{{ title }}</text>
|
||||
<view class="simul" @click="simulShoot">模拟射箭</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
@@ -67,8 +55,4 @@ onMounted(() => {
|
||||
.container > text {
|
||||
color: #fff;
|
||||
}
|
||||
.simul {
|
||||
color: #fff;
|
||||
margin-left: 20px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -77,13 +77,14 @@ const onSelect = (userId) => {
|
||||
<BowTarget
|
||||
:scores="scores"
|
||||
:showLatestArrow="false"
|
||||
:avatar="currentUser.avatar"
|
||||
:avatar="currentUser ? currentUser.avatar : ''"
|
||||
/>
|
||||
</view>
|
||||
<view class="score-text"
|
||||
><text :style="{ color: '#fed847' }">12</text>支箭,共<text
|
||||
:style="{ color: '#fed847' }"
|
||||
>100</text
|
||||
><text :style="{ color: '#fed847' }">{{ scores.length }}</text
|
||||
>支箭,共<text :style="{ color: '#fed847' }">{{
|
||||
scores.reduce((last, next) => last + next.ring, 0)
|
||||
}}</text
|
||||
>环</view
|
||||
>
|
||||
<view class="score-row">
|
||||
|
||||
@@ -53,16 +53,15 @@ const rowCount = new Array(6).fill(0);
|
||||
|
||||
<style scoped>
|
||||
.container {
|
||||
width: calc(100% - 75px);
|
||||
width: calc(100% - 70px);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border: 1px solid #fff3;
|
||||
margin: 10px 0;
|
||||
margin-left: 40px;
|
||||
margin-left: 35px;
|
||||
border-radius: 15px;
|
||||
padding: 10px;
|
||||
color: #fff9;
|
||||
margin-right: 20px;
|
||||
font-size: 14px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
@@ -44,7 +44,8 @@ watch(
|
||||
margin: margin + 'px',
|
||||
}"
|
||||
>
|
||||
{{ scores[index] }}
|
||||
<image src="../static/score-bg.png" mode="widthFix" />
|
||||
<text>{{ scores[index] }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
@@ -58,13 +59,22 @@ watch(
|
||||
margin: 0 5vw;
|
||||
}
|
||||
.score-item {
|
||||
background-image: url("../static/score-bg.png");
|
||||
/* background-image: url("../static/score-bg.png");
|
||||
background-size: cover;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
background-position: center; */
|
||||
color: #fed847;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
}
|
||||
.score-item > image {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
top: 5%;
|
||||
}
|
||||
.score-item > text {
|
||||
position: relative;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -52,11 +52,7 @@ setTimeout(() => {
|
||||
<image src="../static/finish-frame.png" mode="widthFix" />
|
||||
<text
|
||||
>完成<text class="gold-text">{{ total }}</text
|
||||
>箭,获得<text class="gold-text">{{
|
||||
result.arrows
|
||||
.map((a) => a.ring)
|
||||
.reduce((last, next) => last + next, 0)
|
||||
}}</text
|
||||
>箭,获得<text class="gold-text">{{ total }}</text
|
||||
>点经验</text
|
||||
>
|
||||
</view>
|
||||
|
||||
@@ -118,6 +118,7 @@ onUnmounted(() => {
|
||||
}
|
||||
.container > view:first-child > button:last-child > image {
|
||||
width: 50px;
|
||||
transform: translateX(10px);
|
||||
}
|
||||
.container > view:last-child {
|
||||
z-index: -1;
|
||||
|
||||
@@ -137,7 +137,7 @@ const handleLogin = () => {
|
||||
align-items: center;
|
||||
margin-bottom: 20px;
|
||||
border-bottom: 1px solid #fff3;
|
||||
padding: 20px 2px;
|
||||
line-height: 55px;
|
||||
}
|
||||
.avatar {
|
||||
margin: 0;
|
||||
|
||||
@@ -22,6 +22,7 @@ const redScores = ref([]);
|
||||
const blueScores = ref([]);
|
||||
const tabs = ref(["所有轮次"]);
|
||||
const players = ref([]);
|
||||
const allRoundsScore = ref({});
|
||||
const onClickTab = (index) => {
|
||||
selected.value = index;
|
||||
redScores.value = [];
|
||||
@@ -29,14 +30,22 @@ const onClickTab = (index) => {
|
||||
const { bluePlayers, redPlayers, roundsData } = props.data;
|
||||
if (index === 0) {
|
||||
Object.keys(bluePlayers).forEach((p) => {
|
||||
allRoundsScore.value[p] = [];
|
||||
Object.values(roundsData).forEach((round) => {
|
||||
allRoundsScore.value[p].push(
|
||||
round[p].reduce((last, next) => last + next.ring, 0)
|
||||
);
|
||||
round[p].forEach((arrow) => {
|
||||
blueScores.value.push(arrow);
|
||||
});
|
||||
});
|
||||
});
|
||||
Object.keys(redPlayers).forEach((p) => {
|
||||
allRoundsScore.value[p] = [];
|
||||
Object.values(roundsData).forEach((round) => {
|
||||
allRoundsScore.value[p].push(
|
||||
round[p].reduce((last, next) => last + next.ring, 0)
|
||||
);
|
||||
round[p].forEach((arrow) => {
|
||||
redScores.value.push(arrow);
|
||||
});
|
||||
@@ -108,6 +117,15 @@ watch(
|
||||
:src="player.avatar"
|
||||
:borderColor="data.bluePlayers[player.playerId] ? 1 : 2"
|
||||
/>
|
||||
<view
|
||||
v-if="selected === 0"
|
||||
v-for="(ring, index) in allRoundsScore[player.playerId]"
|
||||
:key="index"
|
||||
class="score-item"
|
||||
:style="{ width: '13vw', height: '13vw' }"
|
||||
>
|
||||
{{ ring }}
|
||||
</view>
|
||||
<view
|
||||
v-if="selected > 0"
|
||||
v-for="(score, index) in data.roundsData[selected][player.playerId]"
|
||||
|
||||
@@ -10,6 +10,10 @@ const props = defineProps({
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
onSignin: {
|
||||
type: Function,
|
||||
default: () => {},
|
||||
},
|
||||
});
|
||||
const nextLvlPoints = ref("");
|
||||
const containerWidth = computed(() => (props.showRank ? "72vw" : "100vw"));
|
||||
@@ -39,46 +43,65 @@ onMounted(() => {
|
||||
|
||||
<template>
|
||||
<view class="container" :style="{ width: containerWidth }">
|
||||
<Avatar :frame="true" :src="user.avatar" :onClick="toUserPage" :size="42" />
|
||||
<view class="user-details">
|
||||
<view class="user-name">
|
||||
<text>{{ user.nickName }}</text>
|
||||
<image
|
||||
class="user-name-image"
|
||||
src="../static/vip1.png"
|
||||
mode="widthFix"
|
||||
/>
|
||||
</view>
|
||||
<view class="user-stats">
|
||||
<text class="level-tag level-tag-first">{{ user.lvlName }}</text>
|
||||
<text class="level-tag level-tag-second">L{{ user.lvl }}</text>
|
||||
<view class="rank-tag">
|
||||
<view
|
||||
class="rank-tag-progress"
|
||||
:style="{
|
||||
width: `${(Math.max(user.scores, 0) / nextLvlPoints) * 100}%`,
|
||||
}"
|
||||
<block v-if="user.id"
|
||||
><Avatar
|
||||
:frame="true"
|
||||
:src="user.avatar"
|
||||
:onClick="toUserPage"
|
||||
:size="42"
|
||||
/>
|
||||
<view class="user-details">
|
||||
<view class="user-name">
|
||||
<text>{{ user.nickName }}</text>
|
||||
<image
|
||||
class="user-name-image"
|
||||
src="../static/vip1.png"
|
||||
mode="widthFix"
|
||||
/>
|
||||
<text class="rank-tag-text">
|
||||
{{ Math.max(user.scores, 0) }}/{{ nextLvlPoints }}
|
||||
</text>
|
||||
</view>
|
||||
<view class="user-stats">
|
||||
<text class="level-tag level-tag-first">{{ user.lvlName }}</text>
|
||||
<text class="level-tag level-tag-second">L{{ user.lvl }}</text>
|
||||
<view class="rank-tag">
|
||||
<view
|
||||
class="rank-tag-progress"
|
||||
:style="{
|
||||
width: `${(Math.max(user.scores, 0) / nextLvlPoints) * 100}%`,
|
||||
}"
|
||||
/>
|
||||
<text class="rank-tag-text">
|
||||
{{ Math.max(user.scores, 0) }}/{{ nextLvlPoints }}
|
||||
</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="showRank === true" class="rank-info">
|
||||
<image
|
||||
class="rank-info-image"
|
||||
src="../static/global-rank.png"
|
||||
mode="widthFix"
|
||||
/>
|
||||
<text>本赛季</text>
|
||||
<text>暂未上榜</text>
|
||||
<!-- <text class="rank-number"
|
||||
<view v-if="showRank === true" class="rank-info">
|
||||
<image
|
||||
class="rank-info-image"
|
||||
src="../static/global-rank.png"
|
||||
mode="widthFix"
|
||||
/>
|
||||
<text>本赛季</text>
|
||||
<text>暂未上榜</text>
|
||||
<!-- <text class="rank-number"
|
||||
>第<text :style="{ color: '#ffd700' }"
|
||||
>{{ user.points }}/{{ user.rankLvl }}</text
|
||||
>名</text
|
||||
> -->
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
<block v-else>
|
||||
<view class="signin">
|
||||
<image src="../static/user-icon.png" mode="widthFix" />
|
||||
<view @click="() => (showModal = true)">
|
||||
<text>新来的弓箭手你好呀~</text>
|
||||
<view @click="onSignin">
|
||||
<text>微信登录</text>
|
||||
<image src="../static/enter-arrow-blue.png" mode="widthFix" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
@@ -163,23 +186,54 @@ onMounted(() => {
|
||||
}
|
||||
|
||||
.rank-info {
|
||||
width: 68px;
|
||||
text-align: left;
|
||||
font-size: 12px;
|
||||
position: relative;
|
||||
color: #b3b3b3;
|
||||
padding-left: 8px;
|
||||
margin-left: 8px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.rank-info-image {
|
||||
position: absolute;
|
||||
top: -6px;
|
||||
left: -9px;
|
||||
width: 90px;
|
||||
}
|
||||
|
||||
.rank-info > text {
|
||||
text-align: center;
|
||||
}
|
||||
.rank-number {
|
||||
display: block;
|
||||
}
|
||||
.signin {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.signin > image {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
}
|
||||
.signin > view {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: flex-start;
|
||||
margin-left: 12px;
|
||||
font-size: 14px;
|
||||
}
|
||||
.signin > view > view:last-child {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.signin > view > view:last-child > text {
|
||||
color: #39a8ff;
|
||||
margin-top: 2px;
|
||||
}
|
||||
.signin > view > view:last-child > image {
|
||||
width: 15px;
|
||||
margin-top: 2px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -68,6 +68,15 @@
|
||||
},
|
||||
{
|
||||
"path": "pages/battle-result"
|
||||
},
|
||||
{
|
||||
"path": "pages/team-bow-data"
|
||||
},
|
||||
{
|
||||
"path": "pages/melee-bow-data"
|
||||
},
|
||||
{
|
||||
"path": "pages/mine-bow-data"
|
||||
}
|
||||
],
|
||||
"globalStyle": {
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
import { ref, onMounted } from "vue";
|
||||
import { onLoad } from "@dcloudio/uni-app";
|
||||
import { getGameAPI } from "@/apis";
|
||||
import TeamResult from "@/components/TeamResult.vue";
|
||||
import MeleeResult from "@/components/MeleeResult.vue";
|
||||
import Avatar from "@/components/Avatar.vue";
|
||||
import { getHomeData } from "@/apis";
|
||||
import useStore from "@/store";
|
||||
@@ -16,13 +14,12 @@ const battleId = ref("");
|
||||
const ifWin = ref(false);
|
||||
const data = ref({});
|
||||
const totalPoints = ref(0);
|
||||
const show = ref(false);
|
||||
|
||||
onLoad(async (options) => {
|
||||
battleId.value = options.battleId;
|
||||
const result = await getGameAPI(
|
||||
// options.battleId || "BATTLE-1749386862250435325-854"
|
||||
options.battleId || "BATTLE-1750142722977234017-746"
|
||||
// options.battleId || "BATTLE-1750688685843436271-553"
|
||||
options.battleId || "BATTLE-1750688536849458226-518"
|
||||
);
|
||||
data.value = result;
|
||||
if (result.mode === 1 && result.redPlayers[user.value.id]) {
|
||||
@@ -45,6 +42,18 @@ onMounted(async () => {
|
||||
const result = await getHomeData();
|
||||
if (result.user) updateUser(result.user);
|
||||
});
|
||||
|
||||
const checkBowData = () => {
|
||||
if (data.value.mode === 1) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/team-bow-data?battleId=${battleId.value}`,
|
||||
});
|
||||
} else if (data.value.mode === 2) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/melee-bow-data?battleId=${battleId.value}`,
|
||||
});
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -56,7 +65,7 @@ onMounted(async () => {
|
||||
mode="widthFix"
|
||||
/>
|
||||
<block v-if="data.mode === 1">
|
||||
<view class="header-team">
|
||||
<view class="header-team" :style="{ marginTop: '25%' }">
|
||||
<image src="../static/battle-result.png" mode="widthFix" />
|
||||
</view>
|
||||
<view class="battle-winner">
|
||||
@@ -73,7 +82,13 @@ onMounted(async () => {
|
||||
<view />
|
||||
</view>
|
||||
<view class="players">
|
||||
<view v-for="(player, index) in data.players" :key="index">
|
||||
<view
|
||||
v-for="(player, index) in data.players"
|
||||
:key="index"
|
||||
:style="{
|
||||
border: player.playerId === user.id ? '1px solid #B04630' : 'none',
|
||||
}"
|
||||
>
|
||||
<image
|
||||
v-if="index === 0"
|
||||
class="player-bg"
|
||||
@@ -111,7 +126,7 @@ onMounted(async () => {
|
||||
mode="widthFix"
|
||||
/>
|
||||
<view v-if="index > 2" class="view-crown">{{ index + 1 }}</view>
|
||||
<Avatar src="../static/avatar.png" :size="36" />
|
||||
<Avatar :src="player.avatar" :size="36" />
|
||||
<view class="player-title">
|
||||
<text>{{ player.name }}</text>
|
||||
<text>钻石三级</text>
|
||||
@@ -133,21 +148,9 @@ onMounted(async () => {
|
||||
>好成绩!全国排位赛等着你!</text
|
||||
>
|
||||
<view class="op-btn">
|
||||
<view @click="() => (show = true)">查看靶纸</view>
|
||||
<view @click="checkBowData">查看靶纸</view>
|
||||
<view @click="exit">退出</view>
|
||||
</view>
|
||||
<TeamResult
|
||||
v-if="data.mode === 1"
|
||||
:show="show"
|
||||
:onClose="() => (show = false)"
|
||||
:data="data"
|
||||
/>
|
||||
<MeleeResult
|
||||
v-if="data.mode === 2"
|
||||
:show="show"
|
||||
:onClose="() => (show = false)"
|
||||
:data="data"
|
||||
/>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
@@ -155,12 +158,12 @@ onMounted(async () => {
|
||||
.container {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
background-color: #000;
|
||||
background-color: #292929;
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
.tag {
|
||||
position: absolute;
|
||||
@@ -199,14 +202,16 @@ onMounted(async () => {
|
||||
}
|
||||
.battle-winner > text:nth-child(3) {
|
||||
font-size: 30px;
|
||||
margin: 10px;
|
||||
margin-bottom: 5px;
|
||||
font-weight: bold;
|
||||
color: #fed847;
|
||||
}
|
||||
.battle-winner > text:nth-child(4) {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.battle-e {
|
||||
width: 100%;
|
||||
height: 60px;
|
||||
margin: 20px 0;
|
||||
}
|
||||
.battle-e > image {
|
||||
position: absolute;
|
||||
@@ -251,6 +256,7 @@ onMounted(async () => {
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
margin-bottom: 30px;
|
||||
margin-top: 25%;
|
||||
}
|
||||
.header-melee > view {
|
||||
height: 1px;
|
||||
@@ -280,6 +286,7 @@ onMounted(async () => {
|
||||
background-color: #ffffff1a;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.player-bg {
|
||||
position: absolute;
|
||||
|
||||
@@ -3,12 +3,15 @@ import { ref } from "vue";
|
||||
import Container from "@/components/Container.vue";
|
||||
import Avatar from "@/components/Avatar.vue";
|
||||
import SButton from "@/components/SButton.vue";
|
||||
import SModal from "@/components/SModal.vue";
|
||||
import Signin from "@/components/Signin.vue";
|
||||
import useStore from "@/store";
|
||||
import { storeToRefs } from "pinia";
|
||||
const store = useStore();
|
||||
const { user, config } = storeToRefs(store);
|
||||
|
||||
const selectedVIP = ref(0);
|
||||
const showModal = ref(false);
|
||||
|
||||
const chooseVip = (index) => {
|
||||
selectedVIP.value = index;
|
||||
@@ -16,10 +19,8 @@ const chooseVip = (index) => {
|
||||
|
||||
const onPay = () => {
|
||||
if (!user.value.id) {
|
||||
return uni.showToast({
|
||||
title: "请先登录",
|
||||
icon: "none",
|
||||
});
|
||||
showModal.value = true;
|
||||
} else {
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -29,7 +30,7 @@ const onPay = () => {
|
||||
<view v-if="user.id" class="header">
|
||||
<view>
|
||||
<Avatar :src="user.avatar" :size="35" :border="true" />
|
||||
<text>{{ user.nickName }}</text>
|
||||
<text class="truncate">{{ user.nickName }}</text>
|
||||
</view>
|
||||
<text>5月5号到期</text>
|
||||
</view>
|
||||
@@ -76,6 +77,9 @@ const onPay = () => {
|
||||
</view>
|
||||
</view>
|
||||
<SButton :onClick="onPay">支付</SButton>
|
||||
<SModal :show="showModal" :onClose="() => (showModal = false)">
|
||||
<Signin :onClose="() => (showModal = false)" />
|
||||
</SModal>
|
||||
</view>
|
||||
</Container>
|
||||
</template>
|
||||
@@ -97,6 +101,8 @@ const onPay = () => {
|
||||
}
|
||||
.header > view > text:last-child {
|
||||
margin-left: 10px;
|
||||
width: 120px;
|
||||
text-align: left;
|
||||
}
|
||||
.header > text:nth-child(2) {
|
||||
color: #fed847;
|
||||
|
||||
@@ -118,8 +118,12 @@ const onClose = () => {
|
||||
<view class="container">
|
||||
<Guide
|
||||
v-if="step !== 4"
|
||||
:tall="
|
||||
(step === 1 && user.nickName.length > 6) || step === 2 || step === 5
|
||||
:type="
|
||||
step === 2
|
||||
? 2
|
||||
: step === 5 || (step === 1 && user.nickName.length > 6)
|
||||
? 1
|
||||
: 0
|
||||
"
|
||||
>
|
||||
<text v-if="step === 0">
|
||||
|
||||
@@ -67,21 +67,19 @@ onMounted(async () => {
|
||||
console.error("获取配置失败:", error);
|
||||
}
|
||||
});
|
||||
|
||||
const comingSoon = () => {
|
||||
uni.showToast({
|
||||
title: "敬请期待",
|
||||
icon: "none",
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<view class="root-container" :style="{ paddingTop: isIos ? '45px' : '40px' }">
|
||||
<AppBackground />
|
||||
<!-- 根据登录状态显示用户信息或登录按钮 -->
|
||||
<block v-if="user.id">
|
||||
<UserHeader showRank />
|
||||
</block>
|
||||
<block v-else>
|
||||
<view class="signin-btn" @click="() => (showModal = true)">
|
||||
<text>新来的弓箭手你好呀~</text>
|
||||
<text>微信登录 ></text>
|
||||
</view>
|
||||
</block>
|
||||
<UserHeader showRank :onSignin="() => (showModal = true)" />
|
||||
<view class="container">
|
||||
<view class="feature-grid">
|
||||
<view class="bow-card">
|
||||
@@ -141,6 +139,7 @@ onMounted(async () => {
|
||||
v-for="(region, index) in ['广东', '湖南', '内蒙', '海南', '四川']"
|
||||
:key="index"
|
||||
class="region-item"
|
||||
@click="comingSoon"
|
||||
>
|
||||
<image src="../static/region-bg.png" mode="widthFix" />
|
||||
<image
|
||||
@@ -174,7 +173,7 @@ onMounted(async () => {
|
||||
<text>分</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="region-more">
|
||||
<view class="region-more" @click="comingSoon">
|
||||
<image src="../static/region-more.png" mode="widthFix" />
|
||||
<text>...</text>
|
||||
<text>更多</text>
|
||||
@@ -385,16 +384,4 @@ onMounted(async () => {
|
||||
line-height: 20px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.signin-btn {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: flex-start;
|
||||
margin-left: 10px;
|
||||
font-size: 14px;
|
||||
}
|
||||
.signin-btn > text:last-child {
|
||||
color: #39a8ff;
|
||||
margin-top: 2px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -4,21 +4,23 @@ import { onLoad } from "@dcloudio/uni-app";
|
||||
import Container from "@/components/Container.vue";
|
||||
import BattleHeader from "@/components/BattleHeader.vue";
|
||||
import Avatar from "@/components/Avatar.vue";
|
||||
import TeamResult from "@/components/TeamResult.vue";
|
||||
import MeleeResult from "@/components/MeleeResult.vue";
|
||||
// import TeamResult from "@/components/TeamResult.vue";
|
||||
// import MeleeResult from "@/components/MeleeResult.vue";
|
||||
import PlayerScore from "@/components/PlayerScore.vue";
|
||||
import { getGameAPI } from "@/apis";
|
||||
|
||||
const blueTeam = ref([]);
|
||||
const redTeam = ref([]);
|
||||
const roundsData = ref([]);
|
||||
const battleId = ref("");
|
||||
const data = ref({
|
||||
players: [],
|
||||
});
|
||||
const show = ref(false);
|
||||
// const show = ref(false);
|
||||
|
||||
onLoad(async (options) => {
|
||||
if (options.id) {
|
||||
battleId.value = options.id;
|
||||
const result = await getGameAPI(options.id);
|
||||
data.value = result;
|
||||
if (result.mode === 1) {
|
||||
@@ -51,6 +53,18 @@ onLoad(async (options) => {
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const checkBowData = () => {
|
||||
if (data.value.mode === 1) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/team-bow-data?battleId=${battleId.value}`,
|
||||
});
|
||||
} else if (data.value.mode === 2) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/melee-bow-data?battleId=${battleId.value}`,
|
||||
});
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -93,7 +107,7 @@ onLoad(async (options) => {
|
||||
:style="{ border: 'none', padding: '5px 15px' }"
|
||||
>
|
||||
<text>大乱斗</text>
|
||||
<view @click="() => (show = true)">
|
||||
<view @click="checkBowData">
|
||||
<text>查看靶纸</text>
|
||||
<image src="../static/back.png" mode="widthFix" />
|
||||
</view>
|
||||
@@ -114,7 +128,7 @@ onLoad(async (options) => {
|
||||
>
|
||||
<view class="score-header">
|
||||
<text>第{{ index + 1 }}轮</text>
|
||||
<view @click="() => (show = true)">
|
||||
<view @click="checkBowData">
|
||||
<text>查看靶纸</text>
|
||||
<image src="../static/back.png" mode="widthFix" />
|
||||
</view>
|
||||
@@ -150,7 +164,7 @@ onLoad(async (options) => {
|
||||
</view>
|
||||
<view :style="{ height: '20px' }"></view>
|
||||
</view>
|
||||
<TeamResult
|
||||
<!-- <TeamResult
|
||||
v-if="data.mode === 1"
|
||||
:show="show"
|
||||
:onClose="() => (show = false)"
|
||||
@@ -161,7 +175,7 @@ onLoad(async (options) => {
|
||||
:show="show"
|
||||
:onClose="() => (show = false)"
|
||||
:data="data"
|
||||
/>
|
||||
/> -->
|
||||
</Container>
|
||||
</template>
|
||||
|
||||
|
||||
187
src/pages/melee-bow-data.vue
Normal file
187
src/pages/melee-bow-data.vue
Normal file
@@ -0,0 +1,187 @@
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import { onLoad } from "@dcloudio/uni-app";
|
||||
import Container from "@/components/Container.vue";
|
||||
import BowTarget from "@/components/BowTarget.vue";
|
||||
import Avatar from "@/components/Avatar.vue";
|
||||
import { roundsName } from "@/constants";
|
||||
import { getGameAPI } from "@/apis";
|
||||
import useStore from "@/store";
|
||||
import { storeToRefs } from "pinia";
|
||||
const store = useStore();
|
||||
const { user } = storeToRefs(store);
|
||||
const scores = ref([]);
|
||||
const currentUser = ref({});
|
||||
const data = ref({});
|
||||
onLoad(async (options) => {
|
||||
if (options.battleId) {
|
||||
const result = await getGameAPI(options.battleId);
|
||||
data.value = result;
|
||||
const mine = result.players.find((p) => p.playerId === user.value.id);
|
||||
currentUser.value = mine;
|
||||
if (mine && mine.arrowHistory) {
|
||||
scores.value = mine.arrowHistory;
|
||||
}
|
||||
}
|
||||
});
|
||||
const onSelect = (userId) => {
|
||||
const user = data.value.players.find((p) => p.playerId === userId);
|
||||
currentUser.value = user;
|
||||
if (user && user.arrowHistory) {
|
||||
scores.value = user.arrowHistory;
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Container title="5人大乱斗 - 靶纸">
|
||||
<view class="container">
|
||||
<view class="rank-rows">
|
||||
<view
|
||||
v-for="(player, index) in data.players"
|
||||
:key="index"
|
||||
@click="() => onSelect(player.playerId)"
|
||||
>
|
||||
<image
|
||||
v-if="index === 0"
|
||||
src="../static/champ1.png"
|
||||
mode="widthFix"
|
||||
/>
|
||||
<image
|
||||
v-if="index === 1"
|
||||
src="../static/champ2.png"
|
||||
mode="widthFix"
|
||||
/>
|
||||
<image
|
||||
v-if="index === 2"
|
||||
src="../static/champ3.png"
|
||||
mode="widthFix"
|
||||
/>
|
||||
<view v-if="index > 2" class="rank-view">{{ index + 1 }}</view>
|
||||
<Avatar :src="player.avatar" :size="24" />
|
||||
<text
|
||||
>积分
|
||||
{{
|
||||
player.totalScore > 0
|
||||
? "+" + player.totalScore
|
||||
: player.totalScore
|
||||
}}分</text
|
||||
>
|
||||
<text>{{ player.totalRings }}环</text>
|
||||
<text v-for="(arrow, index2) in player.arrowHistory" :key="index2">
|
||||
{{ arrow.ring }}环
|
||||
</text>
|
||||
</view>
|
||||
</view>
|
||||
<view :style="{ margin: '20px 0' }">
|
||||
<BowTarget
|
||||
:scores="scores"
|
||||
:showLatestArrow="false"
|
||||
:avatar="currentUser ? currentUser.avatar : ''"
|
||||
/>
|
||||
</view>
|
||||
<view class="score-text"
|
||||
><text :style="{ color: '#fed847' }">{{ scores.length }}</text
|
||||
>支箭,共<text :style="{ color: '#fed847' }">{{
|
||||
scores.reduce((last, next) => last + next.ring, 0)
|
||||
}}</text
|
||||
>环</view
|
||||
>
|
||||
<view class="score-row">
|
||||
<view
|
||||
v-for="(score, index) in scores"
|
||||
:key="index"
|
||||
class="score-item"
|
||||
:style="{ width: '13vw', height: '13vw' }"
|
||||
>
|
||||
{{ score.ring }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</Container>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.container {
|
||||
width: 100%;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
.score-text {
|
||||
width: 100%;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
font-size: 16px;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
.score-row {
|
||||
margin: 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.score-item {
|
||||
background-image: url("../static/score-bg.png");
|
||||
background-size: cover;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
color: #fed847;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-size: 24px;
|
||||
margin: 3px;
|
||||
}
|
||||
.rank-rows {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
border-top: 1px solid #fff3;
|
||||
}
|
||||
.rank-rows > view {
|
||||
width: clac(100% - 20px);
|
||||
color: #fff9;
|
||||
border-bottom: 1px solid #fff3;
|
||||
padding: 7px 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 14px;
|
||||
overflow-x: auto;
|
||||
}
|
||||
.rank-rows > view::-webkit-scrollbar {
|
||||
width: 0;
|
||||
height: 0;
|
||||
color: transparent;
|
||||
}
|
||||
.rank-rows > view > image:first-child,
|
||||
.rank-rows > view > view:first-child {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
text-align: center;
|
||||
font-size: 12px;
|
||||
margin-right: 10px;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
.rank-rows > view > view:first-child {
|
||||
background-color: #6d6d6d;
|
||||
border-radius: 50%;
|
||||
}
|
||||
.rank-rows > view > text {
|
||||
margin-left: 10px;
|
||||
flex: 0 0 auto;
|
||||
display: block;
|
||||
width: 25px;
|
||||
}
|
||||
.rank-rows > view > text:nth-child(3) {
|
||||
width: 80px;
|
||||
}
|
||||
.rank-rows > view > text:nth-child(4) {
|
||||
color: #fed847;
|
||||
padding-right: 10px;
|
||||
border-right: 1px solid #fff3;
|
||||
width: 32px;
|
||||
}
|
||||
</style>
|
||||
102
src/pages/mine-bow-data.vue
Normal file
102
src/pages/mine-bow-data.vue
Normal file
@@ -0,0 +1,102 @@
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import { onLoad } from "@dcloudio/uni-app";
|
||||
import Container from "@/components/Container.vue";
|
||||
import Avatar from "@/components/Avatar.vue";
|
||||
import BowTarget from "@/components/BowTarget.vue";
|
||||
import ScorePanel from "@/components/ScorePanel.vue";
|
||||
import { getPractiseAPI } from "@/apis";
|
||||
import useStore from "@/store";
|
||||
import { storeToRefs } from "pinia";
|
||||
const store = useStore();
|
||||
const { user } = storeToRefs(store);
|
||||
const arrows = ref([]);
|
||||
|
||||
onLoad(async (options) => {
|
||||
if (options.id) {
|
||||
const result = await getPractiseAPI(options.id);
|
||||
arrows.value = result.arrows;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Container title="个人练习 - 靶纸">
|
||||
<view class="container">
|
||||
<!-- <view class="header">
|
||||
<view>
|
||||
<Avatar :src="user.avatar" frame />
|
||||
<view>
|
||||
<text>{{ user.nickName }}</text>
|
||||
<text>{{ user.lvlName }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view> -->
|
||||
<view :style="{ marginBottom: '20px' }">
|
||||
<BowTarget :scores="arrows" :showLatestArrow="false" />
|
||||
</view>
|
||||
<view class="desc">
|
||||
<text>{{ arrows.length }}</text>
|
||||
<text>支箭,共</text>
|
||||
<text>{{ arrows.reduce((a, b) => a + b.ring, 0) }}</text>
|
||||
<text>环</text>
|
||||
</view>
|
||||
<ScorePanel
|
||||
:rowCount="arrows.length === 12 ? 6 : 9"
|
||||
:total="arrows.length"
|
||||
:scores="arrows.map((a) => a.ring)"
|
||||
:margin="arrows.length === 12 ? 4 : 1"
|
||||
:fontSize="arrows.length === 12 ? 25 : 22"
|
||||
/>
|
||||
</view>
|
||||
</Container>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.container {
|
||||
width: 100%;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
.header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
width: calc(100% - 20px);
|
||||
padding: 10px;
|
||||
}
|
||||
.header > view:first-child {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-left: 10px;
|
||||
}
|
||||
.header > view:first-child > view:last-child {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
margin-left: 10px;
|
||||
color: #fff;
|
||||
}
|
||||
.header > view:first-child > view:last-child > text:last-child {
|
||||
font-size: 10px;
|
||||
color: #fff9;
|
||||
background-color: #5f51ff;
|
||||
padding: 2px 5px;
|
||||
border-radius: 10px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
.header > view:last-child > image {
|
||||
width: 40px;
|
||||
}
|
||||
.desc {
|
||||
color: #fff;
|
||||
margin-bottom: 40px;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
.desc > text:nth-child(2),
|
||||
.desc > text:nth-child(4) {
|
||||
color: #fed847;
|
||||
}
|
||||
</style>
|
||||
@@ -4,11 +4,7 @@ import Container from "@/components/Container.vue";
|
||||
import Avatar from "@/components/Avatar.vue";
|
||||
import BowData from "@/components/BowData.vue";
|
||||
import ScrollList from "@/components/ScrollList.vue";
|
||||
import {
|
||||
getBattleListAPI,
|
||||
getPractiseResultListAPI,
|
||||
getPractiseAPI,
|
||||
} from "@/apis";
|
||||
import { getBattleListAPI, getPractiseResultListAPI } from "@/apis";
|
||||
|
||||
import { ref } from "vue";
|
||||
|
||||
@@ -16,8 +12,8 @@ const selectedIndex = ref(0);
|
||||
const matchList = ref([]);
|
||||
const battleList = ref([]);
|
||||
const practiseList = ref([]);
|
||||
const showBowData = ref(false);
|
||||
const arrows = ref([]);
|
||||
// const showBowData = ref(false);
|
||||
// const arrows = ref([]);
|
||||
|
||||
const toMatchDetail = (id) => {
|
||||
uni.navigateTo({
|
||||
@@ -25,9 +21,9 @@ const toMatchDetail = (id) => {
|
||||
});
|
||||
};
|
||||
const getPractiseDetail = async (id) => {
|
||||
const result = await getPractiseAPI(id);
|
||||
arrows.value = result.arrows;
|
||||
showBowData.value = true;
|
||||
uni.navigateTo({
|
||||
url: `/pages/mine-bow-data?id=${id}`,
|
||||
});
|
||||
};
|
||||
const onMatchLoading = async (page) => {
|
||||
const result = await getBattleListAPI(page, 2);
|
||||
@@ -175,11 +171,11 @@ const onPractiseLoading = async (page) => {
|
||||
</view>
|
||||
</ScrollList>
|
||||
</view>
|
||||
<BowData
|
||||
<!-- <BowData
|
||||
:arrows="arrows"
|
||||
:show="showBowData"
|
||||
:onClose="() => (showBowData = false)"
|
||||
/>
|
||||
/> -->
|
||||
</Container>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ const subTitles = ["排位赛积分", "本周MVP次数", "本周十环次数"];
|
||||
<text>{{ subTitles[selectedIndex] }}</text>
|
||||
</view>
|
||||
<view
|
||||
v-for="(_, index) in new Array(10).fill(1)"
|
||||
v-for="(_, index) in new Array(100).fill(1)"
|
||||
:key="index"
|
||||
class="rank-list-item"
|
||||
:style="{
|
||||
|
||||
@@ -36,6 +36,16 @@ const toMeleeMatchPage = (gameType, teamSize) => {
|
||||
url: `/pages/melee-match?gameType=${gameType}&teamSize=${teamSize}`,
|
||||
});
|
||||
};
|
||||
const toMyGrowthPage = () => {
|
||||
uni.navigateTo({
|
||||
url: "/pages/my-growth",
|
||||
});
|
||||
};
|
||||
const toRankListPage = () => {
|
||||
uni.navigateTo({
|
||||
url: "/pages/rank-list",
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -101,7 +111,7 @@ const toMeleeMatchPage = (gameType, teamSize) => {
|
||||
<view :style="{ width: '45%', backgroundColor: '#FFD947' }" />
|
||||
</view>
|
||||
</view>
|
||||
<view>查看我的比赛记录</view>
|
||||
<view @click="toMyGrowthPage">查看我的比赛记录</view>
|
||||
</view>
|
||||
<view class="ranking-data">
|
||||
<view>
|
||||
@@ -143,6 +153,7 @@ const toMeleeMatchPage = (gameType, teamSize) => {
|
||||
<text>8850<text>分</text></text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="see-more" @click="toRankListPage">点击查看更多</view>
|
||||
</view>
|
||||
</Container>
|
||||
</template>
|
||||
@@ -160,6 +171,8 @@ const toMeleeMatchPage = (gameType, teamSize) => {
|
||||
border: 1px solid #54431d;
|
||||
border-radius: 10px;
|
||||
margin: 0 15px;
|
||||
}
|
||||
.ranking-my-data {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
.ranking-my-data {
|
||||
@@ -318,4 +331,12 @@ const toMeleeMatchPage = (gameType, teamSize) => {
|
||||
font-size: 13px;
|
||||
margin-left: 3px;
|
||||
}
|
||||
.see-more {
|
||||
color: #39a8ff;
|
||||
font-size: 14px;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
margin-top: 10px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
</style>
|
||||
|
||||
180
src/pages/team-bow-data.vue
Normal file
180
src/pages/team-bow-data.vue
Normal file
@@ -0,0 +1,180 @@
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import { onLoad } from "@dcloudio/uni-app";
|
||||
import Container from "@/components/Container.vue";
|
||||
import BowTarget from "@/components/BowTarget.vue";
|
||||
import Avatar from "@/components/Avatar.vue";
|
||||
import { roundsName } from "@/constants";
|
||||
import { getGameAPI } from "@/apis";
|
||||
const selected = ref(0);
|
||||
const redScores = ref([]);
|
||||
const blueScores = ref([]);
|
||||
const tabs = ref(["所有轮次"]);
|
||||
const players = ref([]);
|
||||
const allRoundsScore = ref({});
|
||||
const data = ref({});
|
||||
onLoad(async (options) => {
|
||||
if (options.battleId) {
|
||||
const result = await getGameAPI(options.battleId);
|
||||
data.value = result;
|
||||
if (result.winner === 0) {
|
||||
players.value = [
|
||||
...Object.values(result.redPlayers),
|
||||
...Object.values(result.bluePlayers),
|
||||
];
|
||||
} else if (result.winner === 1) {
|
||||
players.value = [
|
||||
...Object.values(result.bluePlayers),
|
||||
...Object.values(result.redPlayers),
|
||||
];
|
||||
}
|
||||
Object.keys(result.roundsData).forEach((key) => {
|
||||
tabs.value.push(`第${roundsName[key]}轮`);
|
||||
});
|
||||
onClickTab(0);
|
||||
}
|
||||
});
|
||||
const onClickTab = (index) => {
|
||||
selected.value = index;
|
||||
redScores.value = [];
|
||||
blueScores.value = [];
|
||||
const { bluePlayers, redPlayers, roundsData } = data.value;
|
||||
if (index === 0) {
|
||||
Object.keys(bluePlayers).forEach((p) => {
|
||||
allRoundsScore.value[p] = [];
|
||||
Object.values(roundsData).forEach((round) => {
|
||||
allRoundsScore.value[p].push(
|
||||
round[p].reduce((last, next) => last + next.ring, 0)
|
||||
);
|
||||
round[p].forEach((arrow) => {
|
||||
blueScores.value.push(arrow);
|
||||
});
|
||||
});
|
||||
});
|
||||
Object.keys(redPlayers).forEach((p) => {
|
||||
allRoundsScore.value[p] = [];
|
||||
Object.values(roundsData).forEach((round) => {
|
||||
allRoundsScore.value[p].push(
|
||||
round[p].reduce((last, next) => last + next.ring, 0)
|
||||
);
|
||||
round[p].forEach((arrow) => {
|
||||
redScores.value.push(arrow);
|
||||
});
|
||||
});
|
||||
});
|
||||
} else {
|
||||
Object.keys(bluePlayers).forEach((p) => {
|
||||
roundsData[index][p].forEach((arrow) => {
|
||||
blueScores.value.push(arrow);
|
||||
});
|
||||
});
|
||||
Object.keys(redPlayers).forEach((p) => {
|
||||
roundsData[index][p].forEach((arrow) => {
|
||||
redScores.value.push(arrow);
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Container title="1v1排位赛 - 靶纸">
|
||||
<view class="container">
|
||||
<view>
|
||||
<view
|
||||
v-for="(tab, index) in tabs"
|
||||
:key="index"
|
||||
@click="() => onClickTab(index)"
|
||||
:class="selected === index ? 'selected-tab' : ''"
|
||||
>
|
||||
{{ tab }}
|
||||
</view>
|
||||
</view>
|
||||
<view :style="{ margin: '20px 0' }">
|
||||
<BowTarget
|
||||
:scores="redScores"
|
||||
:blueScores="blueScores"
|
||||
:showLatestArrow="false"
|
||||
/>
|
||||
</view>
|
||||
<view class="score-row" v-for="(player, index) in players" :key="index">
|
||||
<Avatar
|
||||
:src="player.avatar"
|
||||
:borderColor="data.bluePlayers[player.playerId] ? 1 : 2"
|
||||
/>
|
||||
<view
|
||||
v-if="selected === 0"
|
||||
v-for="(ring, index) in allRoundsScore[player.playerId]"
|
||||
:key="index"
|
||||
class="score-item"
|
||||
:style="{ width: '13vw', height: '13vw' }"
|
||||
>
|
||||
{{ ring }}
|
||||
</view>
|
||||
<view
|
||||
v-if="selected > 0"
|
||||
v-for="(score, index) in data.roundsData[selected][player.playerId]"
|
||||
:key="index"
|
||||
class="score-item"
|
||||
:style="{ width: '13vw', height: '13vw' }"
|
||||
>
|
||||
{{ score.ring }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</Container>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.container {
|
||||
width: 100%;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
.container > view:nth-child(1) {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
width: calc(100% - 20px);
|
||||
color: #fff9;
|
||||
padding: 10px;
|
||||
overflow-x: auto;
|
||||
}
|
||||
.container > view:nth-child(1)::-webkit-scrollbar {
|
||||
width: 0;
|
||||
height: 0;
|
||||
color: transparent;
|
||||
}
|
||||
.container > view:nth-child(1) > view {
|
||||
border: 1px solid #fff9;
|
||||
border-radius: 20px;
|
||||
padding: 7px 10px;
|
||||
margin: 0 5px;
|
||||
font-size: 14px;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
.selected-tab {
|
||||
background-color: #fed847;
|
||||
border-color: #fed847 !important;
|
||||
color: #000;
|
||||
}
|
||||
.score-row {
|
||||
margin: 10px 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
.score-item {
|
||||
background-image: url("../static/score-bg.png");
|
||||
background-size: cover;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
color: #fed847;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-size: 24px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
</style>
|
||||
@@ -150,7 +150,7 @@ onUnmounted(() => {
|
||||
:redTeam="redTeam"
|
||||
:blueTeam="blueTeam"
|
||||
/>
|
||||
<Guide noBg v-if="!start && matching">
|
||||
<Guide noBg v-if="!start && battleId">
|
||||
<view :style="{ display: 'flex', justifyContent: 'space-between' }">
|
||||
<view :style="{ display: 'flex', flexDirection: 'column' }">
|
||||
<text :style="{ color: '#fed847' }">请预先射几箭测试</text>
|
||||
@@ -159,7 +159,7 @@ onUnmounted(() => {
|
||||
<BowPower :power="45" />
|
||||
</view>
|
||||
</Guide>
|
||||
<ShootProgress v-if="start" :tips="tips" :seq="seq" :total="30" />
|
||||
<ShootProgress v-if="start" :tips="tips" :seq="seq" :total="15" />
|
||||
<PlayersRow
|
||||
v-if="start"
|
||||
:currentShooterId="currentShooterId"
|
||||
@@ -167,7 +167,7 @@ onUnmounted(() => {
|
||||
:redTeam="redTeam"
|
||||
/>
|
||||
<BowTarget
|
||||
v-if="matching"
|
||||
v-if="battleId"
|
||||
:showE="start && user.id === currentShooterId"
|
||||
:power="start ? power : 0"
|
||||
:currentRound="currentRound"
|
||||
|
||||
BIN
src/static/long-bubble-middle.png
Normal file
BIN
src/static/long-bubble-middle.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.1 KiB |
BIN
src/static/user-icon.png
Normal file
BIN
src/static/user-icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 981 B |
16
src/util.js
16
src/util.js
@@ -33,7 +33,7 @@ export function renderScores(ctx, arrows = []) {
|
||||
item.ring,
|
||||
18,
|
||||
"#fed847",
|
||||
30 + (i % 9) * 30,
|
||||
29.5 + (i % 9) * 30,
|
||||
310 + Math.ceil((i + 1) / 9) * 30,
|
||||
"center"
|
||||
);
|
||||
@@ -171,22 +171,22 @@ export function generateCanvasImage(canvasId, type, user, data) {
|
||||
} else if (type == 3) {
|
||||
titleImage = "../static/practise-two-title.png";
|
||||
}
|
||||
ctx.drawImage(titleImage, (width - 160) / 2 - 5, 160, 160, 40);
|
||||
ctx.drawImage(titleImage, (width - 160) / 2, 160, 160, 40);
|
||||
const subTitleWidth = ctx.measureText(subTitle).width;
|
||||
renderText(
|
||||
ctx,
|
||||
subTitle,
|
||||
18,
|
||||
"#fff",
|
||||
width / 2 - subTitleWidth - (type > 1 ? 15 : 13),
|
||||
width / 2 - subTitleWidth - (type > 1 ? 15 : 9),
|
||||
220
|
||||
);
|
||||
renderText(ctx, "共", 14, "#fff", 124, 300);
|
||||
renderText(ctx, "共", 14, "#fff", 122, 300);
|
||||
const totalRing = data.arrows.reduce((last, next) => last + next.ring, 0);
|
||||
renderText(ctx, totalRing, 14, "#fed847", 150, 300, "center");
|
||||
renderText(ctx, "环", 14, "#fff", 163, 300);
|
||||
renderLine(ctx, 80);
|
||||
renderLine(ctx, 187);
|
||||
renderText(ctx, totalRing, 14, "#fed847", 148, 300, "center");
|
||||
renderText(ctx, "环", 14, "#fff", 161, 300);
|
||||
renderLine(ctx, 77);
|
||||
renderLine(ctx, 185);
|
||||
renderScores(ctx, data.arrows);
|
||||
ctx.drawImage(
|
||||
"../static/device-icon.png",
|
||||
|
||||
@@ -5,9 +5,9 @@ let reconnectTimer = null;
|
||||
|
||||
// 重连配置
|
||||
const RECONNECT_CONFIG = {
|
||||
MAX_COUNT: 10, // 最大重连次数
|
||||
MAX_COUNT: 999, // 最大重连次数
|
||||
INITIAL_DELAY: 2000, // 初始重连延迟(2秒)
|
||||
MAX_DELAY: 60000, // 最大重连延迟(1分钟)
|
||||
MAX_DELAY: 5000, // 最大重连延迟(5秒)
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user