attachment.component.ts 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452
  1. import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
  2. import { CommonCompModule } from '../../../../services/common.modules';
  3. import { NzSelectModule } from 'ng-zorro-antd/select';
  4. import { ReactiveFormsModule } from '@angular/forms';
  5. import { NzRadioModule } from 'ng-zorro-antd/radio';
  6. import { NzMessageService } from 'ng-zorro-antd/message';
  7. import { NzGridModule } from 'ng-zorro-antd/grid';
  8. import { NzCheckboxModule } from 'ng-zorro-antd/checkbox';
  9. import { NzTableModule } from 'ng-zorro-antd/table';
  10. import { NzUploadChangeParam } from 'ng-zorro-antd/upload';
  11. import { NzUploadModule } from 'ng-zorro-antd/upload';
  12. import { NzModalService } from 'ng-zorro-antd/modal';
  13. import Parse from 'parse';
  14. import { CompUploadComponent } from '../../../../app/comp-upload/comp-upload.component';
  15. import { DatePipe } from '@angular/common';
  16. import {
  17. FormControl,
  18. FormGroup,
  19. NonNullableFormBuilder,
  20. Validators,
  21. ValidatorFn,
  22. AbstractControl,
  23. } from '@angular/forms';
  24. import { textbookServer } from '../../../../services/textbook';
  25. import * as eduTextBook from '../../../../services/EduTextbook'
  26. import { HttpClient } from '@angular/common/http';
  27. import { Router } from '@angular/router'
  28. @Component({
  29. selector: 'app-attachment',
  30. imports: [
  31. CommonCompModule,
  32. ReactiveFormsModule,
  33. NzSelectModule,
  34. NzRadioModule,
  35. NzGridModule,
  36. NzCheckboxModule,
  37. NzTableModule,
  38. NzUploadModule,
  39. CompUploadComponent,DatePipe,
  40. ],
  41. standalone: true,
  42. templateUrl: './attachment.component.html',
  43. styleUrls: ['./attachment.component.scss'],
  44. providers: [DatePipe],
  45. })
  46. export class AttachmentComponent implements OnInit {
  47. @Input('eduTextbook') eduTextbook: any;
  48. @Input('maxWidth') maxWidth: number = 0;
  49. @Output() state: EventEmitter<any> = new EventEmitter<any>();
  50. @Output() save: EventEmitter<any> = new EventEmitter<any>();
  51. //填写诚信承诺是否正确
  52. confirmationValidator: ValidatorFn = (
  53. control: AbstractControl
  54. ): { [s: string]: boolean } => {
  55. if (
  56. control.value !=
  57. '本人自愿参加此次申报,已认真填写并检查以上材料,保证内容真实'
  58. ) {
  59. return { required: true };
  60. }
  61. return {};
  62. };
  63. /** 版权页截图*/
  64. copyrightImgUrl: string = ''
  65. /** 中国版本图书馆CIP查询截图*/
  66. CIPImgUrl: string = ''
  67. /**cip证明材料 {name: '',url: '',} */
  68. cipProveFile: Array<any> = []
  69. /**图书编校质量自查结果记录表 */
  70. selfResults: any = {
  71. name: '',
  72. url: '',
  73. }
  74. /** 专家审查意见表*/
  75. expertOpinion: any = {
  76. name: '',
  77. url: '',
  78. }
  79. /** 教材使用情况证明材料*/
  80. evidence: any = {
  81. name: '',
  82. url: '',
  83. }
  84. /**其他材料 {name: '',url: '',} */
  85. moreMaterial: Array<any> = []
  86. /**申报单位承诺意见 */
  87. unitMaterial: any = {
  88. name: '',
  89. url: '',
  90. }
  91. // /**作者政治审核表 {name: '',url: '',} */
  92. // examine: Array<any> = []
  93. constructor(
  94. public tbookSer: textbookServer,
  95. private msg: NzMessageService,
  96. private modal: NzModalService,
  97. private http: HttpClient,
  98. private router: Router
  99. ) { }
  100. ngOnInit() {
  101. if (this.eduTextbook.id) {
  102. this.copyrightImgUrl = this.eduTextbook?.get('copyrightImgUrl') || this.copyrightImgUrl
  103. this.CIPImgUrl = this.eduTextbook?.get('CIPImgUrl') || this.CIPImgUrl
  104. this.selfResults = this.eduTextbook?.get('selfResults') || this.selfResults
  105. this.expertOpinion = this.eduTextbook?.get('expertOpinion') || this.expertOpinion
  106. this.evidence = this.eduTextbook?.get('evidence') || this.evidence
  107. this.moreMaterial = this.eduTextbook?.get('moreMaterial') || this.moreMaterial
  108. this.cipProveFile = this.eduTextbook?.get('cipProveFile') || this.cipProveFile
  109. this.unitMaterial = this.eduTextbook?.get('unitMaterial') || this.unitMaterial
  110. // this.examine = this.eduTextbook?.get('examine') || this.examine
  111. this.authorList = this.eduTextbook?.get('authorList')
  112. }
  113. }
  114. /**本页必填是否存在空项 */
  115. examineNull() {
  116. let isNull = false
  117. let msgList = []
  118. if (this.copyrightImgUrl == '' || !this.copyrightImgUrl) {
  119. msgList.push('版权页截图')
  120. isNull = true
  121. }
  122. // if (this.CIPImgUrl == '' || !this.CIPImgUrl) {
  123. // if (this.cipProveFile?.length > 0) {
  124. // let isExist = this.cipProveFile.every(item => item?.url == '' || !item?.url)
  125. // if (isExist) {
  126. // msgList.push('CIP 相关内容截图')
  127. // isNull = true
  128. // }
  129. // } else {
  130. // msgList.push('CIP 查询截图')
  131. // isNull = true
  132. // }
  133. // }
  134. if (this.CIPImgUrl == '' || !this.CIPImgUrl) {
  135. msgList.push('CIP查询截图')
  136. isNull = true
  137. }
  138. if (this.cipProveFile?.length > 0) {
  139. let isExist = this.cipProveFile.every(item => item?.url == '' || !item?.url)
  140. if (isExist) {
  141. msgList.push('CIP证明材料')
  142. isNull = true
  143. }
  144. }
  145. if (this.selfResults.url == '' || !this.selfResults.url) {
  146. msgList.push('自查结果记录表')
  147. isNull = true
  148. }
  149. if (this.expertOpinion.url == '' || !this.expertOpinion.url) {
  150. msgList.push('专家审查意见表')
  151. isNull = true
  152. }
  153. if (this.evidence.url == '' || !this.evidence.url) {
  154. msgList.push('证明材料')
  155. isNull = true
  156. }
  157. if (this.moreMaterial?.length > 0) {
  158. let isExist = this.moreMaterial.every(item => item?.url == '' || !item?.url)
  159. if (isExist) {
  160. msgList.push('其他材料')
  161. isNull = true
  162. }
  163. }
  164. // if (this.examine?.length <= 0) {
  165. // isNull = true
  166. // msgList.push('作者政治审核表')
  167. // } else if (this.examine?.length > 0) {
  168. // let isExist = this.examine.every(item => item?.url == '' || !item?.url)
  169. // if (isExist) {
  170. // msgList.push('作者政治审核表')
  171. // isNull = true
  172. // }
  173. // }
  174. // if (this.unitMaterial.url == '' || !this.unitMaterial.url) {
  175. // msgList.push('申报单位承诺意见')
  176. // isNull = true
  177. // }
  178. // if (isNull) {
  179. // this.msg.create('error', `请上传完整 ${msgList.join()}`)
  180. // }
  181. return isNull
  182. }
  183. /**判断是否存在未填字段 */
  184. isIgnoreFiledNull() {
  185. let selectList = this.eduTextbook?.get('characteristic')
  186. let check = false
  187. for (let i in selectList) {
  188. if (selectList[i].label == '通识课' || selectList[i].label == '公共基础课' || selectList[i].label == '专业课') {
  189. if (selectList[i].checked) {
  190. check = true
  191. break;
  192. }
  193. }
  194. }
  195. if (!check) {
  196. // this.msg.create('warning', '请返回选择适用课程性质')
  197. return true
  198. }
  199. let eduColumn = eduTextBook.EduTextbook.fields
  200. let ignoreFiled = [
  201. 'typeNumber', 'code', 'editionNumber', 'importantProjectOther',
  202. 'textbookFiles', 'createdAt', 'updatedAt', 'copyright', 'authorSign',
  203. 'CIP', 'isDeleted', 'opinions', 'printNumber', 'printSum', 'render',
  204. 'importantProject', 'importantProjectOther', 'complete', 'links', 'recommend',
  205. 'printSun', 'discard', 'edition', 'eduProcess', 'authors', 'editor',
  206. 'copyrightImgUrl', 'CIPImgurl', 'selfResults', 'expertOpinion', 'evidence',
  207. 'moreMaterial', 'unitMaterial', 'approvedImgUrl', 'department','CIPImgUrl','cipProveFile',
  208. 'examine'
  209. ] //非必填字段
  210. let textBookJson = this.eduTextbook.toJSON()
  211. let isVrifly = Object.keys(eduColumn).some((item: string) => {
  212. if (!ignoreFiled.includes(item) && (textBookJson[item] === '' || textBookJson[item] === undefined || textBookJson[item] === null)) {
  213. console.warn('字段未填写:' + item)
  214. return true
  215. }
  216. return
  217. })
  218. /* 检验authorList字段是否留空 */
  219. let authorListAuth
  220. console.log(this.authorList);
  221. authorListAuth = this.authorList.some((obj:any)=>{
  222. return Object.keys(obj).some((item: string) => !obj[item])
  223. })
  224. // console.log(authorListAuth);
  225. if (isVrifly || authorListAuth) {
  226. // this.msg.warning('存在未填项')
  227. return true
  228. } else {
  229. return false
  230. }
  231. }
  232. async submitForm(event?: string): Promise<void> {
  233. let params = {
  234. copyrightImgUrl: this.copyrightImgUrl,
  235. CIPImgUrl: this.CIPImgUrl,
  236. cipProveFile: this.cipProveFile,
  237. selfResults: this.selfResults,
  238. expertOpinion: this.expertOpinion,
  239. evidence: this.evidence,
  240. moreMaterial: this.moreMaterial,
  241. // examine: this.examine,
  242. authorList:this.authorList
  243. // unitMaterial: this.unitMaterial,
  244. }
  245. let isPageNull = this.examineNull()//检查本页空项
  246. let isIgnoreFiled = this.isIgnoreFiledNull()//检查数据空项
  247. // console.log(isPageNull, isIgnoreFiled);
  248. if (event == 'pre') {//上一步
  249. this.state.emit({ type: 'pre' });
  250. return;
  251. }
  252. await this.saveEduTextbook(params, (!isPageNull && !isIgnoreFiled));
  253. if (event == 'complete') {
  254. this.state.emit({ type: 'complete', textBook: this.eduTextbook });
  255. if (isPageNull || isIgnoreFiled) {
  256. console.log('教材填写不完整');
  257. } else {
  258. this.eduTextbook.set('complete', true)
  259. this.eduTextbook.set('status', '102')
  260. await this.eduTextbook.save()
  261. this.msg.success('已填写完成')
  262. }
  263. this.router.navigate(['/nav-author/manage/space'])
  264. } else if (event == 'save') {
  265. this.modal.success({
  266. nzTitle: '保存成功',
  267. nzContent: '<p>已保存并且至空间</p>',
  268. nzOnOk: () => console.log('Info OK'),
  269. });
  270. return;
  271. }
  272. }
  273. async saveEduTextbook(params: any, isComplete: boolean) {
  274. console.log(isComplete);
  275. if (!this.eduTextbook) {
  276. this.msg.error('请先创建教材');
  277. return;
  278. }
  279. //如果填写未完整,仅保存,状态修改待完善101
  280. if (this.eduTextbook.get('status') == '102' && !isComplete) {
  281. this.eduTextbook?.set('status', '101');
  282. } else if (!this.eduTextbook.get('status')) {
  283. this.eduTextbook?.set('status', '101');
  284. }
  285. this.eduTextbook?.set('user', Parse.User.current()?.toPointer());
  286. this.eduTextbook?.set('company', {
  287. __type: 'Pointer',
  288. className: 'Company',
  289. objectId: this.tbookSer.company,
  290. });
  291. params.selfResults &&
  292. this.eduTextbook?.set('selfResults', params.selfResults);
  293. // params.unitMaterial &&
  294. // this.eduTextbook?.set('unitMaterial', params.unitMaterial);
  295. params.expertOpinion &&
  296. this.eduTextbook?.set('expertOpinion', params.expertOpinion);
  297. params.evidence && this.eduTextbook?.set('evidence', params.evidence);
  298. params.cipProveFile &&
  299. this.eduTextbook?.set('cipProveFile', params.cipProveFile);
  300. params.moreMaterial &&
  301. this.eduTextbook?.set('moreMaterial', params.moreMaterial);
  302. // params.examine &&
  303. // this.eduTextbook?.set('examine', params.examine);
  304. this.eduTextbook?.set('copyrightImgUrl', params.copyrightImgUrl);
  305. this.eduTextbook?.set('CIPImgUrl', params.CIPImgUrl);
  306. this.eduTextbook?.set('authorList', params.authorList);
  307. await this.eduTextbook?.save();
  308. return;
  309. }
  310. upload(e: any, type: string, index?: any) {
  311. let file = e[(e?.length - 1) || 0];
  312. if (type == 'copyrightImgUrl' || type == 'CIPImgUrl') {
  313. this[type] = file?.url
  314. } else if (type == 'selfResults' || type == 'expertOpinion' ||
  315. type == 'evidence' || type == 'unitMaterial') {
  316. this[type].url = file?.url
  317. this[type].name = file?.name
  318. } else if (type == 'moreMaterial' || type == 'cipProveFile') {
  319. this[type] = [...(this[type] || []), { name: file.name, url: file.url }]
  320. }else if (type == 'signature' || type == 'examine') {
  321. this.authorList[index][type] = file?.url
  322. }
  323. console.log(this.authorList)
  324. }
  325. /**获取文件名 */
  326. getFileName(url: string) {
  327. if (!url) return ''
  328. let str = url?.split('/')[5]
  329. let index = str?.indexOf('-')
  330. let result = decodeURIComponent(str?.substring(index + 1))
  331. return result || '未知文件名'
  332. }
  333. downloadFile(fileName: string) {
  334. // let fileName = '十四五”普通高等教育本科国家级规划教材第一次遴选推荐申报表.docx'
  335. const fileUrl = `../../../../../public/file/${fileName}`;
  336. this.http.get(fileUrl, { responseType: 'blob' }).subscribe((blob) => {
  337. const url = window.URL.createObjectURL(blob);
  338. const a = document.createElement('a');
  339. a.href = url;
  340. a.download = fileName;
  341. document.body.appendChild(a);
  342. a.click();
  343. document.body.removeChild(a);
  344. window.URL.revokeObjectURL(url);
  345. })
  346. }
  347. openFile(url: string) {
  348. console.log(url);
  349. window.open(url)
  350. }
  351. /**作者信息 */
  352. authorList:Array<any>=[]
  353. //添加作者信息
  354. onPush(type: string, idx: number) {
  355. switch (type) {
  356. case 'authorList':
  357. if (this.authorList?.length >= 6) {
  358. this.msg.warning('最多添加6条');
  359. break;
  360. }
  361. this.authorList.splice(idx + 1, 0, {
  362. name: '',
  363. unit: '',
  364. birth: '',
  365. nationality: '',
  366. job: '',
  367. title: '',
  368. mobile: '',
  369. email: '',
  370. work: '',
  371. signature: '',
  372. examine: '',
  373. });
  374. break;
  375. // case 'achievementOptions':
  376. // if (this.achievementOptions.length >= 5) {
  377. // this.msg.warning('最多添加5条');
  378. // return;
  379. // }
  380. // this.achievementOptions.splice(idx + 1, 0, {
  381. // name: '',
  382. // unit: '',
  383. // date: '',
  384. // });
  385. // break;
  386. }
  387. }
  388. //删除作者信息
  389. onDel(type: string, idx: number) {
  390. switch (type) {
  391. case 'authorList':
  392. if (this.authorList.length == 1) {
  393. this.authorList = [
  394. {
  395. name: '',
  396. unit: '',
  397. birth: '',
  398. nationality: '',
  399. job: '',
  400. title: '',
  401. mobile: '',
  402. email: '',
  403. work: '',
  404. signature: '',
  405. examine: '',
  406. },
  407. ];
  408. return;
  409. }
  410. this.authorList.splice(idx, 1);
  411. break;
  412. // case 'achievementOptions':
  413. // if (this.achievementOptions.length == 1) {
  414. // this.achievementOptions = [
  415. // {
  416. // name: '',
  417. // unit: '',
  418. // date: '',
  419. // },
  420. // ];
  421. // return;
  422. // }
  423. // this.achievementOptions.splice(idx, 1);
  424. // break;
  425. }
  426. }
  427. }