Merge branch 'stat' into case

This commit is contained in:
daihh
2022-11-30 14:44:59 +08:00
20 changed files with 392 additions and 37 deletions

View File

@@ -0,0 +1,17 @@
package com.xboe.module.scorm;
import com.xboe.module.scorm.cam.model.Manifest;
/**
* manifest.xml内容的保存
* @author seastar
*
*/
public interface IManifestInfoSave{
/**
* 保存配置文件
* @param manifest
*/
void save(Manifest manifest);
}

View File

@@ -122,7 +122,7 @@ public class SCORMPackageManager {
// .loadSCORMContentPackageFromZipFile("1", "learningserver-scorm/scorm-test-pkg.zip")
// .getContent());
System.out.println("test");
ContentPackage cp=SCORMPackageManager.getInstance().loadSCORMContentPackageFromZipFile("1", "E:/Projects/BOEU/scorm/file/test.zip");
ContentPackage cp=SCORMPackageManager.getInstance().loadSCORMContentPackageFromZipFile("1", "E:/Projects/BOEU/scorm/file/ContentPackagingSingleSCO_SCORM12.zip");
System.out.println(cp.getManifest().getIdentifier());
System.out.println(cp.getContent());
System.out.println("title="+cp.getManifest().getOrganizations().getOrganizationList().get(0).getTitle());

View File

@@ -8,6 +8,9 @@ public interface CacheName {
*/
String NAME_AUTH= "auth";
String NAME_USER_LOGIN_ERROR_NUM= "user:login:error:aid:";
/**
* 验证码key前缀
*/

View File

@@ -0,0 +1,127 @@
package com.xboe.data.api;
import java.time.LocalDateTime;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.xboe.account.entity.Account;
import com.xboe.account.service.IAccountService;
import com.xboe.core.JsonResponse;
import com.xboe.core.api.ApiBaseController;
import com.xboe.data.dto.UserData;
import com.xboe.data.service.IDataUserSyncService;
import com.xboe.system.organization.entity.Organization;
import com.xboe.system.organization.service.IOrganizationService;
import com.xboe.system.user.entity.User;
import com.xboe.system.user.service.IUserService;
import lombok.extern.slf4j.Slf4j;
/**
* 用户数据同步的处理
*
*/
@Slf4j
@RestController
@RequestMapping(value = "/inner/data")
public class UserDataSyncApi extends ApiBaseController {
@Autowired
IAccountService accountService;
@Autowired
IUserService userService;
@Autowired
IOrganizationService orgService;
@Autowired
IDataUserSyncService service;
@PostMapping("/user")
public JsonResponse<Boolean> syncUser( @RequestBody UserData user) {
if (StringUtils.isBlank(user.getId())) {
return error("无用户的id");
}
//清除缓存需要loginName
try {
//先查询是否存在
Account a=accountService.get(user.getId());
User u=userService.get(user.getId());
Organization org=null;
if(a!=null) {
//账户只是修改状态
a.setDeleted(user.getDeleted());
}else {
//新账户
a=new Account();
a.setDeleted(user.getDeleted());
a.setSysId(user.getKid());
a.setLoginName(user.getCode());
a.setAvatar(user.getAvatar());
a.setId(user.getId());
a.setRegTime(LocalDateTime.now());
a.setSysId(user.getKid());
a.setStatus(1);
}
if(u!=null) {
//更新部分用户字段
u.setDepartId(user.getDepartId());
u.setDepartName(user.getDepartName());
u.setName(user.getName());
u.setUserType(user.getUserType());
if(user.getLearningDuration()>0) { //不大于0才会更新
u.setLearningDuration(user.getLearningDuration());
}
}else {
//新建用户
u=new User();
u.setId(user.getId());
u.setDepartId(user.getDepartId());
u.setDepartName(user.getDepartName());
u.setDynamic(0);
u.setGender(u.getGender());
u.setName(user.getName());
u.setSign("");
u.setUserNo(user.getCode());
u.setUserType(user.getUserType());
u.setSysId(user.getKid());
u.setStudyTotal(0);
u.setLearningDuration(user.getLearningDuration());
if(user.getBandLevel()!=null && user.getBandLevel()>15) {
u.setShowHome(false);//band16及以上
}else {
u.setShowHome(true);//band16以下及其它无bandLevel的信息
}
}
//对机构的判断,不为空时才会处理,为空时不处理
if(StringUtils.isNotBlank(user.getDepartId())) {
org=orgService.get(user.getDepartId());
if(org==null) {
org=new Organization();
org.setCode("");
org.setId(user.getDepartId());
org.setName(user.getDepartName());
org.setDeleted(false);
org.setStatus(1);
}
org.setNamePath(user.getOrgNamePath());
}
service.syncUserFull(a, u, org);
return success(true);
} catch (Exception e) {
log.error("同步处理用户错误", e);
return error("同步处理用户失败", e.getMessage());
}
}
}

View File

@@ -0,0 +1,55 @@
package com.xboe.data.dto;
import lombok.Data;
/**
* 用于同步的用户数据
* @author seastar
*
*/
@Data
public class UserData {
/**用户的id*/
private String id;
/**主要是为了兼容之前的使用,新用户可以为空*/
private String kid;
/**用户工号*/
private String code;
/**band的级别*/
private Integer bandLevel;
/**姓名*/
private String name;
/**用户的头像*/
private String avatar;
/**性别 1:男 2女*/
private Integer gender;
/**学习时长,秒*/
private Integer learningDuration;
/**部门id*/
private String departId;
/**部门名称*/
private String departName;
/**此字段主要是为了人员的显示*/
private String orgNamePath;
/**
* 用户类型1表学员2表教师3表管理员
*/
private Integer userType;
/**
* 是否删除的如果是删除的上面所有的字段可以不提供只提供id就可以了
*/
private Boolean deleted;
}

View File

@@ -0,0 +1,21 @@
package com.xboe.data.service;
import com.xboe.account.entity.Account;
import com.xboe.system.organization.entity.Organization;
import com.xboe.system.user.entity.User;
/**
* 用户数据的更橷
*
*/
public interface IDataUserSyncService {
/**
* 同步用户,账号,机构等信息
* @param a
* @param u
* @param org
* @return
*/
void syncUserFull(Account a,User u,Organization org);
}

View File

@@ -0,0 +1,60 @@
package com.xboe.data.service.impl;
import javax.transaction.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.xboe.account.dao.AccountDao;
import com.xboe.account.entity.Account;
import com.xboe.data.service.IDataUserSyncService;
import com.xboe.module.teacher.dao.TeacherDao;
import com.xboe.module.teacher.entity.Teacher;
import com.xboe.system.organization.dao.OrganizationDao;
import com.xboe.system.organization.entity.Organization;
import com.xboe.system.user.dao.UserDao;
import com.xboe.system.user.entity.User;
@Service
public class DataUserSyncServiceImpl implements IDataUserSyncService{
@Autowired
AccountDao accountDao;
@Autowired
UserDao userDao;
@Autowired
OrganizationDao orgDao;
@Autowired
TeacherDao teacherDao;
@Override
@Transactional
public void syncUserFull(Account a, User u, Organization org) {
accountDao.saveOrUpdate(a);
userDao.saveOrUpdate(u);
if(org!=null) {
orgDao.saveOrUpdate(org);
}
//老师信息
if(u.getUserType()!=null && u.getUserType()==2) {
Teacher t = teacherDao.get(u.getId());
if(t==null) {
t=new Teacher();
t.setId(u.getId());
t.setDepartId(u.getDepartId());
t.setDeleted(false);
t.setGender(u.getGender());
t.setName(u.getName());
t.setStatus(1);
t.setWaitStatus(0);
t.setUser(u);
teacherDao.save(t);
}
}
}
}

View File

@@ -223,6 +223,8 @@ public class Cases extends BaseEntity {
@Column(name = "case_value")
private String caseValue;
@Transient
private List<String> majorIds;

View File

@@ -472,12 +472,6 @@ public class CourseServiceImpl implements ICourseService {
//同时添加发布事件,这里的创建人需要修改为教师
Course c=courseDao.get(id);
//删除分两种情况,一个是管理员删除,一个是自己删除 ,所以这里的处理移到前端了
// if(eventSender!=null) {
// eventSender.send("删除课程","DeleteCourse", "删除课程【"+c.getName()+"】", c.getId(), "1", c.getName(), c.getSysCreateAid(), c.getSysCreateBy(),"");
// }else {
// log.error("未配置事件消息发送的实现");
// }
//删除
if(c.getFullTextId()!=null) {
try {
fullTextSearch.remove(ICourseFullTextSearch.DEFAULT_INDEX_NAME,c.getFullTextId());
@@ -485,6 +479,26 @@ public class CourseServiceImpl implements ICourseService {
log.error("删除课程时删除全文索引错误",e);
}
}
//只有速有全文检索返回标识的,才算是发布过再删除的,删除消息
if(StringUtils.isNotBlank(c.getFullTextId())){
if(eventSender!=null) {
List<CourseTeacher> teachers = courseTeacherDao.findList(FieldFilters.eq("courseId", id));
if(teachers.size()>0) {
String authorIds="";
for(CourseTeacher cteacher:teachers) {
if(authorIds.equals("")) {
authorIds+=cteacher.getTeacherId();
}else {
authorIds+="|"+cteacher.getTeacherId();
}
}
String txt="管理删除课程";
eventSender.send(txt,"CourseDelete", "管理删除课程", c.getId(), "1", c.getName(), aid, name,"authors:"+authorIds);
}
}else {
log.error("未配置事件消息发送的实现");
}
}
}else {
//彻底删除,课件设置为无课程状态
courseDao.setDeleted(id);
@@ -834,12 +848,23 @@ public class CourseServiceImpl implements ICourseService {
//发布到全文检索中
Course c=courseDao.get(courseId);
if(fullTextSearch!=null) {
this.fullTextPublish(c);
}
//同时添加发布事件,这里的创建人需要修改为教师
if(eventSender!=null) {
eventSender.send("发布课程","PublishCourse", "发布课程【"+c.getName()+"", c.getId(), "1", c.getName(), c.getSysCreateAid(), c.getSysCreateBy(),"");
List<CourseTeacher> teachers = courseTeacherDao.findList(FieldFilters.eq("courseId", courseId));
if(teachers.size()>0) {
String authorIds="";
for(CourseTeacher cteacher:teachers) {
if(authorIds.equals("")) {
authorIds+=cteacher.getTeacherId();
}else {
authorIds+="|"+cteacher.getTeacherId();
}
}
eventSender.send("发布课程","PublishCourse", "发布课程【"+c.getName()+"", c.getId(), "1", c.getName(), aid,name,"authors:"+authorIds);
}
}else {
log.error("未配置事件消息发送的实现");
}
@@ -943,7 +968,7 @@ public class CourseServiceImpl implements ICourseService {
@Override
public List<CourseTeacher> findTeachersByCourseId(String courseId) {
return courseTeacherDao.findList(FieldFilters.eq("courseId", courseId));
return courseTeacherDao.findList(OrderCondition.desc("teacherName"),FieldFilters.eq("courseId", courseId));
}
@Override
@@ -961,7 +986,7 @@ public class CourseServiceImpl implements ICourseService {
@Override
public List<CourseTeacher> findTeachersByCourseIds(List<String> ids) {
return courseTeacherDao.findList(FieldFilters.in("courseId",ids));
return courseTeacherDao.findList(OrderCondition.desc("teacherName"),FieldFilters.in("courseId",ids));
}
@Override

View File

@@ -78,6 +78,7 @@ public class ExamPaper extends BaseEntity {
@Column(name = "counts")
private Integer counts;
public ExamPaper(String testName, String paperType, Integer paperMode, String resOwner1,
String resOwner2, String resOwner3,String sysCreateBy,LocalDateTime sysUpdateTime,String id,Integer counts) {
this.testName = testName;

View File

@@ -156,6 +156,7 @@ public class ExamTest extends BaseEntity {
@Column(name = "deadline_time")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime deadlineTime;
@Transient
private String paperName;

View File

@@ -2,6 +2,7 @@ package com.xboe.module.interaction.api;
import javax.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@@ -15,6 +16,8 @@ import com.xboe.module.interaction.service.ICourseGradeService;
import lombok.extern.slf4j.Slf4j;
import java.util.Map;
@Slf4j
@RestController
@RequestMapping(value = "/xboe/m/grade")
@@ -50,5 +53,23 @@ public class CourseGradeApi extends ApiBaseController {
return success(has);
}
/**
* 查询当前用户评分的课程 分数
* */
@PostMapping("/score")
public JsonResponse<CourseGrade> score(String courseId,String aid){
if(StringUtils.isBlank(courseId)){
return badRequest("参数异常");
}
if(StringUtils.isBlank(aid)){
aid=this.getCurrent().getAccountId();
}
CourseGrade score = service.score(courseId, aid);
if(score==null) {
return notfound();
}
return success(score);
}
}

View File

@@ -4,6 +4,8 @@ import com.xboe.common.PageList;
import com.xboe.module.course.entity.Course;
import com.xboe.module.interaction.entity.CourseGrade;
import java.util.Map;
public interface ICourseGradeService {
@@ -20,4 +22,9 @@ public interface ICourseGradeService {
* 查询当前用户是否评分
* */
Boolean has(String courseId,String aid);
/**
* 查询当前用户评分的课程
* */
CourseGrade score(String courseId,String aid);
}

View File

@@ -1,9 +1,12 @@
package com.xboe.module.interaction.service.impl;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
import com.xboe.core.orm.FieldFilters;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -77,6 +80,13 @@ public class CourseGradeServiceImpl implements ICourseGradeService {
}
}
@Override
public CourseGrade score(String courseId, String aid) {
CourseGrade cg = courseGradeDao.findOne(FieldFilters.eq("courseId", courseId), FieldFilters.eq("sysCreateAid", aid));
return cg;
}
}

View File

@@ -35,7 +35,7 @@ public class EventDataSender implements IEventDataSender{
@Override
public void send(String title, String eventKey, String content, String objId, String objType, String objInfo,
String aid, String aname,String author) {
String aid, String aname,String parameters) {
String statBaseUrl=SysConstant.getConfigValue("xboe.stat.base.url");
if(StringUtils.isBlank(statBaseUrl)) {
log.error("发送事件失败:未配置【xboe.stat.base.url】的值");
@@ -58,7 +58,7 @@ public class EventDataSender implements IEventDataSender{
params.put("objInfo", objInfo);
params.put("aid", aid);
params.put("aname", aname);
params.put("parameters","");
params.put("parameters",parameters);
String token = TokenProxy.getToken(request);
//最后采用异常发送,不影响当前进程

View File

@@ -81,24 +81,6 @@ public class SysLoginApi extends ApiBaseController {
return success(map);
}
@GetMapping("/login/send")
public JsonResponse<Map<String, String>> sendMessage() {
Map<String, String> rs=new HashMap<String, String>();
if(eventSender!=null) {
try {
eventSender.send("测试消息","keykey", "all测试消息","1231231", "1", "aaaa", "asdqadqw","wqwrqre","");
}catch(Exception e) {
e.printStackTrace();
return error("发送失败"+e.getMessage());
}
}else {
//log.error();
return error("未配置事件消息发送的实现");
}
return success(rs);
}
/**
* 根据用户名和密码登录
*
@@ -117,6 +99,9 @@ public class SysLoginApi extends ApiBaseController {
if (!code.toLowerCase().equals(verCode)) {
return error("验证码错误");
}
// 检查系统用户是否存在
Account account = accountService.check(loginName,null);
String passStr = "";
@@ -124,8 +109,27 @@ public class SysLoginApi extends ApiBaseController {
passStr = MD5Util.MD5Encode(password + account.getPassKey());
}
// 从redis缓存中获取5分钟内登陆错误的次数
String loginErrorNum = redisTemplate.opsForValue().get(CacheName.NAME_USER_LOGIN_ERROR_NUM+account);
Integer loginErrorCount = 0;
if(loginErrorNum != null){
loginErrorCount = Integer.parseInt(loginErrorNum);
}
if (account == null || StringUtil.isBlank(passStr) || !passStr.equals(account.getPassValue())) {
return error("用户名或密码错误");
if(loginErrorCount >=5){
redisTemplate.opsForValue().set(CacheName.NAME_USER_LOGIN_ERROR_NUM+account, "5", 5, TimeUnit.MINUTES);
return error("由于您登录失败次数过多,账号已被锁定!");
}else{
loginErrorCount = loginErrorCount + 1;
redisTemplate.opsForValue().set(CacheName.NAME_USER_LOGIN_ERROR_NUM+account, loginErrorCount+"", 5, TimeUnit.MINUTES);
int next = (6-loginErrorCount);
if(next == 0){
return error("账号已被锁定");
}
return error("用户名或密码错误,您还有"+(6-loginErrorCount)+"次登录机会");
}
// return error("用户名或密码错误");
}
if (account.getStatus().equals(Constants.ACCOUNT_STATUS_DEACTIVATE)) {

View File

@@ -65,7 +65,7 @@ public class AuthenticationFilter extends OncePerRequestFilter {
String url = request.getServletPath();
//当前先写固定的url判断
//以下是针对于url规划的判断这里简写
if(url.startsWith("/xboe/account/captcha") || url.startsWith("/xboe/account/login") || url.startsWith("/xboe/account/boelogin") || url.startsWith("/xboe/account/mobile-login") || url.startsWith("/xboe/account/logout") || url.startsWith("/xboe/system/captcha") || url.startsWith("/xboe/system/logout") || url.startsWith("/xboe/system/login") || url.startsWith("/xboe/sys/user/sync-all")){
if(url.startsWith("/inner/data") || url.startsWith("/xboe/account/captcha") || url.startsWith("/xboe/account/login") || url.startsWith("/xboe/account/boelogin") || url.startsWith("/xboe/account/mobile-login") || url.startsWith("/xboe/account/logout") || url.startsWith("/xboe/system/captcha") || url.startsWith("/xboe/system/logout") || url.startsWith("/xboe/system/login") || url.startsWith("/xboe/sys/user/sync-all")){
filterChain.doFilter(request, response);
return;
}

View File

@@ -35,7 +35,7 @@ public class Organization extends BaseEntity {
/**
* 组织部门代码
*/
@Column(name = "code", nullable = false, length = 50)
@Column(name = "code", nullable = true, length = 50)
private String code;
/**

View File

@@ -287,6 +287,7 @@ public class UserServiceImpl implements IUserService {
return user.getAccount();
}
@Override
public void syncUpdateUser(UserVo uv)throws XaskException{

View File

@@ -122,9 +122,9 @@ public class CaseTaskApi extends ApiBaseController{
*/
@PostMapping("/sync-by-time")
public JsonResponse<Boolean> runByTime(String id,String time) {
if (StringUtils.isBlank(id)) {
return error("缺少必要参数");
}
// if (StringUtils.isBlank(id)) {
// return error("缺少必要参数");
// }
if (StringUtils.isBlank(time)) {
return error("缺少必要参数");
}