├── dist
├── web
│ └── .gitkeep
└── electron
│ └── .gitkeep
├── static
└── .gitkeep
├── src
├── renderer
│ ├── assets
│ │ ├── .gitkeep
│ │ ├── img
│ │ │ ├── china.png
│ │ │ ├── world.png
│ │ │ └── excel_example.png
│ │ └── my-theme
│ │ │ ├── components
│ │ │ ├── checkbox.less
│ │ │ ├── affix.less
│ │ │ ├── circle.less
│ │ │ ├── loading-bar.less
│ │ │ ├── select-dropdown.less
│ │ │ ├── dropdown.less
│ │ │ ├── back-top.less
│ │ │ ├── index.less
│ │ │ ├── tooltip.less
│ │ │ ├── card.less
│ │ │ ├── message.less
│ │ │ ├── collapse.less
│ │ │ ├── badge.less
│ │ │ ├── spin.less
│ │ │ ├── input.less
│ │ │ ├── rate.less
│ │ │ ├── form.less
│ │ │ ├── progress.less
│ │ │ ├── upload.less
│ │ │ ├── timeline.less
│ │ │ ├── cascader.less
│ │ │ ├── alert.less
│ │ │ ├── slider.less
│ │ │ ├── switch.less
│ │ │ ├── modal.less
│ │ │ ├── notice.less
│ │ │ ├── button.less
│ │ │ ├── transfer.less
│ │ │ ├── carousel.less
│ │ │ ├── poptip.less
│ │ │ ├── tree.less
│ │ │ ├── input-number.less
│ │ │ ├── tag.less
│ │ │ ├── tabs.less
│ │ │ ├── time-picker.less
│ │ │ ├── select.less
│ │ │ └── menu.less
│ │ │ ├── common
│ │ │ ├── index.less
│ │ │ ├── iconfont
│ │ │ │ ├── ionicons.less
│ │ │ │ ├── fonts
│ │ │ │ │ ├── ionicons.eot
│ │ │ │ │ ├── ionicons.ttf
│ │ │ │ │ └── ionicons.woff
│ │ │ │ └── _ionicons-font.less
│ │ │ ├── article.less
│ │ │ ├── base.less
│ │ │ └── layout.less
│ │ │ ├── dist
│ │ │ └── fonts
│ │ │ │ ├── ionicons.eot
│ │ │ │ ├── ionicons.ttf
│ │ │ │ └── ionicons.woff
│ │ │ ├── copyright.less
│ │ │ ├── README.md
│ │ │ ├── index.less
│ │ │ ├── mixins
│ │ │ ├── close.less
│ │ │ ├── loading.less
│ │ │ ├── mask.less
│ │ │ ├── clearfix.less
│ │ │ ├── index.less
│ │ │ ├── size.less
│ │ │ ├── breadcrumb.less
│ │ │ ├── common.less
│ │ │ ├── caret.less
│ │ │ ├── content.less
│ │ │ ├── select.less
│ │ │ ├── layout.less
│ │ │ ├── tooltip.less
│ │ │ └── checkbox.less
│ │ │ ├── animation
│ │ │ ├── fade.less
│ │ │ ├── index.less
│ │ │ ├── ease.less
│ │ │ ├── slide.less
│ │ │ └── move.less
│ │ │ └── custom.css
│ ├── version
│ │ └── version.js
│ ├── key
│ │ └── mapApiKey.js
│ ├── filter
│ │ └── index.js
│ ├── store
│ │ ├── mutations_types.js
│ │ ├── modules
│ │ │ ├── map.js
│ │ │ ├── user_info.js
│ │ │ └── excel.js
│ │ ├── index.js
│ │ └── actions.js
│ ├── App.vue
│ ├── server
│ │ ├── url.js
│ │ └── ajax.js
│ ├── main.js
│ ├── tool
│ │ └── index.js
│ ├── components
│ │ ├── Page
│ │ │ ├── Auth.vue
│ │ │ ├── Map.vue
│ │ │ ├── Register.vue
│ │ │ ├── ForgetPassword.vue
│ │ │ ├── Help.vue
│ │ │ ├── MyProject.vue
│ │ │ └── Login.vue
│ │ ├── Layout
│ │ │ └── Header.vue
│ │ └── Ui
│ │ │ ├── DelPointModal.vue
│ │ │ ├── EditPointModal.vue
│ │ │ └── AddPointModal.vue
│ ├── router
│ │ └── index.js
│ └── data
│ │ └── map.js
├── main
│ ├── index.dev.js
│ └── index.js
└── index.ejs
├── .gitattributes
├── .gitignore
├── .electron-vue
├── build.config.js
├── dev-client.js
├── webpack.main.config.js
├── webpack.web.config.js
├── build.js
├── dev-runner.js
└── webpack.renderer.config.js
├── .babelrc
├── LICENSE
├── README.md
└── package.json
/dist/web/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/static/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/dist/electron/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/renderer/assets/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/renderer/version/version.js:
--------------------------------------------------------------------------------
1 | export default {
2 | VERSION: '0.0.3-beta'
3 | }
4 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | *.css linguist-language=JavaScript
2 | *.less linguist-language=JavaScript
3 |
--------------------------------------------------------------------------------
/src/renderer/assets/img/china.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i-Map/iMap/HEAD/src/renderer/assets/img/china.png
--------------------------------------------------------------------------------
/src/renderer/assets/img/world.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i-Map/iMap/HEAD/src/renderer/assets/img/world.png
--------------------------------------------------------------------------------
/src/renderer/key/mapApiKey.js:
--------------------------------------------------------------------------------
1 | export default {
2 | GOOGLE: 'AIzaSyDyfBSBmSsUsGO3iVPc4xXpCPKJ1j5__HY'
3 | }
4 |
--------------------------------------------------------------------------------
/src/renderer/assets/my-theme/components/checkbox.less:
--------------------------------------------------------------------------------
1 | @checkbox-prefix-cls: ~"@{css-prefix}checkbox";
2 | .checkboxFn();
--------------------------------------------------------------------------------
/src/renderer/assets/img/excel_example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i-Map/iMap/HEAD/src/renderer/assets/img/excel_example.png
--------------------------------------------------------------------------------
/src/renderer/assets/my-theme/components/affix.less:
--------------------------------------------------------------------------------
1 | .ivu-affix {
2 | position: fixed;
3 | z-index: @zindex-affix;
4 | }
5 |
--------------------------------------------------------------------------------
/src/renderer/assets/my-theme/common/index.less:
--------------------------------------------------------------------------------
1 | @import "base";
2 | @import "iconfont/ionicons";
3 | @import "layout";
4 | @import "article";
--------------------------------------------------------------------------------
/src/renderer/assets/my-theme/dist/fonts/ionicons.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i-Map/iMap/HEAD/src/renderer/assets/my-theme/dist/fonts/ionicons.eot
--------------------------------------------------------------------------------
/src/renderer/assets/my-theme/dist/fonts/ionicons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i-Map/iMap/HEAD/src/renderer/assets/my-theme/dist/fonts/ionicons.ttf
--------------------------------------------------------------------------------
/src/renderer/assets/my-theme/dist/fonts/ionicons.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i-Map/iMap/HEAD/src/renderer/assets/my-theme/dist/fonts/ionicons.woff
--------------------------------------------------------------------------------
/src/renderer/assets/my-theme/common/iconfont/ionicons.less:
--------------------------------------------------------------------------------
1 | @import "_ionicons-variables";
2 | @import "_ionicons-font";
3 | @import "_ionicons-icons";
4 |
--------------------------------------------------------------------------------
/src/renderer/assets/my-theme/copyright.less:
--------------------------------------------------------------------------------
1 | /*!
2 | * iView
3 | * Web: https://www.iviewui.com
4 | * Github: https://github.com/iview/iview
5 | * Author: Aresn
6 | */
--------------------------------------------------------------------------------
/src/renderer/assets/my-theme/common/iconfont/fonts/ionicons.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i-Map/iMap/HEAD/src/renderer/assets/my-theme/common/iconfont/fonts/ionicons.eot
--------------------------------------------------------------------------------
/src/renderer/assets/my-theme/common/iconfont/fonts/ionicons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i-Map/iMap/HEAD/src/renderer/assets/my-theme/common/iconfont/fonts/ionicons.ttf
--------------------------------------------------------------------------------
/src/renderer/assets/my-theme/common/iconfont/fonts/ionicons.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i-Map/iMap/HEAD/src/renderer/assets/my-theme/common/iconfont/fonts/ionicons.woff
--------------------------------------------------------------------------------
/src/renderer/filter/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 |
3 | Vue.filter('dateFormat', time => {
4 | if(time === '')
5 | return '暂无数据'
6 | else
7 | return time
8 | })
9 |
--------------------------------------------------------------------------------
/src/renderer/assets/my-theme/README.md:
--------------------------------------------------------------------------------
1 | # 样式库说明
2 |
3 | ## 目录
4 |
5 | |-- animation (动画)
6 |
7 | |-- common (全局样式)
8 |
9 | |-- components (组件样式)
10 |
11 | |-- mixins (混入)
12 |
--------------------------------------------------------------------------------
/src/renderer/assets/my-theme/index.less:
--------------------------------------------------------------------------------
1 | @import "./custom";
2 | @import "./mixins/index";
3 | @import "./common/index";
4 | @import "./animation/index";
5 | @import "./components/index";
6 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | .vscode
3 | dist/electron/*
4 | dist/web/*
5 | build/*
6 | !build/icons
7 | node_modules/
8 | npm-debug.log
9 | npm-debug.log.*
10 | thumbs.db
11 | !.gitkeep
12 |
--------------------------------------------------------------------------------
/src/renderer/store/mutations_types.js:
--------------------------------------------------------------------------------
1 | export const SET_USER_INFO = 'SET_USER_INFO'
2 | export const SET_EXCEL_DATA = 'SET_EXCEL_DATA'
3 | export const ADD_EXCEL_DATA = 'ADD_EXCEL_DATA'
4 | export const EDIT_EXCEL_DATA = 'EDIT_EXCEL_DATA'
5 | export const DEL_EXCEL_DATA = 'DEL_EXCEL_DATA'
6 |
--------------------------------------------------------------------------------
/src/renderer/assets/my-theme/mixins/close.less:
--------------------------------------------------------------------------------
1 | .close-base(@top: 0, @icon-font-size: 22px) {
2 | font-size: @icon-font-size;
3 | color: @legend-color;
4 | transition: color @transition-time ease;
5 | position: relative;
6 | top: @top;
7 | &:hover {
8 | color: #444;
9 | }
10 | }
--------------------------------------------------------------------------------
/src/renderer/assets/my-theme/mixins/loading.less:
--------------------------------------------------------------------------------
1 | // Loading for loop
2 | .ivu-load-loop{
3 | animation: ani-load-loop 1s linear infinite;
4 | }
5 |
6 | @keyframes ani-load-loop {
7 | from { transform: rotate(0deg);}
8 | 50% { transform: rotate(180deg);}
9 | to { transform: rotate(360deg);}
10 | }
11 |
--------------------------------------------------------------------------------
/src/renderer/assets/my-theme/mixins/mask.less:
--------------------------------------------------------------------------------
1 | .mask() {
2 | position: fixed;
3 | top: 0;
4 | bottom: 0;
5 | left: 0;
6 | right: 0;
7 | background-color: rgba(55, 55, 55, 0.6);
8 | height: 100%;
9 | z-index: @zindex-modal;
10 |
11 | &-hidden {
12 | display: none;
13 | }
14 | }
--------------------------------------------------------------------------------
/src/renderer/assets/my-theme/mixins/clearfix.less:
--------------------------------------------------------------------------------
1 | .clearfix() {
2 | zoom: 1;
3 | &:before,
4 | &:after {
5 | content: "";
6 | display: table;
7 | }
8 | &:after {
9 | clear: both;
10 | visibility: hidden;
11 | font-size: 0;
12 | height: 0;
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/renderer/store/modules/map.js:
--------------------------------------------------------------------------------
1 | import * as types from '../mutations_types'
2 |
3 | // state
4 | const state = {
5 | mapType: ''
6 | }
7 |
8 | // mutations
9 | const mutations = {
10 | // 设置mapType
11 | [types.SET_MAP_TYPE] (state, data) {
12 | state.mapType = data
13 | }
14 | }
15 |
16 | // 导出state, mutations
17 | export default {
18 | state,
19 | mutations
20 | }
21 |
--------------------------------------------------------------------------------
/src/renderer/assets/my-theme/mixins/index.less:
--------------------------------------------------------------------------------
1 | @import "common";
2 | @import "clearfix";
3 | @import "button";
4 | @import "layout";
5 | @import "size";
6 | @import "loading";
7 | @import "close";
8 | @import "checkbox";
9 | @import "input";
10 | @import "breadcrumb";
11 | @import "mask";
12 | @import "content"; // card、modal
13 | @import "tooltip";
14 | @import "select";
15 | @import "caret";
--------------------------------------------------------------------------------
/src/renderer/store/modules/user_info.js:
--------------------------------------------------------------------------------
1 | import * as types from '../mutations_types'
2 |
3 | // state
4 | const state = {
5 | userInfo: {}
6 | }
7 |
8 | // mutations
9 | const mutations = {
10 | // 设置userInfo
11 | [types.SET_USER_INFO] (state, data) {
12 | state.userInfo = data
13 | }
14 | }
15 |
16 | // 导出state, mutations
17 | export default {
18 | state,
19 | mutations
20 | }
--------------------------------------------------------------------------------
/src/renderer/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
21 |
--------------------------------------------------------------------------------
/src/renderer/assets/my-theme/components/circle.less:
--------------------------------------------------------------------------------
1 | @circle-prefix-cls: ~"@{css-prefix}chart-circle";
2 |
3 | .@{circle-prefix-cls}{
4 | display: inline-block;
5 | position: relative;
6 |
7 | &-inner {
8 | width: 100%;
9 | text-align: center;
10 | position: absolute;
11 | left: 0;
12 | top: 50%;
13 | transform: translateY(-50%);
14 | line-height: 1;
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/renderer/store/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import Vuex from 'vuex'
3 | import * as actions from './actions'
4 | import userInfo from './modules/user_info'
5 | import excel from './modules/excel'
6 |
7 | Vue.use(Vuex)
8 |
9 | const debug = process.env.NODE_ENV !== 'production'
10 |
11 | export default new Vuex.Store({
12 | actions,
13 | modules: {
14 | userInfo,
15 | excel
16 | },
17 | strict: debug
18 | })
19 |
--------------------------------------------------------------------------------
/.electron-vue/build.config.js:
--------------------------------------------------------------------------------
1 | const path = require('path')
2 |
3 | /**
4 | * `electron-packager` options
5 | * https://simulatedgreg.gitbooks.io/electron-vue/content/en/using-electron-packager.html
6 | */
7 | module.exports = {
8 | arch: 'x64',
9 | asar: true,
10 | dir: path.join(__dirname, '../'),
11 | icon: path.join(__dirname, '../build/icons/icon'),
12 | ignore: /(^\/(src|test|\.[a-z]+|README|yarn|static|dist\/web))|\.gitkeep/,
13 | out: path.join(__dirname, '../build'),
14 | overwrite: true,
15 | platform: process.env.BUILD_TARGET || 'all'
16 | }
17 |
--------------------------------------------------------------------------------
/src/renderer/server/url.js:
--------------------------------------------------------------------------------
1 | export default {
2 | REGISTER : '/api/v1/auth/register',
3 | EMAILLOGIN : '/api/v1/auth/login',
4 | ASKCODE : '/api/v1/auth/login/askCode',
5 | PHONELOGIN : '/api/v1/auth/login/phone',
6 | FORGETPASSWORD : '/api/v1/auth/forgetPassword',
7 | RESOLVEEXCEL : '/api/v1/resolveExcel',
8 | ASYNC_UPLOAD : '/api/v1/async/upload',
9 | ASYNC_DOWNLOAD : '/api/v1/async/download',
10 | DELMAPDATA : '/api/v1/delMapData',
11 | GETLOCATION_WORLD: 'https://google.cn/maps/api/geocode/json'
12 | }
13 |
--------------------------------------------------------------------------------
/src/renderer/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 |
3 | import App from './App'
4 | import router from './router'
5 | import store from './store'
6 | import iView from 'iview'
7 | import '@/filter/index.js'
8 | import 'iview/dist/styles/iview.css'
9 | import '@/assets/my-theme/dist/iview.css'
10 |
11 |
12 | if (!process.env.IS_WEB) Vue.use(require('vue-electron'))
13 | Vue.config.productionTip = false
14 | Vue.use(iView)
15 |
16 | /* eslint-disable no-new */
17 | new Vue({
18 | components: { App },
19 | router,
20 | store,
21 | template: ''
22 | }).$mount('#app')
23 |
--------------------------------------------------------------------------------
/src/renderer/assets/my-theme/components/loading-bar.less:
--------------------------------------------------------------------------------
1 | @loading-bar-prefix-cls: ~"@{css-prefix}loading-bar";
2 |
3 | .@{loading-bar-prefix-cls} {
4 | width: 100%;
5 | position: fixed;
6 | top: 0;
7 | left: 0;
8 | right: 0;
9 | z-index: @zindex-loading-bar;
10 |
11 | &-inner {
12 | transition: width @transition-time linear;
13 |
14 | &-color-primary {
15 | background-color: @primary-color;
16 | }
17 |
18 | &-failed-color-error {
19 | background-color: @error-color;
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/renderer/assets/my-theme/components/select-dropdown.less:
--------------------------------------------------------------------------------
1 | @select-dropdown-prefix-cls: ~"@{css-prefix}select-dropdown";
2 |
3 | .@{select-dropdown-prefix-cls} {
4 | width: inherit;
5 | max-height: 200px;
6 | overflow: auto;
7 | margin: 5px 0;
8 | padding: 5px 0;
9 | background-color: #fff;
10 | box-sizing: border-box;
11 | //border: 1px solid @border-color-split;
12 | border-radius: @btn-border-radius;
13 | //box-shadow: 0 1px 3px rgba(0,0,0,.2);
14 | box-shadow: @shadow-base;
15 | position: absolute;
16 | z-index: @zindex-select;
17 | }
--------------------------------------------------------------------------------
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "comments": false,
3 | "env": {
4 | "main": {
5 | "presets": [
6 | ["env", {
7 | "targets": { "node": 7 }
8 | }],
9 | "stage-0"
10 | ]
11 | },
12 | "renderer": {
13 | "presets": [
14 | ["env", {
15 | "modules": false
16 | }],
17 | "stage-0"
18 | ]
19 | },
20 | "web": {
21 | "presets": [
22 | ["env", {
23 | "modules": false
24 | }],
25 | "stage-0"
26 | ]
27 | }
28 | },
29 | "plugins": ["transform-runtime"]
30 | }
31 |
--------------------------------------------------------------------------------
/src/renderer/assets/my-theme/mixins/size.less:
--------------------------------------------------------------------------------
1 | .size(@width; @height) {
2 | width: @width;
3 | height: @height;
4 | }
5 |
6 | .square(@size) {
7 | .size(@size; @size);
8 | }
9 |
10 | // fix chrome 12px bug, support ie
11 | .iconfont-size-under-12px(@size, @rotate: 0deg) {
12 | display: inline-block;
13 | @font-scale: unit(@size / @font-size-base);
14 | font-size: @font-size-base;
15 | font-size: ~"@{size} \9"; // ie8-9
16 | transform: scale(@font-scale) rotate(@rotate);
17 | :root & {
18 | font-size: @font-size-base; // reset ie9 and above
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/renderer/tool/index.js:
--------------------------------------------------------------------------------
1 | const REGEX_EMAIL = /^(\w)+(\.\w+)*@(\w)+((\.\w{2,3}){1,3})$/,
2 | REGEX_PASSWORD = /^(\w){6,20}$/,
3 | REGEX_PHONE = /^1[34578]\d{9}$/,
4 | REGEX_NUM = /[\d.]/
5 |
6 | export default {
7 | judgeEmail(value) {
8 | return REGEX_EMAIL.test(value)
9 | },
10 | judgePassword(value) {
11 | return REGEX_PASSWORD.exec(value)
12 | },
13 | judgePhone(value) {
14 | return REGEX_PHONE.test(value)
15 | },
16 | judgeNum(value) {
17 | if(!/[\d.]/.test(value))
18 | return false
19 | else if(isNaN(value))
20 | return false
21 | else
22 | return true
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/renderer/assets/my-theme/animation/fade.less:
--------------------------------------------------------------------------------
1 | .fade-motion(@className, @keyframeName) {
2 | .make-motion(@className, @keyframeName);
3 | .@{className}-enter, .@{className}-appear {
4 | opacity: 0;
5 | animation-timing-function: linear;
6 | }
7 | .@{className}-leave {
8 | animation-timing-function: linear;
9 | }
10 | }
11 |
12 | .fade-motion(fade, ivuFade);
13 |
14 | @keyframes ivuFadeIn {
15 | 0% {
16 | opacity: 0;
17 | }
18 | 100% {
19 | opacity: 1;
20 | }
21 | }
22 |
23 | @keyframes ivuFadeOut {
24 | 0% {
25 | opacity: 1;
26 | }
27 | 100% {
28 | opacity: 0;
29 | }
30 | }
--------------------------------------------------------------------------------
/src/renderer/assets/my-theme/components/dropdown.less:
--------------------------------------------------------------------------------
1 | @dropdown-prefix-cls: ~"@{css-prefix}dropdown";
2 | @dropdown-item-prefix-cls: ~"@{dropdown-prefix-cls}-item";
3 |
4 | .@{dropdown-prefix-cls} {
5 | display: inline-block;
6 | //position: relative;
7 |
8 | .@{select-dropdown-prefix-cls} {
9 | overflow: visible;
10 | max-height: none;
11 | }
12 | .@{dropdown-prefix-cls} {
13 | width: 100%;
14 | }
15 |
16 | &-rel{
17 | display: inline-block;
18 | position: relative;
19 | }
20 |
21 | &-menu{
22 | min-width: 100px;
23 | }
24 | }
25 |
26 | .select-item(@dropdown-prefix-cls, @dropdown-item-prefix-cls);
--------------------------------------------------------------------------------
/src/renderer/components/Page/Auth.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
17 |
18 |
19 |
33 |
--------------------------------------------------------------------------------
/src/renderer/assets/my-theme/components/back-top.less:
--------------------------------------------------------------------------------
1 | @backtop-prefix-cls: ~"@{css-prefix}back-top";
2 |
3 | .@{backtop-prefix-cls} {
4 | z-index: @zindex-back-top;
5 | position: fixed;
6 | cursor: pointer;
7 | display: none;
8 |
9 | &.@{backtop-prefix-cls}-show {
10 | display: block;
11 | }
12 |
13 | &-inner {
14 | background-color: rgba(0,0,0,.6);
15 | border-radius: 2px;
16 | box-shadow: 0 1px 3px rgba(0,0,0,.2);
17 | transition: all @transition-time @ease-in-out;
18 |
19 | &:hover {
20 | background-color: rgba(0,0,0,.7);
21 | }
22 | }
23 |
24 | i{
25 | color: #fff;
26 | font-size: 24px;
27 | padding: 8px 12px;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/renderer/assets/my-theme/animation/index.less:
--------------------------------------------------------------------------------
1 | .motion-common() {
2 | animation-duration: @animation-time;
3 | animation-fill-mode: both;
4 | }
5 |
6 | .make-motion(@className, @keyframeName) {
7 | .@{className}-enter, .@{className}-appear {
8 | .motion-common();
9 | animation-play-state: paused;
10 | }
11 | .@{className}-leave {
12 | .motion-common();
13 | animation-play-state: paused;
14 | }
15 | .@{className}-enter, .@{className}-appear {
16 | animation-name: ~"@{keyframeName}In";
17 | animation-play-state: running;
18 | }
19 | .@{className}-leave {
20 | animation-name: ~"@{keyframeName}Out";
21 | animation-play-state: running;
22 | }
23 | }
24 |
25 | @import "fade";
26 | @import "move";
27 | @import "ease";
28 | @import "slide";
--------------------------------------------------------------------------------
/src/renderer/assets/my-theme/mixins/breadcrumb.less:
--------------------------------------------------------------------------------
1 | @breadcrumb-prefix-cls: ~"@{css-prefix}breadcrumb";
2 |
3 | .@{breadcrumb-prefix-cls} {
4 | color: #999;
5 | font-size: @font-size-base;
6 |
7 | a {
8 | color: @text-color;
9 | transition: color @transition-time @ease-in-out;
10 | &:hover {
11 | color: tint(@primary-color, 20%);
12 | }
13 | }
14 |
15 | & > span:last-child {
16 | font-weight: bold;
17 | color: @text-color;
18 | }
19 |
20 | & > span:last-child &-item-separator {
21 | display: none;
22 | }
23 |
24 | &-item-separator {
25 | margin: 0 8px;
26 | color: @border-color-base;
27 | }
28 |
29 | &-item-link {
30 | > .ivu-icon + span {
31 | margin-left: 4px;
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/renderer/assets/my-theme/mixins/common.less:
--------------------------------------------------------------------------------
1 | .placeholder(@color: @input-placeholder-color) {
2 | // Firefox
3 | &::-moz-placeholder {
4 | color: @color;
5 | opacity: 1; // Override Firefox's unusual default opacity; see https://github.com/twbs/bootstrap/pull/11526
6 | }
7 | // Internet Explorer 10+
8 | &:-ms-input-placeholder {
9 | color: @color;
10 | }
11 | // Safari and Chrome
12 | &::-webkit-input-placeholder {
13 | color: @color;
14 | }
15 | }
16 |
17 | // for select and input like component's arrow
18 | .inner-arrow() {
19 | position: absolute;
20 | top: 50%;
21 | right: 8px;
22 | line-height: 1;
23 | margin-top: -7px;
24 | font-size: @font-size-base;
25 | color: @subsidiary-color;
26 | transition: all @transition-time @ease-in-out;
27 | }
28 |
--------------------------------------------------------------------------------
/src/renderer/assets/my-theme/mixins/caret.less:
--------------------------------------------------------------------------------
1 | // sortable
2 | .sortable() {
3 | display: inline-block;
4 | width: 9px;
5 | height: 12px;
6 | margin-left: 4px;
7 | margin-top: -1px;
8 | vertical-align: middle;
9 | overflow: hidden;
10 | cursor: pointer;
11 | position: relative;
12 |
13 | i {
14 | display: block;
15 | height: 6px;
16 | line-height: 6px;
17 | overflow: hidden;
18 | position: absolute;
19 | color: @btn-disable-color;
20 | transition: color @transition-time @ease-in-out;
21 |
22 | &:hover{
23 | color: inherit;
24 | }
25 |
26 | &.on{
27 | color: @primary-color;
28 | }
29 |
30 | &:first-child{
31 | top: 0;
32 | }
33 | &:last-child{
34 | bottom: 0;
35 | }
36 | }
37 | }
--------------------------------------------------------------------------------
/src/renderer/assets/my-theme/animation/ease.less:
--------------------------------------------------------------------------------
1 | .ease-motion(@className, @keyframeName) {
2 | .make-motion(@className, @keyframeName);
3 | .@{className}-enter, .@{className}-appear {
4 | opacity: 0;
5 | animation-timing-function: linear;
6 | animation-duration: @transition-time;
7 | }
8 | .@{className}-leave {
9 | animation-timing-function: linear;
10 | animation-duration: @transition-time;
11 | }
12 | }
13 |
14 | .ease-motion(ease, ivuEase);
15 |
16 | @keyframes ivuEaseIn {
17 | 0% {
18 | opacity: 0;
19 | transform: scale(0.9);
20 | }
21 | 100% {
22 | opacity: 1;
23 | transform: scale(1);
24 | }
25 | }
26 |
27 | @keyframes ivuEaseOut {
28 | 0% {
29 | opacity: 1;
30 | transform: scale(1);
31 | }
32 | 100% {
33 | opacity: 0;
34 | transform: scale(0.9);
35 | }
36 | }
--------------------------------------------------------------------------------
/src/main/index.dev.js:
--------------------------------------------------------------------------------
1 | /**
2 | * This file is used specifically and only for development. It installs
3 | * `electron-debug` & `vue-devtools`. There shouldn't be any need to
4 | * modify this file, but it can be used to extend your development
5 | * environment.
6 | */
7 |
8 | /* eslint-disable */
9 |
10 | // Set environment for development
11 | process.env.NODE_ENV = 'development'
12 |
13 | // Install `electron-debug` with `devtron`
14 | require('electron-debug')({ showDevTools: true })
15 |
16 | // Install `vue-devtools`
17 | require('electron').app.on('ready', () => {
18 | let installExtension = require('electron-devtools-installer')
19 | installExtension.default(installExtension.VUEJS_DEVTOOLS)
20 | .then(() => {})
21 | .catch(err => {
22 | console.log('Unable to install `vue-devtools`: \n', err)
23 | })
24 | })
25 |
26 | // Require `main` process to boot app
27 | require('./index')
28 |
--------------------------------------------------------------------------------
/src/renderer/assets/my-theme/mixins/content.less:
--------------------------------------------------------------------------------
1 | @icon-prefix-cls: ~"@{css-prefix}icon";
2 |
3 | .content-header() {
4 | border-bottom: 1px solid @border-color-split;
5 | padding: 14px 16px;
6 | line-height: 1;
7 |
8 | p,
9 | &-inner
10 | {
11 | display: inline-block;
12 | width: 100%;
13 | height: 20px;
14 | line-height: 20px;
15 | font-size: @font-size-base;
16 | color: @title-color;
17 | font-weight: bold;
18 | overflow: hidden;
19 | text-overflow: ellipsis;
20 | white-space: nowrap;
21 | }
22 | }
23 |
24 | .content-close(@top: 0, @icon-font-size: 22px) {
25 | font-size: @font-size-small;
26 | position: absolute;
27 | right: 16px;
28 | top: 8px;
29 | overflow: hidden;
30 | cursor: pointer;
31 |
32 | .@{icon-prefix-cls}-ios-close-empty {
33 | .close-base(@top, @icon-font-size);
34 | }
35 | }
--------------------------------------------------------------------------------
/src/renderer/store/actions.js:
--------------------------------------------------------------------------------
1 | import * as types from './mutations_types'
2 |
3 | /**
4 | * 保存用户信息
5 | * @param {Object} data
6 | */
7 | export const setUserInfo = ({ commit }, data) => {
8 | commit(types.SET_USER_INFO, data)
9 | }
10 |
11 | /**
12 | * 保存Excel数据
13 | * @param {Object} data
14 | */
15 | export const setExcelData = ({ commit }, data) => {
16 | commit(types.SET_EXCEL_DATA, data)
17 | }
18 |
19 | /**
20 | * 添加Excel数据
21 | * @param {Array} data
22 | */
23 | export const addExcelData = ({ commit }, data) => {
24 | commit(types.ADD_EXCEL_DATA, data)
25 | }
26 |
27 | /**
28 | * 修改Excel数据
29 | * @param {Array} data
30 | */
31 | export const editExcelData = ({ commit }, data) => {
32 | commit(types.EDIT_EXCEL_DATA, data)
33 | }
34 |
35 | /**
36 | * 删除Excel数据
37 | * @param {Array} data
38 | */
39 | export const delExcelData = ({ commit }, data) => {
40 | commit(types.DEL_EXCEL_DATA, data)
41 | }
42 |
--------------------------------------------------------------------------------
/src/index.ejs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | iMap
6 |
7 | <% if (htmlWebpackPlugin.options.nodeModules) { %>
8 |
9 |
12 | <% } %>
13 |
14 |
15 |
16 |
17 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/src/renderer/assets/my-theme/components/index.less:
--------------------------------------------------------------------------------
1 | @import "button";
2 | @import "affix";
3 | @import "back-top";
4 | @import "badge";
5 | @import "circle";
6 | @import "spin";
7 | @import "alert";
8 | @import "collapse";
9 | @import "card";
10 | @import "message";
11 | @import "notice";
12 | @import "radio";
13 | @import "checkbox";
14 | @import "switch";
15 | @import "input-number";
16 | @import "tag";
17 | @import "loading-bar";
18 | @import "progress";
19 | @import "timeline";
20 | @import "page";
21 | @import "steps";
22 | @import "modal";
23 | @import "select";
24 | @import "select-dropdown";
25 | @import "tooltip";
26 | @import "poptip";
27 | @import "input";
28 | @import "slider";
29 | @import "cascader";
30 | @import "transfer";
31 | @import "table";
32 | @import "dropdown";
33 | @import "tabs";
34 | @import "menu";
35 | @import "date-picker";
36 | @import "time-picker";
37 | @import "form";
38 | @import "carousel";
39 | @import "rate";
40 | @import "upload";
41 | @import "tree";
--------------------------------------------------------------------------------
/src/renderer/assets/my-theme/common/iconfont/_ionicons-font.less:
--------------------------------------------------------------------------------
1 | // Ionicons Font Path
2 | // --------------------------
3 |
4 | @font-face {
5 | font-family: @ionicons-font-family;
6 | src:url("@{ionicons-font-path}/ionicons.eot?v=@{ionicons-version}");
7 | src:url("@{ionicons-font-path}/ionicons.eot?v=@{ionicons-version}#iefix") format("embedded-opentype"),
8 | url("@{ionicons-font-path}/ionicons.ttf?v=@{ionicons-version}") format("truetype"),
9 | url("@{ionicons-font-path}/ionicons.woff?v=@{ionicons-version}") format("woff"),
10 | url("@{ionicons-font-path}/ionicons.svg?v=@{ionicons-version}#Ionicons") format("svg");
11 | font-weight: normal;
12 | font-style: normal;
13 | }
14 |
15 | .ivu-icon() {
16 | display: inline-block;
17 | font-family: @ionicons-font-family;
18 | speak: none;
19 | font-style: normal;
20 | font-weight: normal;
21 | font-variant: normal;
22 | text-transform: none;
23 | text-rendering: auto;
24 | line-height: 1;
25 | -webkit-font-smoothing: antialiased;
26 | -moz-osx-font-smoothing: grayscale;
27 | }
28 |
29 | .ivu-icon {
30 | .ivu-icon();
31 | }
--------------------------------------------------------------------------------
/src/renderer/assets/my-theme/components/tooltip.less:
--------------------------------------------------------------------------------
1 | @tooltip-prefix-cls: ~"@{css-prefix}tooltip";
2 | @tooltip-arrow: ~"@{tooltip-prefix-cls}-arrow";
3 | @tooltip-max-width: 250px;
4 | @tooltip-arrow-width: 5px;
5 | @tooltip-distance: @tooltip-arrow-width - 1 + 4;
6 |
7 | .@{tooltip-prefix-cls} {
8 | display: inline-block;
9 |
10 | &-rel{
11 | display: inline-block;
12 | position: relative;
13 | }
14 |
15 | &-popper{
16 | .popper(@tooltip-arrow, @tooltip-arrow-width, @tooltip-distance, @tooltip-bg);
17 | }
18 |
19 | &-inner{
20 | max-width: @tooltip-max-width;
21 | min-height: 34px;
22 | padding: 8px 12px;
23 | color: @tooltip-color;
24 | text-align: left;
25 | text-decoration: none;
26 | background-color: @tooltip-bg;
27 | border-radius: @border-radius-small;
28 | box-shadow: @shadow-base;
29 | white-space: nowrap;
30 | }
31 |
32 | &-arrow{
33 | position: absolute;
34 | width: 0;
35 | height: 0;
36 | border-color: transparent;
37 | border-style: solid;
38 | }
39 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2017-present iMap
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/.electron-vue/dev-client.js:
--------------------------------------------------------------------------------
1 | const hotClient = require('webpack-hot-middleware/client?noInfo=true&reload=true')
2 |
3 | hotClient.subscribe(event => {
4 | /**
5 | * Reload browser when HTMLWebpackPlugin emits a new index.html
6 | */
7 | if (event.action === 'reload') {
8 | window.location.reload()
9 | }
10 |
11 | /**
12 | * Notify `mainWindow` when `main` process is compiling,
13 | * giving notice for an expected reload of the `electron` process
14 | */
15 | if (event.action === 'compiling') {
16 | document.body.innerHTML += `
17 |
30 |
31 |
32 | Compiling Main Process...
33 |
34 | `
35 | }
36 | })
37 |
--------------------------------------------------------------------------------
/src/renderer/assets/my-theme/components/card.less:
--------------------------------------------------------------------------------
1 | @card-prefix-cls: ~"@{css-prefix}card";
2 |
3 | .@{card-prefix-cls}{
4 | background: #fff;
5 | border-radius: @border-radius-small;
6 | font-size: @font-size-base;
7 | position: relative;
8 | //overflow: hidden;
9 | transition: all @transition-time @ease-in-out;
10 |
11 | &-bordered {
12 | border: 1px solid @border-color-base;
13 | border-color: @border-color-split;
14 | }
15 |
16 | &-shadow{
17 | box-shadow: @shadow-card;
18 | }
19 |
20 | &:hover {
21 | box-shadow: @shadow-base;
22 | border-color: #eee;
23 | }
24 | &&-dis-hover:hover{
25 | box-shadow: none;
26 | border-color: transparent;
27 | }
28 |
29 | &&-dis-hover&-bordered:hover{
30 | border-color: @border-color-split;
31 | }
32 |
33 | &&-shadow:hover{
34 | box-shadow: @shadow-card;
35 | }
36 |
37 | &-head {
38 | .content-header;
39 | }
40 |
41 | &-extra {
42 | position: absolute;
43 | right: 16px;
44 | top: 14px;
45 | }
46 |
47 | &-body {
48 | padding: 16px;
49 | }
50 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # iMap
2 |
3 | 
4 |
5 | 开源
6 |
7 | 跨平台(MacOS,Linux,Windows)
8 |
9 | 一款基于electron和Echarts的旅行地图生成器
10 |
11 | [](https://github.com/HuangXiZhou/iMap/releases)
12 |
13 | ## 下载
14 | [MacOS](https://github.com/HuangXiZhou/iMap/releases/download/0.0.2-beta/iMap-0.0.2-beta-mac.zip)
15 | [Windows](https://github.com/HuangXiZhou/iMap/releases/download/0.0.2-beta/iMap-0.0.2-beta-win32.zip)
16 | [Linux](https://github.com/HuangXiZhou/iMap/releases/download/0.0.2-beta/iMap-0.0.2-beta-linux.zip)
17 |
18 | ###### 你可以在 [github.com/HuangXiZhou/iMap/releases](https://github.com/HuangXiZhou/iMap/releases) 上浏览全部的releases
19 |
20 | ## 启动项目
21 | ```bash
22 | #install dependencies
23 | yarn
24 |
25 | #serve with hot reload at localhost:8090
26 | yarn run dev
27 |
28 | #build for production(mas, darwin, win32, linux)
29 | npm run build
30 | ```
31 |
32 | ## 更新日志
33 | 0.0.3-Beta
34 |
35 | * 修复若干bug
36 | * 暂时移除应用内更新
37 | * 添加海外城市坐标支持
38 | * 支持地图放大、拖动
39 |
40 | ## 下版本更新
41 | * 集成旅行日记
42 | * 添加海外国家地图
43 |
44 | ## 求一份工作
45 | [我的简历](https://huangxizhou.com/resume)
46 |
47 | ## License
48 | [MIT](https://opensource.org/licenses/MIT)
49 |
50 | Copyright © 2017-present, Trevor
51 |
--------------------------------------------------------------------------------
/src/main/index.js:
--------------------------------------------------------------------------------
1 | import { app, BrowserWindow } from 'electron'
2 |
3 | /**
4 | * Set `__static` path to static files in production
5 | * https://simulatedgreg.gitbooks.io/electron-vue/content/en/using-static-assets.html
6 | */
7 | if (process.env.NODE_ENV !== 'development') {
8 | global.__static = require('path').join(__dirname, '/static').replace(/\\/g, '\\\\')
9 | }
10 |
11 | let mainWindow
12 | const winURL = process.env.NODE_ENV === 'development'
13 | ? `http://localhost:9080`
14 | : `file://${__dirname}/index.html`
15 |
16 | function createWindow () {
17 | /**
18 | * Initial window options
19 | */
20 | mainWindow = new BrowserWindow({
21 | show: false,
22 | height: 563,
23 | useContentSize: true,
24 | width: 1000,
25 | resizable: false,
26 | fullscreen: false,
27 | fullscreenable: false
28 | })
29 |
30 | mainWindow.loadURL(winURL)
31 |
32 | mainWindow.on('ready-to-show', function() {
33 | mainWindow.show();
34 | mainWindow.focus();
35 | });
36 |
37 | mainWindow.on('closed', () => {
38 | mainWindow = null
39 | })
40 | }
41 |
42 | app.on('ready', createWindow)
43 |
44 | app.on('window-all-closed', () => {
45 | if (process.platform !== 'darwin') {
46 | app.quit()
47 | }
48 | })
49 |
50 | app.on('activate', () => {
51 | if (mainWindow === null) {
52 | createWindow()
53 | }
54 | })
55 |
--------------------------------------------------------------------------------
/src/renderer/assets/my-theme/components/message.less:
--------------------------------------------------------------------------------
1 | @message-prefix-cls: ~"@{css-prefix}message";
2 | @icon-prefix-cls: ~"@{css-prefix}icon";
3 |
4 | .@{message-prefix-cls} {
5 | font-size: @font-size-small;
6 | position: fixed;
7 | z-index: @zindex-message;
8 | width: 100%;
9 | top: 16px;
10 | left: 0;
11 |
12 | &-notice {
13 | width: auto;
14 | vertical-align: middle;
15 | position: absolute;
16 | left: 50%;
17 | }
18 |
19 | &-notice-content {
20 | position: relative;
21 | right: 50%;
22 | padding: 8px 16px;
23 | //border: 1px solid @border-color-split;
24 | border-radius: @border-radius-small;
25 | box-shadow: @shadow-base;
26 | background: #fff;
27 | display: block;
28 | }
29 |
30 | &-success .@{icon-prefix-cls} {
31 | color: @success-color;
32 | }
33 |
34 | &-error .@{icon-prefix-cls} {
35 | color: @error-color;
36 | }
37 |
38 | &-warning .@{icon-prefix-cls} {
39 | color: @warning-color;
40 | }
41 |
42 | &-info .@{icon-prefix-cls},
43 | &-loading .@{icon-prefix-cls} {
44 | color: @primary-color;
45 | }
46 |
47 | .@{icon-prefix-cls} {
48 | margin-right: 8px;
49 | font-size: 14px;
50 | top: 1px;
51 | position: relative;
52 | }
53 | }
--------------------------------------------------------------------------------
/src/renderer/store/modules/excel.js:
--------------------------------------------------------------------------------
1 | import * as types from '../mutations_types'
2 | import _ from 'lodash'
3 |
4 | // state
5 | const state = {
6 | excelData: {}
7 | }
8 |
9 | // mutations
10 | const mutations = {
11 | // 设置excelData
12 | [types.SET_EXCEL_DATA] (state, data) {
13 | if(data.data)
14 | state.excelData = data
15 | else {
16 | state.excelData.data = []
17 | state.excelData.data.length = 0
18 | state.excelData.data.push(data)
19 | }
20 | },
21 | // 添加excelData
22 | [types.ADD_EXCEL_DATA] (state, data) {
23 | state.excelData.data.push(data)
24 | },
25 | // 修改excelData
26 | [types.EDIT_EXCEL_DATA] (state, data) {
27 | let newArr = state.excelData.data.map((item, idx) => {
28 | if(item[0] === data[0]) {
29 | item[1] = data[1]
30 | item[2] = data[2]
31 | item[3] = data[3]
32 | }
33 | if(item[1] === data[1] && item[2] === data[2]) {
34 | item[0] = data[0]
35 | }
36 | return item
37 | })
38 | state.excelData.data = newArr
39 | },
40 | // 删除excelData
41 | [types.DEL_EXCEL_DATA] (state, data) {
42 | let newArr = _.remove(state.excelData.data, n => {
43 | return n[0] !== data[0]
44 | })
45 | state.excelData.data = newArr
46 | },
47 | }
48 |
49 | // 导出state, mutations
50 | export default {
51 | state,
52 | mutations
53 | }
54 |
--------------------------------------------------------------------------------
/src/renderer/assets/my-theme/common/article.less:
--------------------------------------------------------------------------------
1 | .ivu-article {
2 | h1{
3 | font-size: 26px;
4 | font-weight: normal;
5 | }
6 | h2{
7 | font-size: 20px;
8 | font-weight: normal;
9 | }
10 | h3{
11 | font-size: 16px;
12 | font-weight: normal;
13 | }
14 | h4{
15 | font-size: 14px;
16 | font-weight: normal;
17 | }
18 | h5{
19 | font-size: 12px;
20 | font-weight: normal;
21 | }
22 | h6{
23 | font-size: 12px;
24 | font-weight: normal;
25 | }
26 |
27 | blockquote{
28 | padding: 5px 5px 3px 10px;
29 | line-height: 1.5;
30 | border-left: 4px solid #ddd;
31 | margin-bottom: 20px;
32 | color: #666;
33 | font-size: 14px;
34 | }
35 |
36 | ul:not([class^="ivu-"]){
37 | padding-left: 40px;
38 | list-style-type: disc;
39 | }
40 | li:not([class^="ivu-"]){
41 | margin-bottom: 5px;
42 | font-size: 14px;
43 | }
44 | ul ul:not([class^="ivu-"]), ol ul:not([class^="ivu-"]){
45 | list-style-type: circle;
46 | }
47 |
48 | p{
49 | margin: 5px;
50 | font-size: 14px;
51 | }
52 |
53 | a[target="_blank"]:after{
54 | content: "\F220";
55 | font-family: Ionicons;
56 | color: #aaa;
57 | margin-left: 3px;
58 | }
59 | }
--------------------------------------------------------------------------------
/src/renderer/assets/my-theme/components/collapse.less:
--------------------------------------------------------------------------------
1 | @collapse-prefix-cls: ~"@{css-prefix}collapse";
2 |
3 | .@{collapse-prefix-cls}{
4 | background-color: @background-color-base;
5 | border-radius: 3px;
6 | border: 1px solid @border-color-base;
7 |
8 | & > &-item{
9 | border-top: 1px solid @border-color-base;
10 | &:first-child {
11 | border-top: 0;
12 | }
13 |
14 | > .@{collapse-prefix-cls}-header{
15 | height: 38px;
16 | line-height: 38px;
17 | padding-left: 32px;
18 | color: #666;
19 | cursor: pointer;
20 | position: relative;
21 |
22 | > i{
23 | transition: transform @transition-time @ease-in-out;
24 | }
25 | }
26 | }
27 | & > &-item&-item-active > &-header > i{
28 | transform: rotate(90deg);
29 | }
30 |
31 | &-content{
32 | //display: none;
33 | overflow: hidden;
34 | color: @text-color;
35 | padding: 0 16px;
36 | background-color: #fff;
37 |
38 | & > &-box {
39 | padding-top: 16px;
40 | padding-bottom: 16px;
41 | }
42 | }
43 | &-item-active > &-content{
44 | //display: block;
45 | }
46 | &-item:last-child {
47 | > .@{collapse-prefix-cls}-content {
48 | border-radius: 0 0 3px 3px;
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/renderer/components/Page/Map.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
中国地图
7 |
![china]()
8 |
9 |
10 |
世界地图
11 |
![word]()
12 |
13 |
14 |
15 |
16 |
17 |
18 |
36 |
37 |
38 |
60 |
--------------------------------------------------------------------------------
/src/renderer/assets/my-theme/components/badge.less:
--------------------------------------------------------------------------------
1 | @badge-prefix-cls: ~"@{css-prefix}badge";
2 |
3 | .@{badge-prefix-cls} {
4 | position: relative;
5 | display: inline-block;
6 | line-height: 1;
7 | vertical-align: middle;
8 |
9 | &-count {
10 | position: absolute;
11 | transform: translateX(50%);
12 | top: -10px;
13 | right: 0;
14 | height: 20px;
15 | border-radius: 10px;
16 | min-width: 20px;
17 | background: @error-color;
18 | border: 1px solid transparent;
19 | color: #fff;
20 | line-height: 18px;
21 | text-align: center;
22 | padding: 0 6px;
23 | font-size: 12px;
24 | white-space: nowrap;
25 | transform-origin: -10% center;
26 | z-index: 10;
27 | box-shadow: 0 0 0 1px #fff;
28 |
29 | a,
30 | a:hover {
31 | color: #fff;
32 | }
33 |
34 | &-alone {
35 | top: auto;
36 | display: block;
37 | position: relative;
38 | transform: translateX(0);
39 | }
40 | }
41 |
42 | &-dot {
43 | position: absolute;
44 | transform: translateX(-50%);
45 | transform-origin: 0 center;
46 | top: -4px;
47 | right: -8px;
48 | height: 8px;
49 | width: 8px;
50 | border-radius: 100%;
51 | background: @error-color;
52 | z-index: 10;
53 | box-shadow: 0 0 0 1px #fff;
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/renderer/assets/my-theme/components/spin.less:
--------------------------------------------------------------------------------
1 | @spin-prefix-cls: ~"@{css-prefix}spin";
2 | @spin-dot-size-small: 12px;
3 | @spin-dot-size: 20px;
4 | @spin-dot-size-large: 32px;
5 |
6 | .@{spin-prefix-cls} {
7 | color: @primary-color;
8 | vertical-align: middle;
9 | text-align: center;
10 |
11 | &-dot {
12 | position: relative;
13 | display: block;
14 | border-radius: 50%;
15 | background-color: @primary-color;
16 | .square(@spin-dot-size);
17 | animation: ani-spin-bounce 1s 0s ease-in-out infinite;
18 | }
19 |
20 | &-large &-dot {
21 | .square(@spin-dot-size-large);
22 | }
23 |
24 | &-small &-dot {
25 | .square(@spin-dot-size-small);
26 | }
27 |
28 | &-fix {
29 | position: absolute;
30 | top: 0;
31 | bottom: 0;
32 | left: 0;
33 | right: 0;
34 | z-index: @zindex-spin;
35 | display: table;
36 | .square(100%);
37 | background-color: #fff;
38 | }
39 |
40 | &-fix &-main {
41 | display: table-cell;
42 | vertical-align: middle;
43 | .square(inherit);
44 | }
45 |
46 | &-fix &-dot {
47 | display: inline-block;
48 | }
49 |
50 | &-text,
51 | &-show-text &-dot {
52 | display: none;
53 | }
54 |
55 | &-show-text &-text {
56 | display: block;
57 | }
58 | }
59 |
60 | @keyframes ani-spin-bounce {
61 | 0% {
62 | transform: scale(0);
63 | }
64 |
65 | 100% {
66 | transform: scale(1);
67 | opacity: 0;
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/src/renderer/assets/my-theme/components/input.less:
--------------------------------------------------------------------------------
1 | @input-prefix-cls: ~"@{css-prefix}input";
2 |
3 | .@{input-prefix-cls} {
4 | .input;
5 | &-wrapper{
6 | display: inline-block;
7 | width: 100%;
8 | position: relative;
9 | vertical-align: middle;
10 | }
11 | &-icon {
12 | width: 32px;
13 | height: @input-height-base;
14 | line-height: @input-height-base;
15 | font-size: 16px;
16 | text-align: center;
17 | color: @subsidiary-color;
18 | position: absolute;
19 | right: 0;
20 | z-index: 1;
21 | }
22 | &-icon-validate{
23 | display: none;
24 | }
25 |
26 | &-icon + &{
27 | padding-right: 32px;
28 | }
29 |
30 | &-wrapper-large &-icon{
31 | font-size: 18px;
32 | height: @input-height-large;
33 | line-height: @input-height-large;
34 | }
35 | &-wrapper-small &-icon{
36 | width: 24px;
37 | font-size: 14px;
38 | height: @input-height-small;
39 | line-height: @input-height-small;
40 |
41 | + .@{input-prefix-cls} {
42 | padding-right: 24px;
43 | }
44 | }
45 | }
46 |
47 | .@{input-prefix-cls}-group{
48 | .input-group(~"@{input-prefix-cls}");
49 | }
50 |
51 | .@{form-item-prefix-cls}-error{
52 | .@{input-prefix-cls}{
53 | .input-error;
54 | &-icon{
55 | color: @error-color;
56 | }
57 | }
58 | .@{input-prefix-cls}-group{
59 | .input-group-error;
60 | }
61 | }
62 | .@{form-item-prefix-cls}-validating{
63 | .@{input-prefix-cls}{
64 | &-icon-validate{
65 | display: inline-block;
66 | }
67 | }
68 | }
--------------------------------------------------------------------------------
/src/renderer/assets/my-theme/custom.css:
--------------------------------------------------------------------------------
1 | .ivu-menu-horizontal {
2 | height: 51px;
3 | line-height: 51px;
4 | }
5 | .ivu-menu-horizontal .ivu-menu-item,
6 | .ivu-menu-horizontal .ivu-menu-submenu {
7 | float: right;
8 | }
9 | .ivu-select-dropdown {
10 | background-color: #262529;
11 | }
12 | .ivu-menu-horizontal {
13 | height: 51px;
14 | line-height: 51px;
15 | }
16 | .ivu-menu-horizontal .ivu-menu-item,
17 | .ivu-menu-horizontal .ivu-menu-submenu {
18 | float: right;
19 | }
20 | .ivu-select-dropdown {
21 | background-color: #262529;
22 | }
23 | .ivu-input {
24 | border: none;
25 | }
26 | .ivu-input {
27 | margin-bottom: 12px;
28 | }
29 | .ivu-input:hover {
30 | border: none;
31 | background-color: #131414;
32 | }
33 | .ivu-input:focus {
34 | background: #131414;
35 | }
36 | .ivu-icon.ivu-icon-android-map {
37 | margin-right: 10px;
38 | }
39 | .ivu-input-group {
40 | margin-bottom: 12px;
41 | margin-left: auto;
42 | margin-right: auto;
43 | }
44 | .ivu-input-group-append {
45 | background-color: #1E1E21;
46 | }
47 | .ivu-select-selection {
48 | border: 0;
49 | background-color: #222222;
50 | }
51 | .ivu-select-single .ivu-select-selection {
52 | border: 0;
53 | background-color: #222222;
54 | }
55 | .ivu-spin-large .ivu-spin-dot {
56 | width: 55px;
57 | height: 55px;
58 | }
59 | .ivu-spin-dot {
60 | position: fixed;
61 | top: 42%;
62 | left: 48%;
63 | transform: translate(-50%, -50%);
64 | background-color: #ff3300;
65 | }
66 | .ivu-spin-fix {
67 | opacity: .9;
68 | background-color: #222222;
69 | }
70 | .ivu-modal-content {
71 | background-color: #1D1C1F;
72 | }
73 | .ivu-modal-header {
74 | border-bottom: 0;
75 | }
76 | .ivu-modal-footer {
77 | border-top: 0;
78 | }
79 |
--------------------------------------------------------------------------------
/src/renderer/assets/my-theme/common/base.less:
--------------------------------------------------------------------------------
1 | @import "normalize";
2 |
3 | * {
4 | box-sizing: border-box;
5 | -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
6 | }
7 |
8 | *:before,
9 | *:after {
10 | box-sizing: border-box;
11 | }
12 |
13 | body {
14 | font-family: @font-family;
15 | font-size: @font-size-small;
16 | line-height: @line-height-base;
17 | color: @text-color;
18 | background-color: @body-background;
19 | -webkit-font-smoothing: antialiased;
20 | -moz-osx-font-smoothing: grayscale;
21 | }
22 |
23 | body, div, dl, dt, dd, ul, ol, li, h1, h2, h3, h4, h5, h6, form, fieldset, legend, input, textarea, p, blockquote, th, td, hr, button, article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section {
24 | margin: 0;
25 | padding: 0;
26 | }
27 |
28 | button, input, select, textarea {
29 | font-family: inherit;
30 | font-size: inherit;
31 | line-height: inherit;
32 | }
33 |
34 | ul,
35 | ol {
36 | list-style: none;
37 | }
38 |
39 | input::-ms-clear, input::-ms-reveal {
40 | display: none;
41 | }
42 |
43 | a {
44 | color: @link-color;
45 | background: transparent;
46 | text-decoration: none;
47 | outline: none;
48 | cursor: pointer;
49 | transition: color @transition-time ease;
50 |
51 | &:hover {
52 | color: @link-hover-color;
53 | }
54 |
55 | &:active {
56 | color: @link-active-color;
57 | }
58 |
59 | &:active,
60 | &:hover {
61 | outline: 0;
62 | text-decoration: none;
63 | }
64 |
65 | &[disabled] {
66 | color: #ccc;
67 | cursor: @cursor-disabled;
68 | pointer-events: none;
69 | }
70 | }
71 |
72 | code,
73 | kbd,
74 | pre,
75 | samp {
76 | font-family: @code-family;
77 | }
78 |
--------------------------------------------------------------------------------
/src/renderer/assets/my-theme/mixins/select.less:
--------------------------------------------------------------------------------
1 | .select-item(@size-class, @item-class) {
2 | .@{item-class} {
3 | margin: 0;
4 | padding: 7px 16px;
5 | clear: both;
6 | color: @text-color;
7 | font-size: @font-size-small !important;
8 | white-space: nowrap;
9 | list-style: none;
10 | cursor: pointer;
11 | transition: background @transition-time @ease-in-out;
12 |
13 | &:hover{
14 | background: @background-color-select-hover;
15 | }
16 |
17 | &-focus {
18 | background: @background-color-select-hover;
19 | }
20 |
21 | &-disabled {
22 | color: @btn-disable-color;
23 | cursor: @cursor-disabled;
24 |
25 | &:hover {
26 | color: @btn-disable-color;
27 | background-color: #fff;
28 | cursor: @cursor-disabled;
29 | }
30 | }
31 |
32 | &-selected ,&-selected:hover{
33 | color: #fff;
34 | background: @selected-color;
35 | }
36 |
37 | &-selected&-focus {
38 | background: shade(@selected-color, 10%);
39 | }
40 |
41 | &-divided{
42 | margin-top: 5px;
43 | border-top: 1px solid @border-color-split;
44 | &:before{
45 | content: '';
46 | height: 5px;
47 | display: block;
48 | margin: 0 -16px;
49 | background-color: #fff;
50 | position: relative;
51 | top: -7px;
52 | }
53 | }
54 | }
55 |
56 | .@{size-class}-large .@{item-class} {
57 | padding: 7px 16px 8px;
58 | font-size: @font-size-base !important;
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/.electron-vue/webpack.main.config.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | process.env.BABEL_ENV = 'main'
4 |
5 | const path = require('path')
6 | const { dependencies } = require('../package.json')
7 | const webpack = require('webpack')
8 |
9 | const BabiliWebpackPlugin = require('babili-webpack-plugin')
10 |
11 | let mainConfig = {
12 | entry: {
13 | main: path.join(__dirname, '../src/main/index.js')
14 | },
15 | externals: [
16 | ...Object.keys(dependencies || {})
17 | ],
18 | module: {
19 | rules: [
20 | {
21 | test: /\.js$/,
22 | use: 'babel-loader',
23 | exclude: /node_modules/
24 | },
25 | {
26 | test: /\.node$/,
27 | use: 'node-loader'
28 | }
29 | ]
30 | },
31 | node: {
32 | __dirname: process.env.NODE_ENV !== 'production',
33 | __filename: process.env.NODE_ENV !== 'production'
34 | },
35 | output: {
36 | filename: '[name].js',
37 | libraryTarget: 'commonjs2',
38 | path: path.join(__dirname, '../dist/electron')
39 | },
40 | plugins: [
41 | new webpack.NoEmitOnErrorsPlugin()
42 | ],
43 | resolve: {
44 | extensions: ['.js', '.json', '.node']
45 | },
46 | target: 'electron-main'
47 | }
48 |
49 | /**
50 | * Adjust mainConfig for development settings
51 | */
52 | if (process.env.NODE_ENV !== 'production') {
53 | mainConfig.plugins.push(
54 | new webpack.DefinePlugin({
55 | '__static': `"${path.join(__dirname, '../static').replace(/\\/g, '\\\\')}"`
56 | })
57 | )
58 | }
59 |
60 | /**
61 | * Adjust mainConfig for production settings
62 | */
63 | if (process.env.NODE_ENV === 'production') {
64 | mainConfig.plugins.push(
65 | new BabiliWebpackPlugin(),
66 | new webpack.DefinePlugin({
67 | 'process.env.NODE_ENV': '"production"'
68 | })
69 | )
70 | }
71 |
72 | module.exports = mainConfig
73 |
--------------------------------------------------------------------------------
/src/renderer/assets/my-theme/components/rate.less:
--------------------------------------------------------------------------------
1 | @rate-prefix-cls: ~"@{css-prefix}rate";
2 |
3 | .@{rate-prefix-cls} {
4 | display: inline-block;
5 | margin: 0;
6 | padding: 0;
7 | font-size: 20px;
8 | vertical-align: middle;
9 | font-weight: normal;
10 | font-style: normal;
11 |
12 | &-disabled &-star {
13 | &:before,
14 | &-content:before {
15 | cursor: default;
16 | }
17 | &:hover {
18 | transform: scale(1);
19 | }
20 | }
21 |
22 | &-star {
23 | display: inline-block;
24 | margin: 0;
25 | padding: 0;
26 | margin-right: 8px;
27 | position: relative;
28 | font-family: 'Ionicons';
29 | transition: all 0.3s ease;
30 |
31 | &:hover {
32 | transform: scale(1.1);
33 | }
34 |
35 | &:before,
36 | &-content:before {
37 | color: #e9e9e9;
38 | cursor: pointer;
39 | content: "\F4B3";
40 | transition: all @transition-time @ease-in-out;
41 | display: block;
42 | }
43 |
44 | &-content {
45 | position: absolute;
46 | left: 0;
47 | top: 0;
48 | width: 50%;
49 | height: 100%;
50 | overflow: hidden;
51 | &:before {
52 | color: transparent;
53 | }
54 | }
55 |
56 | &-half &-content:before,
57 | &-full:before {
58 | color: @rate-star-color;
59 | }
60 |
61 | &-half:hover &-content:before,
62 | &-full:hover:before {
63 | color: tint(@rate-star-color, 20%);
64 | }
65 | }
66 | &-text {
67 | margin-left: 8px;
68 | vertical-align: middle;
69 | display: inline-block;
70 | font-size: @font-size-small;
71 | }
72 | }
--------------------------------------------------------------------------------
/src/renderer/assets/my-theme/components/form.less:
--------------------------------------------------------------------------------
1 | @form-prefix-cls: ~"@{css-prefix}form";
2 | @form-item-prefix-cls: ~"@{form-prefix-cls}-item";
3 |
4 | .@{form-prefix-cls} {
5 | .@{form-item-prefix-cls}-label {
6 | text-align: right;
7 | vertical-align: middle;
8 | float: left;
9 | font-size: @font-size-small;
10 | color: @text-color;
11 | line-height: 1;
12 | padding: 10px 12px 10px 0;
13 | box-sizing: border-box;
14 | }
15 | &-label-left .@{form-item-prefix-cls}-label {
16 | text-align: left;
17 | }
18 | &-label-top .@{form-item-prefix-cls}-label {
19 | float: none;
20 | display: inline-block;
21 | padding: 0 0 10px 0;
22 | }
23 | &-inline{
24 | .@{form-item-prefix-cls} {
25 | display: inline-block;
26 | margin-right: 10px;
27 | vertical-align: top;
28 | }
29 | }
30 | }
31 |
32 | .@{form-item-prefix-cls} {
33 | margin-bottom: 24px;
34 | vertical-align: top;
35 | .clearfix();
36 | &-content {
37 | position: relative;
38 | line-height: 32px;
39 | font-size: @font-size-small;
40 | }
41 | & & {
42 | margin-bottom: 0;
43 | }
44 | & & &-content {
45 | margin-left: 0!important;
46 | }
47 |
48 | &-error-tip{
49 | position: absolute;
50 | top: 100%;
51 | left: 0;
52 | line-height: 1;
53 | padding-top: 6px;
54 | color: @error-color;
55 | }
56 |
57 | &-required {
58 | .@{form-item-prefix-cls}-label:before {
59 | content: '*';
60 | display: inline-block;
61 | margin-right: 4px;
62 | line-height: 1;
63 | font-family: SimSun;
64 | font-size: @font-size-small;
65 | color: @error-color;
66 | }
67 | }
68 | &-error {
69 | // todo
70 | }
71 | }
--------------------------------------------------------------------------------
/src/renderer/assets/my-theme/common/layout.less:
--------------------------------------------------------------------------------
1 | .@{row-prefix-cls} {
2 | .make-row();
3 | display: block;
4 |
5 | &-flex {
6 | display: flex;
7 | flex-direction: row;
8 | flex-wrap: wrap;
9 |
10 | &:before,
11 | &:after {
12 | display: flex;
13 | }
14 | // x轴原点
15 | &-start {
16 | justify-content: flex-start;
17 | }
18 | // x轴居中
19 | &-center {
20 | justify-content: center;
21 | }
22 | // x轴反方向
23 | &-end {
24 | justify-content: flex-end;
25 | }
26 | // x轴平分
27 | &-space-between {
28 | justify-content: space-between;
29 | }
30 | // x轴有间隔地平分
31 | &-space-around {
32 | justify-content: space-around;
33 | }
34 | // 顶部对齐
35 | &-top {
36 | align-items: flex-start;
37 | }
38 | // 居中对齐
39 | &-middle {
40 | align-items: center;
41 | }
42 | // 底部对齐
43 | &-bottom {
44 | align-items: flex-end;
45 | }
46 | };
47 | }
48 |
49 | .@{col-prefix-cls} {
50 | position: relative;
51 | display: block;
52 | }
53 |
54 | .make-grid();
55 |
56 | // Extra small grid
57 | //
58 | // Columns, offsets, pushes, and pulls for extra small devices like
59 | // smartphones.
60 |
61 | .make-grid(-xs);
62 |
63 | // Small grid
64 | //
65 | // Columns, offsets, pushes, and pulls for the small device range, from phones
66 | // to tablets.
67 |
68 | @media (min-width: @screen-sm-min) {
69 | .make-grid(-sm);
70 | }
71 |
72 |
73 | // Medium grid
74 | //
75 | // Columns, offsets, pushes, and pulls for the desktop device range.
76 |
77 | @media (min-width: @screen-md-min) {
78 | .make-grid(-md);
79 | }
80 |
81 |
82 | // Large grid
83 | //
84 | // Columns, offsets, pushes, and pulls for the large desktop device range.
85 |
86 | @media (min-width: @screen-lg-min) {
87 | .make-grid(-lg);
88 | }
89 |
--------------------------------------------------------------------------------
/src/renderer/assets/my-theme/mixins/layout.less:
--------------------------------------------------------------------------------
1 | @row-prefix-cls: ~"@{css-prefix}row";
2 | @col-prefix-cls: ~"@{css-prefix}col";
3 |
4 | .make-row(@gutter: @grid-gutter-width) {
5 | position: relative;
6 | margin-left: (@gutter / -2);
7 | margin-right: (@gutter / -2);
8 | height: auto;
9 | .clearfix;
10 | }
11 |
12 | .float-grid-columns(@class) {
13 | .col(@index) { // initial
14 | @item: ~".@{col-prefix-cls}-span@{class}-@{index}";
15 | .col((@index + 1), @item);
16 | }
17 | .col(@index, @list) when (@index =< @grid-columns) { // general
18 | @item: ~".@{col-prefix-cls}-span@{class}-@{index}";
19 | .col((@index + 1), ~"@{list}, @{item}");
20 | }
21 | .col(@index, @list) when (@index > @grid-columns) { // terminal
22 | @{list} {
23 | float: left;
24 | flex: 0 0 auto;
25 | }
26 | }
27 | .col(1); // kickstart it
28 | }
29 |
30 | .loop-grid-columns(@index, @class) when (@index > 0) {
31 | .@{col-prefix-cls}-span@{class}-@{index} {
32 | display: block;
33 | width: percentage((@index / @grid-columns));
34 | }
35 | .@{col-prefix-cls}@{class}-push-@{index} {
36 | left: percentage((@index / @grid-columns));
37 | }
38 | .@{col-prefix-cls}@{class}-pull-@{index} {
39 | right: percentage((@index / @grid-columns));
40 | }
41 | .@{col-prefix-cls}@{class}-offset-@{index} {
42 | margin-left: percentage((@index / @grid-columns));
43 | }
44 | .@{col-prefix-cls}@{class}-order-@{index} {
45 | order: @index;
46 | }
47 | .loop-grid-columns((@index - 1), @class);
48 | }
49 |
50 | .loop-grid-columns(@index, @class) when (@index = 0) {
51 | .@{col-prefix-cls}-span@{class}-@{index} {
52 | display: none;
53 | }
54 | .@{col-prefix-cls}@{class}-push-@{index} {
55 | left: auto;
56 | }
57 | .@{col-prefix-cls}@{class}-pull-@{index} {
58 | right: auto;
59 | }
60 | }
61 |
62 | .make-grid(@class: ~'') {
63 | .float-grid-columns(@class);
64 | .loop-grid-columns(@grid-columns, @class);
65 | }
--------------------------------------------------------------------------------
/src/renderer/router/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import Router from 'vue-router'
3 | import storage from 'store'
4 | import Home from '@/components/Page/Home'
5 |
6 | Vue.use(Router)
7 |
8 | const router = new Router({
9 | routes: [
10 | {
11 | path: '/',
12 | name: 'Home',
13 | component: Home,
14 | meta: { requiresAuth: true }
15 | }, {
16 | path: '/auth',
17 | name: 'Auth',
18 | component: resolve => require(['@/components/Page/Auth'], resolve),
19 | children: [
20 | {
21 | path: '/auth/login',
22 | name: 'Login',
23 | component: resolve => require(['@/components/Page/Login'], resolve)
24 | }, {
25 | path: '/auth/register',
26 | name: 'Register',
27 | component: resolve => require(['@/components/Page/Register'], resolve)
28 | }, {
29 | path: '/auth/forgetPassword',
30 | name: 'ForgetPassword',
31 | component: resolve => require(['@/components/Page/ForgetPassword'], resolve)
32 | }
33 | ]
34 | }, {
35 | path: '/chart',
36 | name: 'Chart',
37 | component: resolve => require(['@/components/Page/Chart'], resolve)
38 | }, {
39 | path: '/myProject',
40 | name: 'MyProject',
41 | component: resolve => require(['@/components/Page/MyProject'], resolve)
42 | }, {
43 | path: '/map',
44 | name: 'Map',
45 | component: resolve => require(['@/components/Page/Map'], resolve)
46 | }, {
47 | path: '/help',
48 | name: 'Help',
49 | component: resolve => require(['@/components/Page/Help'], resolve)
50 | }, {
51 | path: '*',
52 | redirect: '/'
53 | }
54 | ]
55 | })
56 |
57 | router.beforeEach((to, from, next) => {
58 | let token = storage.get('accessToken')
59 | if (to.matched.some(record => record.meta.requiresAuth)) {
60 | if (!token) {
61 | next({
62 | path: '/auth/login',
63 | query: { redirect: to.fullPath }
64 | })
65 | } else {
66 | next()
67 | }
68 | } else {
69 | next()
70 | }
71 | })
72 |
73 | export default router
74 |
--------------------------------------------------------------------------------
/src/renderer/assets/my-theme/components/progress.less:
--------------------------------------------------------------------------------
1 | @progress-prefix-cls: ~"@{css-prefix}progress";
2 |
3 | .@{progress-prefix-cls} {
4 | display: inline-block;
5 | width: 100%;
6 | font-size: @font-size-small;
7 | position: relative;
8 |
9 | &-outer {
10 | display: inline-block;
11 | width: 100%;
12 | margin-right: 0;
13 | padding-right: 0;
14 |
15 | .@{progress-prefix-cls}-show-info & {
16 | padding-right: 55px;
17 | margin-right: -55px;
18 | }
19 | }
20 |
21 | &-inner {
22 | display: inline-block;
23 | width: 100%;
24 | background-color: #f3f3f3;
25 | border-radius: 100px;
26 | vertical-align: middle;
27 | }
28 |
29 | &-bg {
30 | border-radius: 100px;
31 | background-color: @info-color;
32 | transition: all @transition-time linear;
33 | position: relative;
34 | }
35 |
36 | &-text {
37 | display: inline-block;
38 | margin-left: 5px;
39 | text-align: left;
40 | font-size: 1em;
41 | vertical-align: middle;
42 | }
43 |
44 | &-active {
45 | .@{progress-prefix-cls}-bg:before {
46 | content: '';
47 | opacity: 0;
48 | position: absolute;
49 | top: 0;
50 | left: 0;
51 | right: 0;
52 | bottom: 0;
53 | background: #fff;
54 | border-radius: 10px;
55 | animation: ivu-progress-active 2s @ease-in-out infinite;
56 | }
57 | }
58 |
59 | &-wrong {
60 | .@{progress-prefix-cls}-bg {
61 | background-color: @error-color;
62 | }
63 | .@{progress-prefix-cls}-text {
64 | color: @error-color;
65 | }
66 | }
67 |
68 | &-success {
69 | .@{progress-prefix-cls}-bg {
70 | background-color: @success-color;
71 | }
72 | .@{progress-prefix-cls}-text {
73 | color: @success-color;
74 | }
75 | }
76 | }
77 |
78 | @keyframes ivu-progress-active {
79 | 0% {
80 | opacity: .3;
81 | width: 0;
82 | }
83 | 100% {
84 | opacity: 0;
85 | width: 100%;
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/src/renderer/components/Layout/Header.vue:
--------------------------------------------------------------------------------
1 |
2 |
26 |
27 |
28 |
29 |
71 |
72 |
73 |
81 |
--------------------------------------------------------------------------------
/src/renderer/assets/my-theme/components/upload.less:
--------------------------------------------------------------------------------
1 | @upload-prefix-cls: ~"@{css-prefix}upload";
2 |
3 | .@{upload-prefix-cls} {
4 | input[type="file"]{
5 | display: none;
6 | }
7 |
8 | &-list{
9 | margin-top: 8px;
10 |
11 | &-file{
12 | padding: 4px;
13 | color: @text-color;
14 | border-radius: @border-radius-small;
15 | transition: background-color @transition-time @ease-in-out;
16 | overflow: hidden;
17 | position: relative;
18 |
19 | & > span{
20 | cursor: pointer;
21 | transition: color @transition-time @ease-in-out;
22 | i{
23 | display: inline-block;
24 | width: @font-size-small;
25 | height: @font-size-small;
26 | color: @text-color;
27 | text-align: center;
28 | }
29 | }
30 |
31 | &:hover{
32 | background: @input-disabled-bg;
33 | & > span{
34 | color: @primary-color;
35 | i{
36 | color: @text-color;
37 | }
38 | }
39 | .@{upload-prefix-cls}-list-remove{
40 | opacity: 1;
41 | }
42 | }
43 | }
44 | &-remove{
45 | opacity: 0;
46 | font-size: 18px;
47 | cursor: pointer;
48 | float: right;
49 | margin-right: 4px;
50 | color: @legend-color;
51 | transition: all @transition-time ease;
52 | &:hover{
53 | color: #444;
54 | }
55 | }
56 | }
57 |
58 | &-drag{
59 | background: #fff;
60 | border: 1px dashed @border-color-base;
61 | border-radius: @border-radius-small;
62 | text-align: center;
63 | cursor: pointer;
64 | position: relative;
65 | overflow: hidden;
66 | transition: border-color @transition-time ease;
67 |
68 | &:hover{
69 | border: 1px dashed @primary-color;
70 | }
71 | }
72 | &-dragOver{
73 | border: 2px dashed @primary-color;
74 | }
75 | }
--------------------------------------------------------------------------------
/src/renderer/assets/my-theme/components/timeline.less:
--------------------------------------------------------------------------------
1 | @timeline-prefix-cls: ~"@{css-prefix}timeline";
2 | @timeline-color: @border-color-split;
3 |
4 | .@{timeline-prefix-cls} {
5 | list-style: none;
6 | margin: 0;
7 | padding: 0;
8 |
9 | &-item {
10 | margin: 0 !important;
11 | padding: 0 0 12px 0;
12 | list-style: none;
13 | position: relative;
14 |
15 | &-tail {
16 | height: 100%;
17 | border-left: 1px solid @timeline-color;
18 | position: absolute;
19 | left: 6px;
20 | top: 0;
21 | }
22 |
23 | &-pending &-tail {
24 | display: none;
25 | }
26 |
27 | &-head {
28 | width: 13px;
29 | height: 13px;
30 | background-color: #fff;
31 | border-radius: 50%;
32 | border: 1px solid transparent;
33 | position: absolute;
34 |
35 | &-blue {
36 | border-color: @primary-color;
37 | color: @primary-color;
38 | }
39 | &-red {
40 | border-color: @error-color;
41 | color: @error-color;
42 | }
43 | &-green {
44 | border-color: @success-color;
45 | color: @success-color;
46 | }
47 | }
48 |
49 | &-head-custom {
50 | width: 40px;
51 | height: auto;
52 | margin-top: 6px;
53 | padding: 3px 0;
54 | text-align: center;
55 | line-height: 1;
56 | border: 0;
57 | border-radius: 0;
58 | font-size: @font-size-base;
59 | position: absolute;
60 | left: -13px;
61 | transform: translateY(-50%);
62 | }
63 |
64 | &-content {
65 | padding: 1px 1px 10px 24px;
66 | font-size: @font-size-small;
67 | position: relative;
68 | top: -3px;
69 | }
70 |
71 | &:last-child {
72 | .@{timeline-prefix-cls}-item-tail {
73 | display: none;
74 | }
75 | }
76 | }
77 |
78 | &&-pending &-item:nth-last-of-type(2) {
79 |
80 | .@{timeline-prefix-cls}-item-tail {
81 | border-left: 1px dotted @timeline-color;
82 | }
83 | .@{timeline-prefix-cls}-item-content {
84 | min-height: 48px;
85 | }
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/src/renderer/server/ajax.js:
--------------------------------------------------------------------------------
1 | import axios from 'axios'
2 | import { Message } from 'iview'
3 | import jsonp from 'jsonp'
4 | import qs from 'qs'
5 | axios.defaults.timeout = 1000000; //响应时间
6 | axios.defaults.headers.post['Content-Type'] = 'application/json' //通信格式
7 | // axios.defaults.baseURL = 'http://127.0.0.1:7001' //配置接口地址
8 | // axios.defaults.baseURL = 'https://api.imap.trevor.top' //配置接口地址
9 | axios.defaults.baseURL = 'https://imap.leanapp.cn' //配置接口地址
10 |
11 | export default {
12 | // POST请求
13 | post({...obj}) {
14 | return new Promise((resolve,reject) => {
15 | axios.post(obj.url, obj.data).then(data => {
16 | if(data.data.code === 0) {
17 | Message.success(data.data.msg)
18 | resolve(data.data)
19 | } else if (data.data.code === 1) {
20 | Message.warning(data.data.msg)
21 | resolve(data.data)
22 | } else if (data.data.code === 2) {
23 | Message.error(data.data.msg)
24 | resolve(data.data)
25 | } else {
26 | Message.error(data.data.msg)
27 | resolve(data.data)
28 | }
29 | }).catch(data => {
30 | reject(data)
31 | })
32 | })
33 | },
34 | // GET请求
35 | get({...obj}) {
36 | return new Promise((resolve,reject) => {
37 | axios.get(obj.url, { params: obj.data }).then(data => {
38 | if(data.status === 200) {
39 | resolve(data.data)
40 | } else if(data.data.code === 0) {
41 | resolve(data.data)
42 | } else if (data.data.code === 1) {
43 | Message.warning(data.data.msg)
44 | resolve(data.data)
45 | } else if (data.data.code === 2) {
46 | Message.error(data.data.msg)
47 | resolve(data.data)
48 | } else {
49 | Message.error(data.data.msg)
50 | resolve(data.data)
51 | }
52 | }).catch(data => {
53 | reject(data)
54 | })
55 | })
56 | },
57 | // jsonp
58 | jsonp({...obj}) {
59 | return new Promise((resolve, reject) => {
60 | jsonp(obj.url + '?' + qs.stringify(obj.data) , null, (err, data) => {
61 | if (err) {
62 | Message.error('请求错误')
63 | } else if(data.status === 0) {
64 | resolve(data)
65 | } else if(data.code === 0) {
66 | resolve(data)
67 | } else {
68 | if(getUrlRelativePath() === '/')
69 | resolve(data)
70 | else
71 | Message.error('请求错误')
72 | }
73 | })
74 | })
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/src/renderer/assets/my-theme/components/cascader.less:
--------------------------------------------------------------------------------
1 | @cascader-prefix-cls: ~"@{css-prefix}cascader";
2 | @cascader-item-prefix-cls: ~"@{css-prefix}cascader-menu-item";
3 |
4 | .@{cascader-prefix-cls} {
5 | //position: relative;
6 | line-height: normal;
7 |
8 | &-rel{
9 | position: relative;
10 | }
11 |
12 | .@{css-prefix}input{
13 | display: block;
14 | cursor: pointer;
15 | }
16 | &-disabled .@{css-prefix}input{
17 | cursor: @cursor-disabled;
18 | }
19 |
20 | .@{cascader-prefix-cls}-arrow:nth-of-type(1) {
21 | display: none;
22 | cursor: pointer;
23 | }
24 |
25 | &:hover {
26 | .@{cascader-prefix-cls}-arrow:nth-of-type(1) {
27 | display: inline-block;
28 | }
29 | }
30 | &-show-clear:hover .@{cascader-prefix-cls}-arrow:nth-of-type(2){
31 | display: none;
32 | }
33 |
34 | &-arrow {
35 | .inner-arrow();
36 | }
37 | &-visible &-arrow:nth-of-type(2) {
38 | transform: rotate(180deg);
39 | }
40 |
41 | .@{select-dropdown-prefix-cls} {
42 | width: auto;
43 | padding: 0;
44 | white-space: nowrap;
45 | overflow: visible;
46 | }
47 |
48 | .select-item(@cascader-prefix-cls, @cascader-item-prefix-cls);
49 |
50 | &-menu{
51 | display: inline-block;
52 | min-width: 100px;
53 | height: 180px;
54 | margin: 0;
55 | padding: 5px 0 !important;
56 | vertical-align: top;
57 | list-style: none;
58 | border-right: 1px solid @border-color-split;
59 | overflow: auto;
60 |
61 | &:first-child {
62 |
63 | }
64 | &:last-child {
65 | border-right-color: transparent;
66 | margin-right: -1px;
67 | }
68 | &:only-child {
69 |
70 | }
71 |
72 | & &-item{
73 | position: relative;
74 | padding-right: 24px;
75 | transition: all @transition-time @ease-in-out;
76 |
77 | i{
78 | font-size: @font-size-small;
79 | position: absolute;
80 | right: 15px;
81 | top: 50%;
82 | margin-top: -6px;
83 | }
84 |
85 | &-active{
86 | background-color: @background-color-select-hover;
87 | color: @primary-color;
88 | }
89 | }
90 | }
91 | }
92 |
93 | .@{form-item-prefix-cls}-error{
94 | .@{cascader-prefix-cls} {
95 | &-arrow{
96 | color: @error-color;
97 | }
98 | }
99 | }
--------------------------------------------------------------------------------
/src/renderer/assets/my-theme/mixins/tooltip.less:
--------------------------------------------------------------------------------
1 | .popper(@arrow, @arrow-width, @arrow-distance, @bg){
2 | display: block;
3 | visibility: visible;
4 | font-size: @font-size-small;
5 | line-height: @line-height-base;
6 | position: absolute;
7 | z-index: @zindex-tooltip;
8 |
9 | &[x-placement^="top"] {
10 | padding: @arrow-width 0 @arrow-distance 0;
11 | }
12 | &[x-placement^="right"] {
13 | padding: 0 @arrow-width 0 @arrow-distance;
14 | }
15 | &[x-placement^="bottom"] {
16 | padding: @arrow-distance 0 @arrow-width 0;
17 | }
18 | &[x-placement^="left"] {
19 | padding: 0 @arrow-distance 0 @arrow-width;
20 | }
21 |
22 | &[x-placement^="top"] .@{arrow} {
23 | bottom: @arrow-distance - @arrow-width;
24 | border-width: @arrow-width @arrow-width 0;
25 | border-top-color: @bg;
26 | }
27 | &[x-placement="top"] .@{arrow} {
28 | left: 50%;
29 | margin-left: -@arrow-width;
30 | }
31 | &[x-placement="top-start"] .@{arrow} {
32 | left: 16px;
33 | }
34 | &[x-placement="top-end"] .@{arrow} {
35 | right: 16px;
36 | }
37 |
38 | &[x-placement^="right"] .@{arrow} {
39 | left: @arrow-distance - @arrow-width;
40 | border-width: @arrow-width @arrow-width @arrow-width 0;
41 | border-right-color: @bg;
42 | }
43 | &[x-placement="right"] .@{arrow} {
44 | top: 50%;
45 | margin-top: -@arrow-width;
46 | }
47 | &[x-placement="right-start"] .@{arrow} {
48 | top: 8px;
49 | }
50 | &[x-placement="right-end"] .@{arrow} {
51 | bottom: 8px;
52 | }
53 |
54 | &[x-placement^="left"] .@{arrow} {
55 | right: @arrow-distance - @arrow-width;
56 | border-width: @arrow-width 0 @arrow-width @arrow-width;
57 | border-left-color: @bg;
58 | }
59 | &[x-placement="left"] .@{arrow} {
60 | top: 50%;
61 | margin-top: -@arrow-width;
62 | }
63 | &[x-placement="left-start"] .@{arrow} {
64 | top: 8px;
65 | }
66 | &[x-placement="left-end"] .@{arrow} {
67 | bottom: 8px;
68 | }
69 |
70 | &[x-placement^="bottom"] .@{arrow} {
71 | top: @arrow-distance - @arrow-width;
72 | border-width: 0 @arrow-width @arrow-width;
73 | border-bottom-color: @bg;
74 | }
75 | &[x-placement="bottom"] .@{arrow} {
76 | left: 50%;
77 | margin-left: -@arrow-width;
78 | }
79 | &[x-placement="bottom-start"] .@{arrow} {
80 | left: 16px;
81 | }
82 | &[x-placement="bottom-end"] .@{arrow} {
83 | right: 16px;
84 | }
85 | }
--------------------------------------------------------------------------------
/src/renderer/assets/my-theme/components/alert.less:
--------------------------------------------------------------------------------
1 | @alert-prefix-cls: ~"@{css-prefix}alert";
2 | @icon-prefix-cls: ~"@{css-prefix}icon";
3 |
4 | .@{alert-prefix-cls}{
5 | position: relative;
6 | padding: 8px 48px 8px 16px;
7 | border-radius: @border-radius-base;
8 | color: @text-color;
9 | font-size: @font-size-small;
10 | line-height: 16px;
11 | margin-bottom: 10px;
12 |
13 | &&-with-icon{
14 | padding: 8px 48px 8px 38px;
15 | }
16 |
17 | &-icon {
18 | font-size: @font-size-base;
19 | top: 8px;
20 | left: 16px;
21 | position: absolute;
22 | }
23 |
24 | &-desc {
25 | font-size: @font-size-small;
26 | color: @text-color;
27 | line-height: 21px;
28 | display: none;
29 | text-align: justify;
30 | }
31 |
32 | &-success {
33 | border: 1px solid tint(@success-color, 80%);
34 | background-color: tint(@success-color, 90%);
35 | .@{alert-prefix-cls}-icon {
36 | color: @success-color;
37 | }
38 | }
39 |
40 | &-info {
41 | border: 1px solid tint(@primary-color, 80%);
42 | background-color: tint(@primary-color, 90%);
43 | .@{alert-prefix-cls}-icon {
44 | color: @primary-color;
45 | }
46 | }
47 |
48 | &-warning {
49 | border: 1px solid tint(@warning-color, 80%);
50 | background-color: tint(@warning-color, 90%);
51 | .@{alert-prefix-cls}-icon {
52 | color: @warning-color;
53 | }
54 | }
55 |
56 | &-error {
57 | border: 1px solid tint(@error-color, 80%);
58 | background-color: tint(@error-color, 90%);
59 | .@{alert-prefix-cls}-icon {
60 | color: @error-color;
61 | }
62 | }
63 |
64 | &-close {
65 | .content-close(-3px);
66 | }
67 |
68 | &-with-desc {
69 | padding: 16px;
70 | position: relative;
71 | border-radius: @border-radius-base;
72 | margin-bottom: 10px;
73 | color: @text-color;
74 | line-height: 1.5;
75 | }
76 |
77 | &-with-desc&-with-icon{
78 | padding: 16px 16px 16px 69px;
79 | }
80 |
81 | &-with-desc &-desc{
82 | display: block;
83 | }
84 |
85 | &-with-desc &-message {
86 | font-size: 14px;
87 | color: @title-color;
88 | display: block;
89 | }
90 |
91 | &-with-desc &-icon {
92 | top: 50%;
93 | left: 24px;
94 | margin-top: -21px;
95 | font-size: 28px;
96 | }
97 |
98 | &-with-banner{
99 | border-radius: 0;
100 | }
101 | }
--------------------------------------------------------------------------------
/src/renderer/components/Ui/DelPointModal.vue:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
11 | 删除地点
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
95 |
96 |
97 |
103 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "imap",
3 | "productName": "iMap",
4 | "version": "0.0.3-beta",
5 | "author": "xizhouh@gmail.com",
6 | "description": "iMap让你生成专属你的旅行地图",
7 | "license": "MIT",
8 | "main": "./dist/electron/main.js",
9 | "scripts": {
10 | "build": "node .electron-vue/build.js",
11 | "build:darwin": "cross-env BUILD_TARGET=darwin node .electron-vue/build.js",
12 | "build:linux": "cross-env BUILD_TARGET=linux node .electron-vue/build.js",
13 | "build:mas": "cross-env BUILD_TARGET=mas node .electron-vue/build.js",
14 | "build:win32": "cross-env BUILD_TARGET=win32 node .electron-vue/build.js",
15 | "build:clean": "cross-env BUILD_TARGET=clean node .electron-vue/build.js",
16 | "build:web": "cross-env BUILD_TARGET=web node .electron-vue/build.js",
17 | "dev": "node .electron-vue/dev-runner.js",
18 | "pack": "npm run pack:main && npm run pack:renderer",
19 | "pack:main": "cross-env NODE_ENV=production webpack --progress --colors --config .electron-vue/webpack.main.config.js",
20 | "pack:renderer": "cross-env NODE_ENV=production webpack --progress --colors --config .electron-vue/webpack.renderer.config.js",
21 | "postinstall": ""
22 | },
23 | "dependencies": {
24 | "axios": "^0.16.1",
25 | "iview": "^2.4.0",
26 | "jsonp": "^0.2.1",
27 | "left-pad": "1.1.3",
28 | "less": "^2.7.2",
29 | "less-loader": "^4.0.5",
30 | "lodash": "^4.17.4",
31 | "particles.js": "^2.0.0",
32 | "qs": "^6.5.1",
33 | "store": "^2.0.12",
34 | "vue": "^2.3.3",
35 | "vue-echarts": "^2.4.1",
36 | "vue-electron": "^1.0.6",
37 | "vue-particles": "^1.0.9",
38 | "vue-router": "^2.5.3",
39 | "vuex": "^2.3.1"
40 | },
41 | "devDependencies": {
42 | "babel-core": "^6.25.0",
43 | "babel-loader": "^7.1.1",
44 | "babel-plugin-transform-runtime": "^6.23.0",
45 | "babel-preset-env": "^1.6.0",
46 | "babel-preset-stage-0": "^6.24.1",
47 | "babel-register": "^6.24.1",
48 | "babili-webpack-plugin": "^0.1.2",
49 | "cfonts": "^1.1.3",
50 | "chalk": "^2.1.0",
51 | "copy-webpack-plugin": "^4.2.0",
52 | "cross-env": "^5.0.5",
53 | "css-loader": "^0.28.4",
54 | "del": "^3.0.0",
55 | "devtron": "^1.4.0",
56 | "electron": "^1.7.5",
57 | "electron-debug": "^1.4.0",
58 | "electron-devtools-installer": "^2.2.0",
59 | "electron-packager": "^8.5.0",
60 | "electron-rebuild": "^1.1.3",
61 | "extract-text-webpack-plugin": "^3.0.0",
62 | "file-loader": "^0.11.2",
63 | "html-webpack-plugin": "^2.30.1",
64 | "multispinner": "^0.2.1",
65 | "node-loader": "^0.6.0",
66 | "style-loader": "^0.18.2",
67 | "url-loader": "^0.5.9",
68 | "vue-html-loader": "^1.2.4",
69 | "vue-loader": "^13.0.5",
70 | "vue-style-loader": "^3.0.1",
71 | "vue-template-compiler": "^2.4.2",
72 | "webpack": "^3.5.2",
73 | "webpack-dev-server": "^2.7.1",
74 | "webpack-hot-middleware": "^2.18.2"
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/src/renderer/assets/my-theme/animation/slide.less:
--------------------------------------------------------------------------------
1 | .slide-motion(@className, @keyframeName) {
2 | .make-motion(@className, @keyframeName);
3 | .@{className}-enter, .@{className}-appear {
4 | opacity: 0;
5 | animation-timing-function: @ease-in-out;
6 | }
7 | .@{className}-leave {
8 | animation-timing-function: @ease-in-out;
9 | }
10 | }
11 |
12 | .slide-motion(slide-up, ivuSlideUp);
13 | .slide-motion(slide-down, ivuSlideDown);
14 | .slide-motion(slide-left, ivuSlideLeft);
15 | .slide-motion(slide-right, ivuSlideRight);
16 |
17 | @keyframes ivuSlideUpIn {
18 | 0% {
19 | opacity: 0;
20 | transform-origin: 0% 0%;
21 | transform: scaleY(.8);
22 | }
23 | 100% {
24 | opacity: 1;
25 | transform-origin: 0% 0%;
26 | transform: scaleY(1);
27 | }
28 | }
29 |
30 | @keyframes ivuSlideUpOut {
31 | 0% {
32 | opacity: 1;
33 | transform-origin: 0% 0%;
34 | transform: scaleY(1);
35 | }
36 | 100% {
37 | opacity: 0;
38 | transform-origin: 0% 0%;
39 | transform: scaleY(.8);
40 | }
41 | }
42 |
43 | @keyframes ivuSlideDownIn {
44 | 0% {
45 | opacity: 0;
46 | transform-origin: 100% 100%;
47 | transform: scaleY(.8);
48 | }
49 | 100% {
50 | opacity: 1;
51 | transform-origin: 100% 100%;
52 | transform: scaleY(1);
53 | }
54 | }
55 |
56 | @keyframes ivuSlideDownOut {
57 | 0% {
58 | opacity: 1;
59 | transform-origin: 100% 100%;
60 | transform: scaleY(1);
61 | }
62 | 100% {
63 | opacity: 0;
64 | transform-origin: 100% 100%;
65 | transform: scaleY(.8);
66 | }
67 | }
68 |
69 | @keyframes ivuSlideLeftIn {
70 | 0% {
71 | opacity: 0;
72 | transform-origin: 0% 0%;
73 | transform: scaleX(.8);
74 | }
75 | 100% {
76 | opacity: 1;
77 | transform-origin: 0% 0%;
78 | transform: scaleX(1);
79 | }
80 | }
81 |
82 | @keyframes ivuSlideLeftOut {
83 | 0% {
84 | opacity: 1;
85 | transform-origin: 0% 0%;
86 | transform: scaleX(1);
87 | }
88 | 100% {
89 | opacity: 0;
90 | transform-origin: 0% 0%;
91 | transform: scaleX(.8);
92 | }
93 | }
94 |
95 | @keyframes ivuSlideRightIn {
96 | 0% {
97 | opacity: 0;
98 | transform-origin: 100% 0%;
99 | transform: scaleX(.8);
100 | }
101 | 100% {
102 | opacity: 1;
103 | transform-origin: 100% 0%;
104 | transform: scaleX(1);
105 | }
106 | }
107 |
108 | @keyframes ivuSlideRightOut {
109 | 0% {
110 | opacity: 1;
111 | transform-origin: 100% 0%;
112 | transform: scaleX(1);
113 | }
114 | 100% {
115 | opacity: 0;
116 | transform-origin: 100% 0%;
117 | transform: scaleX(.8);
118 | }
119 | }
--------------------------------------------------------------------------------
/src/renderer/assets/my-theme/components/slider.less:
--------------------------------------------------------------------------------
1 | @slider-prefix-cls: ~"@{css-prefix}slider";
2 |
3 | .@{slider-prefix-cls} {
4 | line-height: normal;
5 | &-wrap{
6 | width: 100%;
7 | height: @slider-height;
8 | margin: @slider-margin;
9 | background-color: @border-color-split;
10 | border-radius: @btn-border-radius-small;
11 | vertical-align: middle;
12 | position: relative;
13 | cursor: pointer;
14 | }
15 |
16 | &-button-wrap{
17 | .square(@slider-button-wrap-size);
18 | text-align: center;
19 | background-color: transparent;
20 | position: absolute;
21 | top: @slider-button-wrap-offset;
22 | transform: translateX(-50%);
23 |
24 | .@{tooltip-prefix-cls} {
25 | display: block;
26 | user-select: none;
27 | }
28 | }
29 |
30 | &-button{
31 | width: 12px;
32 | height: 12px;
33 | border: 2px solid @slider-color;
34 | border-radius: 50%;
35 | background-color: #fff;
36 | transition: all @transition-time linear;
37 |
38 | &:hover,
39 | &-dragging
40 | {
41 | border-color: @primary-color;
42 | transform: scale(1.5);
43 | }
44 |
45 | &:hover{
46 | cursor: grab;
47 | }
48 | &-dragging,
49 | &-dragging:hover
50 | {
51 | cursor: grabbing;
52 | }
53 | }
54 |
55 | &-bar{
56 | height: @slider-height;
57 | background: @slider-color;
58 | border-radius: @btn-border-radius-small;
59 | position: absolute;
60 | }
61 |
62 | &-stop{
63 | position: absolute;
64 | .square(@slider-height);
65 | border-radius: 50%;
66 | background-color: @slider-disabled-color;
67 | transform: translateX(-50%);
68 | }
69 | }
70 |
71 | .@{slider-prefix-cls}-disabled{
72 | cursor: @cursor-disabled;
73 |
74 | .@{slider-prefix-cls}-wrap{
75 | background-color: @slider-disabled-color;
76 | cursor: @cursor-disabled;
77 | }
78 | .@{slider-prefix-cls}-bar{
79 | background-color: @slider-disabled-color;
80 | }
81 |
82 | .@{slider-prefix-cls}-button{
83 | border-color: @slider-disabled-color;
84 |
85 | &:hover,
86 | &-dragging
87 | {
88 | border-color: @slider-disabled-color;
89 | }
90 | &:hover{
91 | cursor: @cursor-disabled;
92 | }
93 | &-dragging,
94 | &-dragging:hover
95 | {
96 | cursor: @cursor-disabled;
97 | }
98 | }
99 | }
100 |
101 | .@{slider-prefix-cls}-input{
102 | .@{slider-prefix-cls}-wrap{
103 | width: auto;
104 | margin-right: 100px;
105 | }
106 |
107 | .@{input-number-prefix-cls}{
108 | float: right;
109 | margin-top: -14px;
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/src/renderer/assets/my-theme/components/switch.less:
--------------------------------------------------------------------------------
1 | @switch-prefix-cls: ~"@{css-prefix}switch";
2 |
3 | .@{switch-prefix-cls} {
4 | display: inline-block;
5 | width: 48px;
6 | height: 24px;
7 | line-height: 22px;
8 | border-radius: 24px;
9 | vertical-align: middle;
10 | border: 1px solid #ccc;
11 | background-color: #ccc;
12 | position: relative;
13 | cursor: pointer;
14 | user-select: none;
15 | transition: all @transition-time @ease-in-out;
16 |
17 | &-inner {
18 | color: #fff;
19 | font-size: @font-size-small;
20 | position: absolute;
21 | left: 25px;
22 |
23 | i {
24 | width: 12px;
25 | height: 12px;
26 | text-align: center;
27 | }
28 | }
29 |
30 | &:after {
31 | content: '';
32 | width: 20px;
33 | height: 20px;
34 | border-radius: 20px;
35 | background-color: #fff;
36 | position: absolute;
37 | left: 1px;
38 | top: 1px;
39 | cursor: pointer;
40 | transition: left @transition-time @ease-in-out, width @transition-time @ease-in-out;
41 | }
42 |
43 | &:active:after {
44 | width: 26px;
45 | }
46 |
47 | &:focus {
48 | box-shadow: 0 0 0 2px fade(@primary-color, 20%);
49 | outline: 0;
50 | }
51 |
52 | &:focus:hover {
53 | box-shadow: none;
54 | }
55 |
56 | &-small {
57 | width: 24px;
58 | height: 12px;
59 | line-height: 10px;
60 | &:after {
61 | width: 10px;
62 | height: 10px;
63 | top: 0;
64 | left: 0;
65 | }
66 | &:active:after {
67 | width: 14px;
68 | }
69 | }
70 |
71 | &-small&-checked:after {
72 | left: 12px;
73 | }
74 |
75 | &-small:active&-checked:after {
76 | left: 8px;
77 | }
78 |
79 | &-large{
80 | width: 60px;
81 | &:active:after {
82 | width: 26px;
83 | }
84 | }
85 |
86 | &-large:active:after {
87 | width: 32px;
88 | }
89 |
90 | &-large&-checked:after {
91 | left: 37px;
92 | }
93 |
94 | &-large:active&-checked:after {
95 | left: 25px;
96 | }
97 |
98 | &-checked {
99 | border-color: @primary-color;
100 | background-color: @primary-color;
101 |
102 | .@{switch-prefix-cls}-inner {
103 | left: 8px;
104 | }
105 |
106 | &:after {
107 | left: 25px;
108 | }
109 |
110 | &:active:after {
111 | left: 19px;
112 | }
113 | }
114 |
115 | &-disabled {
116 | cursor: @cursor-disabled;
117 | background: #f3f3f3;
118 | border-color: #f3f3f3;
119 |
120 | &:after {
121 | background: #ccc;
122 | cursor: not-allowed;
123 | }
124 |
125 | .@{switch-prefix-cls}-inner {
126 | color: #ccc;
127 | }
128 | }
129 | }
130 |
--------------------------------------------------------------------------------
/src/renderer/data/map.js:
--------------------------------------------------------------------------------
1 | import _ from 'lodash'
2 |
3 | let data = []
4 | let geoCoordMap = []
5 |
6 | /**
7 | * 赋值函数
8 | * @param {Array} data
9 | */
10 | const convertData = data => {
11 | let res = []
12 | for(let i = 0; i < data.length; i++) {
13 | let geoCoord = _.last(geoCoordMap[i])
14 | if(geoCoord) {
15 | res.push({
16 | name: data[i].name,
17 | value: geoCoord.concat(data[i].value).concat(data[i].time)
18 | })
19 | }
20 | }
21 | return res
22 | }
23 |
24 | export default {
25 | /**
26 | * 返回地图数据
27 | * @param {Object} obj
28 | * @param {Object} options
29 | */
30 | getMapData({...obj}, options) {
31 | data = []
32 | geoCoordMap = []
33 | let geoModel = []
34 | try {
35 | obj.data.forEach((item, idx) => {
36 | let dataModel = {
37 | name: '',
38 | value: 84,
39 | time: ''
40 | }
41 | geoModel.push(item[0])
42 | let itemArr = [+item[1], +item[2]]
43 | geoModel.push(itemArr)
44 | dataModel.name = item[0]
45 | dataModel.time = item[3]
46 | data.push(dataModel)
47 | })
48 | geoCoordMap = _.chunk(geoModel, 2)
49 | return {
50 | backgroundColor: '#302F33',
51 | title: {
52 | text: '我的足迹',
53 | subtext: 'My footprints',
54 | left: 'center',
55 | textStyle: {
56 | color: '#fff'
57 | }
58 | },
59 | tooltip: {
60 | trigger: 'item'
61 | },
62 | toolbox: {
63 | show: true,
64 | right: '40',
65 | feature: {
66 | saveAsImage: {
67 | show: true,
68 | pixelRatio: 3
69 | }
70 | }
71 | },
72 | legend: {
73 | orient: 'vertical',
74 | y: 'bottom',
75 | x: 'right',
76 | data: ['去过的地点'],
77 | textStyle: {
78 | color: '#fff'
79 | }
80 | },
81 | geo: {
82 | map: options.mapType,
83 | zoom: options.zoom,
84 | roam: options.roam ? 'move' : false,
85 | label: {
86 | emphasis: {
87 | show: false
88 | }
89 | },
90 | itemStyle: {
91 | normal: {
92 | areaColor: '#323c48',
93 | borderColor: '#111'
94 | },
95 | emphasis: {
96 | areaColor: '#2a333d'
97 | }
98 | }
99 | },
100 | series: [
101 | {
102 | name: '去过的地点',
103 | type: 'effectScatter',
104 | coordinateSystem: 'geo',
105 | data: convertData(data),
106 | symbolSize: val => val[2] / 10,
107 | showEffectOn: 'render',
108 | rippleEffect: {
109 | brushType: 'stroke'
110 | },
111 | hoverAnimation: true,
112 | label: {
113 | normal: {
114 | formatter: '{b}',
115 | position: 'right',
116 | show: true
117 | }
118 | },
119 | itemStyle: {
120 | normal: {
121 | color: '#f4e925',
122 | shadowBlur: 10,
123 | shadowColor: '#333'
124 | }
125 | },
126 | zlevel: 1
127 | }
128 | ]
129 | }
130 | } catch(error) {
131 | this.$Message.error('Excel内容格式错误')
132 | }
133 | }
134 | }
135 |
--------------------------------------------------------------------------------
/src/renderer/components/Page/Register.vue:
--------------------------------------------------------------------------------
1 |
2 |
14 |
15 |
16 |
17 |
63 |
64 |
65 |
--------------------------------------------------------------------------------
/src/renderer/components/Page/ForgetPassword.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
iMap
4 |
5 |
6 |
7 |
10 |
11 |
12 |
13 |
14 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/src/renderer/components/Ui/EditPointModal.vue:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
11 | 编辑地点
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
105 |
106 |
107 |
113 |
--------------------------------------------------------------------------------
/src/renderer/assets/my-theme/components/modal.less:
--------------------------------------------------------------------------------
1 | @modal-prefix-cls: ~"@{css-prefix}modal";
2 | @confirm-prefix-cls: ~"@{css-prefix}modal-confirm";
3 |
4 | .@{modal-prefix-cls} {
5 | width: auto;
6 | margin: 0 auto;
7 | position: relative;
8 | outline: none;
9 | top: 100px;
10 |
11 | &-hidden {
12 | display: none !important;
13 | }
14 |
15 | &-wrap {
16 | position: fixed;
17 | overflow: auto;
18 | top: 0;
19 | right: 0;
20 | bottom: 0;
21 | left: 0;
22 | z-index: @zindex-modal;
23 | -webkit-overflow-scrolling: touch;
24 | outline: 0;
25 | }
26 |
27 | &-wrap * {
28 | box-sizing: border-box;
29 | -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
30 | }
31 |
32 | &-mask {
33 | .mask;
34 | }
35 |
36 | &-content {
37 | position: relative;
38 | background-color: #fff;
39 | border: 0;
40 | border-radius: @border-radius-base;
41 | background-clip: padding-box;
42 | }
43 |
44 | &-header {
45 | .content-header;
46 | }
47 |
48 | &-close {
49 | .content-close(1px, 31px);
50 | }
51 |
52 | &-body {
53 | padding: 16px;
54 | font-size: 12px;
55 | line-height: 1.5;
56 | }
57 |
58 | &-footer {
59 | border-top: 1px solid @border-color-split;
60 | padding: 12px 18px 12px 18px;
61 | text-align: right;
62 | button + button {
63 | margin-left: 8px;
64 | margin-bottom: 0;
65 | }
66 | }
67 | }
68 |
69 | @media (max-width: 768px) {
70 | .@{modal-prefix-cls} {
71 | width: auto !important;
72 | margin: 10px;
73 | }
74 | .vertical-center-modal {
75 | .@{modal-prefix-cls} {
76 | flex: 1;
77 | }
78 | }
79 | }
80 |
81 | .@{confirm-prefix-cls} {
82 | padding: 0 4px;
83 | &-head {
84 |
85 | &-title {
86 | display: inline-block;
87 | font-size: @font-size-base;
88 | color: @title-color;
89 | font-weight: 700;
90 | }
91 | }
92 |
93 | &-body{
94 | margin-top: 6px;
95 | padding-left: 48px;
96 | padding-top: 18px;
97 | font-size: @font-size-small;
98 | color: @text-color;
99 | position: relative;
100 |
101 | &-icon {
102 | font-size: 36px;
103 | position: absolute;
104 | top: 0;
105 | left: 0;
106 |
107 | &-info {
108 | color: @primary-color;
109 | }
110 | &-success {
111 | color: @success-color;
112 | }
113 | &-warning {
114 | color: @warning-color;
115 | }
116 | &-error {
117 | color: @error-color;
118 | }
119 | &-confirm {
120 | color: @warning-color;
121 | }
122 | }
123 | }
124 |
125 | &-footer{
126 | margin-top: 40px;
127 | text-align: right;
128 |
129 | button + button {
130 | margin-left: 8px;
131 | margin-bottom: 0;
132 | }
133 | }
134 | }
--------------------------------------------------------------------------------
/src/renderer/assets/my-theme/components/notice.less:
--------------------------------------------------------------------------------
1 | @notice-prefix-cls: ~"@{css-prefix}notice";
2 | @icon-prefix-cls: ~"@{css-prefix}icon";
3 |
4 | @notice-width: 335px;
5 | @notice-padding: 16px;
6 | @notice-margin-bottom: 10px;
7 |
8 | .@{notice-prefix-cls} {
9 | width: @notice-width;
10 | margin-right: 24px;
11 | position: fixed;
12 | z-index: @zindex-notification;
13 |
14 | &-notice {
15 | margin-bottom: @notice-margin-bottom;
16 | padding: @notice-padding;
17 | //border: 1px solid @border-color-split;
18 | border-radius: @border-radius-small;
19 | box-shadow: @shadow-base;
20 | background: #fff;
21 | line-height: 1;
22 | position: relative;
23 | overflow: hidden;
24 |
25 | &-close {
26 | position: absolute;
27 | right: 16px;
28 | top: 15px;
29 | color: #999;
30 | outline: none;
31 |
32 | i{
33 | .close-base(-3px);
34 | }
35 | }
36 |
37 | &-with-desc{
38 | .@{notice-prefix-cls}-notice-close{
39 | top: 11px;
40 | }
41 | }
42 | }
43 |
44 | &-title {
45 | font-size: @font-size-base;
46 | color: @title-color;
47 | padding-right: 10px;
48 | overflow: hidden;
49 | text-overflow: ellipsis;
50 | white-space: nowrap;
51 | }
52 | &-with-desc &-title{
53 | margin-bottom: 8px;
54 | }
55 | &-with-desc&-with-icon &-title{
56 | margin-left: 51px;
57 | }
58 |
59 | &-desc {
60 | font-size: 12px;
61 | color: @legend-color;
62 | text-align: justify;
63 | line-height: 1.5;
64 | }
65 | &-with-desc&-with-icon &-desc{
66 | margin-left: 51px;
67 | }
68 |
69 | &-with-icon &-title{
70 | margin-left: 26px;
71 | }
72 |
73 | &-icon {
74 | position: absolute;
75 | left: 20px;
76 | margin-top: -1px;
77 | font-size: 16px;
78 |
79 | &-success {
80 | color: @success-color;
81 | }
82 | &-info {
83 | color: @primary-color;
84 | }
85 | &-warning {
86 | color: @warning-color;
87 | }
88 | &-error {
89 | color: @error-color;
90 | }
91 | }
92 | &-with-desc &-icon{
93 | font-size: 36px;
94 | }
95 |
96 | &-custom-content{
97 | &:after{
98 | content: "";
99 | display: block;
100 | width: 4px;
101 | position: absolute;
102 | top: 0;
103 | bottom: 0;
104 | left: 0;
105 | }
106 | }
107 | &-with-normal{
108 | &:after{
109 | background: @primary-color;
110 | }
111 | }
112 | &-with-info{
113 | &:after{
114 | background: @primary-color;
115 | }
116 | }
117 | &-with-success{
118 | &:after{
119 | background: @success-color;
120 | }
121 | }
122 | &-with-warning{
123 | &:after{
124 | background: @warning-color;
125 | }
126 | }
127 | &-with-error{
128 | &:after{
129 | background: @error-color;
130 | }
131 | }
132 | }
--------------------------------------------------------------------------------
/src/renderer/components/Page/Help.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
欢迎使用iMap,在开始之前,请您花费一些时间阅读帮助文档。
6 |
- 新建项目
7 |
8 | 每次新建项目时,你将会看到两个选项:导入Excel和自定义输入
9 |
导入Excel
10 |
11 | 在导入Excel操作中,请务必注意格式,请按以下图片格式为标准
12 | ![Excel格式]()
13 | 数据说明:
14 | 第一列:城市名称(示例:南昌)
15 | 第二列:地点经度(示例:115.89)
16 | 第三列:地点纬度(示例:28.68)
17 | 第四列:游玩时间(示例:2017.10.10)
18 | 注意:每次导入新的Excel文件,代表着重新启动项目,之前的数据将会清空。
19 |
20 |
自定义输入
21 |
22 | 如果你之前拥有项目(可以在 个人中心 - 我的项目 中看到),你将会看到两个按钮:
23 | 新建项目:
24 | 意味着你同样将放弃之前的项目,重新启动一个新的项目。
25 | 编辑项目:
26 | 你可以在之前的项目上追加地点。
27 |
28 |
29 |
- 生成地图
30 |
31 | 进入制作页面,请先选择地图类型(中国地图,世界地图),再点击生成地图,这样一张旅行地图就完成了。
32 |
33 |
- 编辑地图
34 |
35 | 在地图的右上角,你可以看到编辑地图的按钮,按照提示输入即可。
36 | 注意: 当前版本只能自动获取中国城市的坐标,国外城市坐标请手动输入。
37 |
38 |
- 下载地图
39 |
40 | 在地图的右上角,你可以看到下载地图的按钮,保存图片格式为.png格式。
41 |
42 |
- 我的项目
43 |
44 | 在 个人中心 - 我的项目 中可以查询以往项目,删除即代表着你将放弃本项目,请谨慎操作。
45 | 项目在你操作的时候会实时保存,所以不用担心地图数据会丢失。
46 |
47 |
- 最后
48 |
49 | Enjoy iMap ; )
50 | 如有疑问,请联系制作人 xizhouh@gmail.com | Trevor
51 |
52 |
53 |
54 |
55 |
56 |
57 |
73 |
74 |
75 |
126 |
--------------------------------------------------------------------------------
/src/renderer/assets/my-theme/components/button.less:
--------------------------------------------------------------------------------
1 | @btn-prefix-cls: ~"@{css-prefix}btn";
2 |
3 | .@{btn-prefix-cls} {
4 | .btn;
5 | .btn-default;
6 |
7 | &-long{
8 | width: 100%;
9 | }
10 |
11 | & > .ivu-icon + span, & > span + .ivu-icon{
12 | margin-left: 4px;
13 | }
14 |
15 | &-primary {
16 | .btn-primary;
17 |
18 | .@{btn-prefix-cls}-group:not(.@{btn-prefix-cls}-group-vertical) &:not(:first-child):not(:last-child) {
19 | border-right-color: @btn-group-border;
20 | border-left-color: @btn-group-border;
21 | }
22 |
23 | .@{btn-prefix-cls}-group:not(.@{btn-prefix-cls}-group-vertical) &:first-child {
24 | &:not(:last-child) {
25 | border-right-color: @btn-group-border;
26 | &[disabled] {
27 | border-right-color: @btn-default-border;
28 | }
29 | }
30 | }
31 |
32 | .@{btn-prefix-cls}-group:not(.@{btn-prefix-cls}-group-vertical) &:last-child:not(:first-child),
33 | .@{btn-prefix-cls}-group:not(.@{btn-prefix-cls}-group-vertical) & + .@{btn-prefix-cls} {
34 | border-left-color: @btn-group-border;
35 | &[disabled] {
36 | border-left-color: @btn-default-border;
37 | }
38 | }
39 |
40 | .@{btn-prefix-cls}-group-vertical &:not(:first-child):not(:last-child) {
41 | border-top-color: @btn-group-border;
42 | border-bottom-color: @btn-group-border;
43 | }
44 |
45 | .@{btn-prefix-cls}-group-vertical &:first-child {
46 | &:not(:last-child) {
47 | border-bottom-color: @btn-group-border;
48 | &[disabled] {
49 | border-top-color: @btn-default-border;
50 | }
51 | }
52 | }
53 |
54 | .@{btn-prefix-cls}-group-vertical &:last-child:not(:first-child),
55 | .@{btn-prefix-cls}-group-vertical & + .@{btn-prefix-cls} {
56 | border-top-color: @btn-group-border;
57 | &[disabled] {
58 | border-bottom-color: @btn-default-border;
59 | }
60 | }
61 | }
62 |
63 | &-ghost {
64 | .btn-ghost;
65 | }
66 |
67 | &-dashed{
68 | .btn-dashed;
69 | }
70 |
71 | &-text{
72 | .btn-text;
73 | }
74 |
75 | &-success {
76 | .btn-color(@success-color);
77 | }
78 |
79 | &-warning {
80 | .btn-color(@warning-color);
81 | }
82 |
83 | &-error {
84 | .btn-color(@error-color);
85 | }
86 |
87 | &-info {
88 | .btn-color(@info-color);
89 | }
90 |
91 | &-circle,
92 | &-circle-outline {
93 | .btn-circle(@btn-prefix-cls);
94 | }
95 |
96 | &:before {
97 | position: absolute;
98 | top: -1px;
99 | left: -1px;
100 | bottom: -1px;
101 | right: -1px;
102 | background: #fff;
103 | opacity: 0.35;
104 | content: '';
105 | border-radius: inherit;
106 | z-index: 1;
107 | transition: opacity @transition-time;
108 | pointer-events: none;
109 | display: none;
110 | }
111 |
112 | &&-loading {
113 | pointer-events: none;
114 | position: relative;
115 |
116 | &:before {
117 | display: block;
118 | }
119 | }
120 |
121 | &-group {
122 | .btn-group(@btn-prefix-cls);
123 | }
124 |
125 | &-group-vertical {
126 | .btn-group-vertical(@btn-prefix-cls);
127 | }
128 | }
129 |
--------------------------------------------------------------------------------
/.electron-vue/webpack.web.config.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | process.env.BABEL_ENV = 'web'
4 |
5 | const path = require('path')
6 | const webpack = require('webpack')
7 |
8 | const BabiliWebpackPlugin = require('babili-webpack-plugin')
9 | const CopyWebpackPlugin = require('copy-webpack-plugin')
10 | const ExtractTextPlugin = require('extract-text-webpack-plugin')
11 | const HtmlWebpackPlugin = require('html-webpack-plugin')
12 |
13 | let webConfig = {
14 | devtool: '#cheap-module-eval-source-map',
15 | entry: {
16 | web: path.join(__dirname, '../src/renderer/main.js')
17 | },
18 | module: {
19 | rules: [
20 | {
21 | test: /\.css$/,
22 | use: ExtractTextPlugin.extract({
23 | fallback: 'style-loader',
24 | use: 'css-loader'
25 | })
26 | },
27 | {
28 | test: /\.html$/,
29 | use: 'vue-html-loader'
30 | },
31 | {
32 | test: /\.js$/,
33 | use: 'babel-loader',
34 | include: [ path.resolve(__dirname, '../src/renderer') ],
35 | exclude: /node_modules/
36 | },
37 | {
38 | test: /\.vue$/,
39 | use: {
40 | loader: 'vue-loader',
41 | options: {
42 | extractCSS: true,
43 | loaders: {
44 | sass: 'vue-style-loader!css-loader!sass-loader?indentedSyntax=1',
45 | scss: 'vue-style-loader!css-loader!sass-loader'
46 | }
47 | }
48 | }
49 | },
50 | {
51 | test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
52 | use: {
53 | loader: 'url-loader',
54 | query: {
55 | limit: 10000,
56 | name: 'imgs/[name].[ext]'
57 | }
58 | }
59 | },
60 | {
61 | test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
62 | use: {
63 | loader: 'url-loader',
64 | query: {
65 | limit: 10000,
66 | name: 'fonts/[name].[ext]'
67 | }
68 | }
69 | }
70 | ]
71 | },
72 | plugins: [
73 | new ExtractTextPlugin('styles.css'),
74 | new HtmlWebpackPlugin({
75 | filename: 'index.html',
76 | template: path.resolve(__dirname, '../src/index.ejs'),
77 | minify: {
78 | collapseWhitespace: true,
79 | removeAttributeQuotes: true,
80 | removeComments: true
81 | },
82 | nodeModules: false
83 | }),
84 | new webpack.DefinePlugin({
85 | 'process.env.IS_WEB': 'true'
86 | }),
87 | new webpack.HotModuleReplacementPlugin(),
88 | new webpack.NoEmitOnErrorsPlugin()
89 | ],
90 | output: {
91 | filename: '[name].js',
92 | path: path.join(__dirname, '../dist/web')
93 | },
94 | resolve: {
95 | alias: {
96 | '@': path.join(__dirname, '../src/renderer'),
97 | 'vue$': 'vue/dist/vue.esm.js'
98 | },
99 | extensions: ['.js', '.vue', '.json', '.css']
100 | },
101 | target: 'web'
102 | }
103 |
104 | /**
105 | * Adjust webConfig for production settings
106 | */
107 | if (process.env.NODE_ENV === 'production') {
108 | webConfig.devtool = ''
109 |
110 | webConfig.plugins.push(
111 | new BabiliWebpackPlugin(),
112 | new CopyWebpackPlugin([
113 | {
114 | from: path.join(__dirname, '../static'),
115 | to: path.join(__dirname, '../dist/web/static'),
116 | ignore: ['.*']
117 | }
118 | ]),
119 | new webpack.DefinePlugin({
120 | 'process.env.NODE_ENV': '"production"'
121 | }),
122 | new webpack.LoaderOptionsPlugin({
123 | minimize: true
124 | })
125 | )
126 | }
127 |
128 | module.exports = webConfig
129 |
--------------------------------------------------------------------------------
/src/renderer/assets/my-theme/components/transfer.less:
--------------------------------------------------------------------------------
1 | @transfer-prefix-cls: ~"@{css-prefix}transfer";
2 | @transfer-item-prefix-cls: ~"@{css-prefix}transfer-list-content-item";
3 |
4 | .@{transfer-prefix-cls} {
5 | position: relative;
6 | line-height: @line-height-base;
7 |
8 | &-list{
9 | display: inline-block;
10 | width: 180px;
11 | height: 210px;
12 | font-size: @font-size-small;
13 | vertical-align: middle;
14 | position: relative;
15 | padding-top: 35px;
16 |
17 | &-with-footer{
18 | padding-bottom: 35px;
19 | }
20 |
21 | &-header {
22 | padding: 8px 16px;
23 | background: @head-bg;
24 | color: @text-color;
25 | border: 1px solid @border-color-base;
26 | border-bottom: 1px solid @border-color-split;
27 | border-radius: @border-radius-base @border-radius-base 0 0;
28 | overflow: hidden;
29 | position: absolute;
30 | top: 0;
31 | left: 0;
32 | width: 100%;
33 |
34 | & > span{
35 | padding-left: 4px;
36 | }
37 |
38 | &-count {
39 | margin: 0 !important;
40 | float: right;
41 | }
42 | }
43 |
44 | &-body{
45 | height: 100%;
46 | border: 1px solid @border-color-base;
47 | border-top: none;
48 | border-radius: 0 0 @border-radius-base @border-radius-base;
49 | position: relative;
50 | overflow: hidden;
51 |
52 | &-with-search{
53 | padding-top: 34px;
54 | }
55 | &-with-footer{
56 | border-radius: 0;
57 | }
58 | }
59 |
60 | &-content{
61 | height: 100%;
62 | padding: 4px 0;
63 | overflow: auto;
64 |
65 | &-item{
66 | overflow: hidden;
67 | white-space: nowrap;
68 | text-overflow: ellipsis;
69 |
70 | & > span{
71 | padding-left: 4px;
72 | }
73 | }
74 |
75 | &-not-found{
76 | display: none;
77 | text-align: center;
78 | color: @btn-disable-color;
79 | }
80 | li&-not-found:only-child{
81 | display: block;
82 | }
83 | }
84 | &-body-with-search &-content{
85 | padding: 6px 0 0;
86 | }
87 |
88 | &-body-search-wrapper{
89 | padding: 8px 8px 0;
90 | position: absolute;
91 | top: 0;
92 | left: 0;
93 | right: 0;
94 | }
95 |
96 | &-search{
97 | position: relative;
98 | }
99 |
100 | &-footer{
101 | border: 1px solid @border-color-base;
102 | border-top: none;
103 | border-radius: 0 0 @border-radius-base @border-radius-base;
104 | position: absolute;
105 | bottom: 0;
106 | left: 0;
107 | right: 0;
108 |
109 | .clearfix();
110 | }
111 | }
112 | &-operation {
113 | display: inline-block;
114 | overflow: hidden;
115 | margin: 0 16px;
116 | vertical-align: middle;
117 |
118 | .@{btn-prefix-cls} {
119 | display: block;
120 | min-width: @btn-circle-size-small;
121 |
122 | &:first-child {
123 | margin-bottom: 12px;
124 | }
125 | }
126 | }
127 | }
128 | .select-item(@transfer-prefix-cls, @transfer-item-prefix-cls);
--------------------------------------------------------------------------------
/src/renderer/components/Page/MyProject.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 我的足迹
6 | 上次更新:{{ updateDate | dateFormat }}
7 |
15 | 暂无数据
16 |
17 |
22 | 确定要删除已有项目么?
23 |
24 |
25 |
26 |
27 |
28 |
95 |
96 |
97 |
145 |
--------------------------------------------------------------------------------
/.electron-vue/build.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | process.env.NODE_ENV = 'production'
4 |
5 | const { say } = require('cfonts')
6 | const chalk = require('chalk')
7 | const del = require('del')
8 | const packager = require('electron-packager')
9 | const webpack = require('webpack')
10 | const Multispinner = require('multispinner')
11 |
12 | const buildConfig = require('./build.config')
13 | const mainConfig = require('./webpack.main.config')
14 | const rendererConfig = require('./webpack.renderer.config')
15 | const webConfig = require('./webpack.web.config')
16 |
17 | const doneLog = chalk.bgGreen.white(' DONE ') + ' '
18 | const errorLog = chalk.bgRed.white(' ERROR ') + ' '
19 | const okayLog = chalk.bgBlue.white(' OKAY ') + ' '
20 | const isCI = process.env.CI || false
21 |
22 | if (process.env.BUILD_TARGET === 'clean') clean()
23 | else if (process.env.BUILD_TARGET === 'web') web()
24 | else build()
25 |
26 | function clean () {
27 | del.sync(['build/*', '!build/icons', '!build/icons/icon.*'])
28 | console.log(`\n${doneLog}\n`)
29 | process.exit()
30 | }
31 |
32 | function build () {
33 | greeting()
34 |
35 | del.sync(['dist/electron/*', '!.gitkeep'])
36 |
37 | const tasks = ['main', 'renderer']
38 | const m = new Multispinner(tasks, {
39 | preText: 'building',
40 | postText: 'process'
41 | })
42 |
43 | let results = ''
44 |
45 | m.on('success', () => {
46 | process.stdout.write('\x1B[2J\x1B[0f')
47 | console.log(`\n\n${results}`)
48 | console.log(`${okayLog}take it away ${chalk.yellow('`electron-packager`')}\n`)
49 | bundleApp()
50 | })
51 |
52 | pack(mainConfig).then(result => {
53 | results += result + '\n\n'
54 | m.success('main')
55 | }).catch(err => {
56 | m.error('main')
57 | console.log(`\n ${errorLog}failed to build main process`)
58 | console.error(`\n${err}\n`)
59 | process.exit(1)
60 | })
61 |
62 | pack(rendererConfig).then(result => {
63 | results += result + '\n\n'
64 | m.success('renderer')
65 | }).catch(err => {
66 | m.error('renderer')
67 | console.log(`\n ${errorLog}failed to build renderer process`)
68 | console.error(`\n${err}\n`)
69 | process.exit(1)
70 | })
71 | }
72 |
73 | function pack (config) {
74 | return new Promise((resolve, reject) => {
75 | webpack(config, (err, stats) => {
76 | if (err) reject(err.stack || err)
77 | else if (stats.hasErrors()) {
78 | let err = ''
79 |
80 | stats.toString({
81 | chunks: false,
82 | colors: true
83 | })
84 | .split(/\r?\n/)
85 | .forEach(line => {
86 | err += ` ${line}\n`
87 | })
88 |
89 | reject(err)
90 | } else {
91 | resolve(stats.toString({
92 | chunks: false,
93 | colors: true
94 | }))
95 | }
96 | })
97 | })
98 | }
99 |
100 | function bundleApp () {
101 | packager(buildConfig, (err, appPaths) => {
102 | if (err) {
103 | console.log(`\n${errorLog}${chalk.yellow('`electron-packager`')} says...\n`)
104 | console.log(err + '\n')
105 | } else {
106 | console.log(`\n${doneLog}\n`)
107 | }
108 | })
109 | }
110 |
111 | function web () {
112 | del.sync(['dist/web/*', '!.gitkeep'])
113 | webpack(webConfig, (err, stats) => {
114 | if (err || stats.hasErrors()) console.log(err)
115 |
116 | console.log(stats.toString({
117 | chunks: false,
118 | colors: true
119 | }))
120 |
121 | process.exit()
122 | })
123 | }
124 |
125 | function greeting () {
126 | const cols = process.stdout.columns
127 | let text = ''
128 |
129 | if (cols > 85) text = 'lets-build'
130 | else if (cols > 60) text = 'lets-|build'
131 | else text = false
132 |
133 | if (text && !isCI) {
134 | say(text, {
135 | colors: ['yellow'],
136 | font: 'simple3d',
137 | space: false
138 | })
139 | } else console.log(chalk.yellow.bold('\n lets-build'))
140 | console.log()
141 | }
142 |
--------------------------------------------------------------------------------
/src/renderer/assets/my-theme/animation/move.less:
--------------------------------------------------------------------------------
1 | .move-motion(@className, @keyframeName) {
2 | .make-motion(@className, @keyframeName);
3 | .@{className}-enter, .@{className}-appear {
4 | opacity: 0;
5 | animation-timing-function: @ease-in-out;
6 | }
7 | .@{className}-leave {
8 | animation-timing-function: @ease-in-out;
9 | }
10 | }
11 |
12 | .move-motion(move-up, ivuMoveUp);
13 | .move-motion(move-down, ivuMoveDown);
14 | .move-motion(move-left, ivuMoveLeft);
15 | .move-motion(move-right, ivuMoveRight);
16 |
17 | @keyframes ivuMoveDownIn {
18 | 0% {
19 | transform-origin: 0 0;
20 | transform: translateY(100%);
21 | opacity: 0;
22 | }
23 | 100% {
24 | transform-origin: 0 0;
25 | transform: translateY(0%);
26 | opacity: 1;
27 | }
28 | }
29 |
30 | @keyframes ivuMoveDownOut {
31 | 0% {
32 | transform-origin: 0 0;
33 | transform: translateY(0%);
34 | opacity: 1;
35 | }
36 | 100% {
37 | transform-origin: 0 0;
38 | transform: translateY(100%);
39 | opacity: 0;
40 | }
41 | }
42 |
43 | @keyframes ivuMoveLeftIn {
44 | 0% {
45 | transform-origin: 0 0;
46 | transform: translateX(-100%);
47 | opacity: 0;
48 | }
49 | 100% {
50 | transform-origin: 0 0;
51 | transform: translateX(0%);
52 | opacity: 1;
53 | }
54 | }
55 |
56 | @keyframes ivuMoveLeftOut {
57 | 0% {
58 | transform-origin: 0 0;
59 | transform: translateX(0%);
60 | opacity: 1;
61 | }
62 | 100% {
63 | transform-origin: 0 0;
64 | transform: translateX(-100%);
65 | opacity: 0;
66 | }
67 | }
68 |
69 | @keyframes ivuMoveRightIn {
70 | 0% {
71 | opacity: 0;
72 | transform-origin: 0 0;
73 | transform: translateX(100%);
74 | }
75 | 100% {
76 | opacity: 1;
77 | transform-origin: 0 0;
78 | transform: translateX(0%);
79 | }
80 | }
81 |
82 | @keyframes ivuMoveRightOut {
83 | 0% {
84 | transform-origin: 0 0;
85 | transform: translateX(0%);
86 | opacity: 1;
87 | }
88 | 100% {
89 | transform-origin: 0 0;
90 | transform: translateX(100%);
91 | opacity: 0;
92 | }
93 | }
94 |
95 | @keyframes ivuMoveUpIn {
96 | 0% {
97 | transform-origin: 0 0;
98 | transform: translateY(-100%);
99 | opacity: 0;
100 | }
101 | 100% {
102 | transform-origin: 0 0;
103 | transform: translateY(0%);
104 | opacity: 1;
105 | }
106 | }
107 |
108 | @keyframes ivuMoveUpOut {
109 | 0% {
110 | transform-origin: 0 0;
111 | transform: translateY(0%);
112 | opacity: 1;
113 | }
114 | 100% {
115 | transform-origin: 0 0;
116 | transform: translateY(-100%);
117 | opacity: 0;
118 | }
119 | }
120 |
121 | // specific transition for Notice
122 |
123 | .move-motion(move-notice, ivuMoveNotice);
124 | @import '../components/notice.less';
125 |
126 | @keyframes ivuMoveNoticeIn {
127 | 0% {
128 | opacity: 0;
129 | transform-origin: 0 0;
130 | transform: translateX(100%);
131 | }
132 | 100% {
133 | opacity: 1;
134 | transform-origin: 0 0;
135 | transform: translateX(0%);
136 | }
137 | }
138 |
139 | @keyframes ivuMoveNoticeOut {
140 | 0% {
141 | transform-origin: 0 0;
142 | transform: translateX(0%);
143 | opacity: 1;
144 | }
145 | 70% {
146 | transform-origin: 0 0;
147 | transform: translateX(100%);
148 | height: auto;
149 | padding: @notice-padding;
150 | margin-bottom: @notice-margin-bottom;
151 | opacity: 0;
152 | }
153 | 100% {
154 | transform-origin: 0 0;
155 | transform: translateX(100%);
156 | height: 0;
157 | padding: 0;
158 | margin-bottom: 0;
159 | opacity: 0;
160 | }
161 | }
162 |
--------------------------------------------------------------------------------
/src/renderer/assets/my-theme/components/carousel.less:
--------------------------------------------------------------------------------
1 | @carousel-prefix-cls: ~"@{css-prefix}carousel";
2 | @carousel-item-prefix-cls: ~"@{css-prefix}carousel-item";
3 |
4 | .@{carousel-prefix-cls} {
5 | position: relative;
6 | display: block;
7 | box-sizing: border-box;
8 | user-select: none;
9 | touch-action: pan-y;
10 | -webkit-tap-highlight-color: transparent;
11 |
12 | &-track, &-list {
13 | transform: translate3d(0, 0, 0);
14 | }
15 |
16 | &-list {
17 | position: relative;
18 | display: block;
19 | overflow: hidden;
20 |
21 | margin: 0;
22 | padding: 0;
23 | }
24 |
25 | &-track {
26 | position: relative;
27 | top: 0;
28 | left: 0;
29 | display: block;
30 |
31 | overflow: hidden;
32 |
33 | z-index: 1;
34 | }
35 |
36 | &-item {
37 | float: left;
38 | height: 100%;
39 | min-height: 1px;
40 | display: block;
41 | }
42 |
43 | &-arrow {
44 |
45 | border: none;
46 | outline: none;
47 |
48 | padding: 0;
49 | margin: 0;
50 |
51 | width: 36px;
52 | height: 36px;
53 | border-radius: 50%;
54 |
55 | cursor: pointer;
56 |
57 | display: none;
58 |
59 | position: absolute;
60 | top: 50%;
61 | z-index: 10;
62 | transform: translateY(-50%);
63 |
64 | transition: @transition-time;
65 | background-color: rgba(31, 45, 61, .11);
66 | color: #fff;
67 |
68 | &:hover {
69 | background-color: rgba(31, 45, 61, 0.5);
70 | }
71 |
72 | text-align: center;
73 | font-size: 1em;
74 |
75 | font-family: inherit;
76 | line-height: inherit;
77 |
78 | & > * {
79 | vertical-align: baseline;
80 | }
81 |
82 | &.left {
83 | left: 16px;
84 | }
85 |
86 | &.right {
87 | right: 16px;
88 | }
89 |
90 | &-always {
91 | display: inherit;
92 | }
93 |
94 | &-hover {
95 | display: inherit;
96 |
97 | opacity: 0;
98 | }
99 | }
100 |
101 | &:hover &-arrow-hover {
102 | opacity: 1;
103 | }
104 |
105 | &-dots {
106 | z-index: 10;
107 |
108 | @padding: 7px;
109 |
110 | display: none;
111 |
112 | position: relative;
113 | &-inside {
114 | display: block;
115 | position: absolute;
116 | bottom: 10px - @padding;
117 | }
118 |
119 | &-outside {
120 | display: block;
121 | margin-top: 10px - @padding;
122 | }
123 |
124 | list-style: none;
125 |
126 | text-align: center;
127 |
128 | padding: 0;
129 | width: 100%;
130 | height: 3px + @padding * 2;
131 |
132 | li {
133 | position: relative;
134 | display: inline-block;
135 |
136 | vertical-align: top;
137 | text-align: center;
138 |
139 | margin: 0 2px;
140 | padding: @padding 0;
141 |
142 | cursor: pointer;
143 |
144 | button {
145 | border: 0;
146 | cursor: pointer;
147 |
148 | background: #8391a5;
149 | opacity: 0.3;
150 |
151 | display: block;
152 | width: 16px;
153 | height: 3px;
154 |
155 | border-radius: 1px;
156 | outline: none;
157 |
158 | font-size: 0;
159 | color: transparent;
160 |
161 | transition: all .5s;
162 | }
163 |
164 | &:hover > button {
165 | opacity: 0.7;
166 | }
167 |
168 | &.@{carousel-prefix-cls}-active > button {
169 | opacity: 1;
170 | width: 24px;
171 | }
172 | }
173 | }
174 | }
175 |
--------------------------------------------------------------------------------
/src/renderer/assets/my-theme/components/poptip.less:
--------------------------------------------------------------------------------
1 | @poptip-prefix-cls: ~"@{css-prefix}poptip";
2 | @poptip-arrow: ~"@{poptip-prefix-cls}-arrow";
3 | @poptip-max-width: 250px;
4 | @poptip-arrow-width: 5px;
5 | @poptip-arrow-outer-width: (@poptip-arrow-width + 1);
6 | @poptip-distance: @poptip-arrow-width - 1 + 4;
7 | //@poptip-arrow-color: fadein(@border-color-base, 5%);
8 | @poptip-arrow-color: hsla(0,0%,85%,.5);
9 |
10 | .@{poptip-prefix-cls} {
11 | display: inline-block;
12 |
13 | &-rel{
14 | display: inline-block;
15 | position: relative;
16 | }
17 |
18 | &-title {
19 | margin: 0;
20 | padding: 8px 16px;
21 | position: relative;
22 |
23 | &:after{
24 | content: '';
25 | display: block;
26 | height: 1px;
27 | position: absolute;
28 | left: 8px;
29 | right: 8px;
30 | bottom: 0;
31 | background-color: @border-color-split;
32 | }
33 |
34 | &-inner{
35 | color: @title-color;
36 | font-size: @font-size-base;
37 | }
38 | }
39 |
40 | &-body{
41 | padding: 8px 16px;
42 |
43 | &-content{
44 | overflow: auto;
45 |
46 | &-inner{
47 | color: @text-color;
48 | }
49 | }
50 | }
51 |
52 | &-inner{
53 | width: 100%;
54 | background-color: #fff;
55 | background-clip: padding-box;
56 | //border: 1px solid @border-color-split;
57 | border-radius: @border-radius-small;
58 | box-shadow: @shadow-base;
59 | white-space: nowrap;
60 | }
61 |
62 | &-popper{
63 | min-width: 150px;
64 | font-size: @font-size-small;
65 | .popper(@poptip-arrow, @poptip-arrow-width, @poptip-distance, @poptip-arrow-color);
66 |
67 | &[x-placement^="top"] .@{poptip-arrow}:after {
68 | content: " ";
69 | bottom: 1px;
70 | margin-left: -@poptip-arrow-width;
71 | border-bottom-width: 0;
72 | border-top-color: #fff;
73 | }
74 |
75 | &[x-placement^="right"] .@{poptip-arrow}:after {
76 | content: " ";
77 | left: 1px;
78 | bottom: -@poptip-arrow-width;
79 | border-left-width: 0;
80 | border-right-color: #fff;
81 | }
82 |
83 | &[x-placement^="bottom"] .@{poptip-arrow}:after {
84 | content: " ";
85 | top: 1px;
86 | margin-left: -@poptip-arrow-width;
87 | border-top-width: 0;
88 | border-bottom-color: #fff;
89 | }
90 |
91 | &[x-placement^="left"] .@{poptip-arrow}:after {
92 | content: " ";
93 | right: 1px;
94 | border-right-width: 0;
95 | border-left-color: #fff;
96 | bottom: -@poptip-arrow-width;
97 | }
98 | }
99 |
100 | &-arrow{
101 | &, &:after{
102 | display: block;
103 | width: 0;
104 | height: 0;
105 | position: absolute;
106 | border-color: transparent;
107 | border-style: solid;
108 | }
109 | }
110 | &-arrow {
111 | border-width: @poptip-arrow-outer-width;
112 | }
113 | &-arrow:after{
114 | content: "";
115 | border-width: @poptip-arrow-width;
116 | }
117 |
118 | &-confirm &-popper{
119 | max-width: 300px;
120 | }
121 | &-confirm &-inner{
122 | white-space: normal;
123 | }
124 |
125 | &-confirm &-body{
126 | padding: 16px 16px 8px;
127 | .ivu-icon{
128 | font-size: 16px;
129 | color: @warning-color;
130 | line-height: 18px;
131 | position: absolute;
132 | }
133 |
134 | &-message{
135 | padding-left: 20px;
136 | }
137 | }
138 |
139 | &-confirm &-footer{
140 | text-align: right;
141 | padding: 8px 16px 16px;
142 | button {
143 | margin-left: 4px;
144 | }
145 | }
146 | }
--------------------------------------------------------------------------------
/src/renderer/components/Page/Login.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
iMap
4 |
5 |
6 |
7 |
8 |
9 |
12 |
15 |
16 |
17 |
18 |
19 |
108 |
109 |
110 |
154 |
--------------------------------------------------------------------------------
/src/renderer/assets/my-theme/components/tree.less:
--------------------------------------------------------------------------------
1 | @tree-prefix-cls: ~"@{css-prefix}tree";
2 |
3 | .@{tree-prefix-cls} {
4 | margin: 0;
5 | padding: 5px;
6 | font-size: @font-size-small;
7 | li {
8 | padding: 0;
9 | margin: 8px 0;
10 | list-style: none;
11 | white-space: nowrap;
12 | outline: 0;
13 | a[draggable],
14 | a[draggable="true"] {
15 | user-select: none;
16 | /* Required to make elements draggable in old WebKit */
17 | -khtml-user-drag: element;
18 | -webkit-user-drag: element;
19 | }
20 | &.drag-over {
21 | > a[draggable] {
22 | background-color: @primary-color;
23 | color: white;
24 | opacity: 0.8;
25 | }
26 | }
27 | &.drag-over-gap-top {
28 | > a[draggable] {
29 | border-top: 2px @primary-color solid;
30 | }
31 | }
32 | &.drag-over-gap-bottom {
33 | > a[draggable] {
34 | border-bottom: 2px @primary-color solid;
35 | }
36 | }
37 | &.filter-node {
38 | > a {
39 | color: @error-color!important;
40 | font-weight: bold!important;
41 | }
42 | }
43 | ul {
44 | margin: 0;
45 | padding: 0 0 0 18px;
46 | }
47 | a {
48 | display: inline-block;
49 | margin: 0;
50 | padding: 0 4px;
51 | border-radius: @btn-border-radius-small;
52 | cursor: pointer;
53 | text-decoration: none;
54 | vertical-align: top;
55 | color: @text-color;
56 | transition: all @transition-time @ease-in-out;
57 | &:hover {
58 | background-color: tint(@primary-color, 90%);
59 | }
60 | &.@{tree-prefix-cls}-node-selected {
61 | background-color: tint(@primary-color, 80%);
62 | }
63 | }
64 | .@{checkbox-prefix-cls}-wrapper{
65 | margin-right: 4px;
66 | }
67 | span {
68 | &.@{tree-prefix-cls}-switcher,
69 | &.@{tree-prefix-cls}-iconEle {
70 | display: inline-block;
71 | text-align: center;
72 | width: 16px;
73 | height: 16px;
74 | line-height: 16px;
75 | margin: 0;
76 | vertical-align: middle;
77 | border: 0 none;
78 | cursor: pointer;
79 | outline: none;
80 | }
81 | //&.@{tree-prefix-cls}-icon_loading {
82 | // &:after {
83 | // display: inline-block;
84 | // //.iconfont-font("\e6a1");
85 | // animation: loadingCircle 1s infinite linear;
86 | // color: @primary-color;
87 | // }
88 | //}
89 | &.@{tree-prefix-cls}-switcher {
90 | i{
91 | transition: all @transition-time @ease-in-out;
92 | }
93 | &.@{tree-prefix-cls}-switcher-noop {
94 | display: none;
95 | cursor: auto;
96 | i{
97 | display: none;
98 | }
99 | }
100 | &.@{tree-prefix-cls}-roots_open,
101 | &.@{tree-prefix-cls}-center_open,
102 | &.@{tree-prefix-cls}-bottom_open,
103 | &.@{tree-prefix-cls}-noline_open {
104 | i {
105 | transform: rotate(90deg);
106 | }
107 | }
108 | &.@{tree-prefix-cls}-roots_close,
109 | &.@{tree-prefix-cls}-center_close,
110 | &.@{tree-prefix-cls}-bottom_close,
111 | &.@{tree-prefix-cls}-noline_close {
112 |
113 | }
114 | }
115 | }
116 | }
117 | &-child-tree {
118 | display: none;
119 | &-open {
120 | display: block;
121 | }
122 | }
123 | &-treenode-disabled {
124 | >span,
125 | >a,
126 | >a span {
127 | color: @input-disabled-bg;
128 | cursor: not-allowed;
129 | }
130 | }
131 | &-icon__open {
132 | margin-right: 2px;
133 | vertical-align: top;
134 | }
135 | &-icon__close {
136 | margin-right: 2px;
137 | vertical-align: top;
138 | }
139 | }
--------------------------------------------------------------------------------
/src/renderer/components/Ui/AddPointModal.vue:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
11 | 添加地点
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
141 |
142 |
143 |
--------------------------------------------------------------------------------
/.electron-vue/dev-runner.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | const chalk = require('chalk')
4 | const electron = require('electron')
5 | const path = require('path')
6 | const { say } = require('cfonts')
7 | const { spawn } = require('child_process')
8 | const webpack = require('webpack')
9 | const WebpackDevServer = require('webpack-dev-server')
10 | const webpackHotMiddleware = require('webpack-hot-middleware')
11 |
12 | const mainConfig = require('./webpack.main.config')
13 | const rendererConfig = require('./webpack.renderer.config')
14 |
15 | let electronProcess = null
16 | let manualRestart = false
17 | let hotMiddleware
18 |
19 | function logStats (proc, data) {
20 | let log = ''
21 |
22 | log += chalk.yellow.bold(`┏ ${proc} Process ${new Array((19 - proc.length) + 1).join('-')}`)
23 | log += '\n\n'
24 |
25 | if (typeof data === 'object') {
26 | data.toString({
27 | colors: true,
28 | chunks: false
29 | }).split(/\r?\n/).forEach(line => {
30 | log += ' ' + line + '\n'
31 | })
32 | } else {
33 | log += ` ${data}\n`
34 | }
35 |
36 | log += '\n' + chalk.yellow.bold(`┗ ${new Array(28 + 1).join('-')}`) + '\n'
37 |
38 | console.log(log)
39 | }
40 |
41 | function startRenderer () {
42 | return new Promise((resolve, reject) => {
43 | rendererConfig.entry.renderer = [path.join(__dirname, 'dev-client')].concat(rendererConfig.entry.renderer)
44 |
45 | const compiler = webpack(rendererConfig)
46 | hotMiddleware = webpackHotMiddleware(compiler, {
47 | log: false,
48 | heartbeat: 2500
49 | })
50 |
51 | compiler.plugin('compilation', compilation => {
52 | compilation.plugin('html-webpack-plugin-after-emit', (data, cb) => {
53 | hotMiddleware.publish({ action: 'reload' })
54 | cb()
55 | })
56 | })
57 |
58 | compiler.plugin('done', stats => {
59 | logStats('Renderer', stats)
60 | })
61 |
62 | const server = new WebpackDevServer(
63 | compiler,
64 | {
65 | contentBase: path.join(__dirname, '../'),
66 | quiet: true,
67 | setup (app, ctx) {
68 | app.use(hotMiddleware)
69 | ctx.middleware.waitUntilValid(() => {
70 | resolve()
71 | })
72 | }
73 | }
74 | )
75 |
76 | server.listen(9080)
77 | })
78 | }
79 |
80 | function startMain () {
81 | return new Promise((resolve, reject) => {
82 | mainConfig.entry.main = [path.join(__dirname, '../src/main/index.dev.js')].concat(mainConfig.entry.main)
83 |
84 | const compiler = webpack(mainConfig)
85 |
86 | compiler.plugin('watch-run', (compilation, done) => {
87 | logStats('Main', chalk.white.bold('compiling...'))
88 | hotMiddleware.publish({ action: 'compiling' })
89 | done()
90 | })
91 |
92 | compiler.watch({}, (err, stats) => {
93 | if (err) {
94 | console.log(err)
95 | return
96 | }
97 |
98 | logStats('Main', stats)
99 |
100 | if (electronProcess && electronProcess.kill) {
101 | manualRestart = true
102 | process.kill(electronProcess.pid)
103 | electronProcess = null
104 | startElectron()
105 |
106 | setTimeout(() => {
107 | manualRestart = false
108 | }, 5000)
109 | }
110 |
111 | resolve()
112 | })
113 | })
114 | }
115 |
116 | function startElectron () {
117 | electronProcess = spawn(electron, ['--inspect=5858', path.join(__dirname, '../dist/electron/main.js')])
118 |
119 | electronProcess.stdout.on('data', data => {
120 | electronLog(data, 'blue')
121 | })
122 | electronProcess.stderr.on('data', data => {
123 | electronLog(data, 'red')
124 | })
125 |
126 | electronProcess.on('close', () => {
127 | if (!manualRestart) process.exit()
128 | })
129 | }
130 |
131 | function electronLog (data, color) {
132 | let log = ''
133 | data = data.toString().split(/\r?\n/)
134 | data.forEach(line => {
135 | log += ` ${line}\n`
136 | })
137 | if (/[0-9A-z]+/.test(log)) {
138 | console.log(
139 | chalk[color].bold('┏ Electron -------------------') +
140 | '\n\n' +
141 | log +
142 | chalk[color].bold('┗ ----------------------------') +
143 | '\n'
144 | )
145 | }
146 | }
147 |
148 | function greeting () {
149 | const cols = process.stdout.columns
150 | let text = ''
151 |
152 | if (cols > 104) text = 'electron-vue'
153 | else if (cols > 76) text = 'electron-|vue'
154 | else text = false
155 |
156 | if (text) {
157 | say(text, {
158 | colors: ['yellow'],
159 | font: 'simple3d',
160 | space: false
161 | })
162 | } else console.log(chalk.yellow.bold('\n electron-vue'))
163 | console.log(chalk.blue(' getting ready...') + '\n')
164 | }
165 |
166 | function init () {
167 | greeting()
168 |
169 | Promise.all([startRenderer(), startMain()])
170 | .then(() => {
171 | startElectron()
172 | })
173 | .catch(err => {
174 | console.error(err)
175 | })
176 | }
177 |
178 | init()
179 |
--------------------------------------------------------------------------------
/.electron-vue/webpack.renderer.config.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | process.env.BABEL_ENV = 'renderer'
4 |
5 | const path = require('path')
6 | const { dependencies } = require('../package.json')
7 | const webpack = require('webpack')
8 |
9 | const BabiliWebpackPlugin = require('babili-webpack-plugin')
10 | const CopyWebpackPlugin = require('copy-webpack-plugin')
11 | const ExtractTextPlugin = require('extract-text-webpack-plugin')
12 | const HtmlWebpackPlugin = require('html-webpack-plugin')
13 |
14 | /**
15 | * List of node_modules to include in webpack bundle
16 | *
17 | * Required for specific packages like Vue UI libraries
18 | * that provide pure *.vue files that need compiling
19 | * https://simulatedgreg.gitbooks.io/electron-vue/content/en/webpack-configurations.html#white-listing-externals
20 | */
21 | let whiteListedModules = ['vue']
22 |
23 | let rendererConfig = {
24 | devtool: '#cheap-module-eval-source-map',
25 | entry: {
26 | renderer: path.join(__dirname, '../src/renderer/main.js')
27 | },
28 | externals: [
29 | ...Object.keys(dependencies || {}).filter(d => !whiteListedModules.includes(d))
30 | ],
31 | module: {
32 | rules: [
33 | {
34 | test: /\.css$/,
35 | use: ExtractTextPlugin.extract({
36 | fallback: 'style-loader',
37 | use: 'css-loader'
38 | })
39 | },
40 | {
41 | test: /\.html$/,
42 | use: 'vue-html-loader'
43 | },
44 | {
45 | test: /\.js$/,
46 | use: 'babel-loader',
47 | exclude: /node_modules/
48 | },
49 | {
50 | test: /\.node$/,
51 | use: 'node-loader'
52 | },
53 | {
54 | test: /\.vue$/,
55 | use: {
56 | loader: 'vue-loader',
57 | options: {
58 | extractCSS: process.env.NODE_ENV === 'production',
59 | loaders: {
60 | sass: 'vue-style-loader!css-loader!sass-loader?indentedSyntax=1',
61 | scss: 'vue-style-loader!css-loader!sass-loader'
62 | }
63 | }
64 | }
65 | },
66 | {
67 | test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
68 | use: {
69 | loader: 'url-loader',
70 | query: {
71 | limit: 10000,
72 | name: 'imgs/[name]--[folder].[ext]'
73 | }
74 | }
75 | },
76 | {
77 | test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
78 | loader: 'url-loader',
79 | options: {
80 | limit: 10000,
81 | name: 'media/[name]--[folder].[ext]'
82 | }
83 | },
84 | {
85 | test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
86 | use: {
87 | loader: 'url-loader',
88 | query: {
89 | limit: 10000,
90 | name: 'fonts/[name]--[folder].[ext]'
91 | }
92 | }
93 | }
94 | ]
95 | },
96 | node: {
97 | __dirname: process.env.NODE_ENV !== 'production',
98 | __filename: process.env.NODE_ENV !== 'production'
99 | },
100 | plugins: [
101 | new ExtractTextPlugin('styles.css'),
102 | new HtmlWebpackPlugin({
103 | filename: 'index.html',
104 | template: path.resolve(__dirname, '../src/index.ejs'),
105 | minify: {
106 | collapseWhitespace: true,
107 | removeAttributeQuotes: true,
108 | removeComments: true
109 | },
110 | nodeModules: process.env.NODE_ENV !== 'production'
111 | ? path.resolve(__dirname, '../node_modules')
112 | : false
113 | }),
114 | new webpack.HotModuleReplacementPlugin(),
115 | new webpack.NoEmitOnErrorsPlugin()
116 | ],
117 | output: {
118 | filename: '[name].js',
119 | libraryTarget: 'commonjs2',
120 | path: path.join(__dirname, '../dist/electron')
121 | },
122 | resolve: {
123 | alias: {
124 | '@': path.join(__dirname, '../src/renderer'),
125 | 'vue$': 'vue/dist/vue.esm.js'
126 | },
127 | extensions: ['.js', '.vue', '.json', '.css', '.node']
128 | },
129 | target: 'electron-renderer'
130 | }
131 |
132 | /**
133 | * Adjust rendererConfig for development settings
134 | */
135 | if (process.env.NODE_ENV !== 'production') {
136 | rendererConfig.plugins.push(
137 | new webpack.DefinePlugin({
138 | '__static': `"${path.join(__dirname, '../static').replace(/\\/g, '\\\\')}"`
139 | })
140 | )
141 | }
142 |
143 | /**
144 | * Adjust rendererConfig for production settings
145 | */
146 | if (process.env.NODE_ENV === 'production') {
147 | rendererConfig.devtool = ''
148 |
149 | rendererConfig.plugins.push(
150 | new BabiliWebpackPlugin(),
151 | new CopyWebpackPlugin([
152 | {
153 | from: path.join(__dirname, '../static'),
154 | to: path.join(__dirname, '../dist/electron/static'),
155 | ignore: ['.*']
156 | }
157 | ]),
158 | new webpack.DefinePlugin({
159 | 'process.env.NODE_ENV': '"production"'
160 | }),
161 | new webpack.LoaderOptionsPlugin({
162 | minimize: true
163 | })
164 | )
165 | }
166 |
167 | module.exports = rendererConfig
168 |
--------------------------------------------------------------------------------
/src/renderer/assets/my-theme/components/input-number.less:
--------------------------------------------------------------------------------
1 | @input-number-prefix-cls: ~"@{css-prefix}input-number";
2 |
3 | .handler-disabled() {
4 | opacity: 0.72;
5 | color: #ccc !important;
6 | cursor: @cursor-disabled;
7 | }
8 |
9 | .@{input-number-prefix-cls} {
10 | @radius-wrap: 0 @btn-border-radius @btn-border-radius 0;
11 |
12 | .input;
13 | margin: 0;
14 | padding: 0;
15 | width: 80px;
16 | height: @input-height-base;
17 | line-height: @input-height-base;
18 | vertical-align: middle;
19 | border: 1px solid @border-color-base;
20 | border-radius: @btn-border-radius;
21 | overflow: hidden;
22 |
23 | &-handler-wrap {
24 | width: 22px;
25 | height: 100%;
26 | border-left: 1px solid @border-color-base;
27 | border-radius: @radius-wrap;
28 | background: #fff;
29 | position: absolute;
30 | top: 0;
31 | right: 0;
32 | opacity: 0;
33 | transition: opacity @transition-time @ease-in-out;
34 | }
35 |
36 | &:hover &-handler-wrap {
37 | opacity: 1;
38 | }
39 |
40 | &-handler-up {
41 | cursor: pointer;
42 | &-inner {
43 | top: 1px;
44 | }
45 | }
46 |
47 | &-handler-down {
48 | border-top: 1px solid @border-color-base;
49 | top: -1px;
50 | cursor: pointer;
51 | }
52 |
53 | &-handler {
54 | display: block;
55 | width: 100%;
56 | height: @input-height-base / 2;
57 | line-height: 0;
58 | text-align: center;
59 | overflow: hidden;
60 | color: #999;
61 | position: relative;
62 |
63 | &:hover &-up-inner,
64 | &:hover &-down-inner {
65 | color: tint(@primary-color, 20%);
66 | }
67 | }
68 |
69 | &-handler-up-inner,
70 | &-handler-down-inner {
71 | width: 12px;
72 | height: 12px;
73 | line-height: 12px;
74 | font-size: 14px;
75 | color: #999;
76 | user-select: none;
77 | position: absolute;
78 | right: 4px;
79 | transition: all @transition-time linear;
80 | }
81 |
82 | &:hover {
83 | .hover();
84 | }
85 |
86 | &-focused {
87 | .active();
88 | }
89 |
90 | &-disabled {
91 | .disabled();
92 | }
93 |
94 | &-input-wrap {
95 | overflow: hidden;
96 | height: @input-height-base;
97 | }
98 |
99 | &-input {
100 | width: 100%;
101 | height: @input-height-base;
102 | line-height: @input-height-base;
103 | padding: 0 7px;
104 | text-align: left;
105 | outline: 0;
106 | -moz-appearance: textfield;
107 | color: #666;
108 | border: 0;
109 | border-radius: @btn-border-radius;
110 | transition: all @transition-time linear;
111 |
112 | &[disabled] {
113 | .disabled();
114 | }
115 | }
116 |
117 | &-large {
118 | padding: 0;
119 | .@{input-number-prefix-cls}-input-wrap {
120 | height: @input-height-large;
121 | }
122 | .@{input-number-prefix-cls}-handler {
123 | height: @input-height-large / 2;
124 | }
125 |
126 | input {
127 | height: @input-height-large;
128 | line-height: @input-height-large;
129 | }
130 |
131 | .@{input-number-prefix-cls}-handler-up-inner {
132 | top: 2px;
133 | }
134 | .@{input-number-prefix-cls}-handler-down-inner {
135 | bottom: 2px;
136 | }
137 | }
138 |
139 | &-small {
140 | padding: 0;
141 | .@{input-number-prefix-cls}-input-wrap {
142 | height: @input-height-small;
143 | }
144 | .@{input-number-prefix-cls}-handler {
145 | height: @input-height-small / 2;
146 | }
147 |
148 | input {
149 | height: @input-height-small;
150 | line-height: @input-height-small;
151 | margin-top: -1px;
152 | vertical-align: top;
153 | }
154 | .@{input-number-prefix-cls}-handler-up-inner {
155 | top: -1px;
156 | }
157 | .@{input-number-prefix-cls}-handler-down-inner {
158 | bottom: -1px;
159 | }
160 | }
161 |
162 |
163 |
164 | &-handler-down-disabled,
165 | &-handler-up-disabled,
166 | &-disabled {
167 | .@{input-number-prefix-cls}-handler-down-inner,
168 | .@{input-number-prefix-cls}-handler-up-inner {
169 | .handler-disabled();
170 | }
171 | }
172 |
173 | &-disabled {
174 | .@{input-number-prefix-cls}-input {
175 | opacity: 0.72;
176 | cursor: @cursor-disabled;
177 | background-color: #f3f3f3;
178 | }
179 | .@{input-number-prefix-cls}-handler-wrap {
180 | display: none;
181 | }
182 | .@{input-number-prefix-cls}-handler {
183 | .handler-disabled();
184 | }
185 | }
186 | }
187 |
188 | .@{form-item-prefix-cls}-error {
189 | .@{input-number-prefix-cls}{
190 | .input-error;
191 | &-focused {
192 | .active-error;
193 | }
194 | }
195 | }
--------------------------------------------------------------------------------
/src/renderer/assets/my-theme/components/tag.less:
--------------------------------------------------------------------------------
1 | @tag-prefix-cls: ~"@{css-prefix}tag";
2 | @tag-close-prefix-cls: ivu-icon-ios-close-empty;
3 |
4 | .@{tag-prefix-cls} {
5 | display: inline-block;
6 | height: 22px;
7 | line-height: 22px;
8 | margin: 2px 4px 2px 0;
9 | padding: 0 8px;
10 | border: 1px solid @border-color-split;
11 | border-radius: @btn-border-radius-small;
12 | background: @background-color-base;
13 | font-size: @tag-font-size;
14 | vertical-align: middle;
15 | opacity: 1;
16 | overflow: hidden;
17 | cursor: pointer;
18 | //transition: all @transition-time @ease-in-out;
19 |
20 | &-dot{
21 | height: 32px;
22 | line-height: 32px;
23 | border: 1px solid @border-color-split !important;
24 | color: @text-color !important;
25 | background: #fff !important;
26 | padding: 0 12px;
27 |
28 | &-inner{
29 | display: inline-block;
30 | width: 12px;
31 | height: 12px;
32 | margin-right: 8px;
33 | border-radius: 50%;
34 | background: @border-color-split;
35 | position: relative;
36 | top: 1px;
37 | }
38 | .@{tag-close-prefix-cls} {
39 | color: #666 !important;
40 | margin-left: 12px !important;
41 | }
42 | }
43 |
44 | &-border{
45 | height: 24px;
46 | line-height: 24px;
47 | border: 1px solid @border-color-split !important;
48 | color: @text-color !important;
49 | background: #fff !important;
50 | position: relative;
51 |
52 | .@{tag-close-prefix-cls} {
53 | color: #666 !important;
54 | margin-left: 12px !important;
55 | }
56 |
57 | &:after{
58 | content: "";
59 | display: none;
60 | width: 1px;
61 | background: @border-color-split;
62 | position: absolute;
63 | top: 0;
64 | bottom: 0;
65 | right: 22px;
66 | }
67 |
68 | &.@{tag-prefix-cls}-closable {
69 | &:after{
70 | display: block;
71 | }
72 | .@{tag-close-prefix-cls} {
73 | margin-left: 18px !important;
74 | }
75 | }
76 |
77 | &.@{tag-prefix-cls}-blue {
78 | color: @link-color !important;
79 | border: 1px solid @link-color !important;
80 |
81 | &:after{
82 | background: @link-color;
83 | }
84 | .@{tag-close-prefix-cls}{
85 | color: @link-color !important;
86 | }
87 | }
88 | &.@{tag-prefix-cls}-green {
89 | color: @success-color !important;
90 | border: 1px solid @success-color !important;
91 |
92 | &:after{
93 | background: @success-color;
94 | }
95 | .@{tag-close-prefix-cls}{
96 | color: @success-color !important;
97 | }
98 | }
99 | &.@{tag-prefix-cls}-yellow {
100 | color: @warning-color !important;
101 | border: 1px solid @warning-color !important;
102 |
103 | &:after{
104 | background: @warning-color;
105 | }
106 | .@{tag-close-prefix-cls}{
107 | color: @warning-color !important;
108 | }
109 | }
110 | &.@{tag-prefix-cls}-red {
111 | color: @error-color !important;
112 | border: 1px solid @error-color !important;
113 |
114 | &:after{
115 | background: @error-color;
116 | }
117 | .@{tag-close-prefix-cls}{
118 | color: @error-color !important;
119 | }
120 | }
121 | }
122 |
123 | &:hover {
124 | opacity: 0.85;
125 | }
126 |
127 | &,
128 | a,
129 | a:hover {
130 | color: @text-color;
131 | }
132 |
133 | &-text {
134 | a:first-child:last-child {
135 | display: inline-block;
136 | margin: 0 -8px;
137 | padding: 0 8px;
138 | }
139 | }
140 |
141 | .@{tag-close-prefix-cls} {
142 | .iconfont-size-under-12px(20px);
143 | cursor: pointer;
144 | margin-left: 8px;
145 | color: #666;
146 | opacity: 0.66;
147 | position: relative;
148 | top: 1px;
149 | //transition: all @transition-time @ease-in-out;
150 |
151 | &:hover {
152 | opacity: 1;
153 | }
154 | }
155 |
156 | &-blue,
157 | &-green,
158 | &-yellow,
159 | &-red {
160 | border: 0;
161 | &,
162 | a,
163 | a:hover,
164 | .@{tag-close-prefix-cls},
165 | .@{tag-close-prefix-cls}:hover {
166 | color: #fff;
167 | }
168 | }
169 |
170 | &-blue,
171 | &-blue&-dot &-dot-inner
172 | {
173 | background: @link-color;
174 | }
175 |
176 | &-green,
177 | &-green&-dot &-dot-inner
178 | {
179 | background: @success-color;
180 | }
181 |
182 | &-yellow,
183 | &-yellow&-dot &-dot-inner
184 | {
185 | background: @warning-color;
186 | }
187 |
188 | &-red,
189 | &-red&-dot &-dot-inner
190 | {
191 | background: @error-color;
192 | }
193 | }
194 |
--------------------------------------------------------------------------------
/src/renderer/assets/my-theme/mixins/checkbox.less:
--------------------------------------------------------------------------------
1 | .checkboxFn(@checkbox-prefix-cls: ~"@{css-prefix}checkbox") {
2 | @checkbox-inner-prefix-cls: ~"@{checkbox-prefix-cls}-inner";
3 |
4 | // 普通状态
5 | .@{checkbox-prefix-cls} {
6 | display: inline-block;
7 | vertical-align: middle;
8 | white-space: nowrap;
9 | cursor: pointer;
10 | outline: none;
11 | line-height: 1;
12 | position: relative;
13 |
14 | &-disabled{
15 | cursor: @cursor-disabled;
16 | }
17 |
18 | &:hover {
19 | .@{checkbox-inner-prefix-cls} {
20 | border-color: #bcbcbc;
21 | }
22 | }
23 |
24 | &-inner {
25 | display: inline-block;
26 | width: 14px;
27 | height: 14px;
28 | position: relative;
29 | top: 0;
30 | left: 0;
31 | border: 1px solid @border-color-base;
32 | border-radius: 2px;
33 | background-color: #fff;
34 | transition: border-color @transition-time @ease-in-out, background-color @transition-time @ease-in-out;
35 |
36 | &:after {
37 | content: '';
38 | display: table;
39 | width: 4px;
40 | height: 8px;
41 | position: absolute;
42 | top: 1px;
43 | left: 4px;
44 | border: 2px solid #fff;
45 | border-top: 0;
46 | border-left: 0;
47 | transform: rotate(45deg) scale(0);
48 | transition: all @transition-time @ease-in-out;
49 | }
50 | }
51 |
52 | &-input {
53 | width: 100%;
54 | height: 100%;
55 | position: absolute;
56 | top: 0;
57 | bottom: 0;
58 | left: 0;
59 | right: 0;
60 | z-index: 1;
61 | cursor: pointer;
62 | opacity: 0;
63 |
64 | &[disabled]{
65 | cursor: @cursor-disabled;
66 | }
67 | }
68 | }
69 |
70 | // 选中状态
71 | .@{checkbox-prefix-cls}-checked {
72 |
73 | &:hover {
74 | .@{checkbox-inner-prefix-cls} {
75 | border-color: @primary-color;
76 | }
77 | }
78 |
79 | .@{checkbox-inner-prefix-cls} {
80 | border-color: @primary-color;
81 | background-color: @primary-color;
82 |
83 | &:after {
84 | content: '';
85 | display: table;
86 | width: 4px;
87 | height: 8px;
88 | position: absolute;
89 | top: 1px;
90 | left: 4px;
91 | border: 2px solid #fff;
92 | border-top: 0;
93 | border-left: 0;
94 | transform: rotate(45deg) scale(1);
95 | transition: all @transition-time @ease-in-out;
96 | }
97 | }
98 | }
99 |
100 | // 禁用
101 | .@{checkbox-prefix-cls}-disabled {
102 | &.@{checkbox-prefix-cls}-checked {
103 | &:hover {
104 | .@{checkbox-inner-prefix-cls} {
105 | border-color: @border-color-base;
106 | }
107 | }
108 |
109 | .@{checkbox-inner-prefix-cls} {
110 | background-color: #f3f3f3;
111 | border-color: @border-color-base;
112 |
113 | &:after {
114 | animation-name: none;
115 | border-color: #ccc;
116 | }
117 | }
118 | }
119 |
120 | &:hover {
121 | .@{checkbox-inner-prefix-cls} {
122 | border-color: @border-color-base;
123 | }
124 | }
125 |
126 | .@{checkbox-inner-prefix-cls} {
127 | border-color: @border-color-base;
128 | background-color: #f3f3f3;
129 | &:after {
130 | animation-name: none;
131 | border-color: #f3f3f3;
132 | }
133 | }
134 |
135 | .@{checkbox-inner-prefix-cls}-input {
136 | cursor: default;
137 | }
138 |
139 | & + span {
140 | color: #ccc;
141 | cursor: @cursor-disabled;
142 | }
143 | }
144 |
145 | // 半选状态
146 | .@{checkbox-prefix-cls}-indeterminate{
147 | .@{checkbox-inner-prefix-cls}:after{
148 | content: '';
149 | width: 8px;
150 | height: 1px;
151 | transform: scale(1);
152 | position: absolute;
153 | left: 2px;
154 | top: 5px;
155 | }
156 |
157 | &:hover {
158 | .@{checkbox-inner-prefix-cls} {
159 | border-color: @primary-color;
160 | }
161 | }
162 | .@{checkbox-inner-prefix-cls}{
163 | background-color: @primary-color;
164 | border-color: @primary-color;
165 | }
166 | }
167 |
168 | .@{checkbox-prefix-cls}-wrapper {
169 | cursor: pointer;
170 | font-size: @font-size-small;
171 | display: inline-block;
172 | margin-right: 8px;
173 | &-disabled{
174 | cursor: @cursor-disabled;
175 | }
176 | }
177 |
178 | .@{checkbox-prefix-cls}-wrapper + span,
179 | .@{checkbox-prefix-cls} + span {
180 | //margin-left: 4px;
181 | margin-right: 4px;
182 | }
183 |
184 | .@{checkbox-prefix-cls}-group {
185 | font-size: @font-size-base;
186 | &-item {
187 | display: inline-block;
188 | }
189 | }
190 | }
191 |
--------------------------------------------------------------------------------
/src/renderer/assets/my-theme/components/tabs.less:
--------------------------------------------------------------------------------
1 | @tabs-prefix-cls: ~"@{css-prefix}tabs";
2 |
3 | .@{tabs-prefix-cls} {
4 | box-sizing: border-box;
5 | position: relative;
6 | overflow: hidden;
7 | color: @text-color;
8 | .clearfix;
9 |
10 | &-bar {
11 | outline: none;
12 | }
13 |
14 | &-ink-bar {
15 | height: 2px;
16 | box-sizing: border-box;
17 | background-color: @primary-color;
18 | position: absolute;
19 | left: 0;
20 | bottom: 1px;
21 | z-index: 1;
22 | transition: transform .3s @ease-in-out;
23 | transform-origin: 0 0;
24 | }
25 |
26 | &-bar {
27 | border-bottom: 1px solid @border-color-base;
28 | margin-bottom: 16px;
29 | }
30 |
31 | &-nav-container {
32 | margin-bottom: -1px;
33 | line-height: @line-height-base;
34 | font-size: @font-size-base;
35 | box-sizing: border-box;
36 | white-space: nowrap;
37 | overflow: hidden;
38 | position: relative;
39 | .clearfix;
40 | }
41 |
42 | &-nav-container-scrolling {
43 | padding-left: 32px;
44 | padding-right: 32px;
45 | }
46 |
47 | &-nav-wrap {
48 | overflow: hidden;
49 | margin-bottom: -1px;
50 | }
51 |
52 | &-nav-scroll {
53 | overflow: hidden;
54 | white-space: nowrap;
55 | }
56 |
57 | &-nav {
58 | padding-left: 0;
59 | margin: 0;
60 | float: left;
61 | list-style: none;
62 | box-sizing: border-box;
63 | position: relative;
64 | transition: transform 0.5s @ease-in-out;
65 |
66 | &:before,
67 | &:after {
68 | display: table;
69 | content: " ";
70 | }
71 |
72 | &:after {
73 | clear: both;
74 | }
75 |
76 | .@{tabs-prefix-cls}-tab-disabled {
77 | pointer-events: none;
78 | cursor: default;
79 | color: #ccc;
80 | }
81 |
82 | .@{tabs-prefix-cls}-tab {
83 | display: inline-block;
84 | height: 100%;
85 | padding: 8px 16px;
86 | margin-right: 16px;
87 | box-sizing: border-box;
88 | cursor: pointer;
89 | text-decoration: none;
90 | position: relative;
91 | transition: color .3s @ease-in-out;
92 |
93 | &:hover {
94 | color: @link-hover-color;
95 | }
96 |
97 | &:active {
98 | color: @link-active-color;
99 | }
100 | .@{css-prefix-iconfont} {
101 | width: 14px;
102 | height: 14px;
103 | margin-right: 8px;
104 | }
105 | }
106 |
107 | .@{tabs-prefix-cls}-tab-active {
108 | color: @primary-color;
109 | }
110 | }
111 | &-mini &-nav-container {
112 | font-size: @font-size-base;
113 | }
114 |
115 | &-mini &-tab {
116 | margin-right: 0;
117 | padding: 8px 16px;
118 | font-size: @font-size-small;
119 | }
120 |
121 | & {
122 | .@{tabs-prefix-cls}-content-animated {
123 | display: flex;
124 | flex-direction: row;
125 | will-change: transform;
126 | transition: transform .3s @ease-in-out;
127 | }
128 |
129 | .@{tabs-prefix-cls}-tabpane {
130 | flex-shrink: 0;
131 | width: 100%;
132 | transition: opacity .3s;
133 | opacity: 1;
134 | }
135 |
136 | .@{tabs-prefix-cls}-tabpane-inactive {
137 | opacity: 0;
138 | height: 0;
139 | }
140 | }
141 |
142 | // card style
143 | &&-card > &-bar &-nav-container {
144 | height: 32px;
145 | }
146 | &&-card > &-bar &-ink-bar {
147 | visibility: hidden;
148 | }
149 | &&-card > &-bar &-tab {
150 | margin: 0;
151 | margin-right: 4px;
152 | height: 31px;
153 | padding: 5px 16px 4px;
154 | border: 1px solid @border-color-base;
155 | border-bottom: 0;
156 | border-radius: @btn-border-radius @btn-border-radius 0 0;
157 | transition: all 0.3s @ease-in-out;
158 | background: @table-thead-bg;
159 | }
160 | &&-card > &-bar &-tab-active {
161 | height: 32px;
162 | padding-bottom: 5px;
163 | background: #fff;
164 | transform: translateZ(0);
165 | border-color: @border-color-base;
166 | color: @primary-color;
167 | }
168 | &&-card > &-bar &-nav-wrap {
169 | margin-bottom: 0;
170 | }
171 | &&-card > &-bar &-tab .@{css-prefix-iconfont}-ios-close-empty {
172 | width: 0;
173 | height: 22px;
174 | font-size: 22px;
175 | margin-right: 0;
176 | color: @legend-color;
177 | text-align: right;
178 | vertical-align: middle;
179 | overflow: hidden;
180 | position: relative;
181 | top: -1px;
182 | transform-origin: 100% 50%;
183 | transition: all 0.3s @ease-in-out;
184 | &:hover {
185 | color: #444;
186 | }
187 | }
188 |
189 | &&-card > &-bar &-tab-active .@{css-prefix-iconfont}-ios-close-empty,
190 | &&-card > &-bar &-tab:hover .@{css-prefix-iconfont}-ios-close-empty {
191 | width: 14px;
192 | transform: translateZ(0);
193 | }
194 | }
195 |
196 | .@{tabs-prefix-cls}-no-animation{
197 | .@{tabs-prefix-cls}-content {
198 | transform: none!important;
199 |
200 | > .@{tabs-prefix-cls}-tabpane-inactive {
201 | display: none;
202 | }
203 | }
204 | }
--------------------------------------------------------------------------------
/src/renderer/assets/my-theme/components/time-picker.less:
--------------------------------------------------------------------------------
1 | @time-picker-prefix-cls: ~"@{css-prefix}time-picker";
2 | @time-picker-cells-width-base: 56px;
3 | @time-picker-cells-width-with-date-base: 72px;
4 | @time-picker-cells-width: @time-picker-cells-width-base * 2;
5 | @time-picker-cells-width-with-seconds: @time-picker-cells-width-base *3;
6 | @time-picker-cells-width-with-date: @time-picker-cells-width-with-date-base * 2;
7 | @time-picker-cells-width-with-date-with-seconds: @time-picker-cells-width-with-date-base * 3;
8 |
9 | .@{time-picker-prefix-cls} {
10 | &-cells{
11 | min-width: @time-picker-cells-width;
12 | &-with-seconds{
13 | min-width: @time-picker-cells-width-with-seconds;
14 | }
15 |
16 | &-list{
17 | width: @time-picker-cells-width-base;
18 | max-height: 144px;
19 | float: left;
20 | overflow: hidden;
21 | border-left: 1px solid @border-color-split;
22 | position: relative;
23 | &:hover{
24 | overflow-y: auto;
25 | }
26 |
27 | &:first-child{
28 | border-left: none;
29 | border-radius: @btn-border-radius 0 0 @btn-border-radius;
30 | }
31 | &:last-child{
32 | border-radius: 0 @btn-border-radius @btn-border-radius 0;
33 | }
34 | ul{
35 | width: 100%;
36 | margin: 0;
37 | padding: 0 0 120px 0;
38 | list-style: none;
39 | li{
40 | width: 100%;
41 | height: 24px;
42 | line-height: 24px;
43 | margin: 0;
44 | padding: 0 0 0 16px;
45 | box-sizing: content-box;
46 | text-align: left;
47 | user-select: none;
48 | cursor: pointer;
49 | list-style: none;
50 | transition: background @transition-time @ease-in-out;
51 |
52 | }
53 | }
54 | }
55 | &-cell{
56 | &:hover{
57 | background: @background-color-select-hover;
58 | }
59 | &-disabled {
60 | color: @btn-disable-color;
61 | cursor: @cursor-disabled;
62 |
63 | &:hover {
64 | color: @btn-disable-color;
65 | background-color: #fff;
66 | cursor: @cursor-disabled;
67 | }
68 | }
69 | &-selected ,&-selected:hover{
70 | color: @primary-color;
71 | background: @background-color-select-hover;
72 | }
73 | }
74 | }
75 |
76 | &-header{
77 | height: 32px;
78 | line-height: 32px;
79 | text-align: center;
80 | border-bottom: 1px solid @border-color-split;
81 | }
82 |
83 | &-with-range{
84 | .@{picker-prefix-cls}-panel{
85 | &-body{
86 | min-width: @time-picker-cells-width * 2 + 4px;
87 | }
88 | &-content{
89 | float: left;
90 | position: relative;
91 |
92 | &:after{
93 | content: '';
94 | display: block;
95 | width: 2px;
96 | position: absolute;
97 | top: 31px;
98 | bottom: 0;
99 | right: -2px;
100 | background: @border-color-split;
101 | z-index: 1;
102 | }
103 |
104 | &-right{
105 | float: right;
106 | &:after{
107 | right: auto;
108 | left: -2px;
109 | }
110 | }
111 | }
112 | }
113 | .@{time-picker-prefix-cls}-cells{
114 | &-list{
115 | &:first-child{
116 | border-radius: 0;
117 | }
118 | &:last-child{
119 | border-radius: 0;
120 | }
121 | }
122 | }
123 | }
124 | &-with-range&-with-seconds{
125 | .@{picker-prefix-cls}-panel{
126 | &-body{
127 | min-width: @time-picker-cells-width-with-seconds * 2 + 4px;
128 | }
129 | }
130 | }
131 | }
132 |
133 | .@{picker-prefix-cls}-panel-content{
134 | .@{picker-prefix-cls}-panel-content{
135 | .@{time-picker-prefix-cls}{
136 | &-cells{
137 | min-width: @time-picker-cells-width-with-date-with-seconds;
138 | &-with-seconds{
139 | min-width: @time-picker-cells-width-with-date-with-seconds;
140 | .@{time-picker-prefix-cls}-cells-list{
141 | width: @time-picker-cells-width-with-date-with-seconds / 3;
142 | ul{
143 | li{
144 | padding: 0 0 0 28px;
145 | }
146 | }
147 | }
148 | }
149 | &-list {
150 | width: @time-picker-cells-width-with-date-with-seconds / 2;
151 | max-height: 216px;
152 | &:first-child{
153 | border-radius: 0;
154 | }
155 | &:last-child{
156 | border-radius: 0;
157 | }
158 | ul{
159 | padding: 0 0 192px 0;
160 | li{
161 | padding: 0 0 0 46px;
162 | }
163 | }
164 | }
165 | }
166 | }
167 | }
168 | }
--------------------------------------------------------------------------------
/src/renderer/assets/my-theme/components/select.less:
--------------------------------------------------------------------------------
1 | @select-prefix-cls: ~"@{css-prefix}select";
2 | @select-item-prefix-cls: ~"@{css-prefix}select-item";
3 | @select-group-prefix-cls: ~"@{css-prefix}select-group";
4 |
5 | .@{select-prefix-cls} {
6 | display: inline-block;
7 | width: 100%;
8 | box-sizing: border-box;
9 | vertical-align: middle;
10 | color: @text-color;
11 | font-size: @font-size-base;
12 | //position: relative;
13 | line-height: normal;
14 |
15 | &-selection {
16 | display: block;
17 | box-sizing: border-box;
18 | outline: none;
19 | user-select: none;
20 | cursor: pointer;
21 | position: relative;
22 |
23 | background-color: #fff;
24 | border-radius: @btn-border-radius;
25 | border: 1px solid @border-color-base;
26 | transition: all @transition-time @ease-in-out;
27 |
28 | .@{select-prefix-cls}-arrow:nth-of-type(1) {
29 | display: none;
30 | cursor: pointer;
31 | }
32 |
33 | &:hover {
34 | .hover();
35 | .@{select-prefix-cls}-arrow:nth-of-type(1) {
36 | display: inline-block;
37 | }
38 | }
39 | }
40 |
41 | &-show-clear &-selection:hover .@{select-prefix-cls}-arrow:nth-of-type(2){
42 | display: none;
43 | }
44 |
45 | &-arrow {
46 | .inner-arrow();
47 | }
48 |
49 | &-visible{
50 | .@{select-prefix-cls}-selection{
51 | .active();
52 | }
53 |
54 | .@{select-prefix-cls}-arrow:nth-of-type(2) {
55 | transform: rotate(180deg);
56 | }
57 | }
58 |
59 | &-disabled {
60 | .@{select-prefix-cls}-selection {
61 | .disabled();
62 |
63 | .@{select-prefix-cls}-arrow:nth-of-type(1) {
64 | display: none;
65 | }
66 |
67 | &:hover {
68 | border-color: @border-color-base;
69 | box-shadow: none;
70 |
71 | .@{select-prefix-cls}-arrow:nth-of-type(2) {
72 | display: inline-block;
73 | }
74 | }
75 | }
76 | }
77 |
78 | &-single &-selection{
79 | height: @input-height-base;
80 | position: relative;
81 |
82 | .@{select-prefix-cls}-placeholder{
83 | color: @input-placeholder-color;
84 | }
85 |
86 | .@{select-prefix-cls}-placeholder, .@{select-prefix-cls}-selected-value{
87 | display: block;
88 | height: @input-height-base - 2px;
89 | line-height: @input-height-base - 2px;
90 | font-size: @font-size-small;
91 | overflow: hidden;
92 | text-overflow: ellipsis;
93 | white-space: nowrap;
94 | padding-left: 8px;
95 | padding-right: 24px;
96 | }
97 | }
98 |
99 | &-large&-single &-selection{
100 | height: @input-height-large;
101 |
102 | .@{select-prefix-cls}-placeholder, .@{select-prefix-cls}-selected-value{
103 | height: @input-height-large - 2px;
104 | line-height: @input-height-large - 2px;
105 | font-size: @font-size-base;
106 | }
107 | }
108 |
109 | &-small&-single &-selection{
110 | height: @input-height-small;
111 | border-radius: @btn-border-radius-small;
112 |
113 | .@{select-prefix-cls}-placeholder, .@{select-prefix-cls}-selected-value{
114 | height: @input-height-small - 2px;
115 | line-height: @input-height-small - 2px;
116 | }
117 | }
118 |
119 | &-multiple &-selection{
120 | padding: 0 24px 0 4px;
121 | min-height: @input-height-base;
122 |
123 | .@{select-prefix-cls}-placeholder{
124 | display: block;
125 | height: @input-height-base - 2px;
126 | line-height: @input-height-base - 2px;
127 | color: @input-placeholder-color;
128 | font-size: @font-size-small;
129 | overflow: hidden;
130 | text-overflow: ellipsis;
131 | white-space: nowrap;
132 | padding-left: 4px;
133 | padding-right: 22px;
134 | }
135 | }
136 |
137 | // input
138 | &-input{
139 | display: inline-block;
140 | height: @input-height-base;
141 | line-height: @input-height-base;
142 | padding: 0 24px 0 8px;
143 | font-size: @font-size-small;
144 | outline: none;
145 | border: none;
146 | box-sizing: border-box;
147 | color: @input-color;
148 | background-color: transparent;
149 | position: relative;
150 | cursor: pointer;
151 | .placeholder();
152 | }
153 |
154 | &-single &-input{
155 | width: 100%;
156 | }
157 |
158 | &-large &-input{
159 | font-size: @font-size-base;
160 | height: @input-height-large;
161 | }
162 |
163 | &-small &-input{
164 | height: @input-height-small;
165 | }
166 |
167 | &-multiple &-input{
168 | height: @input-height-base - 3px;
169 | line-height: @input-height-base;
170 | padding: 0 0 0 4px;
171 | }
172 |
173 | &-not-found{
174 | text-align: center;
175 | color: @btn-disable-color;
176 | }
177 |
178 | &-multiple .@{css-prefix}tag{
179 | margin: 3px 4px 2px 0;
180 | }
181 | }
182 |
183 | .select-item(@select-prefix-cls, @select-item-prefix-cls);
184 |
185 | .@{select-prefix-cls}-multiple .@{select-item-prefix-cls} {
186 | &-selected{
187 | color: @selected-color;
188 | background: #fff;
189 | }
190 | &-focus,&-selected:hover{
191 | background: @background-color-select-hover;
192 | }
193 |
194 | &-selected&-focus {
195 | color: shade(@selected-color, 10%);
196 | background: #fff;
197 | }
198 |
199 | &-selected:after{
200 | .ivu-icon();
201 | float: right;
202 | font-size: 24px;
203 | content: '\F3FD';
204 | color: @selected-color;
205 | }
206 | }
207 |
208 | .@{select-group-prefix-cls} {
209 | list-style: none;
210 | margin: 0;
211 | padding: 0;
212 |
213 | &-title {
214 | padding-left: 8px;
215 | font-size: 12px;
216 | color: @legend-color;
217 | height: 30px;
218 | line-height: 30px;
219 | }
220 | }
221 |
222 | .@{form-item-prefix-cls}-error{
223 | .@{select-prefix-cls}{
224 | &-selection{
225 | border: 1px solid @error-color;
226 | }
227 | &-arrow{
228 | color: @error-color;
229 | }
230 | &-visible .@{select-prefix-cls}-selection{
231 | .active-error;
232 | }
233 | }
234 | }
--------------------------------------------------------------------------------
/src/renderer/assets/my-theme/components/menu.less:
--------------------------------------------------------------------------------
1 | @menu-prefix-cls: ~"@{css-prefix}menu";
2 | @menu-dropdown-item-prefix-cls: ~"@{menu-prefix-cls}-horizontal .@{menu-prefix-cls}-submenu .@{select-dropdown-prefix-cls} .@{menu-prefix-cls}-item";
3 |
4 | .@{menu-prefix-cls} {
5 | display: block;
6 | margin: 0;
7 | padding: 0;
8 | outline: none;
9 | list-style: none;
10 | color: @text-color;
11 | font-size: @font-size-base;
12 | position: relative;
13 |
14 | &-horizontal{
15 | height: 60px;
16 | line-height: 60px;
17 |
18 | &.@{menu-prefix-cls}-light{
19 | &:after{
20 | content: '';
21 | display: block;
22 | width: 100%;
23 | height: 1px;
24 | background: @border-color-base;
25 | position: absolute;
26 | bottom: 0;
27 | left: 0;
28 | }
29 | }
30 | }
31 | &-vertical{
32 | &.@{menu-prefix-cls}-light{
33 | &:after{
34 | content: '';
35 | display: block;
36 | width: 1px;
37 | height: 100%;
38 | background: @border-color-base;
39 | position: absolute;
40 | top: 0;
41 | bottom: 0;
42 | right: 0;
43 | z-index: 1;
44 | }
45 | }
46 | }
47 |
48 | &-light{
49 | background: #fff;
50 | }
51 | &-dark{
52 | background: @title-color;
53 | }
54 | &-primary{
55 | background: @primary-color;
56 | }
57 |
58 | &-item{
59 | display: block;
60 | outline: none;
61 | list-style: none;
62 | font-size: @font-size-base;
63 | position: relative;
64 | z-index: 1;
65 | cursor: pointer;
66 | transition: all @transition-time @ease-in-out;
67 | }
68 | &-item > i{
69 | margin-right: 6px;
70 | }
71 | &-submenu-title > i, &-submenu-title span > i{
72 | margin-right: 8px;
73 | }
74 |
75 | &-horizontal &-item,
76 | &-horizontal &-submenu
77 | {
78 | float: left;
79 | padding: 0 20px;
80 | position: relative;
81 | cursor: pointer;
82 | z-index: 3;
83 | transition: all @transition-time @ease-in-out;
84 | }
85 |
86 | &-light&-horizontal &-item, &-light&-horizontal &-submenu{
87 | height: inherit;
88 | line-height: inherit;
89 | border-bottom: 2px solid transparent;
90 | color: @text-color;
91 | &-active, &:hover{
92 | color: @primary-color;
93 | border-bottom: 2px solid @primary-color;
94 | }
95 | }
96 |
97 | &-dark&-horizontal &-item, &-dark&-horizontal &-submenu{
98 | color: @subsidiary-color;
99 | &-active, &:hover{
100 | color: #fff;
101 | }
102 | }
103 |
104 | &-primary&-horizontal &-item, &-primary&-horizontal &-submenu{
105 | color: #fff;
106 | &-active, &:hover{
107 | background: @link-active-color;
108 | }
109 | }
110 |
111 | &-horizontal &-submenu .@{select-dropdown-prefix-cls} {
112 | min-width: 100%;
113 | width: auto;
114 | max-height: none;
115 | .@{menu-prefix-cls}-item{
116 | height: auto;
117 | line-height: normal;
118 | border-bottom: 0;
119 | float: none;
120 | }
121 | }
122 |
123 | &-item-group{
124 | line-height: normal;
125 | &-title {
126 | height: 30px;
127 | line-height: 30px;
128 | padding-left: 8px;
129 | font-size: @font-size-small;
130 | color: @legend-color;
131 | }
132 |
133 | & > ul{
134 | padding: 0 !important;
135 | list-style: none !important;
136 | }
137 | }
138 |
139 | // vertical
140 | &-vertical &-item,
141 | &-vertical &-submenu-title
142 | {
143 | padding: 14px 24px;
144 | position: relative;
145 | cursor: pointer;
146 | z-index: 1;
147 | transition: all @transition-time @ease-in-out;
148 |
149 | &:hover{
150 | background: @background-color-select-hover;
151 | }
152 | }
153 |
154 | &-vertical &-submenu-title-icon{
155 | float: right;
156 | position: relative;
157 | top: 4px;
158 | }
159 | &-submenu-title-icon {
160 | transition: transform @transition-time @ease-in-out;
161 | }
162 | &-opened &-submenu-title-icon{
163 | transform: rotate(180deg);
164 | }
165 |
166 | &-vertical &-submenu &-item{
167 | padding-left: 43px;
168 | }
169 | &-vertical &-item-group{
170 | &-title{
171 | height: 48px;
172 | line-height: 48px;
173 | font-size: @font-size-base;
174 | padding-left: 28px;
175 | }
176 | }
177 | &-dark&-vertical &-item-group{
178 | &-title{
179 | color: @text-color;
180 | }
181 | }
182 |
183 | &-light&-vertical &-item{
184 | border-right: 2px solid transparent;
185 | &-active:not(.@{menu-prefix-cls}-submenu){
186 | color: @primary-color;
187 | border-right: 2px solid @primary-color;
188 | z-index: 2;
189 | }
190 | }
191 |
192 | &-dark&-vertical &-item, &-dark&-vertical &-submenu-title{
193 | color: @subsidiary-color;
194 | &-active:not(.@{menu-prefix-cls}-submenu),
195 | &-active:not(.@{menu-prefix-cls}-submenu):hover
196 | {
197 | background: @menu-dark-active-bg;
198 | }
199 | &:hover{
200 | color: #fff;
201 | background: @title-color;
202 | }
203 | &-active:not(.@{menu-prefix-cls}-submenu){
204 | color: @primary-color;
205 | border-right: 2px solid @primary-color;
206 | }
207 | }
208 | &-dark&-vertical &-submenu &-item{
209 | &:hover{
210 | color: #fff;
211 | background: transparent !important;
212 | }
213 | &-active,&-active:hover{
214 | border-right: none;
215 | color: #fff;
216 | background: @primary-color !important;
217 | }
218 | }
219 | &-dark&-vertical &-item-active &-submenu-title{
220 | color: #fff;
221 | }
222 |
223 | &-dark&-vertical &-opened{
224 | background: @menu-dark-active-bg;
225 | .@{menu-prefix-cls}-submenu-title{
226 | background: @title-color;
227 | }
228 | }
229 | }
230 | .select-item(@menu-prefix-cls, @menu-dropdown-item-prefix-cls);
231 |
232 | .@{menu-dropdown-item-prefix-cls} {
233 | padding: 7px 16px 8px;
234 | font-size: @font-size-base !important;
235 | }
--------------------------------------------------------------------------------