user-edit.component.ts 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474
  1. import { Component, Input, OnInit } from '@angular/core';
  2. import { CommonModule } from '@angular/common';
  3. import { NzSpaceModule } from 'ng-zorro-antd/space';
  4. import { CommonCompModule } from '../../../services/common.modules';
  5. import { NzTabsModule } from 'ng-zorro-antd/tabs';
  6. import { ActivatedRoute, Router } from '@angular/router';
  7. import { NzAvatarModule } from 'ng-zorro-antd/avatar';
  8. import { NzDropDownModule } from 'ng-zorro-antd/dropdown';
  9. import { NzPopoverModule } from 'ng-zorro-antd/popover';
  10. import { NzTagModule } from 'ng-zorro-antd/tag';
  11. import { NzModalModule } from 'ng-zorro-antd/modal';
  12. import { NzMessageService } from 'ng-zorro-antd/message';
  13. import { textbookServer } from '../../../services/textbook';
  14. import { NzRadioModule } from 'ng-zorro-antd/radio';
  15. import Parse from 'parse';
  16. import { NzImageService } from 'ng-zorro-antd/image';
  17. import { NzImageModule } from 'ng-zorro-antd/image';
  18. import { NzSelectModule } from 'ng-zorro-antd/select';
  19. import { MatButtonModule } from '@angular/material/button';
  20. import { provinces } from '../../../services/provinces';
  21. import { NzModalService } from 'ng-zorro-antd/modal';
  22. import { Observable, of } from 'rxjs';
  23. @Component({
  24. selector: 'app-user-edit',
  25. templateUrl: './user-edit.component.html',
  26. styleUrls: ['./user-edit.component.scss'],
  27. imports: [
  28. CommonModule,
  29. NzSpaceModule,
  30. CommonCompModule,
  31. NzTabsModule,
  32. NzAvatarModule,
  33. NzDropDownModule,
  34. NzPopoverModule,
  35. NzTagModule,
  36. NzModalModule,
  37. NzRadioModule,
  38. NzImageModule,
  39. NzSelectModule,
  40. MatButtonModule,
  41. ],
  42. standalone: true,
  43. })
  44. export class UserEditComponent implements OnInit {
  45. inputValue: string = `
  46. async function pipe(user, context, callback) {
  47. if (context.connection === "weibo") {
  48. return callback(new Error("当前系统禁止使用微博登录!"))
  49. }
  50. callback(null, user, context)
  51. }`;
  52. isVisible: boolean = false;
  53. user: Parse.Object | any;
  54. profile: Parse.Object | any;
  55. password: string = '';
  56. edit: boolean = false; //编辑权限
  57. //可编辑
  58. userDataJson: any = {
  59. companyType: '',
  60. department: null,
  61. };
  62. parentMap: Array<any> = [];
  63. parentList: Array<any> = []; //单位列表
  64. isShowModal: boolean = false;
  65. searchValue: string = ''; //搜索部门内容
  66. unitTypes: Array<any> = [];
  67. userJson: any = {
  68. //user编辑数据
  69. email: '',
  70. phone: '',
  71. name: '',
  72. username: '',
  73. };
  74. profileJson: any = {
  75. //身份编辑数据
  76. identity: '',
  77. telephone: '',
  78. province: '',
  79. departmentName: '',
  80. postName: '',
  81. majorSubject: '',
  82. };
  83. userType: Array<string> = ['教师', '评审专家', '高校联系人', '工作联系人'];
  84. provinces: Array<string> = provinces.options; //省份
  85. constructor(
  86. public tbookSer: textbookServer,
  87. private activeRoute: ActivatedRoute,
  88. private router: Router,
  89. private route: ActivatedRoute,
  90. private message: NzMessageService,
  91. private nzImageService: NzImageService,
  92. private modal: NzModalService
  93. ) {}
  94. goUserList() {
  95. this.router.navigate(['/nav-admin/manage/user'], {
  96. queryParams: { page: this.route.snapshot.queryParamMap.get('page') },
  97. });
  98. }
  99. ngOnInit() {
  100. // window.onbeforeunload = (event) => {
  101. // (event || window.event).returnValue = '还未保存是否离开';
  102. // };
  103. this.activeRoute.paramMap.subscribe(async (params) => {
  104. let id = params.get('id');
  105. console.log(id);
  106. if (id) {
  107. let query = new Parse.Query('_User');
  108. query.include('department');
  109. this.user = await query.get(id);
  110. this.userJson = this.user.toJSON();
  111. let queryProfile = new Parse.Query('Profile');
  112. queryProfile.equalTo('user', id);
  113. this.profile = await queryProfile.first();
  114. this.profileJson = this.profile.toJSON();
  115. this.userJson.email = this.profileJson.email
  116. this.userDataJson = {
  117. companyType: this.profile?.get('companyType'),
  118. department: this.user.get('department'),
  119. };
  120. }
  121. await this.getUnitTypes();
  122. let arr = ['教师', '评审专家', '高校联系人'];
  123. if (this.tbookSer.profile.identity == '国家级管理员') {
  124. this.edit = true;
  125. } else if (
  126. this.tbookSer.profile.identity == '工作联系人' &&
  127. arr.includes(this.profile.get('identity'))
  128. ) {
  129. if(this.tbookSer.profile.companyType == '省级教育行政部门' || this.tbookSer.profile.companyType == '有关部门(单位)教育司(局)'){
  130. this.userType = ['教师', '评审专家', '高校联系人'];
  131. }else{
  132. this.userType = ['教师', '评审专家'];
  133. }
  134. this.edit = true;
  135. } else if (
  136. this.tbookSer.profile.identity == '高校联系人' &&
  137. this.profile.get('identity') == '教师'
  138. ) {
  139. this.userType = ['教师'];
  140. this.edit = true;
  141. }
  142. });
  143. }
  144. async updateUser(type: string) {
  145. console.log(type);
  146. if (!this.edit) {
  147. this.message.warning('同级身份暂无权限操作');
  148. return;
  149. }
  150. switch (type) {
  151. case '已认证':
  152. this.user.set('accountState', '已认证');
  153. Parse.Cloud.run('aliSmsSend', {
  154. mobileList: [this.user?.get('phone')],
  155. templateCode: 'SMS_468870790',
  156. params: {},
  157. signName: '普通高等教育教材网',
  158. });
  159. break;
  160. case '已禁用':
  161. this.user.set('accountState', '已禁用');
  162. break;
  163. case '删除':
  164. this.user.set('isDeleted', true);
  165. break;
  166. }
  167. await this.user.save();
  168. this.ngOnInit();
  169. }
  170. async handleOk() {
  171. if (!this.edit) {
  172. this.message.warning('同级身份暂无权限操作');
  173. return;
  174. }
  175. this.password = this.password?.trim();
  176. if (!this.password) {
  177. this.message.warning('密码格式错误');
  178. return;
  179. }
  180. try {
  181. this.user.set('password', this.password);
  182. await this.user.save();
  183. this.ngOnInit();
  184. } catch (err) {
  185. this.message.warning('保存出错,请注意密码格式');
  186. }
  187. this.isVisible = false;
  188. }
  189. //切换单位类型
  190. onChangeType() {
  191. this.userDataJson.department = null;
  192. }
  193. //选择部门
  194. async showModalDepart() {
  195. if (!this.edit) {
  196. this.message.warning('同级身份暂无权限操作');
  197. return;
  198. }
  199. if (this.unitTypes.length == 0) {
  200. await this.getUnitTypes();
  201. }
  202. let parent = this.unitTypes.find(
  203. (item) => item.name == this.userDataJson.companyType
  204. );
  205. if (parent?.id) {
  206. this.parentMap = await this.formatNode(parent.id);
  207. }
  208. this.provinceChange(this.parentMap[this.parentMap.length - 1]?.id);
  209. this.isShowModal = true;
  210. }
  211. async getUnitTypes() {
  212. let query = new Parse.Query('Department');
  213. query.equalTo('branch', undefined);
  214. query.equalTo('parent', undefined);
  215. query.notEqualTo('isDeleted', true);
  216. query.select('name');
  217. let r = await query.find();
  218. r.forEach((item) => {
  219. this.unitTypes.push({ id: item.id, name: item.get('name') });
  220. });
  221. }
  222. //根据所选单位类型获取对应单位
  223. async provinceChange(id?: string, val?: string) {
  224. let query = new Parse.Query('Department');
  225. query.select('name', 'branch', 'parent');
  226. if (this.tbookSer.profile.identity != '国家级管理员') {
  227. query.equalTo(
  228. 'objectId',
  229. this.tbookSer.profile?.user.department?.objectId
  230. );
  231. }
  232. if (this.tbookSer.profile.identity == '国家级管理员' || id) {
  233. query.equalTo('parent', id ? id : null);
  234. }
  235. query.limit(100);
  236. val && query.contains('name', val);
  237. let r = await query.find();
  238. this.parentList = r;
  239. }
  240. async formatNode(id: string): Promise<Array<any>> {
  241. let arr = [];
  242. if (id) {
  243. let query = new Parse.Query('Department');
  244. query.equalTo('objectId', id);
  245. query.select('parent', 'name');
  246. let r = await query.first();
  247. arr.push({
  248. title: r?.get('name'),
  249. id: r?.id,
  250. });
  251. if (r?.get('parent')) {
  252. arr.unshift(...(await this.formatNode(r?.get('parent')?.id)));
  253. }
  254. }
  255. return arr;
  256. }
  257. onCheck(e: any) {
  258. console.log(e);
  259. this.userDataJson.department = undefined;
  260. this.provinceChange();
  261. }
  262. parent: string = ''; //搜索时传入的id
  263. //选择部门
  264. async onCheckedDepart(e: any) {
  265. console.log(e);
  266. if (e?.get('parent')?.id) {
  267. this.userDataJson.department = e;
  268. this.parent = e?.get('parent')?.id;
  269. } else {
  270. this.provinceChange(e.id);
  271. this.parent = e?.id;
  272. }
  273. this.parentMap = await this.formatNode(e.id);
  274. }
  275. handleCancel(): void {
  276. console.log('Button cancel clicked!');
  277. this.userDataJson = {
  278. companyType: this.profile?.get('companyType'),
  279. department: this.user.get('department'),
  280. };
  281. this.isShowModal = false;
  282. this.parent = '';
  283. }
  284. async completeChange(): Promise<void> {
  285. if (!this.userDataJson.department?.id) {
  286. this.message.warning('请选择部门');
  287. return;
  288. }
  289. this.userDataJson.companyType = this.userDataJson.department.get('branch');
  290. this.profile?.set('companyType', this.userDataJson.companyType);
  291. await this.profile?.save();
  292. this.user?.set('department', this.userDataJson.department?.toPointer());
  293. await this.user?.save();
  294. this.ngOnInit();
  295. this.isShowModal = false;
  296. this.parent = '';
  297. }
  298. openUrl(url: string) {
  299. if (!/\.(jpg|jpeg|png|GIF|JPG|PNG)$/.test(url)) {
  300. window.open(url);
  301. } else {
  302. let images = [
  303. {
  304. src: url,
  305. width: '200px',
  306. height: '200px',
  307. alt: 'ng-zorro',
  308. },
  309. ];
  310. this.nzImageService.preview(images, { nzZoom: 1.5, nzRotate: 0 });
  311. }
  312. }
  313. /* 修改账号 */
  314. loading: boolean = false;
  315. submitForm(type: string) {
  316. if (this.loading) return;
  317. this.loading = true;
  318. if (type == 'save') {
  319. this.updateUserJson();
  320. } else {
  321. this.userJson = this.user.toJSON();
  322. this.profileJson = this.profile.toJSON();
  323. this.userDataJson = {
  324. companyType: this.profile?.get('companyType'),
  325. department: this.user.get('department'),
  326. };
  327. this.loading = false;
  328. }
  329. }
  330. async updateUserJson() {
  331. //修改用户数据
  332. console.log(this.userJson);
  333. console.log(this.profileJson);
  334. this.userJson.username = this.userJson?.username?.trim();
  335. this.userJson.email = this.userJson?.email?.trim();
  336. this.userJson.phone = this.userJson?.phone?.trim();
  337. this.userJson.name = this.userJson?.name?.trim();
  338. if (!(await this.authVrifly())) {
  339. this.loading = false;
  340. return;
  341. }
  342. try {
  343. this.user?.set('username', this.userJson?.username);
  344. this.user?.set('name', this.userJson?.name);
  345. this.user?.set('phone', this.userJson?.phone);
  346. this.userJson?.email && this.user?.set('email', this.userJson?.email);
  347. await this.user.save();
  348. this.profile?.set('companyType', this.userDataJson.companyType);
  349. this.profile?.set('email', this.userJson.email);
  350. this.profile?.set('identity', this.profileJson.identity);
  351. this.profile?.set('telephone', this.profileJson.telephone);
  352. this.profile?.set('province', this.profileJson.province);
  353. this.profile?.set('departmentName', this.profileJson.departmentName);
  354. this.profile?.set('postName', this.profileJson.postName);
  355. this.profile?.set('majorSubject', this.profileJson.majorSubject);
  356. await this.profile?.save();
  357. this.loading = false;
  358. this.modal.success({
  359. nzTitle: '修改成功',
  360. nzContent: '',
  361. nzOnOk: () => {},
  362. });
  363. } catch (err: any) {
  364. console.warn('添加用户错误', err);
  365. this.loading = false;
  366. this.message.error(
  367. err?.Error || '错误:请检查用户或邮箱及手机号是否已存在'
  368. );
  369. return;
  370. }
  371. }
  372. async authVrifly(): Promise<boolean | undefined> {
  373. this.userJson.username = this.userJson?.username?.trim();
  374. this.userJson.email = this.userJson?.email?.trim();
  375. this.userJson.phone = this.userJson?.phone?.trim();
  376. this.userJson.name = this.userJson?.name?.trim();
  377. if (
  378. !this.userJson?.username ||
  379. !this.userJson?.name ||
  380. !this.userJson.phone ||
  381. !this.userJson?.email
  382. ) {
  383. this.message.warning('请填写必填项');
  384. return;
  385. }
  386. if (!this.userDataJson?.department) {
  387. this.message.error('请选择所属部门');
  388. return;
  389. }
  390. if (!this.profileJson.identity) {
  391. this.message.error('请选择人员类型');
  392. return;
  393. }
  394. let a = /^(?:(?:\+|00)86)?1[3-9]\d{9}$/;
  395. if (this.userJson.phone && !String(this.userJson.phone).match(a)) {
  396. this.message.error('请填写正确手机号');
  397. return;
  398. }
  399. let m =
  400. /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
  401. if (!String(this.userJson.email).match(m)) {
  402. this.message.error('邮箱格式有误');
  403. return;
  404. }
  405. if (
  406. this.userJson.phone != this.user.get('phone') &&
  407. !(await this.tbookSer.userFind(this.userJson.phone))
  408. ) {
  409. this.message.error('手机号已存在');
  410. return;
  411. }
  412. return true;
  413. }
  414. //页面数据变化时
  415. vrifly: boolean = false;
  416. moduleChange(): Observable<boolean> {
  417. let a =
  418. this.userJson.username != this.user.get('username') ||
  419. this.userJson.name != this.user.get('name') ||
  420. this.userJson.email != this.profile.get('email') ||
  421. this.userJson.phone != this.user.get('phone');
  422. let b =
  423. this.profileJson.identity != this.profile.get('identity') ||
  424. this.profileJson.telephone != this.profile.get('telephone') ||
  425. this.profileJson.province != this.profile.get('province') ||
  426. this.profileJson.departmentName != this.profile.get('departmentName') ||
  427. this.profileJson.postName != this.profile.get('postName') ||
  428. this.profileJson.majorSubject != this.profile.get('majorSubject');
  429. console.log(a, b);
  430. if (
  431. a ||
  432. b ||
  433. this.userDataJson.companyType != this.profile?.get('companyType')
  434. ) {
  435. if (this.vrifly) return of(this.vrifly);
  436. this.updateCanDeActivate();
  437. return of(false);
  438. }
  439. return of(true);
  440. }
  441. //提示保存
  442. updateCanDeActivate() {
  443. new Promise((result) => {
  444. this.modal.confirm({
  445. nzTitle: '离开当前页面?',
  446. nzContent: '<p>当前编辑未保存,是否保存?</p>',
  447. nzOkText: '保存',
  448. nzOkType: 'primary',
  449. nzOkDanger: true,
  450. nzClosable: false,
  451. nzMaskClosable: false,
  452. nzOnOk: async () => {
  453. await this.updateUserJson();
  454. this.goUserList();
  455. result(true);
  456. },
  457. nzCancelText: '取消',
  458. nzOnCancel: () => {
  459. this.vrifly = true;
  460. this.goUserList();
  461. },
  462. });
  463. });
  464. }
  465. }