diff --git a/.babelrc b/.babelrc index 710f153e..e391846f 100644 --- a/.babelrc +++ b/.babelrc @@ -13,8 +13,7 @@ "enums": "./src/utils/enums", "services": "./src/services", "models": "./src/models", - "routes": "./src/routes", - "themes": "./src/themes" + "routes": "./src/routes" } } ] diff --git a/.umirc.mock.js b/.umirc.mock.js index 08feb114..fb7e6fb0 100644 --- a/.umirc.mock.js +++ b/.umirc.mock.js @@ -1,5 +1,8 @@ -const mock = {} -require('fs').readdirSync(require('path').join(__dirname + '/mock')).forEach(function(file) { - Object.assign(mock, require('./mock/' + file)) -}) -module.exports = mock + +export default { + ...require('./mock/common'), + ...require('./mock/dashboard'), + ...require('./mock/menu'), + ...require('./mock/post'), + ...require('./mock/user'), +} diff --git a/.webpackrc.js b/.webpackrc.js index 4249e0a2..a96cd180 100644 --- a/.webpackrc.js +++ b/.webpackrc.js @@ -1,3 +1,5 @@ +import { resolve } from 'path'; + export default { theme: "./theme.config.js", // 接口代理示例 @@ -13,4 +15,7 @@ export default { // "pathRewrite": { "^/api/v2" : "/api/v2" } // } }, + alias: { + themes: resolve(__dirname, './src/themes'), + }, } diff --git a/mock/common.js b/mock/common.js index c8b79e9a..1d5436de 100644 --- a/mock/common.js +++ b/mock/common.js @@ -1,5 +1,5 @@ const Mock = require('mockjs') -const config = require('../utils/config') +const config = require('../src/utils/config') const queryArray = (array, key, keyAlias = 'key') => { if (!(array instanceof Array)) { diff --git a/mock/dashboard.js b/mock/dashboard.js index 788bc56a..9f31a4a9 100644 --- a/mock/dashboard.js +++ b/mock/dashboard.js @@ -1,7 +1,7 @@ -import { color } from '../utils/theme' +import { color } from '../src/utils/theme' const Mock = require('mockjs') -const config = require('../utils/config') +const config = require('../src/utils/config') const { apiPrefix } = config diff --git a/mock/user.js b/mock/user.js index 6dd8a8f2..c3ee292c 100644 --- a/mock/user.js +++ b/mock/user.js @@ -1,6 +1,6 @@ const qs = require('qs') const Mock = require('mockjs') -const config = require('../utils/config') +const config = require('../src/utils/config') const { apiPrefix } = config diff --git a/src/components/Layout/Header.less b/src/components/Layout/Header.less index 9312ad2c..9bfde842 100644 --- a/src/components/Layout/Header.less +++ b/src/components/Layout/Header.less @@ -1,92 +1,92 @@ -@import "~themes/vars"; - -.header { - :global { - .ant-menu-submenu-title { - height: 56px; - } - - .ant-menu-horizontal { - line-height: 56px; - - & > .ant-menu-submenu:hover { - color: #1890ff; - background-color: rgba(24, 144, 255, 0.15); - } - } - - .ant-menu { - border-bottom: none; - height: 56px; - } - - .ant-menu-horizontal > .ant-menu-submenu { - top: 0; - margin-top: 0; - } - - .ant-menu-horizontal > .ant-menu-item, - .ant-menu-horizontal > .ant-menu-submenu { - border-bottom: none; - } - - .ant-menu-horizontal > .ant-menu-item-active, - .ant-menu-horizontal > .ant-menu-item-open, - .ant-menu-horizontal > .ant-menu-item-selected, - .ant-menu-horizontal > .ant-menu-item:hover, - .ant-menu-horizontal > .ant-menu-submenu-active, - .ant-menu-horizontal > .ant-menu-submenu-open, - .ant-menu-horizontal > .ant-menu-submenu-selected, - .ant-menu-horizontal > .ant-menu-submenu:hover { - border-bottom: none; - } - } - box-shadow: @shadow-2; - position: relative; - display: flex; - justify-content: space-between; - height: 56px; - z-index: 9; - display: flex; - align-items: center; - background-color: #fff; - - .rightWarpper { - display: flex; - padding-right: 16px; - } - - .button { - width: 56px; - height: 56px; - line-height: 56px; - text-align: center; - font-size: 18px; - cursor: pointer; - transition: @transition-ease-in; - - &:hover { - color: @primary-color; - background-color: fade(@primary-color, 15%); - } - } -} - -.popovermenu { - width: 280px; - margin-left: 6px; - - :global .ant-popover-inner-content { - padding: 0; - - .ant-menu-inline .ant-menu-item, - .ant-menu-vertical .ant-menu-item { - border-right: 0; - } - - .ant-menu-inline .ant-menu-item-selected, - .ant-menu-inline .ant-menu-selected { - border-right: 0; - } - } -} +@import "~themes/vars.less"; + +.header { + :global { + .ant-menu-submenu-title { + height: 56px; + } + + .ant-menu-horizontal { + line-height: 56px; + + & > .ant-menu-submenu:hover { + color: #1890ff; + background-color: rgba(24, 144, 255, 0.15); + } + } + + .ant-menu { + border-bottom: none; + height: 56px; + } + + .ant-menu-horizontal > .ant-menu-submenu { + top: 0; + margin-top: 0; + } + + .ant-menu-horizontal > .ant-menu-item, + .ant-menu-horizontal > .ant-menu-submenu { + border-bottom: none; + } + + .ant-menu-horizontal > .ant-menu-item-active, + .ant-menu-horizontal > .ant-menu-item-open, + .ant-menu-horizontal > .ant-menu-item-selected, + .ant-menu-horizontal > .ant-menu-item:hover, + .ant-menu-horizontal > .ant-menu-submenu-active, + .ant-menu-horizontal > .ant-menu-submenu-open, + .ant-menu-horizontal > .ant-menu-submenu-selected, + .ant-menu-horizontal > .ant-menu-submenu:hover { + border-bottom: none; + } + } + box-shadow: @shadow-2; + position: relative; + display: flex; + justify-content: space-between; + height: 56px; + z-index: 9; + display: flex; + align-items: center; + background-color: #fff; + + .rightWarpper { + display: flex; + padding-right: 16px; + } + + .button { + width: 56px; + height: 56px; + line-height: 56px; + text-align: center; + font-size: 18px; + cursor: pointer; + transition: @transition-ease-in; + + &:hover { + color: @primary-color; + background-color: fade(@primary-color, 15%); + } + } +} + +.popovermenu { + width: 280px; + margin-left: 6px; + + :global .ant-popover-inner-content { + padding: 0; + + .ant-menu-inline .ant-menu-item, + .ant-menu-vertical .ant-menu-item { + border-right: 0; + } + + .ant-menu-inline .ant-menu-item-selected, + .ant-menu-inline .ant-menu-selected { + border-right: 0; + } + } +} diff --git a/src/components/Layout/Layout.less b/src/components/Layout/Layout.less index 0ca53820..7fb56e0b 100644 --- a/src/components/Layout/Layout.less +++ b/src/components/Layout/Layout.less @@ -1,188 +1,188 @@ -@import "~themes/vars"; - -:global { - .ant-layout-header { - padding: 0; - } - - .ant-layout-sider { - transition: all 0.3s; - - .ant-menu-root { - height: ~"calc(100vh - 144px)"; - overflow-x: hidden; - border-right: none; - - &::-webkit-scrollbar-thumb { - background-color: transparent; - } - - &:hover { - &::-webkit-scrollbar-thumb { - background-color: rgba(0, 0, 0, 0.2); - } - } - } - - .ant-menu { - .ant-menu-item, - .ant-menu-submenu-title { - overflow: hidden; - white-space: normal; - } - } - } - - .ant-layout-content { - padding: 24px; - } - - .ant-layout-footer { - text-align: center; - padding: 0 24px; - height: 40px; - font-size: 12px; - line-height: 40px; - } - - .ant-back-top { - right: 50px; - } - - .ant-switch.ant-switch-large { - line-height: 24px; - height: 26px; - - &:after, - &:before { - width: 22px; - height: 22px; - } - - &.ant-switch-checked:after, - &.ant-switch-checked:before { - margin-left: -23px; - } - } - - .flex-vertical-center { - display: flex; - align-items: center; - } - - .ant-form-item { - margin-bottom: 12px; - } -} - - - -.logo { - height: 96px; - display: flex; - align-items: center; - justify-content: center; - - img { - width: 40px; - margin-right: 8px; - } - - span { - vertical-align: text-bottom; - font-size: 16px; - text-transform: uppercase; - display: inline-block; - font-weight: 700; - color: @primary-color; - white-space: nowrap; - :local { - animation: fadeLeftIn 500ms linear; - animation-fill-mode: both; - } - } -} - -.switchtheme { - width: 100%; - position: absolute; - bottom: 0; - height: 48px; - background-color: #fff; - border-top: solid 1px #f8f8f8; - display: flex; - justify-content: space-between; - align-items: center; - padding: 0 16px; - overflow: hidden; - z-index: 9; - transition: all 0.3s; - - span { - white-space: nowrap; - overflow: hidden; - font-size: 12px; - } - - :global { - .anticon { - min-width: 14px; - margin-right: 4px; - font-size: 14px; - } - } -} - -.bread { - margin-bottom: 24px; - - :global { - .ant-breadcrumb { - display: flex; - align-items: center; - } - } -} - -.dark { - .switchtheme { - background-color: #000d18; - border-color: #001629; - } -} - -.light { - :global { - .ant-layout-sider { - background: #fff; - } - } -} -@media (max-width: 767px) { - .bread { - margin-bottom: 12px; - } - - :global { - .ant-layout-content { - padding: 12px; - } - - .ant-back-top { - right: 20px; - bottom: 20px; - } - } -} - -@keyframes fadeLeftIn { - 0% { - transform: translateX(5px); - opacity: 0; - } - - 100% { - transform: translateX(0); - opacity: 1; - } -} +@import "~themes/vars.less"; + +:global { + .ant-layout-header { + padding: 0; + } + + .ant-layout-sider { + transition: all 0.3s; + + .ant-menu-root { + height: ~"calc(100vh - 144px)"; + overflow-x: hidden; + border-right: none; + + &::-webkit-scrollbar-thumb { + background-color: transparent; + } + + &:hover { + &::-webkit-scrollbar-thumb { + background-color: rgba(0, 0, 0, 0.2); + } + } + } + + .ant-menu { + .ant-menu-item, + .ant-menu-submenu-title { + overflow: hidden; + white-space: normal; + } + } + } + + .ant-layout-content { + padding: 24px; + } + + .ant-layout-footer { + text-align: center; + padding: 0 24px; + height: 40px; + font-size: 12px; + line-height: 40px; + } + + .ant-back-top { + right: 50px; + } + + .ant-switch.ant-switch-large { + line-height: 24px; + height: 26px; + + &:after, + &:before { + width: 22px; + height: 22px; + } + + &.ant-switch-checked:after, + &.ant-switch-checked:before { + margin-left: -23px; + } + } + + .flex-vertical-center { + display: flex; + align-items: center; + } + + .ant-form-item { + margin-bottom: 12px; + } +} + + + +.logo { + height: 96px; + display: flex; + align-items: center; + justify-content: center; + + img { + width: 40px; + margin-right: 8px; + } + + span { + vertical-align: text-bottom; + font-size: 16px; + text-transform: uppercase; + display: inline-block; + font-weight: 700; + color: @primary-color; + white-space: nowrap; + :local { + animation: fadeLeftIn 500ms linear; + animation-fill-mode: both; + } + } +} + +.switchtheme { + width: 100%; + position: absolute; + bottom: 0; + height: 48px; + background-color: #fff; + border-top: solid 1px #f8f8f8; + display: flex; + justify-content: space-between; + align-items: center; + padding: 0 16px; + overflow: hidden; + z-index: 9; + transition: all 0.3s; + + span { + white-space: nowrap; + overflow: hidden; + font-size: 12px; + } + + :global { + .anticon { + min-width: 14px; + margin-right: 4px; + font-size: 14px; + } + } +} + +.bread { + margin-bottom: 24px; + + :global { + .ant-breadcrumb { + display: flex; + align-items: center; + } + } +} + +.dark { + .switchtheme { + background-color: #000d18; + border-color: #001629; + } +} + +.light { + :global { + .ant-layout-sider { + background: #fff; + } + } +} +@media (max-width: 767px) { + .bread { + margin-bottom: 12px; + } + + :global { + .ant-layout-content { + padding: 12px; + } + + .ant-back-top { + right: 20px; + bottom: 20px; + } + } +} + +@keyframes fadeLeftIn { + 0% { + transform: translateX(5px); + opacity: 0; + } + + 100% { + transform: translateX(0); + opacity: 1; + } +} diff --git a/src/components/Page/Page.less b/src/components/Page/Page.less index 0a8156f2..8355fb7a 100644 --- a/src/components/Page/Page.less +++ b/src/components/Page/Page.less @@ -1,16 +1,16 @@ -@import "~themes/vars"; - -.contentInner{ - background: #fff; - padding: 24px; - box-shadow: @shadow-1; - min-height: ~"calc(100vh - 198px)"; - position: relative; -} - -@media (max-width: 767px) { - .contentInner { - padding: 12px; - min-height: ~"calc(100vh - 160px)"; - } -} +@import "~themes/vars.less"; + +.contentInner{ + background: #fff; + padding: 24px; + box-shadow: @shadow-1; + min-height: ~"calc(100vh - 198px)"; + position: relative; +} + +@media (max-width: 767px) { + .contentInner { + padding: 12px; + min-height: ~"calc(100vh - 160px)"; + } +} diff --git a/src/layouts/app.less b/src/layouts/app.less index 32023d43..6af0944d 100644 --- a/src/layouts/app.less +++ b/src/layouts/app.less @@ -1,72 +1,72 @@ -@import "~themes/vars"; - -:global { - #nprogress { - pointer-events: none; - - .bar { - background: @primary-color; - position: fixed; - z-index: 1024; - top: 0; - left: 0; - right: 0; - width: 100%; - height: 2px; - } - - .peg { - display: block; - position: absolute; - right: 0; - width: 100px; - height: 100%; - box-shadow: 0 0 10px @primary-color,0 0 5px @primary-color; - opacity: 1.0; - transform: rotate(3deg) translate(0px,-4px); - } - - .spinner { - display: block; - position: fixed; - z-index: 1031; - top: 15px; - right: 15px; - } - - .spinner-icon { - width: 18px; - height: 18px; - box-sizing: border-box; - border: solid 2px transparent; - border-top-color: @primary-color; - border-left-color: @primary-color; - border-radius: 50%; - - :local { - animation: nprogress-spinner 400ms linear infinite; - } - } - } - - .nprogress-custom-parent { - overflow: hidden; - position: relative; - - #nprogress { - .bar, - .spinner { - position: absolute; - } - } - } -} -@keyframes nprogress-spinner { - 0% { - transform: rotate(0deg); - } - - 100% { - transform: rotate(360deg); - } -} +@import "~themes/vars.less"; + +:global { + #nprogress { + pointer-events: none; + + .bar { + background: @primary-color; + position: fixed; + z-index: 1024; + top: 0; + left: 0; + right: 0; + width: 100%; + height: 2px; + } + + .peg { + display: block; + position: absolute; + right: 0; + width: 100px; + height: 100%; + box-shadow: 0 0 10px @primary-color,0 0 5px @primary-color; + opacity: 1.0; + transform: rotate(3deg) translate(0px,-4px); + } + + .spinner { + display: block; + position: fixed; + z-index: 1031; + top: 15px; + right: 15px; + } + + .spinner-icon { + width: 18px; + height: 18px; + box-sizing: border-box; + border: solid 2px transparent; + border-top-color: @primary-color; + border-left-color: @primary-color; + border-radius: 50%; + + :local { + animation: nprogress-spinner 400ms linear infinite; + } + } + } + + .nprogress-custom-parent { + overflow: hidden; + position: relative; + + #nprogress { + .bar, + .spinner { + position: absolute; + } + } + } +} +@keyframes nprogress-spinner { + 0% { + transform: rotate(0deg); + } + + 100% { + transform: rotate(360deg); + } +} diff --git a/src/plugins/onError.js b/src/plugins/onError.js index 9b769852..5661d64c 100644 --- a/src/plugins/onError.js +++ b/src/plugins/onError.js @@ -1,8 +1,8 @@ import { message } from 'antd' export default { - onError(e) { + onError (e) { e.preventDefault() - message.error(error.message) - } + message.error(e.message) + }, } diff --git a/src/themes/index.less b/src/themes/index.less index 74582f7a..a6f29a42 100644 --- a/src/themes/index.less +++ b/src/themes/index.less @@ -1,135 +1,135 @@ -@import "~themes/vars"; - -body { - height: 100%; - overflow-y: hidden; - background-color: #f8f8f8; -} - -::-webkit-scrollbar-thumb { - background-color: #e6e6e6; -} - -::-webkit-scrollbar { - width: 8px; - height: 8px; -} - -:global { - .ant-breadcrumb { - & > span { - &:last-child { - color: #999; - font-weight: normal; - } - } - } - - .ant-breadcrumb-link { - .anticon + span { - margin-left: 4px; - } - } - - .ant-table { - .ant-table-thead > tr > th { - text-align: center; - } - - .ant-table-tbody > tr > td { - text-align: center; - } - - &.ant-table-small { - .ant-table-thead > tr > th { - background: #f7f7f7; - } - - .ant-table-body > table { - padding: 0; - } - } - } - - .ant-table-pagination { - float: none!important; - display: table; - margin: 16px auto !important; - } - - .ant-popover-inner { - border: none; - border-radius: 0; - box-shadow: 0 0 20px rgba(100, 100, 100, 0.2); - } - - .vertical-center-modal { - display: flex; - align-items: center; - justify-content: center; - - .ant-modal { - top: 0; - - .ant-modal-body { - max-height: 80vh; - overflow-y: auto; - } - } - } - - .ant-form-item-control { - vertical-align: middle; - } - - .ant-modal-mask { - background-color: rgba(55, 55, 55, 0.2); - } - - .ant-modal-content { - box-shadow: none; - } - - .ant-select-dropdown-menu-item { - padding: 12px 16px !important; - } - - .margin-right { - margin-right: 16px; - } - - a:focus { - text-decoration: none; - } -} -@media (min-width: 1600px) { - :global { - .ant-col-xl-48 { - width: 20%; - } - - .ant-col-xl-96 { - width: 40%; - } - } -} -@media (max-width: 767px) { - :global { - .ant-pagination-item, - .ant-pagination-next, - .ant-pagination-options, - .ant-pagination-prev { - margin-bottom: 8px; - } - - .ant-card { - .ant-card-head { - padding: 0 12px; - } - - .ant-card-body { - padding: 12px; - } - } - } -} +@import "~themes/vars.less"; + +body { + height: 100%; + overflow-y: hidden; + background-color: #f8f8f8; +} + +::-webkit-scrollbar-thumb { + background-color: #e6e6e6; +} + +::-webkit-scrollbar { + width: 8px; + height: 8px; +} + +:global { + .ant-breadcrumb { + & > span { + &:last-child { + color: #999; + font-weight: normal; + } + } + } + + .ant-breadcrumb-link { + .anticon + span { + margin-left: 4px; + } + } + + .ant-table { + .ant-table-thead > tr > th { + text-align: center; + } + + .ant-table-tbody > tr > td { + text-align: center; + } + + &.ant-table-small { + .ant-table-thead > tr > th { + background: #f7f7f7; + } + + .ant-table-body > table { + padding: 0; + } + } + } + + .ant-table-pagination { + float: none!important; + display: table; + margin: 16px auto !important; + } + + .ant-popover-inner { + border: none; + border-radius: 0; + box-shadow: 0 0 20px rgba(100, 100, 100, 0.2); + } + + .vertical-center-modal { + display: flex; + align-items: center; + justify-content: center; + + .ant-modal { + top: 0; + + .ant-modal-body { + max-height: 80vh; + overflow-y: auto; + } + } + } + + .ant-form-item-control { + vertical-align: middle; + } + + .ant-modal-mask { + background-color: rgba(55, 55, 55, 0.2); + } + + .ant-modal-content { + box-shadow: none; + } + + .ant-select-dropdown-menu-item { + padding: 12px 16px !important; + } + + .margin-right { + margin-right: 16px; + } + + a:focus { + text-decoration: none; + } +} +@media (min-width: 1600px) { + :global { + .ant-col-xl-48 { + width: 20%; + } + + .ant-col-xl-96 { + width: 40%; + } + } +} +@media (max-width: 767px) { + :global { + .ant-pagination-item, + .ant-pagination-next, + .ant-pagination-options, + .ant-pagination-prev { + margin-bottom: 8px; + } + + .ant-card { + .ant-card-head { + padding: 0 12px; + } + + .ant-card-body { + padding: 12px; + } + } + } +} diff --git a/src/themes/vars.less b/src/themes/vars.less index 69f340ed..8b052a40 100644 --- a/src/themes/vars.less +++ b/src/themes/vars.less @@ -1,2 +1,2 @@ -@import "~themes/default"; -@import "~themes/mixin"; +@import "~themes/default.less"; +@import "~themes/mixin.less"; diff --git a/src/utils/index.js b/src/utils/index.js index dad7e5f5..ac4e4cde 100644 --- a/src/utils/index.js +++ b/src/utils/index.js @@ -1,9 +1,10 @@ /* global window */ -import classnames from 'classnames' import lodash from 'lodash' -import config from './config' -import request from './request' -import { color } from './theme' + +export classnames from 'classnames' +export config from './config' +export request from './request' +export { color } from './theme' // 连字符转驼峰 String.prototype.hyphenToHump = function () { @@ -42,11 +43,10 @@ Date.prototype.format = function (format) { /** - * @param {String} + * @param name {String} * @return {String} */ - -const queryURL = (name) => { +export function queryURL (name) { let reg = new RegExp(`(^|&)${name}=([^&]*)(&|$)`, 'i') let r = window.location.search.substr(1).match(reg) if (r != null) return decodeURI(r[2]) @@ -60,7 +60,7 @@ const queryURL = (name) => { * @param {String} keyAlias * @return {Array} */ -const queryArray = (array, key, keyAlias = 'key') => { +export function queryArray (array, key, keyAlias = 'key') { if (!(array instanceof Array)) { return null } @@ -79,7 +79,7 @@ const queryArray = (array, key, keyAlias = 'key') => { * @param {String} children * @return {Array} */ -const arrayToTree = (array, id = 'id', pid = 'pid', children = 'children') => { +export function arrayToTree (array, id = 'id', pid = 'pid', children = 'children') { let data = lodash.cloneDeep(array) let result = [] let hash = {} @@ -98,13 +98,3 @@ const arrayToTree = (array, id = 'id', pid = 'pid', children = 'children') => { }) return result } - -module.exports = { - config, - request, - color, - classnames, - queryURL, - queryArray, - arrayToTree, -} diff --git a/src/utils/model.js b/src/utils/model.js index bcd9e46d..79997277 100644 --- a/src/utils/model.js +++ b/src/utils/model.js @@ -1,6 +1,6 @@ import modelExtend from 'dva-model-extend' -const model = { +export const model = { reducers: { updateState (state, { payload }) { return { @@ -11,7 +11,7 @@ const model = { }, } -const pageModel = modelExtend(model, { +export const pageModel = modelExtend(model, { state: { list: [], @@ -40,9 +40,3 @@ const pageModel = modelExtend(model, { }, }) - - -module.exports = { - model, - pageModel, -}