修复
This commit is contained in:
7
Service/Application.Web/Config/TokenConfig.cs
Normal file
7
Service/Application.Web/Config/TokenConfig.cs
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
namespace Application.Web;
|
||||||
|
|
||||||
|
public class TokenConfig
|
||||||
|
{
|
||||||
|
public const int TokenTime = 5;//分钟
|
||||||
|
|
||||||
|
}
|
||||||
@@ -174,7 +174,7 @@ namespace Application.Web.Controllers.Login
|
|||||||
string Key = App.Configuration["JwtTokenOptions:SecurityKey"].ToString();
|
string Key = App.Configuration["JwtTokenOptions:SecurityKey"].ToString();
|
||||||
string Issuer = App.Configuration["JwtTokenOptions:Issuer"].ToString();
|
string Issuer = App.Configuration["JwtTokenOptions:Issuer"].ToString();
|
||||||
string Audience = App.Configuration["JwtTokenOptions:Audience"].ToString();
|
string Audience = App.Configuration["JwtTokenOptions:Audience"].ToString();
|
||||||
string token = JwtHelper.CreateToken(Key, Issuer, Audience, loadData, 300);
|
string token = JwtHelper.CreateToken(Key, Issuer, Audience, loadData, TokenConfig.TokenTime);
|
||||||
return PoAction.Ok(new { token = token, refToken = userInfo.token, userId = userInfo.userId });
|
return PoAction.Ok(new { token = token, refToken = userInfo.token, userId = userInfo.userId });
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -226,11 +226,46 @@ namespace Application.Web.Controllers.Login
|
|||||||
string Key = App.Configuration["JwtTokenOptions:SecurityKey"].ToString();
|
string Key = App.Configuration["JwtTokenOptions:SecurityKey"].ToString();
|
||||||
string Issuer = App.Configuration["JwtTokenOptions:Issuer"].ToString();
|
string Issuer = App.Configuration["JwtTokenOptions:Issuer"].ToString();
|
||||||
string Audience = App.Configuration["JwtTokenOptions:Audience"].ToString();
|
string Audience = App.Configuration["JwtTokenOptions:Audience"].ToString();
|
||||||
string token = JwtHelper.CreateToken(Key, Issuer, Audience, loadData, 1);
|
string token = JwtHelper.CreateToken(Key, Issuer, Audience, loadData, TokenConfig.TokenTime);
|
||||||
return PoAction.Ok(new
|
return PoAction.Ok(new
|
||||||
{ regOk = userInfo.regOk, token = token, refToken = userInfo.token, userId = userInfo.userId });
|
{ regOk = userInfo.regOk, token = token, refToken = userInfo.token, userId = userInfo.userId });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<IPoAction> RefreshToken([FromBody] RefreshTokenParms parms)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(parms.token) || string.IsNullOrEmpty(parms.refToken))
|
||||||
|
{
|
||||||
|
return PoAction.Message("刷新失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
string Key = App.Configuration["JwtTokenOptions:SecurityKey"].ToString();
|
||||||
|
string Issuer = App.Configuration["JwtTokenOptions:Issuer"].ToString();
|
||||||
|
string Audience = App.Configuration["JwtTokenOptions:Audience"].ToString();
|
||||||
|
var data = JwtHelper.GetTokenPload(parms.token,Key);
|
||||||
|
string accId = string.Empty;
|
||||||
|
if (data.TryGetValue("accId", out object _accId))
|
||||||
|
{
|
||||||
|
accId = _accId.ToString();
|
||||||
|
}
|
||||||
|
var userInfo = await _userService.GetUserInfoByToken(parms.refToken);
|
||||||
|
if (userInfo == null)
|
||||||
|
{
|
||||||
|
return PoAction.Message("刷新失败,用户不存在!");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (userInfo.accId != accId)
|
||||||
|
{
|
||||||
|
return PoAction.Message("刷新失败,数据信息不合法!");
|
||||||
|
}
|
||||||
|
Dictionary<string, object> loadData = new Dictionary<string, object>();
|
||||||
|
loadData.Add("userId", userInfo.userId);
|
||||||
|
loadData.Add("accId", userInfo.accId);
|
||||||
|
string token = JwtHelper.CreateToken(Key, Issuer, Audience, loadData, TokenConfig.TokenTime);
|
||||||
|
return PoAction.Ok(new
|
||||||
|
{ token = token, refToken = userInfo.token, userId = userInfo.userId });
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 注册角色信息
|
/// 注册角色信息
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
namespace Application.Web;
|
||||||
|
|
||||||
|
public class RefreshTokenParms
|
||||||
|
{
|
||||||
|
public string refToken { get; set; }
|
||||||
|
public string token { get; set; }
|
||||||
|
}
|
||||||
@@ -115,6 +115,27 @@ a:focus {
|
|||||||
box-shadow: inset 0 1px 1px rgb(0 0 0 / 8%);
|
box-shadow: inset 0 1px 1px rgb(0 0 0 / 8%);
|
||||||
transition: border-color ease-in-out .15s,box-shadow ease-in-out .15s;
|
transition: border-color ease-in-out .15s,box-shadow ease-in-out .15s;
|
||||||
}
|
}
|
||||||
|
.ipt-btn-gray-m {
|
||||||
|
width: 60px;
|
||||||
|
height: 20px;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
.chat {
|
||||||
|
word-wrap: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat img {
|
||||||
|
margin-right: 2px;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
.em {
|
||||||
|
height: 30px;
|
||||||
|
width: 30px;
|
||||||
|
}
|
||||||
|
.badge {
|
||||||
|
max-height: 25px;
|
||||||
|
max-width: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
.btn {
|
.btn {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
|||||||
@@ -1,12 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<button class="but" @click="handleClick">{{ text }}</button>
|
<button class="but" @click="handleClick">
|
||||||
|
<slot></slot>
|
||||||
|
</button>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
// 1. 定义接收父组件传来的参数 props
|
|
||||||
const props = defineProps({
|
|
||||||
// 字段名、类型、默认值
|
|
||||||
text: String,
|
|
||||||
})
|
|
||||||
|
|
||||||
const emit = defineEmits(['click'])
|
const emit = defineEmits(['click'])
|
||||||
// 定义 click 事件
|
// 定义 click 事件
|
||||||
@@ -19,11 +16,16 @@ const handleClick = (): any => {
|
|||||||
|
|
||||||
<style>
|
<style>
|
||||||
.but {
|
.but {
|
||||||
text-decoration: underline;
|
/* text-decoration: underline; */
|
||||||
color: #1e5494;
|
color: #1e5494;
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
background: none;
|
background: none;
|
||||||
border: none;
|
border: none;
|
||||||
}
|
}
|
||||||
|
.but:hover{
|
||||||
|
color: #FFFFFF;
|
||||||
|
background: #1e5494;
|
||||||
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ export type HandledRedirectError = {
|
|||||||
|
|
||||||
export class ApiService {
|
export class ApiService {
|
||||||
private static initialized = false;
|
private static initialized = false;
|
||||||
|
private static isRefreshing = false;
|
||||||
|
private static refreshWaiters: Array<(success: boolean) => void> = [];
|
||||||
|
|
||||||
private static get userStore() {
|
private static get userStore() {
|
||||||
return useUserStore()
|
return useUserStore()
|
||||||
@@ -29,13 +31,57 @@ export class ApiService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static redirectToLogin() {
|
private static redirectToLogin() {
|
||||||
if (typeof localStorage !== "undefined") {
|
this.userStore.offOnline();
|
||||||
localStorage.removeItem("token");
|
window.location.href = "/";
|
||||||
localStorage.removeItem("userInfo");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof window !== "undefined") {
|
private static waitForRefresh(): Promise<boolean> {
|
||||||
PageExtend.Redirect("/home");
|
return new Promise(resolve => {
|
||||||
|
this.refreshWaiters.push(resolve);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static notifyWaiters(success: boolean): void {
|
||||||
|
this.refreshWaiters.forEach(resolve => resolve(success));
|
||||||
|
this.refreshWaiters = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 刷新 token,支持并发排队:多个请求同时 401 时只发一次刷新请求
|
||||||
|
private static async doRefreshToken(): Promise<boolean> {
|
||||||
|
if (this.isRefreshing) {
|
||||||
|
return this.waitForRefresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.isRefreshing = true;
|
||||||
|
try {
|
||||||
|
const refToken = this.userStore.getRefToken;
|
||||||
|
const token = this.userStore.getToken
|
||||||
|
if (!refToken) {
|
||||||
|
this.notifyWaiters(false);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = await this.request.post<IResultData<{ token: string; refToken: string; userId: string }>>(
|
||||||
|
"/Login/RefreshToken",
|
||||||
|
{ refToken, token }
|
||||||
|
);
|
||||||
|
if (result.code === 0 && result.data) {
|
||||||
|
this.userStore.setToken(
|
||||||
|
result.data.userId,
|
||||||
|
result.data.token,
|
||||||
|
result.data.refToken ?? this.userStore.refToken
|
||||||
|
);
|
||||||
|
this.notifyWaiters(true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.notifyWaiters(false);
|
||||||
|
return false;
|
||||||
|
} catch {
|
||||||
|
this.notifyWaiters(false);
|
||||||
|
return false;
|
||||||
|
} finally {
|
||||||
|
this.isRefreshing = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,30 +112,17 @@ export class ApiService {
|
|||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
const result = response.data;
|
const result = response.data;
|
||||||
if (result.code === 401) {
|
if (result.code === 500) {
|
||||||
//401刷新token
|
|
||||||
|
|
||||||
console.log(result.data);
|
|
||||||
} else if (result.code === 40101) {
|
|
||||||
this.redirectToLogin();
|
|
||||||
throw {
|
throw {
|
||||||
handled: true,
|
handled: true,
|
||||||
redirectTo: "/",//跳转回首页
|
redirectTo: "/",
|
||||||
message: result.msg || "登录已失效"
|
message: result.msg || "服务器内部错误"
|
||||||
} satisfies HandledRedirectError;
|
|
||||||
} else if (result.code === 500) {
|
|
||||||
// 跳转错误页面
|
|
||||||
throw {
|
|
||||||
handled: true,
|
|
||||||
redirectTo: "/",//跳转回首页
|
|
||||||
message: result.msg || "登录已失效"
|
|
||||||
} satisfies HandledRedirectError;
|
} satisfies HandledRedirectError;
|
||||||
} else if (result.code === 404) {
|
} else if (result.code === 404) {
|
||||||
// 跳转不存在页面
|
|
||||||
throw {
|
throw {
|
||||||
handled: true,
|
handled: true,
|
||||||
redirectTo: "/",//跳转回首页
|
redirectTo: "/",
|
||||||
message: result.msg || "登录已失效"
|
message: result.msg || "资源不存在"
|
||||||
} satisfies HandledRedirectError;
|
} satisfies HandledRedirectError;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -107,26 +140,57 @@ export class ApiService {
|
|||||||
this.initialized = true;
|
this.initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static executeRequest<T>(
|
||||||
|
method: HttpMethod,
|
||||||
|
url: string,
|
||||||
|
params: RequestParams
|
||||||
|
): Promise<IResultData<T>> {
|
||||||
|
switch (method) {
|
||||||
|
case "get":
|
||||||
|
return this.request.get<IResultData<T>>(url, { params });
|
||||||
|
case "post":
|
||||||
|
return this.request.post<IResultData<T>>(url, params);
|
||||||
|
case "put":
|
||||||
|
return this.request.put<IResultData<T>>(url, params);
|
||||||
|
case "delete":
|
||||||
|
return this.request.delete<IResultData<T>>(url, { params });
|
||||||
|
case "patch":
|
||||||
|
return this.request.patch<IResultData<T>>(url, params);
|
||||||
|
default:
|
||||||
|
throw new Error(`不支持的请求方法: ${method}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async requestWithRetry<T>(
|
||||||
|
method: HttpMethod,
|
||||||
|
url: string,
|
||||||
|
params: RequestParams,
|
||||||
|
isRetry: boolean
|
||||||
|
): Promise<IResultData<T>> {
|
||||||
|
const result = await this.executeRequest<T>(method, url, params);
|
||||||
|
|
||||||
|
if (result.code === 401 && !isRetry) {
|
||||||
|
const refreshed = await this.doRefreshToken();
|
||||||
|
if (refreshed) {
|
||||||
|
return this.requestWithRetry<T>(method, url, params, true);
|
||||||
|
}
|
||||||
|
this.redirectToLogin();
|
||||||
|
throw {
|
||||||
|
handled: true,
|
||||||
|
redirectTo: "/",
|
||||||
|
message: "登录已失效,请重新登录"
|
||||||
|
} satisfies HandledRedirectError;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
public static async Request<T = any>(
|
public static async Request<T = any>(
|
||||||
method: HttpMethod,
|
method: HttpMethod,
|
||||||
url: string,
|
url: string,
|
||||||
params: RequestParams = {}
|
params: RequestParams = {}
|
||||||
): Promise<IResultData<T>> {
|
): Promise<IResultData<T>> {
|
||||||
this.ensureInitialized();
|
this.ensureInitialized();
|
||||||
|
return this.requestWithRetry<T>(method, url, params, false);
|
||||||
switch (method) {
|
|
||||||
case "get":
|
|
||||||
return await this.request.get<IResultData<T>>(url, { params });
|
|
||||||
case "post":
|
|
||||||
return await this.request.post<IResultData<T>>(url, params);
|
|
||||||
case "put":
|
|
||||||
return await this.request.put<IResultData<T>>(url, params);
|
|
||||||
case "delete":
|
|
||||||
return await this.request.delete<IResultData<T>>(url, { params });
|
|
||||||
case "patch":
|
|
||||||
return await this.request.patch<IResultData<T>>(url, params);
|
|
||||||
default:
|
|
||||||
throw new Error(`不支持的请求方法: ${method}`);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,33 @@
|
|||||||
<template>
|
<template>
|
||||||
|
<div class="main">
|
||||||
<slot />
|
<slot />
|
||||||
|
</div>
|
||||||
|
<div class="content ">
|
||||||
|
<button class="btn btn-ret" @click="GoBack">返回</button><br />
|
||||||
|
<Abar href="/map">返回游戏</Abar>
|
||||||
|
</div>
|
||||||
|
<div class="clear"></div>
|
||||||
|
<div class="foot">
|
||||||
|
<div class="common">
|
||||||
|
<Abar href="/">首页</Abar>-
|
||||||
|
<Abar href="/">挂机</Abar>-
|
||||||
|
<a target="_blank" href="https://work.weixin.qq.com/kfid/kfc86bc348120aea3e7">反馈</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="timeService">
|
||||||
|
小G报时({{ TimeExtend.Now("HH:mm") }})
|
||||||
|
</div>
|
||||||
|
<p style="font-weight:bold;font-size:14px">官方QQ群:931835791</p>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
const router = useRouter()
|
||||||
|
//返回
|
||||||
|
const GoBack = (): void => {
|
||||||
|
router.back();
|
||||||
|
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped></style>
|
||||||
|
|
||||||
</style>
|
|
||||||
@@ -6,8 +6,8 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<div class="item" v-for="(item, index) in userData" :key="index">
|
<div class="item" v-for="(item, index) in userData" :key="index">
|
||||||
✧<a @click="loginGame(item.userId)">【{{ item.areaId }}区】{{ item.nick }}({{ (item.sex == null || item.sex == '') ?
|
✧<Abutton @click="loginGame(item.userId)" >【{{ item.areaId }}区】{{ item.nick }}({{ (item.sex == null || item.sex == '') ?
|
||||||
"未知" : item.sex }})</a>
|
"未知" : item.sex }})</Abutton>
|
||||||
</div>
|
</div>
|
||||||
<span v-if="userData.length == 0">暂无角色.</span>
|
<span v-if="userData.length == 0">暂无角色.</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
➸<a :href='"https://3g.fan/Regain/ToBbs?openid=" + AccountInfo.openId + "&bbs=1146"'>游戏论坛</a>
|
➸<a :href='"https://3g.fan/Regain/ToBbs?openid=" + AccountInfo.openId + "&bbs=1146"'>游戏论坛</a>
|
||||||
➸<a @click.stop="offOnline">退出游戏</a>
|
➸<Abutton @click="offOnline">退出游戏</Abutton>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -31,8 +31,8 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<div class="item" v-for="(item, index) in userData" :key="index">
|
<div class="item" v-for="(item, index) in userData" :key="index">
|
||||||
<a @click="loginGame(item.userId)">【{{ item.areaId }}区】{{ item.nick }}({{ (item.sex == null || item.sex == '') ?
|
<Abutton @click="loginGame(item.userId)" >【{{ item.areaId }}区】{{ item.nick }}({{ (item.sex == null || item.sex == '') ?
|
||||||
"未知" : item.sex }})</a>
|
"未知" : item.sex }})</Abutton>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -42,7 +42,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<div class="item" v-for="(item, index) in areaData" :key="index">
|
<div class="item" v-for="(item, index) in areaData" :key="index">
|
||||||
✧<a @click="registerGame(item.areaId)">({{ item.areaId }}区){{ item.name }}</a>
|
✧<Abutton @click="registerGame(item.areaId)">({{ item.areaId }}区){{ item.name }}</Abutton>
|
||||||
{{ item.status == 1 ? "(推荐)" : "(繁忙)" }}
|
{{ item.status == 1 ? "(推荐)" : "(繁忙)" }}
|
||||||
</div>
|
</div>
|
||||||
<span v-if="areaData.length == 0">暂无区服.</span>
|
<span v-if="areaData.length == 0">暂无区服.</span>
|
||||||
@@ -164,7 +164,7 @@ const loginGame = async (gameId: string): Promise<void> => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
MessageExtend.ShowDialog("注册角色", result.msg);
|
MessageExtend.ShowDialog("登录游戏", result.msg);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1 +1,124 @@
|
|||||||
<template></template>
|
<template>
|
||||||
|
<div class="item" style="font-size:15px;">
|
||||||
|
<span>[在线奖励]:3分钟后可领取.</span>
|
||||||
|
</div>
|
||||||
|
<div class="content">
|
||||||
|
威尼斯·广场
|
||||||
|
<Abutton @click="Refresh">刷新</Abutton>
|
||||||
|
<a class="a-nomargin"
|
||||||
|
href="/Task/Index/Index?sid=W6Wg8iH9gY7wIBNSEdtFcQ3KbI5YiKDo">任务</a><a class=""
|
||||||
|
href="/Message/Index/Index?sid=W6Wg8iH9gY7wIBNSEdtFcQ3KbI5YiKDo">消息</a>
|
||||||
|
</div>
|
||||||
|
<div class="content" style="font-size:14px;font-weight:bold;color:dodgerblue">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="notification">
|
||||||
|
<div class="chat">
|
||||||
|
<div class="item">
|
||||||
|
[公共]
|
||||||
|
<span><img src='http://gree.pccsh.com/res/badge/9001.gif' class='user-head' alt='头像' /><a class='a-nodec'
|
||||||
|
href='/User/Index/Home/250822?sid=W6Wg8iH9gY7wIBNSEdtFcQ3KbI5YiKDo'><span
|
||||||
|
class='Nick-Gold'> 航海百曉生 </span></a><img src='http://gree.pccsh.com/res/badge/9001.gif' alt='vip'
|
||||||
|
class='vip' /> <span class='icon-cry'><i class='icon-crystal liangHao'></i></span><img
|
||||||
|
src='http://gree.pccsh.com/res/badge/9001.gif' alt='心愿星河' class='badge' /> </span>
|
||||||
|
:
|
||||||
|
<span class=''>出身上天魔套15,复仇8,白副手10块,白四象5块,4级审判20,一套5级房子材料20</span>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
[公共]
|
||||||
|
<span><a class='a-nodec'
|
||||||
|
href='/User/Index/Home/14637160?sid=W6Wg8iH9gY7wIBNSEdtFcQ3KbI5YiKDo'>长剑小苍穹失散多年的亲爹</a></span>
|
||||||
|
:
|
||||||
|
<span class=''><img src='http://r.kexunkeji.cn/em/unit/1.png' alt='嘟嘴' class='em' /></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="content">
|
||||||
|
您看到:
|
||||||
|
<a class="" href="/Map/Index/MapUser/16_27?sid=W6Wg8iH9gY7wIBNSEdtFcQ3KbI5YiKDo">
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="content">
|
||||||
|
<div class="item"><a href='/Task/Npc/Index?npc=1101006&sid=W6Wg8iH9gY7wIBNSEdtFcQ3KbI5YiKDo'>巴萨尼奥</a></div>
|
||||||
|
<div class="item"><a href='/Map/Npc/Index?npc=1101016&sid=W6Wg8iH9gY7wIBNSEdtFcQ3KbI5YiKDo'>海精灵(福利)</a></div>
|
||||||
|
<div class="item"><a href='/Map/Npc/Index?npc=1101061&sid=W6Wg8iH9gY7wIBNSEdtFcQ3KbI5YiKDo'>战场指挥官(攻城)</a></div>
|
||||||
|
<div class="item"><a href='/Map/Npc/Index?npc=1101064&sid=W6Wg8iH9gY7wIBNSEdtFcQ3KbI5YiKDo'>欧若拉(主神)</a></div>
|
||||||
|
</div>
|
||||||
|
<div class="content">
|
||||||
|
</div>
|
||||||
|
<div class="content">
|
||||||
|
</div>
|
||||||
|
<div class="content">请选择出口:<br />东:<a
|
||||||
|
href='/Map/17_27?sid=W6Wg8iH9gY7wIBNSEdtFcQ3KbI5YiKDo&_r=YA9mrXPxwRpy'>市场</a> 西:<a
|
||||||
|
href='/Map/15_27?sid=W6Wg8iH9gY7wIBNSEdtFcQ3KbI5YiKDo&_r=YA9mrXPxwRpy'>教堂</a> <br />南:<a
|
||||||
|
href='/Map/16_28?sid=W6Wg8iH9gY7wIBNSEdtFcQ3KbI5YiKDo&_r=YA9mrXPxwRpy'>银行</a> 北:<a
|
||||||
|
href='/Map/16_26?sid=W6Wg8iH9gY7wIBNSEdtFcQ3KbI5YiKDo&_r=YA9mrXPxwRpy'>珠宝店</a> </div>
|
||||||
|
<div class="content">
|
||||||
|
【<a class="" href="/Map/Index/MapCity/16_27?sid=W6Wg8iH9gY7wIBNSEdtFcQ3KbI5YiKDo">城内地图</a>】.<a class=""
|
||||||
|
href="/Business/Help/Index?sid=W6Wg8iH9gY7wIBNSEdtFcQ3KbI5YiKDo">帮助</a>.<a class=""
|
||||||
|
href="/Privilege/Purdiam/MapTo?sid=W6Wg8iH9gY7wIBNSEdtFcQ3KbI5YiKDo">传送</a><br />
|
||||||
|
<div style="font-size:16px;line-height:16px;">
|
||||||
|
➢当前坐标:X-16 Y-27
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="content">
|
||||||
|
每逢节假日,来找海精灵,有惊喜~
|
||||||
|
</div>
|
||||||
|
<div class="content">
|
||||||
|
<div class="common">
|
||||||
|
<a class="" href="/User/Index/Index?sid=W6Wg8iH9gY7wIBNSEdtFcQ3KbI5YiKDo">状态</a>. <a class=""
|
||||||
|
href="/Bag/Index/Index?sid=W6Wg8iH9gY7wIBNSEdtFcQ3KbI5YiKDo">物品</a>. <a class=""
|
||||||
|
href="/Chat/Index/Index?sid=W6Wg8iH9gY7wIBNSEdtFcQ3KbI5YiKDo">聊天</a>
|
||||||
|
</div>
|
||||||
|
<div class="common">
|
||||||
|
<a class="" href="/Friend/Index/Index?sid=W6Wg8iH9gY7wIBNSEdtFcQ3KbI5YiKDo">好友</a>. <a class=""
|
||||||
|
href="/Pet/Index/Index?sid=W6Wg8iH9gY7wIBNSEdtFcQ3KbI5YiKDo">宠物</a>. <a class=""
|
||||||
|
href="/Team/Index/Index?sid=W6Wg8iH9gY7wIBNSEdtFcQ3KbI5YiKDo">队伍</a>
|
||||||
|
</div>
|
||||||
|
<div class="common">
|
||||||
|
<a class="" href="/Mall/Index/Index?sid=W6Wg8iH9gY7wIBNSEdtFcQ3KbI5YiKDo">商城</a>. <a class=""
|
||||||
|
href="/Bus/Proffer/Index?sid=W6Wg8iH9gY7wIBNSEdtFcQ3KbI5YiKDo">神殿</a>. <a class=""
|
||||||
|
href="/Business/Market/Act?sid=W6Wg8iH9gY7wIBNSEdtFcQ3KbI5YiKDo">活动</a>
|
||||||
|
</div>
|
||||||
|
<div class="common">
|
||||||
|
<a class="" href="/Act/Kill/Index?sid=W6Wg8iH9gY7wIBNSEdtFcQ3KbI5YiKDo">天榜</a>. <a class=""
|
||||||
|
href="/Act/Sky/Index?sid=W6Wg8iH9gY7wIBNSEdtFcQ3KbI5YiKDo">赛事</a>. <a class=""
|
||||||
|
href="/Rank/Index/Index?sid=W6Wg8iH9gY7wIBNSEdtFcQ3KbI5YiKDo">排行</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
definePageMeta({
|
||||||
|
layout: layout.default,
|
||||||
|
middleware: 'page-loading'
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
try {
|
||||||
|
await BindData();
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
PageLoading.Close();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
/**加载方法 */
|
||||||
|
const BindData = async (): Promise<void> => {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/**刷新 */
|
||||||
|
const Refresh = async (): Promise<void> => {
|
||||||
|
MessageExtend.LoadingToast("刷新中...");
|
||||||
|
await BindData();
|
||||||
|
window.setTimeout(() => {
|
||||||
|
MessageExtend.LoadingClose();
|
||||||
|
MessageExtend.Notify("刷新成功!", "success");
|
||||||
|
}, 1000)
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
Reference in New Issue
Block a user