260720
This commit is contained in:
@@ -0,0 +1,20 @@
|
||||
package com.gxwebsoft.gxmu.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.gxwebsoft.common.core.web.PageResult;
|
||||
import com.gxwebsoft.gxmu.entity.ClassInfo;
|
||||
import com.gxwebsoft.gxmu.param.ClassInfoParam;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 班级管理Service
|
||||
*/
|
||||
public interface ClassInfoService extends IService<ClassInfo> {
|
||||
|
||||
PageResult<ClassInfo> pageRel(ClassInfoParam param);
|
||||
|
||||
List<ClassInfo> listRel(ClassInfoParam param);
|
||||
|
||||
ClassInfo getByIdRel(Integer id, Integer tenantId);
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.gxwebsoft.gxmu.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.gxwebsoft.common.core.web.PageResult;
|
||||
import com.gxwebsoft.gxmu.entity.College;
|
||||
import com.gxwebsoft.gxmu.param.CollegeParam;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 学院管理Service
|
||||
*/
|
||||
public interface CollegeService extends IService<College> {
|
||||
|
||||
PageResult<College> pageRel(CollegeParam param);
|
||||
|
||||
List<College> listRel(CollegeParam param);
|
||||
|
||||
College getByIdRel(Integer id, Integer tenantId);
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.gxwebsoft.gxmu.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.gxwebsoft.common.core.web.PageResult;
|
||||
import com.gxwebsoft.gxmu.entity.CrossSchoolActivityArticle;
|
||||
import com.gxwebsoft.gxmu.param.CrossSchoolActivityArticleParam;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 跨校活动情报文章Service
|
||||
*
|
||||
* @author Codex
|
||||
* @since 2026-07-04
|
||||
*/
|
||||
public interface CrossSchoolActivityArticleService extends IService<CrossSchoolActivityArticle> {
|
||||
|
||||
PageResult<CrossSchoolActivityArticle> pageRel(CrossSchoolActivityArticleParam param);
|
||||
|
||||
List<CrossSchoolActivityArticle> listRel(CrossSchoolActivityArticleParam param);
|
||||
|
||||
CrossSchoolActivityArticle getByIdRel(Integer id);
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.gxwebsoft.gxmu.service;
|
||||
|
||||
/**
|
||||
* 跨校活动情报抓取Service
|
||||
*
|
||||
* @author Codex
|
||||
* @since 2026-07-04
|
||||
*/
|
||||
public interface CrossSchoolActivityCrawlerService {
|
||||
|
||||
/**
|
||||
* 同步全部来源站点
|
||||
*
|
||||
* @return 写入/更新条数
|
||||
*/
|
||||
int syncAll();
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.gxwebsoft.gxmu.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.gxwebsoft.common.core.web.PageResult;
|
||||
import com.gxwebsoft.gxmu.entity.Declare;
|
||||
import com.gxwebsoft.gxmu.param.DeclareParam;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 申报管理Service
|
||||
*
|
||||
* @author LX
|
||||
* @since 2026-03-28 15:06:52
|
||||
*/
|
||||
public interface DeclareService extends IService<Declare> {
|
||||
|
||||
/**
|
||||
* 分页关联查询
|
||||
*
|
||||
* @param param 查询参数
|
||||
* @return PageResult<Declare>
|
||||
*/
|
||||
PageResult<Declare> pageRel(DeclareParam param);
|
||||
|
||||
/**
|
||||
* 关联查询全部
|
||||
*
|
||||
* @param param 查询参数
|
||||
* @return List<Declare>
|
||||
*/
|
||||
List<Declare> listRel(DeclareParam param);
|
||||
|
||||
/**
|
||||
* 根据id查询
|
||||
*
|
||||
* @param id
|
||||
* @return Declare
|
||||
*/
|
||||
Declare getByIdRel(Integer id);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.gxwebsoft.gxmu.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.gxwebsoft.gxmu.entity.QmgcForm;
|
||||
|
||||
/**
|
||||
* 青马工程培训班学员登记表Service
|
||||
*/
|
||||
public interface QmgcFormService extends IService<QmgcForm> {
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package com.gxwebsoft.gxmu.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.gxwebsoft.common.core.web.PageResult;
|
||||
import com.gxwebsoft.gxmu.entity.ReviewFlowConfig;
|
||||
import com.gxwebsoft.gxmu.param.ReviewFlowConfigParam;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Service
|
||||
*
|
||||
* @author LX
|
||||
* @since 2026-03-18 10:37:18
|
||||
*/
|
||||
public interface ReviewFlowConfigService extends IService<ReviewFlowConfig> {
|
||||
|
||||
/**
|
||||
* 分页关联查询
|
||||
*
|
||||
* @param param 查询参数
|
||||
* @return PageResult<ReviewFlowConfig>
|
||||
*/
|
||||
PageResult<ReviewFlowConfig> pageRel(ReviewFlowConfigParam param);
|
||||
|
||||
/**
|
||||
* 关联查询全部
|
||||
*
|
||||
* @param param 查询参数
|
||||
* @return List<ReviewFlowConfig>
|
||||
*/
|
||||
List<ReviewFlowConfig> listRel(ReviewFlowConfigParam param);
|
||||
|
||||
/**
|
||||
* 根据id查询
|
||||
*
|
||||
* @param id
|
||||
* @return ReviewFlowConfig
|
||||
*/
|
||||
ReviewFlowConfig getByIdRel(Integer id);
|
||||
|
||||
ReviewFlowConfig getByModule(String module);
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.gxwebsoft.gxmu.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.gxwebsoft.common.core.web.PageResult;
|
||||
import com.gxwebsoft.gxmu.entity.ReviewFlow;
|
||||
import com.gxwebsoft.gxmu.param.ReviewFlowParam;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 审核流Service
|
||||
*
|
||||
* @author LX
|
||||
* @since 2026-03-18 10:37:18
|
||||
*/
|
||||
public interface ReviewFlowService extends IService<ReviewFlow> {
|
||||
|
||||
/**
|
||||
* 分页关联查询
|
||||
*
|
||||
* @param param 查询参数
|
||||
* @return PageResult<ReviewFlow>
|
||||
*/
|
||||
PageResult<ReviewFlow> pageRel(ReviewFlowParam param);
|
||||
|
||||
/**
|
||||
* 关联查询全部
|
||||
*
|
||||
* @param param 查询参数
|
||||
* @return List<ReviewFlow>
|
||||
*/
|
||||
List<ReviewFlow> listRel(ReviewFlowParam param);
|
||||
|
||||
/**
|
||||
* 根据id查询
|
||||
*
|
||||
* @param id
|
||||
* @return ReviewFlow
|
||||
*/
|
||||
ReviewFlow getByIdRel(Integer id);
|
||||
|
||||
ReviewFlow getByTitle(String title);
|
||||
|
||||
List<ReviewFlow> listByTitle(String title);
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.gxwebsoft.gxmu.service;
|
||||
|
||||
/**
|
||||
* 审核流程发起服务
|
||||
*
|
||||
* @author LX
|
||||
* @since 2026-03-18
|
||||
*/
|
||||
public interface ReviewFlowStarterService {
|
||||
|
||||
/**
|
||||
* 发起模块的首个审核节点
|
||||
*
|
||||
* @param module 模块编码
|
||||
* @param pk 业务主键
|
||||
*/
|
||||
void startReview(String module, Integer pk);
|
||||
|
||||
/**
|
||||
* 当最新审核记录为拒绝时,重新生成第一条审核流
|
||||
*
|
||||
* @param module 模块编码
|
||||
* @param pk 业务主键
|
||||
*/
|
||||
void restartReviewWhenLastRejected(String module, Integer pk);
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.gxwebsoft.gxmu.service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.gxwebsoft.gxmu.entity.ReviewList;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* 审核记录回填服务
|
||||
*
|
||||
* @author LX
|
||||
* @since 2026-03-18
|
||||
*/
|
||||
public interface ReviewListBindingService {
|
||||
|
||||
<T, E extends IPage<T>> E bindPage(E page, String module, Function<T, Integer> idGetter,
|
||||
BiConsumer<T, List<ReviewList>> setter);
|
||||
|
||||
<T> List<T> bindList(List<T> list, String module, Function<T, Integer> idGetter,
|
||||
BiConsumer<T, List<ReviewList>> setter);
|
||||
|
||||
<T> T bindOne(T entity, String module, Function<T, Integer> idGetter,
|
||||
BiConsumer<T, List<ReviewList>> setter);
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package com.gxwebsoft.gxmu.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.gxwebsoft.common.core.web.PageResult;
|
||||
import com.gxwebsoft.gxmu.entity.ReviewList;
|
||||
import com.gxwebsoft.gxmu.param.ReviewListParam;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 审核列表Service
|
||||
*
|
||||
* @author LX
|
||||
* @since 2026-03-18 15:50:51
|
||||
*/
|
||||
public interface ReviewListService extends IService<ReviewList> {
|
||||
|
||||
/**
|
||||
* 分页关联查询
|
||||
*
|
||||
* @param param 查询参数
|
||||
* @return PageResult<ReviewList>
|
||||
*/
|
||||
PageResult<ReviewList> pageRel(ReviewListParam param);
|
||||
|
||||
/**
|
||||
* 分页查询聚合后的审核列表
|
||||
*
|
||||
* @param param 查询参数
|
||||
* @return PageResult<ReviewList>
|
||||
*/
|
||||
PageResult<ReviewList> pageGroupRel(ReviewListParam param);
|
||||
|
||||
/**
|
||||
* 关联查询全部
|
||||
*
|
||||
* @param param 查询参数
|
||||
* @return List<ReviewList>
|
||||
*/
|
||||
List<ReviewList> listRel(ReviewListParam param);
|
||||
|
||||
/**
|
||||
* 根据id查询
|
||||
*
|
||||
* @param id
|
||||
* @return ReviewList
|
||||
*/
|
||||
ReviewList getByIdRel(Integer id);
|
||||
|
||||
List<ReviewList> listByModuleNPK(String module, Integer pk);
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.gxwebsoft.gxmu.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.gxwebsoft.gxmu.entity.SjqnForm;
|
||||
|
||||
/**
|
||||
* 十佳青年申报表Service
|
||||
*/
|
||||
public interface SjqnFormService extends IService<SjqnForm> {
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.gxwebsoft.gxmu.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.gxwebsoft.gxmu.entity.SjtbzbsjForm;
|
||||
|
||||
/**
|
||||
* 十佳团支部书记申报表Service
|
||||
*/
|
||||
public interface SjtbzbsjFormService extends IService<SjtbzbsjForm> {
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.gxwebsoft.gxmu.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.gxwebsoft.gxmu.entity.TyglForm;
|
||||
import com.gxwebsoft.gxmu.param.TyglGrowthArchivesUpdateParam;
|
||||
import com.gxwebsoft.gxmu.param.TyglMemberRecordsUpdateParam;
|
||||
|
||||
/**
|
||||
* 团员管理Service
|
||||
*/
|
||||
public interface TyglFormService extends IService<TyglForm> {
|
||||
TyglForm getCurrentUserForm(Integer userId, Integer tenantId);
|
||||
|
||||
boolean updateMemberRecords(Integer id, TyglMemberRecordsUpdateParam param);
|
||||
|
||||
boolean updateGrowthArchives(Integer id, TyglGrowthArchivesUpdateParam param);
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.gxwebsoft.gxmu.service;
|
||||
|
||||
/**
|
||||
* 挑战杯项目/人才库爬虫Service
|
||||
*
|
||||
* @author Codex
|
||||
* @since 2026-04-14
|
||||
*/
|
||||
public interface TzbProjectLibraryCrawlerService {
|
||||
|
||||
/**
|
||||
* 抓取并同步项目库列表
|
||||
*/
|
||||
void syncProjectList();
|
||||
|
||||
/**
|
||||
* 抓取并同步项目库列表
|
||||
*
|
||||
* @param maxRows 本次最多同步记录数
|
||||
* @return 实际写入/更新记录数
|
||||
*/
|
||||
int syncProjectList(int maxRows);
|
||||
|
||||
/**
|
||||
* 抓取并同步人才库列表
|
||||
*/
|
||||
void syncTalentList();
|
||||
|
||||
/**
|
||||
* 抓取并同步人才库列表
|
||||
*
|
||||
* @param maxRows 本次最多同步记录数
|
||||
* @return 实际写入/更新记录数
|
||||
*/
|
||||
int syncTalentList(int maxRows);
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package com.gxwebsoft.gxmu.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.gxwebsoft.common.core.web.PageResult;
|
||||
import com.gxwebsoft.gxmu.entity.TzbProjectListRecord;
|
||||
import com.gxwebsoft.gxmu.param.TzbProjectListRecordParam;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 挑战杯项目库列表Service
|
||||
*
|
||||
* @author Codex
|
||||
* @since 2026-04-14
|
||||
*/
|
||||
public interface TzbProjectListRecordService extends IService<TzbProjectListRecord> {
|
||||
|
||||
/**
|
||||
* 分页查询
|
||||
*
|
||||
* @param param 查询参数
|
||||
* @return 分页结果
|
||||
*/
|
||||
PageResult<TzbProjectListRecord> pageRel(TzbProjectListRecordParam param);
|
||||
|
||||
/**
|
||||
* 查询列表
|
||||
*
|
||||
* @param param 查询参数
|
||||
* @return 列表数据
|
||||
*/
|
||||
List<TzbProjectListRecord> listRel(TzbProjectListRecordParam param);
|
||||
|
||||
/**
|
||||
* 根据ID查询
|
||||
*
|
||||
* @param id 主键ID
|
||||
* @return 列表记录
|
||||
*/
|
||||
TzbProjectListRecord getByIdRel(Integer id);
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package com.gxwebsoft.gxmu.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.gxwebsoft.common.core.web.PageResult;
|
||||
import com.gxwebsoft.gxmu.entity.TzbTalentListRecord;
|
||||
import com.gxwebsoft.gxmu.param.TzbTalentListRecordParam;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 挑战杯人才库列表Service
|
||||
*
|
||||
* @author Codex
|
||||
* @since 2026-04-14
|
||||
*/
|
||||
public interface TzbTalentListRecordService extends IService<TzbTalentListRecord> {
|
||||
|
||||
/**
|
||||
* 分页查询
|
||||
*
|
||||
* @param param 查询参数
|
||||
* @return 分页结果
|
||||
*/
|
||||
PageResult<TzbTalentListRecord> pageRel(TzbTalentListRecordParam param);
|
||||
|
||||
/**
|
||||
* 查询列表
|
||||
*
|
||||
* @param param 查询参数
|
||||
* @return 列表数据
|
||||
*/
|
||||
List<TzbTalentListRecord> listRel(TzbTalentListRecordParam param);
|
||||
|
||||
/**
|
||||
* 根据ID查询
|
||||
*
|
||||
* @param id 主键ID
|
||||
* @return 列表记录
|
||||
*/
|
||||
TzbTalentListRecord getByIdRel(Integer id);
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.gxwebsoft.gxmu.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.gxwebsoft.gxmu.entity.TzbcyForm;
|
||||
import com.gxwebsoft.gxmu.model.TzbcyStatisticsResult;
|
||||
|
||||
/**
|
||||
* 挑战杯创业计划竞赛申报表Service
|
||||
*/
|
||||
public interface TzbcyFormService extends IService<TzbcyForm> {
|
||||
TzbcyStatisticsResult getStatistics(Integer year);
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.gxwebsoft.gxmu.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.gxwebsoft.common.core.web.PageResult;
|
||||
import com.gxwebsoft.common.system.entity.FileRecord;
|
||||
import com.gxwebsoft.gxmu.entity.TzbcyMaterial;
|
||||
import com.gxwebsoft.gxmu.param.TzbcyMaterialParam;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 挑战杯申报材料Service
|
||||
*/
|
||||
public interface TzbcyMaterialService extends IService<TzbcyMaterial> {
|
||||
PageResult<TzbcyMaterial> pageRel(TzbcyMaterialParam param);
|
||||
|
||||
List<TzbcyMaterial> listRel(TzbcyMaterialParam param);
|
||||
|
||||
TzbcyMaterial getByIdRel(Integer id);
|
||||
|
||||
boolean saveMaterial(TzbcyMaterial material, FileRecord fileRecord, Integer loginUserId, Integer tenantId);
|
||||
|
||||
boolean updateMaterial(TzbcyMaterial material, FileRecord fileRecord);
|
||||
|
||||
boolean audit(Integer id, Integer status, String rejectReason, Integer auditUserId);
|
||||
|
||||
FileRecord exportZip(TzbcyMaterialParam param, String uploadPath, String requestURL, Integer loginUserId)
|
||||
throws IOException;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.gxwebsoft.gxmu.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.gxwebsoft.gxmu.entity.WorkLedger;
|
||||
|
||||
public interface WorkLedgerService extends IService<WorkLedger> {
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.gxwebsoft.gxmu.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.gxwebsoft.gxmu.entity.WshqtwForm;
|
||||
|
||||
/**
|
||||
* 五四红旗团委申报表Service
|
||||
*/
|
||||
public interface WshqtwFormService extends IService<WshqtwForm> {
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.gxwebsoft.gxmu.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.gxwebsoft.gxmu.entity.WshqtzbForm;
|
||||
|
||||
/**
|
||||
* 五四红旗团支部申报表Service
|
||||
*/
|
||||
public interface WshqtzbFormService extends IService<WshqtzbForm> {
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.gxwebsoft.gxmu.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.gxwebsoft.gxmu.entity.WxxzxForm;
|
||||
import com.gxwebsoft.gxmu.param.WxxzxMaterialUpdateParam;
|
||||
|
||||
/**
|
||||
* 未来学术之星课题申报表Service
|
||||
*/
|
||||
public interface WxxzxFormService extends IService<WxxzxForm> {
|
||||
boolean updateMaterials(Integer id, WxxzxMaterialUpdateParam param);
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.gxwebsoft.gxmu.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.gxwebsoft.gxmu.entity.YxgqtdgbForm;
|
||||
|
||||
/**
|
||||
* 优秀共青团干部申报表Service
|
||||
*/
|
||||
public interface YxgqtdgbFormService extends IService<YxgqtdgbForm> {
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.gxwebsoft.gxmu.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.gxwebsoft.gxmu.entity.YxgqtyForm;
|
||||
|
||||
/**
|
||||
* 优秀共青团员申报表Service
|
||||
*/
|
||||
public interface YxgqtyFormService extends IService<YxgqtyForm> {
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
package com.gxwebsoft.gxmu.service.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.gxwebsoft.common.core.web.PageParam;
|
||||
import com.gxwebsoft.common.core.web.PageResult;
|
||||
import com.gxwebsoft.common.system.entity.Organization;
|
||||
import com.gxwebsoft.common.system.service.OrganizationService;
|
||||
import com.gxwebsoft.gxmu.entity.ClassInfo;
|
||||
import com.gxwebsoft.gxmu.mapper.ClassInfoMapper;
|
||||
import com.gxwebsoft.gxmu.param.ClassInfoParam;
|
||||
import com.gxwebsoft.gxmu.service.ClassInfoService;
|
||||
import com.gxwebsoft.gxmu.util.GxmuQueryHelper;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 班级管理Service实现
|
||||
*/
|
||||
@Service
|
||||
public class ClassInfoServiceImpl extends ServiceImpl<ClassInfoMapper, ClassInfo> implements ClassInfoService {
|
||||
|
||||
@Resource
|
||||
private OrganizationService organizationService;
|
||||
|
||||
@Override
|
||||
public PageResult<ClassInfo> pageRel(ClassInfoParam param) {
|
||||
PageParam<ClassInfo, ClassInfoParam> page = new PageParam<>(param);
|
||||
page.setDefaultOrder("sort_number asc, id desc");
|
||||
QueryWrapper<ClassInfo> wrapper = buildWrapper(page, param);
|
||||
IPage<ClassInfo> result = baseMapper.selectPage(page, wrapper);
|
||||
bindCollegeName(result.getRecords(), param == null ? null : param.getTenantId());
|
||||
return new PageResult<>(result.getRecords(), result.getTotal());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ClassInfo> listRel(ClassInfoParam param) {
|
||||
PageParam<ClassInfo, ClassInfoParam> page = new PageParam<>(param);
|
||||
page.setDefaultOrder("sort_number asc, id desc");
|
||||
QueryWrapper<ClassInfo> wrapper = buildWrapper(page, param);
|
||||
List<ClassInfo> list = baseMapper.selectList(wrapper);
|
||||
list = page.sortRecords(list);
|
||||
bindCollegeName(list, param == null ? null : param.getTenantId());
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClassInfo getByIdRel(Integer id, Integer tenantId) {
|
||||
ClassInfo classInfo = baseMapper.selectOne(new LambdaQueryWrapper<ClassInfo>()
|
||||
.eq(ClassInfo::getId, id)
|
||||
.eq(ClassInfo::getTenantId, tenantId));
|
||||
if (classInfo != null) {
|
||||
Organization organization = organizationService.getOne(new LambdaQueryWrapper<Organization>()
|
||||
.eq(Organization::getOrganizationId, classInfo.getCollegeId())
|
||||
.eq(tenantId != null, Organization::getTenantId, tenantId));
|
||||
if (organization != null) {
|
||||
classInfo.setCollegeName(organization.getOrganizationName());
|
||||
}
|
||||
}
|
||||
return classInfo;
|
||||
}
|
||||
|
||||
private QueryWrapper<ClassInfo> buildWrapper(PageParam<ClassInfo, ClassInfoParam> page, ClassInfoParam param) {
|
||||
QueryWrapper<ClassInfo> wrapper = page.getWrapper("keywords");
|
||||
if (param != null && param.getTenantId() != null) {
|
||||
wrapper.eq("tenant_id", param.getTenantId());
|
||||
}
|
||||
if (param == null || param.getDeleted() == null) {
|
||||
wrapper.eq("deleted", 0);
|
||||
}
|
||||
if (param != null) {
|
||||
GxmuQueryHelper.applyKeywords(wrapper, param.getKeywords(), "class_name", "class_code", "counselor_name");
|
||||
}
|
||||
return page.getOrderWrapper(wrapper);
|
||||
}
|
||||
|
||||
private void bindCollegeName(List<ClassInfo> list, Integer tenantId) {
|
||||
if (CollUtil.isEmpty(list)) {
|
||||
return;
|
||||
}
|
||||
Set<Integer> collegeIds = list.stream()
|
||||
.map(ClassInfo::getCollegeId)
|
||||
.filter(id -> id != null)
|
||||
.collect(Collectors.toSet());
|
||||
if (CollUtil.isEmpty(collegeIds)) {
|
||||
return;
|
||||
}
|
||||
List<Organization> organizationList = organizationService.list(new LambdaQueryWrapper<Organization>()
|
||||
.in(Organization::getOrganizationId, collegeIds)
|
||||
.eq(tenantId != null, Organization::getTenantId, tenantId));
|
||||
Map<Integer, String> collegeMap = organizationList.stream()
|
||||
.collect(Collectors.toMap(Organization::getOrganizationId, Organization::getOrganizationName, (a, b) -> a));
|
||||
list.forEach(item -> item.setCollegeName(collegeMap.get(item.getCollegeId())));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
package com.gxwebsoft.gxmu.service.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.gxwebsoft.common.core.web.PageParam;
|
||||
import com.gxwebsoft.common.core.web.PageResult;
|
||||
import com.gxwebsoft.gxmu.entity.College;
|
||||
import com.gxwebsoft.gxmu.mapper.CollegeMapper;
|
||||
import com.gxwebsoft.gxmu.param.CollegeParam;
|
||||
import com.gxwebsoft.gxmu.service.CollegeService;
|
||||
import com.gxwebsoft.gxmu.util.GxmuQueryHelper;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 学院管理Service实现
|
||||
*/
|
||||
@Service
|
||||
public class CollegeServiceImpl extends ServiceImpl<CollegeMapper, College> implements CollegeService {
|
||||
|
||||
@Override
|
||||
public PageResult<College> pageRel(CollegeParam param) {
|
||||
PageParam<College, CollegeParam> page = new PageParam<>(param);
|
||||
page.setDefaultOrder("sort_number asc, id desc");
|
||||
QueryWrapper<College> wrapper = buildWrapper(page, param);
|
||||
IPage<College> result = baseMapper.selectPage(page, wrapper);
|
||||
bindClassCount(result.getRecords(), param == null ? null : param.getTenantId());
|
||||
return new PageResult<>(result.getRecords(), result.getTotal());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<College> listRel(CollegeParam param) {
|
||||
PageParam<College, CollegeParam> page = new PageParam<>(param);
|
||||
page.setDefaultOrder("sort_number asc, id desc");
|
||||
QueryWrapper<College> wrapper = buildWrapper(page, param);
|
||||
List<College> list = baseMapper.selectList(wrapper);
|
||||
list = page.sortRecords(list);
|
||||
bindClassCount(list, param == null ? null : param.getTenantId());
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public College getByIdRel(Integer id, Integer tenantId) {
|
||||
College college = baseMapper.selectOne(new LambdaQueryWrapper<College>()
|
||||
.eq(College::getId, id)
|
||||
.eq(College::getTenantId, tenantId));
|
||||
if (college != null) {
|
||||
college.setClassCount(0);
|
||||
}
|
||||
return college;
|
||||
}
|
||||
|
||||
private QueryWrapper<College> buildWrapper(PageParam<College, CollegeParam> page, CollegeParam param) {
|
||||
QueryWrapper<College> wrapper = page.getWrapper("keywords");
|
||||
if (param != null && param.getTenantId() != null) {
|
||||
wrapper.eq("tenant_id", param.getTenantId());
|
||||
}
|
||||
if (param == null || param.getDeleted() == null) {
|
||||
wrapper.eq("deleted", 0);
|
||||
}
|
||||
if (param != null) {
|
||||
GxmuQueryHelper.applyKeywords(wrapper, param.getKeywords(), "college_name", "college_code", "short_name");
|
||||
}
|
||||
return page.getOrderWrapper(wrapper);
|
||||
}
|
||||
|
||||
private void bindClassCount(List<College> list, Integer tenantId) {
|
||||
if (CollUtil.isEmpty(list)) {
|
||||
return;
|
||||
}
|
||||
for (College college : list) {
|
||||
college.setClassCount(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
package com.gxwebsoft.gxmu.service.impl;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.gxwebsoft.common.core.web.PageParam;
|
||||
import com.gxwebsoft.common.core.web.PageResult;
|
||||
import com.gxwebsoft.gxmu.entity.CrossSchoolActivityArticle;
|
||||
import com.gxwebsoft.gxmu.mapper.CrossSchoolActivityArticleMapper;
|
||||
import com.gxwebsoft.gxmu.param.CrossSchoolActivityArticleParam;
|
||||
import com.gxwebsoft.gxmu.service.CrossSchoolActivityArticleService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 跨校活动情报文章Service实现
|
||||
*
|
||||
* @author Codex
|
||||
* @since 2026-07-04
|
||||
*/
|
||||
@Service
|
||||
public class CrossSchoolActivityArticleServiceImpl
|
||||
extends ServiceImpl<CrossSchoolActivityArticleMapper, CrossSchoolActivityArticle>
|
||||
implements CrossSchoolActivityArticleService {
|
||||
|
||||
@Override
|
||||
public PageResult<CrossSchoolActivityArticle> pageRel(CrossSchoolActivityArticleParam param) {
|
||||
PageParam<CrossSchoolActivityArticle, CrossSchoolActivityArticleParam> page = new PageParam<>(param);
|
||||
page.setDefaultOrder("publish_time desc, id desc");
|
||||
QueryWrapper<CrossSchoolActivityArticle> wrapper = buildWrapper(page, param);
|
||||
IPage<CrossSchoolActivityArticle> result = baseMapper.selectPage(page, wrapper);
|
||||
return new PageResult<>(result.getRecords(), result.getTotal());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CrossSchoolActivityArticle> listRel(CrossSchoolActivityArticleParam param) {
|
||||
PageParam<CrossSchoolActivityArticle, CrossSchoolActivityArticleParam> page = new PageParam<>(param);
|
||||
page.setDefaultOrder("publish_time desc, id desc");
|
||||
QueryWrapper<CrossSchoolActivityArticle> wrapper = buildWrapper(page, param);
|
||||
List<CrossSchoolActivityArticle> list = baseMapper.selectList(wrapper);
|
||||
return page.sortRecords(list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CrossSchoolActivityArticle getByIdRel(Integer id) {
|
||||
return baseMapper.selectById(id);
|
||||
}
|
||||
|
||||
private QueryWrapper<CrossSchoolActivityArticle> buildWrapper(
|
||||
PageParam<CrossSchoolActivityArticle, CrossSchoolActivityArticleParam> page,
|
||||
CrossSchoolActivityArticleParam param
|
||||
) {
|
||||
QueryWrapper<CrossSchoolActivityArticle> wrapper = page.getWrapper();
|
||||
if (param == null || param.getDeleted() == null) {
|
||||
wrapper.eq("deleted", 0);
|
||||
}
|
||||
if (param != null && StrUtil.isNotBlank(param.getKeywords())) {
|
||||
wrapper.and(q -> q.like("title", param.getKeywords())
|
||||
.or()
|
||||
.like("school_name", param.getKeywords())
|
||||
.or()
|
||||
.like("summary", param.getKeywords())
|
||||
.or()
|
||||
.like("tags", param.getKeywords()));
|
||||
}
|
||||
return page.getOrderWrapper(wrapper);
|
||||
}
|
||||
}
|
||||
+450
@@ -0,0 +1,450 @@
|
||||
package com.gxwebsoft.gxmu.service.impl;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.http.Header;
|
||||
import cn.hutool.http.HttpRequest;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.gxwebsoft.gxmu.entity.CrossSchoolActivityArticle;
|
||||
import com.gxwebsoft.gxmu.mapper.CrossSchoolActivityArticleMapper;
|
||||
import com.gxwebsoft.gxmu.service.CrossSchoolActivityCrawlerService;
|
||||
import org.jsoup.Jsoup;
|
||||
import org.jsoup.nodes.Document;
|
||||
import org.jsoup.nodes.Element;
|
||||
import org.jsoup.select.Elements;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.MessageDigest;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.format.DateTimeFormatterBuilder;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* 跨校活动情报抓取Service实现
|
||||
*
|
||||
* @author Codex
|
||||
* @since 2026-07-04
|
||||
*/
|
||||
@Service
|
||||
public class CrossSchoolActivityCrawlerServiceImpl implements CrossSchoolActivityCrawlerService {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(CrossSchoolActivityCrawlerServiceImpl.class);
|
||||
|
||||
private static final String DEFAULT_USER_AGENT = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) "
|
||||
+ "AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36";
|
||||
|
||||
private static final Pattern FULL_DATE_PATTERN = Pattern.compile("(20\\d{2})[-/年.](\\d{1,2})[-/月.](\\d{1,2})");
|
||||
|
||||
private static final int MAX_ARTICLES_PER_RUN_LIMIT = 100;
|
||||
|
||||
private static final DateTimeFormatter DATE_TIME_FORMATTER = new DateTimeFormatterBuilder()
|
||||
.appendPattern("yyyy-MM-dd")
|
||||
.optionalStart()
|
||||
.appendPattern(" HH:mm")
|
||||
.optionalEnd()
|
||||
.toFormatter(Locale.CHINA);
|
||||
|
||||
@Resource
|
||||
private CrossSchoolActivityArticleMapper crossSchoolActivityArticleMapper;
|
||||
|
||||
@Value("${gxmu.cross-school-crawler.timeout-ms:15000}")
|
||||
private int timeoutMs;
|
||||
|
||||
@Value("${gxmu.cross-school-crawler.max-retries:2}")
|
||||
private int maxRetries;
|
||||
|
||||
@Value("${gxmu.cross-school-crawler.max-articles-per-site:12}")
|
||||
private int maxArticlesPerSite;
|
||||
|
||||
@Value("${gxmu.cross-school-crawler.max-articles-per-run:100}")
|
||||
private int maxArticlesPerRun;
|
||||
|
||||
@Override
|
||||
public int syncAll() {
|
||||
LocalDateTime syncTime = LocalDateTime.now();
|
||||
int runLimit = resolveRunLimit();
|
||||
int totalRows = 0;
|
||||
for (SiteConfig site : buildSites()) {
|
||||
if (totalRows >= runLimit) {
|
||||
logger.info("跨校活动情报同步达到本轮上限 {} 条,停止继续抓取", runLimit);
|
||||
break;
|
||||
}
|
||||
try {
|
||||
List<CrossSchoolActivityArticle> articles = crawlSite(site, syncTime, runLimit - totalRows);
|
||||
if (!CollectionUtils.isEmpty(articles)) {
|
||||
crossSchoolActivityArticleMapper.batchUpsert(articles);
|
||||
totalRows += articles.size();
|
||||
}
|
||||
logger.info("跨校活动情报同步来源完成:{},{} 条", site.schoolName, articles.size());
|
||||
} catch (Exception e) {
|
||||
logger.error("跨校活动情报同步来源失败:" + site.schoolName, e);
|
||||
}
|
||||
}
|
||||
logger.info("跨校活动情报同步完成,共写入/更新 {} 条", totalRows);
|
||||
return totalRows;
|
||||
}
|
||||
|
||||
private List<CrossSchoolActivityArticle> crawlSite(SiteConfig site, LocalDateTime syncTime, int remainingLimit) {
|
||||
int siteLimit = Math.min(Math.max(maxArticlesPerSite, 1), Math.max(remainingLimit, 0));
|
||||
if (siteLimit <= 0) {
|
||||
return new ArrayList<CrossSchoolActivityArticle>();
|
||||
}
|
||||
Document document = fetchDocument(site.listUrl);
|
||||
Elements links = document.select(site.linkSelector);
|
||||
Map<String, CrossSchoolActivityArticle> articleMap = new LinkedHashMap<String, CrossSchoolActivityArticle>();
|
||||
for (Element link : links) {
|
||||
if (articleMap.size() >= siteLimit) {
|
||||
break;
|
||||
}
|
||||
String detailUrl = link.attr("abs:href");
|
||||
if (StrUtil.isBlank(detailUrl) || articleMap.containsKey(detailUrl)) {
|
||||
continue;
|
||||
}
|
||||
Element item = findContainer(link);
|
||||
String title = firstNotBlank(link.attr("title"), selectText(item, ".title"), selectText(item, "h5"), link.text());
|
||||
title = cleanTitle(title);
|
||||
if (StrUtil.isBlank(title) || title.length() < 4) {
|
||||
continue;
|
||||
}
|
||||
CrossSchoolActivityArticle article = new CrossSchoolActivityArticle();
|
||||
article.setSourceKey(md5(detailUrl));
|
||||
article.setTitle(title);
|
||||
article.setSchoolName(site.schoolName);
|
||||
article.setSourceName(site.sourceName);
|
||||
article.setDetailUrl(detailUrl);
|
||||
article.setSourceUrl(site.listUrl);
|
||||
article.setSummary(truncate(firstNotBlank(selectText(item, ".abstract"), selectText(item, ".intro"), selectText(item, ".news_text"), selectText(item, "p")), 360));
|
||||
article.setCoverImage(firstImage(item));
|
||||
article.setPublishTime(parsePublishTime(item, title));
|
||||
article.setLastSyncTime(syncTime);
|
||||
enrichFromDetail(article);
|
||||
enrichAnalysis(article);
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
article.setCreateTime(now);
|
||||
article.setUpdateTime(now);
|
||||
article.setDeleted(0);
|
||||
articleMap.put(detailUrl, article);
|
||||
}
|
||||
return new ArrayList<CrossSchoolActivityArticle>(articleMap.values());
|
||||
}
|
||||
|
||||
private int resolveRunLimit() {
|
||||
return Math.min(Math.max(maxArticlesPerRun, 1), MAX_ARTICLES_PER_RUN_LIMIT);
|
||||
}
|
||||
|
||||
private void enrichFromDetail(CrossSchoolActivityArticle article) {
|
||||
try {
|
||||
Document detail = fetchDocument(article.getDetailUrl());
|
||||
String metaTitle = metaContent(detail, "ArticleTitle");
|
||||
if (StrUtil.isNotBlank(metaTitle)) {
|
||||
article.setTitle(cleanTitle(metaTitle));
|
||||
}
|
||||
String metaDate = firstNotBlank(metaContent(detail, "PubDate"), textAfter(detail.text(), "发布时间:"), textAfter(detail.text(), "日期:"));
|
||||
LocalDateTime publishTime = parsePublishTime(metaDate);
|
||||
if (publishTime != null) {
|
||||
article.setPublishTime(publishTime);
|
||||
}
|
||||
String metaSource = firstNotBlank(metaContent(detail, "ContentSource"), textAfter(detail.text(), "来源:"));
|
||||
if (StrUtil.isNotBlank(metaSource)) {
|
||||
article.setSourceName(cleanSource(metaSource));
|
||||
}
|
||||
String contentText = firstNotBlank(
|
||||
selectText(detail, ".v_news_content"),
|
||||
selectText(detail, "[data-power-area=content] .conTxt"),
|
||||
selectText(detail, ".conTxt"),
|
||||
selectText(detail, ".news_text"),
|
||||
selectText(detail, ".content")
|
||||
);
|
||||
article.setContentText(truncate(contentText, 4000));
|
||||
String description = firstNotBlank(metaContent(detail, "Description"), contentText);
|
||||
if (StrUtil.isBlank(article.getSummary())) {
|
||||
article.setSummary(truncate(description, 360));
|
||||
}
|
||||
String cover = firstNotBlank(metaContent(detail, "Image"), firstImage(detail.selectFirst(".v_news_content, [data-power-area=content], .conTxt, .content")));
|
||||
if (StrUtil.isBlank(article.getCoverImage())) {
|
||||
article.setCoverImage(cover);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.warn("跨校活动情报详情补充失败:{}", article.getDetailUrl());
|
||||
}
|
||||
}
|
||||
|
||||
private void enrichAnalysis(CrossSchoolActivityArticle article) {
|
||||
String text = firstNotBlank(article.getTitle(), "") + " " + firstNotBlank(article.getSummary(), "");
|
||||
String category = "校园要闻";
|
||||
if (containsAny(text, "竞赛", "比赛", "挑战杯", "创新创业", "科创", "大赛", "项目", "一等奖", "二等奖", "冠军")) {
|
||||
category = "科创竞赛";
|
||||
} else if (containsAny(text, "实践", "志愿", "服务", "调研", "社会实践", "走访", "慰问")) {
|
||||
category = "实践活动";
|
||||
} else if (containsAny(text, "诵读", "歌", "体育", "运动", "文化", "艺术", "读书", "沙龙", "毕业典礼")) {
|
||||
category = "文体活动";
|
||||
} else if (containsAny(text, "团委", "青年", "学生", "党课", "培训", "座谈会", "交流")) {
|
||||
category = "品牌活动";
|
||||
}
|
||||
article.setCategory(category);
|
||||
|
||||
LocalDate publishDate = article.getPublishTime() == null ? null : article.getPublishTime().toLocalDate();
|
||||
long days = publishDate == null ? 99 : ChronoUnit.DAYS.between(publishDate, LocalDate.now());
|
||||
boolean highSignal = containsAny(text, "全国", "一等奖", "冠军", "表彰", "揭牌", "成立", "重要讲话", "高质量");
|
||||
if (days <= 3 && highSignal) {
|
||||
article.setHeatLevel("高热");
|
||||
} else if (days <= 7 || containsAny(text, "交流", "调研", "座谈", "培训", "比赛")) {
|
||||
article.setHeatLevel("跟进");
|
||||
} else {
|
||||
article.setHeatLevel("观察");
|
||||
}
|
||||
|
||||
Set<String> tags = new LinkedHashSet<String>();
|
||||
tags.add(article.getSchoolName().replace("大学", ""));
|
||||
tags.add(category);
|
||||
addTagIfMatch(tags, text, "交流", "校际交流");
|
||||
addTagIfMatch(tags, text, "竞赛", "赛事");
|
||||
addTagIfMatch(tags, text, "比赛", "赛事");
|
||||
addTagIfMatch(tags, text, "实践", "实践育人");
|
||||
addTagIfMatch(tags, text, "培训", "培训");
|
||||
addTagIfMatch(tags, text, "青年", "青年工作");
|
||||
addTagIfMatch(tags, text, "学生", "学生参与");
|
||||
article.setTags(JSON.toJSONString(tags));
|
||||
article.setHighlight(resolveHighlight(category));
|
||||
if (StrUtil.isBlank(article.getSummary())) {
|
||||
article.setSummary("来源站点暂未提供摘要,可点击原文查看完整内容。");
|
||||
}
|
||||
}
|
||||
|
||||
private List<SiteConfig> buildSites() {
|
||||
return Arrays.asList(
|
||||
new SiteConfig("广西大学", "新闻中心", "https://news.gxu.edu.cn/", "a[href*='info/1002/']"),
|
||||
new SiteConfig("广西师范大学", "师大要闻", "https://news.gxnu.edu.cn/1334/list.htm", "a[href*='/c1334a']"),
|
||||
new SiteConfig("桂林医科大学", "桂医要闻", "https://www.glmu.edu.cn/xyzy/gyyw.htm", "a[href*='/info/1057/']"),
|
||||
new SiteConfig("广西中医药大学", "学校要闻", "https://www.gxtcmu.edu.cn/xwzx/xyxw/xxyw", "a.tit[href*='/xwzx/xyxw/xxyw/content_']"),
|
||||
new SiteConfig("桂林电子科技大学", "桂电要闻", "https://www.guet.edu.cn/gdyw_6356/list.htm", ".news_title a[href*='/c6356a']"),
|
||||
new SiteConfig("桂林理工大学", "桂工要闻", "https://www.glut.edu.cn/ggyw.htm", ".list_box_riqi a[href*='info/1073/']")
|
||||
);
|
||||
}
|
||||
|
||||
private Document fetchDocument(String pageUrl) {
|
||||
RuntimeException lastException = null;
|
||||
int retryTimes = Math.max(maxRetries, 1);
|
||||
for (int attempt = 1; attempt <= retryTimes; attempt++) {
|
||||
try {
|
||||
String body = HttpRequest.get(pageUrl)
|
||||
.timeout(timeoutMs)
|
||||
.header(Header.USER_AGENT, DEFAULT_USER_AGENT)
|
||||
.header(Header.ACCEPT, "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8")
|
||||
.execute()
|
||||
.body();
|
||||
return Jsoup.parse(body, pageUrl);
|
||||
} catch (Exception e) {
|
||||
lastException = new RuntimeException("抓取页面失败: " + pageUrl, e);
|
||||
logger.warn("抓取跨校活动页面失败,第 {}/{} 次:{}", attempt, retryTimes, pageUrl);
|
||||
}
|
||||
}
|
||||
throw lastException;
|
||||
}
|
||||
|
||||
private Element findContainer(Element link) {
|
||||
Element current = link;
|
||||
for (int i = 0; i < 5 && current != null; i++) {
|
||||
if ("li".equalsIgnoreCase(current.tagName()) || current.hasClass("news") || current.hasClass("con")) {
|
||||
return current;
|
||||
}
|
||||
current = current.parent();
|
||||
}
|
||||
return link.parent() == null ? link : link.parent();
|
||||
}
|
||||
|
||||
private LocalDateTime parsePublishTime(Element item, String title) {
|
||||
String y = selectText(item, ".y");
|
||||
String m = selectText(item, ".m");
|
||||
if (StrUtil.isNotBlank(y) && StrUtil.isNotBlank(m)) {
|
||||
LocalDateTime time = parsePublishTime(y.trim() + "-" + m.trim());
|
||||
if (time != null) {
|
||||
return time;
|
||||
}
|
||||
}
|
||||
String d1 = selectText(item, ".d1");
|
||||
String d2 = selectText(item, ".d2");
|
||||
String d3 = selectText(item, ".d3");
|
||||
if (StrUtil.isNotBlank(d1) && StrUtil.isNotBlank(d2) && StrUtil.isNotBlank(d3)) {
|
||||
LocalDateTime time = parsePublishTime(d3.trim() + "-" + d2.replace(".", "").trim() + "-" + d1.trim());
|
||||
if (time != null) {
|
||||
return time;
|
||||
}
|
||||
}
|
||||
return parsePublishTime(firstNotBlank(selectText(item, ".news_date"), selectText(item, ".date"), item.text(), title));
|
||||
}
|
||||
|
||||
private LocalDateTime parsePublishTime(String text) {
|
||||
if (StrUtil.isBlank(text)) {
|
||||
return null;
|
||||
}
|
||||
Matcher matcher = FULL_DATE_PATTERN.matcher(text);
|
||||
if (!matcher.find()) {
|
||||
return null;
|
||||
}
|
||||
String date = matcher.group(1) + "-" + pad2(matcher.group(2)) + "-" + pad2(matcher.group(3));
|
||||
try {
|
||||
return LocalDate.parse(date, DateTimeFormatter.ofPattern("yyyy-MM-dd")).atStartOfDay();
|
||||
} catch (Exception ignored) {
|
||||
try {
|
||||
return LocalDateTime.parse(date, DATE_TIME_FORMATTER);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String metaContent(Document document, String name) {
|
||||
Element element = document.selectFirst("meta[name=" + name + "]");
|
||||
return element == null ? null : normalizeText(element.attr("content"));
|
||||
}
|
||||
|
||||
private String textAfter(String text, String marker) {
|
||||
if (StrUtil.isBlank(text) || !text.contains(marker)) {
|
||||
return null;
|
||||
}
|
||||
String value = text.substring(text.indexOf(marker) + marker.length());
|
||||
int end = Math.min(value.length(), 32);
|
||||
return normalizeText(value.substring(0, end));
|
||||
}
|
||||
|
||||
private String selectText(Element element, String selector) {
|
||||
if (element == null || StrUtil.isBlank(selector)) {
|
||||
return null;
|
||||
}
|
||||
Element selected = element.selectFirst(selector);
|
||||
return selected == null ? null : normalizeText(selected.text());
|
||||
}
|
||||
|
||||
private String firstImage(Element element) {
|
||||
if (element == null) {
|
||||
return null;
|
||||
}
|
||||
Element image = element.selectFirst("img[src]");
|
||||
return image == null ? null : image.attr("abs:src");
|
||||
}
|
||||
|
||||
private String firstNotBlank(String... values) {
|
||||
if (values == null) {
|
||||
return null;
|
||||
}
|
||||
for (String value : values) {
|
||||
if (StrUtil.isNotBlank(value)) {
|
||||
return normalizeText(value);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private String cleanTitle(String title) {
|
||||
if (StrUtil.isBlank(title)) {
|
||||
return title;
|
||||
}
|
||||
return normalizeText(title).replaceAll("(20\\d{2}[-/.年]\\d{1,2}[-/.月]\\d{1,2}日?)$", "");
|
||||
}
|
||||
|
||||
private String cleanSource(String source) {
|
||||
if (StrUtil.isBlank(source)) {
|
||||
return source;
|
||||
}
|
||||
return normalizeText(source).replace("发布时间", "").replace("日期", "").replace("点击数", "");
|
||||
}
|
||||
|
||||
private String normalizeText(String text) {
|
||||
if (text == null) {
|
||||
return null;
|
||||
}
|
||||
return text.replace('\u00A0', ' ').replaceAll("\\s+", " ").trim();
|
||||
}
|
||||
|
||||
private String truncate(String value, int maxLength) {
|
||||
if (StrUtil.isBlank(value)) {
|
||||
return value;
|
||||
}
|
||||
String text = normalizeText(value);
|
||||
return text.length() <= maxLength ? text : text.substring(0, maxLength) + "...";
|
||||
}
|
||||
|
||||
private boolean containsAny(String text, String... keywords) {
|
||||
if (StrUtil.isBlank(text)) {
|
||||
return false;
|
||||
}
|
||||
for (String keyword : keywords) {
|
||||
if (text.contains(keyword)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void addTagIfMatch(Set<String> tags, String text, String keyword, String tag) {
|
||||
if (text.contains(keyword)) {
|
||||
tags.add(tag);
|
||||
}
|
||||
}
|
||||
|
||||
private String resolveHighlight(String category) {
|
||||
if ("科创竞赛".equals(category)) {
|
||||
return "赛事成果 + 经验沉淀";
|
||||
}
|
||||
if ("实践活动".equals(category)) {
|
||||
return "现场行动 + 后续报道";
|
||||
}
|
||||
if ("文体活动".equals(category)) {
|
||||
return "主题内容 + 参与扩散";
|
||||
}
|
||||
if ("品牌活动".equals(category)) {
|
||||
return "议题设计 + 组织联动";
|
||||
}
|
||||
return "选题跟踪 + 案例复盘";
|
||||
}
|
||||
|
||||
private String pad2(String value) {
|
||||
return value.length() == 1 ? "0" + value : value;
|
||||
}
|
||||
|
||||
private String md5(String text) {
|
||||
try {
|
||||
MessageDigest digest = MessageDigest.getInstance("MD5");
|
||||
byte[] bytes = digest.digest(text.getBytes(StandardCharsets.UTF_8));
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (byte item : bytes) {
|
||||
builder.append(String.format("%02x", item & 0xff));
|
||||
}
|
||||
return builder.toString();
|
||||
} catch (Exception e) {
|
||||
return String.valueOf(text.hashCode());
|
||||
}
|
||||
}
|
||||
|
||||
private static class SiteConfig {
|
||||
private final String schoolName;
|
||||
private final String sourceName;
|
||||
private final String listUrl;
|
||||
private final String linkSelector;
|
||||
|
||||
private SiteConfig(String schoolName, String sourceName, String listUrl, String linkSelector) {
|
||||
this.schoolName = schoolName;
|
||||
this.sourceName = sourceName;
|
||||
this.listUrl = listUrl;
|
||||
this.linkSelector = linkSelector;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package com.gxwebsoft.gxmu.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.gxwebsoft.gxmu.mapper.DeclareMapper;
|
||||
import com.gxwebsoft.gxmu.service.DeclareService;
|
||||
import com.gxwebsoft.gxmu.entity.Declare;
|
||||
import com.gxwebsoft.gxmu.param.DeclareParam;
|
||||
import com.gxwebsoft.common.core.web.PageParam;
|
||||
import com.gxwebsoft.common.core.web.PageResult;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 申报管理Service实现
|
||||
*
|
||||
* @author LX
|
||||
* @since 2026-03-28 15:06:52
|
||||
*/
|
||||
@Service
|
||||
public class DeclareServiceImpl extends ServiceImpl<DeclareMapper, Declare> implements DeclareService {
|
||||
|
||||
@Override
|
||||
public PageResult<Declare> pageRel(DeclareParam param) {
|
||||
PageParam<Declare, DeclareParam> page = new PageParam<>(param);
|
||||
page.setDefaultOrder("create_time desc");
|
||||
List<Declare> list = baseMapper.selectPageRel(page, param);
|
||||
return new PageResult<>(list, page.getTotal());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Declare> listRel(DeclareParam param) {
|
||||
List<Declare> list = baseMapper.selectListRel(param);
|
||||
// 排序
|
||||
PageParam<Declare, DeclareParam> page = new PageParam<>();
|
||||
page.setDefaultOrder("create_time desc");
|
||||
return page.sortRecords(list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Declare getByIdRel(Integer id) {
|
||||
DeclareParam param = new DeclareParam();
|
||||
param.setId(id);
|
||||
return param.getOne(baseMapper.selectListRel(param));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package com.gxwebsoft.gxmu.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.Wrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.gxwebsoft.gxmu.entity.QmgcForm;
|
||||
import com.gxwebsoft.gxmu.mapper.QmgcFormMapper;
|
||||
import com.gxwebsoft.gxmu.service.QmgcFormService;
|
||||
import com.gxwebsoft.gxmu.service.ReviewListBindingService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 青马工程培训班学员登记表Service实现
|
||||
*/
|
||||
@Service
|
||||
public class QmgcFormServiceImpl extends ServiceImpl<QmgcFormMapper, QmgcForm> implements QmgcFormService {
|
||||
@Resource
|
||||
private ReviewListBindingService reviewListBindingService;
|
||||
|
||||
@Override
|
||||
public <E extends IPage<QmgcForm>> E page(E page, Wrapper<QmgcForm> queryWrapper) {
|
||||
return reviewListBindingService.bindPage(super.page(page, queryWrapper), "gxmu_qmgc_form",
|
||||
QmgcForm::getId, QmgcForm::setReviewList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<QmgcForm> list(Wrapper<QmgcForm> queryWrapper) {
|
||||
return reviewListBindingService.bindList(super.list(queryWrapper), "gxmu_qmgc_form",
|
||||
QmgcForm::getId, QmgcForm::setReviewList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public QmgcForm getById(Serializable id) {
|
||||
return reviewListBindingService.bindOne(super.getById(id), "gxmu_qmgc_form",
|
||||
QmgcForm::getId, QmgcForm::setReviewList);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
package com.gxwebsoft.gxmu.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.gxwebsoft.gxmu.entity.ReviewFlow;
|
||||
import com.gxwebsoft.gxmu.mapper.ReviewFlowConfigMapper;
|
||||
import com.gxwebsoft.gxmu.service.ReviewFlowService;
|
||||
import com.gxwebsoft.gxmu.service.ReviewFlowConfigService;
|
||||
import com.gxwebsoft.gxmu.entity.ReviewFlowConfig;
|
||||
import com.gxwebsoft.gxmu.param.ReviewFlowConfigParam;
|
||||
import com.gxwebsoft.common.system.entity.Organization;
|
||||
import com.gxwebsoft.common.system.service.OrganizationService;
|
||||
import com.gxwebsoft.common.core.web.PageParam;
|
||||
import com.gxwebsoft.common.core.web.PageResult;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Service实现
|
||||
*
|
||||
* @author LX
|
||||
* @since 2026-03-18 10:37:18
|
||||
*/
|
||||
@Service
|
||||
public class ReviewFlowConfigServiceImpl extends ServiceImpl<ReviewFlowConfigMapper, ReviewFlowConfig> implements ReviewFlowConfigService {
|
||||
private static final Map<String, String> MODULE_NAME_MAP;
|
||||
|
||||
static {
|
||||
Map<String, String> moduleNameMap = new LinkedHashMap<>();
|
||||
moduleNameMap.put("cms_manuscript", "稿件");
|
||||
moduleNameMap.put("gxmu_sjqn", "十佳青年岗位能手");
|
||||
moduleNameMap.put("gxmu_sjtbzbsj", "十佳团支部书记");
|
||||
moduleNameMap.put("gxmu_wshqtw", "五四红旗团委");
|
||||
moduleNameMap.put("gxmu_wshqtzb", "五四红旗团支部");
|
||||
moduleNameMap.put("gxmu_yxgqtdgb", "优秀共青团干部");
|
||||
moduleNameMap.put("gxmu_yxgqty", "优秀共青团员");
|
||||
moduleNameMap.put("gxmu_tzbcy_form", "挑战杯");
|
||||
moduleNameMap.put("gxmu_qmgc_form", "青马工程");
|
||||
moduleNameMap.put("gxmu_wxxzx_project", "未来学术之星");
|
||||
MODULE_NAME_MAP = Collections.unmodifiableMap(moduleNameMap);
|
||||
}
|
||||
|
||||
@Resource
|
||||
private ReviewFlowService reviewFlowService;
|
||||
@Resource
|
||||
private OrganizationService organizationService;
|
||||
|
||||
@Override
|
||||
public PageResult<ReviewFlowConfig> pageRel(ReviewFlowConfigParam param) {
|
||||
PageParam<ReviewFlowConfig, ReviewFlowConfigParam> page = new PageParam<>(param);
|
||||
page.setDefaultOrder("create_time desc");
|
||||
List<ReviewFlowConfig> list = baseMapper.selectPageRel(page, param);
|
||||
fillReviewFlowConfigNames(list);
|
||||
return new PageResult<>(list, page.getTotal());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ReviewFlowConfig> listRel(ReviewFlowConfigParam param) {
|
||||
List<ReviewFlowConfig> list = baseMapper.selectListRel(param);
|
||||
fillReviewFlowConfigNames(list);
|
||||
// 排序
|
||||
PageParam<ReviewFlowConfig, ReviewFlowConfigParam> page = new PageParam<>();
|
||||
page.setDefaultOrder("create_time desc");
|
||||
return page.sortRecords(list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReviewFlowConfig getByIdRel(Integer id) {
|
||||
ReviewFlowConfigParam param = new ReviewFlowConfigParam();
|
||||
param.setId(id);
|
||||
return param.getOne(baseMapper.selectListRel(param));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReviewFlowConfig getByModule(String module) {
|
||||
return getOne(
|
||||
new LambdaQueryWrapper<ReviewFlowConfig>()
|
||||
.eq(ReviewFlowConfig::getModule, module)
|
||||
.last("limit 1")
|
||||
);
|
||||
}
|
||||
|
||||
private void fillReviewFlowConfigNames(List<ReviewFlowConfig> list) {
|
||||
if (list == null || list.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
Set<Integer> organizationIds = list.stream()
|
||||
.map(ReviewFlowConfig::getOrganizationId)
|
||||
.filter(organizationId -> organizationId != null)
|
||||
.collect(Collectors.toSet());
|
||||
Map<Integer, String> organizationNameMap = new HashMap<>();
|
||||
if (!organizationIds.isEmpty()) {
|
||||
organizationNameMap = organizationService.listByIds(organizationIds).stream()
|
||||
.collect(Collectors.toMap(Organization::getOrganizationId, Organization::getOrganizationName, (left, right) -> left));
|
||||
}
|
||||
Set<Integer> flowIds = list.stream()
|
||||
.map(ReviewFlowConfig::getFlowId)
|
||||
.filter(flowId -> flowId != null)
|
||||
.collect(Collectors.toSet());
|
||||
Map<Integer, String> flowNameMap = new HashMap<>();
|
||||
if (!flowIds.isEmpty()) {
|
||||
flowNameMap = reviewFlowService.listByIds(flowIds).stream()
|
||||
.collect(Collectors.toMap(ReviewFlow::getId, ReviewFlow::getTitle, (left, right) -> left));
|
||||
}
|
||||
for (ReviewFlowConfig item : list) {
|
||||
item.setFlowName(flowNameMap.get(item.getFlowId()));
|
||||
item.setModuleName(MODULE_NAME_MAP.get(item.getModule()));
|
||||
item.setOrganizationName(organizationNameMap.get(item.getOrganizationId()));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
package com.gxwebsoft.gxmu.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.gxwebsoft.common.system.entity.Organization;
|
||||
import com.gxwebsoft.common.system.service.OrganizationService;
|
||||
import com.gxwebsoft.common.system.service.UserService;
|
||||
import com.gxwebsoft.gxmu.mapper.ReviewFlowMapper;
|
||||
import com.gxwebsoft.gxmu.service.ReviewFlowService;
|
||||
import com.gxwebsoft.gxmu.entity.ReviewFlow;
|
||||
import com.gxwebsoft.gxmu.param.ReviewFlowParam;
|
||||
import com.gxwebsoft.common.core.web.PageParam;
|
||||
import com.gxwebsoft.common.core.web.PageResult;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 审核流Service实现
|
||||
*
|
||||
* @author LX
|
||||
* @since 2026-03-18 10:37:18
|
||||
*/
|
||||
@Service
|
||||
public class ReviewFlowServiceImpl extends ServiceImpl<ReviewFlowMapper, ReviewFlow> implements ReviewFlowService {
|
||||
@Resource
|
||||
private OrganizationService organizationService;
|
||||
@Resource
|
||||
private UserService userService;
|
||||
|
||||
@Override
|
||||
public PageResult<ReviewFlow> pageRel(ReviewFlowParam param) {
|
||||
PageParam<ReviewFlow, ReviewFlowParam> page = new PageParam<>(param);
|
||||
page.setDefaultOrder("create_time desc");
|
||||
List<ReviewFlow> list = baseMapper.selectPageRel(page, param);
|
||||
if (param.getWithGroup() != null && param.getWithGroup()) {
|
||||
for (ReviewFlow reviewFlow : list) {
|
||||
List<ReviewFlow> flows = list(
|
||||
new LambdaQueryWrapper<ReviewFlow>()
|
||||
.eq(ReviewFlow::getTitle, reviewFlow.getTitle())
|
||||
.orderByAsc(ReviewFlow::getLevel)
|
||||
);
|
||||
if (!flows.isEmpty()) {
|
||||
for (ReviewFlow flow : flows) {
|
||||
Organization organization = organizationService.getById(flow.getOrganizationId());
|
||||
if (organization != null) {
|
||||
flow.setOrganizationName(organization.getOrganizationName());
|
||||
}
|
||||
if (flow.getReviewUserId() != null)
|
||||
flow.setReviewUser(userService.getById(flow.getReviewUserId()));
|
||||
}
|
||||
}
|
||||
reviewFlow.setFlows(flows);
|
||||
}
|
||||
}
|
||||
return new PageResult<>(list, page.getTotal());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ReviewFlow> listRel(ReviewFlowParam param) {
|
||||
List<ReviewFlow> list = baseMapper.selectListRel(param);
|
||||
// 排序
|
||||
PageParam<ReviewFlow, ReviewFlowParam> page = new PageParam<>();
|
||||
page.setDefaultOrder("create_time desc");
|
||||
return page.sortRecords(list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReviewFlow getByIdRel(Integer id) {
|
||||
ReviewFlowParam param = new ReviewFlowParam();
|
||||
param.setId(id);
|
||||
return param.getOne(baseMapper.selectListRel(param));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReviewFlow getByTitle(String title) {
|
||||
return getOne(
|
||||
new LambdaQueryWrapper<ReviewFlow>()
|
||||
.eq(ReviewFlow::getTitle, title)
|
||||
.last("limit 1")
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ReviewFlow> listByTitle(String title) {
|
||||
return list(
|
||||
new LambdaQueryWrapper<ReviewFlow>()
|
||||
.eq(ReviewFlow::getTitle, title)
|
||||
.orderByAsc(ReviewFlow::getLevel)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
package com.gxwebsoft.gxmu.service.impl;
|
||||
|
||||
import com.gxwebsoft.gxmu.entity.ReviewFlow;
|
||||
import com.gxwebsoft.gxmu.entity.ReviewFlowConfig;
|
||||
import com.gxwebsoft.gxmu.entity.ReviewList;
|
||||
import com.gxwebsoft.gxmu.service.ReviewFlowConfigService;
|
||||
import com.gxwebsoft.gxmu.service.ReviewFlowService;
|
||||
import com.gxwebsoft.gxmu.service.ReviewFlowStarterService;
|
||||
import com.gxwebsoft.gxmu.service.ReviewListService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 审核流程发起服务实现
|
||||
*
|
||||
* @author LX
|
||||
* @since 2026-03-18
|
||||
*/
|
||||
@Service
|
||||
public class ReviewFlowStarterServiceImpl implements ReviewFlowStarterService {
|
||||
@Resource
|
||||
private ReviewFlowConfigService reviewFlowConfigService;
|
||||
@Resource
|
||||
private ReviewFlowService reviewFlowService;
|
||||
@Resource
|
||||
private ReviewListService reviewListService;
|
||||
|
||||
@Override
|
||||
public void startReview(String module, Integer pk) {
|
||||
if (module == null || pk == null) {
|
||||
return;
|
||||
}
|
||||
List<ReviewList> reviewLists = reviewListService.listByModuleNPK(module, pk);
|
||||
if (reviewLists != null && !reviewLists.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
ReviewFlowConfig reviewFlowConfig = reviewFlowConfigService.getByModule(module);
|
||||
if (reviewFlowConfig == null || reviewFlowConfig.getFlowId() == null) {
|
||||
return;
|
||||
}
|
||||
ReviewFlow firstOne = getFirstFlow(reviewFlowConfig);
|
||||
if (firstOne == null) {
|
||||
return;
|
||||
}
|
||||
saveFirstReviewNode(module, pk, firstOne);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void restartReviewWhenLastRejected(String module, Integer pk) {
|
||||
if (module == null || pk == null) {
|
||||
return;
|
||||
}
|
||||
List<ReviewList> reviewLists = reviewListService.listByModuleNPK(module, pk);
|
||||
if (reviewLists == null || reviewLists.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
ReviewList latestReview = reviewLists.stream()
|
||||
.max(Comparator
|
||||
.comparing(ReviewList::getCreateTime,
|
||||
Comparator.nullsLast(LocalDateTime::compareTo))
|
||||
.thenComparing(ReviewList::getId, Comparator.nullsLast(Integer::compareTo)))
|
||||
.orElse(null);
|
||||
if (latestReview == null || latestReview.getStatus() == null || latestReview.getStatus() != 2) {
|
||||
return;
|
||||
}
|
||||
ReviewFlowConfig reviewFlowConfig = reviewFlowConfigService.getByModule(module);
|
||||
if (reviewFlowConfig == null || reviewFlowConfig.getFlowId() == null) {
|
||||
return;
|
||||
}
|
||||
ReviewFlow firstOne = getFirstFlow(reviewFlowConfig);
|
||||
if (firstOne == null) {
|
||||
return;
|
||||
}
|
||||
saveFirstReviewNode(module, pk, firstOne);
|
||||
}
|
||||
|
||||
private ReviewFlow getFirstFlow(ReviewFlowConfig reviewFlowConfig) {
|
||||
ReviewFlow reviewFlow = reviewFlowService.getById(reviewFlowConfig.getFlowId());
|
||||
if (reviewFlow == null) {
|
||||
return null;
|
||||
}
|
||||
List<ReviewFlow> reviewFlowList = reviewFlowService.listByTitle(reviewFlow.getTitle());
|
||||
if (reviewFlowList == null || reviewFlowList.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return reviewFlowList.get(0);
|
||||
}
|
||||
|
||||
private void saveFirstReviewNode(String module, Integer pk, ReviewFlow firstOne) {
|
||||
ReviewList reviewList = new ReviewList();
|
||||
reviewList.setPk(pk);
|
||||
reviewList.setModule(module);
|
||||
reviewList.setUserId(firstOne.getReviewUserId());
|
||||
reviewList.setSortNumber(0);
|
||||
reviewListService.save(reviewList);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package com.gxwebsoft.gxmu.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.gxwebsoft.gxmu.entity.ReviewList;
|
||||
import com.gxwebsoft.gxmu.service.ReviewListBindingService;
|
||||
import com.gxwebsoft.gxmu.service.ReviewListService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* 审核记录回填服务实现
|
||||
*
|
||||
* @author LX
|
||||
* @since 2026-03-18
|
||||
*/
|
||||
@Service
|
||||
public class ReviewListBindingServiceImpl implements ReviewListBindingService {
|
||||
@Resource
|
||||
private ReviewListService reviewListService;
|
||||
|
||||
@Override
|
||||
public <T, E extends IPage<T>> E bindPage(E page, String module, Function<T, Integer> idGetter,
|
||||
BiConsumer<T, List<ReviewList>> setter) {
|
||||
if (page == null) {
|
||||
return null;
|
||||
}
|
||||
bindList(page.getRecords(), module, idGetter, setter);
|
||||
return page;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> List<T> bindList(List<T> list, String module, Function<T, Integer> idGetter,
|
||||
BiConsumer<T, List<ReviewList>> setter) {
|
||||
if (list == null || list.isEmpty()) {
|
||||
return list;
|
||||
}
|
||||
for (T item : list) {
|
||||
Integer pk = idGetter.apply(item);
|
||||
setter.accept(item, reviewListService.listByModuleNPK(module, pk));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T bindOne(T entity, String module, Function<T, Integer> idGetter,
|
||||
BiConsumer<T, List<ReviewList>> setter) {
|
||||
if (entity == null) {
|
||||
return null;
|
||||
}
|
||||
Integer pk = idGetter.apply(entity);
|
||||
setter.accept(entity, reviewListService.listByModuleNPK(module, pk));
|
||||
return entity;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
package com.gxwebsoft.gxmu.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.gxwebsoft.common.system.service.UserService;
|
||||
import com.gxwebsoft.gxmu.mapper.ReviewListMapper;
|
||||
import com.gxwebsoft.gxmu.service.ReviewListService;
|
||||
import com.gxwebsoft.gxmu.entity.ReviewList;
|
||||
import com.gxwebsoft.gxmu.param.ReviewListParam;
|
||||
import com.gxwebsoft.common.core.web.PageParam;
|
||||
import com.gxwebsoft.common.core.web.PageResult;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 审核列表Service实现
|
||||
*
|
||||
* @author LX
|
||||
* @since 2026-03-18 15:50:51
|
||||
*/
|
||||
@Service
|
||||
public class ReviewListServiceImpl extends ServiceImpl<ReviewListMapper, ReviewList> implements ReviewListService {
|
||||
private static final Map<String, String> MODULE_NAME_MAP;
|
||||
|
||||
static {
|
||||
Map<String, String> moduleNameMap = new LinkedHashMap<>();
|
||||
moduleNameMap.put("cms_manuscript", "稿件");
|
||||
moduleNameMap.put("gxmu_sjqn", "十佳青年岗位能手");
|
||||
moduleNameMap.put("gxmu_sjtbzbsj", "十佳团支部书记");
|
||||
moduleNameMap.put("gxmu_wshqtw", "五四红旗团委");
|
||||
moduleNameMap.put("gxmu_wshqtzb", "五四红旗团支部");
|
||||
moduleNameMap.put("gxmu_yxgqtdgb", "优秀共青团干部");
|
||||
moduleNameMap.put("gxmu_yxgqty", "优秀共青团员");
|
||||
moduleNameMap.put("gxmu_tzbcy_form", "挑战杯");
|
||||
moduleNameMap.put("gxmu_qmgc_form", "青马工程");
|
||||
moduleNameMap.put("gxmu_wxxzx_project", "未来学术之星");
|
||||
MODULE_NAME_MAP = Collections.unmodifiableMap(moduleNameMap);
|
||||
}
|
||||
|
||||
@Resource
|
||||
private UserService userService;
|
||||
|
||||
@Override
|
||||
public PageResult<ReviewList> pageRel(ReviewListParam param) {
|
||||
PageParam<ReviewList, ReviewListParam> page = new PageParam<>(param);
|
||||
page.setDefaultOrder("sort_number asc, create_time desc, id desc");
|
||||
List<ReviewList> list = baseMapper.selectPageRel(page, param);
|
||||
fillUsers(list);
|
||||
fillModuleNames(list);
|
||||
return new PageResult<>(list, page.getTotal());
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<ReviewList> pageGroupRel(ReviewListParam param) {
|
||||
PageParam<ReviewList, ReviewListParam> page = new PageParam<>(param);
|
||||
page.setDefaultOrder("create_time desc, id desc");
|
||||
List<ReviewList> list = baseMapper.selectPageGroupRel(page, param);
|
||||
fillUsers(list);
|
||||
fillModuleNames(list);
|
||||
return new PageResult<>(list, page.getTotal());
|
||||
}
|
||||
|
||||
private void fillUsers(List<ReviewList> list) {
|
||||
if (list == null || list.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
for (ReviewList reviewList : list) {
|
||||
if (reviewList.getUserId() != null) {
|
||||
reviewList.setUser(userService.getById(reviewList.getUserId()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ReviewList> listRel(ReviewListParam param) {
|
||||
List<ReviewList> list = baseMapper.selectListRel(param);
|
||||
fillModuleNames(list);
|
||||
// 排序
|
||||
PageParam<ReviewList, ReviewListParam> page = new PageParam<>();
|
||||
page.setDefaultOrder("sort_number asc, create_time desc, id desc");
|
||||
fillUsers(list);
|
||||
return page.sortRecords(list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReviewList getByIdRel(Integer id) {
|
||||
ReviewListParam param = new ReviewListParam();
|
||||
param.setId(id);
|
||||
return param.getOne(baseMapper.selectListRel(param));
|
||||
}
|
||||
|
||||
private void fillModuleNames(List<ReviewList> list) {
|
||||
if (list == null || list.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
for (ReviewList item : list) {
|
||||
item.setModuleName(MODULE_NAME_MAP.get(item.getModule()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ReviewList> listByModuleNPK(String module, Integer pk){
|
||||
return list(
|
||||
new LambdaQueryWrapper<ReviewList>()
|
||||
.eq(ReviewList::getModule, module)
|
||||
.eq(ReviewList::getPk, pk)
|
||||
.orderByAsc(ReviewList::getSortNumber)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package com.gxwebsoft.gxmu.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.Wrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.gxwebsoft.gxmu.entity.SjqnForm;
|
||||
import com.gxwebsoft.gxmu.mapper.SjqnFormMapper;
|
||||
import com.gxwebsoft.gxmu.service.ReviewListBindingService;
|
||||
import com.gxwebsoft.gxmu.service.SjqnFormService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 十佳青年申报表Service实现
|
||||
*/
|
||||
@Service
|
||||
public class SjqnFormServiceImpl extends ServiceImpl<SjqnFormMapper, SjqnForm> implements SjqnFormService {
|
||||
@Resource
|
||||
private ReviewListBindingService reviewListBindingService;
|
||||
|
||||
@Override
|
||||
public <E extends IPage<SjqnForm>> E page(E page, Wrapper<SjqnForm> queryWrapper) {
|
||||
return reviewListBindingService.bindPage(super.page(page, queryWrapper), "gxmu_sjqn",
|
||||
SjqnForm::getId, SjqnForm::setReviewList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SjqnForm> list(Wrapper<SjqnForm> queryWrapper) {
|
||||
return reviewListBindingService.bindList(super.list(queryWrapper), "gxmu_sjqn",
|
||||
SjqnForm::getId, SjqnForm::setReviewList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SjqnForm getById(Serializable id) {
|
||||
return reviewListBindingService.bindOne(super.getById(id), "gxmu_sjqn",
|
||||
SjqnForm::getId, SjqnForm::setReviewList);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package com.gxwebsoft.gxmu.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.Wrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.gxwebsoft.gxmu.entity.SjtbzbsjForm;
|
||||
import com.gxwebsoft.gxmu.mapper.SjtbzbsjFormMapper;
|
||||
import com.gxwebsoft.gxmu.service.ReviewListBindingService;
|
||||
import com.gxwebsoft.gxmu.service.SjtbzbsjFormService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 十佳团支部书记申报表Service实现
|
||||
*/
|
||||
@Service
|
||||
public class SjtbzbsjFormServiceImpl extends ServiceImpl<SjtbzbsjFormMapper, SjtbzbsjForm> implements SjtbzbsjFormService {
|
||||
@Resource
|
||||
private ReviewListBindingService reviewListBindingService;
|
||||
|
||||
@Override
|
||||
public <E extends IPage<SjtbzbsjForm>> E page(E page, Wrapper<SjtbzbsjForm> queryWrapper) {
|
||||
return reviewListBindingService.bindPage(super.page(page, queryWrapper), "gxmu_sjtbzbsj",
|
||||
SjtbzbsjForm::getId, SjtbzbsjForm::setReviewList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SjtbzbsjForm> list(Wrapper<SjtbzbsjForm> queryWrapper) {
|
||||
return reviewListBindingService.bindList(super.list(queryWrapper), "gxmu_sjtbzbsj",
|
||||
SjtbzbsjForm::getId, SjtbzbsjForm::setReviewList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SjtbzbsjForm getById(Serializable id) {
|
||||
return reviewListBindingService.bindOne(super.getById(id), "gxmu_sjtbzbsj",
|
||||
SjtbzbsjForm::getId, SjtbzbsjForm::setReviewList);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
package com.gxwebsoft.gxmu.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.Wrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.gxwebsoft.gxmu.entity.TyglForm;
|
||||
import com.gxwebsoft.gxmu.mapper.TyglFormMapper;
|
||||
import com.gxwebsoft.gxmu.param.TyglGrowthArchivesUpdateParam;
|
||||
import com.gxwebsoft.gxmu.param.TyglMemberRecordsUpdateParam;
|
||||
import com.gxwebsoft.gxmu.service.ReviewListBindingService;
|
||||
import com.gxwebsoft.gxmu.service.TyglFormService;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 团员管理Service实现
|
||||
*/
|
||||
@Service
|
||||
public class TyglFormServiceImpl extends ServiceImpl<TyglFormMapper, TyglForm>
|
||||
implements TyglFormService {
|
||||
@Resource
|
||||
private ReviewListBindingService reviewListBindingService;
|
||||
|
||||
@Override
|
||||
public <E extends IPage<TyglForm>> E page(E page, Wrapper<TyglForm> queryWrapper) {
|
||||
return reviewListBindingService.bindPage(super.page(page, queryWrapper), "gxmu_tygl_form",
|
||||
TyglForm::getId, TyglForm::setReviewList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TyglForm> list(Wrapper<TyglForm> queryWrapper) {
|
||||
return reviewListBindingService.bindList(super.list(queryWrapper), "gxmu_tygl_form",
|
||||
TyglForm::getId, TyglForm::setReviewList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TyglForm getById(Serializable id) {
|
||||
return reviewListBindingService.bindOne(super.getById(id), "gxmu_tygl_form",
|
||||
TyglForm::getId, TyglForm::setReviewList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TyglForm getCurrentUserForm(Integer userId, Integer tenantId) {
|
||||
if (userId == null || tenantId == null) {
|
||||
return null;
|
||||
}
|
||||
LambdaQueryWrapper<TyglForm> queryWrapper = new LambdaQueryWrapper<TyglForm>()
|
||||
.eq(TyglForm::getUserId, userId)
|
||||
.eq(TyglForm::getTenantId, tenantId)
|
||||
.orderByDesc(TyglForm::getUpdateTime)
|
||||
.orderByDesc(TyglForm::getId)
|
||||
.last("limit 1");
|
||||
return reviewListBindingService.bindOne(super.getOne(queryWrapper, false), "gxmu_tygl_form",
|
||||
TyglForm::getId, TyglForm::setReviewList);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public boolean updateMemberRecords(Integer id, TyglMemberRecordsUpdateParam param) {
|
||||
if (id == null || param == null) {
|
||||
return false;
|
||||
}
|
||||
TyglForm entity = new TyglForm();
|
||||
entity.setId(id);
|
||||
entity.setMemberRecords(param.getMemberRecords());
|
||||
return super.updateById(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public boolean updateGrowthArchives(Integer id, TyglGrowthArchivesUpdateParam param) {
|
||||
if (id == null || param == null) {
|
||||
return false;
|
||||
}
|
||||
TyglForm entity = new TyglForm();
|
||||
entity.setId(id);
|
||||
entity.setGrowthArchives(param.getGrowthArchives());
|
||||
return super.updateById(entity);
|
||||
}
|
||||
}
|
||||
+341
@@ -0,0 +1,341 @@
|
||||
package com.gxwebsoft.gxmu.service.impl;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.http.Header;
|
||||
import cn.hutool.http.HttpRequest;
|
||||
import com.gxwebsoft.gxmu.entity.TzbProjectListRecord;
|
||||
import com.gxwebsoft.gxmu.entity.TzbTalentListRecord;
|
||||
import com.gxwebsoft.gxmu.mapper.TzbProjectListRecordMapper;
|
||||
import com.gxwebsoft.gxmu.mapper.TzbTalentListRecordMapper;
|
||||
import com.gxwebsoft.gxmu.service.TzbProjectLibraryCrawlerService;
|
||||
import org.jsoup.Jsoup;
|
||||
import org.jsoup.nodes.Document;
|
||||
import org.jsoup.nodes.Element;
|
||||
import org.jsoup.select.Elements;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* 挑战杯项目/人才库爬虫Service实现
|
||||
*
|
||||
* @author Codex
|
||||
* @since 2026-04-14
|
||||
*/
|
||||
@Service
|
||||
public class TzbProjectLibraryCrawlerServiceImpl implements TzbProjectLibraryCrawlerService {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(TzbProjectLibraryCrawlerServiceImpl.class);
|
||||
|
||||
private static final String BASE_HOST = "https://xmk.tiaozhanbei.net";
|
||||
|
||||
private static final Pattern PAGE_PATTERN = Pattern.compile("[?&]page=(\\d+)");
|
||||
|
||||
private static final Pattern DETAIL_ID_PATTERN = Pattern.compile("/project/(\\d+)/");
|
||||
|
||||
private static final String DEFAULT_USER_AGENT = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) "
|
||||
+ "AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36";
|
||||
|
||||
private static final int MAX_RECORDS_PER_RUN_LIMIT = 100;
|
||||
|
||||
@Resource
|
||||
private TzbProjectListRecordMapper tzbProjectListRecordMapper;
|
||||
|
||||
@Resource
|
||||
private TzbTalentListRecordMapper tzbTalentListRecordMapper;
|
||||
|
||||
@Value("${gxmu.tzb-crawler.project-list-url:https://xmk.tiaozhanbei.net/project/list/project/}")
|
||||
private String projectListUrl;
|
||||
|
||||
@Value("${gxmu.tzb-crawler.talent-list-url:https://xmk.tiaozhanbei.net/project/list/talent/}")
|
||||
private String talentListUrl;
|
||||
|
||||
@Value("${gxmu.tzb-crawler.timeout-ms:15000}")
|
||||
private int timeoutMs;
|
||||
|
||||
@Value("${gxmu.tzb-crawler.max-retries:3}")
|
||||
private int maxRetries;
|
||||
|
||||
@Value("${gxmu.tzb-crawler.max-pages:0}")
|
||||
private int maxPages;
|
||||
|
||||
@Value("${gxmu.tzb-crawler.log-page-interval:100}")
|
||||
private int logPageInterval;
|
||||
|
||||
@Override
|
||||
public void syncProjectList() {
|
||||
syncProjectList(Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int syncProjectList(int maxRows) {
|
||||
LocalDateTime syncTime = LocalDateTime.now();
|
||||
int runLimit = resolveRunLimit(maxRows);
|
||||
int totalRows = 0;
|
||||
int totalPages = 1;
|
||||
for (int pageNo = 1; pageNo <= totalPages; pageNo++) {
|
||||
if (totalRows >= runLimit) {
|
||||
logger.info("挑战杯项目库同步达到本次上限 {} 条,停止继续抓取", runLimit);
|
||||
break;
|
||||
}
|
||||
String pageUrl = buildPageUrl(projectListUrl, pageNo);
|
||||
Document document = fetchDocument(pageUrl);
|
||||
if (pageNo == 1) {
|
||||
totalPages = resolveTargetPages(document);
|
||||
logger.info("挑战杯项目库开始同步,共 {} 页", totalPages);
|
||||
}
|
||||
List<TzbProjectListRecord> records = parseProjectRows(document, pageUrl, pageNo, syncTime, runLimit - totalRows);
|
||||
if (CollectionUtils.isEmpty(records)) {
|
||||
logger.warn("挑战杯项目库第 {} 页未解析到数据,提前结束", pageNo);
|
||||
break;
|
||||
}
|
||||
tzbProjectListRecordMapper.batchUpsert(records);
|
||||
totalRows += records.size();
|
||||
logPageProgress("项目库", pageNo, totalPages, records.size(), totalRows);
|
||||
}
|
||||
logger.info("挑战杯项目库同步完成,共写入/更新 {} 条记录", totalRows);
|
||||
return totalRows;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void syncTalentList() {
|
||||
syncTalentList(Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int syncTalentList(int maxRows) {
|
||||
LocalDateTime syncTime = LocalDateTime.now();
|
||||
int runLimit = resolveRunLimit(maxRows);
|
||||
int totalRows = 0;
|
||||
int totalPages = 1;
|
||||
for (int pageNo = 1; pageNo <= totalPages; pageNo++) {
|
||||
if (totalRows >= runLimit) {
|
||||
logger.info("挑战杯人才库同步达到本次上限 {} 条,停止继续抓取", runLimit);
|
||||
break;
|
||||
}
|
||||
String pageUrl = buildPageUrl(talentListUrl, pageNo);
|
||||
Document document = fetchDocument(pageUrl);
|
||||
if (pageNo == 1) {
|
||||
totalPages = resolveTargetPages(document);
|
||||
logger.info("挑战杯人才库开始同步,共 {} 页", totalPages);
|
||||
}
|
||||
List<TzbTalentListRecord> records = parseTalentRows(document, pageUrl, pageNo, syncTime, runLimit - totalRows);
|
||||
if (CollectionUtils.isEmpty(records)) {
|
||||
logger.warn("挑战杯人才库第 {} 页未解析到数据,提前结束", pageNo);
|
||||
break;
|
||||
}
|
||||
tzbTalentListRecordMapper.batchUpsert(records);
|
||||
totalRows += records.size();
|
||||
logPageProgress("人才库", pageNo, totalPages, records.size(), totalRows);
|
||||
}
|
||||
logger.info("挑战杯人才库同步完成,共写入/更新 {} 条记录", totalRows);
|
||||
return totalRows;
|
||||
}
|
||||
|
||||
private void logPageProgress(String typeName, int pageNo, int totalPages, int pageRows, int totalRows) {
|
||||
if (pageNo == 1 || pageNo == totalPages || (logPageInterval > 0 && pageNo % logPageInterval == 0)) {
|
||||
logger.info("挑战杯{}同步进度:第 {}/{} 页,本页 {} 条,累计 {} 条", typeName, pageNo, totalPages, pageRows, totalRows);
|
||||
}
|
||||
}
|
||||
|
||||
private int resolveTargetPages(Document document) {
|
||||
int resolvedPages = resolveTotalPages(document);
|
||||
if (maxPages > 0) {
|
||||
return Math.min(resolvedPages, maxPages);
|
||||
}
|
||||
return resolvedPages;
|
||||
}
|
||||
|
||||
private int resolveTotalPages(Document document) {
|
||||
int maxPage = 1;
|
||||
Elements links = document.select("nav[aria-label=pagination] a[href*=\"page=\"]");
|
||||
for (Element link : links) {
|
||||
int pageNo = extractPageNumber(link.attr("href"));
|
||||
if (pageNo > maxPage) {
|
||||
maxPage = pageNo;
|
||||
}
|
||||
}
|
||||
return maxPage;
|
||||
}
|
||||
|
||||
private int resolveRunLimit(int maxRows) {
|
||||
return Math.min(Math.max(maxRows, 1), MAX_RECORDS_PER_RUN_LIMIT);
|
||||
}
|
||||
|
||||
private List<TzbProjectListRecord> parseProjectRows(Document document, String pageUrl, int pageNo, LocalDateTime syncTime, int remainingLimit) {
|
||||
List<TzbProjectListRecord> records = new ArrayList<TzbProjectListRecord>();
|
||||
int rowLimit = Math.max(remainingLimit, 0);
|
||||
if (rowLimit <= 0) {
|
||||
return records;
|
||||
}
|
||||
Elements rows = document.select("table tbody tr");
|
||||
for (Element row : rows) {
|
||||
if (records.size() >= rowLimit) {
|
||||
break;
|
||||
}
|
||||
Elements cells = row.select("td");
|
||||
if (cells.size() < 7) {
|
||||
continue;
|
||||
}
|
||||
String detailUrl = getDetailUrl(row);
|
||||
Long sourceId = extractSourceId(detailUrl);
|
||||
if (sourceId == null) {
|
||||
continue;
|
||||
}
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
TzbProjectListRecord record = new TzbProjectListRecord();
|
||||
record.setSourceId(sourceId);
|
||||
record.setProjectName(normalizeText(cells.get(0).select("div").text()));
|
||||
record.setSchoolName(normalizeText(cells.get(1).text()));
|
||||
record.setAwardName(normalizeText(cells.get(2).text()));
|
||||
record.setMatchYear(parseInteger(normalizeText(cells.get(3).text())));
|
||||
record.setMatchTerm(normalizeText(cells.get(4).text()));
|
||||
record.setMatchLevel(normalizeText(cells.get(5).text()));
|
||||
record.setCoverImage(row.select("td:eq(0) img").attr("abs:src"));
|
||||
record.setDetailUrl(detailUrl);
|
||||
record.setSourceUrl(pageUrl);
|
||||
record.setPageNo(pageNo);
|
||||
record.setLastSyncTime(syncTime);
|
||||
record.setCreateTime(now);
|
||||
record.setUpdateTime(now);
|
||||
record.setDeleted(0);
|
||||
records.add(record);
|
||||
}
|
||||
return records;
|
||||
}
|
||||
|
||||
private List<TzbTalentListRecord> parseTalentRows(Document document, String pageUrl, int pageNo, LocalDateTime syncTime, int remainingLimit) {
|
||||
List<TzbTalentListRecord> records = new ArrayList<TzbTalentListRecord>();
|
||||
int rowLimit = Math.max(remainingLimit, 0);
|
||||
if (rowLimit <= 0) {
|
||||
return records;
|
||||
}
|
||||
Elements rows = document.select("table tbody tr");
|
||||
for (Element row : rows) {
|
||||
if (records.size() >= rowLimit) {
|
||||
break;
|
||||
}
|
||||
Elements cells = row.select("td");
|
||||
if (cells.size() < 8) {
|
||||
continue;
|
||||
}
|
||||
String detailUrl = getDetailUrl(row);
|
||||
Long sourceId = extractSourceId(detailUrl);
|
||||
if (sourceId == null) {
|
||||
continue;
|
||||
}
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
TzbTalentListRecord record = new TzbTalentListRecord();
|
||||
record.setSourceId(sourceId);
|
||||
record.setPersonName(normalizeText(cells.get(0).select("div").text()));
|
||||
record.setSchoolName(normalizeText(cells.get(1).text()));
|
||||
record.setTalentType(normalizeText(cells.get(2).text()));
|
||||
record.setProjectName(normalizeText(cells.get(3).text()));
|
||||
record.setAwardName(normalizeText(cells.get(4).text()));
|
||||
record.setMatchTerm(normalizeText(cells.get(5).text()));
|
||||
record.setMatchLevel(normalizeText(cells.get(6).text()));
|
||||
record.setCoverImage(row.select("td:eq(0) img").attr("abs:src"));
|
||||
record.setDetailUrl(detailUrl);
|
||||
record.setSourceUrl(pageUrl);
|
||||
record.setPageNo(pageNo);
|
||||
record.setLastSyncTime(syncTime);
|
||||
record.setCreateTime(now);
|
||||
record.setUpdateTime(now);
|
||||
record.setDeleted(0);
|
||||
records.add(record);
|
||||
}
|
||||
return records;
|
||||
}
|
||||
|
||||
private Document fetchDocument(String pageUrl) {
|
||||
RuntimeException lastException = null;
|
||||
int retryTimes = Math.max(maxRetries, 1);
|
||||
for (int attempt = 1; attempt <= retryTimes; attempt++) {
|
||||
try {
|
||||
String body = HttpRequest.get(pageUrl)
|
||||
.timeout(timeoutMs)
|
||||
.header(Header.USER_AGENT, DEFAULT_USER_AGENT)
|
||||
.header(Header.REFERER, BASE_HOST + "/project/")
|
||||
.execute()
|
||||
.body();
|
||||
return Jsoup.parse(body, BASE_HOST);
|
||||
} catch (Exception e) {
|
||||
lastException = new RuntimeException("抓取页面失败: " + pageUrl + ",第 " + attempt + " 次重试失败", e);
|
||||
logger.warn("抓取页面失败,第 {}/{} 次:{}", attempt, retryTimes, pageUrl);
|
||||
}
|
||||
}
|
||||
throw lastException;
|
||||
}
|
||||
|
||||
private String buildPageUrl(String baseUrl, int pageNo) {
|
||||
if (pageNo <= 1) {
|
||||
return baseUrl;
|
||||
}
|
||||
return baseUrl + (baseUrl.contains("?") ? "&" : "?") + "page=" + pageNo;
|
||||
}
|
||||
|
||||
private String getDetailUrl(Element row) {
|
||||
Element link = row.select("a[href]").last();
|
||||
if (link == null) {
|
||||
return null;
|
||||
}
|
||||
return link.attr("abs:href");
|
||||
}
|
||||
|
||||
private int extractPageNumber(String href) {
|
||||
if (StrUtil.isBlank(href)) {
|
||||
return 0;
|
||||
}
|
||||
Matcher matcher = PAGE_PATTERN.matcher(href);
|
||||
if (matcher.find()) {
|
||||
return parseInteger(matcher.group(1), 0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private Long extractSourceId(String detailUrl) {
|
||||
if (StrUtil.isBlank(detailUrl)) {
|
||||
return null;
|
||||
}
|
||||
Matcher matcher = DETAIL_ID_PATTERN.matcher(detailUrl);
|
||||
if (matcher.find()) {
|
||||
try {
|
||||
return Long.valueOf(matcher.group(1));
|
||||
} catch (NumberFormatException e) {
|
||||
logger.warn("解析详情ID失败:{}", detailUrl);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Integer parseInteger(String value) {
|
||||
return parseInteger(value, null);
|
||||
}
|
||||
|
||||
private Integer parseInteger(String value, Integer defaultValue) {
|
||||
if (StrUtil.isBlank(value)) {
|
||||
return defaultValue;
|
||||
}
|
||||
try {
|
||||
return Integer.valueOf(value);
|
||||
} catch (NumberFormatException e) {
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
private String normalizeText(String value) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
return value.replace('\u00A0', ' ').replaceAll("\\s+", " ").trim();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
package com.gxwebsoft.gxmu.service.impl;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.gxwebsoft.common.core.web.PageParam;
|
||||
import com.gxwebsoft.common.core.web.PageResult;
|
||||
import com.gxwebsoft.gxmu.entity.TzbProjectListRecord;
|
||||
import com.gxwebsoft.gxmu.mapper.TzbProjectListRecordMapper;
|
||||
import com.gxwebsoft.gxmu.param.TzbProjectListRecordParam;
|
||||
import com.gxwebsoft.gxmu.service.TzbProjectListRecordService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 挑战杯项目库列表Service实现
|
||||
*
|
||||
* @author Codex
|
||||
* @since 2026-04-14
|
||||
*/
|
||||
@Service
|
||||
public class TzbProjectListRecordServiceImpl extends ServiceImpl<TzbProjectListRecordMapper, TzbProjectListRecord>
|
||||
implements TzbProjectListRecordService {
|
||||
|
||||
@Override
|
||||
public PageResult<TzbProjectListRecord> pageRel(TzbProjectListRecordParam param) {
|
||||
PageParam<TzbProjectListRecord, TzbProjectListRecordParam> page = new PageParam<>(param);
|
||||
page.setDefaultOrder("source_id desc");
|
||||
QueryWrapper<TzbProjectListRecord> wrapper = buildWrapper(page, param);
|
||||
IPage<TzbProjectListRecord> result = baseMapper.selectPage(page, wrapper);
|
||||
return new PageResult<>(result.getRecords(), result.getTotal());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TzbProjectListRecord> listRel(TzbProjectListRecordParam param) {
|
||||
PageParam<TzbProjectListRecord, TzbProjectListRecordParam> page = new PageParam<>(param);
|
||||
page.setDefaultOrder("source_id desc");
|
||||
QueryWrapper<TzbProjectListRecord> wrapper = buildWrapper(page, param);
|
||||
List<TzbProjectListRecord> list = baseMapper.selectList(wrapper);
|
||||
return page.sortRecords(list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TzbProjectListRecord getByIdRel(Integer id) {
|
||||
return baseMapper.selectById(id);
|
||||
}
|
||||
|
||||
private QueryWrapper<TzbProjectListRecord> buildWrapper(
|
||||
PageParam<TzbProjectListRecord, TzbProjectListRecordParam> page,
|
||||
TzbProjectListRecordParam param
|
||||
) {
|
||||
QueryWrapper<TzbProjectListRecord> wrapper = page.getWrapper();
|
||||
if (param == null || param.getDeleted() == null) {
|
||||
wrapper.eq("deleted", 0);
|
||||
}
|
||||
if (param != null && StrUtil.isNotBlank(param.getKeywords())) {
|
||||
wrapper.and(q -> q.like("project_name", param.getKeywords())
|
||||
.or()
|
||||
.like("school_name", param.getKeywords())
|
||||
.or()
|
||||
.like("award_name", param.getKeywords())
|
||||
.or()
|
||||
.like("match_term", param.getKeywords()));
|
||||
}
|
||||
return page.getOrderWrapper(wrapper);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
package com.gxwebsoft.gxmu.service.impl;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.gxwebsoft.common.core.web.PageParam;
|
||||
import com.gxwebsoft.common.core.web.PageResult;
|
||||
import com.gxwebsoft.gxmu.entity.TzbTalentListRecord;
|
||||
import com.gxwebsoft.gxmu.mapper.TzbTalentListRecordMapper;
|
||||
import com.gxwebsoft.gxmu.param.TzbTalentListRecordParam;
|
||||
import com.gxwebsoft.gxmu.service.TzbTalentListRecordService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 挑战杯人才库列表Service实现
|
||||
*
|
||||
* @author Codex
|
||||
* @since 2026-04-14
|
||||
*/
|
||||
@Service
|
||||
public class TzbTalentListRecordServiceImpl extends ServiceImpl<TzbTalentListRecordMapper, TzbTalentListRecord>
|
||||
implements TzbTalentListRecordService {
|
||||
|
||||
@Override
|
||||
public PageResult<TzbTalentListRecord> pageRel(TzbTalentListRecordParam param) {
|
||||
PageParam<TzbTalentListRecord, TzbTalentListRecordParam> page = new PageParam<>(param);
|
||||
page.setDefaultOrder("source_id desc");
|
||||
QueryWrapper<TzbTalentListRecord> wrapper = buildWrapper(page, param);
|
||||
IPage<TzbTalentListRecord> result = baseMapper.selectPage(page, wrapper);
|
||||
return new PageResult<>(result.getRecords(), result.getTotal());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TzbTalentListRecord> listRel(TzbTalentListRecordParam param) {
|
||||
PageParam<TzbTalentListRecord, TzbTalentListRecordParam> page = new PageParam<>(param);
|
||||
page.setDefaultOrder("source_id desc");
|
||||
QueryWrapper<TzbTalentListRecord> wrapper = buildWrapper(page, param);
|
||||
List<TzbTalentListRecord> list = baseMapper.selectList(wrapper);
|
||||
return page.sortRecords(list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TzbTalentListRecord getByIdRel(Integer id) {
|
||||
return baseMapper.selectById(id);
|
||||
}
|
||||
|
||||
private QueryWrapper<TzbTalentListRecord> buildWrapper(
|
||||
PageParam<TzbTalentListRecord, TzbTalentListRecordParam> page,
|
||||
TzbTalentListRecordParam param
|
||||
) {
|
||||
QueryWrapper<TzbTalentListRecord> wrapper = page.getWrapper();
|
||||
if (param == null || param.getDeleted() == null) {
|
||||
wrapper.eq("deleted", 0);
|
||||
}
|
||||
if (param != null && StrUtil.isNotBlank(param.getKeywords())) {
|
||||
wrapper.and(q -> q.like("person_name", param.getKeywords())
|
||||
.or()
|
||||
.like("school_name", param.getKeywords())
|
||||
.or()
|
||||
.like("project_name", param.getKeywords())
|
||||
.or()
|
||||
.like("award_name", param.getKeywords())
|
||||
.or()
|
||||
.like("talent_type", param.getKeywords()));
|
||||
}
|
||||
return page.getOrderWrapper(wrapper);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,262 @@
|
||||
package com.gxwebsoft.gxmu.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.Wrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.gxwebsoft.gxmu.entity.ReviewList;
|
||||
import com.gxwebsoft.gxmu.entity.TzbcyForm;
|
||||
import com.gxwebsoft.gxmu.mapper.TzbcyFormMapper;
|
||||
import com.gxwebsoft.gxmu.model.TzbcyStatisticsResult;
|
||||
import com.gxwebsoft.gxmu.service.ReviewListBindingService;
|
||||
import com.gxwebsoft.gxmu.service.TzbcyFormService;
|
||||
import com.gxwebsoft.gxmu.util.TzbcyFormItemNormalizer;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 挑战杯创业计划竞赛申报表Service实现
|
||||
*/
|
||||
@Service
|
||||
public class TzbcyFormServiceImpl extends ServiceImpl<TzbcyFormMapper, TzbcyForm> implements TzbcyFormService {
|
||||
@Resource
|
||||
private ReviewListBindingService reviewListBindingService;
|
||||
|
||||
@Override
|
||||
public <E extends IPage<TzbcyForm>> E page(E page, Wrapper<TzbcyForm> queryWrapper) {
|
||||
E result = reviewListBindingService.bindPage(super.page(page, queryWrapper), "gxmu_tzbcy_form",
|
||||
TzbcyForm::getId, TzbcyForm::setReviewList);
|
||||
normalizeForms(result.getRecords());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TzbcyForm> list(Wrapper<TzbcyForm> queryWrapper) {
|
||||
List<TzbcyForm> result = reviewListBindingService.bindList(super.list(queryWrapper), "gxmu_tzbcy_form",
|
||||
TzbcyForm::getId, TzbcyForm::setReviewList);
|
||||
normalizeForms(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TzbcyForm getById(Serializable id) {
|
||||
TzbcyForm result = reviewListBindingService.bindOne(super.getById(id), "gxmu_tzbcy_form",
|
||||
TzbcyForm::getId, TzbcyForm::setReviewList);
|
||||
normalizeForm(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TzbcyStatisticsResult getStatistics(Integer year) {
|
||||
List<TzbcyForm> allForms = list(new LambdaQueryWrapper<TzbcyForm>()
|
||||
.orderByDesc(TzbcyForm::getYear)
|
||||
.orderByDesc(TzbcyForm::getId));
|
||||
|
||||
List<TzbcyForm> filteredForms = allForms.stream()
|
||||
.filter(item -> year == null || year.equals(item.getYear()))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
TzbcyStatisticsResult result = new TzbcyStatisticsResult();
|
||||
result.setYear(year);
|
||||
result.setAvailableYears(allForms.stream()
|
||||
.map(TzbcyForm::getYear)
|
||||
.filter(item -> item != null)
|
||||
.distinct()
|
||||
.sorted(Comparator.reverseOrder())
|
||||
.collect(Collectors.toList()));
|
||||
result.setAwardCountDescription("当前按“审核通过作品数”统计获奖数量。");
|
||||
|
||||
TzbcyStatisticsResult.Summary summary = new TzbcyStatisticsResult.Summary();
|
||||
summary.setDeclarationCount(filteredForms.size());
|
||||
summary.setParticipantCount(countDistinctParticipants(filteredForms));
|
||||
summary.setAdvisorCount(countDistinctAdvisors(filteredForms));
|
||||
summary.setAwardCount((int) filteredForms.stream().filter(this::isAwardedForm).count());
|
||||
summary.setSchoolCount((int) filteredForms.stream()
|
||||
.map(TzbcyForm::getSchoolName)
|
||||
.filter(this::hasText)
|
||||
.map(String::trim)
|
||||
.distinct()
|
||||
.count());
|
||||
result.setSummary(summary);
|
||||
|
||||
result.setYearDistribution(buildDistribution(allForms, new LabelExtractor() {
|
||||
@Override
|
||||
public String extract(TzbcyForm form) {
|
||||
return form.getYear() == null ? "未填年份" : String.valueOf(form.getYear());
|
||||
}
|
||||
}, false, 0));
|
||||
result.setTypeDistribution(buildDistribution(filteredForms, new LabelExtractor() {
|
||||
@Override
|
||||
public String extract(TzbcyForm form) {
|
||||
return form.getProjectType();
|
||||
}
|
||||
}, true, 0));
|
||||
result.setGroupDistribution(buildDistribution(filteredForms, new LabelExtractor() {
|
||||
@Override
|
||||
public String extract(TzbcyForm form) {
|
||||
return form.getProjectGroup();
|
||||
}
|
||||
}, true, 0));
|
||||
result.setSchoolDistribution(buildDistribution(filteredForms, new LabelExtractor() {
|
||||
@Override
|
||||
public String extract(TzbcyForm form) {
|
||||
return form.getSchoolName();
|
||||
}
|
||||
}, true, 10));
|
||||
return result;
|
||||
}
|
||||
|
||||
private int countDistinctParticipants(List<TzbcyForm> forms) {
|
||||
Set<String> participants = new LinkedHashSet<>();
|
||||
for (TzbcyForm form : forms) {
|
||||
if (form.getTeamMembers() == null) {
|
||||
continue;
|
||||
}
|
||||
for (TzbcyForm.TeamMember member : form.getTeamMembers()) {
|
||||
String key = buildPersonKey(member == null ? null : member.getName(),
|
||||
member == null ? null : member.getPhone());
|
||||
if (key != null) {
|
||||
participants.add(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
return participants.size();
|
||||
}
|
||||
|
||||
private int countDistinctAdvisors(List<TzbcyForm> forms) {
|
||||
Set<String> advisors = new LinkedHashSet<>();
|
||||
for (TzbcyForm form : forms) {
|
||||
if (form.getAdvisors() == null) {
|
||||
continue;
|
||||
}
|
||||
for (TzbcyForm.Advisor advisor : form.getAdvisors()) {
|
||||
String key = buildPersonKey(advisor == null ? null : advisor.getName(),
|
||||
advisor == null ? null : advisor.getPhone());
|
||||
if (key != null) {
|
||||
advisors.add(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
return advisors.size();
|
||||
}
|
||||
|
||||
private boolean isAwardedForm(TzbcyForm form) {
|
||||
if (form == null || form.getReviewList() == null || form.getReviewList().isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
List<ReviewList> reviewList = form.getReviewList();
|
||||
ReviewList latest = reviewList.get(reviewList.size() - 1);
|
||||
return latest != null && latest.getStatus() != null && latest.getStatus() == 1;
|
||||
}
|
||||
|
||||
private String buildPersonKey(String name, String phone) {
|
||||
String normalizedName = normalizeText(name);
|
||||
String normalizedPhone = normalizeText(phone);
|
||||
if (normalizedName == null && normalizedPhone == null) {
|
||||
return null;
|
||||
}
|
||||
if (normalizedName != null && normalizedPhone != null) {
|
||||
return normalizedName + "#" + normalizedPhone;
|
||||
}
|
||||
return normalizedName != null ? normalizedName : normalizedPhone;
|
||||
}
|
||||
|
||||
private String normalizeText(String value) {
|
||||
if (!hasText(value)) {
|
||||
return null;
|
||||
}
|
||||
return value.trim();
|
||||
}
|
||||
|
||||
private boolean hasText(String value) {
|
||||
return value != null && !value.trim().isEmpty();
|
||||
}
|
||||
|
||||
private List<TzbcyStatisticsResult.StatisticItem> buildDistribution(List<TzbcyForm> forms,
|
||||
LabelExtractor extractor,
|
||||
boolean sortByValueDesc,
|
||||
int limit) {
|
||||
if (forms == null || forms.isEmpty()) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
Map<String, Integer> countMap = new LinkedHashMap<>();
|
||||
for (TzbcyForm form : forms) {
|
||||
String label = normalizeText(extractor.extract(form));
|
||||
if (label == null) {
|
||||
label = "未填写";
|
||||
}
|
||||
countMap.put(label, countMap.getOrDefault(label, 0) + 1);
|
||||
}
|
||||
List<TzbcyStatisticsResult.StatisticItem> list = countMap.entrySet().stream()
|
||||
.map(item -> new TzbcyStatisticsResult.StatisticItem(item.getKey(), item.getValue()))
|
||||
.collect(Collectors.toList());
|
||||
if (sortByValueDesc) {
|
||||
list.sort(Comparator
|
||||
.comparing(TzbcyStatisticsResult.StatisticItem::getValue, Comparator.reverseOrder())
|
||||
.thenComparing(TzbcyStatisticsResult.StatisticItem::getLabel, Comparator.nullsLast(String::compareTo)));
|
||||
} else {
|
||||
list.sort(new Comparator<TzbcyStatisticsResult.StatisticItem>() {
|
||||
@Override
|
||||
public int compare(TzbcyStatisticsResult.StatisticItem left, TzbcyStatisticsResult.StatisticItem right) {
|
||||
Integer leftYear = parseYear(left.getLabel());
|
||||
Integer rightYear = parseYear(right.getLabel());
|
||||
if (leftYear != null && rightYear != null) {
|
||||
return leftYear.compareTo(rightYear);
|
||||
}
|
||||
if (leftYear != null) {
|
||||
return -1;
|
||||
}
|
||||
if (rightYear != null) {
|
||||
return 1;
|
||||
}
|
||||
String leftLabel = left.getLabel() == null ? "" : left.getLabel();
|
||||
String rightLabel = right.getLabel() == null ? "" : right.getLabel();
|
||||
return leftLabel.compareTo(rightLabel);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (limit > 0 && list.size() > limit) {
|
||||
return new ArrayList<>(list.subList(0, limit));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private Integer parseYear(String value) {
|
||||
if (!hasText(value)) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return Integer.parseInt(value.trim());
|
||||
} catch (NumberFormatException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private void normalizeForms(List<TzbcyForm> forms) {
|
||||
if (forms == null || forms.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
for (TzbcyForm form : forms) {
|
||||
normalizeForm(form);
|
||||
}
|
||||
}
|
||||
|
||||
private void normalizeForm(TzbcyForm form) {
|
||||
TzbcyFormItemNormalizer.normalize(form);
|
||||
}
|
||||
|
||||
private interface LabelExtractor {
|
||||
String extract(TzbcyForm form);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,319 @@
|
||||
package com.gxwebsoft.gxmu.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.gxwebsoft.common.core.config.ConfigProperties;
|
||||
import com.gxwebsoft.common.core.exception.BusinessException;
|
||||
import com.gxwebsoft.common.core.web.PageParam;
|
||||
import com.gxwebsoft.common.core.web.PageResult;
|
||||
import com.gxwebsoft.common.system.entity.FileRecord;
|
||||
import com.gxwebsoft.common.system.service.FileRecordService;
|
||||
import com.gxwebsoft.gxmu.entity.TzbcyForm;
|
||||
import com.gxwebsoft.gxmu.entity.TzbcyMaterial;
|
||||
import com.gxwebsoft.gxmu.mapper.TzbcyMaterialMapper;
|
||||
import com.gxwebsoft.gxmu.param.TzbcyMaterialParam;
|
||||
import com.gxwebsoft.gxmu.service.TzbcyFormService;
|
||||
import com.gxwebsoft.gxmu.service.TzbcyMaterialService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
/**
|
||||
* 挑战杯申报材料Service实现
|
||||
*/
|
||||
@Service
|
||||
public class TzbcyMaterialServiceImpl extends ServiceImpl<TzbcyMaterialMapper, TzbcyMaterial>
|
||||
implements TzbcyMaterialService {
|
||||
|
||||
@Resource
|
||||
private TzbcyFormService tzbcyFormService;
|
||||
@Resource
|
||||
private FileRecordService fileRecordService;
|
||||
@Resource
|
||||
private ConfigProperties config;
|
||||
|
||||
@Override
|
||||
public PageResult<TzbcyMaterial> pageRel(TzbcyMaterialParam param) {
|
||||
PageParam<TzbcyMaterial, TzbcyMaterialParam> page = new PageParam<>(param);
|
||||
page.setDefaultOrder("id desc");
|
||||
List<TzbcyMaterial> list = baseMapper.selectPageRel(page, param);
|
||||
normalizeFileUrls(list);
|
||||
return new PageResult<>(list, page.getTotal());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TzbcyMaterial> listRel(TzbcyMaterialParam param) {
|
||||
List<TzbcyMaterial> list = baseMapper.selectListRel(param);
|
||||
normalizeFileUrls(list);
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TzbcyMaterial getByIdRel(Integer id) {
|
||||
TzbcyMaterialParam param = new TzbcyMaterialParam();
|
||||
param.setId(id);
|
||||
List<TzbcyMaterial> list = baseMapper.selectListRel(param);
|
||||
normalizeFileUrls(list);
|
||||
return list == null || list.isEmpty() ? null : list.get(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean saveMaterial(TzbcyMaterial material, FileRecord fileRecord, Integer loginUserId, Integer tenantId) {
|
||||
validateEditablePayload(material, fileRecord);
|
||||
TzbcyForm form = tzbcyFormService.getById(material.getFormId());
|
||||
if (form == null) {
|
||||
throw new BusinessException("申报记录不存在");
|
||||
}
|
||||
fillFileInfo(material, fileRecord);
|
||||
material.setStatus(0);
|
||||
material.setRejectReason(null);
|
||||
material.setAuditUserId(null);
|
||||
material.setAuditTime(null);
|
||||
material.setUserId(loginUserId != null ? loginUserId : form.getUserId());
|
||||
material.setTenantId(tenantId);
|
||||
return save(material);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean updateMaterial(TzbcyMaterial material, FileRecord fileRecord) {
|
||||
validateEditablePayload(material, fileRecord);
|
||||
TzbcyMaterial old = getById(material.getId());
|
||||
if (old == null) {
|
||||
throw new BusinessException("材料不存在");
|
||||
}
|
||||
if (Integer.valueOf(1).equals(old.getStatus())) {
|
||||
throw new BusinessException("材料已审核通过,不能再编辑");
|
||||
}
|
||||
material.setFormId(old.getFormId());
|
||||
fillFileInfo(material, fileRecord);
|
||||
material.setStatus(0);
|
||||
material.setRejectReason(null);
|
||||
material.setAuditUserId(null);
|
||||
material.setAuditTime(null);
|
||||
material.setUserId(old.getUserId());
|
||||
material.setTenantId(old.getTenantId());
|
||||
return updateById(material);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean audit(Integer id, Integer status, String rejectReason, Integer auditUserId) {
|
||||
if (!Integer.valueOf(1).equals(status) && !Integer.valueOf(2).equals(status)) {
|
||||
throw new BusinessException("审核状态不正确");
|
||||
}
|
||||
TzbcyMaterial old = getById(id);
|
||||
if (old == null) {
|
||||
throw new BusinessException("材料不存在");
|
||||
}
|
||||
TzbcyMaterial update = new TzbcyMaterial();
|
||||
update.setId(id);
|
||||
update.setStatus(status);
|
||||
update.setRejectReason(Integer.valueOf(2).equals(status) ? rejectReason : null);
|
||||
update.setAuditUserId(auditUserId);
|
||||
update.setAuditTime(LocalDateTime.now());
|
||||
return updateById(update);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileRecord exportZip(TzbcyMaterialParam param, String uploadPath, String requestURL, Integer loginUserId)
|
||||
throws IOException {
|
||||
List<TzbcyMaterial> materials = listRel(param);
|
||||
if (materials == null || materials.isEmpty()) {
|
||||
throw new BusinessException("暂无可导出的材料");
|
||||
}
|
||||
String relativePath = "file/zip/挑战杯材料_" + System.currentTimeMillis() + ".zip";
|
||||
File targetFile = new File(uploadPath + relativePath);
|
||||
File parentFile = targetFile.getParentFile();
|
||||
if (parentFile != null && !parentFile.exists()) {
|
||||
parentFile.mkdirs();
|
||||
}
|
||||
|
||||
Set<String> entryNames = new LinkedHashSet<>();
|
||||
int count = 0;
|
||||
try (FileOutputStream outputStream = new FileOutputStream(targetFile);
|
||||
ZipOutputStream zipOutputStream = new ZipOutputStream(outputStream)) {
|
||||
byte[] buffer = new byte[8192];
|
||||
for (TzbcyMaterial material : materials) {
|
||||
File sourceFile = resolveSourceFile(material, uploadPath);
|
||||
if (sourceFile == null || !sourceFile.exists() || !sourceFile.isFile()) {
|
||||
continue;
|
||||
}
|
||||
String entryName = buildEntryName(material, entryNames);
|
||||
zipOutputStream.putNextEntry(new ZipEntry(entryName));
|
||||
try (FileInputStream inputStream = new FileInputStream(sourceFile)) {
|
||||
int len;
|
||||
while ((len = inputStream.read(buffer)) != -1) {
|
||||
zipOutputStream.write(buffer, 0, len);
|
||||
}
|
||||
}
|
||||
zipOutputStream.closeEntry();
|
||||
count++;
|
||||
}
|
||||
zipOutputStream.finish();
|
||||
}
|
||||
if (count == 0) {
|
||||
targetFile.delete();
|
||||
throw new BusinessException("暂无可导出的实体文件");
|
||||
}
|
||||
|
||||
FileRecord result = new FileRecord();
|
||||
result.setCreateUserId(loginUserId);
|
||||
result.setName(targetFile.getName());
|
||||
result.setPath(targetFile.getAbsolutePath());
|
||||
result.setLength(targetFile.length());
|
||||
result.setContentType("application/zip");
|
||||
result.setUrl(trimEnd(requestURL) + "/" + relativePath);
|
||||
result.setDownloadUrl(result.getUrl());
|
||||
fileRecordService.save(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
private void validateEditablePayload(TzbcyMaterial material, FileRecord fileRecord) {
|
||||
if (material == null || material.getFormId() == null && material.getId() == null) {
|
||||
throw new BusinessException("材料参数不完整");
|
||||
}
|
||||
if (!hasText(material.getMaterialType())) {
|
||||
throw new BusinessException("请输入材料类型");
|
||||
}
|
||||
if (fileRecord == null || fileRecord.getId() == null) {
|
||||
throw new BusinessException("请上传材料文件");
|
||||
}
|
||||
}
|
||||
|
||||
private void fillFileInfo(TzbcyMaterial material, FileRecord fileRecord) {
|
||||
material.setFileId(fileRecord.getId());
|
||||
material.setFileName(fileRecord.getName());
|
||||
material.setFilePath(fileRecord.getPath());
|
||||
material.setFileUrl(resolveFileUrl(fileRecord.getPath()));
|
||||
material.setDownloadUrl(resolveDownloadUrl(fileRecord.getPath()));
|
||||
material.setFileSize(fileRecord.getLength());
|
||||
material.setContentType(fileRecord.getContentType());
|
||||
}
|
||||
|
||||
private void normalizeFileUrls(List<TzbcyMaterial> materials) {
|
||||
if (materials == null || materials.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
for (TzbcyMaterial material : materials) {
|
||||
if (material == null) {
|
||||
continue;
|
||||
}
|
||||
String path = material.getFilePath();
|
||||
if (!hasText(path) && material.getFileId() != null) {
|
||||
FileRecord fileRecord = fileRecordService.getById(material.getFileId());
|
||||
path = fileRecord == null ? null : fileRecord.getPath();
|
||||
if (fileRecord != null && !hasText(material.getFileName())) {
|
||||
material.setFileName(fileRecord.getName());
|
||||
}
|
||||
}
|
||||
if (!hasText(material.getFileUrl())) {
|
||||
material.setFileUrl(resolveFileUrl(path));
|
||||
}
|
||||
if (!hasText(material.getDownloadUrl())) {
|
||||
material.setDownloadUrl(resolveDownloadUrl(path));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String resolveFileUrl(String path) {
|
||||
if (!hasText(path)) {
|
||||
return null;
|
||||
}
|
||||
return (trimEnd(config.getFileServer()) + "/api/file/" + normalizeUrlPath(path))
|
||||
.replace("file//", "file/");
|
||||
}
|
||||
|
||||
private String resolveDownloadUrl(String path) {
|
||||
if (!hasText(path)) {
|
||||
return null;
|
||||
}
|
||||
return trimEnd(config.getFileServer()) + "/download" + ensureLeadingSlash(path);
|
||||
}
|
||||
|
||||
private File resolveSourceFile(TzbcyMaterial material, String uploadPath) {
|
||||
FileRecord fileRecord = material.getFileId() == null ? null : fileRecordService.getById(material.getFileId());
|
||||
String path = fileRecord != null && hasText(fileRecord.getPath()) ? fileRecord.getPath() : material.getFilePath();
|
||||
if (!hasText(path)) {
|
||||
return null;
|
||||
}
|
||||
File file = new File(path);
|
||||
if (file.isAbsolute()) {
|
||||
return file;
|
||||
}
|
||||
String normalized = path.startsWith("/") ? path.substring(1) : path;
|
||||
if (normalized.startsWith("file/")) {
|
||||
normalized = normalized.substring("file/".length());
|
||||
}
|
||||
return new File(uploadPath + "file/", normalized);
|
||||
}
|
||||
|
||||
private String buildEntryName(TzbcyMaterial material, Set<String> entryNames) {
|
||||
String folder = safeName(material.getMaterialType(), "未分类");
|
||||
String project = safeName(material.getProjectName(), "项目");
|
||||
String leader = safeName(material.getLeader(), "负责人");
|
||||
String fileName = safeName(material.getFileName(), "材料");
|
||||
String baseName = folder + "/" + project + "_" + leader + "_" + fileName;
|
||||
String entryName = baseName;
|
||||
int index = 1;
|
||||
while (entryNames.contains(entryName)) {
|
||||
entryName = appendIndex(baseName, index++);
|
||||
}
|
||||
entryNames.add(entryName);
|
||||
return entryName;
|
||||
}
|
||||
|
||||
private String appendIndex(String name, int index) {
|
||||
int slashIndex = name.lastIndexOf('/');
|
||||
int dotIndex = name.lastIndexOf('.');
|
||||
if (dotIndex > slashIndex) {
|
||||
return name.substring(0, dotIndex) + "_" + index + name.substring(dotIndex);
|
||||
}
|
||||
return name + "_" + index;
|
||||
}
|
||||
|
||||
private String safeName(String value, String fallback) {
|
||||
String text = hasText(value) ? value.trim() : fallback;
|
||||
text = text.replaceAll("[\\\\/:*?\"<>|]", "_");
|
||||
return text.length() > 80 ? text.substring(0, 80) : text;
|
||||
}
|
||||
|
||||
private boolean hasText(String value) {
|
||||
return value != null && !value.trim().isEmpty();
|
||||
}
|
||||
|
||||
private String trimEnd(String value) {
|
||||
if (value == null) {
|
||||
return "";
|
||||
}
|
||||
while (value.endsWith("/")) {
|
||||
value = value.substring(0, value.length() - 1);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
private String normalizeUrlPath(String path) {
|
||||
String normalized = ensureLeadingSlash(path);
|
||||
if (normalized == null) {
|
||||
return "";
|
||||
}
|
||||
return normalized.startsWith("/") ? normalized.substring(1) : normalized;
|
||||
}
|
||||
|
||||
private String ensureLeadingSlash(String path) {
|
||||
if (!hasText(path)) {
|
||||
return null;
|
||||
}
|
||||
return path.startsWith("/") ? path : "/" + path;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.gxwebsoft.gxmu.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.gxwebsoft.gxmu.entity.WorkLedger;
|
||||
import com.gxwebsoft.gxmu.mapper.WorkLedgerMapper;
|
||||
import com.gxwebsoft.gxmu.service.WorkLedgerService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class WorkLedgerServiceImpl extends ServiceImpl<WorkLedgerMapper, WorkLedger>
|
||||
implements WorkLedgerService {
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package com.gxwebsoft.gxmu.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.Wrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.gxwebsoft.gxmu.entity.WshqtwForm;
|
||||
import com.gxwebsoft.gxmu.mapper.WshqtwFormMapper;
|
||||
import com.gxwebsoft.gxmu.service.ReviewListBindingService;
|
||||
import com.gxwebsoft.gxmu.service.WshqtwFormService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 五四红旗团委申报表Service实现
|
||||
*/
|
||||
@Service
|
||||
public class WshqtwFormServiceImpl extends ServiceImpl<WshqtwFormMapper, WshqtwForm> implements WshqtwFormService {
|
||||
@Resource
|
||||
private ReviewListBindingService reviewListBindingService;
|
||||
|
||||
@Override
|
||||
public <E extends IPage<WshqtwForm>> E page(E page, Wrapper<WshqtwForm> queryWrapper) {
|
||||
return reviewListBindingService.bindPage(super.page(page, queryWrapper), "gxmu_wshqtw",
|
||||
WshqtwForm::getId, WshqtwForm::setReviewList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<WshqtwForm> list(Wrapper<WshqtwForm> queryWrapper) {
|
||||
return reviewListBindingService.bindList(super.list(queryWrapper), "gxmu_wshqtw",
|
||||
WshqtwForm::getId, WshqtwForm::setReviewList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WshqtwForm getById(Serializable id) {
|
||||
return reviewListBindingService.bindOne(super.getById(id), "gxmu_wshqtw",
|
||||
WshqtwForm::getId, WshqtwForm::setReviewList);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package com.gxwebsoft.gxmu.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.Wrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.gxwebsoft.gxmu.entity.WshqtzbForm;
|
||||
import com.gxwebsoft.gxmu.mapper.WshqtzbFormMapper;
|
||||
import com.gxwebsoft.gxmu.service.ReviewListBindingService;
|
||||
import com.gxwebsoft.gxmu.service.WshqtzbFormService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 五四红旗团支部申报表Service实现
|
||||
*/
|
||||
@Service
|
||||
public class WshqtzbFormServiceImpl extends ServiceImpl<WshqtzbFormMapper, WshqtzbForm> implements WshqtzbFormService {
|
||||
@Resource
|
||||
private ReviewListBindingService reviewListBindingService;
|
||||
|
||||
@Override
|
||||
public <E extends IPage<WshqtzbForm>> E page(E page, Wrapper<WshqtzbForm> queryWrapper) {
|
||||
return reviewListBindingService.bindPage(super.page(page, queryWrapper), "gxmu_wshqtzb",
|
||||
WshqtzbForm::getId, WshqtzbForm::setReviewList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<WshqtzbForm> list(Wrapper<WshqtzbForm> queryWrapper) {
|
||||
return reviewListBindingService.bindList(super.list(queryWrapper), "gxmu_wshqtzb",
|
||||
WshqtzbForm::getId, WshqtzbForm::setReviewList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WshqtzbForm getById(Serializable id) {
|
||||
return reviewListBindingService.bindOne(super.getById(id), "gxmu_wshqtzb",
|
||||
WshqtzbForm::getId, WshqtzbForm::setReviewList);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,349 @@
|
||||
package com.gxwebsoft.gxmu.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.Wrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.gxwebsoft.gxmu.entity.WxxzxApplicant;
|
||||
import com.gxwebsoft.gxmu.entity.WxxzxArchiveRecord;
|
||||
import com.gxwebsoft.gxmu.entity.WxxzxBudgetItem;
|
||||
import com.gxwebsoft.gxmu.entity.WxxzxForm;
|
||||
import com.gxwebsoft.gxmu.entity.WxxzxGuidanceTeacher;
|
||||
import com.gxwebsoft.gxmu.entity.WxxzxReviewMemberEntity;
|
||||
import com.gxwebsoft.gxmu.mapper.WxxzxApplicantMapper;
|
||||
import com.gxwebsoft.gxmu.mapper.WxxzxArchiveRecordMapper;
|
||||
import com.gxwebsoft.gxmu.mapper.WxxzxBudgetItemMapper;
|
||||
import com.gxwebsoft.gxmu.mapper.WxxzxFormMapper;
|
||||
import com.gxwebsoft.gxmu.mapper.WxxzxGuidanceTeacherMapper;
|
||||
import com.gxwebsoft.gxmu.mapper.WxxzxReviewMemberEntityMapper;
|
||||
import com.gxwebsoft.gxmu.param.WxxzxMaterialUpdateParam;
|
||||
import com.gxwebsoft.gxmu.service.ReviewListBindingService;
|
||||
import com.gxwebsoft.gxmu.service.WxxzxFormService;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 未来学术之星课题申报表Service实现
|
||||
*/
|
||||
@Service
|
||||
public class WxxzxFormServiceImpl extends ServiceImpl<WxxzxFormMapper, WxxzxForm> implements WxxzxFormService {
|
||||
@Resource
|
||||
private WxxzxGuidanceTeacherMapper guidanceTeacherMapper;
|
||||
@Resource
|
||||
private WxxzxApplicantMapper applicantMapper;
|
||||
@Resource
|
||||
private WxxzxArchiveRecordMapper archiveRecordMapper;
|
||||
@Resource
|
||||
private WxxzxBudgetItemMapper budgetItemMapper;
|
||||
@Resource
|
||||
private WxxzxReviewMemberEntityMapper reviewMemberEntityMapper;
|
||||
@Resource
|
||||
private ReviewListBindingService reviewListBindingService;
|
||||
|
||||
@Override
|
||||
public <E extends IPage<WxxzxForm>> E page(E page, Wrapper<WxxzxForm> queryWrapper) {
|
||||
return reviewListBindingService.bindPage(super.page(page, queryWrapper), "gxmu_wxxzx_project",
|
||||
WxxzxForm::getId, WxxzxForm::setReviewList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<WxxzxForm> list(Wrapper<WxxzxForm> queryWrapper) {
|
||||
return reviewListBindingService.bindList(super.list(queryWrapper), "gxmu_wxxzx_project",
|
||||
WxxzxForm::getId, WxxzxForm::setReviewList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WxxzxForm getById(Serializable id) {
|
||||
WxxzxForm form = super.getById(id);
|
||||
if (form == null) {
|
||||
return null;
|
||||
}
|
||||
fillChildren(form);
|
||||
return reviewListBindingService.bindOne(form, "gxmu_wxxzx_project",
|
||||
WxxzxForm::getId, WxxzxForm::setReviewList);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public boolean save(WxxzxForm entity) {
|
||||
boolean saved = super.save(entity);
|
||||
if (!saved) {
|
||||
return false;
|
||||
}
|
||||
saveChildren(entity);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public boolean updateById(WxxzxForm entity) {
|
||||
boolean updated = super.updateById(entity);
|
||||
if (!updated) {
|
||||
return false;
|
||||
}
|
||||
removeChildren(entity.getId());
|
||||
saveChildren(entity);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public boolean updateMaterials(Integer id, WxxzxMaterialUpdateParam param) {
|
||||
if (id == null || param == null) {
|
||||
return false;
|
||||
}
|
||||
WxxzxForm entity = new WxxzxForm();
|
||||
entity.setId(id);
|
||||
entity.setFundingBudgetFile(param.getFundingBudgetFile());
|
||||
entity.setFundingAllocationFile(param.getFundingAllocationFile());
|
||||
entity.setMidtermRemark(param.getMidtermRemark());
|
||||
entity.setMidtermMaterials(param.getMidtermMaterials());
|
||||
entity.setFinalRemark(param.getFinalRemark());
|
||||
entity.setFinalMaterials(param.getFinalMaterials());
|
||||
entity.setArchiveAwards(param.getArchiveAwards());
|
||||
entity.setArchiveProofs(param.getArchiveProofs());
|
||||
boolean updated = super.updateById(entity);
|
||||
if (!updated) {
|
||||
return false;
|
||||
}
|
||||
WxxzxForm current = super.getById(id);
|
||||
replaceArchiveRecords(id, param.getArchiveRecords(), current);
|
||||
return true;
|
||||
}
|
||||
|
||||
private void fillChildren(WxxzxForm form) {
|
||||
Integer projectId = form.getId();
|
||||
form.setGuidanceTeachers(guidanceTeacherMapper.selectList(
|
||||
new LambdaQueryWrapper<WxxzxGuidanceTeacher>()
|
||||
.eq(WxxzxGuidanceTeacher::getProjectId, projectId)
|
||||
.orderByAsc(WxxzxGuidanceTeacher::getTeacherOrder)
|
||||
).stream().map(this::toGuidanceTeacher).collect(Collectors.toList()));
|
||||
form.setApplicants(applicantMapper.selectList(
|
||||
new LambdaQueryWrapper<WxxzxApplicant>()
|
||||
.eq(WxxzxApplicant::getProjectId, projectId)
|
||||
.orderByAsc(WxxzxApplicant::getApplicantOrder)
|
||||
).stream().map(this::toApplicant).collect(Collectors.toList()));
|
||||
form.setBudgets(budgetItemMapper.selectList(
|
||||
new LambdaQueryWrapper<WxxzxBudgetItem>()
|
||||
.eq(WxxzxBudgetItem::getProjectId, projectId)
|
||||
.orderByAsc(WxxzxBudgetItem::getBudgetOrder)
|
||||
).stream().map(this::toBudget).collect(Collectors.toList()));
|
||||
form.setReviewMembers(reviewMemberEntityMapper.selectList(
|
||||
new LambdaQueryWrapper<WxxzxReviewMemberEntity>()
|
||||
.eq(WxxzxReviewMemberEntity::getProjectId, projectId)
|
||||
.orderByAsc(WxxzxReviewMemberEntity::getMemberOrder)
|
||||
).stream().map(this::toReviewMember).collect(Collectors.toList()));
|
||||
form.setArchiveRecords(archiveRecordMapper.selectList(
|
||||
new LambdaQueryWrapper<WxxzxArchiveRecord>()
|
||||
.eq(WxxzxArchiveRecord::getProjectId, projectId)
|
||||
.orderByAsc(WxxzxArchiveRecord::getArchiveOrder)
|
||||
).stream().map(this::toArchiveRecord).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
private void saveChildren(WxxzxForm form) {
|
||||
if (form.getId() == null) {
|
||||
return;
|
||||
}
|
||||
Long userId = form.getUserId() == null ? null : form.getUserId().longValue();
|
||||
Long tenantId = form.getTenantId() == null ? null : form.getTenantId().longValue();
|
||||
|
||||
List<WxxzxForm.GuidanceTeacher> guidanceTeachers = filterItems(
|
||||
form.getGuidanceTeachers(),
|
||||
item -> hasText(item.getName()) || hasText(item.getGender()) || hasText(item.getTitle())
|
||||
|| hasText(item.getDept()) || hasText(item.getSign())
|
||||
);
|
||||
for (int i = 0; i < guidanceTeachers.size(); i++) {
|
||||
WxxzxForm.GuidanceTeacher item = guidanceTeachers.get(i);
|
||||
WxxzxGuidanceTeacher entity = new WxxzxGuidanceTeacher();
|
||||
entity.setProjectId(form.getId());
|
||||
entity.setTeacherOrder(i + 1);
|
||||
entity.setName(item.getName());
|
||||
entity.setGender(item.getGender());
|
||||
entity.setJobTitle(item.getTitle());
|
||||
entity.setDepartmentName(item.getDept());
|
||||
entity.setSignName(item.getSign());
|
||||
entity.setYear(form.getYear());
|
||||
entity.setUserId(userId);
|
||||
entity.setTenantId(tenantId);
|
||||
guidanceTeacherMapper.insert(entity);
|
||||
}
|
||||
|
||||
List<WxxzxForm.Applicant> applicants = filterItems(
|
||||
form.getApplicants(),
|
||||
item -> hasText(item.getName()) || hasText(item.getGrade()) || hasText(item.getClassName())
|
||||
|| hasText(item.getGender()) || hasText(item.getMajor()) || hasText(item.getRole())
|
||||
);
|
||||
for (int i = 0; i < applicants.size(); i++) {
|
||||
WxxzxForm.Applicant item = applicants.get(i);
|
||||
WxxzxApplicant entity = new WxxzxApplicant();
|
||||
entity.setProjectId(form.getId());
|
||||
entity.setApplicantOrder(i + 1);
|
||||
entity.setName(item.getName());
|
||||
entity.setGrade(item.getGrade());
|
||||
entity.setClassName(item.getClassName());
|
||||
entity.setGender(item.getGender());
|
||||
entity.setMajor(item.getMajor());
|
||||
entity.setRoleDesc(item.getRole());
|
||||
entity.setYear(form.getYear());
|
||||
entity.setUserId(userId);
|
||||
entity.setTenantId(tenantId);
|
||||
applicantMapper.insert(entity);
|
||||
}
|
||||
|
||||
List<WxxzxForm.Budget> budgets = filterItems(
|
||||
form.getBudgets(),
|
||||
item -> hasText(item.getItem()) || hasText(item.getAmount()) || hasText(item.getReason())
|
||||
);
|
||||
for (int i = 0; i < budgets.size(); i++) {
|
||||
WxxzxForm.Budget item = budgets.get(i);
|
||||
WxxzxBudgetItem entity = new WxxzxBudgetItem();
|
||||
entity.setProjectId(form.getId());
|
||||
entity.setBudgetOrder(i + 1);
|
||||
entity.setExpenseItem(item.getItem());
|
||||
entity.setAmount(item.getAmount());
|
||||
entity.setReason(item.getReason());
|
||||
entity.setYear(form.getYear());
|
||||
entity.setUserId(userId);
|
||||
entity.setTenantId(tenantId);
|
||||
budgetItemMapper.insert(entity);
|
||||
}
|
||||
|
||||
List<WxxzxForm.ReviewMember> reviewMembers = filterItems(
|
||||
form.getReviewMembers(),
|
||||
item -> hasText(item.getName()) || hasText(item.getGender()) || hasText(item.getNation())
|
||||
|| hasText(item.getPolitics()) || hasText(item.getBirthMonth()) || hasText(item.getTitle())
|
||||
|| hasText(item.getDuty()) || hasText(item.getDepartment()) || hasText(item.getRemark())
|
||||
);
|
||||
for (int i = 0; i < reviewMembers.size(); i++) {
|
||||
WxxzxForm.ReviewMember item = reviewMembers.get(i);
|
||||
WxxzxReviewMemberEntity entity = new WxxzxReviewMemberEntity();
|
||||
entity.setProjectId(form.getId());
|
||||
entity.setMemberOrder(i + 1);
|
||||
entity.setName(item.getName());
|
||||
entity.setGender(item.getGender());
|
||||
entity.setNation(item.getNation());
|
||||
entity.setPolitics(item.getPolitics());
|
||||
entity.setBirthMonth(item.getBirthMonth());
|
||||
entity.setJobTitle(item.getTitle());
|
||||
entity.setDuty(item.getDuty());
|
||||
entity.setDepartmentName(item.getDepartment());
|
||||
entity.setRemark(item.getRemark());
|
||||
entity.setYear(form.getYear());
|
||||
entity.setUserId(userId);
|
||||
entity.setTenantId(tenantId);
|
||||
reviewMemberEntityMapper.insert(entity);
|
||||
}
|
||||
}
|
||||
|
||||
private void removeChildren(Integer projectId) {
|
||||
guidanceTeacherMapper.delete(new LambdaQueryWrapper<WxxzxGuidanceTeacher>()
|
||||
.eq(WxxzxGuidanceTeacher::getProjectId, projectId));
|
||||
applicantMapper.delete(new LambdaQueryWrapper<WxxzxApplicant>()
|
||||
.eq(WxxzxApplicant::getProjectId, projectId));
|
||||
budgetItemMapper.delete(new LambdaQueryWrapper<WxxzxBudgetItem>()
|
||||
.eq(WxxzxBudgetItem::getProjectId, projectId));
|
||||
reviewMemberEntityMapper.delete(new LambdaQueryWrapper<WxxzxReviewMemberEntity>()
|
||||
.eq(WxxzxReviewMemberEntity::getProjectId, projectId));
|
||||
archiveRecordMapper.delete(new LambdaQueryWrapper<WxxzxArchiveRecord>()
|
||||
.eq(WxxzxArchiveRecord::getProjectId, projectId));
|
||||
}
|
||||
|
||||
private WxxzxForm.GuidanceTeacher toGuidanceTeacher(WxxzxGuidanceTeacher entity) {
|
||||
WxxzxForm.GuidanceTeacher item = new WxxzxForm.GuidanceTeacher();
|
||||
item.setName(entity.getName());
|
||||
item.setGender(entity.getGender());
|
||||
item.setTitle(entity.getJobTitle());
|
||||
item.setDept(entity.getDepartmentName());
|
||||
item.setSign(entity.getSignName());
|
||||
return item;
|
||||
}
|
||||
|
||||
private WxxzxForm.Applicant toApplicant(WxxzxApplicant entity) {
|
||||
WxxzxForm.Applicant item = new WxxzxForm.Applicant();
|
||||
item.setName(entity.getName());
|
||||
item.setGrade(entity.getGrade());
|
||||
item.setClassName(entity.getClassName());
|
||||
item.setGender(entity.getGender());
|
||||
item.setMajor(entity.getMajor());
|
||||
item.setRole(entity.getRoleDesc());
|
||||
return item;
|
||||
}
|
||||
|
||||
private WxxzxForm.Budget toBudget(WxxzxBudgetItem entity) {
|
||||
WxxzxForm.Budget item = new WxxzxForm.Budget();
|
||||
item.setItem(entity.getExpenseItem());
|
||||
item.setAmount(entity.getAmount());
|
||||
item.setReason(entity.getReason());
|
||||
return item;
|
||||
}
|
||||
|
||||
private WxxzxForm.ReviewMember toReviewMember(WxxzxReviewMemberEntity entity) {
|
||||
WxxzxForm.ReviewMember item = new WxxzxForm.ReviewMember();
|
||||
item.setName(entity.getName());
|
||||
item.setGender(entity.getGender());
|
||||
item.setNation(entity.getNation());
|
||||
item.setPolitics(entity.getPolitics());
|
||||
item.setBirthMonth(entity.getBirthMonth());
|
||||
item.setTitle(entity.getJobTitle());
|
||||
item.setDuty(entity.getDuty());
|
||||
item.setDepartment(entity.getDepartmentName());
|
||||
item.setRemark(entity.getRemark());
|
||||
return item;
|
||||
}
|
||||
|
||||
private WxxzxForm.ArchiveRecord toArchiveRecord(WxxzxArchiveRecord entity) {
|
||||
WxxzxForm.ArchiveRecord item = new WxxzxForm.ArchiveRecord();
|
||||
item.setId(entity.getId());
|
||||
item.setAwardName(entity.getAwardName());
|
||||
item.setAwardTime(entity.getAwardTime());
|
||||
item.setRemark(entity.getRemark());
|
||||
item.setProofFile(entity.getProofFile());
|
||||
return item;
|
||||
}
|
||||
|
||||
private void replaceArchiveRecords(Integer projectId, List<WxxzxForm.ArchiveRecord> archiveRecords,
|
||||
WxxzxForm current) {
|
||||
archiveRecordMapper.delete(new LambdaQueryWrapper<WxxzxArchiveRecord>()
|
||||
.eq(WxxzxArchiveRecord::getProjectId, projectId));
|
||||
List<WxxzxForm.ArchiveRecord> records = filterItems(
|
||||
archiveRecords,
|
||||
item -> hasText(item.getAwardName()) || hasText(item.getAwardTime())
|
||||
|| hasText(item.getRemark()) || hasText(item.getProofFile())
|
||||
);
|
||||
for (int i = 0; i < records.size(); i++) {
|
||||
WxxzxForm.ArchiveRecord item = records.get(i);
|
||||
WxxzxArchiveRecord entity = new WxxzxArchiveRecord();
|
||||
entity.setProjectId(projectId);
|
||||
entity.setArchiveOrder(i + 1);
|
||||
entity.setAwardName(item.getAwardName());
|
||||
entity.setAwardTime(item.getAwardTime());
|
||||
entity.setRemark(item.getRemark());
|
||||
entity.setProofFile(item.getProofFile());
|
||||
if (current != null) {
|
||||
entity.setYear(current.getYear());
|
||||
entity.setUserId(current.getUserId() == null ? null : current.getUserId().longValue());
|
||||
entity.setTenantId(current.getTenantId() == null ? null : current.getTenantId().longValue());
|
||||
}
|
||||
archiveRecordMapper.insert(entity);
|
||||
}
|
||||
}
|
||||
|
||||
private <T> List<T> filterItems(List<T> items, Predicate<T> predicate) {
|
||||
if (items == null || items.isEmpty()) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
return items.stream().filter(Objects::nonNull).filter(predicate).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private boolean hasText(String value) {
|
||||
return value != null && !value.trim().isEmpty();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package com.gxwebsoft.gxmu.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.Wrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.gxwebsoft.gxmu.entity.YxgqtdgbForm;
|
||||
import com.gxwebsoft.gxmu.mapper.YxgqtdgbFormMapper;
|
||||
import com.gxwebsoft.gxmu.service.ReviewListBindingService;
|
||||
import com.gxwebsoft.gxmu.service.YxgqtdgbFormService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 优秀共青团干部申报表Service实现
|
||||
*/
|
||||
@Service
|
||||
public class YxgqtdgbFormServiceImpl extends ServiceImpl<YxgqtdgbFormMapper, YxgqtdgbForm> implements YxgqtdgbFormService {
|
||||
@Resource
|
||||
private ReviewListBindingService reviewListBindingService;
|
||||
|
||||
@Override
|
||||
public <E extends IPage<YxgqtdgbForm>> E page(E page, Wrapper<YxgqtdgbForm> queryWrapper) {
|
||||
return reviewListBindingService.bindPage(super.page(page, queryWrapper), "gxmu_yxgqtdgb",
|
||||
YxgqtdgbForm::getId, YxgqtdgbForm::setReviewList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<YxgqtdgbForm> list(Wrapper<YxgqtdgbForm> queryWrapper) {
|
||||
return reviewListBindingService.bindList(super.list(queryWrapper), "gxmu_yxgqtdgb",
|
||||
YxgqtdgbForm::getId, YxgqtdgbForm::setReviewList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public YxgqtdgbForm getById(Serializable id) {
|
||||
return reviewListBindingService.bindOne(super.getById(id), "gxmu_yxgqtdgb",
|
||||
YxgqtdgbForm::getId, YxgqtdgbForm::setReviewList);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package com.gxwebsoft.gxmu.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.Wrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.gxwebsoft.gxmu.entity.YxgqtyForm;
|
||||
import com.gxwebsoft.gxmu.mapper.YxgqtyFormMapper;
|
||||
import com.gxwebsoft.gxmu.service.ReviewListBindingService;
|
||||
import com.gxwebsoft.gxmu.service.YxgqtyFormService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 优秀共青团员申报表Service实现
|
||||
*/
|
||||
@Service
|
||||
public class YxgqtyFormServiceImpl extends ServiceImpl<YxgqtyFormMapper, YxgqtyForm> implements YxgqtyFormService {
|
||||
@Resource
|
||||
private ReviewListBindingService reviewListBindingService;
|
||||
|
||||
@Override
|
||||
public <E extends IPage<YxgqtyForm>> E page(E page, Wrapper<YxgqtyForm> queryWrapper) {
|
||||
return reviewListBindingService.bindPage(super.page(page, queryWrapper), "gxmu_yxgqty",
|
||||
YxgqtyForm::getId, YxgqtyForm::setReviewList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<YxgqtyForm> list(Wrapper<YxgqtyForm> queryWrapper) {
|
||||
return reviewListBindingService.bindList(super.list(queryWrapper), "gxmu_yxgqty",
|
||||
YxgqtyForm::getId, YxgqtyForm::setReviewList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public YxgqtyForm getById(Serializable id) {
|
||||
return reviewListBindingService.bindOne(super.getById(id), "gxmu_yxgqty",
|
||||
YxgqtyForm::getId, YxgqtyForm::setReviewList);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user