Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
IoTSharp
IoTSharp
提交
7e048363
IoTSharp
项目概览
IoTSharp
/
IoTSharp
9 个月 前同步成功
通知
15
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
IoTSharp
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
未验证
提交
7e048363
编写于
7月 11, 2021
作者:
麦壳饼
提交者:
GitHub
7月 11, 2021
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #416 from wq1234wq/master
ntv/x6 导入X6图形库
上级
90a7a8ea
5d18780d
变更
17
展开全部
隐藏空白更改
内联
并排
Showing
17 changed file
with
1307 addition
and
110 deletion
+1307
-110
ClientApp/Angular/package.json
ClientApp/Angular/package.json
+1
-1
ClientApp/Angular/src/app/core/startup/startup.service.ts
ClientApp/Angular/src/app/core/startup/startup.service.ts
+94
-94
ClientApp/Angular/src/app/routes/device/devicegraph/devicegraph.component.html
.../app/routes/device/devicegraph/devicegraph.component.html
+7
-0
ClientApp/Angular/src/app/routes/device/devicegraph/devicegraph.component.less
.../app/routes/device/devicegraph/devicegraph.component.less
+0
-0
ClientApp/Angular/src/app/routes/device/devicegraph/devicegraph.component.spec.ts
...p/routes/device/devicegraph/devicegraph.component.spec.ts
+25
-0
ClientApp/Angular/src/app/routes/device/devicegraph/devicegraph.component.ts
...rc/app/routes/device/devicegraph/devicegraph.component.ts
+369
-0
ClientApp/Angular/src/app/routes/routes-routing.module.ts
ClientApp/Angular/src/app/routes/routes-routing.module.ts
+2
-0
ClientApp/Angular/src/app/routes/routes.module.ts
ClientApp/Angular/src/app/routes/routes.module.ts
+2
-0
ClientApp/Angular/tsconfig.app.json
ClientApp/Angular/tsconfig.app.json
+2
-1
ClientApp/Vue/.husky/.gitignore
ClientApp/Vue/.husky/.gitignore
+1
-0
ClientApp/Vue/package.json
ClientApp/Vue/package.json
+5
-0
ClientApp/Vue/src/router/routes/modules/iotsharp.ts
ClientApp/Vue/src/router/routes/modules/iotsharp.ts
+10
-0
ClientApp/Vue/src/views/iotsharp/device/devicegraph.vue
ClientApp/Vue/src/views/iotsharp/device/devicegraph.vue
+458
-0
ClientApp/Vue/src/views/iotsharp/device/devicelist.vue
ClientApp/Vue/src/views/iotsharp/device/devicelist.vue
+15
-2
ClientApp/Vue/src/views/iotsharp/device/propform.vue
ClientApp/Vue/src/views/iotsharp/device/propform.vue
+4
-5
ClientApp/Vue/src/views/iotsharp/device/useGraph.ts
ClientApp/Vue/src/views/iotsharp/device/useGraph.ts
+35
-0
ClientApp/Vue/yarn.lock
ClientApp/Vue/yarn.lock
+277
-7
未找到文件。
ClientApp/Angular/package.json
浏览文件 @
7e048363
...
...
@@ -49,7 +49,7 @@
"@angular/platform-browser"
:
"~11.2.14"
,
"@angular/platform-browser-dynamic"
:
"~11.2.14"
,
"@angular/router"
:
"~11.2.14"
,
"@antv/x6"
:
"^1.2
3.12
"
,
"@antv/x6"
:
"^1.2
4.4
"
,
"@delon/abc"
:
"^11.10.2"
,
"@delon/acl"
:
"^11.10.2"
,
"@delon/auth"
:
"^11.10.2"
,
...
...
ClientApp/Angular/src/app/core/startup/startup.service.ts
浏览文件 @
7e048363
...
...
@@ -26,7 +26,8 @@ export class StartupService {
private
settingService
:
SettingsService
,
private
aclService
:
ACLService
,
private
titleService
:
TitleService
,
private
httpClient
:
HttpClient
,
@
Inject
(
DA_SERVICE_TOKEN
)
private
tokenService
:
ITokenService
,
private
httpClient
:
HttpClient
,
@
Inject
(
DA_SERVICE_TOKEN
)
private
tokenService
:
ITokenService
,
)
{
iconSrv
.
addIcon
(...
ICONS_AUTO
,
...
ICONS
);
}
...
...
@@ -38,107 +39,106 @@ export class StartupService {
var
token
=
this
.
tokenService
;
if
(
token
&&
token
.
get
()
&&
token
.
get
()?.
token
)
{
return
concat
(
this
.
httpClient
.
get
(
`assets/tmp/i18n/
${
this
.
i18n
.
defaultLang
}
.json`
).
pipe
(
map
(
langData
=>
{
this
.
translate
.
setTranslation
(
this
.
i18n
.
defaultLang
,
langData
);
this
.
translate
.
setDefaultLang
(
this
.
i18n
.
defaultLang
);
})),
this
.
httpClient
.
get
(
'
api/Account/MyInfo
'
).
pipe
(
map
(
appData
=>
{
const
res
=
appData
as
NzSafeAny
;
console
.
log
(
res
)
this
.
settingService
.
setApp
({
name
:
'
IotSharp
'
,
description
:
'
IotSharp
'
});
this
.
settingService
.
setUser
(
res
.
data
.
customer
);
this
.
aclService
.
setFull
(
true
);
var
menu
=
[
{
"
text
"
:
"
主导航1
"
,
"
i18n
"
:
"
menu.main
"
,
"
group
"
:
true
,
"
hideInBreadcrumb
"
:
true
,
"
children
"
:
[
return
concat
(
this
.
httpClient
.
get
(
`assets/tmp/i18n/
${
this
.
i18n
.
defaultLang
}
.json`
).
pipe
(
map
((
langData
)
=>
{
this
.
translate
.
setTranslation
(
this
.
i18n
.
defaultLang
,
langData
);
this
.
translate
.
setDefaultLang
(
this
.
i18n
.
defaultLang
);
}),
),
this
.
httpClient
.
get
(
'
api/Account/MyInfo
'
).
pipe
(
map
((
appData
)
=>
{
const
res
=
appData
as
NzSafeAny
;
console
.
log
(
res
);
this
.
settingService
.
setApp
({
name
:
'
IotSharp
'
,
description
:
'
IotSharp
'
});
this
.
settingService
.
setUser
(
res
.
data
.
customer
);
this
.
aclService
.
setFull
(
true
);
var
menu
=
[
{
"
text
"
:
"
仪表盘
"
,
"
i18n
"
:
"
menu.dashboard
"
,
"
icon
"
:
"
anticon-dashboard
"
,
"
children
"
:
[
text
:
'
主导航1
'
,
i18n
:
'
menu.main
'
,
group
:
true
,
hideInBreadcrumb
:
true
,
children
:
[
{
"
text
"
:
"
仪表盘V1
"
,
"
link
"
:
"
/dashboard/v1
"
,
"
i18n
"
:
"
menu.dashboard.v1
"
}
]
},
{
"
text
"
:
"
租户管理
"
,
"
icon
"
:
"
anticon-rocket
"
,
"
shortcutRoot
"
:
true
,
"
i18n
"
:
"
menu.tenant.tenantmanage
"
,
"
children
"
:
[
text
:
'
仪表盘
'
,
i18n
:
'
menu.dashboard
'
,
icon
:
'
anticon-dashboard
'
,
children
:
[
{
text
:
'
仪表盘V1
'
,
link
:
'
/dashboard/v1
'
,
i18n
:
'
menu.dashboard.v1
'
,
},
],
},
{
"
text
"
:
"
租户列表
"
,
"
link
"
:
"
/iot/tenant/tenantlist
"
,
"
i18n
"
:
"
menu.tenant.tenantlist
"
}
]
},
{
"
text
"
:
"
客户管理
"
,
"
icon
"
:
"
anticon-appstore
"
,
"
i18n
"
:
"
menu.customer.customermanage
"
,
"
children
"
:
[
text
:
'
租户管理
'
,
icon
:
'
anticon-rocket
'
,
shortcutRoot
:
true
,
i18n
:
'
menu.tenant.tenantmanage
'
,
children
:
[
{
text
:
'
租户列表
'
,
link
:
'
/iot/tenant/tenantlist
'
,
i18n
:
'
menu.tenant.tenantlist
'
,
}
,
],
},
{
"
text
"
:
"
客户列表
"
,
"
link
"
:
"
/iot/customer/customerlist
"
,
"
i18n
"
:
"
menu.customer.customerlist
"
}
]
},
{
"
text
"
:
"
设备管理
"
,
"
icon
"
:
"
anticon-appstore
"
,
"
i18n
"
:
"
menu.device.devicemanage
"
,
"
children
"
:
[
text
:
'
客户管理
'
,
icon
:
'
anticon-appstore
'
,
i18n
:
'
menu.customer.customermanage
'
,
children
:
[
{
text
:
'
客户列表
'
,
link
:
'
/iot/customer/customerlist
'
,
i18n
:
'
menu.customer.customerlist
'
,
},
],
},
{
"
text
"
:
"
设备列表
"
,
"
link
"
:
"
/iot/device/devicelist
"
,
"
i18n
"
:
"
menu.device.devicelist
"
}
]
}
]
}]
if
(
!
res
.
data
.
menu
)
{
res
.
data
.
menu
=
menu
;
}
this
.
menuService
.
add
(
res
.
data
.
menu
);
this
.
titleService
.
default
=
''
;
this
.
titleService
.
suffix
=
res
.
data
.
tenant
.
name
;
}))).
toPromise
()
text
:
'
设备管理
'
,
icon
:
'
anticon-appstore
'
,
i18n
:
'
menu.device.devicemanage
'
,
children
:
[
{
text
:
'
设备列表
'
,
link
:
'
/iot/device/devicelist
'
,
i18n
:
'
menu.device.devicelist
'
,
},
{
text
:
'
设计
'
,
link
:
'
/iot/device/devicegraph
'
,
// i18n: 'menu.device.devicelist',
},
],
},
],
},
];
if
(
!
res
.
data
.
menu
)
{
res
.
data
.
menu
=
menu
;
}
this
.
menuService
.
add
(
res
.
data
.
menu
);
this
.
titleService
.
default
=
''
;
this
.
titleService
.
suffix
=
res
.
data
.
tenant
.
name
;
}),
),
).
toPromise
();
}
else
{
return
concat
(
this
.
httpClient
.
get
(
`assets/tmp/i18n/
${
this
.
i18n
.
defaultLang
}
.json`
).
pipe
(
map
(
langData
=>
{
this
.
translate
.
setTranslation
(
this
.
i18n
.
defaultLang
,
langData
);
this
.
translate
.
setDefaultLang
(
this
.
i18n
.
defaultLang
);
}))).
toPromise
()
return
concat
(
this
.
httpClient
.
get
(
`assets/tmp/i18n/
${
this
.
i18n
.
defaultLang
}
.json`
).
pipe
(
map
((
langData
)
=>
{
this
.
translate
.
setTranslation
(
this
.
i18n
.
defaultLang
,
langData
);
this
.
translate
.
setDefaultLang
(
this
.
i18n
.
defaultLang
);
}),
),
).
toPromise
();
}
// return new Promise((resolve) => {
// zip(this.httpClient.get(`assets/tmp/i18n/${this.i18n.defaultLang}.json`), this.httpClient.get('assets/tmp/app-data.json'))
// .pipe(
...
...
ClientApp/Angular/src/app/routes/device/devicegraph/devicegraph.component.html
0 → 100644
浏览文件 @
7e048363
<div
#container
>
</div>
ClientApp/Angular/src/app/routes/device/devicegraph/devicegraph.component.less
0 → 100644
浏览文件 @
7e048363
ClientApp/Angular/src/app/routes/device/devicegraph/devicegraph.component.spec.ts
0 → 100644
浏览文件 @
7e048363
import
{
ComponentFixture
,
TestBed
}
from
'
@angular/core/testing
'
;
import
{
DevicegraphComponent
}
from
'
./devicegraph.component
'
;
describe
(
'
DevicegraphComponent
'
,
()
=>
{
let
component
:
DevicegraphComponent
;
let
fixture
:
ComponentFixture
<
DevicegraphComponent
>
;
beforeEach
(
async
()
=>
{
await
TestBed
.
configureTestingModule
({
declarations
:
[
DevicegraphComponent
]
})
.
compileComponents
();
});
beforeEach
(()
=>
{
fixture
=
TestBed
.
createComponent
(
DevicegraphComponent
);
component
=
fixture
.
componentInstance
;
fixture
.
detectChanges
();
});
it
(
'
should create
'
,
()
=>
{
expect
(
component
).
toBeTruthy
();
});
});
ClientApp/Angular/src/app/routes/device/devicegraph/devicegraph.component.ts
0 → 100644
浏览文件 @
7e048363
import
{
Component
,
ElementRef
,
Input
,
OnInit
,
ViewChild
}
from
'
@angular/core
'
;
import
{
Graph
,
Edge
,
Shape
,
NodeView
}
from
'
@antv/x6
'
;
@
Component
({
selector
:
'
app-devicegraph
'
,
templateUrl
:
'
./devicegraph.component.html
'
,
styleUrls
:
[
'
./devicegraph.component.less
'
],
})
export
class
DevicegraphComponent
implements
OnInit
{
@
Input
()
id
:
Number
=
-
1
;
@
ViewChild
(
'
container
'
,
{
static
:
true
})
private
container
!
:
ElementRef
;
graph
!
:
Graph
;
magnetAvailabilityHighlighter
=
{
name
:
'
stroke
'
,
args
:
{
attrs
:
{
fill
:
'
#fff
'
,
stroke
:
'
#47C769
'
,
},
},
};
constructor
()
{}
ngOnInit
():
void
{
this
.
graph
=
new
Graph
({
grid
:
true
,
container
:
this
.
container
.
nativeElement
,
width
:
800
,
height
:
600
,
highlighting
:
{
magnetAvailable
:
this
.
magnetAvailabilityHighlighter
,
magnetAdsorbed
:
{
name
:
'
stroke
'
,
args
:
{
attrs
:
{
fill
:
'
#fff
'
,
stroke
:
'
#31d0c6
'
,
},
},
},
},
connecting
:
{
snap
:
true
,
allowBlank
:
false
,
allowLoop
:
false
,
highlight
:
true
,
connector
:
'
rounded
'
,
connectionPoint
:
'
boundary
'
,
router
:
{
name
:
'
er
'
,
args
:
{
direction
:
'
V
'
,
},
},
createEdge
()
{
return
new
Shape
.
Edge
({
attrs
:
{
line
:
{
stroke
:
'
#a0a0a0
'
,
strokeWidth
:
1
,
targetMarker
:
{
name
:
'
classic
'
,
size
:
7
,
},
},
},
});
},
validateConnection
({
sourceView
,
targetView
,
targetMagnet
})
{
if
(
!
targetMagnet
)
{
return
false
;
}
if
(
targetMagnet
.
getAttribute
(
'
port-group
'
)
!==
'
in
'
)
{
return
false
;
}
if
(
targetView
)
{
const
node
=
targetView
.
cell
;
if
(
node
instanceof
Device
)
{
const
portId
=
targetMagnet
.
getAttribute
(
'
port
'
);
const
usedInPorts
=
node
.
getUsedInPorts
(
this
);
if
(
usedInPorts
.
find
((
port
)
=>
port
&&
port
.
id
===
portId
))
{
return
false
;
}
}
}
return
true
;
},
},
});
this
.
graph
.
addNode
(
new
Device
().
resize
(
120
,
40
).
position
(
200
,
50
).
updateInPorts
(
this
.
graph
));
this
.
graph
.
addNode
(
new
Device
().
resize
(
120
,
40
).
position
(
400
,
50
).
updateInPorts
(
this
.
graph
));
this
.
graph
.
addNode
(
new
GateWay
().
resize
(
120
,
40
).
position
(
300
,
250
).
updateInPorts
(
this
.
graph
));
this
.
graph
.
addNode
(
new
Device
().
resize
(
120
,
40
).
position
(
300
,
50
).
updateInPorts
(
this
.
graph
));
this
.
graph
.
addNode
(
new
Device
().
resize
(
120
,
40
).
position
(
400
,
50
).
updateInPorts
(
this
.
graph
));
// this.graph.fromJSON(this.data);
this
.
graph
.
on
(
'
edge:connected
'
,
({
previousView
,
currentView
})
=>
{
if
(
previousView
)
{
this
.
update
(
previousView
as
NodeView
);
}
if
(
currentView
)
{
this
.
update
(
currentView
as
NodeView
);
}
console
.
log
(
previousView
);
});
this
.
graph
.
on
(
'
edge:removed
'
,
({
edge
,
options
})
=>
{
if
(
!
options
.
ui
)
{
return
;
}
const
target
=
edge
.
getTargetCell
();
if
(
target
instanceof
Device
)
{
target
.
updateInPorts
(
this
.
graph
);
}
console
.
log
(
target
);
});
this
.
graph
.
on
(
'
edge:mouseenter
'
,
({
edge
})
=>
{
edge
.
addTools
([
'
source-arrowhead
'
,
'
target-arrowhead
'
,
{
name
:
'
button-remove
'
,
args
:
{
distance
:
-
30
,
},
},
]);
console
.
log
(
edge
);
});
this
.
graph
.
on
(
'
edge:mouseleave
'
,
({
edge
})
=>
{
edge
.
removeTools
();
});
}
update
(
view
:
NodeView
)
{
const
cell
=
view
.
cell
;
if
(
cell
instanceof
Device
)
{
cell
.
getInPorts
().
forEach
((
port
)
=>
{
const
portNode
=
view
.
findPortElem
(
port
.
id
!
,
'
portBody
'
);
view
.
unhighlight
(
portNode
,
{
highlighter
:
this
.
magnetAvailabilityHighlighter
,
});
});
cell
.
updateInPorts
(
this
.
graph
);
}
}
}
class
Device
extends
Shape
.
Rect
{
getInPorts
()
{
return
this
.
getPortsByGroup
(
'
in
'
);
}
getOutPorts
()
{
return
this
.
getPortsByGroup
(
'
out
'
);
}
getUsedInPorts
(
graph
:
Graph
)
{
const
incomingEdges
=
graph
.
getIncomingEdges
(
this
)
||
[];
return
incomingEdges
.
map
((
edge
:
Edge
)
=>
{
const
portId
=
edge
.
getTargetPortId
();
return
this
.
getPort
(
portId
!
);
});
}
getNewInPorts
(
length
:
number
)
{
return
Array
.
from
(
{
length
,
},
()
=>
{
return
{
group
:
'
in
'
,
};
},
);
}
updateInPorts
(
graph
:
Graph
)
{
const
minNumberOfPorts
=
1
;
const
ports
=
this
.
getInPorts
();
const
usedPorts
=
this
.
getUsedInPorts
(
graph
);
const
newPorts
=
this
.
getNewInPorts
(
Math
.
max
(
minNumberOfPorts
-
usedPorts
.
length
,
1
));
if
(
ports
.
length
===
minNumberOfPorts
&&
ports
.
length
-
usedPorts
.
length
>
0
)
{
// noop
}
else
if
(
ports
.
length
===
usedPorts
.
length
)
{
this
.
addPorts
(
newPorts
);
}
else
if
(
ports
.
length
+
1
>
usedPorts
.
length
)
{
this
.
prop
([
'
ports
'
,
'
items
'
],
this
.
getOutPorts
().
concat
(
usedPorts
).
concat
(
newPorts
),
{
rewrite
:
true
,
});
}
return
this
;
}
}
Device
.
config
({
attrs
:
{
root
:
{
magnet
:
false
,
},
body
:
{
fill
:
'
#f5f5f5
'
,
stroke
:
'
#d9d9d9
'
,
strokeWidth
:
1
,
},
},
ports
:
{
items
:
[
{
group
:
'
out
'
,
},
],
groups
:
{
in
:
{
position
:
{
name
:
'
top
'
,
},
attrs
:
{
portBody
:
{
magnet
:
'
passive
'
,
r
:
6
,
stroke
:
'
#ffa940
'
,
fill
:
'
#fff
'
,
strokeWidth
:
2
,
},
},
},
out
:
{
position
:
{
name
:
'
bottom
'
,
},
attrs
:
{
portBody
:
{
magnet
:
true
,
r
:
6
,
fill
:
'
#fff
'
,
stroke
:
'
#3199FF
'
,
strokeWidth
:
2
,
},
},
},
},
},
portMarkup
:
[
{
tagName
:
'
circle
'
,
selector
:
'
portBody
'
,
},
],
});
class
GateWay
extends
Shape
.
Circle
{
getInPorts
()
{
return
this
.
getPortsByGroup
(
'
in
'
);
}
getOutPorts
()
{
return
this
.
getPortsByGroup
(
'
out
'
);
}
getUsedInPorts
(
graph
:
Graph
)
{
const
incomingEdges
=
graph
.
getIncomingEdges
(
this
)
||
[];
return
incomingEdges
.
map
((
edge
:
Edge
)
=>
{
const
portId
=
edge
.
getTargetPortId
();
return
this
.
getPort
(
portId
!
);
});
}
getNewInPorts
(
length
:
number
)
{
return
Array
.
from
(
{
length
,
},
()
=>
{
return
{
group
:
'
in
'
,
};
},
);
}
updateInPorts
(
graph
:
Graph
)
{
const
minNumberOfPorts
=
8
;
const
ports
=
this
.
getInPorts
();
const
usedPorts
=
this
.
getUsedInPorts
(
graph
);
const
newPorts
=
this
.
getNewInPorts
(
Math
.
max
(
minNumberOfPorts
-
usedPorts
.
length
,
1
));
if
(
ports
.
length
===
minNumberOfPorts
&&
ports
.
length
-
usedPorts
.
length
>
0
)
{
// noop
}
else
if
(
ports
.
length
===
usedPorts
.
length
)
{
this
.
addPorts
(
newPorts
);
}
else
if
(
ports
.
length
+
1
>
usedPorts
.
length
)
{
this
.
prop
([
'
ports
'
,
'
items
'
],
this
.
getOutPorts
().
concat
(
usedPorts
).
concat
(
newPorts
),
{
rewrite
:
true
,
});
}
return
this
;
}
}
GateWay
.
config
({
attrs
:
{
root
:
{
magnet
:
false
,
},
body
:
{
fill
:
'
#ffa940
'
,
stroke
:
'
#d9d9d9
'
,
strokeWidth
:
1
,
},
},
ports
:
{
items
:
[
{
group
:
'
out
'
,
},
],
groups
:
{
in
:
{
position
:
{
name
:
'
top
'
,
},
attrs
:
{
portBody
:
{
magnet
:
'
passive
'
,
r
:
6
,
stroke
:
'
#ffa940
'
,
fill
:
'
#fff
'
,
strokeWidth
:
2
,
},
},
},
out
:
{
position
:
{
name
:
'
bottom
'
,
},
attrs
:
{
portBody
:
{
magnet
:
true
,
r
:
6
,
fill
:
'
#fff
'
,
stroke
:
'
#3199FF
'
,
strokeWidth
:
2
,
},
},
},
},
},
portMarkup
:
[
{
tagName
:
'
circle
'
,
selector
:
'
portBody
'
,
},
],
});
ClientApp/Angular/src/app/routes/routes-routing.module.ts
浏览文件 @
7e048363
...
...
@@ -5,6 +5,7 @@ import { environment } from '@env/environment';
// layout
import
{
LayoutBasicComponent
}
from
'
../layout/basic/basic.component
'
;
import
{
LayoutBlankComponent
}
from
'
../layout/blank/blank.component
'
;
import
{
DevicegraphComponent
}
from
'
./device/devicegraph/devicegraph.component
'
;
import
{
DevicelistComponent
}
from
'
./device/devicelist/devicelist.component
'
;
import
{
TenantlistComponent
}
from
'
./tenant/tenantlist/tenantlist.component
'
;
...
...
@@ -37,6 +38,7 @@ const routes: Routes = [
{
path
:
'
user/userlist
'
,
component
:
UserlistComponent
},
{
path
:
'
customer
'
,
loadChildren
:
()
=>
import
(
'
./customer/customer.module
'
).
then
((
m
)
=>
m
.
CustomerModule
)
},
{
path
:
'
device/devicelist
'
,
component
:
DevicelistComponent
},
{
path
:
'
device/devicegraph
'
,
component
:
DevicegraphComponent
},
],
},
...
...
ClientApp/Angular/src/app/routes/routes.module.ts
浏览文件 @
7e048363
...
...
@@ -13,6 +13,7 @@ import { ProppartComponent } from './device/deviceprop/proppart/proppart.compone
import
{
DesignerComponent
}
from
'
./device/designer/designer.component
'
;
import
{
UserlistComponent
}
from
'
./user/userlist/userlist.component
'
;
import
{
UserformComponent
}
from
'
./user/userform/userform.component
'
;
import
{
DevicegraphComponent
}
from
'
./device/devicegraph/devicegraph.component
'
;
const
COMPONENTS
:
Type
<
null
>
[]
=
[];
...
...
@@ -29,6 +30,7 @@ const COMPONENTS: Type<null>[] = [];
DesignerComponent
,
UserlistComponent
,
UserformComponent
,
DevicegraphComponent
,
],
})
export
class
RoutesModule
{}
ClientApp/Angular/tsconfig.app.json
浏览文件 @
7e048363
...
...
@@ -3,7 +3,8 @@
"extends"
:
"./tsconfig.json"
,
"compilerOptions"
:
{
"outDir"
:
"./out-tsc/app"
,
"types"
:
[
"node"
]
"types"
:
[
"node"
],
"skipLibCheck"
:
true
,
},
"files"
:
[
"src/main.ts"
,
"src/polyfills.ts"
],
"include"
:
[
"src/**/*.d.ts"
]
...
...
ClientApp/Vue/.husky/.gitignore
0 → 100644
浏览文件 @
7e048363
_
ClientApp/Vue/package.json
浏览文件 @
7e048363
...
...
@@ -34,6 +34,9 @@
"postinstall"
:
"npm run install:husky"
},
"dependencies"
:
{
"@antv/x6"
:
"^1.24.4"
,
"@antv/x6-react-components"
:
"^1.1.13"
,
"@antv/x6-vue3-shape"
:
"^1.0.0"
,
"@iconify/iconify"
:
"^2.0.2"
,
"@logicflow/core"
:
"^0.5.0"
,
"@logicflow/extension"
:
"^0.5.0"
,
...
...
@@ -45,6 +48,8 @@
"cropperjs"
:
"^1.5.12"
,
"crypto-js"
:
"^4.0.0"
,
"echarts"
:
"^5.1.2"
,
"guid-typescript"
:
"^1.0.9"
,
"imagemin-gifsicle"
:
"^7.0.0"
,
"intro.js"
:
"^4.1.0"
,
"lodash-es"
:
"^4.17.21"
,
"mockjs"
:
"^1.1.0"
,
...
...
ClientApp/Vue/src/router/routes/modules/iotsharp.ts
浏览文件 @
7e048363
...
...
@@ -42,6 +42,16 @@ const iotsharp: AppRouteModule = {
icon
:
'
simple-icons:about-dot-me
'
,
},
},
{
path
:
'
devicegraph
'
,
name
:
'
devicegraph
'
,
component
:
()
=>
import
(
'
../../../views/iotsharp/device/devicegraph.vue
'
),
meta
:
{
// title: t('routes.iotsharp.device'),
title
:
t
(
'
设计
'
),
icon
:
'
simple-icons:about-dot-me
'
,
},
},
{
path
:
'
user
'
,
name
:
'
User
'
,
...
...
ClientApp/Vue/src/views/iotsharp/device/devicegraph.vue
0 → 100644
浏览文件 @
7e048363
<
template
>
<div
class=
"x6-graph-wrap"
>
<div
ref=
"container"
class=
"x6-graph"
></div>
</div>
</
template
>
<
script
lang=
"ts"
>
//安装完X6但是报缺少MenuItem的错,是没有安装 @antv/x6-react-components,手动执行 yarn add @antv/x6-react-components,在angular这个又不是必要的,很有趣
import
{
Graph
,
Edge
,
Shape
,
NodeView
}
from
'
@antv/x6
'
;
import
{
defineComponent
,
ref
}
from
'
vue
'
;
// reactive
const
magnetAvailabilityHighlighter
=
{
name
:
'
stroke
'
,
args
:
{
attrs
:
{
fill
:
'
#fff
'
,
stroke
:
'
#47C769
'
,
},
},
};
export
default
defineComponent
({
name
:
'
Index
'
,
setup
()
{
const
canUndo
=
ref
(
true
);
const
canRedo
=
ref
(
false
);
const
graph
=
ref
(
Graph
);
const
init
:
(
any
)
=>
void
=
(
that
)
=>
{
that
.
graph
=
new
Graph
({
grid
:
true
,
container
:
that
.
$refs
.
container
as
HTMLDivElement
,
width
:
800
,
height
:
600
,
highlighting
:
{
magnetAvailable
:
magnetAvailabilityHighlighter
,
magnetAdsorbed
:
{
name
:
'
stroke
'
,
args
:
{
attrs
:
{
fill
:
'
#fff
'
,
stroke
:
'
#31d0c6
'
,
},
},
},
},
connecting
:
{
snap
:
true
,
allowBlank
:
false
,
allowLoop
:
false
,
highlight
:
true
,
connector
:
'
rounded
'
,
connectionPoint
:
'
boundary
'
,
router
:
{
name
:
'
er
'
,
args
:
{
direction
:
'
V
'
,
},
},
createEdge
()
{
return
new
Shape
.
Edge
({
attrs
:
{
line
:
{
stroke
:
'
#a0a0a0
'
,
strokeWidth
:
1
,
targetMarker
:
{
name
:
'
classic
'
,
size
:
7
,
},
},
},
});
},
validateConnection
({
sourceView
,
targetView
,
targetMagnet
})
{
if
(
!
targetMagnet
)
{
return
false
;
}
if
(
targetMagnet
.
getAttribute
(
'
port-group
'
)
!==
'
in
'
)
{
return
false
;
}
if
(
targetView
)
{
const
node
=
targetView
.
cell
;
if
(
node
instanceof
Device
)
{
const
portId
=
targetMagnet
.
getAttribute
(
'
port
'
);
const
usedInPorts
=
node
.
getUsedInPorts
(
this
);
if
(
usedInPorts
.
find
((
port
)
=>
port
&&
port
.
id
===
portId
))
{
return
false
;
}
}
}
return
true
;
},
},
});
that
.
graph
.
addNode
(
new
Device
({
attrs
:
{
root
:
{
magnet
:
false
,
},
body
:
{
fill
:
'
#f5f5f5
'
,
stroke
:
'
#d9d9d9
'
,
strokeWidth
:
1
,
},
},
ports
:
{
items
:
[
{
group
:
'
out
'
,
},
],
groups
:
{
in
:
{
position
:
{
name
:
'
top
'
,
},
attrs
:
{
portBody
:
{
magnet
:
'
passive
'
,
r
:
6
,
stroke
:
'
#ffa940
'
,
fill
:
'
#fff
'
,
strokeWidth
:
2
,
},
},
},
out
:
{
position
:
{
name
:
'
bottom
'
,
},
attrs
:
{
portBody
:
{
magnet
:
true
,
r
:
6
,
fill
:
'
#fff
'
,
stroke
:
'
#3199FF
'
,
strokeWidth
:
2
,
},
},
},
},
},
portMarkup
:
[
{
tagName
:
'
circle
'
,
selector
:
'
portBody
'
,
},
],
})
.
resize
(
120
,
40
)
.
position
(
200
,
50
)
.
updateInPorts
(
that
.
graph
)
);
that
.
graph
.
addNode
(
new
Device
().
resize
(
120
,
40
).
position
(
0
,
0
).
updateInPorts
(
that
.
graph
));
that
.
graph
.
addNode
(
new
GateWay
().
resize
(
120
,
40
).
position
(
300
,
250
).
updateInPorts
(
that
.
graph
)
);
that
.
graph
.
addNode
(
new
Device
().
resize
(
120
,
40
).
position
(
300
,
50
).
updateInPorts
(
that
.
graph
)
);
that
.
graph
.
addNode
(
new
Device
().
resize
(
120
,
40
).
position
(
400
,
50
).
updateInPorts
(
that
.
graph
)
);
// this.graph.fromJSON(this.data);
that
.
graph
.
on
(
'
edge:connected
'
,
({
previousView
,
currentView
})
=>
{
if
(
previousView
)
{
update
(
previousView
as
NodeView
);
}
if
(
currentView
)
{
update
(
currentView
as
NodeView
);
}
console
.
log
(
previousView
);
});
that
.
graph
.
on
(
'
edge:removed
'
,
({
edge
,
options
})
=>
{
if
(
!
options
.
ui
)
{
return
;
}
const
target
=
edge
.
getTargetCell
();
if
(
target
instanceof
Device
)
{
target
.
updateInPorts
(
that
.
graph
);
}
console
.
log
(
target
);
});
that
.
graph
.
on
(
'
edge:mouseenter
'
,
({
edge
})
=>
{
edge
.
addTools
([
'
source-arrowhead
'
,
'
target-arrowhead
'
,
{
name
:
'
button-remove
'
,
args
:
{
distance
:
-
30
,
},
},
]);
console
.
log
(
edge
);
});
that
.
graph
.
on
(
'
edge:mouseleave
'
,
({
edge
})
=>
{
edge
.
removeTools
();
});
};
const
update
:
(
view
:
NodeView
)
=>
void
=
(
view
:
NodeView
)
=>
{
const
cell
=
view
.
cell
;
if
(
cell
instanceof
Device
)
{
cell
.
getInPorts
().
forEach
((
port
)
=>
{
const
portNode
=
view
.
findPortElem
(
port
.
id
!
,
'
portBody
'
);
view
.
unhighlight
(
portNode
,
{
highlighter
:
magnetAvailabilityHighlighter
,
});
});
cell
.
updateInPorts
(
graph
);
}
};
return
{
canUndo
,
canRedo
,
history
,
init
,
update
,
graph
,
};
},
mounted
()
{
/* eslint-disable */
const
that
=
this
as
any
;
this
.
$nextTick
(
function
()
{
that
.
init
(
that
);
});
},
});
class
Device
extends
Shape
.
Circle
{
getInPorts
()
{
return
this
.
getPortsByGroup
(
'
in
'
);
}
getOutPorts
()
{
return
this
.
getPortsByGroup
(
'
out
'
);
}
getUsedInPorts
(
graph
:
Graph
)
{
const
incomingEdges
=
graph
.
getIncomingEdges
(
this
)
||
[];
return
incomingEdges
.
map
((
edge
:
Edge
)
=>
{
const
portId
=
edge
.
getTargetPortId
();
return
this
.
getPort
(
portId
!
);
});
}
getNewInPorts
(
length
:
number
)
{
return
Array
.
from
(
{
length
,
},
()
=>
{
return
{
group
:
'
in
'
,
};
}
);
}
updateInPorts
(
graph
:
Graph
)
{
const
minNumberOfPorts
=
1
;
const
ports
=
this
.
getInPorts
();
const
usedPorts
=
this
.
getUsedInPorts
(
graph
);
const
newPorts
=
this
.
getNewInPorts
(
Math
.
max
(
minNumberOfPorts
-
usedPorts
.
length
,
1
));
if
(
ports
.
length
===
minNumberOfPorts
&&
ports
.
length
-
usedPorts
.
length
>
0
)
{
// noop
}
else
if
(
ports
.
length
===
usedPorts
.
length
)
{
this
.
addPorts
(
newPorts
);
}
else
if
(
ports
.
length
+
1
>
usedPorts
.
length
)
{
this
.
prop
([
'
ports
'
,
'
items
'
],
this
.
getOutPorts
().
concat
(
usedPorts
).
concat
(
newPorts
),
{
rewrite
:
true
,
});
}
return
this
;
}
}
//只是demo,实际上是这个JSON结构应该从后端传过来,然后在Device的构造方法中传入,参看左上角第一个设备
Device
.
config
({
attrs
:
{
root
:
{
magnet
:
false
,
},
body
:
{
fill
:
'
#f5f5f5
'
,
stroke
:
'
#d9d9d9
'
,
strokeWidth
:
1
,
},
},
ports
:
{
items
:
[
{
group
:
'
out
'
,
},
],
groups
:
{
in
:
{
position
:
{
name
:
'
top
'
,
},
attrs
:
{
portBody
:
{
magnet
:
'
passive
'
,
r
:
6
,
stroke
:
'
#ffa940
'
,
fill
:
'
#fff
'
,
strokeWidth
:
2
,
},
},
},
out
:
{
position
:
{
name
:
'
bottom
'
,
},
attrs
:
{
portBody
:
{
magnet
:
true
,
r
:
6
,
fill
:
'
#fff
'
,
stroke
:
'
#3199FF
'
,
strokeWidth
:
2
,
},
},
},
},
},
portMarkup
:
[
{
tagName
:
'
circle
'
,
selector
:
'
portBody
'
,
},
],
});
class
GateWay
extends
Shape
.
Rect
{
getInPorts
()
{
return
this
.
getPortsByGroup
(
'
in
'
);
}
getOutPorts
()
{
return
this
.
getPortsByGroup
(
'
out
'
);
}
getUsedInPorts
(
graph
:
Graph
)
{
const
incomingEdges
=
graph
.
getIncomingEdges
(
this
)
||
[];
return
incomingEdges
.
map
((
edge
:
Edge
)
=>
{
const
portId
=
edge
.
getTargetPortId
();
return
this
.
getPort
(
portId
!
);
});
}
getNewInPorts
(
length
:
number
)
{
return
Array
.
from
(
{
length
,
},
()
=>
{
return
{
group
:
'
in
'
,
};
}
);
}
updateInPorts
(
graph
:
Graph
)
{
const
minNumberOfPorts
=
8
;
const
ports
=
this
.
getInPorts
();
const
usedPorts
=
this
.
getUsedInPorts
(
graph
);
const
newPorts
=
this
.
getNewInPorts
(
Math
.
max
(
minNumberOfPorts
-
usedPorts
.
length
,
1
));
if
(
ports
.
length
===
minNumberOfPorts
&&
ports
.
length
-
usedPorts
.
length
>
0
)
{
// noop
}
else
if
(
ports
.
length
===
usedPorts
.
length
)
{
this
.
addPorts
(
newPorts
);
}
else
if
(
ports
.
length
+
1
>
usedPorts
.
length
)
{
this
.
prop
([
'
ports
'
,
'
items
'
],
this
.
getOutPorts
().
concat
(
usedPorts
).
concat
(
newPorts
),
{
rewrite
:
true
,
});
}
return
this
;
}
}
GateWay
.
config
({
attrs
:
{
root
:
{
magnet
:
false
,
},
body
:
{
fill
:
'
#ffa940
'
,
stroke
:
'
#d9d9d9
'
,
strokeWidth
:
1
,
},
},
ports
:
{
items
:
[
{
group
:
'
out
'
,
},
],
groups
:
{
in
:
{
position
:
{
name
:
'
top
'
,
},
attrs
:
{
portBody
:
{
magnet
:
'
passive
'
,
r
:
6
,
stroke
:
'
#ffa940
'
,
fill
:
'
#fff
'
,
strokeWidth
:
2
,
},
},
},
out
:
{
position
:
{
name
:
'
bottom
'
,
},
attrs
:
{
portBody
:
{
magnet
:
true
,
r
:
6
,
fill
:
'
#fff
'
,
stroke
:
'
#3199FF
'
,
strokeWidth
:
2
,
},
},
},
},
},
portMarkup
:
[
{
tagName
:
'
circle
'
,
selector
:
'
portBody
'
,
},
],
});
</
script
>
<
style
scoped
></
style
>
ClientApp/Vue/src/views/iotsharp/device/devicelist.vue
浏览文件 @
7e048363
...
...
@@ -3,6 +3,7 @@
<div
class=
"mb-4"
>
<a-button
class=
"mr-2"
@
click=
"Open"
>
新增
</a-button>
<a-button
class=
"mr-2"
@
click=
"reloadTable"
>
刷新
</a-button>
<a-button
class=
"mr-2"
@
click=
"graphtest"
>
X6 Test
</a-button>
</div>
<BasicTable
@
register=
"registerTable"
:searchInfo=
"searchInfo"
@
expand=
"handleexpand"
>
...
...
@@ -24,7 +25,7 @@
</tr>
</tbody>
</table>
<BasicTitle
helpMessage=
"遥测数据"
>
遥测数据
</BasicTitle>
<BasicTitle
helpMessage=
"遥测数据"
>
遥测数据
</BasicTitle>
<table
style=
"width: 100%"
>
<tbody>
...
...
@@ -66,12 +67,14 @@
</BasicTable>
<deviceform
@
register=
"registerDrawer"
@
success=
"handleSuccess"
/>
<propform
@
register=
"propDrawer"
@
success=
"handleSuccess"
/>
<devicegraph
@
register=
"graphtestDrawer"
@
success=
"handleSuccess"
/>
</div>
</template>
<
script
lang=
"ts"
>
import
{
defineComponent
,
reactive
}
from
'
vue
'
;
import
{
BasicTable
,
ColumnChangeParam
,
useTable
,
TableAction
}
from
'
/@/components/Table
'
;
import
{
useDrawer
}
from
'
/@/components/Drawer
'
;
import
deviceform
from
'
./deviceform.vue
'
;
import
propform
from
'
./propform.vue
'
;
import
{
useRouter
}
from
'
vue-router
'
;
...
...
@@ -90,6 +93,7 @@
searchInfo
.
customerId
=
router
.
currentRoute
.
value
.
query
.
customerid
;
const
[
propDrawer
,
{
openDrawer
:
openPropDrawer
}]
=
useDrawer
();
const
[
registerDrawer
,
{
openDrawer
:
openDrawer
}]
=
useDrawer
();
function
onChange
()
{
console
.
log
(
'
onChange
'
,
arguments
);
}
...
...
@@ -123,7 +127,13 @@
isUpdate
:
false
,
});
}
function
graphtest
():
void
{
opengraphtestDrawer
(
true
,
{
// one of you need transfer data
data
:
{},
title
:
'
dummy title
'
,
});
}
function
PropEdit
(
record
:
Recordable
)
{
GetAttributeLatest
({
id
:
record
.
id
}).
then
((
x
)
=>
{
let
b
=
[{
keyName
:
'
id
'
,
value
:
record
.
id
},
...
x
];
...
...
@@ -172,8 +182,11 @@
PropEdit
,
handleexpand
,
registerDrawer
,
graphtest
,
propDrawer
,
openPropDrawer
,
searchInfo
,
};
},
...
...
ClientApp/Vue/src/views/iotsharp/device/propform.vue
浏览文件 @
7e048363
...
...
@@ -23,7 +23,6 @@
</template>
<
script
lang=
"ts"
>
import
{
Guid
}
from
'
guid-typescript
'
;
import
{
GetIdentity
,
Save
,
Update
,
SetAttribute
}
from
'
../../../api/iotsharp/device
'
;
import
{
defineComponent
,
ref
,
computed
,
unref
}
from
'
vue
'
;
import
{
BasicForm
,
useForm
}
from
'
/@/components/Form/index
'
;
...
...
@@ -59,14 +58,14 @@
async
function
handleSubmit
()
{
try
{
const
values
=
await
validate
();
console
.
log
(
values
);
setDrawerProps
({
confirmLoading
:
true
});
// TODO custom api
GetIdentity
(
values
.
id
).
then
((
x
)
=>
{
delete
values
.
id
;
//remove extra data
// delete values.accesstoken;
GetIdentity
(
values
.
id
).
then
((
x
)
=>
{
delete
values
.
id
;
//remove extra data
// delete values.accesstoken;
SetAttribute
(
values
,
x
.
identityId
).
then
((
y
)
=>
{
emit
(
'
success
'
);
...
...
ClientApp/Vue/src/views/iotsharp/device/useGraph.ts
0 → 100644
浏览文件 @
7e048363
import
{
shallowRef
,
ref
,
onMounted
}
from
'
vue
'
;
import
{
Graph
}
from
'
@antv/x6
'
;
import
'
@antv/x6-vue3-shape
'
;
import
Comp
from
'
./devicegraph.vue
'
;
export
default
function
useGraph
()
{
const
container
=
ref
<
HTMLElement
|
null
>
(
null
);
const
graph
=
shallowRef
<
Graph
|
null
>
();
onMounted
(()
=>
{
if
(
container
.
value
)
{
graph
.
value
=
new
Graph
({
container
:
container
.
value
,
panning
:
true
,
});
graph
.
value
.
addNode
({
id
:
'
node1
'
,
x
:
40
,
y
:
40
,
width
:
100
,
height
:
40
,
shape
:
'
vue3-shape
'
,
// here are 4 ways usages:
// 1. component: Comp
// 2. component: <Comp />
// 3. component: () => <Comp />
// 4. component: 'text node'
component
:
Comp
,
});
}
});
return
{
container
,
graph
,
};
}
ClientApp/Vue/yarn.lock
浏览文件 @
7e048363
此差异已折叠。
点击以展开。
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录