roadhog first commit

This commit is contained in:
zuiidea
2017-04-01 12:04:03 +08:00
parent 0be85a93b9
commit 83f71c7d3e
16 changed files with 194 additions and 287 deletions
+26
View File
@@ -0,0 +1,26 @@
const path = require('path')
const svgSpriteDirs = [
path.resolve(__dirname, 'src/svg/'),
]
export default {
entry: 'src/index.js',
svgSpriteLoaderDirs: svgSpriteDirs,
"theme": "src/theme.js",
"env": {
"development": {
"extraBabelPlugins": [
"dva-hmr",
"transform-runtime",
["import", { "libraryName": "antd", "style": true }]
]
},
"production": {
"extraBabelPlugins": [
"transform-runtime",
["import", { "libraryName": "antd", "style": true}]
]
}
}
}
+5
View File
@@ -0,0 +1,5 @@
const mock = {}
require('fs').readdirSync(require('path').join(__dirname + '/src/mock')).forEach(function(file) {
Object.assign(mock, require('./src/mock/' + file))
})
module.exports = mock
+1 -1
View File
@@ -39,7 +39,7 @@
- [x] 规范代码: EsLint; 自用[开发配置](assets/standard.md)
- [ ] 数据可视化页面
- [ ] 模拟消息收发
- [ ] 升级dva-cli
- [ ] 升级为roadhog
## 开发及构建
-74
View File
@@ -1,74 +0,0 @@
const Cookie = require('js-cookie')
import mockStorge from '../src/utils/mockStorge'
const userPermission = {
DEFAULT: ['dashboard', 'chart'],
ADMIN: ['dashboard', 'users', 'UIElement', 'UIElementIconfont', 'chart'],
DEVELOPER: ['dashboard', 'users', 'UIElement', 'UIElementIconfont', 'chart'],
}
let dataKey = mockStorge('AdminUsers', [
{
username: 'admin',
password: 'admin',
permissions: userPermission.ADMIN,
},
{
username: 'guest',
password: 'guest',
permissions: userPermission.DEFAULT,
},
{
username: '吴彦祖',
password: '123456',
permissions: userPermission.DEVELOPER,
},
])
module.exports = {
'POST /api/login' (req, res) {
const userItem = JSON.parse(req.body)
const response = {
success: false,
message: '',
}
const currentUser = global[dataKey].filter((item) => {
return item.username === userItem.username
})
if (currentUser.length) {
if (currentUser[0].password === userItem.password) {
const now = new Date()
now.setDate(now.getDate() + 1)
Cookie.set('user_session', now.getTime(), { path: '/' })
Cookie.set('user_name', userItem.username, { path: '/' })
response.message = '登录成功'
response.success = true
response.userPermissions = global[dataKey].filter(_ => _.username === userItem.username)[0].permissions
} else {
response.message = '密码不正确'
}
} else {
response.message = '用户不存在'
}
res.json(response)
},
'GET /api/userInfo' (req, res) {
const response = {
success: Cookie.get('user_session') && Cookie.get('user_session') > new Date().getTime(),
username: Cookie.get('user_name') || '',
message: '',
userPermissions: global[dataKey].filter(_ => _.username === Cookie.get('user_name'))[0].permissions,
}
res.json(response)
},
'POST /api/logout' (req, res) {
Cookie.remove('user_session', { path: '/' })
Cookie.remove('user_name', { path: '/' })
res.json({
success: true,
message: '退出成功',
})
},
}
+7 -5
View File
@@ -22,10 +22,10 @@
"devDependencies": {
"atool-build": "^0.7.6",
"axios": "^0.15.3",
"babel-eslint": "^6.0.4",
"babel-eslint": "^6.1.2",
"babel-plugin-dev-expression": "^0.2.1",
"babel-plugin-dva-hmr": "^0.1.0",
"babel-plugin-import": "^1.0.1",
"babel-plugin-dva-hmr": "^0.3.2",
"babel-plugin-import": "^1.1.1",
"babel-plugin-transform-runtime": "^6.9.0",
"babel-polyfill": "^6.23.0",
"babel-runtime": "^6.9.2",
@@ -41,17 +41,19 @@
"eslint-plugin-jsx-a11y": "^1.4.2",
"eslint-plugin-react": "^5.1.1",
"glob": "^7.0.5",
"jsonp": "^0.2.1",
"less-vars-to-js": "^1.1.2",
"mockjs": "^1.0.1-beta3",
"rc-tween-one": "^1.0.0",
"redbox-react": "^1.2.10",
"roadhog": "^0.6.0-beta1",
"watchjs": "^0.0.0"
},
"pre-commit": [
"lint"
],
"scripts": {
"start": "dora --plugins \"proxy,webpack?publicPath=/,webpack-hmr,browser-history?index=/src/index.html\"",
"dev": "dora --plugins \"webpack?publicPath=/,webpack-hmr,browser-history?index=/src/index.html\"",
"dev": "set BROWSER=none&&roadhog server",
"lint": "eslint --fix --ext .js src",
"build": "atool-build"
},
-7
View File
@@ -1,7 +0,0 @@
const mock = {}
require('fs').readdirSync(require('path').join(`${__dirname}/mock`)).forEach((file) => {
Object.assign(mock, require(`./mock/${file}`))
})
module.exports = mock
+4 -176
View File
@@ -1,185 +1,13 @@
@import "../../node_modules/antd/lib/style/themes/default.less"; // // Prefix
// @ant-prefix : ant;
//
// // Color
// @primary-color : #2db7f5;
// @info-color : #2db7f5;
// @success-color : #87d068;
// @error-color : #f50;
// @warning-color : #fa0;
// @normal-color : #d9d9d9;
//
// // ------ Base & Require ------
// @body-background : #fff;
// @font-family : -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", SimSun, sans-serif;
// @code-family : Consolas,Menlo,Courier,monospace;
// @text-color : #666;
// @heading-color : #404040;
// @font-size-base : 12px;
// @line-height-base : 1.5;
// @line-height-computed : floor((@font-size-base * @line-height-base));
// @border-radius-base : 6px;
// @border-radius-sm : 4px;
//
// // ICONFONT
// @iconfont-css-prefix : anticon;
// @icon-url : "https://at.alicdn.com/t/font_1473840929_824008";
//
// // LINK
// @link-color : #2db7f5;
// @link-hover-color : tint(@link-color, 20%);
// @link-active-color : shade(@link-color, 5%);
// @link-hover-decoration : none;
//
// // Disabled cursor for form controls and buttons.
// @cursor-disabled : not-allowed;
//
// // Animation
// @ease-out : cubic-bezier(0.215, 0.61, 0.355, 1);
// @ease-in : cubic-bezier(0.55, 0.055, 0.675, 0.19);
// @ease-in-out : cubic-bezier(0.645, 0.045, 0.355, 1);
// @ease-out-back : cubic-bezier(0.12, 0.4, 0.29, 1.46);
// @ease-in-back : cubic-bezier(0.71, -0.46, 0.88, 0.6);
// @ease-in-out-back : cubic-bezier(0.71, -0.46, 0.29, 1.46);
// @ease-out-circ : cubic-bezier(0.08, 0.82, 0.17, 1);
// @ease-in-circ : cubic-bezier(0.6, 0.04, 0.98, 0.34);
// @ease-in-out-circ : cubic-bezier(0.78, 0.14, 0.15, 0.86);
// @ease-out-quint : cubic-bezier(0.23, 1, 0.32, 1);
// @ease-in-quint : cubic-bezier(0.755, 0.05, 0.855, 0.06);
// @ease-in-out-quint : cubic-bezier(0.86, 0, 0.07, 1);
//
// // Border color
// @border-color-base : #d9d9d9; // base border outline a component
// @border-color-split : #e9e9e9; // split border inside a component
//
// // Outline
// @outline-blur-size : 0;
// @outline-width : 2px;
// @outline-color : @primary-color;
//
// // Background color
// @background-color-base : #f7f7f7; // basic gray background
//
// // Shadow
// @shadow-color : rgba(100, 100, 100, .2);
// @box-shadow-base : @shadow-1-down;
// @shadow-1-up : 0 -1px 6px @shadow-color;
// @shadow-1-down : 0 1px 6px @shadow-color;
// @shadow-1-left : -1px 0 6px @shadow-color;
// @shadow-1-right : 1px 0 6px @shadow-color;
// @shadow-2 : 0 1px 8px @shadow-color;
//
// // Buttons
// @btn-font-weight : 500;
// @btn-border-radius-base : @border-radius-base;
// @btn-border-radius-sm : @border-radius-sm;
//
// @btn-primary-color : #fff;
// @btn-primary-bg : @primary-color;
// @btn-group-border : shade(@primary-color, 5%);
//
// @btn-default-color : @text-color;
// @btn-default-bg : @background-color-base;
// @btn-default-border : @border-color-base;
//
// @btn-ghost-color : @text-color;
// @btn-ghost-bg : transparent;
// @btn-ghost-border : @border-color-base;
//
// @btn-disable-color : #ccc;
// @btn-disable-bg : @background-color-base;
// @btn-disable-border : @border-color-base;
//
// @btn-padding-base : 4px 15px;
//
// @btn-font-size-lg : 14px;
// @btn-padding-lg : 4px 15px 5px 15px;
//
// @btn-padding-sm : 1px 7px;
//
// @btn-circle-size : 28px;
// @btn-circle-size-lg : 32px;
// @btn-circle-size-sm : 22px;
//
// // Media queries breakpoints
// // Extra small screen / phone
// @screen-xs : 480px;
// @screen-xs-min : @screen-xs;
// @screen-xs-max : (@screen-xs-min - 1);
//
// // Small screen / tablet
// @screen-sm : 768px;
// @screen-sm-min : @screen-sm;
// @screen-sm-max : (@screen-sm-min - 1);
//
// // Medium screen / desktop
// @screen-md : 992px;
// @screen-md-min : @screen-md;
// @screen-md-max : (@screen-md-min - 1);
//
// // Large screen / wide desktop
// @screen-lg : 1200px;
// @screen-lg-min : @screen-lg;
// @screen-lg-max : (@screen-lg-min - 1);
//
// // Layout and Grid system
// @grid-columns : 24;
// @grid-gutter-width : 0;
//
// // Container sizes
// @container-sm : (720px + @grid-gutter-width);
// @container-md : (940px + @grid-gutter-width);
// @container-lg : (1140px + @grid-gutter-width);
//
// // z-index list
// @zindex-affix : 10;
// @zindex-back-top : 10;
// @zindex-modal-mask : 1000;
// @zindex-modal : 1000;
// @zindex-notification : 1010;
// @zindex-message : 1010;
// @zindex-popover : 1030;
// @zindex-picker : 1050;
// @zindex-dropdown : 1050;
// @zindex-tooltip : 1060;
//
// // Form
// // --------------------------------
// // Legend
// @legend-color : #999;
// @legend-border-color : @border-color-base;
// // Label
// @label-required-color : #f50;
// @label-color : @text-color;
// // Input
// @input-height-base: 28px;
// @input-height-lg: 32px;
// @input-height-sm: 22px;
//
// @input-padding-horizontal : 7px;
// @input-padding-vertical-base : 4px;
// @input-padding-vertical-sm : 1px;
// @input-padding-vertical-lg : 6px;
//
// @input-placeholder-color : #ccc;
// @input-color : @text-color;
// @input-border-color : @border-color-base;
// @input-bg : #fff;
//
// @input-hover-border-color : @primary-color;
// @input-disabled-bg : @background-color-base;
//
// @form-item-margin-bottom : 24px;
@import '~antd/lib/style/themes/default.less'; // https://github.com/ant-design/ant-design/blob/master/components/style/themes/default.less
/*========================*/
/*=======Antd Admin=======*/
/*========================*/
//Color
@dark-half: #494949;
@purple: #d897eb; // Shadow
@purple: #d897eb;
@shadow-1: 4px 4px 20px 0 rgba(0,0,0,0.01);
@shadow-2: 4px 4px 40px 0 rgba(0,0,0,0.05); //transition
@shadow-2: 4px 4px 40px 0 rgba(0,0,0,0.05);
@transition-ease-in: all 0.3s @ease-in;
@transition-ease-out: all 0.3s @ease-out; //mix
@transition-ease-out: all 0.3s @ease-out;
.text-overflow() {
overflow: hidden;
+86
View File
@@ -0,0 +1,86 @@
const userPermission = {
DEFAULT: ['dashboard', 'chart'],
ADMIN: ['dashboard', 'users', 'UIElement', 'UIElementIconfont', 'chart'],
DEVELOPER: ['dashboard', 'users', 'UIElement', 'UIElementIconfont', 'chart'],
}
const adminUsers = [
{
username: 'admin',
password: 'admin',
permissions: userPermission.ADMIN,
},
{
username: 'guest',
password: 'guest',
permissions: userPermission.DEFAULT,
},
{
username: '吴彦祖',
password: '123456',
permissions: userPermission.DEVELOPER,
},
]
module.exports = {
'POST /api/login' (req, res) {
console.log(req.query)
console.log(req.params)
console.log(req.body)
// console.log(req.baseUrl)
// console.log(req.cookies)
// console.log(req.hostname)
// console.log(req.fresh)
// const userItem = JSON.parse(req.body)
// const response = {
// success: false,
// message: '',
// }
// const currentUser = AdminUsers.filter((item) => {
// return item.username === userItem.username
// })
// if (currentUser.length) {
// if (currentUser[0].password === userItem.password) {
// const now = new Date()
// now.setDate(now.getDate() + 1)
// // Cookie.set('user_session', now.getTime(), { path: '/' })
// // Cookie.set('user_name', userItem.username, { path: '/' })
// response.message = '登录成功'
// response.success = true
// response.userPermissions = AdminUsers.filter(_ => _.username === userItem.username)[0].permissions
// } else {
// response.message = '密码不正确'
// }
// } else {
// response.message = '用户不存在'
// }
// res.json(req)
// res.end({ success: true })
const now = new Date()
now.setDate(now.getDate() + 1)
res.cookie('user_session', now.getTime(), { maxAge: 900000, httpOnly: true })
res.json({
success: true,
message: '登录',
})
},
'GET /api/userInfo' (req, res) {
const response = {
// success: Cookie.get('user_session') && Cookie.get('user_session') > new Date().getTime(),
// username: Cookie.get('user_name') || '',
message: '',
}
if (response.success) {
// response.userPermissions = AdminUsers.filter(_ => _.username === Cookie.get('user_name'))[0].permissions
}
res.json(response)
},
'POST /api/logout' (req, res) {
res.json({
success: true,
message: '退出成功',
})
},
}
+4 -5
View File
@@ -1,8 +1,7 @@
import { color } from '../src/utils/theme'
import { color } from '../utils/theme'
const Mock = require('mockjs')
import mockStorge from '../src/utils/mockStorge'
let dataKey = mockStorge('Dashboard', Mock.mock({
const Dashboard = Mock.mock({
'sales|8': [
{
'name|+1': 2008,
@@ -120,10 +119,10 @@ let dataKey = mockStorge('Dashboard', Mock.mock({
number: 4324,
},
],
}))
})
module.exports = {
'GET /api/dashboard' (req, res) {
res.json(global[dataKey])
res.json(Dashboard)
},
}
+8 -7
View File
@@ -1,8 +1,7 @@
const qs = require('qs')
const Mock = require('mockjs')
import mockStorge from '../src/utils/mockStorge'
let dataKey = mockStorge('UsersList', Mock.mock({
let antdAdminUsersList = Mock.mock({
'data|100': [
{
'id|+1': 1,
@@ -23,13 +22,15 @@ let dataKey = mockStorge('UsersList', Mock.mock({
total: 100,
current: 1,
},
}))
})
let usersListData = global[dataKey]
let usersListData = antdAdminUsersList
module.exports = {
'GET /api/users' (req, res) {
console.log(req.query)
const page = qs.parse(req.query)
const pageSize = page.pageSize || 10
const currentPage = page.page || 1
@@ -69,7 +70,7 @@ module.exports = {
usersListData.page.total = usersListData.data.length
usersListData.page.current = 1
global[dataKey] = usersListData
antdAdminUsersList = usersListData
res.json({ success: true, data: usersListData.data, page: usersListData.page })
},
@@ -86,7 +87,7 @@ module.exports = {
usersListData.page.total = usersListData.data.length
global[dataKey] = usersListData
antdAdminUsersList = usersListData
res.json({ success: true, data: usersListData.data, page: usersListData.page })
},
@@ -104,7 +105,7 @@ module.exports = {
return item
})
global[dataKey] = usersListData
antdAdminUsersList = usersListData
res.json({ success: true, data: usersListData.data, page: usersListData.page })
},
+2
View File
@@ -10,4 +10,6 @@ module.exports = {
crossDomains: [
'http://www.zuimeitianqi.com',
],
YQL: ['http://www.zuimeitianqi.com'],
CORS: ['http://localhost:7001'],
}
+1 -1
View File
@@ -3,7 +3,7 @@ import menu from './menu'
import request from './request'
import classnames from 'classnames'
import { color } from './theme'
require('./mock.js')
// require('./mock.js')
// 连字符转驼峰
String.prototype.hyphenToHump = function () {
+1 -1
View File
@@ -1,5 +1,5 @@
const Watch = require('watchjs')
import config from './config'
const config = require('./config')
export default function mockStorge (name, defaultValue) {
let key = config.prefix + name
+41 -10
View File
@@ -1,16 +1,38 @@
import axios from 'axios'
import qs from 'qs'
import config from './config'
import { YQL, CORS } from './config'
import jsonp from 'jsonp'
import lodash from 'lodash'
const fetch = (options) => {
const {
let {
method = 'get',
data,
fetchType,
url,
} = options
if (fetchType === 'JSONP') {
return new Promise((resolve, reject) => {
jsonp(url, {
param: `${qs.stringify(data)}&callback`,
name: `jsonp_${new Date().getTime()}`,
timeout: 4000,
}, (error, result) => {
if (error) {
reject(error)
}
resolve({ statusText: 'OK', status: 200, data: result })
})
})
} else if (fetchType === 'YQL') {
url = `http://query.yahooapis.com/v1/public/yql?q=select * from json where url='${options.url}?${qs.stringify(options.data)}'&format=json`
data = null
}
switch (method.toLowerCase()) {
case 'get':
return axios.get(`${url}${options.data ? `?${qs.stringify(options.data)}` : ''}`)
return axios.get(`${url}${!lodash.isEmpty(data) ? `?${qs.stringify(data)}` : ''}`)
case 'delete':
return axios.delete(url, { data })
case 'head':
@@ -27,17 +49,22 @@ const fetch = (options) => {
}
export default function request (options) {
if (options.url.indexOf('//') > -1) {
if (config.crossDomains && config.crossDomains.indexOf(`${options.url.split('//')[0]}//${options.url.split('//')[1].split('/')[0]}`) > -1) {
options.isCross = true
options.url = `http://query.yahooapis.com/v1/public/yql?q=select * from json where url='${options.url}?${qs.stringify(options.data)}'&format=json`
delete options.data
if (options.url && options.url.indexOf('//') > -1) {
const origin = `${options.url.split('//')[0]}//${options.url.split('//')[1].split('/')[0]}`
if (window.location.origin !== origin) {
if (CORS && CORS.indexOf(origin) > -1) {
options.fetchType = 'CORS'
} else if (YQL && YQL.indexOf(origin) > -1) {
options.fetchType = 'YQL'
} else {
options.fetchType = 'JSONP'
}
}
}
return fetch(options).then((response) => {
const { statusText, status } = response
let data = options.isCross ? response.data.query.results.json : response.data
let data = options.fetchType === 'YQL' ? response.data.query.results.json : response.data
return {
code: 0,
status,
@@ -45,7 +72,11 @@ export default function request (options) {
...data,
}
}).catch((error) => {
const { response = { statusText: 'Network Error' } } = error
const {
response = {
statusText: error.message || 'Network Error',
},
} = error
return { code: 1, message: response.statusText }
})
}
+8
View File
@@ -0,0 +1,8 @@
const fs = require('fs')
const path = require('path')
const lessToJs = require('less-vars-to-js')
module.exports = () => {
const themePath = path.join(__dirname, './src/components/vars.less')
return lessToJs(fs.readFileSync(themePath, 'utf8'))
}