cloud-web-corejs 1.0.0 → 1.0.2

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,112 @@
1
+ <template>
2
+ <el-scrollbar ref="scrollContainer" :vertical="false" class="scroll-container" @wheel.native.prevent="handleScroll">
3
+ <slot />
4
+ </el-scrollbar>
5
+ </template>
6
+
7
+ <script>
8
+ const tagAndTagSpacing = 4 // tagAndTagSpacing
9
+
10
+ export default {
11
+ name: 'ScrollPane',
12
+ data() {
13
+ return {
14
+ left: 0
15
+ }
16
+ },
17
+ computed: {
18
+ scrollWrapper() {
19
+ return this.$refs.scrollContainer.$refs.wrap
20
+ }
21
+ },
22
+ mounted() {
23
+ this.scrollWrapper.addEventListener('scroll', this.emitScroll, true)
24
+ },
25
+ beforeDestroy() {
26
+ this.scrollWrapper.removeEventListener('scroll', this.emitScroll)
27
+ },
28
+ methods: {
29
+ handleScrollLeft(e) {
30
+ const eventDelta = -200
31
+ const $scrollWrapper = this.scrollWrapper
32
+ let data = $scrollWrapper.scrollLeft + eventDelta / 4;
33
+ data = data < 0 ? 0 : data;
34
+ $scrollWrapper.scrollLeft = data
35
+ },
36
+ handleScrollRight(e) {
37
+ const eventDelta = 200
38
+ const $scrollWrapper = this.scrollWrapper
39
+ const $container = this.$refs.scrollContainer.$el
40
+ const $containerWidth = $container.offsetWidth
41
+ let maxData = $scrollWrapper.scrollWidth - $containerWidth
42
+ let data = $scrollWrapper.scrollLeft + eventDelta / 4;
43
+ data = data > maxData ? maxData : data;
44
+ $scrollWrapper.scrollLeft = data
45
+ },
46
+ handleScroll(e) {
47
+ const eventDelta = e.wheelDelta || -e.deltaY * 40
48
+ const $scrollWrapper = this.scrollWrapper
49
+ $scrollWrapper.scrollLeft = $scrollWrapper.scrollLeft + eventDelta / 4
50
+ },
51
+ emitScroll() {
52
+ this.$emit('scroll')
53
+ },
54
+ moveToTarget(currentTag) {
55
+ const $container = this.$refs.scrollContainer.$el
56
+ const $containerWidth = $container.offsetWidth
57
+ const $scrollWrapper = this.scrollWrapper
58
+ const tagList = this.$parent.$refs.tag
59
+
60
+ let firstTag = null
61
+ let lastTag = null
62
+
63
+ // find first tag and last tag
64
+ if (tagList.length > 0) {
65
+ firstTag = tagList[0]
66
+ lastTag = tagList[tagList.length - 1]
67
+ }
68
+
69
+ if (firstTag === currentTag) {
70
+ $scrollWrapper.scrollLeft = 0
71
+ } else if (lastTag === currentTag) {
72
+ $scrollWrapper.scrollLeft = $scrollWrapper.scrollWidth - $containerWidth
73
+ } else {
74
+ // find preTag and nextTag
75
+ const currentIndex = tagList.findIndex(item => item === currentTag)
76
+ const prevTag = tagList[currentIndex - 1]
77
+ const nextTag = tagList[currentIndex + 1]
78
+
79
+ // the tag's offsetLeft after of nextTag
80
+ const afterNextTagOffsetLeft = nextTag.$el.offsetLeft + nextTag.$el.offsetWidth + tagAndTagSpacing
81
+
82
+ // the tag's offsetLeft before of prevTag
83
+ const beforePrevTagOffsetLeft = prevTag.$el.offsetLeft - tagAndTagSpacing
84
+
85
+ if (afterNextTagOffsetLeft > $scrollWrapper.scrollLeft + $containerWidth) {
86
+ $scrollWrapper.scrollLeft = afterNextTagOffsetLeft - $containerWidth
87
+ } else if (beforePrevTagOffsetLeft < $scrollWrapper.scrollLeft) {
88
+ $scrollWrapper.scrollLeft = beforePrevTagOffsetLeft
89
+ }
90
+ }
91
+ }
92
+ }
93
+ }
94
+ </script>
95
+
96
+ <style lang="scss" scoped>
97
+ .scroll-container {
98
+ white-space: nowrap;
99
+ position: relative;
100
+ overflow: hidden;
101
+ width: 100%;
102
+ height: 45px;
103
+ ::v-deep {
104
+ .el-scrollbar__bar {
105
+ bottom: 0px;
106
+ }
107
+ .el-scrollbar__wrap {
108
+ height: 66px;
109
+ }
110
+ }
111
+ }
112
+ </style>
@@ -0,0 +1,281 @@
1
+ <template>
2
+ <div id="tags-view-container" class="navbar-tag">
3
+ <scroll-pane ref="scrollPane" class="tags-view-wrapper" @scroll="handleScroll">
4
+ <router-link
5
+ v-for="tag in visitedViews"
6
+ ref="tag"
7
+ :key="tag.path"
8
+ :class="isActive(tag)?'active':''"
9
+ :to="{ path: tag.path, query: tag.query, fullPath: tag.fullPath }"
10
+ tag="span"
11
+ class="tags-view-item"
12
+ @click.middle.native="!isAffix(tag)?closeSelectedTag(tag):''"
13
+ @contextmenu.prevent.native="openMenu(tag,$event)"
14
+ >
15
+ <i class="el-icon-s-home" v-if="tag.name =='home'"></i>
16
+ {{ getMenuName(tag) }}
17
+
18
+ <span v-if="!isAffix(tag)" class="el-icon-close" @click.prevent.stop="closeSelectedTag(tag)"/>
19
+ </router-link>
20
+ </scroll-pane>
21
+ <div class="tags-operBox">
22
+ <el-tooltip :enterable="false" class="item" effect="dark" content="左移" placement="bottom">
23
+ <i class="el-icon-arrow-left" layadmin-event="leftPage"
24
+ one-link-mark="yes" @click="$refs.scrollPane.handleScrollLeft()"/>
25
+ </el-tooltip>
26
+ <el-tooltip :enterable="false" class="item" effect="dark" content="右移" placement="bottom" l>
27
+ <i class="el-icon-arrow-right" ayadmin-event="rightPage"
28
+ one-link-mark="yes" @click="$refs.scrollPane.handleScrollRight()"/>
29
+ </el-tooltip>
30
+ <el-tooltip :enterable="false" class="item" effect="dark" content="刷新" placement="bottom">
31
+ <i class="el-icon-refresh" @click="refreshSelectedTag($route)"/>
32
+ </el-tooltip>
33
+ <el-tooltip :enterable="false" class="item" effect="dark" content="全部关闭" placement="bottom">
34
+ <i class="el-icon-close" @click="closeAllTags(selectedTag)"/>
35
+ </el-tooltip>
36
+ </div>
37
+ <!-- <ul v-show="visible" :style="{left:left+'px',top:top+'px'}" class="contextmenu">
38
+ <li @click="refreshSelectedTag(selectedTag)">Refresh</li>
39
+ <li v-if="!isAffix(selectedTag)" @click="closeSelectedTag(selectedTag)">Close</li>
40
+ <li @click="closeOthersTags">Close Others</li>
41
+ <li @click="closeAllTags(selectedTag)">Close All</li>
42
+ </ul> -->
43
+ </div>
44
+ </template>
45
+
46
+ <script>
47
+ import ScrollPane from './ScrollPane'
48
+ import path from 'path'
49
+
50
+ export default {
51
+ components: {ScrollPane},
52
+ data() {
53
+ return {
54
+ visible: false,
55
+ top: 0,
56
+ left: 0,
57
+ selectedTag: {},
58
+ affixTags: []
59
+ }
60
+ },
61
+ computed: {
62
+ visitedViews() {
63
+ return this.$store.state.tagsView.visitedViews
64
+ },
65
+ routes() {
66
+ return this.$store.state.permission.routes
67
+ }
68
+ },
69
+ watch: {
70
+ $route() {
71
+ this.addTags()
72
+ this.moveToCurrentTag()
73
+ },
74
+ visible(value) {
75
+ if (value) {
76
+ document.body.addEventListener('click', this.closeMenu)
77
+ } else {
78
+ document.body.removeEventListener('click', this.closeMenu)
79
+ }
80
+ }
81
+ },
82
+ mounted() {
83
+ this.initTags()
84
+ this.addTags()
85
+ },
86
+ methods: {
87
+ getMenuName(item) {
88
+ let locale = this.$i18n?.locale;
89
+ let zhTitle = (item.meta ? item.meta.title : '');
90
+ let enTitle = (item.meta ? item.meta.enTitle : '');
91
+ let title;
92
+ if (locale == "en") {
93
+ title = enTitle || zhTitle;
94
+ } else {
95
+ title = zhTitle
96
+ }
97
+ if (!enTitle || locale !== "en") {
98
+ title = zhTitle
99
+ }
100
+ if (this.$t) {
101
+ title = this.$t(title)
102
+ }
103
+ return title;
104
+ },
105
+ isActive(route) {
106
+ return route.path === this.$route.path
107
+ },
108
+ isAffix(tag) {
109
+ return tag.meta && tag.meta.affix
110
+ },
111
+ filterAffixTags(routes, basePath = '/') {
112
+ let tags = []
113
+ routes.forEach(route => {
114
+ if (route.meta && route.meta.affix) {
115
+ const tagPath = path.resolve(basePath, route.path)
116
+ tags.push({
117
+ fullPath: tagPath,
118
+ path: tagPath,
119
+ name: route.name,
120
+ meta: {...route.meta}
121
+ })
122
+ }
123
+ if (route.children) {
124
+ const tempTags = this.filterAffixTags(route.children, route.path)
125
+ if (tempTags.length >= 1) {
126
+ tags = [...tags, ...tempTags]
127
+ }
128
+ }
129
+ })
130
+ return tags
131
+ },
132
+ initTags() {
133
+ const affixTags = this.affixTags = this.filterAffixTags(this.routes)
134
+ for (const tag of affixTags) {
135
+ // Must have tag name
136
+ if (tag.name) {
137
+ this.$store.dispatch('tagsView/addVisitedView', tag)
138
+ }
139
+ }
140
+ },
141
+ addTags() {
142
+ const {name} = this.$route
143
+ if (name) {
144
+ this.$store.dispatch('tagsView/addView', this.$route)
145
+ }
146
+ return false
147
+ },
148
+ moveToCurrentTag() {
149
+ const tags = this.$refs.tag
150
+ this.$nextTick(() => {
151
+ for (const tag of tags) {
152
+ if (tag.to.path === this.$route.path) {
153
+ this.$refs.scrollPane.moveToTarget(tag)
154
+ // when query is different then update
155
+ if (tag.to.fullPath !== this.$route.fullPath) {
156
+ this.$store.dispatch('tagsView/updateVisitedView', this.$route)
157
+ }
158
+ break
159
+ }
160
+ }
161
+ })
162
+ },
163
+ refreshSelectedTag(view) {
164
+ this.$baseEventBus.$emit("reflushRouteView", view);
165
+ /* if(this.$route.name=="outLink"){
166
+ let a = this.$baseEventBus.$emit("getAppMain");
167
+ debugger
168
+ let t = this.$parent.$refs["appMain"].$refs["ref_"+this.$route.path][0];
169
+ t.$baseReload();
170
+ }else{
171
+ this.$store.dispatch('tagsView/delCachedView', view).then(() => {
172
+ const { fullPath } = view
173
+ this.$nextTick(() => {
174
+ this.$router.replace({
175
+ path: '/redirect' + fullPath
176
+ })
177
+ })
178
+ })
179
+ } */
180
+ },
181
+ closeSelectedTag(view) {
182
+ this.$store.dispatch('tagsView/delView', view).then(({visitedViews}) => {
183
+ if (this.isActive(view)) {
184
+ this.toLastView(visitedViews, view)
185
+ }
186
+ })
187
+ },
188
+ closeOthersTags() {
189
+ this.$router.push(this.selectedTag)
190
+ this.$store.dispatch('tagsView/delOthersViews', this.selectedTag).then(() => {
191
+ this.moveToCurrentTag()
192
+ })
193
+ },
194
+ closeAllTags(view) {
195
+ this.$store.dispatch('tagsView/delAllViews').then(({visitedViews}) => {
196
+ if (this.affixTags.some(tag => tag.path === view.path)) {
197
+ return
198
+ }
199
+ this.toLastView(visitedViews, view)
200
+ })
201
+ },
202
+ toLastView(visitedViews, view) {
203
+ const latestView = visitedViews.slice(-1)[0]
204
+ if (latestView) {
205
+ this.$router.push(latestView.fullPath)
206
+ } else {
207
+ // now the default is to redirect to the home page if there is no tags-view,
208
+ // you can adjust it according to your needs.
209
+ if (view.name === 'Dashboard') {
210
+ // to reload home page
211
+ this.$router.replace({path: '/redirect' + view.fullPath})
212
+ } else {
213
+ this.$router.push('/')
214
+ }
215
+ }
216
+ },
217
+ openMenu(tag, e) {
218
+ const menuMinWidth = 105
219
+ const offsetLeft = this.$el.getBoundingClientRect().left // container margin left
220
+ const offsetWidth = this.$el.offsetWidth // container width
221
+ const maxLeft = offsetWidth - menuMinWidth // left boundary
222
+ const left = e.clientX - offsetLeft + 15 // 15: margin right
223
+
224
+ if (left > maxLeft) {
225
+ this.left = maxLeft
226
+ } else {
227
+ this.left = left
228
+ }
229
+
230
+ this.top = e.clientY
231
+ this.visible = true
232
+ this.selectedTag = tag
233
+ },
234
+ closeMenu() {
235
+ this.visible = false
236
+ },
237
+ handleScroll() {
238
+ this.closeMenu()
239
+ }
240
+ }
241
+ }
242
+ </script>
243
+
244
+ <style scoped lang="scss">
245
+ @import '~@/styles/variables.scss';
246
+
247
+ .navbar-tag .tags-view-item.active {
248
+ background: $baseColor !important;
249
+ }
250
+ </style>
251
+ <style lang="scss">
252
+ //reset element css of el-icon-close
253
+ .tags-view-wrapper {
254
+ .tags-view-item {
255
+ .el-icon-close {
256
+ width: 14px;
257
+ height: 14px;
258
+ vertical-align: text-bottom;
259
+ line-height: 12px;
260
+ border-radius: 50%;
261
+ text-align: center;
262
+ transition: all .3s cubic-bezier(.645, .045, .355, 1);
263
+ transform-origin: 100% 50%;
264
+ display: none;
265
+ position: absolute;
266
+ right: 12px;
267
+ top: 8px;
268
+
269
+ &:before {
270
+ transform: scale(.84);
271
+ display: inline-block;
272
+ vertical-align: -1.8px;
273
+ }
274
+ }
275
+
276
+ &:hover .el-icon-close {
277
+ display: block;
278
+ }
279
+ }
280
+ }
281
+ </style>
@@ -0,0 +1,5 @@
1
+ export { default as AppMain } from './AppMain'
2
+ // export { default as Navbar } from './Navbar'
3
+ // export { default as Settings } from './Settings'
4
+ export { default as Sidebar } from './Sidebar/index.vue'
5
+ export { default as TagsView } from './TagsView/index.vue'
@@ -0,0 +1,121 @@
1
+ <template>
2
+ <div class="item" v-if="i18nEnabled && languageSettings.length>1">
3
+ <el-dropdown class='lang-box' trigger="click">
4
+ <span class="el-dropdown-link">
5
+ <i class="iconfont icon-duoyuyan"></i><i
6
+ class="el-icon-arrow-down el-icon--right"></i>
7
+ </span>
8
+ <el-dropdown-menu slot="dropdown" class="lang-box-pup">
9
+ <el-dropdown-item v-for="(item,index) in languageSettings" :key="index" :command="item.languageCode"
10
+ @click.native="changeLanguage(item.languageCode)"
11
+ :class="{'cur':currentName == item.languageName}">{{ item.languageName }}
12
+ </el-dropdown-item>
13
+ </el-dropdown-menu>
14
+ </el-dropdown>
15
+ </div>
16
+ </template>
17
+
18
+ <script>
19
+ import indexUtil from "@base/utils/index.js"
20
+ import settingConfig from "@/settings";
21
+
22
+ export default {
23
+ name: "langTool",
24
+ data() {
25
+ return {
26
+ languageSettings: [],
27
+ languageSettingMap: {},
28
+ i18nEnabled: settingConfig.i18nEnabled
29
+ }
30
+ },
31
+ computed: {
32
+ currentName() {
33
+ return this.languageSettingMap[this.$i18n.locale]
34
+ }
35
+ },
36
+ mounted() {
37
+ this.initLanguageSetting();
38
+ },
39
+ methods: {
40
+ changeLanguage(command) {
41
+ if (this.$i18n.locale != command) {
42
+ this.$http({
43
+ url: USER_PREFIX + `/auth/switchLanguage`,
44
+ method: `post`,
45
+ data: {
46
+ "stringOne": command
47
+ },
48
+ isLoading: true,
49
+ modalStrictly: true,
50
+ loadingTarget: document.body,
51
+ success: res => {
52
+ this.$i18n.locale = command // 设置给本地的i18n插件
53
+ localStorage.setItem("i18n-lang", command);
54
+ this.$message.success('切换多语言成功')
55
+ location.reload()
56
+ }
57
+ })
58
+ }
59
+ },
60
+ initLanguageSetting() {
61
+ if (settingConfig.i18nEnabled !== true) return;
62
+ let languageSettings = []
63
+ languageSettings.push(...(this.$store.state.user.languageSettings));
64
+ let map = {};
65
+ languageSettings.forEach(item => {
66
+ map[item.languageCode] = item.languageName;
67
+ });
68
+ this.languageSettingMap = map;
69
+ this.languageSettings = languageSettings;
70
+ },
71
+ }
72
+ }
73
+ </script>
74
+ <style scoped lang="scss">
75
+ /*多语言*/
76
+ .lang-box {
77
+ border-right: solid 1px #ffffff24;
78
+ padding-right: 7px;
79
+ height: 18px;
80
+ line-height: 18px;
81
+ vertical-align: middle;
82
+ color: #FFF;
83
+ font-size: 12px;
84
+
85
+ .el-icon--right {
86
+ margin-left: 3px;
87
+ }
88
+
89
+ .el-dropdown-link {
90
+ color: #FFF;
91
+
92
+ .name {
93
+ display: inline-block;
94
+ width: 28px;
95
+ height: 19px;
96
+ overflow: hidden;
97
+ vertical-align: middle;
98
+ font-size: 12px;
99
+ line-height: 19px
100
+ }
101
+
102
+ i {
103
+ zoom: 0.7;
104
+ margin-left: 3px;
105
+ opacity: 0.8;
106
+
107
+ &.iconfont {
108
+ font-size: 24px;
109
+ vertical-align: middle;
110
+ margin-right: 2px;
111
+ }
112
+ }
113
+ }
114
+
115
+ }
116
+
117
+ .lang-box-pup .el-dropdown-menu__item.cur {
118
+ background-color: #eaf0f4;
119
+ color: #5583a9;
120
+ }
121
+ </style>
@@ -0,0 +1,135 @@
1
+ <template>
2
+ <div>
3
+ <el-dialog
4
+ title="消息列表"
5
+ :append-to-body="true"
6
+ :modal-append-to-body="true"
7
+ :close-on-click-modal="falseValue"
8
+ :visible.sync="showDialog"
9
+ :modal="falseValue"
10
+ width="1001px"
11
+ custom-class="dialog-style news-box"
12
+ :destroy-on-close="true"
13
+ @close="dialogClose"
14
+ v-el-drag-dialog
15
+ v-el-dialog-center
16
+ top="2vh"
17
+ >
18
+ <div class="n-list">
19
+ <div class="item" v-for="(item, index) in tableDatas" :key="index" :class="{ on: currentIndex == index }"
20
+ @click="checkLine(index)">
21
+ <div class="name">
22
+ {{ item.notifyTypeName }}
23
+ </div>
24
+ <p>{{ item.createDate ? item.createDate.substring(0, 10) : '' }}</p>
25
+ </div>
26
+ </div>
27
+ <div class="n-cont">
28
+ <h2 class="t1">{{ currentRow.notifyTypeName }}</h2>
29
+ <!-- <h3 class="t2">紧急通知</h3>-->
30
+ <p class="time">{{ currentRow.createDate }}</p>
31
+ <div class="c"><p v-html="currentRow.content"></p></div>
32
+ </div>
33
+ </el-dialog>
34
+ <systemNoticeInfoDialog v-if="showSystemNoticeInfoDialog" :visiable.sync="showSystemNoticeInfoDialog"
35
+ :appendToTop="true"></systemNoticeInfoDialog>
36
+ </div>
37
+ </template>
38
+
39
+ <script>
40
+ import systemNoticeInfoDialog from "@base/views/user/system_notice/infoDialog.vue";
41
+
42
+ export default {
43
+ name: 'notifyMessageDialog',
44
+ components: {systemNoticeInfoDialog},
45
+ props: {},
46
+ created() {
47
+ },
48
+ mounted() {
49
+ this.init();
50
+ },
51
+ data() {
52
+ return {
53
+ showDialog: false,
54
+ falseValue: false,
55
+ tableDatas: [],
56
+ currentIndex: 0,
57
+ currentRow: {},
58
+ showSystemNoticeInfoDialog: false
59
+ };
60
+ },
61
+
62
+ methods: {
63
+ init() {
64
+ this.$http({
65
+ url: USER_PREFIX + '/notify_message/lastUnreadList',
66
+ method: 'post',
67
+ data: {},
68
+ success: res => {
69
+ let rows = res.objx || [];
70
+ if (rows.length > 0) {
71
+ this.tableDatas = rows;
72
+ this.checkLine(0, () => {
73
+ this.showDialog = true;
74
+ });
75
+ }/* else {
76
+ this.initSystemNoticeInfoDialog();
77
+ } */
78
+ }
79
+ });
80
+ },
81
+ handleRead(index, callback) {
82
+ let row = this.tableDatas[index];
83
+ if (row.readed == 0) {
84
+ this.$http({
85
+ url: USER_PREFIX + `/notify_message/read`,
86
+ method: `post`,
87
+ data: [row.id],
88
+ isLoading: true,
89
+ success: res => {
90
+ row.readed = 1;
91
+ callback && callback()
92
+ }
93
+ });
94
+ } else {
95
+ callback && callback()
96
+ }
97
+ },
98
+
99
+ dialogClose() {
100
+ this.$emit('update:visiable', false);
101
+ },
102
+ dialogPrimary() {
103
+ // var rows = this.$refs['table-m2'].getTableData().fullData
104
+ // this.$emit("confirm", rows)
105
+ this.$emit('update:visiable', false);
106
+ },
107
+ checkLine(index, callback) {
108
+ this.currentIndex = index;
109
+ let item = this.tableDatas[index];
110
+ this.handleRead(index, () => {
111
+ this.currentIndex = index;
112
+ this.currentRow = item;
113
+ callback && callback();
114
+ })
115
+
116
+ },
117
+ initSystemNoticeInfoDialog() {
118
+ this.$http({
119
+ url: USER_PREFIX + '/system_notice/listPage',
120
+ data: {publish: true, important: true, size: 1},
121
+ method: 'post',
122
+ success: res => {
123
+ this.systemNotices = res.objx && res.objx.records ? res.objx.records : [];
124
+ let rows = res?.objx?.records || []
125
+ if (rows.length > 0) {
126
+ this.showSystemNoticeInfoDialog = true;
127
+ }
128
+ }
129
+ });
130
+ }
131
+ }
132
+ };
133
+ </script>
134
+
135
+ <style></style>