技术框架:Node.js、Parse Server
编写语言: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(结束)
全局采用路由守卫 auth.guard.ts
入口路由文件:projects\textbook\src\app\app.routes.ts
各个身份子路由
nav-author //作者 / 教师 / 主编
app-comp-manage【全局组件】:登录成功后跳转后页面显示;包括左侧menu,通过optionsMap身份对应显示身份功能栏
app-comp-nav 【个人信息组件】:页面左下角个人信息,包括退出登录功能
app-comp-upload 【文件上传组件】
app-textbook 【教材列表组件】
getTextbook
:获取教材列表重要函数,利用Parse.Query.fromJSON多条件查询,通过设定参数传入接口查询获取教材,满足全平台90%以上页面教材列表管理getDepartment
:获取所有单位部门reject
: 退回教材del
:删除教材updateStatus
:加入/移除推荐submit
:提交教材beforSubmit
:高校联系人提交教材至工作联系人restore
:恢复教材exportProcess
:导出教材;功能业务:导出推荐汇总表submitted
:提交报送跳转,非直接请求报送教材接口
parse-authing.ts 【登录服务类】 应用authing登录回调,返回获取登录结果
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
组件(教材创建)
主要函数方法
getEduTextbookVolumeList
:获取分册表upload
:上传附件回调saveEduTextbook
:保存教材信息部分主要代码
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-comp-upload [type]="'pdf'" (change)="upload($event, 'approvedImgUrl')" title="上传教材获批截图"
分册信息
<app-one #children
[eduTextbookId]="eduTextbookId"
[eduTextbookVolumeId]="panel?.id"
></app-one>
- app-textbook-pertain【填写教材适用情况】
- 必填参数
- @eduTextbook 教材
- 主要函数方法
- `saveEduTextbook`:保存教材信息
- `saveEduTextbookVolume`:上传分册数据
- 子组件调用
- 分册信息
<app-author #children [eduTextbook]="eduTextbook?.id" [eduTextbookVolume]="panel"
app-textbook-content【填写教材内容】
必填参数
主要函数方法
saveEduTextbook
:保存教材信息saveEduTextbookVolume
:上传分册数据子组件调用
分册信息
<app-three
#children
[eduTextbook]="eduTextbook?.id"
[eduTextbookVolume]="panel"
></app-three>
app-faith【填写教材内容】
必填参数
主要函数方法
saveEduTextbook
:保存教材信息saveEduTextbookVolume
:上传分册数据verify
:校验填写字段是否匹配app-attachment【上传附件材料】
必填参数
主要函数方法
saveEduTextbook
:保存教材信息saveEduTextbookVolume
:上传分册数据examineNull
:检查本页必填是否存在空项isIgnoreFiledNull
:判断教材所有字段是否必填upload
:上传附件回调子组件调用
分册信息
<app-author-file
#children
[eduTextbook]="eduTextbook?.id"
[eduTextbookVolume]="panel"
></app-author-file>
个人空间:app-space
调用组件:app-textbook
主要函数:getEduProcess
获取教师所属单位的流程
创建教材:app-apply
组件调用
app-basic
app-textbook-pertain
app-textbook-content
app-faith
app-attachment
应用代码
@switch (state) { @case (0) {
<app-basic
[eduTextbook]="textBook"
(state)="changeState($event)"
(save)="save()"
></app-basic>
} @case (1) {
<app-textbook-pertain
[eduTextbook]="textBook"
(state)="changeState($event)"
(save)="save()"
(maxWidth)="(submitComp.style.width)"
></app-textbook-pertain>
} @case (2) {
<app-textbook-content
[eduTextbook]="textBook"
(state)="changeState($event)"
(save)="save()"
(maxWidth)="(submitComp.style.width)"
></app-textbook-content>
}@case (3) {
<app-faith
[eduTextbook]="textBook"
(state)="changeState($event)"
(save)="save()"
(maxWidth)="(submitComp.style.width)"
></app-faith>
}
@case (4) {
<app-attachment
[eduTextbook]="textBook"
(state)="changeState($event)"
(save)="save()"
(maxWidth)="(submitComp.style.width)"
></app-attachment>
} }
回收站:app-recycle
调用组件:app-textbook
<app-textbook
[filterObj]="filterObj"
[uid]="user?.id"
path="/nav-author/manage/details"
[discard]="true"
></app-textbook>
路由模块:NavAdminRoutingModule
组件
app-collect-textbook 【教材文件收集列表】
必填参数
主要函数方法
getTextbook
:获取教材onEmitMsg
:短信提醒,提交状态置为100onReject
:退回教材给出版社app-profile 【工作联系人】
必填参数
主要函数方法
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
功能说明
默认进入报送流程tab栏,可修改流程名称、限额、工作联系人等相关配置信息
教材列表可查看已提交到国家级管理员的所有教材
教材文件功能查看上传教材的状态
调用组件
app-process-create:流程管理
app-textbook
app-collect-textbook
用户列表:app-page-user
功能说明
本页权限通过tbookSer.profile.identity
判断给与相应权限,包含国家级管理员、高校联系人管理权限区分;国家级管理员可管理平台所有身份用户,工作联系人可管理所属部门节点及下级节点的部门用户,不包含“工作联系人”身份的用户
统一管理平台所有用户,可创建、删除、修改用户
创建用户:点击addMember
弹出创建用户弹窗,填写用户基本信息后点击确定完成请求创建用户,人员类型校验必须选择部门后才能选择
主要参数说明
profiles
:用户列表
parentList
:部门选择
filters
:筛选条件,用于列表搜索或列表条件查询等
主要函数方法
getProfile
:获取用户列表
updateUrlPageIndex
:更新页面,路由返回功能回显作用
updateUser
:更新用户信息,通过认证或删除操作
addMember
:添加用户初始化,初始化后通过accountIsVisible
设置弹窗弹出用户信息弹出,对其设置
getDepart
:获取部门信息
onCheckedDepart
:选择所属类别下级列表
accountComplete
:添加账号,需通过authVrifly
表单信息校验
authVrifly
:用户信息表单校验,含邮箱格式正则、手机号正则等
用户管理&编辑:app-user-edit
功能说明
路由须携带用户ID
编辑、查看用户信息,含扩展字段,省份、职务等
修改密码:判断是否具有修改权限,如果有可直接在弹出中修改,修改后会直接通过邮箱或短信通知
用户教材:可查看该用户所创建的所有教材,含未提交的,组件传入参数
submitTextBook = {
status:['102','103','200','201','300','400'],
btns:{
review:true,//查阅
}
}
调用组件
app-textbook
<app-textbook
[filterObj]="submitTextBook"
[uid]="user?.id"
></app-textbook>
主要参数说明
user
:用户信息
profileJson
:身份编辑数据
userJson
:user编辑数据,用于编辑未保存提示
edit
:是否可编辑权限
profile
:用户角色信息
主要函数方法
updateUser
:操作用户删除、变更用户状态
handleOk
:变更密码
showModalDepart
:选择部门
getDepart
:根据所选单位类型获取对应单位
onCheckedDepart
:选择部门
completeChange
:选择部门
submitForm
:修改账户所属部门单位
updateUserJson
:更新用户数据
moduleChange
:判断编辑数据变化
updateCanDeActivate
:保存提示
申报单位管理:app-page-role
功能说明
通过权限判断获取单位部门getDepart
,存储nodes节点,部分代码
nodes.push({
title: item.get('name'),
key: item.id,
children: [],
branch: item.get('branch'),
parent: item.get('parent')?.id, //上级
isLeaf: !item.get('hasChildren'), //是否是最下级
type: item.get('type'),
});
点击部门获取用户列表,在左侧用户显示,可对其管理
添加成员:addMember
添加选中部门的用户角色,工作联系人管理状态下默认同节点
添加部门:国家级管理员可添加任意节点部门、工作联系人可添加当前单位下的部门
使用nz-tree
组件,通过contextmenu
函数调用鼠标左击直接操作选中单位可编辑的权限
主要参数说明
nodes
:部门节点
profileLength
:用户列表
activatedNode
:当前选中节点
activeDepart
:当前编辑部门
editObject
:编辑部门字段,单项赋值绑定
主要函数方法
getDepart
:获取部门单位
getProfile
:获取用户列表
contextMenu
:鼠标右击事件
onDelDepart
:删除部门
showModalDepart
:初始化用户
handleOk
:保存编辑&新增部门
showProfile
:变更用户部门
accountComplete
:添加账号
updateProfile
:保存更新部门
NavProContactRoutingModule
getTextbook
:获取教材export
:导出表格upload
:上传回调参数处理submitForm
:提交教材文件通过textbook?.export()
调用app-textbook
组件直接下载汇总表
<app-textbook
hidden
#textbook
[recommend]="true"
[filterObj]="filterObj"
[eduProcess]="eduProcess"
></app-textbook>
调用组件
app-textbook
主要参数说明
beforeFilterObj
:待审核参数
beforeFilterObj: any = {
showMore: true, //显示更多字段
isCheck: true,
noStared: true,
status: ['200'],
btns: {
export: true,
},
};
afterFilterObj
:已加入推荐
afterFilterObj: any = {
showMore: true, //显示更多字段
isCheck: true,
status: ['200', '201', '400'],
btns: {
// remove: true, //移除推荐
export: true,
},
};
主要函数方法
getProcess
:获取流程
submitted
:报送
申报流程:app-process-list
功能说明
查看本单位申报流程的流程,可点击教材名称进入详情查看
主要参数说明
formatStatus:格式化流程状态,收集状态
主要函数方法
getEduProcess:获取流程
流程详情:app-page-process
功能说明
流程管理可以查看报送限额、开始及结束时间
评审活动显示评审活动时间
显示所有的已提交的教材列表;
调用组件
app-process-create
app-textbook
<div class="title">待评审教材列表</div>
<app-textbook
[filterObj]="beforeFilterObj"
[eduProcess]="eduProcess"
></app-textbook>
<br />
<div class="title">推荐教材列表</div>
<app-textbook
[filterObj]="afterFilterObj"
[recommend]="true"
[eduProcess]="eduProcess"
></app-textbook>
//待审核
beforeFilterObj: any = {
showMore: true, //显示更多字段
isCheck: true,
noStared: true,
status: ['200'],
btns: {
export: true,
},
};
//已加入推荐
afterFilterObj: any = {
showMore: true, //显示更多字段
isCheck: true,
status: ['200', '201', '400'],
btns: {
export: true,
},
};
主要参数说明
beforeFilterObj
:待审核
afterFilterObj
:已加入推荐
activity
:评审活动
主要函数方法
getActivity
:获取评审活动
getExpertGroup
:获取评审组
startActivity
:开始活动
onCompute
:计算平均分
getEduReview
:获取评审详情列表
创建&编辑评委活动:app-activity
功能说明
编辑评审活动,name、startDate、deadline;评审端评选打分教材以此时间为准,评审端通过条件判断是否在评审时间段内为评审条件之一
评审规则:平均数mean、截尾平均数truncatedMean用于计算时评审计平均分分
评审组:设置教材可评审的评审人员,教材与评审组关系:n:1
调用组件
app-comp-upload
//上传教材评审文件,在评审端评审时可在弹出的打分中看到该文件
<app-comp-upload
[type]="'pdf'"
(change)="upload($event)"
title="上传评审细则文件"
></app-comp-upload>
app-review-details
<app-review-details
[listOfFilter]="listOfFilter"
[filterObj]="filterObj"
></app-review-details>
主要参数说明
filterObj
:评审明细子组件介绍参数条件;showGroup:显示评审组名称,contained:指定评审组查询,bookMap:教材对应评审组结构{booid:评审组名称}
主要函数方法
getActivity
:获取评审活动
getExpertGroup
:评审组
deleteGroup
:删除评审组
创建&编辑评委组:app-review-edit
功能说明
默认评审教材为全部,可以onchangeTextbook切换手动选中教材,选中手动选中教材后,显示教材列表app-textbook组件,可勾选后确定,在app-textbook组件的回调中获取勾选的教材赋值变量在保存请求
默认评审专家为全部,可手动onchangeReview切换手动选择专家,选择的专家会在右侧
所有设置均有回显类名class="dep-right"元素显示,也会在当前类class="dep-comp"显示选中样式
教材评审明细显示已打分的各个评审专家分数
调用组件
主要参数说明
app-textbook
<app-textbook
[hidden]="radio == 'all'"
[filterObj]="filterObj"
[eduProcess]="eduProcess"
[setOfCheckedId]="setOfCheckedTextbookAll"
(updateCheck)="updateCheck()"
#textbook
>
app-review-details
<app-review-details [filterObj]="reviewFilterObj"></app-review-details>