package jnpf.limsService;
|
|
import jnpf.base.service.SuperService;
|
import jnpf.limsEntity.LimsModifySignPasswordParam;
|
import jnpf.limsEntity.LimsSignEntity;
|
import jnpf.limsEntity.LimsSignUsageTarget;
|
import jnpf.limsEntity.LimsSignVerifyParam;
|
import jnpf.limsEntity.SignOpType;
|
|
import java.util.Collection;
|
|
/**
|
* LIMS 电子签名服务。
|
* 校验账户 + 签名密码后落一条 lims_sign,返回主键作为 biz_sign 凭证给前端。
|
*/
|
public interface LimsSignService extends SuperService<LimsSignEntity> {
|
|
/**
|
* 校验签名并落 lims_sign 一条,返回新记录的主键 id(即给前端的 biz_sign)。
|
*
|
* <p>校验链:
|
* <ol>
|
* <li>opType 必须在 {@link jnpf.limsEntity.SignOpType} 枚举内</li>
|
* <li>accountName 必须等于当前 session 用户的 account(防代签)</li>
|
* <li>note 非空(前端可填 "N/A")</li>
|
* <li>查 lims_user_sign_password by user_id;无记录 → 抛 "未初始化签名密码"</li>
|
* <li>password_hash = Md5(password + secretkey.toLowerCase()) 比对</li>
|
* <li>校验全通过后插入 lims_sign,返回 id</li>
|
* </ol>
|
*
|
* @return lims_sign 主键 id
|
* @throws jnpf.exception.DataException 校验失败
|
*/
|
String verifyAndRecord(LimsSignVerifyParam param);
|
|
/**
|
* 校验指定用户签名并落 lims_sign 一条。
|
*
|
* <p>与 {@link #verifyAndRecord(LimsSignVerifyParam)} 的差异:
|
* <ul>
|
* <li>allowSelf 不为 yes 时,accountName 对应的用户不能是当前 session 用户</li>
|
* <li>按 accountName 查询目标用户,并校验目标用户的签名密码</li>
|
* <li>签名记录的 creatorUserId 写入目标用户 id</li>
|
* </ul>
|
*
|
* @return 校验通过后新建的签名记录
|
*/
|
LimsSignEntity verifyUserAndRecord(LimsSignVerifyParam param);
|
|
/**
|
* 给所有未软删 base_user 批量初始化签名密码 = "123456"。
|
* 已有 lims_user_sign_password 记录的跳过。每个用户独立生成 secretkey。
|
*
|
* @return [插入条数, 跳过条数]
|
*/
|
int[] initAllUsers();
|
|
/**
|
* 修改 / 初始化当前登录用户的签名密码。
|
*
|
* <p>校验链:
|
* <ol>
|
* <li>code + timestamp 命中图形验证码缓存(不区分大小写)</li>
|
* <li>当前 session 用户存在</li>
|
* <li>accountPassword 通过 Md5(accountPassword + secretkey) 比对 base_user.f_password</li>
|
* <li>password / repeatPassword 均非空且相等</li>
|
* <li>生成新的 secretkey 与 hash,写入 / 更新 lims_user_sign_password,刷新 last_reset_time</li>
|
* </ol>
|
*
|
* <p>用户首次设置签名密码(未存在 lims_user_sign_password 记录)和后续修改走同一接口,
|
* 行为分别为 INSERT 与 UPDATE。
|
*
|
* @throws jnpf.exception.DataException 任一校验失败
|
*/
|
void modifySignPassword(LimsModifySignPasswordParam param);
|
|
/**
|
* 校验业务侧传入的 biz_sign(即 lims_sign 主键)真实有效。
|
*
|
* <p>op_type 与 data_id 各自独立支持 lazy / eager(自方案 C 起):
|
* <ul>
|
* <li>字段为空 → 仅在返回实体中补全业务期望值,暂不写库</li>
|
* <li>字段已有值 → 严格校验与业务期望匹配,不符抛 DataException</li>
|
* </ul>
|
* 真正认领由 {@link #recordSignUsage} 在业务成功后原子完成,避免状态冲突时提前消费签名。
|
* 已有 {@code extra_json} 的签名视为已消费,必须重新签名,不能跨业务周期复用。
|
*
|
* <p>expectedDataId 传 null = 业务接口不需要 data_id 锚点(如 jiance-task 批量类),
|
* 此时完全跳过 data_id 校验,保留 verify 时的原值不动。
|
*
|
* <p>签名人始终校验:必须等于当前 session 用户(防别人签的被偷用)。
|
*
|
* @param signId 前端回传的 biz_sign(lims_sign 主键)
|
* @param expectedOpType 业务期望的操作类型
|
* @param expectedDataId 业务期望的 data_id;传 null 表示不锚 data_id
|
* @return 校验通过的签名记录
|
*/
|
LimsSignEntity requireValidSign(String signId, SignOpType expectedOpType, String expectedDataId);
|
|
/**
|
* 在业务写库成功后记录签名被实际使用的事实。
|
*
|
* <p>只接受业务 service 返回的实际成功目标;请求中因状态、权限或并发被跳过的目标不得传入。
|
* 实际目标为空时不认领签名、不更新 {@code lims_sign.extra_json},也不生成 {@code SIGN_USED}。
|
* 非空时先通过条件更新一次性原子认领签名,再将事件交给 AuditTxHolder 在事务提交后发布;
|
* 已消费签名、认领冲突或结果保存失败会标记当前事务回滚。
|
*/
|
void recordSignUsage(LimsSignEntity sign,
|
SignOpType opType,
|
Collection<String> requestedTargetIds,
|
Collection<LimsSignUsageTarget> actualTargets);
|
|
/**
|
* 只做签名的原子认领,<b>不发审计事件</b>。
|
*
|
* <p>给「签名事实由别处记录」的调用方用——当前是在线表单路径:表单保存本身已经产生层 0
|
* 事件,层 0 会据表单里的签名字段补写一条签名事件;这里再发一条 {@code SIGN_USED}
|
* 就是同一次签名两条证据。
|
*
|
* <p><b>认领逻辑必须保留</b>:它是「签名单次消费」的防重放护栏(ed4d908),
|
* 去掉等于同一个签名可以反复使用。
|
*
|
* <p>与 {@link #recordSignUsage} 的关系是「同一段认领 + 是否再发事件」:
|
* {@code recordSignUsage} 内部就调本方法,两处认领逻辑只有一份,不会各自漂移。
|
* 认领的全部前置条件(空目标不认领、认领冲突标记事务回滚)与 {@code recordSignUsage} 完全一致。
|
*/
|
void claimSignUsageOnly(LimsSignEntity sign,
|
SignOpType opType,
|
Collection<String> requestedTargetIds,
|
Collection<LimsSignUsageTarget> actualTargets);
|
|
/**
|
* 把任意结构数据序列化为 JSON 后回写到 lims_sign.extra_json。
|
*
|
* <p>典型用法:
|
* <ul>
|
* <li>jiance-task 批量类把 ids 包成 {"targets":[...]} 落库</li>
|
* <li>业务想加结构化操作日志:{"targets":[...],"comments":"..."}</li>
|
* </ul>
|
*
|
* <p>extra 为 null 时不更新。重复调用会覆盖(业务最新一次最权威)。
|
*
|
* @param signId 签名记录主键(即 biz_sign)
|
* @param extra 任意可序列化对象(Map / List / POJO 都可)
|
*/
|
void attachExtra(String signId, Object extra);
|
}
|