刘光辉
昨天 bb638871a7fb692d80f1b7a758f991dc0879002c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
package jnpf.bizcommon.onlyoffice.entity;
 
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
 
import java.util.Date;
 
/**
 * OnlyOffice 编辑会话(onlyoffice_session)。
 *
 * <p>一个文件一行,随保存递增 {@link #versionNo} 并轮换 {@link #docKey}。它承担两个职责:
 * <ol>
 *   <li><b>业务上下文的落脚点</b>——OnlyOffice 回调体字段是固定的一套,config 里的自定义
 *       字段不会回传,所以 bizModule/bizDataId 必须在签发 config 时落库,回调时靠 docKey 反查;</li>
 *   <li><b>编辑锁</b>——DS 默认行为就是协同(同 docKey 自动合并会话),本期不做协同,
 *       靠 lockUserId + lockHeartbeat 让第二个人只拿到只读 config。</li>
 * </ol>
 *
 * <p>表名前缀用能力名而非服务名(对齐 audit_events):能力会在服务间搬家,
 * 表名绑服务迟早名不符实。
 */
@Data
@TableName("onlyoffice_session")
public class OnlyOfficeSessionEntity {
 
    @TableId(value = "f_id")
    private String id;
 
    @TableField(value = "f_tenant_id", fill = FieldFill.INSERT_UPDATE)
    private String tenantId;
 
    /**
     * 交给 DS 的文档版本标识,md5(fileId + "_" + versionNo)。
     * 字符集只允许 [0-9a-zA-Z_-]、长度 ≤128,且必须与内容版本一一对应——
     * 内容变了不换 key,DS 会命中自身缓存返回旧内容。
     */
    @TableField("doc_key")
    private String docKey;
 
    /** jnpf-file 的文件标识(annex 类型下即磁盘文件名) */
    @TableField("file_id")
    private String fileId;
 
    /** 文件存储类型,默认 annex(表单附件) */
    @TableField("file_type")
    private String fileType;
 
    /** 原始文件名,做编辑器标题用 */
    @TableField("file_name")
    private String fileName;
 
    /** DS 的文档类型:word / cell / slide / pdf */
    @TableField("document_type")
    private String documentType;
 
    /** 业务归属模块,权限判定与审计留痕用 */
    @TableField("biz_module")
    private String bizModule;
 
    /** 业务归属记录 id */
    @TableField("biz_data_id")
    private String bizDataId;
 
    /** 内容版本号,保存成功后 +1;与 docKey 联动 */
    @TableField("version_no")
    private Integer versionNo;
 
    /** 会话状态,取值见 {@code SessionStatus} 常量 */
    @TableField("session_status")
    private Integer sessionStatus;
 
    /** 当前持有编辑锁的用户;为空表示无人编辑 */
    @TableField("lock_user_id")
    private String lockUserId;
 
    /** 锁心跳,随 status 1 回调刷新;超过 lock-timeout-minutes 视为失效 */
    @TableField("lock_heartbeat")
    private Date lockHeartbeat;
 
    /** 最近一次保存回写完成的时间 */
    @TableField("last_save_time")
    private Date lastSaveTime;
 
    /** 最近一次保存时 DS 报告的编辑者(回调 users 字段,逗号分隔) */
    @TableField("last_editor_ids")
    private String lastEditorIds;
 
    @TableField("f_version")
    private Integer version;
 
    @TableField("f_delete_mark")
    private Integer deleteMark;
 
    @TableField("f_delete_time")
    private Date deleteTime;
 
    @TableField("f_delete_user_id")
    private String deleteUserId;
 
    @TableField(value = "f_creator_user_id", fill = FieldFill.INSERT)
    private String creatorUserId;
 
    @TableField(value = "f_creator_time", fill = FieldFill.INSERT)
    private Date creatorTime;
 
    @TableField(value = "f_last_modify_user_id", fill = FieldFill.UPDATE)
    private String lastModifyUserId;
 
    @TableField(value = "f_last_modify_time", fill = FieldFill.UPDATE)
    private Date lastModifyTime;
 
    /** 会话状态取值 */
    public static final class SessionStatus {
        /** 空闲:无人打开,或已保存关闭 */
        public static final int IDLE = 0;
        /** 编辑中:已下发可编辑 config,锁生效 */
        public static final int EDITING = 1;
        /** 保存出错:DS 回调 status 3/7,需人工介入 */
        public static final int SAVE_FAILED = 3;
 
        private SessionStatus() {
        }
    }
}