Quellcode durchsuchen

update 上传组件类型

warrior vor 8 Monaten
Ursprung
Commit
e12f46ae26

+ 1 - 1
docker-front

@@ -1 +1 @@
-Subproject commit fa9142c46427d306cdc0025ef9466717265d83e3
+Subproject commit 670fb82d36d8c078793a4f4dbf7b1b399924573b

+ 164 - 113
projects/textbook/src/modules/nav-author/components/attachment/attachment.component.html

@@ -1,129 +1,180 @@
 <div class="entry">
   <!-- <form nz-form [formGroup]="validateForm" class="login-form" (ngSubmit)="submitForm()"> -->
-    <div class="author-content">
-      <div class="title">教材版权信息</div>
-      <nz-form-item class="row" style="margin-bottom: 16px">
-        <nz-form-label class="label" [nzNoColon]="true" [nzSm]="10" [nzXs]="10" nzRequired>版权页截图</nz-form-label>
-        <nz-form-control class="val" nzErrorTip="请上传版权页截图" style="width: 100%">
-          @if (copyrightImgUrl) {
-            <a style="color: #3e49b3;" (click)="openFile(copyrightImgUrl)">
-              <span nz-icon nzType="file" nzTheme="outline"></span>
-              版权页截图
-            </a>
-          }
-          <app-comp-upload [type]="'pdf'" [width]="320" (change)="upload($event, 'copyrightImgUrl')" title="上传PDF"></app-comp-upload>
+  <div class="author-content">
+    <div class="title">教材版权信息</div>
+    <nz-form-item class="row" style="margin-bottom: 16px">
+      <nz-form-label class="label" [nzNoColon]="true" [nzSm]="10" [nzXs]="10" nzRequired>版权页截图</nz-form-label>
+      <nz-form-control class="val" nzErrorTip="请上传版权页截图" style="width: 100%">
+        @if (copyrightImgUrl) {
+        <a style="color: #3e49b3;" (click)="openFile(copyrightImgUrl)">
+          <span nz-icon nzType="file" nzTheme="outline"></span>
+          版权页截图
+        </a>
+        }
+        <app-comp-upload [width]="320" [type]="'pdf'" (change)="upload($event, 'copyrightImgUrl')" title="上传PDF"></app-comp-upload>
+
+        <div class="text upText" style="margin: 10px 0">
+          支持上传PDF,大小不超过 2M
+        </div>
+      </nz-form-control>
+    </nz-form-item>
+    
+    <nz-form-item class="row" style="margin-bottom: 16px">
+      <nz-form-label class="label" [nzNoColon]="true" [nzSm]="10" [nzXs]="10" nzRequired>中国版本图书馆 CIP
+        查询截图</nz-form-label>
+      <nz-form-control class="val" nzErrorTip="请上传中国版本图书馆 CIP 查询截图" style="width: 100%">
+        @if (CIPImgUrl) {
+        <a style="color: #3e49b3;" (click)="openFile(CIPImgUrl)">
+          <span nz-icon nzType="file" nzTheme="outline"></span>
+          CIP 查询截图
+        </a>
+        }
+        <app-comp-upload [width]="320" (change)="upload($event, 'CIPImgUrl')" title="上传PDF"></app-comp-upload>
+
+        <div class="text upText" style="margin: 10px 0">
+          支持批量上传 PDF 格式,单个文件大小不超过 2M。
+        </div>
+      </nz-form-control>
+    </nz-form-item>
+
 
-          <div class="text upText" style="margin: 10px 0">
-            支持上传PDF,大小不超过 2M
-          </div>
-        </nz-form-control>
-      </nz-form-item>
-      <nz-form-item class="row" style="margin-bottom: 16px">
-        <nz-form-label class="label" [nzNoColon]="true" [nzSm]="10" [nzXs]="10" nzRequired>中国版本图书馆 CIP
-          查询截图</nz-form-label>
-        <nz-form-control class="val" nzErrorTip="请上传中国版本图书馆 CIP 查询截图" style="width: 100%">
-          @if (CIPImgUrl) {
-            <a style="color: #3e49b3;" (click)="openFile(CIPImgUrl)">
-              <span nz-icon nzType="file" nzTheme="outline"></span>
-              CIP 查询截图
-            </a>
-          }
-          <app-comp-upload [width]="320" (change)="upload($event, 'CIPImgUrl')" title="上传PDF"></app-comp-upload>
 
-          <div class="text upText" style="margin: 10px 0">
-            支持批量上传 PDF 格式,单个文件大小不超过 2M。如 CIP 数据中无“教材”字样的,须再上传内容提要或前言或后记中可以证明本书为教材的相关内容截图
-          </div>
-        </nz-form-control>
-      </nz-form-item>
-    </div>
     <div class="author-content">
-      <div class="title">图书编校质量自查结果记录表</div>
-      <div class="text">
-        教材出版单位对申报教材的编校质量自查后,按要求提供图书编校质量自查结果记录表,并加盖出版社公章。全册教材的不同分册以不同文件分别上传。<a (click)="downloadFile('图书编校质量自查结果记录表.docx')">下载模板</a>
+      <div class="text">如 CIP 数据中无“教材”字样的,须再上传内容提要或前言或后记中可以证明本书为教材的相关内容截图</div>
+      @if (cipProveFile.length>0) {
+      @for (url of cipProveFile; track $index) {
+      <p>
+        <a style="color: #3e49b3;font-size: 14px;" (click)="openFile(url?.url)">
+          <span nz-icon nzType="file" nzTheme="outline"></span>
+          CIP 相关截图 {{$index+1}}
+        </a>
+      </p>
+      }
+      }
+      <app-comp-upload [width]="320" [maxlenght]="99" (change)="upload($event, 'cipProveFile')"
+        title="上传PDF"></app-comp-upload>
+  
+      <div class="text upText" style="margin: 10px 0">
+        支持上传PDF,大小不超过 2M
       </div>
-      <nz-form-item class="row" style="margin-bottom: 16px">
-        <nz-form-label class="label" [nzNoColon]="true" [nzSm]="10" [nzXs]="10"
-          nzRequired>上传图书编校质量自查结果记录表</nz-form-label>
-        <nz-form-control class="val" nzErrorTip="请上图书编校质量自查结果记录表" style="width: 100%">
-          @if (selfResults?.url) {
-            <a style="color: #3e49b3;" (click)="openFile(selfResults?.url)">
-              <span nz-icon nzType="file" nzTheme="outline"></span>
-              自查结果记录表
-            </a>
-          }
-          <app-comp-upload [width]="320" (change)="upload($event, 'selfResults')" title="上传PDF"></app-comp-upload>
-          <div class="text upText" style="margin: 10px 0">
-            支持上传PDF,大小不超过 2M
-          </div>
-        </nz-form-control>
-      </nz-form-item>
     </div>
-    <div class="author-content">
-      <div class="title">专家审查意见表</div>
-      <div class="text">
-        由第一主编所在单位和出版机构邀请校内外相关学科专业领域专家,对教材进行思想性、学术性审核。专家不少于
-        3
-        名,其中半数以上为校外专家,专家分别实名评价并签字,并注明所在单位及专业身份。评价人不得是本教材的作者。<a (click)="downloadFile('专家审查意见表.docx')">下载模板</a>
-      </div>
-      <nz-form-item class="row" style="margin-bottom: 16px">
-        <nz-form-label class="label" [nzNoColon]="true" [nzSm]="10" [nzXs]="10" nzRequired>上传专家审查意见表</nz-form-label>
-        <nz-form-control class="val" nzErrorTip="请上传专家审查意见表" style="width: 100%">
-          @if (expertOpinion?.url) {
-            <a style="color: #3e49b3;" (click)="openFile(expertOpinion?.url)">
-              <span nz-icon nzType="file" nzTheme="outline"></span>
-              专家审查意见表
-            </a>
-          }
-          <app-comp-upload [width]="320" (change)="upload($event, 'expertOpinion')" title="上传PDF"></app-comp-upload>
-          <div class="text upText" style="margin: 10px 0">
-            支持批量上传 PDF、JPG、JPEG、PNG 格式,单个大小不超过 2M
-          </div>
-        </nz-form-control>
-      </nz-form-item>
+
+
+
+
+
+  </div>
+  <div class="author-content">
+    <div class="title">图书编校质量自查结果记录表</div>
+    <div class="text">
+      教材出版单位对申报教材的编校质量自查后,按要求提供图书编校质量自查结果记录表,并加盖出版社公章。全册教材的不同分册以不同文件分别上传。<a
+        (click)="downloadFile('图书编校质量自查结果记录表.docx')">下载模板</a>
     </div>
-    <div class="author-content">
-      <div class="title">教材使用情况证明材料</div>
-      <div class="text">
-        教材出版单位提供教材主要使用高校名单及使用情况证明材料,并加盖公章。
-        <!-- <a (click)="downloadFile('专家审查意见表.docx')">下载模板</a> -->
-      </div>
-      <nz-form-item class="row" style="margin-bottom: 16px">
-        <nz-form-label class="label" [nzNoColon]="true" [nzSm]="10" [nzXs]="10" nzRequired>教材使用情况证明材料</nz-form-label>
-        <nz-form-control class="val" nzErrorTip="请上教材使用情况证明材料" style="width: 100%">
-          @if (evidence?.url) {
-            <a style="color: #3e49b3;" (click)="openFile(evidence?.url)">
-              <span nz-icon nzType="file" nzTheme="outline"></span>
-              证明材料
-            </a>
-          }
-          <app-comp-upload [width]="320" (change)="upload($event, 'evidence')" title="上传PDF"></app-comp-upload>
-          <div class="text upText" style="margin: 10px 0">
-            支持上传PDF,大小不超过 2M
-          </div>
-        </nz-form-control>
-      </nz-form-item>
+    <nz-form-item class="row" style="margin-bottom: 16px">
+      <nz-form-label class="label" [nzNoColon]="true" [nzSm]="10" [nzXs]="10" nzRequired>上传图书编校质量自查结果记录表</nz-form-label>
+      <nz-form-control class="val" nzErrorTip="请上图书编校质量自查结果记录表" style="width: 100%">
+        @if (selfResults?.url) {
+        <a style="color: #3e49b3;" (click)="openFile(selfResults?.url)">
+          <span nz-icon nzType="file" nzTheme="outline"></span>
+          自查结果记录表
+        </a>
+        }
+        <app-comp-upload [width]="320" (change)="upload($event, 'selfResults')" title="上传PDF"></app-comp-upload>
+        <div class="text upText" style="margin: 10px 0">
+          支持上传PDF,大小不超过 2M
+        </div>
+      </nz-form-control>
+    </nz-form-item>
+  </div>
+  <div class="author-content">
+    <div class="title">专家审查意见表</div>
+    <div class="text">
+      由第一主编所在单位和出版机构邀请校内外相关学科专业领域专家,对教材进行思想性、学术性审核。专家不少于
+      3
+      名,其中半数以上为校外专家,专家分别实名评价并签字,并注明所在单位及专业身份。评价人不得是本教材的作者。<a (click)="downloadFile('专家审查意见表.docx')">下载模板</a>
     </div>
-    <div class="author-content">
-      <div class="title">其他材料</div>
-      <div class="text">其他佐证材料。</div>
-      @if (moreMaterial.length>0) {
-        @for (url of moreMaterial; track $index) {
-          <p>
-            <a style="color: #3e49b3;" (click)="openFile(url?.url)">
-              <span nz-icon nzType="file" nzTheme="outline"></span>
-              佐证材料 {{$index+1}}
-            </a>
-          </p>
+    <nz-form-item class="row" style="margin-bottom: 16px">
+      <nz-form-label class="label" [nzNoColon]="true" [nzSm]="10" [nzXs]="10" nzRequired>上传专家审查意见表</nz-form-label>
+      <nz-form-control class="val" nzErrorTip="请上传专家审查意见表" style="width: 100%">
+        @if (expertOpinion?.url) {
+        <a style="color: #3e49b3;" (click)="openFile(expertOpinion?.url)">
+          <span nz-icon nzType="file" nzTheme="outline"></span>
+          专家审查意见表
+        </a>
         }
-      }
-      <app-comp-upload [width]="320" [maxlenght]="99" (change)="upload($event, 'moreMaterial')" title="上传PDF"></app-comp-upload>
+        <app-comp-upload [width]="320" (change)="upload($event, 'expertOpinion')" title="上传PDF"></app-comp-upload>
+        <div class="text upText" style="margin: 10px 0">
+          支持批量上传 PDF、JPG、JPEG、PNG 格式,单个大小不超过 2M
+        </div>
+      </nz-form-control>
+    </nz-form-item>
+  </div>
+  <div class="author-content">
+    <div class="title">教材使用情况证明材料</div>
+    <div class="text">
+      教材出版单位提供教材主要使用高校名单及使用情况证明材料,并加盖公章。
+      <!-- <a (click)="downloadFile('专家审查意见表.docx')">下载模板</a> -->
+    </div>
+    <nz-form-item class="row" style="margin-bottom: 16px">
+      <nz-form-label class="label" [nzNoColon]="true" [nzSm]="10" [nzXs]="10" nzRequired>教材使用情况证明材料</nz-form-label>
+      <nz-form-control class="val" nzErrorTip="请上教材使用情况证明材料" style="width: 100%">
+        @if (evidence?.url) {
+        <a style="color: #3e49b3;" (click)="openFile(evidence?.url)">
+          <span nz-icon nzType="file" nzTheme="outline"></span>
+          证明材料
+        </a>
+        }
+        <app-comp-upload [width]="320" (change)="upload($event, 'evidence')" title="上传PDF"></app-comp-upload>
+        <div class="text upText" style="margin: 10px 0">
+          支持上传PDF,大小不超过 2M
+        </div>
+      </nz-form-control>
+    </nz-form-item>
+  </div>
+  <div class="author-content">
+    <div class="title">其他材料</div>
+    <div class="text">其他佐证材料。</div>
+    @if (moreMaterial.length>0) {
+    @for (url of moreMaterial; track $index) {
+    <p>
+      <a style="color: #3e49b3;font-size: 14px;" (click)="openFile(url?.url)">
+        <span nz-icon nzType="file" nzTheme="outline"></span>
+        佐证材料 {{$index+1}}
+      </a>
+    </p>
+    }
+    }
+    <app-comp-upload [width]="320" [maxlenght]="99" (change)="upload($event, 'moreMaterial')"
+      title="上传PDF"></app-comp-upload>
 
-      <div class="text upText" style="margin: 10px 0">
-        支持上传PDF,大小不超过 2M
-      </div>
+    <div class="text upText" style="margin: 10px 0">
+      支持上传PDF,大小不超过 2M
     </div>
+  </div>
+  <div class="author-content">
+    <div class="title">作者政治审核表</div>
+    <div class="text">
+      <span style="color: red;">*</span> 作者政治审核表
+      <a (click)="downloadFile('教材编写人员政治审查表.docx')">下载模板</a>
+    </div>
+    @if (examine.length>0) {
+    @for (url of examine; track $index) {
+    <p>
+      <a style="color: #3e49b3;font-size: 14px;" (click)="openFile(url?.url)">
+        <span nz-icon nzType="file" nzTheme="outline"></span>
+        作者政治审核表 {{$index+1}}
+      </a>
+    </p>
+    }
+    }
+    <app-comp-upload [width]="320" [maxlenght]="99" (change)="upload($event, 'examine')"
+      title="上传PDF"></app-comp-upload>
 
-    <!-- <div class="author-content">
+    <div class="text upText" style="margin: 10px 0">
+      支持上传PDF,大小不超过 2M
+    </div>
+  </div>
+  <!-- <div class="author-content">
       <div class="nav"><b>申报单位承诺意见</b></div>
       <div class="text">
         作者 /

+ 50 - 7
projects/textbook/src/modules/nav-author/components/attachment/attachment.component.ts

@@ -24,7 +24,7 @@ import {
 import { textbookServer } from '../../../../services/textbook';
 import * as eduTextBook from '../../../../services/EduTextbook'
 import { HttpClient } from '@angular/common/http';
-import { Router} from '@angular/router'
+import { Router } from '@angular/router'
 
 
 
@@ -69,6 +69,8 @@ export class AttachmentComponent implements OnInit {
   copyrightImgUrl: string = ''
   /** 中国版本图书馆CIP查询截图*/
   CIPImgUrl: string = ''
+  /**cip证明材料 {name: '',url: '',} */
+  cipProveFile: Array<any> = []
   /**图书编校质量自查结果记录表 */
   selfResults: any = {
     name: '',
@@ -93,12 +95,17 @@ export class AttachmentComponent implements OnInit {
     url: '',
   }
 
+
+  /**作者政治审核表 {name: '',url: '',} */
+  examine: Array<any> = []
+
+
   constructor(
     public tbookSer: textbookServer,
     private msg: NzMessageService,
     private modal: NzModalService,
     private http: HttpClient,
-    private router:Router
+    private router: Router
   ) { }
   ngOnInit() {
     if (this.eduTextbook.id) {
@@ -108,7 +115,9 @@ export class AttachmentComponent implements OnInit {
       this.expertOpinion = this.eduTextbook?.get('expertOpinion') || this.expertOpinion
       this.evidence = this.eduTextbook?.get('evidence') || this.evidence
       this.moreMaterial = this.eduTextbook?.get('moreMaterial') || this.moreMaterial
+      this.cipProveFile = this.eduTextbook?.get('cipProveFile') || this.cipProveFile
       this.unitMaterial = this.eduTextbook?.get('unitMaterial') || this.unitMaterial
+      this.examine = this.eduTextbook?.get('examine') || this.examine
     }
   }
 
@@ -121,9 +130,27 @@ export class AttachmentComponent implements OnInit {
       isNull = true
     }
     if (this.CIPImgUrl == '' || !this.CIPImgUrl) {
-      msgList.push('CIP查询截图')
-      isNull = true
-    }
+      if (this.cipProveFile?.length > 0) {
+        let isExist = this.cipProveFile.every(item => item?.url == '' || !item?.url)
+        if (isExist) {
+          msgList.push('CIP 相关内容截图')
+          isNull = true
+        }
+      } else {
+          msgList.push('CIP 查询截图')
+          isNull = true
+      }
+    } 
+    // if (this.CIPImgUrl == '' || !this.CIPImgUrl) {
+    //   msgList.push('CIP查询截图')
+    //   isCipNull = true
+    // }else if (this.cipProveFile?.length > 0) {
+    //   let isExist = this.cipProveFile.every(item => item?.url == '' || !item?.url)
+    //   if (isExist) {
+    //     msgList.push('CIP证明材料')
+    //     isNull = true
+    //   }
+    // }
     if (this.selfResults.url == '' || !this.selfResults.url) {
       msgList.push('自查结果记录表')
       isNull = true
@@ -143,6 +170,16 @@ export class AttachmentComponent implements OnInit {
         isNull = true
       }
     }
+    if (this.examine?.length <= 0) {
+      isNull = true
+      msgList.push('作者政治审核表')
+    } else if (this.examine?.length > 0) {
+      let isExist = this.examine.every(item => item?.url == '' || !item?.url)
+      if (isExist) {
+        msgList.push('作者政治审核表')
+        isNull = true
+      }
+    }
     // if (this.unitMaterial.url == '' || !this.unitMaterial.url) {
     //   msgList.push('申报单位承诺意见')
     //   isNull = true
@@ -178,7 +215,7 @@ export class AttachmentComponent implements OnInit {
       'importantProject', 'importantProjectOther', 'complete', 'links', 'recommend',
       'printSun', 'discard', 'edition', 'eduProcess', 'authors', 'editor',
       'copyrightImgUrl', 'CIPImgurl', 'selfResults', 'expertOpinion', 'evidence',
-      'moreMaterial', 'unitMaterial', 'approvedImgUrl', 'department'
+      'moreMaterial', 'unitMaterial', 'approvedImgUrl', 'department','CIPImgUrl','cipProveFile'
     ] //非必填字段
     let textBookJson = this.eduTextbook.toJSON()
 
@@ -202,10 +239,12 @@ export class AttachmentComponent implements OnInit {
     let params = {
       copyrightImgUrl: this.copyrightImgUrl,
       CIPImgUrl: this.CIPImgUrl,
+      cipProveFile: this.cipProveFile,
       selfResults: this.selfResults,
       expertOpinion: this.expertOpinion,
       evidence: this.evidence,
       moreMaterial: this.moreMaterial,
+      examine: this.examine,
       // unitMaterial: this.unitMaterial,
     }
     await this.saveEduTextbook(params, true);
@@ -262,8 +301,12 @@ export class AttachmentComponent implements OnInit {
     params.expertOpinion &&
       this.eduTextbook?.set('expertOpinion', params.expertOpinion);
     params.evidence && this.eduTextbook?.set('evidence', params.evidence);
+    params.cipProveFile &&
+      this.eduTextbook?.set('cipProveFile', params.cipProveFile);
     params.moreMaterial &&
       this.eduTextbook?.set('moreMaterial', params.moreMaterial);
+    params.examine &&
+      this.eduTextbook?.set('examine', params.examine);
     this.eduTextbook?.set('copyrightImgUrl', params.copyrightImgUrl);
     this.eduTextbook?.set('CIPImgUrl', params.CIPImgUrl);
     await this.eduTextbook?.save();
@@ -277,7 +320,7 @@ export class AttachmentComponent implements OnInit {
       type == 'evidence' || type == 'unitMaterial') {
       this[type].url = file?.url
       this[type].name = file?.name
-    } else if (type == 'moreMaterial') {
+    } else if (type == 'moreMaterial' || type == 'examine' || type == 'cipProveFile') {
       this[type] = [...(this[type] || []), { name: file.name, url: file.url }]
     }
   }

+ 80 - 0
server/cloud/aliyun/func-aliyun-sms.js

@@ -0,0 +1,80 @@
+
+const sms = require("ali-sms");
+const SMSAccessKeyID     = process.env.ALI_SMS_ACCESSKEYID || "LTAI5tETwA37KgHfDo5p2Ej6";
+const SMSAccessKeySecret = process.env.ALI_SMS_ACCESSKEYSECRET || "EBDQEchETlNcEYzE8zYb1zl4gBImrJ";
+
+/**
+ * @desc
+ curl -X POST -H "Content-Type: application/json" -H 'X-Parse-Application-Id: edu-textbook' http://8.140.98.43/parse/functions/aliSmsSend
+ curl -X POST -H "Content-Type: application/json" -H 'X-Parse-Application-Id: edu-textbook' -d '{ "mobileList": ["18607007073"],"templateCode":"SMS_468995773","params":{},"signName":"普通高等教育教材网" }' http://127.0.0.1:61337/parse/functions/aliSmsSend
+ * @returns
+ 成功
+ {"result":"{\"Message\":\"OK\",\"RequestId\":\"41DDC6F4-A8B8-55A3-95E7-AD06D3F0E94F\",\"Code\":\"OK\",\"BizId\":\"261804722010619993^0\"}"}
+ 失败
+ {"result":"{\"Message\":\"手机号码格式错误\",\"RequestId\":\"63C4A4DB-B337-5630-8E00-51535C7377D7\",\"Code\":\"isv.MOBILE_NUMBER_ILLEGAL\"}"}
+
+ */
+ export function defineAliSMSSend(){
+    // function defineAuthingLogin(){
+        Parse.Cloud.define("aliSmsSend", async (request) => {
+            let mobileList = request.params.mobileList;
+            let signName = request.params.signName;
+            let params = request.params.params;
+            let templateCode = request.params.templateCode;
+            
+            let result = await sendAliyunSMS({
+                signName:signName,
+                mobileList:mobileList,
+                params:params,
+                templateCode:templateCode
+                
+            })
+            return result
+        },{
+            fields : {
+                mobileList:{
+                    required:true
+                },
+                params:{
+                    required:true
+                },
+                signName:{
+                    required:true
+                },
+                templateCode:{
+                    required:true
+                },
+            }
+        });
+}
+
+
+/**
+ * @desc
+    手机号解绑验证码 SMS_469065757
+    手机号修改验证码 SMS_469055726
+    手机号绑定验证码 SMS_468890757
+    密码重置验证码 SMS_468915747
+    账号认证失败通知 SMS_468995773
+    账号认证成功通知 SMS_468870790
+    账号注册通知 SMS_469060724
+ */
+async function sendAliyunSMS(options){
+    return new Promise(resolve=>{
+        const config = {
+            accessKeyID       : SMSAccessKeyID,
+            accessKeySecret   : SMSAccessKeySecret,
+            paramString       : {code: '123456'},
+            recNum            : ['18691770343','18607007073'],
+            signName          : '普通高等教育教材网',
+            templateCode      : 'SMS_468870790',
+        };
+        sms(config, (err, body) => {
+            console.log(err, body);
+            resolve(body||err)
+        });
+    })
+
+}
+
+module.exports.sendAliyunSMS = sendAliyunSMS()

+ 34 - 0
server/cloud/aliyun/sms.md

@@ -0,0 +1,34 @@
+
+# 开发参数
+阿里云hep-api-authing-sms@cloudhep.onaliyun.com
+AccessKey ID LTAI5tETwA37KgHfDo5p2Ej6
+AccessKey Secret EBDQEchETlNcEYzE8zYb1zl4gBImrJ
+
+手机号解绑验证码:SMS_469065757
+手机号修改验证码:SMS_469055726
+手机号绑定验证码:SMS_468890757
+密码重置验证码:SMS_468915747
+账号认证失败通知:SMS_468995773
+账号认证成功通知:SMS_468870790
+账号注册通知:SMS_469060724
+
+
+
+
+# 示例样板
+
+【普通高等教育教材网】账号注册通知:您已经成功注册,请耐心等待审核认证结果,待认证通过后即可登录。
+
+【普通高等教育教材网】账号认证成功通知:您的账号已经通过认证,可使用注册时的账号密码登录系统使用管理功能。
+
+【普通高等教育教材网】账号认证失败通知:抱歉,您申请的账号认证失败,请仔细核对相关信息和材料后再尝试。
+
+【普通高等教育教材网】您的密码重置验证码是:${code}, 5分钟内有效。请勿将验证码告知他人并确定该申请为您本人操作。
+
+【普通高等教育教材网】您的手机号绑定验证码是:${code}, 5分钟内有效。请勿将验证码告知他人并确定该申请为您本人操作。
+
+【普通高等教育教材网】您在的手机号修改验证码是:${code}, 5分钟内有效。请勿将验证码告知他人并确定该申请为您本人操作。
+
+【普通高等教育教材网】您的手机号解绑验证码是:${code}, 5分钟内有效。请勿将验证码告知他人并确定该申请为您本人操作。
+
+

+ 22 - 4
server/cloud/tbook/func-tbook-export.js

@@ -196,16 +196,34 @@ function padString(str,width) {
     width = width || 21 // 目标宽度为21个单位
     spaceChar = "&#160;" // 占位符
     // 计算字符串的宽度
+    const charWidth = {
+        'space': 1, // 空格占用1个单位
+        'zh': 2,    // 汉字占用2个单位
+        'en': 1,    // 英文字母占用1个单位
+        'other': 1  // 其他字符(如标点符号)占用1个单位
+    };
     let strWidth = 0;
     console.log(str)
+    // 遍历文本中的每个字符
     for (let char of str) {
-        // 判断字符是否为中文
-        if (char.match(/[\u4e00-\u9fa5]/)) {
-            strWidth += 2; // 中文字符占4个单位
+        if (/\s/.test(char)) {
+            strWidth += charWidth.space; // 空格
+        } else if (/[\u4e00-\u9fa5]/.test(char)) {
+            strWidth += charWidth.zh; // 汉字
+        } else if (/[a-zA-Z]/.test(char)) {
+            strWidth += charWidth.en; // 英文字母
         } else {
-            strWidth += 1; // 英文字符占1个单位
+            strWidth += charWidth.other; // 其他字符
         }
     }
+    // for (let char of str) {
+    //     // 判断字符是否为中文
+    //     if (char.match(/[\u4e00-\u9fa5]/)) {
+    //         strWidth += 2; // 中文字符占4个单位
+    //     } else {
+    //         strWidth += 1; // 英文字符占1个单位
+    //     }
+    // }
 
     const totalPadding = width - strWidth;
     // 如果已经达到或超过目标宽度,直接返回原字符串

+ 36 - 0
server/package-lock.json

@@ -10,6 +10,7 @@
       "license": "ISC",
       "dependencies": {
         "ali-oss": "^6.20.0",
+        "ali-sms": "^1.0.3",
         "authing-js-sdk": "^4.23.51",
         "authing-node-sdk": "^3.1.0",
         "chromiumly": "^3.6.0",
@@ -3563,6 +3564,41 @@
         "node": ">=4.0.0"
       }
     },
+    "node_modules/ali-sms": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmmirror.com/ali-sms/-/ali-sms-1.0.3.tgz",
+      "integrity": "sha512-D9uF3YNTUs+ZK6nHtZcOPJMd1d6uvzjqKb+cAg9GpFw4X6OqZE4buuuqtV6T6dOXUyYAWw9toj9hULLzzZ9PXg==",
+      "dependencies": {
+        "debug": "^2.3.3",
+        "request": "^2.79.0",
+        "uuid": "^3.1.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ali-sms/node_modules/debug": {
+      "version": "2.6.9",
+      "resolved": "https://registry.npmmirror.com/debug/-/debug-2.6.9.tgz",
+      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+      "dependencies": {
+        "ms": "2.0.0"
+      }
+    },
+    "node_modules/ali-sms/node_modules/ms": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/ms/-/ms-2.0.0.tgz",
+      "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
+    },
+    "node_modules/ali-sms/node_modules/uuid": {
+      "version": "3.4.0",
+      "resolved": "https://registry.npmmirror.com/uuid/-/uuid-3.4.0.tgz",
+      "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==",
+      "deprecated": "Please upgrade  to version 7 or higher.  Older versions may use Math.random() in certain circumstances, which is known to be problematic.  See https://v8.dev/blog/math-random for details.",
+      "bin": {
+        "uuid": "bin/uuid"
+      }
+    },
     "node_modules/ansi-escapes": {
       "version": "4.3.2",
       "resolved": "https://registry.npmmirror.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz",

+ 1 - 0
server/package.json

@@ -29,6 +29,7 @@
   "license": "ISC",
   "dependencies": {
     "ali-oss": "^6.20.0",
+    "ali-sms": "^1.0.3",
     "authing-js-sdk": "^4.23.51",
     "authing-node-sdk": "^3.1.0",
     "chromiumly": "^3.6.0",

+ 2 - 0
server/server.js

@@ -44,6 +44,7 @@ global.config["LOCAL"] = argv.local || process.env["LOCAL"] || appConfig["LOCAL"
 
 import  {textbookRouter} from "./api/textbook/routes";
 import { defineAliOssSTS } from "./cloud/aliyun"
+import { defineAliSMSSend } from "./cloud/aliyun/func-aliyun-sms"
 import { defineAuthingLogin, defineDepartmentTrigger, defineUserAfterDelete, defineUserBeforeSave } from "./cloud/authing"
 import { defineAuthingDepartSync } from "./cloud/authing"
 import { defineUserAfterSave } from "./cloud/authing"
@@ -183,6 +184,7 @@ async function initParseAndDatabase(){
       defineAuthingLogin();
       defineAuthingDepartSync();
       defineAliOssSTS();
+      defineAliSMSSend();
       defineUserAfterSave();
       defineUserBeforeSave();
       defineUserAfterDelete();