userStore.ts 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  1. import { defineStore } from 'pinia';
  2. import { useTransferPage } from '@/hooks/useTransferPage';
  3. import { getUserInfo, logoutPhysical } from '@/api/modules/login';
  4. import config from '@/config';
  5. import type { Study, UserStoreState } from '@/types';
  6. import type { UserInfo, VipCardInfo } from '@/types/user';
  7. import tools from '@/utils/uni-tool';
  8. import defaultAvatar from '@/static/personal/avatar_default.png'
  9. import { CardType, EnumBindScene, EnumExamType, EnumReviewMode, EnumUserType } from '@/common/enum';
  10. import { getDirectedSchool, saveDirectedSchool } from '@/api/modules/study';
  11. import { usePay } from '@/hooks/usePay';
  12. import { getUserBindCard } from '@/api/modules/user';
  13. const themeColor = '#31A0FC';
  14. type CheckLoginOptions = {
  15. askToLogin?: boolean;
  16. }
  17. export const useUserStore = defineStore('ie-user', {
  18. state: (): UserStoreState => ({
  19. accessToken: null,
  20. user: null,
  21. card: null,
  22. isDefaultModifyPwd: false,
  23. isPasswordExpired: false,
  24. isExamGuideShow: false,
  25. tempInfo: {
  26. location: '',
  27. examType: undefined,
  28. },
  29. org: {
  30. ...config.defaultOrg,
  31. },
  32. rememberPwd: false,
  33. cardPassword: '',
  34. cardNo: '',
  35. directedSchoolList: [],
  36. practiceSettings: {
  37. reviewMode: EnumReviewMode.AFTER_SUBMIT,
  38. autoNext: false
  39. }
  40. }),
  41. getters: {
  42. isLogin(state: UserStoreState): boolean {
  43. return !!state.accessToken && state.user !== null && Object.keys(state.user).length > 0;
  44. },
  45. userInfo(state: UserStoreState): UserInfo {
  46. return state.user || {} as UserInfo;
  47. },
  48. avatar(state: UserStoreState): string {
  49. return this.userInfo.avatar || defaultAvatar
  50. },
  51. nickName(state: UserStoreState): string {
  52. return this.userInfo.nickName || '游客'
  53. },
  54. anonymousPhoneNumber(state: UserStoreState): string {
  55. if (this.userInfo.phonenumber && this.userInfo.phonenumber.length === 11) {
  56. return this.userInfo.phonenumber.slice(0, 3) + '****' + this.userInfo.phonenumber.slice(7)
  57. }
  58. return '';
  59. },
  60. isVip(): boolean {
  61. if (!this.card) {
  62. return false;
  63. }
  64. const { outDate } = this.card;
  65. return !!this.userInfo.cardId && new Date(outDate) > new Date();
  66. },
  67. isExperienceVip(): boolean {
  68. if (!this.card) {
  69. return false;
  70. }
  71. const { outDate } = this.card;
  72. return this.card?.type === CardType.EXPERIENCE && new Date(outDate) > new Date();
  73. },
  74. vipInfo(state: UserStoreState): VipCardInfo {
  75. if (state.card) {
  76. return state.card;
  77. }
  78. return {} as VipCardInfo;
  79. },
  80. orgInfo(state: UserStoreState) {
  81. return state.org;
  82. },
  83. isStudent(): boolean {
  84. return this.userInfo.userType === EnumUserType.STUDENT;
  85. },
  86. isTeacher(): boolean {
  87. return this.userInfo.userType === EnumUserType.TEACHER;
  88. },
  89. isAgent(): boolean {
  90. return this.userInfo.userType === EnumUserType.AGENT;
  91. },
  92. isAuditor(): boolean {
  93. return false;
  94. return this.userInfo.accountType === 2;
  95. },
  96. hasDirectedSchool(): boolean {
  97. return this.directedSchoolList.length > 0;
  98. },
  99. hasTestAndRecord(): boolean {
  100. // 职高对口升学 目前不支持测评
  101. return this.getExamType != EnumExamType.VHS;
  102. },
  103. /**
  104. * 需要完成信息完善的用户类型
  105. * @returns
  106. */
  107. needCompleteInfo(): boolean {
  108. return this.isTeacher || this.isAgent;
  109. },
  110. // 兼容游客时显示
  111. getLocation(): string {
  112. if (this.isLogin) {
  113. return this.user?.location || '';
  114. }
  115. return this.tempInfo?.location || '';
  116. },
  117. getExamType(): string {
  118. if (this.isLogin) {
  119. return this.user?.examType || '';
  120. }
  121. return this.tempInfo?.examType || '';
  122. },
  123. isHN(): boolean {
  124. return this.getLocation == '湖南'
  125. },
  126. isVHS(): boolean {
  127. return this.getExamType === EnumExamType.VHS;
  128. }
  129. },
  130. actions: {
  131. setToken(token: string) {
  132. this.accessToken = token;
  133. },
  134. async login(token: string) {
  135. try {
  136. this.accessToken = token;
  137. const userInfo = await this.getUserInfo();;
  138. return Promise.resolve({
  139. success: true,
  140. userInfo: userInfo
  141. });
  142. } catch (error) {
  143. return Promise.resolve({
  144. success: false,
  145. userInfo: null
  146. });
  147. }
  148. },
  149. checkLogin({ askToLogin = true }: CheckLoginOptions = {}): Promise<boolean> {
  150. if (this.isLogin) {
  151. return Promise.resolve(true);
  152. }
  153. const { transferTo } = useTransferPage();
  154. return new Promise((resolve, reject) => {
  155. if (askToLogin) {
  156. tools.showModal({
  157. title: '提示',
  158. content: '当前未登录,是否前往登录?',
  159. confirmColor: themeColor
  160. }).then(confirm => {
  161. if (confirm) {
  162. transferTo('/pagesSystem/pages/login/login').then((res) => {
  163. resolve(res as boolean);
  164. }).catch(() => {
  165. resolve(false);
  166. });
  167. }
  168. });
  169. } else {
  170. transferTo('/pagesSystem/pages/login/login').then((res) => {
  171. resolve(res as boolean);
  172. }).catch(() => {
  173. resolve(false);
  174. });
  175. }
  176. });
  177. },
  178. checkVip() {
  179. return new Promise((resolve, reject) => {
  180. if (!this.isVip) {
  181. resolve(false);
  182. }
  183. resolve(true);
  184. });
  185. },
  186. /**
  187. * 检查老师是否完善信息
  188. * @returns
  189. */
  190. checkInfoTeacherComplete() {
  191. return new Promise((resolve, reject) => {
  192. if (this.needCompleteInfo && (!this.userInfo.location || !this.userInfo.examType || !this.userInfo.endYear)) {
  193. const { transferTo } = useTransferPage();
  194. transferTo('/pagesSystem/pages/bind-teacher-profile/bind-teacher-profile').then(res => {
  195. resolve(res as boolean);
  196. }).catch(() => {
  197. resolve(false);
  198. });
  199. } else {
  200. resolve(true);
  201. }
  202. });
  203. },
  204. /**
  205. * 检查学生是否需要完善信息
  206. * @returns
  207. */
  208. checkInfoStudentComplete(): Promise<boolean> {
  209. const { queryPayStatus } = usePay();
  210. return new Promise(async (resolve, reject) => {
  211. const payResult = await queryPayStatus();
  212. if (payResult && payResult.isPaySuccess) {
  213. const { data } = await getUserBindCard();
  214. if (data && data.cardNo && data.password) {
  215. const submitInfo = {
  216. token: this.accessToken,
  217. scene: EnumBindScene.LOGIN_BIND,
  218. userInfo: this.userInfo,
  219. cardInfo: data,
  220. registerInfo: {
  221. username: data.cardNo,
  222. password: data.password,
  223. }
  224. };
  225. const { transferTo } = useTransferPage();
  226. transferTo('/pagesSystem/pages/bind-profile/bind-profile', {
  227. data: submitInfo
  228. }).then(res => {
  229. resolve(res as boolean);
  230. }).catch(() => {
  231. resolve(false);
  232. });
  233. }
  234. } else {
  235. resolve(false);
  236. }
  237. });
  238. },
  239. async getUserInfo() {
  240. const res = await getUserInfo();
  241. const { data, isDefaultModifyPwd, isPasswordExpired, card, org } = res;
  242. if (data) {
  243. this.user = data;
  244. if (card) {
  245. this.card = card;
  246. }
  247. this.isDefaultModifyPwd = isDefaultModifyPwd;
  248. this.isPasswordExpired = isPasswordExpired;
  249. }
  250. if (org) {
  251. this.org = org;
  252. }
  253. const { getPrice } = usePay();
  254. getPrice();
  255. return data;
  256. },
  257. /**
  258. * 保存定向学校列表
  259. * @param list 定向学校列表
  260. */
  261. async saveDirectedSchoolList(list: Study.DirectedSchool[]) {
  262. await saveDirectedSchool(list);
  263. await this.getDirectedSchoolList();
  264. },
  265. /**
  266. * 获取定向学校列表
  267. */
  268. async getDirectedSchoolList() {
  269. const { data } = await getDirectedSchool();
  270. this.directedSchoolList = data || [];
  271. },
  272. setPracticeSettings(settings: Study.PracticeSettings) {
  273. this.practiceSettings = settings;
  274. },
  275. askLogout() {
  276. return new Promise((resolve, reject) => {
  277. uni.$ie.showModal({
  278. title: '提示',
  279. content: '确定退出登录吗?',
  280. confirmColor: themeColor
  281. }).then(confirm => {
  282. if (confirm) {
  283. this.logout();
  284. resolve(true);
  285. } else {
  286. resolve(false);
  287. }
  288. });
  289. });
  290. },
  291. rememberLoginInfo(remember: boolean, cardNo: string, cardPassword: string) {
  292. this.rememberPwd = remember;
  293. if (remember) {
  294. this.cardNo = cardNo;
  295. this.cardPassword = cardPassword;
  296. } else {
  297. this.cardNo = '';
  298. this.cardPassword = '';
  299. }
  300. },
  301. logout() {
  302. this.accessToken = null;
  303. this.user = null;
  304. this.isDefaultModifyPwd = false;
  305. this.isPasswordExpired = false;
  306. this.org = {
  307. ...config.defaultOrg,
  308. };
  309. const { transferTo, routes } = useTransferPage();
  310. setTimeout(() => {
  311. transferTo(routes.pageIndex, {
  312. type: 'reLaunch'
  313. });
  314. }, 0);
  315. },
  316. deleteAccount() {
  317. uni.$ie.showLoading('注销中...');
  318. logoutPhysical().then(() => {
  319. this.logout();
  320. }).finally(() => {
  321. uni.$ie.hideLoading();
  322. });
  323. },
  324. /**
  325. * 拨打客服电话
  326. * @returns
  327. */
  328. callContactPhone() {
  329. if (!this.orgInfo.contactPhone) {
  330. uni.$ie.showToast('暂无客服电话');
  331. return;
  332. }
  333. uni.showActionSheet({
  334. title: '客服电话',
  335. itemList: [`拨打电话:${this.orgInfo.contactPhone}`],
  336. success: (res) => {
  337. uni.makePhoneCall({
  338. phoneNumber: this.orgInfo.contactPhone
  339. });
  340. }
  341. });
  342. }
  343. },
  344. persist: {
  345. storage: {
  346. getItem: uni.getStorageSync,
  347. setItem: uni.setStorageSync,
  348. }
  349. }
  350. });