@v2coding/ui 0.1.3 → 0.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,236 @@
1
+ <template>
2
+ <div class="ui-field-latlng" v-loading="loading">
3
+ <div class="map"></div>
4
+ <div class="info" v-show="!loading">
5
+ <div class="input-item searchbox">
6
+ <div class="input-item-prepend">
7
+ <span class="input-item-text">搜索关键字</span>
8
+ </div>
9
+ <!-- form="__ignore__" 避免 enter提交表单 -->
10
+ <input ref="input" type="text" form="__ignore__" placeholder="请输入...">
11
+ <div ref="output" class="search-result"></div>
12
+ </div>
13
+ </div>
14
+ </div>
15
+ </template>
16
+
17
+ <script>
18
+ import gcoord from 'gcoord';
19
+ import {getAMap} from '../../config/config.amap';
20
+ import FieldMixin from './field.mixin';
21
+
22
+ const CoordTypes = {
23
+ bd09: gcoord.BD09,
24
+ gcj02: gcoord.GCJ02,
25
+ wgs84: gcoord.WGS84,
26
+ };
27
+
28
+ export default {
29
+ name: 'ui-field-latlng',
30
+ mixins: [FieldMixin],
31
+ props: {
32
+ coordType: {
33
+ type: String,
34
+ default: 'wgs84',
35
+ validator: (val) => Object.keys(CoordTypes).includes(val),
36
+ },
37
+ },
38
+ data() {
39
+ return {
40
+ loading: true,
41
+ keyword: '',
42
+ };
43
+ },
44
+ computed: {
45
+ point() {
46
+ if (!this.value) {
47
+ return null;
48
+ }
49
+ if (!this.isValidPoint(this.value)) {
50
+ return null;
51
+ }
52
+ const [lat, lng] = this.value.split(',');
53
+ return {lat: +lat, lng: +lng};
54
+ },
55
+ },
56
+ watch: {
57
+ point(p) {
58
+ this.onPointChange(p);
59
+ },
60
+ },
61
+ methods: {
62
+ init() {
63
+ getAMap(['AMap.ToolBar', 'AMap.Geolocation', 'AMap.AutoComplete']).then((AMap) => {
64
+ this.initMap(AMap);
65
+ this.loading = false;
66
+ this.done();
67
+ });
68
+ },
69
+ initMap(AMap) {
70
+ const map = new AMap.Map(this.$el.querySelector('.map'), {
71
+ zoom: 11,
72
+ });
73
+
74
+ map.addControl(new AMap.ToolBar({position: 'RT'}));
75
+ map.addControl(new AMap.Geolocation({position: 'RB'}));
76
+ const auto = new AMap.AutoComplete({
77
+ input: this.$refs.input,
78
+ output: this.$refs.output,
79
+ });
80
+
81
+ map.on('click', this.onMapClick);
82
+ auto.on('select', (event) => {
83
+ if (!event.poi || !event.poi.location) {
84
+ return;
85
+ }
86
+ map.setZoomAndCenter(16, event.poi.location);
87
+ });
88
+
89
+ this.map = map;
90
+
91
+ this.onPointChange(this.point);
92
+ },
93
+ isValidPoint(val) {
94
+ const [lat, lng] = val.split(',');
95
+ return !(isNaN(+lat) || isNaN(+lng));
96
+ },
97
+ onMapClick({lnglat}) {
98
+ let {lat, lng} = lnglat;
99
+ // 当前地图是 GCJ02 坐标系
100
+ if (this.coordType !== 'gcj02') {
101
+ [lng, lat] = gcoord.transform([lng, lat], gcoord.GCJ02, CoordTypes[this.coordType]);
102
+ lng = lng.toFixed(7) / 1;
103
+ lat = lat.toFixed(7) / 1;
104
+ }
105
+ this.onChange([lat, lng].join(','));
106
+ },
107
+ onPointChange(point) {
108
+ if (!this.map) {
109
+ return;
110
+ }
111
+ this.map.clearMap();
112
+ if (!point) {
113
+ return;
114
+ }
115
+ let {lng, lat} = point;
116
+ // 当前地图是 GCJ02 坐标系
117
+ if (this.coordType !== 'gcj02') {
118
+ [lng, lat] = gcoord.transform([lng, lat], CoordTypes[this.coordType], gcoord.GCJ02);
119
+ }
120
+ // eslint-disable-next-line no-undef
121
+ const marker = new AMap.Marker({position: new AMap.LngLat(lng, lat)});
122
+ this.map.add(marker);
123
+ this.map.setCenter([lng, lat]);
124
+ },
125
+ },
126
+ };
127
+ </script>
128
+
129
+ <style lang="less">
130
+ .ui-field-latlng {
131
+ width: 100%;
132
+ height: 280px;
133
+ position: relative;
134
+
135
+ .map {
136
+ width: 100%;
137
+ height: 100%;
138
+ }
139
+
140
+ .info {
141
+ position: absolute;
142
+ top: 0;
143
+ left: 0;
144
+ right: 0;
145
+ bottom: 0;
146
+ pointer-events: none;
147
+
148
+ .searchbox {
149
+ left: 12px;
150
+ top: 12px;
151
+ background-color: #fff;
152
+ box-shadow: 0 0 3px rgba(0, 0, 0, .5);
153
+ pointer-events: initial;
154
+ border-radius: 3px;
155
+ padding: 3px;
156
+
157
+ .search-result {
158
+ position: absolute;
159
+ top: calc(100% - 2px);
160
+ left: 0;
161
+ right: 0;
162
+ background-color: #fefefe;
163
+ box-shadow: 0 1px 3px #999 ;
164
+ visibility: hidden;
165
+ border-radius: 0 0 3px 3px;
166
+
167
+ .auto-item {
168
+ white-space: nowrap;
169
+ font-size: 12px;
170
+ cursor: pointer;
171
+ padding: 4px;
172
+ line-height: 14px;
173
+ }
174
+ }
175
+ }
176
+ }
177
+
178
+ .input-item {
179
+ position: relative;
180
+ display: inline-flex;
181
+ align-items: center;
182
+ width: 220px;
183
+ font-size: 12px;
184
+
185
+ .input-item-prepend {
186
+ margin-right: -1px;
187
+
188
+ .input-item-text {
189
+ padding: 0.25em 0.5em;
190
+ display: block;
191
+ text-justify: distribute-all-lines;
192
+ text-align-last: justify;
193
+ align-items: center;
194
+ margin-bottom: 0;
195
+ font-weight: 400;
196
+ line-height: 1.5;
197
+ color: #495057;
198
+ text-align: center;
199
+ white-space: nowrap;
200
+ background-color: #e9ecef;
201
+ border: 1px solid #ced4da;
202
+ border-radius: .25rem 0 0 .25rem;
203
+ box-sizing: border-box;
204
+ }
205
+ }
206
+
207
+ input {
208
+ position: relative;
209
+ flex: 1 1 auto;
210
+ width: 1%;
211
+ margin: 0;
212
+ background: #fff;
213
+ padding: 0.25em 0.5em;
214
+ display: inline-block;
215
+ line-height: 1.5;
216
+ color: #495057;
217
+ vertical-align: middle;
218
+ border: 1px solid #ced4da;
219
+ border-radius: 0 .25rem .25rem 0;
220
+ appearance: none;
221
+ box-sizing: border-box;
222
+
223
+ &:focus {
224
+ border-color: #80bdff;
225
+ outline: 0;
226
+ box-shadow: 0 0 0 0.1rem rgba(128, 189, 255, .1);
227
+ }
228
+ }
229
+ }
230
+
231
+ .amap-logo,
232
+ .amap-copyright {
233
+ display: none !important;
234
+ }
235
+ }
236
+ </style>
@@ -79,7 +79,7 @@
79
79
  },
80
80
  createAttachmentUrl: {
81
81
  type: String,
82
- default: '/Sys/SysAttachment/create',
82
+ default: '/System/SystemSysAttachment/create',
83
83
  },
84
84
  createAttachmentParams: null,
85
85
  createAttachment: {
@@ -109,7 +109,7 @@ export default {
109
109
  this.$emit("remove-history", { type: "current", name: path });
110
110
  },
111
111
  onContextMenu(event) {
112
- const container = this.$el.querySelector(".scroll-nav__nav");
112
+ const container = this.$el.querySelector(".ui-scroll-view__nav");
113
113
  const index = this.getChildContainIndex(container, event.target);
114
114
  const rect = this.$el.getBoundingClientRect();
115
115
  if (index !== -1) {
@@ -168,7 +168,7 @@ export default {
168
168
  position: relative;
169
169
  margin: 10px 0 0;
170
170
 
171
- .history-tabs.scroll-nav__nav-wrap {
171
+ .history-tabs.ui-scroll-view__nav-wrap {
172
172
  left: 0;
173
173
  right: 0;
174
174
  top: 0;
@@ -176,11 +176,11 @@ export default {
176
176
  position: absolute;
177
177
  align-items: flex-end;
178
178
 
179
- .scroll-nav__nav-scroll {
179
+ .ui-scroll-view__nav-scroll {
180
180
  flex: 1;
181
181
  }
182
182
 
183
- .scroll-nav__nav-control {
183
+ .ui-scroll-view__nav-control {
184
184
  width: 20px;
185
185
  height: 30px;
186
186
 
@@ -194,7 +194,7 @@ export default {
194
194
  }
195
195
  }
196
196
 
197
- .scroll-nav__nav {
197
+ .ui-scroll-view__nav {
198
198
  align-items: flex-end;
199
199
  }
200
200
 
@@ -779,7 +779,7 @@
779
779
 
780
780
  .ui-table-empty {
781
781
  padding-top: 110px;
782
- background: url("../../assets/svg/empty.svg") center top no-repeat;
782
+ background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTg0IiBoZWlnaHQ9IjE1MiIgdmlld0JveD0iMCAwIDE4NCAxNTIiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CiAgPGcgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIj4KICAgIDxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKDI0IDMxLjY3KSI+CiAgICAgIDxlbGxpcHNlIGZpbGwtb3BhY2l0eT0iLjgiIGZpbGw9IiNGNUY1RjciIGN4PSI2Ny43OTciIGN5PSIxMDYuODkiIHJ4PSI2Ny43OTciIHJ5PSIxMi42NjgiPjwvZWxsaXBzZT4KICAgICAgPHBhdGggZD0iTTEyMi4wMzQgNjkuNjc0TDk4LjEwOSA0MC4yMjljLTEuMTQ4LTEuMzg2LTIuODI2LTIuMjI1LTQuNTkzLTIuMjI1aC01MS40NGMtMS43NjYgMC0zLjQ0NC44MzktNC41OTIgMi4yMjVMMTMuNTYgNjkuNjc0djE1LjM4M2gxMDguNDc1VjY5LjY3NHoiIGZpbGw9IiNBRUI4QzIiPjwvcGF0aD4KICAgICAgPHBhdGggZD0iTTEwMS41MzcgODYuMjE0TDgwLjYzIDYxLjEwMmMtMS4wMDEtMS4yMDctMi41MDctMS44NjctNC4wNDgtMS44NjdIMzEuNzI0Yy0xLjU0IDAtMy4wNDcuNjYtNC4wNDggMS44NjdMNi43NjkgODYuMjE0djEzLjc5Mmg5NC43NjhWODYuMjE0eiIgZmlsbD0idXJsKCNsaW5lYXJHcmFkaWVudC0xKSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTMuNTYpIj48L3BhdGg+CiAgICAgIDxwYXRoIGQ9Ik0zMy44MyAwaDY3LjkzM2E0IDQgMCAwIDEgNCA0djkzLjM0NGE0IDQgMCAwIDEtNCA0SDMzLjgzYTQgNCAwIDAgMS00LTRWNGE0IDQgMCAwIDEgNC00eiIgZmlsbD0iI0Y1RjVGNyI+PC9wYXRoPgogICAgICA8cGF0aAogICAgICAgIGQ9Ik00Mi42NzggOS45NTNoNTAuMjM3YTIgMiAwIDAgMSAyIDJWMzYuOTFhMiAyIDAgMCAxLTIgMkg0Mi42NzhhMiAyIDAgMCAxLTItMlYxMS45NTNhMiAyIDAgMCAxIDItMnpNNDIuOTQgNDkuNzY3aDQ5LjcxM2EyLjI2MiAyLjI2MiAwIDEgMSAwIDQuNTI0SDQyLjk0YTIuMjYyIDIuMjYyIDAgMCAxIDAtNC41MjR6TTQyLjk0IDYxLjUzaDQ5LjcxM2EyLjI2MiAyLjI2MiAwIDEgMSAwIDQuNTI1SDQyLjk0YTIuMjYyIDIuMjYyIDAgMCAxIDAtNC41MjV6TTEyMS44MTMgMTA1LjAzMmMtLjc3NSAzLjA3MS0zLjQ5NyA1LjM2LTYuNzM1IDUuMzZIMjAuNTE1Yy0zLjIzOCAwLTUuOTYtMi4yOS02LjczNC01LjM2YTcuMzA5IDcuMzA5IDAgMCAxLS4yMjItMS43OVY2OS42NzVoMjYuMzE4YzIuOTA3IDAgNS4yNSAyLjQ0OCA1LjI1IDUuNDJ2LjA0YzAgMi45NzEgMi4zNyA1LjM3IDUuMjc3IDUuMzdoMzQuNzg1YzIuOTA3IDAgNS4yNzctMi40MjEgNS4yNzctNS4zOTNWNzUuMWMwLTIuOTcyIDIuMzQzLTUuNDI2IDUuMjUtNS40MjZoMjYuMzE4djMzLjU2OWMwIC42MTctLjA3NyAxLjIxNi0uMjIxIDEuNzg5eiIKICAgICAgICBmaWxsPSIjRENFMEU2Ij48L3BhdGg+CiAgICA8L2c+CiAgICA8cGF0aCBkPSJNMTQ5LjEyMSAzMy4yOTJsLTYuODMgMi42NWExIDEgMCAwIDEtMS4zMTctMS4yM2wxLjkzNy02LjIwN2MtMi41ODktMi45NDQtNC4xMDktNi41MzQtNC4xMDktMTAuNDA4QzEzOC44MDIgOC4xMDIgMTQ4LjkyIDAgMTYxLjQwMiAwIDE3My44ODEgMCAxODQgOC4xMDIgMTg0IDE4LjA5N2MwIDkuOTk1LTEwLjExOCAxOC4wOTctMjIuNTk5IDE4LjA5Ny00LjUyOCAwLTguNzQ0LTEuMDY2LTEyLjI4LTIuOTAyeiIgZmlsbD0iI0RDRTBFNiI+PC9wYXRoPgogICAgPGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTQ5LjY1IDE1LjM4MykiIGZpbGw9IiNGRkYiPgogICAgICA8ZWxsaXBzZSBjeD0iMjAuNjU0IiBjeT0iMy4xNjciIHJ4PSIyLjg0OSIgcnk9IjIuODE1Ij48L2VsbGlwc2U+CiAgICAgIDxwYXRoIGQ9Ik01LjY5OCA1LjYzSDBMMi44OTguNzA0ek05LjI1OS43MDRoNC45ODVWNS42M0g5LjI1OXoiPjwvcGF0aD4KICAgIDwvZz4KICA8L2c+Cjwvc3ZnPgo=) center top no-repeat;
783
783
  background-size: auto 100px;
784
784
  color: rgba(0, 0, 0, 0.65);
785
785
  font-size: 14px;
@@ -1,188 +0,0 @@
1
- <template>
2
- <el-menu
3
- class="head-menu"
4
- v-bind="$attrs"
5
- v-on="$listeners"
6
- :mode="mode"
7
- :router="router"
8
- :default-active="active"
9
- >
10
- <menu-item v-for="item in displayMenus" :item="item" :key="item.id"/>
11
- </el-menu>
12
- </template>
13
-
14
- <script>
15
- import {mapState} from 'vuex';
16
- import MenuItem from './menu-item';
17
-
18
- export default {
19
- name: 'ui-head-menu',
20
- components: {MenuItem},
21
- provide() {
22
- return {
23
- headMenu: this,
24
- };
25
- },
26
- props: {
27
- router: {
28
- type: Boolean,
29
- default: true,
30
- },
31
- defaultActive: String,
32
- mode: {
33
- default: 'horizontal',
34
- },
35
- },
36
- data() {
37
- return {
38
- packUpWidth: 0,
39
- };
40
- },
41
- computed: {
42
- ...mapState(['menus']),
43
- headMenu() {
44
- // eslint-disable-next-line
45
- return this.menus.filter(menu => [1, 2].includes(menu.type)).map(({children, ...menu}) => menu);
46
- },
47
- active() {
48
- if (!this.router) {
49
- return this.defaultActive;
50
- }
51
- const currentPath = this.$route.path;
52
- const isHeadRoute = this.headMenu.some(menu => menu.url === currentPath);
53
- if (isHeadRoute) {
54
- return currentPath;
55
- }
56
- const currentHeadMenu = this.getCurrentHeadMenu(currentPath, this.menus);
57
- return currentHeadMenu && (currentHeadMenu.path || currentHeadMenu.url);
58
- },
59
- menuWidth() {
60
- return this.headMenu.reduce((total, item) => {
61
- return total + (item.name || '').split('').length * 16 + 25 * 2; // 16:字体大小值; 25:左右padding/margin值
62
- }, 60); // 100:菜单左边的margin值
63
- },
64
- packUpIndex() {
65
- if (this.packUpWidth <= 0) {
66
- return -1;
67
- }
68
- let index = -1;
69
- let width = this.packUpWidth + 130; // 50:更多下拉菜单所占宽度
70
- for(let i = this.headMenu.length - 1; i >= 0; i--) {
71
- const item = this.headMenu[i];
72
- const currentWidth = (item.name || '').split('').length * 16 + 25 * 2;
73
- if (currentWidth >= width) {
74
- index = i - 1;
75
- break;
76
- }
77
- width = width - currentWidth;
78
- }
79
- return Math.max(0, index);
80
- },
81
- displayMenus() {
82
- if (this.packUpIndex === -1) {
83
- return this.headMenu;
84
- }
85
- const menus = this.headMenu.slice(0, this.packUpIndex);
86
- const moreMenus = this.headMenu.slice(this.packUpIndex);
87
- menus.push({
88
- id: 'more',
89
- name: '更多菜单',
90
- children: moreMenus,
91
- });
92
- return menus;
93
- },
94
- },
95
- mounted() {
96
- window.addEventListener('resize', this.onResize);
97
- this.onResize();
98
-
99
- const logo = document.querySelector('.page-header > .logo');
100
- logo && logo.addEventListener('load', () => this.onResize());
101
- },
102
- beforeDestroy() {
103
- window.removeEventListener('resize', this.onResize);
104
- },
105
- methods: {
106
- onResize() {
107
- clearTimeout(this.timer);
108
- this.timer = setTimeout(() => {
109
- const headerWidth = document.documentElement.clientWidth;
110
- const logoEl = document.querySelector('.page-header > .logo');
111
- const titleEl = document.querySelector('.page-header > .title');
112
- const messageEl = document.querySelector('.page-header > .screen');
113
- const usernameEl = document.querySelector('.page-header > .username');
114
- const logoWidth = (logoEl && logoEl.offsetWidth || 0) + 20; // 20 margin
115
- const titleWidth = titleEl && titleEl.offsetWidth || 0;
116
- const messageElWidth = messageEl && messageEl.offsetWidth || 0;
117
- const usernameWidth = usernameEl && usernameEl.offsetWidth || 0;
118
- const allowedMenuWidth = headerWidth - 60 - logoWidth - titleWidth - messageElWidth - usernameWidth;
119
- this.packUpWidth = Math.max(0, this.menuWidth - allowedMenuWidth);
120
- }, 50);
121
- },
122
- getCurrentHeadMenu(path, menus) {
123
- if (!Array.isArray(menus) || menus.length <= 0) {
124
- return undefined;
125
- }
126
- return menus.find(menu => {
127
- const isMatched = (menu.children || []).some(childMenu => (childMenu.path || childMenu.url) === path);
128
- if (isMatched) {
129
- return true;
130
- }
131
- return this.getCurrentHeadMenu(path, menu.children);
132
- });
133
- },
134
- },
135
- };
136
- </script>
137
-
138
- <style lang="scss">
139
-
140
- .head-menu.el-menu {
141
- background-color: transparent;
142
- border-bottom: none;
143
-
144
- > .el-menu-item,
145
- > .el-submenu .el-submenu__title {
146
- font-size: 16px;
147
- font-weight: 400;
148
- color: inherit;
149
- height: var(--header-height);
150
- line-height: var(--header-height);
151
- padding: 0 25px;
152
- border: none;
153
- box-sizing: border-box;
154
- transition: all 0.2s ease-in-out;
155
-
156
- span {
157
- vertical-align: unset;
158
- }
159
-
160
- i {
161
- width: 20px;
162
- font-size: 14px;
163
- }
164
- }
165
-
166
- > .el-menu-item:not(.is-disabled):not(.is-active):hover,
167
- > .el-menu-item:not(.is-disabled):not(.is-active):focus,
168
- > .el-submenu:not(.is-disabled):not(.is-active):hover .el-submenu__title,
169
- > .el-submenu:not(.is-disabled):not(.is-active):focus .el-submenu__title {
170
- color: inherit;
171
- background-color: rgba(0, 146, 63, 0.3);
172
- }
173
-
174
- > .el-menu-item.is-active,
175
- > .el-submenu.is-active .el-submenu__title {
176
- color: inherit;
177
- background-color: rgba(0, 146, 63, 0.6);
178
- }
179
-
180
- .el-submenu__title i {
181
- color: inherit;
182
- }
183
-
184
- .el-menu--popup {
185
-
186
- }
187
- }
188
- </style>
@@ -1,80 +0,0 @@
1
- <script type="text/jsx">
2
- export default {
3
- name: 'head-menu-submenu',
4
- inject: ['headMenu'],
5
- props: {
6
- item: Object,
7
- },
8
- computed: {
9
- isLeaf() {
10
- const {children} = this.item;
11
- return !Array.isArray(children) || children.length <= 0;
12
- },
13
- index() {
14
- const {url, id} = this.item;
15
- if (this.isRouter) {
16
- return url || id + '';
17
- }
18
- return id + '';
19
- },
20
- route() {
21
- const {url} = this.item;
22
- return url;
23
- },
24
- isRouter() {
25
- return this.headMenu.router;
26
- },
27
- theme() {
28
- return this.headMenu.theme;
29
- },
30
- popperClass() {
31
- return ['nav-menu-submenu-popup', this.theme].join(' ');
32
- },
33
- },
34
- render(createElement) {
35
- if (this.isLeaf) {
36
- return createElement('el-menu-item', {props: {index: this.index, route: this.route}}, [
37
- createElement('template', {slot: 'title'}, [this.item.name]),
38
- ]);
39
- }
40
- return createElement('el-submenu', {props: {index: this.index, popperClass: this.popperClass, popperAppendToBody: false}}, [
41
- createElement('template', {slot: 'title'}, [this.item.name]),
42
- ...this.item.children.map(child => createElement('head-menu-submenu', {key: child.id, props: {item: child}})),
43
- ]);
44
- },
45
- };
46
- </script>
47
- <style lang="less">
48
- .el-menu--collapse .el-menu-item [class^=el-icon-],
49
- .el-menu--collapse .el-submenu .el-submenu__title [class^=el-icon-] {
50
- margin: 0;
51
- vertical-align: middle;
52
- width: 24px;
53
- text-align: center
54
- }
55
-
56
- .el-menu--collapse .el-menu-item .el-submenu__icon-arrow,
57
- .el-menu--collapse .el-submenu .el-submenu__title .el-submenu__icon-arrow {
58
- display: none
59
- }
60
-
61
- .el-menu--collapse .el-menu-item span,
62
- .el-menu--collapse .el-submenu .el-submenu__title span {
63
- height: 0;
64
- width: 0;
65
- overflow: hidden;
66
- visibility: hidden;
67
- display: inline-block
68
- }
69
-
70
- .nav-menu-submenu-popup {
71
-
72
- .el-menu-item,
73
- .el-submenu__title {
74
- height: 40px;
75
- line-height: 40px;
76
- font-size: 12px;
77
- }
78
- }
79
-
80
- </style>