attachment.component.ts 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  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 {
  16. FormControl,
  17. FormGroup,
  18. NonNullableFormBuilder,
  19. Validators,
  20. ValidatorFn,
  21. AbstractControl,
  22. } from '@angular/forms';
  23. import { textbookServer } from '../../../../services/textbook';
  24. import * as eduTextBook from '../../../../services/EduTextbook'
  25. import { HttpClient } from '@angular/common/http';
  26. import { Router} from '@angular/router'
  27. @Component({
  28. selector: 'app-attachment',
  29. imports: [
  30. CommonCompModule,
  31. ReactiveFormsModule,
  32. NzSelectModule,
  33. NzRadioModule,
  34. NzGridModule,
  35. NzCheckboxModule,
  36. NzTableModule,
  37. NzUploadModule,
  38. CompUploadComponent,
  39. ],
  40. standalone: true,
  41. templateUrl: './attachment.component.html',
  42. styleUrls: ['./attachment.component.scss'],
  43. })
  44. export class AttachmentComponent implements OnInit {
  45. @Input('eduTextbook') eduTextbook: any;
  46. @Input('maxWidth') maxWidth: number = 0;
  47. @Output() state: EventEmitter<any> = new EventEmitter<any>();
  48. @Output() save: EventEmitter<any> = new EventEmitter<any>();
  49. //填写诚信承诺是否正确
  50. confirmationValidator: ValidatorFn = (
  51. control: AbstractControl
  52. ): { [s: string]: boolean } => {
  53. if (
  54. control.value !=
  55. '本人自愿参加此次申报,已认真填写并检查以上材料,保证内容真实'
  56. ) {
  57. return { required: true };
  58. }
  59. return {};
  60. };
  61. /** 版权页截图*/
  62. copyrightImgUrl: string = ''
  63. /** 中国版本图书馆CIP查询截图*/
  64. CIPImgUrl: string = ''
  65. /**图书编校质量自查结果记录表 */
  66. selfResults: any = {
  67. name: '',
  68. url: '',
  69. }
  70. /** 专家审查意见表*/
  71. expertOpinion: any = {
  72. name: '',
  73. url: '',
  74. }
  75. /** 教材使用情况证明材料*/
  76. evidence: any = {
  77. name: '',
  78. url: '',
  79. }
  80. /**其他材料 {name: '',url: '',} */
  81. moreMaterial: Array<any> = []
  82. /**申报单位承诺意见 */
  83. unitMaterial: any = {
  84. name: '',
  85. url: '',
  86. }
  87. constructor(
  88. public tbookSer: textbookServer,
  89. private msg: NzMessageService,
  90. private modal: NzModalService,
  91. private http: HttpClient,
  92. private router:Router
  93. ) { }
  94. ngOnInit() {
  95. if (this.eduTextbook.id) {
  96. this.copyrightImgUrl = this.eduTextbook?.get('copyrightImgUrl') || this.copyrightImgUrl
  97. this.CIPImgUrl = this.eduTextbook?.get('CIPImgUrl') || this.CIPImgUrl
  98. this.selfResults = this.eduTextbook?.get('selfResults') || this.selfResults
  99. this.expertOpinion = this.eduTextbook?.get('expertOpinion') || this.expertOpinion
  100. this.evidence = this.eduTextbook?.get('evidence') || this.evidence
  101. this.moreMaterial = this.eduTextbook?.get('moreMaterial') || this.moreMaterial
  102. this.unitMaterial = this.eduTextbook?.get('unitMaterial') || this.unitMaterial
  103. }
  104. }
  105. /**本页必填是否存在空项 */
  106. examineNull() {
  107. let isNull = false
  108. let msgList = []
  109. if (this.copyrightImgUrl == '' || !this.copyrightImgUrl) {
  110. msgList.push('版权页截图')
  111. isNull = true
  112. }
  113. if (this.CIPImgUrl == '' || !this.CIPImgUrl) {
  114. msgList.push('CIP查询截图')
  115. isNull = true
  116. }
  117. if (this.selfResults.url == '' || !this.selfResults.url) {
  118. msgList.push('自查结果记录表')
  119. isNull = true
  120. }
  121. if (this.expertOpinion.url == '' || !this.expertOpinion.url) {
  122. msgList.push('专家审查意见表')
  123. isNull = true
  124. }
  125. if (this.evidence.url == '' || !this.evidence.url) {
  126. msgList.push('证明材料')
  127. isNull = true
  128. }
  129. if (this.moreMaterial?.length > 0) {
  130. let isExist = this.moreMaterial.every(item => item?.url == '' || !item?.url)
  131. if (isExist) {
  132. msgList.push('其他材料')
  133. isNull = true
  134. }
  135. }
  136. if (this.unitMaterial.url == '' || !this.unitMaterial.url) {
  137. msgList.push('申报单位承诺意见')
  138. isNull = true
  139. }
  140. if (isNull) {
  141. // this.msg.create('error', `请上传完整 ${msgList.join()}`)
  142. }
  143. return isNull
  144. }
  145. /**判断是否存在未填字段 */
  146. isIgnoreFiledNull() {
  147. let selectList = this.eduTextbook?.get('characteristic')
  148. let check = false
  149. for (let i in selectList) {
  150. if (selectList[i].label == '通识课' || selectList[i].label == '公共基础课' || selectList[i].label == '专业课') {
  151. if (selectList[i].checked) {
  152. check = true
  153. break;
  154. }
  155. }
  156. }
  157. if (!check) {
  158. // this.msg.create('warning', '请返回选择适用课程性质')
  159. return true
  160. }
  161. let eduColumn = eduTextBook.EduTextbook.fields
  162. let ignoreFiled = [
  163. 'typeNumber', 'code', 'editionNumber', 'importantProjectOther',
  164. 'textbookFiles', 'createdAt', 'updatedAt', 'copyright', 'authorSign',
  165. 'CIP', 'isDeleted', 'opinions', 'printNumber', 'printSum', 'render',
  166. 'importantProject', 'importantProjectOther', 'complete', 'links', 'recommend',
  167. 'printSun', 'discard', 'edition', 'eduProcess', 'authors', 'editor',
  168. 'copyrightImgUrl', 'CIPImgurl', 'selfResults', 'expertOpinion', 'evidence',
  169. 'moreMaterial', 'unitMaterial', 'approvedImgUrl', 'department'
  170. ] //非必填字段
  171. let textBookJson = this.eduTextbook.toJSON()
  172. let isVrifly = Object.keys(eduColumn).some((item: string) => {
  173. if (!ignoreFiled.includes(item) && (textBookJson[item] === '' || textBookJson[item] === undefined || textBookJson[item] === null)) {
  174. console.warn('字段未填写:' + item)
  175. return true
  176. }
  177. return
  178. })
  179. if (isVrifly) {
  180. this.msg.warning('存在未填项')
  181. return true
  182. } else {
  183. return false
  184. }
  185. }
  186. async submitForm(event?: string): Promise<void> {
  187. let params = {
  188. copyrightImgUrl: this.copyrightImgUrl,
  189. CIPImgUrl: this.CIPImgUrl,
  190. selfResults: this.selfResults,
  191. expertOpinion: this.expertOpinion,
  192. evidence: this.evidence,
  193. moreMaterial: this.moreMaterial,
  194. unitMaterial: this.unitMaterial,
  195. }
  196. await this.saveEduTextbook(params, true);
  197. if (event == 'pre') {//上一步
  198. this.state.emit({ type: 'pre' });
  199. return;
  200. }
  201. if (event == 'complete') {
  202. this.state.emit({ type: 'complete', textBook: this.eduTextbook });
  203. let isPageNull = this.examineNull()//检查本页空项
  204. let isIgnoreFiled = this.isIgnoreFiledNull()//检查数据空项
  205. if (isPageNull || isIgnoreFiled) {
  206. } else {
  207. this.eduTextbook.set('complete', true)
  208. this.eduTextbook.set('status', '102')
  209. await this.eduTextbook.save()
  210. this.msg.success('已填写完成')
  211. }
  212. this.router.navigate(['/nav-author/manage/space'])
  213. } else if (event == 'save') {
  214. this.modal.success({
  215. nzTitle: '保存成功',
  216. nzContent: '<p>已保存并且至空间</p>',
  217. nzOnOk: () => console.log('Info OK'),
  218. });
  219. return;
  220. }
  221. }
  222. async saveEduTextbook(params: any, isComplete: boolean) {
  223. if (!this.eduTextbook) {
  224. this.msg.error('请先创建教材');
  225. return;
  226. }
  227. //如果填写未完整,仅保存,状态修改待完善101
  228. if (this.eduTextbook.get('status') == '102' && !isComplete) {
  229. this.eduTextbook?.set('status', '101');
  230. } else if (!this.eduTextbook.get('status')) {
  231. this.eduTextbook?.set('status', '101');
  232. }
  233. this.eduTextbook?.set('user', Parse.User.current()?.toPointer());
  234. this.eduTextbook?.set('company', {
  235. __type: 'Pointer',
  236. className: 'Company',
  237. objectId: this.tbookSer.company,
  238. });
  239. params.selfResults &&
  240. this.eduTextbook?.set('selfResults', params.selfResults);
  241. params.unitMaterial &&
  242. this.eduTextbook?.set('unitMaterial', params.unitMaterial);
  243. params.expertOpinion &&
  244. this.eduTextbook?.set('expertOpinion', params.expertOpinion);
  245. params.evidence && this.eduTextbook?.set('evidence', params.evidence);
  246. params.moreMaterial &&
  247. this.eduTextbook?.set('moreMaterial', params.moreMaterial);
  248. this.eduTextbook?.set('copyrightImgUrl', params.copyrightImgUrl);
  249. this.eduTextbook?.set('CIPImgUrl', params.CIPImgUrl);
  250. await this.eduTextbook?.save();
  251. return;
  252. }
  253. upload(e: any, type: string) {
  254. let file = e[(e?.length - 1) || 0];
  255. if (type == 'copyrightImgUrl' || type == 'CIPImgUrl') {
  256. this[type] = file?.url
  257. } else if (type == 'selfResults' || type == 'expertOpinion' ||
  258. type == 'evidence' || type == 'unitMaterial') {
  259. this[type].url = file?.url
  260. this[type].name = file?.name
  261. } else if (type == 'moreMaterial') {
  262. this[type] = [...(this[type] || []), { name: file.name, url: file.url }]
  263. }
  264. }
  265. /**获取文件名 */
  266. getFileName(url: string) {
  267. if (!url) return ''
  268. let str = url?.split('/')[5]
  269. let index = str?.indexOf('-')
  270. let result = decodeURIComponent(str?.substring(index + 1))
  271. return result || '未知文件名'
  272. }
  273. downloadFile(fileName: string) {
  274. // let fileName = '十四五”普通高等教育本科国家级规划教材第一次遴选推荐申报表.docx'
  275. const fileUrl = `../../../../../public/file/${fileName}`;
  276. this.http.get(fileUrl, { responseType: 'blob' }).subscribe((blob) => {
  277. const url = window.URL.createObjectURL(blob);
  278. const a = document.createElement('a');
  279. a.href = url;
  280. a.download = fileName;
  281. document.body.appendChild(a);
  282. a.click();
  283. document.body.removeChild(a);
  284. window.URL.revokeObjectURL(url);
  285. })
  286. }
  287. openFile(url: string) {
  288. console.log(url);
  289. window.open(url)
  290. }
  291. }