修改右键菜单、创建新节点
This commit is contained in:
parent
de98e82461
commit
eaad38508c
143
docs/设计文档.docx
143
docs/设计文档.docx
|
|
@ -10,26 +10,38 @@ node:节点表:
|
|||
id
|
||||
|
||||
int
|
||||
AUTO_INCREMENT PRIMARY KEY
|
||||
自增、主键
|
||||
uuid
|
||||
节点标识
|
||||
VARCHAR(36)
|
||||
|
||||
type
|
||||
code
|
||||
编号
|
||||
VARCHAR(150)
|
||||
按照节点级别编号,一级节点的编号为000,001,002,003,004;二级节点的编号为001000,001001,001002,001003,这4个编号表明节点都是编号001的子节点
|
||||
node_type
|
||||
类型
|
||||
VARCHAR(50)
|
||||
以下之一:product scenario, product definition, product target, attribute, function, system, component
|
||||
VARCHAR(10)
|
||||
以下之一:folder、doc,folder下允许添加folder和doc节点,doc节点只能作为文档编辑(其下不能添加节点)
|
||||
owner_id
|
||||
所有者id
|
||||
int
|
||||
用户表id
|
||||
外键,用户表id
|
||||
title
|
||||
标题
|
||||
|
||||
|
||||
parent_id
|
||||
父节点ID
|
||||
int
|
||||
为0表示1级节点
|
||||
sort_order
|
||||
排序权重
|
||||
|
||||
越小越靠前
|
||||
create_time
|
||||
创建时间
|
||||
TIMESTAMP
|
||||
time
|
||||
|
||||
hierarchy
|
||||
层次
|
||||
|
|
@ -40,9 +52,37 @@ product target及子树:3
|
|||
attribute, function及子树:4
|
||||
system及子树:5
|
||||
component及子树:6
|
||||
说明:预先创建树形结构一级节点product scenario, product definition, product target, attribute, function, system, component,赋好层次的值。在创建子节点时,继承父节点的层次值。
|
||||
projects及创建的子树(不包括branch的子树):0
|
||||
content
|
||||
内容
|
||||
|
||||
node_relation: 节点关系表
|
||||
存储富文本文档的内容
|
||||
last_change
|
||||
最后修改时间
|
||||
time
|
||||
|
||||
last_change_by
|
||||
最后修改人id
|
||||
int
|
||||
|
||||
ref_id
|
||||
引用的文档节点id
|
||||
|
||||
外键,本表的id
|
||||
task_type
|
||||
分工类型
|
||||
varchar(15)
|
||||
以下之一:project、standards。MainTree下的结点均为standards,Projects下的结点均为project
|
||||
source_type
|
||||
文档来源类型
|
||||
varchar(10)
|
||||
如果ref_id不为空,则为以下之一:map, clone
|
||||
map_version
|
||||
map的版本id
|
||||
int
|
||||
外键,docVersion表的id,如果source_type为map才有值
|
||||
|
||||
docVersion:文档版本表
|
||||
字段名
|
||||
含义
|
||||
类型
|
||||
|
|
@ -50,38 +90,67 @@ node_relation: 节点关系表
|
|||
id
|
||||
|
||||
int
|
||||
AUTO_INCREMENT PRIMARY KEY
|
||||
parent_id
|
||||
父节点ID
|
||||
自增、主键
|
||||
doc_id
|
||||
文档节点id
|
||||
int
|
||||
node表id,为0表示1级节点
|
||||
child_id
|
||||
子节点ID
|
||||
int
|
||||
node表id
|
||||
sort_order
|
||||
排序权重
|
||||
外键,node表的id
|
||||
version
|
||||
版本号
|
||||
varchar(20)
|
||||
xxx.yyy.zzz形式,xxx为public的大版本、yyy为release的小版本、zzz为review的微版本,分别从1开始编号
|
||||
|
||||
越小越靠前
|
||||
relation_type
|
||||
关系类型
|
||||
VARCHAR(20)
|
||||
direct直接子节点,reference引用节点。DEFAULT 'direct'
|
||||
|
||||
操作:
|
||||
1、预先创建树形结构一级节点product scenario, product definition, product target, attribute, function, system, component,赋好层次的值hierarchy。projects的层次值为0。
|
||||
2、sort_order的作用:每个节点下的所有n个子节点的sort_order为从1到n的值。支持调整显示顺序,sort_order小的显示在前。在界面上允许拖拽调整顺序,拖拽的目的地不能改变父节点。
|
||||
3、节点的右键菜单:
|
||||
|
||||
(1)根节点没有"添加同级节点"
|
||||
(2)node_type为doc的节点没有"添加下级节点"(文档下不能添加子节点)
|
||||
(3)ref_id不为空的节点没有"edit"(即不能编辑引用自其它文档的文档)
|
||||
(4)node_type为folder的节点没有"copy to"、"clone to"和"map to"(这三个操作仅针对文档)。task_type为standards的节点没有"map to"(projects树下的文档才可map)。
|
||||
(5)hierarchy为0的节点以及node_type为doc的节点没有"branch to"(hierarchy大于0的节点包括maintree里的节点或者从maintree里branch到projects的节点)
|
||||
4、创建节点(添加同级节点、添加下级节点)界面如下:
|
||||
|
||||
界面上输入title、node_type、owner(从用户列表里选择),在保存时,自动生成id、uuid、sort_order、create_time,获取parent_id、继承父节点的hierarchy、task_type。
|
||||
code生成方法:按照节点级别编号,一级节点的编号为000,001,002,003,004;二级节点的编号为001000,001001,001002,001003,这4个编号表明节点都是编号001的子节点。001的二级节点的编号从001000到001999,如果中间某些code被删除而导致缺失,则在添加了001999后,绕回到001000及之后的缺失编号。说明:000到999不要求连续(删除后可以缺失),不要求排序(大编号在小编号之前也可以)
|
||||
sort_order生成方法:如果是添加下级节点,则新节点的sort_order为已有下级节点最大sort_order加1。如果是添加同级节点,则新节点的sort_order为操作节点的sort_order加1(即添加到操作节点的后面),同一父节点的后面的所有节点sort_order都需要加1。
|
||||
5、edit菜单:只能修改title和owner
|
||||
6、delete菜单:
|
||||
node_type为doc的节点,如果有其它节点的ref_id指向自己,则提示"有其它文档由本文档clone或map,不能删除"。如果存在外键指向自己,则提示"存在外键约束,不能删除"。
|
||||
node_type为folder的节点,如果以该节点为根的子树上存在文档,则提示"请先删除子树上的文档,才能删除本文件夹"。
|
||||
7、copy to菜单(复制节点):
|
||||
选中一个doc节点,点击copy to时,弹出界面,要求选择maintree或projects里的一个folder节点(需要检查操作人员是否对该节点有write权限),点击确认,即执行copy操作。
|
||||
copy将在数据库中添加新记录,其中:
|
||||
parent_id为目标folder节点的id。
|
||||
code根据parent folder的code添加3位,生成规则见"创建新节点"。
|
||||
owner_id、task_type、hierarchy与parent folder的owner_id、task_type、hierarchy相同
|
||||
id、uuid、sort_order(添加为最后一个节点)、create_time(为当前时间)根据规则生成。
|
||||
字段:node_type、title、content、last_change、last_change_by、ref_id、source_type、map_version从选中的doc节点复制。
|
||||
8、clone to菜单(对节点添加引用):
|
||||
选中一个doc节点,点击clone to时,弹出界面,要求选择maintree或projects里的一个folder节点(需要检查操作人员是否对该节点有write权限),点击确认,即执行clone操作。
|
||||
clone将在数据库中添加新记录,其中:
|
||||
parent_id为目标folder节点的id。
|
||||
code根据parent folder的code添加3位,生成规则见"创建新节点"。
|
||||
owner_id、task_type、hierarchy与parent folder的owner_id、task_type、hierarchy相同
|
||||
id、uuid、sort_order(添加为最后一个节点)根据规则生成。
|
||||
如果选中doc节点的ref_id为空,则新记录的ref_id为该doc的id,source_type为clone,map_version为空;如果选中doc节点的ref_id不为空,则新记录的ref_id复制该doc的ref_id,source_type为clone,map_version为空
|
||||
title、content、last_change、last_change_by为空,在select检索时根据ref_id获取。
|
||||
字段:node_type、create_time从选中的doc节点复制。
|
||||
(疑问:map的节点能否被copy和clone?)
|
||||
9、branch to菜单(复制子树):
|
||||
选中一个folder节点,点击branch to时,弹出界面,要求选择projects里hierarchy为0的一个folder节点(需要检查操作人员是否对该节点有write权限),点击确认,即执行复制操作。
|
||||
复制将在数据库中添加新记录,需要逐层添加,先添加被复制子树的根节点,再添加它的子孙节点。
|
||||
其中根节点复制到目标folder的下面。对于根节点:
|
||||
parent_id为目标folder节点的id。
|
||||
code根据parent folder的code添加3位,生成规则见"创建新节点"。
|
||||
owner_id、task_type与parent folder的owner_id、task_type相同
|
||||
id、uuid、sort_order(添加为最后一个节点)、create_time(为当前时间)根据规则生成。
|
||||
字段:node_type、hierarchy、title、content、last_change、last_change_by、ref_id、source_type、map_version从选中的doc节点复制。
|
||||
以下每层节点在复制时,注意它的parent folder为复制过来的那个parent,id为新创建的。code也根据新的parent folder的code添加3位。其它复制规则同上。
|
||||
8、map to菜单:
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
确保同一父节点下,同一子节点不会重复添加:
|
||||
UNIQUE KEY uk_parent_child (parent_id, child_id),
|
||||
说明:
|
||||
1.分离 nodes 和 node_relations的原因:
|
||||
支持DAG结构:一个节点只能是一个父节点的direct子节点,但可以是多个父节点的reference子节点。如果存在reference子节点,那么不允许删除direct子节点。
|
||||
2、sort_order的作用
|
||||
支持调整显示顺序,sort_order小的显示在前。在界面上允许拖拽调整顺序,拖拽不能改变父节点。
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -670,7 +670,7 @@ const addNodeDialog = ref({
|
|||
})
|
||||
|
||||
// 节点类型选项
|
||||
const nodeTypes = ['product scenario', 'product definition', 'product target', 'attribute', 'function', 'system', 'component']
|
||||
const nodeTypes = ['folder', 'document']
|
||||
|
||||
const initExpanded = (nodes: TreeNode[]) => {
|
||||
nodes.forEach(node => {
|
||||
|
|
@ -1121,24 +1121,6 @@ defineExpose({
|
|||
<!-- 右键菜单 -->
|
||||
<div v-if="contextMenu.show" class="context-menu" :style="{ left: contextMenu.x + 'px', top: contextMenu.y + 'px' }"
|
||||
@click.stop>
|
||||
<div class="menu-group">
|
||||
<div class="menu-item" :class="{ disabled: !isCopyEnabled(contextMenuNode) }"
|
||||
@click="isCopyEnabled(contextMenuNode) && openOperationDialog('copy')">
|
||||
<Copy :size="14" />
|
||||
<span>Copy To...</span>
|
||||
</div>
|
||||
<div class="menu-item" :class="{ disabled: !isCloneEnabled(contextMenuNode) }"
|
||||
@click="isCloneEnabled(contextMenuNode) && openOperationDialog('clone')">
|
||||
<Database :size="14" />
|
||||
<span>Clone To...</span>
|
||||
</div>
|
||||
<div class="menu-item" :class="{ disabled: !isBranchEnabled(contextMenuNode) }"
|
||||
@click="isBranchEnabled(contextMenuNode) && openOperationDialog('branch')">
|
||||
<GitBranch :size="14" />
|
||||
<span>Branch To...</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="menu-divider"></div>
|
||||
<div class="menu-group">
|
||||
<div class="menu-item" @click="handleAddSibling">
|
||||
<CornerUpLeft :size="14" />
|
||||
|
|
@ -1148,12 +1130,38 @@ defineExpose({
|
|||
<CornerDownLeft :size="14" />
|
||||
<span>添加下级节点</span>
|
||||
</div>
|
||||
<div class="menu-item delete" @click="handleDelete">
|
||||
<Trash2 :size="14" />
|
||||
<span>edit</span>
|
||||
</div>
|
||||
<div class="menu-item delete" @click="handleDelete">
|
||||
<Trash2 :size="14" />
|
||||
<span>Delete</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="menu-divider"></div>
|
||||
<div class="menu-group">
|
||||
<div class="menu-item" :class="{ disabled: !isCopyEnabled(contextMenuNode) }"
|
||||
@click="isCopyEnabled(contextMenuNode) && openOperationDialog('copy')">
|
||||
<Copy :size="14" />
|
||||
<span>Copy To...</span>
|
||||
</div>
|
||||
<div class="menu-item" :class="{ disabled: !isCloneEnabled(contextMenuNode) }"
|
||||
@click="isCloneEnabled(contextMenuNode) && openOperationDialog('clone')">
|
||||
<Database :size="14" />
|
||||
<span>Clone To...</span>
|
||||
</div>
|
||||
<div class="menu-item" :class="{ disabled: !isBranchEnabled(contextMenuNode) }"
|
||||
@click="isBranchEnabled(contextMenuNode) && openOperationDialog('branch')">
|
||||
<GitBranch :size="14" />
|
||||
<span>Branch To...</span>
|
||||
</div>
|
||||
<div class="menu-item" :class="{ disabled: !isBranchEnabled(contextMenuNode) }"
|
||||
@click="isBranchEnabled(contextMenuNode) && openOperationDialog('branch')">
|
||||
<GitBranch :size="14" />
|
||||
<span>Map To...</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="menu-divider"></div>
|
||||
<div class="menu-item delete" @click="handleDelete">
|
||||
<Trash2 :size="14" />
|
||||
<span>Delete</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 添加节点对话框 -->
|
||||
|
|
|
|||
Loading…
Reference in New Issue