电子签名
This commit is contained in:
215
docs/electronic_signature_api.md
Normal file
215
docs/electronic_signature_api.md
Normal file
@@ -0,0 +1,215 @@
|
|||||||
|
# 电子签名后端对接说明
|
||||||
|
|
||||||
|
## 目标
|
||||||
|
|
||||||
|
支持前端在“点击使用电子签名”时,自动获取当前登录人员已配置的电子签名并回填。
|
||||||
|
|
||||||
|
当当前人员未配置电子签名时,后端返回提示:
|
||||||
|
|
||||||
|
`暂未设置电子签名,请在个人资料内设置后重试或使用手动签名`
|
||||||
|
|
||||||
|
## 数据设计
|
||||||
|
|
||||||
|
### 表名
|
||||||
|
|
||||||
|
`sys_user_electronic_signature`
|
||||||
|
|
||||||
|
### 核心设计说明
|
||||||
|
|
||||||
|
- 一条记录对应“当前登录人员”的一份电子签名配置
|
||||||
|
- 人员唯一性通过 `tenant_id + person_key` 控制
|
||||||
|
- `person_key` 生成规则:`loginPort:companyId:businessUserId`
|
||||||
|
- 当 `businessUserId` 为空时,回退为 `loginPort:companyId:userId`
|
||||||
|
- 签名文件本体继续复用现有 OSS 表,不重复存文件内容,只存 `sign_oss_id`
|
||||||
|
- 支持“清空签名”:保留记录,将 `status` 置为 `0`,并清空 `sign_oss_id`
|
||||||
|
|
||||||
|
### 主要字段
|
||||||
|
|
||||||
|
- `person_key`:当前登录人员唯一键
|
||||||
|
- `user_id`:系统用户 ID
|
||||||
|
- `business_user_id`:业务人员 ID,例如驾驶员/安全员 ID
|
||||||
|
- `company_id`:当前企业 ID
|
||||||
|
- `login_port`:当前登录端口
|
||||||
|
- `sign_oss_id`:电子签名图片 OSS ID
|
||||||
|
- `sign_name`:签署人名称快照
|
||||||
|
- `status`:`1=已设置`,`0=未设置`
|
||||||
|
|
||||||
|
建表脚本见:
|
||||||
|
|
||||||
|
- `sql/1289/3_user_electronic_signature.sql`
|
||||||
|
|
||||||
|
## 接口列表
|
||||||
|
|
||||||
|
统一前缀:
|
||||||
|
|
||||||
|
- `/system/user/profile`
|
||||||
|
|
||||||
|
### 1. 查询当前登录人员电子签名信息
|
||||||
|
|
||||||
|
- 方法:`GET`
|
||||||
|
- 路径:`/system/user/profile/electronic-signature/info`
|
||||||
|
- 用途:个人资料页进入时查询当前签名配置状态
|
||||||
|
- 特点:即使未配置,也返回成功,前端通过 `data.configured` 判断
|
||||||
|
|
||||||
|
响应示例:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 200,
|
||||||
|
"msg": "操作成功",
|
||||||
|
"data": {
|
||||||
|
"id": 1,
|
||||||
|
"configured": true,
|
||||||
|
"personKey": "port-driver:1001:DRV0001",
|
||||||
|
"userId": 20001,
|
||||||
|
"businessUserId": "DRV0001",
|
||||||
|
"companyId": 1001,
|
||||||
|
"loginPort": "port-driver",
|
||||||
|
"signOssId": 98765,
|
||||||
|
"signUrl": "https://xxx/signature.png",
|
||||||
|
"signName": "张三",
|
||||||
|
"status": "1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
未配置时示例:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 200,
|
||||||
|
"msg": "操作成功",
|
||||||
|
"data": {
|
||||||
|
"configured": false,
|
||||||
|
"personKey": "port-driver:1001:DRV0001",
|
||||||
|
"userId": 20001,
|
||||||
|
"businessUserId": "DRV0001",
|
||||||
|
"companyId": 1001,
|
||||||
|
"loginPort": "port-driver",
|
||||||
|
"signOssId": null,
|
||||||
|
"signUrl": null,
|
||||||
|
"signName": "张三",
|
||||||
|
"status": "0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. 业务页获取当前电子签名并回填
|
||||||
|
|
||||||
|
- 方法:`GET`
|
||||||
|
- 路径:`/system/user/profile/electronic-signature/current`
|
||||||
|
- 用途:点击“使用电子签名”时直接调用
|
||||||
|
- 特点:已配置时返回签名信息;未配置时直接返回失败提示,前端弹出 `msg` 即可
|
||||||
|
|
||||||
|
已配置响应示例:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 200,
|
||||||
|
"msg": "操作成功",
|
||||||
|
"data": {
|
||||||
|
"configured": true,
|
||||||
|
"signOssId": 98765,
|
||||||
|
"signUrl": "https://xxx/signature.png",
|
||||||
|
"signName": "张三"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
未配置响应示例:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 500,
|
||||||
|
"msg": "暂未设置电子签名,请在个人资料内设置后重试或使用手动签名",
|
||||||
|
"data": null
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
前端建议处理:
|
||||||
|
|
||||||
|
- 当接口成功时,将 `data.signUrl` 回填到下方签名展示区域
|
||||||
|
- 同时保留 `data.signOssId`,提交业务表单时直接透传
|
||||||
|
- 当接口失败时,直接提示后端返回的 `msg`
|
||||||
|
|
||||||
|
### 3. 保存当前登录人员电子签名
|
||||||
|
|
||||||
|
- 方法:`PUT`
|
||||||
|
- 路径:`/system/user/profile/electronic-signature`
|
||||||
|
- 用途:个人资料页设置或更换电子签名
|
||||||
|
|
||||||
|
请求参数:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"signOssId": 98765
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
说明:
|
||||||
|
|
||||||
|
- `signOssId` 必填
|
||||||
|
- 文件需要先通过现有 OSS 上传接口上传成功
|
||||||
|
- 后端会校验该文件是否存在,且是否为图片格式
|
||||||
|
|
||||||
|
成功响应示例:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 200,
|
||||||
|
"msg": "操作成功",
|
||||||
|
"data": {
|
||||||
|
"configured": true,
|
||||||
|
"signOssId": 98765,
|
||||||
|
"signUrl": "https://xxx/signature.png",
|
||||||
|
"signName": "张三",
|
||||||
|
"status": "1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. 清空当前登录人员电子签名
|
||||||
|
|
||||||
|
- 方法:`DELETE`
|
||||||
|
- 路径:`/system/user/profile/electronic-signature`
|
||||||
|
- 用途:个人资料页删除当前电子签名配置
|
||||||
|
|
||||||
|
成功响应示例:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 200,
|
||||||
|
"msg": "操作成功",
|
||||||
|
"data": null
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 与前端交互建议
|
||||||
|
|
||||||
|
### 个人资料页
|
||||||
|
|
||||||
|
1. 页面加载时调用 `GET /electronic-signature/info`
|
||||||
|
2. 若 `configured = true`,展示当前签名图片
|
||||||
|
3. 用户更换签名时,先调用现有 OSS 上传接口,再把返回的 `ossId` 提交到保存接口
|
||||||
|
4. 用户删除签名时,调用清空接口
|
||||||
|
|
||||||
|
### 业务签署页
|
||||||
|
|
||||||
|
1. 点击“使用电子签名”
|
||||||
|
2. 调用 `GET /electronic-signature/current`
|
||||||
|
3. 若成功:
|
||||||
|
- 回填 `signUrl`
|
||||||
|
- 保存 `signOssId`
|
||||||
|
4. 若失败:
|
||||||
|
- 直接提示 `msg`
|
||||||
|
- 保留“手动签名”入口
|
||||||
|
|
||||||
|
## 依赖的现有上传接口
|
||||||
|
|
||||||
|
上传签名图片时继续复用现有 OSS 上传能力:
|
||||||
|
|
||||||
|
- 方法:`POST`
|
||||||
|
- 路径:`/resource/oss/upload`
|
||||||
|
- 表单字段:`file`
|
||||||
|
|
||||||
|
返回示例中的 `data.ossId` 即为后续保存电子签名所需的 `signOssId`。
|
||||||
25
sql/1289/3_user_electronic_signature.sql
Normal file
25
sql/1289/3_user_electronic_signature.sql
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
CREATE TABLE IF NOT EXISTS `sys_user_electronic_signature` (
|
||||||
|
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
|
||||||
|
`tenant_id` varchar(20) NOT NULL DEFAULT '000000' COMMENT '租户编号',
|
||||||
|
`person_key` varchar(128) NOT NULL COMMENT '人员唯一标识,规则:loginPort:companyId:businessUserId,业务ID为空时回退为 userId',
|
||||||
|
`user_id` bigint NOT NULL COMMENT '系统用户ID',
|
||||||
|
`business_user_id` varchar(64) DEFAULT NULL COMMENT '业务人员ID',
|
||||||
|
`company_id` bigint DEFAULT NULL COMMENT '企业ID',
|
||||||
|
`login_port` varchar(64) NOT NULL COMMENT '登录端口',
|
||||||
|
`sign_oss_id` bigint DEFAULT NULL COMMENT '电子签名图片OSS ID',
|
||||||
|
`sign_name` varchar(64) DEFAULT NULL COMMENT '签署人名称快照',
|
||||||
|
`status` char(1) NOT NULL DEFAULT '1' COMMENT '状态:1=已设置 0=未设置',
|
||||||
|
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
|
||||||
|
`create_dept` bigint DEFAULT NULL COMMENT '创建部门',
|
||||||
|
`create_by` bigint DEFAULT NULL COMMENT '创建人',
|
||||||
|
`create_by_name` varchar(64) DEFAULT NULL COMMENT '创建人名称',
|
||||||
|
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
|
||||||
|
`update_by` bigint DEFAULT NULL COMMENT '更新人',
|
||||||
|
`update_by_name` varchar(64) DEFAULT NULL COMMENT '更新人名称',
|
||||||
|
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
|
||||||
|
PRIMARY KEY (`id`),
|
||||||
|
UNIQUE KEY `uk_tenant_person_key` (`tenant_id`, `person_key`),
|
||||||
|
KEY `idx_user_id` (`user_id`),
|
||||||
|
KEY `idx_business_user_id` (`business_user_id`),
|
||||||
|
KEY `idx_company_id` (`company_id`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='用户电子签名配置表';
|
||||||
@@ -17,11 +17,14 @@ import org.dromara.common.mybatis.helper.DataPermissionHelper;
|
|||||||
import org.dromara.common.satoken.utils.LoginHelper;
|
import org.dromara.common.satoken.utils.LoginHelper;
|
||||||
import org.dromara.common.web.core.BaseController;
|
import org.dromara.common.web.core.BaseController;
|
||||||
import org.dromara.system.domain.bo.SysUserBo;
|
import org.dromara.system.domain.bo.SysUserBo;
|
||||||
|
import org.dromara.system.domain.bo.SysUserElectronicSignatureBo;
|
||||||
import org.dromara.system.domain.bo.SysUserPasswordBo;
|
import org.dromara.system.domain.bo.SysUserPasswordBo;
|
||||||
import org.dromara.system.domain.bo.SysUserProfileBo;
|
import org.dromara.system.domain.bo.SysUserProfileBo;
|
||||||
import org.dromara.system.domain.vo.ProfileUserVo;
|
import org.dromara.system.domain.vo.ProfileUserVo;
|
||||||
import org.dromara.system.domain.vo.SysOssVo;
|
import org.dromara.system.domain.vo.SysOssVo;
|
||||||
|
import org.dromara.system.domain.vo.SysUserElectronicSignatureVo;
|
||||||
import org.dromara.system.domain.vo.SysUserVo;
|
import org.dromara.system.domain.vo.SysUserVo;
|
||||||
|
import org.dromara.system.service.ISysUserElectronicSignatureService;
|
||||||
import org.dromara.system.service.ISysOssService;
|
import org.dromara.system.service.ISysOssService;
|
||||||
import org.dromara.system.service.ISysUserService;
|
import org.dromara.system.service.ISysUserService;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
@@ -45,6 +48,7 @@ public class SysProfileController extends BaseController {
|
|||||||
private final ISysUserService userService;
|
private final ISysUserService userService;
|
||||||
private final ISysOssService ossService;
|
private final ISysOssService ossService;
|
||||||
private final ISysUserLoginPortService sysUserLoginPortService;
|
private final ISysUserLoginPortService sysUserLoginPortService;
|
||||||
|
private final ISysUserElectronicSignatureService userElectronicSignatureService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 个人信息
|
* 个人信息
|
||||||
@@ -93,6 +97,46 @@ public class SysProfileController extends BaseController {
|
|||||||
return R.fail("修改个人信息异常,请联系管理员");
|
return R.fail("修改个人信息异常,请联系管理员");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 当前登录人员电子签名信息
|
||||||
|
*/
|
||||||
|
@GetMapping("/electronic-signature/info")
|
||||||
|
public R<SysUserElectronicSignatureVo> electronicSignatureInfo() {
|
||||||
|
return R.ok(userElectronicSignatureService.getCurrentUserSignature());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取当前登录人员可直接用于业务回填的电子签名
|
||||||
|
*/
|
||||||
|
@GetMapping("/electronic-signature/current")
|
||||||
|
public R<SysUserElectronicSignatureVo> currentElectronicSignature() {
|
||||||
|
SysUserElectronicSignatureVo vo = userElectronicSignatureService.getCurrentUserSignature();
|
||||||
|
if (Boolean.FALSE.equals(vo.getConfigured())) {
|
||||||
|
return R.fail("暂未设置电子签名,请在个人资料内设置后重试或使用手动签名");
|
||||||
|
}
|
||||||
|
return R.ok(vo);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存当前登录人员电子签名
|
||||||
|
*/
|
||||||
|
@RepeatSubmit
|
||||||
|
@Log(title = "电子签名", businessType = BusinessType.UPDATE)
|
||||||
|
@PutMapping("/electronic-signature")
|
||||||
|
public R<SysUserElectronicSignatureVo> saveElectronicSignature(@Validated @RequestBody SysUserElectronicSignatureBo bo) {
|
||||||
|
return R.ok(userElectronicSignatureService.saveCurrentUserSignature(bo));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清空当前登录人员电子签名
|
||||||
|
*/
|
||||||
|
@RepeatSubmit
|
||||||
|
@Log(title = "电子签名", businessType = BusinessType.UPDATE)
|
||||||
|
@DeleteMapping("/electronic-signature")
|
||||||
|
public R<Void> clearElectronicSignature() {
|
||||||
|
return toAjax(userElectronicSignatureService.clearCurrentUserSignature());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 重置密码
|
* 重置密码
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -0,0 +1,74 @@
|
|||||||
|
package org.dromara.system.domain;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import org.dromara.common.tenant.core.TenantEntity;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户电子签名配置对象 sys_user_electronic_signature
|
||||||
|
*
|
||||||
|
* @author shihongwei
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@TableName("sys_user_electronic_signature")
|
||||||
|
public class SysUserElectronicSignature extends TenantEntity {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 主键ID
|
||||||
|
*/
|
||||||
|
@TableId(value = "id")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 人员唯一标识
|
||||||
|
*/
|
||||||
|
private String personKey;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 系统用户ID
|
||||||
|
*/
|
||||||
|
private Long userId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 业务人员ID
|
||||||
|
*/
|
||||||
|
private String businessUserId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 企业ID
|
||||||
|
*/
|
||||||
|
private Long companyId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 登录端口
|
||||||
|
*/
|
||||||
|
private String loginPort;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 电子签名图片OSS ID
|
||||||
|
*/
|
||||||
|
private Long signOssId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 签署人名称快照
|
||||||
|
*/
|
||||||
|
private String signName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 状态:1=已设置 0=未设置
|
||||||
|
*/
|
||||||
|
private String status;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 备注
|
||||||
|
*/
|
||||||
|
private String remark;
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package org.dromara.system.domain.bo;
|
||||||
|
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 当前登录人员电子签名保存参数
|
||||||
|
*
|
||||||
|
* @author shihongwei
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class SysUserElectronicSignatureBo {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 电子签名图片OSS ID
|
||||||
|
*/
|
||||||
|
@NotNull(message = "电子签名图片不能为空")
|
||||||
|
private Long signOssId;
|
||||||
|
}
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
package org.dromara.system.domain.vo;
|
||||||
|
|
||||||
|
import io.github.linpeilie.annotations.AutoMapper;
|
||||||
|
import lombok.Data;
|
||||||
|
import org.dromara.common.translation.annotation.Translation;
|
||||||
|
import org.dromara.common.translation.constant.TransConstant;
|
||||||
|
import org.dromara.system.domain.SysUserElectronicSignature;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 当前登录人员电子签名信息
|
||||||
|
*
|
||||||
|
* @author shihongwei
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@AutoMapper(target = SysUserElectronicSignature.class)
|
||||||
|
public class SysUserElectronicSignatureVo implements Serializable {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 主键ID
|
||||||
|
*/
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否已配置电子签名
|
||||||
|
*/
|
||||||
|
private Boolean configured;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 人员唯一标识
|
||||||
|
*/
|
||||||
|
private String personKey;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 系统用户ID
|
||||||
|
*/
|
||||||
|
private Long userId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 业务人员ID
|
||||||
|
*/
|
||||||
|
private String businessUserId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 企业ID
|
||||||
|
*/
|
||||||
|
private Long companyId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 登录端口
|
||||||
|
*/
|
||||||
|
private String loginPort;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 电子签名图片OSS ID
|
||||||
|
*/
|
||||||
|
private Long signOssId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 电子签名图片URL
|
||||||
|
*/
|
||||||
|
@Translation(type = TransConstant.OSS_ID_TO_URL, mapper = "signOssId")
|
||||||
|
private String signUrl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 签署人名称
|
||||||
|
*/
|
||||||
|
private String signName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 状态:1=已设置 0=未设置
|
||||||
|
*/
|
||||||
|
private String status;
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package org.dromara.system.mapper;
|
||||||
|
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
|
||||||
|
import org.dromara.system.domain.SysUserElectronicSignature;
|
||||||
|
import org.dromara.system.domain.vo.SysUserElectronicSignatureVo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户电子签名配置Mapper接口
|
||||||
|
*
|
||||||
|
* @author shihongwei
|
||||||
|
*/
|
||||||
|
@Mapper
|
||||||
|
public interface SysUserElectronicSignatureMapper extends BaseMapperPlus<SysUserElectronicSignature, SysUserElectronicSignatureVo> {
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
package org.dromara.system.service;
|
||||||
|
|
||||||
|
import org.dromara.system.domain.bo.SysUserElectronicSignatureBo;
|
||||||
|
import org.dromara.system.domain.vo.SysUserElectronicSignatureVo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 当前登录人员电子签名服务
|
||||||
|
*
|
||||||
|
* @author shihongwei
|
||||||
|
*/
|
||||||
|
public interface ISysUserElectronicSignatureService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取当前登录人员电子签名信息
|
||||||
|
*
|
||||||
|
* @return 电子签名信息
|
||||||
|
*/
|
||||||
|
SysUserElectronicSignatureVo getCurrentUserSignature();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存当前登录人员电子签名
|
||||||
|
*
|
||||||
|
* @param bo 保存参数
|
||||||
|
* @return 保存后的电子签名信息
|
||||||
|
*/
|
||||||
|
SysUserElectronicSignatureVo saveCurrentUserSignature(SysUserElectronicSignatureBo bo);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清空当前登录人员电子签名
|
||||||
|
*
|
||||||
|
* @return 是否成功
|
||||||
|
*/
|
||||||
|
Boolean clearCurrentUserSignature();
|
||||||
|
}
|
||||||
@@ -0,0 +1,166 @@
|
|||||||
|
package org.dromara.system.service.impl;
|
||||||
|
|
||||||
|
import cn.hutool.core.io.FileUtil;
|
||||||
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.dromara.common.core.domain.model.LoginUser;
|
||||||
|
import org.dromara.common.core.exception.ServiceException;
|
||||||
|
import org.dromara.common.core.utils.MapstructUtils;
|
||||||
|
import org.dromara.common.core.utils.StringUtils;
|
||||||
|
import org.dromara.common.core.utils.file.MimeTypeUtils;
|
||||||
|
import org.dromara.common.satoken.utils.LoginHelper;
|
||||||
|
import org.dromara.system.domain.SysUserElectronicSignature;
|
||||||
|
import org.dromara.system.domain.bo.SysUserElectronicSignatureBo;
|
||||||
|
import org.dromara.system.domain.vo.SysOssVo;
|
||||||
|
import org.dromara.system.domain.vo.SysUserElectronicSignatureVo;
|
||||||
|
import org.dromara.system.mapper.SysUserElectronicSignatureMapper;
|
||||||
|
import org.dromara.system.service.ISysOssService;
|
||||||
|
import org.dromara.system.service.ISysUserElectronicSignatureService;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 当前登录人员电子签名服务实现
|
||||||
|
*
|
||||||
|
* @author shihongwei
|
||||||
|
*/
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@Service
|
||||||
|
public class SysUserElectronicSignatureServiceImpl implements ISysUserElectronicSignatureService {
|
||||||
|
|
||||||
|
private static final String STATUS_ENABLED = "1";
|
||||||
|
private static final String STATUS_DISABLED = "0";
|
||||||
|
|
||||||
|
private final SysUserElectronicSignatureMapper baseMapper;
|
||||||
|
private final ISysOssService ossService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SysUserElectronicSignatureVo getCurrentUserSignature() {
|
||||||
|
LoginUser loginUser = getRequiredLoginUser();
|
||||||
|
String personKey = buildPersonKey(loginUser);
|
||||||
|
SysUserElectronicSignature entity = baseMapper.selectOne(
|
||||||
|
Wrappers.<SysUserElectronicSignature>lambdaQuery()
|
||||||
|
.eq(SysUserElectronicSignature::getTenantId, loginUser.getTenantId())
|
||||||
|
.eq(SysUserElectronicSignature::getPersonKey, personKey)
|
||||||
|
.last("limit 1")
|
||||||
|
);
|
||||||
|
if (entity == null) {
|
||||||
|
return buildEmptyVo(loginUser, personKey);
|
||||||
|
}
|
||||||
|
SysUserElectronicSignatureVo vo = MapstructUtils.convert(entity, SysUserElectronicSignatureVo.class);
|
||||||
|
vo.setConfigured(isConfigured(entity));
|
||||||
|
if (StringUtils.isBlank(vo.getSignName())) {
|
||||||
|
vo.setSignName(resolveSignName(loginUser));
|
||||||
|
}
|
||||||
|
return vo;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public SysUserElectronicSignatureVo saveCurrentUserSignature(SysUserElectronicSignatureBo bo) {
|
||||||
|
LoginUser loginUser = getRequiredLoginUser();
|
||||||
|
validateSignatureOss(bo.getSignOssId());
|
||||||
|
String personKey = buildPersonKey(loginUser);
|
||||||
|
SysUserElectronicSignature entity = baseMapper.selectOne(
|
||||||
|
Wrappers.<SysUserElectronicSignature>lambdaQuery()
|
||||||
|
.eq(SysUserElectronicSignature::getTenantId, loginUser.getTenantId())
|
||||||
|
.eq(SysUserElectronicSignature::getPersonKey, personKey)
|
||||||
|
.last("limit 1")
|
||||||
|
);
|
||||||
|
if (entity == null) {
|
||||||
|
entity = new SysUserElectronicSignature();
|
||||||
|
entity.setTenantId(loginUser.getTenantId());
|
||||||
|
entity.setPersonKey(personKey);
|
||||||
|
}
|
||||||
|
entity.setUserId(loginUser.getUserId());
|
||||||
|
entity.setBusinessUserId(loginUser.getBusinessUserId());
|
||||||
|
entity.setCompanyId(loginUser.getCompanyId());
|
||||||
|
entity.setLoginPort(defaultLoginPort(loginUser));
|
||||||
|
entity.setSignOssId(bo.getSignOssId());
|
||||||
|
entity.setSignName(resolveSignName(loginUser));
|
||||||
|
entity.setStatus(STATUS_ENABLED);
|
||||||
|
if (entity.getId() == null) {
|
||||||
|
baseMapper.insert(entity);
|
||||||
|
} else {
|
||||||
|
baseMapper.updateById(entity);
|
||||||
|
}
|
||||||
|
return getCurrentUserSignature();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public Boolean clearCurrentUserSignature() {
|
||||||
|
LoginUser loginUser = getRequiredLoginUser();
|
||||||
|
String personKey = buildPersonKey(loginUser);
|
||||||
|
SysUserElectronicSignature entity = baseMapper.selectOne(
|
||||||
|
Wrappers.<SysUserElectronicSignature>lambdaQuery()
|
||||||
|
.eq(SysUserElectronicSignature::getTenantId, loginUser.getTenantId())
|
||||||
|
.eq(SysUserElectronicSignature::getPersonKey, personKey)
|
||||||
|
.last("limit 1")
|
||||||
|
);
|
||||||
|
if (entity == null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
entity.setUserId(loginUser.getUserId());
|
||||||
|
entity.setBusinessUserId(loginUser.getBusinessUserId());
|
||||||
|
entity.setCompanyId(loginUser.getCompanyId());
|
||||||
|
entity.setLoginPort(defaultLoginPort(loginUser));
|
||||||
|
entity.setSignOssId(null);
|
||||||
|
entity.setSignName(resolveSignName(loginUser));
|
||||||
|
entity.setStatus(STATUS_DISABLED);
|
||||||
|
return baseMapper.updateById(entity) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isConfigured(SysUserElectronicSignature entity) {
|
||||||
|
return entity != null
|
||||||
|
&& STATUS_ENABLED.equals(entity.getStatus())
|
||||||
|
&& entity.getSignOssId() != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private SysUserElectronicSignatureVo buildEmptyVo(LoginUser loginUser, String personKey) {
|
||||||
|
SysUserElectronicSignatureVo vo = new SysUserElectronicSignatureVo();
|
||||||
|
vo.setConfigured(false);
|
||||||
|
vo.setPersonKey(personKey);
|
||||||
|
vo.setUserId(loginUser.getUserId());
|
||||||
|
vo.setBusinessUserId(loginUser.getBusinessUserId());
|
||||||
|
vo.setCompanyId(loginUser.getCompanyId());
|
||||||
|
vo.setLoginPort(defaultLoginPort(loginUser));
|
||||||
|
vo.setSignName(resolveSignName(loginUser));
|
||||||
|
vo.setStatus(STATUS_DISABLED);
|
||||||
|
return vo;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validateSignatureOss(Long signOssId) {
|
||||||
|
SysOssVo ossVo = ossService.getById(signOssId);
|
||||||
|
if (ossVo == null) {
|
||||||
|
throw new ServiceException("电子签名文件不存在,请重新上传后再试");
|
||||||
|
}
|
||||||
|
String fileName = StringUtils.defaultIfBlank(ossVo.getOriginalName(), ossVo.getFileName());
|
||||||
|
String extension = FileUtil.extName(fileName);
|
||||||
|
if (!StringUtils.equalsAnyIgnoreCase(extension, MimeTypeUtils.IMAGE_EXTENSION)) {
|
||||||
|
throw new ServiceException("电子签名必须为图片格式");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private LoginUser getRequiredLoginUser() {
|
||||||
|
LoginUser loginUser = LoginHelper.getLoginUser();
|
||||||
|
if (loginUser == null || loginUser.getUserId() == null) {
|
||||||
|
throw new ServiceException("用户未登录");
|
||||||
|
}
|
||||||
|
return loginUser;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String buildPersonKey(LoginUser loginUser) {
|
||||||
|
String businessUserId = StringUtils.defaultIfBlank(loginUser.getBusinessUserId(), String.valueOf(loginUser.getUserId()));
|
||||||
|
String companyId = loginUser.getCompanyId() == null ? "0" : String.valueOf(loginUser.getCompanyId());
|
||||||
|
return defaultLoginPort(loginUser) + ":" + companyId + ":" + businessUserId;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String defaultLoginPort(LoginUser loginUser) {
|
||||||
|
return StringUtils.defaultIfBlank(loginUser.getLoginPort(), "default");
|
||||||
|
}
|
||||||
|
|
||||||
|
private String resolveSignName(LoginUser loginUser) {
|
||||||
|
return StringUtils.defaultIfBlank(loginUser.getNickname(), loginUser.getUsername());
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user