Commit 3bf97d48 authored by 陈冲's avatar 陈冲

fix: 已上榜的玩家不显示在大屏

parent 2ce3787b
...@@ -60,4 +60,43 @@ impl Game { ...@@ -60,4 +60,43 @@ impl Game {
} }
} }
} }
pub async fn get_rank(wechat_id: &str) -> i32 {
let Some(_) = &config.db else {
println!("没有配置数据库, get_rank return 0;");
return 0;
};
let res = crate::db::db_query(
r#"SELECT COUNT(1) AS rank_count FROM tb_game WHERE wechat_id = ?
AND game_rank <= 10"#,
vec![json!(&wechat_id)],
)
.await;
match res {
Ok(res) => res
.first()
.and_then(|row| row.get("rank_count"))
.and_then(|value| value.as_i64().or_else(|| value.as_u64().map(|v| v as i64)))
.unwrap_or(0) as i32,
Err(err) => {
// dbg!(&err);
// let log = Log {
// id: 0,
// msg: err,
// params: json!({
// "wechat_id": self.wechat_id,
// "nickname": self.nickname,
// "avatar": self.avatar,
// "item_num": self.item_num,
// "game_rank":self.game_rank,
// "score": self.score,
// }),
// create_date: None,
// };
// log.insert().await;
0
}
}
}
} }
This diff is collapsed.
...@@ -326,11 +326,11 @@ export function $read_socket_storge(): any | null { ...@@ -326,11 +326,11 @@ export function $read_socket_storge(): any | null {
export function $getWechat(): any | null { export function $getWechat(): any | null {
const q = $query(['token', 'nickname', 'avatar']); const q = $query(['token', 'nickname', 'avatar','userno']);
if (q && q.length == 3) { if (q && q.length == 4) {
return { return {
token: SHA256(q[0]).toString(), //原token很长,这里压缩下,压缩后不能还原,最后提交成绩时要提交原始token token: q[3], //玩家的唯一码,不用做压缩
token_origin: q[0], token_origin: q[0],//这个token要提交给api.guocai365.org.cn做验证
nickname: q[1], nickname: q[1],
avatar: q[2], avatar: q[2],
}; };
...@@ -349,47 +349,12 @@ export function $getWechat(): any | null { ...@@ -349,47 +349,12 @@ export function $getWechat(): any | null {
return null; return null;
} }
export async function postJson(token: string, index: number) { export async function postScreenGameScore(gameCode: string, score: number) {
const url = "https://api.guocai365.org.cn/adminapi/offline_clearance/score/list";
let arr = ['', 'JGQF', 'JBJF', 'MSYF', 'CMYF', 'QCNF', 'FYDT'];
try {
const resp = await fetch(url, {
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
activity_id: 1,
game_code: arr[index],
page: 1,
pageSize: 20,
}),
});
const text = await resp.text();
if (!resp.ok) {
console.error("请求失败:", resp.status, text);
return;
}
// 如果返回的是 JSON
const data = JSON.parse(text);
console.log("响应:", data);
} catch (err) {
console.error("请求异常:", err);
}
}
export async function postScreenGameScore(token: string, gameCode: string, score: number) {
try { try {
const resp = await fetch('https://api.guocai365.org.cn/api/offline_clearance/user/screen_game_score', { const resp = await fetch('https://api.guocai365.org.cn/api/offline_clearance/user/screen_game_score', {
method: 'POST', method: 'POST',
headers: { headers: {
Authorization: token, Authorization: $getWechat()?.token_origin,
'Content-Type': 'application/json', 'Content-Type': 'application/json',
}, },
body: JSON.stringify({ body: JSON.stringify({
......
...@@ -55,6 +55,7 @@ export function sendGameMessage(cmd: string, data: any = {}) { ...@@ -55,6 +55,7 @@ export function sendGameMessage(cmd: string, data: any = {}) {
return sendSocketMessage(cmd, data) return sendSocketMessage(cmd, data)
} }
export const userJoinStatus = ref(false) export const userJoinStatus = ref(false)
export const userTop10RankStatus = ref(false)
export function useGameSocket(options: GameSocketOptions) { export function useGameSocket(options: GameSocketOptions) {
const router = useRouter() const router = useRouter()
...@@ -96,7 +97,7 @@ export function useGameSocket(options: GameSocketOptions) { ...@@ -96,7 +97,7 @@ export function useGameSocket(options: GameSocketOptions) {
// router.replace('/loading').then(() => { }); // router.replace('/loading').then(() => { });
return; return;
} }
if (evt == 'submit_score_save') { if (evt == 'submit_score_save_result') {
//提交分数的情况下有问题的情况下,只重试3次 //提交分数的情况下有问题的情况下,只重试3次
if (resubmitcount >= 3) { if (resubmitcount >= 3) {
return; return;
...@@ -111,12 +112,6 @@ export function useGameSocket(options: GameSocketOptions) { ...@@ -111,12 +112,6 @@ export function useGameSocket(options: GameSocketOptions) {
return; return;
} }
if (state === 0) {
// alert(msg)
$toast(msg)
return
}
switch (evt) { switch (evt) {
case 'room_create_result': { case 'room_create_result': {
// if (`game${data}` == options.gameId) { // if (`game${data}` == options.gameId) {
...@@ -133,10 +128,12 @@ export function useGameSocket(options: GameSocketOptions) { ...@@ -133,10 +128,12 @@ export function useGameSocket(options: GameSocketOptions) {
// break // break
} }
case 'room_join_result': { case 'room_join_result': {
if (data != options.gameId) { if (data.gameId != options.gameId) {
// debugger // debugger
return; return;
} }
//是否上过前十榜
userTop10RankStatus.value = data.alreadyTopRanked
$toast('您已进入游戏房间') $toast('您已进入游戏房间')
userJoinStatus.value = true userJoinStatus.value = true
break break
...@@ -163,10 +160,12 @@ export function useGameSocket(options: GameSocketOptions) { ...@@ -163,10 +160,12 @@ export function useGameSocket(options: GameSocketOptions) {
break break
} }
case 'submit_score_save_result': { case 'submit_score_save_result': {
const submittedScore = options.onScoreSubmitted?.(true, data) if (!userTop10RankStatus) {
const token = $getWechat()?.token_origin const submittedScore = options.onScoreSubmitted?.(true, data)
if (token && submittedScore && Number.isFinite(submittedScore.score)) { const token_origin = $getWechat()?.token_origin
void postScreenGameScore(token, submittedScore.code, submittedScore.score) if (token_origin && submittedScore && Number.isFinite(submittedScore.score)) {
void postScreenGameScore(submittedScore.code, submittedScore.score)
}
} }
break break
} }
...@@ -199,6 +198,7 @@ export function useGameSocket(options: GameSocketOptions) { ...@@ -199,6 +198,7 @@ export function useGameSocket(options: GameSocketOptions) {
return { return {
socket, socket,
userJoinStatus, userJoinStatus,
userTop10RankStatus,
offSocketMessage offSocketMessage
} }
} }
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
import { onBeforeUnmount, onMounted, ref, watch } from 'vue' import { onBeforeUnmount, onMounted, ref, watch } from 'vue'
import { cssAssetUrl } from '@/commons/assets.ts' import { cssAssetUrl } from '@/commons/assets.ts'
import MobileStage from '@/components/MobileStage.vue' import MobileStage from '@/components/MobileStage.vue'
import { useGameSocket, sendGameMessage, userJoinStatus, joinSharedRoom } from '@/composables/useGameSocket' import { useGameSocket, sendGameMessage, userJoinStatus,userTop10RankStatus, joinSharedRoom } from '@/composables/useGameSocket'
import LoadingView from './views/LoadingView.vue' import LoadingView from './views/LoadingView.vue'
import PlayingView from './views/PlayingView.vue' import PlayingView from './views/PlayingView.vue'
import ScoreView from './views/ScoreView.vue' import ScoreView from './views/ScoreView.vue'
...@@ -69,7 +69,7 @@ function submitScore(save: boolean = false) { ...@@ -69,7 +69,7 @@ function submitScore(save: boolean = false) {
//wechat 原始token //wechat 原始token
sendGameMessage('submit_score_save', { sendGameMessage('submit_score_save', {
score: tick.value, score: tick.value,
wechat: wechat.token_origin, wechat: wechat.token,
item_num: 1, item_num: 1,
nickname: wechat.nickname, nickname: wechat.nickname,
avatar: wechat.avatar, avatar: wechat.avatar,
...@@ -143,7 +143,13 @@ function showScoreView() { ...@@ -143,7 +143,13 @@ function showScoreView() {
showGameRule.value = false; showGameRule.value = false;
stopGameCountdown() stopGameCountdown()
setDivDescVisible(false) setDivDescVisible(false)
currentView.value = 'score' if(userTop10RankStatus.value){
currentView.value = 'loading'
userJoinStatus.value = false;
$toast('一人只能上榜领奖一次,您的福利已到手,把机会留给其他玩家吧',30000)
}else{
currentView.value = 'score'
}
} }
const touchHandler = () => { const touchHandler = () => {
...@@ -290,7 +296,7 @@ const showGameRuleHandler = () => { ...@@ -290,7 +296,7 @@ const showGameRuleHandler = () => {
@touchGameRule="showGameRuleHandler" /> @touchGameRule="showGameRuleHandler" />
<PlayingView v-else-if="currentView === 'playing'" :image-urls="imageUrls" :tick="tick" :rank="rank" <PlayingView v-else-if="currentView === 'playing'" :image-urls="imageUrls" :tick="tick" :rank="rank"
:current-gu-frame="currentGuFrame" :countdown-interval="countdownInterval" :is-div-desc-visible="isDivDescVisible" :current-gu-frame="currentGuFrame" :countdown-interval="countdownInterval" :is-div-desc-visible="isDivDescVisible"
@touch="touchHandler" /> @touch="touchHandler" :userTop10RankStatus="userTop10RankStatus" />
<ScoreView v-else :image-urls="imageUrls" :rank="rank" :tick="tick" /> <ScoreView v-else :image-urls="imageUrls" :rank="rank" :tick="tick" />
</MobileStage> </MobileStage>
<div v-else style="text-align: center; width: 100vw; height: 100vh; line-height: 30; font-size: 20px;"> <div v-else style="text-align: center; width: 100vw; height: 100vh; line-height: 30; font-size: 20px;">
......
...@@ -5,7 +5,8 @@ defineProps<{ ...@@ -5,7 +5,8 @@ defineProps<{
isDivDescVisible: boolean isDivDescVisible: boolean
tick: number tick: number
rank: number rank: number
currentGuFrame: number currentGuFrame: number,
userTop10RankStatus: boolean,
}>() }>()
defineEmits<{ defineEmits<{
...@@ -25,7 +26,7 @@ defineEmits<{ ...@@ -25,7 +26,7 @@ defineEmits<{
<div class="play-content"> <div class="play-content">
<div>当前击鼓积分</div> <div>当前击鼓积分</div>
<div>{{ tick }}</div> <div>{{ tick }}</div>
<div>当前排名: &nbsp;&nbsp;<label>{{ rank }}</label>&nbsp;</div> <div v-if="!userTop10RankStatus">当前排名: &nbsp;&nbsp;<label>{{ rank }}</label>&nbsp;</div>
</div> </div>
<div class="bg-bottom"></div> <div class="bg-bottom"></div>
<div class="play-gu" :style="{ backgroundPosition: `-${currentGuFrame * 400}px 0` }" @click="$emit('touch')"></div> <div class="play-gu" :style="{ backgroundPosition: `-${currentGuFrame * 400}px 0` }" @click="$emit('touch')"></div>
......
...@@ -94,7 +94,7 @@ function submitScore(save: boolean = false, currentTick = score.value) { ...@@ -94,7 +94,7 @@ function submitScore(save: boolean = false, currentTick = score.value) {
//wechat 原始token //wechat 原始token
sendGameMessage('submit_score_save', { sendGameMessage('submit_score_save', {
score: currentTick, score: currentTick,
wechat: wechat.token_origin, wechat: wechat.token,
item_num: 2, item_num: 2,
nickname: wechat.nickname, nickname: wechat.nickname,
avatar: wechat.avatar, avatar: wechat.avatar,
......
...@@ -108,7 +108,7 @@ function submitScore(save: boolean = false, currentTick = score.value) { ...@@ -108,7 +108,7 @@ function submitScore(save: boolean = false, currentTick = score.value) {
} }
sendGameMessage('submit_score_save', { sendGameMessage('submit_score_save', {
score: currentTick, score: currentTick,
wechat: wechat.token_origin, wechat: wechat.token,
item_num: 3, item_num: 3,
nickname: wechat.nickname, nickname: wechat.nickname,
avatar: wechat.avatar, avatar: wechat.avatar,
...@@ -244,6 +244,7 @@ if (wechat) { ...@@ -244,6 +244,7 @@ if (wechat) {
rank.value = nextRank rank.value = nextRank
} }
} }
return { code: 'MSYF', score: score.value }
}, },
onRescoreSubmitted: (_recount) => { onRescoreSubmitted: (_recount) => {
submitScore(true); submitScore(true);
......
...@@ -89,7 +89,7 @@ function submitScore(save: boolean = false) { ...@@ -89,7 +89,7 @@ function submitScore(save: boolean = false) {
// wechat 原始token // wechat 原始token
sendGameMessage("submit_score_save", { sendGameMessage("submit_score_save", {
score: tick.value, score: tick.value,
wechat: wechat.token_origin, wechat: wechat.token,
item_num: 4, item_num: 4,
nickname: wechat.nickname, nickname: wechat.nickname,
avatar: wechat.avatar, avatar: wechat.avatar,
......
...@@ -136,7 +136,7 @@ function submitScore(save: boolean = false) { ...@@ -136,7 +136,7 @@ function submitScore(save: boolean = false) {
//wechat 原始token //wechat 原始token
const data = { const data = {
score: tick.value, score: tick.value,
wechat: wechat.token_origin, wechat: wechat.token,
item_num: 1, item_num: 1,
nickname: wechat.nickname, nickname: wechat.nickname,
avatar: wechat.avatar, avatar: wechat.avatar,
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
import { computed, onBeforeUnmount, onMounted, ref } from 'vue' import { computed, onBeforeUnmount, onMounted, ref } from 'vue'
import { cssAssetUrl } from '@/commons/assets.ts' import { cssAssetUrl } from '@/commons/assets.ts'
import MobileStage from '@/components/MobileStage.vue' import MobileStage from '@/components/MobileStage.vue'
import { useGameSocket, sendGameMessage, userJoinStatus, joinSharedRoom } from '@/composables/useGameSocket' import { useGameSocket, sendGameMessage, userJoinStatus, userTop10RankStatus, joinSharedRoom } from '@/composables/useGameSocket'
import LoadingView from './views/LoadingView.vue' import LoadingView from './views/LoadingView.vue'
import PlayingView from './views/PlayingView.vue' import PlayingView from './views/PlayingView.vue'
import { $format_str, $getWechat, $toast } from '@/commons/utils.ts' import { $format_str, $getWechat, $toast } from '@/commons/utils.ts'
...@@ -101,7 +101,7 @@ function submitScore(save: boolean = false, currentTick = score.value) { ...@@ -101,7 +101,7 @@ function submitScore(save: boolean = false, currentTick = score.value) {
//wechat 原始token //wechat 原始token
sendGameMessage('submit_score_save', { sendGameMessage('submit_score_save', {
score: currentTick, score: currentTick,
wechat: wechat.token_origin, wechat: wechat.token,
item_num: 6, item_num: 6,
nickname: wechat.nickname, nickname: wechat.nickname,
avatar: wechat.avatar, avatar: wechat.avatar,
...@@ -123,9 +123,16 @@ function startGameCountdown(seconds = 60) { ...@@ -123,9 +123,16 @@ function startGameCountdown(seconds = 60) {
if (countdownInterval.value <= 0) { if (countdownInterval.value <= 0) {
countdownInterval.value = 0 countdownInterval.value = 0
gameCountdownTimer = undefined gameCountdownTimer = undefined
setDivDescVisible(false) currentView.value = 'loading'
submitScore(true) if (userTop10RankStatus.value) {
showGameOverRank() userJoinStatus.value = false;
showGameRank.value = false;
$toast('一人只能上榜领奖一次,您的福利已到手,把机会留给其他玩家吧', 30000)
} else {
setDivDescVisible(false)
submitScore(true)
showGameOverRank()
}
return return
} }
...@@ -343,7 +350,7 @@ const rankCloseHandler = () => { ...@@ -343,7 +350,7 @@ const rankCloseHandler = () => {
<div class="col-2"> <div class="col-2">
<div class="avatar" <div class="avatar"
:style="item.avatar ? { backgroundImage: `url(${item.avatar})` } : {}"></div> :style="item.avatar ? { backgroundImage: `url(${item.avatar})` } : {}"></div>
<div>{{ $format_str(item.nickname,12) }}</div> <div>{{ $format_str(item.nickname, 12) }}</div>
</div> </div>
<div class="col-3">{{ item.score }}</div> <div class="col-3">{{ item.score }}</div>
</div> </div>
...@@ -358,12 +365,12 @@ const rankCloseHandler = () => { ...@@ -358,12 +365,12 @@ const rankCloseHandler = () => {
</div> </div>
</div> </div>
<div class="img-close" @click="rankCloseHandler"></div> <div class="img-close" @click="rankCloseHandler"></div>
</div> </div>
</template> </template>
<LoadingView v-if="currentView === 'loading'" :image-urls="imageUrls" :user-join-status="userJoinStatus" <LoadingView v-if="currentView === 'loading'" :image-urls="imageUrls" :user-join-status="userJoinStatus"
@touchGameRule="showGameRuleHandler" /> @touchGameRule="showGameRuleHandler" />
<PlayingView v-else :image-urls="imageUrls" :tick="score" :rank="rank" :countdown-interval="countdownInterval" <PlayingView v-else :image-urls="imageUrls" :tick="score" :rank="rank" :countdown-interval="countdownInterval"
:is-div-desc-visible="isDivDescVisible" @touch="touchHandler" /> :is-div-desc-visible="isDivDescVisible" @touch="touchHandler" :userTop10RankStatus="userTop10RankStatus" />
</MobileStage> </MobileStage>
<div v-else style="text-align: center; width: 100vw; height: 100vh; line-height: 30; font-size: 20px;"> <div v-else style="text-align: center; width: 100vw; height: 100vh; line-height: 30; font-size: 20px;">
请使用微信扫码进入游戏 请使用微信扫码进入游戏
...@@ -399,7 +406,7 @@ const rankCloseHandler = () => { ...@@ -399,7 +406,7 @@ const rankCloseHandler = () => {
width: 57px; width: 57px;
height: 57px; height: 57px;
background: v-bind('imageUrls.close') center / cover no-repeat; background: v-bind('imageUrls.close') center / cover no-repeat;
transform: translateX(-50%) scale(1.5); transform: translateX(-50%) scale(1.5);
position: absolute; position: absolute;
top: -73px; top: -73px;
left: 100%; left: 100%;
......
...@@ -4,7 +4,7 @@ import { onMounted, ref } from 'vue'; ...@@ -4,7 +4,7 @@ import { onMounted, ref } from 'vue';
defineProps<{ defineProps<{
imageUrls: Record<string, string> imageUrls: Record<string, string>
userJoinStatus: boolean userJoinStatus: boolean,
}>(); }>();
const nickname = ref(''); const nickname = ref('');
const avatar = ref(''); const avatar = ref('');
......
...@@ -7,7 +7,7 @@ defineProps<{ ...@@ -7,7 +7,7 @@ defineProps<{
isDivDescVisible: boolean isDivDescVisible: boolean
tick: number tick: number
rank: number rank: number
// currentGu: string userTop10RankStatus:boolean
}>() }>()
const emit = defineEmits<{ const emit = defineEmits<{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment