Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
F
fc-minigame
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
陈冲
fc-minigame
Commits
40a1a7b0
Commit
40a1a7b0
authored
Jun 09, 2026
by
陈冲
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: 功能修复
parent
a8efe97a
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
31 changed files
with
851 additions
and
184 deletions
+851
-184
Cargo.lock
backend/Cargo.lock
+51
-4
Cargo.toml
backend/Cargo.toml
+1
-0
config.rs
backend/src/commons/config.rs
+4
-2
utils.rs
backend/src/commons/utils.rs
+53
-0
mod.rs
backend/src/db/mod.rs
+14
-10
game.rs
backend/src/db/models/game.rs
+5
-2
manager.rs
backend/src/db/models/manager.rs
+11
-2
mysql.rs
backend/src/db/mysql.rs
+1
-1
pg.rs
backend/src/db/pg.rs
+1
-1
socket_io.rs
backend/src/protocols/socket_io.rs
+0
-0
utils.ts
frontend-h5/src/commons/utils.ts
+263
-0
ws.ts
frontend-h5/src/commons/ws.ts
+15
-15
useGameSocket.ts
frontend-h5/src/composables/useGameSocket.ts
+18
-15
Game.vue
frontend-h5/src/pages/game1/Game.vue
+6
-4
LoadingView.vue
frontend-h5/src/pages/game1/views/LoadingView.vue
+6
-5
Game4.vue
frontend-h5/src/pages/game4/Game4.vue
+6
-4
Game5.vue
frontend-h5/src/pages/game5/Game5.vue
+6
-4
LoadingView.vue
frontend-h5/src/pages/game5/views/LoadingView.vue
+13
-11
Game.vue
frontend-h5/src/pages/game6/Game.vue
+6
-5
LoadingView.vue
frontend-h5/src/pages/game6/views/LoadingView.vue
+6
-6
podium.png
frontend-large/src/assets/images/game1/podium.png
+0
-0
music.ts
frontend-large/src/commons/music.ts
+21
-11
utils.ts
frontend-large/src/commons/utils.ts
+230
-0
ws.ts
frontend-large/src/commons/ws.ts
+2
-2
useAdminGameSocket.ts
frontend-large/src/composables/useAdminGameSocket.ts
+5
-8
Login.vue
frontend-large/src/pages/Login.vue
+38
-36
Game.vue
frontend-large/src/pages/game1/Game.vue
+14
-7
Rank2View.vue
frontend-large/src/pages/game1/views/Rank2View.vue
+19
-14
Game4.vue
frontend-large/src/pages/game4/Game4.vue
+12
-5
Game5.vue
frontend-large/src/pages/game5/Game5.vue
+12
-5
Game.vue
frontend-large/src/pages/game6/Game.vue
+12
-5
No files found.
backend/Cargo.lock
View file @
40a1a7b0
...
@@ -379,6 +379,16 @@ dependencies = [
...
@@ -379,6 +379,16 @@ dependencies = [
[[package]]
[[package]]
name = "core-foundation"
name = "core-foundation"
version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f"
dependencies = [
"core-foundation-sys",
"libc",
]
[[package]]
name = "core-foundation"
version = "0.10.1"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6"
checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6"
...
@@ -1044,6 +1054,7 @@ dependencies = [
...
@@ -1044,6 +1054,7 @@ dependencies = [
"lazy_static",
"lazy_static",
"md-5",
"md-5",
"rand 0.10.0",
"rand 0.10.0",
"reqwest",
"rmp-serde",
"rmp-serde",
"rust-embed",
"rust-embed",
"salvo",
"salvo",
...
@@ -1222,9 +1233,11 @@ dependencies = [
...
@@ -1222,9 +1233,11 @@ dependencies = [
"percent-encoding",
"percent-encoding",
"pin-project-lite",
"pin-project-lite",
"socket2",
"socket2",
"system-configuration",
"tokio",
"tokio",
"tower-service",
"tower-service",
"tracing",
"tracing",
"windows-registry",
]
]
[[package]]
[[package]]
...
@@ -2187,9 +2200,9 @@ checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a"
...
@@ -2187,9 +2200,9 @@ checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a"
[[package]]
[[package]]
name = "reqwest"
name = "reqwest"
version = "0.13.
2
"
version = "0.13.
4
"
source = "registry+https://github.com/rust-lang/crates.io-index"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "
ab3f43e3283ab1488b624b44b0e988d0acea0b3214e694730a055cb6b2efa801
"
checksum = "
219c5811de6525e5416c7d5d53bb656d3afdbc6c5af816e0802bcfa42dbdc1c3
"
dependencies = [
dependencies = [
"base64",
"base64",
"bytes",
"bytes",
...
@@ -2212,6 +2225,8 @@ dependencies = [
...
@@ -2212,6 +2225,8 @@ dependencies = [
"rustls",
"rustls",
"rustls-pki-types",
"rustls-pki-types",
"rustls-platform-verifier",
"rustls-platform-verifier",
"serde",
"serde_json",
"sync_wrapper",
"sync_wrapper",
"tokio",
"tokio",
"tokio-rustls",
"tokio-rustls",
...
@@ -2376,7 +2391,7 @@ version = "0.6.2"
...
@@ -2376,7 +2391,7 @@ version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d99feebc72bae7ab76ba994bb5e121b8d83d910ca40b36e0921f53becc41784"
checksum = "1d99feebc72bae7ab76ba994bb5e121b8d83d910ca40b36e0921f53becc41784"
dependencies = [
dependencies = [
"core-foundation",
"core-foundation
0.10.1
",
"core-foundation-sys",
"core-foundation-sys",
"jni",
"jni",
"log",
"log",
...
@@ -2607,7 +2622,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
...
@@ -2607,7 +2622,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d"
checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d"
dependencies = [
dependencies = [
"bitflags",
"bitflags",
"core-foundation",
"core-foundation
0.10.1
",
"core-foundation-sys",
"core-foundation-sys",
"libc",
"libc",
"security-framework-sys",
"security-framework-sys",
...
@@ -3133,6 +3148,27 @@ dependencies = [
...
@@ -3133,6 +3148,27 @@ dependencies = [
]
]
[[package]]
[[package]]
name = "system-configuration"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a13f3d0daba03132c0aa9767f98351b3488edc2c100cda2d2ec2b04f3d8d3c8b"
dependencies = [
"bitflags",
"core-foundation 0.9.4",
"system-configuration-sys",
]
[[package]]
name = "system-configuration-sys"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4"
dependencies = [
"core-foundation-sys",
"libc",
]
[[package]]
name = "tempfile"
name = "tempfile"
version = "3.27.0"
version = "3.27.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
source = "registry+https://github.com/rust-lang/crates.io-index"
...
@@ -3874,6 +3910,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
...
@@ -3874,6 +3910,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
[[package]]
[[package]]
name = "windows-registry"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "02752bf7fbdcce7f2a27a742f798510f3e5ad88dbe84871e5168e2120c3d5720"
dependencies = [
"windows-link",
"windows-result",
"windows-strings",
]
[[package]]
name = "windows-result"
name = "windows-result"
version = "0.4.1"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
source = "registry+https://github.com/rust-lang/crates.io-index"
...
...
backend/Cargo.toml
View file @
40a1a7b0
...
@@ -25,6 +25,7 @@ lazy_static = "1.5.0"
...
@@ -25,6 +25,7 @@ lazy_static = "1.5.0"
aes
=
"0.8.4"
aes
=
"0.8.4"
cbc
=
{
version
=
"0.1.2"
,
features
=
["alloc"]
}
cbc
=
{
version
=
"0.1.2"
,
features
=
["alloc"]
}
md5
=
{
version
=
"0.10.6"
,
package
=
"md-5"
}
md5
=
{
version
=
"0.10.6"
,
package
=
"md-5"
}
reqwest
=
{
version
=
"0.13.4"
,
features
=
["json"]
}
[[bin]]
[[bin]]
name
=
"hddpServer"
name
=
"hddpServer"
...
...
backend/src/commons/config.rs
View file @
40a1a7b0
...
@@ -15,7 +15,8 @@ pub struct Config {
...
@@ -15,7 +15,8 @@ pub struct Config {
#[serde(skip_serializing_if
=
"Option::is_none"
)]
#[serde(skip_serializing_if
=
"Option::is_none"
)]
pub
aes_passphrase
:
Option
<
String
>
,
pub
aes_passphrase
:
Option
<
String
>
,
// 数据库配置:所有 master/worker 节点都可以直连同一台 DB。
// 数据库配置:所有 master/worker 节点都可以直连同一台 DB。
pub
db
:
DbConfig
,
pub
db
:
Option
<
DbConfig
>
,
// pub post: String,
}
}
#[derive(Clone,
Deserialize,
Serialize,
Debug)]
#[derive(Clone,
Deserialize,
Serialize,
Debug)]
...
@@ -34,7 +35,8 @@ impl Default for Config {
...
@@ -34,7 +35,8 @@ impl Default for Config {
client_ns
:
"/ws"
.to_string
(),
client_ns
:
"/ws"
.to_string
(),
socket_path
:
"/socket.io"
.to_string
(),
socket_path
:
"/socket.io"
.to_string
(),
aes_passphrase
:
None
,
aes_passphrase
:
None
,
db
:
DbConfig
::
default
(),
db
:
None
,
//DbConfig::default(),
// post: "".to_string(),
}
}
}
}
}
}
...
...
backend/src/commons/utils.rs
View file @
40a1a7b0
...
@@ -7,6 +7,10 @@ use base64::{Engine as _, engine::general_purpose};
...
@@ -7,6 +7,10 @@ use base64::{Engine as _, engine::general_purpose};
use
cbc
::
Decryptor
;
use
cbc
::
Decryptor
;
use
md5
::{
Digest
,
Md5
};
use
md5
::{
Digest
,
Md5
};
use
rand
::
Rng
;
use
rand
::
Rng
;
use
reqwest
::
Client
;
use
std
::
option
::
Option
;
use
serde
::
Serialize
;
use
std
::
collections
::
HashMap
;
use
std
::
sync
::
LazyLock
;
use
std
::
sync
::
LazyLock
;
pub
static
CONFIG
:
LazyLock
<
Config
>
=
LazyLock
::
new
(||
Config
::
load
()
.unwrap
());
pub
static
CONFIG
:
LazyLock
<
Config
>
=
LazyLock
::
new
(||
Config
::
load
()
.unwrap
());
...
@@ -141,3 +145,52 @@ pub fn add_minute(ts: u64, val: u64) -> u64 {
...
@@ -141,3 +145,52 @@ pub fn add_minute(ts: u64, val: u64) -> u64 {
pub
fn
add_hour
(
ts
:
u64
,
val
:
u64
)
->
u64
{
pub
fn
add_hour
(
ts
:
u64
,
val
:
u64
)
->
u64
{
add_minute
(
ts
,
val
*
60
)
add_minute
(
ts
,
val
*
60
)
}
}
// ///返回为空时表示提交异常
// pub async fn post(token: &str, index: i64) -> Result<Option<String>, Box<dyn std::error::Error>> {
// let url = CONFIG.post.clone();
// #[derive(Debug, Serialize)]
// struct RequestBody {
// activity_id: i32,
// game_code: String,
// page: i32,
// pageSize: i32,
// }
// let mut map = HashMap::new();
// map.insert(1, "JGQF");
// map.insert(2, "JBJF");
// map.insert(3, "MSYF");
// map.insert(4, "CMYF");
// map.insert(5, "QCNF");
// map.insert(6, "FYDT");
// let code = map.get(&index).and_then(|v| Some("")).unwrap();
// let body = RequestBody {
// activity_id: 1,
// game_code: code.to_string(), //大屏游戏代码 (马上有福:MSYF, 击鼓齐福:JGQF, 策马迎福:CMYF, 圈彩纳福:QCNF, 福运当头:FYDT, 聚宝接福:JBJF)
// page: 1,
// pageSize: 20,
// };
// let client = Client::new();
// let resp = client
// .post(url)
// .bearer_auth(token)
// .json(&body)
// .send()
// .await?;
// let status = resp.status();
// if !status.is_success() {
// let text = resp.text().await?;
// println!("请求失败: {}, body: {}", status, text);
// return Ok(None);
// }
// let result = resp.text().await?;
// println!("响应: {:?}", result);
// Ok(Some(result))
// }
backend/src/db/mod.rs
View file @
40a1a7b0
...
@@ -18,17 +18,21 @@ trait DbDriver: Send + Sync {
...
@@ -18,17 +18,21 @@ trait DbDriver: Send + Sync {
static
DB_CONN
:
OnceCell
<
Box
<
dyn
DbDriver
>>
=
OnceCell
::
const_new
();
static
DB_CONN
:
OnceCell
<
Box
<
dyn
DbDriver
>>
=
OnceCell
::
const_new
();
pub
async
fn
init_db
()
->
Result
<
(),
String
>
{
pub
async
fn
init_db
()
->
Result
<
(),
String
>
{
let
conn
:
Box
<
dyn
DbDriver
>
=
match
config
.db.kind
.as_str
()
{
if
let
Some
(
db
)
=
&
config
.db
{
"postgresql"
=>
Box
::
new
(
PgDb
::
new
()
.await
?
),
let
conn
:
Box
<
dyn
DbDriver
>
=
match
db
.kind
.as_str
()
{
"mysql"
=>
Box
::
new
(
MysqlDb
::
new
()
.await
?
),
"postgresql"
=>
Box
::
new
(
PgDb
::
new
()
.await
?
),
other
=>
{
"mysql"
=>
Box
::
new
(
MysqlDb
::
new
()
.await
?
),
return
Err
(
format!
(
"unsupported db kind: {other}"
));
other
=>
{
}
return
Err
(
format!
(
"unsupported db kind: {other}"
));
};
}
};
DB_CONN
DB_CONN
.set
(
conn
)
.set
(
conn
)
.map_err
(|
_
|
"db already initialized"
.to_string
())
.map_err
(|
_
|
"db already initialized"
.to_string
())
}
else
{
Ok
(())
}
}
}
pub
async
fn
db_query
(
sql
:
&
str
,
params
:
Vec
<
Value
>
)
->
Result
<
Vec
<
Value
>
,
String
>
{
pub
async
fn
db_query
(
sql
:
&
str
,
params
:
Vec
<
Value
>
)
->
Result
<
Vec
<
Value
>
,
String
>
{
...
...
backend/src/db/models/game.rs
View file @
40a1a7b0
use
crate
::{
commons
::
utils
::
CONFIG
as
config
,
db
::
models
::
log
::
Log
};
use
chrono
::{
DateTime
,
NaiveDate
,
Utc
};
use
chrono
::{
DateTime
,
NaiveDate
,
Utc
};
use
serde_json
::
json
;
use
serde_json
::
json
;
use
crate
::
db
::
models
::
log
::
Log
;
pub
struct
Game
{
pub
struct
Game
{
pub
wechat_id
:
String
,
pub
wechat_id
:
String
,
pub
nickname
:
String
,
pub
nickname
:
String
,
...
@@ -19,6 +18,10 @@ pub struct Game {
...
@@ -19,6 +18,10 @@ pub struct Game {
impl
Game
{
impl
Game
{
pub
async
fn
insert
(
&
self
)
->
bool
{
pub
async
fn
insert
(
&
self
)
->
bool
{
let
Some
(
_
)
=
&
config
.db
else
{
println!
(
"没有配置数据库, return true;"
);
return
true
;
};
let
res
=
crate
::
db
::
db_query
(
let
res
=
crate
::
db
::
db_query
(
r
#
"insert into tb_game(wechat_id,nickname,avatar,item_num,game_rank,score,create_date) values(?,?,?,?,?,?,now());"
#
,
r
#
"insert into tb_game(wechat_id,nickname,avatar,item_num,game_rank,score,create_date) values(?,?,?,?,?,?,now());"
#
,
vec!
[
vec!
[
...
...
backend/src/db/models/manager.rs
View file @
40a1a7b0
use
serde_json
::{
Value
,
json
};
use
crate
::
commons
::
utils
::
CONFIG
as
config
;
use
crate
::
db
::
models
::
*
;
use
crate
::
db
::
models
::
*
;
use
serde_json
::{
Value
,
json
};
#[derive(Debug)]
#[derive(Debug)]
pub
struct
Manager
{
pub
struct
Manager
{
...
@@ -18,6 +18,15 @@ pub enum ManagerLogin {
...
@@ -18,6 +18,15 @@ pub enum ManagerLogin {
impl
Manager
{
impl
Manager
{
pub
async
fn
Login
(
m
:
ManagerLogin
)
->
Result
<
Self
,
String
>
{
pub
async
fn
Login
(
m
:
ManagerLogin
)
->
Result
<
Self
,
String
>
{
let
Some
(
_
)
=
&
config
.db
else
{
println!
(
"没有配置数据库, return Self;"
);
return
Ok
(
Manager
{
id
:
1
,
username
:
"admin"
.to_string
(),
password
:
"123456"
.to_string
(),
token
:
"88236aeb-8d3f-6d56-fdf5-3adca3961df1"
.to_string
(),
});
};
match
m
{
match
m
{
ManagerLogin
::
user
(
username
,
password
)
=>
{
ManagerLogin
::
user
(
username
,
password
)
=>
{
let
rows
=
crate
::
db
::
db_query
(
let
rows
=
crate
::
db
::
db_query
(
...
...
backend/src/db/mysql.rs
View file @
40a1a7b0
...
@@ -21,7 +21,7 @@ impl MysqlDb {
...
@@ -21,7 +21,7 @@ impl MysqlDb {
})
})
})
})
.max_connections
(
16
)
.max_connections
(
16
)
.connect
(
&
config
.db.uri
)
.connect
(
&
config
.db
.
clone
()
.unwrap
()
.
uri
)
.await
.await
.map_err
(|
err
|
err
.to_string
())
?
;
.map_err
(|
err
|
err
.to_string
())
?
;
Ok
(
Self
{
pool
})
Ok
(
Self
{
pool
})
...
...
backend/src/db/pg.rs
View file @
40a1a7b0
...
@@ -13,7 +13,7 @@ impl PgDb {
...
@@ -13,7 +13,7 @@ impl PgDb {
pub
async
fn
new
()
->
Result
<
Self
,
String
>
{
pub
async
fn
new
()
->
Result
<
Self
,
String
>
{
let
pool
=
PgPoolOptions
::
new
()
let
pool
=
PgPoolOptions
::
new
()
.max_connections
(
16
)
.max_connections
(
16
)
.connect
(
&
config
.db.uri
)
.connect
(
&
config
.db
.
clone
()
.unwrap
()
.
uri
)
.await
.await
.map_err
(|
err
|
err
.to_string
())
?
;
.map_err
(|
err
|
err
.to_string
())
?
;
...
...
backend/src/protocols/socket_io.rs
View file @
40a1a7b0
This diff is collapsed.
Click to expand it.
frontend-h5/src/commons/utils.ts
View file @
40a1a7b0
...
@@ -63,6 +63,233 @@ export function $format_str(str: string, num: number) {
...
@@ -63,6 +63,233 @@ export function $format_str(str: string, num: number) {
return
str
.
substring
(
0
,
num
)
+
'...'
;
return
str
.
substring
(
0
,
num
)
+
'...'
;
}
}
let
toastElement
:
HTMLDivElement
|
undefined
;
let
toastTimer
:
ReturnType
<
typeof
window
.
setTimeout
>
|
undefined
;
export
function
$toast
(
message
?:
string
,
duration
=
2000
)
{
if
(
!
message
)
{
return
;
}
if
(
!
toastElement
)
{
toastElement
=
document
.
createElement
(
'div'
);
toastElement
.
style
.
cssText
=
[
'position: fixed'
,
'left: 50%'
,
'top: 45%'
,
'z-index: 99999'
,
'max-width: 560px'
,
'padding: 18px 28px'
,
'border-radius: 18px'
,
'background: rgba(0, 0, 0, 0.72)'
,
'color: #fff'
,
'font-size: 22px'
,
'line-height: 1.4'
,
'text-align: center'
,
'transform: translate(-50%, -40%)'
,
'opacity: 0'
,
'pointer-events: none'
,
'transition: opacity 0.2s ease, transform 0.2s ease'
,
].
join
(
';'
);
document
.
body
.
appendChild
(
toastElement
);
}
if
(
toastTimer
)
{
window
.
clearTimeout
(
toastTimer
);
toastTimer
=
undefined
;
}
toastElement
.
textContent
=
message
;
toastElement
.
style
.
opacity
=
'1'
;
toastElement
.
style
.
transform
=
'translate(-50%, -50%)'
;
toastTimer
=
window
.
setTimeout
(()
=>
{
if
(
!
toastElement
)
{
return
;
}
toastElement
.
style
.
opacity
=
'0'
;
toastElement
.
style
.
transform
=
'translate(-50%, -40%)'
;
toastTimer
=
undefined
;
},
duration
);
}
type
ConfirmOptions
=
{
title
?:
string
;
message
?:
string
;
confirmText
?:
string
;
cancelText
?:
string
;
}
let
confirmMaskElement
:
HTMLDivElement
|
undefined
;
let
confirmBoxElement
:
HTMLDivElement
|
undefined
;
let
confirmTitleElement
:
HTMLDivElement
|
undefined
;
let
confirmMessageElement
:
HTMLDivElement
|
undefined
;
let
confirmCancelElement
:
HTMLButtonElement
|
undefined
;
let
confirmOkElement
:
HTMLButtonElement
|
undefined
;
let
confirmResolve
:
((
value
:
boolean
)
=>
void
)
|
undefined
;
let
confirmHideTimer
:
ReturnType
<
typeof
window
.
setTimeout
>
|
undefined
;
function
closeConfirm
(
result
:
boolean
)
{
if
(
!
confirmMaskElement
||
!
confirmBoxElement
)
{
confirmResolve
?.(
result
);
confirmResolve
=
undefined
;
return
;
}
if
(
confirmHideTimer
)
{
window
.
clearTimeout
(
confirmHideTimer
);
confirmHideTimer
=
undefined
;
}
confirmMaskElement
.
style
.
opacity
=
'0'
;
confirmBoxElement
.
style
.
transform
=
'scale(0.96)'
;
confirmHideTimer
=
window
.
setTimeout
(()
=>
{
if
(
confirmMaskElement
)
{
confirmMaskElement
.
style
.
display
=
'none'
;
}
confirmHideTimer
=
undefined
;
},
200
);
confirmResolve
?.(
result
);
confirmResolve
=
undefined
;
}
function
ensureConfirmElement
()
{
if
(
confirmMaskElement
)
{
return
;
}
confirmMaskElement
=
document
.
createElement
(
'div'
);
confirmMaskElement
.
style
.
cssText
=
[
'position: fixed'
,
'inset: 0'
,
'z-index: 99998'
,
'display: none'
,
'align-items: center'
,
'justify-content: center'
,
'background: rgba(0, 0, 0, 0.45)'
,
'opacity: 0'
,
'transition: opacity 0.2s ease'
,
].
join
(
';'
);
confirmBoxElement
=
document
.
createElement
(
'div'
);
confirmBoxElement
.
style
.
cssText
=
[
'width: min(560px, calc(100vw - 80px))'
,
'box-sizing: border-box'
,
'padding: 34px 32px 28px'
,
'border-radius: 22px'
,
'background: #fff'
,
'color: #333'
,
'font-size: 24px'
,
'line-height: 1.45'
,
'text-align: center'
,
'box-shadow: 0 18px 48px rgba(0, 0, 0, 0.22)'
,
'transform: scale(0.96)'
,
'transition: transform 0.2s ease'
,
].
join
(
';'
);
confirmTitleElement
=
document
.
createElement
(
'div'
);
confirmTitleElement
.
style
.
cssText
=
[
'margin-bottom: 16px'
,
'font-size: 30px'
,
'font-weight: 700'
,
'color: #222'
,
].
join
(
';'
);
confirmMessageElement
=
document
.
createElement
(
'div'
);
confirmMessageElement
.
style
.
cssText
=
[
'min-height: 34px'
,
'word-break: break-word'
,
].
join
(
';'
);
const
buttonWrap
=
document
.
createElement
(
'div'
);
buttonWrap
.
style
.
cssText
=
[
'display: flex'
,
'gap: 18px'
,
'margin-top: 30px'
,
].
join
(
';'
);
confirmCancelElement
=
document
.
createElement
(
'button'
);
confirmCancelElement
.
type
=
'button'
;
confirmCancelElement
.
style
.
cssText
=
[
'flex: 1'
,
'height: 58px'
,
'border: 1px solid #ddd'
,
'border-radius: 29px'
,
'background: #fff'
,
'color: #666'
,
'font-size: 24px'
,
].
join
(
';'
);
confirmCancelElement
.
onclick
=
()
=>
closeConfirm
(
false
);
confirmOkElement
=
document
.
createElement
(
'button'
);
confirmOkElement
.
type
=
'button'
;
confirmOkElement
.
style
.
cssText
=
[
'flex: 1'
,
'height: 58px'
,
'border: 0'
,
'border-radius: 29px'
,
'background: #AA0000'
,
'color: #fff'
,
'font-size: 24px'
,
].
join
(
';'
);
confirmOkElement
.
onclick
=
()
=>
closeConfirm
(
true
);
confirmMaskElement
.
onclick
=
(
event
)
=>
{
if
(
event
.
target
===
confirmMaskElement
)
{
closeConfirm
(
false
);
}
};
buttonWrap
.
append
(
confirmCancelElement
,
confirmOkElement
);
confirmBoxElement
.
append
(
confirmTitleElement
,
confirmMessageElement
,
buttonWrap
);
confirmMaskElement
.
appendChild
(
confirmBoxElement
);
document
.
body
.
appendChild
(
confirmMaskElement
);
}
export
function
$confirm
(
message
?:
string
,
title
?:
string
):
Promise
<
boolean
>
;
export
function
$confirm
(
options
?:
ConfirmOptions
):
Promise
<
boolean
>
;
export
function
$confirm
(
messageOrOptions
?:
string
|
ConfirmOptions
,
title
?:
string
):
Promise
<
boolean
>
{
const
options
:
ConfirmOptions
=
typeof
messageOrOptions
===
'object'
?
messageOrOptions
:
{
message
:
messageOrOptions
,
title
};
if
(
!
options
.
message
)
{
return
Promise
.
resolve
(
false
);
}
ensureConfirmElement
();
if
(
confirmResolve
)
{
confirmResolve
(
false
);
confirmResolve
=
undefined
;
}
if
(
confirmHideTimer
)
{
window
.
clearTimeout
(
confirmHideTimer
);
confirmHideTimer
=
undefined
;
}
confirmTitleElement
!
.
textContent
=
options
.
title
??
'提示'
;
confirmMessageElement
!
.
textContent
=
options
.
message
;
confirmCancelElement
!
.
textContent
=
options
.
cancelText
??
'取消'
;
confirmOkElement
!
.
textContent
=
options
.
confirmText
??
'确定'
;
confirmMaskElement
!
.
style
.
display
=
'flex'
;
window
.
requestAnimationFrame
(()
=>
{
if
(
!
confirmMaskElement
||
!
confirmBoxElement
)
{
return
;
}
confirmMaskElement
.
style
.
opacity
=
'1'
;
confirmBoxElement
.
style
.
transform
=
'scale(1)'
;
});
return
new
Promise
<
boolean
>
((
resolve
)
=>
{
confirmResolve
=
resolve
;
});
}
export
function
$is_run_local
():
boolean
{
export
function
$is_run_local
():
boolean
{
if
(
/https
?
:
\/\/
localhost|192.168/gim
.
test
(
location
.
href
))
{
if
(
/https
?
:
\/\/
localhost|192.168/gim
.
test
(
location
.
href
))
{
return
true
;
return
true
;
...
@@ -102,4 +329,39 @@ export function $getWechat(): any | null {
...
@@ -102,4 +329,39 @@ export function $getWechat(): any | null {
}
}
return
null
;
return
null
;
}
export
async
function
postJson
(
token
:
string
,
index
:
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
);
}
}
}
\ No newline at end of file
frontend-h5/src/commons/ws.ts
View file @
40a1a7b0
...
@@ -32,15 +32,15 @@ export function initSocket(args: SocketInitArgs): Socket | null {
...
@@ -32,15 +32,15 @@ export function initSocket(args: SocketInitArgs): Socket | null {
onSocketMessage
(
args
.
onMessage
);
onSocketMessage
(
args
.
onMessage
);
}
}
if
(
socket
)
{
//
if (socket) {
if
(
socket
.
connected
)
{
//
if (socket.connected) {
args
.
onConnect
?.(
socket
);
//
args.onConnect?.(socket);
return
socket
;
//
return socket;
}
//
}
socket
.
removeAllListeners
();
//
socket.removeAllListeners();
socket
.
disconnect
();
//
socket.disconnect();
socket
=
null
;
//
socket = null;
}
//
}
if
(
$is_run_local
())
{
if
(
$is_run_local
())
{
console
.
log
(
'socket.io init:'
,
{
console
.
log
(
'socket.io init:'
,
{
...
@@ -68,7 +68,7 @@ export function initSocket(args: SocketInitArgs): Socket | null {
...
@@ -68,7 +68,7 @@ export function initSocket(args: SocketInitArgs): Socket | null {
socket
.
onAny
((
evt
,
payload
)
=>
{
socket
.
onAny
((
evt
,
payload
)
=>
{
const
data
=
decode
(
payload
);
const
data
=
decode
(
payload
);
if
(
$is_run_local
())
{
if
(
$is_run_local
())
{
console
.
log
(
"
recv<============
"
,
evt
,
data
);
console
.
log
(
"
============>recv
"
,
evt
,
data
);
}
}
messageHandlers
.
forEach
((
handler
)
=>
handler
(
evt
,
data
));
messageHandlers
.
forEach
((
handler
)
=>
handler
(
evt
,
data
));
});
});
...
@@ -95,7 +95,7 @@ export function sendSocketMessage(cmd: string, data: any = {}): boolean {
...
@@ -95,7 +95,7 @@ export function sendSocketMessage(cmd: string, data: any = {}): boolean {
return
false
;
return
false
;
}
}
if
(
$is_run_local
())
{
if
(
$is_run_local
())
{
console
.
log
(
'
================>send
'
,
cmd
,
data
);
console
.
log
(
'
send<================
'
,
cmd
,
data
);
}
}
socket
.
send
(
encode
({
cmd
,
data
}));
socket
.
send
(
encode
({
cmd
,
data
}));
return
true
;
return
true
;
...
@@ -114,7 +114,7 @@ export function emitSocket(eventName: string, data?: any): boolean {
...
@@ -114,7 +114,7 @@ export function emitSocket(eventName: string, data?: any): boolean {
return
true
;
return
true
;
}
}
export
function
closeSocket
():
void
{
//
export function closeSocket(): void {
socket
?.
disconnect
();
//
socket?.disconnect();
socket
=
null
;
//
socket = null;
}
//
}
frontend-h5/src/composables/useGameSocket.ts
View file @
40a1a7b0
...
@@ -2,7 +2,7 @@ import { ref } from 'vue'
...
@@ -2,7 +2,7 @@ import { ref } from 'vue'
import
{
useRouter
}
from
'vue-router'
import
{
useRouter
}
from
'vue-router'
import
type
{
Socket
}
from
'socket.io-client'
import
type
{
Socket
}
from
'socket.io-client'
import
{
initSocket
,
onSocketMessage
,
sendSocketMessage
}
from
'@/commons/ws'
import
{
initSocket
,
onSocketMessage
,
sendSocketMessage
}
from
'@/commons/ws'
import
{
$read
}
from
'@/commons/utils'
import
{
$read
,
$toast
,
postJson
}
from
'@/commons/utils'
type
SocketPayload
=
{
type
SocketPayload
=
{
msg
?:
string
msg
?:
string
...
@@ -76,11 +76,16 @@ export function useGameSocket(options: GameSocketOptions) {
...
@@ -76,11 +76,16 @@ export function useGameSocket(options: GameSocketOptions) {
if
(
state
===
0
)
{
if
(
state
===
0
)
{
if
(
evt
===
'room_join_result'
)
{
if
(
evt
===
'room_join_result'
)
{
switch
(
data
)
{
switch
(
data
)
{
case
1
:
userJoinStatus
.
value
=
true
;
break
;
case
1
:
userJoinStatus
.
value
=
true
;
return
;
case
2
:
case
2
:
{
// $toast(msg)
alert
(
msg
)
return
;
}
case
3
:
case
3
:
alert
(
msg
);
// alert(msg);
break
;
$toast
(
msg
)
return
;
}
}
}
else
if
(
evt
==
'submit_score_save'
)
{
}
else
if
(
evt
==
'submit_score_save'
)
{
//提交分数的情况下有问题的情况下,只重试3次
//提交分数的情况下有问题的情况下,只重试3次
...
@@ -102,7 +107,8 @@ export function useGameSocket(options: GameSocketOptions) {
...
@@ -102,7 +107,8 @@ export function useGameSocket(options: GameSocketOptions) {
}
}
if
(
state
===
0
)
{
if
(
state
===
0
)
{
alert
(
msg
)
// alert(msg)
$toast
(
msg
)
return
return
}
}
...
@@ -113,7 +119,9 @@ export function useGameSocket(options: GameSocketOptions) {
...
@@ -113,7 +119,9 @@ export function useGameSocket(options: GameSocketOptions) {
}
}
case
'room_create_result'
:
{
case
'room_create_result'
:
{
if
(
`game
${
data
}
`
==
options
.
gameId
)
{
if
(
`game
${
data
}
`
==
options
.
gameId
)
{
location
.
reload
();
// location.reload();
options
.
onConnect
?.();
// debugger
return
;
return
;
}
}
const
nextPath
=
getGameHomePath
(
data
)
const
nextPath
=
getGameHomePath
(
data
)
...
@@ -125,20 +133,14 @@ export function useGameSocket(options: GameSocketOptions) {
...
@@ -125,20 +133,14 @@ export function useGameSocket(options: GameSocketOptions) {
}
}
case
'room_join_result'
:
{
case
'room_join_result'
:
{
if
(
data
!=
options
.
gameId
)
{
if
(
data
!=
options
.
gameId
)
{
debugger
return
;
return
;
}
}
$toast
(
'您已进入本游戏房间'
)
userJoinStatus
.
value
=
true
userJoinStatus
.
value
=
true
break
break
}
}
case
'room_recover_result'
:
{
case
'room_recover_result'
:
{
/*{
"gameId": "game6",
"rank": 1,
"reconnect": true,
"remainingSeconds": 56,
"score": 0,
"status": "running"
}*/
//游戏进行中玩家掉线重连时
//游戏进行中玩家掉线重连时
if
(
data
.
gameId
!=
options
.
gameId
)
{
if
(
data
.
gameId
!=
options
.
gameId
)
{
return
;
return
;
...
@@ -160,6 +162,7 @@ export function useGameSocket(options: GameSocketOptions) {
...
@@ -160,6 +162,7 @@ export function useGameSocket(options: GameSocketOptions) {
break
break
}
}
case
'submit_score_save_result'
:
{
case
'submit_score_save_result'
:
{
// postJson()
options
.
onScoreSubmitted
?.(
true
,
data
)
options
.
onScoreSubmitted
?.(
true
,
data
)
break
break
}
}
...
...
frontend-h5/src/pages/game1/Game.vue
View file @
40a1a7b0
...
@@ -6,7 +6,7 @@ import { useGameSocket, joinSharedRoom, sendGameMessage, userJoinStatus } from '
...
@@ -6,7 +6,7 @@ import { useGameSocket, joinSharedRoom, sendGameMessage, userJoinStatus } from '
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'
import
{
$getWechat
}
from
'@/commons/utils.ts'
import
{
$getWechat
,
$toast
}
from
'@/commons/utils.ts'
import
{
playGame1Music
}
from
'@/commons/music'
import
{
playGame1Music
}
from
'@/commons/music'
type
GameView
=
'loading'
|
'playing'
|
'score'
type
GameView
=
'loading'
|
'playing'
|
'score'
...
@@ -212,7 +212,8 @@ if (wechat) {
...
@@ -212,7 +212,8 @@ if (wechat) {
stopGameCountdown
()
stopGameCountdown
()
currentView
.
value
=
'loading'
currentView
.
value
=
'loading'
setDivDescVisible
(
false
)
setDivDescVisible
(
false
)
alert
(
'管理员关闭了该房间'
)
// alert('管理员关闭了该房间')
$toast
(
'管理员关闭了该房间'
)
},
},
onRoomBack
:
()
=>
{
onRoomBack
:
()
=>
{
resetToLoadingView
()
resetToLoadingView
()
...
@@ -282,14 +283,15 @@ const showGameRuleHandler = () => {
...
@@ -282,14 +283,15 @@ const showGameRuleHandler = () => {
background
:
v-bind
(
'imageUrls.rule'
)
center
/
cover
no-repeat
;
background
:
v-bind
(
'imageUrls.rule'
)
center
/
cover
no-repeat
;
width
:
692px
;
width
:
692px
;
height
:
797px
;
height
:
797px
;
margin-top
:
-20%
;
transform
:
scale
(
0.5
);
transform
:
scale
(
0.5
);
.rule-title
{
.rule-title
{
text-align
:
center
;
text-align
:
center
;
color
:
white
;
color
:
white
;
font-weight
:
bold
;
font-weight
:
bold
;
font-size
:
2
2
pt
;
font-size
:
2
6
pt
;
margin-top
:
10px
;
line-height
:
50pt
;
letter-spacing
:
4px
;
letter-spacing
:
4px
;
}
}
...
...
frontend-h5/src/pages/game1/views/LoadingView.vue
View file @
40a1a7b0
...
@@ -40,17 +40,18 @@ onMounted(() => {
...
@@ -40,17 +40,18 @@ onMounted(() => {
.game-desc
{
.game-desc
{
position
:
absolute
;
position
:
absolute
;
top
:
5
0%
;
top
:
4
0%
;
left
:
var
(
--stage-viewport-left
,
0
);
left
:
var
(
--stage-viewport-left
,
0
);
display
:
flex
;
display
:
flex
;
width
:
86px
;
width
:
58px
;
height
:
256px
;
height
:
158px
;
padding-top
:
10px
;
align-items
:
center
;
align-items
:
center
;
justify-content
:
center
;
justify-content
:
center
;
border-radius
:
0
12px
12px
0
;
border-radius
:
0
12px
12px
0
;
background
:
rgba
(
40
,
12
,
8
,
0.52
);
background
:
rgba
(
40
,
12
,
8
,
0.52
);
color
:
white
;
color
:
rgba
(
255
,
255
,
255
,
0.9
)
;
font-size
:
32pt
;
font-size
:
25px
;
letter-spacing
:
10px
;
letter-spacing
:
10px
;
line-height
:
1.25
;
line-height
:
1.25
;
text-align
:
center
;
text-align
:
center
;
...
...
frontend-h5/src/pages/game4/Game4.vue
View file @
40a1a7b0
...
@@ -6,7 +6,7 @@ import { useGameSocket, joinSharedRoom, sendGameMessage, userJoinStatus } from '
...
@@ -6,7 +6,7 @@ import { useGameSocket, joinSharedRoom, sendGameMessage, userJoinStatus } from '
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'
import
{
$getWechat
}
from
'@/commons/utils.ts'
import
{
$getWechat
,
$toast
}
from
'@/commons/utils.ts'
const
gameId
=
'game4'
;
const
gameId
=
'game4'
;
type
GameView
=
'loading'
|
'playing'
|
'score'
type
GameView
=
'loading'
|
'playing'
|
'score'
...
@@ -123,7 +123,8 @@ function showLoadingView() {
...
@@ -123,7 +123,8 @@ function showLoadingView() {
stopGameCountdown
()
stopGameCountdown
()
currentView
.
value
=
'loading'
currentView
.
value
=
'loading'
setDivDescVisible
(
false
)
setDivDescVisible
(
false
)
alert
(
'管理员关闭了该房间'
)
// alert('管理员关闭了该房间')
$toast
(
'管理员关闭了该房间'
)
}
}
function
resetToLoadingView
()
{
function
resetToLoadingView
()
{
...
@@ -266,14 +267,15 @@ onBeforeUnmount(() => {
...
@@ -266,14 +267,15 @@ onBeforeUnmount(() => {
background
:
v-bind
(
'imageUrls.rule'
)
center
/
cover
no-repeat
;
background
:
v-bind
(
'imageUrls.rule'
)
center
/
cover
no-repeat
;
width
:
692px
;
width
:
692px
;
height
:
797px
;
height
:
797px
;
margin-top
:
-20%
;
transform
:
scale
(
0.5
);
transform
:
scale
(
0.5
);
.rule-title
{
.rule-title
{
text-align
:
center
;
text-align
:
center
;
color
:
white
;
color
:
white
;
font-weight
:
bold
;
font-weight
:
bold
;
font-size
:
2
2
pt
;
font-size
:
2
6
pt
;
margin-top
:
10px
;
line-height
:
50pt
;
letter-spacing
:
4px
;
letter-spacing
:
4px
;
}
}
...
...
frontend-h5/src/pages/game5/Game5.vue
View file @
40a1a7b0
...
@@ -6,7 +6,7 @@ import { useGameSocket, joinSharedRoom, sendGameMessage, userJoinStatus } from '
...
@@ -6,7 +6,7 @@ import { useGameSocket, joinSharedRoom, sendGameMessage, userJoinStatus } from '
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'
import
{
$getWechat
}
from
'@/commons/utils.ts'
import
{
$getWechat
,
$toast
}
from
'@/commons/utils.ts'
import
{
playGame1Music
}
from
'@/commons/music'
import
{
playGame1Music
}
from
'@/commons/music'
const
gameId
=
'game5'
;
const
gameId
=
'game5'
;
...
@@ -150,7 +150,8 @@ function showLoadingView() {
...
@@ -150,7 +150,8 @@ function showLoadingView() {
stopGameCountdown
()
stopGameCountdown
()
currentView
.
value
=
'loading'
currentView
.
value
=
'loading'
setDivDescVisible
(
false
)
setDivDescVisible
(
false
)
alert
(
'管理员关闭了该房间'
)
// alert('管理员关闭了该房间')
$toast
(
'管理员关闭了该房间'
)
}
}
function
resetToLoadingView
()
{
function
resetToLoadingView
()
{
...
@@ -349,14 +350,15 @@ const rankCloseHandler = () => {
...
@@ -349,14 +350,15 @@ const rankCloseHandler = () => {
background
:
v-bind
(
'imageUrls.rule'
)
center
/
cover
no-repeat
;
background
:
v-bind
(
'imageUrls.rule'
)
center
/
cover
no-repeat
;
width
:
692px
;
width
:
692px
;
height
:
797px
;
height
:
797px
;
margin-top
:
-20%
;
transform
:
scale
(
0.5
);
transform
:
scale
(
0.5
);
.rule-title
{
.rule-title
{
text-align
:
center
;
text-align
:
center
;
color
:
white
;
color
:
white
;
font-weight
:
bold
;
font-weight
:
bold
;
font-size
:
2
2
pt
;
font-size
:
2
6
pt
;
margin-top
:
10px
;
line-height
:
50pt
;
letter-spacing
:
4px
;
letter-spacing
:
4px
;
}
}
...
...
frontend-h5/src/pages/game5/views/LoadingView.vue
View file @
40a1a7b0
...
@@ -42,17 +42,18 @@ onMounted(() => {
...
@@ -42,17 +42,18 @@ onMounted(() => {
.game-desc
{
.game-desc
{
position
:
absolute
;
position
:
absolute
;
top
:
5
0%
;
top
:
4
0%
;
left
:
var
(
--stage-viewport-left
,
0
);
left
:
var
(
--stage-viewport-left
,
0
);
display
:
flex
;
display
:
flex
;
width
:
86px
;
width
:
58px
;
height
:
256px
;
height
:
158px
;
padding-top
:
10px
;
align-items
:
center
;
align-items
:
center
;
justify-content
:
center
;
justify-content
:
center
;
border-radius
:
0
12px
12px
0
;
border-radius
:
0
12px
12px
0
;
background
:
rgba
(
40
,
12
,
8
,
0.52
);
background
:
rgba
(
40
,
12
,
8
,
0.52
);
color
:
white
;
color
:
rgba
(
255
,
255
,
255
,
0.9
)
;
font-size
:
32pt
;
font-size
:
25px
;
letter-spacing
:
10px
;
letter-spacing
:
10px
;
line-height
:
1.25
;
line-height
:
1.25
;
text-align
:
center
;
text-align
:
center
;
...
@@ -93,7 +94,7 @@ onMounted(() => {
...
@@ -93,7 +94,7 @@ onMounted(() => {
.img-avatar
{
.img-avatar
{
position
:
absolute
;
position
:
absolute
;
bottom
:
11%
;
bottom
:
11%
;
left
:
50%
;
left
:
50%
;
/* width: 148px;
/* width: 148px;
height: 148px;
height: 148px;
...
@@ -114,6 +115,7 @@ onMounted(() => {
...
@@ -114,6 +115,7 @@ onMounted(() => {
text-align
:
center
;
text-align
:
center
;
background
:
v-bind
(
'imageUrls.contdown'
)
center
/
cover
;
background
:
v-bind
(
'imageUrls.contdown'
)
center
/
cover
;
}
}
.txt-nickname
{
.txt-nickname
{
position
:
absolute
;
position
:
absolute
;
bottom
:
10%
;
bottom
:
10%
;
...
@@ -146,15 +148,15 @@ onMounted(() => {
...
@@ -146,15 +148,15 @@ onMounted(() => {
color
:
white
;
color
:
white
;
position
:
absolute
;
position
:
absolute
;
z-index
:
-1
;
z-index
:
-1
;
top
:
786px
;
top
:
786px
;
left
:
50%
;
left
:
50%
;
transform
:
translate
(
-50%
);
transform
:
translate
(
-50%
);
line-height
:
118px
;
line-height
:
118px
;
text-align
:
center
;
text-align
:
center
;
font-weight
:
500
;
font-weight
:
500
;
font-size
:
46px
;
font-size
:
46px
;
color
:
#FFFFFF
;
color
:
#FFFFFF
;
letter-spacing
:
5px
;
letter-spacing
:
5px
;
background
:
v-bind
(
'imageUrls.startBg'
)
center
/
cover
;
background
:
v-bind
(
'imageUrls.startBg'
)
center
/
cover
;
}
}
...
...
frontend-h5/src/pages/game6/Game.vue
View file @
40a1a7b0
...
@@ -5,7 +5,7 @@ import MobileStage from '@/components/MobileStage.vue'
...
@@ -5,7 +5,7 @@ import MobileStage from '@/components/MobileStage.vue'
import
{
useGameSocket
,
joinSharedRoom
,
sendGameMessage
,
userJoinStatus
}
from
'@/composables/useGameSocket'
import
{
useGameSocket
,
joinSharedRoom
,
sendGameMessage
,
userJoinStatus
}
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
{
$getWechat
}
from
'@/commons/utils.ts'
import
{
$getWechat
,
$toast
}
from
'@/commons/utils.ts'
import
{
playGame6Music
,
stopGame6Music
}
from
'@/commons/music'
;
import
{
playGame6Music
,
stopGame6Music
}
from
'@/commons/music'
;
type
GameView
=
'loading'
|
'playing'
type
GameView
=
'loading'
|
'playing'
...
@@ -244,7 +244,7 @@ if (wechat) {
...
@@ -244,7 +244,7 @@ if (wechat) {
stopGameCountdown
()
stopGameCountdown
()
currentView
.
value
=
'loading'
currentView
.
value
=
'loading'
setDivDescVisible
(
false
)
setDivDescVisible
(
false
)
aler
t
(
'管理员关闭了该房间'
)
$toas
t
(
'管理员关闭了该房间'
)
},
},
onRoomBack
:
()
=>
{
onRoomBack
:
()
=>
{
resetToLoadingView
()
resetToLoadingView
()
...
@@ -304,7 +304,7 @@ const rankCloseHandler = () => {
...
@@ -304,7 +304,7 @@ const rankCloseHandler = () => {
4. 禁止外挂作弊,违规账号取消成绩与领奖资格;
<br
/><br
/>
4. 禁止外挂作弊,违规账号取消成绩与领奖资格;
<br
/><br
/>
祝您游戏愉快!
祝您游戏愉快!
</div>
</div>
<div
class=
"rule-close"
@
click=
"showGameRuleHandler"
></div>
<div
class=
"rule-close"
@
click=
"showGameRuleHandler"
></div>
</div>
</div>
</div>
</div>
</
template
>
</
template
>
...
@@ -358,14 +358,15 @@ const rankCloseHandler = () => {
...
@@ -358,14 +358,15 @@ const rankCloseHandler = () => {
background
:
v-bind
(
'imageUrls.rule'
)
center
/
cover
no-repeat
;
background
:
v-bind
(
'imageUrls.rule'
)
center
/
cover
no-repeat
;
width
:
692px
;
width
:
692px
;
height
:
797px
;
height
:
797px
;
margin-top
:
-20%
;
transform
:
scale
(
0.5
);
transform
:
scale
(
0.5
);
.rule-title
{
.rule-title
{
text-align
:
center
;
text-align
:
center
;
color
:
white
;
color
:
white
;
font-weight
:
bold
;
font-weight
:
bold
;
font-size
:
2
2
pt
;
font-size
:
2
6
pt
;
margin-top
:
10px
;
line-height
:
50pt
;
letter-spacing
:
4px
;
letter-spacing
:
4px
;
}
}
...
...
frontend-h5/src/pages/game6/views/LoadingView.vue
View file @
40a1a7b0
...
@@ -77,18 +77,18 @@ onMounted(() => {
...
@@ -77,18 +77,18 @@ onMounted(() => {
.game-desc
{
.game-desc
{
position
:
absolute
;
position
:
absolute
;
z-index
:
9999999999
;
top
:
40%
;
top
:
50%
;
left
:
var
(
--stage-viewport-left
,
0
);
left
:
var
(
--stage-viewport-left
,
0
);
display
:
flex
;
display
:
flex
;
width
:
86px
;
width
:
58px
;
height
:
256px
;
height
:
158px
;
padding-top
:
10px
;
align-items
:
center
;
align-items
:
center
;
justify-content
:
center
;
justify-content
:
center
;
border-radius
:
0
12px
12px
0
;
border-radius
:
0
12px
12px
0
;
background
:
rgba
(
40
,
12
,
8
,
0.52
);
background
:
rgba
(
40
,
12
,
8
,
0.52
);
color
:
white
;
color
:
rgba
(
255
,
255
,
255
,
0.9
)
;
font-size
:
32pt
;
font-size
:
25px
;
letter-spacing
:
10px
;
letter-spacing
:
10px
;
line-height
:
1.25
;
line-height
:
1.25
;
text-align
:
center
;
text-align
:
center
;
...
...
frontend-large/src/assets/images/game1/podium.png
View replaced file @
a8efe97a
View file @
40a1a7b0
386 KB
|
W:
|
H:
151 KB
|
W:
|
H:
2-up
Swipe
Onion skin
frontend-large/src/commons/music.ts
View file @
40a1a7b0
...
@@ -23,17 +23,28 @@ export function stopAllMusic() {
...
@@ -23,17 +23,28 @@ export function stopAllMusic() {
backgroundMusic
=
null
;
backgroundMusic
=
null
;
}
}
function
playAudioTimes
(
audio
:
HTMLAudioElement
,
times
:
number
)
{
let
count
=
1
audio
.
currentTime
=
0
audio
.
play
()
audio
.
onended
=
()
=>
{
if
(
count
>=
times
)
{
audio
.
onended
=
null
return
}
count
++
audio
.
currentTime
=
0
audio
.
play
()
}
}
function
getBackgroundMusic
(
music
:
string
,
force
:
boolean
=
true
)
{
function
getBackgroundMusic
(
music
:
string
,
force
:
boolean
=
true
)
{
if
(
force
)
{
//
if
(
force
)
{
//
if
(
backgroundMusic
)
{
if
(
backgroundMusic
)
{
stopApplauseMusic
();
stopAllMusic
();
stopGame1Music
();
// stopGame2Music();
// stopGame3Music();
stopGame4Music
();
stopGame5Music
();
stopGame6Music
();
backgroundMusic
=
null
;
}
}
}
}
if
(
!
backgroundMusic
)
{
if
(
!
backgroundMusic
)
{
...
@@ -47,13 +58,12 @@ function getBackgroundMusic(music: string, force: boolean = true) {
...
@@ -47,13 +58,12 @@ function getBackgroundMusic(music: string, force: boolean = true) {
return
backgroundMusic
return
backgroundMusic
}
}
//播放庆祝音乐
export
async
function
playApplauseMusic
()
{
export
async
function
playApplauseMusic
()
{
const
audio
=
getBackgroundMusic
(
applause
)
const
audio
=
getBackgroundMusic
(
applause
)
try
{
try
{
await
audio
.
play
()
playAudioTimes
(
audio
,
2
);
//播放两次停止
window
.
removeEventListener
(
'pointerdown'
,
playApplauseMusic
)
window
.
removeEventListener
(
'keydown'
,
playApplauseMusic
)
}
catch
{
}
catch
{
window
.
addEventListener
(
'pointerdown'
,
playApplauseMusic
,
{
once
:
false
})
window
.
addEventListener
(
'pointerdown'
,
playApplauseMusic
,
{
once
:
false
})
window
.
addEventListener
(
'keydown'
,
playApplauseMusic
,
{
once
:
false
})
window
.
addEventListener
(
'keydown'
,
playApplauseMusic
,
{
once
:
false
})
...
...
frontend-large/src/commons/utils.ts
View file @
40a1a7b0
...
@@ -93,4 +93,233 @@ export function $query(q: string | string[]): string | string[] {
...
@@ -93,4 +93,233 @@ export function $query(q: string | string[]): string | string[] {
return
q
.
map
((
key
)
=>
params
.
get
(
key
)).
filter
((
v
):
v
is
string
=>
!!
v
);
return
q
.
map
((
key
)
=>
params
.
get
(
key
)).
filter
((
v
):
v
is
string
=>
!!
v
);
}
}
return
params
.
get
(
q
)
||
''
;
return
params
.
get
(
q
)
||
''
;
}
let
toastElement
:
HTMLDivElement
|
undefined
;
let
toastTimer
:
ReturnType
<
typeof
window
.
setTimeout
>
|
undefined
;
export
function
$toast
(
message
?:
string
,
duration
=
2000
)
{
if
(
!
message
)
{
return
;
}
if
(
!
toastElement
)
{
toastElement
=
document
.
createElement
(
'div'
);
toastElement
.
style
.
cssText
=
[
'position: fixed'
,
'left: 50%'
,
'top: 45%'
,
'z-index: 99999'
,
'max-width: 560px'
,
'padding: 18px 28px'
,
'border-radius: 18px'
,
'background: rgba(0, 0, 0, 0.72)'
,
'color: #fff'
,
'font-size: 22px'
,
'line-height: 1.4'
,
'text-align: center'
,
'transform: translate(-50%, -40%)'
,
'opacity: 0'
,
'pointer-events: none'
,
'transition: opacity 0.2s ease, transform 0.2s ease'
,
].
join
(
';'
);
document
.
body
.
appendChild
(
toastElement
);
}
if
(
toastTimer
)
{
window
.
clearTimeout
(
toastTimer
);
toastTimer
=
undefined
;
}
toastElement
.
textContent
=
message
;
toastElement
.
style
.
opacity
=
'1'
;
toastElement
.
style
.
transform
=
'translate(-50%, -50%)'
;
toastTimer
=
window
.
setTimeout
(()
=>
{
if
(
!
toastElement
)
{
return
;
}
toastElement
.
style
.
opacity
=
'0'
;
toastElement
.
style
.
transform
=
'translate(-50%, -40%)'
;
toastTimer
=
undefined
;
},
duration
);
}
type
ConfirmOptions
=
{
title
?:
string
;
message
?:
string
;
confirmText
?:
string
;
cancelText
?:
string
;
}
let
confirmMaskElement
:
HTMLDivElement
|
undefined
;
let
confirmBoxElement
:
HTMLDivElement
|
undefined
;
let
confirmTitleElement
:
HTMLDivElement
|
undefined
;
let
confirmMessageElement
:
HTMLDivElement
|
undefined
;
let
confirmCancelElement
:
HTMLButtonElement
|
undefined
;
let
confirmOkElement
:
HTMLButtonElement
|
undefined
;
let
confirmResolve
:
((
value
:
boolean
)
=>
void
)
|
undefined
;
let
confirmHideTimer
:
ReturnType
<
typeof
window
.
setTimeout
>
|
undefined
;
function
closeConfirm
(
result
:
boolean
)
{
if
(
!
confirmMaskElement
||
!
confirmBoxElement
)
{
confirmResolve
?.(
result
);
confirmResolve
=
undefined
;
return
;
}
if
(
confirmHideTimer
)
{
window
.
clearTimeout
(
confirmHideTimer
);
confirmHideTimer
=
undefined
;
}
confirmMaskElement
.
style
.
opacity
=
'0'
;
confirmBoxElement
.
style
.
transform
=
'scale(0.96)'
;
confirmHideTimer
=
window
.
setTimeout
(()
=>
{
if
(
confirmMaskElement
)
{
confirmMaskElement
.
style
.
display
=
'none'
;
}
confirmHideTimer
=
undefined
;
},
200
);
confirmResolve
?.(
result
);
confirmResolve
=
undefined
;
}
function
ensureConfirmElement
()
{
if
(
confirmMaskElement
)
{
return
;
}
confirmMaskElement
=
document
.
createElement
(
'div'
);
confirmMaskElement
.
style
.
cssText
=
[
'position: fixed'
,
'inset: 0'
,
'z-index: 99998'
,
'display: none'
,
'align-items: center'
,
'justify-content: center'
,
'background: rgba(0, 0, 0, 0.45)'
,
'opacity: 0'
,
'transition: opacity 0.2s ease'
,
].
join
(
';'
);
confirmBoxElement
=
document
.
createElement
(
'div'
);
confirmBoxElement
.
style
.
cssText
=
[
'width: min(560px, calc(100vw - 80px))'
,
'box-sizing: border-box'
,
'padding: 34px 32px 28px'
,
'border-radius: 22px'
,
'background: #fff'
,
'color: #333'
,
'font-size: 24px'
,
'line-height: 1.45'
,
'text-align: center'
,
'box-shadow: 0 18px 48px rgba(0, 0, 0, 0.22)'
,
'transform: scale(0.96)'
,
'transition: transform 0.2s ease'
,
].
join
(
';'
);
confirmTitleElement
=
document
.
createElement
(
'div'
);
confirmTitleElement
.
style
.
cssText
=
[
'margin-bottom: 16px'
,
'font-size: 30px'
,
'font-weight: 700'
,
'color: #222'
,
].
join
(
';'
);
confirmMessageElement
=
document
.
createElement
(
'div'
);
confirmMessageElement
.
style
.
cssText
=
[
'min-height: 34px'
,
'word-break: break-word'
,
].
join
(
';'
);
const
buttonWrap
=
document
.
createElement
(
'div'
);
buttonWrap
.
style
.
cssText
=
[
'display: flex'
,
'gap: 18px'
,
'margin-top: 30px'
,
].
join
(
';'
);
confirmCancelElement
=
document
.
createElement
(
'button'
);
confirmCancelElement
.
type
=
'button'
;
confirmCancelElement
.
style
.
cssText
=
[
'flex: 1'
,
'height: 58px'
,
'border: 1px solid #ddd'
,
'border-radius: 29px'
,
'background: #fff'
,
'color: #666'
,
'font-size: 24px'
,
].
join
(
';'
);
confirmCancelElement
.
onclick
=
()
=>
closeConfirm
(
false
);
confirmOkElement
=
document
.
createElement
(
'button'
);
confirmOkElement
.
type
=
'button'
;
confirmOkElement
.
style
.
cssText
=
[
'flex: 1'
,
'height: 58px'
,
'border: 0'
,
'border-radius: 29px'
,
'background: #AA0000'
,
'color: #fff'
,
'font-size: 24px'
,
].
join
(
';'
);
confirmOkElement
.
onclick
=
()
=>
closeConfirm
(
true
);
confirmMaskElement
.
onclick
=
(
event
)
=>
{
if
(
event
.
target
===
confirmMaskElement
)
{
closeConfirm
(
false
);
}
};
buttonWrap
.
append
(
confirmCancelElement
,
confirmOkElement
);
confirmBoxElement
.
append
(
confirmTitleElement
,
confirmMessageElement
,
buttonWrap
);
confirmMaskElement
.
appendChild
(
confirmBoxElement
);
document
.
body
.
appendChild
(
confirmMaskElement
);
}
export
function
$confirm
(
message
?:
string
,
title
?:
string
):
Promise
<
boolean
>
;
export
function
$confirm
(
options
?:
ConfirmOptions
):
Promise
<
boolean
>
;
export
function
$confirm
(
messageOrOptions
?:
string
|
ConfirmOptions
,
title
?:
string
):
Promise
<
boolean
>
{
const
options
:
ConfirmOptions
=
typeof
messageOrOptions
===
'object'
?
messageOrOptions
:
{
message
:
messageOrOptions
,
title
};
if
(
!
options
.
message
)
{
return
Promise
.
resolve
(
false
);
}
ensureConfirmElement
();
if
(
confirmResolve
)
{
confirmResolve
(
false
);
confirmResolve
=
undefined
;
}
if
(
confirmHideTimer
)
{
window
.
clearTimeout
(
confirmHideTimer
);
confirmHideTimer
=
undefined
;
}
confirmTitleElement
!
.
textContent
=
options
.
title
??
'提示'
;
confirmMessageElement
!
.
textContent
=
options
.
message
;
confirmCancelElement
!
.
textContent
=
options
.
cancelText
??
'取消'
;
confirmOkElement
!
.
textContent
=
options
.
confirmText
??
'确定'
;
confirmMaskElement
!
.
style
.
display
=
'flex'
;
window
.
requestAnimationFrame
(()
=>
{
if
(
!
confirmMaskElement
||
!
confirmBoxElement
)
{
return
;
}
confirmMaskElement
.
style
.
opacity
=
'1'
;
confirmBoxElement
.
style
.
transform
=
'scale(1)'
;
});
return
new
Promise
<
boolean
>
((
resolve
)
=>
{
confirmResolve
=
resolve
;
});
}
}
\ No newline at end of file
frontend-large/src/commons/ws.ts
View file @
40a1a7b0
...
@@ -57,7 +57,7 @@ export function initSocket(args: SocketInitArgs): Socket | null {
...
@@ -57,7 +57,7 @@ export function initSocket(args: SocketInitArgs): Socket | null {
socket
.
onAny
((
evt
,
payload
)
=>
{
socket
.
onAny
((
evt
,
payload
)
=>
{
const
data
=
decode
(
payload
);
const
data
=
decode
(
payload
);
if
(
$is_run_local
())
{
if
(
$is_run_local
())
{
console
.
log
(
"
recv<============
"
,
evt
,
data
);
console
.
log
(
"
============>recv
"
,
evt
,
data
);
}
}
messageHandlers
.
forEach
((
handler
)
=>
handler
(
evt
,
data
));
messageHandlers
.
forEach
((
handler
)
=>
handler
(
evt
,
data
));
});
});
...
@@ -78,7 +78,7 @@ export function sendSocketMessage(cmd: string, data: any = {}): boolean {
...
@@ -78,7 +78,7 @@ export function sendSocketMessage(cmd: string, data: any = {}): boolean {
return
false
;
return
false
;
}
}
if
(
$is_run_local
())
{
if
(
$is_run_local
())
{
console
.
log
(
'
================>send
'
,
cmd
,
data
);
console
.
log
(
'
send<================
'
,
cmd
,
data
);
}
}
socket
.
send
(
encode
({
cmd
,
data
}));
socket
.
send
(
encode
({
cmd
,
data
}));
return
true
;
return
true
;
...
...
frontend-large/src/composables/useAdminGameSocket.ts
View file @
40a1a7b0
import
CryptoJS
from
'crypto-js'
import
CryptoJS
from
'crypto-js'
import
{
onBeforeUnmount
,
onMounted
}
from
'vue'
import
{
onBeforeUnmount
,
onMounted
}
from
'vue'
import
{
$read_socket_storge
,
$remove_socket_storage
}
from
'@/commons/utils'
import
{
$read_socket_storge
,
$remove_socket_storage
,
$toast
}
from
'@/commons/utils'
import
{
initSocket
,
onSocketMessage
,
sendSocketMessage
}
from
'@/commons/ws'
import
{
initSocket
,
onSocketMessage
,
sendSocketMessage
}
from
'@/commons/ws'
import
router
from
'@/router'
import
router
from
'@/router'
...
@@ -64,21 +64,18 @@ export function useAdminGameSocket(options: AdminGameSocketOptions) {
...
@@ -64,21 +64,18 @@ export function useAdminGameSocket(options: AdminGameSocketOptions) {
offSocketMessage
=
onSocketMessage
(
async
(
evt
,
payload
:
SocketPayload
)
=>
{
offSocketMessage
=
onSocketMessage
(
async
(
evt
,
payload
:
SocketPayload
)
=>
{
const
{
msg
,
state
,
data
}
=
payload
const
{
msg
,
state
,
data
}
=
payload
if
(
state
===
0
)
{
if
(
state
===
0
)
{
// if (evt === 'game_start_result' && data === 1) {
// return
// }
if
(
evt
==
'login_result'
)
{
if
(
evt
==
'login_result'
)
{
alert
(
msg
)
//
alert(msg)
// options.onRelogin?.()
// options.onRelogin?.()
socket
?.
close
(
);
$toast
(
msg
);
$remove_socket_storage
();
$remove_socket_storage
();
await
router
.
replace
(
`/login`
);
await
router
.
replace
(
`/login`
);
location
.
href
=
location
.
href
;
location
.
href
=
location
.
href
;
return
;
return
;
}
}
else
if
(
evt
==
'new_admin_result'
)
{
else
if
(
evt
==
'new_admin_result'
)
{
alert
(
msg
);
//
alert(msg);
socket
?.
close
(
);
$toast
(
msg
);
$remove_socket_storage
();
$remove_socket_storage
();
await
router
.
replace
(
`/login`
);
await
router
.
replace
(
`/login`
);
location
.
href
=
location
.
href
;
location
.
href
=
location
.
href
;
...
...
frontend-large/src/pages/Login.vue
View file @
40a1a7b0
<
script
setup
lang=
"ts"
>
<
script
setup
lang=
"ts"
>
import
{
cssAssetUrl
}
from
'@/commons/assets'
;
import
{
cssAssetUrl
}
from
'@/commons/assets'
;
import
{
$save
}
from
'@/commons/utils.ts'
;
import
{
$save
,
$toast
}
from
'@/commons/utils.ts'
;
import
{
onMounted
,
ref
}
from
'vue'
import
{
onMounted
,
ref
}
from
'vue'
import
{
useRouter
}
from
'vue-router'
import
{
useRouter
}
from
'vue-router'
...
@@ -9,9 +9,9 @@ const username = ref('')
...
@@ -9,9 +9,9 @@ const username = ref('')
const
password
=
ref
(
''
)
const
password
=
ref
(
''
)
const
imageUrls
=
{
const
imageUrls
=
{
bg1
:
cssAssetUrl
(
'main-bg1.png'
),
bg1
:
cssAssetUrl
(
'main-bg1.png'
),
logo
:
cssAssetUrl
(
'game1/logo.png'
),
logo
:
cssAssetUrl
(
'game1/logo.png'
),
title1
:
cssAssetUrl
(
'main-title.png'
),
title1
:
cssAssetUrl
(
'main-title.png'
),
}
}
async
function
login
()
{
async
function
login
()
{
...
@@ -25,10 +25,11 @@ async function login() {
...
@@ -25,10 +25,11 @@ async function login() {
})
})
const
data
=
await
res
.
json
()
const
data
=
await
res
.
json
()
// if (!res.ok || data.state !== 1) {
if
(
!
res
.
ok
||
data
.
state
!==
1
)
{
// alert(data.msg || 'Login failed')
$toast
(
data
.
msg
)
// throw new Error(data.msg || 'Login failed')
//alert(data.msg || 'Login failed')
// }
// throw new Error(data.msg || 'Login failed')
}
return
data
return
data
}
}
...
@@ -36,13 +37,15 @@ const loginHandler = async () => {
...
@@ -36,13 +37,15 @@ const loginHandler = async () => {
const
{
state
,
msg
,
data
}
=
await
login
()
const
{
state
,
msg
,
data
}
=
await
login
()
if
(
state
===
0
)
{
if
(
state
===
0
)
{
alert
(
msg
)
// alert(msg)
$toast
(
msg
)
return
return
}
}
for
(
let
i
in
data
)
{
for
(
let
i
in
data
)
{
$save
(
i
,
data
[
i
]);
$save
(
i
,
data
[
i
]);
}
}
alert
(
'登录成功'
)
// alert('登录成功')
$toast
(
'登录成功'
)
await
router
.
replace
(
`/main`
);
await
router
.
replace
(
`/main`
);
}
}
...
@@ -77,34 +80,33 @@ onMounted(() => {
...
@@ -77,34 +80,33 @@ onMounted(() => {
</
template
>
</
template
>
<
style
scoped
>
<
style
scoped
>
.bg
{
.bg
{
width
:
1920px
;
width
:
1920px
;
height
:
1080px
;
height
:
1080px
;
background
:
v-bind
(
'imageUrls.bg1'
)
center
/
cover
no-repeat
;
background
:
v-bind
(
'imageUrls.bg1'
)
center
/
cover
no-repeat
;
display
:
flex
;
display
:
flex
;
flex-direction
:
column
;
flex-direction
:
column
;
overflow
:
hidden
;
overflow
:
hidden
;
position
:
relative
;
position
:
relative
;
.img-logo
{
background
:
v-bind
(
'imageUrls.logo'
);
background-size
:
cover
;
width
:
428px
;
height
:
77px
;
position
:
absolute
;
left
:
37px
;
top
:
82px
;
}
.img-logo
{
.img-title1
{
background
:
v-bind
(
'imageUrls.logo'
);
background
:
v-bind
(
'imageUrls.title1'
)
center
/
cover
no-repeat
;
background-size
:
cover
;
width
:
1024px
;
width
:
428px
;
height
:
143px
;
height
:
77px
;
margin
:
0
auto
;
position
:
absolute
;
position
:
relative
;
left
:
37px
;
top
:
50px
;
top
:
82px
;
}
}
.img-title1
{
background
:
v-bind
(
'imageUrls.title1'
)
center
/
cover
no-repeat
;
width
:
1024px
;
height
:
143px
;
margin
:
0
auto
;
position
:
relative
;
top
:
50px
;
}
}
}
.login-page
{
.login-page
{
...
...
frontend-large/src/pages/game1/Game.vue
View file @
40a1a7b0
...
@@ -7,7 +7,7 @@ import Rank2 from './views/Rank2View.vue'
...
@@ -7,7 +7,7 @@ import Rank2 from './views/Rank2View.vue'
import
{
useAdminGameSocket
}
from
'@/composables/useAdminGameSocket'
import
{
useAdminGameSocket
}
from
'@/composables/useAdminGameSocket'
import
type
Player
from
'@/commons/player.ts'
import
type
Player
from
'@/commons/player.ts'
import
{
playApplauseMusic
,
playGame1Music
,
stopAllMusic
,
stopGame1Music
}
from
'@/commons/music'
import
{
playApplauseMusic
,
playGame1Music
,
stopAllMusic
,
stopGame1Music
}
from
'@/commons/music'
import
{
$
remove_socket_storage
}
from
'@/commons/utils.ts'
import
{
$
confirm
,
$remove_socket_storage
,
$toast
}
from
'@/commons/utils.ts'
const
router
=
useRouter
()
const
router
=
useRouter
()
...
@@ -155,7 +155,8 @@ const { startGame, createRoom, backRoom, closeRoom } = useAdminGameSocket({
...
@@ -155,7 +155,8 @@ const { startGame, createRoom, backRoom, closeRoom } = useAdminGameSocket({
const
startGameWithMusic
=
()
=>
{
const
startGameWithMusic
=
()
=>
{
if
(
playerCount
.
value
==
0
)
{
if
(
playerCount
.
value
==
0
)
{
alert
(
'房间中没有玩家'
)
// alert('房间中没有玩家')
$toast
(
'房间中没有玩家'
);
return
;
return
;
}
}
startGame
()
startGame
()
...
@@ -171,10 +172,16 @@ const nextRoundWithMusic = () => {
...
@@ -171,10 +172,16 @@ const nextRoundWithMusic = () => {
nextRound
()
nextRound
()
}
}
const
backHandler
=
()
=>
{
const
backHandler
=
async
()
=>
{
if
(
confirm
(
'是否关闭当前房间回到首页'
))
{
const
ok
=
await
$confirm
({
title
:
'提示'
,
message
:
'是否关闭当前房间回到首页'
,
confirmText
:
'确定'
,
cancelText
:
'取消'
,
})
if
(
ok
)
{
closeRoom
();
closeRoom
();
stop
Game1
Music
()
stop
All
Music
()
router
.
replace
(
'/main'
);
router
.
replace
(
'/main'
);
}
}
}
}
...
@@ -191,9 +198,9 @@ onUnmounted(() => {
...
@@ -191,9 +198,9 @@ onUnmounted(() => {
watch
(
screen
,
(
value
)
=>
{
watch
(
screen
,
(
value
)
=>
{
// console.log(value);
// console.log(value);
if
(
value
==
'rank2'
)
{
if
(
value
==
'rank2'
)
{
playApplauseMusic
();
playApplauseMusic
();
}
else
if
(
value
==
'loading'
)
{
}
else
if
(
value
==
'loading'
)
{
playGame1Music
();
playGame1Music
();
}
}
})
})
...
...
frontend-large/src/pages/game1/views/Rank2View.vue
View file @
40a1a7b0
...
@@ -152,11 +152,10 @@ const renderAvatar = (item: any | null) => {
...
@@ -152,11 +152,10 @@ const renderAvatar = (item: any | null) => {
.podium
{
.podium
{
background
:
v-bind
(
'imageUrls.podium'
)
no-repeat
center
;
background
:
v-bind
(
'imageUrls.podium'
)
no-repeat
center
;
width
:
1
347
px
;
width
:
1
920
px
;
height
:
269
px
;
height
:
740
px
;
position
:
absolute
;
position
:
absolute
;
top
:
427px
;
bottom
:
0
;
left
:
287px
;
.gu-burst
{
.gu-burst
{
width
:
200px
;
width
:
200px
;
...
@@ -174,6 +173,8 @@ const renderAvatar = (item: any | null) => {
...
@@ -174,6 +173,8 @@ const renderAvatar = (item: any | null) => {
.rank-no1
{
.rank-no1
{
position
:
relative
;
position
:
relative
;
left
:
308px
;
top
:
150px
;
.gu-burst
{
.gu-burst
{
left
:
580px
;
left
:
580px
;
...
@@ -207,7 +208,8 @@ const renderAvatar = (item: any | null) => {
...
@@ -207,7 +208,8 @@ const renderAvatar = (item: any | null) => {
.rank-no2
{
.rank-no2
{
position
:
relative
;
position
:
relative
;
left
:
308px
;
top
:
150px
;
.gu-burst
{
.gu-burst
{
left
:
140px
;
left
:
140px
;
top
:
-170px
;
top
:
-170px
;
...
@@ -232,7 +234,7 @@ const renderAvatar = (item: any | null) => {
...
@@ -232,7 +234,7 @@ const renderAvatar = (item: any | null) => {
text-align
:
center
;
text-align
:
center
;
line-height
:
46px
;
line-height
:
46px
;
position
:
absolute
;
position
:
absolute
;
left
:
1
57
px
;
left
:
1
65
px
;
top
:
2px
;
top
:
2px
;
z-index
:
1
;
z-index
:
1
;
border-radius
:
23px
;
border-radius
:
23px
;
...
@@ -241,7 +243,8 @@ const renderAvatar = (item: any | null) => {
...
@@ -241,7 +243,8 @@ const renderAvatar = (item: any | null) => {
.rank-no3
{
.rank-no3
{
position
:
relative
;
position
:
relative
;
left
:
308px
;
top
:
150px
;
.gu-burst
{
.gu-burst
{
left
:
1020px
;
left
:
1020px
;
top
:
-170px
;
top
:
-170px
;
...
@@ -280,8 +283,8 @@ const renderAvatar = (item: any | null) => {
...
@@ -280,8 +283,8 @@ const renderAvatar = (item: any | null) => {
height
:
238px
;
height
:
238px
;
background
:
v-bind
(
'imageUrls.vip'
);
background
:
v-bind
(
'imageUrls.vip'
);
position
:
absolute
;
position
:
absolute
;
left
:
171
px
;
left
:
480
px
;
top
:
-
20
0px
;
top
:
-
5
0px
;
}
}
.rank-container
{
.rank-container
{
...
@@ -324,19 +327,21 @@ const renderAvatar = (item: any | null) => {
...
@@ -324,19 +327,21 @@ const renderAvatar = (item: any | null) => {
position
:
absolute
;
position
:
absolute
;
inset
:
0
;
inset
:
0
;
border-radius
:
inherit
;
border-radius
:
inherit
;
background
:
v-bind
(
'imageUrls.avatarAnimation'
);
transform-origin
:
center
center
;
background
:
v-bind
(
'imageUrls.avatarAnimation'
)
center
/
cover
no-repeat
;
animation
:
avatar-rotate
10s
linear
infinite
;
animation
:
avatar-rotate
10s
linear
infinite
;
}
}
.img-avatar
{
.img-avatar
{
position
:
relative
;
position
:
absolute
;
top
:
6px
;
left
:
50%
;
top
:
50%
;
z-index
:
1
;
z-index
:
1
;
margin
:
0
auto
;
width
:
60px
;
width
:
60px
;
height
:
60px
;
height
:
60px
;
border-radius
:
30px
;
border-radius
:
30px
;
background
:
v-bind
(
'imageUrls.avatar'
);
transform
:
translate
(
-50%
,
-50%
);
background
:
v-bind
(
'imageUrls.avatar'
)
center
/
cover
no-repeat
;
}
}
.txt-nickname
{
.txt-nickname
{
...
...
frontend-large/src/pages/game4/Game4.vue
View file @
40a1a7b0
...
@@ -8,7 +8,7 @@ import { useAdminGameSocket } from "@/composables/useAdminGameSocket";
...
@@ -8,7 +8,7 @@ import { useAdminGameSocket } from "@/composables/useAdminGameSocket";
import
{
onSocketMessage
}
from
"@/commons/ws"
;
import
{
onSocketMessage
}
from
"@/commons/ws"
;
import
type
Player
from
"@/commons/player.ts"
;
import
type
Player
from
"@/commons/player.ts"
;
import
{
useRouter
}
from
'vue-router'
import
{
useRouter
}
from
'vue-router'
import
{
$
remove_socket_storage
}
from
"@/commons/utils.ts"
;
import
{
$
confirm
,
$remove_socket_storage
,
$toast
}
from
"@/commons/utils.ts"
;
const
router
=
useRouter
()
const
router
=
useRouter
()
...
@@ -194,7 +194,8 @@ const { startGame, createRoom, backRoom, closeRoom } = useAdminGameSocket({
...
@@ -194,7 +194,8 @@ const { startGame, createRoom, backRoom, closeRoom } = useAdminGameSocket({
const
startGameWithMusic
=
()
=>
{
const
startGameWithMusic
=
()
=>
{
if
(
playerCount
.
value
==
0
)
{
if
(
playerCount
.
value
==
0
)
{
alert
(
'房间中没有玩家'
)
// alert('房间中没有玩家')
$toast
(
'房间中没有玩家'
);
return
;
return
;
}
}
startGame
()
startGame
()
...
@@ -210,10 +211,16 @@ const nextRoundWithMusic = () => {
...
@@ -210,10 +211,16 @@ const nextRoundWithMusic = () => {
nextRound
()
nextRound
()
}
}
const
backHandler
=
()
=>
{
const
backHandler
=
async
()
=>
{
if
(
confirm
(
'是否关闭当前房间回到首页'
))
{
const
ok
=
await
$confirm
({
title
:
'提示'
,
message
:
'是否关闭当前房间回到首页'
,
confirmText
:
'确定'
,
cancelText
:
'取消'
,
})
if
(
ok
)
{
closeRoom
();
closeRoom
();
stop
Game4
Music
()
stop
All
Music
()
router
.
replace
(
'/main'
);
router
.
replace
(
'/main'
);
}
}
}
}
...
...
frontend-large/src/pages/game5/Game5.vue
View file @
40a1a7b0
...
@@ -7,7 +7,7 @@ import Rank2 from './views/Rank2View.vue'
...
@@ -7,7 +7,7 @@ import Rank2 from './views/Rank2View.vue'
import
{
useAdminGameSocket
}
from
'@/composables/useAdminGameSocket'
import
{
useAdminGameSocket
}
from
'@/composables/useAdminGameSocket'
import
type
Player
from
'@/commons/player.ts'
import
type
Player
from
'@/commons/player.ts'
import
{
playApplauseMusic
,
playGame5Music
,
stopAllMusic
,
stopGame5Music
}
from
'@/commons/music'
import
{
playApplauseMusic
,
playGame5Music
,
stopAllMusic
,
stopGame5Music
}
from
'@/commons/music'
import
{
$
remove_socket_storage
}
from
'@/commons/utils.ts'
import
{
$
confirm
,
$remove_socket_storage
,
$toast
}
from
'@/commons/utils.ts'
const
router
=
useRouter
()
const
router
=
useRouter
()
...
@@ -163,7 +163,8 @@ const { startGame, createRoom, closeRoom, backRoom } = useAdminGameSocket({
...
@@ -163,7 +163,8 @@ const { startGame, createRoom, closeRoom, backRoom } = useAdminGameSocket({
const
startGameWithMusic
=
()
=>
{
const
startGameWithMusic
=
()
=>
{
if
(
playerCount
.
value
==
0
)
{
if
(
playerCount
.
value
==
0
)
{
alert
(
'房间中没有玩家'
)
// alert('房间中没有玩家')
$toast
(
'房间中没有玩家'
);
return
;
return
;
}
}
playGame5Music
()
playGame5Music
()
...
@@ -191,10 +192,16 @@ onUnmounted(() => {
...
@@ -191,10 +192,16 @@ onUnmounted(() => {
window
.
removeEventListener
(
'beforeunload'
,
confirmRefresh
)
window
.
removeEventListener
(
'beforeunload'
,
confirmRefresh
)
})
})
const
backHandler
=
()
=>
{
const
backHandler
=
async
()
=>
{
if
(
confirm
(
'是否关闭当前房间回到首页'
))
{
const
ok
=
await
$confirm
({
title
:
'提示'
,
message
:
'是否关闭当前房间回到首页'
,
confirmText
:
'确定'
,
cancelText
:
'取消'
,
})
if
(
ok
)
{
closeRoom
();
closeRoom
();
stop
Game5
Music
()
stop
All
Music
()
router
.
replace
(
'/main'
);
router
.
replace
(
'/main'
);
}
}
}
}
...
...
frontend-large/src/pages/game6/Game.vue
View file @
40a1a7b0
...
@@ -7,7 +7,7 @@ import Rank2 from './views/Rank2View.vue'
...
@@ -7,7 +7,7 @@ import Rank2 from './views/Rank2View.vue'
import
{
useAdminGameSocket
}
from
'@/composables/useAdminGameSocket'
import
{
useAdminGameSocket
}
from
'@/composables/useAdminGameSocket'
import
type
Player
from
'@/commons/player.ts'
import
type
Player
from
'@/commons/player.ts'
import
{
playApplauseMusic
,
playGame6Music
,
stopAllMusic
,
stopGame6Music
}
from
'@/commons/music'
import
{
playApplauseMusic
,
playGame6Music
,
stopAllMusic
,
stopGame6Music
}
from
'@/commons/music'
import
{
$
remove_socket_storage
}
from
'@/commons/utils.ts'
import
{
$
confirm
,
$remove_socket_storage
,
$toast
}
from
'@/commons/utils.ts'
const
router
=
useRouter
()
const
router
=
useRouter
()
...
@@ -153,7 +153,8 @@ const { startGame, createRoom, backRoom, closeRoom } = useAdminGameSocket({
...
@@ -153,7 +153,8 @@ const { startGame, createRoom, backRoom, closeRoom } = useAdminGameSocket({
const
startGameWithMusic
=
()
=>
{
const
startGameWithMusic
=
()
=>
{
if
(
playerCount
.
value
==
0
)
{
if
(
playerCount
.
value
==
0
)
{
alert
(
'房间中没有玩家'
)
// alert('房间中没有玩家')
$toast
(
'房间中没有玩家'
);
return
;
return
;
}
}
startGame
()
startGame
()
...
@@ -169,10 +170,16 @@ const nextRoundWithMusic = () => {
...
@@ -169,10 +170,16 @@ const nextRoundWithMusic = () => {
nextRound
()
nextRound
()
}
}
const
backHandler
=
()
=>
{
const
backHandler
=
async
()
=>
{
if
(
confirm
(
'是否关闭当前房间回到首页'
))
{
const
ok
=
await
$confirm
({
title
:
'提示'
,
message
:
'是否关闭当前房间回到首页'
,
confirmText
:
'确定'
,
cancelText
:
'取消'
,
})
if
(
ok
)
{
closeRoom
();
closeRoom
();
stop
Game6
Music
()
stop
All
Music
()
router
.
replace
(
'/main'
);
router
.
replace
(
'/main'
);
}
}
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment