刘光辉
2 小时以前 06f314545ac3514d7ce28939920866ae8188d31c
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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
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;
 
    /** ONLYOFFICE 业务场景;回调时用来选择场景专属保存策略 */
    @TableField("biz_scene")
    private String bizScene;
 
    /** 内容版本号,保存成功后 +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;
 
    /** 签批页另存为成功后的上传组件 fileItem JSON;其他场景始终为空 */
    @TableField("qianpiye_saved_file_json")
    private String qianpiyeSavedFileJson;
 
    /** 独占业务 fence token;PUBLISHING/RECORD_RETIRING 状态非空 */
    @TableField("publish_token")
    private String publishToken;
 
    @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;
        /** 保存中:已取得当前租约的保存权,禁止新的编辑租约穿透 */
        public static final int SAVING = 2;
        /** 保存出错:DS 正常保存回调 status 3,需人工介入 */
        public static final int SAVE_FAILED = 3;
        /** 模板发布中:阻止新编辑和保存写回,不允许超时自动接管 */
        public static final int PUBLISHING = 4;
        /** 记录修订中:修订事务未决,旧文档不允许新编辑或写回 */
        public static final int RECORD_RETIRING = 5;
        /** 历史记录文档:可读但永不允许再获取编辑租约 */
        public static final int RECORD_HISTORICAL = 6;
 
        private SessionStatus() {
        }
    }
}