user.ts 3.9 KB

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