Эх сурвалжийг харах

修复联系人提交和编辑功能

沐梦. 2 долоо хоног өмнө
parent
commit
6d3ebce582

+ 24 - 3
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/CustomerContactInfo.java

@@ -27,7 +27,8 @@ public class CustomerContactInfo extends TenantEntity {
     /**
      * 主键ID
      */
-    @TableId(value = "id")
+    // 使用 INPUT 类型,由 Service 层手动赋值(与主表 customer_contact 的 id 保持一致,实现强一对一绑定)
+    @TableId(value = "id", type = IdType.INPUT)
     private Long id;
 
     /**
@@ -94,7 +95,7 @@ public class CustomerContactInfo extends TenantEntity {
      * 家庭地址(市)ID
      */
     private Long homeCityId;
-    
+
     /**
      * 家庭地址(区)ID
      */
@@ -104,7 +105,27 @@ public class CustomerContactInfo extends TenantEntity {
      * 家庭详细地址
      */
     private String homeAddressDetail;
-    
+
+    /**
+     * 职位
+     */
+    private String position;
+
+    /**
+     * 项目角色
+     */
+    private Integer projectRole;
+
+    /**
+     * 公关情况
+     */
+    private String prStatus;
+
+    /**
+     * 是否关键人
+     */
+    private Integer isKeyPerson;
+
     /**
      * 平台标识
      */

+ 31 - 8
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/bo/CustomerContactBo.java

@@ -1,14 +1,11 @@
 package org.dromara.customer.domain.bo;
 
-import org.dromara.customer.domain.CustomerContact;
 import org.dromara.common.mybatis.core.domain.BaseEntity;
-import org.dromara.common.core.validate.AddGroup;
-import org.dromara.common.core.validate.EditGroup;
 import io.github.linpeilie.annotations.AutoMapper;
 import io.github.linpeilie.annotations.AutoMappers;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
-import jakarta.validation.constraints.*;
+import org.dromara.customer.domain.CustomerContact;
 import org.dromara.customer.domain.CustomerContactInfo;
 
 import java.util.Date;
@@ -43,7 +40,6 @@ public class CustomerContactBo extends BaseEntity {
     /**
      * 联系人姓名
      */
-//    @NotBlank(message = "联系人姓名不能为空", groups = {AddGroup.class, EditGroup.class})
     private String contactName;
 
     private String wechat;
@@ -51,7 +47,6 @@ public class CustomerContactBo extends BaseEntity {
     /**
      * 手机号码
      */
-//    @NotBlank(message = "手机号码不能为空", groups = {AddGroup.class, EditGroup.class})
     private String phone;
 
     /**
@@ -127,13 +122,16 @@ public class CustomerContactBo extends BaseEntity {
      */
     private String remark;
 
-    private String customerName;
-
     /**
      * 平台标识
      */
     private String platformCode;
 
+    /**
+     * 客户名称
+     */
+    private String customerName;
+
     /**
      * 客户编号
      */
@@ -144,6 +142,11 @@ public class CustomerContactBo extends BaseEntity {
      */
     private String type;
 
+    /**
+     * 项目编号
+     */
+    private String projectNo;
+
     /**
      * 年龄
      */
@@ -209,4 +212,24 @@ public class CustomerContactBo extends BaseEntity {
      */
     private String homeAddressDetail;
 
+    /**
+     * 职位
+     */
+    private String position;
+
+    /**
+     * 项目角色
+     */
+    private Integer projectRole;
+
+    /**
+     * 公关情况
+     */
+    private String prStatus;
+
+    /**
+     * 是否关键人
+     */
+    private Integer isKeyPerson;
+
 }

+ 36 - 1
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/vo/CustomerContactVo.java

@@ -13,6 +13,9 @@ import java.io.Serializable;
 import java.util.Date;
 
 
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+
 /**
  * 客户联系人信息视图对象 customer_contact
  *
@@ -30,18 +33,20 @@ public class CustomerContactVo implements Serializable {
     /**
      * 联系人ID
      */
+    @JsonSerialize(using = ToStringSerializer.class)
     @ExcelProperty(value = "联系人ID")
     private Long id;
 
     /*联系人编号*/
     private String contactNo;
 
-    /*系统用户id*/
+    @JsonSerialize(using = ToStringSerializer.class)
     private Long userId;
 
     /**
      * 所属客户ID
      */
+    @JsonSerialize(using = ToStringSerializer.class)
     @ExcelProperty(value = "所属客户ID")
     private Long customerId;
 
@@ -90,6 +95,7 @@ public class CustomerContactVo implements Serializable {
 
     private String roleName;
 
+    @JsonSerialize(using = ToStringSerializer.class)
     private Long deptId;
 
     private String deptName;
@@ -213,20 +219,49 @@ public class CustomerContactVo implements Serializable {
     /**
      * 家庭地址(省)ID
      */
+    @JsonSerialize(using = ToStringSerializer.class)
     private Long homeProvinceId;
 
     /**
      * 家庭地址(市)ID
      */
+    @JsonSerialize(using = ToStringSerializer.class)
     private Long homeCityId;
 
     /**
      * 家庭地址(区)ID
      */
+    @JsonSerialize(using = ToStringSerializer.class)
     private Long homeAreaId;
 
     /**
      * 家庭详细地址
      */
     private String homeAddressDetail;
+
+    /**
+     * 职位
+     */
+    @ExcelProperty(value = "职位")
+    private String position;
+
+    /**
+     * 项目角色
+     */
+    @ExcelProperty(value = "项目角色", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(dictType = "LXRJE0001")
+    private Integer projectRole;
+
+    /**
+     * 公关情况
+     */
+    @ExcelProperty(value = "公关情况")
+    private String prStatus;
+
+    /**
+     * 是否关键人
+     */
+    @ExcelProperty(value = "是否关键人", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(readConverterExp = "1=是,0=否")
+    private Integer isKeyPerson;
 }

+ 155 - 46
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/CustomerContactServiceImpl.java

@@ -73,12 +73,30 @@ public class CustomerContactServiceImpl extends ServiceImpl<CustomerContactMappe
     public CustomerContactVo queryById(Long id) {
         CustomerContactVo vo = baseMapper.selectVoById(id);
         if (vo != null) {
-            // 查询扩展信息
+            // 查询扩展信息 (固定 platformCode 为 crm)
             CustomerContactInfo info = contactInfoMapper.selectOne(new LambdaQueryWrapper<CustomerContactInfo>()
-                .eq(CustomerContactInfo::getContactId, id));
+                .eq(CustomerContactInfo::getContactId, id)
+                .eq(CustomerContactInfo::getPlatformCode, "crm"));
             if (info != null) {
-                // 将扩展信息字段合并到 VO 中
-                MapstructUtils.convert(info, vo);
+                // 显式合并扩展信息,确保回显成功率
+                vo.setType(info.getType());
+                vo.setAge(info.getAge());
+                vo.setNativePlace(info.getNativePlace());
+                vo.setJobStatus(info.getJobStatus());
+                vo.setJobContent(info.getJobContent());
+                vo.setFamilyStatus(info.getFamilyStatus());
+                vo.setHobby(info.getHobby());
+                vo.setCharacterTrait(info.getCharacterTrait());
+                vo.setIsSmoke(info.getIsSmoke());
+                vo.setIsDrink(info.getIsDrink());
+                vo.setHomeProvinceId(info.getHomeProvinceId());
+                vo.setHomeCityId(info.getHomeCityId());
+                vo.setHomeAreaId(info.getHomeAreaId());
+                vo.setHomeAddressDetail(info.getHomeAddressDetail());
+                vo.setPosition(info.getPosition());
+                vo.setProjectRole(info.getProjectRole());
+                vo.setPrStatus(info.getPrStatus());
+                vo.setIsKeyPerson(info.getIsKeyPerson());
             }
         }
         return vo;
@@ -116,6 +134,13 @@ public class CustomerContactServiceImpl extends ServiceImpl<CustomerContactMappe
                 ? new HashMap<>()
                 : remoteDeptService.selectDeptNameByIds(deptIds);
 
+            // 批量查询扩展信息 (固定 platformCode 为 crm)
+            Set<Long> contactIds = records.stream().map(CustomerContactVo::getId).collect(Collectors.toSet());
+            List<CustomerContactInfo> infoList = contactInfoMapper.selectList(new LambdaQueryWrapper<CustomerContactInfo>()
+                .in(CustomerContactInfo::getContactId, contactIds)
+                .eq(CustomerContactInfo::getPlatformCode, "crm"));
+            Map<Long, CustomerContactInfo> infoMap = infoList.stream().collect(Collectors.toMap(CustomerContactInfo::getContactId, i -> i, (k1, k2) -> k1));
+
             records.forEach(item -> {
                 item.setCustomerName(customerNameMap.get(item.getCustomerId()));
                 if (item.getDeptId() != null) {
@@ -124,6 +149,28 @@ public class CustomerContactServiceImpl extends ServiceImpl<CustomerContactMappe
                         item.setDeptName(remoteDeptName);
                     }
                 }
+                // 合并扩展信息
+                CustomerContactInfo info = infoMap.get(item.getId());
+                if (info != null) {
+                    item.setType(info.getType());
+                    item.setAge(info.getAge());
+                    item.setNativePlace(info.getNativePlace());
+                    item.setJobStatus(info.getJobStatus());
+                    item.setJobContent(info.getJobContent());
+                    item.setFamilyStatus(info.getFamilyStatus());
+                    item.setHobby(info.getHobby());
+                    item.setCharacterTrait(info.getCharacterTrait());
+                    item.setIsSmoke(info.getIsSmoke());
+                    item.setIsDrink(info.getIsDrink());
+                    item.setHomeProvinceId(info.getHomeProvinceId());
+                    item.setHomeCityId(info.getHomeCityId());
+                    item.setHomeAreaId(info.getHomeAreaId());
+                    item.setHomeAddressDetail(info.getHomeAddressDetail());
+                    item.setPosition(info.getPosition());
+                    item.setProjectRole(info.getProjectRole());
+                    item.setPrStatus(info.getPrStatus());
+                    item.setIsKeyPerson(info.getIsKeyPerson());
+                }
             });
         }
         return TableDataInfo.build(result);
@@ -138,14 +185,51 @@ public class CustomerContactServiceImpl extends ServiceImpl<CustomerContactMappe
     @Override
     public List<CustomerContactVo> queryList(CustomerContactBo bo) {
         LambdaQueryWrapper<CustomerContact> lqw = buildQueryWrapper(bo);
-        return baseMapper.selectVoList(lqw);
+        List<CustomerContactVo> list = baseMapper.selectVoList(lqw);
+        if (ObjectUtil.isNotEmpty(list)) {
+            // 批量查询扩展信息并合并 (固定 platformCode 为 crm)
+            Set<Long> contactIds = list.stream().map(CustomerContactVo::getId).collect(Collectors.toSet());
+            List<CustomerContactInfo> infoList = contactInfoMapper.selectList(Wrappers.lambdaQuery(CustomerContactInfo.class)
+                .in(CustomerContactInfo::getContactId, contactIds)
+                .eq(CustomerContactInfo::getPlatformCode, "crm"));
+            Map<Long, CustomerContactInfo> infoMap = infoList.stream().collect(Collectors.toMap(CustomerContactInfo::getContactId, i -> i, (k1, k2) -> k1));
+            
+            list.forEach(item -> {
+                CustomerContactInfo info = infoMap.get(item.getId());
+                if (info != null) {
+                    item.setType(info.getType());
+                    item.setAge(info.getAge());
+                    item.setNativePlace(info.getNativePlace());
+                    item.setJobStatus(info.getJobStatus());
+                    item.setJobContent(info.getJobContent());
+                    item.setFamilyStatus(info.getFamilyStatus());
+                    item.setHobby(info.getHobby());
+                    item.setCharacterTrait(info.getCharacterTrait());
+                    item.setIsSmoke(info.getIsSmoke());
+                    item.setIsDrink(info.getIsDrink());
+                    item.setHomeProvinceId(info.getHomeProvinceId());
+                    item.setHomeCityId(info.getHomeCityId());
+                    item.setHomeAreaId(info.getHomeAreaId());
+                    item.setHomeAddressDetail(info.getHomeAddressDetail());
+                    item.setPosition(info.getPosition());
+                    item.setProjectRole(info.getProjectRole());
+                    item.setPrStatus(info.getPrStatus());
+                    item.setIsKeyPerson(info.getIsKeyPerson());
+                }
+            });
+        }
+        return list;
     }
 
     private LambdaQueryWrapper<CustomerContact> buildQueryWrapper(CustomerContactBo bo) {
         Map<String, Object> params = bo.getParams();
         LambdaQueryWrapper<CustomerContact> lqw = Wrappers.lambdaQuery();
         lqw.orderByDesc(CustomerContact::getCreateTime);
-        lqw.eq(bo.getCustomerId() != null, CustomerContact::getCustomerId, bo.getCustomerId());
+        // 核心回显逻辑:如果传了项目编号,则必须匹配备注
+        if (StringUtils.isNotBlank(bo.getProjectNo())) {
+            lqw.like(CustomerContact::getRemark, bo.getProjectNo());
+        }
+
         lqw.like(StringUtils.isNotBlank(bo.getContactNo()), CustomerContact::getContactNo, bo.getContactNo());
         lqw.like(StringUtils.isNotBlank(bo.getContactName()), CustomerContact::getContactName, bo.getContactName());
         lqw.eq(StringUtils.isNotBlank(bo.getPhone()), CustomerContact::getPhone, bo.getPhone());
@@ -164,20 +248,20 @@ public class CustomerContactServiceImpl extends ServiceImpl<CustomerContactMappe
         lqw.like(StringUtils.isNotBlank(bo.getRoleName()), CustomerContact::getRoleName, bo.getRoleName());
         lqw.eq(StringUtils.isNotBlank(bo.getPlatformCode()), CustomerContact::getPlatformCode, bo.getPlatformCode());
 
-        if (ObjectUtil.isNotEmpty(bo.getCustomerName())) {
-            CustomerInfoVo customerInfoVo = customerInfoMapper.selectVoOne(new LambdaQueryWrapper<CustomerInfo>().eq(CustomerInfo::getCustomerName, bo.getCustomerName()));
-            if (ObjectUtil.isNotEmpty(customerInfoVo)) {
-                lqw.eq(CustomerContact::getCustomerId, customerInfoVo.getId());
-            } else {
-                lqw.eq(CustomerContact::getCustomerId, 0);
-            }
-        }
-        if (ObjectUtil.isNotEmpty(bo.getCustomerNo())) {
-            CustomerInfoVo customerInfoVo = customerInfoMapper.selectVoOne(new LambdaQueryWrapper<CustomerInfo>().eq(CustomerInfo::getCustomerNo, bo.getCustomerNo()));
-            if (ObjectUtil.isNotEmpty(customerInfoVo)) {
-                lqw.eq(CustomerContact::getCustomerId, customerInfoVo.getId());
-            } else {
-                lqw.eq(CustomerContact::getCustomerId, 0);
+        if (bo.getCustomerId() != null && bo.getCustomerId() != 0) {
+            lqw.eq(CustomerContact::getCustomerId, bo.getCustomerId());
+        } else if (bo.getCustomerId() == null) {
+            // 尝试通过名称或编号补全 ID 过滤
+            if (ObjectUtil.isNotEmpty(bo.getCustomerName())) {
+                CustomerInfoVo customerInfoVo = customerInfoMapper.selectVoOne(new LambdaQueryWrapper<CustomerInfo>().eq(CustomerInfo::getCustomerName, bo.getCustomerName()));
+                if (customerInfoVo != null) {
+                    lqw.eq(CustomerContact::getCustomerId, customerInfoVo.getId());
+                }
+            } else if (ObjectUtil.isNotEmpty(bo.getCustomerNo())) {
+                CustomerInfoVo customerInfoVo = customerInfoMapper.selectVoOne(new LambdaQueryWrapper<CustomerInfo>().eq(CustomerInfo::getCustomerNo, bo.getCustomerNo()));
+                if (customerInfoVo != null) {
+                    lqw.eq(CustomerContact::getCustomerId, customerInfoVo.getId());
+                }
             }
         }
         if (bo.getDeptId() != null) {
@@ -202,24 +286,30 @@ public class CustomerContactServiceImpl extends ServiceImpl<CustomerContactMappe
     @Transactional(rollbackFor = Exception.class)
     public Boolean insertByBo(CustomerContactBo bo) {
         syncDeptName(bo);
-        // 1. 获取并校验客户编号
-        String customerNo = null;
+        // 1. 获取并补全客户信息 (兼容通过 customerId 或 customerNo 传参)
+        String customerNo = bo.getCustomerNo();
         if (bo.getCustomerId() != null) {
             CustomerInfoVo customerInfoVo = customerInfoMapper.selectVoById(bo.getCustomerId());
-            if (customerInfoVo == null) {
-                log.error("客户不存在,无法创建联系人 (ID: " + bo.getCustomerId() + ")");
-                throw new RuntimeException("客户不存在,无法创建联系人 (ID: " + bo.getCustomerId() + ")");
+            if (customerInfoVo != null) {
+                customerNo = customerInfoVo.getCustomerNo();
             }
-
-            customerNo = customerInfoVo.getCustomerNo();
-
-            // 二次校验:防止 customerNo 本身为空
-            if (StringUtils.isBlank(customerNo)) {
-                log.error("客户编号为空,数据异常 (ID: " + bo.getCustomerId() + ")");
-                throw new RuntimeException("客户编号为空,数据异常 (ID: " + bo.getCustomerId() + ")");
+        } else if (StringUtils.isNotBlank(customerNo)) {
+            // 如果只有客户编号,则反查客户 ID
+            CustomerInfo customerInfo = customerInfoMapper.selectOne(new LambdaQueryWrapper<CustomerInfo>().eq(CustomerInfo::getCustomerNo, customerNo));
+            if (customerInfo != null) {
+                bo.setCustomerId(customerInfo.getId());
             }
         }
-        // 1. 准备创建系统用户的数据
+
+        // 校验关键信息
+        if (bo.getCustomerId() == null) {
+            throw new ServiceException("未关联有效客户,无法创建联系人");
+        }
+        if (StringUtils.isBlank(customerNo)) {
+            throw new ServiceException("客户编号缺失,无法生成联系人编号");
+        }
+
+        // 2. 准备创建系统用户的数据
         RemoteUserBo remoteUserBo = new RemoteUserBo();
         remoteUserBo.setNickName(bo.getContactName());
         remoteUserBo.setDeptId(bo.getDeptId());
@@ -230,42 +320,45 @@ public class CustomerContactServiceImpl extends ServiceImpl<CustomerContactMappe
         remoteUserBo.setUserSonType("3");
         remoteUserBo.setTenantId(LoginHelper.getTenantId());
         remoteUserBo.setRoleIds(new Long[]{bo.getRoleId()});
+        
         Long userId = null;
-        // 使用自定义方法查询
         CustomerContact customerContact = baseMapper.selectOneByPhoneIgnoreDelete(bo.getPhone());
 
         if (customerContact != null) {
-            // 如果查到了数据
             if ("1".equals(customerContact.getDelFlag())) {
-                // 情况 A:数据已删除 -> 复用原有的 userId
                 userId = customerContact.getUserId();
             } else {
-                // 情况 B:数据未删除 -> 报错,禁止重复
                 throw new ServiceException("该手机号已存在有效联系人,请勿重复添加");
             }
         } else {
-            // 情况 C:完全没数据 -> 创建新用户
             userId = remoteUserService.addUser(remoteUserBo);
         }
 
         if (userId == null) {
-            throw new ServiceException("创建系统用户失败" + userId);
+            throw new ServiceException("创建系统用户失败");
         }
 
         // 3. 生成联系人编号
-        // 1. 构造带客户编号的 Key,实现“每个客户独立计数”
         String seqKey = "customer_contact:contact_no:" + customerNo;
-
-        // 2. 调用工具类
         String seqId = SequenceUtils.nextPaddedIdStr(seqKey, Duration.ofDays(3650), 4);
-
-        // 3. 拼接最终结果
         String contactNo = "1" + customerNo + seqId;
 
+        // 根据用户要求:项目编号放在备注里面,用于详情页列表回显
+        if (StringUtils.isNotBlank(bo.getProjectNo())) {
+            String projectRemark = "项目编号:" + bo.getProjectNo();
+            if (StringUtils.isBlank(bo.getRemark())) {
+                bo.setRemark(projectRemark);
+            } else if (!bo.getRemark().contains(bo.getProjectNo())) {
+                bo.setRemark(bo.getRemark() + " (" + projectRemark + ")");
+            }
+        }
 
+        // 4. 转换并显式设置关键字段,确保插入成功
         CustomerContact add = MapstructUtils.convert(bo, CustomerContact.class);
+        add.setCustomerId(bo.getCustomerId()); // 显式设置,防止映射失败
         add.setContactNo(contactNo);
         add.setUserId(userId);
+        
         validEntityBeforeSave(add);
         boolean flag = baseMapper.insert(add) > 0;
         if (flag) {
@@ -273,10 +366,12 @@ public class CustomerContactServiceImpl extends ServiceImpl<CustomerContactMappe
             try {
                 // 保存扩展信息
                 CustomerContactInfo info = MapstructUtils.convert(bo, CustomerContactInfo.class);
+                info.setId(add.getId()); // 显式设置 ID,对应 IdType.INPUT
                 info.setContactId(add.getId());
+                info.setPlatformCode("crm"); // 固定平台标识
                 contactInfoMapper.insert(info);
             } catch (Exception e) {
-                log.warn("保存联系人扩展信息失败,可能表 customer_contact_info 尚未创建: {}", e.getMessage());
+                log.warn("保存联系人扩展信息失败: {}", e.getMessage());
             }
         }
         return flag;
@@ -292,6 +387,17 @@ public class CustomerContactServiceImpl extends ServiceImpl<CustomerContactMappe
     @Transactional(rollbackFor = Exception.class)
     public Boolean updateByBo(CustomerContactBo bo) {
         syncDeptName(bo);
+
+        // 补全备注关联逻辑,确保编辑后项目联系人回显不失效
+        if (StringUtils.isNotBlank(bo.getProjectNo())) {
+            String projectRemark = "项目编号:" + bo.getProjectNo();
+            if (StringUtils.isBlank(bo.getRemark())) {
+                bo.setRemark(projectRemark);
+            } else if (!bo.getRemark().contains(bo.getProjectNo())) {
+                bo.setRemark(bo.getRemark() + " (" + projectRemark + ")");
+            }
+        }
+
         CustomerContact update = MapstructUtils.convert(bo, CustomerContact.class);
         validEntityBeforeSave(update);
         //查询角色有变更,如果角色有变更,则需要更新用户角色
@@ -308,12 +414,15 @@ public class CustomerContactServiceImpl extends ServiceImpl<CustomerContactMappe
                 // 更新或插入扩展信息
                 CustomerContactInfo info = MapstructUtils.convert(bo, CustomerContactInfo.class);
                 info.setContactId(bo.getId());
+                info.setPlatformCode("crm"); // 固定平台标识
                 CustomerContactInfo exist = contactInfoMapper.selectOne(new LambdaQueryWrapper<CustomerContactInfo>()
-                    .eq(CustomerContactInfo::getContactId, bo.getId()));
+                    .eq(CustomerContactInfo::getContactId, bo.getId())
+                    .eq(CustomerContactInfo::getPlatformCode, "crm"));
                 if (exist != null) {
                     info.setId(exist.getId());
                     contactInfoMapper.updateById(info);
                 } else {
+                    info.setId(bo.getId()); // 显式设置 ID,确保 1:1 绑定
                     contactInfoMapper.insert(info);
                 }
             } catch (Exception e) {

+ 35 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysIndexController.java

@@ -0,0 +1,35 @@
+package org.dromara.system.controller.system;
+
+import cn.dev33.satoken.annotation.SaIgnore;
+import lombok.RequiredArgsConstructor;
+import org.dromara.common.core.domain.R;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * 首页/基础 接口
+ *
+ * @author Lion Li
+ */
+@SaIgnore
+@RequiredArgsConstructor
+@RestController
+public class SysIndexController {
+
+    /**
+     * 服务器健康检查
+     * 用于解决负载均衡或其他监控系统的健康检查请求
+     */
+    @GetMapping("/checkAliveServer")
+    public String checkAliveServer() {
+        return "Server is alive";
+    }
+
+    /**
+     * 系统索引
+     */
+    @GetMapping("/")
+    public String index() {
+        return "System is running";
+    }
+}