Authored by 陈峰

history模式

@@ -8,10 +8,12 @@ import yohoPluginUser from './plugins/yoho-plugin-user'; @@ -8,10 +8,12 @@ import yohoPluginUser from './plugins/yoho-plugin-user';
8 import './filters'; 8 import './filters';
9 import './directives'; 9 import './directives';
10 import 'iview/dist/styles/iview.css'; 10 import 'iview/dist/styles/iview.css';
11 -import 'common.scss';  
12 import 'font-awesome/css/font-awesome.css'; 11 import 'font-awesome/css/font-awesome.css';
13 12
14 -let router = new Router({routes: Routers}); 13 +let router = new Router({
  14 + routes: Routers,
  15 + mode: 'history'
  16 +});
15 17
16 Vue.use(yohoPluginCore, {router}); 18 Vue.use(yohoPluginCore, {router});
17 Vue.use(yohoPluginPurview); 19 Vue.use(yohoPluginPurview);
@@ -11,9 +11,10 @@ module.exports = { @@ -11,9 +11,10 @@ module.exports = {
11 app: ['./app.js'] 11 app: ['./app.js']
12 }, 12 },
13 output: { 13 output: {
14 - path: util.resolve('../server/public'), 14 + path: util.resolve('./build/bundle'),
15 filename: '[name].[hash:7].js', 15 filename: '[name].[hash:7].js',
16 - chunkFilename: '[name].[hash:7].js' 16 + chunkFilename: '[name].[hash:7].js',
  17 + publicPath: '/'
17 }, 18 },
18 resolve: { 19 resolve: {
19 extensions: ['.js', '.vue', '.json'], 20 extensions: ['.js', '.vue', '.json'],
@@ -40,11 +41,21 @@ module.exports = { @@ -40,11 +41,21 @@ module.exports = {
40 chunks: false, 41 chunks: false,
41 assetsSort: 'size', 42 assetsSort: 'size',
42 }, 43 },
  44 + historyApiFallback: {
  45 + rewrites: [
  46 + { from: /\.html$/, to: '/index.html' },
  47 + { from: /.*?\.(js)|(css)$/,
  48 + to: (context) => {
  49 + return context.parsedUrl.pathname;
  50 + }
  51 + }
  52 + ]
  53 + },
43 headers: { 54 headers: {
44 'Access-Control-Allow-Origin': '*' 55 'Access-Control-Allow-Origin': '*'
45 }, 56 },
46 proxy: { 57 proxy: {
47 - '**': 'http://localhost:6007' 58 + '/Api': 'http://localhost:6007'
48 } 59 }
49 }, 60 },
50 module: { 61 module: {
@@ -110,7 +121,7 @@ module.exports = { @@ -110,7 +121,7 @@ module.exports = {
110 name: ['view', 'libs'], 121 name: ['view', 'libs'],
111 }), 122 }),
112 new CleanWebpackPlugin(['*'], { 123 new CleanWebpackPlugin(['*'], {
113 - root: util.resolve('../server/public'), 124 + root: util.resolve('./build/bundle'),
114 verbose: true, 125 verbose: true,
115 dry: false 126 dry: false
116 }) 127 })
@@ -9,7 +9,7 @@ const component = function editor(resolve) { @@ -9,7 +9,7 @@ const component = function editor(resolve) {
9 image: { 9 image: {
10 sizeLimit: 512 * 1024, 10 sizeLimit: 512 * 1024,
11 upload: { 11 upload: {
12 - url: '/upload/image', 12 + url: '/Api/upload/image',
13 headers: {}, 13 headers: {},
14 params: { 14 params: {
15 bucket: 'goodsimg' 15 bucket: 'goodsimg'
@@ -19,7 +19,7 @@ export default { @@ -19,7 +19,7 @@ export default {
19 props: { 19 props: {
20 action: { 20 action: {
21 type: String, 21 type: String,
22 - default: '/upload/image' 22 + default: '/Api/upload/image'
23 }, 23 },
24 data: { 24 data: {
25 type: Object, 25 type: Object,
@@ -5,7 +5,7 @@ let purviews = { @@ -5,7 +5,7 @@ let purviews = {
5 subPurviews: { 5 subPurviews: {
6 create: { 6 create: {
7 name: '发布新商品', 7 name: '发布新商品',
8 - path: '/product/create/step1', 8 + path: '/product/create/step1.html',
9 menu: true, 9 menu: true,
10 own: true, 10 own: true,
11 subPurviews: { 11 subPurviews: {
@@ -25,20 +25,20 @@ let purviews = { @@ -25,20 +25,20 @@ let purviews = {
25 }, 25 },
26 onsale: { 26 onsale: {
27 name: '在售商品', 27 name: '在售商品',
28 - path: '/product/onsale', 28 + path: '/product/onsale.html',
29 menu: true, 29 menu: true,
30 own: true 30 own: true
31 }, 31 },
32 offsale: { 32 offsale: {
33 name: '未上架商品', 33 name: '未上架商品',
34 - path: '/product/offsale', 34 + path: '/product/offsale.html',
35 menu: true, 35 menu: true,
36 own: true 36 own: true
37 }, 37 },
38 vips: { 38 vips: {
39 name: 'VIP价格商品', 39 name: 'VIP价格商品',
40 menu: true, 40 menu: true,
41 - path: '/product/vips' 41 + path: '/product/vips.html'
42 } 42 }
43 } 43 }
44 } 44 }
1 const home = r => require.ensure([], () => r(require('./login')), 'auth.login'); 1 const home = r => require.ensure([], () => r(require('./login')), 'auth.login');
2 2
3 export default { 3 export default {
4 - path: '/login', 4 + path: '/login.html',
5 name: 'login', 5 name: 'login',
6 component: home, 6 component: home,
7 meta: { 7 meta: {
1 const page = r => require.ensure([], () => r(require('./error')), 'error'); 1 const page = r => require.ensure([], () => r(require('./error')), 'error');
2 2
3 const router = [{ 3 const router = [{
4 - path: '/401', 4 + path: '/401.html',
5 name: 'error.401', 5 name: 'error.401',
6 component: page, 6 component: page,
7 meta: { 7 meta: {
8 authPass: true 8 authPass: true
9 } 9 }
10 }, { 10 }, {
11 - path: '/404', 11 + path: '/404.html',
12 name: 'error.404', 12 name: 'error.404',
13 component: page, 13 component: page,
14 meta: { 14 meta: {
15 authPass: true 15 authPass: true
16 } 16 }
17 }, { 17 }, {
18 - path: '/500', 18 + path: '/500.html',
19 name: 'error.500', 19 name: 'error.500',
20 component: page, 20 component: page,
21 meta: { 21 meta: {
@@ -2,14 +2,14 @@ @@ -2,14 +2,14 @@
2 <div> 2 <div>
3 默认页 3 默认页
4 <div style="display:none;"> 4 <div style="display:none;">
5 - <Table ref="table" :data="data" :columns="columns"></Table> 5 + <!--<Table ref="table" :data="data" :columns="columns"></Table>
6 <Button @click="getTable">获得数据</Button> 6 <Button @click="getTable">获得数据</Button>
7 <Button @click="addRow">增加一列</Button> 7 <Button @click="addRow">增加一列</Button>
8 {{data}} 8 {{data}}
9 <br /> 9 <br />
10 <editor :content="content" @change="updateData"></editor> 10 <editor :content="content" @change="updateData"></editor>
11 {{content}} 11 {{content}}
12 - <yoho-upload id="123" @on-success="uploadSuccess" @on-error="uploadError"></yoho-upload> 12 + <yoho-upload id="123" @on-success="uploadSuccess" @on-error="uploadError"></yoho-upload>-->
13 </div> 13 </div>
14 </div> 14 </div>
15 </template> 15 </template>
@@ -25,6 +25,9 @@ export default { @@ -25,6 +25,9 @@ export default {
25 </script> 25 </script>
26 26
27 <style lang="scss"> 27 <style lang="scss">
  28 +body {
  29 + color: #444;
  30 +}
28 31
29 .layout { 32 .layout {
30 position: absolute; 33 position: absolute;
@@ -7,15 +7,15 @@ const step3 = r => require.ensure([], () => r(require('./step3')), 'product.crea @@ -7,15 +7,15 @@ const step3 = r => require.ensure([], () => r(require('./step3')), 'product.crea
7 7
8 8
9 export default [{ 9 export default [{
10 - path: 'step1', 10 + path: 'step1.html',
11 name: 'product.create.step1', 11 name: 'product.create.step1',
12 component: step1 12 component: step1
13 }, { 13 }, {
14 - path: 'step2', 14 + path: 'step2.html',
15 name: 'product.create.step2', 15 name: 'product.create.step2',
16 component: step2 16 component: step2
17 }, { 17 }, {
18 - path: 'step3', 18 + path: 'step3.html',
19 name: 'product.create.step3', 19 name: 'product.create.step3',
20 component: step3 20 component: step3
21 }]; 21 }];
@@ -8,49 +8,43 @@ @@ -8,49 +8,43 @@
8 </div> 8 </div>
9 </Row> 9 </Row>
10 10
  11 + <Form :model="product" :label-width="70">
11 <Row> 12 <Row>
12 <Col span="8"> 13 <Col span="8">
13 - <Form :model="product" :label-width="70">  
14 <Form-item label="品 牌*"> 14 <Form-item label="品 牌*">
15 <Select v-model="product.brandId" placeholder="请选择" :label-in-value="true" @on-change="selectBrand"> 15 <Select v-model="product.brandId" placeholder="请选择" :label-in-value="true" @on-change="selectBrand">
16 <Option v-for="brand in brands" :value="brand.brandId" :key="brand">{{ brand.brandName }}</Option> 16 <Option v-for="brand in brands" :value="brand.brandId" :key="brand">{{ brand.brandName }}</Option>
17 </Select> 17 </Select>
18 </Form-item> 18 </Form-item>
19 - </Form>  
20 </Col> 19 </Col>
21 </Row> 20 </Row>
22 21
23 <Row> 22 <Row>
24 <Col span="8" v-if="show[1]"> 23 <Col span="8" v-if="show[1]">
25 - <Form :model="product" :label-width="70">  
26 <Form-item label="类目*"> 24 <Form-item label="类目*">
27 <Select v-model="pickedSortId[1]" placeholder="一级类目" @on-change="selectSort1" :label-in-value="true"> 25 <Select v-model="pickedSortId[1]" placeholder="一级类目" @on-change="selectSort1" :label-in-value="true">
28 <Option v-for="sort in sorts[1]" :value="sort.sortId" :key="sort">{{ sort.sortName }}</Option> 26 <Option v-for="sort in sorts[1]" :value="sort.sortId" :key="sort">{{ sort.sortName }}</Option>
29 </Select> 27 </Select>
30 </Form-item> 28 </Form-item>
31 - </Form>  
32 </Col> 29 </Col>
33 30
34 <Col span="6" offset="1" v-if="show[2]"> 31 <Col span="6" offset="1" v-if="show[2]">
35 - <Form :model="product">  
36 <Form-item> 32 <Form-item>
37 <Select v-model="pickedSortId[2]" placeholder="二级类目" @on-change="selectSort2" :label-in-value="true"> 33 <Select v-model="pickedSortId[2]" placeholder="二级类目" @on-change="selectSort2" :label-in-value="true">
38 <Option v-for="sort in sorts[2]" :value="sort.sortId" :key="sort">{{ sort.sortName }}</Option> 34 <Option v-for="sort in sorts[2]" :value="sort.sortId" :key="sort">{{ sort.sortName }}</Option>
39 </Select> 35 </Select>
40 </Form-item> 36 </Form-item>
41 - </Form>  
42 </Col> 37 </Col>
43 38
44 <Col span="6" offset="1" v-if="show[3]"> 39 <Col span="6" offset="1" v-if="show[3]">
45 - <Form :model="product">  
46 <Form-item> 40 <Form-item>
47 <Select v-model="pickedSortId[3]" placeholder="三级类目" @on-change="selectSort3" :label-in-value="true"> 41 <Select v-model="pickedSortId[3]" placeholder="三级类目" @on-change="selectSort3" :label-in-value="true">
48 <Option v-for="sort in sorts[3]" :value="sort.sortId" :key="sort">{{ sort.sortName }}</Option> 42 <Option v-for="sort in sorts[3]" :value="sort.sortId" :key="sort">{{ sort.sortName }}</Option>
49 </Select> 43 </Select>
50 </Form-item> 44 </Form-item>
51 - </Form>  
52 </Col> 45 </Col>
53 </Row> 46 </Row>
  47 + </Form>
54 48
55 <Row> 49 <Row>
56 <Col span="2" offset="12"> 50 <Col span="2" offset="12">
1 const page = r => require.ensure([], () => r(require('./offsale')), 'product.offsale'); 1 const page = r => require.ensure([], () => r(require('./offsale')), 'product.offsale');
2 2
3 export default { 3 export default {
4 - path: '/offsale', 4 + path: '/offsale.html',
5 name: 'offsale', 5 name: 'offsale',
6 component: page 6 component: page
7 }; 7 };
1 const page = r => require.ensure([], () => r(require('./onsale')), 'product.onsale'); 1 const page = r => require.ensure([], () => r(require('./onsale')), 'product.onsale');
2 2
3 export default { 3 export default {
4 - path: '/onsale', 4 + path: '/onsale.html',
5 name: 'onsale', 5 name: 'onsale',
6 component: page 6 component: page
7 }; 7 };
1 const page = r => require.ensure([], () => r(require('./vips')), 'product.vips'); 1 const page = r => require.ensure([], () => r(require('./vips')), 'product.vips');
2 2
3 export default { 3 export default {
4 - path: '/vips', 4 + path: '/vips.html',
5 name: 'vips', 5 name: 'vips',
6 component: page 6 component: page
7 }; 7 };
@@ -23,7 +23,7 @@ const plugin = { @@ -23,7 +23,7 @@ const plugin = {
23 Vue.$router = options.router; 23 Vue.$router = options.router;
24 options.router.beforeEach((to, from, next) => { 24 options.router.beforeEach((to, from, next) => {
25 if (to.matched.length === 0) { 25 if (to.matched.length === 0) {
26 - return next('/404'); 26 + return next('/404.html');
27 } 27 }
28 return next(); 28 return next();
29 }); 29 });
@@ -38,7 +38,7 @@ const plugin = { @@ -38,7 +38,7 @@ const plugin = {
38 }); 38 });
39 39
40 // 设置axios默认参数 40 // 设置axios默认参数
41 - // axios.defaults.baseURL = ''; 41 + axios.defaults.baseURL = '/Api';
42 axios.defaults.responseType = 'json'; 42 axios.defaults.responseType = 'json';
43 } 43 }
44 }; 44 };
@@ -24,7 +24,7 @@ const plugin = { @@ -24,7 +24,7 @@ const plugin = {
24 if (purview.own) { 24 if (purview.own) {
25 return next(); 25 return next();
26 } else { 26 } else {
27 - return next('/401'); 27 + return next('/401.html');
28 } 28 }
29 } 29 }
30 }); 30 });
@@ -31,10 +31,10 @@ const plugin = { @@ -31,10 +31,10 @@ const plugin = {
31 } 31 }
32 return next(); 32 return next();
33 } else { 33 } else {
34 - return next('/login'); 34 + return next('/login.html');
35 } 35 }
36 } 36 }
37 - return next('/login'); 37 + return next('/login.html');
38 } 38 }
39 }); 39 });
40 Vue.passport = { 40 Vue.passport = {
@@ -52,11 +52,10 @@ const plugin = { @@ -52,11 +52,10 @@ const plugin = {
52 }; 52 };
53 Vue.logout = () => { 53 Vue.logout = () => {
54 Vue.$store.remove(config.userKey); 54 Vue.$store.remove(config.userKey);
55 - Vue.$router.push('/login'); 55 + Vue.$router.push('/login.html');
56 axios.post('/logout'); 56 axios.post('/logout');
57 }; 57 };
58 Vue.updateUser = (user) => { 58 Vue.updateUser = (user) => {
59 - console.log('upda')  
60 Vue.$store.set(config.userKey, user); 59 Vue.$store.set(config.userKey, user);
61 Vue.prototype.isLogin = Vue.isLogin = true; 60 Vue.prototype.isLogin = Vue.isLogin = true;
62 Vue.prototype.$user = user; 61 Vue.prototype.$user = user;
1 -body {  
2 - color: #444;  
3 -}  
  1 +import axios from 'axios';
  2 +
  3 +const purviewService = {
  4 + getPurviews() {
  5 + return axios.post('')
  6 + }
  7 +};
  8 +
  9 +export default purviewService;
@@ -40,7 +40,6 @@ app.use(cookieSession({ @@ -40,7 +40,6 @@ app.use(cookieSession({
40 40
41 app.use(compression()); 41 app.use(compression());
42 app.use(favicon(path.join(__dirname, '/favicon.ico'))); 42 app.use(favicon(path.join(__dirname, '/favicon.ico')));
43 -app.use(Express.static(path.join(__dirname, 'public')));  
44 app.use(bodyParser.json()); 43 app.use(bodyParser.json());
45 app.use(bodyParser.urlencoded({extended: false})); 44 app.use(bodyParser.urlencoded({extended: false}));
46 app.use(cookieParser()); 45 app.use(cookieParser());
@@ -53,7 +52,7 @@ try { @@ -53,7 +52,7 @@ try {
53 app.use(middleware.before); 52 app.use(middleware.before);
54 53
55 // controller 54 // controller
56 - app.use(controllers); 55 + app.use('/Api', controllers);
57 56
58 // // 鉴权中间件 57 // // 鉴权中间件
59 app.use(middleware.auth); 58 app.use(middleware.auth);
@@ -14,8 +14,15 @@ module.exports = (err, req, res, next) => { // eslint-disable-line @@ -14,8 +14,15 @@ module.exports = (err, req, res, next) => { // eslint-disable-line
14 redirect: '/signin.html' 14 redirect: '/signin.html'
15 }); 15 });
16 } 16 }
17 - return res.status(err.code || 500).json({  
18 - code: err.code || 500, 17 + if (err.code === 404) {
  18 + return res.status(404).json({
  19 + code: 404,
  20 + message: 'Not Found'
  21 + });
  22 + }
  23 + return res.status(500).json({
  24 + code: 500,
19 message: '服务器错误!' 25 message: '服务器错误!'
20 }); 26 });
  27 +
21 }; 28 };
@@ -8,6 +8,7 @@ const _ = require('lodash'); @@ -8,6 +8,7 @@ const _ = require('lodash');
8 const blacklist = require('../common/api-blacklist'); 8 const blacklist = require('../common/api-blacklist');
9 const apiDomain = global.yoho.apiDomain; 9 const apiDomain = global.yoho.apiDomain;
10 const logger = global.yoho.logger; 10 const logger = global.yoho.logger;
  11 +const apiReg = /^\/Api/;
11 12
12 module.exports = (req, res, next) => { 13 module.exports = (req, res, next) => {
13 let api = new Api(); 14 let api = new Api();
@@ -16,7 +17,12 @@ module.exports = (req, res, next) => { @@ -16,7 +17,12 @@ module.exports = (req, res, next) => {
16 req, 17 req,
17 res 18 res
18 }); 19 });
19 - let apiMap = req.path.split('/').filter(n => n).join('.'); 20 + if (!apiReg.test(req.path)) {
  21 + return next({
  22 + code: 404
  23 + });
  24 + }
  25 + let apiMap = req.path.replace(apiReg, '').split('/').filter(n => n).join('.');
20 26
21 if (_.some(blacklist, n => n.toLowerCase() === apiMap.toLowerCase())) { 27 if (_.some(blacklist, n => n.toLowerCase() === apiMap.toLowerCase())) {
22 logger.error(`proxy [${req.method}] fail`, `${req.path} can't blacklist`); 28 logger.error(`proxy [${req.method}] fail`, `${req.path} can't blacklist`);