{
29 |
30 | /**
31 | * Returns whether this node is a leader node
32 | *
33 | * @param group business module info
34 | * @return is leader
35 | */
36 | boolean isLeader(String group);
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/mmq-core/src/main/java/org/monkey/mmq/core/consistency/cp/MetadataKey.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021-2021 Monkey Group.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.monkey.mmq.core.consistency.cp;
18 |
19 | /**
20 | * Key value of metadata information of CP protocol.
21 | *
22 | * @author solley
23 | */
24 | public class MetadataKey {
25 |
26 | public static final String LEADER_META_DATA = "leader";
27 |
28 | public static final String TERM_META_DATA = "term";
29 |
30 | public static final String RAFT_GROUP_MEMBER = "raftGroupMember";
31 |
32 | public static final String ERR_MSG = "errMsg";
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/mmq-core/src/main/java/org/monkey/mmq/core/consistency/matedata/Record.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021-2021 Monkey Group.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.monkey.mmq.core.consistency.matedata;
18 |
19 | import java.io.Serializable;
20 |
21 | /**
22 | * Record to transfer and store in MMQ cluster.
23 | *
24 | * @author solley
25 | * @since 1.0.0
26 | */
27 | public interface Record extends Serializable {
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/mmq-core/src/main/java/org/monkey/mmq/core/consistency/model/IResultCode.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021-2021 Monkey Group.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.monkey.mmq.core.consistency.model;
18 |
19 | /**
20 | * IResultCode.
21 | *
22 | * @author klw
23 | * @ClassName: IResultCode
24 | * @Description: result code enum needs to be implemented this interface
25 | * @date 2019/6/28 14:44
26 | */
27 | @Deprecated
28 | public interface IResultCode {
29 |
30 | /**
31 | * Get the result code.
32 | *
33 | * @return code value.
34 | */
35 | int getCode();
36 |
37 | /**
38 | * Get the result code's message.
39 | *
40 | * @return code's message.
41 | */
42 | String getCodeMsg();
43 | }
44 |
--------------------------------------------------------------------------------
/mmq-core/src/main/java/org/monkey/mmq/core/consistency/persistent/PersistentConsistencyService.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021-2021 Monkey Group.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.monkey.mmq.core.consistency.persistent;
17 |
18 | /**
19 | * A consistency service that guarantee CP consistency for the published data.
20 | *
21 | * CP consistency is hereby defined as follows:
22 | *
23 | *
Once the writing operation returned client a success, the data within the operation is guaranteed to be
24 | * successfully written to the cluster. And the data should be consistent between servers after some time without any
25 | * outside interfere.
26 | *
27 | * @author solley
28 | */
29 | public interface PersistentConsistencyService extends ConsistencyService {
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/mmq-core/src/main/java/org/monkey/mmq/core/distributed/id/IdGenerator.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021-2021 Monkey Group.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.monkey.mmq.core.distributed.id;
18 |
19 | import java.util.Map;
20 |
21 | /**
22 | * Id generator.
23 | *
24 | * @author solley
25 | */
26 | public interface IdGenerator {
27 |
28 | /**
29 | * Perform the corresponding initialization operation.
30 | */
31 | void init();
32 |
33 | /**
34 | * current id info.
35 | *
36 | * @return current id
37 | */
38 | long currentId();
39 |
40 | /**
41 | * Get next id.
42 | *
43 | * @return next id
44 | */
45 | long nextId();
46 |
47 | /**
48 | * Returns information for the current IDGenerator.
49 | *
50 | * @return {@link Map}
51 | */
52 | Map
15 |
16 |
17 |
65 |
--------------------------------------------------------------------------------
/mmq-ui/src/components/Charts/chart.less:
--------------------------------------------------------------------------------
1 | .antv-chart-mini {
2 | position: relative;
3 | width: 100%;
4 |
5 | .chart-wrapper {
6 | position: absolute;
7 | bottom: -28px;
8 | width: 100%;
9 |
10 | /* margin: 0 -5px;
11 | overflow: hidden;*/
12 | }
13 | }
--------------------------------------------------------------------------------
/mmq-ui/src/components/Charts/smooth.area.less:
--------------------------------------------------------------------------------
1 | @import "../index";
2 |
3 | @smoothArea-prefix-cls: ~"@{ant-pro-prefix}-smooth-area";
4 |
5 | .@{smoothArea-prefix-cls} {
6 | position: relative;
7 | width: 100%;
8 |
9 | .chart-wrapper {
10 | position: absolute;
11 | bottom: -28px;
12 | width: 100%;
13 | }
14 | }
--------------------------------------------------------------------------------
/mmq-ui/src/components/Editor/WangEditor.vue:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
50 |
51 |
58 |
--------------------------------------------------------------------------------
/mmq-ui/src/components/Ellipsis/index.js:
--------------------------------------------------------------------------------
1 | import Ellipsis from './Ellipsis'
2 |
3 | export default Ellipsis
4 |
--------------------------------------------------------------------------------
/mmq-ui/src/components/Ellipsis/index.md:
--------------------------------------------------------------------------------
1 | # Ellipsis 文本自动省略号
2 |
3 | 文本过长自动处理省略号,支持按照文本长度和最大行数两种方式截取。
4 |
5 |
6 |
7 | 引用方式:
8 |
9 | ```javascript
10 | import Ellipsis from '@/components/Ellipsis'
11 |
12 | export default {
13 | components: {
14 | Ellipsis
15 | }
16 | }
17 | ```
18 |
19 |
20 |
21 | ## 代码演示 [demo](https://pro.loacg.com/test/home)
22 |
23 | ```html
24 |
25 | There were injuries alleged in three cases in 2015, and a
26 | fourth incident in September, according to the safety recall report. After meeting with US regulators in October, the firm decided to issue a voluntary recall.
27 |
28 | ```
29 |
30 |
31 |
32 | ## API
33 |
34 |
35 | 参数 | 说明 | 类型 | 默认值
36 | ----|------|-----|------
37 | tooltip | 移动到文本展示完整内容的提示 | boolean | -
38 | length | 在按照长度截取下的文本最大字符数,超过则截取省略 | number | -
--------------------------------------------------------------------------------
/mmq-ui/src/components/FooterToolbar/FooterToolBar.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{ extra }}
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
44 |
45 |
48 |
--------------------------------------------------------------------------------
/mmq-ui/src/components/FooterToolbar/index.js:
--------------------------------------------------------------------------------
1 | import FooterToolBar from './FooterToolBar'
2 | import './index.less'
3 |
4 | export default FooterToolBar
5 |
--------------------------------------------------------------------------------
/mmq-ui/src/components/FooterToolbar/index.less:
--------------------------------------------------------------------------------
1 | @import "../index";
2 |
3 | @footer-toolbar-prefix-cls: ~"@{ant-pro-prefix}-footer-toolbar";
4 |
5 | .@{footer-toolbar-prefix-cls} {
6 | position: fixed;
7 | width: 100%;
8 | bottom: 0;
9 | right: 0;
10 | height: 56px;
11 | line-height: 56px;
12 | box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.03);
13 | background: #fff;
14 | border-top: 1px solid #e8e8e8;
15 | padding: 0 24px;
16 | z-index: 9;
17 |
18 | &:after {
19 | content: "";
20 | display: block;
21 | clear: both;
22 | }
23 | }
--------------------------------------------------------------------------------
/mmq-ui/src/components/FooterToolbar/index.md:
--------------------------------------------------------------------------------
1 | # FooterToolbar 底部工具栏
2 |
3 | 固定在底部的工具栏。
4 |
5 |
6 |
7 | ## 何时使用
8 |
9 | 固定在内容区域的底部,不随滚动条移动,常用于长页面的数据搜集和提交工作。
10 |
11 |
12 |
13 | 引用方式:
14 |
15 | ```javascript
16 | import FooterToolBar from '@/components/FooterToolbar'
17 |
18 | export default {
19 | components: {
20 | FooterToolBar
21 | }
22 | }
23 | ```
24 |
25 |
26 |
27 | ## 代码演示
28 |
29 | ```html
30 |
31 | 提交
32 |
33 | ```
34 | 或
35 | ```html
36 |
37 | 提交
38 |
39 | ```
40 |
41 |
42 | ## API
43 |
44 | 参数 | 说明 | 类型 | 默认值
45 | ----|------|-----|------
46 | children (slot) | 工具栏内容,向右对齐 | - | -
47 | extra | 额外信息,向左对齐 | String, Object | -
48 |
49 |
--------------------------------------------------------------------------------
/mmq-ui/src/components/GlobalFooter/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
14 |
24 |
--------------------------------------------------------------------------------
/mmq-ui/src/components/GlobalHeader/RightContent.vue:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
59 |
--------------------------------------------------------------------------------
/mmq-ui/src/components/IconSelector/README.md:
--------------------------------------------------------------------------------
1 | IconSelector
2 | ====
3 |
4 | > 图标选择组件,常用于为某一个数据设定一个图标时使用
5 | > eg: 设定菜单列表时,为每个菜单设定一个图标
6 |
7 | 该组件由 [@Saraka](https://github.com/saraka-tsukai) 封装
8 |
9 |
10 |
11 | ### 使用方式
12 |
13 | ```vue
14 |
15 |
16 |
17 |
18 |
19 |
20 |
39 | ```
40 |
41 |
42 |
43 | ### 事件
44 |
45 |
46 | | 名称 | 说明 | 类型 | 默认值 |
47 | | ------ | -------------------------- | ------ | ------ |
48 | | change | 当改变了 `icon` 选中项触发 | String | - |
49 |
--------------------------------------------------------------------------------
/mmq-ui/src/components/IconSelector/index.js:
--------------------------------------------------------------------------------
1 | import IconSelector from './IconSelector'
2 | export default IconSelector
3 |
--------------------------------------------------------------------------------
/mmq-ui/src/components/MultiTab/events.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | export default new Vue()
3 |
--------------------------------------------------------------------------------
/mmq-ui/src/components/MultiTab/index.js:
--------------------------------------------------------------------------------
1 | import events from './events'
2 | import MultiTab from './MultiTab'
3 | import './index.less'
4 |
5 | const api = {
6 | /**
7 | * open new tab on route fullPath
8 | * @param config
9 | */
10 | open: function (config) {
11 | events.$emit('open', config)
12 | },
13 | rename: function (key, name) {
14 | events.$emit('rename', { key: key, name: name })
15 | },
16 | /**
17 | * close current page
18 | */
19 | closeCurrentPage: function () {
20 | this.close()
21 | },
22 | /**
23 | * close route fullPath tab
24 | * @param config
25 | */
26 | close: function (config) {
27 | events.$emit('close', config)
28 | }
29 | }
30 |
31 | MultiTab.install = function (Vue) {
32 | if (Vue.prototype.$multiTab) {
33 | return
34 | }
35 | api.instance = events
36 | Vue.prototype.$multiTab = api
37 | Vue.component('multi-tab', MultiTab)
38 | }
39 |
40 | export default MultiTab
41 |
--------------------------------------------------------------------------------
/mmq-ui/src/components/MultiTab/index.less:
--------------------------------------------------------------------------------
1 | @import '../index';
2 |
3 | @multi-tab-prefix-cls: ~"@{ant-pro-prefix}-multi-tab";
4 | @multi-tab-wrapper-prefix-cls: ~"@{ant-pro-prefix}-multi-tab-wrapper";
5 |
6 | /*
7 | .topmenu .@{multi-tab-prefix-cls} {
8 | max-width: 1200px;
9 | margin: -23px auto 24px auto;
10 | }
11 | */
12 | .@{multi-tab-prefix-cls} {
13 | margin: -23px -24px 24px -24px;
14 | background: #fff;
15 | }
16 |
17 | .topmenu .@{multi-tab-wrapper-prefix-cls} {
18 | max-width: 1200px;
19 | margin: 0 auto;
20 | }
21 |
22 | .topmenu.content-width-Fluid .@{multi-tab-wrapper-prefix-cls} {
23 | max-width: 100%;
24 | margin: 0 auto;
25 | }
26 |
--------------------------------------------------------------------------------
/mmq-ui/src/components/NoticeIcon/index.js:
--------------------------------------------------------------------------------
1 | import NoticeIcon from './NoticeIcon'
2 | export default NoticeIcon
3 |
--------------------------------------------------------------------------------
/mmq-ui/src/components/NumberInfo/NumberInfo.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{ typeof subTitle === 'string' ? subTitle : subTitle() }}
5 |
6 |
7 | {{ total }}
8 |
9 | {{ subTotal }}
10 |
11 |
12 |
13 |
14 |
15 |
16 |
51 |
52 |
55 |
--------------------------------------------------------------------------------
/mmq-ui/src/components/NumberInfo/index.js:
--------------------------------------------------------------------------------
1 | import NumberInfo from './NumberInfo'
2 |
3 | export default NumberInfo
4 |
--------------------------------------------------------------------------------
/mmq-ui/src/components/NumberInfo/index.less:
--------------------------------------------------------------------------------
1 | @import "../index";
2 |
3 | @numberInfo-prefix-cls: ~"@{ant-pro-prefix}-number-info";
4 |
5 | .@{numberInfo-prefix-cls} {
6 |
7 | .ant-pro-number-info-subtitle {
8 | color: @text-color-secondary;
9 | font-size: @font-size-base;
10 | height: 22px;
11 | line-height: 22px;
12 | overflow: hidden;
13 | text-overflow: ellipsis;
14 | word-break: break-all;
15 | white-space: nowrap;
16 | }
17 |
18 | .number-info-value {
19 | margin-top: 4px;
20 | font-size: 0;
21 | overflow: hidden;
22 | text-overflow: ellipsis;
23 | word-break: break-all;
24 | white-space: nowrap;
25 |
26 | & > span {
27 | color: @heading-color;
28 | display: inline-block;
29 | line-height: 32px;
30 | height: 32px;
31 | font-size: 24px;
32 | margin-right: 32px;
33 | }
34 |
35 | .sub-total {
36 | color: @text-color-secondary;
37 | font-size: @font-size-lg;
38 | vertical-align: top;
39 | margin-right: 0;
40 | i {
41 | font-size: 12px;
42 | transform: scale(0.82);
43 | margin-left: 4px;
44 | }
45 | :global {
46 | .anticon-caret-up {
47 | color: @red-6;
48 | }
49 | .anticon-caret-down {
50 | color: @green-6;
51 | }
52 | }
53 | }
54 | }
55 | }
--------------------------------------------------------------------------------
/mmq-ui/src/components/NumberInfo/index.md:
--------------------------------------------------------------------------------
1 | # NumberInfo 数据文本
2 |
3 | 常用在数据卡片中,用于突出展示某个业务数据。
4 |
5 |
6 |
7 | 引用方式:
8 |
9 | ```javascript
10 | import NumberInfo from '@/components/NumberInfo'
11 |
12 | export default {
13 | components: {
14 | NumberInfo
15 | }
16 | }
17 | ```
18 |
19 |
20 |
21 | ## 代码演示 [demo](https://pro.loacg.com/test/home)
22 |
23 | ```html
24 |
29 | ```
30 |
31 |
32 |
33 | ## API
34 |
35 | 参数 | 说明 | 类型 | 默认值
36 | ----|------|-----|------
37 | title | 标题 | ReactNode\|string | -
38 | subTitle | 子标题 | ReactNode\|string | -
39 | total | 总量 | ReactNode\|string | -
40 | subTotal | 子总量 | ReactNode\|string | -
41 | status | 增加状态 | 'up \| down' | -
42 | theme | 状态样式 | string | 'light'
43 | gap | 设置数字和描述之间的间距(像素)| number | 8
44 |
--------------------------------------------------------------------------------
/mmq-ui/src/components/Search/index.less:
--------------------------------------------------------------------------------
1 | @import "~ant-design-vue/es/style/themes/default";
2 |
3 | .global-search-wrapper {
4 | position: fixed;
5 | top: 0;
6 | left: 0;
7 | right: 0;
8 | bottom: 0;
9 | z-index: @zindex-modal-mask;
10 | background: @modal-mask-bg;
11 |
12 | .global-search-box {
13 | position: absolute;
14 | top: 20%;
15 | left: 50%;
16 | width: 450px;
17 | transform: translate(-50%, -50%);
18 |
19 | .global-search-tips {
20 | color: @white;
21 | font-size: @font-size-lg;
22 | text-align: right;
23 | }
24 | }
25 | }
--------------------------------------------------------------------------------
/mmq-ui/src/components/SelectLang/index.less:
--------------------------------------------------------------------------------
1 | @import "~ant-design-vue/es/style/themes/default";
2 |
3 | @header-menu-prefix-cls: ~'@{ant-prefix}-pro-header-menu';
4 | @header-drop-down-prefix-cls: ~'@{ant-prefix}-pro-drop-down';
5 |
6 | .@{header-menu-prefix-cls} {
7 |
8 | .anticon {
9 | margin-right: 8px;
10 | }
11 | .ant-dropdown-menu-item {
12 | min-width: 160px;
13 | }
14 | }
15 |
16 | .@{header-drop-down-prefix-cls} {
17 |
18 | line-height: @layout-header-height;
19 | vertical-align: top;
20 | cursor: pointer;
21 |
22 | > i {
23 | font-size: 16px !important;
24 | transform: none !important;
25 |
26 | svg {
27 | position: relative;
28 | top: -1px;
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/mmq-ui/src/components/SettingDrawer/SettingItem.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
{{ title }}
4 |
5 |
6 |
7 |
8 |
9 |
24 |
25 |
39 |
--------------------------------------------------------------------------------
/mmq-ui/src/components/SettingDrawer/index.js:
--------------------------------------------------------------------------------
1 | import SettingDrawer from './SettingDrawer'
2 | export default SettingDrawer
3 |
--------------------------------------------------------------------------------
/mmq-ui/src/components/SettingDrawer/settingConfig.js:
--------------------------------------------------------------------------------
1 | import message from 'ant-design-vue/es/message'
2 | // import defaultSettings from '../defaultSettings';
3 | import themeColor from './themeColor.js'
4 |
5 | // let lessNodesAppended
6 | const colorList = [
7 | {
8 | key: '薄暮', color: '#F5222D'
9 | },
10 | {
11 | key: '火山', color: '#FA541C'
12 | },
13 | {
14 | key: '日暮', color: '#FAAD14'
15 | },
16 | {
17 | key: '明青', color: '#13C2C2'
18 | },
19 | {
20 | key: '极光绿', color: '#52C41A'
21 | },
22 | {
23 | key: '拂晓蓝(默认)', color: '#1890FF'
24 | },
25 | {
26 | key: '极客蓝', color: '#2F54EB'
27 | },
28 | {
29 | key: '酱紫', color: '#722ED1'
30 | }
31 | ]
32 |
33 | const updateTheme = newPrimaryColor => {
34 | const hideMessage = message.loading('正在切换主题!', 0)
35 | themeColor.changeColor(newPrimaryColor).finally(() => {
36 | setTimeout(() => {
37 | hideMessage()
38 | }, 10)
39 | })
40 | }
41 |
42 | const updateColorWeak = colorWeak => {
43 | // document.body.className = colorWeak ? 'colorWeak' : '';
44 | const app = document.body.querySelector('#app')
45 | colorWeak ? app.classList.add('colorWeak') : app.classList.remove('colorWeak')
46 | }
47 |
48 | export { updateTheme, colorList, updateColorWeak }
49 |
--------------------------------------------------------------------------------
/mmq-ui/src/components/SettingDrawer/themeColor.js:
--------------------------------------------------------------------------------
1 | import client from 'webpack-theme-color-replacer/client'
2 | import generate from '@ant-design/colors/lib/generate'
3 |
4 | export default {
5 | getAntdSerials (color) {
6 | // 淡化(即less的tint)
7 | const lightens = new Array(9).fill().map((t, i) => {
8 | return client.varyColor.lighten(color, i / 10)
9 | })
10 | // colorPalette变换得到颜色值
11 | const colorPalettes = generate(color)
12 | const rgb = client.varyColor.toNum3(color.replace('#', '')).join(',')
13 | return lightens.concat(colorPalettes).concat(rgb)
14 | },
15 | changeColor (newColor) {
16 | var options = {
17 | newColors: this.getAntdSerials(newColor), // new colors array, one-to-one corresponde with `matchColors`
18 | changeUrl (cssUrl) {
19 | return `/${cssUrl}` // while router is not `hash` mode, it needs absolute path
20 | }
21 | }
22 | return client.changer.changeColor(options, Promise)
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/mmq-ui/src/components/StandardFormRow/index.js:
--------------------------------------------------------------------------------
1 | import StandardFormRow from './StandardFormRow'
2 |
3 | export default StandardFormRow
4 |
--------------------------------------------------------------------------------
/mmq-ui/src/components/TagSelect/TagSelectOption.jsx:
--------------------------------------------------------------------------------
1 | import { Tag } from 'ant-design-vue'
2 | const { CheckableTag } = Tag
3 |
4 | export default {
5 | name: 'TagSelectOption',
6 | props: {
7 | prefixCls: {
8 | type: String,
9 | default: 'ant-pro-tag-select-option'
10 | },
11 | value: {
12 | type: [String, Number, Object],
13 | default: ''
14 | },
15 | checked: {
16 | type: Boolean,
17 | default: false
18 | }
19 | },
20 | data () {
21 | return {
22 | localChecked: this.checked || false
23 | }
24 | },
25 | watch: {
26 | 'checked' (val) {
27 | this.localChecked = val
28 | },
29 | '$parent.items': {
30 | handler: function (val) {
31 | this.value && val.hasOwnProperty(this.value) && (this.localChecked = val[this.value])
32 | },
33 | deep: true
34 | }
35 | },
36 | render () {
37 | const { $slots, value } = this
38 | const onChange = (checked) => {
39 | this.$emit('change', { value, checked })
40 | }
41 | return (
42 | {$slots.default}
43 | )
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/mmq-ui/src/components/TextArea/style.less:
--------------------------------------------------------------------------------
1 | .ant-textarea-limit {
2 | position: relative;
3 |
4 | .limit {
5 | position: absolute;
6 | color: #909399;
7 | background: #fff;
8 | font-size: 12px;
9 | bottom: 5px;
10 | right: 10px;
11 | }
12 | }
--------------------------------------------------------------------------------
/mmq-ui/src/components/Trend/Trend.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
38 |
39 |
42 |
--------------------------------------------------------------------------------
/mmq-ui/src/components/Trend/index.js:
--------------------------------------------------------------------------------
1 | import Trend from './Trend.vue'
2 |
3 | export default Trend
4 |
--------------------------------------------------------------------------------
/mmq-ui/src/components/Trend/index.less:
--------------------------------------------------------------------------------
1 | @import "../index";
2 |
3 | @trend-prefix-cls: ~"@{ant-pro-prefix}-trend";
4 |
5 | .@{trend-prefix-cls} {
6 | display: inline-block;
7 | font-size: @font-size-base;
8 | line-height: 22px;
9 |
10 | .up,
11 | .down {
12 | margin-left: 4px;
13 | position: relative;
14 | top: 1px;
15 |
16 | i {
17 | font-size: 12px;
18 | transform: scale(0.83);
19 | }
20 | }
21 |
22 | .item-text {
23 | display: inline-block;
24 | margin-left: 8px;
25 | color: rgba(0,0,0,.85);
26 | }
27 |
28 | .up {
29 | color: @red-6;
30 | }
31 | .down {
32 | color: @green-6;
33 | top: -1px;
34 | }
35 |
36 | &.reverse-color .up {
37 | color: @green-6;
38 | }
39 | &.reverse-color .down {
40 | color: @red-6;
41 | }
42 | }
--------------------------------------------------------------------------------
/mmq-ui/src/components/Trend/index.md:
--------------------------------------------------------------------------------
1 | # Trend 趋势标记
2 |
3 | 趋势符号,标记上升和下降趋势。通常用绿色代表“好”,红色代表“不好”,股票涨跌场景除外。
4 |
5 |
6 |
7 | 引用方式:
8 |
9 | ```javascript
10 | import Trend from '@/components/Trend'
11 |
12 | export default {
13 | components: {
14 | Trend
15 | }
16 | }
17 | ```
18 |
19 |
20 |
21 | ## 代码演示 [demo](https://pro.loacg.com/test/home)
22 |
23 | ```html
24 | 5%
25 | ```
26 | 或
27 | ```html
28 |
29 | 工资
30 | 5%
31 |
32 | ```
33 | 或
34 | ```html
35 | 5%
36 | ```
37 |
38 |
39 | ## API
40 |
41 | | 参数 | 说明 | 类型 | 默认值 |
42 | |----------|------------------------------------------|-------------|-------|
43 | | flag | 上升下降标识:`up|down` | string | - |
44 | | reverseColor | 颜色反转 | Boolean | false |
45 |
46 |
--------------------------------------------------------------------------------
/mmq-ui/src/components/_util/util.js:
--------------------------------------------------------------------------------
1 | /**
2 | * components util
3 | */
4 |
5 | /**
6 | * 清理空值,对象
7 | * @param children
8 | * @returns {*[]}
9 | */
10 | export function filterEmpty (children = []) {
11 | return children.filter(c => c.tag || (c.text && c.text.trim() !== ''))
12 | }
13 |
14 | /**
15 | * 获取字符串长度,英文字符 长度1,中文字符长度2
16 | * @param {*} str
17 | */
18 | export const getStrFullLength = (str = '') =>
19 | str.split('').reduce((pre, cur) => {
20 | const charCode = cur.charCodeAt(0)
21 | if (charCode >= 0 && charCode <= 128) {
22 | return pre + 1
23 | }
24 | return pre + 2
25 | }, 0)
26 |
27 | /**
28 | * 截取字符串,根据 maxLength 截取后返回
29 | * @param {*} str
30 | * @param {*} maxLength
31 | */
32 | export const cutStrByFullLength = (str = '', maxLength) => {
33 | let showLength = 0
34 | return str.split('').reduce((pre, cur) => {
35 | const charCode = cur.charCodeAt(0)
36 | if (charCode >= 0 && charCode <= 128) {
37 | showLength += 1
38 | } else {
39 | showLength += 2
40 | }
41 | if (showLength <= maxLength) {
42 | return pre + cur
43 | }
44 | return pre
45 | }, '')
46 | }
47 |
--------------------------------------------------------------------------------
/mmq-ui/src/components/index.less:
--------------------------------------------------------------------------------
1 | @import "~ant-design-vue/lib/style/index";
2 |
3 | // The prefix to use on all css classes from ant-pro.
4 | @ant-pro-prefix : ant-pro;
5 | @ant-global-sider-zindex : 106;
6 | @ant-global-header-zindex : 105;
--------------------------------------------------------------------------------
/mmq-ui/src/config/defaultSettings.js:
--------------------------------------------------------------------------------
1 | /**
2 | * 项目默认配置项
3 | * primaryColor - 默认主题色, 如果修改颜色不生效,请清理 localStorage
4 | * navTheme - sidebar theme ['dark', 'light'] 两种主题
5 | * colorWeak - 色盲模式
6 | * layout - 整体布局方式 ['sidemenu', 'topmenu'] 两种布局
7 | * fixedHeader - 固定 Header : boolean
8 | * fixSiderbar - 固定左侧菜单栏 : boolean
9 | * contentWidth - 内容区布局: 流式 | 固定
10 | *
11 | * storageOptions: {} - Vue-ls 插件配置项 (localStorage/sessionStorage)
12 | *
13 | */
14 |
15 | export default {
16 | navTheme: 'dark', // theme for nav menu
17 | primaryColor: '#F5222D', // primary color of ant design
18 | layout: 'sidemenu', // nav menu position: `sidemenu` or `topmenu`
19 | contentWidth: 'Fluid', // layout of content: `Fluid` or `Fixed`, only works when layout is topmenu
20 | fixedHeader: false, // sticky header
21 | fixSiderbar: false, // sticky siderbar
22 | colorWeak: false,
23 | menu: {
24 | locale: true
25 | },
26 | title: 'MMQ Broker',
27 | pwa: false,
28 | iconfontUrl: '',
29 | production: process.env.NODE_ENV === 'production' && process.env.VUE_APP_PREVIEW !== 'true'
30 | }
31 |
--------------------------------------------------------------------------------
/mmq-ui/src/core/directives/action.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import store from '@/store'
3 |
4 | /**
5 | * Action 权限指令
6 | * 指令用法:
7 | * - 在需要控制 action 级别权限的组件上使用 v-action:[method] , 如下:
8 | * 添加用户
9 | * 删除用户
10 | * 修改
11 | *
12 | * - 当前用户没有权限时,组件上使用了该指令则会被隐藏
13 | * - 当后台权限跟 pro 提供的模式不同时,只需要针对这里的权限过滤进行修改即可
14 | *
15 | * @see https://github.com/vueComponent/ant-design-vue-pro/pull/53
16 | */
17 | const action = Vue.directive('action', {
18 | inserted: function (el, binding, vnode) {
19 | const actionName = binding.arg
20 | const roles = store.getters.roles
21 | const elVal = vnode.context.$route.meta.permission
22 | const permissionId = elVal instanceof String && [elVal] || elVal
23 | roles.permissions.forEach(p => {
24 | if (!permissionId.includes(p.permissionId)) {
25 | return
26 | }
27 | if (p.actionList && !p.actionList.includes(actionName)) {
28 | el.parentNode && el.parentNode.removeChild(el) || (el.style.display = 'none')
29 | }
30 | })
31 | }
32 | })
33 |
34 | export default action
35 |
--------------------------------------------------------------------------------
/mmq-ui/src/core/icons.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Custom icon list
3 | * All icons are loaded here for easy management
4 | * @see https://vue.ant.design/components/icon/#Custom-Font-Icon
5 | *
6 | * 自定义图标加载表
7 | * 所有图标均从这里加载,方便管理
8 | */
9 | import bxAnaalyse from '@/assets/icons/bx-analyse.svg?inline' // path to your '*.svg?inline' file.
10 |
11 | export { bxAnaalyse }
12 |
--------------------------------------------------------------------------------
/mmq-ui/src/core/use.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 |
3 | // base library
4 | import Antd from 'ant-design-vue'
5 | import Viser from 'viser-vue'
6 | import VueCropper from 'vue-cropper'
7 | import 'ant-design-vue/dist/antd.less'
8 |
9 | // ext library
10 | import VueClipboard from 'vue-clipboard2'
11 | import MultiTab from '@/components/MultiTab'
12 | import PageLoading from '@/components/PageLoading'
13 | import PermissionHelper from '@/core/permission/permission'
14 | // import '@/components/use'
15 | import './directives/action'
16 |
17 | VueClipboard.config.autoSetContainer = true
18 |
19 | Vue.use(Antd)
20 | Vue.use(Viser)
21 | Vue.use(MultiTab)
22 | Vue.use(PageLoading)
23 | Vue.use(VueClipboard)
24 | Vue.use(PermissionHelper)
25 | Vue.use(VueCropper)
26 |
27 | process.env.NODE_ENV !== 'production' && console.warn('[antd-pro] WARNING: Antd now use fulled imported.')
28 |
--------------------------------------------------------------------------------
/mmq-ui/src/layouts/BasicLayout.less:
--------------------------------------------------------------------------------
1 | @import "~ant-design-vue/es/style/themes/default.less";
2 |
3 | .ant-pro-global-header-index-right {
4 | margin-right: 8px;
5 |
6 | &.ant-pro-global-header-index-dark {
7 | .ant-pro-global-header-index-action {
8 | color: hsla(0, 0%, 100%, .85);
9 |
10 | &:hover {
11 | background: #1890ff;
12 | }
13 | }
14 | }
15 |
16 | .ant-pro-account-avatar {
17 | .antd-pro-global-header-index-avatar {
18 | margin: ~'calc((@{layout-header-height} - 24px) / 2)' 0;
19 | margin-right: 8px;
20 | color: @primary-color;
21 | vertical-align: top;
22 | background: rgba(255, 255, 255, 0.85);
23 | }
24 | }
25 |
26 | .menu {
27 | .anticon {
28 | margin-right: 8px;
29 | }
30 |
31 | .ant-dropdown-menu-item {
32 | min-width: 100px;
33 | }
34 | }
35 | }
36 |
37 |
--------------------------------------------------------------------------------
/mmq-ui/src/layouts/BlankLayout.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
13 |
14 |
17 |
--------------------------------------------------------------------------------
/mmq-ui/src/layouts/PageView.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
13 |
--------------------------------------------------------------------------------
/mmq-ui/src/layouts/RouteView.vue:
--------------------------------------------------------------------------------
1 |
33 |
--------------------------------------------------------------------------------
/mmq-ui/src/layouts/index.js:
--------------------------------------------------------------------------------
1 | import UserLayout from './UserLayout'
2 | import BlankLayout from './BlankLayout'
3 | import BasicLayout from './BasicLayout'
4 | import RouteView from './RouteView'
5 | import PageView from './PageView'
6 |
7 | export { UserLayout, BasicLayout, BlankLayout, RouteView, PageView }
8 |
--------------------------------------------------------------------------------
/mmq-ui/src/locales/lang/en-US.js:
--------------------------------------------------------------------------------
1 | import antdEnUS from 'ant-design-vue/es/locale-provider/en_US'
2 | import momentEU from 'moment/locale/eu'
3 | import global from './en-US/global'
4 |
5 | import menu from './en-US/menu'
6 | import setting from './en-US/setting'
7 | import user from './en-US/user'
8 | import overview from './en-US/overview'
9 |
10 | import dashboard from './en-US/dashboard'
11 | import form from './en-US/form'
12 | import result from './en-US/result'
13 | import account from './en-US/account'
14 |
15 | const components = {
16 | antLocale: antdEnUS,
17 | momentName: 'eu',
18 | momentLocale: momentEU
19 | }
20 |
21 | export default {
22 | message: '-',
23 |
24 | 'layouts.usermenu.dialog.title': 'Message',
25 | 'layouts.usermenu.dialog.content': 'Are you sure you would like to logout?',
26 | 'layouts.userLayout.title': 'MQTT Broker System',
27 | ...components,
28 | ...global,
29 | ...menu,
30 | ...setting,
31 | ...user,
32 | ...dashboard,
33 | ...form,
34 | ...result,
35 | overview,
36 | ...account
37 | }
38 |
--------------------------------------------------------------------------------
/mmq-ui/src/locales/lang/en-US/account.js:
--------------------------------------------------------------------------------
1 | import settings from './account/settings'
2 |
3 | export default {
4 | ...settings
5 | }
6 |
--------------------------------------------------------------------------------
/mmq-ui/src/locales/lang/en-US/dashboard.js:
--------------------------------------------------------------------------------
1 | import analysis from './dashboard/analysis'
2 |
3 | export default {
4 | ...analysis
5 | }
6 |
--------------------------------------------------------------------------------
/mmq-ui/src/locales/lang/en-US/form.js:
--------------------------------------------------------------------------------
1 | import basicForm from './form/basicForm'
2 |
3 | export default {
4 | ...basicForm
5 | }
6 |
--------------------------------------------------------------------------------
/mmq-ui/src/locales/lang/en-US/global.js:
--------------------------------------------------------------------------------
1 | export default {
2 | submit: 'Submit',
3 | save: 'Save',
4 | 'submit.ok': 'Submit successfully',
5 | 'save.ok': 'Saved successfully'
6 | }
7 |
--------------------------------------------------------------------------------
/mmq-ui/src/locales/lang/en-US/menu.js:
--------------------------------------------------------------------------------
1 | export default {
2 | 'menu.welcome': 'Welcome',
3 | 'menu.home': 'Home',
4 | 'menu.dashboard': 'Monitor',
5 | 'menu.dashboard.monitor': 'Overview',
6 | 'menu.dashboard.topics': 'Topics',
7 | 'menu.dashboard.clients': 'Client',
8 | 'menu.dashboard.subscription': 'Subscription',
9 | 'menu.ruleEngine': 'RuleEngine',
10 | 'menu.ruleEngine.resources': 'Resources',
11 | 'menu.ruleEngine.ruleEngine': 'RuleEngine',
12 | 'menu.modules': 'Modules',
13 | 'menu.modules.modules': 'Modules',
14 | 'menu.account.logout': 'Logout',
15 | 'menu.account.settings': 'Settings',
16 | 'menu.plugs': 'Plugs',
17 | 'menu.plugs.plugs': 'Plugs'
18 | }
19 |
--------------------------------------------------------------------------------
/mmq-ui/src/locales/lang/en-US/overview.js:
--------------------------------------------------------------------------------
1 | export default {
2 | 'overview.systemName': 'System Name'
3 | }
4 |
--------------------------------------------------------------------------------
/mmq-ui/src/locales/lang/en-US/result.js:
--------------------------------------------------------------------------------
1 | import success from './result/success'
2 | import fail from './result/fail'
3 |
4 | export default {
5 | ...success,
6 | ...fail
7 | }
8 |
--------------------------------------------------------------------------------
/mmq-ui/src/locales/lang/en-US/result/fail.js:
--------------------------------------------------------------------------------
1 | export default {
2 | 'result.fail.error.title': 'Submission Failed',
3 | 'result.fail.error.description':
4 | 'Please check and modify the following information before resubmitting.',
5 | 'result.fail.error.hint-title': 'The content you submitted has the following error:',
6 | 'result.fail.error.hint-text1': 'Your account has been frozen',
7 | 'result.fail.error.hint-btn1': 'Thaw immediately',
8 | 'result.fail.error.hint-text2': 'Your account is not yet eligible to apply',
9 | 'result.fail.error.hint-btn2': 'Upgrade immediately',
10 | 'result.fail.error.btn-text': 'Return to modify'
11 | }
12 |
--------------------------------------------------------------------------------
/mmq-ui/src/locales/lang/en-US/result/success.js:
--------------------------------------------------------------------------------
1 | export default {
2 | 'result.success.title': 'Submission Success',
3 | 'result.success.description':
4 | 'The submission results page is used to feed back the results of a series of operational tasks. If it is a simple operation, use the Message global prompt feedback. This text area can show a simple supplementary explanation. If there is a similar requirement for displaying “documents”, the following gray area can present more complicated content.',
5 | 'result.success.operate-title': 'Project Name',
6 | 'result.success.operate-id': 'Project ID',
7 | 'result.success.principal': 'Principal',
8 | 'result.success.operate-time': 'Effective time',
9 | 'result.success.step1-title': 'Create project',
10 | 'result.success.step1-operator': 'Qu Lili',
11 | 'result.success.step2-title': 'Departmental preliminary review',
12 | 'result.success.step2-operator': 'Zhou Maomao',
13 | 'result.success.step2-extra': 'Urge',
14 | 'result.success.step3-title': 'Financial review',
15 | 'result.success.step4-title': 'Finish',
16 | 'result.success.btn-return': 'Back List',
17 | 'result.success.btn-project': 'View Project',
18 | 'result.success.btn-print': 'Print'
19 | }
20 |
--------------------------------------------------------------------------------
/mmq-ui/src/locales/lang/zh-CN.js:
--------------------------------------------------------------------------------
1 | import antd from 'ant-design-vue/es/locale-provider/zh_CN'
2 | import momentCN from 'moment/locale/zh-cn'
3 | import global from './zh-CN/global'
4 |
5 | import menu from './zh-CN/menu'
6 | import setting from './zh-CN/setting'
7 | import user from './zh-CN/user'
8 | import dashboard from './zh-CN/dashboard'
9 | import form from './zh-CN/form'
10 | import result from './zh-CN/result'
11 | import account from './zh-CN/account'
12 | import overview from './zh-CN/overview'
13 |
14 | const components = {
15 | antLocale: antd,
16 | momentName: 'zh-cn',
17 | momentLocale: momentCN
18 | }
19 |
20 | export default {
21 | message: '-',
22 |
23 | 'layouts.usermenu.dialog.title': '信息',
24 | 'layouts.usermenu.dialog.content': '您确定要注销吗?',
25 | 'layouts.userLayout.title': 'MQTT Broker System',
26 | ...components,
27 | ...global,
28 | ...menu,
29 | ...setting,
30 | ...user,
31 | ...dashboard,
32 | ...form,
33 | ...result,
34 | overview,
35 | ...account
36 | }
37 |
--------------------------------------------------------------------------------
/mmq-ui/src/locales/lang/zh-CN/account.js:
--------------------------------------------------------------------------------
1 | import settings from './account/settings'
2 |
3 | export default {
4 | ...settings
5 | }
6 |
--------------------------------------------------------------------------------
/mmq-ui/src/locales/lang/zh-CN/dashboard.js:
--------------------------------------------------------------------------------
1 | import analysis from './dashboard/analysis'
2 |
3 | export default {
4 | ...analysis
5 | }
6 |
--------------------------------------------------------------------------------
/mmq-ui/src/locales/lang/zh-CN/form.js:
--------------------------------------------------------------------------------
1 | import basicForm from './form/basicForm'
2 |
3 | export default {
4 | ...basicForm
5 | }
6 |
--------------------------------------------------------------------------------
/mmq-ui/src/locales/lang/zh-CN/global.js:
--------------------------------------------------------------------------------
1 | export default {
2 | submit: '提交',
3 | save: '保存',
4 | 'submit.ok': '提交成功',
5 | 'save.ok': '保存成功'
6 | }
7 |
--------------------------------------------------------------------------------
/mmq-ui/src/locales/lang/zh-CN/menu.js:
--------------------------------------------------------------------------------
1 | export default {
2 | 'menu.welcome': '欢迎',
3 | 'menu.home': '主页',
4 | 'menu.dashboard': '监控',
5 | 'menu.dashboard.monitor': '概述',
6 | 'menu.dashboard.clients': '客户端',
7 | 'menu.dashboard.topics': '主题',
8 | 'menu.dashboard.subscription': '订阅',
9 | 'menu.ruleEngine': '规则引擎',
10 | 'menu.ruleEngine.resources': '资源',
11 | 'menu.ruleEngine.ruleEngine': '规则引擎',
12 | 'menu.modules': '模块',
13 | 'menu.modules.modules': '模块',
14 | 'menu.account.logout': '登出',
15 | 'menu.account.settings': '设置',
16 | 'menu.plugs': '插件',
17 | 'menu.plugs.plugs': '插件'
18 | }
19 |
--------------------------------------------------------------------------------
/mmq-ui/src/locales/lang/zh-CN/overview.js:
--------------------------------------------------------------------------------
1 | export default {
2 | 'overview.systemName': '系统名'
3 | }
4 |
--------------------------------------------------------------------------------
/mmq-ui/src/locales/lang/zh-CN/result.js:
--------------------------------------------------------------------------------
1 | import success from './result/success'
2 | import fail from './result/fail'
3 |
4 | export default {
5 | ...success,
6 | ...fail
7 | }
8 |
--------------------------------------------------------------------------------
/mmq-ui/src/locales/lang/zh-CN/result/fail.js:
--------------------------------------------------------------------------------
1 | export default {
2 | 'result.fail.error.title': '提交失败',
3 | 'result.fail.error.description': '请核对并修改以下信息后,再重新提交。',
4 | 'result.fail.error.hint-title': '您提交的内容有如下错误:',
5 | 'result.fail.error.hint-text1': '您的账户已被冻结',
6 | 'result.fail.error.hint-btn1': '立即解冻',
7 | 'result.fail.error.hint-text2': '您的账户还不具备申请资格',
8 | 'result.fail.error.hint-btn2': '立即升级',
9 | 'result.fail.error.btn-text': '返回修改'
10 | }
11 |
--------------------------------------------------------------------------------
/mmq-ui/src/locales/lang/zh-CN/result/success.js:
--------------------------------------------------------------------------------
1 | export default {
2 | 'result.success.title': '提交成功',
3 | 'result.success.description':
4 | '提交结果页用于反馈一系列操作任务的处理结果, 如果仅是简单操作,使用 Message 全局提示反馈即可。 本文字区域可以展示简单的补充说明,如果有类似展示 “单据”的需求,下面这个灰色区域可以呈现比较复杂的内容。',
5 | 'result.success.operate-title': '项目名称',
6 | 'result.success.operate-id': '项目 ID',
7 | 'result.success.principal': '负责人',
8 | 'result.success.operate-time': '生效时间',
9 | 'result.success.step1-title': '创建项目',
10 | 'result.success.step1-operator': '曲丽丽',
11 | 'result.success.step2-title': '部门初审',
12 | 'result.success.step2-operator': '周毛毛',
13 | 'result.success.step2-extra': '催一下',
14 | 'result.success.step3-title': '财务复核',
15 | 'result.success.step4-title': '完成',
16 | 'result.success.btn-return': '返回列表',
17 | 'result.success.btn-project': '查看项目',
18 | 'result.success.btn-print': '打印'
19 | }
20 |
--------------------------------------------------------------------------------
/mmq-ui/src/locales/lang/zh-CN/setting.js:
--------------------------------------------------------------------------------
1 | export default {
2 | 'app.setting.pagestyle': '整体风格设置',
3 | 'app.setting.pagestyle.light': '亮色菜单风格',
4 | 'app.setting.pagestyle.dark': '暗色菜单风格',
5 | 'app.setting.pagestyle.realdark': '暗黑模式',
6 | 'app.setting.themecolor': '主题色',
7 | 'app.setting.navigationmode': '导航模式',
8 | 'app.setting.content-width': '内容区域宽度',
9 | 'app.setting.fixedheader': '固定 Header',
10 | 'app.setting.fixedsidebar': '固定侧边栏',
11 | 'app.setting.sidemenu': '侧边菜单布局',
12 | 'app.setting.topmenu': '顶部菜单布局',
13 | 'app.setting.content-width.fixed': 'Fixed',
14 | 'app.setting.content-width.fluid': 'Fluid',
15 | 'app.setting.othersettings': '其他设置',
16 | 'app.setting.weakmode': '色弱模式',
17 | 'app.setting.copy': '拷贝设置',
18 | 'app.setting.loading': '加载主题中',
19 | 'app.setting.copyinfo': '拷贝设置成功 src/config/defaultSettings.js',
20 | 'app.setting.production.hint': '配置栏只在开发环境用于预览,生产环境不会展现,请拷贝后手动修改配置文件',
21 | 'app.setting.themecolor.daybreak': '拂晓蓝',
22 | 'app.setting.themecolor.dust': '薄暮',
23 | 'app.setting.themecolor.volcano': '火山',
24 | 'app.setting.themecolor.sunset': '日暮',
25 | 'app.setting.themecolor.cyan': '明青',
26 | 'app.setting.themecolor.green': '极光绿',
27 | 'app.setting.themecolor.geekblue': '极客蓝',
28 | 'app.setting.themecolor.purple': '酱紫'
29 | }
30 |
--------------------------------------------------------------------------------
/mmq-ui/src/main.js:
--------------------------------------------------------------------------------
1 | // with polyfills
2 | import 'core-js/stable'
3 | import 'regenerator-runtime/runtime'
4 |
5 | import Vue from 'vue'
6 | import App from './App.vue'
7 | import router from './router'
8 | import store from './store/'
9 | import i18n from './locales'
10 | import { VueAxios } from './utils/request'
11 | import ProLayout, { PageHeaderWrapper } from '@ant-design-vue/pro-layout'
12 | import themePluginConfig from '../config/themePluginConfig'
13 |
14 | // mock
15 | // WARNING: `mockjs` NOT SUPPORT `IE` PLEASE DO NOT USE IN `production` ENV.
16 | import './mock'
17 |
18 | import bootstrap from './core/bootstrap'
19 | import './core/lazy_use' // use lazy load components
20 | import './permission' // permission control
21 | import './utils/filter' // global filter
22 | import './global.less' // global style
23 |
24 | Vue.config.productionTip = false
25 |
26 | // mount axios to `Vue.$http` and `this.$http`
27 | Vue.use(VueAxios)
28 | // use pro-layout components
29 | Vue.component('pro-layout', ProLayout)
30 | Vue.component('page-container', PageHeaderWrapper)
31 | Vue.component('page-header-wrapper', PageHeaderWrapper)
32 |
33 | window.umi_plugin_ant_themeVar = themePluginConfig.theme
34 |
35 | new Vue({
36 | router,
37 | store,
38 | i18n,
39 | // init localstorage, vuex, Logo message
40 | created: bootstrap,
41 | render: h => h(App)
42 | }).$mount('#app')
43 |
--------------------------------------------------------------------------------
/mmq-ui/src/mock/index.js:
--------------------------------------------------------------------------------
1 | import { isIE } from '@/utils/util'
2 |
3 | // 判断环境不是 prod 或者 preview 是 true 时,加载 mock 服务
4 | if (process.env.NODE_ENV !== 'production' || process.env.VUE_APP_PREVIEW === 'true') {
5 | if (isIE()) {
6 | console.error('[antd-pro] ERROR: `mockjs` NOT SUPPORT `IE` PLEASE DO NOT USE IN `production` ENV.')
7 | }
8 | // 使用同步加载依赖
9 | // 防止 vuex 中的 GetInfo 早于 mock 运行,导致无法 mock 请求返回结果
10 | console.log('[antd-pro] mock mounting')
11 | const Mock = require('mockjs2')
12 | require('./services/auth')
13 | require('./services/user')
14 | require('./services/manage')
15 | require('./services/other')
16 | require('./services/tagCloud')
17 | require('./services/article')
18 |
19 | Mock.setup({
20 | timeout: 800 // setter delay time
21 | })
22 | console.log('[antd-pro] mock mounted')
23 | }
24 |
--------------------------------------------------------------------------------
/mmq-ui/src/mock/util.js:
--------------------------------------------------------------------------------
1 | const responseBody = {
2 | message: '',
3 | timestamp: 0,
4 | result: null,
5 | code: 0
6 | }
7 |
8 | export const builder = (data, message, code = 0, headers = {}) => {
9 | responseBody.result = data
10 | if (message !== undefined && message !== null) {
11 | responseBody.message = message
12 | }
13 | if (code !== undefined && code !== 0) {
14 | responseBody.code = code
15 | responseBody._status = code
16 | }
17 | if (headers !== null && typeof headers === 'object' && Object.keys(headers).length > 0) {
18 | responseBody._headers = headers
19 | }
20 | responseBody.timestamp = new Date().getTime()
21 | return responseBody
22 | }
23 |
24 | export const getQueryParameters = (options) => {
25 | const url = options.url
26 | const search = url.split('?')[1]
27 | if (!search) {
28 | return {}
29 | }
30 | return JSON.parse('{"' + decodeURIComponent(search)
31 | .replace(/"/g, '\\"')
32 | .replace(/&/g, '","')
33 | .replace(/=/g, '":"') + '"}')
34 | }
35 |
36 | export const getBody = (options) => {
37 | return options.body && JSON.parse(options.body)
38 | }
39 |
--------------------------------------------------------------------------------
/mmq-ui/src/router/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import Router from 'vue-router'
3 | import { constantRouterMap } from '@/config/router.config'
4 |
5 | // hack router push callback
6 | const originalPush = Router.prototype.push
7 | Router.prototype.push = function push (location, onResolve, onReject) {
8 | if (onResolve || onReject) return originalPush.call(this, location, onResolve, onReject)
9 | return originalPush.call(this, location).catch(err => err)
10 | }
11 |
12 | Vue.use(Router)
13 |
14 | export default new Router({
15 | mode: 'history',
16 | routes: constantRouterMap
17 | })
18 |
--------------------------------------------------------------------------------
/mmq-ui/src/store/app-mixin.js:
--------------------------------------------------------------------------------
1 | import { mapState } from 'vuex'
2 |
3 | const baseMixin = {
4 | computed: {
5 | ...mapState({
6 | layout: state => state.app.layout,
7 | navTheme: state => state.app.theme,
8 | primaryColor: state => state.app.color,
9 | colorWeak: state => state.app.weak,
10 | fixedHeader: state => state.app.fixedHeader,
11 | fixedSidebar: state => state.app.fixedSidebar,
12 | contentWidth: state => state.app.contentWidth,
13 | autoHideHeader: state => state.app.autoHideHeader,
14 |
15 | isMobile: state => state.app.isMobile,
16 | sideCollapsed: state => state.app.sideCollapsed,
17 | multiTab: state => state.app.multiTab
18 | }),
19 | isTopMenu () {
20 | return this.layout === 'topmenu'
21 | }
22 | },
23 | methods: {
24 | isSideMenu () {
25 | return !this.isTopMenu
26 | }
27 | }
28 | }
29 |
30 | export {
31 | baseMixin
32 | }
33 |
--------------------------------------------------------------------------------
/mmq-ui/src/store/device-mixin.js:
--------------------------------------------------------------------------------
1 | import { mapState } from 'vuex'
2 |
3 | const deviceMixin = {
4 | computed: {
5 | ...mapState({
6 | isMobile: state => state.app.isMobile
7 | })
8 | }
9 | }
10 |
11 | export { deviceMixin }
12 |
--------------------------------------------------------------------------------
/mmq-ui/src/store/getters.js:
--------------------------------------------------------------------------------
1 | const getters = {
2 | isMobile: state => state.app.isMobile,
3 | lang: state => state.app.lang,
4 | theme: state => state.app.theme,
5 | color: state => state.app.color,
6 | token: state => state.user.token,
7 | avatar: state => state.user.avatar,
8 | nickname: state => state.user.name,
9 | welcome: state => state.user.welcome,
10 | roles: state => state.user.roles,
11 | userInfo: state => state.user.info,
12 | addRouters: state => state.permission.addRouters,
13 | multiTab: state => state.app.multiTab
14 | }
15 |
16 | export default getters
17 |
--------------------------------------------------------------------------------
/mmq-ui/src/store/i18n-mixin.js:
--------------------------------------------------------------------------------
1 | import { mapState } from 'vuex'
2 |
3 | const i18nMixin = {
4 | computed: {
5 | ...mapState({
6 | currentLang: state => state.app.lang
7 | })
8 | },
9 | methods: {
10 | setLang (lang) {
11 | this.$store.dispatch('setLang', lang)
12 | }
13 | }
14 | }
15 |
16 | export default i18nMixin
17 |
--------------------------------------------------------------------------------
/mmq-ui/src/store/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import Vuex from 'vuex'
3 |
4 | import app from './modules/app'
5 | import user from './modules/user'
6 |
7 | // default router permission control
8 | import permission from './modules/permission'
9 |
10 | // dynamic router permission control (Experimental)
11 | // import permission from './modules/async-router'
12 | import getters from './getters'
13 |
14 | Vue.use(Vuex)
15 |
16 | export default new Vuex.Store({
17 | modules: {
18 | app,
19 | user,
20 | permission
21 | },
22 | state: {
23 |
24 | },
25 | mutations: {
26 |
27 | },
28 | actions: {
29 |
30 | },
31 | getters
32 | })
33 |
--------------------------------------------------------------------------------
/mmq-ui/src/store/modules/async-router.js:
--------------------------------------------------------------------------------
1 | /**
2 | * 向后端请求用户的菜单,动态生成路由
3 | */
4 | import { constantRouterMap } from '@/config/router.config'
5 | import { generatorDynamicRouter } from '@/router/generator-routers'
6 |
7 | const permission = {
8 | state: {
9 | routers: constantRouterMap,
10 | addRouters: []
11 | },
12 | mutations: {
13 | SET_ROUTERS: (state, routers) => {
14 | state.addRouters = routers
15 | state.routers = constantRouterMap.concat(routers)
16 | }
17 | },
18 | actions: {
19 | GenerateRoutes ({ commit }, data) {
20 | return new Promise(resolve => {
21 | const { token } = data
22 | generatorDynamicRouter(token).then(routers => {
23 | commit('SET_ROUTERS', routers)
24 | resolve()
25 | })
26 | resolve()
27 | })
28 | }
29 | }
30 | }
31 |
32 | export default permission
33 |
--------------------------------------------------------------------------------
/mmq-ui/src/store/mutation-types.js:
--------------------------------------------------------------------------------
1 | export const ACCESS_TOKEN = 'Access-Token'
2 |
3 | export const SIDEBAR_TYPE = 'sidebar_type'
4 | export const TOGGLE_MOBILE_TYPE = 'is_mobile'
5 | export const TOGGLE_NAV_THEME = 'nav_theme'
6 | export const TOGGLE_LAYOUT = 'layout'
7 | export const TOGGLE_FIXED_HEADER = 'fixed_header'
8 | export const TOGGLE_FIXED_SIDEBAR = 'fixed_sidebar'
9 | export const TOGGLE_CONTENT_WIDTH = 'content_width'
10 | export const TOGGLE_HIDE_HEADER = 'auto_hide_header'
11 | export const TOGGLE_COLOR = 'color'
12 | export const TOGGLE_WEAK = 'weak'
13 | export const TOGGLE_MULTI_TAB = 'multi_tab'
14 | export const APP_LANGUAGE = 'app_language'
15 |
16 | export const CONTENT_WIDTH_TYPE = {
17 | Fluid: 'Fluid',
18 | Fixed: 'Fixed'
19 | }
20 |
21 | export const NAV_THEME = {
22 | LIGHT: 'light',
23 | DARK: 'dark'
24 | }
25 |
--------------------------------------------------------------------------------
/mmq-ui/src/utils/axios.js:
--------------------------------------------------------------------------------
1 | const VueAxios = {
2 | vm: {},
3 | // eslint-disable-next-line no-unused-vars
4 | install (Vue, instance) {
5 | if (this.installed) {
6 | return
7 | }
8 | this.installed = true
9 |
10 | if (!instance) {
11 | // eslint-disable-next-line no-console
12 | console.error('You have to install axios')
13 | return
14 | }
15 |
16 | Vue.axios = instance
17 |
18 | Object.defineProperties(Vue.prototype, {
19 | axios: {
20 | get: function get () {
21 | return instance
22 | }
23 | },
24 | $http: {
25 | get: function get () {
26 | return instance
27 | }
28 | }
29 | })
30 | }
31 | }
32 |
33 | export {
34 | VueAxios
35 | }
36 |
--------------------------------------------------------------------------------
/mmq-ui/src/utils/domUtil.js:
--------------------------------------------------------------------------------
1 | import config from '@/config/defaultSettings'
2 |
3 | export const setDocumentTitle = function (title) {
4 | document.title = title
5 | const ua = navigator.userAgent
6 | // eslint-disable-next-line
7 | const regex = /\bMicroMessenger\/([\d\.]+)/
8 | if (regex.test(ua) && /ip(hone|od|ad)/i.test(ua)) {
9 | const i = document.createElement('iframe')
10 | i.src = '/favicon.ico'
11 | i.style.display = 'none'
12 | i.onload = function () {
13 | setTimeout(function () {
14 | i.remove()
15 | }, 9)
16 | }
17 | document.body.appendChild(i)
18 | }
19 | }
20 |
21 | export const domTitle = config.title
22 |
--------------------------------------------------------------------------------
/mmq-ui/src/utils/filter.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import moment from 'moment'
3 | import 'moment/locale/zh-cn'
4 | moment.locale('zh-cn')
5 |
6 | Vue.filter('NumberFormat', function (value) {
7 | if (!value) {
8 | return '0'
9 | }
10 | const intPartFormat = value.toString().replace(/(\d)(?=(?:\d{3})+$)/g, '$1,') // 将整数部分逢三一断
11 | return intPartFormat
12 | })
13 |
14 | Vue.filter('dayjs', function (dataStr, pattern = 'YYYY-MM-DD HH:mm:ss') {
15 | return moment(dataStr).format(pattern)
16 | })
17 |
18 | Vue.filter('moment', function (dataStr, pattern = 'YYYY-MM-DD HH:mm:ss') {
19 | return moment(dataStr).format(pattern)
20 | })
21 |
--------------------------------------------------------------------------------
/mmq-ui/src/utils/routeConvert.js:
--------------------------------------------------------------------------------
1 | import cloneDeep from 'lodash.clonedeep'
2 |
3 | export function convertRoutes (nodes) {
4 | if (!nodes) return null
5 |
6 | nodes = cloneDeep(nodes)
7 |
8 | let queue = Array.isArray(nodes) ? nodes.concat() : [nodes]
9 |
10 | while (queue.length) {
11 | const levelSize = queue.length
12 |
13 | for (let i = 0; i < levelSize; i++) {
14 | const node = queue.shift()
15 |
16 | if (!node.children || !node.children.length) continue
17 |
18 | node.children.forEach(child => {
19 | // 转化相对路径
20 | if (child.path[0] !== '/' && !child.path.startsWith('http')) {
21 | child.path = node.path.replace(/(\w*)[/]*$/, `$1/${child.path}`)
22 | }
23 | })
24 |
25 | queue = queue.concat(node.children)
26 | }
27 | }
28 |
29 | return nodes
30 | }
31 |
--------------------------------------------------------------------------------
/mmq-ui/src/utils/screenLog.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 | export const printANSI = () => {
3 | // console.clear()
4 | console.log('[antd pro] created()')
5 | // ASCII - ANSI Shadow
6 | let text = `
7 | __ __ __ __ ___
8 | | \/ || \/ | / _ \
9 | | |\/| || |\/| || (_) |
10 | |_|__|_||_|__|_| \__\_\
11 | _|"""""|_|"""""|_|"""""|
12 | \t\t\t\t\tPublished ${APP_VERSION}-${GIT_HASH} @ antdv.com
13 | \t\t\t\t\tBuild date: ${BUILD_DATE}`
14 | console.log(`%c${text}`, 'color: #fc4d50')
15 | console.log('%c感谢使用 MMQ!', 'color: #000; font-size: 14px; font-family: Hiragino Sans GB,Microsoft YaHei,\\\\5FAE\\8F6F\\96C5\\9ED1,Droid Sans Fallback,Source Sans,Wenquanyi Micro Hei,WenQuanYi Micro Hei Mono,WenQuanYi Zen Hei,Apple LiGothic Medium,SimHei,ST Heiti,WenQuanYi Zen Hei Sharp,sans-serif;')
16 | console.log('%cThanks for using MMQ!', 'color: #fff; font-size: 14px; font-weight: 300; text-shadow:#000 1px 0 0,#000 0 1px 0,#000 -1px 0 0,#000 0 -1px 0;')
17 | }
18 |
--------------------------------------------------------------------------------
/mmq-ui/src/utils/utils.less:
--------------------------------------------------------------------------------
1 | .textOverflow() {
2 | overflow: hidden;
3 | white-space: nowrap;
4 | text-overflow: ellipsis;
5 | word-break: break-all;
6 | }
7 |
8 | .textOverflowMulti(@line: 3, @bg: #fff) {
9 | position: relative;
10 | max-height: @line * 1.5em;
11 | margin-right: -1em;
12 | padding-right: 1em;
13 | overflow: hidden;
14 | line-height: 1.5em;
15 | text-align: justify;
16 | &::before {
17 | position: absolute;
18 | right: 14px;
19 | bottom: 0;
20 | padding: 0 1px;
21 | background: @bg;
22 | content: '...';
23 | }
24 | &::after {
25 | position: absolute;
26 | right: 14px;
27 | width: 1em;
28 | height: 1em;
29 | margin-top: 0.2em;
30 | background: white;
31 | content: '';
32 | }
33 | }
34 |
35 | // mixins for clearfix
36 | // ------------------------
37 | .clearfix() {
38 | zoom: 1;
39 | &::before,
40 | &::after {
41 | display: table;
42 | content: ' ';
43 | }
44 | &::after {
45 | clear: both;
46 | height: 0;
47 | font-size: 0;
48 | visibility: hidden;
49 | }
50 | }
--------------------------------------------------------------------------------
/mmq-ui/src/views/404.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | 404 page
4 |
5 |
6 |
7 |
12 |
13 |
16 |
--------------------------------------------------------------------------------
/mmq-ui/src/views/exception/403.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Back Home
6 |
7 |
8 |
9 |
10 |
11 |
21 |
--------------------------------------------------------------------------------
/mmq-ui/src/views/exception/404.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Back Home
6 |
7 |
8 |
9 |
10 |
11 |
21 |
--------------------------------------------------------------------------------
/mmq-ui/src/views/exception/500.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Back Home
6 |
7 |
8 |
9 |
10 |
11 |
21 |
--------------------------------------------------------------------------------
/mmq-ui/src/views/user/RegisterResult.vue:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 | 查看邮箱
10 | 返回首页
11 |
12 |
13 |
14 |
15 |
16 |
41 |
42 |
45 |
--------------------------------------------------------------------------------
/mmq-ui/tests/unit/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | env: {
3 | jest: true
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/mmq-ui/webstorm.config.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const webpackConfig = require('@vue/cli-service/webpack.config.js')
3 | module.exports = webpackConfig
4 |
--------------------------------------------------------------------------------
/mmq-web/src/main/java/org/monkey/mmq/web/Mmq.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021-2021 Monkey Group.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.monkey.mmq.web;
17 |
18 | import org.monkey.mmq.core.env.EnvUtil;
19 | import org.springframework.boot.SpringApplication;
20 | import org.springframework.boot.autoconfigure.SpringBootApplication;
21 | import org.springframework.boot.web.servlet.ServletComponentScan;
22 |
23 | import java.util.TimeZone;
24 |
25 | /**
26 | * Health Controller.
27 | *
28 | * @author solley
29 | */
30 | @SpringBootApplication(scanBasePackages = "org.monkey.mmq")
31 | @ServletComponentScan
32 | public class Mmq {
33 | public static void main(String[] args) {
34 | // EnvUtil.setIsStandalone(true);
35 | SpringApplication.run(Mmq.class, args);
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/mmq-web/src/main/java/org/monkey/mmq/web/config/BasicApi.java:
--------------------------------------------------------------------------------
1 | package org.monkey.mmq.web.config;
2 |
3 | import java.lang.annotation.*;
4 |
5 | /**
6 | * @ClassNameBasicApi
7 | * @Description HTTP API 使用Basic认证方式,id 和 password 须分别填写 AppID 和 AppSecret
8 | * @Author Solley
9 | * @Date2022/1/19 12:43
10 | * @Version V1.0
11 | **/
12 | @Documented
13 | @Retention(RetentionPolicy.RUNTIME)
14 | @Target(ElementType.METHOD)
15 | public @interface BasicApi {
16 | }
17 |
--------------------------------------------------------------------------------
/mmq-web/src/main/java/org/monkey/mmq/web/config/NotWrap.java:
--------------------------------------------------------------------------------
1 | package org.monkey.mmq.web.config;
2 |
3 | import java.lang.annotation.*;
4 |
5 | /**
6 | * 对spring mvc controller返回的结果不进行封装,直接以原生结果返回
7 | * @author solley
8 | * @date 2018年4月3日 上午9:10:41 123123123
9 | * @version 1.0.0
10 | */
11 | @Documented
12 | @Retention(RetentionPolicy.RUNTIME)
13 | @Target(ElementType.METHOD)
14 | public @interface NotWrap {
15 | String value() default "";
16 | }
17 |
--------------------------------------------------------------------------------
/mmq-web/src/main/java/org/monkey/mmq/web/controller/HealthController.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021-2021 Monkey Group.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.monkey.mmq.web.controller;
17 |
18 | import org.springframework.http.ResponseEntity;
19 | import org.springframework.web.bind.annotation.GetMapping;
20 | import org.springframework.web.bind.annotation.RequestMapping;
21 | import org.springframework.web.bind.annotation.RestController;
22 |
23 | /**
24 | * Health Controller.
25 | *
26 | * @author solley
27 | */
28 | @RestController
29 | @RequestMapping("/v1/console/health")
30 | public class HealthController {
31 | @GetMapping("/liveness")
32 | public ResponseEntity liveness() {
33 | return ResponseEntity.ok().body("OK");
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/mmq-web/src/main/java/org/monkey/mmq/web/util/BaseContextUtil.java:
--------------------------------------------------------------------------------
1 | package org.monkey.mmq.web.util;
2 |
3 | import java.util.HashMap;
4 | import java.util.Map;
5 |
6 | public class BaseContextUtil {
7 |
8 | public static final String USER_NAME = "username";
9 |
10 | public static ThreadLocal