瀏覽代碼

feat 添加后台接口

tumobi 7 年之前
父節點
當前提交
51b3cecaca
共有 39 個文件被更改,包括 752 次插入2 次删除
  1. 34 2
      nideshop.sql
  2. 2 0
      package.json
  3. 4 0
      src/admin/config/config.js
  4. 41 0
      src/admin/controller/auth.js
  5. 15 0
      src/admin/controller/base.js
  6. 54 0
      src/admin/controller/brand.js
  7. 70 0
      src/admin/controller/category.js
  8. 55 0
      src/admin/controller/goods.js
  9. 7 0
      src/admin/controller/index.js
  10. 64 0
      src/admin/controller/order.js
  11. 54 0
      src/admin/controller/topic.js
  12. 98 0
      src/admin/controller/upload.js
  13. 54 0
      src/admin/controller/user.js
  14. 9 0
      src/admin/logic/auth.js
  15. 5 0
      src/admin/logic/brand.js
  16. 5 0
      src/admin/logic/category.js
  17. 5 0
      src/admin/logic/goods.js
  18. 5 0
      src/admin/logic/index.js
  19. 5 0
      src/admin/logic/order.js
  20. 5 0
      src/admin/logic/topic.js
  21. 5 0
      src/admin/logic/upload.js
  22. 5 0
      src/admin/logic/user.js
  23. 3 0
      src/admin/model/index.js
  24. 83 0
      src/admin/model/order.js
  25. 60 0
      src/admin/service/token.js
  26. 5 0
      src/common/config/middleware.js
  27. 二進制
      www/static/brand/1VEM1w9wv6VLJ48xSfS0Ksw3Qb6uD6yt.jpg
  28. 二進制
      www/static/brand/3jDIpczPXWcL_21qYxOwci2HMKgkqrRT.jpg
  29. 二進制
      www/static/brand/AF7zHqYO_H93v9C3n8q_ax_Q3mhiDnR6.jpg
  30. 二進制
      www/static/brand/BTIzKSu0I_Hzb5I6P_wMqzey96HYK5QI.jpg
  31. 二進制
      www/static/brand/MOp9W2GfK_tLCcTdgrBEkToVT6EoS4CQ.jpg
  32. 二進制
      www/static/brand/OJ9SOIOTVoy1YK1s1zyQWVk79LyUXIGF.jpg
  33. 二進制
      www/static/brand/Rr2CN3UGfB6VKi2NcbRWYsfgkl4nmWup.jpg
  34. 二進制
      www/static/brand/Ru5_NnfPzH7WlVJD_sIk2sbHjEo6T4D1.jpg
  35. 二進制
      www/static/brand/XPKZO6W_wlz_ZU77iF_Hm7ym9_EnvgKV.jpg
  36. 二進制
      www/static/brand/i6giRipkAPmSkmu7tjvBajuYzAzqyKDB.jpg
  37. 二進制
      www/static/brand/ku6zGnrITGuSWusTdY9HUbK_qL8HhL2P.jpg
  38. 二進制
      www/static/brand/mr9j2YzOCdgviQbpGOVfneg5VoaJM3T_.jpg
  39. 二進制
      www/static/brand/wB0ODeShC7DUY_oplfD3sgbfmeYTG14o.jpg

File diff suppressed because it is too large
+ 34 - 2
nideshop.sql


+ 2 - 0
package.json

@@ -9,7 +9,9 @@
     "lint-fix": "eslint --fix src/"
   },
   "dependencies": {
+    "gm": "^1.23.0",
     "jsonwebtoken": "^8.0.0",
+    "kcors": "^2.2.1",
     "lodash": "^4.17.4",
     "moment": "^2.18.1",
     "request": "^2.81.0",

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

@@ -0,0 +1,4 @@
+// default config
+module.exports = {
+
+};

+ 41 - 0
src/admin/controller/auth.js

@@ -0,0 +1,41 @@
+const Base = require('./base.js');
+
+module.exports = class extends Base {
+  async loginAction() {
+    const username = this.post('username');
+    const password = this.post('password');
+
+    const admin = await this.model('admin').where({ username: username }).find();
+    if (think.isEmpty(admin)) {
+      return this.fail(401, '用户名或密码不正确1');
+    }
+
+    if (think.md5(password + '' + admin.password_salt) !== admin.password) {
+      return this.fail(400, '用户名或密码不正确2');
+    }
+
+    // 更新登录信息
+    await this.model('admin').where({ id: admin.id }).update({
+      last_login_time: parseInt(Date.now() / 1000),
+      last_login_ip: this.ctx.ip
+    });
+
+    const TokenSerivce = this.service('token', 'admin');
+    const sessionKey = await TokenSerivce.create({
+      user_id: admin.id
+    });
+
+    if (think.isEmpty(sessionKey)) {
+      return this.fail('登录失败');
+    }
+
+    const userInfo = {
+      id: admin.id,
+      username: admin.username,
+      avatar: admin.avatar,
+      admin_role_id: admin.admin_role_id
+    };
+
+    return this.success({ token: sessionKey, userInfo: userInfo });
+  }
+};

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

@@ -0,0 +1,15 @@
+module.exports = class extends think.Controller {
+  async __before() {
+    // 根据token值获取用户id
+    think.token = this.ctx.header['x-nideshop-token'] || '';
+    const tokenSerivce = think.service('token', 'admin');
+    think.userId = await tokenSerivce.getUserId();
+
+    // 只允许登录操作
+    if (this.ctx.controller !== 'auth') {
+      if (think.userId <= 0) {
+        return this.fail(401, '请先登录');
+      }
+    }
+  }
+};

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

@@ -0,0 +1,54 @@
+const Base = require('./base.js');
+
+module.exports = class extends Base {
+  /**
+   * index action
+   * @return {Promise} []
+   */
+  async indexAction() {
+    const page = this.get('page') || 1;
+    const size = this.get('size') || 10;
+    const name = this.get('name') || '';
+
+    const model = this.model('brand');
+    const data = await model.field(['id', 'name', 'floor_price', 'app_list_pic_url', 'is_new', 'sort_order', 'is_show']).where({name: ['like', `%${name}%`]}).order(['id DESC']).page(page, size).countSelect();
+
+    return this.success(data);
+  }
+
+  async infoAction() {
+    const id = this.get('id');
+    const model = this.model('brand');
+    const data = await model.where({id: id}).find();
+
+    return this.success(data);
+  }
+
+  async storeAction() {
+    if (!this.isPost) {
+      return false;
+    }
+
+    const values = this.post();
+    const id = this.post('id');
+
+    const model = this.model('brand');
+    values.is_show = values.is_show ? 1 : 0;
+    values.is_new = values.is_new ? 1 : 0;
+    if (id > 0) {
+      await model.where({id: id}).update(values);
+    } else {
+      delete values.id;
+      await model.add(values);
+    }
+    return this.success(values);
+  }
+
+  async destoryAction() {
+    const id = this.post('id');
+    await this.model('brand').where({id: id}).limit(1).delete();
+    // TODO 删除图片
+
+    return this.success();
+  }
+};

+ 70 - 0
src/admin/controller/category.js

@@ -0,0 +1,70 @@
+const Base = require('./base.js');
+const _ = require('lodash');
+
+module.exports = class extends Base {
+  /**
+   * index action
+   * @return {Promise} []
+   */
+  async indexAction() {
+    const model = this.model('category');
+    const data = await model.where({is_show: 1}).order(['sort_order ASC']).select();
+    const topCategory = data.filter((item) => {
+      return item.parent_id === 0;
+    });
+    const categoryList = [];
+    topCategory.map((item) => {
+      item.level = 1;
+      categoryList.push(item);
+      data.map((child) => {
+        if (child.parent_id === item.id) {
+          child.level = 2;
+          categoryList.push(child);
+        }
+      });
+    });
+    return this.success(categoryList);
+  }
+
+  async topCategoryAction() {
+    const model = this.model('category');
+    const data = await model.where({parent_id: 0}).order(['id ASC']).select();
+
+    return this.success(data);
+  }
+
+  async infoAction() {
+    const id = this.get('id');
+    const model = this.model('category');
+    const data = await model.where({id: id}).find();
+
+    return this.success(data);
+  }
+
+  async storeAction() {
+    if (!this.isPost) {
+      return false;
+    }
+
+    const values = this.post();
+    const id = this.post('id');
+
+    const model = this.model('category');
+    values.is_show = values.is_show ? 1 : 0;
+    if (id > 0) {
+      await model.where({id: id}).update(values);
+    } else {
+      delete values.id;
+      await model.add(values);
+    }
+    return this.success(values);
+  }
+
+  async destoryAction() {
+    const id = this.post('id');
+    await this.model('category').where({id: id}).limit(1).delete();
+    // TODO 删除图片
+
+    return this.success();
+  }
+};

+ 55 - 0
src/admin/controller/goods.js

@@ -0,0 +1,55 @@
+const Base = require('./base.js');
+
+module.exports = class extends Base {
+  /**
+   * index action
+   * @return {Promise} []
+   */
+  async indexAction() {
+    const page = this.get('page') || 1;
+    const size = this.get('size') || 10;
+    const name = this.get('name') || '';
+
+    const model = this.model('goods');
+    const data = await model.where({name: ['like', `%${name}%`]}).order(['id DESC']).page(page, size).countSelect();
+
+    return this.success(data);
+  }
+
+  async infoAction() {
+    const id = this.get('id');
+    const model = this.model('goods');
+    const data = await model.where({id: id}).find();
+
+    return this.success(data);
+  }
+
+  async storeAction() {
+    if (!this.isPost) {
+      return false;
+    }
+
+    const values = this.post();
+    const id = this.post('id');
+
+    const model = this.model('goods');
+    values.is_on_sale = values.is_on_sale ? 1 : 0;
+    values.is_new = values.is_new ? 1 : 0;
+    values.is_hot = values.is_hot ? 1 : 0;
+    if (id > 0) {
+      await model.where({id: id}).update(values);
+    } else {
+      delete values.id;
+      await model.add(values);
+    }
+    return this.success(values);
+  }
+
+  async destoryAction() {
+    const id = this.post('id');
+    await this.model('goods').where({id: id}).limit(1).delete();
+    // TODO 删除图片
+
+    return this.success();
+  }
+};

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

@@ -0,0 +1,7 @@
+const Base = require('./base.js');
+
+module.exports = class extends Base {
+  indexAction() {
+    return this.display();
+  }
+};

+ 64 - 0
src/admin/controller/order.js

@@ -0,0 +1,64 @@
+const Base = require('./base.js');
+
+module.exports = class extends Base {
+  /**
+   * index action
+   * @return {Promise} []
+   */
+  async indexAction() {
+    const page = this.get('page') || 1;
+    const size = this.get('size') || 10;
+    const orderSn = this.get('orderSn') || '';
+    const consignee = this.get('consignee') || '';
+
+    const model = this.model('order');
+    const data = await model.where({order_sn: ['like', `%${orderSn}%`], consignee: ['like', `%${consignee}%`]}).order(['id DESC']).page(page, size).countSelect();
+    const newList = [];
+    for (const item of data.data) {
+      item.order_status_text = await this.model('order').getOrderStatusText(item.id);
+      newList.push(item);
+    }
+    data.data = newList;
+    return this.success(data);
+  }
+
+  async infoAction() {
+    const id = this.get('id');
+    const model = this.model('order');
+    const data = await model.where({id: id}).find();
+
+    return this.success(data);
+  }
+
+  async storeAction() {
+    if (!this.isPost) {
+      return false;
+    }
+
+    const values = this.post();
+    const id = this.post('id');
+
+    const model = this.model('order');
+    values.is_show = values.is_show ? 1 : 0;
+    values.is_new = values.is_new ? 1 : 0;
+    if (id > 0) {
+      await model.where({id: id}).update(values);
+    } else {
+      delete values.id;
+      await model.add(values);
+    }
+    return this.success(values);
+  }
+
+  async destoryAction() {
+    const id = this.post('id');
+    await this.model('order').where({id: id}).limit(1).delete();
+
+    // 删除订单商品
+    await this.model('order_goods').where({order_id: id}).delete();
+
+    // TODO 事务,验证订单是否可删除(只有失效的订单才可以删除)
+
+    return this.success();
+  }
+};

+ 54 - 0
src/admin/controller/topic.js

@@ -0,0 +1,54 @@
+const Base = require('./base.js');
+
+module.exports = class extends Base {
+  /**
+   * index action
+   * @return {Promise} []
+   */
+  async indexAction() {
+    const page = this.get('page') || 1;
+    const size = this.get('size') || 10;
+    const name = this.get('name') || '';
+
+    const model = this.model('topic');
+    const data = await model.where({title: ['like', `%${name}%`]}).order(['id DESC']).page(page, size).countSelect();
+
+    return this.success(data);
+  }
+
+  async infoAction() {
+    const id = this.get('id');
+    const model = this.model('topic');
+    const data = await model.where({id: id}).find();
+
+    return this.success(data);
+  }
+
+  async storeAction() {
+    if (!this.isPost) {
+      return false;
+    }
+
+    const values = this.post();
+    const id = this.post('id');
+
+    const model = this.model('topic');
+    values.is_show = values.is_show ? 1 : 0;
+    values.is_new = values.is_new ? 1 : 0;
+    if (id > 0) {
+      await model.where({id: id}).update(values);
+    } else {
+      delete values.id;
+      await model.add(values);
+    }
+    return this.success(values);
+  }
+
+  async destoryAction() {
+    const id = this.post('id');
+    await this.model('topic').where({id: id}).limit(1).delete();
+    // TODO 删除图片
+
+    return this.success();
+  }
+};

+ 98 - 0
src/admin/controller/upload.js

@@ -0,0 +1,98 @@
+const Base = require('./base.js');
+const gm = require('gm').subClass({imageMagick: true});
+const fs = require('fs');
+
+module.exports = class extends Base {
+  async brandPicAction() {
+    const brandFile = this.file('brand_pic');
+    if (think.isEmpty(brandFile)) {
+      return this.fail('保存失败');
+    }
+    const that = this;
+    const filename = '/static/upload/brand/' + think.uuid(32) + '.jpg';
+    const is = fs.createReadStream(brandFile.path);
+    const os = fs.createWriteStream(think.ROOT_PATH + '/www' + filename);
+    is.pipe(os);
+
+    return that.success({
+      name: 'brand_pic',
+      fileUrl: 'http://127.0.0.1:8360' + filename
+    });
+    // gm(brandFile.path)
+    //   .resize(750, 420, '!')
+    //   .write(think.RESOURCE_PATH + filename, function (err) {
+    //     if (err) {
+    //       return that.fail('图片上传失败');
+    //     }
+    //     return that.success({
+    //       name: 'brand_pic',
+    //       fileUrl: 'http://127.0.0.1:8360' + filename
+    //     });
+    //   });
+  }
+
+  async brandNewPicAction() {
+    const brandFile = this.file('brand_new_pic');
+    if (think.isEmpty(brandFile)) {
+      return this.fail('保存失败');
+    }
+    const that = this;
+    const filename = '/static/upload/brand/' + think.uuid(32) + '.jpg';
+
+    const is = fs.createReadStream(brandFile.path);
+    const os = fs.createWriteStream(think.ROOT_PATH + '/www' + filename);
+    is.pipe(os);
+
+    return that.success({
+      name: 'brand_new_pic',
+      fileUrl: 'http://127.0.0.1:8360' + filename
+    });
+    // gm(brandFile.path)
+    //   .resize(375, 252, '!')
+    //   .write(think.ROOT_PATH + '/www' + filename, function(err) {
+    //     if (err) {
+    //       return that.fail('上传失败');
+    //     }
+    //     return that.success({
+    //       name: 'brand_new_pic',
+    //       fileUrl: 'http://127.0.0.1:8360' + filename
+    //     });
+    //   });
+  }
+
+  async categoryWapBannerPicAction() {
+    const imageFile = this.file('wap_banner_pic');
+    if (think.isEmpty(imageFile)) {
+      return this.fail('保存失败');
+    }
+    const that = this;
+    const filename = '/static/upload/category/' + think.uuid(32) + '.jpg';
+
+    const is = fs.createReadStream(imageFile.path);
+    const os = fs.createWriteStream(think.ROOT_PATH + '/www' + filename);
+    is.pipe(os);
+
+    return that.success({
+      name: 'wap_banner_url',
+      fileUrl: 'http://127.0.0.1:8360' + filename
+    });
+  }
+
+  async topicThumbAction() {
+    const imageFile = this.file('scene_pic_url');
+    if (think.isEmpty(imageFile)) {
+      return this.fail('保存失败');
+    }
+    const that = this;
+    const filename = '/static/upload/topic/' + think.uuid(32) + '.jpg';
+
+    const is = fs.createReadStream(imageFile.path);
+    const os = fs.createWriteStream(think.ROOT_PATH + '/www' + filename);
+    is.pipe(os);
+
+    return that.success({
+      name: 'scene_pic_url',
+      fileUrl: 'http://127.0.0.1:8360' + filename
+    });
+  }
+};

+ 54 - 0
src/admin/controller/user.js

@@ -0,0 +1,54 @@
+const Base = require('./base.js');
+
+module.exports = class extends Base {
+  /**
+   * index action
+   * @return {Promise} []
+   */
+  async indexAction() {
+    const page = this.get('page') || 1;
+    const size = this.get('size') || 10;
+    const name = this.get('name') || '';
+
+    const model = this.model('user');
+    const data = await model.where({username: ['like', `%${name}%`]}).order(['id DESC']).page(page, size).countSelect();
+
+    return this.success(data);
+  }
+
+  async infoAction() {
+    const id = this.get('id');
+    const model = this.model('user');
+    const data = await model.where({id: id}).find();
+
+    return this.success(data);
+  }
+
+  async storeAction() {
+    if (!this.isPost) {
+      return false;
+    }
+
+    const values = this.post();
+    const id = this.post('id');
+
+    const model = this.model('user');
+    values.is_show = values.is_show ? 1 : 0;
+    values.is_new = values.is_new ? 1 : 0;
+    if (id > 0) {
+      await model.where({id: id}).update(values);
+    } else {
+      delete values.id;
+      await model.add(values);
+    }
+    return this.success(values);
+  }
+
+  async destoryAction() {
+    const id = this.post('id');
+    await this.model('user').where({id: id}).limit(1).delete();
+    // TODO 删除图片
+
+    return this.success();
+  }
+};

+ 9 - 0
src/admin/logic/auth.js

@@ -0,0 +1,9 @@
+module.exports = class extends think.Logic {
+  loginAction(){
+    this.allowMethods = 'post';
+    this.rules = {
+      username: {required: true, string: true},
+      password: {required: true, string: true}
+    };
+  }
+};

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

@@ -0,0 +1,5 @@
+module.exports = class extends think.Logic {
+  indexAction() {
+    this.allowMethods = 'get';
+  }
+};

+ 5 - 0
src/admin/logic/category.js

@@ -0,0 +1,5 @@
+module.exports = class extends think.Logic {
+  indexAction() {
+
+  }
+};

+ 5 - 0
src/admin/logic/goods.js

@@ -0,0 +1,5 @@
+module.exports = class extends think.Logic {
+  indexAction() {
+
+  }
+};

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

@@ -0,0 +1,5 @@
+module.exports = class extends think.Logic {
+  indexAction() {
+
+  }
+};

+ 5 - 0
src/admin/logic/order.js

@@ -0,0 +1,5 @@
+module.exports = class extends think.Logic {
+  indexAction() {
+
+  }
+};

+ 5 - 0
src/admin/logic/topic.js

@@ -0,0 +1,5 @@
+module.exports = class extends think.Logic {
+  indexAction() {
+
+  }
+};

+ 5 - 0
src/admin/logic/upload.js

@@ -0,0 +1,5 @@
+module.exports = class extends think.Logic {
+  indexAction() {
+
+  }
+};

+ 5 - 0
src/admin/logic/user.js

@@ -0,0 +1,5 @@
+module.exports = class extends think.Logic {
+  indexAction() {
+
+  }
+};

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

@@ -0,0 +1,3 @@
+module.exports = class extends think.Model {
+
+};

+ 83 - 0
src/admin/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;
+  }
+};

+ 60 - 0
src/admin/service/token.js

@@ -0,0 +1,60 @@
+const jwt = require('jsonwebtoken');
+const secret = 'SLDLKKDS323ssdd@#@@gf';
+
+module.exports = class extends think.Service {
+  /**
+   * 根据header中的X-Nideshop-Token值获取用户id
+   */
+  async getUserId() {
+    const token = think.token;
+    if (!token) {
+      return 0;
+    }
+
+    const result = await this.parse();
+    if (think.isEmpty(result) || result.user_id <= 0) {
+      return 0;
+    }
+
+    return result.user_id;
+  }
+
+  /**
+   * 根据值获取用户信息
+   */
+  async getUserInfo() {
+    const userId = await this.getUserId();
+    if (userId <= 0) {
+      return null;
+    }
+
+    const userInfo = await this.model('admin').where({ id: userId }).find();
+
+    return think.isEmpty(userInfo) ? null : userInfo;
+  }
+
+  async create(userInfo) {
+    const token = jwt.sign(userInfo, secret);
+    return token;
+  }
+
+  async parse() {
+    if (think.token) {
+      try {
+        return jwt.verify(think.token, secret);
+      } catch (err) {
+        return null;
+      }
+    }
+    return null;
+  }
+
+  async verify() {
+    const result = await this.parse();
+    if (think.isEmpty(result)) {
+      return false;
+    }
+
+    return true;
+  }
+};

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

@@ -1,8 +1,13 @@
 const path = require('path');
 const isDev = think.env === 'development';
+const kcors = require('kcors');
 
 module.exports = [
   {
+    handle: kcors, // 处理跨域
+    options: {}
+  },
+  {
     handle: 'meta',
     options: {
       logRequest: isDev,

二進制
www/static/brand/1VEM1w9wv6VLJ48xSfS0Ksw3Qb6uD6yt.jpg


二進制
www/static/brand/3jDIpczPXWcL_21qYxOwci2HMKgkqrRT.jpg


二進制
www/static/brand/AF7zHqYO_H93v9C3n8q_ax_Q3mhiDnR6.jpg


二進制
www/static/brand/BTIzKSu0I_Hzb5I6P_wMqzey96HYK5QI.jpg


二進制
www/static/brand/MOp9W2GfK_tLCcTdgrBEkToVT6EoS4CQ.jpg


二進制
www/static/brand/OJ9SOIOTVoy1YK1s1zyQWVk79LyUXIGF.jpg


二進制
www/static/brand/Rr2CN3UGfB6VKi2NcbRWYsfgkl4nmWup.jpg


二進制
www/static/brand/Ru5_NnfPzH7WlVJD_sIk2sbHjEo6T4D1.jpg


二進制
www/static/brand/XPKZO6W_wlz_ZU77iF_Hm7ym9_EnvgKV.jpg


二進制
www/static/brand/i6giRipkAPmSkmu7tjvBajuYzAzqyKDB.jpg


二進制
www/static/brand/ku6zGnrITGuSWusTdY9HUbK_qL8HhL2P.jpg


二進制
www/static/brand/mr9j2YzOCdgviQbpGOVfneg5VoaJM3T_.jpg


二進制
www/static/brand/wB0ODeShC7DUY_oplfD3sgbfmeYTG14o.jpg


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