feat(sms): 添加生日短信、短信任务、短信日志和专家通讯录功能模块

- 新增生日短信实体类SmsBirthday及其相关控制器、服务和Mapper
- 新增短信任务实体类SmsTask及其相关控制器、服务和Mapper
- 新增短信日志实体类SmsLog及其相关控制器、服务和Mapper
- 新增专家通讯录实体类Specialist及其相关控制器、服务和Mapper
- 提供各模块的增删改查接口实现
- 添加数据库建表SQL脚本
master
李一帆 2025-09-23 10:22:38 +08:00
parent ae3f7eca91
commit b2773e47e2
22 changed files with 746 additions and 1 deletions

2
.gitignore vendored
View File

@ -3,7 +3,7 @@ npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
CLAUDE.md
/target/
!.mvn/wrapper/maven-wrapper.jar

47
sql/tables.sms.sql Normal file
View File

@ -0,0 +1,47 @@
-- 姓名,职务,生日,称呼,电话号码,生效状态,创建日期
-- 达梦数据库SPECIALIST表建表语句
CREATE TABLE SPECIALIST (
ID BIGINT IDENTITY(1,1) PRIMARY KEY,
NAME VARCHAR(50) NOT NULL COMMENT '姓名',
POSITION VARCHAR(100) COMMENT '职务',
BIRTHDAY DATE COMMENT '生日',
TITLE VARCHAR(20) COMMENT '称呼',
PHONE VARCHAR(20) COMMENT '电话号码',
STATUS INT DEFAULT 1 COMMENT '生效状态 1:有效 0:无效',
CREATE_TM DATETIME DEFAULT CURRENT_TIME COMMENT '创建日期'
);
--
--20252025-10-012025-10-0308:00:002025-09-15
--20262026-02-172026-02-1708:00:002025-09-15
-- 达梦数据库TASK表建表语句
CREATE TABLE SMS_TASK (
ID BIGINT IDENTITY(1,1) PRIMARY KEY,
SUBJECT_NAME VARCHAR(200) NOT NULL COMMENT '主题名称',
START_DATE DATE COMMENT '任务开始日期',
END_DATE DATE COMMENT '任务结束日期',
EXECUTION_TM_STR VARCHAR(8) COMMENT '任务执行时间',
STATUS INT DEFAULT 1 COMMENT '状态 1:有效 0:无效',
TEMPLATE VARCHAR(500),
CREATE_TM DATETIME DEFAULT CURRENT_TIME COMMENT '创建日期'
);
CREATE TABLE SMS_BIRTHDAY (
ID BIGINT IDENTITY(1,1) PRIMARY KEY,
EXECUTION_TM_STR VARCHAR(8) COMMENT '任务执行时间',
STATUS INT DEFAULT 1 COMMENT '状态 1:有效 0:无效',
TEMPLATE VARCHAR(500)
);
CREATE TABLE SMS_LOG (
ID BIGINT IDENTITY(1,1) PRIMARY KEY,
SEND_TM DATETIME NOT NULL COMMENT '发送时间',
NAME VARCHAR(50) NOT NULL COMMENT '姓名',
PHONE VARCHAR(20) COMMENT '电话号码',
REMARK VARCHAR(500) COMMENT '备注',
CONTENT VARCHAR(500) COMMENT '短信内容'
)

View File

@ -0,0 +1,43 @@
package com.whdc.controller;
import com.whdc.model.entity.SmsBirthday;
import com.whdc.model.group.Insert;
import com.whdc.model.group.Update;
import com.whdc.service.ISmsBirthdayService;
import com.whdc.utils.ResultJson;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
*
*
* @author lyf
* @since 2025-09-23
*/
@Api(tags = "生日短信 - Controller")
@RestController
@RequestMapping("/smsBirthday")
public class SmsBirthdayController {
@Autowired
private ISmsBirthdayService smsBirthdayService;
private static final Long THE_ONLY_ONE = 1L;
@ApiOperation(value = "修改")
@PostMapping(value = "edit")
public ResultJson<Boolean> edit(@RequestBody @Validated(Update.class) SmsBirthday model) {
return ResultJson.ok(smsBirthdayService.updateById(model));
}
@ApiOperation(value = "查询")
@GetMapping(value = "get")
public ResultJson<SmsBirthday> getById() {
return ResultJson.ok(smsBirthdayService.getById(THE_ONLY_ONE));
}
}

View File

@ -0,0 +1,59 @@
package com.whdc.controller;
import com.whdc.model.entity.SmsLog;
import com.whdc.model.group.Insert;
import com.whdc.model.group.Update;
import com.whdc.service.ISmsLogService;
import com.whdc.utils.ResultJson;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
*
*
* @author lyf
* @since 2025-09-23
*/
@Api(tags = "短信日志 - Controller")
@RestController
@RequestMapping("/smsLog")
public class SmsLogController {
@Autowired
private ISmsLogService smsLogService;
@ApiOperation(value = "分页查询")
@PostMapping(value = "page")
public ResultJson<List<SmsLog>> page(@RequestBody SmsLog dto) {
return ResultJson.ok(smsLogService.list());
}
@ApiOperation(value = "新增")
@PostMapping(value = "add")
public ResultJson<Boolean> add(@RequestBody @Validated(Insert.class) SmsLog model) {
return ResultJson.ok(smsLogService.save(model));
}
@ApiOperation(value = "修改")
@PostMapping(value = "edit")
public ResultJson<Boolean> edit(@RequestBody @Validated(Update.class) SmsLog model) {
return ResultJson.ok(smsLogService.updateById(model));
}
@ApiOperation(value = "删除")
@GetMapping(value = "del/{id}")
public ResultJson<Boolean> delete(@PathVariable("id") Long id) {
return ResultJson.ok(smsLogService.removeById(id));
}
@ApiOperation(value = "根据ID查询")
@GetMapping(value = "get/{id}")
public ResultJson<SmsLog> getById(@PathVariable("id") Long id) {
return ResultJson.ok(smsLogService.getById(id));
}
}

View File

@ -0,0 +1,59 @@
package com.whdc.controller;
import com.whdc.model.entity.SmsTask;
import com.whdc.model.group.Insert;
import com.whdc.model.group.Update;
import com.whdc.service.ISmsTaskService;
import com.whdc.utils.ResultJson;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
*
*
* @author lyf
* @since 2025-09-23
*/
@Api(tags = "短信任务 - Controller")
@RestController
@RequestMapping("/smsTask")
public class SmsTaskController {
@Autowired
private ISmsTaskService smsTaskService;
@ApiOperation(value = "分页查询")
@PostMapping(value = "page")
public ResultJson<List<SmsTask>> page(@RequestBody SmsTask dto) {
return ResultJson.ok(smsTaskService.list());
}
@ApiOperation(value = "新增")
@PostMapping(value = "add")
public ResultJson<Boolean> add(@RequestBody @Validated(Insert.class) SmsTask model) {
return ResultJson.ok(smsTaskService.save(model));
}
@ApiOperation(value = "修改")
@PostMapping(value = "edit")
public ResultJson<Boolean> edit(@RequestBody @Validated(Update.class) SmsTask model) {
return ResultJson.ok(smsTaskService.updateById(model));
}
@ApiOperation(value = "删除")
@GetMapping(value = "del/{id}")
public ResultJson<Boolean> delete(@PathVariable("id") Long id) {
return ResultJson.ok(smsTaskService.removeById(id));
}
@ApiOperation(value = "根据ID查询")
@GetMapping(value = "get/{id}")
public ResultJson<SmsTask> getById(@PathVariable("id") Long id) {
return ResultJson.ok(smsTaskService.getById(id));
}
}

View File

@ -0,0 +1,60 @@
package com.whdc.controller;
import com.whdc.model.entity.Specialist;
import com.whdc.model.group.Insert;
import com.whdc.model.group.Update;
import com.whdc.service.ISpecialistService;
import com.whdc.utils.ResultJson;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
*
*
* @author lyf
* @since 2025-09-23
*/
@Api(tags = "专家通讯录 - Controller")
@RestController
@RequestMapping("/specialist")
public class SpecialistController {
@Autowired
private ISpecialistService specialistService;
@ApiOperation(value = "分页查询")
@PostMapping(value = "page")
public ResultJson<List<Specialist>> page(@RequestBody Specialist dto) {
return ResultJson.ok(specialistService.list());
}
@ApiOperation(value = "新增")
@PostMapping(value = "add")
public ResultJson<Boolean> add(@RequestBody @Validated(Insert.class) Specialist model) {
return ResultJson.ok(specialistService.save(model));
}
@ApiOperation(value = "修改")
@PostMapping(value = "edit")
public ResultJson<Boolean> edit(@RequestBody @Validated(Update.class) Specialist model) {
return ResultJson.ok(specialistService.updateById(model));
}
@ApiOperation(value = "删除")
@GetMapping(value = "del/{id}")
public ResultJson<Boolean> delete(@PathVariable("id") Long id) {
return ResultJson.ok(specialistService.removeById(id));
}
@ApiOperation(value = "根据ID查询")
@GetMapping(value = "get/{id}")
public ResultJson<Specialist> getById(@PathVariable("id") Long id) {
return ResultJson.ok(specialistService.getById(id));
}
}

View File

@ -0,0 +1,11 @@
package com.whdc.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.whdc.model.entity.SmsBirthday;
/**
* @author lyf
* @since 2025-09-23
*/
public interface SmsBirthdayMapper extends BaseMapper<SmsBirthday> {
}

View File

@ -0,0 +1,13 @@
package com.whdc.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.whdc.model.entity.SmsLog;
/**
* Mapper
*
* @author lyf
* @since 2025-09-23
*/
public interface SmsLogMapper extends BaseMapper<SmsLog> {
}

View File

@ -0,0 +1,13 @@
package com.whdc.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.whdc.model.entity.SmsTask;
/**
* Mapper
*
* @author lyf
* @since 2025-09-23
*/
public interface SmsTaskMapper extends BaseMapper<SmsTask> {
}

View File

@ -0,0 +1,13 @@
package com.whdc.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.whdc.model.entity.Specialist;
/**
* Mapper
*
* @author lyf
* @since 2025-09-23
*/
public interface SpecialistMapper extends BaseMapper<Specialist> {
}

View File

@ -0,0 +1,64 @@
package com.whdc.model.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
/**
*
*
* @author
* @date
*/
@Data
@EqualsAndHashCode
@Accessors(chain = true)
@ApiModel(description = "生日短信")
@TableName("SMS_BIRTHDAY")
public class SmsBirthday implements Serializable {
private static final long serialVersionUID = 1L;
/**
* ID
*/
@TableId(value = "ID", type = IdType.AUTO)
@ApiModelProperty(value = "主键ID")
private Long id;
/**
*
*/
@TableField("EXECUTION_TM_STR")
@ApiModelProperty(value = "任务执行时间")
private String executionTmStr;
/**
* 1: 0:
*/
@TableField("STATUS")
@ApiModelProperty(value = "状态 1:有效 0:无效")
private Integer status;
/**
*
*/
@TableField("TEMPLATE")
@ApiModelProperty(value = "模板")
private String template;
/**
*
*/
@TableField("CREATE_TM")
@ApiModelProperty(value = "创建日期")
private Date createTm;
}

View File

@ -0,0 +1,72 @@
package com.whdc.model.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
/**
*
*
* @author
* @since 2025-09-23
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@ApiModel(description = "短信日志")
@TableName("SMS_LOG")
public class SmsLog implements Serializable {
private static final long serialVersionUID = 1L;
/**
* ID
*/
@TableId(value = "ID", type = IdType.AUTO)
@ApiModelProperty(value = "主键ID")
private Long id;
/**
*
*/
@TableField("SEND_TM")
@ApiModelProperty(value = "发送时间")
private Date sendTm;
/**
*
*/
@TableField("NAME")
@ApiModelProperty(value = "姓名")
private String name;
/**
*
*/
@TableField("PHONE")
@ApiModelProperty(value = "电话号码")
private String phone;
/**
*
*/
@TableField("REMARK")
@ApiModelProperty(value = "备注")
private String remark;
/**
*
*/
@TableField("CONTENT")
@ApiModelProperty(value = "短信内容")
private String content;
}

View File

@ -0,0 +1,85 @@
package com.whdc.model.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
/**
*
*
* @author
* @date
*/
@Data
@EqualsAndHashCode
@Accessors(chain = true)
@ApiModel(description = "节日短信")
@TableName("SMS_TASK")
public class SmsTask implements Serializable {
private static final long serialVersionUID = 1L;
/**
* ID
*/
@TableId(value = "ID", type = IdType.AUTO)
@ApiModelProperty(value = "主键ID")
private Long id;
/**
*
*/
@TableField("SUBJECT_NAME")
@ApiModelProperty(value = "主题名称")
private String subjectName;
/**
*
*/
@TableField("START_DATE")
@ApiModelProperty(value = "任务开始日期")
private Date startDate;
/**
*
*/
@TableField("END_DATE")
@ApiModelProperty(value = "任务结束日期")
private Date endDate;
/**
*
*/
@TableField("EXECUTION_TM_STR")
@ApiModelProperty(value = "任务执行时间")
private String executionTmStr;
/**
* 1: 0:
*/
@TableField("STATUS")
@ApiModelProperty(value = "状态 1:有效 0:无效")
private Integer status;
/**
*
*/
@TableField("TEMPLATE")
@ApiModelProperty(value = "模板")
private String template;
/**
*
*/
@TableField("CREATE_TM")
@ApiModelProperty(value = "创建日期")
private Date createTm;
}

View File

@ -0,0 +1,86 @@
package com.whdc.model.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
/**
* @author
* @date
*/
@Data
@EqualsAndHashCode
@Accessors(chain = true)
@ApiModel(description = "专家通讯录")
@TableName("SPECIALIST")
public class Specialist implements Serializable {
private static final long serialVersionUID = 1L;
/**
* ID
*/
@TableId(value = "ID", type = IdType.AUTO)
@ApiModelProperty(value = "主键ID")
private Long id;
/**
*
*/
@TableField("NAME")
@ApiModelProperty(value = "姓名")
private String name;
/**
*
*/
@TableField("POSITION")
@ApiModelProperty(value = "职务")
private String position;
/**
*
*/
@TableField("BIRTHDAY")
@ApiModelProperty(value = "生日")
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
private Date birthday;
/**
*
*/
@TableField("TITLE")
@ApiModelProperty(value = "称呼")
private String title;
/**
*
*/
@TableField("PHONE")
@ApiModelProperty(value = "电话号码")
private String phone;
/**
* 1: 0:
*/
@TableField("STATUS")
@ApiModelProperty(value = "生效状态 1:有效 0:无效")
private Integer status;
/**
*
*/
@TableField("CREATE_TM")
@ApiModelProperty(value = "创建日期")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date createTm;
}

View File

@ -0,0 +1,13 @@
package com.whdc.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.whdc.model.entity.SmsBirthday;
/**
*
*
* @author lyf
* @since 2025-09-23
*/
public interface ISmsBirthdayService extends IService<SmsBirthday> {
}

View File

@ -0,0 +1,13 @@
package com.whdc.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.whdc.model.entity.SmsLog;
/**
*
*
* @author lyf
* @since 2025-09-23
*/
public interface ISmsLogService extends IService<SmsLog> {
}

View File

@ -0,0 +1,13 @@
package com.whdc.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.whdc.model.entity.SmsTask;
/**
*
*
* @author lyf
* @since 2025-09-23
*/
public interface ISmsTaskService extends IService<SmsTask> {
}

View File

@ -0,0 +1,13 @@
package com.whdc.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.whdc.model.entity.Specialist;
/**
*
*
* @author lyf
* @since 2025-09-23
*/
public interface ISpecialistService extends IService<Specialist> {
}

View File

@ -0,0 +1,17 @@
package com.whdc.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.whdc.mapper.SmsBirthdayMapper;
import com.whdc.model.entity.SmsBirthday;
import com.whdc.service.ISmsBirthdayService;
import org.springframework.stereotype.Service;
/**
*
*
* @author lyf
* @since 2025-09-23
*/
@Service
public class SmsBirthdayServiceImpl extends ServiceImpl<SmsBirthdayMapper, SmsBirthday> implements ISmsBirthdayService {
}

View File

@ -0,0 +1,17 @@
package com.whdc.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.whdc.mapper.SmsLogMapper;
import com.whdc.model.entity.SmsLog;
import com.whdc.service.ISmsLogService;
import org.springframework.stereotype.Service;
/**
*
*
* @author lyf
* @since 2025-09-23
*/
@Service
public class SmsLogServiceImpl extends ServiceImpl<SmsLogMapper, SmsLog> implements ISmsLogService {
}

View File

@ -0,0 +1,17 @@
package com.whdc.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.whdc.mapper.SmsTaskMapper;
import com.whdc.model.entity.SmsTask;
import com.whdc.service.ISmsTaskService;
import org.springframework.stereotype.Service;
/**
*
*
* @author lyf
* @since 2025-09-23
*/
@Service
public class SmsTaskServiceImpl extends ServiceImpl<SmsTaskMapper, SmsTask> implements ISmsTaskService {
}

View File

@ -0,0 +1,17 @@
package com.whdc.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.whdc.mapper.SpecialistMapper;
import com.whdc.model.entity.Specialist;
import com.whdc.service.ISpecialistService;
import org.springframework.stereotype.Service;
/**
*
*
* @author lyf
* @since 2025-09-23
*/
@Service
public class SpecialistServiceImpl extends ServiceImpl<SpecialistMapper, Specialist> implements ISpecialistService {
}