refactor(sms): 重构短信服务相关类名和包结构

- 将 Specialist 相关类重命名为 SmsSpecialist
- 将 SmsTask 相关类重命名为 SmsHoliday
- 更新所有引用和导入语句以匹配新的类名- 调整控制器路由路径前缀统一为 /sms- 修改数据库表名 SPECIALIST 为 SMS_SPECIALIST
- 修改数据库表名 SMS_TASK 为 SMS_HOLIDAY
master
李一帆 2025-09-26 11:02:40 +08:00
parent c32e27b174
commit 66c73425ae
17 changed files with 103 additions and 106 deletions

View File

@ -1,7 +1,7 @@
-- 姓名,职务,生日,称呼,电话号码,生效状态,创建日期
-- 达梦数据库SPECIALIST表建表语句
CREATE TABLE SPECIALIST (
CREATE TABLE SMS_SPECIALIST (
ID BIGINT IDENTITY(1,1) PRIMARY KEY,
NAME VARCHAR(50) NOT NULL COMMENT '姓名',
POSITION VARCHAR(100) COMMENT '职务',
@ -10,7 +10,7 @@ CREATE TABLE SPECIALIST (
PHONE VARCHAR(20) UNIQUE COMMENT '电话号码',
STATUS INT DEFAULT 1 COMMENT '生效状态 1:有效 0:无效',
CREATE_TM DATETIME DEFAULT CURRENT_TIME COMMENT '创建日期',
FLAG_BIRTHDAY_SENT_TODAY INT DEFAULT 0
FLAG_BIRTHDAY_SENT_TODAY INT DEFAULT 0,
FLAG_HOLIDAY_SENT_TODAY INT DEFAULT 0
);
@ -19,7 +19,7 @@ CREATE TABLE SPECIALIST (
--20252025-10-012025-10-0308:00:002025-09-15
--20262026-02-172026-02-1708:00:002025-09-15
-- 达梦数据库TASK表建表语句
CREATE TABLE SMS_TASK (
CREATE TABLE SMS_HOLIDAY (
ID BIGINT IDENTITY(1,1) PRIMARY KEY,
SUBJECT_NAME VARCHAR(200) NOT NULL COMMENT '主题名称',
START_DATE DATE COMMENT '任务开始日期',

View File

@ -21,7 +21,7 @@ import java.util.List;
*/
@Api(tags = "生日短信 - Controller")
@RestController
@RequestMapping("/smsBirthday")
@RequestMapping("/sms/birthday")
public class SmsBirthdayController {
@Autowired

View File

@ -1,9 +1,9 @@
package com.whdc.controller;
import com.whdc.model.entity.SmsTask;
import com.whdc.model.entity.SmsHoliday;
import com.whdc.model.group.Insert;
import com.whdc.model.group.Update;
import com.whdc.service.ISmsTaskService;
import com.whdc.service.ISmsHolidayService;
import com.whdc.utils.ResultJson;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
@ -21,27 +21,27 @@ import java.util.List;
*/
@Api(tags = "短信任务 - Controller")
@RestController
@RequestMapping("/smsTask")
public class SmsTaskController {
@RequestMapping("/sms/holiday")
public class SmsHolidayController {
@Autowired
private ISmsTaskService smsTaskService;
private ISmsHolidayService smsTaskService;
@ApiOperation(value = "分页查询")
@PostMapping(value = "page")
public ResultJson<List<SmsTask>> page(@RequestBody SmsTask dto) {
public ResultJson<List<SmsHoliday>> page(@RequestBody SmsHoliday dto) {
return ResultJson.ok(smsTaskService.list());
}
@ApiOperation(value = "新增")
@PostMapping(value = "add")
public ResultJson<Boolean> add(@RequestBody @Validated(Insert.class) SmsTask model) {
public ResultJson<Boolean> add(@RequestBody @Validated(Insert.class) SmsHoliday model) {
return ResultJson.ok(smsTaskService.save(model));
}
@ApiOperation(value = "修改")
@PostMapping(value = "edit")
public ResultJson<Boolean> edit(@RequestBody @Validated(Update.class) SmsTask model) {
public ResultJson<Boolean> edit(@RequestBody @Validated(Update.class) SmsHoliday model) {
return ResultJson.ok(smsTaskService.updateById(model));
}
@ -53,7 +53,7 @@ public class SmsTaskController {
@ApiOperation(value = "根据ID查询")
@GetMapping(value = "get/{id}")
public ResultJson<SmsTask> getById(@PathVariable("id") Long id) {
public ResultJson<SmsHoliday> getById(@PathVariable("id") Long id) {
return ResultJson.ok(smsTaskService.getById(id));
}
}

View File

@ -21,7 +21,7 @@ import java.util.List;
*/
@Api(tags = "短信日志 - Controller")
@RestController
@RequestMapping("/smsLog")
@RequestMapping("/sms/log")
public class SmsLogController {
@Autowired

View File

@ -2,10 +2,10 @@ package com.whdc.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.whdc.model.dto.FindPageDto;
import com.whdc.model.entity.Specialist;
import com.whdc.model.entity.SmsSpecialist;
import com.whdc.model.group.Insert;
import com.whdc.model.group.Update;
import com.whdc.service.ISpecialistService;
import com.whdc.service.ISmsSpecialistService;
import com.whdc.utils.ResultJson;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
@ -21,28 +21,28 @@ import org.springframework.web.bind.annotation.*;
*/
@Api(tags = "专家通讯录 - Controller")
@RestController
@RequestMapping("/specialist")
public class SpecialistController {
@RequestMapping("/sms/specialist")
public class SmsSpecialistController {
@Autowired
private ISpecialistService specialistService;
private ISmsSpecialistService specialistService;
@ApiOperation(value = "分页查询")
@PostMapping(value = "page")
public ResultJson<IPage<Specialist>> page(@RequestBody FindPageDto dto) {
public ResultJson<IPage<SmsSpecialist>> page(@RequestBody FindPageDto dto) {
return ResultJson.ok(specialistService.page(dto.getPage()));
}
@ApiOperation(value = "新增")
@PostMapping(value = "add")
public ResultJson<Boolean> add(@RequestBody @Validated(Insert.class) Specialist model) {
public ResultJson<Boolean> add(@RequestBody @Validated(Insert.class) SmsSpecialist model) {
return ResultJson.ok(specialistService.save(model));
}
@ApiOperation(value = "修改")
@PostMapping(value = "edit")
public ResultJson<Boolean> edit(@RequestBody @Validated(Update.class) Specialist model) {
public ResultJson<Boolean> edit(@RequestBody @Validated(Update.class) SmsSpecialist model) {
return ResultJson.ok(specialistService.updateById(model));
}
@ -54,7 +54,7 @@ public class SpecialistController {
@ApiOperation(value = "根据ID查询")
@GetMapping(value = "get/{id}")
public ResultJson<Specialist> getById(@PathVariable("id") Long id) {
public ResultJson<SmsSpecialist> getById(@PathVariable("id") Long id) {
return ResultJson.ok(specialistService.getById(id));
}
}

View File

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

View File

@ -1,7 +1,7 @@
package com.whdc.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.whdc.model.entity.Specialist;
import com.whdc.model.entity.SmsSpecialist;
import org.apache.ibatis.annotations.Update;
/**
@ -10,7 +10,7 @@ import org.apache.ibatis.annotations.Update;
* @author lyf
* @since 2025-09-23
*/
public interface SpecialistMapper extends BaseMapper<Specialist> {
public interface SmsSpecialistMapper extends BaseMapper<SmsSpecialist> {
@Update("update specialist set flag_birthday_sent_today = 0")
void resetFlagBirthdaySentToday();
}

View File

@ -23,8 +23,8 @@ import java.util.Date;
@EqualsAndHashCode
@Accessors(chain = true)
@ApiModel(description = "节日短信")
@TableName("SMS_TASK")
public class SmsTask implements Serializable {
@TableName("SMS_HOLIDAY")
public class SmsHoliday implements Serializable {
private static final long serialVersionUID = 1L;
/**

View File

@ -22,8 +22,8 @@ import java.util.Date;
@EqualsAndHashCode
@Accessors(chain = true)
@ApiModel(description = "专家")
@TableName("SPECIALIST")
public class Specialist implements Serializable {
@TableName("SMS_SPECIALIST")
public class SmsSpecialist implements Serializable {
private static final long serialVersionUID = 1L;
/**

View File

@ -2,7 +2,7 @@ package com.whdc.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.whdc.model.entity.SmsBirthday;
import com.whdc.model.entity.Specialist;
import com.whdc.model.entity.SmsSpecialist;
import java.util.List;
@ -16,10 +16,10 @@ public interface ISmsBirthdayService extends IService<SmsBirthday> {
/**
*
*/
List<Specialist> listBirthdayToday();
List<SmsSpecialist> listBirthdayToday();
/**
*
*/
void sendBirthdaySms(List<Specialist> specialists);
void sendBirthdaySms(List<SmsSpecialist> specialists);
}

View File

@ -1,8 +1,7 @@
package com.whdc.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.whdc.model.entity.SmsTask;
import com.whdc.model.entity.Specialist;
import com.whdc.model.entity.SmsHoliday;
import java.util.List;
@ -12,24 +11,24 @@ import java.util.List;
* @author lyf
* @since 2025-09-23
*/
public interface ISmsTaskService extends IService<SmsTask> {
public interface ISmsHolidayService extends IService<SmsHoliday> {
/**
*
*/
List<SmsTask> listActiveTasks();
List<SmsHoliday> listActiveTasks();
/**
*
*/
List<SmsTask> listTodayTasks();
List<SmsHoliday> listTodayTasks();
/**
*
*/
void sendThemeSms(SmsTask smsTask);
void sendThemeSms(SmsHoliday smsTask);
/**
*
*/
void sendBatchThemeSms(List<SmsTask> smsTasks);
void sendBatchThemeSms(List<SmsHoliday> smsTasks);
}

View File

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

View File

@ -4,10 +4,10 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.whdc.mapper.SmsBirthdayMapper;
import com.whdc.mapper.SmsLogMapper;
import com.whdc.mapper.SpecialistMapper;
import com.whdc.mapper.SmsSpecialistMapper;
import com.whdc.model.entity.SmsBirthday;
import com.whdc.model.entity.SmsLog;
import com.whdc.model.entity.Specialist;
import com.whdc.model.entity.SmsSpecialist;
import com.whdc.service.ISmsBirthdayService;
import com.whdc.utils.SmsHelper;
import lombok.extern.slf4j.Slf4j;
@ -32,7 +32,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
public class SmsBirthdayServiceImpl extends ServiceImpl<SmsBirthdayMapper, SmsBirthday> implements ISmsBirthdayService {
@Autowired
private SpecialistMapper specialistMapper;
private SmsSpecialistMapper specialistMapper;
@Autowired
private SmsLogMapper smsLogMapper;
@ -44,20 +44,20 @@ public class SmsBirthdayServiceImpl extends ServiceImpl<SmsBirthdayMapper, SmsBi
private final AtomicBoolean sending = new AtomicBoolean(false);
@Override
public List<Specialist> listBirthdayToday() {
public List<SmsSpecialist> listBirthdayToday() {
try {
// 获取当前日期的月和日
LocalDate today = LocalDate.now();
String monthDay = today.format(DateTimeFormatter.ofPattern("MM-dd"));
// 查询今天过生日的专家(状态为有效的)
LambdaQueryWrapper<Specialist> queryWrapper = new LambdaQueryWrapper<>();
LambdaQueryWrapper<SmsSpecialist> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper
.apply("DATE_FORMAT(BIRTHDAY, '%m-%d') = {0}", monthDay)
.eq(Specialist::getFlagBirthdaySentToday, 0)
.eq(Specialist::getStatus, 1); // 1:有效
.eq(SmsSpecialist::getFlagBirthdaySentToday, 0)
.eq(SmsSpecialist::getStatus, 1); // 1:有效
List<Specialist> specialists = specialistMapper.selectList(queryWrapper);
List<SmsSpecialist> specialists = specialistMapper.selectList(queryWrapper);
return specialists != null ? specialists : Collections.emptyList();
} catch (Exception e) {
// 记录异常并返回空列表
@ -66,7 +66,7 @@ public class SmsBirthdayServiceImpl extends ServiceImpl<SmsBirthdayMapper, SmsBi
}
@Override
public void sendBirthdaySms(List<Specialist> specialists) {
public void sendBirthdaySms(List<SmsSpecialist> specialists) {
if (specialists == null || specialists.isEmpty()) {
log.info("没有需要发送生日短信的专家");
return;
@ -92,7 +92,7 @@ public class SmsBirthdayServiceImpl extends ServiceImpl<SmsBirthdayMapper, SmsBi
//去重
Set<String> distinct = new HashSet<>();
for (int i = 0; i < specialists.size(); i++) {
Specialist specialist = specialists.get(i);
SmsSpecialist specialist = specialists.get(i);
if (distinct.contains(specialist.getPhone())) {
continue;
}
@ -227,7 +227,7 @@ public class SmsBirthdayServiceImpl extends ServiceImpl<SmsBirthdayMapper, SmsBi
log.info("到达生日短信发送时间: {}, 开始执行发送任务", executionTime);
// 查询今天过生日的专家
List<Specialist> birthdaySpecialists = listBirthdayToday();
List<SmsSpecialist> birthdaySpecialists = listBirthdayToday();
if (birthdaySpecialists.isEmpty()) {
log.info("今天没有专家过生日,无需发送生日短信");

View File

@ -3,12 +3,12 @@ package com.whdc.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.whdc.mapper.SmsLogMapper;
import com.whdc.mapper.SmsTaskMapper;
import com.whdc.mapper.SpecialistMapper;
import com.whdc.mapper.SmsHolidayMapper;
import com.whdc.mapper.SmsSpecialistMapper;
import com.whdc.model.entity.SmsLog;
import com.whdc.model.entity.SmsTask;
import com.whdc.model.entity.Specialist;
import com.whdc.service.ISmsTaskService;
import com.whdc.model.entity.SmsHoliday;
import com.whdc.model.entity.SmsSpecialist;
import com.whdc.service.ISmsHolidayService;
import com.whdc.utils.SmsHelper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
@ -32,10 +32,10 @@ import java.util.concurrent.atomic.AtomicBoolean;
*/
@Service
@Slf4j
public class SmsTaskServiceImpl extends ServiceImpl<SmsTaskMapper, SmsTask> implements ISmsTaskService {
public class SmsHolidayServiceImpl extends ServiceImpl<SmsHolidayMapper, SmsHoliday> implements ISmsHolidayService {
@Autowired
private SpecialistMapper specialistMapper;
private SmsSpecialistMapper specialistMapper;
@Autowired
private SmsLogMapper smsLogMapper;
@ -47,18 +47,18 @@ public class SmsTaskServiceImpl extends ServiceImpl<SmsTaskMapper, SmsTask> impl
private final Map<Long, AtomicBoolean> taskSmsSentToday = new ConcurrentHashMap<>();
@Override
public List<SmsTask> listActiveTasks() {
public List<SmsHoliday> listActiveTasks() {
try {
LocalDate today = LocalDate.now();
// 查询当前活动中的主题日短信任务
LambdaQueryWrapper<SmsTask> queryWrapper = new LambdaQueryWrapper<>();
LambdaQueryWrapper<SmsHoliday> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper
.eq(SmsTask::getStatus, 1) // 1:有效
.le(SmsTask::getStartDate, today) // 开始日期小于等于今天
.ge(SmsTask::getEndDate, today); // 结束日期大于等于今天
.eq(SmsHoliday::getStatus, 1) // 1:有效
.le(SmsHoliday::getStartDate, today) // 开始日期小于等于今天
.ge(SmsHoliday::getEndDate, today); // 结束日期大于等于今天
List<SmsTask> tasks = this.list(queryWrapper);
List<SmsHoliday> tasks = this.list(queryWrapper);
return tasks != null ? tasks : Collections.emptyList();
} catch (Exception e) {
log.error("查询活动中的主题日短信任务失败: {}", e.getMessage(), e);
@ -67,19 +67,19 @@ public class SmsTaskServiceImpl extends ServiceImpl<SmsTaskMapper, SmsTask> impl
}
@Override
public List<SmsTask> listTodayTasks() {
public List<SmsHoliday> listTodayTasks() {
try {
// 获取当前活动中的任务
List<SmsTask> activeTasks = listActiveTasks();
List<SmsHoliday> activeTasks = listActiveTasks();
if (activeTasks.isEmpty()) {
return Collections.emptyList();
}
LocalDate today = LocalDate.now();
List<SmsTask> todayTasks = new java.util.ArrayList<>();
List<SmsHoliday> todayTasks = new java.util.ArrayList<>();
// 筛选今天需要执行的任务
for (SmsTask task : activeTasks) {
for (SmsHoliday task : activeTasks) {
// 检查是否已经发送过
AtomicBoolean sentFlag = taskSmsSentToday.computeIfAbsent(task.getId(), k -> new AtomicBoolean(false));
if (sentFlag.get()) {
@ -118,14 +118,14 @@ public class SmsTaskServiceImpl extends ServiceImpl<SmsTaskMapper, SmsTask> impl
}
@Override
public void sendThemeSms(SmsTask smsTask) {
public void sendThemeSms(SmsHoliday smsTask) {
if (smsTask == null) {
log.warn("主题日短信任务为空");
return;
}
// 获取所有有效专家
List<Specialist> specialists = getValidSpecialists();
List<SmsSpecialist> specialists = getValidSpecialists();
if (specialists.isEmpty()) {
log.info("没有有效专家,跳过主题日短信发送");
return;
@ -142,7 +142,7 @@ public class SmsTaskServiceImpl extends ServiceImpl<SmsTaskMapper, SmsTask> impl
log.info("开始向{}位专家发送主题日短信[{}]", totalSpecialists, smsTask.getSubjectName());
for (int i = 0; i < specialists.size(); i++) {
Specialist specialist = specialists.get(i);
SmsSpecialist specialist = specialists.get(i);
// 替换模板中的占位符
String content = template.replace("{姓名}", specialist.getName())
.replace("{主题}", smsTask.getSubjectName());
@ -211,14 +211,14 @@ public class SmsTaskServiceImpl extends ServiceImpl<SmsTaskMapper, SmsTask> impl
}
@Override
public void sendBatchThemeSms(List<SmsTask> smsTasks) {
public void sendBatchThemeSms(List<SmsHoliday> smsTasks) {
if (smsTasks == null || smsTasks.isEmpty()) {
log.info("没有需要发送的主题日短信任务");
return;
}
log.info("开始批量发送{}个主题日短信任务", smsTasks.size());
for (SmsTask task : smsTasks) {
for (SmsHoliday task : smsTasks) {
try {
sendThemeSms(task);
} catch (Exception e) {
@ -231,13 +231,13 @@ public class SmsTaskServiceImpl extends ServiceImpl<SmsTaskMapper, SmsTask> impl
/**
*
*/
private List<Specialist> getValidSpecialists() {
private List<SmsSpecialist> getValidSpecialists() {
try {
LambdaQueryWrapper<Specialist> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(Specialist::getStatus, 1); // 1:有效
queryWrapper.isNotNull(Specialist::getPhone); // 手机号不为空
LambdaQueryWrapper<SmsSpecialist> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(SmsSpecialist::getStatus, 1); // 1:有效
queryWrapper.isNotNull(SmsSpecialist::getPhone); // 手机号不为空
List<Specialist> specialists = specialistMapper.selectList(queryWrapper);
List<SmsSpecialist> specialists = specialistMapper.selectList(queryWrapper);
return specialists != null ? specialists : Collections.emptyList();
} catch (Exception e) {
log.error("查询有效专家失败: {}", e.getMessage(), e);
@ -253,7 +253,7 @@ public class SmsTaskServiceImpl extends ServiceImpl<SmsTaskMapper, SmsTask> impl
public void checkAndSendThemeSms() {
try {
// 查询今日需要执行的主题日任务
List<SmsTask> todayTasks = listTodayTasks();
List<SmsHoliday> todayTasks = listTodayTasks();
if (todayTasks.isEmpty()) {
log.debug("今日没有需要执行的主题日短信任务");

View File

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

View File

@ -1,17 +0,0 @@
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 {
}

View File

@ -1,10 +1,8 @@
package com.whdc.service.impl;
import com.whdc.model.entity.Specialist;
import com.whdc.model.entity.SmsSpecialist;
import com.whdc.utils.SmsHelper;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;
import java.util.Arrays;
@ -29,13 +27,13 @@ public class BirthdaySmsServiceTest {
System.out.println("=== 开始测试生日短信发送功能 ===");
// 创建测试专家数据
Specialist specialist = new Specialist();
SmsSpecialist specialist = new SmsSpecialist();
specialist.setName("唐威");
// specialist.setPhone("18154318312");
specialist.setPhone("15671545233");
specialist.setStatus(1);
List<Specialist> specialists = Arrays.asList(specialist);
List<SmsSpecialist> specialists = Arrays.asList(specialist);
System.out.println("专家信息:");
System.out.println("姓名:" + specialist.getName());
@ -61,10 +59,10 @@ public class BirthdaySmsServiceTest {
/**
* 使
*/
private void testSendWithTemplate(List<Specialist> specialists, String template) {
private void testSendWithTemplate(List<SmsSpecialist> specialists, String template) {
System.out.println("开始使用模板发送短信...");
for (Specialist specialist : specialists) {
for (SmsSpecialist specialist : specialists) {
try {
// 替换模板中的占位符
String content = template.replace("{姓名}", specialist.getName());