a
This commit is contained in:
131
src/stores/agentStore.js
Normal file
131
src/stores/agentStore.js
Normal file
@@ -0,0 +1,131 @@
|
||||
import { defineStore } from "pinia";
|
||||
import { getAgentInfo } from "@/api/agent";
|
||||
|
||||
export const useAgentStore = defineStore("agent", {
|
||||
state: () => ({
|
||||
isLoaded: false,
|
||||
level: 0, // 1=普通,2=黄金,3=钻石
|
||||
levelName: "", // 等级名称
|
||||
isAgent: false,
|
||||
agentID: null,
|
||||
agentCode: 0,
|
||||
mobile: "",
|
||||
region: "",
|
||||
wechatId: "",
|
||||
teamLeaderId: null,
|
||||
isRealName: false,
|
||||
}),
|
||||
getters: {
|
||||
// 是否是代理
|
||||
isAgentUser: (state) => state.isAgent && state.agentID !== null,
|
||||
// 是否是钻石代理
|
||||
isDiamond: (state) => state.level === 3,
|
||||
// 是否是黄金代理
|
||||
isGold: (state) => state.level === 2,
|
||||
// 是否是普通代理
|
||||
isNormal: (state) => state.level === 1,
|
||||
// 获取等级显示名称
|
||||
levelDisplayName: (state) => {
|
||||
const levelMap = {
|
||||
1: "普通代理",
|
||||
2: "黄金代理",
|
||||
3: "钻石代理",
|
||||
};
|
||||
return levelMap[state.level] || "普通代理";
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
async fetchAgentStatus() {
|
||||
const { data, error } = await getAgentInfo();
|
||||
|
||||
if (data.value && !error.value) {
|
||||
if (data.value.code === 200) {
|
||||
const agentData = data.value.data;
|
||||
// 如果 agent_id 为空字符串或不存在,说明不是代理
|
||||
if (!agentData.agent_id || agentData.agent_id === "") {
|
||||
this.resetAgent();
|
||||
} else {
|
||||
this.level = agentData.level || 0;
|
||||
this.levelName = agentData.level_name || "";
|
||||
this.isAgent = true; // 如果能获取到信息,说明是代理
|
||||
this.agentID = agentData.agent_id;
|
||||
this.agentCode = agentData.agent_code || 0;
|
||||
this.mobile = agentData.mobile || "";
|
||||
this.region = agentData.region || "";
|
||||
this.wechatId = agentData.wechat_id || "";
|
||||
this.teamLeaderId = agentData.team_leader_id || null;
|
||||
this.isRealName = agentData.is_real_name || false;
|
||||
|
||||
// 保存到localStorage
|
||||
localStorage.setItem(
|
||||
"agentInfo",
|
||||
JSON.stringify({
|
||||
isAgent: this.isAgent,
|
||||
level: this.level,
|
||||
levelName: this.levelName,
|
||||
agentID: this.agentID,
|
||||
agentCode: this.agentCode,
|
||||
mobile: this.mobile,
|
||||
region: this.region,
|
||||
wechatId: this.wechatId,
|
||||
teamLeaderId: this.teamLeaderId,
|
||||
isRealName: this.isRealName,
|
||||
})
|
||||
);
|
||||
}
|
||||
} else {
|
||||
// 检查是否是临时用户需要绑定手机号的错误(100010)
|
||||
if (data.value.code === 100010) {
|
||||
// 临时用户,不重置状态,静默处理
|
||||
console.log("临时用户需要绑定手机号,跳过代理状态检查");
|
||||
} else {
|
||||
// 如果不是代理或获取失败,重置状态
|
||||
this.resetAgent();
|
||||
console.log("Error fetching agent info", data.value);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 检查错误码
|
||||
if (error.value && error.value.code === 100010) {
|
||||
// 临时用户需要绑定手机号,静默处理
|
||||
console.log("临时用户需要绑定手机号,跳过代理状态检查");
|
||||
} else {
|
||||
// 请求失败或未登录,重置状态
|
||||
this.resetAgent();
|
||||
}
|
||||
}
|
||||
this.isLoaded = true;
|
||||
},
|
||||
|
||||
// 更新代理信息
|
||||
updateAgentInfo(agentInfo) {
|
||||
if (agentInfo) {
|
||||
this.isAgent = agentInfo.isAgent || false;
|
||||
this.level = agentInfo.level || 0;
|
||||
this.levelName = agentInfo.levelName || "";
|
||||
this.agentID = agentInfo.agentID || null;
|
||||
this.mobile = agentInfo.mobile || "";
|
||||
this.region = agentInfo.region || "";
|
||||
this.wechatId = agentInfo.wechatId || "";
|
||||
this.teamLeaderId = agentInfo.teamLeaderId || null;
|
||||
this.isRealName = agentInfo.isRealName || false;
|
||||
this.isLoaded = true;
|
||||
}
|
||||
},
|
||||
|
||||
// 重置代理信息
|
||||
resetAgent() {
|
||||
this.isLoaded = false;
|
||||
this.level = 0;
|
||||
this.levelName = "";
|
||||
this.isAgent = false;
|
||||
this.agentID = null;
|
||||
this.agentCode = 0;
|
||||
this.mobile = "";
|
||||
this.region = "";
|
||||
this.wechatId = "";
|
||||
this.teamLeaderId = null;
|
||||
this.isRealName = false;
|
||||
},
|
||||
},
|
||||
});
|
||||
21
src/stores/appStore.js
Normal file
21
src/stores/appStore.js
Normal file
@@ -0,0 +1,21 @@
|
||||
import { defineStore } from 'pinia'
|
||||
|
||||
export const useAppStore = defineStore('app', {
|
||||
state: () => ({
|
||||
queryRetentionDays: 0,
|
||||
isLoaded: false,
|
||||
}),
|
||||
actions: {
|
||||
async fetchAppConfig() {
|
||||
try {
|
||||
const { data, error } = await useApiFetch('/app/config').get().json()
|
||||
if (data.value && !error.value && data.value.code === 200) {
|
||||
const cfg = data.value.data
|
||||
this.queryRetentionDays = Number(cfg.query_retention_days) || 0
|
||||
}
|
||||
} catch (e) {
|
||||
}
|
||||
this.isLoaded = true
|
||||
},
|
||||
},
|
||||
})
|
||||
129
src/stores/authStore.js
Normal file
129
src/stores/authStore.js
Normal file
@@ -0,0 +1,129 @@
|
||||
import { defineStore } from "pinia";
|
||||
|
||||
export const useAuthStore = defineStore("auth", {
|
||||
state: () => ({
|
||||
// 微信授权状态
|
||||
isWeixinAuthing: false, // 是否正在进行微信授权
|
||||
weixinAuthComplete: false, // 微信授权是否完成
|
||||
pendingRoute: null, // 等待授权完成后跳转的路由
|
||||
authStartTime: 0, // 授权开始时间,用于防止超时重复授权
|
||||
}),
|
||||
|
||||
actions: {
|
||||
// 开始微信授权
|
||||
startWeixinAuth(targetRoute = null) {
|
||||
// 如果已经在授权过程中,不再重复启动
|
||||
if (this.isWeixinAuthing) {
|
||||
console.warn("WeChat auth already in progress");
|
||||
return;
|
||||
}
|
||||
|
||||
this.isWeixinAuthing = true;
|
||||
this.weixinAuthComplete = false;
|
||||
this.pendingRoute = targetRoute;
|
||||
this.authStartTime = Date.now();
|
||||
|
||||
// 保存到localStorage,防止页面刷新后状态丢失
|
||||
localStorage.setItem("weixinAuthing", "true");
|
||||
localStorage.setItem(
|
||||
"authStartTime",
|
||||
this.authStartTime.toString()
|
||||
);
|
||||
|
||||
if (targetRoute) {
|
||||
const routeData =
|
||||
typeof targetRoute === "string"
|
||||
? targetRoute
|
||||
: targetRoute.fullPath || targetRoute.path || "";
|
||||
if (routeData) {
|
||||
let sanitized = routeData;
|
||||
const parts = routeData.split("?");
|
||||
if (parts.length > 1) {
|
||||
const base = parts[0];
|
||||
const params = new URLSearchParams(parts[1]);
|
||||
params.delete("code");
|
||||
params.delete("state");
|
||||
const qs = params.toString();
|
||||
sanitized = qs ? `${base}?${qs}` : base;
|
||||
}
|
||||
localStorage.setItem(
|
||||
"pendingRoute",
|
||||
JSON.stringify(sanitized)
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// 微信授权完成
|
||||
completeWeixinAuth() {
|
||||
this.isWeixinAuthing = false;
|
||||
this.weixinAuthComplete = true;
|
||||
this.authStartTime = 0;
|
||||
|
||||
// 清除localStorage中的授权状态
|
||||
localStorage.removeItem("weixinAuthing");
|
||||
localStorage.removeItem("authStartTime");
|
||||
},
|
||||
|
||||
// 重置授权状态
|
||||
resetAuthState() {
|
||||
this.isWeixinAuthing = false;
|
||||
this.weixinAuthComplete = false;
|
||||
this.pendingRoute = null;
|
||||
this.authStartTime = 0;
|
||||
localStorage.removeItem("weixinAuthing");
|
||||
localStorage.removeItem("pendingRoute");
|
||||
localStorage.removeItem("authStartTime");
|
||||
},
|
||||
|
||||
// 检查授权是否超时(超过30秒视为超时)
|
||||
isAuthTimeout() {
|
||||
if (!this.authStartTime) return false;
|
||||
const elapsed = Date.now() - this.authStartTime;
|
||||
return elapsed > 30000; // 30秒超时
|
||||
},
|
||||
|
||||
// 从localStorage恢复状态(页面刷新后调用)
|
||||
restoreFromStorage() {
|
||||
const isAuthing = localStorage.getItem("weixinAuthing") === "true";
|
||||
const pendingRouteStr = localStorage.getItem("pendingRoute");
|
||||
const authStartTime = localStorage.getItem("authStartTime");
|
||||
|
||||
if (isAuthing) {
|
||||
console.log("🔄 Restoring WeChat auth state from storage");
|
||||
this.isWeixinAuthing = true;
|
||||
this.weixinAuthComplete = false;
|
||||
this.authStartTime = authStartTime
|
||||
? parseInt(authStartTime)
|
||||
: 0;
|
||||
|
||||
// 检查是否超时,如果超时则重置
|
||||
if (this.isAuthTimeout()) {
|
||||
console.warn("WeChat auth timeout, resetting state");
|
||||
this.resetAuthState();
|
||||
return;
|
||||
}
|
||||
|
||||
if (pendingRouteStr) {
|
||||
try {
|
||||
this.pendingRoute = JSON.parse(pendingRouteStr);
|
||||
console.log(
|
||||
"✅ Restored pendingRoute from storage:",
|
||||
this.pendingRoute
|
||||
);
|
||||
} catch (e) {
|
||||
console.error("Failed to parse pending route:", e);
|
||||
this.pendingRoute = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// 清除待处理路由时,确保同步清除内存和localStorage
|
||||
clearPendingRoute() {
|
||||
this.pendingRoute = null;
|
||||
localStorage.removeItem("pendingRoute");
|
||||
console.log("✅ Cleared pendingRoute from both memory and storage");
|
||||
},
|
||||
},
|
||||
});
|
||||
44
src/stores/dialogStore.js
Normal file
44
src/stores/dialogStore.js
Normal file
@@ -0,0 +1,44 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import { ref } from 'vue'
|
||||
|
||||
export const useDialogStore = defineStore('dialog', () => {
|
||||
const showBindPhone = ref(false) // 推广页面专用的绑定手机号(不要求邀请码)
|
||||
const showRegisterAgent = ref(false) // 注册成为代理(带邀请码)
|
||||
const showRealNameAuth = ref(false)
|
||||
|
||||
function openBindPhone() {
|
||||
showBindPhone.value = true
|
||||
}
|
||||
|
||||
function closeBindPhone() {
|
||||
showBindPhone.value = false
|
||||
}
|
||||
|
||||
function openRegisterAgent() {
|
||||
showRegisterAgent.value = true
|
||||
}
|
||||
|
||||
function closeRegisterAgent() {
|
||||
showRegisterAgent.value = false
|
||||
}
|
||||
|
||||
function openRealNameAuth() {
|
||||
showRealNameAuth.value = true
|
||||
}
|
||||
|
||||
function closeRealNameAuth() {
|
||||
showRealNameAuth.value = false
|
||||
}
|
||||
|
||||
return {
|
||||
showBindPhone,
|
||||
openBindPhone,
|
||||
closeBindPhone,
|
||||
showRegisterAgent,
|
||||
openRegisterAgent,
|
||||
closeRegisterAgent,
|
||||
showRealNameAuth,
|
||||
openRealNameAuth,
|
||||
closeRealNameAuth,
|
||||
}
|
||||
})
|
||||
76
src/stores/userStore.js
Normal file
76
src/stores/userStore.js
Normal file
@@ -0,0 +1,76 @@
|
||||
import { defineStore } from "pinia";
|
||||
|
||||
export const useUserStore = defineStore("user", {
|
||||
state: () => ({
|
||||
userName: "",
|
||||
mobile: "",
|
||||
userAvatar: "",
|
||||
isLoggedIn: false,
|
||||
}),
|
||||
actions: {
|
||||
async fetchUserInfo() {
|
||||
const { data, error } = await useApiFetch("/user/detail")
|
||||
.get()
|
||||
.json();
|
||||
if (data.value && !error.value) {
|
||||
if (data.value.code === 200) {
|
||||
const userinfo = data.value.data.userInfo;
|
||||
this.userName = userinfo.mobile || "";
|
||||
this.mobile = userinfo.mobile || "";
|
||||
this.userAvatar = userinfo.userAvatar;
|
||||
this.isLoggedIn = true;
|
||||
|
||||
// 保存到localStorage
|
||||
localStorage.setItem(
|
||||
"userInfo",
|
||||
JSON.stringify({
|
||||
nickName: this.userName,
|
||||
avatar: this.userAvatar,
|
||||
})
|
||||
);
|
||||
} else if (data.value.code === 100009) {
|
||||
// Token 无效或用户不存在,清除数据但不 reload
|
||||
// reload 会导致无限循环
|
||||
console.warn(
|
||||
"User not found or token invalid (100009), clearing auth data"
|
||||
);
|
||||
localStorage.removeItem("token");
|
||||
localStorage.removeItem("refreshAfter");
|
||||
localStorage.removeItem("accessExpire");
|
||||
localStorage.removeItem("userInfo");
|
||||
localStorage.removeItem("agentInfo");
|
||||
|
||||
this.resetUser();
|
||||
|
||||
// 不要 reload,让调用者处理错误
|
||||
throw new Error("User not found or token invalid");
|
||||
} else {
|
||||
// 其他错误
|
||||
console.error("Unexpected response code:", data.value.code);
|
||||
throw new Error(
|
||||
`Unexpected response code: ${data.value.code}`
|
||||
);
|
||||
}
|
||||
} else {
|
||||
console.error("API error:", error.value);
|
||||
throw error.value || new Error("Unknown error");
|
||||
}
|
||||
},
|
||||
|
||||
// 更新用户信息
|
||||
updateUserInfo(userInfo) {
|
||||
if (userInfo) {
|
||||
this.userName = userInfo.mobile || userInfo.nickName || "";
|
||||
this.userAvatar = userInfo.avatar || "";
|
||||
this.isLoggedIn = true;
|
||||
}
|
||||
},
|
||||
|
||||
// 重置用户信息
|
||||
resetUser() {
|
||||
this.userName = "";
|
||||
this.userAvatar = "";
|
||||
this.isLoggedIn = false;
|
||||
},
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user