# 145教材系统技术文档 ## 一、技术语言和框架 #### 数据库和数据表 - 数据库:[PostgreSQL](https://www.postgresql.org/ "PostgreSQL") - 数据表 - _User【用户】 - Profile 【用户角色】 - Department 【单位部门】 - EduTextbook 【教材】 - EduTextbookVolume 【分册】 - Activity 【评审活动】 - Company 【公司】 - EduProcess 【流程】 - EduReview 【评审记录】 - ExpertGroup 【评审组】 ### 后端语言及框架 - 编写语言:JavaScript - 技术框架:[Node.js](https://bcn4fkmpxbdo.feishu.cn/wiki/N10SwNRbmi2lfCktmAacehxInzf#share-W6CqdCNP7oyKTMxFjKTcxSIgnYd "Node.js")、[Parse Server](https://parseplatform.org/parse-server/api/7.3.0/ "Parse") ### 前端语言及框架 - 编写语言:TypeScript、HTML、SCSS - 技术框架:Angular18、Vite、NG-ZORRO ## 二、客户端前端 ### 用户操作逻辑介绍 graph TB Start(开始) --> User[用户登录页] User --> Register[注册] User --> Login[用户登录] Register --> Regcomplete[注册成功] Regcomplete --> User Login --> Manage[登录成功进入后台] Manage --> LogOut[退出登录] LogOut --> End(结束) ### 身份权限 - 登录成功时存储本地缓存profile; - 通过profile.identity身份判断角色验证 - 全局采用路由守卫 [auth.guard.ts](projects\textbook\src\services\auth.guard.ts "Parse") ### 页面路由 - 入口路由文件:projects\textbook\src\app\app.routes.ts - 各个身份子路由 - user/login //默认路由 - nav-admin //国家级管理员管理平台 - nav-province-contact //工作联系人:中央部门所属高校联系人、部省合建高校联系人、出版单位联系人、省属高校流程管理员 - nav-province-school-contact //高校联系人 - nav-review //教材评审组成员 - nav-author //作者 / 教师 / 主编 ### 主组件 - app-comp-manage【全局组件】:登录成功后跳转后页面显示;包括左侧menu,通过optionsMap身份对应显示身份功能栏 - 附件下载功能函数:openFile、downloadFile - app-comp-nav 【个人信息组件】:页面左下角个人信息,包括退出登录功能 - app-comp-upload 【文件上传组件】 - provider-oss-aliyun 引入阿里OSS处理函数等,含公开转私有、私有转公开、临时链接等 - 重点传入参数 - @files:回显文件 - @acl 上传类型,是否加密 - 上传成功、失败、删除文件触发回调 - 函数`change`,返回fileList - app-textbook 【教材列表组件】 - 重点传入参数 - @filterObj 相关权限配置 - @uid 对应用户 - @eduProcess 流程id,verify存在时需要 - @discard 是否删除 - @recommend 是否推荐 - 重要函数解释 - `getTextbook`:获取教材列表重要函数,利用Parse.Query.fromJSON多条件查询,通过设定参数传入接口查询获取教材,满足全平台90%以上页面教材列表管理 - `getDepartment`:获取所有单位部门 - `reject`: 退回教材 - `del`:删除教材 - `updateStatus`:加入/移除推荐 - `submit`:提交教材 - `beforSubmit`:高校联系人提交教材至工作联系人 - `restore`:恢复教材 - `exportProcess`:导出教材;功能业务:导出推荐汇总表 - `submitted`:提交报送跳转,非直接请求报送教材接口 ### 各身份模块 ##### 用户登录 - parse-authing.ts 【登录服务类】 应用authing登录回调,返回获取登录结果 - initLoginModal 初始化登录模块 - app-login 登录页 - new ParseAuthing实例化authing登录服务,通过login成功后回调调用AuthServr服务类,profileVerify处理登录成功后函数 ``` let parseAuthing = new ParseAuthing({ // 监听事件:登陆成功后,返回用户信息 login:(user,authClient)=>{ console.log(user) console.log(Parse.User.current()); Parse.User.current()?.id && this.authServr.profileVerify(this.modal) }, beforeChangeModule:(data:any)=>{ if(data=='register'){ this.router.navigate(['/user/account_info']) } } }); parseAuthing.initLoginModal(); ``` ##### 作者/教师/主编 - 路由模块:`NavAuthorRoutingModule` - 组件(教材创建) - app-basic 【填写基本信息】 - 必填参数 - @eduTextbook 教材 - 主要函数方法 - `getEduTextbookVolumeList`:获取分册表 - `upload`:上传附件回调 - `saveEduTextbook`:保存教材信息 - 保存接口中判断是否填写完成 - 判断各分册填写及获取分册id代码 - 部分主要代码 ``` let eduTextbookVolumes = await this.saveEduTextbookVolume(this.eduTextbookId); console.log(eduTextbookVolumes?.isVrifly); console.log(eduTextbookVolumes.list); this.eduTextbook?.set('childrens', eduTextbookVolumes.list); this.eduTextbook?.set('typeNumber', eduTextbookVolumes.list.length); isComplete = isComplete && eduTextbookVolumes?.isVrifly; //如果填写未完整,仅保存,状态修改待完善101 if (this.eduTextbook.get('status') == '102' && !isComplete) { this.eduTextbook?.set('status', '101'); this.eduTextbook.set('complete', false); } else if (!this.eduTextbook.get('status')) { this.eduTextbook?.set('status', '101'); } if(isComplete){ this.eduTextbook.set('complete', true) } - `saveEduTextbookVolume`:上传分册数据 - 子组件调用 - 上传获批截图 ``` - 分册信息 ``` - app-textbook-pertain【填写教材适用情况】 - 必填参数 - @eduTextbook 教材 - 主要函数方法 - `saveEduTextbook`:保存教材信息 - `saveEduTextbookVolume`:上传分册数据 - 子组件调用 - 分册信息 ``` - app-textbook-content【填写教材内容】 - 必填参数 - @eduTextbook 教材 - 主要函数方法 - `saveEduTextbook`:保存教材信息 - `saveEduTextbookVolume`:上传分册数据 - 子组件调用 - 分册信息 ``` ``` - app-faith【填写教材内容】 - 必填参数 - @eduTextbook 教材 - 主要函数方法 - `saveEduTextbook`:保存教材信息 - `saveEduTextbookVolume`:上传分册数据 - `verify`:校验填写字段是否匹配 - app-attachment【上传附件材料】 - 必填参数 - @eduTextbook 教材 - 主要函数方法 - `saveEduTextbook`:保存教材信息 - `saveEduTextbookVolume`:上传分册数据 - `examineNull`:检查本页必填是否存在空项 - `isIgnoreFiledNull`:判断教材所有字段是否必填 - `upload`:上传附件回调 - 子组件调用 - app-comp-upload 附件上传组件 - 分册信息 ``` ``` - 个人空间:app-space - 调用组件:app-textbook - 主要函数:`getEduProcess` 获取教师所属单位的流程 - 创建教材:app-apply - 组件调用 - app-basic - app-textbook-pertain - app-textbook-content - app-faith - app-attachment - 应用代码 ``` @switch (state) { @case (0) { } @case (1) { } @case (2) { }@case (3) { } @case (4) { } } ``` - 回收站:app-recycle - 调用组件:app-textbook ``` ``` ##### 国家级管理员管理平台 - 路由模块:`NavAdminRoutingModule` - 组件 - app-collect-textbook 【教材文件收集列表】 - 必填参数 - @eduProcess 流程id - 主要函数方法 - `getTextbook`:获取教材 - `onEmitMsg`:短信提醒,提交状态置为100 - `onReject`:退回教材给出版社 - app-profile 【工作联系人】 - 必填参数 - depart:单位,用于查询本单位下注册联系人身份用户列表 - 主要函数方法 - `getProfile`:获取用户角色列表 - 全部教材:app-page-textbook - 调用组件 - app-textbook - app-collect-textbook: - app-collect-textbook - 申报流程:app-process-list - 功能说明 - 进入页面通过`getDepart`方法获取所有一级节点部门 - 点击左侧流程调用`getDepart`获取对应一级节点下全部流程,右侧显示流程table - table操作栏可对流程进行操作,可操作按钮通过statusMap状态判断 - 可通过`toUrl('/nav-admin/manage/process/create')`跳转创建流程页 - 主要参数说明 - `activeDepart`:当前编辑部门 - `eduProcessList`:流程列表 - `formatStatus`:格式化流程状态 - `formatFileStatus`:教材上传状态 - 主要函数方法 - `getDepart`:获取部门单位节点 - `getEduProcess`:获取部门列表 - `formatNode`:格式化链 - `statusSelected`:操作流程,开始、暂停、结束、删除 - `onStatusChange`:暂停流程 - `openEditCollect`:保存收集文件设置 - `sendNoticeMSG`:短信通知 - 流程详情:app-page-process