checkout-SAMS-R

SAMS-R
bruce 2025-05-18 23:35:05 +08:00
parent 46708ceee4
commit 724a32df17
101 changed files with 9033 additions and 1078 deletions

32
bs-sams/pom.xml 100644
View File

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi</artifactId>
<version>3.8.9</version>
</parent>
<artifactId>bs-sams</artifactId>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common</artifactId>
</dependency>
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-system</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,107 @@
package com.ruoyi.sams.ams.controller;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import com.ruoyi.sams.ams.domain.AmsActivity;
import com.ruoyi.sams.ams.domain.vo.ActivityListGetVO;
import com.ruoyi.sams.ams.domain.vo.ActivityListVO;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.sams.ams.service.IAmsActivityService;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;
/**
* Controller
*
* @author ruoyi
* @date 2025-05-06
*/
@RestController
@RequestMapping("/ams/activity")
public class AmsActivityController extends BaseController
{
@Autowired
private IAmsActivityService amsActivityService;
/**
*
*/
@PreAuthorize("@ss.hasPermi('ams:activity:list')")
@GetMapping("/list")
public TableDataInfo list(ActivityListGetVO amsActivity)
{
startPage();
List<ActivityListVO> list = amsActivityService.selectAmsActivityList(amsActivity);
return getDataTable(list);
}
/**
*
*/
@PreAuthorize("@ss.hasPermi('ams:activity:export')")
@Log(title = "活动列表", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, ActivityListGetVO amsActivity)
{
List<ActivityListVO> list = amsActivityService.selectAmsActivityList(amsActivity);
ExcelUtil<ActivityListVO> util = new ExcelUtil<ActivityListVO>(ActivityListVO.class);
util.exportExcel(response, list, "活动列表数据");
}
/**
*
*/
@PreAuthorize("@ss.hasPermi('ams:activity:query')")
@GetMapping(value = "/{actId}")
public AjaxResult getInfo(@PathVariable("actId") Long actId)
{
return success(amsActivityService.selectAmsActivityByActId(actId));
}
/**
*
*/
@PreAuthorize("@ss.hasPermi('ams:activity:add')")
@Log(title = "活动列表", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody AmsActivity amsActivity)
{
return toAjax(amsActivityService.insertAmsActivity(amsActivity));
}
/**
*
*/
@PreAuthorize("@ss.hasPermi('ams:activity:edit')")
@Log(title = "活动列表", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody AmsActivity amsActivity)
{
return toAjax(amsActivityService.updateAmsActivity(amsActivity));
}
/**
*
*/
@PreAuthorize("@ss.hasPermi('ams:activity:remove')")
@Log(title = "活动列表", businessType = BusinessType.DELETE)
@DeleteMapping("/{actIds}")
public AjaxResult remove(@PathVariable Long[] actIds)
{
return toAjax(amsActivityService.deleteAmsActivityByActIds(actIds));
}
}

View File

@ -0,0 +1,106 @@
package com.ruoyi.sams.ams.controller;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import com.ruoyi.sams.ams.domain.AmsComment;
import com.ruoyi.sams.ams.domain.vo.AmsCommentListVO;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.sams.ams.service.IAmsCommentService;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;
/**
* Controller
*
* @author ruoyi
* @date 2025-05-06
*/
@RestController
@RequestMapping("/ams/comment")
public class AmsCommentController extends BaseController
{
@Autowired
private IAmsCommentService amsCommentService;
/**
*
*/
@PreAuthorize("@ss.hasPermi('ams:comment:list')")
@GetMapping("/list")
public TableDataInfo list(AmsCommentListVO amsComment)
{
startPage();
List<AmsCommentListVO> list = amsCommentService.selectAmsCommentList(amsComment);
return getDataTable(list);
}
/**
*
*/
@PreAuthorize("@ss.hasPermi('ams:comment:export')")
@Log(title = "活动评论", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, AmsCommentListVO amsComment)
{
List<AmsCommentListVO> list = amsCommentService.selectAmsCommentList(amsComment);
ExcelUtil<AmsCommentListVO> util = new ExcelUtil<AmsCommentListVO>(AmsCommentListVO.class);
util.exportExcel(response, list, "活动评论数据");
}
/**
*
*/
@PreAuthorize("@ss.hasPermi('ams:comment:query')")
@GetMapping(value = "/{commentId}")
public AjaxResult getInfo(@PathVariable("commentId") Long commentId)
{
return success(amsCommentService.selectAmsCommentByCommentId(commentId));
}
/**
*
*/
@PreAuthorize("@ss.hasPermi('ams:comment:add')")
@Log(title = "活动评论", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody AmsComment amsComment)
{
return toAjax(amsCommentService.insertAmsComment(amsComment));
}
/**
*
*/
@PreAuthorize("@ss.hasPermi('ams:comment:edit')")
@Log(title = "活动评论", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody AmsComment amsComment)
{
return toAjax(amsCommentService.updateAmsComment(amsComment));
}
/**
*
*/
@PreAuthorize("@ss.hasPermi('ams:comment:remove')")
@Log(title = "活动评论", businessType = BusinessType.DELETE)
@DeleteMapping("/{commentIds}")
public AjaxResult remove(@PathVariable Long[] commentIds)
{
return toAjax(amsCommentService.deleteAmsCommentByCommentIds(commentIds));
}
}

View File

@ -0,0 +1,106 @@
package com.ruoyi.sams.ams.controller;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import com.ruoyi.sams.ams.domain.AmsReaction;
import com.ruoyi.sams.ams.domain.vo.AmsReactionVO;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.sams.ams.service.IAmsReactionService;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;
/**
* Controller
*
* @author ruoyi
* @date 2025-05-06
*/
@RestController
@RequestMapping("/ams/reaction")
public class AmsReactionController extends BaseController
{
@Autowired
private IAmsReactionService amsReactionService;
/**
*
*/
@PreAuthorize("@ss.hasPermi('ams:reaction:list')")
@GetMapping("/list")
public TableDataInfo list(AmsReactionVO amsReaction)
{
startPage();
List<AmsReactionVO> list = amsReactionService.selectAmsReactionList(amsReaction);
return getDataTable(list);
}
/**
*
*/
@PreAuthorize("@ss.hasPermi('ams:reaction:export')")
@Log(title = "点赞记录", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, AmsReactionVO amsReaction)
{
List<AmsReactionVO> list = amsReactionService.selectAmsReactionList(amsReaction);
ExcelUtil<AmsReactionVO> util = new ExcelUtil<AmsReactionVO>(AmsReactionVO.class);
util.exportExcel(response, list, "点赞记录数据");
}
/**
*
*/
@PreAuthorize("@ss.hasPermi('ams:reaction:query')")
@GetMapping(value = "/{reactionId}")
public AjaxResult getInfo(@PathVariable("reactionId") Long reactionId)
{
return success(amsReactionService.selectAmsReactionByReactionId(reactionId));
}
/**
*
*/
@PreAuthorize("@ss.hasPermi('ams:reaction:add')")
@Log(title = "点赞记录", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody AmsReaction amsReaction)
{
return toAjax(amsReactionService.insertAmsReaction(amsReaction));
}
/**
*
*/
@PreAuthorize("@ss.hasPermi('ams:reaction:edit')")
@Log(title = "点赞记录", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody AmsReaction amsReaction)
{
return toAjax(amsReactionService.updateAmsReaction(amsReaction));
}
/**
*
*/
@PreAuthorize("@ss.hasPermi('ams:reaction:remove')")
@Log(title = "点赞记录", businessType = BusinessType.DELETE)
@DeleteMapping("/{reactionIds}")
public AjaxResult remove(@PathVariable Long[] reactionIds)
{
return toAjax(amsReactionService.deleteAmsReactionByReactionIds(reactionIds));
}
}

View File

@ -0,0 +1,104 @@
package com.ruoyi.sams.ams.controller;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.sams.ams.domain.AmsRegistration;
import com.ruoyi.sams.ams.service.IAmsRegistrationService;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;
/**
* Controller
*
* @author ruoyi
* @date 2025-05-08
*/
@RestController
@RequestMapping("/ams/registration")
public class AmsRegistrationController extends BaseController
{
@Autowired
private IAmsRegistrationService amsRegistrationService;
/**
*
*/
@PreAuthorize("@ss.hasPermi('ams:registration:list')")
@GetMapping("/list")
public TableDataInfo list(AmsRegistration amsRegistration)
{
startPage();
List<AmsRegistration> list = amsRegistrationService.selectAmsRegistrationList(amsRegistration);
return getDataTable(list);
}
/**
*
*/
@PreAuthorize("@ss.hasPermi('ams:registration:export')")
@Log(title = "活动报名", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, AmsRegistration amsRegistration)
{
List<AmsRegistration> list = amsRegistrationService.selectAmsRegistrationList(amsRegistration);
ExcelUtil<AmsRegistration> util = new ExcelUtil<AmsRegistration>(AmsRegistration.class);
util.exportExcel(response, list, "活动报名数据");
}
/**
*
*/
@PreAuthorize("@ss.hasPermi('ams:registration:query')")
@GetMapping(value = "/{regId}")
public AjaxResult getInfo(@PathVariable("regId") Long regId)
{
return success(amsRegistrationService.selectAmsRegistrationByRegId(regId));
}
/**
*
*/
@PreAuthorize("@ss.hasPermi('ams:registration:add')")
@Log(title = "活动报名", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody AmsRegistration amsRegistration)
{
return toAjax(amsRegistrationService.insertAmsRegistration(amsRegistration));
}
/**
*
*/
@PreAuthorize("@ss.hasPermi('ams:registration:edit')")
@Log(title = "活动报名", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody AmsRegistration amsRegistration)
{
return toAjax(amsRegistrationService.updateAmsRegistration(amsRegistration));
}
/**
*
*/
@PreAuthorize("@ss.hasPermi('ams:registration:remove')")
@Log(title = "活动报名", businessType = BusinessType.DELETE)
@DeleteMapping("/{regIds}")
public AjaxResult remove(@PathVariable Long[] regIds)
{
return toAjax(amsRegistrationService.deleteAmsRegistrationByRegIds(regIds));
}
}

View File

@ -0,0 +1,274 @@
package com.ruoyi.sams.ams.domain;
import java.math.BigDecimal;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.core.domain.BaseEntity;
/**
* ams_activity
*
* @author ruoyi
* @date 2025-05-07
*/
public class AmsActivity extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 活动ID */
private Long actId;
/** 活动标题 */
@Excel(name = "活动标题")
private String title;
/** 活动描述 */
@Excel(name = "活动描述")
private String description;
/** 封面图 */
@Excel(name = "封面图")
private String coverImage;
/** 开始时间 */
@JsonFormat(pattern = "yyyy-MM-dd")
@Excel(name = "开始时间", width = 30, dateFormat = "yyyy-MM-dd")
private Date startTime;
/** 结束时间 */
@JsonFormat(pattern = "yyyy-MM-dd")
@Excel(name = "结束时间", width = 30, dateFormat = "yyyy-MM-dd")
private Date endTime;
/** 活动地点 */
@Excel(name = "活动地点")
private String location;
/** 预算金额 */
@Excel(name = "预算金额")
private BigDecimal budget;
/** 最大参与人数 */
@Excel(name = "最大参与人数")
private Long maxParticipants;
/** 创建人IDsys_user */
@Excel(name = "创建人ID", readConverterExp = "s=ys_user")
private Long creatorId;
/** 所属社团IDsms_club */
@Excel(name = "所属社团ID", readConverterExp = "s=ms_club")
private Long clubId;
/** 所属院系IDsys_dept */
@Excel(name = "所属院系ID", readConverterExp = "s=ys_dept")
private Long deptId;
/** 活动类型 */
@Excel(name = "活动类型")
private String activityType;
/** 活动状态 */
@Excel(name = "活动状态")
private String status;
/** 是否公开 */
@Excel(name = "是否公开")
private String visibility;
/** 当前审批人ID */
@Excel(name = "当前审批人ID")
private Long currentApproverId;
public void setActId(Long actId)
{
this.actId = actId;
}
public Long getActId()
{
return actId;
}
public void setTitle(String title)
{
this.title = title;
}
public String getTitle()
{
return title;
}
public void setDescription(String description)
{
this.description = description;
}
public String getDescription()
{
return description;
}
public void setCoverImage(String coverImage)
{
this.coverImage = coverImage;
}
public String getCoverImage()
{
return coverImage;
}
public void setStartTime(Date startTime)
{
this.startTime = startTime;
}
public Date getStartTime()
{
return startTime;
}
public void setEndTime(Date endTime)
{
this.endTime = endTime;
}
public Date getEndTime()
{
return endTime;
}
public void setLocation(String location)
{
this.location = location;
}
public String getLocation()
{
return location;
}
public void setBudget(BigDecimal budget)
{
this.budget = budget;
}
public BigDecimal getBudget()
{
return budget;
}
public void setMaxParticipants(Long maxParticipants)
{
this.maxParticipants = maxParticipants;
}
public Long getMaxParticipants()
{
return maxParticipants;
}
public void setCreatorId(Long creatorId)
{
this.creatorId = creatorId;
}
public Long getCreatorId()
{
return creatorId;
}
public void setClubId(Long clubId)
{
this.clubId = clubId;
}
public Long getClubId()
{
return clubId;
}
public void setDeptId(Long deptId)
{
this.deptId = deptId;
}
public Long getDeptId()
{
return deptId;
}
public void setActivityType(String activityType)
{
this.activityType = activityType;
}
public String getActivityType()
{
return activityType;
}
public void setStatus(String status)
{
this.status = status;
}
public String getStatus()
{
return status;
}
public void setVisibility(String visibility)
{
this.visibility = visibility;
}
public String getVisibility()
{
return visibility;
}
public void setCurrentApproverId(Long currentApproverId)
{
this.currentApproverId = currentApproverId;
}
public Long getCurrentApproverId()
{
return currentApproverId;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("actId", getActId())
.append("title", getTitle())
.append("description", getDescription())
.append("coverImage", getCoverImage())
.append("startTime", getStartTime())
.append("endTime", getEndTime())
.append("location", getLocation())
.append("budget", getBudget())
.append("maxParticipants", getMaxParticipants())
.append("creatorId", getCreatorId())
.append("clubId", getClubId())
.append("deptId", getDeptId())
.append("activityType", getActivityType())
.append("status", getStatus())
.append("visibility", getVisibility())
.append("currentApproverId", getCurrentApproverId())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime())
.append("remark", getRemark())
.toString();
}
}

View File

@ -0,0 +1,102 @@
package com.ruoyi.sams.ams.domain;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.core.domain.BaseEntity;
/**
* ams_comment
*
* @author ruoyi
* @date 2025-05-06
*/
public class AmsComment extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 评论ID */
private Long commentId;
/** 活动ID */
@Excel(name = "活动ID")
private Long actId;
/** 用户ID */
@Excel(name = "用户ID")
private Long userId;
/** 父评论ID嵌套结构 */
@Excel(name = "父评论ID", readConverterExp = "嵌=套结构")
private Long parentCommentId;
/** 评论内容 */
@Excel(name = "评论内容")
private String content;
public void setCommentId(Long commentId)
{
this.commentId = commentId;
}
public Long getCommentId()
{
return commentId;
}
public void setActId(Long actId)
{
this.actId = actId;
}
public Long getActId()
{
return actId;
}
public void setUserId(Long userId)
{
this.userId = userId;
}
public Long getUserId()
{
return userId;
}
public void setParentCommentId(Long parentCommentId)
{
this.parentCommentId = parentCommentId;
}
public Long getParentCommentId()
{
return parentCommentId;
}
public void setContent(String content)
{
this.content = content;
}
public String getContent()
{
return content;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("commentId", getCommentId())
.append("actId", getActId())
.append("userId", getUserId())
.append("parentCommentId", getParentCommentId())
.append("content", getContent())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime())
.append("remark", getRemark())
.toString();
}
}

View File

@ -0,0 +1,87 @@
package com.ruoyi.sams.ams.domain;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.core.domain.BaseEntity;
/**
* ams_reaction
*
* @author ruoyi
* @date 2025-05-06
*/
public class AmsReaction extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 互动ID */
private Long reactionId;
/** 活动ID */
@Excel(name = "活动ID")
private Long actId;
/** 用户ID */
@Excel(name = "用户ID")
private Long userId;
/** 反应类型like点赞 / dislike点踩 */
@Excel(name = "反应类型", readConverterExp = "l=ike点赞,/=,d=islike点踩")
private String reactionType;
public void setReactionId(Long reactionId)
{
this.reactionId = reactionId;
}
public Long getReactionId()
{
return reactionId;
}
public void setActId(Long actId)
{
this.actId = actId;
}
public Long getActId()
{
return actId;
}
public void setUserId(Long userId)
{
this.userId = userId;
}
public Long getUserId()
{
return userId;
}
public void setReactionType(String reactionType)
{
this.reactionType = reactionType;
}
public String getReactionType()
{
return reactionType;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("reactionId", getReactionId())
.append("actId", getActId())
.append("userId", getUserId())
.append("reactionType", getReactionType())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime())
.append("remark", getRemark())
.toString();
}
}

View File

@ -0,0 +1,132 @@
package com.ruoyi.sams.ams.domain;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.core.domain.BaseEntity;
/**
* ams_registration
*
* @author ruoyi
* @date 2025-05-08
*/
public class AmsRegistration extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 报名ID */
private Long regId;
/** 活动ID */
@Excel(name = "活动ID")
private Long actId;
/** 用户ID */
@Excel(name = "用户ID")
private Long userId;
/** 角色 */
@Excel(name = "角色")
private String role;
/** 报名状态 */
@Excel(name = "报名状态")
private String status;
/** 报名时间 */
private Date registerTime;
/** 签到时间 */
private Date attendTime;
public void setRegId(Long regId)
{
this.regId = regId;
}
public Long getRegId()
{
return regId;
}
public void setActId(Long actId)
{
this.actId = actId;
}
public Long getActId()
{
return actId;
}
public void setUserId(Long userId)
{
this.userId = userId;
}
public Long getUserId()
{
return userId;
}
public void setRole(String role)
{
this.role = role;
}
public String getRole()
{
return role;
}
public void setStatus(String status)
{
this.status = status;
}
public String getStatus()
{
return status;
}
public void setRegisterTime(Date registerTime)
{
this.registerTime = registerTime;
}
public Date getRegisterTime()
{
return registerTime;
}
public void setAttendTime(Date attendTime)
{
this.attendTime = attendTime;
}
public Date getAttendTime()
{
return attendTime;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("regId", getRegId())
.append("actId", getActId())
.append("userId", getUserId())
.append("role", getRole())
.append("status", getStatus())
.append("registerTime", getRegisterTime())
.append("attendTime", getAttendTime())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime())
.append("remark", getRemark())
.toString();
}
}

View File

@ -0,0 +1,57 @@
package com.ruoyi.sams.ams.domain.vo;
/**
*
*/
public class ActivityListGetVO {
private String title; // 活动标题(模糊查询)
private String status; // 状态筛选
private Long clubId; // 所属社团
private Long creatorId; // 创建人ID
/**
* 稿使
*/
private Boolean excludeOtherDraft;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public Long getClubId() {
return clubId;
}
public void setClubId(Long clubId) {
this.clubId = clubId;
}
public Long getCreatorId() {
return creatorId;
}
public void setCreatorId(Long creatorId) {
this.creatorId = creatorId;
}
public Boolean getExcludeOtherDraft() {
return excludeOtherDraft;
}
public void setExcludeOtherDraft(Boolean excludeOtherDraft) {
this.excludeOtherDraft = excludeOtherDraft;
}
}

View File

@ -0,0 +1,231 @@
package com.ruoyi.sams.ams.domain.vo;
import com.ruoyi.common.annotation.Excel;
import java.math.BigDecimal;
import java.util.Date;
public class ActivityListVO {
@Excel(name = "活动ID")
private Long actId;
@Excel(name = "活动标题")
private String title;
@Excel(name = "活动描述")
private String description;
/** 封面图 */
@Excel(name = "封面图")
private String coverImage;
@Excel(name = "预算")
private BigDecimal budget;
@Excel(name = "创建人ID")
private Long creatorId;
@Excel(name = "创建人姓名")
private String creatorName;
@Excel(name = "所属社团ID")
private Long clubId;
@Excel(name = "社团名称")
private String clubName;
@Excel(name = "所属院系ID")
private Long deptId;
@Excel(name = "院系名称")
private String deptName;
@Excel(name = "活动地点")
private String location;
@Excel(name = "活动类型")
private String activityType;
@Excel(name = "活动状态")
private String status;
@Excel(name = "可见性")
private String visibility;
@Excel(name = "开始时间", dateFormat = "yyyy-MM-dd HH:mm:ss")
private Date startTime;
@Excel(name = "结束时间", dateFormat = "yyyy-MM-dd HH:mm:ss")
private Date endTime;
@Excel(name = "备注")
private String remark;
public Long getActId() {
return actId;
}
public void setActId(Long actId) {
this.actId = actId;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getCoverImage() {
return coverImage;
}
public void setCoverImage(String coverImage) {
this.coverImage = coverImage;
}
public BigDecimal getBudget() {
return budget;
}
public void setBudget(BigDecimal budget) {
this.budget = budget;
}
public Long getCreatorId() {
return creatorId;
}
public void setCreatorId(Long creatorId) {
this.creatorId = creatorId;
}
public String getCreatorName() {
return creatorName;
}
public void setCreatorName(String creatorName) {
this.creatorName = creatorName;
}
public Long getClubId() {
return clubId;
}
public void setClubId(Long clubId) {
this.clubId = clubId;
}
public String getClubName() {
return clubName;
}
public void setClubName(String clubName) {
this.clubName = clubName;
}
public Long getDeptId() {
return deptId;
}
public void setDeptId(Long deptId) {
this.deptId = deptId;
}
public String getDeptName() {
return deptName;
}
public void setDeptName(String deptName) {
this.deptName = deptName;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
public String getActivityType() {
return activityType;
}
public void setActivityType(String activityType) {
this.activityType = activityType;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getVisibility() {
return visibility;
}
public void setVisibility(String visibility) {
this.visibility = visibility;
}
public Date getStartTime() {
return startTime;
}
public void setStartTime(Date startTime) {
this.startTime = startTime;
}
public Date getEndTime() {
return endTime;
}
public void setEndTime(Date endTime) {
this.endTime = endTime;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
@Override
public String toString() {
return "ActivityListVO{" +
"actId=" + actId +
", title='" + title + '\'' +
", description='" + description + '\'' +
", coverImage='" + coverImage + '\'' +
", budget=" + budget +
", creatorId=" + creatorId +
", creatorName='" + creatorName + '\'' +
", clubId=" + clubId +
", clubName='" + clubName + '\'' +
", deptId=" + deptId +
", deptName='" + deptName + '\'' +
", location='" + location + '\'' +
", activityType='" + activityType + '\'' +
", status='" + status + '\'' +
", visibility='" + visibility + '\'' +
", startTime=" + startTime +
", endTime=" + endTime +
", remark='" + remark + '\'' +
'}';
}
}

View File

@ -0,0 +1,106 @@
package com.ruoyi.sams.ams.domain.vo;
import com.ruoyi.common.annotation.Excel;
import java.util.Date;
public class AmsCommentListVO {
@Excel(name = "评论ID")
private Long commentId;
@Excel(name = "活动ID")
private Long actId;
@Excel(name = "活动名称")
private String activityName;
@Excel(name = "用户ID")
private Long userId;
@Excel(name = "用户名")
private String userName;
@Excel(name = "父评论ID")
private Long parentCommentId;
@Excel(name = "评论内容")
private String content;
@Excel(name = "备注")
private String remark;
@Excel(name = "创建时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
public Long getCommentId() {
return commentId;
}
public void setCommentId(Long commentId) {
this.commentId = commentId;
}
public Long getActId() {
return actId;
}
public void setActId(Long actId) {
this.actId = actId;
}
public String getActivityName() {
return activityName;
}
public void setActivityName(String activityName) {
this.activityName = activityName;
}
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public Long getParentCommentId() {
return parentCommentId;
}
public void setParentCommentId(Long parentCommentId) {
this.parentCommentId = parentCommentId;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
}

View File

@ -0,0 +1,96 @@
package com.ruoyi.sams.ams.domain.vo;
import com.ruoyi.common.annotation.Excel;
/**
* AmsReactionVO
*/
public class AmsReactionVO {
@Excel(name = "互动ID")
private Long reactionId;
@Excel(name = "活动ID")
private Long actId;
@Excel(name = "活动名称")
private String actTitle;
@Excel(name = "用户ID")
private Long userId;
@Excel(name = "用户名")
private String userName;
@Excel(name = "反应类型", dictType = "ams_reaction_type")
private String reactionType;
@Excel(name = "备注")
private String remark;
@Excel(name = "创建时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
private String createTime;
public Long getReactionId() {
return reactionId;
}
public void setReactionId(Long reactionId) {
this.reactionId = reactionId;
}
public Long getActId() {
return actId;
}
public void setActId(Long actId) {
this.actId = actId;
}
public String getActTitle() {
return actTitle;
}
public void setActTitle(String actTitle) {
this.actTitle = actTitle;
}
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getReactionType() {
return reactionType;
}
public void setReactionType(String reactionType) {
this.reactionType = reactionType;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
public String getCreateTime() {
return createTime;
}
public void setCreateTime(String createTime) {
this.createTime = createTime;
}
}

View File

@ -0,0 +1,69 @@
package com.ruoyi.sams.ams.domain.vo;
import java.util.Date;
public class AmsRegistrationGetVO {
private Long actId;
private Long userId;
private String role;
private String activityName; // 活动名称(模糊查询)
private String userName; // 用户名(模糊查询)
private Date registerTime;
private Date attendTime;
public Long getActId() {
return actId;
}
public void setActId(Long actId) {
this.actId = actId;
}
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
public String getActivityName() {
return activityName;
}
public void setActivityName(String activityName) {
this.activityName = activityName;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public Date getRegisterTime() {
return registerTime;
}
public void setRegisterTime(Date registerTime) {
this.registerTime = registerTime;
}
public Date getAttendTime() {
return attendTime;
}
public void setAttendTime(Date attendTime) {
this.attendTime = attendTime;
}
}

View File

@ -0,0 +1,162 @@
package com.ruoyi.sams.ams.domain.vo;
import com.ruoyi.common.annotation.Excel;
import java.time.LocalDate;
import java.time.LocalDateTime;
public class AmsRegistrationVO {
@Excel(name = "报名ID")
private Long regId;
@Excel(name = "活动ID")
private Long actId;
@Excel(name = "活动名称")
private String activityName;
@Excel(name = "用户ID")
private Long userId;
@Excel(name = "用户姓名")
private String userName;
@Excel(name = "报名角色")
private String role;
@Excel(name = "报名状态")
private String status;
@Excel(name = "报名时间", dateFormat = "yyyy-MM-dd")
private LocalDate registerTime;
@Excel(name = "签到时间", dateFormat = "yyyy-MM-dd")
private LocalDate attendTime;
@Excel(name = "创建人")
private String createBy;
@Excel(name = "创建时间", dateFormat = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime createTime;
@Excel(name = "更新人")
private String updateBy;
@Excel(name = "更新时间", dateFormat = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime updateTime;
@Excel(name = "备注")
private String remark;
public Long getRegId() {
return regId;
}
public void setRegId(Long regId) {
this.regId = regId;
}
public Long getActId() {
return actId;
}
public void setActId(Long actId) {
this.actId = actId;
}
public String getActivityName() {
return activityName;
}
public void setActivityName(String activityName) {
this.activityName = activityName;
}
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public LocalDate getRegisterTime() {
return registerTime;
}
public void setRegisterTime(LocalDate registerTime) {
this.registerTime = registerTime;
}
public LocalDate getAttendTime() {
return attendTime;
}
public void setAttendTime(LocalDate attendTime) {
this.attendTime = attendTime;
}
public String getCreateBy() {
return createBy;
}
public void setCreateBy(String createBy) {
this.createBy = createBy;
}
public LocalDateTime getCreateTime() {
return createTime;
}
public void setCreateTime(LocalDateTime createTime) {
this.createTime = createTime;
}
public String getUpdateBy() {
return updateBy;
}
public void setUpdateBy(String updateBy) {
this.updateBy = updateBy;
}
public LocalDateTime getUpdateTime() {
return updateTime;
}
public void setUpdateTime(LocalDateTime updateTime) {
this.updateTime = updateTime;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
}

View File

@ -0,0 +1,75 @@
package com.ruoyi.sams.ams.mapper;
import java.util.List;
import com.ruoyi.sams.ams.domain.vo.ActivityListVO;
import com.ruoyi.sams.ams.domain.AmsActivity;
import com.ruoyi.sams.ams.domain.vo.ActivityListGetVO;
import com.ruoyi.sams.ui.domain.vo.ActivityQueryDTO;
import com.ruoyi.sams.ui.domain.vo.HotClubVO;
import org.apache.ibatis.annotations.Param;
/**
* Mapper
*
* @author ruoyi
* @date 2025-05-06
*/
public interface AmsActivityMapper
{
/**
*
*
* @param actId
* @return
*/
public ActivityListVO selectAmsActivityByActId(Long actId);
/**
*
*
* @param amsActivity
* @return
*/
public List<ActivityListVO> selectAmsActivityList(ActivityListGetVO amsActivity);
/**
*
*
* @param amsActivity
* @return
*/
public int insertAmsActivity(AmsActivity amsActivity);
/**
*
*
* @param amsActivity
* @return
*/
public int updateAmsActivity(AmsActivity amsActivity);
/**
*
*
* @param actId
* @return
*/
public int deleteAmsActivityByActId(Long actId);
/**
*
*
* @param actIds
* @return
*/
public int deleteAmsActivityByActIds(Long[] actIds);
List<ActivityListVO> selectBannerActivities();
List<ActivityListVO> selectApprovedActivities();
List<HotClubVO> selectTopClubsByActivityCount(@Param("limit") int limit);
List<ActivityListVO> selectMyRegisteredActivities(@Param("userId") Long userId);
}

View File

@ -0,0 +1,70 @@
package com.ruoyi.sams.ams.mapper;
import java.util.List;
import com.ruoyi.sams.ams.domain.AmsComment;
import com.ruoyi.sams.ams.domain.vo.AmsCommentListVO;
import org.apache.ibatis.annotations.Param;
/**
* Mapper
*
* @author ruoyi
* @date 2025-05-06
*/
public interface AmsCommentMapper
{
/**
*
*
* @param commentId
* @return
*/
public AmsComment selectAmsCommentByCommentId(Long commentId);
/**
*
*
* @param amsComment
* @return
*/
public List<AmsCommentListVO> selectAmsCommentList(AmsCommentListVO amsComment);
/**
*
*
* @param amsComment
* @return
*/
public int insertAmsComment(AmsComment amsComment);
/**
*
*
* @param amsComment
* @return
*/
public int updateAmsComment(AmsComment amsComment);
/**
*
*
* @param commentId
* @return
*/
public int deleteAmsCommentByCommentId(Long commentId);
/**
*
*
* @param commentIds
* @return
*/
public int deleteAmsCommentByCommentIds(Long[] commentIds);
/**
*
* @param actId ID
* @return
*/
List<AmsComment> selectCommentListByActId(@Param("actId") Long actId);
}

View File

@ -0,0 +1,74 @@
package com.ruoyi.sams.ams.mapper;
import java.util.List;
import java.util.Map;
import com.ruoyi.sams.ams.domain.AmsReaction;
import com.ruoyi.sams.ams.domain.vo.AmsReactionVO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
/**
* Mapper
*
* @author ruoyi
* @date 2025-05-06
*/
@Mapper
public interface AmsReactionMapper
{
/**
*
*
* @param reactionId
* @return
*/
public AmsReaction selectAmsReactionByReactionId(Long reactionId);
/**
*
*
* @param amsReaction
* @return
*/
public List<AmsReactionVO> selectAmsReactionList(AmsReactionVO amsReaction);
/**
*
*
* @param amsReaction
* @return
*/
public int insertAmsReaction(AmsReaction amsReaction);
/**
*
*
* @param amsReaction
* @return
*/
public int updateAmsReaction(AmsReaction amsReaction);
/**
*
*
* @param reactionId
* @return
*/
public int deleteAmsReactionByReactionId(Long reactionId);
/**
*
*
* @param reactionIds
* @return
*/
public int deleteAmsReactionByReactionIds(Long[] reactionIds);
/**
* /
* @param actId ID
* @return
*/
List<Map<String, Object>> countReactionByType(@Param("actId") Long actId);
}

View File

@ -0,0 +1,61 @@
package com.ruoyi.sams.ams.mapper;
import java.util.List;
import com.ruoyi.sams.ams.domain.AmsRegistration;
/**
* Mapper
*
* @author ruoyi
* @date 2025-05-08
*/
public interface AmsRegistrationMapper
{
/**
*
*
* @param regId
* @return
*/
public AmsRegistration selectAmsRegistrationByRegId(Long regId);
/**
*
*
* @param amsRegistration
* @return
*/
public List<AmsRegistration> selectAmsRegistrationList(AmsRegistration amsRegistration);
/**
*
*
* @param amsRegistration
* @return
*/
public int insertAmsRegistration(AmsRegistration amsRegistration);
/**
*
*
* @param amsRegistration
* @return
*/
public int updateAmsRegistration(AmsRegistration amsRegistration);
/**
*
*
* @param regId
* @return
*/
public int deleteAmsRegistrationByRegId(Long regId);
/**
*
*
* @param regIds
* @return
*/
public int deleteAmsRegistrationByRegIds(Long[] regIds);
}

View File

@ -0,0 +1,84 @@
package com.ruoyi.sams.ams.service;
import java.util.List;
import com.ruoyi.sams.ams.domain.AmsActivity;
import com.ruoyi.sams.ams.domain.vo.ActivityListGetVO;
import com.ruoyi.sams.ams.domain.vo.ActivityListVO;
import com.ruoyi.sams.ui.domain.vo.ActivityQueryDTO;
import com.ruoyi.sams.ui.domain.vo.HotClubVO;
/**
* Service
*
* @author ruoyi
* @date 2025-05-06
*/
public interface IAmsActivityService
{
/**
*
*
* @param actId
* @return
*/
public ActivityListVO selectAmsActivityByActId(Long actId);
/**
*
*
* @param amsActivity
* @return
*/
public List<ActivityListVO> selectAmsActivityList(ActivityListGetVO amsActivity);
/**
*
*
* @param amsActivity
* @return
*/
public int insertAmsActivity(AmsActivity amsActivity);
/**
*
*
* @param amsActivity
* @return
*/
public int updateAmsActivity(AmsActivity amsActivity);
/**
*
*
* @param actIds
* @return
*/
public int deleteAmsActivityByActIds(Long[] actIds);
/**
*
*
* @param actId
* @return
*/
public int deleteAmsActivityByActId(Long actId);
/**
* 4
*/
List<ActivityListVO> listBannerActivities();
/**
*
*/
List<ActivityListVO> listApprovedActivities();
/**
* 4
*/
List<HotClubVO> listTop4ByActivityCount();
List<ActivityListVO> selectMyRegisteredActivities(Long userId);
}

View File

@ -0,0 +1,72 @@
package com.ruoyi.sams.ams.service;
import java.util.List;
import com.ruoyi.sams.ams.domain.AmsComment;
import com.ruoyi.sams.ams.domain.vo.AmsCommentListVO;
/**
* Service
*
* @author ruoyi
* @date 2025-05-06
*/
public interface IAmsCommentService
{
/**
*
*
* @param commentId
* @return
*/
public AmsComment selectAmsCommentByCommentId(Long commentId);
/**
*
*
* @param amsComment
* @return
*/
public List<AmsCommentListVO> selectAmsCommentList(AmsCommentListVO amsComment);
/**
*
*
* @param amsComment
* @return
*/
public int insertAmsComment(AmsComment amsComment);
/**
*
*
* @param amsComment
* @return
*/
public int updateAmsComment(AmsComment amsComment);
/**
*
*
* @param commentIds
* @return
*/
public int deleteAmsCommentByCommentIds(Long[] commentIds);
/**
*
*
* @param commentId
* @return
*/
public int deleteAmsCommentByCommentId(Long commentId);
/**
*
* @param actId ID
* @return
*/
List<AmsComment> selectCommentListByActId(Long actId);
}

View File

@ -0,0 +1,71 @@
package com.ruoyi.sams.ams.service;
import java.util.List;
import java.util.Map;
import com.ruoyi.sams.ams.domain.AmsReaction;
import com.ruoyi.sams.ams.domain.vo.AmsReactionVO;
/**
* Service
*
* @author ruoyi
* @date 2025-05-06
*/
public interface IAmsReactionService
{
/**
*
*
* @param reactionId
* @return
*/
public AmsReaction selectAmsReactionByReactionId(Long reactionId);
/**
*
*
* @param amsReaction
* @return
*/
public List<AmsReactionVO> selectAmsReactionList(AmsReactionVO amsReaction);
/**
*
*
* @param amsReaction
* @return
*/
public int insertAmsReaction(AmsReaction amsReaction);
/**
*
*
* @param amsReaction
* @return
*/
public int updateAmsReaction(AmsReaction amsReaction);
/**
*
*
* @param reactionIds
* @return
*/
public int deleteAmsReactionByReactionIds(Long[] reactionIds);
/**
*
*
* @param reactionId
* @return
*/
public int deleteAmsReactionByReactionId(Long reactionId);
/**
* like/dislike
* @param actId ID
* @return Map{"like": 12, "dislike": 3}
*/
Map<String, Integer> getReactionStats(Long actId);
}

View File

@ -0,0 +1,61 @@
package com.ruoyi.sams.ams.service;
import java.util.List;
import com.ruoyi.sams.ams.domain.AmsRegistration;
/**
* Service
*
* @author ruoyi
* @date 2025-05-08
*/
public interface IAmsRegistrationService
{
/**
*
*
* @param regId
* @return
*/
public AmsRegistration selectAmsRegistrationByRegId(Long regId);
/**
*
*
* @param amsRegistration
* @return
*/
public List<AmsRegistration> selectAmsRegistrationList(AmsRegistration amsRegistration);
/**
*
*
* @param amsRegistration
* @return
*/
public int insertAmsRegistration(AmsRegistration amsRegistration);
/**
*
*
* @param amsRegistration
* @return
*/
public int updateAmsRegistration(AmsRegistration amsRegistration);
/**
*
*
* @param regIds
* @return
*/
public int deleteAmsRegistrationByRegIds(Long[] regIds);
/**
*
*
* @param regId
* @return
*/
public int deleteAmsRegistrationByRegId(Long regId);
}

View File

@ -0,0 +1,126 @@
package com.ruoyi.sams.ams.service.impl;
import java.util.List;
import java.util.Map;
import com.ruoyi.sams.ams.domain.AmsActivity;
import com.ruoyi.sams.ams.domain.vo.ActivityListGetVO;
import com.ruoyi.sams.ams.domain.vo.ActivityListVO;
import com.ruoyi.sams.ams.mapper.AmsActivityMapper;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.sams.ui.domain.vo.ActivityQueryDTO;
import com.ruoyi.sams.ui.domain.vo.HotClubVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.sams.ams.service.IAmsActivityService;
/**
* Service
*
* @author ruoyi
* @date 2025-05-06
*/
@Service
public class AmsActivityServiceImpl implements IAmsActivityService
{
@Autowired
private AmsActivityMapper amsActivityMapper;
/**
*
*
* @param actId
* @return
*/
@Override
public ActivityListVO selectAmsActivityByActId(Long actId)
{
return amsActivityMapper.selectAmsActivityByActId(actId);
}
/**
*
*
* @param amsActivity
* @return
*/
@Override
public List<ActivityListVO> selectAmsActivityList(ActivityListGetVO amsActivity)
{
return amsActivityMapper.selectAmsActivityList(amsActivity);
}
/**
*
*
* @param amsActivity
* @return
*/
@Override
public int insertAmsActivity(AmsActivity amsActivity)
{
amsActivity.setCreateTime(DateUtils.getNowDate());
return amsActivityMapper.insertAmsActivity(amsActivity);
}
/**
*
*
* @param amsActivity
* @return
*/
@Override
public int updateAmsActivity(AmsActivity amsActivity)
{
amsActivity.setUpdateTime(DateUtils.getNowDate());
return amsActivityMapper.updateAmsActivity(amsActivity);
}
/**
*
*
* @param actIds
* @return
*/
@Override
public int deleteAmsActivityByActIds(Long[] actIds)
{
return amsActivityMapper.deleteAmsActivityByActIds(actIds);
}
/**
*
*
* @param actId
* @return
*/
@Override
public int deleteAmsActivityByActId(Long actId)
{
return amsActivityMapper.deleteAmsActivityByActId(actId);
}
@Override
public List<ActivityListVO> listBannerActivities() {
System.out.println(amsActivityMapper.selectBannerActivities());
return amsActivityMapper.selectBannerActivities();
}
@Override
public List<ActivityListVO> listApprovedActivities() {
System.out.println(amsActivityMapper.selectApprovedActivities());
return amsActivityMapper.selectApprovedActivities();
}
@Override
public List<HotClubVO> listTop4ByActivityCount() {
System.out.println(amsActivityMapper.selectTopClubsByActivityCount(4));
return amsActivityMapper.selectTopClubsByActivityCount(4);
}
@Override
public List<ActivityListVO> selectMyRegisteredActivities(Long userId ) {
return amsActivityMapper.selectMyRegisteredActivities(userId);
}
}

View File

@ -0,0 +1,103 @@
package com.ruoyi.sams.ams.service.impl;
import java.util.List;
import com.ruoyi.sams.ams.domain.AmsComment;
import com.ruoyi.sams.ams.domain.vo.AmsCommentListVO;
import com.ruoyi.sams.ams.mapper.AmsCommentMapper;
import com.ruoyi.common.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.sams.ams.service.IAmsCommentService;
/**
* Service
*
* @author ruoyi
* @date 2025-05-06
*/
@Service
public class AmsCommentServiceImpl implements IAmsCommentService
{
@Autowired
private AmsCommentMapper amsCommentMapper;
/**
*
*
* @param commentId
* @return
*/
@Override
public AmsComment selectAmsCommentByCommentId(Long commentId)
{
return amsCommentMapper.selectAmsCommentByCommentId(commentId);
}
/**
*
*
* @param amsComment
* @return
*/
@Override
public List<AmsCommentListVO> selectAmsCommentList(AmsCommentListVO amsComment)
{
return amsCommentMapper.selectAmsCommentList(amsComment);
}
/**
*
*
* @param amsComment
* @return
*/
@Override
public int insertAmsComment(AmsComment amsComment)
{
amsComment.setCreateTime(DateUtils.getNowDate());
return amsCommentMapper.insertAmsComment(amsComment);
}
/**
*
*
* @param amsComment
* @return
*/
@Override
public int updateAmsComment(AmsComment amsComment)
{
amsComment.setUpdateTime(DateUtils.getNowDate());
return amsCommentMapper.updateAmsComment(amsComment);
}
/**
*
*
* @param commentIds
* @return
*/
@Override
public int deleteAmsCommentByCommentIds(Long[] commentIds)
{
return amsCommentMapper.deleteAmsCommentByCommentIds(commentIds);
}
/**
*
*
* @param commentId
* @return
*/
@Override
public int deleteAmsCommentByCommentId(Long commentId)
{
return amsCommentMapper.deleteAmsCommentByCommentId(commentId);
}
@Override
public List<AmsComment> selectCommentListByActId(Long actId) {
return amsCommentMapper.selectCommentListByActId(actId);
}
}

View File

@ -0,0 +1,116 @@
package com.ruoyi.sams.ams.service.impl;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.ruoyi.sams.ams.domain.AmsReaction;
import com.ruoyi.sams.ams.mapper.AmsReactionMapper;
import com.ruoyi.sams.ams.domain.vo.AmsReactionVO;
import com.ruoyi.common.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.sams.ams.service.IAmsReactionService;
/**
* Service
*
* @author ruoyi
* @date 2025-05-06
*/
@Service
public class AmsReactionServiceImpl implements IAmsReactionService
{
@Autowired
private AmsReactionMapper amsReactionMapper;
/**
*
*
* @param reactionId
* @return
*/
@Override
public AmsReaction selectAmsReactionByReactionId(Long reactionId)
{
return amsReactionMapper.selectAmsReactionByReactionId(reactionId);
}
/**
*
*
* @param amsReaction
* @return
*/
@Override
public List<AmsReactionVO> selectAmsReactionList(AmsReactionVO amsReaction)
{
return amsReactionMapper.selectAmsReactionList(amsReaction);
}
/**
*
*
* @param amsReaction
* @return
*/
@Override
public int insertAmsReaction(AmsReaction amsReaction)
{
amsReaction.setCreateTime(DateUtils.getNowDate());
return amsReactionMapper.insertAmsReaction(amsReaction);
}
/**
*
*
* @param amsReaction
* @return
*/
@Override
public int updateAmsReaction(AmsReaction amsReaction)
{
amsReaction.setUpdateTime(DateUtils.getNowDate());
return amsReactionMapper.updateAmsReaction(amsReaction);
}
/**
*
*
* @param reactionIds
* @return
*/
@Override
public int deleteAmsReactionByReactionIds(Long[] reactionIds)
{
return amsReactionMapper.deleteAmsReactionByReactionIds(reactionIds);
}
/**
*
*
* @param reactionId
* @return
*/
@Override
public int deleteAmsReactionByReactionId(Long reactionId)
{
return amsReactionMapper.deleteAmsReactionByReactionId(reactionId);
}
@Override
public Map<String, Integer> getReactionStats(Long actId) {
List<Map<String, Object>> rawStats = amsReactionMapper.countReactionByType(actId);
Map<String, Integer> result = new HashMap<>();
result.put("like", 0);
result.put("dislike", 0);
for (Map<String, Object> row : rawStats) {
String type = (String) row.get("reaction_type");
Long count = (Long) row.get("cnt");
result.put(type, count.intValue());
}
return result;
}
}

View File

@ -0,0 +1,96 @@
package com.ruoyi.sams.ams.service.impl;
import java.util.List;
import com.ruoyi.common.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.sams.ams.mapper.AmsRegistrationMapper;
import com.ruoyi.sams.ams.domain.AmsRegistration;
import com.ruoyi.sams.ams.service.IAmsRegistrationService;
/**
* Service
*
* @author ruoyi
* @date 2025-05-08
*/
@Service
public class AmsRegistrationServiceImpl implements IAmsRegistrationService
{
@Autowired
private AmsRegistrationMapper amsRegistrationMapper;
/**
*
*
* @param regId
* @return
*/
@Override
public AmsRegistration selectAmsRegistrationByRegId(Long regId)
{
return amsRegistrationMapper.selectAmsRegistrationByRegId(regId);
}
/**
*
*
* @param amsRegistration
* @return
*/
@Override
public List<AmsRegistration> selectAmsRegistrationList(AmsRegistration amsRegistration)
{
return amsRegistrationMapper.selectAmsRegistrationList(amsRegistration);
}
/**
*
*
* @param amsRegistration
* @return
*/
@Override
public int insertAmsRegistration(AmsRegistration amsRegistration)
{
amsRegistration.setCreateTime(DateUtils.getNowDate());
return amsRegistrationMapper.insertAmsRegistration(amsRegistration);
}
/**
*
*
* @param amsRegistration
* @return
*/
@Override
public int updateAmsRegistration(AmsRegistration amsRegistration)
{
amsRegistration.setUpdateTime(DateUtils.getNowDate());
return amsRegistrationMapper.updateAmsRegistration(amsRegistration);
}
/**
*
*
* @param regIds
* @return
*/
@Override
public int deleteAmsRegistrationByRegIds(Long[] regIds)
{
return amsRegistrationMapper.deleteAmsRegistrationByRegIds(regIds);
}
/**
*
*
* @param regId
* @return
*/
@Override
public int deleteAmsRegistrationByRegId(Long regId)
{
return amsRegistrationMapper.deleteAmsRegistrationByRegId(regId);
}
}

View File

@ -0,0 +1,106 @@
package com.ruoyi.sams.sms.controller;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import com.ruoyi.sams.sms.domain.SmsClub;
import com.ruoyi.sams.sms.domain.vo.ClubReturnVO;
import com.ruoyi.sams.sms.service.ISmsClubService;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;
/**
* Controller
*
* @author ruoyi
* @date 2025-05-06
*/
@RestController
@RequestMapping("/sms/club")
public class SmsClubController extends BaseController
{
@Autowired
private ISmsClubService smsClubService;
/**
*
*/
@PreAuthorize("@ss.hasPermi('sms:club:list')")
@GetMapping("/list")
public TableDataInfo list(SmsClub smsClub)
{
startPage();
List<ClubReturnVO> list = smsClubService.selectSmsClubList(smsClub);
return getDataTable(list);
}
/**
*
*/
@PreAuthorize("@ss.hasPermi('sms:club:export')")
@Log(title = "社团信息", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, SmsClub smsClub)
{
List<ClubReturnVO> list = smsClubService.selectSmsClubList(smsClub);
ExcelUtil<ClubReturnVO> util = new ExcelUtil<>(ClubReturnVO.class);
util.exportExcel(response, list, "社团信息数据");
}
/**
*
*/
@PreAuthorize("@ss.hasPermi('sms:club:query')")
@GetMapping(value = "/{clubId}")
public AjaxResult getInfo(@PathVariable("clubId") Long clubId)
{
return success(smsClubService.selectSmsClubByClubId(clubId));
}
/**
*
*/
@PreAuthorize("@ss.hasPermi('sms:club:add')")
@Log(title = "社团信息", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody SmsClub smsClub)
{
return toAjax(smsClubService.insertSmsClub(smsClub));
}
/**
*
*/
@PreAuthorize("@ss.hasPermi('sms:club:edit')")
@Log(title = "社团信息", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody SmsClub smsClub)
{
return toAjax(smsClubService.updateSmsClub(smsClub));
}
/**
*
*/
@PreAuthorize("@ss.hasPermi('sms:club:remove')")
@Log(title = "社团信息", businessType = BusinessType.DELETE)
@DeleteMapping("/{clubIds}")
public AjaxResult remove(@PathVariable Long[] clubIds)
{
return toAjax(smsClubService.deleteSmsClubByClubIds(clubIds));
}
}

View File

@ -0,0 +1,107 @@
package com.ruoyi.sams.sms.controller;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import com.ruoyi.sams.sms.domain.SmsClubUser;
import com.ruoyi.sams.sms.domain.vo.ClubUserReturnVO;
import com.ruoyi.sams.sms.domain.vo.ClubUserSelectVO;
import com.ruoyi.sams.sms.service.ISmsClubUserService;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;
/**
* Controller
*
* @author ruoyi
* @date 2025-05-06
*/
@RestController
@RequestMapping("/sms/user")
public class SmsClubUserController extends BaseController
{
@Autowired
private ISmsClubUserService smsClubUserService;
/**
*
*/
@PreAuthorize("@ss.hasPermi('sms:user:list')")
@GetMapping("/list")
public TableDataInfo list(ClubUserSelectVO smsClubUser)
{
startPage();
List<ClubUserReturnVO> list = smsClubUserService.selectSmsClubUserList(smsClubUser);
return getDataTable(list);
}
/**
*
*/
@PreAuthorize("@ss.hasPermi('sms:user:export')")
@Log(title = "成员管理", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, ClubUserSelectVO smsClubUser)
{
List<ClubUserReturnVO> list = smsClubUserService.selectSmsClubUserList(smsClubUser);
ExcelUtil<ClubUserReturnVO> util = new ExcelUtil<ClubUserReturnVO>(ClubUserReturnVO.class);
util.exportExcel(response, list, "成员管理数据");
}
/**
*
*/
@PreAuthorize("@ss.hasPermi('sms:user:query')")
@GetMapping(value = "/{id}")
public AjaxResult getInfo(@PathVariable("id") Long id)
{
return success(smsClubUserService.selectSmsClubUserById(id));
}
/**
*
*/
@PreAuthorize("@ss.hasPermi('sms:user:add')")
@Log(title = "成员管理", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody SmsClubUser smsClubUser)
{
return toAjax(smsClubUserService.insertSmsClubUser(smsClubUser));
}
/**
*
*/
@PreAuthorize("@ss.hasPermi('sms:user:edit')")
@Log(title = "成员管理", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody SmsClubUser smsClubUser)
{
return toAjax(smsClubUserService.updateSmsClubUser(smsClubUser));
}
/**
*
*/
@PreAuthorize("@ss.hasPermi('sms:user:remove')")
@Log(title = "成员管理", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable Long[] ids)
{
return toAjax(smsClubUserService.deleteSmsClubUserByIds(ids));
}
}

View File

@ -0,0 +1,146 @@
package com.ruoyi.sams.sms.domain;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.core.domain.BaseEntity;
/**
* sms_club
*
* @author ruoyi
* @date 2025-05-06
*/
public class SmsClub extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 社团ID */
private Long clubId;
/** 社团名称 */
@Excel(name = "社团名称")
private String clubName;
/** 社团简介 */
private String description;
/** 社团类型 */
@Excel(name = "社团类型")
private String category;
/** 所属院系IDsys_dept */
@Excel(name = "所属院系ID", readConverterExp = "s=ys_dept")
private Long deptId;
/** 负责人IDsys_user */
@Excel(name = "负责人ID", readConverterExp = "s=ys_user")
private Long leaderId;
/** logo */
@Excel(name = "logo")
private String logo;
/** 状态 */
@Excel(name = "状态")
private String status;
public void setClubId(Long clubId)
{
this.clubId = clubId;
}
public Long getClubId()
{
return clubId;
}
public void setClubName(String clubName)
{
this.clubName = clubName;
}
public String getClubName()
{
return clubName;
}
public void setDescription(String description)
{
this.description = description;
}
public String getDescription()
{
return description;
}
public void setCategory(String category)
{
this.category = category;
}
public String getCategory()
{
return category;
}
public void setDeptId(Long deptId)
{
this.deptId = deptId;
}
public Long getDeptId()
{
return deptId;
}
public void setLeaderId(Long leaderId)
{
this.leaderId = leaderId;
}
public Long getLeaderId()
{
return leaderId;
}
public void setLogo(String logo)
{
this.logo = logo;
}
public String getLogo()
{
return logo;
}
public void setStatus(String status)
{
this.status = status;
}
public String getStatus()
{
return status;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("clubId", getClubId())
.append("clubName", getClubName())
.append("description", getDescription())
.append("category", getCategory())
.append("deptId", getDeptId())
.append("leaderId", getLeaderId())
.append("logo", getLogo())
.append("status", getStatus())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime())
.append("remark", getRemark())
.toString();
}
}

View File

@ -0,0 +1,105 @@
package com.ruoyi.sams.sms.domain;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.core.domain.BaseEntity;
/**
* sms_club_user
*
* @author ruoyi
* @date 2025-05-06
*/
public class SmsClubUser extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 主键ID */
private Long id;
/** 用户ID */
@Excel(name = "用户ID")
private Long userId;
/** 社团ID */
@Excel(name = "社团ID")
private Long clubId;
/** 是否活跃 */
@Excel(name = "是否活跃")
private Integer isActive;
/** 加入社团时间 */
@JsonFormat(pattern = "yyyy-MM-dd")
@Excel(name = "加入社团时间", width = 30, dateFormat = "yyyy-MM-dd")
private Date joinDate;
public void setId(Long id)
{
this.id = id;
}
public Long getId()
{
return id;
}
public void setUserId(Long userId)
{
this.userId = userId;
}
public Long getUserId()
{
return userId;
}
public void setClubId(Long clubId)
{
this.clubId = clubId;
}
public Long getClubId()
{
return clubId;
}
public void setIsActive(Integer isActive)
{
this.isActive = isActive;
}
public Integer getIsActive()
{
return isActive;
}
public void setJoinDate(Date joinDate)
{
this.joinDate = joinDate;
}
public Date getJoinDate()
{
return joinDate;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("id", getId())
.append("userId", getUserId())
.append("clubId", getClubId())
.append("isActive", getIsActive())
.append("joinDate", getJoinDate())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime())
.append("remark", getRemark())
.toString();
}
}

View File

@ -0,0 +1,141 @@
package com.ruoyi.sams.sms.domain.vo;
import java.io.Serializable;
public class ClubReturnVO implements Serializable {
private Long clubId;
private String clubName;
private String description;
private String category;
private Long deptId;
private String deptName; // 院系名称
private Long leaderId;
private String leaderName; // 负责人名称
private String logo;
private String status;
private String remark;
private String createBy;
private String updateBy;
private String createTime;
private String updateTime;
public Long getClubId() {
return clubId;
}
public void setClubId(Long clubId) {
this.clubId = clubId;
}
public String getClubName() {
return clubName;
}
public void setClubName(String clubName) {
this.clubName = clubName;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
public Long getDeptId() {
return deptId;
}
public void setDeptId(Long deptId) {
this.deptId = deptId;
}
public String getDeptName() {
return deptName;
}
public void setDeptName(String deptName) {
this.deptName = deptName;
}
public Long getLeaderId() {
return leaderId;
}
public void setLeaderId(Long leaderId) {
this.leaderId = leaderId;
}
public String getLeaderName() {
return leaderName;
}
public void setLeaderName(String leaderName) {
this.leaderName = leaderName;
}
public String getLogo() {
return logo;
}
public void setLogo(String logo) {
this.logo = logo;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
public String getCreateBy() {
return createBy;
}
public void setCreateBy(String createBy) {
this.createBy = createBy;
}
public String getUpdateBy() {
return updateBy;
}
public void setUpdateBy(String updateBy) {
this.updateBy = updateBy;
}
public String getCreateTime() {
return createTime;
}
public void setCreateTime(String createTime) {
this.createTime = createTime;
}
public String getUpdateTime() {
return updateTime;
}
public void setUpdateTime(String updateTime) {
this.updateTime = updateTime;
}
}

View File

@ -0,0 +1,71 @@
package com.ruoyi.sams.sms.domain.vo;
import com.ruoyi.common.core.domain.BaseEntity;
import java.time.LocalDateTime;
public class ClubUserReturnVO extends BaseEntity {
private Long id;
private Long userId;
private String userName;
private Long clubId;
private String clubName;
private Integer isActive;
private LocalDateTime joinDate;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public Long getClubId() {
return clubId;
}
public void setClubId(Long clubId) {
this.clubId = clubId;
}
public String getClubName() {
return clubName;
}
public void setClubName(String clubName) {
this.clubName = clubName;
}
public Integer getIsActive() {
return isActive;
}
public void setIsActive(Integer isActive) {
this.isActive = isActive;
}
public LocalDateTime getJoinDate() {
return joinDate;
}
public void setJoinDate(LocalDateTime joinDate) {
this.joinDate = joinDate;
}
}

View File

@ -0,0 +1,72 @@
package com.ruoyi.sams.sms.domain.vo;
/**
* VO
*/
public class ClubUserSelectVO {
/**
*
*/
private String userName;
/**
*
*/
private String clubName;
/**
*
*/
private Integer isActive;
/**
* ID
*/
private Long userId;
/**
* ID
*/
private Long clubId;
// ---------- Getters & Setters ----------
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getClubName() {
return clubName;
}
public void setClubName(String clubName) {
this.clubName = clubName;
}
public Integer getIsActive() {
return isActive;
}
public void setIsActive(Integer isActive) {
this.isActive = isActive;
}
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
public Long getClubId() {
return clubId;
}
public void setClubId(Long clubId) {
this.clubId = clubId;
}
}

View File

@ -0,0 +1,63 @@
package com.ruoyi.sams.sms.mapper;
import java.util.List;
import com.ruoyi.sams.sms.domain.SmsClub;
import com.ruoyi.sams.sms.domain.vo.ClubReturnVO;
/**
* Mapper
*
* @author ruoyi
* @date 2025-05-06
*/
public interface SmsClubMapper
{
/**
*
*
* @param clubId
* @return
*/
public ClubReturnVO selectSmsClubByClubId(Long clubId);
/**
*
*
* @param smsClub
* @return
*/
public List<ClubReturnVO> selectSmsClubList(SmsClub smsClub);
/**
*
*
* @param smsClub
* @return
*/
public int insertSmsClub(SmsClub smsClub);
/**
*
*
* @param smsClub
* @return
*/
public int updateSmsClub(SmsClub smsClub);
/**
*
*
* @param clubId
* @return
*/
public int deleteSmsClubByClubId(Long clubId);
/**
*
*
* @param clubIds
* @return
*/
public int deleteSmsClubByClubIds(Long[] clubIds);
}

View File

@ -0,0 +1,65 @@
package com.ruoyi.sams.sms.mapper;
import java.util.List;
import com.ruoyi.sams.sms.domain.vo.ClubUserReturnVO;
import com.ruoyi.sams.sms.domain.SmsClubUser;
import com.ruoyi.sams.sms.domain.vo.ClubUserSelectVO;
import org.apache.ibatis.annotations.Param;
/**
* Mapper
*
* @author ruoyi
* @date 2025-05-06
*/
public interface SmsClubUserMapper
{
/**
*
*
* @param id
* @return
*/
public ClubUserReturnVO selectSmsClubUserById(Long id);
/**
*
*
* @param smsClubUser
* @return
*/
public List<ClubUserReturnVO> selectSmsClubUserList(@Param("vo") ClubUserSelectVO smsClubUser);
/**
*
*
* @param smsClubUser
* @return
*/
public int insertSmsClubUser(SmsClubUser smsClubUser);
/**
*
*
* @param smsClubUser
* @return
*/
public int updateSmsClubUser(SmsClubUser smsClubUser);
/**
*
*
* @param id
* @return
*/
public int deleteSmsClubUserById(Long id);
/**
*
*
* @param ids
* @return
*/
public int deleteSmsClubUserByIds(Long[] ids);
}

View File

@ -0,0 +1,64 @@
package com.ruoyi.sams.sms.service;
import java.util.List;
import com.ruoyi.sams.sms.domain.SmsClub;
import com.ruoyi.sams.sms.domain.vo.ClubReturnVO;
import com.ruoyi.sams.ui.domain.vo.HotClubVO;
/**
* Service
*
* @author ruoyi
* @date 2025-05-06
*/
public interface ISmsClubService
{
/**
*
*
* @param clubId
* @return
*/
public ClubReturnVO selectSmsClubByClubId(Long clubId);
/**
*
*
* @param smsClub
* @return
*/
public List<ClubReturnVO> selectSmsClubList(SmsClub smsClub);
/**
*
*
* @param smsClub
* @return
*/
public int insertSmsClub(SmsClub smsClub);
/**
*
*
* @param smsClub
* @return
*/
public int updateSmsClub(SmsClub smsClub);
/**
*
*
* @param clubIds
* @return
*/
public int deleteSmsClubByClubIds(Long[] clubIds);
/**
*
*
* @param clubId
* @return
*/
public int deleteSmsClubByClubId(Long clubId);
}

View File

@ -0,0 +1,64 @@
package com.ruoyi.sams.sms.service;
import java.util.List;
import com.ruoyi.sams.sms.domain.vo.ClubUserReturnVO;
import com.ruoyi.sams.sms.domain.SmsClubUser;
import com.ruoyi.sams.sms.domain.vo.ClubUserSelectVO;
/**
* Service
*
* @author ruoyi
* @date 2025-05-06
*/
public interface ISmsClubUserService
{
/**
*
*
* @param id
* @return
*/
public ClubUserReturnVO selectSmsClubUserById(Long id);
/**
*
*
* @param smsClubUser
* @return
*/
public List<ClubUserReturnVO> selectSmsClubUserList(ClubUserSelectVO smsClubUser);
/**
*
*
* @param smsClubUser
* @return
*/
public int insertSmsClubUser(SmsClubUser smsClubUser);
/**
*
*
* @param smsClubUser
* @return
*/
public int updateSmsClubUser(SmsClubUser smsClubUser);
/**
*
*
* @param ids
* @return
*/
public int deleteSmsClubUserByIds(Long[] ids);
/**
*
*
* @param id
* @return
*/
public int deleteSmsClubUserById(Long id);
}

View File

@ -0,0 +1,99 @@
package com.ruoyi.sams.sms.service.impl;
import java.util.List;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.sams.sms.domain.SmsClub;
import com.ruoyi.sams.sms.domain.vo.ClubReturnVO;
import com.ruoyi.sams.sms.mapper.SmsClubMapper;
import com.ruoyi.sams.sms.service.ISmsClubService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* Service
*
* @author ruoyi
* @date 2025-05-06
*/
@Service
public class SmsClubServiceImpl implements ISmsClubService
{
@Autowired
private SmsClubMapper smsClubMapper;
/**
*
*
* @param clubId
* @return
*/
@Override
public ClubReturnVO selectSmsClubByClubId(Long clubId)
{
return smsClubMapper.selectSmsClubByClubId(clubId);
}
/**
*
*
* @param smsClub
* @return
*/
@Override
public List<ClubReturnVO> selectSmsClubList(SmsClub smsClub)
{
return smsClubMapper.selectSmsClubList(smsClub);
}
/**
*
*
* @param smsClub
* @return
*/
@Override
public int insertSmsClub(SmsClub smsClub)
{
smsClub.setCreateTime(DateUtils.getNowDate());
return smsClubMapper.insertSmsClub(smsClub);
}
/**
*
*
* @param smsClub
* @return
*/
@Override
public int updateSmsClub(SmsClub smsClub)
{
smsClub.setUpdateTime(DateUtils.getNowDate());
return smsClubMapper.updateSmsClub(smsClub);
}
/**
*
*
* @param clubIds
* @return
*/
@Override
public int deleteSmsClubByClubIds(Long[] clubIds)
{
return smsClubMapper.deleteSmsClubByClubIds(clubIds);
}
/**
*
*
* @param clubId
* @return
*/
@Override
public int deleteSmsClubByClubId(Long clubId)
{
return smsClubMapper.deleteSmsClubByClubId(clubId);
}
}

View File

@ -0,0 +1,98 @@
package com.ruoyi.sams.sms.service.impl;
import java.util.List;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.sams.sms.domain.SmsClubUser;
import com.ruoyi.sams.sms.domain.vo.ClubUserReturnVO;
import com.ruoyi.sams.sms.domain.vo.ClubUserSelectVO;
import com.ruoyi.sams.sms.mapper.SmsClubUserMapper;
import com.ruoyi.sams.sms.service.ISmsClubUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* Service
*
* @author ruoyi
* @date 2025-05-06
*/
@Service
public class SmsClubUserServiceImpl implements ISmsClubUserService
{
@Autowired
private SmsClubUserMapper smsClubUserMapper;
/**
*
*
* @param id
* @return
*/
@Override
public ClubUserReturnVO selectSmsClubUserById(Long id)
{
return smsClubUserMapper.selectSmsClubUserById(id);
}
/**
*
*
* @param smsClubUser
* @return
*/
@Override
public List<ClubUserReturnVO> selectSmsClubUserList(ClubUserSelectVO smsClubUser)
{
return smsClubUserMapper.selectSmsClubUserList(smsClubUser);
}
/**
*
*
* @param smsClubUser
* @return
*/
@Override
public int insertSmsClubUser(SmsClubUser smsClubUser)
{
smsClubUser.setCreateTime(DateUtils.getNowDate());
return smsClubUserMapper.insertSmsClubUser(smsClubUser);
}
/**
*
*
* @param smsClubUser
* @return
*/
@Override
public int updateSmsClubUser(SmsClubUser smsClubUser)
{
smsClubUser.setUpdateTime(DateUtils.getNowDate());
return smsClubUserMapper.updateSmsClubUser(smsClubUser);
}
/**
*
*
* @param ids
* @return
*/
@Override
public int deleteSmsClubUserByIds(Long[] ids)
{
return smsClubUserMapper.deleteSmsClubUserByIds(ids);
}
/**
*
*
* @param id
* @return
*/
@Override
public int deleteSmsClubUserById(Long id)
{
return smsClubUserMapper.deleteSmsClubUserById(id);
}
}

View File

@ -0,0 +1,61 @@
package com.ruoyi.sams.ui.controller;
import com.ruoyi.sams.ams.domain.vo.ActivityListGetVO;
import com.ruoyi.sams.ams.service.IAmsActivityService;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.sams.sms.domain.SmsClub;
import com.ruoyi.sams.sms.service.ISmsClubService;
import com.ruoyi.system.service.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.Map;
/**
*
*/
@RestController
@RequestMapping("/sams/dashboard")
public class DashboardController {
@Autowired
private IAmsActivityService activityService;
@Autowired
private ISmsClubService clubService;
@Autowired
private ISysUserService userService;
@GetMapping("/list")
public AjaxResult getDashboardStats() {
// 所有活动数量
int activityCount = activityService.selectAmsActivityList(new ActivityListGetVO()).size();
// 状态为待审批的活动数量
ActivityListGetVO pendingVO = new ActivityListGetVO();
pendingVO.setStatus("pending");
int pendingCount = activityService.selectAmsActivityList(pendingVO).size();
// 社团数量
int clubCount = clubService.selectSmsClubList(new SmsClub()).size();
// 用户数量
int userCount = userService.selectUserList(new SysUser()).size();
Map<String, Integer> data =new HashMap<>();
data.put("activityCount", activityCount);
data.put("pendingCount", pendingCount);
data.put("clubCount", clubCount);
data.put("userCount", userCount);
// 返回数据
AjaxResult result = AjaxResult.success();
result.put("data", data);
return result;
}
}

View File

@ -0,0 +1,86 @@
package com.ruoyi.sams.ui.controller;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.sams.ams.domain.AmsComment;
import com.ruoyi.sams.ams.domain.vo.ActivityListGetVO;
import com.ruoyi.sams.ams.domain.vo.ActivityListVO;
import com.ruoyi.sams.ams.service.IAmsActivityService;
import com.ruoyi.sams.ams.service.IAmsCommentService;
import com.ruoyi.sams.ams.service.IAmsReactionService;
import com.ruoyi.sams.ui.domain.vo.ActivityQueryDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
@RequestMapping("/front/activity")
public class FrontActivityController extends BaseController {
@Autowired
private IAmsActivityService activityService;
@Autowired
private IAmsReactionService reactionService;
@Autowired
private IAmsCommentService commentService;
/**
* 4
*/
@GetMapping("/banner")
public AjaxResult listBannerActivities() {
return AjaxResult.success(activityService.listBannerActivities());
}
/**
*
*/
@GetMapping("/list")
public AjaxResult listActivities() {
return AjaxResult.success(activityService.listApprovedActivities());
}
/**
* 4
*/
@GetMapping("/hot")
public AjaxResult listHotClubs() {
return AjaxResult.success(activityService.listTop4ByActivityCount());
}
/**
* /
*/
@GetMapping("/reaction")
public AjaxResult getReactionStats(Long actId) {
return AjaxResult.success(reactionService.getReactionStats(actId));
}
/**
*
*/
@GetMapping("/comment")
public TableDataInfo listComments(Long actId) {
startPage(); // 启用分页
List<AmsComment> list = commentService.selectCommentListByActId(actId);
return getDataTable(list);
}
/**
*
*/
@GetMapping("/my-regist")
public TableDataInfo listMyRegisteredActivities(Long userId) {
startPage();
List<ActivityListVO> list = activityService.selectMyRegisteredActivities(userId);
return getDataTable(list);
}
}

View File

@ -0,0 +1,18 @@
package com.ruoyi.sams.ui.controller;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.sams.sms.service.ISmsClubService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/front/club")
public class FrontClubController {
@Autowired
private ISmsClubService clubService;
}

View File

@ -0,0 +1,22 @@
package com.ruoyi.sams.ui.domain.vo;
public class ActivityQueryDTO {
private String title;
private Long clubId;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public Long getClubId() {
return clubId;
}
public void setClubId(Long clubId) {
this.clubId = clubId;
}
}

View File

@ -0,0 +1,49 @@
package com.ruoyi.sams.ui.domain.vo;
public class HotClubVO {
private Long clubId;
private String clubName;
private String logo;
private Integer activityCount;
public Long getClubId() {
return clubId;
}
public void setClubId(Long clubId) {
this.clubId = clubId;
}
public String getClubName() {
return clubName;
}
public void setClubName(String clubName) {
this.clubName = clubName;
}
public String getLogo() {
return logo;
}
public void setLogo(String logo) {
this.logo = logo;
}
public Integer getActivityCount() {
return activityCount;
}
public void setActivityCount(Integer activityCount) {
this.activityCount = activityCount;
}
@Override
public String toString() {
return "HotClubVO{" +
"clubId=" + clubId +
", clubName='" + clubName + '\'' +
", activityCount=" + activityCount +
'}';
}
}

View File

@ -0,0 +1,205 @@
<?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.sams.ams.mapper.AmsActivityMapper">
<resultMap id="ActivityListResult" type="com.ruoyi.sams.ams.domain.vo.ActivityListVO">
<id column="act_id" property="actId"/>
<result column="title" property="title"/>
<result column="description" property="description"/>
<result column="budget" property="budget"/>
<result column="cover_image" property="coverImage"/>
<result column="creator_id" property="creatorId"/>
<result column="creator_name" property="creatorName"/>
<result column="club_id" property="clubId"/>
<result column="club_name" property="clubName"/>
<result column="dept_id" property="deptId"/>
<result column="dept_name" property="deptName"/>
<result column="location" property="location"/>
<result column="activity_type" property="activityType"/>
<result column="status" property="status"/>
<result column="visibility" property="visibility"/>
<result column="start_time" property="startTime"/>
<result column="end_time" property="endTime"/>
<result column="remark" property="remark"/>
</resultMap>
<sql id="selectAmsActivityVo">
SELECT
a.act_id, a.title, a.description ,a.cover_image,
a.budget, a.creator_id, u.nick_name AS creator_name,
a.club_id, c.club_name, a.dept_id, d.dept_name,
a.location, a.activity_type, a.status, a.visibility,
a.start_time, a.end_time, a.remark
FROM ams_activity a
LEFT JOIN sys_user u ON a.creator_id = u.user_id
LEFT JOIN sms_club c ON a.club_id = c.club_id
LEFT JOIN sys_dept d ON a.dept_id = d.dept_id
</sql>
<select id="selectAmsActivityList" resultMap="ActivityListResult">
<if test="excludeOtherDraft != null and excludeOtherDraft">
AND (a.status != 'draft' OR a.creator_id = #{creatorId})
</if>
<include refid="selectAmsActivityVo"/>
WHERE 1 = 1
<if test="title != null and title != ''">
AND a.title LIKE CONCAT('%', #{title}, '%')
</if>
<if test="status != null and status != ''">
AND a.status = #{status}
</if>
<if test="clubId != null">
AND a.club_id = #{clubId}
</if>
ORDER BY a.create_time DESC
</select>
<select id="selectAmsActivityByActId" parameterType="Long" resultMap="ActivityListResult">
<include refid="selectAmsActivityVo"/>
where act_id = #{actId}
</select>
<insert id="insertAmsActivity" parameterType="AmsActivity" useGeneratedKeys="true" keyProperty="actId">
insert into ams_activity
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="title != null and title != ''">title,</if>
<if test="description != null">description,</if>
<if test="coverImage != null">cover_image,</if>
<if test="startTime != null">start_time,</if>
<if test="endTime != null">end_time,</if>
<if test="location != null">location,</if>
<if test="budget != null">budget,</if>
<if test="maxParticipants != null">max_participants,</if>
<if test="creatorId != null">creator_id,</if>
<if test="clubId != null">club_id,</if>
<if test="deptId != null">dept_id,</if>
<if test="activityType != null">activity_type,</if>
<if test="status != null">status,</if>
<if test="visibility != null">visibility,</if>
<if test="currentApproverId != null">current_approver_id,</if>
<if test="createBy != null">create_by,</if>
<if test="createTime != null">create_time,</if>
<if test="updateBy != null">update_by,</if>
<if test="updateTime != null">update_time,</if>
<if test="remark != null">remark,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="title != null and title != ''">#{title},</if>
<if test="description != null">#{description},</if>
<if test="coverImage != null">#{coverImage},</if>
<if test="startTime != null">#{startTime},</if>
<if test="endTime != null">#{endTime},</if>
<if test="location != null">#{location},</if>
<if test="budget != null">#{budget},</if>
<if test="maxParticipants != null">#{maxParticipants},</if>
<if test="creatorId != null">#{creatorId},</if>
<if test="clubId != null">#{clubId},</if>
<if test="deptId != null">#{deptId},</if>
<if test="activityType != null">#{activityType},</if>
<if test="status != null">#{status},</if>
<if test="visibility != null">#{visibility},</if>
<if test="currentApproverId != null">#{currentApproverId},</if>
<if test="createBy != null">#{createBy},</if>
<if test="createTime != null">#{createTime},</if>
<if test="updateBy != null">#{updateBy},</if>
<if test="updateTime != null">#{updateTime},</if>
<if test="remark != null">#{remark},</if>
</trim>
</insert>
<update id="updateAmsActivity" parameterType="AmsActivity">
update ams_activity
<trim prefix="SET" suffixOverrides=",">
<if test="title != null and title != ''">title = #{title},</if>
<if test="description != null">description = #{description},</if>
<if test="coverImage != null">cover_image = #{coverImage},</if>
<if test="startTime != null">start_time = #{startTime},</if>
<if test="endTime != null">end_time = #{endTime},</if>
<if test="location != null">location = #{location},</if>
<if test="budget != null">budget = #{budget},</if>
<if test="maxParticipants != null">max_participants = #{maxParticipants},</if>
<if test="creatorId != null">creator_id = #{creatorId},</if>
<if test="clubId != null">club_id = #{clubId},</if>
<if test="deptId != null">dept_id = #{deptId},</if>
<if test="activityType != null">activity_type = #{activityType},</if>
<if test="status != null">status = #{status},</if>
<if test="visibility != null">visibility = #{visibility},</if>
<if test="currentApproverId != null">current_approver_id = #{currentApproverId},</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>
<if test="updateTime != null">update_time = #{updateTime},</if>
<if test="remark != null">remark = #{remark},</if>
</trim>
where act_id = #{actId}
</update>
<delete id="deleteAmsActivityByActId" parameterType="Long">
delete from ams_activity where act_id = #{actId}
</delete>
<delete id="deleteAmsActivityByActIds" parameterType="String">
delete from ams_activity where act_id in
<foreach item="actId" collection="array" open="(" separator="," close=")">
#{actId}
</foreach>
</delete>
<!-- 获取轮播图活动最多4条 -->
<select id="selectBannerActivities" resultMap="ActivityListResult">
SELECT * FROM ams_activity
WHERE status = 'approved'
ORDER BY start_time DESC
LIMIT 4
</select>
<!-- 分页+条件筛选:活动列表(已审批通过) -->
<select id="selectApprovedActivities" resultMap="ActivityListResult">
SELECT * FROM ams_activity
WHERE status = 'approved'
ORDER BY start_time ASC
LIMIT 8
</select>
<resultMap id="HotClubVOMap" type="com.ruoyi.sams.ui.domain.vo.HotClubVO">
<result column="club_id" property="clubId"/>
<result column="club_name" property="clubName"/>
<result column="logo" property="logo"/>
<result column="activityCount" property="activityCount"/>
</resultMap>
<!-- 活动最多的前4个社团 -->
<select id="selectTopClubsByActivityCount" resultMap="HotClubVOMap">
SELECT c.club_id, c.club_name, c.logo , COUNT(a.act_id) AS activityCount
FROM sms_club c
JOIN ams_activity a ON c.club_id = a.club_id
WHERE a.status = 'approved'
GROUP BY c.club_id, c.club_name
ORDER BY activityCount DESC
LIMIT #{limit}
</select>
<select id="selectMyRegisteredActivities"
resultMap="ActivityListResult"
parameterType="java.lang.Long">
SELECT
a.act_id, a.title, a.description ,a.cover_image,
a.budget, a.creator_id, u.nick_name AS creator_name,
a.club_id, c.club_name, a.dept_id, d.dept_name,
a.location, a.activity_type, a.status, a.visibility,
a.start_time, a.end_time, a.remark
FROM ams_activity a
INNER JOIN ams_registration r ON a.act_id = r.act_id
LEFT JOIN sys_user u ON a.creator_id = u.user_id
LEFT JOIN sms_club c ON a.club_id = c.club_id
LEFT JOIN sys_dept d ON a.dept_id = d.dept_id
WHERE r.user_id = #{userId}
AND a.status = 'approved'
ORDER BY a.start_time ASC
</select>
</mapper>

View File

@ -0,0 +1,124 @@
<?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.sams.ams.mapper.AmsCommentMapper">
<resultMap id="AmsCommentListVOResult" type="com.ruoyi.sams.ams.domain.vo.AmsCommentListVO">
<result property="commentId" column="comment_id"/>
<result property="actId" column="act_id"/>
<result property="activityName" column="title"/>
<result property="userId" column="user_id"/>
<result property="userName" column="user_name"/>
<result property="parentCommentId" column="parent_comment_id"/>
<result property="content" column="content"/>
<result property="remark" column="remark"/>
<result property="createTime" column="create_time"/>
</resultMap>
<sql id="selectAmsCommentVo">
SELECT c.comment_id,
c.act_id,
a.title,
c.user_id,
u.user_name,
c.parent_comment_id,
c.content,
c.remark,
c.create_time
FROM ams_comment c
LEFT JOIN ams_activity a ON c.act_id = a.act_id
LEFT JOIN sys_user u ON c.user_id = u.user_id
</sql>
<select id="selectAmsCommentList" parameterType="com.ruoyi.sams.ams.domain.AmsComment"
resultMap="AmsCommentListVOResult">
<include refid="selectAmsCommentVo"/>
WHERE 1=1
<if test="activityName != null and activityName != ''">
AND a.title LIKE CONCAT('%', #{activityName}, '%')
</if>
<if test="userName != null and userName != ''">
AND u.user_name LIKE CONCAT('%', #{userName}, '%')
</if>
ORDER BY c.create_time DESC
</select>
<select id="selectAmsCommentByCommentId" parameterType="Long" resultMap="AmsCommentListVOResult">
<include refid="selectAmsCommentVo"/>
where comment_id = #{commentId}
</select>
<insert id="insertAmsComment" parameterType="AmsComment" useGeneratedKeys="true" keyProperty="commentId">
insert into ams_comment
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="actId != null">act_id,</if>
<if test="userId != null">user_id,</if>
<if test="parentCommentId != null">parent_comment_id,</if>
<if test="content != null and content != ''">content,</if>
<if test="createBy != null">create_by,</if>
<if test="createTime != null">create_time,</if>
<if test="updateBy != null">update_by,</if>
<if test="updateTime != null">update_time,</if>
<if test="remark != null">remark,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="actId != null">#{actId},</if>
<if test="userId != null">#{userId},</if>
<if test="parentCommentId != null">#{parentCommentId},</if>
<if test="content != null and content != ''">#{content},</if>
<if test="createBy != null">#{createBy},</if>
<if test="createTime != null">#{createTime},</if>
<if test="updateBy != null">#{updateBy},</if>
<if test="updateTime != null">#{updateTime},</if>
<if test="remark != null">#{remark},</if>
</trim>
</insert>
<update id="updateAmsComment" parameterType="AmsComment">
update ams_comment
<trim prefix="SET" suffixOverrides=",">
<if test="actId != null">act_id = #{actId},</if>
<if test="userId != null">user_id = #{userId},</if>
<if test="parentCommentId != null">parent_comment_id = #{parentCommentId},</if>
<if test="content != null and content != ''">content = #{content},</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>
<if test="updateTime != null">update_time = #{updateTime},</if>
<if test="remark != null">remark = #{remark},</if>
</trim>
where comment_id = #{commentId}
</update>
<delete id="deleteAmsCommentByCommentId" parameterType="Long">
delete
from ams_comment
where comment_id = #{commentId}
</delete>
<delete id="deleteAmsCommentByCommentIds" parameterType="String">
delete from ams_comment where comment_id in
<foreach item="commentId" collection="array" open="(" separator="," close=")">
#{commentId}
</foreach>
</delete>
<select id="selectCommentListByActId" resultType="com.ruoyi.sams.ams.domain.AmsComment">
SELECT c.comment_id AS commentId,
c.act_id AS actId,
c.user_id AS userId,
c.content AS content,
c.parent_comment_id AS parentCommentId,
c.create_by AS createBy,
c.create_time AS createTime,
c.update_by AS updateBy,
c.update_time AS updateTime,
c.remark AS remark
FROM ams_comment c
WHERE c.act_id = #{actId}
ORDER BY c.create_time ASC
</select>
</mapper>

View File

@ -0,0 +1,105 @@
<?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.sams.ams.mapper.AmsReactionMapper">
<resultMap id="AmsReactionVOResult" type="com.ruoyi.sams.ams.domain.vo.AmsReactionVO">
<id property="reactionId" column="reaction_id" />
<result property="actId" column="act_id"/>
<result property="actTitle" column="title"/>
<result property="userId" column="user_id"/>
<result property="userName" column="user_name"/>
<result property="reactionType" column="reaction_type"/>
<result property="remark" column="remark"/>
<result property="createTime" column="created_at"/>
</resultMap>
<sql id="selectAmsReactionJoinVo">
SELECT
r.reaction_id,
r.act_id,
a.title,
r.user_id,
u.user_name,
r.reaction_type,
r.remark,
r.create_time
FROM ams_reaction r
LEFT JOIN ams_activity a ON r.act_id = a.act_id
LEFT JOIN sys_user u ON r.user_id = u.user_id
</sql>
<select id="selectAmsReactionList" resultMap="AmsReactionVOResult" parameterType="AmsReaction">
<include refid="selectAmsReactionJoinVo"/>
<where>
<if test="actId != null">AND r.act_id = #{actId}</if>
<if test="userId != null">AND r.user_id = #{userId}</if>
<if test="reactionType != null and reactionType != ''">AND r.reaction_type = #{reactionType}</if>
</where>
ORDER BY r.create_time DESC
</select>
<select id="selectAmsReactionByReactionId" resultMap="AmsReactionVOResult" parameterType="Long">
<include refid="selectAmsReactionJoinVo"/>
WHERE r.reaction_id = #{reactionId}
</select>
<insert id="insertAmsReaction" parameterType="AmsReaction" useGeneratedKeys="true" keyProperty="reactionId">
insert into ams_reaction
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="actId != null">act_id,</if>
<if test="userId != null">user_id,</if>
<if test="reactionType != null and reactionType != ''">reaction_type,</if>
<if test="createBy != null">create_by,</if>
<if test="createTime != null">create_time,</if>
<if test="updateBy != null">update_by,</if>
<if test="updateTime != null">update_time,</if>
<if test="remark != null">remark,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="actId != null">#{actId},</if>
<if test="userId != null">#{userId},</if>
<if test="reactionType != null and reactionType != ''">#{reactionType},</if>
<if test="createBy != null">#{createBy},</if>
<if test="createTime != null">#{createTime},</if>
<if test="updateBy != null">#{updateBy},</if>
<if test="updateTime != null">#{updateTime},</if>
<if test="remark != null">#{remark},</if>
</trim>
</insert>
<update id="updateAmsReaction" parameterType="AmsReaction">
update ams_reaction
<trim prefix="SET" suffixOverrides=",">
<if test="actId != null">act_id = #{actId},</if>
<if test="userId != null">user_id = #{userId},</if>
<if test="reactionType != null and reactionType != ''">reaction_type = #{reactionType},</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>
<if test="updateTime != null">update_time = #{updateTime},</if>
<if test="remark != null">remark = #{remark},</if>
</trim>
where reaction_id = #{reactionId}
</update>
<delete id="deleteAmsReactionByReactionId" parameterType="Long">
delete from ams_reaction where reaction_id = #{reactionId}
</delete>
<delete id="deleteAmsReactionByReactionIds" parameterType="String">
delete from ams_reaction where reaction_id in
<foreach item="reactionId" collection="array" open="(" separator="," close=")">
#{reactionId}
</foreach>
</delete>
<select id="countReactionByType" parameterType="long" resultType="map">
SELECT reaction_type, COUNT(*) AS cnt
FROM ams_reaction
WHERE act_id = #{actId}
GROUP BY reaction_type
</select>
</mapper>

View File

@ -0,0 +1,98 @@
<?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.sams.ams.mapper.AmsRegistrationMapper">
<resultMap type="AmsRegistration" id="AmsRegistrationResult">
<result property="regId" column="reg_id" />
<result property="actId" column="act_id" />
<result property="userId" column="user_id" />
<result property="role" column="role" />
<result property="status" column="status" />
<result property="registerTime" column="register_time" />
<result property="attendTime" column="attend_time" />
<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="selectAmsRegistrationVo">
select reg_id, act_id, user_id, role, status, register_time, attend_time, create_by, create_time, update_by, update_time, remark from ams_registration
</sql>
<select id="selectAmsRegistrationList" parameterType="AmsRegistration" resultMap="AmsRegistrationResult">
<include refid="selectAmsRegistrationVo"/>
<where>
<if test="actId != null "> and act_id = #{actId}</if>
<if test="userId != null "> and user_id = #{userId}</if>
<if test="role != null and role != ''"> and role = #{role}</if>
</where>
</select>
<select id="selectAmsRegistrationByRegId" parameterType="Long" resultMap="AmsRegistrationResult">
<include refid="selectAmsRegistrationVo"/>
where reg_id = #{regId}
</select>
<insert id="insertAmsRegistration" parameterType="AmsRegistration" useGeneratedKeys="true" keyProperty="regId">
insert into ams_registration
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="actId != null">act_id,</if>
<if test="userId != null">user_id,</if>
<if test="role != null">role,</if>
<if test="status != null">status,</if>
<if test="registerTime != null">register_time,</if>
<if test="attendTime != null">attend_time,</if>
<if test="createBy != null">create_by,</if>
<if test="createTime != null">create_time,</if>
<if test="updateBy != null">update_by,</if>
<if test="updateTime != null">update_time,</if>
<if test="remark != null">remark,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="actId != null">#{actId},</if>
<if test="userId != null">#{userId},</if>
<if test="role != null">#{role},</if>
<if test="status != null">#{status},</if>
<if test="registerTime != null">#{registerTime},</if>
<if test="attendTime != null">#{attendTime},</if>
<if test="createBy != null">#{createBy},</if>
<if test="createTime != null">#{createTime},</if>
<if test="updateBy != null">#{updateBy},</if>
<if test="updateTime != null">#{updateTime},</if>
<if test="remark != null">#{remark},</if>
</trim>
</insert>
<update id="updateAmsRegistration" parameterType="AmsRegistration">
update ams_registration
<trim prefix="SET" suffixOverrides=",">
<if test="actId != null">act_id = #{actId},</if>
<if test="userId != null">user_id = #{userId},</if>
<if test="role != null">role = #{role},</if>
<if test="status != null">status = #{status},</if>
<if test="registerTime != null">register_time = #{registerTime},</if>
<if test="attendTime != null">attend_time = #{attendTime},</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>
<if test="updateTime != null">update_time = #{updateTime},</if>
<if test="remark != null">remark = #{remark},</if>
</trim>
where reg_id = #{regId}
</update>
<delete id="deleteAmsRegistrationByRegId" parameterType="Long">
delete from ams_registration where reg_id = #{regId}
</delete>
<delete id="deleteAmsRegistrationByRegIds" parameterType="String">
delete from ams_registration where reg_id in
<foreach item="regId" collection="array" open="(" separator="," close=")">
#{regId}
</foreach>
</delete>
</mapper>

View File

@ -0,0 +1,128 @@
<?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.sams.sms.mapper.SmsClubMapper">
<resultMap id="ClubReturnVOResult" type="com.ruoyi.sams.sms.domain.vo.ClubReturnVO">
<result column="club_id" property="clubId" />
<result column="club_name" property="clubName" />
<result column="description" property="description" />
<result column="category" property="category" />
<result column="dept_id" property="deptId" />
<result column="dept_name" property="deptName" />
<result column="leader_id" property="leaderId" />
<result column="leader_name" property="leaderName" />
<result column="logo" property="logo" />
<result column="status" property="status" />
<result column="remark" property="remark" />
<result column="create_by" property="createBy" />
<result column="update_by" property="updateBy" />
<result column="create_time" property="createTime" />
<result column="update_time" property="updateTime" />
</resultMap>
<sql id="selectSmsClubVO">
SELECT
c.club_id,
c.club_name,
c.description,
c.category,
c.dept_id,
d.dept_name,
c.leader_id,
u.nick_name AS leader_name,
c.logo,
c.status,
c.remark,
c.create_by,
c.update_by,
c.create_time,
c.update_time
FROM sms_club c
LEFT JOIN sys_dept d ON c.dept_id = d.dept_id
LEFT JOIN sys_user u ON c.leader_id = u.user_id
</sql>
<select id="selectSmsClubList" parameterType="com.ruoyi.sams.sms.domain.SmsClub" resultMap="ClubReturnVOResult">
<include refid="selectSmsClubVO"/>
<where>
<if test="clubName != null and clubName != ''">
AND c.club_name LIKE CONCAT('%', #{clubName}, '%')
</if>
<if test="category != null and category != ''">
AND c.category = #{category}
</if>
<if test="deptId != null">
AND c.dept_id = #{deptId}
</if>
</where>
</select>
<select id="selectSmsClubByClubId" parameterType="Long" resultMap="ClubReturnVOResult">
<include refid="selectSmsClubVO"/>
where club_id = #{clubId}
</select>
<insert id="insertSmsClub" parameterType="SmsClub" useGeneratedKeys="true" keyProperty="clubId">
insert into sms_club
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="clubName != null and clubName != ''">club_name,</if>
<if test="description != null">description,</if>
<if test="category != null and category != ''">category,</if>
<if test="deptId != null">dept_id,</if>
<if test="leaderId != null">leader_id,</if>
<if test="logo != null">logo,</if>
<if test="status != null">status,</if>
<if test="createBy != null">create_by,</if>
<if test="createTime != null">create_time,</if>
<if test="updateBy != null">update_by,</if>
<if test="updateTime != null">update_time,</if>
<if test="remark != null">remark,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="clubName != null and clubName != ''">#{clubName},</if>
<if test="description != null">#{description},</if>
<if test="category != null and category != ''">#{category},</if>
<if test="deptId != null">#{deptId},</if>
<if test="leaderId != null">#{leaderId},</if>
<if test="logo != null">#{logo},</if>
<if test="status != null">#{status},</if>
<if test="createBy != null">#{createBy},</if>
<if test="createTime != null">#{createTime},</if>
<if test="updateBy != null">#{updateBy},</if>
<if test="updateTime != null">#{updateTime},</if>
<if test="remark != null">#{remark},</if>
</trim>
</insert>
<update id="updateSmsClub" parameterType="SmsClub">
update sms_club
<trim prefix="SET" suffixOverrides=",">
<if test="clubName != null and clubName != ''">club_name = #{clubName},</if>
<if test="description != null">description = #{description},</if>
<if test="category != null and category != ''">category = #{category},</if>
<if test="deptId != null">dept_id = #{deptId},</if>
<if test="leaderId != null">leader_id = #{leaderId},</if>
<if test="logo != null">logo = #{logo},</if>
<if test="status != null">status = #{status},</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>
<if test="updateTime != null">update_time = #{updateTime},</if>
<if test="remark != null">remark = #{remark},</if>
</trim>
where club_id = #{clubId}
</update>
<delete id="deleteSmsClubByClubId" parameterType="Long">
delete from sms_club where club_id = #{clubId}
</delete>
<delete id="deleteSmsClubByClubIds" parameterType="String">
delete from sms_club where club_id in
<foreach item="clubId" collection="array" open="(" separator="," close=")">
#{clubId}
</foreach>
</delete>
</mapper>

View File

@ -0,0 +1,119 @@
<?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.sams.sms.mapper.SmsClubUserMapper">
<resultMap type="com.ruoyi.sams.sms.domain.vo.ClubUserReturnVO" id="SmsClubUserResult">
<result property="id" column="id"/>
<result property="userId" column="user_id"/>
<result property="clubId" column="club_id"/>
<result property="userName" column="user_name"/>
<result property="clubName" column="club_name"/>
<result property="isActive" column="is_active"/>
<result property="joinDate" column="join_date"/>
<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="selectSmsClubUserVo">
SELECT
scu.id,
scu.user_id,
scu.club_id,
u.nick_name AS user_name,
c.club_name,
scu.is_active,
scu.join_date,
scu.create_by,
scu.create_time,
scu.update_by,
scu.update_time,
scu.remark
FROM sms_club_user scu
LEFT JOIN sys_user u ON scu.user_id = u.user_id
LEFT JOIN sms_club c ON scu.club_id = c.club_id
</sql>
<select id="selectSmsClubUserList" parameterType="com.ruoyi.sams.sms.domain.vo.ClubUserSelectVO" resultMap="SmsClubUserResult">
<include refid="selectSmsClubUserVo"/>
<where>
<if test="vo.userName != null and vo.userName != ''">
AND u.nick_name LIKE CONCAT('%', #{vo.userName}, '%')
</if>
<if test="vo.clubName != null and vo.clubName != ''">
AND c.club_name LIKE CONCAT('%', #{vo.clubName}, '%')
</if>
<if test="vo.isActive != null">
AND scu.is_active = #{vo.isActive}
</if>
<if test="vo.userId != null">
AND scu.user_id = #{vo.userId}
</if>
<if test="vo.clubId != null">
AND scu.club_id = #{vo.clubId}
</if>
</where>
</select>
<select id="selectSmsClubUserById" parameterType="Long" resultMap="SmsClubUserResult">
<include refid="selectSmsClubUserVo"/>
where id = #{id}
</select>
<insert id="insertSmsClubUser" parameterType="SmsClubUser" useGeneratedKeys="true" keyProperty="id">
insert into sms_club_user
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="userId != null">user_id,</if>
<if test="clubId != null">club_id,</if>
<if test="isActive != null">is_active,</if>
<if test="joinDate != null">join_date,</if>
<if test="createBy != null">create_by,</if>
<if test="createTime != null">create_time,</if>
<if test="updateBy != null">update_by,</if>
<if test="updateTime != null">update_time,</if>
<if test="remark != null">remark,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="userId != null">#{userId},</if>
<if test="clubId != null">#{clubId},</if>
<if test="isActive != null">#{isActive},</if>
<if test="joinDate != null">#{joinDate},</if>
<if test="createBy != null">#{createBy},</if>
<if test="createTime != null">#{createTime},</if>
<if test="updateBy != null">#{updateBy},</if>
<if test="updateTime != null">#{updateTime},</if>
<if test="remark != null">#{remark},</if>
</trim>
</insert>
<update id="updateSmsClubUser" parameterType="SmsClubUser">
update sms_club_user
<trim prefix="SET" suffixOverrides=",">
<if test="userId != null">user_id = #{userId},</if>
<if test="clubId != null">club_id = #{clubId},</if>
<if test="isActive != null">is_active = #{isActive},</if>
<if test="joinDate != null">join_date = #{joinDate},</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>
<if test="updateTime != null">update_time = #{updateTime},</if>
<if test="remark != null">remark = #{remark},</if>
</trim>
where id = #{id}
</update>
<delete id="deleteSmsClubUserById" parameterType="Long">
delete from sms_club_user where id = #{id}
</delete>
<delete id="deleteSmsClubUserByIds" parameterType="String">
delete from sms_club_user where id in
<foreach item="id" collection="array" open="(" separator="," close=")">
#{id}
</foreach>
</delete>
</mapper>

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

View File

@ -0,0 +1,31 @@
@startuml
start
:发起活动申请;
:选择活动类型(社团/院级/校级);
:提交活动信息;
if (是否为社团内部活动?) then (是)
:社团管理员审批;
if (审批通过?) then (是)
:活动发布;
else (否)
:退回修改;
endif
else (否)
:社团管理员初审;
if (初审通过?) then (是)
:提交至对应上级审批;
:院级/校级管理员终审;
if (终审通过?) then (是)
:活动发布;
else (否)
:退回修改;
endif
else (否)
:退回修改;
endif
endif
stop
@enduml

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

View File

@ -0,0 +1,22 @@
@startuml
left to right direction
actor 系统管理员
usecase "用户管理" as UC1
usecase "社团管理" as UC2
usecase "成员管理" as UC3
usecase "活动管理" as UC4
usecase "审批管理" as UC5
usecase "统计总览" as UC6
usecase "账户管理" as UC7
系统管理员 --> UC1
系统管理员 --> UC2
系统管理员 --> UC3
系统管理员 --> UC4
系统管理员 --> UC5
系统管理员 --> UC6
系统管理员 --> UC7
@enduml

Binary file not shown.

After

Width:  |  Height:  |  Size: 207 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 438 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 362 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 274 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 613 KiB

BIN
pic/登录@1x.jpg 100644

Binary file not shown.

After

Width:  |  Height:  |  Size: 334 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 176 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 188 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 213 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 212 KiB

13
pom.xml
View File

@ -218,6 +218,18 @@
<version>${ruoyi.version}</version> <version>${ruoyi.version}</version>
</dependency> </dependency>
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>bs-sms</artifactId>
<version>${ruoyi.version}</version>
</dependency>
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>bs-sams</artifactId>
<version>${ruoyi.version}</version>
</dependency>
</dependencies> </dependencies>
</dependencyManagement> </dependencyManagement>
@ -228,6 +240,7 @@
<module>ruoyi-quartz</module> <module>ruoyi-quartz</module>
<module>ruoyi-generator</module> <module>ruoyi-generator</module>
<module>ruoyi-common</module> <module>ruoyi-common</module>
<module>bs-sams</module>
</modules> </modules>
<packaging>pom</packaging> <packaging>pom</packaging>

View File

@ -61,6 +61,13 @@
<artifactId>ruoyi-generator</artifactId> <artifactId>ruoyi-generator</artifactId>
</dependency> </dependency>
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>bs-sams</artifactId>
<version>3.8.9</version>
<scope>compile</scope>
</dependency>
</dependencies> </dependencies>
<build> <build>

View File

@ -6,9 +6,9 @@ spring:
druid: druid:
# 主库数据源 # 主库数据源
master: master:
url: jdbc:mysql://localhost:3306/ry-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 url: jdbc:mysql://localhost:3306/SAMS-R?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
username: root username: root
password: password password: admin123
# 从库数据源 # 从库数据源
slave: slave:
# 从数据源开关/默认关闭 # 从数据源开关/默认关闭

View File

@ -105,7 +105,6 @@ mybatis:
mapperLocations: classpath*:mapper/**/*Mapper.xml mapperLocations: classpath*:mapper/**/*Mapper.xml
# 加载全局的配置文件 # 加载全局的配置文件
configLocation: classpath:mybatis/mybatis-config.xml configLocation: classpath:mybatis/mybatis-config.xml
# PageHelper分页插件 # PageHelper分页插件
pagehelper: pagehelper:
helperDialect: mysql helperDialect: mysql

View File

@ -1894,4 +1894,5 @@ public class ExcelUtil<T>
} }
return method; return method;
} }
} }

View File

@ -0,0 +1,46 @@
import request from '@/utils/request'
// 查询活动列表列表
export function listActivity(query) {
return request({
url: '/ams/activity/list',
method: 'get',
params: query
})
}
// 查询活动列表详细
export function getActivity(actId) {
return request({
url: '/ams/activity/' + actId,
method: 'get'
})
}
// 新增活动列表
export function addActivity(data) {
return request({
url: '/ams/activity',
method: 'post',
data: data
})
}
// 修改活动列表
export function updateActivity(data) {
return request({
url: '/ams/activity',
method: 'put',
data: data
})
}
// 删除活动列表
export function delActivity(actId) {
return request({
url: '/ams/activity/' + actId,
method: 'delete'
})
}

View File

@ -0,0 +1,44 @@
import request from '@/utils/request'
// 查询活动评论列表
export function listComment(query) {
return request({
url: '/ams/comment/list',
method: 'get',
params: query
})
}
// 查询活动评论详细
export function getComment(commentId) {
return request({
url: '/ams/comment/' + commentId,
method: 'get'
})
}
// 新增活动评论
export function addComment(data) {
return request({
url: '/ams/comment',
method: 'post',
data: data
})
}
// 修改活动评论
export function updateComment(data) {
return request({
url: '/ams/comment',
method: 'put',
data: data
})
}
// 删除活动评论
export function delComment(commentId) {
return request({
url: '/ams/comment/' + commentId,
method: 'delete'
})
}

View File

@ -0,0 +1,44 @@
import request from '@/utils/request'
// 查询点赞记录列表
export function listReaction(query) {
return request({
url: '/ams/reaction/list',
method: 'get',
params: query
})
}
// 查询点赞记录详细
export function getReaction(reactionId) {
return request({
url: '/ams/reaction/' + reactionId,
method: 'get'
})
}
// 新增点赞记录
export function addReaction(data) {
return request({
url: '/ams/reaction',
method: 'post',
data: data
})
}
// 修改点赞记录
export function updateReaction(data) {
return request({
url: '/ams/reaction',
method: 'put',
data: data
})
}
// 删除点赞记录
export function delReaction(reactionId) {
return request({
url: '/ams/reaction/' + reactionId,
method: 'delete'
})
}

View File

@ -0,0 +1,44 @@
import request from '@/utils/request'
// 查询活动报名列表
export function listRegistration(query) {
return request({
url: '/ams/registration/list',
method: 'get',
params: query
})
}
// 查询活动报名详细
export function getRegistration(regId) {
return request({
url: '/ams/registration/' + regId,
method: 'get'
})
}
// 新增活动报名
export function addRegistration(data) {
return request({
url: '/ams/registration',
method: 'post',
data: data
})
}
// 修改活动报名
export function updateRegistration(data) {
return request({
url: '/ams/registration',
method: 'put',
data: data
})
}
// 删除活动报名
export function delRegistration(regId) {
return request({
url: '/ams/registration/' + regId,
method: 'delete'
})
}

View File

@ -0,0 +1,44 @@
import request from '@/utils/request'
// 查询社团信息列表
export function listClub(query) {
return request({
url: '/sms/club/list',
method: 'get',
params: query
})
}
// 查询社团信息详细
export function getClub(clubId) {
return request({
url: '/sms/club/' + clubId,
method: 'get'
})
}
// 新增社团信息
export function addClub(data) {
return request({
url: '/sms/club',
method: 'post',
data: data
})
}
// 修改社团信息
export function updateClub(data) {
return request({
url: '/sms/club',
method: 'put',
data: data
})
}
// 删除社团信息
export function delClub(clubId) {
return request({
url: '/sms/club/' + clubId,
method: 'delete'
})
}

View File

@ -0,0 +1,44 @@
import request from '@/utils/request'
// 查询成员管理列表
export function listUser(query) {
return request({
url: '/sms/user/list',
method: 'get',
params: query
})
}
// 查询成员管理详细
export function getUser(id) {
return request({
url: '/sms/user/' + id,
method: 'get'
})
}
// 新增成员管理
export function addUser(data) {
return request({
url: '/sms/user',
method: 'post',
data: data
})
}
// 修改成员管理
export function updateUser(data) {
return request({
url: '/sms/user',
method: 'put',
data: data
})
}
// 删除成员管理
export function delUser(id) {
return request({
url: '/sms/user/' + id,
method: 'delete'
})
}

View File

@ -0,0 +1,8 @@
import request from '@/utils/request'
export function getDashboardStats() {
return request({
url: '/sams/dashboard/list',
method: 'get'
})
}

View File

@ -0,0 +1,58 @@
import request from '@/utils/request'
// 获取轮播图活动最多4条
export function listBannerActivities() {
return request({
url: '/front/activity/banner',
method: 'get'
})
}
// 获取分页活动列表(已审批通过,按开始时间排序)
export function listActivities(query) {
return request({
url: '/front/activity/list',
method: 'get',
params: query
})
}
// 获取活动最多的前4个社团
export function listHotClubs() {
return request({
url: '/front/activity/hot',
method: 'get'
})
}
/**
* 查询活动评论分页
* @param {Object} query 查询参数包含 actId, pageNum, pageSize
*/
export function listComment(query) {
return request({
url: '/front/activity/comment',
method: 'get',
params: query
})
}
/**
* 查询活动点赞记录分页或全量
* @param {Object} query 查询参数包含 actId可选 pageNum/pageSize
*/
export function listReaction(query) {
return request({
url: '/front/activity/reaction',
method: 'get',
params: query
})
}
export function listMyRegisteredActivity(query) {
return request({
url: '/front/activity/my-regist',
method: 'get',
params: query
})
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 137 KiB

View File

@ -0,0 +1,507 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="活动标题" prop="title">
<el-input
v-model="queryParams.title"
placeholder="请输入活动标题"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="活动地点" prop="location">
<el-input
v-model="queryParams.location"
placeholder="请输入活动地点"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery"></el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery"></el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['ams:activity:add']"
>新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="success"
plain
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
v-hasPermi="['ams:activity:edit']"
>修改</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['ams:activity:remove']"
>删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['ams:activity:export']"
>导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="activityList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="活动ID" align="center" prop="actId" />
<el-table-column label="活动标题" align="center" prop="title" />
<el-table-column label="所属院系" align="center" prop="deptName" />
<el-table-column label="所属社团" align="center" prop="clubName" />
<el-table-column label="预算金额" align="center" prop="budget" />
<el-table-column label="活动状态" align="center" prop="status">
<template slot-scope="scope">
<dict-tag :options="dict.type.ams_activity_status" :value="scope.row.status"/>
</template>
</el-table-column>
<el-table-column label="开始时间" align="center" prop="startTime" width="140">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.startTime, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="是否公开" align="center" prop="visibility">
<template slot-scope="scope">
<dict-tag :options="dict.type.ams_activity_visibility" :value="scope.row.visibility"/>
</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleApproval(scope.row)"
v-hasPermi="['ams:activity:approve']"
>审批</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['ams:activity:edit']"
>修改</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['ams:activity:remove']"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改活动列表对话框 -->
<el-dialog :title="title" :visible.sync="open" width="1200px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="100px">
<el-row :gutter="20">
<!-- 左侧活动标题 + 活动描述 -->
<el-col :span="16">
<el-form-item label="活动标题" prop="title">
<el-input v-model="form.title" :disabled="isApproveMode" placeholder="请输入活动标题" />
</el-form-item>
<el-row>
<el-col :span="12">
<el-form-item label="开始时间" prop="startTime">
<el-date-picker clearable v-model="form.startTime" :disabled="isApproveMode" type="date" value-format="yyyy-MM-dd" placeholder="请选择开始时间" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="结束时间" prop="endTime">
<el-date-picker clearable v-model="form.endTime" :disabled="isApproveMode" type="date" value-format="yyyy-MM-dd" placeholder="请选择结束时间" />
</el-form-item>
</el-col>
</el-row>
<el-form-item label="封面图" prop="coverImage">
<image-upload v-model="form.coverImage"/>
</el-form-item>
<el-form-item label="活动描述">
<editor v-model="form.description" :min-height="330" />
</el-form-item>
</el-col>
<!-- 右侧其他字段 -->
<el-col :span="8">
<el-form-item label="活动地点" prop="location">
<el-input v-model="form.location" :disabled="isApproveMode" placeholder="请输入活动地点" />
</el-form-item>
<el-form-item label="预算金额" prop="budget">
<el-input v-model="form.budget" :disabled="isApproveMode" placeholder="请输入预算金额" />
</el-form-item>
<el-form-item label="最大参与人数" prop="maxParticipants">
<el-input v-model="form.maxParticipants" :disabled="isApproveMode" placeholder="请输入最大参与人数" />
</el-form-item>
<el-form-item v-if="form.actId" label="创建人">
<el-input v-model="form.creatorName" :disabled="true" />
</el-form-item>
<el-form-item label="所属院系" prop="deptId">
<treeselect
v-model="form.deptId"
:options="deptOptions"
:show-count="true"
placeholder="请选择所属院系"
:disabled="isApproveMode"
@input="handleDeptChange"
/>
</el-form-item>
<el-form-item label="所属社团" prop="clubId">
<el-select v-model="form.clubName" placeholder="请选择所属社团" :disabled="clubOptions.length === 0 || isApproveMode">
<el-option
v-for="club in clubOptions"
:key="club.clubId"
:label="club.clubName"
:value="club.clubId"
/>
</el-select>
</el-form-item>
<el-form-item label="活动类型" prop="activityType">
<el-select v-model="form.activityType" :disabled="isApproveMode" placeholder="请选择活动类型">
<el-option
v-for="dict in dict.type.ams_activity_type"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item v-if="form.actId != null" label="活动状态" prop="status">
<el-select v-model="form.status" :disabled="isApproveMode" placeholder="请选择活动状态">
<el-option
v-for="dict in dict.type.ams_activity_status"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="是否公开" prop="visibility">
<el-select v-model="form.visibility" :disabled="isApproveMode" placeholder="请选择是否公开">
<el-option
v-for="dict in dict.type.ams_activity_visibility"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item v-if="form.remark!==null" label="备注" prop="remark">
<el-input v-model="form.remark" type="textarea" :disabled="!isApproveMode" placeholder="请输入备注内容" />
</el-form-item>
</el-col>
</el-row>
</el-form>
<div slot="footer" class="dialog-footer">
<template v-if="isApproveMode">
<el-button type="success" @click="submitToApproval('approved')"> </el-button>
<el-button type="danger" @click="submitToApproval('rejected')"> </el-button>
</template>
<el-button type="success" @click="submitToReview" v-if="canSubmitToReview"> </el-button>
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { listActivity, getActivity, delActivity, addActivity, updateActivity } from "@/api/ams/activity"
import Treeselect from "@riophae/vue-treeselect"
import "@riophae/vue-treeselect/dist/vue-treeselect.css"
import { listClub } from "@/api/sms/club"
import {deptTreeSelect} from "@/api/system/user";
export default {
name: "Activity",
dicts: ['ams_activity_status', 'ams_activity_visibility', 'ams_activity_type'],
components: { Treeselect },
data() {
return {
//
loading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
activityList: [],
//
deptOptions: undefined,
clubOptions: [],
//
enabledDeptOptions: true,
//
title: "",
//
open: false,
//
queryParams: {
pageNum: 1,
pageSize: 10,
title: null,
},
//
form: {},
isApproveMode: false,
uploadUrl: process.env.VUE_APP_BASE_API + '/ams/activity/upload-cover',
uploadHeaders: {
Authorization: 'Bearer ' + this.$store.state.user.token
},
//
rules: {
title: [
{ required: true, message: "活动标题不能为空", trigger: "blur" }
],
startTime: [
{ required: true, message: "开始时间不能为空", trigger: "blur" }
],
endTime: [
{ required: true, message: "结束时间不能为空", trigger: "blur" }
],
creatorId: [
{ required: true, message: "创建人ID不能为空", trigger: "blur" }
],
}
}
},
computed: {
canSubmitToReview() {
return (
this.form.creatorId === this.userInfo.userId &&
this.form.status === 'draft'
)
},
userInfo() {
return {
userId: this.$store.state.user.id,
nickName: this.$store.state.user.name
}
}
},
created() {
this.getList()
this.getDeptTree()
},
methods: {
/** 查询活动列表列表 */
getList() {
this.loading = true
const query = { ...this.queryParams }
//
const roles = this.$store.state.user.roles
const userId = this.$store.state.user.id
const isAdmin = roles.includes('club_admin') || roles.includes('department_admin') || roles.includes('college_admin')
if (isAdmin) {
query.excludeOtherDraft = true // 稿
query.creatorId = userId // 稿
}
listActivity(query).then(response => {
this.activityList = response.rows
this.total = response.total
this.loading = false
})
},
getDeptTree() {
deptTreeSelect().then(response => {
this.deptOptions = response.data
this.enabledDeptOptions = this.filterDisabledDept(JSON.parse(JSON.stringify(response.data)))
})
},
filterDisabledDept(deptList) {
return deptList.filter(dept => {
if (dept.disabled) {
return false
}
if (dept.children && dept.children.length) {
dept.children = this.filterDisabledDept(dept.children)
}
return true
})
},
handleDeptChange(deptId) {
this.form.clubId = null //
if (!deptId) {
this.clubOptions = []
return
}
// collegeId
listClub({ collegeId: deptId, pageNum: 1, pageSize: 100 }).then(res => {
this.clubOptions = res.rows || []
})
},
//
cancel() {
this.open = false
this.isApproveMode = false
this.reset()
},
//
reset() {
this.form = {
actId: null,
title: null,
description: null,
coverImage: null,
startTime: null,
endTime: null,
location: null,
budget: null,
maxParticipants: null,
creatorId: null,
clubId: null,
deptId: null,
activityType: null,
status: null,
visibility: null,
currentApproverId: null,
createBy: null,
createTime: null,
updateBy: null,
updateTime: null,
remark: null
}
this.resetForm("form")
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm")
this.handleQuery()
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.actId)
this.single = selection.length!==1
this.multiple = !selection.length
},
/** 新增按钮操作 */
handleAdd() {
this.reset()
this.open = true
this.form.creatorId = this.userInfo.userId; // ID
this.form.status = 'draft'
this.title = "添加活动列表"
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset()
const actId = row.actId || this.ids
getActivity(actId).then(response => {
Object.assign(this.form, response.data)
this.open = true
this.title = "修改活动列表"
})
//
if (this.form.deptId) {
this.handleDeptChange(this.form.deptId)
}
},
handleApproval(row) {
if (row.status !== 'pending') {
this.$modal.msgWarning('仅支持审批待审批状态的活动')
return
}
this.reset()
this.isApproveMode = true
const actId = row.actId || this.ids
getActivity(actId).then(response => {
Object.assign(this.form, response.data)
this.open = true
this.title = "审批活动"
})
if (row.deptId) {
this.handleDeptChange(row.deptId)
}
},
submitToReview() {
this.form.status = 'pending';
this.submitForm(() => {
this.$modal.msgSuccess("已提交审核!");
});
},
submitToApproval(status) {
this.form.status = status;
this.form.currentApproverId = this.userInfo.userId;
this.submitForm(() => {
this.$modal.msgSuccess(status === 'approved' ? '活动已通过' : '活动被驳回');
});
},
submitForm(callback) {
this.$refs["form"].validate(valid => {
if (valid) {
const apiCall = this.form.actId ? updateActivity : addActivity;
apiCall(this.form).then(() => {
this.$modal.msgSuccess(this.form.actId ? "修改成功" : "新增成功");
this.open = false;
this.getList();
if (callback) callback();
});
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const actIds = row.actId || this.ids
this.$modal.confirm('是否确认删除活动列表编号为"' + actIds + '"的数据项?').then(function() {
return delActivity(actIds)
}).then(() => {
this.getList()
this.$modal.msgSuccess("删除成功")
}).catch(() => {})
},
/** 导出按钮操作 */
handleExport() {
this.download('ams/activity/export', {
...this.queryParams
}, `activity_${new Date().getTime()}.xlsx`)
}
}
}
</script>

View File

@ -0,0 +1,291 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="活动名称" prop="activityName">
<el-input
v-model="queryParams.activityName"
placeholder="请输入活动名称"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="用户名" prop="userName">
<el-input
v-model="queryParams.userName"
placeholder="请输入用户名"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery"></el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery"></el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['ams:comment:add']"
>新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="success"
plain
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
v-hasPermi="['ams:comment:edit']"
>修改</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['ams:comment:remove']"
>删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['ams:comment:export']"
>导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="commentList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="评论ID" align="center" prop="commentId" />
<el-table-column label="活动名称" align="center" prop="activityName" />
<el-table-column label="用户名" align="center" prop="userName" />
<el-table-column label="父评论ID" align="center" prop="parentCommentId" />
<el-table-column label="评论内容" align="center" prop="content" />
<el-table-column label="备注" align="center" prop="remark" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['ams:comment:edit']"
>修改</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['ams:comment:remove']"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改活动评论对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="活动ID" prop="actId">
<el-input v-model="form.actId" placeholder="请输入活动ID" />
</el-form-item>
<el-form-item label="用户ID" prop="userId">
<el-input v-model="form.userId" placeholder="请输入用户ID" />
</el-form-item>
<el-form-item label="父评论ID" prop="parentCommentId">
<el-input v-model="form.parentCommentId" placeholder="请输入父评论ID" />
</el-form-item>
<el-form-item label="评论内容" prop="content">
<el-input v-model="form.content" type="textarea" placeholder="请输入内容" />
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { listComment, getComment, delComment, addComment, updateComment } from "@/api/ams/comment"
export default {
name: "Comment",
data() {
return {
//
loading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
commentList: [],
//
title: "",
//
open: false,
//
queryParams: {
pageNum: 1,
pageSize: 10,
activityName: null,
userName: null,
},
//
form: {},
//
rules: {
actId: [
{ required: true, message: "活动ID不能为空", trigger: "blur" }
],
userId: [
{ required: true, message: "用户ID不能为空", trigger: "blur" }
],
content: [
{ required: true, message: "评论内容不能为空", trigger: "blur" }
],
}
}
},
created() {
this.getList()
},
methods: {
/** 查询活动评论列表 */
getList() {
this.loading = true
listComment(this.queryParams).then(response => {
this.commentList = response.rows
this.total = response.total
this.loading = false
})
},
//
cancel() {
this.open = false
this.reset()
},
//
reset() {
this.form = {
commentId: null,
actId: null,
userId: null,
parentCommentId: null,
content: null,
createBy: null,
createTime: null,
updateBy: null,
updateTime: null,
remark: null
}
this.resetForm("form")
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm")
this.handleQuery()
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.commentId)
this.single = selection.length!==1
this.multiple = !selection.length
},
/** 新增按钮操作 */
handleAdd() {
this.reset()
this.open = true
this.title = "添加活动评论"
},
/** 修改按钮操作 */
// handleUpdate(row) {
// this.reset()
// const commentId = row.commentId || this.ids
// getComment(commentId).then(response => {
// this.form = response.data
// this.open = true
// this.title = ""
// })
// },
handleUpdate(row) {
this.$modal.msgWarning("当前暂不支持修改操作")
return null
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
if (this.form.commentId != null) {
updateComment(this.form).then(response => {
this.$modal.msgSuccess("修改成功")
this.open = false
this.getList()
})
} else {
addComment(this.form).then(response => {
this.$modal.msgSuccess("新增成功")
this.open = false
this.getList()
})
}
}
})
},
/** 删除按钮操作 */
handleDelete(row) {
const commentIds = row.commentId || this.ids
this.$modal.confirm('是否确认删除活动评论编号为"' + commentIds + '"的数据项?').then(function() {
return delComment(commentIds)
}).then(() => {
this.getList()
this.$modal.msgSuccess("删除成功")
}).catch(() => {})
},
/** 导出按钮操作 */
handleExport() {
this.download('ams/comment/export', {
...this.queryParams
}, `comment_${new Date().getTime()}.xlsx`)
}
}
}
</script>

View File

@ -0,0 +1,309 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="活动名称" prop="activityName">
<el-input
v-model="queryParams.activityName"
placeholder="请输入活动名称"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="用户名" prop="userName">
<el-input
v-model="queryParams.userName"
placeholder="请输入用户名"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="反应类型" prop="reactionType">
<el-select v-model="queryParams.reactionType" placeholder="请选择反应类型" clearable>
<el-option
v-for="dict in dict.type.ams_reaction_type"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery"></el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery"></el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['ams:reaction:add']"
>新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="success"
plain
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
v-hasPermi="['ams:reaction:edit']"
>修改</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['ams:reaction:remove']"
>删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['ams:reaction:export']"
>导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="reactionList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="互动ID" align="center" prop="reactionId" />
<el-table-column label="活动名称" align="center" prop="actTitle" />
<el-table-column label="用户名" align="center" prop="userName" />
<el-table-column label="反应类型" align="center" prop="reactionType">
<template slot-scope="scope">
<dict-tag :options="dict.type.ams_reaction_type" :value="scope.row.reactionType"/>
</template>
</el-table-column>
<el-table-column label="备注" align="center" prop="remark" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['ams:reaction:edit']"
>修改</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['ams:reaction:remove']"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改点赞记录对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="活动ID" prop="actId">
<el-input v-model="form.actId" placeholder="请输入活动ID" />
</el-form-item>
<el-form-item label="用户ID" prop="userId">
<el-input v-model="form.userId" placeholder="请输入用户ID" />
</el-form-item>
<el-form-item label="反应类型" prop="reactionType">
<el-select v-model="form.reactionType" placeholder="请选择反应类型">
<el-option
v-for="dict in dict.type.ams_reaction_type"
:key="dict.value"
:label="dict.label"
:value="dict.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { listReaction, getReaction, delReaction, addReaction, updateReaction } from "@/api/ams/reaction"
export default {
name: "Reaction",
dicts: ['ams_reaction_type'],
data() {
return {
//
loading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
reactionList: [],
//
title: "",
//
open: false,
//
queryParams: {
pageNum: 1,
pageSize: 10,
actId: null,
userId: null,
reactionType: null,
},
//
form: {},
//
rules: {
actId: [
{ required: true, message: "活动ID不能为空", trigger: "blur" }
],
userId: [
{ required: true, message: "用户ID不能为空", trigger: "blur" }
],
reactionType: [
{ required: true, message: "反应类型不能为空", trigger: "change" }
],
}
}
},
created() {
this.getList()
},
methods: {
/** 查询点赞记录列表 */
getList() {
this.loading = true
listReaction(this.queryParams).then(response => {
this.reactionList = response.rows
this.total = response.total
this.loading = false
})
},
//
cancel() {
this.open = false
this.reset()
},
//
reset() {
this.form = {
reactionId: null,
actId: null,
userId: null,
reactionType: null,
createBy: null,
createTime: null,
updateBy: null,
updateTime: null,
remark: null
}
this.resetForm("form")
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm")
this.handleQuery()
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.reactionId)
this.single = selection.length!==1
this.multiple = !selection.length
},
/** 新增按钮操作 */
handleAdd() {
this.reset()
this.open = true
this.title = "添加点赞记录"
},
/** 修改按钮操作 */
// handleUpdate(row) {
// this.reset()
// const reactionId = row.reactionId || this.ids
// getReaction(reactionId).then(response => {
// this.form = response.data
// this.open = true
// this.title = ""
// })
// },
handleUpdate(row) {
this.$modal.msgWarning("当前暂不支持修改操作")
return null
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
if (this.form.reactionId != null) {
updateReaction(this.form).then(response => {
this.$modal.msgSuccess("修改成功")
this.open = false
this.getList()
})
} else {
addReaction(this.form).then(response => {
this.$modal.msgSuccess("新增成功")
this.open = false
this.getList()
})
}
}
})
},
/** 删除按钮操作 */
handleDelete(row) {
const reactionIds = row.reactionId || this.ids
this.$modal.confirm('是否确认删除点赞记录编号为"' + reactionIds + '"的数据项?').then(function() {
return delReaction(reactionIds)
}).then(() => {
this.getList()
this.$modal.msgSuccess("删除成功")
}).catch(() => {})
},
/** 导出按钮操作 */
handleExport() {
this.download('ams/reaction/export', {
...this.queryParams
}, `reaction_${new Date().getTime()}.xlsx`)
}
}
}
</script>

View File

@ -0,0 +1,336 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="活动ID" prop="actId">
<el-input
v-model="queryParams.actId"
placeholder="请输入活动ID"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="用户ID" prop="userId">
<el-input
v-model="queryParams.userId"
placeholder="请输入用户ID"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="角色" prop="role">
<el-select v-model="queryParams.role" placeholder="请选择角色" clearable>
<el-option
v-for="dict in dict.type.ams_registration_role"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery"></el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery"></el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['ams:registration:add']"
>新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="success"
plain
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
v-hasPermi="['ams:registration:edit']"
>修改</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['ams:registration:remove']"
>删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['ams:registration:export']"
>导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="registrationList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="报名ID" align="center" prop="regId" />
<el-table-column label="活动ID" align="center" prop="actId" />
<el-table-column label="用户ID" align="center" prop="userId" />
<el-table-column label="角色" align="center" prop="role">
<template slot-scope="scope">
<dict-tag :options="dict.type.ams_registration_role" :value="scope.row.role"/>
</template>
</el-table-column>
<el-table-column label="报名状态" align="center" prop="status">
<template slot-scope="scope">
<dict-tag :options="dict.type.ams_registration_status" :value="scope.row.status"/>
</template>
</el-table-column>
<el-table-column label="备注" align="center" prop="remark" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['ams:registration:edit']"
>修改</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['ams:registration:remove']"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改活动报名对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="活动ID" prop="actId">
<el-input v-model="form.actId" placeholder="请输入活动ID" />
</el-form-item>
<el-form-item label="用户ID" prop="userId">
<el-input v-model="form.userId" placeholder="请输入用户ID" />
</el-form-item>
<el-form-item label="角色" prop="role">
<el-select v-model="form.role" placeholder="请选择角色">
<el-option
v-for="dict in dict.type.ams_registration_role"
:key="dict.value"
:label="dict.label"
:value="dict.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="报名状态" prop="status">
<el-select v-model="form.status" placeholder="请选择报名状态">
<el-option
v-for="dict in dict.type.ams_registration_status"
:key="dict.value"
:label="dict.label"
:value="dict.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="报名时间" prop="registerTime">
<el-date-picker clearable
v-model="form.registerTime"
type="date"
value-format="yyyy-MM-dd"
placeholder="请选择报名时间">
</el-date-picker>
</el-form-item>
<el-form-item label="签到时间" prop="attendTime">
<el-date-picker clearable
v-model="form.attendTime"
type="date"
value-format="yyyy-MM-dd"
placeholder="请选择签到时间">
</el-date-picker>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { listRegistration, getRegistration, delRegistration, addRegistration, updateRegistration } from "@/api/ams/registration"
export default {
name: "Registration",
dicts: ['ams_registration_status', 'ams_registration_role'],
data() {
return {
//
loading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
registrationList: [],
//
title: "",
//
open: false,
//
queryParams: {
pageNum: 1,
pageSize: 10,
actId: null,
userId: null,
role: null,
},
//
form: {},
//
rules: {
actId: [
{ required: true, message: "活动ID不能为空", trigger: "blur" }
],
userId: [
{ required: true, message: "用户ID不能为空", trigger: "blur" }
],
}
}
},
created() {
this.getList()
},
methods: {
/** 查询活动报名列表 */
getList() {
this.loading = true
listRegistration(this.queryParams).then(response => {
this.registrationList = response.rows
this.total = response.total
this.loading = false
})
},
//
cancel() {
this.open = false
this.reset()
},
//
reset() {
this.form = {
regId: null,
actId: null,
userId: null,
role: null,
status: null,
registerTime: null,
attendTime: null,
createBy: null,
createTime: null,
updateBy: null,
updateTime: null,
remark: null
}
this.resetForm("form")
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm")
this.handleQuery()
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.regId)
this.single = selection.length!==1
this.multiple = !selection.length
},
/** 新增按钮操作 */
handleAdd() {
this.reset()
this.open = true
this.title = "添加活动报名"
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset()
const regId = row.regId || this.ids
getRegistration(regId).then(response => {
this.form = response.data
this.open = true
this.title = "修改活动报名"
})
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
if (this.form.regId != null) {
updateRegistration(this.form).then(response => {
this.$modal.msgSuccess("修改成功")
this.open = false
this.getList()
})
} else {
addRegistration(this.form).then(response => {
this.$modal.msgSuccess("新增成功")
this.open = false
this.getList()
})
}
}
})
},
/** 删除按钮操作 */
handleDelete(row) {
const regIds = row.regId || this.ids
this.$modal.confirm('是否确认删除活动报名编号为"' + regIds + '"的数据项?').then(function() {
return delRegistration(regIds)
}).then(() => {
this.getList()
this.$modal.msgSuccess("删除成功")
}).catch(() => {})
},
/** 导出按钮操作 */
handleExport() {
this.download('ams/registration/export', {
...this.queryParams
}, `registration_${new Date().getTime()}.xlsx`)
}
}
}
</script>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,109 @@
<template>
<div class="app-container">
<!-- 搜索栏 -->
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" label-width="68px">
<el-form-item label="活动标题" prop="title">
<el-input
v-model="queryParams.title"
placeholder="请输入活动标题"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery"></el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery"></el-button>
</el-form-item>
</el-form>
<!-- 活动表格 -->
<el-table v-loading="loading" :data="activityList" border>
<el-table-column label="活动标题" align="center" prop="title" />
<el-table-column label="所属院系" align="center" prop="deptName" />
<el-table-column label="所属社团" align="center" prop="clubName" />
<el-table-column label="活动地点" align="center" prop="location" />
<el-table-column label="开始时间" align="center" prop="startTime" width="140">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.startTime, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="结束时间" align="center" prop="endTime" width="140">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.endTime, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="80">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-view"
@click="viewActivity(scope.row.actId)"
>查看</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<pagination
v-show="total > 0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
</div>
</template>
<script>
import { listActivity } from "@/api/ams/activity"
export default {
name: "AllActivity",
data() {
return {
loading: true,
total: 0,
activityList: [],
queryParams: {
pageNum: 1,
pageSize: 10,
title: null,
status: 'approved' //
}
}
},
created() {
this.getList()
},
methods: {
getList() {
this.loading = true
listActivity(this.queryParams).then(response => {
this.activityList = response.rows
this.total = response.total
this.loading = false
})
},
handleQuery() {
this.queryParams.pageNum = 1
this.getList()
},
resetQuery() {
this.queryParams.title = null
this.handleQuery()
},
viewActivity(actId) {
this.$router.push({ path: `/active/detail/${actId}` })
},
parseTime(time, format) {
if (!time) return ''
const date = new Date(time)
const y = date.getFullYear()
const m = (date.getMonth() + 1).toString().padStart(2, '0')
const d = date.getDate().toString().padStart(2, '0')
return format.replace('{y}', y).replace('{m}', m).replace('{d}', d)
}
}
}
</script>

View File

@ -0,0 +1,431 @@
<template>
<div class="activity-detail-page">
<el-card class="activity-card" shadow="hover">
<!-- 活动基本信息 -->
<div class="header">
<h2 class="title">{{ detail.title }}</h2>
<span class="sub">{{ detail.clubName }} | {{ detail.deptName }}</span>
</div>
<div v-if="detail.coverImage" class="cover-wrapper">
<el-image :src="resolveImageUrl(detail.coverImage)" class="cover-image" fit="cover"/>
</div>
<el-descriptions :label-style="{ width: '120px' }" border column="2">
<el-descriptions-item label="开始时间">{{ formatDate(detail.startTime, false) }}</el-descriptions-item>
<el-descriptions-item label="结束时间">{{ formatDate(detail.endTime, false) }}</el-descriptions-item>
<el-descriptions-item label="活动地点">{{ detail.location }}</el-descriptions-item>
</el-descriptions>
<div class="section">
<h3>活动介绍</h3>
<div class="rich-text" v-html="detail.description"/>
</div>
<el-divider/>
<!-- 互动区 -->
<!-- 点赞区 -->
<div class="section interactions">
<h3>互动</h3>
<div class="interaction-row">
<div class="reaction-buttons">
<el-button type="text" @click="handleReaction('like')">👍 {{ reactionStats.like }}</el-button>
<el-button type="text" @click="handleReaction('dislike')">👎 {{ reactionStats.dislike }}</el-button>
</div>
<div class="signup-buttons">
<el-button v-if="!hasRegistered" type="primary" @click="handleRegister"></el-button>
<el-button v-else-if="hasRegistered && !hasAttended" type="success" @click="handleSignIn"></el-button>
<el-button v-else disabled type="success">已签到</el-button>
</div>
</div>
</div>
<el-divider/>
<!-- 评论列表嵌套结构 -->
<div class="section comments">
<h3>评论列表</h3>
<div v-for="comment in nestedComments" :key="comment.commentId" class="comment-block">
<div class="comment-item">
<span class="comment-user">{{ comment.userName }}</span>
<span class="comment-time">{{ formatDate(comment.createdAt) }}</span>
<div class="comment-content">{{ comment.content }}</div>
<div class="comment-actions">
<el-button size="mini" type="text" @click="replyTo(comment)"></el-button>
</div>
</div>
<div v-if="comment.children.length" class="comment-children">
<div
v-for="child in comment.children"
:key="child.commentId"
class="comment-item child"
>
<span class="comment-user">{{ child.userName }}</span>
<span class="comment-time">{{ formatDate(child.createdAt) }}</span>
<div class="comment-content">{{ child.content }}</div>
<div class="comment-actions">
<el-button size="mini" type="text" @click="replyTo(child)"></el-button>
</div>
</div>
</div>
</div>
<!-- 评论输入区 -->
<div class="add-comment">
<el-input
v-model="newCommentContent"
:rows="3"
placeholder="写下你的评论或回复..."
type="textarea"
/>
<el-button :disabled="!newCommentContent.trim()" size="small" type="primary" @click="submitComment">
</el-button>
<el-button v-if="replyTarget" size="small" @click="cancelReply"></el-button>
</div>
</div>
</el-card>
</div>
</template>
<script>
import {getActivity} from '@/api/ams/activity'
import {addRegistration, listRegistration, updateRegistration} from '@/api/ams/registration'
import {addComment} from '@/api/ams/comment'
import {addReaction, delReaction, updateReaction} from '@/api/ams/reaction'
import {parseTime} from '@/utils/ruoyi'
import {listComment, listReaction} from '@/api/ui/stufront'
export default {
name: 'ActivityDetail',
data() {
return {
detail: {},
registration: null,
commentQuery: {pageNum: 1, pageSize: 5, actId: null},
commentList: [],
commentTotal: 0,
loadingComments: false,
newCommentContent: '',
replyTarget: null,
reactions: [],
reactionStats: {like: 0, dislike: 0},
reactionQuery: {pageNum: 1, pageSize: 5, actId: null},
reactionList: [],
reactionTotal: 0,
loadingReactions: false,
}
},
computed: {
userId() {
return this.$store.state.user.id
},
hasRegistered() {
return !!this.registration
},
hasAttended() {
return this.registration && this.registration.attendTime !== null
},
nestedComments() {
const map = {}
this.commentList.forEach(c => {
map[c.commentId] = { ...c, children: [] }
})
const tree = []
this.commentList.forEach(c => {
const parentId = c.parentCommentId
if (parentId && map[parentId]) {
map[parentId].children.push(map[c.commentId])
} else {
tree.push(map[c.commentId])
}
})
return tree
}
},
created() {
const actId = this.$route.params.id
this.commentQuery.actId = actId
this.reactionQuery.actId = actId
this.fetchData(actId)
this.fetchRegistration(actId)
this.getReactions()
this.fetchReactions()
this.getComments()
},
methods: {
fetchData(id) {
getActivity(id).then(r => (this.detail = r.data || {}))
},
fetchRegistration(actId) {
listRegistration({actId, userId: this.userId})
.then(r => (this.registration = r.rows[0] || null))
},
fetchReactions() {
listReaction({actId: this.detail.actId}).then(r => {
this.reactionStats = r.data || {like: 0, dislike: 0}
})
},
getComments() {
this.loadingComments = true
listComment(this.commentQuery).then(r => {
this.commentList = r.rows
this.commentTotal = r.total
}).finally(() => this.loadingComments = false)
},
submitComment() {
if (!this.newCommentContent.trim()) {
return this.$message.warning('评论不能为空')
}
addComment({
actId: this.detail.actId,
userId: this.userId,
content: this.newCommentContent,
parentCommentId: this.replyTarget ? this.replyTarget.commentId : null
}).then(() => {
this.newCommentContent = ''
this.replyTarget = null
this.getComments()
})
},
replyTo(comment) {
this.replyTarget = comment
this.newCommentContent = `@${comment.createBy || comment.userId} `
},
cancelReply() {
this.replyTarget = null
this.newCommentContent = ''
},
getReactions() {
this.loadingReactions = true
listReaction(this.reactionQuery).then(r => {
this.reactionList = r.rows
this.reactionTotal = r.total
}).finally(() => this.loadingReactions = false)
},
handleReaction(type) {
const exist = this.reactions.find(r => r.userId === this.userId)
if (!exist) {
addReaction({
actId: this.detail.actId,
userId: this.userId,
reactionType: type
}).then(() => this.fetchReactions())
} else if (exist.reactionType === type) {
delReaction(exist.reactionId).then(() => this.fetchReactions())
} else {
updateReaction({reactionId: exist.reactionId, reactionType: type}).then(() => this.fetchReactions())
}
},
handleRegister() {
addRegistration({
actId: this.detail.actId,
userId: this.userId,
registerTime: this.formatDateOnly(new Date())
}).then(() => this.fetchRegistration(this.detail.actId))
},
handleSignIn() {
updateRegistration({
regId: this.registration.regId,
actId: this.registration.actId,
userId: this.registration.userId,
attendTime: this.formatDateOnly(new Date()),
status: 'attended' // <--
}).then(() => {
this.$message.success('签到成功')
this.fetchRegistration(this.detail.actId)
})
},
formatDate(date, showTime = true) {
return parseTime(date, showTime ? '{y}-{m}-{d} {h}:{i}' : '{y}-{m}-{d}')
},
formatDateOnly(date) {
const y = date.getFullYear()
const m = (date.getMonth() + 1).toString().padStart(2, '0')
const d = date.getDate().toString().padStart(2, '0')
return `${y}-${m}-${d}`
},
resolveImageUrl(url) {
if (!url) return require('@/assets/images/loading2.png').default
return url.startsWith('http') ? url : process.env.VUE_APP_BASE_API + url
}
}
}
</script>
<style scoped>
.activity-detail-page {
padding: 20px;
}
.activity-card {
max-width: 1000px;
margin: auto;
}
.header {
text-align: center;
margin-bottom: 20px;
}
.header .title {
font-size: 26px;
font-weight: bold;
}
.header .sub {
font-size: 14px;
color: #888;
}
.cover-wrapper {
text-align: center;
margin-bottom: 24px;
}
.cover-image {
width: 100%;
max-height: 400px;
border-radius: 8px;
object-fit: cover;
}
.section {
margin-top: 30px;
}
.section h3 {
margin-bottom: 12px;
font-weight: bold;
}
.rich-text {
background: #fafafa;
padding: 16px;
border-radius: 4px;
}
.interactions .interaction-row {
display: flex;
align-items: center;
gap: 24px;
}
.reaction-buttons {
font-size: 18px;
}
.signup-buttons el-button {
margin-left: 8px;
}
.comments .add-comment {
display: flex;
gap: 8px;
margin-top: 12px;
}
.comment-block {
margin-bottom: 20px;
}
.comment-item {
background: #f9f9f9;
padding: 10px;
border-radius: 6px;
margin-bottom: 6px;
}
.comment-user {
font-weight: bold;
margin-right: 8px;
}
.comment-time {
color: #999;
font-size: 12px;
}
.comment-content {
margin: 6px 0;
}
.comment-actions {
text-align: right;
}
.comment-children {
margin-left: 24px;
}
.child {
background: #f0f0f0;
}
.comment-block {
margin-bottom: 6px;
}
.comment-item {
background: #fafafa;
padding: 6px 10px;
border-radius: 3px;
font-size: 13px;
line-height: 1.4;
margin-bottom: 4px;
border: 1px solid #eee;
position: relative;
}
.comment-user {
font-weight: 500;
margin-right: 6px;
font-size: 13px;
color: #333;
}
.comment-time {
color: #bbb;
font-size: 12px;
}
.comment-content {
margin: 4px 0;
font-size: 13px;
}
.comment-actions {
position: absolute;
top: 6px;
right: 8px;
}
.comment-children {
margin-left: 14px;
}
.comment-item.child {
background: #f3f3f3;
border: 1px solid #e6e6e6;
}
.add-comment {
margin-top: 10px;
display: flex;
gap: 6px;
}
.add-comment .el-input__inner {
font-size: 13px;
padding: 6px 8px;
}
.add-comment .el-button {
padding: 6px 12px;
font-size: 13px;
}
</style>

View File

@ -0,0 +1,146 @@
<template>
<div class="app-container">
<!-- 搜索栏 -->
<el-form
:model="queryParams"
ref="queryForm"
size="small"
:inline="true"
label-width="68px"
>
<el-form-item label="活动标题" prop="title">
<el-input
v-model="queryParams.title"
placeholder="请输入活动标题"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button
type="primary"
icon="el-icon-search"
size="mini"
@click="handleQuery"
>搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery"
>重置</el-button>
</el-form-item>
</el-form>
<!-- 活动表格 -->
<el-table v-loading="loading" :data="activityList" border>
<el-table-column label="活动标题" align="center" prop="title" />
<el-table-column label="所属院系" align="center" prop="deptName" />
<el-table-column label="所属社团" align="center" prop="clubName" />
<el-table-column label="活动地点" align="center" prop="location" />
<el-table-column
label="开始时间"
align="center"
prop="startTime"
width="140"
>
<template #default="{ row }">
<span>{{ parseTime(row.startTime, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column
label="结束时间"
align="center"
prop="endTime"
width="140"
>
<template #default="{ row }">
<span>{{ parseTime(row.endTime, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="80">
<template #default="{ row }">
<el-button
size="mini"
type="text"
icon="el-icon-view"
@click="viewActivity(row.actId)"
>查看</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<pagination
v-show="total > 0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
</div>
</template>
<script>
import { listMyRegisteredActivity } from "@/api/ui/stufront";
export default {
name: "MyActivity",
data() {
return {
loading: false,
total: 0,
activityList: [],
queryParams: {
pageNum: 1,
pageSize: 10,
title: null,
status: "approved", //
userId: this.$store.state.user.id
}
};
},
computed: {
userId() {
return this.$store.state.user.id;
}
},
created() {
this.getList();
},
methods: {
getList() {
this.loading = true
listMyRegisteredActivity(this.queryParams)
.then(res => {
this.activityList = res.rows
this.total = res.total
})
.finally(() => {
this.loading = false
})
},
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
resetQuery() {
this.queryParams.title = null;
this.handleQuery();
},
viewActivity(actId) {
this.$router.push({ path: `/active/detail/${actId}` });
},
parseTime(time, format) {
if (!time) return "";
const date = new Date(time);
const y = date.getFullYear();
const m = String(date.getMonth() + 1).padStart(2, "0");
const d = String(date.getDate()).padStart(2, "0");
return format.replace("{y}", y).replace("{m}", m).replace("{d}", d);
}
}
};
</script>
<style scoped>
.app-container {
padding: 20px;
}
</style>

View File

@ -0,0 +1,120 @@
<template>
<div class="app-container dashboard">
<!-- 欢迎语 -->
<el-card class="box-card" shadow="never">
<div class="clearfix">
<span style="font-size: 18px;">欢迎使用校园社团活动管理系统</span>
<span style="float: right;">{{ currentTime }}</span>
</div>
</el-card>
<!-- 数据统计卡片 -->
<el-row :gutter="20" class="my-20">
<el-col :span="6" v-for="(item, index) in stats" :key="index">
<el-card class="stat-card" shadow="hover">
<div class="stat-title">{{ item.label }}</div>
<div class="stat-value">{{ item.value }}</div>
</el-card>
</el-col>
</el-row>
<!-- 最近活动列表 -->
<el-card class="box-card" shadow="hover">
<div slot="header" class="clearfix">
<span>近期活动预览</span>
</div>
<el-table :data="activityList" border stripe>
<el-table-column prop="title" label="活动标题" />
<el-table-column prop="clubName" label="所属社团" />
<el-table-column prop="deptName" label="承办学院" />
<el-table-column prop="startTime" label="开始时间" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.startTime, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
</el-table>
</el-card>
<!-- 社团预览 -->
<el-card class="box-card" shadow="hover" style="margin-top: 20px;">
<div slot="header" class="clearfix">
<span>社团列表预览</span>
</div>
<el-table :data="clubList" border stripe>
<el-table-column prop="clubName" label="社团名称" />
<el-table-column prop="category" label="分类" />
<el-table-column prop="deptName" label="所属学院" />
</el-table>
</el-card>
</div>
</template>
<script>
import { getDashboardStats } from "@/api/ui/dashboard"
import { listActivity } from "@/api/ams/activity"
import { listClub } from "@/api/sms/club"
export default {
name: "Dashboard",
data() {
return {
currentTime: new Date().toLocaleString(),
stats: [],
activityList: [],
clubList: []
}
},
created() {
this.loadStatistics()
this.loadActivities()
this.loadClubs()
},
methods: {
loadStatistics() {
getDashboardStats().then(res => {
const data = res.data || {}
this.stats = [
{ label: "活动总数", value: data.activityCount || 0 },
{ label: "社团总数", value: data.clubCount || 0 },
{ label: "成员总数", value: data.userCount || 0 },
{ label: "待审批活动", value: data.pendingCount || 0 }
]
})
},
loadActivities() {
listActivity({ pageNum: 1, pageSize: 5 }).then(res => {
this.activityList = res.rows || []
})
},
loadClubs() {
listClub({ pageNum: 1, pageSize: 5 }).then(res => {
this.clubList = res.rows || []
})
}
}
}
</script>
<style scoped>
.dashboard {
padding: 20px;
}
.stat-card {
text-align: center;
padding: 20px 0;
}
.stat-title {
font-size: 14px;
color: #666;
}
.stat-value {
font-size: 24px;
font-weight: bold;
margin-top: 8px;
color: #409EFF;
}
.my-20 {
margin: 20px 0;
}
</style>

View File

@ -0,0 +1,114 @@
<template>
<div class="app-container">
<!-- 查询条件 -->
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" label-width="68px">
<el-form-item label="社团名称" prop="clubName">
<el-input
v-model="queryParams.clubName"
placeholder="请输入社团名称"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="社团类型" prop="category">
<el-select v-model="queryParams.category" placeholder="请选择社团类型" clearable>
<el-option v-for="dict in dict.type.sms_club_category" :key="dict.value" :label="dict.label" :value="dict.value" />
</el-select>
</el-form-item>
<el-form-item label="所属院系" prop="deptId">
<el-select v-model="queryParams.deptId" placeholder="请选择院系" clearable>
<el-option v-for="dept in deptOptions" :key="dept.deptId" :label="dept.deptName" :value="dept.deptId" />
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery"></el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery"></el-button>
</el-form-item>
</el-form>
<!-- 社团列表 -->
<el-table v-loading="loading" :data="clubList">
<el-table-column label="序号" align="center" prop="clubId" />
<el-table-column label="LOGO" align="center" width="100">
<template slot-scope="scope">
<image-preview :src="scope.row.logo" :width="50" :height="50" />
</template>
</el-table-column>
<el-table-column label="社团名称" prop="clubName" align="center" />
<el-table-column label="类型" prop="category" align="center">
<template slot-scope="scope">
<dict-tag :options="dict.type.sms_club_category" :value="scope.row.category" />
</template>
</el-table-column>
<el-table-column label="所属院系" prop="deptName" align="center" />
<el-table-column label="操作" align="center" width="100">
<template slot-scope="scope">
<el-button size="mini" type="primary" @click="goToDetail(scope.row)"></el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total > 0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
</div>
</template>
<script>
import { listClub } from "@/api/sms/club";
import { listDept } from "@/api/system/dept";
export default {
name: "ClubAll",
dicts: ['sms_club_category'],
data() {
return {
loading: true,
total: 0,
clubList: [],
deptOptions: [],
queryParams: {
pageNum: 1,
pageSize: 10,
clubName: null,
category: null,
deptId: null
}
};
},
created() {
this.getList();
this.loadDeptOptions();
},
methods: {
getList() {
this.loading = true;
listClub(this.queryParams).then(res => {
this.clubList = res.rows || [];
this.total = res.total || 0;
this.loading = false;
});
},
loadDeptOptions() {
listDept().then(res => {
this.deptOptions = res.data || [];
});
},
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
resetQuery() {
this.$refs.queryForm.resetFields();
this.handleQuery();
},
goToDetail(row) {
this.$router.push({ path: `/club/detail/${row.clubId}` });
}
}
};
</script>

View File

@ -0,0 +1,131 @@
<template>
<div class="club-detail-container">
<el-card class="club-card" v-if="club">
<div class="club-header">
<img :src="getFullImage(club.logo)" class="club-logo" @error="handleImageError" />
<div class="club-info">
<h2>{{ club.clubName }}</h2>
<p><strong>类型:</strong> {{ club.category }}</p>
<p><strong>所属院系:</strong> {{ club.deptName || '暂无' }}</p>
<p><strong>负责人:</strong> {{ club.leaderName || '暂无' }}</p>
</div>
</div>
<div class="club-description">
<p><strong>简介</strong></p>
<div v-html="club.description || '暂无简介'"></div>
</div>
<div style="margin-top: 20px; text-align: right;">
<el-button type="primary" icon="el-icon-plus" @click="handleJoin"></el-button>
</div>
</el-card>
</div>
</template>
<script>
import { getClub } from '@/api/sms/club'
import { addUser , listUser } from '@/api/sms/user'
export default {
name: 'ClubDetail',
data() {
return {
club: null
}
},
computed: {
userInfo() {
return {
userId: this.$store.state.user.id,
nickName: this.$store.state.user.name
}
}
},
created() {
const clubId = this.$route.params.id
if (clubId) {
getClub(clubId).then(res => {
this.club = res.data
})
}
},
methods: {
handleJoin() {
const { userId } = this.userInfo
const clubId = this.club.clubId
if (!userId || !clubId) return
//
const query = {
clubId: clubId,
userId: userId
}
listUser(query).then(res => {
const userClubList = res.rows || []
if(userClubList.length >= 2){
this.$message.warning('你已加入大于 2 个社团,无法加入新的社团')
} else if (userClubList.length > 0 && userClubList.length< 2) {
const status = userClubList[0].isActive
if (status === 1) {
this.$message.warning('你已加入该社团')
} else if (status === 0) {
this.$message.info('你已申请加入该社团,待审核')
} else if (status === -1) {
this.$message.error('你已被该社团拉黑,无法再次加入')
} else {
this.$message.warning('存在未知状态,无法加入')
}
} else {
//
const data = {
userId: userId,
clubId: clubId,
isActive: 0, //
role: 'MEMBER'
}
addUser(data).then(() => {
this.$message.success('已提交加入申请,等待审核')
})
}
})
},
getFullImage(url) {
if (!url) return require('@/assets/images/loading2.png').default
return process.env.VUE_APP_BASE_API + url
},
handleImageError(e) {
e.target.src = require('@/assets/images/loading2.png').default
}
}
}
</script>
<style scoped>
.club-detail-container {
padding: 24px;
}
.club-card {
padding: 24px;
}
.club-header {
display: flex;
align-items: center;
}
.club-logo {
width: 100px;
height: 100px;
border-radius: 50%;
margin-right: 24px;
object-fit: cover;
border: 1px solid #eee;
}
.club-info h2 {
margin: 0;
font-size: 24px;
}
.club-description {
margin-top: 20px;
font-size: 16px;
}
</style>

View File

@ -0,0 +1,149 @@
<template>
<div class="app-container">
<!-- 我的社团 -->
<el-row :gutter="20" class="my-club-section" style="margin-bottom: 40px">
<el-col v-for="club in clubList" :key="club.clubId" :span="6">
<el-card class="club-card" @click="goToClub(club.clubId)" shadow="hover">
<img :src="getFullImage(club.logo)" class="club-logo" @error="handleImageError" />
<div class="club-name">{{ club.clubName }}</div>
<div class="club-status">
<span v-if="club.hasActiveActivity"></span>
<span v-else class="inactive">暂无进行中的活动</span>
</div>
</el-card>
</el-col>
</el-row>
<!-- 活动列表 -->
<el-table v-loading="loading" :data="activityList" border stripe>
<el-table-column label="活动名称" prop="title" />
<el-table-column label="所属社团" prop="clubName" />
<el-table-column label="开始时间" prop="startTime" width="140">
<template slot-scope="scope">
{{ formatDate(scope.row.startTime) }}
</template>
</el-table-column>
<el-table-column label="结束时间" prop="endTime" width="140">
<template slot-scope="scope">
{{ formatDate(scope.row.endTime) }}
</template>
</el-table-column>
<el-table-column label="地点" prop="location" />
<el-table-column label="操作" align="center" width="100">
<template slot-scope="scope">
<el-button type="text" size="mini" @click="goToActivity(scope.row.actId)"></el-button>
</template>
</el-table-column>
</el-table>
</div>
</template>
<script>
import { listUser } from '@/api/sms/user'
import { listActivity } from '@/api/ams/activity'
import { listClub } from '@/api/sms/club'
export default {
name: 'MyClubActivities',
data() {
return {
clubList: [],
activityList: [],
loading: false
}
},
created() {
this.loadMyJoinedClubActivities()
},
methods: {
async loadMyJoinedClubActivities() {
this.loading = true
try {
const now = new Date()
const userId = this.$store.state.user.id
// 1. sms_user
const userRes = await listUser({ userId, pageNum: 1, pageSize: 100 })
const joinedClubIds = [...new Set((userRes.rows || []).map(row => row.clubId).filter(Boolean))]
if (joinedClubIds.length === 0) {
this.clubList = []
this.activityList = []
return
}
// 2.
const allClubs = (await listClub({ pageNum: 1, pageSize: 100 })).rows || []
this.clubList = allClubs.filter(c => joinedClubIds.includes(c.clubId)).map(c => ({ ...c, hasActiveActivity: false }))
// 3. status=approved
const activityPromises = joinedClubIds.map(clubId =>
listActivity({ clubId, status: 'approved', pageNum: 1, pageSize: 100 })
)
const activityResults = await Promise.all(activityPromises)
const allActivities = activityResults.flatMap(res => res.rows || [])
const filtered = allActivities.filter(act => new Date(act.endTime) > now)
this.activityList = filtered.sort((a, b) => new Date(a.startTime) - new Date(b.startTime))
//
this.clubList.forEach(club => {
club.hasActiveActivity = filtered.some(act => act.clubId === club.clubId)
})
} catch (e) {
console.error('加载失败', e)
} finally {
this.loading = false
}
},
getFullImage(url) {
if (!url) return require('@/assets/images/loading2.png').default
return url.startsWith('http') ? url : process.env.VUE_APP_BASE_API + url
},
handleImageError(e) {
e.target.src = require('@/assets/images/loading2.png').default
},
formatDate(dateStr) {
const d = new Date(dateStr)
return `${d.getFullYear()}-${(d.getMonth() + 1).toString().padStart(2, '0')}-${d.getDate().toString().padStart(2, '0')}`
},
goToClub(clubId) {
this.$router.push(`/club/detail/${clubId}`)
},
goToActivity(actId) {
this.$router.push(`/activity/detail/${actId}`)
}
}
}
</script>
<style scoped>
.club-card {
text-align: center;
cursor: pointer;
transition: all 0.3s;
}
.club-card:hover {
transform: translateY(-4px);
}
.club-logo {
width: 80px;
height: 80px;
border-radius: 50%;
object-fit: cover;
margin-bottom: 10px;
}
.club-name {
font-size: 18px;
font-weight: bold;
margin-bottom: 8px;
}
.club-status {
color: #666;
}
.inactive {
color: #999;
}
</style>

View File

@ -0,0 +1,364 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="社团名称" prop="clubName">
<el-input
v-model="queryParams.clubName"
placeholder="请输入社团名称"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="社团类型" prop="category">
<el-select v-model="queryParams.category" placeholder="请选择社团类型" clearable>
<el-option
v-for="dict in dict.type.sms_club_category"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="所属院系" prop="deptId">
<el-select v-model="queryParams.deptId" placeholder="请选择院系" clearable>
<el-option v-for="dept in deptOptions" :key="dept.deptId" :label="dept.deptName" :value="dept.deptId" />
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery"></el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery"></el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['sms:club:add']"
>新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="success"
plain
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
v-hasPermi="['sms:club:edit']"
>修改</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['sms:club:remove']"
>删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['sms:club:export']"
>导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="clubList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="社团ID" align="center" prop="clubId" />
<el-table-column label="社团名称" align="center" prop="clubName" />
<el-table-column label="社团类型" align="center" prop="category">
<template slot-scope="scope">
<dict-tag :options="dict.type.sms_club_category" :value="scope.row.category"/>
</template>
</el-table-column>
<el-table-column label="所属院系" align="center" prop="deptName" />
<el-table-column label="负责人" align="center" prop="leaderName" />
<el-table-column label="logo" align="center" prop="logo" width="100">
<template slot-scope="scope">
<image-preview :src="scope.row.logo" :width="50" :height="50"/>
</template>
</el-table-column>
<el-table-column label="状态" align="center" prop="status">
<template slot-scope="scope">
<dict-tag :options="dict.type.sms_club_status" :value="scope.row.status"/>
</template>
</el-table-column>
<el-table-column label="备注" align="center" prop="remark" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['sms:club:edit']"
>修改</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['sms:club:remove']"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改社团信息对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="社团名称" prop="clubName">
<el-input v-model="form.clubName" placeholder="请输入社团名称" />
</el-form-item>
<el-form-item label="社团简介" prop="description">
<editor v-model="form.description" :min-height="192"/>
</el-form-item>
<el-form-item label="社团类型" prop="category">
<el-select v-model="form.category" placeholder="请选择社团类型">
<el-option
v-for="dict in dict.type.sms_club_category"
:key="dict.value"
:label="dict.label"
:value="dict.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="所属院系" prop="deptId">
<el-select v-model="form.deptId" placeholder="请选择所属院系">
<el-option
v-for="item in deptOptions"
:key="item.deptId"
:label="item.deptName"
:value="item.deptId"
/>
</el-select>
</el-form-item>
<el-form-item label="负责人" prop="leaderId">
<el-select v-model="form.leaderId" placeholder="请选择负责人">
<el-option
v-for="item in userOptions"
:key="item.userId"
:label="item.nickName"
:value="item.userId"
/>
</el-select>
</el-form-item>
<el-form-item label="logo" prop="logo">
<image-upload v-model="form.logo"/>
</el-form-item>
<el-form-item label="状态" prop="status">
<el-radio-group v-model="form.status">
<el-radio
v-for="dict in dict.type.sms_club_status"
:key="dict.value"
:label="dict.value"
>{{dict.label}}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { listClub, getClub, delClub, addClub, updateClub } from "@/api/sms/club"
import { listDept } from "@/api/system/dept";
import { listUser } from "@/api/system/user";
export default {
name: "Club",
dicts: ['sms_club_status', 'sms_club_category'],
data() {
return {
//
loading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
clubList: [],
deptOptions: [], //
userOptions: [], //
//
title: "",
//
open: false,
//
queryParams: {
pageNum: 1,
pageSize: 10,
clubName: null,
category: null,
deptId: null,
},
//
form: {},
//
rules: {
clubName: [
{ required: true, message: "社团名称不能为空", trigger: "blur" }
],
category: [
{ required: true, message: "社团类型不能为空", trigger: "change" }
],
deptId: [
{ required: true, message: "所属院系ID不能为空", trigger: "blur" }
],
}
}
},
created() {
this.getList()
this.loadDeptOptions()
this.loadUserOptions()
},
methods: {
/** 查询社团信息列表 */
getList() {
this.loading = true
listClub(this.queryParams).then(response => {
this.clubList = response.rows
this.total = response.total
this.loading = false
})
},
loadDeptOptions() {
listDept().then(res => {
this.deptOptions = res.data || []
})
},
loadUserOptions() {
listUser().then(res => {
this.userOptions = res.rows || []
})
},
//
cancel() {
this.open = false
this.reset()
},
//
reset() {
this.form = {
clubId: null,
clubName: null,
description: null,
category: null,
deptId: null,
leaderId: null,
logo: null,
status: null,
createBy: null,
createTime: null,
updateBy: null,
updateTime: null,
remark: null
}
this.resetForm("form")
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm")
this.handleQuery()
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.clubId)
this.single = selection.length!==1
this.multiple = !selection.length
},
/** 新增按钮操作 */
handleAdd() {
this.reset()
this.open = true
this.title = "添加社团信息"
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset()
const clubId = row.clubId || this.ids
getClub(clubId).then(response => {
this.form = response.data
this.open = true
this.title = "修改社团信息"
})
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
if (this.form.clubId != null) {
updateClub(this.form).then(response => {
this.$modal.msgSuccess("修改成功")
this.open = false
this.getList()
})
} else {
addClub(this.form).then(response => {
this.$modal.msgSuccess("新增成功")
this.open = false
this.getList()
})
}
}
})
},
/** 删除按钮操作 */
handleDelete(row) {
const clubIds = row.clubId || this.ids
this.$modal.confirm('是否确认删除社团信息编号为"' + clubIds + '"的数据项?').then(function() {
return delClub(clubIds)
}).then(() => {
this.getList()
this.$modal.msgSuccess("删除成功")
}).catch(() => {})
},
/** 导出按钮操作 */
handleExport() {
this.download('sms/club/export', {
...this.queryParams
}, `club_${new Date().getTime()}.xlsx`)
}
}
}
</script>

View File

@ -0,0 +1,313 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="用户名" prop="userName">
<el-input
v-model="queryParams.userName"
placeholder="请输入用户名"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="社团名称" prop="clubName">
<el-input
v-model="queryParams.clubName"
placeholder="请输入社团名称"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="是否活跃" prop="isActive">
<el-select v-model="queryParams.isActive" placeholder="请选择是否活跃" clearable>
<el-option
v-for="dict in dict.type.sms_user_active"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery"></el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery"></el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['sms:user:add']"
>新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="success"
plain
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
v-hasPermi="['sms:user:edit']"
>修改</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['sms:user:remove']"
>删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['sms:user:export']"
>导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="userList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="主键ID" align="center" prop="id" />
<el-table-column label="用户名" align="center" prop="userName" />
<el-table-column label="社团名称" align="center" prop="clubName" />
<el-table-column label="是否活跃" align="center" prop="isActive">
<template slot-scope="scope">
<dict-tag :options="dict.type.sms_user_active" :value="scope.row.isActive"/>
</template>
</el-table-column>
<el-table-column label="加入社团时间" align="center" prop="joinDate" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.joinDate, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="备注" align="center" prop="remark" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['sms:user:edit']"
>审核</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['sms:user:remove']"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改成员管理对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="用户名">
<el-input :value="form.userName" disabled />
</el-form-item>
<el-form-item label="社团名称">
<el-input :value="form.clubName" disabled />
</el-form-item>
<el-form-item label="是否活跃" prop="isActive">
<el-select v-model="form.isActive" placeholder="请选择是否活跃">
<el-option
v-for="dict in dict.type.sms_user_active"
:key="dict.value"
:label="dict.label"
:value="parseInt(dict.value)"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="加入时间">
<el-input :value="parseTime(form.joinDate, '{y}-{m}-{d}')" disabled />
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { listUser, getUser, delUser, addUser, updateUser } from "@/api/sms/user"
import {parseTime} from "@/utils/ruoyi";
export default {
name: "User",
dicts: ['sms_user_active'],
data() {
return {
//
loading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
userList: [],
//
title: "",
//
open: false,
//
queryParams: {
pageNum: 1,
pageSize: 10,
userName: null,
clubName: null,
isActive: null
},
//
form: {},
//
rules: {
userId: [
{ required: true, message: "用户ID不能为空", trigger: "blur" }
],
clubId: [
{ required: true, message: "社团ID不能为空", trigger: "blur" }
],
}
}
},
created() {
this.getList()
},
methods: {
parseTime,
/** 查询成员管理列表 */
getList() {
this.loading = true
listUser(this.queryParams).then(response => {
this.userList = response.rows
this.total = response.total
this.loading = false
})
},
//
cancel() {
this.open = false
this.reset()
},
//
reset() {
this.form = {
id: null,
userId: null,
clubId: null,
isActive: null,
joinDate: null,
createBy: null,
createTime: null,
updateBy: null,
updateTime: null,
remark: null
}
this.resetForm("form")
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm")
this.handleQuery()
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.single = selection.length!==1
this.multiple = !selection.length
},
/** 新增按钮操作 */
handleAdd() {
this.reset()
this.open = true
this.title = "添加成员管理"
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset()
const id = row.id || this.ids
getUser(id).then(response => {
this.form = response.data
this.open = true
this.title = "修改成员管理"
})
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
if (this.form.id != null) {
updateUser(this.form).then(response => {
this.$modal.msgSuccess("修改成功")
this.open = false
this.getList()
})
} else {
addUser(this.form).then(response => {
this.$modal.msgSuccess("新增成功")
this.open = false
this.getList()
})
}
}
})
},
/** 删除按钮操作 */
handleDelete(row) {
const ids = row.id || this.ids
this.$modal.confirm('是否确认删除成员管理编号为"' + ids + '"的数据项?').then(function() {
return delUser(ids)
}).then(() => {
this.getList()
this.$modal.msgSuccess("删除成功")
}).catch(() => {})
},
/** 导出按钮操作 */
handleExport() {
this.download('sms/user/export', {
...this.queryParams
}, `user_${new Date().getTime()}.xlsx`)
}
}
}
</script>

View File

@ -0,0 +1,22 @@
-- 菜单 SQL
insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
values('活动列表', '2049', '1', 'activity', 'ams/activity/index', 1, 0, 'C', '0', '0', 'ams:activity:list', '#', 'admin', sysdate(), '', null, '活动列表菜单');
-- 按钮父菜单ID
SELECT @parentId := LAST_INSERT_ID();
-- 按钮 SQL
insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
values('活动列表查询', @parentId, '1', '#', '', 1, 0, 'F', '0', '0', 'ams:activity:query', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
values('活动列表新增', @parentId, '2', '#', '', 1, 0, 'F', '0', '0', 'ams:activity:add', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
values('活动列表修改', @parentId, '3', '#', '', 1, 0, 'F', '0', '0', 'ams:activity:edit', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
values('活动列表删除', @parentId, '4', '#', '', 1, 0, 'F', '0', '0', 'ams:activity:remove', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
values('活动列表导出', @parentId, '5', '#', '', 1, 0, 'F', '0', '0', 'ams:activity:export', '#', 'admin', sysdate(), '', null, '');

View File

@ -0,0 +1,22 @@
-- 菜单 SQL
insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
values('活动评论', '2049', '1', 'comment', 'ams/comment/index', 1, 0, 'C', '0', '0', 'ams:comment:list', '#', 'admin', sysdate(), '', null, '活动评论菜单');
-- 按钮父菜单ID
SELECT @parentId := LAST_INSERT_ID();
-- 按钮 SQL
insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
values('活动评论查询', @parentId, '1', '#', '', 1, 0, 'F', '0', '0', 'ams:comment:query', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
values('活动评论新增', @parentId, '2', '#', '', 1, 0, 'F', '0', '0', 'ams:comment:add', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
values('活动评论修改', @parentId, '3', '#', '', 1, 0, 'F', '0', '0', 'ams:comment:edit', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
values('活动评论删除', @parentId, '4', '#', '', 1, 0, 'F', '0', '0', 'ams:comment:remove', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
values('活动评论导出', @parentId, '5', '#', '', 1, 0, 'F', '0', '0', 'ams:comment:export', '#', 'admin', sysdate(), '', null, '');

View File

@ -0,0 +1,22 @@
-- 菜单 SQL
insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
values('点赞记录', '2049', '1', 'reaction', 'ams/reaction/index', 1, 0, 'C', '0', '0', 'ams:reaction:list', '#', 'admin', sysdate(), '', null, '点赞记录菜单');
-- 按钮父菜单ID
SELECT @parentId := LAST_INSERT_ID();
-- 按钮 SQL
insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
values('点赞记录查询', @parentId, '1', '#', '', 1, 0, 'F', '0', '0', 'ams:reaction:query', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
values('点赞记录新增', @parentId, '2', '#', '', 1, 0, 'F', '0', '0', 'ams:reaction:add', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
values('点赞记录修改', @parentId, '3', '#', '', 1, 0, 'F', '0', '0', 'ams:reaction:edit', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
values('点赞记录删除', @parentId, '4', '#', '', 1, 0, 'F', '0', '0', 'ams:reaction:remove', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
values('点赞记录导出', @parentId, '5', '#', '', 1, 0, 'F', '0', '0', 'ams:reaction:export', '#', 'admin', sysdate(), '', null, '');

Some files were not shown because too many files have changed in this diff Show More