diff --git a/mocks/scene/getById b/mocks/scene/getById
index 0c3d458..f912358 100644
--- a/mocks/scene/getById
+++ b/mocks/scene/getById
@@ -4,7 +4,62 @@
"data": {
"id": "mock-scene-1",
"label": "模拟场景A",
- "robotGroups": [],
+ "robotGroups": [
+ {
+ "id": "mock-robot-group-1",
+ "label": "模拟机器人组A",
+ "robots": [
+ {
+ "id": "mock-robot-1",
+ "label": "模拟机器人A",
+ "brand": "模拟品牌A",
+ "type": 1,
+ "ip": "127.0.1.1"
+ },
+ {
+ "id": "mock-robot-2",
+ "label": "模拟机器人B",
+ "brand": "模拟品牌A",
+ "type": 2,
+ "ip": "127.0.1.2"
+ },
+ {
+ "id": "mock-robot-3",
+ "label": "模拟机器人C",
+ "brand": "模拟品牌A",
+ "type": 3,
+ "ip": "127.0.1.3"
+ }
+ ]
+ },
+ {
+ "id": "mock-robot-group-2",
+ "label": "模拟机器人组B",
+ "robots": [
+ {
+ "id": "mock-robot-4",
+ "label": "模拟机器人D",
+ "brand": "模拟品牌B",
+ "type": 1,
+ "ip": "127.0.2.1"
+ },
+ {
+ "id": "mock-robot-5",
+ "label": "模拟机器人E",
+ "brand": "模拟品牌B",
+ "type": 2,
+ "ip": "127.0.2.2"
+ },
+ {
+ "id": "mock-robot-6",
+ "label": "模拟机器人F",
+ "brand": "模拟品牌B",
+ "type": 3,
+ "ip": "127.0.2.3"
+ }
+ ]
+ }
+ ],
"map": ""
},
"message": "模拟提示"
diff --git a/package-lock.json b/package-lock.json
index 9c7435a..bb3cbce 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -8,6 +8,7 @@
"name": "arm_system",
"version": "0.0.0",
"dependencies": {
+ "@ant-design/icons-vue": "^7.0.1",
"@meta2d/core": "^1.0.78",
"@vueuse/rxjs": "^13.1.0",
"ant-design-vue": "^4.2.6",
diff --git a/package.json b/package.json
index 8ebb4a1..468c774 100644
--- a/package.json
+++ b/package.json
@@ -9,6 +9,7 @@
"preview": "vite preview"
},
"dependencies": {
+ "@ant-design/icons-vue": "^7.0.1",
"@meta2d/core": "^1.0.78",
"@vueuse/rxjs": "^13.1.0",
"ant-design-vue": "^4.2.6",
diff --git a/src/App.vue b/src/App.vue
index 3af02f3..cb67900 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -10,6 +10,8 @@ import sTheme from '@core/theme.service';
:autoInsertSpaceInButton="false"
:wave="{ disabled: true }"
>
-
+
+
+
diff --git a/src/_ant.scss b/src/_ant.scss
new file mode 100644
index 0000000..b12a982
--- /dev/null
+++ b/src/_ant.scss
@@ -0,0 +1,188 @@
+@use 'asset/themes/theme' as *;
+
+@include themed {
+ .ant-app {
+ width: 100vw;
+ height: 100vh;
+ overflow: hidden;
+ }
+
+ .ant-btn {
+ display: inline-flex;
+ align-items: center;
+ font: 400 14px/22px Roboto;
+ border-radius: 2px;
+
+ &.ant-btn-default {
+ color: get-color(primary);
+ background-color: get-color(141414);
+ border-color: get-color(primary);
+ box-shadow: 0 2px 0 0 get-color(00000005);
+ }
+
+ &.ant-btn-primary {
+ font-weight: 500;
+ color: get-color(141414);
+ background-color: get-color(primary);
+ border-color: get-color(primary);
+ box-shadow: 0 2px 0 0 get-color(0000000a);
+ }
+
+ &.warning {
+ font-weight: 500;
+ color: get-color(141414);
+ background-color: get-color(warning);
+ border-color: get-color(warning);
+ box-shadow: 0 2px 0 0 get-color(0000000a);
+ }
+ }
+
+ .ant-collapse.ant-collapse-ghost {
+ border-radius: 0;
+
+ & > .ant-collapse-item {
+ & > .ant-collapse-header {
+ align-items: center;
+ height: 36px;
+ padding: 0 0 0 8px;
+ font: 500 14px/22px Roboto;
+ color: get-color(ffffffd9);
+ background: get-color(ffffff14);
+ border-radius: 2px;
+
+ & > .ant-collapse-expand-icon {
+ width: 24px;
+ height: 24px;
+ padding: 0;
+
+ & > .ant-collapse-arrow {
+ font-size: 24px;
+
+ &.active {
+ transform: rotate(180deg);
+ }
+ }
+ }
+ }
+
+ & > .ant-collapse-content {
+ & > .ant-collapse-content-box {
+ padding: 0;
+ }
+ }
+
+ & + .ant-collapse-item {
+ margin-block-start: 8px;
+ }
+ }
+ }
+
+ .ant-input {
+ color: get-color(ffffffd9);
+ background-color: transparent;
+
+ &::placeholder {
+ color: get-color(ffffff40);
+ }
+ }
+
+ .ant-input-affix-wrapper {
+ box-shadow: none;
+
+ &::before {
+ display: none;
+ }
+
+ & > .ant-input-suffix {
+ margin-inline-start: 12px;
+ font-size: 16px;
+ color: get-color(ffffffd9);
+ }
+
+ &.search {
+ padding-inline-start: 7px;
+ background-color: transparent;
+ border-color: get-color(595959);
+ border-radius: 4px;
+ }
+ }
+
+ .ant-layout {
+ background-color: get-color(2a2c2c);
+
+ & > .ant-layout-header {
+ line-height: unset;
+ background-color: get-color(242525);
+ box-shadow: 0 2px 8px 0 get-color(00000026);
+ }
+
+ & > .ant-layout-sider {
+ background-color: get-color(36393a);
+ border-radius: 8px;
+ box-shadow: 0 2px 8px 0 get-color(ffffff14);
+ }
+ }
+
+ .ant-list-items {
+ & > .ant-list-item {
+ padding: 0;
+ border-color: get-color(f9f9f914);
+
+ &:hover {
+ background-color: get-color(f9f9f914);
+ }
+ }
+ }
+
+ .ant-tabs {
+ border-radius: 8px;
+
+ & > .ant-tabs-nav {
+ margin: 0;
+ background-color: get-color(ffffff2e);
+
+ & > .ant-tabs-nav-wrap > .ant-tabs-nav-list {
+ & > .ant-tabs-tab {
+ padding: 14px 32px;
+ margin: 0;
+ font: 400 16px/20px Roboto;
+ color: get-color(ffffff73);
+ background-color: transparent;
+ border: none;
+ border-radius: 0;
+
+ & > .ant-tabs-tab-btn {
+ color: inherit;
+ text-shadow: none;
+ }
+
+ &.ant-tabs-tab-active {
+ font-weight: 600;
+ color: get-color(primary);
+ background-color: get-color(36393a);
+ }
+ }
+
+ & > .ant-tabs-ink-bar {
+ display: none;
+ }
+ }
+ }
+
+ & > .ant-tabs-content-holder > .ant-tabs-content {
+ height: 100%;
+ padding: 16px;
+ overflow-y: auto;
+ }
+ }
+
+ .ant-typography {
+ font: 400 14px/22px Roboto;
+ color: get-color(ffffffa6);
+
+ & > strong {
+ font: 500 16px/22px SourceHanSansSC;
+ color: get-color(ffffffd9);
+ }
+ }
+}
diff --git a/src/_icon.scss b/src/_icon.scss
new file mode 100644
index 0000000..79604ca
--- /dev/null
+++ b/src/_icon.scss
@@ -0,0 +1,19 @@
+@use 'asset/themes/theme' as *;
+@use 'asset/icons/icon' as *;
+
+@include themed {
+ .icon {
+ display: inline-block;
+ width: 1em;
+ height: 1em;
+ font-size: 18px;
+ line-height: 1;
+ vertical-align: top;
+
+ @each $icon in $icons {
+ &.#{$icon} {
+ background: get-icon($icon);
+ }
+ }
+ }
+}
diff --git a/src/ant.scss b/src/ant.scss
deleted file mode 100644
index 4c43d0a..0000000
--- a/src/ant.scss
+++ /dev/null
@@ -1,84 +0,0 @@
-@use 'asset/themes/theme' as *;
-
-@include themed {
- .ant-btn {
- display: inline-flex;
- align-items: center;
- font: 400 14px/22px Roboto;
- border-radius: 2px;
-
- &.ant-btn-default {
- color: get-color(primary);
- background-color: get-color(141414);
- border-color: get-color(primary);
- box-shadow: 0 2px 0 0 get-color(00000005);
- }
-
- &.ant-btn-primary {
- font-weight: 500;
- color: get-color(141414);
- background-color: get-color(primary);
- border-color: get-color(primary);
- box-shadow: 0 2px 0 0 get-color(0000000a);
- }
- }
-
- .ant-layout {
- background-color: get-color(2a2c2c);
-
- & > .ant-layout-header {
- line-height: unset;
- background-color: get-color(242525);
- box-shadow: 0 2px 8px 0 get-color(00000026);
- }
-
- & > .ant-layout-sider {
- background-color: get-color(36393a);
- border-radius: 8px;
- box-shadow: 0 2px 8px 0 get-color(ffffff14);
- }
- }
-
- .ant-tabs {
- border-radius: 8px;
-
- & > .ant-tabs-nav {
- margin: 0;
- background-color: get-color(ffffff2e);
-
- & > .ant-tabs-nav-wrap > .ant-tabs-nav-list {
- & > .ant-tabs-tab {
- padding: 14px 32px;
- margin: 0;
- font: 400 16px/20px Roboto;
- color: get-color(ffffff73);
- background-color: transparent;
- border: none;
- border-radius: 0;
-
- & > .ant-tabs-tab-btn {
- color: inherit;
- text-shadow: none;
- }
-
- &.ant-tabs-tab-active {
- font-weight: 600;
- color: get-color(primary);
- background-color: get-color(36393a);
- }
- }
-
- & > .ant-tabs-ink-bar {
- display: none;
- }
- }
- }
- }
-
- .ant-typography {
- & > strong {
- font: 500 16px/22px SourceHanSansSC;
- color: get-color(ffffffd9);
- }
- }
-}
diff --git a/src/apis/robot/type.ts b/src/apis/robot/type.ts
index b83234c..73f1c5a 100644
--- a/src/apis/robot/type.ts
+++ b/src/apis/robot/type.ts
@@ -3,7 +3,7 @@ import type { RobotBrand, RobotState, RobotType } from './constant';
export interface RobotGroup {
id: string; // 机器人组id
label: string; // 机器人组名称
- robotIds: number[]; // 机器人id列表
+ robots: RobotInfo[]; // 机器人列表
}
export interface RobotInfo {
diff --git a/src/assets/icons/_icon.scss b/src/assets/icons/_icon.scss
index 414c998..26f002b 100644
--- a/src/assets/icons/_icon.scss
+++ b/src/assets/icons/_icon.scss
@@ -1,16 +1 @@
-$icons: (edit upload);
-
-.icon {
- display: inline;
- width: 1em;
- height: 1em;
- font-size: 18px;
- line-height: 1;
- vertical-align: top;
-
- @each $icon in $icons {
- &.#{$icon} {
- background: url(./#{$icon}.png) center / contain no-repeat;
- }
- }
-}
+$icons: (dropdown, edit, exit);
diff --git a/src/assets/icons/dark/dropdown.png b/src/assets/icons/dark/dropdown.png
new file mode 100644
index 0000000..b1203d9
Binary files /dev/null and b/src/assets/icons/dark/dropdown.png differ
diff --git a/src/assets/icons/edit.png b/src/assets/icons/dark/edit.png
similarity index 100%
rename from src/assets/icons/edit.png
rename to src/assets/icons/dark/edit.png
diff --git a/src/assets/icons/upload.png b/src/assets/icons/dark/exit.png
similarity index 100%
rename from src/assets/icons/upload.png
rename to src/assets/icons/dark/exit.png
diff --git a/src/assets/themes/_dark.scss b/src/assets/themes/_dark.scss
index 5d2b14c..8c84f93 100644
--- a/src/assets/themes/_dark.scss
+++ b/src/assets/themes/_dark.scss
@@ -1,4 +1,4 @@
-$color: (
+$colors: (
primary: #0dbb8a,
warning: #d89614,
111e1b: #111e1b,
@@ -8,6 +8,7 @@ $color: (
00000005: #00000005,
0000000a: #0000000a,
00000026: #00000026,
+ f9f9f914: #f9f9f914,
000000: #000,
2a2c2c: #2a2c2c,
diff --git a/src/assets/themes/_light.scss b/src/assets/themes/_light.scss
index 05d55b8..7f6e0e3 100644
--- a/src/assets/themes/_light.scss
+++ b/src/assets/themes/_light.scss
@@ -1,3 +1,3 @@
-$color: (
+$colors: (
text-1: #000,
);
diff --git a/src/assets/themes/_theme.scss b/src/assets/themes/_theme.scss
index 54d6d64..146b5ae 100644
--- a/src/assets/themes/_theme.scss
+++ b/src/assets/themes/_theme.scss
@@ -4,14 +4,16 @@
$themes: (dark, light);
$theme-map: (
- dark-color: dark.$color,
+ dark-colors: dark.$colors,
- light-color: light.$color,
+ light-colors: light.$colors,
);
@mixin themed {
@each $theme in $themes {
- $theme-color: map.get($theme-map, #{$theme}-color) !global;
+ $theme: $theme !global;
+ $theme-colors: map.get($theme-map, #{$theme}-colors) !global;
+
:root[theme='#{$theme}'] {
@content;
}
@@ -19,5 +21,9 @@ $theme-map: (
}
@function get-color($key) {
- @return map.get($theme-color, $key);
+ @return map.get($theme-colors, $key);
+}
+
+@function get-icon($name) {
+ @return url(asset/icons/#{$theme}/#{$name}.png) center / contain no-repeat;
}
diff --git a/src/components/robot-group.vue b/src/components/robot-group.vue
index 26c87f1..99223df 100644
--- a/src/components/robot-group.vue
+++ b/src/components/robot-group.vue
@@ -1,49 +1,54 @@
-
- 常规
- 点位
-
-
- 库区
- 互斥区
- 非互斥区
-
+
+
+
+
+
+
+ {{ $t('全选') }}
+
+
+
+
+
+
+
+
+
+
+
+ {{ item.label }}
+
+
+
+
+
+
diff --git a/src/components/test.vue b/src/components/test.vue
new file mode 100644
index 0000000..f44835c
--- /dev/null
+++ b/src/components/test.vue
@@ -0,0 +1,65 @@
+
+
+
+
+ 常规
+ 点位
+
+
+ 库区
+ 互斥区
+ 非互斥区
+
+ 常规
+ 点位
+
+
+ 库区
+ 互斥区
+ 非互斥区
+
+ 常规
+ 点位
+
+
+ 库区
+ 互斥区
+ 非互斥区
+
+
+
+
diff --git a/src/pages/scene-editor.vue b/src/pages/scene-editor.vue
index 8530b21..e3d4820 100644
--- a/src/pages/scene-editor.vue
+++ b/src/pages/scene-editor.vue
@@ -35,6 +35,9 @@ onMounted(() => {
});
const editable = ref(false);
+watch(editable, (v) => {
+ editor.value?.setState(v);
+});
@@ -43,8 +46,12 @@ const editable = ref(false);
{{ title }}
-
-
+
+
+ {{ $t('退出编辑器') }}
+
+
+
{{ $t('启用编辑器') }}
{{ $t('推送') }}
@@ -58,7 +65,7 @@ const editable = ref(false);
-
+
Content of Tab Pane 2
Content of Tab Pane 3
diff --git a/src/services/editor.service.ts b/src/services/editor.service.ts
index d7bfe58..f1e9ee4 100644
--- a/src/services/editor.service.ts
+++ b/src/services/editor.service.ts
@@ -12,7 +12,7 @@ export class EditorService extends Meta2d {
public load(map?: string, readonly = false): void {
const data = map ? JSON.parse(map) : undefined;
this.open(data);
- this.lock(readonly ? LockState.Disable : LockState.None);
+ this.setState(readonly);
}
public save(): string {
const data = this.data();
@@ -48,6 +48,10 @@ export class EditorService extends Meta2d {
return super.find(target);
}
+ public setState(readonly?: boolean): void {
+ this.lock(readonly ? LockState.Disable : LockState.None);
+ }
+
//#region 点位
public async addPoint(p: Point, type = MapPointType.普通点): Promise {
const pen: MapPen = {
diff --git a/src/services/router.ts b/src/services/router.ts
index 151a226..f02f6d4 100644
--- a/src/services/router.ts
+++ b/src/services/router.ts
@@ -7,6 +7,7 @@ export const ROUTES = Object.freeze([
props: true,
component: () => import('@/exception.vue'),
},
+
{
path: '/scene-editor/:id',
props: true,
diff --git a/src/style.scss b/src/style.scss
index 319cea3..7fc8567 100644
--- a/src/style.scss
+++ b/src/style.scss
@@ -1,5 +1,5 @@
@use './ant';
-@use 'asset/icons/icon';
+@use './icon';
@use 'asset/fonts/font';
html,
@@ -7,13 +7,15 @@ body {
width: 100vw;
height: 100vh;
margin: 0;
+ font: 400 14px/20px system-ui;
user-select: none;
-webkit-user-drag: none;
}
-#app {
- width: 100%;
- height: 100%;
+* {
+ &::-webkit-scrollbar {
+ display: none;
+ }
}
.full {
@@ -22,15 +24,15 @@ body {
overflow: hidden;
}
-@for $i from 0 through 100 {
+.scroll {
+ overflow-y: auto;
+}
+
+@for $i from 0 through 20 {
.size-#{$i * 2} {
font-size: $i * 2px !important;
}
- .w-#{$i * 4} {
- width: $i * 4px !important;
- }
-
.p-#{$i * 2} {
padding: $i * 2px !important;
}