mirror of
https://gitee.com/beijing_hongye_huicheng/lilishop-ui.git
synced 2026-11-10 02:49:03 +08:00
refactor: 四端完成 Options API → script setup + vuex → pinia 迁移
- buyer(95) / seller(169) / im(53) / manager(280) 共 597 个组件全部从 Options API 转换为 <script setup> - 四端 vuex 全部移除,状态管理统一迁移至 pinia 4(stores/ 目录) - util.js 等基础设施去除 vm 首参依赖;全局属性($Message/$filters 等)在 script 内改为具名导入 - 被外部 ref 访问的公共组件均已补齐 defineExpose(清单见各端 MIGRATION-VUE3.md) - 各端 eslint 启用 vue/component-api-style 防止新代码回退 Options API - 四端 yarn build 全部通过;迁移约定与注意事项已更新至各端 MIGRATION-VUE3.md
This commit is contained in:
23
im/src/stores/app.js
Normal file
23
im/src/stores/app.js
Normal file
@@ -0,0 +1,23 @@
|
||||
import { defineStore } from "pinia";
|
||||
import { defaultAvatar } from "@/assets/images";
|
||||
import { useUserStore } from "./user";
|
||||
|
||||
// 原 vuex 根级别 state/mutation/getter
|
||||
export const useAppStore = defineStore("app", {
|
||||
state: () => ({
|
||||
socketStatus: false,
|
||||
website_name: process.env.VUE_APP_WEBSITE_NAME,
|
||||
// 头像加载失败后的默认头像
|
||||
defaultAvatar: "this.src='" + defaultAvatar + "'",
|
||||
}),
|
||||
getters: {
|
||||
// 用户登录状态(跨模块读取 user store)
|
||||
loginStatus: () => useUserStore().loginStatus,
|
||||
},
|
||||
actions: {
|
||||
// 更新socket 连接状态
|
||||
UPDATE_SOCKET_STATUS(status) {
|
||||
this.socketStatus = status;
|
||||
},
|
||||
},
|
||||
});
|
||||
94
im/src/stores/dialogue.js
Normal file
94
im/src/stores/dialogue.js
Normal file
@@ -0,0 +1,94 @@
|
||||
import { defineStore } from "pinia";
|
||||
|
||||
// 原 vuex dialogue 模块
|
||||
export const useDialogueStore = defineStore("dialogue", {
|
||||
state: () => ({
|
||||
// 对话来源[1:私聊;2:群聊]
|
||||
talk_type: 0,
|
||||
|
||||
// 接收者ID
|
||||
receiver_id: 0,
|
||||
|
||||
is_robot: 0,
|
||||
|
||||
// 聊天记录
|
||||
records: [
|
||||
{
|
||||
id: "",
|
||||
createTime: "",
|
||||
toUser: "",
|
||||
isRead: false,
|
||||
messageType: "",
|
||||
talkId: "",
|
||||
text: "",
|
||||
float: "",
|
||||
},
|
||||
],
|
||||
webSocketWithOut: false, // ws 是否是掉线 无输出状态
|
||||
// 对话索引(聊天对话的唯一索引)
|
||||
index_name: null,
|
||||
}),
|
||||
actions: {
|
||||
// 设置ws状态
|
||||
SET_WS_STATUS(resource) {
|
||||
this.webSocketWithOut = resource;
|
||||
},
|
||||
|
||||
// 更新对话
|
||||
UPDATE_DIALOGUE_MESSAGE(resource) {
|
||||
this.records = [];
|
||||
this.talk_type = parseInt(resource.talk_type);
|
||||
this.receiver_id = parseInt(resource.receiver_id);
|
||||
this.is_robot = parseInt(resource.is_robot);
|
||||
|
||||
/**
|
||||
* receiver_id 就是 好友id
|
||||
* 比如 a 和 b 聊天 receiver_id = b的id
|
||||
*/
|
||||
this.index_name = (resource.talk_type || 1) + "_" + resource.receiver_id;
|
||||
},
|
||||
|
||||
// 数组头部压入对话记录
|
||||
UNSHIFT_DIALOGUE(records) {
|
||||
if (this.records.length > 0) {
|
||||
this.records.unshift(...records);
|
||||
} else {
|
||||
this.records.push(...records);
|
||||
}
|
||||
},
|
||||
|
||||
// 推送对话记录
|
||||
PUSH_DIALOGUE(record) {
|
||||
record = { ...record, webSocketStatus: this.webSocketWithOut };
|
||||
console.log("推送对话");
|
||||
this.records.push(record);
|
||||
},
|
||||
|
||||
// 更新对话记录
|
||||
UPDATE_DIALOGUE(resource) {
|
||||
for (let i in this.records) {
|
||||
if (this.records[i].id === resource.id) {
|
||||
Object.assign(this.records[i], resource);
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// 删除对话记录
|
||||
DELETE_DIALOGUE(index) {
|
||||
this.records.splice(index, 1);
|
||||
},
|
||||
|
||||
BATCH_DELETE_DIALOGUE(ids) {
|
||||
ids.forEach((record_id) => {
|
||||
let index = this.records.findIndex((item) => item.id == record_id);
|
||||
if (index >= 0) this.records.splice(index, 1);
|
||||
});
|
||||
},
|
||||
|
||||
// 数组头部压入对话记录
|
||||
SET_DIALOGUE(records) {
|
||||
this.records = records;
|
||||
},
|
||||
},
|
||||
});
|
||||
91
im/src/stores/emoticon.js
Normal file
91
im/src/stores/emoticon.js
Normal file
@@ -0,0 +1,91 @@
|
||||
import { defineStore } from "pinia";
|
||||
import { ServeFindUserEmoticon, ServeUploadEmoticon } from "@/api/emoticon";
|
||||
import { ServeCollectEmoticon } from "@/api/chat";
|
||||
import { ElNotification } from "element-plus";
|
||||
|
||||
// 原 vuex emoticon 模块
|
||||
export const useEmoticonStore = defineStore("emoticon", {
|
||||
state: () => ({
|
||||
items: [],
|
||||
}),
|
||||
actions: {
|
||||
// 加载用户表情包
|
||||
LOAD_USER_EMOTICON() {
|
||||
// TODO 隐藏
|
||||
return;
|
||||
// eslint-disable-next-line no-unreachable
|
||||
ServeFindUserEmoticon().then((res) => {
|
||||
if (res.code == 200) {
|
||||
const { collect_emoticon, sys_emoticon } = res.data;
|
||||
|
||||
this.items = this.items.slice(0, 2);
|
||||
|
||||
// 用户收藏的系统表情包
|
||||
this.items[1].list = collect_emoticon;
|
||||
|
||||
// 用户添加的系统表情包
|
||||
this.items.push(...sys_emoticon);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// 收藏用户表情包
|
||||
SAVE_USER_EMOTICON(resoure) {
|
||||
ServeCollectEmoticon({
|
||||
record_id: resoure.record_id,
|
||||
})
|
||||
.then((res) => {
|
||||
if (res.code == 200) {
|
||||
ElNotification({
|
||||
title: "收藏提示",
|
||||
message: "表情包收藏成功...",
|
||||
type: "success",
|
||||
});
|
||||
|
||||
this.LOAD_USER_EMOTICON();
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
ElNotification({
|
||||
title: "收藏提示",
|
||||
message: "表情包收藏失败...",
|
||||
type: "warning",
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
// 自定义上传用户表情包
|
||||
UPLOAD_USER_EMOTICON(resoure) {
|
||||
let fileData = new FormData();
|
||||
fileData.append("emoticon", resoure.file);
|
||||
ServeUploadEmoticon(fileData)
|
||||
.then((res) => {
|
||||
if (res.code == 200) {
|
||||
this.items[1].list.push(res.data);
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
ElNotification({
|
||||
message: "网络异常请稍后再试...",
|
||||
type: "error",
|
||||
duration: 3000,
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
// 添加系统表情包
|
||||
APPEND_SYS_EMOTICON(resoure) {
|
||||
this.items.push(resoure);
|
||||
},
|
||||
|
||||
// 移除系统表情包
|
||||
REMOVE_SYS_EMOTICON(resoure) {
|
||||
for (let i in this.items) {
|
||||
if (this.items[i].emoticon_id === resoure.emoticon_id) {
|
||||
this.items.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
18
im/src/stores/note.js
Normal file
18
im/src/stores/note.js
Normal file
@@ -0,0 +1,18 @@
|
||||
import { defineStore } from "pinia";
|
||||
|
||||
// 原 vuex note 模块
|
||||
export const useNoteStore = defineStore("note", {
|
||||
state: () => ({
|
||||
tags: [],
|
||||
class: [],
|
||||
}),
|
||||
actions: {
|
||||
SET_NOTE_TAGS(tags) {
|
||||
this.tags = tags;
|
||||
},
|
||||
|
||||
PUSH_NOTE_TAG(tag) {
|
||||
this.tags.unshift(tag);
|
||||
},
|
||||
},
|
||||
});
|
||||
65
im/src/stores/notify.js
Normal file
65
im/src/stores/notify.js
Normal file
@@ -0,0 +1,65 @@
|
||||
import { defineStore } from "pinia";
|
||||
|
||||
// 原 vuex notify 模块
|
||||
export const useNotifyStore = defineStore("notify", {
|
||||
state: () => ({
|
||||
// 聊天消息未读数
|
||||
unreadNum: 0,
|
||||
|
||||
// 好友申请未读数
|
||||
applyNum: 0,
|
||||
|
||||
// 好友键盘事件监听
|
||||
inputEvent: 0,
|
||||
|
||||
// 好友登录状态监听
|
||||
friendStatus: {
|
||||
// 登录状态[0:下线;1:在线;]
|
||||
status: 0,
|
||||
// 好友ID
|
||||
friend_id: 0,
|
||||
},
|
||||
}),
|
||||
actions: {
|
||||
// 消息未读数自增
|
||||
INCR_UNREAD_NUM() {
|
||||
console.log("触发消息未读");
|
||||
this.unreadNum++;
|
||||
},
|
||||
|
||||
// 好友申请事件监听
|
||||
INCR_APPLY_NUM() {
|
||||
this.applyNum++;
|
||||
},
|
||||
|
||||
// 设置消息未读数
|
||||
SET_UNREAD_NUM(value) {
|
||||
this.unreadNum = value;
|
||||
},
|
||||
|
||||
// 好友申请事件监听
|
||||
SET_APPLY_NUM(value) {
|
||||
this.applyNum = value;
|
||||
},
|
||||
|
||||
// 自增好友键盘输入事件
|
||||
UPDATE_KEYBOARD_EVENT() {
|
||||
this.inputEvent++;
|
||||
},
|
||||
|
||||
// 更新好友登录状态
|
||||
UPDATE_FRIEND_STATUS(value) {
|
||||
this.friendStatus = value;
|
||||
},
|
||||
|
||||
// 原 vuex action ACT_UPDATE_FRIEND_STATUS
|
||||
ACT_UPDATE_FRIEND_STATUS(value) {
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(() => {
|
||||
this.UPDATE_FRIEND_STATUS(value);
|
||||
resolve();
|
||||
}, 0);
|
||||
});
|
||||
},
|
||||
},
|
||||
});
|
||||
68
im/src/stores/settings.js
Normal file
68
im/src/stores/settings.js
Normal file
@@ -0,0 +1,68 @@
|
||||
import { defineStore } from "pinia";
|
||||
import {
|
||||
getToken,
|
||||
getUserSettingCache,
|
||||
setUserSettingCache,
|
||||
} from "@/utils/auth";
|
||||
|
||||
// 模块加载时合并本地缓存的设置(与原 vuex settings 模块行为一致)
|
||||
function initState() {
|
||||
const state = {
|
||||
// 主题模式 true:全屏模式 false:居中模式
|
||||
themeMode: true,
|
||||
|
||||
// 主题模式为居中模式下,body 的背景图片
|
||||
themeBagImg: "bag003",
|
||||
|
||||
// 主题颜色
|
||||
themeColor: "",
|
||||
|
||||
// 消息提示音
|
||||
notifyCueTone: true,
|
||||
|
||||
// 键盘输入事件消息推送开关
|
||||
keyboardEventNotify: true,
|
||||
};
|
||||
if (getToken()) {
|
||||
Object.assign(state, getUserSettingCache());
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户相关设置
|
||||
*/
|
||||
export const useSettingsStore = defineStore("settings", {
|
||||
state: initState,
|
||||
actions: {
|
||||
// 设置主题模式
|
||||
SET_THEME_MODE(mode) {
|
||||
this.themeMode = mode;
|
||||
setUserSettingCache(this.$state);
|
||||
},
|
||||
|
||||
// 设置主题的背景图片
|
||||
SET_THEME_BAGIMG(bagName) {
|
||||
this.themeBagImg = bagName;
|
||||
setUserSettingCache(this.$state);
|
||||
},
|
||||
|
||||
// 主题颜色
|
||||
SET_THEME_COLOR(color) {
|
||||
this.themeColor = color;
|
||||
setUserSettingCache(this.$state);
|
||||
},
|
||||
|
||||
// 设置消息提示音状态
|
||||
SET_NOTIFY_CUE_TONE(isTrue) {
|
||||
this.notifyCueTone = isTrue;
|
||||
setUserSettingCache(this.$state);
|
||||
},
|
||||
|
||||
// 设置键盘输入事件消息推送状态
|
||||
SET_KEYBOARD_EVENT_NOTIFY(isTrue) {
|
||||
this.keyboardEventNotify = isTrue;
|
||||
setUserSettingCache(this.$state);
|
||||
},
|
||||
},
|
||||
});
|
||||
111
im/src/stores/talk.js
Normal file
111
im/src/stores/talk.js
Normal file
@@ -0,0 +1,111 @@
|
||||
import { defineStore } from "pinia";
|
||||
import { getSort, getMutipSort } from "@/utils/functions";
|
||||
|
||||
// 原 vuex talks 模块
|
||||
export const useTalkStore = defineStore("talks", {
|
||||
state: () => ({
|
||||
// 用户对话列表
|
||||
items: [],
|
||||
|
||||
// 最后一条消息
|
||||
unreadMessage: {
|
||||
num: 0,
|
||||
nickname: "未知",
|
||||
content: "...",
|
||||
},
|
||||
|
||||
// 对话列表重载状态
|
||||
heavyLoad: false,
|
||||
}),
|
||||
getters: {
|
||||
// 过滤所有置顶对话列表
|
||||
topItems: (state) => {
|
||||
return state.items.filter((item) => item.is_top == 1);
|
||||
},
|
||||
// 原 vuex getter,注意:sort 会原地修改 items 数组(历史行为,原样保留)
|
||||
talkItems: (state) => {
|
||||
return state.items.sort(
|
||||
getMutipSort([getSort((a, b) => a.lastTalkTime > b.lastTalkTime)])
|
||||
);
|
||||
},
|
||||
// 消息未读数总计
|
||||
unreadNum: (state) => {
|
||||
return state.items.reduce((total, item) => {
|
||||
return total + parseInt(item.unread);
|
||||
}, 0);
|
||||
},
|
||||
talkNum: (state) => state.items.length,
|
||||
},
|
||||
actions: {
|
||||
// 设置对话列表
|
||||
SET_TALK_ITEMS(resource) {
|
||||
this.items = resource.items;
|
||||
},
|
||||
|
||||
// 更新对话节点
|
||||
UPDATE_TALK_ITEM(resource) {
|
||||
let index = this.items.findIndex(
|
||||
(item) => item.userId === resource.index_name.split("_")[1]
|
||||
);
|
||||
if (index >= 0) {
|
||||
Object.assign(this.items[index], resource);
|
||||
}
|
||||
},
|
||||
|
||||
// 新增对话节点
|
||||
PUSH_TALK_ITEM(resource) {
|
||||
this.items.push(resource);
|
||||
},
|
||||
|
||||
// 移除对话节点
|
||||
REMOVE_TALK_ITEM(index_name) {
|
||||
for (let i in this.items) {
|
||||
if (this.items[i].index_name === index_name) {
|
||||
this.items.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// 更新对话消息
|
||||
UPDATE_TALK_MESSAGE(resource) {
|
||||
let enableGetTalkList = true;
|
||||
this.items.forEach((item) => {
|
||||
if (item.userId == resource.index_name.split("_")[1]) {
|
||||
item.unread++;
|
||||
item.msg_text = resource.msg_text;
|
||||
item.lastTalkTime = resource.updated_at;
|
||||
item.lastTalkMessage = resource.msg_text;
|
||||
item.updated_at = resource.updated_at;
|
||||
enableGetTalkList = false;
|
||||
}
|
||||
});
|
||||
// 循环如果当前用户不在对话记录列表中 就重新请求对话列表接口
|
||||
// 原代码此处为 this.commit('getTalkList'),目标 action 早已被原作者注释删除,
|
||||
// vuex 对未知 mutation 仅告警不中断,此处保留为空操作
|
||||
if (enableGetTalkList) {
|
||||
/* noop */
|
||||
}
|
||||
},
|
||||
|
||||
// 触发对话列表重新加载
|
||||
TRIGGER_TALK_ITEMS_LOAD(status = false) {
|
||||
this.heavyLoad = status;
|
||||
},
|
||||
|
||||
SET_TLAK_UNREAD_MESSAGE(resource) {
|
||||
this.unreadMessage.num++;
|
||||
this.unreadMessage.nickname = resource.nickname;
|
||||
this.unreadMessage.content = resource.content;
|
||||
},
|
||||
|
||||
// 清除最后一条未读消息
|
||||
CLEAR_TLAK_UNREAD_MESSAGE() {
|
||||
this.unreadMessage = {
|
||||
num: 0,
|
||||
nickname: "未知",
|
||||
content: "...",
|
||||
};
|
||||
},
|
||||
},
|
||||
});
|
||||
68
im/src/stores/user.js
Normal file
68
im/src/stores/user.js
Normal file
@@ -0,0 +1,68 @@
|
||||
import { defineStore } from "pinia";
|
||||
import { setUserInfo, getUserInfo, getToken } from "@/utils/auth";
|
||||
import { defaultAvatar, defaultUserBanner } from "@/assets/images";
|
||||
|
||||
// 判断用户是否登录(模块加载时初始化,与原 vuex user 模块行为一致)
|
||||
function initState() {
|
||||
const state = {
|
||||
// 用户ID
|
||||
id: 0,
|
||||
// 用户昵称
|
||||
name: "",
|
||||
// 个性头像
|
||||
face: defaultAvatar,
|
||||
// 名片背景
|
||||
visitCardBag: defaultUserBanner,
|
||||
// 当前登录状态
|
||||
loginStatus: false,
|
||||
toUser: "",
|
||||
};
|
||||
if (getToken()) {
|
||||
let userInfo = getUserInfo();
|
||||
state.name = userInfo.name;
|
||||
state.id = userInfo.id;
|
||||
// 原代码如此:state.avatar 并不存在(恒为 undefined)
|
||||
state.face = userInfo.face ? userInfo.face : state.avatar;
|
||||
state.loginStatus = true;
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
export const useUserStore = defineStore("user", {
|
||||
state: initState,
|
||||
actions: {
|
||||
// 用户退出登录
|
||||
USER_LOGOUT() {
|
||||
this.id = 0;
|
||||
this.face = "";
|
||||
this.name = "";
|
||||
this.loginStatus = false;
|
||||
},
|
||||
|
||||
// 设置用户登录状态
|
||||
UPDATE_LOGIN_STATUS() {
|
||||
this.loginStatus = true;
|
||||
},
|
||||
|
||||
// 更新用户信息
|
||||
UPDATE_USER_INFO(data) {
|
||||
for (const key in data) {
|
||||
if (Object.prototype.hasOwnProperty.call(this.$state, key)) {
|
||||
this[key] = data[key];
|
||||
}
|
||||
}
|
||||
|
||||
// 保存用户信息到缓存
|
||||
setUserInfo({
|
||||
id: this.id,
|
||||
face: this.face,
|
||||
name: this.name,
|
||||
});
|
||||
},
|
||||
|
||||
// 退出登录处理操作(原 vuex action ACT_USER_LOGOUT)
|
||||
ACT_USER_LOGOUT() {
|
||||
this.USER_LOGOUT();
|
||||
},
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user