Authored by lijing

暂存

@@ -64,6 +64,9 @@ const logger = global.yoho.logger; @@ -64,6 +64,9 @@ const logger = global.yoho.logger;
64 64
65 // 访问域名层级 65 // 访问域名层级
66 app.set('subdomain offset', 3); 66 app.set('subdomain offset', 3);
  67 +
  68 +app.use(global.yoho.httpCtx());
  69 +
67 app.use(global.yoho.hbs({ 70 app.use(global.yoho.hbs({
68 extname: '.hbs', 71 extname: '.hbs',
69 defaultLayout: 'layout', 72 defaultLayout: 'layout',
  1 +'use strict';
  2 +
  3 +const mRoot = '../models';
  4 +const headerModel = require('../../../doraemon/models/header'); // 头部model
  5 +const gradeNewModel = require(`${mRoot}/grade-new`);
  6 +
  7 +exports.index = (req, res, next) => {
  8 + let responseData = {
  9 + module: 'home',
  10 + page: 'grade-new',
  11 + pageHeader: headerModel.setNav({
  12 + navTitle: '会员等级'
  13 + }),
  14 + title: '会员等级',
  15 + width750: true,
  16 + localCss: true,
  17 + pageFooter: true
  18 + };
  19 +
  20 + let params = {
  21 + uid: req.user.uid,
  22 + channel: req.query.channel || 1
  23 + };
  24 +
  25 + req.ctx(gradeNewModel).index(params).then(result => {
  26 + console.log(result);
  27 + res.render('grade-new/index', Object.assign(responseData, result));
  28 + }).catch(next);
  29 +};
  1 +'use strict';
  2 +
  3 +const api = global.yoho.API;
  4 +const helpers = global.yoho.helpers;
  5 +const _ = require('lodash');
  6 +
  7 +/**
  8 + * 会员等级
  9 + * @param params
  10 + */
  11 +
  12 +module.exports = class extends global.yoho.BaseModel {
  13 + constructor(ctx) {
  14 + super(ctx);
  15 + }
  16 +
  17 + getGradeGrade(uid, channel) {
  18 + return api.get('', {
  19 + method: 'app.passport.vip',
  20 + uid: uid,
  21 + channel: channel || 1
  22 + }, {
  23 + code: 200
  24 + });
  25 + }
  26 +
  27 + getGradeUser(uid, channel) {
  28 + return api.get('', {
  29 + method: 'app.passport.profile',
  30 + uid: uid,
  31 + channel: channel || 1
  32 + }, {
  33 + code: 200
  34 + });
  35 + }
  36 +
  37 + index(param) {
  38 + if (param.uid) {
  39 + return api.all([
  40 + this.getGradeGrade(param.uid, param.channel),
  41 + this.getGradeUser(param.uid, param.channel)
  42 + ]).then((result) => {
  43 +
  44 + let resu = {
  45 + vipGrade: []
  46 + };
  47 +
  48 + let enp = {};
  49 +
  50 + let obj = {
  51 + privilege: []
  52 + };
  53 +
  54 + if (result[0] && result[0].data) {
  55 +
  56 + _.forEach(result[0].data.enjoy_preferential, function(val) {
  57 +
  58 + enp = {
  59 + description: val.description,
  60 + pic: val.pic,
  61 + title: val.title
  62 + };
  63 +
  64 + obj.privilege.push(enp);
  65 +
  66 + });
  67 +
  68 + switch (result[0].data.current_vip_level) {
  69 + case '0': // 普通会员
  70 + obj = _.assign(obj, {
  71 + vip0: true
  72 + });
  73 + break;
  74 + case '1': // 银卡会员
  75 + obj = _.assign(obj, {
  76 + vip1: true
  77 + });
  78 + break;
  79 + case '2': // 金卡会员
  80 + obj = _.assign(obj, {
  81 + vip2: true
  82 + });
  83 + break;
  84 + case '3': // 白金会员
  85 + obj = _.assign(obj, {
  86 + vip3: true
  87 + });
  88 + break;
  89 + default:
  90 +
  91 + }
  92 +
  93 + let upg = (1 * (result[0].data.upgrade_need_cost)).toFixed(2);
  94 +
  95 + obj = _.assign(obj, {
  96 + costOfThisYear: result[0].data.current_year_cost,
  97 + sumCost: result[0].data.current_total_cost,
  98 + allUrl: helpers.urlFormat('/home/privilege'),
  99 + costGap: upg
  100 + });
  101 +
  102 + if (result[0].data.next_need_cost === 0 || result[0].data.next_need_cost === '') {
  103 + // 当vip等级升至顶级时,进度条满格
  104 + obj = _.assign(obj, {
  105 + percent: 100
  106 + });
  107 + } else {
  108 +
  109 + let perf = (100 * (result[0].data.current_year_cost /
  110 + result[0].data.next_need_cost)).toFixed(2);
  111 +
  112 + obj = _.assign(obj, {
  113 + percent: perf
  114 + });
  115 +
  116 + }
  117 +
  118 + }
  119 +
  120 + if (result[0] && result[0].data) {
  121 + obj = _.assign(obj, {
  122 + name: result[1].data.nickname
  123 + });
  124 + }
  125 +
  126 + resu.vipGrade.push(obj);
  127 +
  128 + return resu;
  129 + });
  130 + } else {
  131 + return Promise.resolve({});
  132 + }
  133 + }
  134 +};
@@ -28,6 +28,7 @@ const help = require(`${cRoot}/help`); @@ -28,6 +28,7 @@ const help = require(`${cRoot}/help`);
28 const suggest = require(`${cRoot}/suggest`); 28 const suggest = require(`${cRoot}/suggest`);
29 const message = require(`${cRoot}/message`); 29 const message = require(`${cRoot}/message`);
30 const onlineService = require(`${cRoot}/onlineService`); 30 const onlineService = require(`${cRoot}/onlineService`);
  31 +const gradeNew = require(`${cRoot}/grade-new`);
31 32
32 // const myDetail = require(`${cRoot}/myDetail); 33 // const myDetail = require(`${cRoot}/myDetail);
33 34
@@ -142,4 +143,6 @@ router.get('/getaddress.json', addressController.newGetAddress); // TODO 模拟 @@ -142,4 +143,6 @@ router.get('/getaddress.json', addressController.newGetAddress); // TODO 模拟
142 143
143 router.get('/logistic', auth, orderDetailController.logistic); // 查看物流页面 144 router.get('/logistic', auth, orderDetailController.logistic); // 查看物流页面
144 145
  146 +router.get('/gradeNew/index', auth, gradeNew.index); // 会员等级
  147 +
145 module.exports = router; 148 module.exports = router;
  1 +<div class="grade-new-c">
  2 + <div class="tab">
  3 + <span class="active">我的等级</span>
  4 + <span>我的权益</span>
  5 + </div>
  6 + <a class="big-top">
  7 + 成长值进度
  8 + <span class="iconfont">&#xe604;</span>
  9 + <span class="s-title">成长值记录</span>
  10 + </a>
  11 + <div class="user-info clearfix">
  12 + <div class="base clearfix">
  13 + {{# vipGrade}}
  14 + <div class="pic" style="background-image:url('http://172.16.6.52:5001/img/home/index/user-avatar.png')">
  15 + <div class="level-pic" style="background-image:url('http://172.16.6.52:5001/img/home/index/user-avatar.png')"></div>
  16 + </div>
  17 + <div class="intro">
  18 + <div class="name">{{name}},您好!</div>
  19 + <div class="level">
  20 + <span class="now">我的成长值:<span class="val">2250</span> </span>
  21 + <span class="next">下次升级还需:<span class="val">2750</span></span>
  22 + </div>
  23 + </div>
  24 + {{/ vipGrade}}
  25 + </div>
  26 + <div class="level-process clearfix">
  27 + <div class="line-c">
  28 + <div class="line"></div>
  29 + <div class="point">
  30 + <div class="point-item">
  31 + <div class="level-text">
  32 + <p>普通会员</p>
  33 + <p>0</p>
  34 + </div>
  35 + </div>
  36 + <div class="point-item">
  37 + <div class="level-text">
  38 + <p>银卡会员</p>
  39 + <p>800</p>
  40 + </div>
  41 + </div>
  42 + <div class="point-item">
  43 + <div class="level-text">
  44 + <p>金卡会员</p>
  45 + <p>3000</p>
  46 + </div>
  47 + </div>
  48 + <div class="point-item">
  49 + <div class="level-text">
  50 + <p>白金会员</p>
  51 + <p>7000</p>
  52 + </div>
  53 + </div>
  54 + </div>
  55 + </div>
  56 + </div>
  57 + </div>
  58 + <a class="big-top">
  59 + 会员等级介绍
  60 + <span class="iconfont">&#xe604;</span>
  61 + <span class="s-title">了解等级规则</span>
  62 + </a>
  63 + <div class="content">
  64 + <p>1.注册成功即为普通会员,各会员等级均按照历史累计有效的成长值升降级,会员等级越高可享受会员权益越多。</p>
  65 + <p>2.成长值为有货会员通过购物、评价、登录等获得经验累积值。</p>
  66 + <p>3.会员升级后,会员等级有效期一年。每365天进行累计成长值扣减,扣减后的成长值不满足当前级别条件的,直接降级至对应成长值级别。</p>
  67 + <p>自成为银卡之日开始,365天内未继续晋级更高级别,则在366天扣减当前级别所需成长值,扣减值为400</p>
  68 + <p>自成为金卡之日开始,365天内未继续晋级更高级别,则在366天扣减当前级别所需成长值,扣减值为1500</p>
  69 + <p>自成为白金卡之日开始,365天内未继续晋级更高级别,则在366天扣减当前级别所需成长值,扣减值为3500</p>
  70 + </div>
  71 + <div class="big-top">
  72 + 成长值获取方法
  73 + </div>
  74 + <div class="table-c">
  75 + <table>
  76 + <tr>
  77 + <th>场景</th>
  78 + <th>获取规则</th>
  79 + <th>成长数值</th>
  80 + </tr>
  81 + <tr>
  82 + <td>购物</td>
  83 + <td>
  84 + 按商品实际付款金额1元累计1个
  85 + <br />
  86 + 成长值订单完成后奖励</td>
  87 + <td>
  88 + 等于实际
  89 + <br />
  90 + 付款金额
  91 + </td>
  92 + </tr>
  93 + <tr>
  94 + <td>
  95 + 月度购买
  96 + <br />
  97 + 次数
  98 + </td>
  99 + <td>
  100 + 自然月内达到1个购物天数
  101 + <br />
  102 + 且订单已完成
  103 + </td>
  104 + <td>20</td>
  105 + </tr>
  106 + <tr>
  107 + <td>完善资料</td>
  108 + <td>完善个人资料</td>
  109 + <td>50</td>
  110 + </tr>
  111 + <tr>
  112 + <td>
  113 + 手机邮箱
  114 + <br />
  115 + 验证
  116 + </td>
  117 + <td>完成手机邮箱双验证</td>
  118 + <td>20</td>
  119 + </tr>
  120 + <tr>
  121 + <td>VIP登录</td>
  122 + <td>VIP每日登录2个成长值</td>
  123 + <td>2</td>
  124 + </tr>
  125 + <tr>
  126 + <td>评价</td>
  127 + <td>
  128 + 评价成功且审核通过10个成长值
  129 + <br />
  130 + 一个商品仅限一次
  131 + </td>
  132 + <td>10</td>
  133 + </tr>
  134 + </table>
  135 + <p>扣除成长值的情况:</p>
  136 + <p>发生退货或删除评价,扣除当时获得的成长值。</p>
  137 + </div>
  138 +</div>
1 -{  
2 - "name": "m-yohobuy-node",  
3 - "version": "5.6.4",  
4 - "private": true,  
5 - "description": "A New Yohobuy Project With Express",  
6 - "repository": {  
7 - "type": "git",  
8 - "url": "http://git.dev.yoho.cn/web/yohobuywap-node.git"  
9 - },  
10 - "scripts": {  
11 - "start": "NODE_ENV=\"production\" node app.js",  
12 - "dev": "nodemon -e js,hbs -i public/ app.js",  
13 - "static": "webpack-dev-server --config ./public/build/webpack.dev.config.js",  
14 - "build": "webpack --config ./public/build/webpack.prod.config.js",  
15 - "debug": "DEBUG=\"express:*\" nodemon -e js,hbs -i public/ app.js",  
16 - "lint-js": "eslint -c .eslintrc --cache .",  
17 - "lint-css": "stylelint --syntax scss --cache --config .stylelintrc 'public/scss/**/*.css'",  
18 - "lint-vue-js": "eslint -c .eslintrc --cache public/vue",  
19 - "lint-vue-css": "stylelint --syntax scss --extract --cache --config .stylelintrc 'public/scss/**/*.vue'",  
20 - "lint-all": "node lint-all.js",  
21 - "precommit": "node lint-commit.js"  
22 - },  
23 - "license": "MIT",  
24 - "dependencies": {  
25 - "bluebird": "^3.4.7",  
26 - "body-parser": "^1.16.1",  
27 - "captchapng": "0.0.1",  
28 - "cheerio": "^0.22.0",  
29 - "client-sessions": "^0.7.0",  
30 - "compression": "^1.6.2",  
31 - "connect-memcached": "^0.2.0",  
32 - "connect-multiparty": "^2.0.0",  
33 - "cookie-parser": "^1.4.3",  
34 - "express": "^4.14.1",  
35 - "feed": "^1.0.2",  
36 - "geetest": "^4.1.1",  
37 - "lodash": "^4.17.4",  
38 - "memory-cache": "^0.1.6",  
39 - "moment": "^2.18.1",  
40 - "oneapm": "^1.2.20",  
41 - "passport": "^0.3.2",  
42 - "passport-local": "^1.0.0",  
43 - "passport-qq": "0.0.3",  
44 - "passport-sina": "^0.1.0",  
45 - "passport-strategy": "^1.0.0",  
46 - "passport-weixin": "^0.1.0",  
47 - "request": "^2.81.0",  
48 - "request-promise": "^3.0.0",  
49 - "uuid": "^3.0.1",  
50 - "xml2js": "^0.4.17",  
51 - "yoho-express-session": "^2.0.0",  
52 - "yoho-md5": "^2.0.0",  
53 - "yoho-node-lib": "=0.2.22",  
54 - "yoho-zookeeper": "^1.0.8"  
55 - },  
56 - "devDependencies": {  
57 - "autoprefixer": "^6.7.4",  
58 - "babel-core": "^6.24.1",  
59 - "babel-loader": "^6.4.1",  
60 - "babel-polyfill": "^6.23.0",  
61 - "babel-preset-env": "^1.3.3",  
62 - "css-loader": "^0.28.0",  
63 - "cssnano": "^3.10.0",  
64 - "eslint": "^3.19.0",  
65 - "eslint-config-yoho": "^1.0.1",  
66 - "eslint-loader": "^1.7.1",  
67 - "eslint-plugin-html": "^2.0.1",  
68 - "extract-text-webpack-plugin": "^2.1.0",  
69 - "handlebars-loader": "^1.4.0",  
70 - "happypack": "^3.0.3",  
71 - "husky": "^0.13.3",  
72 - "nodemon": "^1.11.0",  
73 - "postcss-assets": "^4.0.1",  
74 - "postcss-calc": "^5.3.1",  
75 - "postcss-center": "^1.0.0",  
76 - "postcss-clearfix": "^1.0.0",  
77 - "postcss-crip": "^2.0.1",  
78 - "postcss-import": "^9.1.0",  
79 - "postcss-loader": "^1.3.1",  
80 - "postcss-position": "^0.5.0",  
81 - "postcss-pxtorem": "^4.0.0",  
82 - "postcss-scss": "^0.4.1",  
83 - "postcss-short": "^3.0.3",  
84 - "postcss-sprites": "^4.2.0",  
85 - "postcss-use": "^2.3.0",  
86 - "precss": "^1.4.0",  
87 - "shelljs": "^0.7.6",  
88 - "style-loader": "^0.16.1",  
89 - "stylelint": "^7.10.1",  
90 - "stylelint-config-yoho": "^1.2.8",  
91 - "stylelint-formatter-table": "^1.0.2",  
92 - "stylelint-processor-html": "^1.0.0",  
93 - "stylelint-webpack-plugin": "^0.7.0",  
94 - "vue": "^2.2.6",  
95 - "vue-loader": "^11.3.4",  
96 - "vue-template-compiler": "^2.2.6",  
97 - "webpack": "^2.3.3",  
98 - "webpack-dev-server": "^2.4.2",  
99 - "webpack-uglify-parallel": "^0.1.3",  
100 - "yoho-cookie": "^1.2.0",  
101 - "yoho-fastclick": "^1.0.6",  
102 - "yoho-hammer": "^2.0.7",  
103 - "yoho-iscroll": "^5.2.0",  
104 - "yoho-jquery": "^2.2.4",  
105 - "yoho-jquery-lazyload": "^1.9.10",  
106 - "yoho-jquery-qrcode": "^0.14.0",  
107 - "yoho-mlellipsis": "0.0.3",  
108 - "yoho-qs": "^1.0.1",  
109 - "yoho-swiper": "^3.3.1",  
110 - "yoho-swiper2": "0.0.5"  
111 - }  
112 -}  
  1 +'use strict';
  2 +
  3 +import {
  4 + Controller
  5 +} from 'yoho-mvc';
  6 +
  7 +import {
  8 + TabView
  9 +} from './view';
  10 +
  11 +class GradeController extends Controller {
  12 + constructor() {
  13 + super();
  14 + this.tabView = new TabView();
  15 + }
  16 +}
  17 +
  18 +
  19 +module.exports = GradeController;
  1 +require('home/grade-new.page.css');
  2 +
  3 +const GradeController = require('./controller');
  4 +
  5 +new GradeController();
  6 +
  1 +import {
  2 + View
  3 +} from 'yoho-mvc';
  4 +
  5 +class TabView extends View {
  6 + constructor() {
  7 + super('.tab');
  8 + this.on('touchend touchcancel', 'span', this.tabClick.bind(this));
  9 + }
  10 +
  11 + tabClick(e) {
  12 + let $this = $(e.currentTarget);
  13 +
  14 + if (!$this.hasClass('active')) {
  15 + $this.addClass('active').siblings('span').removeClass('active');
  16 + }
  17 + }
  18 +}
  19 +
  20 +export {
  21 + TabView
  22 +};
  1 +.grade-new-c {
  2 + background-color: #f0f0f0;
  3 +
  4 + .tab {
  5 + height: 80px;
  6 + line-height: 80px;
  7 + padding: 18px 0;
  8 + background-color: #fff;
  9 +
  10 + span {
  11 + line-height: 44px;
  12 + display: inline-block;
  13 + width: 375px;
  14 + text-align: center;
  15 + float: left;
  16 + font-size: 28px;
  17 + color: #b0b0b0;
  18 +
  19 + &:first-child {
  20 + border-right: solid 1px #e5e5e5;
  21 + }
  22 + }
  23 +
  24 + span.active {
  25 + color: #444;
  26 + }
  27 + }
  28 +
  29 + .big-top {
  30 + display: block;
  31 + font-size: 28px;
  32 + color: #444;
  33 + line-height: 88px;
  34 + margin-top: 20px;
  35 + background-color: #fff;
  36 + padding: 0 30px;
  37 +
  38 + .s-title {
  39 + float: right;
  40 + padding-right: 10px;
  41 + }
  42 +
  43 + .iconfont {
  44 + float: right;
  45 + }
  46 + }
  47 +
  48 + .user-info {
  49 + padding: 30px 30px 115px;
  50 + background-color: #fff;
  51 + border-top: solid 1px #e5e5e5;
  52 +
  53 + .base {
  54 + .pic {
  55 + width: 125px;
  56 + height: 125px;
  57 + float: left;
  58 + background-size: contain;
  59 + background-position: center;
  60 + border-radius: 50%;
  61 + border: 1px solid #eee;
  62 + position: relative;
  63 +
  64 + .level-pic {
  65 + width: 82px;
  66 + height: 36px;
  67 + background-size: 100% 100%;
  68 + position: absolute;
  69 + bottom: -18px;
  70 + left: 50%;
  71 + margin-left: -41px;
  72 + }
  73 + }
  74 +
  75 + .intro {
  76 + padding: 15px 0 15px 20px;
  77 + float: left;
  78 + width: 560px;
  79 + }
  80 +
  81 + .name {
  82 + color: #444;
  83 + font-size: 32px;
  84 + line-height: 60px;
  85 + }
  86 +
  87 + .level {
  88 + font-size: 24px;
  89 + line-height: 40px;
  90 + }
  91 +
  92 + .val {
  93 + font-size: 32px;
  94 + }
  95 +
  96 + .now {
  97 + float: left;
  98 + }
  99 +
  100 + .next {
  101 + float: right;
  102 + }
  103 + }
  104 +
  105 + .level-process {
  106 + .line-c {
  107 + width: 600px;
  108 + height: 4px;
  109 + background-color: #f0f0f0;
  110 + margin: 50px auto 0;
  111 + position: relative;
  112 + }
  113 +
  114 + .line {
  115 + width: 80%;
  116 + height: 100%;
  117 + max-width: 100%;
  118 + background-color: #444;
  119 + }
  120 +
  121 + .point {
  122 + width: 619px;
  123 + position: absolute;
  124 + left: -10px;
  125 + top: -9px;
  126 + }
  127 +
  128 + .point-item {
  129 + width: 22px;
  130 + height: 22px;
  131 + background-image: url("/home/point.png");
  132 + background-size: auto 100%;
  133 + background-repeat: no-repeat;
  134 + float: left;
  135 + margin-right: 177px;
  136 + position: relative;
  137 + }
  138 +
  139 + .point-item:last-child {
  140 + margin-right: 0;
  141 + }
  142 +
  143 + .level-text {
  144 + width: 120px;
  145 + position: absolute;
  146 + top: 29px;
  147 + left: 50%;
  148 + margin-left: -60px;
  149 + font-size: 24px;
  150 + text-align: center;
  151 + line-height: 40px;
  152 + }
  153 + }
  154 + }
  155 +
  156 + .content {
  157 + background-color: #fff;
  158 + padding: 30px;
  159 + border-top: solid 1px #e5e5e5;
  160 +
  161 + p {
  162 + line-height: 40px;
  163 + margin-top: 5px;
  164 + }
  165 + }
  166 +
  167 + .table-c {
  168 + width: 100%;
  169 + background-color: #fff;
  170 +
  171 + table {
  172 + width: 100%;
  173 + }
  174 +
  175 + th {
  176 + border: solid 1px #e5e5e5;
  177 + font-size: 24px;
  178 + text-align: center;
  179 + font-weight: bold;
  180 + padding: 15px;
  181 + line-height: 40px;
  182 + }
  183 +
  184 + td {
  185 + border: solid 1px #e5e5e5;
  186 + font-size: 24px;
  187 + text-align: center;
  188 + padding: 15px;
  189 + line-height: 40px;
  190 + }
  191 +
  192 + p {
  193 + font-size: 24px;
  194 + padding: 0 30px;
  195 + margin-top: 20px;
  196 + }
  197 + }
  198 +}