Commit ef69b7de authored by 郭铭瑶's avatar 郭铭瑶 🤘

新增要素接口改动及批量新增附属节点功能添加

parent b9257356
......@@ -20,7 +20,7 @@
"eslint-config-prettier": "^7.1.0",
"eslint-plugin-prettier": "^3.3.1",
"eslint-plugin-vue": "^7.4.1",
"naive-ui": "^2.16.2",
"naive-ui": "^2.16.5",
"prettier": "^2.2.1",
"stylus": "^0.54.8",
"vite": "^2.1.0"
......@@ -617,9 +617,9 @@
}
},
"node_modules/async-validator": {
"version": "3.5.2",
"resolved": "https://registry.npmjs.org/async-validator/-/async-validator-3.5.2.tgz",
"integrity": "sha512-8eLCg00W9pIRZSB781UUX/H6Oskmm8xloZfr09lz5bikRpBVDlJ3hRVuxxP1SxcwsEYfJ4IU8Q19Y8/893r3rQ==",
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/async-validator/-/async-validator-4.0.2.tgz",
"integrity": "sha512-wPFnOgf9uIu/7uvptlX7PepSf2ArGt60Wng0bYrQ08eZVFG65LRLQpHKQebWEyAYtJcdPN31kndy4nS0jVnf0Q==",
"dev": true
},
"node_modules/atob": {
......@@ -2327,16 +2327,17 @@
"dev": true
},
"node_modules/naive-ui": {
"version": "2.16.2",
"resolved": "https://registry.npmjs.org/naive-ui/-/naive-ui-2.16.2.tgz",
"integrity": "sha512-pIQyg5Im0E3j4BI6Fb3zQRUqqHKLe1zqUEIDJ2GmDzTi9SZIxhSTj4t1ck9C43aCNu93QORZLf7e0sgJLf6LQg==",
"version": "2.16.5",
"resolved": "https://registry.npmjs.org/naive-ui/-/naive-ui-2.16.5.tgz",
"integrity": "sha512-nqIQTivPETbHR+Z7It0iSXlYe71Az5Hi5IBJ1l2tRSNWZU2Tz9v5vMf9F78xfIz1o2Mb+cmQV7PuMazc/EbGXQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@css-render/plugin-bem": "^0.15.4",
"@css-render/vue3-ssr": "^0.15.4",
"@types/lodash": "^4.14.170",
"@types/lodash-es": "^4.17.4",
"async-validator": "^3.5.1",
"async-validator": "^4.0.1",
"css-render": "^0.15.4",
"date-fns": "^2.19.0",
"evtd": "^0.2.2",
......@@ -2344,7 +2345,7 @@
"lodash": "^4.17.21",
"lodash-es": "^4.17.21",
"seemly": "^0.3.1",
"treemate": "^0.2.12",
"treemate": "^0.3.0",
"vdirs": "^0.1.4",
"vfonts": "^0.1.0",
"vooks": "^0.2.6",
......@@ -3122,9 +3123,9 @@
}
},
"node_modules/treemate": {
"version": "0.2.12",
"resolved": "https://registry.npmjs.org/treemate/-/treemate-0.2.12.tgz",
"integrity": "sha512-li5ZxaT7BtBIEnT7eUO3mk4BdefANPUKjCGnTciFp5e5UDy3+07HLvWelKxuIz1jCz+6r5IPoP8P/5+8Xz9Z7w==",
"version": "0.3.2",
"resolved": "https://registry.npmjs.org/treemate/-/treemate-0.3.2.tgz",
"integrity": "sha512-vy4x0kVfNHxNh+AmXbvrCklYc6HlPpIgqy2zzCStBnqdlhuHP+PaOfKUS3YyISAPhj4g4KdqmvfYrgQV2SF6Ag==",
"dev": true
},
"node_modules/type-check": {
......@@ -3832,9 +3833,9 @@
"dev": true
},
"async-validator": {
"version": "3.5.2",
"resolved": "https://registry.npmjs.org/async-validator/-/async-validator-3.5.2.tgz",
"integrity": "sha512-8eLCg00W9pIRZSB781UUX/H6Oskmm8xloZfr09lz5bikRpBVDlJ3hRVuxxP1SxcwsEYfJ4IU8Q19Y8/893r3rQ==",
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/async-validator/-/async-validator-4.0.2.tgz",
"integrity": "sha512-wPFnOgf9uIu/7uvptlX7PepSf2ArGt60Wng0bYrQ08eZVFG65LRLQpHKQebWEyAYtJcdPN31kndy4nS0jVnf0Q==",
"dev": true
},
"atob": {
......@@ -5113,16 +5114,16 @@
"dev": true
},
"naive-ui": {
"version": "2.16.2",
"resolved": "https://registry.npmjs.org/naive-ui/-/naive-ui-2.16.2.tgz",
"integrity": "sha512-pIQyg5Im0E3j4BI6Fb3zQRUqqHKLe1zqUEIDJ2GmDzTi9SZIxhSTj4t1ck9C43aCNu93QORZLf7e0sgJLf6LQg==",
"version": "2.16.5",
"resolved": "https://registry.npmjs.org/naive-ui/-/naive-ui-2.16.5.tgz",
"integrity": "sha512-nqIQTivPETbHR+Z7It0iSXlYe71Az5Hi5IBJ1l2tRSNWZU2Tz9v5vMf9F78xfIz1o2Mb+cmQV7PuMazc/EbGXQ==",
"dev": true,
"requires": {
"@css-render/plugin-bem": "^0.15.4",
"@css-render/vue3-ssr": "^0.15.4",
"@types/lodash": "^4.14.170",
"@types/lodash-es": "^4.17.4",
"async-validator": "^3.5.1",
"async-validator": "^4.0.1",
"css-render": "^0.15.4",
"date-fns": "^2.19.0",
"evtd": "^0.2.2",
......@@ -5130,7 +5131,7 @@
"lodash": "^4.17.21",
"lodash-es": "^4.17.21",
"seemly": "^0.3.1",
"treemate": "^0.2.12",
"treemate": "^0.3.0",
"vdirs": "^0.1.4",
"vfonts": "^0.1.0",
"vooks": "^0.2.6",
......@@ -5718,9 +5719,9 @@
"integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4="
},
"treemate": {
"version": "0.2.12",
"resolved": "https://registry.npmjs.org/treemate/-/treemate-0.2.12.tgz",
"integrity": "sha512-li5ZxaT7BtBIEnT7eUO3mk4BdefANPUKjCGnTciFp5e5UDy3+07HLvWelKxuIz1jCz+6r5IPoP8P/5+8Xz9Z7w==",
"version": "0.3.2",
"resolved": "https://registry.npmjs.org/treemate/-/treemate-0.3.2.tgz",
"integrity": "sha512-vy4x0kVfNHxNh+AmXbvrCklYc6HlPpIgqy2zzCStBnqdlhuHP+PaOfKUS3YyISAPhj4g4KdqmvfYrgQV2SF6Ag==",
"dev": true
},
"type-check": {
......
......@@ -20,7 +20,7 @@
"eslint-config-prettier": "^7.1.0",
"eslint-plugin-prettier": "^3.3.1",
"eslint-plugin-vue": "^7.4.1",
"naive-ui": "^2.16.2",
"naive-ui": "^2.16.5",
"prettier": "^2.2.1",
"stylus": "^0.54.8",
"vite": "^2.1.0"
......
......@@ -163,7 +163,7 @@ export default {
function switchName(key) {
switch (key) {
case 'Subject':
return '主体'
return '要素'
case 'System':
return '系统'
case 'Property_property':
......
......@@ -22,7 +22,7 @@
</svg>
</n-icon>
</template>
新增主体
新增要素
</n-button>
<n-input-group size="small" class="search-bar">
<n-select
......@@ -163,7 +163,7 @@ export default defineComponent({
}
const nodeOptions = ref([
{ label: '主体', value: 'Subject' },
{ label: '要素', value: 'Subject' },
{ label: '附属节点', value: 'Property' },
{ label: '系统', value: 'System' },
])
......@@ -171,7 +171,7 @@ export default defineComponent({
function switchName(key) {
switch (key) {
case 'Subject':
return '主体'
return '要素'
case 'System':
return '系统'
case 'Property_property':
......
......@@ -10,7 +10,7 @@
@add="openAddDrawer"
@curNode="curNode = $event"
@del="deleteNode"
@link="showLinkDrawer = true"
@link="openLinkDrawer"
@del-link="deleteLink"
/>
<Side style="grid-area: side" />
......@@ -18,55 +18,123 @@
style="grid-area: footer"
:node="curNode"
:data="graphData"
@add="showSubjectDrawer = true"
@add="openSubjectDrawer"
@set="setLabelKey"
@search="searchNodes"
/>
</div>
<n-drawer v-model:show="showDrawer" :width="340" placement="left">
<n-drawer-content title="新增附属节点" closable>
<n-form ref="formRef" :model="formData" :rules="rules">
<n-form-item path="propertyName" label="节点名称">
<n-drawer-content
title="新增附属节点"
closable
body-style="flex:1;overflow-y:auto;"
>
<template v-for="(data, i) in formData" :key="i">
<n-form
ref="formRef"
class="add-sub-form"
:model="data"
:rules="rules"
size="small"
>
<n-form-item label="节点名称" path="propertyName">
<n-input
v-model:value="data.propertyName"
placeholder="请输入"
@keydown.enter.prevent
/>
</n-form-item>
<n-form-item label="关系" path="relationId">
<n-select
v-model:value="data.relationId"
placeholder="请选择"
:options="relationOptions"
/>
</n-form-item>
<n-form-item label="所属系统" path="systemId">
<n-select
v-model:value="data.systemIds"
placeholder="请选择"
:options="systemOptions"
multiple
/>
</n-form-item>
<n-button
class="del-btn"
type="error"
dashed
size="small"
style="width: 100%"
@click="deleteItem(i)"
>
删除
</n-button>
</n-form>
<n-divider />
</template>
<template #footer>
<n-space justify="end">
<n-button type="primary" ghost size="small" @click="addNewItem">
新增一项
</n-button>
<n-button
:loading="isLoading"
type="primary"
size="small"
@click="submitNewNode"
>
提交
</n-button>
</n-space>
</template>
</n-drawer-content>
</n-drawer>
<n-drawer v-model:show="showSubjectDrawer" :width="340" placement="left">
<n-drawer-content title="新增要素" closable>
<n-form
ref="subjectFormRef"
:model="subjectData"
:rules="rules"
size="small"
>
<n-form-item path="subjectName" label="名称">
<n-input
v-model:value="formData.propertyName"
v-model:value="subjectData.subjectName"
placeholder="请输入"
@keydown.enter.prevent
/>
</n-form-item>
<n-form-item label="关系" path="relationId">
<n-form-item path="subjectType" label="类型">
<n-select
v-model:value="formData.relationId"
v-model:value="subjectData.subjectType"
placeholder="请选择"
:options="relationOptions"
:options="[
{ label: '主体', value: '1' },
{ label: '客体', value: '2' },
]"
/>
</n-form-item>
<n-form-item label="所属系统" path="systemId">
<n-form-item path="targetSubjectId" label="目标要素">
<n-select
v-model:value="formData.systemId"
v-model:value="subjectData.targetSubjectId"
placeholder="请选择"
:options="systemOptions"
:options="subjectOptions"
/>
</n-form-item>
<n-space justify="end">
<n-button :loading="isLoading" type="primary" @click="submitNewNode">
提交
</n-button>
</n-space>
</n-form>
</n-drawer-content>
</n-drawer>
<n-drawer v-model:show="showSubjectDrawer" :width="340" placement="left">
<n-drawer-content title="新增主体" closable>
<n-form ref="subjectFormRef" :model="subjectData" :rules="rules">
<n-form-item path="subjectName" label="名称">
<n-input
v-model:value="subjectData.subjectName"
placeholder="请输入"
@keydown.enter.prevent
<n-form-item path="sourceSubjectId" label="源要素">
<n-select
v-model:value="subjectData.sourceSubjectId"
placeholder="请选择"
:options="subjectOptions"
/>
</n-form-item>
<n-space justify="end">
<n-button :loading="isLoading" type="primary" @click="addSubject">
<n-button
:loading="isLoading"
size="small"
type="primary"
@click="addSubject"
>
提交
</n-button>
</n-space>
......@@ -74,9 +142,9 @@
</n-drawer-content>
</n-drawer>
<n-drawer v-model:show="showLinkDrawer" :width="340" placement="left">
<n-drawer-content title="连接主体" closable>
<n-form ref="linkFormRef" :model="linkData" :rules="rules">
<n-form-item path="sourceNodeId" label="源主体">
<n-drawer-content title="连接要素" closable>
<n-form ref="linkFormRef" :model="linkData" :rules="rules" size="small">
<n-form-item path="sourceNodeId" label="源要素">
<n-select
v-model:value="linkData.sourceNodeId"
placeholder="请选择"
......@@ -84,7 +152,7 @@
disabled
/>
</n-form-item>
<n-form-item path="targetNodeId" label="目标主体">
<n-form-item path="targetNodeId" label="目标要素">
<n-select
v-model:value="linkData.targetNodeId"
placeholder="请选择"
......@@ -92,7 +160,12 @@
/>
</n-form-item>
<n-space justify="end">
<n-button :loading="isLoading" type="primary" @click="linkSubject">
<n-button
size="small"
:loading="isLoading"
type="primary"
@click="linkSubject"
>
提交
</n-button>
</n-space>
......@@ -116,13 +189,15 @@ export default {
setup() {
const message = useMessage()
const dialog = useDialog()
const subjectId = ref(null)
const curSubject = ref(null)
const formRef = ref(null)
const formData = ref({
propertyName: null,
relationId: null,
systemId: null,
})
const formData = ref([
{
propertyName: null,
relationId: null,
systemIds: null,
},
])
const showDrawer = ref(false)
const isLoading = ref(false)
const d3Ref = ref(null)
......@@ -207,13 +282,15 @@ export default {
})
}
function openAddDrawer({ nodeId }) {
formData.value = {
propertyName: null,
relationId: null,
systemId: null,
}
subjectId.value = nodeId
function openAddDrawer(node) {
formData.value = [
{
propertyName: null,
relationId: null,
systemIds: null,
},
]
curSubject.value = node
showDrawer.value = true
}
......@@ -226,17 +303,20 @@ export default {
formRef.value.validate((errors) => {
if (!errors) {
isLoading.value = true
const { nodeId, subjectName, subjectType } = curSubject.value
ajax
.post({
url: api.POST_NODE,
params: {
subjectId: subjectId.value,
...formData.value,
subjectId: nodeId,
subjectName,
subjectType,
propertyList: formData.value,
},
})
.then(() => {
fetchSubordinates({
nodeId: subjectId.value,
nodeId: nodeId,
nodeLabel: 'Subject',
})
isLoading.value = false
......@@ -311,7 +391,12 @@ export default {
const subjectFormRef = ref(null)
const showSubjectDrawer = ref(false)
const subjectData = ref({ subjectName: null })
const subjectData = ref({
subjectName: null,
subjectType: null,
targetSubjectId: null,
sourceSubjectId: null,
})
const addSubject = (e) => {
e.preventDefault()
subjectFormRef.value.validate((errors) => {
......@@ -392,6 +477,13 @@ export default {
trigger: ['input', 'blur'],
},
],
subjectType: [
{
required: true,
message: '请选择要素类型',
trigger: ['change', 'blur'],
},
],
propertyName: [
{
required: true,
......@@ -406,24 +498,17 @@ export default {
trigger: ['change', 'blur'],
},
],
// systemId: [
// {
// required: true,
// message: '请选择所属系统',
// trigger: ['change', 'blur'],
// },
// ],
sourceNodeId: [
{
required: true,
message: '请选择源主体',
message: '请选择源要素',
trigger: ['change', 'blur'],
},
],
targetNodeId: [
{
required: true,
message: '请选择目标主体',
message: '请选择目标要素',
trigger: ['change', 'blur'],
},
{
......@@ -431,9 +516,53 @@ export default {
return value !== linkData.value.sourceNodeId
},
trigger: ['blur', 'change'],
message: '目标主体不能与源主体相同',
message: '目标要素不能与源要素相同',
},
],
targetSubjectId: [
{
validator(_, value) {
return value !== subjectData.value.sourceSubjectId
},
trigger: ['blur', 'change'],
message: '目标要素不能与源要素相同',
},
],
sourceSubjectId: [
{
validator(_, value) {
return value !== subjectData.value.targetSubjectId
},
trigger: ['blur', 'change'],
message: '源要素不能与目标要素相同',
},
],
}
function openSubjectDrawer() {
showSubjectDrawer.value = true
subjectData.value = {
subjectName: null,
subjectType: null,
targetSubjectId: null,
sourceSubjectId: null,
}
}
function openLinkDrawer() {
showLinkDrawer.value = true
linkData.value = {
sourceNodeId: null,
targetNodeId: null,
}
}
function addNewItem() {
formData.value.push({
propertyName: null,
relationId: null,
systemIds: null,
})
}
function deleteItem(i) {
formData.value.splice(i, 1)
}
return {
formRef,
......@@ -463,6 +592,10 @@ export default {
linkData,
linkSubject,
subjectOptions,
openSubjectDrawer,
openLinkDrawer,
addNewItem,
deleteItem,
}
},
}
......@@ -479,4 +612,11 @@ export default {
grid-template-rows 0px 1fr 70px
padding 4px
font-weight bold !important
.add-sub-form
&:hover
.del-btn
opacity 1
.del-btn
opacity 0
</style>
......@@ -16,6 +16,7 @@ import {
NMessageProvider,
NDialogProvider,
NIcon,
NDivider,
} from 'naive-ui'
const naive = create({
......@@ -33,6 +34,7 @@ const naive = create({
NMessageProvider,
NDialogProvider,
NIcon,
NDivider,
],
})
......
......@@ -83,7 +83,7 @@ const defaultConfig = {
isHighLight: true, // 是否启动 鼠标 hover 到节点上高亮与节点有关的节点,其他无关节点透明的功能
isScale: true, // 是否启用缩放平移zoom功能
scaleExtent: [0.6, 1.5], // 缩放的比例尺
chargeStrength: -300, // 万有引力
chargeStrength: 300, // 万有引力
collide: 80, // 碰撞力的大小 (节点之间的间距)
alphaDecay: 0.1, // 控制力学模拟衰减率
r: 36, // 圈圈的半径 [30 - 45]
......@@ -392,7 +392,7 @@ export default class RelationGraph {
// simulation.force(name,[force])函数,添加某种力
.force('link', d3.forceLink(this.config.links))
// 万有引力
// .force('charge', d3.forceManyBody().strength(this.config.chargeStrength))
.force('charge', d3.forceManyBody().strength(this.config.chargeStrength))
// d3.forceCenter()用指定的x坐标和y坐标创建一个新的居中力。
.force(
'center',
......@@ -438,8 +438,8 @@ export default class RelationGraph {
this.simulation
.nodes(this.config.nodes)
.force('link', d3.forceLink(this.config.links))
.force('charge', null)
.alpha(0.3)
// .force('charge', null)
.alpha(1)
.restart()
}
......@@ -466,12 +466,17 @@ export default class RelationGraph {
this.curActiveNode && (this.curActiveNode.fx = null)
this.curActiveNode && (this.curActiveNode.fy = null)
}
closeMenu(needClearFixedPosition) {
needClearFixedPosition && this.clearFixedPosition()
closeMenu(needClearFixedPositionNow) {
if (menu) {
menu.hide()
menu = null
}
if (needClearFixedPositionNow) {
this.clearFixedPosition()
}
// else {
// setTimeout(() => this.clearFixedPosition(), 1000)
// }
}
init() {
......@@ -620,7 +625,7 @@ export default class RelationGraph {
this.SVG.selectAll('.edge')
.filter((d) => this.dependsLink.indexOf(d.index) == -1)
.transition()
.style('opacity', 0.3)
.style('opacity', 0.1)
} else {
// 取消高亮
// 恢复隐藏的线
......@@ -654,7 +659,7 @@ export default class RelationGraph {
this.SVG.selectAll('.edge')
.filter((d) => d.id != obj.id)
.transition()
.style('opacity', 0.3)
.style('opacity', 0.1)
} else {
this.SVG.selectAll('circle').transition().style('opacity', 1)
this.SVG.selectAll('.edge').transition().style('opacity', 1)
......@@ -671,8 +676,7 @@ export default class RelationGraph {
if (!key || this.curActiveNode.nodeLabel !== 'Subject') {
this.curHighlightKey = null
this.config.isHighLight = true
key = null
// return false
return false
}
this.highlightObject(this.curActiveNode)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment