Authored by shuaiguo

Merge branch 'release/yohood-lottrey' into 'master'

Release/yohood lottrey

YOHOOD球鞋抽奖

See merge request !104
@@ -152,3 +152,4 @@ nbproject/* @@ -152,3 +152,4 @@ nbproject/*
152 dist 152 dist
153 test.js 153 test.js
154 public/docs/*.txt 154 public/docs/*.txt
  155 +Data
@@ -410,11 +410,12 @@ module.exports = class extends global.yoho.BaseModel { @@ -410,11 +410,12 @@ module.exports = class extends global.yoho.BaseModel {
410 isShareTake: false, 410 isShareTake: false,
411 actName: productInfo.name, 411 actName: productInfo.name,
412 actStartTime: productInfo.start_time, 412 actStartTime: productInfo.start_time,
413 - actEndTime: productInfo.end_time 413 + actEndTime: productInfo.end_time,
  414 + channel: productInfo.channel
414 })).then(response => { 415 })).then(response => {
415 if (+response.code === 200) { 416 if (+response.code === 200) {
416 if (shareUid) { 417 if (shareUid) {
417 - this.sendPrizeCode(shareUid, actPrizeId, {isShareTake: true}); 418 + this.sendPrizeCode(shareUid, actPrizeId, {isShareTake: true, channel: productInfo.channel });
418 } 419 }
419 420
420 // 参与人数满时更新活动状态 421 // 参与人数满时更新活动状态
@@ -575,8 +576,13 @@ module.exports = class extends global.yoho.BaseModel { @@ -575,8 +576,13 @@ module.exports = class extends global.yoho.BaseModel {
575 * @param actPrizeId 576 * @param actPrizeId
576 * @param extra 577 * @param extra
577 * @returns {*} 578 * @returns {*}
  579 + * CHANNELTYPE: {'yoluck渠道': 0, 'UFO渠道': 1,'YOHOOD渠道': 2}
578 */ 580 */
579 sendWechatMessage(uid, actPrizeId, extra = {}) { 581 sendWechatMessage(uid, actPrizeId, extra = {}) {
  582 + if (extra.channel === 2) {
  583 + this.sendYohoodWechatMessage(uid, actPrizeId, extra);
  584 + return;
  585 + }
580 let info = {}; 586 let info = {};
581 let baseUri = 'pages/zeroSell/detail'; 587 let baseUri = 'pages/zeroSell/detail';
582 588
@@ -601,4 +607,44 @@ module.exports = class extends global.yoho.BaseModel { @@ -601,4 +607,44 @@ module.exports = class extends global.yoho.BaseModel {
601 logger.error(e); 607 logger.error(e);
602 }); 608 });
603 } 609 }
  610 +
  611 + /**
  612 + * 向用户发送获得抽奖码消息
  613 + * @param uid
  614 + * @param actPrizeId
  615 + * @param extra
  616 + * @returns {*}
  617 + * CHANNELTYPE: {'yoluck渠道': 0, 'UFO渠道': 1,'YOHOOD渠道': 2}
  618 + */
  619 + sendYohoodWechatMessage(uid, actPrizeId, extra = {}) {
  620 + const { actStartTime, actEndTime, miniAppType, actName } = extra;
  621 + const activityTime = `${moment.unix(actStartTime).format('YYYY.MM.DD HH:mm:ss')} - ${moment.unix(actEndTime).format('YYYY.MM.DD HH:mm:ss')}`;
  622 +
  623 + logger.info(`sendYohoodWechatMessage extra: ${JSON.stringify(extra)}`);
  624 +
  625 + const data = {
  626 + method: 'wechat.message.send',
  627 + sendScene: 'MINI_ACTIVITY_JOIN',
  628 + miniAppType: +miniAppType === 63 ? +miniAppType : 29,
  629 + params: JSON.stringify({
  630 + activityTitle: actName || '',
  631 + activityTime,
  632 + pageUrl: `pages/zeroSell/originalPriceSell?actPrizeId=${actPrizeId}`
  633 + }),
  634 + uidList: [uid]
  635 + };
  636 +
  637 + logger.info(`sendYohoodWechatMessage param: ${JSON.stringify(data)}`);
  638 +
  639 + return this.get({
  640 + data
  641 + }).then(result => {
  642 + if (result.code !== 200) {
  643 + logger.info(`zerobuy_join_notice send fail uid: ${uid}`);
  644 + }
  645 + })
  646 + .catch(e => {
  647 + logger.error(e);
  648 + });
  649 + }
604 }; 650 };
@@ -13,6 +13,8 @@ const DO_SUCCESS = '操作成功'; @@ -13,6 +13,8 @@ const DO_SUCCESS = '操作成功';
13 const DO_FAILED = '操作失败!'; 13 const DO_FAILED = '操作失败!';
14 const GET_SUCCESS = '获取成功'; 14 const GET_SUCCESS = '获取成功';
15 const INVALID_PARAMS = '参数错误'; 15 const INVALID_PARAMS = '参数错误';
  16 +const INVALID_PRICE_CODE = '开奖码不存在';
  17 +const logger = global.yoho.logger;
16 18
17 const timeFormat = (time) => { 19 const timeFormat = (time) => {
18 if (_.isNumber(time)) { 20 if (_.isNumber(time)) {
@@ -22,6 +24,7 @@ const timeFormat = (time) => { @@ -22,6 +24,7 @@ const timeFormat = (time) => {
22 return moment(time).format('YYYY-MM-DD HH:mm:ss'); 24 return moment(time).format('YYYY-MM-DD HH:mm:ss');
23 }; 25 };
24 26
  27 +// CHANNELTYPE: {'yoluck渠道': 0, 'UFO渠道': 1,'YOHOOD渠道': 2}
25 const zeroBuy = { 28 const zeroBuy = {
26 zeroBuyList(req, res, next) { 29 zeroBuyList(req, res, next) {
27 let params = req.query; 30 let params = req.query;
@@ -32,6 +35,14 @@ const zeroBuy = { @@ -32,6 +35,14 @@ const zeroBuy = {
32 {name: '开启', status: 1}, 35 {name: '开启', status: 1},
33 {name: '已开奖', status: 2}, 36 {name: '已开奖', status: 2},
34 ]; 37 ];
  38 +
  39 + // 渠道
  40 + const channelList = [
  41 + {name: '全部', value: ''},
  42 + {name: 'yoluck渠道', value: 0},
  43 + {name: 'UFO渠道', value: 1},
  44 + {name: 'YOHOOD渠道', value: 2},
  45 + ];
35 46
36 req.ctx(ActivityModel).getZerobuyList(req.query).then(result => { 47 req.ctx(ActivityModel).getZerobuyList(req.query).then(result => {
37 _.forEach(statusList, value => { 48 _.forEach(statusList, value => {
@@ -40,17 +51,23 @@ const zeroBuy = { @@ -40,17 +51,23 @@ const zeroBuy = {
40 } 51 }
41 }); 52 });
42 53
43 - if (!_.find(statusList, 'active')) {  
44 - statusList[0].active = true;  
45 - } 54 + _.forEach(channelList, channel => {
  55 + if (params.channel === `${channel.value}`) {
  56 + channel.active = true;
  57 + }
  58 + });
46 59
47 res.render('activity/zero-buy-list', Object.assign(result, { 60 res.render('activity/zero-buy-list', Object.assign(result, {
48 bodyClass: 'nav-md', 61 bodyClass: 'nav-md',
49 module: 'admin', 62 module: 'admin',
50 page: 'zero-buy', 63 page: 'zero-buy',
51 qsQuery: params.query, 64 qsQuery: params.query,
52 - qsStatus: params.status,  
53 - statusList 65 + qsStatus: _.isUndefined(params.status) ? -1 : params.status,
  66 + qsChannel: _.isUndefined(params.channel) ? -1 : params.channel,
  67 + isSelectChannel: !_.isUndefined(params.channel),
  68 + isSelectStatus: !_.isUndefined(params.status),
  69 + statusList,
  70 + channelList
54 })); 71 }));
55 }).catch(next); 72 }).catch(next);
56 }, 73 },
@@ -59,6 +76,7 @@ const zeroBuy = { @@ -59,6 +76,7 @@ const zeroBuy = {
59 .then(res.json).catch(next); 76 .then(res.json).catch(next);
60 }, 77 },
61 zeroBuyPublish(req, res, next) { 78 zeroBuyPublish(req, res, next) {
  79 +
62 let ctx = req.ctx(ActivityModel); 80 let ctx = req.ctx(ActivityModel);
63 let id = req.body.id; 81 let id = req.body.id;
64 let channel = req.body.channel; 82 let channel = req.body.channel;
@@ -112,6 +130,31 @@ const zeroBuy = { @@ -112,6 +130,31 @@ const zeroBuy = {
112 zeroBuyUserJoinNum(req, res, next) { 130 zeroBuyUserJoinNum(req, res, next) {
113 req.ctx(ActivityModel).getUserJoinNum(req.body.id) 131 req.ctx(ActivityModel).getUserJoinNum(req.body.id)
114 .then(res.json).catch(next); 132 .then(res.json).catch(next);
  133 + },
  134 + fetchYOHOODActivityTimes(req, res, next) {
  135 + req.ctx(ActivityModel).fetchYOHOODActivityTimes()
  136 + .then(res.json).catch(next);
  137 + },
  138 + yohoodPublish(req, res, next) {
  139 + const {id, channel, code} = req.body;
  140 +
  141 + req.ctx(ActivityModel).fetchPriceCodeInfo(code, id).then((result)=> {
  142 + if (_.isEmpty(result)) {
  143 + return res.json({
  144 + code: 400,
  145 + message: INVALID_PRICE_CODE
  146 + });
  147 + } else {
  148 + req.ctx(ActivityModel).setZeroBuyPublish(id).then(result => {
  149 + if (result.code === 200) {
  150 + req.ctx(ActivityModel).sendWechatMessage(id, channel, code);
  151 + }
  152 + return res.json(result);
  153 + }).catch(function(e) {
  154 + throw e;
  155 + });
  156 + }
  157 + }).catch(next);
115 } 158 }
116 }; 159 };
117 160
@@ -394,8 +394,9 @@ class AdminModel extends global.yoho.BaseModel { @@ -394,8 +394,9 @@ class AdminModel extends global.yoho.BaseModel {
394 * 获取0元购活动列表 394 * 获取0元购活动列表
395 * @param params 395 * @param params
396 * @returns {*} 396 * @returns {*}
  397 + * CHANNELTYPE: {'yoluck渠道': 0, 'UFO渠道': 1,'YOHOOD渠道': 2}
397 */ 398 */
398 - getZerobuyList(params) { 399 + getZerobuyList(params) {
399 const actId = 0; 400 const actId = 0;
400 const pageSize = 10; 401 const pageSize = 10;
401 const page = parseInt(params.page, 10) || 1; 402 const page = parseInt(params.page, 10) || 1;
@@ -410,6 +411,11 @@ class AdminModel extends global.yoho.BaseModel { @@ -410,6 +411,11 @@ class AdminModel extends global.yoho.BaseModel {
410 where.push('status = :status'); 411 where.push('status = :status');
411 } 412 }
412 413
  414 + // 增加筛选条件 渠道
  415 + if (!_.isNaN(parseInt(params.channel, 10))) {
  416 + where.push('channel = :channel');
  417 + }
  418 +
413 return Promise.all([ 419 return Promise.all([
414 mysqlCli.query(`select * from ${TABLE_ACT_PRIZE_PRODUCT} 420 mysqlCli.query(`select * from ${TABLE_ACT_PRIZE_PRODUCT}
415 where ${where.join(' and ')} order by id desc 421 where ${where.join(' and ')} order by id desc
@@ -418,13 +424,15 @@ class AdminModel extends global.yoho.BaseModel { @@ -418,13 +424,15 @@ class AdminModel extends global.yoho.BaseModel {
418 start: (page - 1) * pageSize, 424 start: (page - 1) * pageSize,
419 end: page * pageSize, 425 end: page * pageSize,
420 query: `%${params.query}%`, 426 query: `%${params.query}%`,
421 - status: params.status 427 + status: params.status,
  428 + channel: params.channel
422 }), 429 }),
423 mysqlCli.query(`select count(*) as total from ${TABLE_ACT_PRIZE_PRODUCT} 430 mysqlCli.query(`select count(*) as total from ${TABLE_ACT_PRIZE_PRODUCT}
424 where ${where.join(' and ')}`, { 431 where ${where.join(' and ')}`, {
425 actId, 432 actId,
426 query: `%${params.query}%`, 433 query: `%${params.query}%`,
427 - status: params.status 434 + status: params.status,
  435 + channel: params.channel
428 }), 436 }),
429 ]).then(result => { 437 ]).then(result => {
430 let resData = {}; 438 let resData = {};
@@ -589,9 +597,14 @@ class AdminModel extends global.yoho.BaseModel { @@ -589,9 +597,14 @@ class AdminModel extends global.yoho.BaseModel {
589 }); 597 });
590 } 598 }
591 599
  600 + // CHANNELTYPE: {'yoluck渠道': 0, 'UFO渠道': 1,'YOHOOD渠道': 2}
592 getZerobuyContent(id) { 601 getZerobuyContent(id) {
  602 + let resData = {
  603 + isYohood: false // 是否为YOHOOD渠道
  604 + };
  605 +
593 if (!id) { 606 if (!id) {
594 - return Promise.resolve({}); 607 + return Promise.resolve(resData);
595 } 608 }
596 609
597 return Promise.all([ 610 return Promise.all([
@@ -600,7 +613,6 @@ class AdminModel extends global.yoho.BaseModel { @@ -600,7 +613,6 @@ class AdminModel extends global.yoho.BaseModel {
600 mysqlCli.query(`select * from ${TABLE_ACT_PRIZE_PRODUCT_CONTENT} 613 mysqlCli.query(`select * from ${TABLE_ACT_PRIZE_PRODUCT_CONTENT}
601 where act_prize_id = :id;`, {id}) 614 where act_prize_id = :id;`, {id})
602 ]).then(result => { 615 ]).then(result => {
603 - let resData = {};  
604 let [product, content] = result; 616 let [product, content] = result;
605 617
606 if (product && product.length) { 618 if (product && product.length) {
@@ -608,10 +620,11 @@ class AdminModel extends global.yoho.BaseModel { @@ -608,10 +620,11 @@ class AdminModel extends global.yoho.BaseModel {
608 resData.content = _.sortBy(content || [], o => { 620 resData.content = _.sortBy(content || [], o => {
609 return o.sort; 621 return o.sort;
610 }); 622 });
  623 + resData.isYohood = +resData.channel === 2;
611 624
612 resData.time = `${timeFormat(resData.start_time)} - ${timeFormat(resData.end_time)}`; 625 resData.time = `${timeFormat(resData.start_time)} - ${timeFormat(resData.end_time)}`;
613 } 626 }
614 - 627 +
615 return resData; 628 return resData;
616 }); 629 });
617 } 630 }
@@ -629,14 +642,15 @@ class AdminModel extends global.yoho.BaseModel { @@ -629,14 +642,15 @@ class AdminModel extends global.yoho.BaseModel {
629 limit: params.limit, 642 limit: params.limit,
630 startTime: Date.parse(new Date(_.trim(times[0]).replace(/-/g, '/'))) / 1000, 643 startTime: Date.parse(new Date(_.trim(times[0]).replace(/-/g, '/'))) / 1000,
631 endTime: Date.parse(new Date(_.trim(times[1]).replace(/-/g, '/'))) / 1000, 644 endTime: Date.parse(new Date(_.trim(times[1]).replace(/-/g, '/'))) / 1000,
632 - channel: params.channel || 0 645 + channel: params.channel || 0,
  646 + lotteryPrice: params.lotteryPrice || 0
633 }; 647 };
634 648
635 if (params.id) { 649 if (params.id) {
636 sqls.push(mysqlCli.update(`update ${TABLE_ACT_PRIZE_PRODUCT} set 650 sqls.push(mysqlCli.update(`update ${TABLE_ACT_PRIZE_PRODUCT} set
637 name = :name, price = :price, \`limit\` = :limit, 651 name = :name, price = :price, \`limit\` = :limit,
638 cover_img = :cover, sort = :sort, 652 cover_img = :cover, sort = :sort,
639 - start_time = :startTime, end_time = :endTime, channel = :channel 653 + start_time = :startTime, end_time = :endTime, channel = :channel, lottery_price = :lotteryPrice
640 where id = :id`, proParams)); 654 where id = :id`, proParams));
641 655
642 // 更新楼层 656 // 更新楼层
@@ -687,9 +701,8 @@ class AdminModel extends global.yoho.BaseModel { @@ -687,9 +701,8 @@ class AdminModel extends global.yoho.BaseModel {
687 } 701 }
688 } else { 702 } else {
689 sqls.push(mysqlCli.insert(`insert into ${TABLE_ACT_PRIZE_PRODUCT} ( 703 sqls.push(mysqlCli.insert(`insert into ${TABLE_ACT_PRIZE_PRODUCT} (
690 - name, price, \`limit\`, sort, cover_img, start_time, end_time, channel) values (  
691 - :name, :price, :limit, :sort, :cover, :startTime, :endTime, :channel  
692 - )`, proParams)); 704 + name, price, \`limit\`, sort, cover_img, start_time, end_time, channel, lottery_price) values (
  705 + :name, :price, :limit, :sort, :cover, :startTime, :endTime, :channel, :lotteryPrice)`, proParams));
693 } 706 }
694 707
695 return Promise.all(sqls).then(result => { 708 return Promise.all(sqls).then(result => {
@@ -770,13 +783,21 @@ class AdminModel extends global.yoho.BaseModel { @@ -770,13 +783,21 @@ class AdminModel extends global.yoho.BaseModel {
770 * @param id 783 * @param id
771 * @returns {*} 784 * @returns {*}
772 */ 785 */
773 - async sendWechatMessage(id, channel = 0) {  
774 - let info = await Promise.all([ 786 + async sendWechatMessage(id, channel = 0, code = '') {
  787 + const promises = [
775 mysqlCli.query(`select name from ${TABLE_ACT_PRIZE_PRODUCT} 788 mysqlCli.query(`select name from ${TABLE_ACT_PRIZE_PRODUCT}
776 where id = :id limit 1`, {id}), 789 where id = :id limit 1`, {id}),
777 - mysqlCli.query(`select distinct uid from ${TABLE_ACT_PRIZE_PRODUCT_USER}  
778 - where act_prize_id = :id`, {id})  
779 - ]); 790 + ];
  791 +
  792 + if (code) {
  793 + promises.push(mysqlCli.query(`select distinct uid from ${TABLE_ACT_PRIZE_PRODUCT_USER}
  794 + where act_prize_id = :id and prize_code = :code`, {id, code}));
  795 + } else {
  796 + promises.push(mysqlCli.query(`select distinct uid from ${TABLE_ACT_PRIZE_PRODUCT_USER}
  797 + where act_prize_id = :id`, {id}));
  798 + }
  799 +
  800 + let info = await Promise.all(promises);
780 801
781 let productInfo = _.get(info, '[0][0]'); 802 let productInfo = _.get(info, '[0][0]');
782 let userList = []; 803 let userList = [];
@@ -785,6 +806,7 @@ class AdminModel extends global.yoho.BaseModel { @@ -785,6 +806,7 @@ class AdminModel extends global.yoho.BaseModel {
785 userList.push(value.uid); 806 userList.push(value.uid);
786 }); 807 });
787 808
  809 + // CHANNELTYPE: {'yoluck渠道': 0, 'UFO渠道': 1,'YOHOOD渠道': 2}
788 let msgApi = []; 810 let msgApi = [];
789 let msgData = { 811 let msgData = {
790 method: 'wechat.message.send', 812 method: 'wechat.message.send',
@@ -793,10 +815,25 @@ class AdminModel extends global.yoho.BaseModel { @@ -793,10 +815,25 @@ class AdminModel extends global.yoho.BaseModel {
793 params: JSON.stringify({ 815 params: JSON.stringify({
794 activityTitle: productInfo.name, 816 activityTitle: productInfo.name,
795 activityTime: moment().format('YYYY-MM-DD HH:mm') + ':00', 817 activityTime: moment().format('YYYY-MM-DD HH:mm') + ':00',
796 - pageUrl: 'pages/zeroSell/detail?actPrizeId=' + id 818 + pageUrl: `pages/zeroSell/detail?actPrizeId=${id}`
797 }) 819 })
798 }; 820 };
799 821
  822 + logger.info(`wechat.message.send params:${msgData}`);
  823 +
  824 + if (+channel === 2) {
  825 + msgData = {
  826 + method: 'wechat.message.send',
  827 + sendScene: 'YOHOOD_WINNING_NOTICE',
  828 + miniAppType: 29,
  829 + params: JSON.stringify({
  830 + productName: productInfo.name,
  831 + actPrizeId: id,
  832 + pageUrl: `pages/zeroSell/originalPriceSell?actPrizeId=${id}`
  833 + })
  834 + };
  835 + }
  836 +
800 _.forEach(_.chunk(userList, NOTICE_BATCH_SEND_USER_NUM), value => { 837 _.forEach(_.chunk(userList, NOTICE_BATCH_SEND_USER_NUM), value => {
801 value = _.compact(value); 838 value = _.compact(value);
802 839
@@ -828,6 +865,25 @@ class AdminModel extends global.yoho.BaseModel { @@ -828,6 +865,25 @@ class AdminModel extends global.yoho.BaseModel {
828 865
829 return Promise.all(_.take(apis, NOTICE_BATCH_SEND_API_NUM).map(rp => rp())); 866 return Promise.all(_.take(apis, NOTICE_BATCH_SEND_API_NUM).map(rp => rp()));
830 } 867 }
  868 +
  869 + /**
  870 + * 获取yohood活动时间列表
  871 + */
  872 + fetchYOHOODActivityTimes() {
  873 + const now = new Date().getTime() / 1000;
  874 +
  875 + return mysqlCli.query(
  876 + `select start_time as startTime, end_time as endTime, name, id from ${TABLE_ACT_PRIZE_PRODUCT}
  877 + where channel = 2 and end_time > ${now} and not status = 2`);
  878 + }
  879 +
  880 + /**
  881 + * 查询yohood开奖码信息
  882 + */
  883 + fetchPriceCodeInfo(code, id) {
  884 + return mysqlCli.query(
  885 + `select * from ${TABLE_ACT_PRIZE_PRODUCT_USER} where prize_code = :code and act_prize_id = :id`, {code, id});
  886 + }
831 } 887 }
832 888
833 module.exports = AdminModel; 889 module.exports = AdminModel;
@@ -39,7 +39,9 @@ router.get('/activity/zerobuy/edit', activity.zeroBuyEdit); @@ -39,7 +39,9 @@ router.get('/activity/zerobuy/edit', activity.zeroBuyEdit);
39 router.post('/activity/zerobuy/save', activity.zeroBuySave); 39 router.post('/activity/zerobuy/save', activity.zeroBuySave);
40 router.post('/activity/zerobuy/notice', activity.zeroBuyNoticeEdit); 40 router.post('/activity/zerobuy/notice', activity.zeroBuyNoticeEdit);
41 router.post('/activity/zerobuy/joinnum', activity.zeroBuyUserJoinNum); 41 router.post('/activity/zerobuy/joinnum', activity.zeroBuyUserJoinNum);
42 - 42 +router.get('/activity/yohood/times', activity.fetchYOHOODActivityTimes); // yohood活动时间列表
  43 +router.post('/activity/yohood/publish', activity.yohoodPublish); // yohood活动开奖
  44 +
43 // 用户管理[page] 45 // 用户管理[page]
44 router.get('/user/list', user.userListPage); 46 router.get('/user/list', user.userListPage);
45 router.get('/user/users_list', user.usersListPage); 47 router.get('/user/users_list', user.usersListPage);
@@ -9,19 +9,26 @@ @@ -9,19 +9,26 @@
9 <form id="createForm" class="form-horizontal form-label-left"> 9 <form id="createForm" class="form-horizontal form-label-left">
10 <input class="form-imput" type="hidden" data-type="id" value="{{id}}"> 10 <input class="form-imput" type="hidden" data-type="id" value="{{id}}">
11 <div class="item form-group"> 11 <div class="item form-group">
  12 + <label class="control-label col-md-3 col-sm-3 col-xs-12" for="actChannel">渠道<span
  13 + class="required">*</span>
  14 + </label>
  15 + <div class="col-md-2 col-sm-2 col-xs-12">
  16 + <select {{#if id}}disabled{{/if}} class="form-control col-md-2 form-imput" data-type="channel" name="actChannel"
  17 + form="createForm">
  18 + <option value="0" {{#isEqualOr channel 0}} selected {{/isEqualOr}}>yoluck渠道</option>
  19 + <option value="1" {{#isEqualOr channel 1}} selected {{/isEqualOr}}>UFO渠道</option>
  20 + <option value="2" {{#isEqualOr channel 2}} selected {{/isEqualOr}}>YOHOOD渠道</option>
  21 + </select>
  22 + </div>
  23 + </div>
  24 + <div class="item form-group">
12 <label class="control-label col-md-3 col-sm-3 col-xs-12" for="actName"> 25 <label class="control-label col-md-3 col-sm-3 col-xs-12" for="actName">
13 商品名称<span class="required">*</span> 26 商品名称<span class="required">*</span>
14 </label> 27 </label>
15 <div class="col-md-6 col-sm-6 col-xs-12"> 28 <div class="col-md-6 col-sm-6 col-xs-12">
16 - <input class="form-control col-md-7 col-xs-12 form-imput"  
17 - data-type="name"  
18 - data-toggle="tooltip"  
19 - data-placement="bottom"  
20 - title="商品名称不能为空"  
21 - name="actName"  
22 - type="text"  
23 - maxlength="50"  
24 - value="{{name}}"> 29 + <input class="form-control col-md-7 col-xs-12 form-imput" data-type="name" data-toggle="tooltip"
  30 + data-placement="bottom" title="商品名称不能为空" name="actName" type="text" maxlength="50"
  31 + value="{{name}}">
25 </div> 32 </div>
26 </div> 33 </div>
27 <div class="item form-group"> 34 <div class="item form-group">
@@ -31,7 +38,18 @@ @@ -31,7 +38,18 @@
31 <div class="col-md-6 col-sm-6 col-xs-12"> 38 <div class="col-md-6 col-sm-6 col-xs-12">
32 <img src="{{cover_img}}" class="col-md-6 product-thumb {{#unless cover_img}}hide{{/unless}}"> 39 <img src="{{cover_img}}" class="col-md-6 product-thumb {{#unless cover_img}}hide{{/unless}}">
33 40
34 - <button type="button" class="btn btn-primary btn-upload-thumb" data-cover="{{cover_img}}">上传</button> 41 + <button type="button" class="btn btn-primary btn-upload-thumb"
  42 + data-cover="{{cover_img}}">上传</button>
  43 + </div>
  44 + </div>
  45 + <div class="item form-group lottery-price {{#unless isYohood}}hide{{/unless}}">
  46 + <label class="control-label col-md-3 col-sm-3 col-xs-12" for="actName">
  47 + 抽奖价<span class="required">*</span>
  48 + </label>
  49 + <div class="col-md-6 col-sm-6 col-xs-12">
  50 + <input class="form-control col-md-7 col-xs-12 form-imput" data-type="lotteryPrice"
  51 + data-toggle="tooltip" data-placement="bottom" title="抽奖价不能为空" name="actName" type="text"
  52 + maxlength="10" value="{{lottery_price}}">
35 </div> 53 </div>
36 </div> 54 </div>
37 <div class="item form-group"> 55 <div class="item form-group">
@@ -39,123 +57,92 @@ @@ -39,123 +57,92 @@
39 商品价格<span class="required">*</span> 57 商品价格<span class="required">*</span>
40 </label> 58 </label>
41 <div class="col-md-6 col-sm-6 col-xs-12"> 59 <div class="col-md-6 col-sm-6 col-xs-12">
42 - <input class="form-control col-md-7 col-xs-12 form-imput"  
43 - data-type="price"  
44 - data-toggle="tooltip"  
45 - data-placement="bottom"  
46 - title="商品价格不能为空"  
47 - name="actName"  
48 - type="text"  
49 - maxlength="10"  
50 - value="{{price}}"> 60 + <input class="form-control col-md-7 col-xs-12 form-imput" data-type="price"
  61 + data-toggle="tooltip" data-placement="bottom" title="商品价格不能为空" name="actName" type="text"
  62 + maxlength="10" value="{{price}}">
51 </div> 63 </div>
52 </div> 64 </div>
53 <div class="item form-group"> 65 <div class="item form-group">
54 <label class="control-label col-md-3 col-sm-3 col-xs-12" for="activityTime">活动有效时间<span 66 <label class="control-label col-md-3 col-sm-3 col-xs-12" for="activityTime">活动有效时间<span
55 - class="required">*</span> 67 + class="required">*</span>
56 </label> 68 </label>
57 <div class="col-md-6 col-sm-6 col-xs-12"> 69 <div class="col-md-6 col-sm-6 col-xs-12">
58 <div class="input-prepend input-group"> 70 <div class="input-prepend input-group">
59 <span class="add-on input-group-addon"><i 71 <span class="add-on input-group-addon"><i
60 - class="glyphicon glyphicon-calendar fa fa-calendar"></i></span> 72 + class="glyphicon glyphicon-calendar fa fa-calendar"></i></span>
61 <input type="text" name="activityTime" id="activityTime" 73 <input type="text" name="activityTime" id="activityTime"
62 - class="form-control col-md-7 col-xs-12 form-imput"  
63 - data-type="time"  
64 - placeholder="开始时间 - 结束时间"  
65 - value="{{time}}"/> 74 + class="form-control col-md-7 col-xs-12 form-imput" data-type="time"
  75 + placeholder="开始时间 - 结束时间" value="{{time}}" />
66 </div> 76 </div>
67 </div> 77 </div>
68 </div> 78 </div>
69 <div class="item form-group hide"> 79 <div class="item form-group hide">
70 <label class="control-label col-md-3 col-sm-3 col-xs-12" for="actName">开奖需要人数<span 80 <label class="control-label col-md-3 col-sm-3 col-xs-12" for="actName">开奖需要人数<span
71 - class="required">*</span> 81 + class="required">*</span>
72 </label> 82 </label>
73 <div class="col-md-2 col-sm-2 col-xs-12"> 83 <div class="col-md-2 col-sm-2 col-xs-12">
74 - <input id="actVoteLimit" class="form-control col-md-2 form-imput"  
75 - data-type="limit"  
76 - data-toggle="tooltip" data-placement="bottom" title="开奖需要人数"  
77 - name="actVoteLimit"  
78 - type="text"  
79 - maxlength="10"  
80 - value="9999999"> 84 + <input id="actVoteLimit" class="form-control col-md-2 form-imput" data-type="limit"
  85 + data-toggle="tooltip" data-placement="bottom" title="开奖需要人数" name="actVoteLimit" type="text"
  86 + maxlength="10" value="9999999">
81 </div> 87 </div>
82 </div> 88 </div>
83 - <div class="item form-group">  
84 - <label class="control-label col-md-3 col-sm-3 col-xs-12" for="actName">排序<span  
85 - class="required">*</span> 89 + <div class="item form-group sort {{#isEqualOr channel 2}}hide{{/isEqualOr}}">
  90 + <label class="control-label col-md-3 col-sm-3 col-xs-12" for="sort">排序<span
  91 + class="required">*</span>
86 </label> 92 </label>
87 <div class="col-md-2 col-sm-2 col-xs-12"> 93 <div class="col-md-2 col-sm-2 col-xs-12">
88 - <input id="actVoteLimit" class="form-control col-md-2 form-imput"  
89 - data-type="sort"  
90 - data-toggle="tooltip" data-placement="bottom" title="排序"  
91 - name="actVoteLimit"  
92 - type="text"  
93 - maxlength="10"  
94 - value="{{sort}}"> 94 + <input id="sort" class="form-control col-md-2 form-imput" data-type="sort"
  95 + data-toggle="tooltip" data-placement="bottom" title="排序" name="sort" type="text"
  96 + maxlength="10" value="{{sort}}">
95 </div> 97 </div>
96 </div> 98 </div>
97 - <div class="item form-group">  
98 - <label class="control-label col-md-3 col-sm-3 col-xs-12" for="actChannel">渠道<span  
99 - class="required">*</span>  
100 - </label>  
101 - <div class="col-md-2 col-sm-2 col-xs-12">  
102 - <select class="form-control col-md-2 form-imput" data-type="channel" name="actChannel" form="createForm">  
103 - <option value="0" {{#isEqualOr channel 0}} selected {{/isEqualOr}}>yoluck渠道</option>  
104 - <option value="1"{{#isEqualOr channel 1}} selected {{/isEqualOr}}>UFO渠道</option>  
105 - </select>  
106 - </div>  
107 - </div>  
108 </form> 99 </form>
109 - <div class="x_title">  
110 - <h2>详情内容</h2>  
111 - <div class="clearfix"></div>  
112 - </div>  
113 - <div>  
114 - <div class="col-md-6 col-md-offset-3 floor-view-box">  
115 - {{# content}} 100 + <div class="content-detail {{#isEqualOr channel 2}}hide{{/isEqualOr}}">
  101 + <div class="x_title">
  102 + <h2>详情内容</h2>
  103 + <div class="clearfix"></div>
  104 + </div>
  105 + <div>
  106 + <div class="col-md-6 col-md-offset-3 floor-view-box">
  107 + {{# content}}
116 {{#if floor_type}} 108 {{#if floor_type}}
117 - <div class="floor-item"  
118 - data-id="{{id}}"  
119 - data-sort="{{sort}}"  
120 - data-content="{{content}}"  
121 - {{#isEqualOr floor_type 1}}  
122 - data-type="text"> 109 + <div class="floor-item" data-id="{{id}}" data-sort="{{sort}}" data-content="{{content}}"
  110 + {{#isEqualOr floor_type 1}} data-type="text">
123 111
124 - <p class="item-content">{{content}}</p  
125 - {{/isEqualOr}}  
126 - {{#isEqualOr floor_type 2}} 112 + <p class="item-content">{{content}}</p {{/isEqualOr}} {{#isEqualOr floor_type 2}}
127 data-type="img"> 113 data-type="img">
128 - <img src="{{content}}" class="item-content"  
129 - {{/isEqualOr}}  
130 - {{#isEqualOr floor_type 3}} 114 + <img src="{{content}}" class="item-content" {{/isEqualOr}} {{#isEqualOr floor_type 3}}
131 data-type="video"> 115 data-type="video">
132 - <video src="{{content}}" class="item-content">  
133 - 您的浏览器不支持 video 标签。  
134 - </video> 116 + <video src="{{content}}" class="item-content">
  117 + 您的浏览器不支持 video 标签。
  118 + </video>
135 {{/isEqualOr}} 119 {{/isEqualOr}}
136 > 120 >
137 121
138 - <div class="option-btns">  
139 - <span class="glyphicon glyphicon-arrow-up up-item-btn"></span>  
140 - <span class="glyphicon glyphicon-arrow-down down-item-btn"></span>  
141 - </div>  
142 - <span class="del-item-btn">删除</span> 122 + <div class="option-btns">
  123 + <span class="glyphicon glyphicon-arrow-up up-item-btn"></span>
  124 + <span class="glyphicon glyphicon-arrow-down down-item-btn"></span>
143 </div> 125 </div>
  126 + <span class="del-item-btn">删除</span>
  127 + </div>
144 {{/if}} 128 {{/if}}
145 - {{/ content}}  
146 - </div>  
147 - <div class="col-md-6 col-md-offset-3">  
148 - <button type="button" class="btn btn-primary btn-add-floor" data-type="text">文本</button>  
149 - <button type="button" class="btn btn-primary btn-add-floor" data-type="img">图片</button>  
150 - <button type="button" class="btn btn-primary btn-add-floor" data-type="video">视频</button>  
151 - </div>  
152 - <div class="col-md-2 col-md-offset-10 action-wrap">  
153 - <button type="button" class="btn btn-primary btn-save-activity">保存</button> 129 + {{/ content}}
  130 + </div>
  131 + <div class="col-md-6 col-md-offset-3">
  132 + <button type="button" class="btn btn-primary btn-add-floor" data-type="text">文本</button>
  133 + <button type="button" class="btn btn-primary btn-add-floor" data-type="img">图片</button>
  134 + <button type="button" class="btn btn-primary btn-add-floor" data-type="video">视频</button>
  135 + </div>
154 </div> 136 </div>
155 </div> 137 </div>
  138 +
  139 + <div class="col-md-2 col-md-offset-10 action-wrap">
  140 + <button type="button" class="btn btn-primary btn-save-activity">保存</button>
  141 + </div>
  142 +
156 <a id="upload-btn"></a> 143 <a id="upload-btn"></a>
157 144
158 {{/ content}} 145 {{/ content}}
159 </div> 146 </div>
160 </div> 147 </div>
161 -</div> 148 +</div>
@@ -9,19 +9,61 @@ @@ -9,19 +9,61 @@
9 <div class="search-wrap"> 9 <div class="search-wrap">
10 <input type="text" id="search-key" class="form-control" value="{{qsQuery}}"> 10 <input type="text" id="search-key" class="form-control" value="{{qsQuery}}">
11 <div class="btn-group"> 11 <div class="btn-group">
12 - <button type="button" id="status-switch" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" data-status="{{qsStatus}}"><span class="btn-text">  
13 - {{# statusList}}  
14 - {{#if active}}{{name}}{{/if}}  
15 - {{/ statusList}}  
16 - </span> <span class="caret"></span></button> 12 + <button
  13 + type="button"
  14 + id="status-switch"
  15 + class="btn btn-default dropdown-toggle"
  16 + data-toggle="dropdown"
  17 + aria-haspopup="true"
  18 + aria-expanded="false"
  19 + data-status="{{qsStatus}}">
  20 + <span class="btn-text">
  21 + {{#if isSelectStatus}}
  22 + {{# statusList}}
  23 + {{#if active}}{{name}}{{/if}}
  24 + {{/ statusList}}
  25 + {{else}}请选择活动状态
  26 + {{/if}}
  27 + </span>
  28 + <span class="caret"></span>
  29 + </button>
17 <ul class="dropdown-menu"> 30 <ul class="dropdown-menu">
18 {{# statusList}} 31 {{# statusList}}
19 <li><a href="javascript:;" class="status-switch" data-status="{{status}}">{{name}}</a></li> 32 <li><a href="javascript:;" class="status-switch" data-status="{{status}}">{{name}}</a></li>
20 {{/ statusList}} 33 {{/ statusList}}
21 </ul> 34 </ul>
22 </div> 35 </div>
23 - <button type="button" id="search-btn" class="btn btn-primary">筛选</button>  
24 - <a href="/admin/activity/zerobuy" class="btn btn-primary">全部</a> 36 + <div class="btn-group">
  37 + <button
  38 + type="button"
  39 + id="channel-switch"
  40 + class="btn btn-default dropdown-toggle"
  41 + data-toggle="dropdown"
  42 + aria-haspopup="true"
  43 + aria-expanded="false"
  44 + data-channel="{{qsChannel}}">
  45 +
  46 + <span class="btn-text">
  47 + {{#if isSelectChannel}}
  48 + {{# channelList}}
  49 + {{#if active}}{{name}}{{/if}}
  50 + {{/ channelList}}
  51 + {{else}}请选择活动渠道
  52 + {{/if}}
  53 + </span>
  54 + <span class="caret"></span>
  55 + </button>
  56 + <ul class="dropdown-menu">
  57 + {{# channelList}}
  58 + <li><a href="javascript:;" class="channel-switch" data-channel="{{value}}">{{name}}</a></li>
  59 + {{/ channelList}}
  60 + </ul>
  61 + </div>
  62 + <div class="action-wrapper">
  63 + <button type="button" id="search-btn" class="btn btn-primary">筛选</button>
  64 + <a href="/admin/activity/zerobuy" class="btn btn-primary">全部</a>
  65 + </div>
  66 +
25 </div> 67 </div>
26 </div> 68 </div>
27 69
@@ -52,6 +94,7 @@ @@ -52,6 +94,7 @@
52 <td class="text-center"> 94 <td class="text-center">
53 {{#isEqualOr channel 0}} yoluck渠道 {{/isEqualOr}} 95 {{#isEqualOr channel 0}} yoluck渠道 {{/isEqualOr}}
54 {{#isEqualOr channel 1}} UFO渠道 {{/isEqualOr}} 96 {{#isEqualOr channel 1}} UFO渠道 {{/isEqualOr}}
  97 + {{#isEqualOr channel 2}} YOHOOD渠道 {{/isEqualOr}}
55 </td> 98 </td>
56 <td class="text-center"> 99 <td class="text-center">
57 <image src="{{cover_img}}" class="cover-img"> 100 <image src="{{cover_img}}" class="cover-img">
@@ -296,4 +339,29 @@ @@ -296,4 +339,29 @@
296 </div> 339 </div>
297 </div> 340 </div>
298 341
  342 +<div id='yohood-confirm-model' class="modal fade in" style="display: none;">
  343 + <div class="modal-dialog">
  344 + <div class="modal-content">
  345 + <div class="modal-header">
  346 + <a class="close" data-dismiss="modal">×</a>
  347 + <h3>确认开奖</h3>
  348 + </div>
  349 + <div class="modal-body">
  350 + <form class="form-horizontal">
  351 + <div class="form-group">
  352 + <div class="col-md-9 col-sm-6 col-xs-12">
  353 + <input type="text" class="form-control" name="price-code" placeholder="请输入抽奖码">
  354 + <div class="error-message"></div>
  355 + </div>
  356 + </div>
  357 + </form>
  358 + </div>
  359 + <div class="modal-footer">
  360 + <a class="btn btn-success" data-dismiss="modal">取消</a>
  361 + <a class="btn btn-success sure-yohood-publish-btn">确定</a>
  362 + </div>
  363 + </div>
  364 + </div>
  365 +</div>
  366 +
299 <!-- /page content --> 367 <!-- /page content -->
@@ -4,6 +4,7 @@ require('bootstrap-daterangepicker'); @@ -4,6 +4,7 @@ require('bootstrap-daterangepicker');
4 const _ = require('lodash'); 4 const _ = require('lodash');
5 const $alert = $('#alert-modal'); 5 const $alert = $('#alert-modal');
6 const $confirm = $('#confirm-modal'); 6 const $confirm = $('#confirm-modal');
  7 +const $yohoodConfirm = $('#yohood-confirm-model');
7 8
8 $alert.showMsg = function(msg) { 9 $alert.showMsg = function(msg) {
9 this.find('.modal-text').text(msg); 10 this.find('.modal-text').text(msg);
@@ -13,6 +14,7 @@ $alert.showMsg = function(msg) { @@ -13,6 +14,7 @@ $alert.showMsg = function(msg) {
13 function bindListPageEvent() { 14 function bindListPageEvent() {
14 const $searchKey = $('#search-key'); 15 const $searchKey = $('#search-key');
15 const $statusSwitch = $('#status-switch'); 16 const $statusSwitch = $('#status-switch');
  17 + const $channelSwitch = $('#channel-switch');
16 const $publishForm = $('#publish-form'); 18 const $publishForm = $('#publish-form');
17 const $noticeModal = $('#notice-modal'); 19 const $noticeModal = $('#notice-modal');
18 const $noticeForm = $noticeModal.find('#notice-form'); 20 const $noticeForm = $noticeModal.find('#notice-form');
@@ -20,15 +22,23 @@ function bindListPageEvent() { @@ -20,15 +22,23 @@ function bindListPageEvent() {
20 const searchFn = function() { 22 const searchFn = function() {
21 let val = $searchKey.val(); 23 let val = $searchKey.val();
22 let status = $statusSwitch.data('status'); 24 let status = $statusSwitch.data('status');
  25 + let channel = $channelSwitch.data('channel');
23 26
24 let qs = []; 27 let qs = [];
25 28
26 if (val) { 29 if (val) {
27 qs.push(val ? 'query=' + val : ''); 30 qs.push(val ? 'query=' + val : '');
28 } 31 }
  32 + if (status === '' || _.isNumber(+status)) {
  33 + if (status >= 0) {
  34 + qs.push(`status=${status}`);
  35 + }
  36 + }
29 37
30 - if (!_.isNaN(+status)) {  
31 - qs.push('status=' + status); 38 + if (channel === '' || _.isNumber(+channel)) {
  39 + if (channel >= 0) {
  40 + qs.push(`channel=${channel}`);
  41 + }
32 } 42 }
33 43
34 location.href = `?${qs.join('&')}`; 44 location.href = `?${qs.join('&')}`;
@@ -40,6 +50,13 @@ function bindListPageEvent() { @@ -40,6 +50,13 @@ function bindListPageEvent() {
40 $statusSwitch.data('status', $this.data('status')).children('.btn-text').text($this.text()); 50 $statusSwitch.data('status', $this.data('status')).children('.btn-text').text($this.text());
41 }; 51 };
42 52
  53 + // 渠道
  54 + const channelFn = function() {
  55 + let $this = $(this);
  56 +
  57 + $channelSwitch.data('channel', $this.data('channel')).children('.btn-text').text($this.text());
  58 + };
  59 +
43 const editFn = function() { 60 const editFn = function() {
44 window.open('/admin/activity/zerobuy/edit?id=' + 61 window.open('/admin/activity/zerobuy/edit?id=' +
45 $(this).data('id'), '_blank'); 62 $(this).data('id'), '_blank');
@@ -198,18 +215,30 @@ function bindListPageEvent() { @@ -198,18 +215,30 @@ function bindListPageEvent() {
198 215
199 $('#search-btn').on('click', searchFn); 216 $('#search-btn').on('click', searchFn);
200 $('.status-switch').on('click', statusFn); 217 $('.status-switch').on('click', statusFn);
201 - 218 + $('.channel-switch').on('click', channelFn);
  219 +
202 $('.btn-edit').on('click', editFn); 220 $('.btn-edit').on('click', editFn);
203 $('.btn-switch-open').on('click', switchFn); 221 $('.btn-switch-open').on('click', switchFn);
204 $('.btn-switch-close').on('click', switchFn); 222 $('.btn-switch-close').on('click', switchFn);
205 $('.btn-export').on('click', exportFn); 223 $('.btn-export').on('click', exportFn);
206 $('.btn-publish').on('click', function() { 224 $('.btn-publish').on('click', function() {
207 - $('input', $confirm).val('');  
208 - $('select', $confirm).val(0).change();  
209 -  
210 - $confirm.data('id', $(this).data('id'));  
211 - $confirm.data('channel', $(this).data('channel'));  
212 - $confirm.modal('show'); 225 + // CHANNELTYPE: {'yoluck渠道': 0, 'UFO渠道': 1,'YOHOOD渠道': 2}
  226 + const channel = $(this).data('channel');
  227 +
  228 + if (+channel === 2) {
  229 + $('input', $yohoodConfirm).val('');
  230 + $('.error-message').text('');
  231 + $yohoodConfirm.modal('show');
  232 + $yohoodConfirm.data('id', $(this).data('id'));
  233 + $yohoodConfirm.data('channel', channel);
  234 + } else {
  235 + $('input', $confirm).val('');
  236 + $('select', $confirm).val(0).change();
  237 + $confirm.modal('show');
  238 + $confirm.data('id', $(this).data('id'));
  239 + $confirm.data('channel', channel);
  240 + }
  241 +
213 }); 242 });
214 $('.btn-notice').on('click', function() { 243 $('.btn-notice').on('click', function() {
215 let notice = $(this).parent().data('notice') || {}; 244 let notice = $(this).parent().data('notice') || {};
@@ -233,6 +262,33 @@ function bindListPageEvent() { @@ -233,6 +262,33 @@ function bindListPageEvent() {
233 262
234 $('.sure-publish-btn').on('click', publishFn); 263 $('.sure-publish-btn').on('click', publishFn);
235 $('.sure-notice-btn').on('click', noticeFn); 264 $('.sure-notice-btn').on('click', noticeFn);
  265 + $('.sure-yohood-publish-btn').on('click', function() {
  266 + const code = $('input[name="price-code"]', $yohoodConfirm).val();
  267 +
  268 + if (code) {
  269 + $.ajax({
  270 + method: 'post',
  271 + url: '/admin/activity/yohood/publish',
  272 + data: {
  273 + id: $yohoodConfirm.data('id'),
  274 + channel: $yohoodConfirm.data('channel'),
  275 + code,
  276 + }
  277 + }).then(res=> {
  278 + if (res.code === 200) {
  279 + $('.error-message').text('');
  280 + $yohoodConfirm.modal('hide');
  281 + $alert.find('.modal-text').text('开奖成功,已提醒用户领奖');
  282 + $alert.modal('show');
  283 + $alert.on('hide.bs.modal', function() {
  284 + location.reload();
  285 + });
  286 + } else {
  287 + $('.error-message').text(res.message);
  288 + }
  289 + });
  290 + }
  291 + });
236 292
237 $('.notice-btn-select').change(noticeBtnTypeChangeFn); 293 $('.notice-btn-select').change(noticeBtnTypeChangeFn);
238 } 294 }
@@ -303,9 +359,47 @@ function generateCid(id) { @@ -303,9 +359,47 @@ function generateCid(id) {
303 return Math.floor(Date.now() + Math.random() * 10000000000 * (id + 1)); 359 return Math.floor(Date.now() + Math.random() * 10000000000 * (id + 1));
304 } 360 }
305 361
  362 +/**
  363 + * 获取yohood活动时间列表,用于判断活动时间是否重叠
  364 + */
  365 +function YOHOODActivityApiGenerator() {
  366 + let isFetch = false;
  367 + let yohoodActivityTimeList = [];
  368 +
  369 + function fetchTimeList() {
  370 + if (isFetch) {
  371 + return;
  372 + }
  373 + $.ajax({
  374 + method: 'get',
  375 + url: '/admin/activity/yohood/times',
  376 + }).then(function(res) {
  377 + isFetch = true;
  378 + yohoodActivityTimeList = res || [];
  379 + }).catch(()=> {
  380 + alert('获取yohood活动时间列表失败');
  381 + });
  382 + }
  383 + return {
  384 + fetchTimeList,
  385 + getList: function() {
  386 + return yohoodActivityTimeList;
  387 + }
  388 + };
  389 +}
  390 +
306 function bindEditPageEvent() { 391 function bindEditPageEvent() {
307 initUpload(); 392 initUpload();
308 393
  394 + // 获取yohood活动时间列表
  395 + const id = $('input[data-type="id"]').val();
  396 + const channel = $('select[name="actChannel"]').val();
  397 + const yohoodApi = YOHOODActivityApiGenerator();
  398 +
  399 + if (!!id && +channel === 2) {
  400 + yohoodApi.fetchTimeList();
  401 + }
  402 +
309 let $floorBox = $('.floor-view-box'); 403 let $floorBox = $('.floor-view-box');
310 let floorContent = {}; 404 let floorContent = {};
311 const typeName = { 405 const typeName = {
@@ -324,16 +418,62 @@ function bindEditPageEvent() { @@ -324,16 +418,62 @@ function bindEditPageEvent() {
324 let resData = {}; 418 let resData = {};
325 let error; 419 let error;
326 420
  421 + /**
  422 + * 选择“YOHOOD渠道”带出如下字段:
  423 + * 商品名称(现有)、商品图⽚片(现 有)、抽奖价(新增)、商品价格(现有)、
  424 + * 活动有效时间(YOHOOD活动创建 提交时不不可以重叠,其他渠道不不影响),
  425 + * 排序(隐藏,默认为0)、详情内容 (隐藏,不不需要填写);
  426 + * CHANNELTYPE: {'yoluck渠道': 0, 'UFO渠道': 1,'YOHOOD渠道': 2}
  427 + */
  428 + const selectedChannel = $('select[name="actChannel"]').val();
  429 +
327 $('.form-imput').each(function() { 430 $('.form-imput').each(function() {
328 let $this = $(this); 431 let $this = $(this);
329 let val = $this.val(); 432 let val = $this.val();
330 let data = $this.data(); 433 let data = $this.data();
331 434
332 if (!val && !error && data.type !== 'id') { 435 if (!val && !error && data.type !== 'id') {
333 - error = data.empty || `请填写${data.type}`;  
334 - } 436 + if (+selectedChannel === 2) {
  437 + if (data.type !== 'sort') {
  438 + error = data.empty || `请填写${data.type}`;
  439 + }
  440 +
  441 + } else {
  442 + if (data.type !== 'lotteryPrice') {
  443 + error = data.empty || `请填写${data.type}`;
  444 + }
  445 + }
335 446
336 - resData[data.type] = val; 447 + }
  448 + if (+selectedChannel === 2) {
  449 + if (data.type !== 'sort') {
  450 + resData[data.type] = val;
  451 + }
  452 + if (data.type === 'time') {
  453 + const [startTime, endTime] = val.split(' - ');
  454 + const startTimeInSeconds = new Date(startTime).getTime() / 1000;
  455 + const endTimeInSeconds = new Date(endTime).getTime() / 1000;
  456 +
  457 + // 时间段不能重叠
  458 + for (const timeInfo of yohoodApi.getList()) {
  459 + const {startTime: st, endTime: et, id: actId} = timeInfo;
  460 +
  461 + if (+id !== +actId) {
  462 + if (startTimeInSeconds >= st && startTimeInSeconds <= et ||
  463 + endTimeInSeconds >= st && endTimeInSeconds <= et ||
  464 + startTimeInSeconds <= st && endTimeInSeconds >= et) {
  465 + error = new Error('YOHOOD活动时间重叠');
  466 + break;
  467 + }
  468 + }
  469 +
  470 + }
  471 + }
  472 + } else {
  473 + if (data.type !== 'lotteryPrice') {
  474 + resData[data.type] = val;
  475 + }
  476 + }
337 }); 477 });
338 478
339 if (error) { 479 if (error) {
@@ -447,7 +587,7 @@ function bindEditPageEvent() { @@ -447,7 +587,7 @@ function bindEditPageEvent() {
447 if (typeof ($.fn.daterangepicker) !== 'undefined') { 587 if (typeof ($.fn.daterangepicker) !== 'undefined') {
448 $('#activityTime').daterangepicker({ 588 $('#activityTime').daterangepicker({
449 timePicker: true, 589 timePicker: true,
450 - timePickerIncrement: 30, 590 + timePickerIncrement: 5,
451 locale: { 591 locale: {
452 format: 'YYYY-MM-DD HH:mm:ss' 592 format: 'YYYY-MM-DD HH:mm:ss'
453 } 593 }
@@ -579,6 +719,22 @@ function bindEditPageEvent() { @@ -579,6 +719,22 @@ function bindEditPageEvent() {
579 } 719 }
580 }); 720 });
581 }); 721 });
  722 +
  723 + // CHANNELTYPE: {'yoluck渠道': 0, 'UFO渠道': 1,'YOHOOD渠道': 2}
  724 + // YOHOOD渠道
  725 + $('select[name="actChannel"]').on('change', function(e) {
  726 + if (+e.target.value === 2) {
  727 + // 获取yohood活动时间列表
  728 + yohoodApi.fetchTimeList();
  729 + $('.content-detail').addClass('hide');
  730 + $('.sort').addClass('hide');
  731 + $('.lottery-price').removeClass('hide');
  732 + } else {
  733 + $('.content-detail').removeClass('hide');
  734 + $('.sort').removeClass('hide');
  735 + $('.lottery-price').addClass('hide');
  736 + }
  737 + });
582 } 738 }
583 739
584 if ($('.zerobuy-list-page').length) { 740 if ($('.zerobuy-list-page').length) {
@@ -4,6 +4,13 @@ @@ -4,6 +4,13 @@
4 padding-bottom: 20px; 4 padding-bottom: 20px;
5 } 5 }
6 6
  7 +.action-wrapper .btn {
  8 + margin-top: 5px;
  9 +}
  10 +.error-message {
  11 + margin-top: 5px;
  12 + color: #f5222d;
  13 +}
7 .search-wrap > * { 14 .search-wrap > * {
8 display: inline-block; 15 display: inline-block;
9 max-width: 50%; 16 max-width: 50%;