Browse Source

refactor 升级thinkjs 到 3.x 版本

tumobi 8 years ago
parent
commit
9b83144bad
100 changed files with 1497 additions and 2346 deletions
  1. 0 8
      .babelrc
  2. 3 0
      .eslintrc
  3. 3 1
      .gitignore
  4. 0 5
      .thinkjsrc
  5. 1 4
      README.md
  6. 16 0
      development.js
  7. 2 92
      nginx.conf
  8. 29 20
      package.json
  9. 5 6
      pm2.json
  10. 9 0
      production.js
  11. 0 7
      src/admin/config/config.js
  12. 0 7
      src/admin/controller/base.js
  13. 0 84
      src/admin/controller/brand.js
  14. 0 14
      src/admin/controller/index.js
  15. 0 15
      src/admin/logic/brand.js
  16. 0 15
      src/admin/logic/index.js
  17. 0 7
      src/admin/model/index.js
  18. 9 14
      src/api/config/config.js
  19. 28 34
      src/api/controller/address.js
  20. 23 31
      src/api/controller/auth.js
  21. 26 20
      src/api/controller/base.js
  22. 9 23
      src/api/controller/brand.js
  23. 95 98
      src/api/controller/cart.js
  24. 14 19
      src/api/controller/catalog.js
  25. 26 40
      src/api/controller/collect.js
  26. 90 100
      src/api/controller/comment.js
  27. 58 62
      src/api/controller/footprint.js
  28. 270 296
      src/api/controller/goods.js
  29. 25 34
      src/api/controller/index.js
  30. 148 175
      src/api/controller/order.js
  31. 56 69
      src/api/controller/pay.js
  32. 7 11
      src/api/controller/region.js
  33. 11 19
      src/api/controller/search.js
  34. 13 28
      src/api/controller/topic.js
  35. 10 26
      src/api/controller/user.js
  36. 4 14
      src/api/logic/address.js
  37. 4 14
      src/api/logic/auth.js
  38. 4 14
      src/api/logic/brand.js
  39. 4 14
      src/api/logic/cart.js
  40. 3 17
      src/api/logic/catalog.js
  41. 4 14
      src/api/logic/collect.js
  42. 4 14
      src/api/logic/comment.js
  43. 4 14
      src/api/logic/footprint.js
  44. 4 14
      src/api/logic/goods.js
  45. 4 14
      src/api/logic/index.js
  46. 4 15
      src/api/logic/order.js
  47. 4 14
      src/api/logic/pay.js
  48. 4 14
      src/api/logic/region.js
  49. 4 14
      src/api/logic/search.js
  50. 4 14
      src/api/logic/topic.js
  51. 4 14
      src/api/logic/user.js
  52. 28 0
      src/api/model/cart.js
  53. 12 0
      src/api/model/category.js
  54. 13 0
      src/api/model/collect.js
  55. 12 0
      src/api/model/footprint.js
  56. 16 21
      src/api/model/goods.js
  57. 0 7
      src/api/model/index.js
  58. 83 0
      src/api/model/order.js
  59. 80 0
      src/api/model/region.js
  60. 8 23
      src/api/service/token.js
  61. 0 26
      src/common/bootstrap/global.js
  62. 1 0
      src/common/bootstrap/master.js
  63. 0 16
      src/common/bootstrap/middleware.js
  64. 1 0
      src/common/bootstrap/worker.js
  65. 109 0
      src/common/config/adapter.js
  66. 0 17
      src/common/config/cache.js
  67. 4 15
      src/common/config/config.js
  68. 4 0
      src/common/config/config.production.js
  69. 0 22
      src/common/config/db.js
  70. 0 5
      src/common/config/env/development.js
  71. 0 5
      src/common/config/env/production.js
  72. 0 5
      src/common/config/env/testing.js
  73. 0 9
      src/common/config/error.js
  74. 11 0
      src/common/config/extend.js
  75. 0 9
      src/common/config/hook.js
  76. 0 5
      src/common/config/locale/en.js
  77. 41 0
      src/common/config/middleware.js
  78. 3 0
      src/common/config/router.js
  79. 0 20
      src/common/config/session.js
  80. 0 14
      src/common/config/view.js
  81. 0 77
      src/common/controller/error.js
  82. 0 30
      src/common/model/cart.js
  83. 0 15
      src/common/model/category.js
  84. 0 17
      src/common/model/collect.js
  85. 0 22
      src/common/model/footprint.js
  86. 0 7
      src/common/model/member.js
  87. 0 96
      src/common/model/order.js
  88. 0 82
      src/common/model/region.js
  89. 4 7
      src/home/config/config.js
  90. 4 6
      src/home/controller/base.js
  91. 4 11
      src/home/controller/index.js
  92. 4 14
      src/home/logic/index.js
  93. 2 6
      src/home/model/index.js
  94. 4 4
      view/api/index_index.html
  95. 0 24
      view/common/error_400.html
  96. 0 24
      view/common/error_403.html
  97. 0 24
      view/common/error_404.html
  98. 0 24
      view/common/error_500.html
  99. 0 24
      view/common/error_503.html
  100. 0 1
      view/home/index_index.html

+ 0 - 8
.babelrc

@@ -1,8 +0,0 @@
-{
-  "presets": [
-    ["es2015", {"loose": true}],
-    "stage-1"
-  ],
-  "plugins": ["transform-runtime"],
-  "sourceMaps": true
-}

+ 3 - 0
.eslintrc

@@ -0,0 +1,3 @@
+{
+  "extends": "think"
+}

+ 3 - 1
.gitignore

@@ -30,6 +30,8 @@ node_modules/
 output/
 output.tar.gz
 
+runtime/
 app/
 
-runtime/
+config.development.js
+adapter.development.js

+ 0 - 5
.thinkjsrc

@@ -1,5 +0,0 @@
-{
-  "createAt": "2017-05-10 09:45:57",
-  "mode": "module",
-  "es": true
-}

+ 1 - 4
README.md

@@ -6,9 +6,6 @@
 + 服务端api基于Node.js+ThinkJS+MySQL
 + 计划添加基于Vue.js的后台管理系统、PC版、Wap版
 
-**注意:当前版本功能还未完善,请勿商用。**
-
-
 本项目需要配合微信小程序端使用,GitHub: [https://github.com/tumobi/nideshop-mini-program](https://github.com/tumobi/nideshop-mini-program)
 
 
@@ -54,7 +51,7 @@ npm start
 
 ### 线上部署
 
-+ 没有域名部署参考文档:[通过新浪云部署Node.js微信小程序商城(不用买域名、不用备案、不用配置https)](http://www.jianshu.com/p/78a0f5f424e1)
++ 没有域名部署参考文档:[通过新浪云部署NideShop微信小程序商城(基于Node.js+MySQL+ThinkJS)](http://www.jianshu.com/p/78a0f5f424e1)
 
 + 如有域名且已备案,可参考:[阿里云Ubuntu 16.04 下部署Node.js+MySQL微信小程序商城](http://www.jianshu.com/p/38d13a7c1b78)
 

+ 16 - 0
development.js

@@ -0,0 +1,16 @@
+const Application = require('thinkjs');
+const babel = require('think-babel');
+const watcher = require('think-watcher');
+const notifier = require('node-notifier');
+
+const instance = new Application({
+  ROOT_PATH: __dirname,
+  watcher: watcher,
+  transpiler: [babel, {
+    presets: ['think-node']
+  }],
+  notifier: notifier.notify.bind(notifier),
+  env: 'development'
+});
+
+instance.run();

+ 2 - 92
nginx.conf

@@ -1,7 +1,7 @@
 server {
     listen 80;
     server_name example.com www.example.com;
-    root /home/jiaciwang/Code/tmp/you_thinkjs/www;
+    root D:\projects\nideshop/www;
     set $node_port 8360;
 
     index index.js index.html index.htm;
@@ -22,99 +22,9 @@ server {
         proxy_pass http://127.0.0.1:$node_port$request_uri;
         proxy_redirect off;
     }
-    
-    location = /development.js {
-        deny all;
-    }
-
-    location = /testing.js {
-        deny all;
-    }
-
-    location = /production.js {
-        deny all;
-    }
 
     location ~ /static/ {
         etag         on;
         expires      max;
     }
-}   
-
-
-
-
-## http/2 nginx conf
-
-# server {
-#     listen       80;
-#     server_name example.com www.example.com;
-#     rewrite ^(.*) https://example.com$1 permanent;
-# }
-# 
-# server {
-#     listen 443 ssl http2 fastopen=3 reuseport;
-#     server_name www.thinkjs.org thinkjs.org;
-#     set $node_port 8360;
-# 
-#     root /home/jiaciwang/Code/tmp/you_thinkjs/www;
-#     
-#     keepalive_timeout   70;
-# 
-#     ssl_certificate /path/to/certificate;
-#     ssl_certificate_key /path/to/certificate.key;
-#     ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;
-#     ssl_ciphers "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA";
-#     ssl_prefer_server_ciphers on;
-
-#     # openssl dhparam -out dhparams.pem 2048
-#     ssl_dhparam /path/to/dhparams.pem;
-# 
-#     ssl_session_cache   shared:SSL:10m;
-#     ssl_session_timeout 10m;
-# 
-#     ssl_session_ticket_key /path/to/tls_session_ticket.key;
-#     ssl_session_tickets on;
-# 
-#     ssl_stapling             on;
-#     ssl_stapling_verify      on;
-#     ssl_trusted_certificate  /path/to/startssl_trust_chain.crt;
-# 
-# 
-#     add_header x-Content-Type-Options nosniff;
-#     add_header X-Frame-Options deny;
-#     add_header Strict-Transport-Security "max-age=16070400";
-# 
-#     index index.js index.html index.htm;
-#     if ( -f $request_filename/index.html ){
-#         rewrite (.*) $1/index.html break;
-#     }
-#     if ( !-f $request_filename ){
-#         rewrite (.*) /index.js;
-#     }
-#     location = /index.js {
-#         proxy_http_version 1.1;
-#         proxy_set_header X-Real-IP $remote_addr;
-#         proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
-#         proxy_set_header Host $http_host;
-#         proxy_set_header X-NginX-Proxy true;
-#         proxy_set_header Upgrade $http_upgrade;
-#         proxy_set_header Connection "upgrade";
-#         proxy_pass http://127.0.0.1:$node_port$request_uri;
-#         proxy_redirect off;
-#     }
-# 
-#     location = /production.js {
-#         deny all;
-#     }
-# 
-#     location = /testing.js {
-#         deny all;
-#     }
-#
-#    location ~ /static/ {
-#       etag         on;
-#       expires      max;
-#    }
-#}   
-
+}

+ 29 - 20
package.json

@@ -3,33 +3,42 @@
   "description": "application created by thinkjs",
   "version": "1.0.0",
   "scripts": {
-    "start": "node www/development.js",
-    "compile": "babel src/ --out-dir app/",
-    "watch-compile": "node -e \"console.log('<npm run watch-compile> no longer need, use <npm start> command direct.');console.log();\"",
-    "watch": "npm run watch-compile"
+    "start": "node development.js",
+    "compile": "babel --no-babelrc src/ --presets think-node --out-dir app/",
+    "lint": "eslint src/",
+    "lint-fix": "eslint --fix src/"
   },
   "dependencies": {
-    "babel-runtime": "6.x.x",
-    "cheerio": "^0.22.0",
-    "gm": "^1.23.0",
-    "jsonwebtoken": "^7.4.1",
+    "jsonwebtoken": "^8.0.0",
     "lodash": "^4.17.4",
     "moment": "^2.18.1",
-    "redis": "^2.3.0",
     "request": "^2.81.0",
     "request-promise": "^4.2.1",
-    "source-map-support": "0.4.0",
-    "think-cors": "^1.1.2",
-    "thinkjs": "2.2.x",
-    "uid-safe": "^2.1.4"
+    "think-cache": "^1.0.0",
+    "think-cache-file": "^1.0.8",
+    "think-logger3": "^1.0.0",
+    "think-model": "^1.0.0",
+    "think-model-mysql": "^1.0.0",
+    "think-session": "^1.0.0",
+    "think-session-file": "^1.0.5",
+    "think-view": "^1.0.0",
+    "think-view-nunjucks": "^1.0.1",
+    "thinkjs": "^3.0.0"
   },
   "devDependencies": {
-    "babel-cli": "^6.18.0",
-    "babel-preset-es2015": "^6.18.0",
-    "babel-preset-stage-1": "^6.16.0",
-    "babel-plugin-transform-runtime": "^6.15.0",
-    "babel-core": "^6.20.0"
+    "babel-cli": "^6.24.1",
+    "babel-preset-think-node": "^1.0.0",
+    "node-notifier": "^5.0.2",
+    "think-watcher": "^3.0.0",
+    "think-inspect": "0.0.2",
+    "think-babel": "^1.0.3",
+    "eslint": "^4.2.0",
+    "eslint-config-think": "^1.0.0"
   },
   "repository": "",
-  "license": "MIT"
-}
+  "license": "MIT",
+  "engines": {
+    "node": ">=6.0.0"
+  },
+  "readmeFilename": "README.md"
+}

+ 5 - 6
pm2.json

@@ -1,10 +1,9 @@
 {
   "apps": [{
-    "name": "you_thinkjs",
-    "script": "www/production.js",
-    "cwd": "/home/jiaciwang/Code/tmp/you_thinkjs",
-    "exec_mode": "cluster",
-    "instances": 0,
+    "name": "nideshop",
+    "script": "production.js",
+    "cwd": "/var/www/nideshop",
+    "exec_mode": "fork",
     "max_memory_restart": "1G",
     "autorestart": true,
     "node_args": [],
@@ -13,4 +12,4 @@
       
     }
   }]
-}
+}

+ 9 - 0
production.js

@@ -0,0 +1,9 @@
+const Application = require('thinkjs');
+
+const instance = new Application({
+  ROOT_PATH: __dirname,
+  proxy: true, // use proxy
+  env: 'production'
+});
+
+instance.run();

+ 0 - 7
src/admin/config/config.js

@@ -1,7 +0,0 @@
-'use strict';
-/**
- * config
- */
-export default {
-  //key: value
-};

+ 0 - 7
src/admin/controller/base.js

@@ -1,7 +0,0 @@
-'use strict';
-
-export default class extends think.controller.base {
-  /**
-   * some base method in here
-   */
-}

+ 0 - 84
src/admin/controller/brand.js

@@ -1,84 +0,0 @@
-'use strict';
-
-import Base from './base.js';
-const _ = require('lodash');
-const fs = require('fs');
-let gm = require('gm').subClass({imageMagick: true});
-
-export default class extends Base {
-    /**
-     * index action
-     * @return {Promise} []
-     */
-    async indexAction() {
-
-        let page = this.get('page') || 1;
-        let size = this.get('size') || 10;
-        let name = this.get('name') || '';
-
-        let model = this.model('brand');
-        let data = await model.field(['id', 'name', 'floor_price', 'app_list_pic_url', 'is_new', 'sort_order', 'is_show']).where({name: ['like', `%${name}%`]}).page(page, size).countSelect();
-
-        return this.success(data);
-    }
-
-    async infoAction() {
-        let id = this.get('id');
-        let model = this.model('brand');
-        let data = await model.where({id: id}).find();
-
-        return this.success(data);
-    }
-
-    async storeAction(){
-
-        if (!this.isPost()) {
-            return false;
-        }
-
-        let values = this.post();
-        let id = this.post('id');
-
-        let model = this.model('brand');
-        values.is_show = values.is_show ? 1 : 0;
-        values.is_new = values.is_new ? 1 : 0;
-        if (id > 0) {
-            console.log('update')
-
-            await model.where({id: id}).update(values);
-        } else {
-            delete values.id;
-            console.log('add')
-            await model.add(values);
-        }
-        return this.success(values);
-
-    }
-
-    async destoryAction(){
-        let id = this.post('id');
-        await this.model('brand').where({id: id}).limit(1).delete();
-        return this.success();
-    }
-
-    async uploadAction() {
-        let brandFile = this.file('brand_pic');
-        if (think.isEmpty(brandFile)) {
-            return this.fail('保存失败');
-        }
-        let that = this;
-        let filename = '/static/brand/' + think.uuid(32) + '.jpg';
-        gm(brandFile.path)
-            .resize(750, 420, "!")
-            .write(think.RESOURCE_PATH + filename, function (err) {
-                if (err) {
-                    that.fail('图片上传失败');
-                }
-                that.success({
-                    fileUrl: 'http://127.0.0.1:8360' + filename
-                });
-            });
-    }
-
-
-}

+ 0 - 14
src/admin/controller/index.js

@@ -1,14 +0,0 @@
-'use strict';
-
-import Base from './base.js';
-
-export default class extends Base {
-  /**
-   * index action
-   * @return {Promise} []
-   */
-  indexAction(){
-    //auto render template file index_index.html
-    return this.display();
-  }
-}

+ 0 - 15
src/admin/logic/brand.js

@@ -1,15 +0,0 @@
-'use strict';
-/**
- * logic
- * @param  {} []
- * @return {}     []
- */
-export default class extends think.logic.base {
-  /**
-   * index action logic
-   * @return {} []
-   */
-  indexAction(){
-   
-  }
-}

+ 0 - 15
src/admin/logic/index.js

@@ -1,15 +0,0 @@
-'use strict';
-/**
- * logic
- * @param  {} []
- * @return {}     []
- */
-export default class extends think.logic.base {
-  /**
-   * index action logic
-   * @return {} []
-   */
-  indexAction(){
-   
-  }
-}

+ 0 - 7
src/admin/model/index.js

@@ -1,7 +0,0 @@
-'use strict';
-/**
- * model
- */
-export default class extends think.model.base {
-
-}

+ 9 - 14
src/api/config/config.js

@@ -1,13 +1,8 @@
-'use strict';
-/**
- * config
- */
-export default {
-  //key: value
-
-  //可以公开访问的Controller
+// default config
+module.exports = {
+  // 可以公开访问的Controller
   publicController: [
-    //格式为controller
+    // 格式为controller
     'index',
     'catalog',
     'topic',
@@ -15,12 +10,12 @@ export default {
     'goods',
     'brand',
     'search',
-    'region',
+    'region'
   ],
 
-  //可以公开访问的Action
+  // 可以公开访问的Action
   publicAction: [
-    //格式为: controller+action
+    // 格式为: controller+action
     'comment/list',
     'comment/count',
     'cart/index',
@@ -28,6 +23,6 @@ export default {
     'cart/checked',
     'cart/update',
     'cart/delete',
-    'cart/goodscount',
+    'cart/goodscount'
   ]
-};
+};

+ 28 - 34
src/api/controller/address.js

@@ -1,25 +1,21 @@
-'use strict';
+const Base = require('./base.js');
 
-import Base from './base.js';
-
-export default class extends Base {
+module.exports = class extends Base {
   /**
    * 获取用户的收货地址
    * @return {Promise} []
    */
-  async listAction(){
-    let addressList = await this.model('address').where({user_id: think.userId}).select();
+  async listAction() {
+    const addressList = await this.model('address').where({user_id: think.userId}).select();
     let itemKey = 0;
-    for ( let addressItem of addressList) {
-        addressList[itemKey].province_name = await this.model('region').getRegionName(addressItem.province_id);
-        addressList[itemKey].city_name = await this.model('region').getRegionName(addressItem.city_id);
-        addressList[itemKey].district_name = await this.model('region').getRegionName(addressItem.district_id);
-        addressList[itemKey].full_region = addressList[itemKey].province_name + addressList[itemKey].city_name + addressList[itemKey].district_name;
-
-        itemKey += 1;
+    for (const addressItem of addressList) {
+      addressList[itemKey].province_name = await this.model('region').getRegionName(addressItem.province_id);
+      addressList[itemKey].city_name = await this.model('region').getRegionName(addressItem.city_id);
+      addressList[itemKey].district_name = await this.model('region').getRegionName(addressItem.district_id);
+      addressList[itemKey].full_region = addressList[itemKey].province_name + addressList[itemKey].city_name + addressList[itemKey].district_name;
+      itemKey += 1;
     }
 
-
     return this.success(addressList);
   }
 
@@ -27,10 +23,11 @@ export default class extends Base {
    * 获取收货地址的详情
    * @return {Promise} []
    */
-  async detailAction(){
-    let addressId = this.get('id');
-    let addressInfo = await this.model('address').where({user_id: think.userId, id: addressId}).find();
-    if ( !think.isEmpty(addressInfo)) {
+  async detailAction() {
+    const addressId = this.get('id');
+
+    const addressInfo = await this.model('address').where({user_id: think.userId, id: addressId}).find();
+    if (!think.isEmpty(addressInfo)) {
       addressInfo.province_name = await this.model('region').getRegionName(addressInfo.province_id);
       addressInfo.city_name = await this.model('region').getRegionName(addressInfo.city_id);
       addressInfo.district_name = await this.model('region').getRegionName(addressInfo.district_id);
@@ -44,19 +41,18 @@ export default class extends Base {
    * 添加或更新收货地址
    * @returns {Promise.<Promise|PreventPromise|void>}
    */
-  async saveAction(){
-
+  async saveAction() {
     let addressId = this.post('id');
 
-    let addressData = {
+    const addressData = {
       name: this.post('name'),
       mobile: this.post('mobile'),
       province_id: this.post('province_id'),
       city_id: this.post('city_id'),
       district_id: this.post('district_id'),
       address: this.post('address'),
-      user_id: getLoginUserId(),
-      is_default: this.post('is_default') == true ? 1 : 0
+      user_id: this.getLoginUserId(),
+      is_default: this.post('is_default') === true ? 1 : 0
     };
 
     if (think.isEmpty(addressId)) {
@@ -65,14 +61,13 @@ export default class extends Base {
       await this.model('address').where({id: addressId, user_id: think.userId}).update(addressData);
     }
 
-    //如果设置为默认,则取消其它的默认
-    if (this.post('is_default') == true) {
-        await this.model('address').where({id: ['<>', addressId], user_id: think.userId}).update({
-            is_default: 0
-        });
+    // 如果设置为默认,则取消其它的默认
+    if (this.post('is_default') === true) {
+      await this.model('address').where({id: ['<>', addressId], user_id: think.userId}).update({
+        is_default: 0
+      });
     }
-
-    let addressInfo = await this.model('address').where({id: addressId}).find();
+    const addressInfo = await this.model('address').where({id: addressId}).find();
 
     return this.success(addressInfo);
   }
@@ -81,12 +76,11 @@ export default class extends Base {
    * 删除指定的收货地址
    * @returns {Promise.<Promise|PreventPromise|void>}
    */
-  async deleteAction(){
-    let addressId = this.post('id');
+  async deleteAction() {
+    const addressId = this.post('id');
 
     await this.model('address').where({id: addressId, user_id: think.userId}).delete();
 
     return this.success('删除成功');
   }
-
-}
+};

+ 23 - 31
src/api/controller/auth.js

@@ -1,31 +1,25 @@
-'use strict';
-
-import Base from './base.js';
-const rp = require("request-promise");
-const request = require("request");
-const fs = require('fs');
+const Base = require('./base.js');
+const rp = require('request-promise');
 const _ = require('lodash');
 
-export default class extends Base {
+module.exports = class extends Base {
   /**
    * index action
    * @return {Promise} []
    */
   async indexAction() {
-
-    let avatar_path = think.RESOURCE_PATH + '/static/user/avatar/1.' + _.last(_.split('https://img6.bdstatic.com/img/image/smallpic/liutaoxiaotu.jpg', '.'));
-    //rp('https://img6.bdstatic.com/img/image/smallpic/liutaoxiaotu.jpg').pipe(fs.createWriteStream(avatar_path));
-    return this.success(avatar_path);
+    const avatarPath = think.RESOURCE_PATH + '/static/user/avatar/1.' + _.last(_.split('https://img6.bdstatic.com/img/image/smallpic/liutaoxiaotu.jpg', '.'));
+    // rp('https://img6.bdstatic.com/img/image/smallpic/liutaoxiaotu.jpg').pipe(fs.createWriteStream(avatar_path));
+    return this.success(avatarPath);
   }
 
   async loginByWeixinAction() {
+    const code = this.post('code');
+    const fullUserInfo = this.post('userInfo');
+    const userInfo = fullUserInfo.userInfo;
 
-    let code = this.post('code');
-    let fullUserInfo = this.post('userInfo');
-    let userInfo = fullUserInfo.userInfo;
-
-    //获取openid
-    let options = {
+    // 获取openid
+    const options = {
       method: 'GET',
       url: 'https://api.weixin.qq.com/sns/jscode2session',
       qs: {
@@ -38,13 +32,12 @@ export default class extends Base {
 
     let sessionData = await rp(options);
 
-
     sessionData = JSON.parse(sessionData);
     if (!sessionData.openid) {
       return this.fail('登录失败');
     }
 
-    //验证用户信息完整性
+    // 验证用户信息完整性
     const crypto = require('crypto');
     const sha1 = crypto.createHash('sha1').update(fullUserInfo.rawData + sessionData.session_key).digest('hex');
     if (fullUserInfo.signature !== sha1) {
@@ -54,35 +47,34 @@ export default class extends Base {
     // 根据openid查找用户是否已经注册
     let userId = await this.model('user').where({ weixin_openid: sessionData.openid }).getField('id', true);
     if (think.isEmpty(userId)) {
-      //注册
+      // 注册
       userId = await this.model('user').add({
         username: '微信用户' + think.uuid(6),
         password: sessionData.openid,
         register_time: parseInt(new Date().getTime() / 1000),
-        register_ip: this.ip(),
+        register_ip: this.ctx.ip,
         last_login_time: parseInt(new Date().getTime() / 1000),
-        last_login_ip: this.ip(),
+        last_login_ip: this.ctx.ip,
         weixin_openid: sessionData.openid,
         avatar: userInfo.avatarUrl,
-        gender: userInfo.gender, //性别 0:未知、1:男、2:女
+        gender: userInfo.gender, // 性别 0:未知、1:男、2:女
         nickname: userInfo.nickName
       });
     }
 
     sessionData.user_id = userId;
 
-    //查询用户信息
-    let newUserInfo = await this.model('user').field(['id', 'username', 'nickname', 'gender', 'avatar', 'birthday']).where({ id: userId }).find();
+    // 查询用户信息
+    const newUserInfo = await this.model('user').field(['id', 'username', 'nickname', 'gender', 'avatar', 'birthday']).where({ id: userId }).find();
 
-    //更新登录信息
+    // 更新登录信息
     userId = await this.model('user').where({ id: userId }).update({
       last_login_time: parseInt(new Date().getTime() / 1000),
-      last_login_ip: this.ip(),
+      last_login_ip: this.ctx.ip
     });
 
-    let TokenSerivce = this.service('token');
-    let tokenObj = new TokenSerivce();
-    let sessionKey = await tokenObj.create(sessionData);
+    const TokenSerivce = this.service('token', 'api');
+    const sessionKey = await TokenSerivce.create(sessionData);
 
     if (think.isEmpty(newUserInfo) || think.isEmpty(sessionKey)) {
       return this.fail('登录失败');
@@ -94,4 +86,4 @@ export default class extends Base {
   async logoutAction() {
     return this.success();
   }
-}
+};

+ 26 - 20
src/api/controller/base.js

@@ -1,28 +1,34 @@
-'use strict';
-
-export default class extends think.controller.base {
-
-  /**
-   * 前置操作
-   */
+module.exports = class extends think.Controller {
   async __before() {
+    // 根据token值获取用户id
+    think.token = this.ctx.header['x-nideshop-token'] || '';
+    const tokenSerivce = think.service('token', 'api');
+    think.userId = await tokenSerivce.getUserId();
 
-    //根据token值获取用户id
-    think.token = this.header('X-Nideshop-Token') || '';
-    let TokenSerivce = this.service('token');
-    let tokenObj = new TokenSerivce();
-    think.userId = await tokenObj.getUserId();
-
-    const publicController = this.http.config('publicController');
-    const publicAction = this.http.config('publicAction');
-
-    //如果为非公开,则验证用户是否登录
-    console.log(this.http.controller + '/' + this.http.action)
-    if (!publicController.includes(this.http.controller) && !publicAction.includes(this.http.controller + '/' + this.http.action)) {
+    const publicController = this.config('publicController');
+    const publicAction = this.config('publicAction');
+    // 如果为非公开,则验证用户是否登录
+    const controllerAction = this.ctx.controller + '/' + this.ctx.action;
+    if (!publicController.includes(this.ctx.controller) && !publicAction.includes(controllerAction)) {
       if (think.userId <= 0) {
         return this.fail(401, '请先登录');
       }
     }
+  }
 
+  /**
+   * 获取时间戳
+   * @returns {Number}
+   */
+  getTime() {
+    return parseInt(Date.now() / 1000);
+  }
+
+  /**
+   * 获取当前登录用户的id
+   * @returns {*}
+   */
+  getLoginUserId() {
+    return think.userId;
   }
-}
+};

+ 9 - 23
src/api/controller/brand.js

@@ -1,31 +1,17 @@
-'use strict';
+const Base = require('./base.js');
 
-import Base from './base.js';
-
-export default class extends Base {
-  /**
-   * index action
-   * @return {Promise} []
-   */
-  indexAction(){
-    //auto render template file index_index.html
-    return this.display();
-  }
-
-  async listAction(){
-
-    let model = this.model('brand');
-    let data = await model.field(['id', 'name', 'floor_price', 'app_list_pic_url']).page(this.get('page') || 1, this.get('size') || 10).countSelect();
+module.exports = class extends Base {
+  async listAction() {
+    const model = this.model('brand');
+    const data = await model.field(['id', 'name', 'floor_price', 'app_list_pic_url']).page(this.get('page') || 1, this.get('size') || 10).countSelect();
 
     return this.success(data);
   }
 
-  async detailAction(){
-
-    let model = this.model('brand');
-    let data = await model.where({id: this.get('id')}).find();
+  async detailAction() {
+    const model = this.model('brand');
+    const data = await model.where({id: this.get('id')}).find();
 
     return this.success({brand: data});
   }
-
-}
+};

+ 95 - 98
src/api/controller/cart.js

@@ -1,22 +1,18 @@
-'use strict';
-
-import Base from './base.js';
-
-export default class extends Base {
+const Base = require('./base.js');
 
+module.exports = class extends Base {
   /**
    * 获取购物车中的数据
    * @returns {Promise.<{cartList: *, cartTotal: {goodsCount: number, goodsAmount: number, checkedGoodsCount: number, checkedGoodsAmount: number}}>}
    */
-  async getCart(){
-    let cartList = await this.model('cart').where({user_id: think.userId, session_id: 1}).select();
-
-    //获取购物车统计信息
+  async getCart() {
+    const cartList = await this.model('cart').where({user_id: think.userId, session_id: 1}).select();
+    // 获取购物车统计信息
     let goodsCount = 0;
     let goodsAmount = 0.00;
     let checkedGoodsCount = 0;
     let checkedGoodsAmount = 0.00;
-    for (let cartItem of cartList) {
+    for (const cartItem of cartList) {
       goodsCount += cartItem.number;
       goodsAmount += cartItem.number * cartItem.retail_price;
       if (!think.isEmpty(cartItem.checked)) {
@@ -24,8 +20,8 @@ export default class extends Base {
         checkedGoodsAmount += cartItem.number * cartItem.retail_price;
       }
 
-      //查找商品的图片
-        cartItem.list_pic_url = await this.model('goods').where({id: cartItem.goods_id}).getField('list_pic_url', true);
+      // 查找商品的图片
+      cartItem.list_pic_url = await this.model('goods').where({id: cartItem.goods_id}).getField('list_pic_url', true);
     }
 
     return {
@@ -43,7 +39,7 @@ export default class extends Base {
    * 获取购物车信息,所有对购物车的增删改操作,都要重新返回购物车的信息
    * @return {Promise} []
    */
-  async indexAction(){
+  async indexAction() {
     return this.success(await this.getCart());
   }
 
@@ -51,38 +47,39 @@ export default class extends Base {
    * 添加商品到购物车
    * @returns {Promise.<*>}
    */
-  async addAction(){
-
-    let goodsId = this.post('goodsId');
-    let productId = this.post('productId');
-    let number = this.post('number');
-
-    //判断商品是否可以购买
-    let goodsInfo = await this.model('goods').where({id: goodsId}).find();
-    if (think.isEmpty(goodsInfo) || goodsInfo.is_delete == 1) {
+  async addAction() {
+    const goodsId = this.post('goodsId');
+    const productId = this.post('productId');
+    const number = this.post('number');
+
+    // 判断商品是否可以购买
+    const goodsInfo = await this.model('goods').where({id: goodsId}).find();
+    if (think.isEmpty(goodsInfo) || goodsInfo.is_delete === 1) {
       return this.fail(400, '商品已下架');
     }
 
-    //取得规格的信息,判断规格库存
-    let productInfo = await this.model('product').where({goods_id: goodsId, id: productId}).find();
+    // 取得规格的信息,判断规格库存
+    const productInfo = await this.model('product').where({goods_id: goodsId, id: productId}).find();
     if (think.isEmpty(productInfo) || productInfo.goods_number < number) {
       return this.fail(400, '库存不足');
     }
 
-    //判断购物车中是否存在此规格商品
-    let cartInfo = await this.model('cart').where({goods_id: goodsId, product_id: productId}).find();
-    let result = null;
+    // 判断购物车中是否存在此规格商品
+    const cartInfo = await this.model('cart').where({goods_id: goodsId, product_id: productId}).find();
     if (think.isEmpty(cartInfo)) {
-      //添加操作
+      // 添加操作
 
-      //添加规格名和值
+      // 添加规格名和值
       let goodsSepcifitionValue = [];
       if (!think.isEmpty(productInfo.goods_specification_ids)) {
-          goodsSepcifitionValue = await this.model('goods_specification').where({goods_id: goodsId, id: {'in': productInfo.goods_specification_ids.split('_')}}).getField('value');
+        goodsSepcifitionValue = await this.model('goods_specification').where({
+          goods_id: goodsId,
+          id: {'in': productInfo.goods_specification_ids.split('_')}
+        }).getField('value');
       }
 
-      //添加到购物车
-      let cartData = {
+      // 添加到购物车
+      const cartData = {
         goods_id: goodsId,
         product_id: productId,
         goods_sn: productInfo.goods_sn,
@@ -98,39 +95,39 @@ export default class extends Base {
         checked: 1
       };
 
-      result = await this.model('cart').thenAdd(cartData, {product_id: productId});
-
+      await this.model('cart').thenAdd(cartData, {product_id: productId});
     } else {
-      //如果已经存在购物车中,则数量增加
+      // 如果已经存在购物车中,则数量增加
       if (productInfo.goods_number < (number + cartInfo.number)) {
         return this.fail(400, '库存不足');
       }
 
-      result = await this.model('cart').where({goods_id: goodsId, product_id: productId, id: cartInfo.id}).increment('number', number);
-
+      await this.model('cart').where({
+        goods_id: goodsId,
+        product_id: productId,
+        id: cartInfo.id
+      }).increment('number', number);
     }
-
     return this.success(await this.getCart());
   }
 
-  //更新指定的购物车信息
-  async updateAction(){
-
-    let goodsId = this.post('goodsId');
-    let productId = this.post('productId'); //新的product_id
-    let id = this.post('id'); //cart.id
-    let number = parseInt(this.post('number'));  //不是
+  // 更新指定的购物车信息
+  async updateAction() {
+    const goodsId = this.post('goodsId');
+    const productId = this.post('productId'); // 新的product_id
+    const id = this.post('id'); // cart.id
+    const number = parseInt(this.post('number')); // 不是
 
-    //取得规格的信息,判断规格库存
-    let productInfo = await this.model('product').where({goods_id: goodsId, id: productId}).find();
+    // 取得规格的信息,判断规格库存
+    const productInfo = await this.model('product').where({goods_id: goodsId, id: productId}).find();
     if (think.isEmpty(productInfo) || productInfo.goods_number < number) {
       return this.fail(400, '库存不足');
     }
 
-    //判断是否已经存在product_id购物车商品
-    let cartInfo = await this.model('cart').where({id: id}).find();
-    //只是更新number
-    if (cartInfo.product_id == productId) {
+    // 判断是否已经存在product_id购物车商品
+    const cartInfo = await this.model('cart').where({id: id}).find();
+    // 只是更新number
+    if (cartInfo.product_id === productId) {
       await this.model('cart').where({id: id}).update({
         number: number
       });
@@ -138,18 +135,20 @@ export default class extends Base {
       return this.success(await this.getCart());
     }
 
-
-    let newCartInfo = await this.model('cart').where({goods_id: goodsId, product_id: productId}).find();
+    const newCartInfo = await this.model('cart').where({goods_id: goodsId, product_id: productId}).find();
     if (think.isEmpty(newCartInfo)) {
-      //直接更新原来的cartInfo
+      // 直接更新原来的cartInfo
 
-      //添加规格名和值
+      // 添加规格名和值
       let goodsSepcifition = [];
       if (!think.isEmpty(productInfo.goods_specification_ids)) {
-        goodsSepcifition = await this.model('goods_specification').field(['nideshop_goods_specification.*', 'nideshop_specification.name']).join('nideshop_specification ON nideshop_specification.id=nideshop_goods_specification.specification_id').where({'nideshop_goods_specification.goods_id': goodsId, 'nideshop_goods_specification.id': {'in': productInfo.goods_specification_ids.split('_')}}).select();
+        goodsSepcifition = await this.model('goods_specification').field(['nideshop_goods_specification.*', 'nideshop_specification.name']).join('nideshop_specification ON nideshop_specification.id=nideshop_goods_specification.specification_id').where({
+          'nideshop_goods_specification.goods_id': goodsId,
+          'nideshop_goods_specification.id': {'in': productInfo.goods_specification_ids.split('_')}
+        }).select();
       }
 
-      let cartData = {
+      const cartData = {
         number: number,
         goods_specifition_name_value: JSON.stringify(goodsSepcifition),
         goods_specifition_ids: productInfo.goods_specification_ids,
@@ -161,9 +160,8 @@ export default class extends Base {
 
       await this.model('cart').where({id: id}).update(cartData);
     } else {
-      //合并购物车已有的product信息,删除已有的数据
-
-      let newNumber = number + newCartInfo.number;
+      // 合并购物车已有的product信息,删除已有的数据
+      const newNumber = number + newCartInfo.number;
 
       if (think.isEmpty(productInfo) || productInfo.goods_number < newNumber) {
         return this.fail(400, '库存不足');
@@ -171,7 +169,7 @@ export default class extends Base {
 
       await this.model('cart').where({id: newCartInfo.id}).delete();
 
-      let cartData = {
+      const cartData = {
         number: newNumber,
         goods_specifition_name_value: newCartInfo.goods_specifition_name_value,
         goods_specifition_ids: newCartInfo.goods_specification_ids,
@@ -187,25 +185,23 @@ export default class extends Base {
     return this.success(await this.getCart());
   }
 
-  //是否选择商品,如果已经选择,则取消选择,批量操作
-  async checkedAction(){
+  // 是否选择商品,如果已经选择,则取消选择,批量操作
+  async checkedAction() {
     let productId = this.post('productIds').toString();
-    let isChecked = this.post('isChecked');
+    const isChecked = this.post('isChecked');
 
     if (think.isEmpty(productId)) {
       return this.fail('删除出错');
     }
 
     productId = productId.split(',');
-
-    let updateRes = await this.model('cart').where({product_id: {'in': productId}}).update({checked: parseInt(isChecked)});
+    await this.model('cart').where({product_id: {'in': productId}}).update({checked: parseInt(isChecked)});
 
     return this.success(await this.getCart());
-
   }
 
-  //删除选中的购物车商品,批量删除
-  async deleteAction(){
+  // 删除选中的购物车商品,批量删除
+  async deleteAction() {
     let productId = this.post('productIds');
     if (!think.isString(productId)) {
       return this.fail('删除出错');
@@ -213,14 +209,14 @@ export default class extends Base {
 
     productId = productId.split(',');
 
-    let deleteRes = await this.model('cart').where({product_id: {'in': productId}}).delete();
+    await this.model('cart').where({product_id: {'in': productId}}).delete();
 
     return this.success(await this.getCart());
   }
 
-  //获取购物车商品的总件件数
-  async goodscountAction(){
-    let cartData = await this.getCart();
+  // 获取购物车商品的总件件数
+  async goodscountAction() {
+    const cartData = await this.getCart();
     return this.success({
       cartTotal: {
         goodsCount: cartData.cartTotal.goodsCount
@@ -232,39 +228,42 @@ export default class extends Base {
    * 订单提交前的检验和填写相关订单信息
    * @returns {Promise.<void>}
    */
-  async checkoutAction(){
-
-    let addressId = this.get('addressId');  //收货地址id
-    let couponId = this.get('couponId');    //使用的优惠券id
+  async checkoutAction() {
+    const addressId = this.get('addressId'); // 收货地址id
+    // const couponId = this.get('couponId'); // 使用的优惠券id
+
+    // 选择的收货地址
+    let checkedAddress = null;
+    if (addressId) {
+      checkedAddress = await this.model('address').where({is_default: 1, user_id: think.userId}).find();
+    } else {
+      checkedAddress = await this.model('address').where({id: addressId, user_id: think.userId}).find();
+    }
 
-    //选择的收货地址
-    let checkedAddress = await this.model('address').where({is_default: 1, user_id: think.userId}).find();
-    if ( !think.isEmpty(checkedAddress)) {
+    if (!think.isEmpty(checkedAddress)) {
       checkedAddress.province_name = await this.model('region').getRegionName(checkedAddress.province_id);
       checkedAddress.city_name = await this.model('region').getRegionName(checkedAddress.city_id);
       checkedAddress.district_name = await this.model('region').getRegionName(checkedAddress.district_id);
       checkedAddress.full_region = checkedAddress.province_name + checkedAddress.city_name + checkedAddress.district_name;
     }
 
-    //根据收货地址计算运费
-    let freightPrice = 0.00;
+    // 根据收货地址计算运费
+    const freightPrice = 0.00;
 
-    //获取要购买的商品
-    let cartData = await this.getCart();
-    let checkedGoodsList = cartData.cartList.filter(function (v) {
+    // 获取要购买的商品
+    const cartData = await this.getCart();
+    const checkedGoodsList = cartData.cartList.filter(function(v) {
       return v.checked === 1;
     });
 
+    // 获取可用的优惠券信息,功能还示实现
+    const couponList = await this.model('user_coupon').select();
+    const couponPrice = 0.00; // 使用优惠券减免的金额
 
-    //获取可用的优惠券信息,功能还示实现
-    let couponList = await this.model('user_coupon').select();
-    let couponPrice = 0.00;  //使用优惠券减免的金额
-
-
-    //计算订单的费用
-    let goodsTotalPrice = cartData.cartTotal.checkedGoodsAmount;  //商品总价
-    let orderTotalPrice = cartData.cartTotal.checkedGoodsAmount + freightPrice - couponPrice;  //订单的总价
-    let actualPrice = orderTotalPrice - 0.00;  //减去其它支付的金额后,要实际支付的金额
+    // 计算订单的费用
+    const goodsTotalPrice = cartData.cartTotal.checkedGoodsAmount; // 商品总价
+    const orderTotalPrice = cartData.cartTotal.checkedGoodsAmount + freightPrice - couponPrice; // 订单的总价
+    const actualPrice = orderTotalPrice - 0.00; // 减去其它支付的金额后,要实际支付的金额
 
     return this.success({
       checkedAddress: checkedAddress,
@@ -275,9 +274,7 @@ export default class extends Base {
       checkedGoodsList: checkedGoodsList,
       goodsTotalPrice: goodsTotalPrice,
       orderTotalPrice: orderTotalPrice,
-      actualPrice: actualPrice,
+      actualPrice: actualPrice
     });
-
   }
-
-}
+};

+ 14 - 19
src/api/controller/catalog.js

@@ -1,29 +1,26 @@
-'use strict';
+const Base = require('./base.js');
 
-import Base from './base.js';
-
-export default class extends Base {
+module.exports = class extends Base {
   /**
    * 获取分类栏目数据
    * @returns {Promise.<Promise|void|PreventPromise>}
    */
-  async indexAction(){
-
-    let categoryId = this.get('id');
+  async indexAction() {
+    const categoryId = this.get('id');
 
-    let model = this.model('category');
-    let data = await model.limit(10).where({parent_id: 0}).select();
+    const model = this.model('category');
+    const data = await model.limit(10).where({parent_id: 0}).select();
 
     let currentCategory = null;
     if (categoryId) {
-      currentCategory = await model.where({'id' : categoryId}).find();
+      currentCategory = await model.where({'id': categoryId}).find();
     }
 
     if (think.isEmpty(currentCategory)) {
       currentCategory = data[0];
     }
 
-    //获取子分类数据
+    // 获取子分类数据
     if (currentCategory && currentCategory.id) {
       currentCategory.subCategoryList = await model.where({'parent_id': currentCategory.id}).select();
     }
@@ -34,17 +31,15 @@ export default class extends Base {
     });
   }
 
-  async currentAction(){
-
-    let categoryId = this.get('id');
-
-    let model = this.model('category');
+  async currentAction() {
+    const categoryId = this.get('id');
+    const model = this.model('category');
 
     let currentCategory = null;
     if (categoryId) {
-      currentCategory = await model.where({'id' : categoryId}).find();
+      currentCategory = await model.where({'id': categoryId}).find();
     }
-    //获取子分类数据
+    // 获取子分类数据
     if (currentCategory && currentCategory.id) {
       currentCategory.subCategoryList = await model.where({'parent_id': currentCategory.id}).select();
     }
@@ -53,4 +48,4 @@ export default class extends Base {
       currentCategory: currentCategory
     });
   }
-}
+};

+ 26 - 40
src/api/controller/collect.js

@@ -1,61 +1,47 @@
-'use strict';
+const Base = require('./base.js');
 
-import Base from './base.js';
+module.exports = class extends Base {
+  async listAction() {
+    const typeId = this.get('typeId');
 
-export default class extends Base {
-
-  /**
-   * index action
-   * @return {Promise} []
-   */
-  indexAction(){
-    //auto render template file index_index.html
-    return this.display();
-  }
-
-  async listAction(){
-
-    let typeId = this.post('typeId');
-
-    let list = await this.model('collect')
+    const list = await this.model('collect')
       .field(['c.*', 'g.name', 'g.list_pic_url', 'g.goods_brief', 'g.retail_price'])
       .alias('c')
       .join({
         table: 'goods',
-        join: 'left', //join 方式,有 left, right, inner 3 种方式
-        as: 'g', // 表别名
-        on: ['c.value_id', 'g.id'] //ON 条件
-      }).where({user_id: think.userId, type_id: typeId}).countSelect();
-
+        join: 'left',
+        as: 'g',
+        on: ['c.value_id', 'g.id']
+      }).where({user_id: think.userId, type_id: parseInt(typeId)}).countSelect();
 
     return this.success(list);
   }
 
-  async addordeleteAction(){
-    let typeId = this.post('typeId');
-    let valueId = this.post('valueId');
+  async addordeleteAction() {
+    const typeId = this.post('typeId');
+    const valueId = this.post('valueId');
 
-    let collect = await this.model('collect').where({type_id: typeId, value_id: valueId, user_id: think.userId}).find();
+    const collect = await this.model('collect').where({type_id: typeId, value_id: valueId, user_id: think.userId}).find();
     let collectRes = null;
     let handleType = 'add';
     if (think.isEmpty(collect)) {
-      //添加收藏
-        collectRes = await this.model('collect').add({
-            type_id: typeId,
-            value_id: valueId,
-            user_id: think.userId,
-            add_time: parseInt(new Date().getTime() / 1000)
-        });
+      // 添加收藏
+      collectRes = await this.model('collect').add({
+        type_id: typeId,
+        value_id: valueId,
+        user_id: think.userId,
+        add_time: parseInt(new Date().getTime() / 1000)
+      });
     } else {
-      //取消收藏
-        collectRes = await this.model('collect').where({id: collect.id}).delete();
-        handleType = 'delete';
+      // 取消收藏
+      collectRes = await this.model('collect').where({id: collect.id}).delete();
+      handleType = 'delete';
     }
 
-    if ( collectRes > 0) {
-        return this.success({type: handleType});
+    if (collectRes > 0) {
+      return this.success({type: handleType});
     }
 
     return this.fail('操作失败');
   }
-}
+};

+ 90 - 100
src/api/controller/comment.js

@@ -1,104 +1,94 @@
-'use strict';
-
-import Base from './base.js';
-
-export default class extends Base {
-
-    /**
-     * 评论类型说明:
-     * 0 商品
-     * 1 专题
-     */
-
-    /**
-     * 发表评论
-     * @returns {Promise.<*|PreventPromise|void|Promise>}
-     */
-    async postAction() {
-
-        let typeId = this.post('typeId');
-        let valueId = this.post('valueId');
-        let content = this.post('content');
-        let buffer = new Buffer(content);
-        let insertId  = await this.model('comment').add({
-            type_id: typeId,
-            value_id: valueId,
-            content: buffer.toString('base64'),
-            add_time: getTime(),
-            user_id: getLoginUserId()
-        });
-
-        if (insertId ) {
-            return this.success('评论添加成功');
-        } else {
-            return this.fail('评论保存失败');
-        }
+const Base = require('./base.js');
+
+module.exports = class extends Base {
+  /**
+   * 评论类型说明:
+   * 0 商品
+   * 1 专题
+   */
+
+  /**
+   * 发表评论
+   * @returns {Promise.<*|PreventPromise|void|Promise>}
+   */
+  async postAction() {
+    const typeId = this.post('typeId');
+    const valueId = this.post('valueId');
+    const content = this.post('content');
+    const buffer = new Buffer(content);
+    const insertId = await this.model('comment').add({
+      type_id: typeId,
+      value_id: valueId,
+      content: buffer.toString('base64'),
+      add_time: this.getTime(),
+      user_id: this.getLoginUserId()
+    });
+
+    if (insertId) {
+      return this.success('评论添加成功');
+    } else {
+      return this.fail('评论保存失败');
     }
-
-    async countAction() {
-
-        let typeId = this.get('typeId');
-        let valueId = this.get('valueId');
-
-        let allCount = await this.model('comment').where({type_id: typeId, value_id: valueId}).count('id');
-
-        let hasPicCount = await this.model('comment').alias('comment')
-            .join({
-                table: 'comment_picture',
-                join: 'right', //join 方式,有 left, right, inner 3 种方式
-                alias: 'comment_picture',
-                on: ['id', 'comment_id'] //ON 条件
-            }).where({'comment.type_id': typeId, 'comment.value_id': valueId}).count('comment.id');
-
-
-        return this.success({
-            allCount: allCount,
-            hasPicCount: hasPicCount
-        });
+  }
+
+  async countAction() {
+    const typeId = this.get('typeId');
+    const valueId = this.get('valueId');
+
+    const allCount = await this.model('comment').where({type_id: typeId, value_id: valueId}).count('id');
+
+    const hasPicCount = await this.model('comment').alias('comment')
+      .join({
+        table: 'comment_picture',
+        join: 'right',
+        alias: 'comment_picture',
+        on: ['id', 'comment_id']
+      }).where({'comment.type_id': typeId, 'comment.value_id': valueId}).count('comment.id');
+
+    return this.success({
+      allCount: allCount,
+      hasPicCount: hasPicCount
+    });
+  }
+
+  async listAction() {
+    const typeId = this.get('typeId');
+    const valueId = this.get('valueId');
+    const showType = this.get('showType'); // 选择评论的类型 0 全部, 1 只显示图片
+
+    const page = this.get('page');
+    const size = this.get('size');
+
+    let comments = [];
+    if (showType !== 1) {
+      comments = await this.model('comment').where({
+        type_id: typeId,
+        value_id: valueId
+      }).page(page, size).countSelect();
+    } else {
+      comments = await this.model('comment').alias('comment')
+        .field(['comment.*'])
+        .join({
+          table: 'comment_picture',
+          join: 'right',
+          alias: 'comment_picture',
+          on: ['id', 'comment_id']
+        }).page(page, size).where({'comment.type_id': typeId, 'comment.value_id': valueId}).countSelect();
     }
 
-    async listAction() {
-
-        let typeId = this.get('typeId');
-        let valueId = this.get('valueId');
-        let showType = this.get('showType'); //选择评论的类型 0 全部, 1 只显示图片
-
-        let page = this.get('page');
-        let size = this.get('size');
-
-        let comments = [];
-
-        if (showType != 1) {
-            comments = await this.model('comment').where({
-                type_id: typeId,
-                value_id: valueId
-            }).page(page, size).countSelect();
-
-        } else {
-            comments = await this.model('comment').alias('comment')
-                .field(['comment.*'])
-                .join({
-                    table: 'comment_picture',
-                    join: 'right', //join 方式,有 left, right, inner 3 种方式
-                    alias: 'comment_picture',
-                    on: ['id', 'comment_id'] //ON 条件
-                }).page(page, size).where({'comment.type_id': typeId, 'comment.value_id': valueId}).countSelect();
-        }
-
-
-        let commentList = [];
-        for (let commentItem of comments.data) {
-            let comment = {};
-            comment.content = new Buffer(commentItem.content, 'base64').toString();
-            comment.type_id = commentItem.type_id;
-            comment.value_id = commentItem.value_id;
-            comment.id = commentItem.id;
-            comment.add_time = think.datetime(new Date(commentItem.add_time * 1000));
-            comment.user_info = await this.model('user').field(['username', 'avatar', 'nickname']).where({id: commentItem.user_id}).find();
-            comment.pic_list = await this.model('comment_picture').where({comment_id: commentItem.id}).select();
-            commentList.push(comment);
-        }
-        comments.data = commentList;
-        return this.success(comments);
+    const commentList = [];
+    for (const commentItem of comments.data) {
+      const comment = {};
+      comment.content = new Buffer(commentItem.content, 'base64').toString();
+      comment.type_id = commentItem.type_id;
+      comment.value_id = commentItem.value_id;
+      comment.id = commentItem.id;
+      comment.add_time = think.datetime(new Date(commentItem.add_time * 1000));
+      comment.user_info = await this.model('user').field(['username', 'avatar', 'nickname']).where({id: commentItem.user_id}).find();
+      comment.pic_list = await this.model('comment_picture').where({comment_id: commentItem.id}).select();
+      commentList.push(comment);
     }
-}
+    comments.data = commentList;
+    return this.success(comments);
+  }
+};

+ 58 - 62
src/api/controller/footprint.js

@@ -1,68 +1,64 @@
-'use strict';
+const Base = require('./base.js');
+const moment = require('moment');
+const _ = require('lodash');
 
-import Base from './base.js';
-let moment = require('moment');
-let _ = require('lodash');
+module.exports = class extends Base {
+  /**
+   *
+   * @returns {Promise<void|Promise|PreventPromise>}
+   */
+  async deleteAction() {
+    const footprintId = this.post('footprintId');
+    const userId = this.getLoginUserId();
+    // 删除当天的同一个商品的足迹
+    const goods = await this.model('footprint').where({user_id: userId, id: footprintId}).find();
+    await this.model('footprint').where({user_id: userId, goods_id: goods.goods_id}).delete();
 
-export default class extends Base {
+    return this.success('删除成功');
+  }
 
-    /**
-     *
-     * @returns {Promise<void|Promise|PreventPromise>}
-     */
-    async deleteAction(){
-        let footprintId = this.post('footprintId');
-        let userId = getLoginUserId();
-        //删除当天的同一个商品的足迹
-        let goods = await this.model('footprint').where({user_id: userId, id: footprintId}).find();
-        await this.model('footprint').where({user_id: userId, goods_id: goods.goods_id}).delete();
+  /**
+   * list action
+   * @return {Promise} []
+   */
+  async listAction() {
+    const list = await this.model('footprint')
+      .field(['f.*', 'g.name', 'g.list_pic_url', 'g.goods_brief', 'g.retail_price'])
+      .alias('f')
+      .join({
+        table: 'goods',
+        join: 'left',
+        as: 'g',
+        on: ['f.goods_id', 'g.id']
+      }).where({user_id: this.getLoginUserId()})
+      .order({id: 'desc'})
+      .countSelect();
 
-        return this.success('删除成功');
-    }
+    // 去重、格式化日期、按天分组
+    list.data = _.map(_.uniqBy(list.data, function(item) {
+      return item.goods_id;
+    }), (item) => {
+      item.add_time = moment.unix(item.add_time).format('YYYY-MM-DD');
+      // 今天
+      if (moment().format('YYYY-MM-DD') === item.add_time) {
+        item.add_time = '今天';
+      }
+      // 昨天
+      if (moment().subtract(1, 'days').format('YYYY-MM-DD') === item.add_time) {
+        item.add_time = '昨天';
+      }
+      // 前天
+      if (moment().subtract(2, 'days').format('YYYY-MM-DD') === item.add_time) {
+        item.add_time = '前天';
+      }
+      return item;
+    });
 
-    /**
-     * list action
-     * @return {Promise} []
-     */
-    async listAction() {
+    list.data = _.groupBy(list.data, function(item) {
+      return item.add_time;
+    });
+    list.data = _.values(list.data);
 
-        let list = await this.model('footprint')
-            .field(['f.*', 'g.name', 'g.list_pic_url', 'g.goods_brief', 'g.retail_price'])
-            .alias('f')
-            .join({
-                table: 'goods',
-                join: 'left', //join 方式,有 left, right, inner 3 种方式
-                as: 'g', // 表别名
-                on: ['f.goods_id', 'g.id'] //ON 条件
-            }).where({user_id: getLoginUserId()})
-            .order({id: 'desc'})
-            .countSelect();
-
-        //去重、格式化日期、按天分组
-        list.data = _.map(_.uniqBy(list.data, function (item) {
-            return item.goods_id;
-        }), (item) => {
-            item.add_time = moment.unix(item.add_time).format('YYYY-MM-DD');
-            //今天
-            if (moment().format('YYYY-MM-DD') == item.add_time) {
-                item.add_time = '今天';
-            }
-            //昨天
-            if (moment().subtract(1, 'days').format('YYYY-MM-DD') == item.add_time) {
-                item.add_time = '昨天';
-            }
-            //前天
-            if (moment().subtract(2, 'days').format('YYYY-MM-DD') == item.add_time) {
-                item.add_time = '前天';
-            }
-            return item;
-        });
-
-        list.data = _.groupBy(list.data, function (item) {
-            return item.add_time;
-        });
-        list.data = _.values(list.data);
-
-        return this.success(list);
-    }
-}
+    return this.success(list);
+  }
+};

+ 270 - 296
src/api/controller/goods.js

@@ -1,320 +1,294 @@
-'use strict';
-
-import Base from './base.js';
-
-export default class extends Base {
-    /**
-     * index action
-     * @return {Promise} []
-     */
-    async indexAction() {
-
-        let model = this.model('goods');
-        let goodsList = await model.select();
-
-        return this.success(goodsList);
+const Base = require('./base.js');
+
+module.exports = class extends Base {
+  async indexAction() {
+    const model = this.model('goods');
+    const goodsList = await model.select();
+
+    return this.success(goodsList);
+  }
+
+  /**
+   * 获取sku信息,用于购物车编辑时选择规格
+   * @returns {Promise.<Promise|PreventPromise|void>}
+   */
+  async skuAction() {
+    const goodsId = this.get('id');
+    const model = this.model('goods');
+
+    return this.success({
+      specificationList: await model.getSpecificationList(goodsId),
+      productList: await model.getProductList(goodsId)
+    });
+  }
+
+  /**
+   * 商品详情页数据
+   * @returns {Promise.<Promise|PreventPromise|void>}
+   */
+  async detailAction() {
+    const goodsId = this.get('id');
+    const model = this.model('goods');
+
+    const info = await model.where({'id': goodsId}).find();
+    const gallery = await this.model('goods_gallery').where({goods_id: goodsId}).limit(4).select();
+    const attribute = await this.model('goods_attribute').field('nideshop_goods_attribute.value, nideshop_attribute.name').join('nideshop_attribute ON nideshop_goods_attribute.attribute_id=nideshop_attribute.id').order({'nideshop_goods_attribute.id': 'asc'}).where({'nideshop_goods_attribute.goods_id': goodsId}).select();
+    const issue = await this.model('goods_issue').select();
+    const brand = await this.model('brand').where({id: info.brand_id}).find();
+    const commentCount = await this.model('comment').where({value_id: goodsId, type_id: 0}).count();
+    const hotComment = await this.model('comment').where({value_id: goodsId, type_id: 0}).find();
+    let commentInfo = {};
+    if (!think.isEmpty(hotComment)) {
+      const commentUser = await this.model('user').field(['nickname', 'username', 'avatar']).where({id: hotComment.user_id}).find();
+      commentInfo = {
+        content: new Buffer(hotComment.content, 'base64').toString(),
+        add_time: think.datetime(new Date(hotComment.add_time * 1000)),
+        nickname: commentUser.nickname,
+        avatar: commentUser.avatar,
+        pic_list: await this.model('comment_picture').where({comment_id: hotComment.id}).select()
+      };
     }
 
+    const comment = {
+      count: commentCount,
+      data: commentInfo
+    };
+
+    // 当前用户是否收藏
+    const userHasCollect = await this.model('collect').isUserHasCollect(think.userId, 0, goodsId);
+
+    // 记录用户的足迹 TODO
+    await await this.model('footprint').addFootprint(think.userId, goodsId);
+
+    // return this.json(jsonData);
+    return this.success({
+      info: info,
+      gallery: gallery,
+      attribute: attribute,
+      userHasCollect: userHasCollect,
+      issue: issue,
+      comment: comment,
+      brand: brand,
+      specificationList: await model.getSpecificationList(goodsId),
+      productList: await model.getProductList(goodsId)
+    });
+  }
+
+  /**
+   * 获取分类下的商品
+   * @returns {Promise.<*>}
+   */
+  async categoryAction() {
+    const model = this.model('category');
+    const currentCategory = await model.where({id: this.get('id')}).find();
+    const parentCategory = await model.where({id: currentCategory.parent_id}).find();
+    const brotherCategory = await model.where({parent_id: currentCategory.parent_id}).select();
+
+    return this.success({
+      currentCategory: currentCategory,
+      parentCategory: parentCategory,
+      brotherCategory: brotherCategory
+    });
+  }
+
+  /**
+   * 获取商品列表
+   * @returns {Promise.<*>}
+   */
+  async listAction() {
+    const categoryId = this.get('categoryId');
+    const brandId = this.get('brandId');
+    const keyword = this.get('keyword');
+    const isNew = this.get('isNew');
+    const isHot = this.get('isHot');
+    const page = this.get('page');
+    const size = this.get('size');
+    const sort = this.get('sort');
+    const order = this.get('order');
+
+    const goodsQuery = this.model('goods');
+
+    const whereMap = {};
+    if (!think.isEmpty(isNew)) {
+      whereMap.is_new = isNew;
+    }
 
-    /**
-     * 获取sku信息,用于购物车编辑时选择规格
-     * @returns {Promise.<Promise|PreventPromise|void>}
-     */
-    async skuAction() {
-
-        let goodsId = this.get('id');
-        let model = this.model('goods');
+    if (!think.isEmpty(isHot)) {
+      whereMap.is_hot = isHot;
+    }
 
-        return this.success({
-            specificationList: await model.getSpecificationList(goodsId),
-            productList: await model.getProductList(goodsId)
-        });
+    if (!think.isEmpty(keyword)) {
+      whereMap.name = ['like', `%${keyword}%`];
+      // 添加到搜索历史
+      await this.model('search_history').add({
+        keyword: keyword,
+        user_id: think.userId,
+        add_time: parseInt(new Date().getTime() / 1000)
+      });
     }
 
-    /**
-     * 商品详情页数据
-     * @returns {Promise.<Promise|PreventPromise|void>}
-     */
-    async detailAction() {
-
-        let goodsId = this.get('id');
-        let model = this.model('goods');
-
-        let info = await model.where({'id': goodsId}).find();
-        let gallery = await this.model('goods_gallery').where({goods_id: goodsId}).limit(4).select();
-        let attribute = await this.model('goods_attribute').field('nideshop_goods_attribute.value, nideshop_attribute.name').join('nideshop_attribute ON nideshop_goods_attribute.attribute_id=nideshop_attribute.id').order({'nideshop_goods_attribute.id': 'asc'}).where({'nideshop_goods_attribute.goods_id': goodsId}).select();
-        let issue = await this.model('goods_issue').select();
-        let brand = await this.model('brand').where({id: info.brand_id}).find();
-        let commentCount = await this.model('comment').where({value_id: goodsId, type_id: 0}).count();
-        let hotComment = await this.model('comment').where({value_id: goodsId, type_id: 0}).find();
-        let commentInfo = {};
-        if (!think.isEmpty(hotComment)) {
-            let commentUser = await this.model('user').field(['nickname', 'username', 'avatar']).where({id: hotComment.user_id}).find();
-            commentInfo = {
-                content: new Buffer(hotComment.content, 'base64').toString(),
-                add_time: think.datetime(new Date(hotComment.add_time * 1000)),
-                nickname: commentUser.nickname,
-                avatar: commentUser.avatar,
-                pic_list: await this.model('comment_picture').where({comment_id: hotComment.id}).select()
-            }
-        }
-        let comment = {
-            count: commentCount,
-            data: commentInfo
-        };
-
-
-        //当前用户是否收藏
-        let userHasCollect = await this.model('collect').isUserHasCollect(think.userId, 0, goodsId);
-
-        //记录用户的足迹 TODO
-        await await this.model('footprint').addFootprint(goodsId);
-
-        // return this.json(jsonData);
-        return this.success({
-            info: info,
-            gallery: gallery,
-            attribute: attribute,
-            userHasCollect: userHasCollect,
-            issue: issue,
-            comment: comment,
-            brand: brand,
-            specificationList: await model.getSpecificationList(goodsId),
-            productList: await model.getProductList(goodsId)
-        });
+    if (!think.isEmpty(brandId)) {
+      whereMap.brand_id = brandId;
     }
 
-    /**
-     * 获取分类下的商品
-     * @returns {Promise.<Promise|PreventPromise|void>}
-     */
-    async categoryAction() {
-
-        const model = this.model('category');
-        let currentCategory = await model.where({id: this.get('id')}).find();
-        let parentCategory = await model.where({id: currentCategory.parent_id}).find();
-        let brotherCategory = await model.where({parent_id: currentCategory.parent_id}).select();
-        let categoryGoods = await this.model('goods').field(['id', 'name', 'list_pic_url', 'retail_price']).where({category_id: currentCategory.id}).select();
-
-        // return this.success(ftlData);
-        return this.success({
-            currentCategory: currentCategory,
-            parentCategory: parentCategory,
-            brotherCategory: brotherCategory
-        });
+    // 排序
+    let orderMap = {};
+    if (sort === 'price') {
+      // 按价格
+      orderMap = {
+        retail_price: order
+      };
+    } else {
+      // 按商品添加时间
+      orderMap = {
+        id: 'desc'
+      };
     }
 
-    /**
-     * 获取商品列表
-     * @returns {Promise.<Promise|PreventPromise|void>}
-     */
-    async listAction() {
-
-        let categoryId = this.get('categoryId');
-        let brandId = this.get('brandId');
-        let keyword = this.get('keyword');
-        let isNew = this.get('isNew');
-        let isHot = this.get('isHot');
-        let page = this.get('page');
-        let size = this.get('size');
-        let sort = this.get('sort');
-        let order = this.get('order');
-
-        let goodsQuery = this.model('goods');
-
-        let whereMap = {};
-        if (!think.isEmpty(isNew)) {
-            whereMap.is_new = isNew;
-        }
-
-        if (!think.isEmpty(isHot)) {
-            whereMap.is_hot = isHot;
-        }
-
-        if (!think.isEmpty(keyword)) {
-            whereMap.name = ['like', `%${keyword}%`];
-
-            //添加到搜索历史
-            let keywords = await this.model('search_history').add({
-                keyword: keyword,
-                user_id: think.userId,
-                add_time: parseInt(new Date().getTime() / 1000)
-            });
-
-        }
-
-        if (!think.isEmpty(brandId)) {
-            whereMap.brand_id = brandId;
-        }
-
-        //排序
-        let orderMap = {};
-        if (sort === 'price') {
-            //按价格
-            orderMap = {
-                retail_price: order
-            };
-        } else {
-            //按商品添加时间
-            orderMap = {
-                id: 'desc'
-            };
-        }
-
-        //筛选的分类
-        let filterCategory = [{
-            'id': 0,
-            'name': '全部',
-            'checked': false
-        }];
-
-        let categoryIds = await goodsQuery.where(whereMap).getField('category_id', 10000);
-        if (!think.isEmpty(categoryIds)) {
-            //查找二级分类的parent_id
-            let parentIds = await this.model('category').where({id: {'in': categoryIds}}).getField('parent_id', 10000);
-            //一级分类
-            let parentCategory = await this.model('category').field(['id', 'name']).order({'sort_order': 'asc'}).where({'id': {'in': parentIds}}).select();
-
-            if (!think.isEmpty(parentCategory)) {
-                filterCategory = filterCategory.concat(parentCategory);
-            }
-        }
-
-        //加入分类条件
-        if (!think.isEmpty(categoryId) && parseInt(categoryId) > 0) {
-            whereMap.category_id = ['in', await this.model('category').getCategoryWhereIn(categoryId)];
-        }
-        console.log(whereMap);
-
-        //搜索到的商品
-        let goodsData = await goodsQuery.where(whereMap).field(['id', 'name', 'list_pic_url', 'retail_price']).order(orderMap).page(page, size).countSelect();
-        goodsData.filterCategory = filterCategory.map(function (v) {
-            if ((think.isEmpty(categoryId) && v.id === 0) || v.id === parseInt(categoryId)) {
-                v.checked = true;
-            } else {
-                v.checked = false;
-            }
-            return v;
-        });
-        goodsData.goodsList = goodsData.data;
-        return this.success(goodsData);
+    // 筛选的分类
+    let filterCategory = [{
+      'id': 0,
+      'name': '全部',
+      'checked': false
+    }];
+
+    const categoryIds = await goodsQuery.where(whereMap).getField('category_id', 10000);
+    if (!think.isEmpty(categoryIds)) {
+      // 查找二级分类的parent_id
+      const parentIds = await this.model('category').where({id: {'in': categoryIds}}).getField('parent_id', 10000);
+      // 一级分类
+      const parentCategory = await this.model('category').field(['id', 'name']).order({'sort_order': 'asc'}).where({'id': {'in': parentIds}}).select();
+
+      if (!think.isEmpty(parentCategory)) {
+        filterCategory = filterCategory.concat(parentCategory);
+      }
     }
 
-    /**
-     * 商品列表筛选的分类列表
-     * @returns {Promise.<Promise|void|PreventPromise>}
-     */
-    async filterAction() {
-
-        let categoryId = this.get('categoryId');
-        let keyword = this.get('keyword');
-        let isNew = this.get('isNew');
-        let isHot = this.get('isHot');
-
-        let goodsQuery = this.model('goods');
-
-        if (!think.isEmpty(categoryId)) {
-            goodsQuery.where({category_id: {'in': await this.model('category').getChildCategoryId(categoryId)}});
-        }
-
-        if (!think.isEmpty(isNew)) {
-            goodsQuery.where({is_new: isNew});
-        }
-
-        if (!think.isEmpty(isHot)) {
-            goodsQuery.where({is_hot: isHot});
-        }
-
-        if (!think.isEmpty(keyword)) {
-            goodsQuery.where({name: {'like': `%${keyword}%`}});
-        }
-
-        let filterCategory = [{
-            'id': 0,
-            'name': '全部'
-        }];
-
-        //二级分类id
-        let categoryIds = await goodsQuery.getField('category_id', 10000);
-        if (!think.isEmpty(categoryIds)) {
-            //查找二级分类的parent_id
-            let parentIds = await this.model('category').where({id: {'in': categoryIds}}).getField('parent_id', 10000);
-            //一级分类
-            let parentCategory = await this.model('category').field(['id', 'name']).order({'sort_order': 'asc'}).where({'id': {'in': parentIds}}).select();
-
-            if (!think.isEmpty(parentCategory)) {
-                filterCategory = filterCategory.concat(parentCategory);
-            }
-        }
-
-        return this.success(filterCategory);
+    // 加入分类条件
+    if (!think.isEmpty(categoryId) && parseInt(categoryId) > 0) {
+      whereMap.category_id = ['in', await this.model('category').getCategoryWhereIn(categoryId)];
     }
 
-    /**
-     * 新品首发
-     * @returns {Promise.<Promise|void|PreventPromise>}
-     */
-    async newAction() {
-
-        return this.success({
-            bannerInfo: {
-                url: '',
-                name: '坚持初心,为你寻觅世间好物',
-                img_url: 'http://yanxuan.nosdn.127.net/8976116db321744084774643a933c5ce.png',
-            }
-        });
+    // 搜索到的商品
+    const goodsData = await goodsQuery.where(whereMap).field(['id', 'name', 'list_pic_url', 'retail_price']).order(orderMap).page(page, size).countSelect();
+    goodsData.filterCategory = filterCategory.map(function(v) {
+      v.checked = (think.isEmpty(categoryId) && v.id === 0) || v.id === parseInt(categoryId);
+      return v;
+    });
+    goodsData.goodsList = goodsData.data;
+
+    return this.success(goodsData);
+  }
+
+  /**
+   * 商品列表筛选的分类列表
+   * @returns {Promise.<Promise|void|PreventPromise>}
+   */
+  async filterAction() {
+    const categoryId = this.get('categoryId');
+    const keyword = this.get('keyword');
+    const isNew = this.get('isNew');
+    const isHot = this.get('isHot');
+
+    const goodsQuery = this.model('goods');
+
+    if (!think.isEmpty(categoryId)) {
+      goodsQuery.where({category_id: {'in': await this.model('category').getChildCategoryId(categoryId)}});
     }
 
-    /**
-     * 人气推荐
-     * @returns {Promise.<Promise|void|PreventPromise>}
-     */
-    async hotAction() {
-
-        return this.success({
-            bannerInfo: {
-                url: '',
-                name: '大家都在买的严选好物',
-                img_url: 'http://yanxuan.nosdn.127.net/8976116db321744084774643a933c5ce.png',
-            }
-        });
+    if (!think.isEmpty(isNew)) {
+      goodsQuery.where({is_new: isNew});
     }
 
-    /**
-     * 商品详情页的大家都在看的商品
-     * @returns {Promise.<Promise|PreventPromise|void>}
-     */
-    async relatedAction() {
-        //大家都在看商品,取出关联表的商品,如果没有则随机取同分类下的商品
-
-        const model = this.model('goods');
-        const goodsId = this.get('id');
-        let relatedGoodsIds = await this.model('related_goods').where({goods_id: goodsId}).getField('related_goods_id');
-        let relatedGoods = null;
-        if (think.isEmpty(relatedGoodsIds)) {
-            //查找同分类下的商品
-            let goodsCategory = await model.where({id: goodsId}).find();
-            relatedGoods = await model.where({category_id: goodsCategory.category_id}).field(['id', 'name', 'list_pic_url', 'retail_price']).limit(8).select();
-        } else {
-            relatedGoods = await model.where({id: ['IN', relatedGoodsIds]}).field(['id', 'name', 'list_pic_url', 'retail_price']).select();
-        }
-
-        return this.success({
-            goodsList: relatedGoods,
-        });
+    if (!think.isEmpty(isHot)) {
+      goodsQuery.where({is_hot: isHot});
     }
 
-    /**
-     * 在售的商品总数
-     * @returns {Promise.<Promise|PreventPromise|void>}
-     */
-    async countAction() {
+    if (!think.isEmpty(keyword)) {
+      goodsQuery.where({name: {'like': `%${keyword}%`}});
+    }
 
-        let goodsCount = await this.model('goods').where({is_delete: 0, is_on_sale: 1}).count('id');
+    let filterCategory = [{
+      'id': 0,
+      'name': '全部'
+    }];
+
+    // 二级分类id
+    const categoryIds = await goodsQuery.getField('category_id', 10000);
+    if (!think.isEmpty(categoryIds)) {
+      // 查找二级分类的parent_id
+      const parentIds = await this.model('category').where({id: {'in': categoryIds}}).getField('parent_id', 10000);
+      // 一级分类
+      const parentCategory = await this.model('category').field(['id', 'name']).order({'sort_order': 'asc'}).where({'id': {'in': parentIds}}).select();
+
+      if (!think.isEmpty(parentCategory)) {
+        filterCategory = filterCategory.concat(parentCategory);
+      }
+    }
 
-        return this.success({
-            goodsCount: goodsCount,
-        });
+    return this.success(filterCategory);
+  }
+
+  /**
+   * 新品首发
+   * @returns {Promise.<Promise|void|PreventPromise>}
+   */
+  async newAction() {
+    return this.success({
+      bannerInfo: {
+        url: '',
+        name: '坚持初心,为你寻觅世间好物',
+        img_url: 'http://yanxuan.nosdn.127.net/8976116db321744084774643a933c5ce.png'
+      }
+    });
+  }
+
+  /**
+   * 人气推荐
+   * @returns {Promise.<Promise|void|PreventPromise>}
+   */
+  async hotAction() {
+    return this.success({
+      bannerInfo: {
+        url: '',
+        name: '大家都在买的严选好物',
+        img_url: 'http://yanxuan.nosdn.127.net/8976116db321744084774643a933c5ce.png'
+      }
+    });
+  }
+
+  /**
+   * 商品详情页的大家都在看的商品
+   * @returns {Promise.<Promise|PreventPromise|void>}
+   */
+  async relatedAction() {
+    // 大家都在看商品,取出关联表的商品,如果没有则随机取同分类下的商品
+    const model = this.model('goods');
+    const goodsId = this.get('id');
+    const relatedGoodsIds = await this.model('related_goods').where({goods_id: goodsId}).getField('related_goods_id');
+    let relatedGoods = null;
+    if (think.isEmpty(relatedGoodsIds)) {
+      // 查找同分类下的商品
+      const goodsCategory = await model.where({id: goodsId}).find();
+      relatedGoods = await model.where({category_id: goodsCategory.category_id}).field(['id', 'name', 'list_pic_url', 'retail_price']).limit(8).select();
+    } else {
+      relatedGoods = await model.where({id: ['IN', relatedGoodsIds]}).field(['id', 'name', 'list_pic_url', 'retail_price']).select();
     }
 
-}
+    return this.success({
+      goodsList: relatedGoods
+    });
+  }
+
+  /**
+   * 在售的商品总数
+   * @returns {Promise.<Promise|PreventPromise|void>}
+   */
+  async countAction() {
+    const goodsCount = await this.model('goods').where({is_delete: 0, is_on_sale: 1}).count('id');
+
+    return this.success({
+      goodsCount: goodsCount
+    });
+  }
+};

+ 25 - 34
src/api/controller/index.js

@@ -1,43 +1,34 @@
-'use strict';
+const Base = require('./base.js');
 
-import Base from './base.js';
+module.exports = class extends Base {
+  async indexAction() {
+    const banner = await this.model('ad').where({ad_position_id: 1}).select();
+    const channel = await this.model('channel').order({sort_order: 'asc'}).select();
+    const newGoods = await this.model('goods').field(['id', 'name', 'list_pic_url', 'retail_price']).where({is_new: 1}).limit(4).select();
+    const hotGoods = await this.model('goods').field(['id', 'name', 'list_pic_url', 'retail_price', 'goods_brief']).where({is_hot: 1}).limit(3).select();
+    const brandList = await this.model('brand').where({is_new: 1}).order({new_sort_order: 'asc'}).limit(4).select();
+    const topicList = await this.model('topic').limit(3).select();
 
-export default class extends Base {
-
-  /**
-   * 获取分类栏目数据
-   * @returns {Promise.<Promise|void|PreventPromise>}
-   */
-  async indexAction(){
-
-    let banner = await this.model('ad').where({ad_position_id: 1}).select();
-    let channel = await this.model('channel').order({ sort_order: 'asc'}).select();
-    let newGoods = await this.model('goods').field(['id', 'name', 'list_pic_url', 'retail_price']).where({is_new: 1}).limit(4).select();
-    let hotGoods = await this.model('goods').field(['id', 'name', 'list_pic_url', 'retail_price', 'goods_brief']).where({is_hot: 1}).limit(3).select();
-    let brandList = await this.model('brand').where({is_new: 1}).order({new_sort_order: 'asc'}).limit(4).select();
-    let topicList = await this.model('topic').limit(3).select();
-
-    let categoryList = await this.model('category').where({parent_id: 0, name: ['<>', '推荐']}).select();
-    let newCategoryList = [];
-    for (let categoryItem of categoryList) {
-      let childCategoryIds = await this.model('category').where({parent_id: categoryItem.id}).getField('id', 100);
-      let categoryGoods = await this.model('goods').field(['id', 'name', 'list_pic_url', 'retail_price']).where({category_id: ['IN', childCategoryIds]}).limit(7).select();
+    const categoryList = await this.model('category').where({parent_id: 0, name: ['<>', '推荐']}).select();
+    const newCategoryList = [];
+    for (const categoryItem of categoryList) {
+      const childCategoryIds = await this.model('category').where({parent_id: categoryItem.id}).getField('id', 100);
+      const categoryGoods = await this.model('goods').field(['id', 'name', 'list_pic_url', 'retail_price']).where({category_id: ['IN', childCategoryIds]}).limit(7).select();
       newCategoryList.push({
-          id: categoryItem.id,
-          name: categoryItem.name,
-          goodsList: categoryGoods
+        id: categoryItem.id,
+        name: categoryItem.name,
+        goodsList: categoryGoods
       });
     }
 
     return this.success({
-        banner: banner,
-        channel: channel,
-        newGoodsList: newGoods,
-        hotGoodsList: hotGoods,
-        brandList: brandList,
-        topicList: topicList,
-        categoryList: newCategoryList
+      banner: banner,
+      channel: channel,
+      newGoodsList: newGoods,
+      hotGoodsList: hotGoods,
+      brandList: brandList,
+      topicList: topicList,
+      categoryList: newCategoryList
     });
-    // return this.success(jsonData);
   }
-}
+};

+ 148 - 175
src/api/controller/order.js

@@ -1,191 +1,164 @@
-'use strict';
-
-import Base from './base.js';
-let moment = require('moment');
-
-export default class extends Base {
-    /**
-     * index action
-     * @return {Promise} []
-     */
-    indexAction() {
-        //auto render template file index_index.html
-        let order_sn = this.model('order').generateOrderNumber();
-        return this.success(getTime());
-        //return this.display();
+const Base = require('./base.js');
+const moment = require('moment');
+
+module.exports = class extends Base {
+  /**
+   * 获取订单列表
+   * @return {Promise} []
+   */
+  async listAction() {
+    const orderList = await this.model('order').where({user_id: think.userId}).page(1, 10).countSelect();
+    const newOrderList = [];
+    for (const item of orderList.data) {
+      // 订单的商品
+      item.goodsList = await this.model('order_goods').where({order_id: item.id}).select();
+      item.goodsCount = 0;
+      item.goodsList.forEach(v => {
+        item.goodsCount += v.number;
+      });
+
+      // 订单状态的处理
+      item.order_status_text = await this.model('order').getOrderStatusText(item.id);
+
+      // 可操作的选项
+      item.handleOption = await this.model('order').getOrderHandleOption(item.id);
+
+      newOrderList.push(item);
     }
+    orderList.data = newOrderList;
 
-    /**
-     * 获取订单列表
-     * @return {Promise} []
-     */
-    async listAction() {
+    return this.success(orderList);
+  }
 
-        let orderList = await this.model('order').where({user_id: think.userId}).page(1, 10).countSelect();
+  async detailAction() {
+    const orderId = this.get('orderId');
+    const orderInfo = await this.model('order').where({user_id: think.userId, id: orderId}).find();
 
-        let newOrderList = [];
-        for (let item of orderList.data) {
-
-            //订单的商品
-            item.goodsList = await this.model('order_goods').where({order_id: item.id}).select();
-            item.goodsCount = 0;
-            item.goodsList.forEach(v => {
-                item.goodsCount += v.number;
-            });
+    if (think.isEmpty(orderInfo)) {
+      return this.fail('订单不存在');
+    }
 
-            //订单状态的处理
-            item.order_status_text = await this.model('order').getOrderStatusText(item.id);
+    orderInfo.province_name = await this.model('region').where({id: orderInfo.province}).getField('name', true);
+    orderInfo.city_name = await this.model('region').where({id: orderInfo.city}).getField('name', true);
+    orderInfo.district_name = await this.model('region').where({id: orderInfo.district}).getField('name', true);
+    orderInfo.full_region = orderInfo.province_name + orderInfo.city_name + orderInfo.district_name;
+
+    const orderGoods = await this.model('order_goods').where({order_id: orderId}).select();
+
+    // 订单状态的处理
+    orderInfo.order_status_text = await this.model('order').getOrderStatusText(orderId);
+    orderInfo.add_time = moment.unix(orderInfo.add_time).format('YYYY-MM-DD HH:mm:ss');
+    orderInfo.final_pay_time = moment('001234', 'Hmmss').format('mm:ss');
+    // 订单最后支付时间
+    if (orderInfo.order_status === 0) {
+      // if (moment().subtract(60, 'minutes') < moment(orderInfo.add_time)) {
+      orderInfo.final_pay_time = moment('001234', 'Hmmss').format('mm:ss');
+      // } else {
+      //     //超过时间不支付,更新订单状态为取消
+      // }
+    }
 
-            //可操作的选项
-            item.handleOption = await this.model('order').getOrderHandleOption(item.id);
+    // 订单可操作的选择,删除,支付,收货,评论,退换货
+    const handleOption = await this.model('order').getOrderHandleOption(orderId);
+
+    return this.success({
+      orderInfo: orderInfo,
+      orderGoods: orderGoods,
+      handleOption: handleOption
+    });
+  }
+
+  /**
+   * 提交订单
+   * @returns {Promise.<void>}
+   */
+  async submitAction() {
+    // 获取收货地址信息和计算运费
+    const addressId = this.post('addressId');
+    const checkedAddress = await this.model('address').where({id: addressId}).find();
+    if (think.isEmpty(checkedAddress)) {
+      return this.fail('请选择收货地址');
+    }
+    const freightPrice = 0.00;
 
-            newOrderList.push(item);
+    // 获取要购买的商品
+    const checkedGoodsList = await this.model('cart').where({user_id: think.userId, session_id: 1, checked: 1}).select();
+    if (think.isEmpty(checkedGoodsList)) {
+      return this.fail('请选择商品');
+    }
 
-        }
-        orderList.data = newOrderList;
+    // 统计商品总价
+    let goodsTotalPrice = 0.00;
+    for (const cartItem of checkedGoodsList) {
+      goodsTotalPrice += cartItem.number * cartItem.retail_price;
+    }
 
+    // 获取订单使用的优惠券
+    const couponId = this.post('couponId');
+    const couponPrice = 0.00;
+    if (!think.isEmpty(couponId)) {
 
-        return this.success(orderList);
     }
 
-    async detailAction() {
-        let orderId = this.get('orderId');
-        let orderInfo = await this.model('order').where({user_id: think.userId, id: orderId}).find();
-
-        if (think.isEmpty(orderInfo)) {
-            return this.fail('订单不存在');
-        }
-
-        orderInfo.province_name = await this.model('region').where({id: orderInfo.province}).getField('name', true);
-        orderInfo.city_name = await this.model('region').where({id: orderInfo.city}).getField('name', true);
-        orderInfo.district_name = await this.model('region').where({id: orderInfo.district}).getField('name', true);
-        orderInfo.full_region = orderInfo.province_name + orderInfo.city_name + orderInfo.district_name;
-
-        let orderGoods = await this.model('order_goods').where({order_id: orderId}).select();
-
-        //订单状态的处理
-        orderInfo.order_status_text = await this.model('order').getOrderStatusText(orderId);
-
-        orderInfo.add_time = moment.unix(orderInfo.add_time).format("YYYY-MM-DD HH:mm:ss");
-        orderInfo.final_pay_time = moment("001234", "Hmmss").format("mm:ss");
-        //订单最后支付时间
-        if (orderInfo.order_status === 0) {
-            // if (moment().subtract(60, 'minutes') < moment(orderInfo.add_time)) {
-                orderInfo.final_pay_time = moment("001234", "Hmmss").format("mm:ss")
-            // } else {
-            //     //超过时间不支付,更新订单状态为取消
-            // }
-        }
-
-        //订单可操作的选择,删除,支付,收货,评论,退换货
-        let handleOption = await this.model('order').getOrderHandleOption(orderId);
-
-        return this.success({
-            orderInfo: orderInfo,
-            orderGoods: orderGoods,
-            handleOption: handleOption
-        });
+    // 订单价格计算
+    const orderTotalPrice = goodsTotalPrice + freightPrice - couponPrice; // 订单的总价
+    const actualPrice = orderTotalPrice - 0.00; // 减去其它支付的金额后,要实际支付的金额
+    const currentTime = parseInt(this.getTime() / 1000);
+
+    const orderInfo = {
+      order_sn: this.model('order').generateOrderNumber(),
+      user_id: think.userId,
+
+      // 收货地址和运费
+      consignee: checkedAddress.name,
+      mobile: checkedAddress.mobile,
+      province: checkedAddress.province_id,
+      city: checkedAddress.city_id,
+      district: checkedAddress.district_id,
+      address: checkedAddress.address,
+      freight_price: 0.00,
+
+      // 留言
+      postscript: this.post('postscript'),
+
+      // 使用的优惠券
+      coupon_id: 0,
+      coupon_price: couponPrice,
+
+      add_time: currentTime,
+      goods_price: goodsTotalPrice,
+      order_price: orderTotalPrice,
+      actual_price: actualPrice
+    };
+
+    // 开启事务,插入订单信息和订单商品
+    const orderId = await this.model('order').add(orderInfo);
+    orderInfo.id = orderId;
+    if (!orderId) {
+      return this.fail('订单提交失败');
     }
 
-    /**
-     * 提交订单
-     * @returns {Promise.<void>}
-     */
-    async submitAction() {
-
-        //获取收货地址信息和计算运费
-        let addressId = this.post('addressId');
-        let checkedAddress = await this.model('address').where({id: addressId}).find();
-        if (think.isEmpty(checkedAddress)) {
-            return this.fail('请选择收货地址');
-        }
-        let freightPrice = 0.00;
-
-        //获取要购买的商品
-        let checkedGoodsList = await this.model('cart').where({user_id: think.userId, session_id: 1, checked: 1}).select();
-        if (think.isEmpty(checkedGoodsList)) {
-            return this.fail('请选择商品');
-        }
-
-        //统计商品总价
-        let goodsTotalPrice = 0.00;
-        for (let cartItem of checkedGoodsList) {
-            goodsTotalPrice += cartItem.number * cartItem.retail_price;
-        }
-
-        //获取订单使用的优惠券
-        let couponId = this.post('couponId');
-        let couponPrice = 0.00;
-        if (!think.isEmpty(couponId)) {
-
-        }
-
-        //订单价格计算
-        let orderTotalPrice = goodsTotalPrice + freightPrice - couponPrice;  //订单的总价
-        let actualPrice = orderTotalPrice - 0.00;  //减去其它支付的金额后,要实际支付的金额
-
-
-        let currentTime = parseInt(new Date().getTime() / 1000);
-
-        let orderInfo = {
-
-            order_sn: this.model('order').generateOrderNumber(),
-            user_id: think.userId,
-
-            //收货地址和运费
-            consignee: checkedAddress.name,
-            mobile: checkedAddress.mobile,
-            province: checkedAddress.province_id,
-            city: checkedAddress.city_id,
-            district: checkedAddress.district_id,
-            address: checkedAddress.address,
-            freight_price: 0.00,
-
-            //留言
-            postscript: this.post('postscript'),
-
-            //使用的优惠券
-            coupon_id: 0,
-            coupon_price: couponPrice,
-
-            add_time: currentTime,
-            goods_price: goodsTotalPrice,
-            order_price: orderTotalPrice,
-            actual_price: actualPrice
-
-        };
-
-
-        //开启事务,插入订单信息和订单商品
-        let orderId = await this.model('order').add(orderInfo);
-        orderInfo.id = orderId;
-        if (!orderId) {
-            return this.fail('订单提交失败');
-        }
-
-        //统计商品总价
-        let orderGoodsData = [];
-        for (let goodsItem of checkedGoodsList) {
-            orderGoodsData.push({
-                order_id: orderId,
-                goods_id: goodsItem.goods_id,
-                goods_sn: goodsItem.goods_sn,
-                product_id: goodsItem.product_id,
-                goods_name: goodsItem.goods_name,
-                list_pic_url: goodsItem.list_pic_url,
-                market_price: goodsItem.market_price,
-                retail_price: goodsItem.retail_price,
-                number: goodsItem.number,
-                goods_specifition_name_value: goodsItem.goods_specifition_name_value,
-                goods_specifition_ids: goodsItem.goods_specifition_ids
-            });
-        }
-
-        await this.model('order_goods').addMany(orderGoodsData);
-
-        await this.model('cart').clearBuyGoods();
-
-        return this.success({orderInfo: orderInfo});
+    // 统计商品总价
+    const orderGoodsData = [];
+    for (const goodsItem of checkedGoodsList) {
+      orderGoodsData.push({
+        order_id: orderId,
+        goods_id: goodsItem.goods_id,
+        goods_sn: goodsItem.goods_sn,
+        product_id: goodsItem.product_id,
+        goods_name: goodsItem.goods_name,
+        list_pic_url: goodsItem.list_pic_url,
+        market_price: goodsItem.market_price,
+        retail_price: goodsItem.retail_price,
+        number: goodsItem.number,
+        goods_specifition_name_value: goodsItem.goods_specifition_name_value,
+        goods_specifition_ids: goodsItem.goods_specifition_ids
+      });
     }
 
-}
+    await this.model('order_goods').addMany(orderGoodsData);
+    await this.model('cart').clearBuyGoods();
+
+    return this.success({orderInfo: orderInfo});
+  }
+};

+ 56 - 69
src/api/controller/pay.js

@@ -1,74 +1,61 @@
-'use strict';
-
-import Base from './base.js';
-const rp = require("request-promise");
-const request = require("request");
-
-export default class extends Base {
-
-    // 支付类型 1 微信支付 2支付宝
-    // TODO 支付功能由于没有公司账号和微信支付账号,所以没有经过测试,如您可以提供相关账号测试,可联系 tumobi@163.com
-
-    /**
-     * 获取支付信息(订单信息和支持的支付方式信息)
-     * @return {Promise} []
-     */
-    async indexAction() {
-        //auto render template file index_index.html
-        return this.display();
+const Base = require('./base.js');
+const rp = require('request-promise');
+
+module.exports = class extends Base {
+  // 支付类型 1 微信支付 2支付宝
+  // TODO 支付功能由于没有公司账号和微信支付账号,所以没有经过测试,如您可以提供相关账号测试,可联系 tumobi@163.com
+
+  /**
+   * 获取支付的请求参数
+   * @returns {Promise<PreventPromise|void|Promise>}
+   */
+  async payPrepayAction() {
+    const orderId = this.get('orderId');
+    // const payType = this.get('payType');
+
+    const orderInfo = await this.model('order').where({id: orderId}).find();
+    if (think.isEmpty(orderInfo)) {
+      return this.fail(400, '订单已取消');
+    }
+    if (parseInt(orderInfo.pay_status) !== 0) {
+      return this.fail(400, '订单已支付,请不要重复操作');
     }
 
-    /**
-     * 获取支付的请求参数
-     * @returns {Promise<PreventPromise|void|Promise>}
-     */
-    async payPrepayAction() {
-
-        const orderId = this.get('orderId');
-        const payType = this.get('payType');
-
-        const orderInfo = await this.model('order').where({id: orderId}).find();
-        if (think.isEmpty(orderInfo)) {
-            return this.fail(400, '订单已取消');
-        }
-        console.log(orderInfo)
-        if (parseInt(orderInfo.pay_status) !== 0) {
-            return this.fail(400, '订单已支付,请不要重复操作');
-        }
-
-        //微信支付统一调用接口,body参数请查看微信支付文档:https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_sl_api.php?chapter=9_1
-        let options = {
-            method: 'POST',
-            url: 'https://api.mch.weixin.qq.com/pay/unifiedorder',
-            body: {
-                appid: 'payload',
-                mch_id: '',
-                sub_appid: '',
-                sub_mch_id: '',
-                device_info: '',
-                nonce_str: think.uuid(32),
-                sign: '',
-                sign_type: 'MD5',
-                body: '',
-                out_trade_no: '',
-                total_fee: orderInfo.actual_price * 100,
-                spbill_create_ip: '',
-                notify_url: '',
-                trade_type: 'JSAPI',
-                openid: '',
-                sub_openid: '',
-            },
-        };
-        //let payParam = await rp(options);
+    // 微信支付统一调用接口,body参数请查看微信支付文档:https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_sl_api.php?chapter=9_1
+    const options = {
+      method: 'POST',
+      url: 'https://api.mch.weixin.qq.com/pay/unifiedorder',
+      body: {
+        appid: 'payload',
+        mch_id: '',
+        sub_appid: '',
+        sub_mch_id: '',
+        device_info: '',
+        nonce_str: think.uuid(32),
+        sign: '',
+        sign_type: 'MD5',
+        body: '',
+        out_trade_no: '',
+        total_fee: orderInfo.actual_price * 100,
+        spbill_create_ip: '',
+        notify_url: '',
+        trade_type: 'JSAPI',
+        openid: '',
+        sub_openid: ''
+      }
+    };
+    const payParam = await rp(options);
+    if (payParam) {
 
-        //统一返回成功,方便测试
-        return this.success({
-            'timeStamp': getTime(),
-            'nonceStr': think.uuid(16),
-            'package': 'prepay_id=wx201410272009395522657a690389285100',
-            'signType': 'MD5',
-            'paySign': 'jdsdlsdsd',
-        });
     }
 
-}
+    // 统一返回成功,方便测试
+    return this.success({
+      'timeStamp': this.getTime(),
+      'nonceStr': think.uuid(16),
+      'package': 'prepay_id=wx201410272009395522657a690389285100',
+      'signType': 'MD5',
+      'paySign': 'jdsdlsdsd'
+    });
+  }
+};

+ 7 - 11
src/api/controller/region.js

@@ -1,17 +1,13 @@
-'use strict';
+const Base = require('./base.js');
 
-import Base from './base.js';
-
-export default class extends Base {
-
-
-  async infoAction(){
-    let region = await this.model('region').getRegionInfo(this.get('regionId'));
+module.exports = class extends Base {
+  async infoAction() {
+    const region = await this.model('region').getRegionInfo(this.get('regionId'));
     return this.success(region);
   }
 
-  async listAction(){
-    let regionList = await this.model('region').getRegionList(this.get('parentId'));
+  async listAction() {
+    const regionList = await this.model('region').getRegionList(this.get('parentId'));
     return this.success(regionList);
   }
-}
+};

+ 11 - 19
src/api/controller/search.js

@@ -1,36 +1,28 @@
-'use strict';
+const Base = require('./base.js');
 
-import Base from './base.js';
-
-export default class extends Base {
-  /**
-   * index action
-   * @return {Promise} []
-   */
+module.exports = class extends Base {
   async indexAction() {
-    //取出输入框默认的关键词
-    let defaultKeyword = await this.model('keywords').where({ is_default: 1 }).limit(1).find();
-    //取出热闹关键词
-    let hotKeywordList = await this.model('keywords').distinct('keyword').field(['keyword', 'is_hot']).limit(10).select();
-
-    let historyKeywordList = await this.model('search_history').distinct('keyword').where({ user_id: think.userId }).limit(10).getField('keyword');
+    // 取出输入框默认的关键词
+    const defaultKeyword = await this.model('keywords').where({ is_default: 1 }).limit(1).find();
+    // 取出热闹关键词
+    const hotKeywordList = await this.model('keywords').distinct('keyword').field(['keyword', 'is_hot']).limit(10).select();
+    const historyKeywordList = await this.model('search_history').distinct('keyword').where({ user_id: think.userId }).limit(10).getField('keyword');
 
     return this.success({
       defaultKeyword: defaultKeyword,
       historyKeywordList: historyKeywordList,
       hotKeywordList: hotKeywordList
     });
-
   }
 
   async helperAction() {
-    let keyword = this.get('keyword');
-    let keywords = await this.model('keywords').distinct('keyword').where({ keyword: ['like', keyword + '%'] }).getField('keyword', 10);
+    const keyword = this.get('keyword');
+    const keywords = await this.model('keywords').distinct('keyword').where({ keyword: ['like', keyword + '%'] }).getField('keyword', 10);
     return this.success(keywords);
   }
 
   async clearhistoryAction() {
-    let historyKeywordList = await this.model('search_history').where({ user_id: think.userId }).delete();
+    await this.model('search_history').where({ user_id: think.userId }).delete();
     return this.success();
   }
-}
+};

+ 13 - 28
src/api/controller/topic.js

@@ -1,39 +1,24 @@
-'use strict';
+const Base = require('./base.js');
 
-import Base from './base.js';
+module.exports = class extends Base {
+  async listAction() {
+    const model = this.model('topic');
+    const data = await model.field(['id', 'title', 'price_info', 'scene_pic_url', 'subtitle']).page(this.get('page') || 1, this.get('size') || 10).countSelect();
 
-export default class extends Base {
-  /**
-   * index action
-   * @return {Promise} []
-   */
-  indexAction(){
-    //auto render template file index_index.html
-    return this.display();
+    return this.success(data);
   }
 
-  async listAction(){
-
-    let model = this.model('topic');
-    let data = await model.field(['id', 'title', 'price_info', 'scene_pic_url', 'subtitle']).page(this.get('page') || 1, this.get('size') || 10).countSelect();
+  async detailAction() {
+    const model = this.model('topic');
+    const data = await model.where({id: this.get('id')}).find();
 
     return this.success(data);
   }
 
-  async detailAction(){
-
-    let model = this.model('topic');
-    let data = await model.where({id: this.get('id')}).find();
+  async relatedAction() {
+    const model = this.model('topic');
+    const data = await model.field(['id', 'title', 'price_info', 'scene_pic_url', 'subtitle']).limit(4).select();
 
     return this.success(data);
   }
-
-    async relatedAction(){
-
-        let model = this.model('topic');
-        let data = await model.field(['id', 'title', 'price_info', 'scene_pic_url', 'subtitle']).limit(4).select();
-
-        return this.success(data);
-    }
-
-}
+};

+ 10 - 26
src/api/controller/user.js

@@ -1,23 +1,10 @@
-'use strict';
-
-import Base from './base.js';
+const Base = require('./base.js');
 const fs = require('fs');
 const _ = require('lodash');
 
-export default class extends Base {
-  /**
-   * index action
-   * @return {Promise} []
-   */
-  indexAction(){
-    //auto render template file index_index.html
-
-    return this.display();
-  }
-
-  async infoAction(){
-
-    let userInfo = await this.model('user').where({mobile: '15989389319'}).find();
+module.exports = class extends Base {
+  async infoAction() {
+    const userInfo = await this.model('user').where({mobile: '15989389319'}).find();
     delete userInfo.password;
     return this.json(userInfo);
   }
@@ -26,19 +13,16 @@ export default class extends Base {
    * 保存用户头像
    * @returns {Promise.<void>}
    */
-  async saveAvatarAction(){
-
-    let avatar = this.file('avatar');
+  async saveAvatarAction() {
+    const avatar = this.file('avatar');
     if (think.isEmpty(avatar)) {
       return this.fail('保存失败');
     }
 
-    let filename = 1;
-    let avatar_path = think.RESOURCE_PATH + '/static/user/avatar/1.' + _.last(_.split(avatar.path, '.'));
+    const avatarPath = think.RESOURCE_PATH + '/static/user/avatar/1.' + _.last(_.split(avatar.path, '.'));
 
-    fs.rename(avatar.path, avatar_path, function (res) {
-      return this.success(1);
+    fs.rename(avatar.path, avatarPath, function(res) {
+      return this.success();
     });
-
   }
-}
+};

+ 4 - 14
src/api/logic/address.js

@@ -1,15 +1,5 @@
-'use strict';
-/**
- * logic
- * @param  {} []
- * @return {}     []
- */
-export default class extends think.logic.base {
-  /**
-   * index action logic
-   * @return {} []
-   */
-  indexAction(){
-   
+module.exports = class extends think.Logic {
+  indexAction() {
+
   }
-}
+};

+ 4 - 14
src/api/logic/auth.js

@@ -1,15 +1,5 @@
-'use strict';
-/**
- * logic
- * @param  {} []
- * @return {}     []
- */
-export default class extends think.logic.base {
-  /**
-   * index action logic
-   * @return {} []
-   */
-  indexAction(){
-   
+module.exports = class extends think.Logic {
+  indexAction() {
+
   }
-}
+};

+ 4 - 14
src/api/logic/brand.js

@@ -1,15 +1,5 @@
-'use strict';
-/**
- * logic
- * @param  {} []
- * @return {}     []
- */
-export default class extends think.logic.base {
-  /**
-   * index action logic
-   * @return {} []
-   */
-  indexAction(){
-   
+module.exports = class extends think.Logic {
+  indexAction() {
+
   }
-}
+};

+ 4 - 14
src/api/logic/cart.js

@@ -1,15 +1,5 @@
-'use strict';
-/**
- * logic
- * @param  {} []
- * @return {}     []
- */
-export default class extends think.logic.base {
-  /**
-   * index action logic
-   * @return {} []
-   */
-  indexAction(){
-   
+module.exports = class extends think.Logic {
+  indexAction() {
+
   }
-}
+};

+ 3 - 17
src/api/logic/catalog.js

@@ -1,19 +1,5 @@
-'use strict';
-/**
- * logic
- * @param  {} []
- * @return {}     []
- */
-export default class extends think.logic.base {
-  /**
-   * index action logic
-   * @return {} []
-   */
-  indexAction(){
-   
-  }
-
-  currentAction(){
+module.exports = class extends think.Logic {
+  indexAction() {
 
   }
-}
+};

+ 4 - 14
src/api/logic/collect.js

@@ -1,15 +1,5 @@
-'use strict';
-/**
- * logic
- * @param  {} []
- * @return {}     []
- */
-export default class extends think.logic.base {
-  /**
-   * index action logic
-   * @return {} []
-   */
-  indexAction(){
-   
+module.exports = class extends think.Logic {
+  indexAction() {
+
   }
-}
+};

+ 4 - 14
src/api/logic/comment.js

@@ -1,15 +1,5 @@
-'use strict';
-/**
- * logic
- * @param  {} []
- * @return {}     []
- */
-export default class extends think.logic.base {
-  /**
-   * index action logic
-   * @return {} []
-   */
-  indexAction(){
-   
+module.exports = class extends think.Logic {
+  indexAction() {
+
   }
-}
+};

+ 4 - 14
src/api/logic/footprint.js

@@ -1,15 +1,5 @@
-'use strict';
-/**
- * logic
- * @param  {} []
- * @return {}     []
- */
-export default class extends think.logic.base {
-  /**
-   * index action logic
-   * @return {} []
-   */
-  indexAction(){
-   
+module.exports = class extends think.Logic {
+  indexAction() {
+
   }
-}
+};

+ 4 - 14
src/api/logic/goods.js

@@ -1,15 +1,5 @@
-'use strict';
-/**
- * logic
- * @param  {} []
- * @return {}     []
- */
-export default class extends think.logic.base {
-  /**
-   * index action logic
-   * @return {} []
-   */
-  indexAction(){
-   
+module.exports = class extends think.Logic {
+  indexAction() {
+
   }
-}
+};

+ 4 - 14
src/api/logic/index.js

@@ -1,15 +1,5 @@
-'use strict';
-/**
- * logic
- * @param  {} []
- * @return {}     []
- */
-export default class extends think.logic.base {
-  /**
-   * index action logic
-   * @return {} []
-   */
-  indexAction(){
-   
+module.exports = class extends think.Logic {
+  indexAction() {
+
   }
-}
+};

+ 4 - 15
src/api/logic/order.js

@@ -1,16 +1,5 @@
-'use strict';
-/**
- * logic
- * @param  {} []
- * @return {}     []
- */
-export default class extends think.logic.base {
-  /**
-   * 获取订单列表
-   * @return {} []
-   */
-  indexAction(){
-   
-  }
+module.exports = class extends think.Logic {
+  indexAction() {
 
-}
+  }
+};

+ 4 - 14
src/api/logic/pay.js

@@ -1,15 +1,5 @@
-'use strict';
-/**
- * logic
- * @param  {} []
- * @return {}     []
- */
-export default class extends think.logic.base {
-  /**
-   * index action logic
-   * @return {} []
-   */
-  indexAction(){
-   
+module.exports = class extends think.Logic {
+  indexAction() {
+
   }
-}
+};

+ 4 - 14
src/api/logic/region.js

@@ -1,15 +1,5 @@
-'use strict';
-/**
- * logic
- * @param  {} []
- * @return {}     []
- */
-export default class extends think.logic.base {
-  /**
-   * index action logic
-   * @return {} []
-   */
-  indexAction(){
-   
+module.exports = class extends think.Logic {
+  indexAction() {
+
   }
-}
+};

+ 4 - 14
src/api/logic/search.js

@@ -1,15 +1,5 @@
-'use strict';
-/**
- * logic
- * @param  {} []
- * @return {}     []
- */
-export default class extends think.logic.base {
-  /**
-   * index action logic
-   * @return {} []
-   */
-  indexAction(){
-   
+module.exports = class extends think.Logic {
+  indexAction() {
+
   }
-}
+};

+ 4 - 14
src/api/logic/topic.js

@@ -1,15 +1,5 @@
-'use strict';
-/**
- * logic
- * @param  {} []
- * @return {}     []
- */
-export default class extends think.logic.base {
-  /**
-   * index action logic
-   * @return {} []
-   */
-  indexAction(){
-   
+module.exports = class extends think.Logic {
+  indexAction() {
+
   }
-}
+};

+ 4 - 14
src/api/logic/user.js

@@ -1,15 +1,5 @@
-'use strict';
-/**
- * logic
- * @param  {} []
- * @return {}     []
- */
-export default class extends think.logic.base {
-  /**
-   * index action logic
-   * @return {} []
-   */
-  indexAction(){
-   
+module.exports = class extends think.Logic {
+  indexAction() {
+
   }
-}
+};

+ 28 - 0
src/api/model/cart.js

@@ -0,0 +1,28 @@
+module.exports = class extends think.Model {
+  /**
+   * 获取购物车的商品
+   * @returns {Promise.<*>}
+   */
+  async getGoodsList() {
+    const goodsList = await this.model('cart').where({user_id: think.userId, session_id: 1}).select();
+    return goodsList;
+  }
+
+  /**
+   * 获取购物车的选中的商品
+   * @returns {Promise.<*>}
+   */
+  async getCheckedGoodsList() {
+    const goodsList = await this.model('cart').where({user_id: think.userId, session_id: 1, checked: 1}).select();
+    return goodsList;
+  }
+
+  /**
+   * 清空已购买的商品
+   * @returns {Promise.<*>}
+   */
+  async clearBuyGoods() {
+    const $res = await this.model('cart').where({user_id: think.userId, session_id: 1, checked: 1}).delete();
+    return $res;
+  }
+};

+ 12 - 0
src/api/model/category.js

@@ -0,0 +1,12 @@
+module.exports = class extends think.Model {
+  async getChildCategoryId(parentId) {
+    const childIds = await this.where({parent_id: parentId}).getField('id', 10000);
+    return childIds;
+  }
+
+  async getCategoryWhereIn(categoryId) {
+    const childIds = await this.getChildCategoryId(categoryId);
+    childIds.push(categoryId);
+    return childIds;
+  }
+};

+ 13 - 0
src/api/model/collect.js

@@ -0,0 +1,13 @@
+module.exports = class extends think.Model {
+  /**
+   * 判断用户是否收藏过该对象
+   * @param userId
+   * @param typeId
+   * @param valueId
+   * @returns {Promise.<boolean>}
+   */
+  async isUserHasCollect(userId, typeId, valueId) {
+    const hasCollect = await this.where({type_id: typeId, value_id: valueId, user_id: userId}).limit(1).count('id');
+    return hasCollect;
+  }
+};

+ 12 - 0
src/api/model/footprint.js

@@ -0,0 +1,12 @@
+module.exports = class extends think.Model {
+  async addFootprint(userId, goodsId) {
+    // 用户已经登录才可以添加到足迹
+    if (userId > 0 && goodsId > 0) {
+      await this.add({
+        goods_id: goodsId,
+        user_id: userId,
+        add_time: parseInt(Date.now() / 1000)
+      });
+    }
+  }
+};

+ 16 - 21
src/common/model/goods.js → src/api/model/goods.js

@@ -1,16 +1,12 @@
-'use strict';
-/**
- * model
- */
-export default class extends think.model.base {
-
+module.exports = class extends think.Model {
   /**
    * 获取商品的product
    * @param goodsId
    * @returns {Promise.<*>}
    */
-  async getProductList(goodsId){
-    return await this.model('product').where({goods_id: goodsId}).select();;
+  async getProductList(goodsId) {
+    const goods = await this.model('product').where({goods_id: goodsId}).select();
+    return goods;
   }
 
   /**
@@ -18,24 +14,23 @@ export default class extends think.model.base {
    * @param goodsId
    * @returns {Promise.<Array>}
    */
-  async getSpecificationList(goodsId){
-
-    //根据sku商品信息,查找规格值列表
-    let specificationRes = await this.model('goods_specification').alias('gs')
+  async getSpecificationList(goodsId) {
+    // 根据sku商品信息,查找规格值列表
+    const specificationRes = await this.model('goods_specification').alias('gs')
       .field(['gs.*', 's.name'])
       .join({
         table: 'specification',
-        join: 'inner', //join 方式,有 left, right, inner 3 种方式
-        as: 's', // 表别名
-        on: ['specification_id', 'id'] //ON 条件
+        join: 'inner',
+        as: 's',
+        on: ['specification_id', 'id']
       })
       .where({goods_id: goodsId}).select();
 
-    let specificationList = [];
-    let hasSpecificationList = {};
-    //按规格名称分组
+    const specificationList = [];
+    const hasSpecificationList = {};
+    // 按规格名称分组
     for (let i = 0; i < specificationRes.length; i++) {
-      let specItem = specificationRes[i];
+      const specItem = specificationRes[i];
       if (!hasSpecificationList[specItem.specification_id]) {
         specificationList.push({
           specification_id: specItem.specification_id,
@@ -45,7 +40,7 @@ export default class extends think.model.base {
         hasSpecificationList[specItem.specification_id] = specItem;
       } else {
         for (let j = 0; j < specificationList.length; j++) {
-          if (specificationList[j].specification_id == specItem.specification_id) {
+          if (specificationList[j].specification_id === specItem.specification_id) {
             specificationList[j].valueList.push(specItem);
             break;
           }
@@ -55,4 +50,4 @@ export default class extends think.model.base {
 
     return specificationList;
   }
-}
+};

+ 0 - 7
src/api/model/index.js

@@ -1,7 +0,0 @@
-'use strict';
-/**
- * model
- */
-export default class extends think.model.base {
-
-}

+ 83 - 0
src/api/model/order.js

@@ -0,0 +1,83 @@
+const _ = require('lodash');
+
+module.exports = class extends think.Model {
+  /**
+   * 生成订单的编号order_sn
+   * @returns {string}
+   */
+  generateOrderNumber() {
+    const date = new Date();
+    return date.getFullYear() + _.padStart(date.getMonth(), 2, '0') + _.padStart(date.getDay(), 2, '0') + _.padStart(date.getHours(), 2, '0') + _.padStart(date.getMinutes(), 2, '0') + _.padStart(date.getSeconds(), 2, '0') + _.random(100000, 999999);
+  }
+
+  /**
+   * 获取订单可操作的选项
+   * @param orderId
+   * @returns {Promise.<{cancel: boolean, delete: boolean, pay: boolean, comment: boolean, delivery: boolean, confirm: boolean, return: boolean}>}
+   */
+  async getOrderHandleOption(orderId) {
+    const handleOption = {
+      cancel: false, // 取消操作
+      delete: false, // 删除操作
+      pay: false, // 支付操作
+      comment: false, // 评论操作
+      delivery: false, // 确认收货操作
+      confirm: false, // 完成订单操作
+      return: false, // 退换货操作
+      buy: false // 再次购买
+    };
+
+    const orderInfo = await this.where({id: orderId}).find();
+
+    // 订单流程:下单成功-》支付订单-》发货-》收货-》评论
+    // 订单相关状态字段设计,采用单个字段表示全部的订单状态
+    // 1xx表示订单取消和删除等状态 0订单创建成功等待付款,101订单已取消,102订单已删除
+    // 2xx表示订单支付状态,201订单已付款,等待发货
+    // 3xx表示订单物流相关状态,300订单已发货,301用户确认收货
+    // 4xx表示订单退换货相关的状态,401没有发货,退款402,已收货,退款退货
+    // 如果订单已经取消或是已完成,则可删除和再次购买
+    if (orderInfo.order_status === 101) {
+      handleOption.delete = true;
+      handleOption.buy = true;
+    }
+
+    // 如果订单没有被取消,且没有支付,则可支付,可取消
+    if (orderInfo.order_status === 0) {
+      handleOption.cancel = true;
+      handleOption.pay = true;
+    }
+
+    // 如果订单已付款,没有发货,则可退款操作
+    if (orderInfo.order_status === 201) {
+      handleOption.return = true;
+    }
+
+    // 如果订单已经发货,没有收货,则可收货操作和退款、退货操作
+    if (orderInfo.order_status === 300) {
+      handleOption.cancel = true;
+      handleOption.pay = true;
+      handleOption.return = true;
+    }
+
+    // 如果订单已经支付,且已经收货,则可完成交易、评论和再次购买
+    if (orderInfo.order_status === 301) {
+      handleOption.delete = true;
+      handleOption.comment = true;
+      handleOption.buy = true;
+    }
+
+    return handleOption;
+  }
+
+  async getOrderStatusText(orderId) {
+    const orderInfo = await this.where({id: orderId}).find();
+    let statusText = '未付款';
+    switch (orderInfo.order_status) {
+      case 0:
+        statusText = '未付款';
+        break;
+    }
+
+    return statusText;
+  }
+};

+ 80 - 0
src/api/model/region.js

@@ -0,0 +1,80 @@
+const _ = require('lodash');
+
+module.exports = class extends think.Model {
+  /**
+   * 获取完整的省市区名称组成的字符串
+   * @param provinceId
+   * @param cityId
+   * @param districtId
+   * @returns {Promise.<*>}
+   */
+  async getFullRegionName(provinceId, cityId, districtId) {
+    const isFullRegion = await this.checkFullRegion(provinceId, cityId, districtId);
+    if (!isFullRegion) {
+      return '';
+    }
+
+    const regionList = await this.limit(3).order({'id': 'asc'}).where({id: {'in': [provinceId, cityId, districtId]}}).select();
+    if (think.isEmpty(regionList) || regionList.length !== 3) {
+      return '';
+    }
+
+    return _.flatMap(regionList, 'name').join('');
+  }
+
+  /**
+   * 检查省市区信息是否完整和正确
+   * @param provinceId
+   * @param cityId
+   * @param districtId
+   * @returns {Promise.<boolean>}
+   */
+  async checkFullRegion(provinceId, cityId, districtId) {
+    if (think.isEmpty(provinceId) || think.isEmpty(cityId) || think.isEmpty(districtId)) {
+      return false;
+    }
+
+    const regionList = await this.limit(3).order({'id': 'asc'}).where({id: {'in': [provinceId, cityId, districtId]}}).select();
+    if (think.isEmpty(regionList) || regionList.length !== 3) {
+      return false;
+    }
+
+    // 上下级关系检查
+    if (_.get(regionList, ['0', 'id']) !== _.get(regionList, ['1', 'parent_id'])) {
+      return false;
+    }
+
+    if (_.get(regionList, ['1', 'id']) !== _.get(regionList, ['2', 'parent_id'])) {
+      return false;
+    }
+
+    return true;
+  }
+
+  /**
+   * 获取区域的名称
+   * @param regionId
+   * @returns {Promise.<*>}
+   */
+  async getRegionName(regionId) {
+    return this.where({id: regionId}).getField('name', true);
+  }
+
+  /**
+   * 获取下级的地区列表
+   * @param parentId
+   * @returns {Promise.<*>}
+   */
+  async getRegionList(parentId) {
+    return this.where({parent_id: parentId}).select();
+  }
+
+  /**
+   * 获取区域的信息
+   * @param regionId
+   * @returns {Promise.<*>}
+   */
+  async getRegionInfo(regionId) {
+    return this.where({id: regionId}).find();
+  }
+};

+ 8 - 23
src/api/service/token.js

@@ -1,31 +1,17 @@
-'use strict';
-
 const jwt = require('jsonwebtoken');
+const secret = 'SLDLKKDS323ssdd@#@@gf';
 
-const secret = think.config('session.secret');
-
-export default class extends think.service.base {
-  /**
-   * init
-   * @return {}         []
-   */
-  init(...args) {
-    super.init(...args);
-  }
-
+module.exports = class extends think.Service {
   /**
    * 根据header中的X-Nideshop-Token值获取用户id
    */
   async getUserId() {
-
     const token = think.token;
-
     if (!token) {
       return 0;
     }
 
-    let result = await this.parse();
-
+    const result = await this.parse();
     if (think.isEmpty(result) || result.user_id <= 0) {
       return 0;
     }
@@ -37,19 +23,18 @@ export default class extends think.service.base {
    * 根据值获取用户信息
    */
   async getUserInfo() {
-
-    let userId = await this.getUserId();
+    const userId = await this.getUserId();
     if (userId <= 0) {
       return null;
     }
 
-    let userInfo = await this.model('user').field(['id', 'username', 'nickname', 'gender', 'avatar', 'birthday']).where({ id: userId }).find();
+    const userInfo = await this.model('user').field(['id', 'username', 'nickname', 'gender', 'avatar', 'birthday']).where({ id: userId }).find();
 
     return think.isEmpty(userInfo) ? null : userInfo;
   }
 
   async create(userInfo) {
-    let token = jwt.sign(userInfo, secret);
+    const token = jwt.sign(userInfo, secret);
     return token;
   }
 
@@ -65,11 +50,11 @@ export default class extends think.service.base {
   }
 
   async verify() {
-    let result = await this.parse();
+    const result = await this.parse();
     if (think.isEmpty(result)) {
       return false;
     }
 
     return true;
   }
-}
+};

+ 0 - 26
src/common/bootstrap/global.js

@@ -1,26 +0,0 @@
-/**
- * this file will be loaded before server started
- * you can define global functions used in controllers, models, templates
- */
-
-/**
- * use global.xxx to define global functions
- * 
- * global.fn1 = function(){
- *     
- * }
- */
-
-const _ = require('lodash');
-
-/**
- * 获取当前的时间戳(秒数)
- * @returns {Number}
- */
-global.getTime = function () {
-  return _.parseInt(_.now() / 1000);
-};
-
-global.getLoginUserId = function () {
-  return think.userId 
-};

+ 1 - 0
src/common/bootstrap/master.js

@@ -0,0 +1 @@
+// invoked in master

+ 0 - 16
src/common/bootstrap/middleware.js

@@ -1,16 +0,0 @@
-/**
- * this file will be loaded before server started
- * you can register middleware
- * https://thinkjs.org/doc/middleware.html
- */
-
-/**
- * 
- * think.middleware('xxx', http => {
- *   
- * })
- * 
- */
-
-const cors = require("think-cors");
-think.middleware("cors", cors);

+ 1 - 0
src/common/bootstrap/worker.js

@@ -0,0 +1 @@
+// invoked in worker

+ 109 - 0
src/common/config/adapter.js

@@ -0,0 +1,109 @@
+const fileCache = require('think-cache-file');
+const nunjucks = require('think-view-nunjucks');
+const fileSession = require('think-session-file');
+const mysql = require('think-model-mysql');
+const {Console, File, DateFile} = require('think-logger3');
+const path = require('path');
+const isDev = think.env === 'development';
+
+/**
+ * cache adapter config
+ * @type {Object}
+ */
+exports.cache = {
+  type: 'file',
+  common: {
+    timeout: 24 * 60 * 60 * 1000 // millisecond
+  },
+  file: {
+    handle: fileCache,
+    cachePath: path.join(think.ROOT_PATH, 'runtime/cache'), // absoulte path is necessarily required
+    pathDepth: 1,
+    gcInterval: 24 * 60 * 60 * 1000 // gc interval
+  }
+};
+
+/**
+ * model adapter config
+ * @type {Object}
+ */
+exports.model = {
+  type: 'mysql',
+  common: {
+    logConnect: isDev,
+    logSql: isDev,
+    logger: msg => think.logger.info(msg)
+  },
+  mysql: {
+    handle: mysql,
+    database: 'nideshop',
+    prefix: 'nideshop_',
+    encoding: 'utf8mb4',
+    host: '127.0.0.1',
+    port: '3306',
+    user: 'root',
+    password: 'root',
+    dateStrings: true
+  }
+};
+
+/**
+ * session adapter config
+ * @type {Object}
+ */
+exports.session = {
+  type: 'file',
+  common: {
+    cookie: {
+      name: 'thinkjs'
+      // keys: ['werwer', 'werwer'],
+      // signed: true
+    }
+  },
+  file: {
+    handle: fileSession,
+    sessionPath: path.join(think.ROOT_PATH, 'runtime/session')
+  }
+};
+
+/**
+ * view adapter config
+ * @type {Object}
+ */
+exports.view = {
+  type: 'nunjucks',
+  common: {
+    viewPath: path.join(think.ROOT_PATH, 'view'),
+    sep: '_',
+    extname: '.html'
+  },
+  nunjucks: {
+    handle: nunjucks
+  }
+};
+
+/**
+ * logger adapter config
+ * @type {Object}
+ */
+exports.logger = {
+  type: isDev ? 'console' : 'dateFile',
+  console: {
+    handle: Console
+  },
+  file: {
+    handle: File,
+    backups: 10, // max chunk number
+    absolute: true,
+    maxLogSize: 50 * 1024, // 50M
+    filename: path.join(think.ROOT_PATH, 'logs/app.log')
+  },
+  dateFile: {
+    handle: DateFile,
+    level: 'ALL',
+    absolute: true,
+    pattern: '-yyyy-MM-dd',
+    alwaysIncludePattern: true,
+    filename: path.join(think.ROOT_PATH, 'logs/app.log')
+  }
+};

+ 0 - 17
src/common/config/cache.js

@@ -1,17 +0,0 @@
-export default {
-  type: 'file', //缓存类型
-  timeout: 6 * 3600, //失效时间,单位:秒
-  adapter: { //不同 adapter 下的配置
-    file: {
-      path: think.RUNTIME_PATH + '/cache', //缓存文件的根目录
-      path_depth: 2, //缓存文件生成子目录的深度
-      file_ext: '.json' //缓存文件的扩展名
-    },
-    redis: {
-      prefix: 'nideshop_'
-    },
-    memcache: {
-      prefix: 'nideshop_'
-    }
-  }
-};

+ 4 - 15
src/common/config/config.js

@@ -1,15 +1,4 @@
-'use strict';
-/**
- * config
- */
-export default {
-    //key: value
-    default_module: 'api', //设置默认模块
-    deny_module_list: [], //设置禁用的模块
-
-    cors: {
-        origin: '*',
-        methods: 'GET,HEAD,PUT,PATCH,POST,DELETE',
-        preflightContinue: false
-    },
-};
+// default config
+module.exports = {
+  default_module: 'api'
+};

+ 4 - 0
src/common/config/config.production.js

@@ -0,0 +1,4 @@
+// production config, it will load in production enviroment
+module.exports = {
+  workers: 0
+};

+ 0 - 22
src/common/config/db.js

@@ -1,22 +0,0 @@
-'use strict';
-/**
- * db config
- * @type {Object}
- */
-export default {
-  type: 'mysql',
-  adapter: {
-    mysql: {
-      host: '127.0.0.1',
-      port: '3306',
-      database: 'nideshop',
-      user: 'root',
-      password: 'root',
-      prefix: 'nideshop_',
-      encoding: 'utf8'
-    },
-    mongo: {
-
-    }
-  }
-};

+ 0 - 5
src/common/config/env/development.js

@@ -1,5 +0,0 @@
-'use strict';
-
-export default {
-  
-};

+ 0 - 5
src/common/config/env/production.js

@@ -1,5 +0,0 @@
-'use strict';
-
-export default {
-  resource_on: false
-};

+ 0 - 5
src/common/config/env/testing.js

@@ -1,5 +0,0 @@
-'use strict';
-
-export default {
-  
-};

+ 0 - 9
src/common/config/error.js

@@ -1,9 +0,0 @@
-'use strict';
-/**
- * err config
- */
-export default {
-  //key: value
-  key: 'errno', //error number
-  msg: 'errmsg' //error message
-};

+ 11 - 0
src/common/config/extend.js

@@ -0,0 +1,11 @@
+const view = require('think-view');
+const model = require('think-model');
+const cache = require('think-cache');
+const session = require('think-session');
+
+module.exports = [
+  view, // make application support view
+  model(think.app),
+  cache,
+  session
+];

+ 0 - 9
src/common/config/hook.js

@@ -1,9 +0,0 @@
-'use strict';
-
-/**
- * hook config
- * https://thinkjs.org/doc/middleware.html#toc-df6
- */
-export default {
-    request_begin: ['cors']
-}

+ 0 - 5
src/common/config/locale/en.js

@@ -1,5 +0,0 @@
-'use strict';
-
-export default {
-  
-};

+ 41 - 0
src/common/config/middleware.js

@@ -0,0 +1,41 @@
+const path = require('path');
+const isDev = think.env === 'development';
+
+module.exports = [
+  {
+    handle: 'meta',
+    options: {
+      logRequest: isDev,
+      sendResponseTime: isDev
+    }
+  },
+  {
+    handle: 'resource',
+    enable: isDev,
+    options: {
+      root: path.join(think.ROOT_PATH, 'www'),
+      publicPath: /^\/(static|favicon\.ico)/
+    }
+  },
+  {
+    handle: 'trace',
+    enable: !think.isCli,
+    options: {
+      debug: isDev
+    }
+  },
+  {
+    handle: 'payload',
+    options: {}
+  },
+  {
+    handle: 'router',
+    options: {
+      defaultModule: 'api',
+      defaultController: 'index',
+      defaultAction: 'index'
+    }
+  },
+  'logic',
+  'controller'
+];

+ 3 - 0
src/common/config/router.js

@@ -0,0 +1,3 @@
+module.exports = [
+
+];

+ 0 - 20
src/common/config/session.js

@@ -1,20 +0,0 @@
-'use strict';
-
-/**
- * session configs
- */
-export default {
-  name: 'thinkjs',
-  type: 'file',
-  secret: 'T^%*$XC@',
-  timeout: 30 * 24 * 3600,
-  cookie: { // cookie options
-    length: 32,
-    httponly: true
-  },
-  adapter: {
-    file: {
-      path: think.RUNTIME_PATH + '/session',
-    }
-  }
-};

+ 0 - 14
src/common/config/view.js

@@ -1,14 +0,0 @@
-'use strict';
-/**
- * template config
- */
-export default {
-  type: 'ejs',
-  content_type: 'text/html',
-  file_ext: '.html',
-  file_depr: '_',
-  root_path: think.ROOT_PATH + '/view',
-  adapter: {
-    ejs: {}
-  }
-};

+ 0 - 77
src/common/controller/error.js

@@ -1,77 +0,0 @@
-'use strict';
-/**
- * error controller
- */
-export default class extends think.controller.base {
-  /**
-   * display error page
-   * @param  {Number} status []
-   * @return {Promise}        []
-   */
-  displayError(status){
-
-    //hide error message on production env
-    if(think.env === 'production'){
-      this.http.error = null;
-    }
-
-    let errorConfig = this.config('error');
-    let message = this.http.error && this.http.error.message || '';
-    if(this.isJsonp()){
-      return this.jsonp({
-        [errorConfig.key]: status,
-        [errorConfig.msg]: message
-      })
-    }else if(this.isAjax()){
-      return this.fail(status, message);
-    }
-
-    let module = 'common';
-    if(think.mode !== think.mode_module){
-      module = this.config('default_module');
-    }
-    let file = `${module}/error/${status}.html`;
-    let options = this.config('tpl');
-    options = think.extend({}, options, {type: 'base', file_depr: '_'});
-    this.fetch(file, {}, options).then(content => {
-      content = content.replace('ERROR_MESSAGE', message);
-      this.type(options.content_type);
-      this.end(content);
-    });
-  }
-  /**
-   * Bad Request 
-   * @return {Promise} []
-   */
-  _400Action(){
-    return this.displayError(400);
-  }
-  /**
-   * Forbidden 
-   * @return {Promise} []
-   */
-  _403Action(){
-    return this.displayError(403);
-  }
-  /**
-   * Not Found 
-   * @return {Promise}      []
-   */
-  _404Action(){
-    return this.displayError(404);
-  }
-  /**
-   * Internal Server Error
-   * @return {Promise}      []
-   */
-  _500Action(){
-    return this.displayError(500);
-  }
-  /**
-   * Service Unavailable
-   * @return {Promise}      []
-   */
-  _503Action(){
-    return this.displayError(503);
-  }
-}

+ 0 - 30
src/common/model/cart.js

@@ -1,30 +0,0 @@
-'use strict';
-/**
- * model
- */
-export default class extends think.model.base {
-
-  /**
-   * 获取购物车的商品
-   * @returns {Promise.<*>}
-   */
-  async getGoodsList(){
-    return await this.model('cart').where({user_id: think.userId, session_id: 1}).select();
-  }
-
-  /**
-   * 获取购物车的选中的商品
-   * @returns {Promise.<*>}
-   */
-  async getCheckedGoodsList(){
-    return await this.model('cart').where({user_id: think.userId, session_id: 1, checked: 1}).select();
-  }
-
-    /**
-     * 清空已购买的商品
-     * @returns {Promise.<*>}
-     */
-  async clearBuyGoods(){
-      return await this.model('cart').where({user_id: think.userId, session_id: 1, checked: 1}).delete();
-  }
-}

+ 0 - 15
src/common/model/category.js

@@ -1,15 +0,0 @@
-'use strict';
-/**
- * model
- */
-export default class extends think.model.base {
-    async getChildCategoryId(parentId){
-        return await this.where({parent_id: parentId}).getField('id', 10000);
-    }
-
-    async getCategoryWhereIn(categoryId){
-        let childIds = await this.getChildCategoryId(categoryId);
-        childIds.push(categoryId);
-        return childIds;
-    }
-}

+ 0 - 17
src/common/model/collect.js

@@ -1,17 +0,0 @@
-'use strict';
-/**
- * model
- */
-export default class extends think.model.base {
-
-  /**
-   * 判断用户是否收藏过该对象
-   * @param userId
-   * @param typeId
-   * @param valueId
-   * @returns {Promise.<boolean>}
-   */
-  async isUserHasCollect(userId, typeId, valueId){
-    return await this.where({type_id: typeId, value_id: valueId, user_id: userId}).limit(1).count('id');
-  }
-}

+ 0 - 22
src/common/model/footprint.js

@@ -1,22 +0,0 @@
-'use strict';
-/**
- * model
- */
-export default class extends think.model.base {
-
-  async addFootprint(goodsId){
-
-    //用户已经登录才可以添加到足迹
-    let userId = getLoginUserId();
-
-    if (userId > 0) {
-
-      await this.add({
-        goods_id: goodsId,
-        user_id: userId,
-        add_time: getTime()
-      });
-
-    }
-  }
-}

+ 0 - 7
src/common/model/member.js

@@ -1,7 +0,0 @@
-'use strict';
-/**
- * model
- */
-export default class extends think.model.base {
-
-}

+ 0 - 96
src/common/model/order.js

@@ -1,96 +0,0 @@
-'use strict';
-
-const _ = require('lodash');
-
-/**
- * model
- */
-export default class extends think.model.base {
-
-
-  /**
-   * 生成订单的编号order_sn
-   * @returns {string}
-   */
-  generateOrderNumber(){
-    let date = new Date();
-    return date.getFullYear() + _.padStart(date.getMonth(), 2, '0') + _.padStart(date.getDay(), 2, '0')
-          + _.padStart(date.getHours(), 2, '0') + _.padStart(date.getMinutes(), 2, '0') + _.padStart(date.getSeconds(), 2, '0')
-          + _.random(100000, 999999);
-  }
-
-  /**
-   * 获取订单可操作的选项
-   * @param orderId
-   * @returns {Promise.<{cancel: boolean, delete: boolean, pay: boolean, comment: boolean, delivery: boolean, confirm: boolean, return: boolean}>}
-   */
-  async getOrderHandleOption(orderId){
-
-    let handleOption = {
-      cancel: false,  //取消操作
-      delete: false, //删除操作
-      pay: false,   //支付操作
-      comment: false, //评论操作
-      delivery: false, //确认收货操作
-      confirm: false,  //完成订单操作
-      return: false, //退换货操作
-      buy: false, //再次购买
-    };
-
-    let orderInfo = await this.where({id: orderId}).find();
-
-    //订单流程: 下单成功-》支付订单-》发货-》收货-》评论
-
-    //订单相关状态字段设计,采用单个字段表示全部的订单状态
-    //1xx 表示订单取消和删除等状态 0订单创建成功等待付款, 101订单已取消, 102订单已删除
-    //2xx 表示订单支付状态 201订单已付款,等待发货
-    //3xx 表示订单物流相关状态 300订单已发货, 301用户确认收货
-    //4xx 表示订单退换货相关的状态 401 没有发货,退款 402 已收货,退款退货
-
-    //如果订单已经取消或是已完成,则可删除和再次购买
-    if (orderInfo.order_status === 101) {
-      handleOption.delete = true;
-      handleOption.buy = true;
-    }
-
-    //如果订单没有被取消,且没有支付,则可支付,可取消
-    if (orderInfo.order_status === 0) {
-      handleOption.cancel = true;
-      handleOption.pay = true;
-    }
-
-    //如果订单已付款,没有发货,则可退款操作
-    if (orderInfo.order_status === 201) {
-      handleOption.return = true;
-    }
-
-    //如果订单已经发货,没有收货,则可收货操作和退款、退货操作
-    if (orderInfo.order_status === 300) {
-      handleOption.cancel = true;
-      handleOption.pay = true;
-      handleOption.return = true;
-    }
-
-    //如果订单已经支付,且已经收货,则可完成交易、评论和再次购买
-    if (orderInfo.order_status === 301) {
-      handleOption.delete = true;
-      handleOption.comment = true;
-      handleOption.buy = true;
-    }
-
-    return handleOption;
-  }
-
-  async getOrderStatusText(orderId){
-    let orderInfo = await this.where({id: orderId}).find();
-    let statusText = '未付款';
-    switch (orderInfo.order_status) {
-      case 0:
-        statusText = '未付款';
-        break;
-    }
-
-    return statusText;
-  }
-
-}

+ 0 - 82
src/common/model/region.js

@@ -1,82 +0,0 @@
-'use strict';
-
-const _ = require('lodash');
-/**
- * model
- */
-export default class extends think.model.base {
-
-  /**
-   * 获取完整的省市区名称组成的字符串
-   * @param provinceId
-   * @param cityId
-   * @param districtId
-   * @returns {Promise.<*>}
-   */
-  async getFullRegionName(provinceId, cityId, districtId){
-
-    if (!await this.checkFullRegion(provinceId, cityId, districtId)) {
-      return '';
-    }
-
-    let regionList = await this.limit(3).order({'id': 'asc'}).where({id: {'in' : [provinceId, cityId, districtId]}}).select();
-
-    if (!think.isEmpty(regionList) && regionList.length === 3) {
-      return _.flatMap(regionList, "name").join('');
-    }
-
-    return '';
-  }
-
-  /**
-   * 检查省市区信息是否完整和正确
-   * @param provinceId
-   * @param cityId
-   * @param districtId
-   * @returns {Promise.<boolean>}
-   */
-  async checkFullRegion(provinceId, cityId, districtId) {
-
-    if (think.isEmpty(provinceId) || think.isEmpty(cityId) || think.isEmpty(districtId)) {
-      return false;
-    }
-
-    let regionList = await this.limit(3).order({'id': 'asc'}).where({id: {'in' : [provinceId, cityId, districtId]}}).select();
-
-    if (!think.isEmpty(regionList) && regionList.length === 3) {
-      //上下级关系检查
-      if (_.get(regionList, ['0', 'id', ]) === _.get(regionList, ['1', 'parent_id']) && _.get(regionList, ['1', 'id', ]) === _.get(regionList, ['2', 'parent_id'])) {
-        return true;
-      }
-    }
-
-    return false;
-  }
-
-  /**
-   * 获取区域的名称
-   * @param regionId
-   * @returns {Promise.<*>}
-   */
-  async getRegionName(regionId){
-    return this.where({id: regionId}).getField('name', true);
-  }
-
-  /**
-   * 获取下级的地区列表
-   * @param parentId
-   * @returns {Promise.<*>}
-   */
-  async getRegionList(parentId){
-    return this.where({parent_id: parentId}).select();
-  }
-
-  /**
-   * 获取区域的信息
-   * @param regionId
-   * @returns {Promise.<*>}
-   */
-  async getRegionInfo(regionId){
-    return this.where({id: regionId}).find();
-  }
-}

+ 4 - 7
src/home/config/config.js

@@ -1,7 +1,4 @@
-'use strict';
-/**
- * config
- */
-export default {
-  //key: value
-};
+// default config
+module.exports = {
+
+};

+ 4 - 6
src/home/controller/base.js

@@ -1,7 +1,5 @@
-'use strict';
+module.exports = class extends think.Controller {
+  __before() {
 
-export default class extends think.controller.base {
-  /**
-   * some base method in here
-   */
-}
+  }
+};

+ 4 - 11
src/home/controller/index.js

@@ -1,14 +1,7 @@
-'use strict';
+const Base = require('./base.js');
 
-import Base from './base.js';
-
-export default class extends Base {
-  /**
-   * index action
-   * @return {Promise} []
-   */
-  indexAction(){
-    //auto render template file index_index.html
+module.exports = class extends Base {
+  indexAction() {
     return this.display();
   }
-}
+};

+ 4 - 14
src/home/logic/index.js

@@ -1,15 +1,5 @@
-'use strict';
-/**
- * logic
- * @param  {} []
- * @return {}     []
- */
-export default class extends think.logic.base {
-  /**
-   * index action logic
-   * @return {} []
-   */
-  indexAction(){
-   
+module.exports = class extends think.Logic {
+  indexAction() {
+
   }
-}
+};

+ 2 - 6
src/home/model/index.js

@@ -1,7 +1,3 @@
-'use strict';
-/**
- * model
- */
-export default class extends think.model.base {
+module.exports = class extends think.Model {
 
-}
+};

+ 4 - 4
view/api/index_index.html

@@ -30,17 +30,17 @@ code{  padding: 2px 4px;font-size: 90%;color: #c7254e;background-color: #f9f2f4;
       <div class="item">
         <div class="step">1</div>
         <h2>Generate Files</h2>
-        <p>Run <code>thinkjs</code> command to create module, controler, model, service and so on. visit <a href="https://thinkjs.org/doc/thinkjs_command.html">https://thinkjs.org/doc/thinkjs_command.html</a> to view more infomation.</p>
+        <p>Run <code>thinkjs</code> command to create module, controler, model, service and so on. </p>
       </div>
       <div class="item">
         <div class="step">2</div>
         <h2>Documentation</h2>
-        <p>ThinkJS has html and pdf documents. visit <a href="https://thinkjs.org/doc.html">https://thinkjs.org/doc.html</a></p>
+        <p>ThinkJS has online html documents. visit <a href="https://thinkjs.org/doc.html">https://thinkjs.org/doc.html</a>.</p>
       </div>
       <div class="item">
         <div class="step">3</div>
-        <h2>WebSocket</h2>
-        <p>ThinkJS support <code>socket.io</code> and <code>sockjs</code> WebSocket client and server node. visit <a href="https://thinkjs.org/doc/adapter_websocket.html">https://thinkjs.org/doc/adapter_websocket.html</a></p>
+        <h2>GitHub</h2>
+        <p>If you have some questions, please <a href="https://github.com/thinkjs/thinkjs/issues">new a issue</a>.</p>
       </div>
     </div>
   </div>

File diff suppressed because it is too large
+ 0 - 24
view/common/error_400.html


File diff suppressed because it is too large
+ 0 - 24
view/common/error_403.html


File diff suppressed because it is too large
+ 0 - 24
view/common/error_404.html


File diff suppressed because it is too large
+ 0 - 24
view/common/error_500.html


File diff suppressed because it is too large
+ 0 - 24
view/common/error_503.html


+ 0 - 1
view/home/index_index.html

@@ -1 +0,0 @@
-来早了,PC版还在开发中...

Some files were not shown because too many files changed in this diff