批量推送

This commit is contained in:
郭庆泰
2026-08-16 21:24:53 +08:00
parent 0c093076a4
commit ccfd03a6eb
55 changed files with 3772 additions and 577 deletions
+4
View File
@@ -20,6 +20,10 @@
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common</artifactId>
</dependency>
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-framework</artifactId>
</dependency>
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-system</artifactId>
@@ -0,0 +1,69 @@
package com.ruoyi.business.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.business.domain.BizArticle;
import com.ruoyi.business.service.IBizArticleService;
import com.ruoyi.common.utils.SecurityUtils;
/**
* 平台协议/隐私政策文章 Controller (后台 admin)
*/
@RestController
@RequestMapping("/business/article")
public class BizArticleController extends BaseController
{
@Autowired
private IBizArticleService articleService;
@PreAuthorize("@ss.hasPermi('business:article:list')")
@GetMapping("/list")
public TableDataInfo list(BizArticle entity)
{
startPage();
List<BizArticle> list = articleService.selectList(entity);
return getDataTable(list);
}
@PreAuthorize("@ss.hasPermi('business:article:query')")
@GetMapping("/{id}")
public AjaxResult getInfo(@PathVariable("id") Long id)
{
return success(articleService.getById(id));
}
@PreAuthorize("@ss.hasPermi('business:article:add')")
@Log(title = "平台协议", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody BizArticle entity)
{
if (entity.getStatus() == null) entity.setStatus("0");
entity.setCreateBy(SecurityUtils.getUsername());
entity.setUpdateBy(SecurityUtils.getUsername());
return toAjax(articleService.insert(entity));
}
@PreAuthorize("@ss.hasPermi('business:article:edit')")
@Log(title = "平台协议", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody BizArticle entity)
{
entity.setUpdateBy(SecurityUtils.getUsername());
return toAjax(articleService.updateByPrimaryKey(entity));
}
@PreAuthorize("@ss.hasPermi('business:article:remove')")
@Log(title = "平台协议", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable Long[] ids)
{
return toAjax(articleService.deleteByPrimaryKeys(ids));
}
}
@@ -2,6 +2,9 @@ package com.ruoyi.business.controller;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
@@ -11,9 +14,19 @@ import com.ruoyi.business.domain.BizOrg;
import com.ruoyi.business.dto.SmsValidForm;
import com.ruoyi.business.service.IBizOrgService;
import com.ruoyi.business.service.SysSmsService;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.enums.UserStatus;
import com.ruoyi.common.utils.ip.IpUtils;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.framework.manager.AsyncManager;
import com.ruoyi.framework.manager.factory.AsyncFactory;
import com.ruoyi.framework.web.service.SysPermissionService;
import com.ruoyi.framework.web.service.TokenService;
import com.ruoyi.system.mapper.SysUserMapper;
import com.ruoyi.system.service.ISysUserService;
/**
@@ -27,6 +40,10 @@ import com.ruoyi.system.service.ISysUserService;
* 注: 主账号不建 biz_person
*
* 2026-08-16 重构: 删 biz_user_role_bind, 统一用 sys_user.role_type (见迁移脚本)
*
* 2026-08-16 新增: 短信验证码登录 (loginMode=sms):
* 1. smsSendCode 发送短信 (校验手机号已注册)
* 2. smsLogin 校验短信验证码 + 颁发 JWT token (不走 AuthenticationManager, 因为无密码)
*/
@RestController
@RequestMapping("/business/auth")
@@ -44,6 +61,15 @@ public class BizAuthController extends BaseController {
@Autowired
private BCryptPasswordEncoder passwordEncoder;
@Autowired
private SysUserMapper userMapper;
@Autowired
private TokenService tokenService;
@Autowired
private SysPermissionService permissionService;
@PostMapping("/login")
public AjaxResult login(@RequestBody Map<String, Object> body) {
String username = (String) body.get("username");
@@ -52,6 +78,82 @@ public class BizAuthController extends BaseController {
return success().put("roleType", roleType).put("token", "mock-token");
}
/**
* 登录用 - 发送短信验证码 (手机号必须已注册)
*/
@PostMapping("/smsSendCode")
public AjaxResult smsSendCode(@RequestBody Map<String, String> body) {
String phone = body == null ? null : body.get("phone");
if (phone == null || !phone.matches("^1\\d{10}$")) {
return error("请输入正确的手机号");
}
// 登录反义: 手机号未注册则不发
if (!userService.isPhoneRegistered(phone)) {
return error("该手机号未注册, 请先注册账号");
}
String uuid = smsService.sendCode(phone);
return AjaxResult.success("验证码已发送", uuid);
}
/**
* 短信验证码登录 (无密码)
* 1. 校验手机号 + 短信验证码
* 2. 查用户 (按手机号)
* 3. 校验用户状态
* 4. 构造 LoginUser, 颁发 JWT token (SecurityContext 一并设置, 兼容后续鉴权)
* 5. 记录登录信息 + logininfor
*/
@PostMapping("/smsLogin")
public AjaxResult smsLogin(@RequestBody Map<String, String> body) {
String phone = body == null ? null : body.get("phone");
String code = body == null ? null : body.get("smsCode");
String uuid = body == null ? null : body.get("uuid");
// 1. 基础校验
if (phone == null || !phone.matches("^1\\d{10}$")) return error("手机号格式错误");
if (code == null || code.isEmpty()) return error("请输入短信验证码");
// 2. 校验短信验证码
SmsValidForm smsForm = new SmsValidForm();
smsForm.setPhone(phone);
smsForm.setSmsCode(code);
smsForm.setUuid(uuid);
try {
smsService.verifyCode(smsForm);
} catch (RuntimeException e) {
return error("验证码错误或已过期: " + e.getMessage());
}
// 3. 查用户 (mapper.checkPhoneUnique 返回 SysUser 或 null)
SysUser user = userMapper.checkPhoneUnique(phone);
if (user == null || user.getUserId() == null) {
return error("该手机号未注册");
}
// 4. 校验用户状态
if (UserStatus.DELETED.getCode().equals(user.getDelFlag())) {
return error("账号已被删除");
}
if (UserStatus.DISABLE.getCode().equals(user.getStatus())) {
return error("账号已被停用");
}
// 5. 构造 LoginUser 并设 SecurityContext (兼容后续 spring security 鉴权)
LoginUser loginUser = new LoginUser(user.getUserId(), user.getDeptId(), user, permissionService.getMenuPermission(user));
Authentication authentication = new UsernamePasswordAuthenticationToken(
loginUser, null, loginUser.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(authentication);
// 6. 记录登录信息 + logininfor
AsyncManager.me().execute(AsyncFactory.recordLogininfor(user.getUserName(), Constants.LOGIN_SUCCESS,
"短信验证码登录成功"));
userService.updateLoginInfo(user.getUserId(), IpUtils.getIpAddr(), DateUtils.getNowDate());
// 7. 颁发 token
String token = tokenService.createToken(loginUser);
return AjaxResult.success("登录成功").put(Constants.TOKEN, token);
}
@PostMapping("/registerExecutor")
public AjaxResult registerExecutor(@RequestBody Map<String, Object> body) {
String username = (String) body.get("username");
@@ -39,8 +39,9 @@ public class BizExecutorController extends BaseController
@RequestParam(required = false, defaultValue = "50") Integer pageSize)
{
StringBuilder sql = new StringBuilder()
// 仅返回 MAIN 主账号: 排除 SUB 子账号, 避免项目分配下拉混入下属执行人
.append("SELECT user_id, dept_id, user_name, nick_name, email, phonenumber, role_type, status, create_time ")
.append("FROM sys_user WHERE del_flag = '0' AND status = '0' AND role_type = ?");
.append("FROM sys_user WHERE del_flag = '0' AND status = '0' AND role_type = ? AND account_type = 'MAIN'");
List<Object> args = new ArrayList<>();
args.add(roleType);
if (userId != null) {
@@ -0,0 +1,90 @@
package com.ruoyi.business.controller;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.business.dto.SmsValidForm;
import com.ruoyi.business.service.SysSmsService;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.system.mapper.SysUserMapper;
import com.ruoyi.system.service.ISysUserService;
/**
* 忘记密码 - 通过短信验证码重置密码 (匿名访问)
*
* 流程:
* 1. forgotSendSms 发送短信 (校验手机号已注册)
* 2. resetPassword 校验短信验证码 + 重置密码 (一次提交, 简化前端)
*/
@RestController
@RequestMapping("/business/auth")
public class BizForgotController extends BaseController {
@Autowired
private SysSmsService smsService;
@Autowired
private ISysUserService userService;
@Autowired
private SysUserMapper userMapper;
@Autowired
private BCryptPasswordEncoder passwordEncoder;
@PostMapping("/forgotSendSms")
public AjaxResult forgotSendSms(@RequestBody Map<String, String> body) {
String phone = body == null ? null : body.get("phone");
if (phone == null || !phone.matches("^1\\d{10}$")) {
return error("请输入正确的手机号");
}
// 手机号必须已注册 (忘记密码反义: 该号查不到则不发)
if (!userService.isPhoneRegistered(phone)) {
return error("该手机号未注册, 请先注册账号");
}
String uuid = smsService.sendCode(phone);
return AjaxResult.success("验证码已发送", uuid);
}
@PostMapping("/resetPassword")
public AjaxResult resetPassword(@RequestBody Map<String, Object> body) {
String phone = (String) body.get("phone");
String code = (String) body.get("smsCode");
String uuid = (String) body.get("uuid");
String password = (String) body.get("password");
String confirmPassword = (String) body.get("confirmPassword");
// 1. 基础校验
if (phone == null || !phone.matches("^1\\d{10}$")) return error("手机号格式错误");
if (code == null || code.isEmpty()) return error("请输入短信验证码");
if (password == null || password.length() < 6 || password.length() > 20) return error("密码长度 6-20 位");
if (!password.equals(confirmPassword)) return error("两次密码输入不一致");
// 2. 校验短信验证码
SmsValidForm smsForm = new SmsValidForm();
smsForm.setPhone(phone);
smsForm.setSmsCode(code);
smsForm.setUuid(uuid);
try {
smsService.verifyCode(smsForm);
} catch (RuntimeException e) {
return error("验证码错误或已过期: " + e.getMessage());
}
// 3. 查用户 (mapper.checkPhoneUnique 返回 SysUser 或 null, IService 包装成 boolean 不能用)
SysUser info = userMapper.checkPhoneUnique(phone);
if (info == null || info.getUserId() == null) {
return error("该手机号未注册");
}
// 4. 重置密码
int rows = userService.resetUserPwd(info.getUserId(), passwordEncoder.encode(password));
return rows > 0 ? success("密码重置成功, 请用新密码登录") : error("密码重置失败");
}
}
@@ -10,14 +10,18 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.business.domain.BizArticle;
import com.ruoyi.business.domain.BizProject;
import com.ruoyi.business.domain.BizSupportLetter;
import com.ruoyi.business.domain.BizInvitation;
import com.ruoyi.business.domain.BizProjectPlan;
import com.ruoyi.business.service.IBizArticleService;
import com.ruoyi.business.service.IBizProjectService;
import com.ruoyi.business.service.IBizSupportLetterService;
import com.ruoyi.business.service.IBizInvitationService;
import com.ruoyi.business.service.IBizProjectPlanService;
import com.ruoyi.business.service.IBizSpecialPlanService;
import com.ruoyi.business.domain.BizSpecialPlan;
/**
* 公开门户接口(无需登录)
@@ -30,6 +34,38 @@ public class BizPublicController extends BaseController {
@Autowired private IBizSupportLetterService supportLetterService;
@Autowired private IBizInvitationService invitationService;
@Autowired private IBizProjectPlanService projectPlanService;
@Autowired private IBizArticleService articleService;
@Autowired private IBizSpecialPlanService specialPlanService;
/**
* 按类型获取已发布的协议/政策 (供注册页底部链接打开)
* type: agreement | privacy
*/
@GetMapping("/article/{type}")
public AjaxResult articleByType(@PathVariable("type") String type)
{
BizArticle article = articleService.getByType(type);
return success(article);
}
/**
* 公开接口 - 七大专项计划 (首页用)
*/
@GetMapping("/specialPlan/list")
public AjaxResult specialPlanList() {
return success(specialPlanService.selectPublicList());
}
/**
* 公开接口 - 专项计划详情 (供详情页)
* 注意: id 可能是临时id (小于0 = 新建未保存), 也支持按 序号 (sortOrder) 查
*/
@GetMapping("/specialPlan/{id}")
public AjaxResult specialPlanById(@PathVariable("id") Long id) {
BizSpecialPlan plan = specialPlanService.getById(id);
if (plan == null) return error("专项计划不存在");
return success(plan);
}
@GetMapping("/index")
public AjaxResult index() {
@@ -0,0 +1,71 @@
package com.ruoyi.business.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.business.domain.BizSpecialPlan;
import com.ruoyi.business.service.IBizSpecialPlanService;
/**
* 七大专项计划 Controller (后台 admin)
*/
@RestController
@RequestMapping("/business/specialPlan")
public class BizSpecialPlanController extends BaseController
{
@Autowired
private IBizSpecialPlanService specialPlanService;
@PreAuthorize("@ss.hasPermi('business:specialPlan:list')")
@GetMapping("/list")
public TableDataInfo list(BizSpecialPlan entity)
{
startPage();
List<BizSpecialPlan> list = specialPlanService.selectList(entity);
return getDataTable(list);
}
@PreAuthorize("@ss.hasPermi('business:specialPlan:query')")
@GetMapping("/{id}")
public AjaxResult getInfo(@PathVariable("id") Long id)
{
return success(specialPlanService.getById(id));
}
@PreAuthorize("@ss.hasPermi('business:specialPlan:add')")
@Log(title = "七大专项计划", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody BizSpecialPlan entity)
{
if (entity.getContentType() == null) entity.setContentType("rich");
if (entity.getStatus() == null) entity.setStatus("0");
if (entity.getSortOrder() == null) entity.setSortOrder(0);
entity.setCreateBy(SecurityUtils.getUsername());
entity.setUpdateBy(SecurityUtils.getUsername());
return toAjax(specialPlanService.insert(entity));
}
@PreAuthorize("@ss.hasPermi('business:specialPlan:edit')")
@Log(title = "七大专项计划", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody BizSpecialPlan entity)
{
entity.setUpdateBy(SecurityUtils.getUsername());
return toAjax(specialPlanService.updateByPrimaryKey(entity));
}
@PreAuthorize("@ss.hasPermi('business:specialPlan:remove')")
@Log(title = "七大专项计划", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable Long[] ids)
{
return toAjax(specialPlanService.deleteByPrimaryKeys(ids));
}
}
@@ -0,0 +1,41 @@
package com.ruoyi.business.domain;
import java.util.Date;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.core.domain.BaseEntity;
/** 平台协议/隐私政策文章对象 BizArticle */
public class BizArticle extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 文章ID */
private Long id;
/** 标题 */
@Excel(name = "标题")
private String title;
/** 类型 agreement=用户协议 privacy=隐私政策 */
@Excel(name = "类型", readConverterExp = "agreement=用户协议,privacy=隐私政策")
private String type;
/** 正文 (HTML/富文本) */
@Excel(name = "正文")
private String content;
/** 状态 0启用 1停用 */
@Excel(name = "状态", readConverterExp = "0=启用,1=停用")
private String status;
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public String getTitle() { return title; }
public void setTitle(String title) { this.title = title; }
public String getType() { return type; }
public void setType(String type) { this.type = type; }
public String getContent() { return content; }
public void setContent(String content) { this.content = content; }
public String getStatus() { return status; }
public void setStatus(String status) { this.status = status; }
}
@@ -58,7 +58,7 @@ public class BizMeeting extends BaseEntity {
private Long projectId;
/** 项目名称 */
private String projectName;
/** 所属公司名称 (冗余字段, 由 biz_project.org_name 同步) */
/** 所属公司名称 (冗余字段, 由 biz_project.sponsor_admin_user_name 同步) */
private String orgName;
/** 监察意见 */
private String supervisionOpinion;
@@ -49,12 +49,11 @@ public class BizProject extends BaseEntity {
private BigDecimal ratingQ3;
/** 评分维度: 合规安全 */
private BigDecimal ratingQ4;
/** org_name (赞助方/执行方, 由 org_type 区分) */
@Excel(name = "org_name")
private String orgName;
/** org_type: sponsor 赞助方 / executor 执行方 */
@Excel(name = "org_type")
private String orgType;
/** 赞助方负责人用户名(冗余) — 原 org_name */
@Excel(name = "sponsor_admin_user_name")
private String sponsorAdminUserName;
/** 服务机构名称 (查询条件, 仅匹配 org_type='executor' + org_name LIKE) */
private String execOrgName;
/** project_form */
@Excel(name = "project_form")
private String projectForm;
@@ -64,9 +63,9 @@ public class BizProject extends BaseEntity {
/** is_settled */
@Excel(name = "is_settled")
private String isSettled;
/** org_id (赞助方/执行方, 由 org_type 区分) */
@Excel(name = "org_id")
private Long orgId;
/** 赞助方负责人用户ID (sys_user.user_id, role_type=sponsor) — 原 org_id */
@Excel(name = "sponsor_admin_user_id")
private Long sponsorAdminUserId;
/** create_by */
@Excel(name = "create_by")
private String createBy;
@@ -149,18 +148,18 @@ public class BizProject extends BaseEntity {
public void setRatingQ3(BigDecimal ratingQ3) { this.ratingQ3 = ratingQ3; }
public BigDecimal getRatingQ4() { return ratingQ4; }
public void setRatingQ4(BigDecimal ratingQ4) { this.ratingQ4 = ratingQ4; }
public String getOrgName() { return orgName; }
public void setOrgName(String orgName) { this.orgName = orgName; }
public String getOrgType() { return orgType; }
public void setOrgType(String orgType) { this.orgType = orgType; }
public String getSponsorAdminUserName() { return sponsorAdminUserName; }
public void setSponsorAdminUserName(String sponsorAdminUserName) { this.sponsorAdminUserName = sponsorAdminUserName; }
public String getExecOrgName() { return execOrgName; }
public void setExecOrgName(String execOrgName) { this.execOrgName = execOrgName; }
public String getProjectForm() { return projectForm; }
public void setProjectForm(String projectForm) { this.projectForm = projectForm; }
public String getIsFinished() { return isFinished; }
public void setIsFinished(String isFinished) { this.isFinished = isFinished; }
public String getIsSettled() { return isSettled; }
public void setIsSettled(String isSettled) { this.isSettled = isSettled; }
public Long getOrgId() { return orgId; }
public void setOrgId(Long orgId) { this.orgId = orgId; }
public Long getSponsorAdminUserId() { return sponsorAdminUserId; }
public void setSponsorAdminUserId(Long sponsorAdminUserId) { this.sponsorAdminUserId = sponsorAdminUserId; }
public String getCreateBy() { return createBy; }
public void setCreateBy(String createBy) { this.createBy = createBy; }
public Date getCreateTime() { return createTime; }
@@ -0,0 +1,51 @@
package com.ruoyi.business.domain;
import java.util.Date;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.core.domain.BaseEntity;
/** 七大专项计划对象 BizSpecialPlan */
public class BizSpecialPlan extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 专项计划ID */
private Long id;
/** 专项计划名称 */
@Excel(name = "名称")
private String title;
/** 内容类型 rich=富文本 file=上传文件 */
@Excel(name = "类型", readConverterExp = "rich=富文本,file=上传文件")
private String contentType;
/** 富文本内容 */
private String content;
/** 上传文件URL (PDF/PNG) */
private String fileUrl;
/** 排序 */
@Excel(name = "排序")
private Integer sortOrder;
/** 状态 0启用 1停用 */
@Excel(name = "状态", readConverterExp = "0=启用,1=停用")
private String status;
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public String getTitle() { return title; }
public void setTitle(String title) { this.title = title; }
public String getContentType() { return contentType; }
public void setContentType(String contentType) { this.contentType = contentType; }
public String getContent() { return content; }
public void setContent(String content) { this.content = content; }
public String getFileUrl() { return fileUrl; }
public void setFileUrl(String fileUrl) { this.fileUrl = fileUrl; }
public Integer getSortOrder() { return sortOrder; }
public void setSortOrder(Integer sortOrder) { this.sortOrder = sortOrder; }
public String getStatus() { return status; }
public void setStatus(String status) { this.status = status; }
}
@@ -0,0 +1,15 @@
package com.ruoyi.business.mapper;
import java.util.List;
import com.ruoyi.business.domain.BizArticle;
public interface BizArticleMapper
{
BizArticle selectByPrimaryKey(Long id);
List<BizArticle> selectList(BizArticle entity);
BizArticle selectByType(String type);
int insert(BizArticle entity);
int updateByPrimaryKey(BizArticle entity);
int deleteByPrimaryKey(Long id);
int deleteByPrimaryKeys(Long[] ids);
}
@@ -0,0 +1,20 @@
package com.ruoyi.business.mapper;
import java.util.List;
import com.ruoyi.business.domain.BizSpecialPlan;
public interface BizSpecialPlanMapper
{
BizSpecialPlan selectByPrimaryKey(Long id);
/** 仅查 status='0' 的, 用于首页 / 公开页 */
List<BizSpecialPlan> selectPublicList();
/** 后台管理: 按条件查全部 */
List<BizSpecialPlan> selectList(BizSpecialPlan entity);
int insert(BizSpecialPlan entity);
int updateByPrimaryKey(BizSpecialPlan entity);
int deleteByPrimaryKey(Long id);
int deleteByPrimaryKeys(Long[] ids);
}
@@ -0,0 +1,18 @@
package com.ruoyi.business.service;
import java.util.List;
import com.ruoyi.business.domain.BizArticle;
/**
* 平台协议/隐私政策文章 Service 接口
*/
public interface IBizArticleService
{
BizArticle getById(Long id);
List<BizArticle> selectList(BizArticle entity);
BizArticle getByType(String type);
int insert(BizArticle entity);
int updateByPrimaryKey(BizArticle entity);
int deleteByPrimaryKey(Long id);
int deleteByPrimaryKeys(Long[] ids);
}
@@ -0,0 +1,18 @@
package com.ruoyi.business.service;
import java.util.List;
import com.ruoyi.business.domain.BizSpecialPlan;
/**
* 七大专项计划 Service 接口
*/
public interface IBizSpecialPlanService
{
BizSpecialPlan getById(Long id);
List<BizSpecialPlan> selectPublicList();
List<BizSpecialPlan> selectList(BizSpecialPlan entity);
int insert(BizSpecialPlan entity);
int updateByPrimaryKey(BizSpecialPlan entity);
int deleteByPrimaryKey(Long id);
int deleteByPrimaryKeys(Long[] ids);
}
@@ -0,0 +1,60 @@
package com.ruoyi.business.service.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.business.domain.BizArticle;
import com.ruoyi.business.mapper.BizArticleMapper;
import com.ruoyi.business.service.IBizArticleService;
/**
* 平台协议/隐私政策文章 Service 业务层
*/
@Service
public class BizArticleServiceImpl implements IBizArticleService
{
@Autowired
private BizArticleMapper articleMapper;
@Override
public BizArticle getById(Long id)
{
return articleMapper.selectByPrimaryKey(id);
}
@Override
public List<BizArticle> selectList(BizArticle entity)
{
return articleMapper.selectList(entity);
}
@Override
public BizArticle getByType(String type)
{
return articleMapper.selectByType(type);
}
@Override
public int insert(BizArticle entity)
{
return articleMapper.insert(entity);
}
@Override
public int updateByPrimaryKey(BizArticle entity)
{
return articleMapper.updateByPrimaryKey(entity);
}
@Override
public int deleteByPrimaryKey(Long id)
{
return articleMapper.deleteByPrimaryKey(id);
}
@Override
public int deleteByPrimaryKeys(Long[] ids)
{
return articleMapper.deleteByPrimaryKeys(ids);
}
}
@@ -0,0 +1,39 @@
package com.ruoyi.business.service.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.business.domain.BizSpecialPlan;
import com.ruoyi.business.mapper.BizSpecialPlanMapper;
import com.ruoyi.business.service.IBizSpecialPlanService;
/**
* 七大专项计划 Service 业务层
*/
@Service
public class BizSpecialPlanServiceImpl implements IBizSpecialPlanService
{
@Autowired
private BizSpecialPlanMapper specialPlanMapper;
@Override
public BizSpecialPlan getById(Long id) { return specialPlanMapper.selectByPrimaryKey(id); }
@Override
public List<BizSpecialPlan> selectPublicList() { return specialPlanMapper.selectPublicList(); }
@Override
public List<BizSpecialPlan> selectList(BizSpecialPlan entity) { return specialPlanMapper.selectList(entity); }
@Override
public int insert(BizSpecialPlan entity) { return specialPlanMapper.insert(entity); }
@Override
public int updateByPrimaryKey(BizSpecialPlan entity) { return specialPlanMapper.updateByPrimaryKey(entity); }
@Override
public int deleteByPrimaryKey(Long id) { return specialPlanMapper.deleteByPrimaryKey(id); }
@Override
public int deleteByPrimaryKeys(Long[] ids) { return specialPlanMapper.deleteByPrimaryKeys(ids); }
}
@@ -0,0 +1,93 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.business.mapper.BizArticleMapper">
<resultMap id="BaseResultMap" type="BizArticle">
<id property="id" column="id" />
<result property="title" column="title" />
<result property="type" column="type" />
<result property="content" column="content" />
<result property="status" column="status" />
<result property="createBy" column="create_by" />
<result property="createTime" column="create_time" />
<result property="updateBy" column="update_by" />
<result property="updateTime" column="update_time" />
<result property="remark" column="remark" />
</resultMap>
<sql id="selectFields">
select id, title, type, content, status, create_by, create_time, update_by, update_time, remark
from biz_article
</sql>
<select id="selectByPrimaryKey" parameterType="Long" resultMap="BaseResultMap">
<include refid="selectFields"/>
where id = #{id}
</select>
<select id="selectList" parameterType="BizArticle" resultMap="BaseResultMap">
<include refid="selectFields"/>
<where>
<if test="type != null and type != ''"> and type = #{type}</if>
<if test="title != null and title != ''"> and title like concat('%', #{title}, '%')</if>
<if test="status != null and status != ''"> and status = #{status}</if>
</where>
order by type asc, create_time desc
</select>
<select id="selectByType" parameterType="String" resultMap="BaseResultMap">
<include refid="selectFields"/>
where type = #{type} and status = '0'
limit 1
</select>
<insert id="insert" parameterType="BizArticle" useGeneratedKeys="true" keyProperty="id">
insert into biz_article
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="title != null and title != ''">title,</if>
<if test="type != null and type != ''">type,</if>
<if test="content != null">content,</if>
<if test="status != null">status,</if>
<if test="createBy != null">create_by,</if>
create_time,
<if test="updateBy != null">update_by,</if>
update_time,
<if test="remark != null">remark,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="title != null and title != ''">#{title},</if>
<if test="type != null and type != ''">#{type},</if>
<if test="content != null">#{content},</if>
<if test="status != null">#{status},</if>
<if test="createBy != null">#{createBy},</if>
sysdate(),
<if test="updateBy != null">#{updateBy},</if>
sysdate(),
<if test="remark != null">#{remark},</if>
</trim>
</insert>
<update id="updateByPrimaryKey" parameterType="BizArticle">
update biz_article
<trim prefix="SET" suffixOverrides=",">
<if test="title != null and title != ''">title = #{title},</if>
<if test="type != null and type != ''">type = #{type},</if>
<if test="content != null">content = #{content},</if>
<if test="status != null">status = #{status},</if>
<if test="updateBy != null">update_by = #{updateBy},</if>
update_time = sysdate(),
<if test="remark != null">remark = #{remark},</if>
</trim>
where id = #{id}
</update>
<delete id="deleteByPrimaryKey" parameterType="Long">
delete from biz_article where id = #{id}
</delete>
<delete id="deleteByPrimaryKeys" parameterType="Long[]">
delete from biz_article where id in
<foreach collection="array" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</delete>
</mapper>
@@ -17,12 +17,12 @@
<result property="ratingQ2" column="rating_q2" />
<result property="ratingQ3" column="rating_q3" />
<result property="ratingQ4" column="rating_q4" />
<result property="orgName" column="org_name" />
<result property="orgType" column="org_type" />
<result property="sponsorAdminUserName" column="sponsor_admin_user_name" />
<result property="sponsorAdminUserId" column="sponsor_admin_user_id" />
<result property="projectForm" column="project_form" />
<result property="isFinished" column="is_finished" />
<result property="isSettled" column="is_settled" />
<result property="orgId" column="org_id" />
<result property="sponsorAdminUserId" column="sponsor_admin_user_id" />
<result property="createBy" column="create_by" />
<result property="createTime" column="create_time" />
<result property="updateBy" column="update_by" />
@@ -43,7 +43,7 @@
<result property="announcementType" column="announcement_type" />
</resultMap>
<sql id="selectFields">
select project_id, project_no, project_name, total_sessions, done_sessions, todo_sessions, total_amount, available_amount, paid_labor_amount, paid_meeting_amount, rating_score, rating_q1, rating_q2, rating_q3, rating_q4, org_name, org_type, project_form, is_finished, is_settled, org_id, create_by, create_time, update_by, update_time, manage_fee, start_time, end_time, submit_deadline_days, support_contract_url, execute_contract_url, invitation_url, support_letter_url, publish_url, notice_url, schedule_url, is_published, publish_time, announcement_type
select project_id, project_no, project_name, total_sessions, done_sessions, todo_sessions, total_amount, available_amount, paid_labor_amount, paid_meeting_amount, rating_score, rating_q1, rating_q2, rating_q3, rating_q4, sponsor_admin_user_name, project_form, is_finished, is_settled, sponsor_admin_user_id, create_by, create_time, update_by, update_time, manage_fee, start_time, end_time, submit_deadline_days, support_contract_url, execute_contract_url, invitation_url, support_letter_url, publish_url, notice_url, schedule_url, is_published, publish_time, announcement_type
from biz_project
</sql>
@@ -51,8 +51,8 @@
<sql id="selectFieldsForSponsor">
select p.project_id, p.project_no, p.project_name, p.total_sessions, p.done_sessions, p.todo_sessions,
p.total_amount, p.available_amount, p.paid_labor_amount, p.paid_meeting_amount,
p.org_name, p.org_type, p.project_form, p.is_finished, p.is_settled,
p.org_id,
p.sponsor_admin_user_name, p.project_form, p.is_finished, p.is_settled,
p.sponsor_admin_user_id,
p.create_by, p.create_time, p.update_by, p.update_time, p.manage_fee,
p.start_time, p.end_time, p.submit_deadline_days,
p.support_contract_url, p.execute_contract_url, p.invitation_url, p.support_letter_url,
@@ -107,8 +107,26 @@
<if test="projectNo != null and projectNo != ''">and project_no like concat('%', #{projectNo}, '%')</if>
<if test="projectName != null and projectName != ''">and project_name like concat('%', #{projectName}, '%')</if>
<if test="projectForm != null and projectForm != ''">and project_form = #{projectForm}</if>
<if test="orgName != null and orgName != ''">and org_name like concat('%', #{orgName}, '%')</if>
<if test="orgType != null and orgType != ''">and org_type = #{orgType}</if>
<if test="sponsorAdminUserName != null and sponsorAdminUserName != ''">
and exists (
select 1 from sys_user su
where su.user_id = sponsor_admin_user_id
and su.role_type = 'sponsor'
and (su.user_name like concat('%', #{sponsorAdminUserName}, '%')
or su.nick_name like concat('%', #{sponsorAdminUserName}, '%'))
)
</if>
<if test="execOrgName != null and execOrgName != ''">
and exists (
select 1 from biz_project_assign bpa
join sys_user su on su.user_id = bpa.exec_user_id
where bpa.project_id = project_id
and su.role_type = 'executor'
and (su.user_name like concat('%', #{execOrgName}, '%')
or su.nick_name like concat('%', #{execOrgName}, '%')
or bpa.exec_org like concat('%', #{execOrgName}, '%'))
)
</if>
<if test="isFinished != null and isFinished != ''">and is_finished = #{isFinished}</if>
<if test="isSettled != null and isSettled != ''">and is_settled = #{isSettled}</if>
<if test="isPublished != null and isPublished != ''">and is_published = #{isPublished}</if>
@@ -133,12 +151,11 @@
<if test="ratingQ2 != null">rating_q2,</if>
<if test="ratingQ3 != null">rating_q3,</if>
<if test="ratingQ4 != null">rating_q4,</if>
<if test="orgName != null and orgName != ''">org_name,</if>
<if test="orgType != null and orgType != ''">org_type,</if>
<if test="sponsorAdminUserName != null and sponsorAdminUserName != ''">sponsor_admin_user_name,</if>
<if test="projectForm != null and projectForm != ''">project_form,</if>
<if test="isFinished != null and isFinished != ''">is_finished,</if>
<if test="isSettled != null and isSettled != ''">is_settled,</if>
<if test="orgId != null">org_id,</if>
<if test="sponsorAdminUserId != null">sponsor_admin_user_id,</if>
<if test="createBy != null">create_by,</if>
<if test="createTime != null">create_time,</if>
<if test="updateBy != null">update_by,</if>
@@ -174,12 +191,11 @@
<if test="ratingQ2 != null">#{ratingQ2},</if>
<if test="ratingQ3 != null">#{ratingQ3},</if>
<if test="ratingQ4 != null">#{ratingQ4},</if>
<if test="orgName != null and orgName != ''">#{orgName},</if>
<if test="orgType != null and orgType != ''">#{orgType},</if>
<if test="sponsorAdminUserName != null and sponsorAdminUserName != ''">#{sponsorAdminUserName},</if>
<if test="projectForm != null and projectForm != ''">#{projectForm},</if>
<if test="isFinished != null and isFinished != ''">#{isFinished},</if>
<if test="isSettled != null and isSettled != ''">#{isSettled},</if>
<if test="orgId != null">#{orgId},</if>
<if test="sponsorAdminUserId != null">#{sponsorAdminUserId},</if>
<if test="createBy != null">#{createBy},</if>
<if test="createTime != null">#{createTime},</if>
<if test="updateBy != null">#{updateBy},</if>
@@ -231,12 +247,11 @@
<if test="ratingQ2 != null">rating_q2 = #{ratingQ2},</if>
<if test="ratingQ3 != null">rating_q3 = #{ratingQ3},</if>
<if test="ratingQ4 != null">rating_q4 = #{ratingQ4},</if>
<if test="orgName != null and orgName != ''">org_name = #{orgName},</if>
<if test="orgType != null and orgType != ''">org_type = #{orgType},</if>
<if test="sponsorAdminUserName != null and sponsorAdminUserName != ''">sponsor_admin_user_name = #{sponsorAdminUserName},</if>
<if test="projectForm != null and projectForm != ''">project_form = #{projectForm},</if>
<if test="isFinished != null and isFinished != ''">is_finished = #{isFinished},</if>
<if test="isSettled != null and isSettled != ''">is_settled = #{isSettled},</if>
<if test="orgId != null">org_id = #{orgId},</if>
<if test="sponsorAdminUserId != null">sponsor_admin_user_id = #{sponsorAdminUserId},</if>
<if test="createBy != null">create_by = #{createBy},</if>
<if test="createTime != null">create_time = #{createTime},</if>
<if test="updateBy != null">update_by = #{updateBy},</if>
@@ -0,0 +1,104 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.business.mapper.BizSpecialPlanMapper">
<resultMap id="BaseResultMap" type="BizSpecialPlan">
<id property="id" column="id" />
<result property="title" column="title" />
<result property="contentType" column="content_type" />
<result property="content" column="content" />
<result property="fileUrl" column="file_url" />
<result property="sortOrder" column="sort_order" />
<result property="status" column="status" />
<result property="createBy" column="create_by" />
<result property="createTime" column="create_time" />
<result property="updateBy" column="update_by" />
<result property="updateTime" column="update_time" />
<result property="remark" column="remark" />
</resultMap>
<sql id="selectFields">
select id, title, content_type, content, file_url, sort_order, status,
create_by, create_time, update_by, update_time, remark
from biz_special_plan
</sql>
<select id="selectByPrimaryKey" parameterType="Long" resultMap="BaseResultMap">
<include refid="selectFields"/>
where id = #{id}
</select>
<!-- 公开: 仅启用 (status=0), 按 sort_order 升序 -->
<select id="selectPublicList" resultMap="BaseResultMap">
<include refid="selectFields"/>
where status = '0'
order by sort_order asc, create_time asc
</select>
<!-- 后台管理: 支持 title/status 模糊/精确 -->
<select id="selectList" parameterType="BizSpecialPlan" resultMap="BaseResultMap">
<include refid="selectFields"/>
<where>
<if test="title != null and title != ''"> and title like concat('%', #{title}, '%')</if>
<if test="contentType != null and contentType != ''"> and content_type = #{contentType}</if>
<if test="status != null and status != ''"> and status = #{status}</if>
</where>
order by sort_order asc, id asc
</select>
<insert id="insert" parameterType="BizSpecialPlan" useGeneratedKeys="true" keyProperty="id">
insert into biz_special_plan
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="title != null and title != ''">title,</if>
<if test="contentType != null and contentType != ''">content_type,</if>
<if test="content != null">content,</if>
<if test="fileUrl != null">file_url,</if>
<if test="sortOrder != null">sort_order,</if>
<if test="status != null">status,</if>
<if test="createBy != null">create_by,</if>
create_time,
<if test="updateBy != null">update_by,</if>
update_time,
<if test="remark != null">remark,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="title != null and title != ''">#{title},</if>
<if test="contentType != null and contentType != ''">#{contentType},</if>
<if test="content != null">#{content},</if>
<if test="fileUrl != null">#{fileUrl},</if>
<if test="sortOrder != null">#{sortOrder},</if>
<if test="status != null">#{status},</if>
<if test="createBy != null">#{createBy},</if>
sysdate(),
<if test="updateBy != null">#{updateBy},</if>
sysdate(),
<if test="remark != null">#{remark},</if>
</trim>
</insert>
<update id="updateByPrimaryKey" parameterType="BizSpecialPlan">
update biz_special_plan
<trim prefix="SET" suffixOverrides=",">
<if test="title != null and title != ''">title = #{title},</if>
<if test="contentType != null and contentType != ''">content_type = #{contentType},</if>
<if test="content != null">content = #{content},</if>
<if test="fileUrl != null">file_url = #{fileUrl},</if>
<if test="sortOrder != null">sort_order = #{sortOrder},</if>
<if test="status != null">status = #{status},</if>
<if test="updateBy != null">update_by = #{updateBy},</if>
update_time = sysdate(),
<if test="remark != null">remark = #{remark},</if>
</trim>
where id = #{id}
</update>
<delete id="deleteByPrimaryKey" parameterType="Long">
delete from biz_special_plan where id = #{id}
</delete>
<delete id="deleteByPrimaryKeys" parameterType="Long[]">
delete from biz_special_plan where id in
<foreach collection="array" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</delete>
</mapper>