user.ts 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. import { computed, ref } from "vue";
  2. import { forInObject, isNull, isObject, parse, storage } from "../utils";
  3. import { router } from "../router";
  4. import { request } from "../service";
  5. import type { UserInfo } from "../types";
  6. import { type LoginData, getUsersInfo } from "@/services/user";
  7. import { dict } from "./dict";
  8. export type Token = {
  9. token: string; // 访问token
  10. expire: number; // token过期时间(秒)
  11. refreshToken: string; // 刷新token
  12. refreshExpire: number; // 刷新token过期时间(秒)
  13. };
  14. export class User {
  15. /**
  16. * 用户信息,响应式对象
  17. */
  18. info = ref<UserInfo | null>(null);
  19. /**
  20. * 用户信息,响应式对象
  21. */
  22. courseId = ref<string | null>(null);
  23. /**
  24. * 当前token,字符串或null
  25. */
  26. token: string | 'Basic ZW5kOmVuZA==';
  27. constructor() {
  28. // 获取本地用户信息
  29. const userInfo = storage.get("userInfo");
  30. // 获取本地token
  31. const token = storage.get("token") as string | 'Basic ZW5kOmVuZA==';
  32. // 如果token为空字符串则置为null
  33. this.token = token == "" ? 'Basic ZW5kOmVuZA==' : token;
  34. if (this.token == 'Basic ZW5kOmVuZA==') {
  35. return;
  36. }
  37. // 初始化用户信息
  38. if (userInfo != null && isObject(userInfo)) {
  39. this.set(userInfo);
  40. } else {
  41. this.get()
  42. }
  43. }
  44. /**
  45. * 获取用户信息(从服务端拉取最新信息并更新本地)
  46. * @returns Promise<void>
  47. */
  48. async get() {
  49. try {
  50. const res = await getUsersInfo()
  51. if (res != null) {
  52. this.set(res);
  53. }
  54. } catch (err) {
  55. this.logout();
  56. }
  57. }
  58. /**
  59. * 设置用户信息并存储到本地
  60. * @param data 用户信息对象
  61. */
  62. set(data: any) {
  63. if (isNull(data)) {
  64. return;
  65. }
  66. // 设置
  67. this.info.value = parse<UserInfo>(data)!;
  68. // 持久化到本地存储
  69. storage.set("userInfo", data, 0);
  70. }
  71. setCourseId(id: string) {
  72. this.courseId.value = id
  73. }
  74. /**
  75. * 更新用户信息(本地与服务端同步)
  76. * @param data 新的用户信息
  77. */
  78. async update(data: any) {
  79. if (isNull(data) || isNull(this.info.value)) {
  80. return;
  81. }
  82. // 本地同步更新
  83. forInObject(data, (value, key) => {
  84. this.info.value![key] = value;
  85. });
  86. // 同步到服务端
  87. await request({
  88. url: "/app/user/info/updatePerson",
  89. method: "POST",
  90. data
  91. });
  92. }
  93. /**
  94. * 移除用户信息
  95. */
  96. remove() {
  97. this.info.value = null;
  98. storage.remove("userInfo");
  99. }
  100. /**
  101. * 判断用户信息是否为空
  102. * @returns boolean
  103. */
  104. isNull() {
  105. return this.info.value == null;
  106. }
  107. /**
  108. * 清除本地所有用户信息和token
  109. */
  110. clear() {
  111. storage.remove("userInfo");
  112. storage.remove("token");
  113. // storage.remove("refreshToken");
  114. this.token = 'Basic ZW5kOmVuZA==';
  115. this.remove();
  116. this.info.value = null;
  117. this.courseId.value = null;
  118. }
  119. /**
  120. * 退出登录,清除所有信息并跳转到登录页
  121. */
  122. logout() {
  123. this.clear();
  124. router.login();
  125. }
  126. /**
  127. * 设置token并存储到本地
  128. * @param data Token对象
  129. */
  130. setToken(data: LoginData) {
  131. this.token = `Bearer ${data?.access_token}`;
  132. // 访问token,提前5秒过期,防止边界问题
  133. storage.set("token", this.token, 7 * 24 * 60 * 60 - 5);
  134. this.get();
  135. dict.refresh();
  136. // 刷新token,提前5秒过期
  137. // storage.set("refreshToken", data.refresh_token, data.refreshExpire - 5);
  138. }
  139. // /**
  140. // * 刷新token(调用服务端接口,自动更新本地token)
  141. // * @returns Promise<string> 新的token
  142. // */
  143. // refreshToken(): Promise<string> {
  144. // return new Promise((resolve, reject) => {
  145. // request({
  146. // url: "/app/user/login/refreshToken",
  147. // method: "POST",
  148. // data: {
  149. // refreshToken: storage.get("refreshToken")
  150. // }
  151. // })
  152. // .then((res) => {
  153. // if (res != null) {
  154. // const token = parse<Token>(res);
  155. // if (token != null) {
  156. // this.setToken(token);
  157. // resolve(token.token);
  158. // }
  159. // }
  160. // })
  161. // .catch((err) => {
  162. // reject(err);
  163. // });
  164. // });
  165. // }
  166. }
  167. /**
  168. * 单例用户对象,项目全局唯一
  169. */
  170. export const user = new User();
  171. /**
  172. * 用户信息,响应式对象
  173. */
  174. export const userInfo = computed(() => user.info.value);