Commit ce15a779 authored by 秦海涛's avatar 秦海涛

update

parent 0811bb22
<view class="tb-rule-container"> <view class="tb-rule-container">
<view class="tb-rule-title_container"> <view class="tb-rule-title_container">
<view class="tb-rule-title">用于展示在活动页的规则说明</view> <view class="tb-rule-title">用于展示在活动页的规则说明</view>
<button type="primary" size="small" text onTap="handleTapGeneralRule">{{value ? '重新生成' : '生成规则'}}</button> <button a:if="{{false}}" type="primary" size="small" text onTap="handleTapGeneralRule">{{value ? '重新生成' : '生成规则'}}</button>
</view> </view>
<textarea <textarea
style="width:400px;margin: 10px 0 0 0" style="width:400px;margin: 10px 0 0 0"
......
export default { export default {
// ams:ams接口,cloud: 云函数 // ams:ams接口,cloud: 云函数
requestType: "cloud", requestType: "ams",
// app环境 // app环境
env: "test", // online 线上 test 测试 env: "test", // online 线上 test 测试
......
...@@ -13,6 +13,7 @@ export const descriptor = { ...@@ -13,6 +13,7 @@ export const descriptor = {
}, },
message: "请输入正确的活动名称" message: "请输入正确的活动名称"
}, },
subtitle: { subtitle: {
required: true, required: true,
validator: (rule, value) => { validator: (rule, value) => {
...@@ -25,8 +26,7 @@ export const descriptor = { ...@@ -25,8 +26,7 @@ export const descriptor = {
required: true, required: true,
validator: rankTableValidator validator: rankTableValidator
}, },
timeRange: { timeRange: {required: true
required: true
}, },
logoImg: { logoImg: {
required: true, required: true,
......
...@@ -34,4 +34,10 @@ ...@@ -34,4 +34,10 @@
.submit-btn Button { .submit-btn Button {
margin-left: 20px; margin-left: 20px;
}
.form-flex {
display: flex;
}
.form-check {
margin-right: 10px;
} }
\ No newline at end of file
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
<view class="edit-content"> <view class="edit-content">
<form class="edit-content-form" inline="true" labelTextAlign="right" labelCol="{{labelCol}}"> <form class="edit-content-form" inline="true" labelTextAlign="right" labelCol="{{labelCol}}">
<% for(var i = 0; i < configList.length; ++i) {%> <% for(var i = 0; i < configList.length; ++i) {%>
<%-configList[i]%><% } %> <%-configList[i].template%><% } %>
<view class="submit-btn"> <view class="submit-btn">
<button onTap="onSubmit" type="primary">确定</button> <button onTap="onSubmit" type="primary">确定</button>
......
...@@ -3,7 +3,8 @@ import schema from 'async-validator'; ...@@ -3,7 +3,8 @@ import schema from 'async-validator';
import { descriptor, formatValidator } from './validate'; import { descriptor, formatValidator } from './validate';
import { import {
getActivityDetail, getActivityDetail,
saveActivityInfo saveActivityInfo,
generateRule
} from '/api' } from '/api'
import { import {
addFloat addFloat
...@@ -13,39 +14,126 @@ const THANKS_TYPE = 5 ...@@ -13,39 +14,126 @@ const THANKS_TYPE = 5
var validator = new schema(descriptor); var validator = new schema(descriptor);
/**
*
* 1.任务相关
* 体力值 power
* 参与次数 gameTimes
* 粮食(牧草、水滴等) food
* 金币 coins
* 道具(炸弹、复活卡等) tools
*
*/
Component({ Component({
data: { data: {
labelCol: { labelCol: { fixedSpan: 5 },
fixedSpan: 5
},
id: '', id: '',
title: '',
subtitle: '',
startTime: '', startTime: '',
endTime: '', endTime: '',
timeRange: [],
rule: '', rule: '',
prizeInfoList: [],
taskList:[
// {
// type: "beMembership",//会员
// value: 20,//完成任务获得值
// },
// {
// type: "attentionStore",
// value: 20,
// },
// {
// type: "sign",
// value: 20,
// },
// {
// type: "exchangeCredits",
// value: 20,
// times: 1,
// },
// {
// type: "inviteFriends",
// title: "标题",//任务标题
// taskRateType: 1,//任务频率类型
// times: 3,//任务为每日限次次数值
// value: 30,
// },
// {
// type: "orderGoods",
// title: "标题",
// taskRateType: 2,
// times: 3,
// value: 90,
// itemIds: "111,222,333",//商品类型任务商品id
// },
// {
// type: "browseGoods",
// title: "标题",
// taskRateType: 3,
// times: 3,
// value: 90,
// itemIds: "111,222,333",
// },
// {
// type: "jumpLink",
// title: "标题",
// taskRateType: 3,
// link: "http://www.taobao.com",//跳转链接
// times: 3,
// value: 90,
// },
// {
// type: "collectGoods",
// title: "标题",
// taskRateType: 1,
// times: 3,
// value: 90,
// itemIds: "111,222,333",
// }
],
taskMap: {
attentionStore: {
value: '',
},
beMembership: {
value:'',
checked: false
},
sign: {
value: ''
},
exchangeCredits: {
value: '',
times: '',
},
inviteFriends: {
title: '', // 任务标题
taskRateType: 1, // 任务频率类型
times: 3, // 任务为每日限次次数值
value: '', // 任务奖励
checked: false
},
browseGoods: {
title: "寻宝屋商品",
taskRateType: 1,
times: 3,
value: '',
link: '',
itemIds: '',
checked: true
},
collectGoods: {
title: "",
taskRateType: 1,
times: 3,
value: '90',
itemIds: "",
},
jumpLink: {
title: "",
taskRateType: 3,
link: "",//跳转链接
times: 3,
value: '',
checked: false
},
},
image: '',
isEnd: false, isEnd: false,
isStart: false, isStart: false,
originalStartTime: '', originalStartTime: '',
limitValue: '',
prizeInfoList: [],
prizeDialogData: {}, prizeDialogData: {},
commandTitle: '', formState: formatValidator(descriptor)
beenInvitedText: '',
formState: formatValidator(validator.rules)
}, },
props: {}, props: {},
didMount() { didMount() {
...@@ -72,7 +160,8 @@ Component({ ...@@ -72,7 +160,8 @@ Component({
originalStartTime: +rest.startTime, originalStartTime: +rest.startTime,
isStart: +rest.startTime < Date.now(), isStart: +rest.startTime < Date.now(),
isEnd: +rest.endTime < Date.now(), isEnd: +rest.endTime < Date.now(),
prizeInfoList: prizeInfoList && prizeInfoList.length > 0 ? prizeInfoList : this.data.prizeInfoList taskList: rest.taskList,
taskMap: this.formatTaskListToMap(rest.taskList)
}) })
} catch (error) { } catch (error) {
...@@ -86,9 +175,53 @@ Component({ ...@@ -86,9 +175,53 @@ Component({
[name]: value [name]: value
}) })
}, },
onConfigInputChange(e) { onRuleChange(rule) {
this.setData({
rule
})
},
setDataByKey(name, val) {
const keys = name.split('.');
if(keys.length === 1) {
this.setData({
[keys[0]]: val
})
}
if(keys.length === 2) {
let targetKey = this.data[keys[0]];
targetKey[keys[1]] = val;
let newVal = Object.assign({}, targetKey)
this.setData({
[keys[0]]: newVal
})
}
if(keys.length === 3) {
let targetKey = this.data[keys[0]];
targetKey[keys[1]][keys[2]] = val;
let newVal = Object.assign({}, targetKey)
this.setData({
[keys[0]]: newVal
})
}
},
onTaskInputChange(e) {
const { name } = e.target.dataset;
const { value } = e.detail;
this.setDataByKey(name, value);
},
onCheckChange(e) {
const { name } = e.target.dataset;
const { value } = e.detail;
this.setDataByKey(name, value);
},
onTaskChange(data, key) {
console.log(data, key)
this.setDataByKey(key, data);
},
onImageChange(image) {
console.log('image', image)
this.setData({ this.setData({
limitValue: e.detail.value image
}) })
}, },
onTimeChange(timeRange, error) { onTimeChange(timeRange, error) {
...@@ -108,10 +241,18 @@ Component({ ...@@ -108,10 +241,18 @@ Component({
}) })
}, },
onPrizeListChange(prizeInfoList) {
console.log('prizeInfoList', prizeInfoList);
this.setData({
prizeInfoList
})
},
validateForm(data, target) { validateForm(data, target) {
const _this = this; const _this = this;
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
validator.validate(data, (errors, fields) => { validator.validate(data, (errors, fields) => {
console.log('errors', errors);
console.log('fields', fields);
const { formState } = _this.data; const { formState } = _this.data;
_this.setFormTips(formState, errors, target) _this.setFormTips(formState, errors, target)
if(errors) { if(errors) {
...@@ -139,92 +280,39 @@ Component({ ...@@ -139,92 +280,39 @@ Component({
} }
}) })
console.log('newValidator', newValidator)
this.setData({ this.setData({
formState: newValidator formState: newValidator
}) })
}, },
// 提交信息 // 提交信息
async onSubmit() { async onSubmit() {
const {
id,
activityId,
startTime,
endTime,
rule,
prizeInfoList,
joinTimesEveryday,
joinNeedCredits
} = this.data
const isValidForm = await this.validateForm(this.data); const isValidForm = await this.validateForm(this.data);
// console.log(this.formatActivityParams(this.data))
if(!isValidForm) return; if(!isValidForm) return;
console.log('成功') console.log('成功')
return;
if (!prizeInfoList.length) { const params = this.formatActivityParams(this.data)
this.setDataTips('prizeTipsInfo', 'error', '请至少添加一个奖品配置')
}
if (prizeInfoList.length) {
let totalPercent = prizeInfoList.reduce((total, next) => {
return total = addFloat(total, +next.probablity)
}, 0)
if (totalPercent > 100) {
this.setDataTips('prizeTipsInfo', 'error', '奖品的中奖概率相加不能超过100')
} else {
this.setDataTips('prizeTipsInfo', 'success', '')
}
}
if (joinTimesEveryday !== '' && joinTimesEveryday >= 0 && joinTimesEveryday <= 99 && Number.isInteger(+joinTimesEveryday)) {
this.setDataTips('joinTimesEverydayTipsInfo', 'success', '')
} else {
this.setDataTips('joinTimesEverydayTipsInfo', 'error', '请输入正确的每日可参与次数(0-99)')
}
if (joinNeedCredits !== '' && joinNeedCredits > 0 && joinNeedCredits <= 999 && Number.isInteger(+joinNeedCredits)) {
this.setDataTips('joinNeedCreditsTipsInfo', 'success', '')
} else {
this.setDataTips('joinNeedCreditsTipsInfo', 'error', '请输入正确的购买盲盒消耗积分(1-999)')
}
this.setData({
ruleTipsInfo: !rule
})
const { console.log(params)
prizeTipsInfo,
ruleTipsInfo,
timeRangeTipInfo,
joinTimesEverydayTipsInfo,
joinNeedCreditsTipsInfo
} = this.data
if (
prizeTipsInfo.status === "error" ||
ruleTipsInfo ||
timeRangeTipInfo.status === 'error' ||
joinTimesEverydayTipsInfo.status === 'error' ||
joinNeedCreditsTipsInfo.status === 'error'
) {
this.showFailToast('请检查信息是否全部填写正确')
return
} else {
const params = this.formatActivityParams(this.data)
saveActivityInfo(params) saveActivityInfo(params)
.then(res => { .then(res => {
if (res.success) { if (res.success) {
this.goToActivityList() this.backList()
} else { } else {
this.showFailToast(res.message) this.showFailToast(res.message)
} }
}).catch(err => { }).catch(err => {
console.log(err) console.log(err)
}) })
}
}, },
showFailToast(text) { showFailToast(text) {
my.showToast({ my.showToast({
...@@ -233,21 +321,70 @@ Component({ ...@@ -233,21 +321,70 @@ Component({
}) })
}, },
// 格式化参数 // 格式化参数
formatActivityParams({ formatActivityParams(params) {
activityId, const {
startTime, id = '',
endTime, activityId = '',
rule, startTime,
joinTimesEveryday, endTime,
joinNeedCredits, rule,
prizeInfoList title,
}) { subtitle,
logoImg,
prizeInfoList,
taskList,
taskMap,
commandTitle,
commandImg,
beenInvitedText,
} = params;
// 补足谢谢参与类型
return {
id,
activityId,
title,
subtitle,
logoImg,
startTime: new Date(startTime).getTime(),
endTime: new Date(endTime).getTime(),
rule,
prizeInfoList: this.formatPobalityPrizeList(prizeInfoList),
taskList: this.formatTaskMapToList(taskMap),
commandTitle,
commandImg,
beenInvitedText
}
},
// taskMap转化taskList
formatTaskMapToList(taskMap) {
let list = [];
Object.keys(taskMap).forEach(type => {
if(!taskMap[type].checked) return;
let task = {
...taskMap[type],
type
}
list.push(task)
});
return list;
},
// taskList转化taskMap
formatTaskListToMap(taskList = []) {
let taskMap = {};
taskList.forEach(task => {
taskMap[task['type']] = task;
});
return taskMap
},
// 补足谢谢参与类型
formatPobalityPrizeList(prizeInfoList = []) {
let totalPercent = prizeInfoList.reduce((total, next) => { let totalPercent = prizeInfoList.reduce((total, next) => {
return total = addFloat(total, +next.probablity) return total = addFloat(total, +next.probablity)
}, 0) }, 0)
let prizeInfoListCopy = prizeInfoList.concat() // 排名类型不含谢谢参与
if(prizeInfoList[0].rank) return prizeInfoList;
let prizeInfoListCopy = prizeInfoList.concat().map((v, index) => ({ ...v, level: index }));
if (totalPercent < 100) { if (totalPercent < 100) {
let thanksType = { let thanksType = {
...@@ -257,18 +394,10 @@ Component({ ...@@ -257,18 +394,10 @@ Component({
} }
prizeInfoListCopy.push(thanksType) prizeInfoListCopy.push(thanksType)
} }
return { return prizeInfoListCopy
activityId,
startTime: new Date(startTime).getTime(),
endTime: new Date(endTime).getTime(),
rule,
prizeInfoList: prizeInfoListCopy.map((v, index) => ({ ...v, level: index })),
joinTimesEveryday,
joinNeedCredits
}
}, },
cancleEdit() { cancelEdit() {
this.goToActivityList() this.backList()
}, },
onInputChange(e) { onInputChange(e) {
let { detail: { value }, let { detail: { value },
...@@ -277,6 +406,9 @@ Component({ ...@@ -277,6 +406,9 @@ Component({
let { name } = dataset let { name } = dataset
this.setData({ [name]: value }) this.setData({ [name]: value })
}, },
onChangeByDataName(val, dataName) {
this.setDataByKey(dataName, val)
},
// 选择奖品弹窗 // 选择奖品弹窗
handlerShowPrize(evt) { handlerShowPrize(evt) {
const { const {
...@@ -306,6 +438,49 @@ Component({ ...@@ -306,6 +438,49 @@ Component({
} }
}, },
//生成规则
generateRule() {
const {
title,
startTime,
endTime,
prizeInfoList
} = this.data;
if (title && startTime && endTime && prizeInfoList.length) {
let bool = true;
prizeInfoList.forEach(i => {
if (!i.image || !i.name) {
bool = false
}
})
if (!bool) {
this.showFailToast('请检查奖品配置是否正确')
return
}
console.log({
title,
startTime: startTime,
endTime: endTime,
prizeInfoList
}, 'time');
generateRule({
title,
startTime: new Date(startTime).getTime(),
endTime: new Date(endTime).getTime(),
prizeInfoList
}).then(res => {
if (res.success) {
this.setData({
rule: res.data,
hasEditChangePrize: false
})
}
})
} else {
this.showFailToast('请填写完整信息')
}
},
onCloseDialog(data) { onCloseDialog(data) {
switch (data) { switch (data) {
case "group": case "group":
...@@ -333,24 +508,6 @@ Component({ ...@@ -333,24 +508,6 @@ Component({
}, },
backList() { backList() {
this.$page.$router.push("/activity/list"); this.$page.$router.push("/activity/list");
},
// 更新奖品名次
onUpdateLevel(data, type) {
let dataSourceCopy
if (type || type === 0) {
dataSourceCopy = this.data.prizeInfoList.reduce((s, i, index) => {
if (index === type) {
return s = [...s, data]
} else {
return s = [...s, i]
}
}, [])
} else {
dataSourceCopy = [].concat(this.data.prizeInfoList, data)
}
this.setData({
prizeInfoList: dataSourceCopy
})
} }
}, },
}) })
\ No newline at end of file
...@@ -5,12 +5,14 @@ ...@@ -5,12 +5,14 @@
"tb-input": "/components/form/tb-input/tb-input", "tb-input": "/components/form/tb-input/tb-input",
"tb-config-input": "/components/form/tb-config-input/tb-config-input", "tb-config-input": "/components/form/tb-config-input/tb-config-input",
"tb-range-picker": "/components/form/tb-range-picker/tb-range-picker", "tb-range-picker": "/components/form/tb-range-picker/tb-range-picker",
"question-tips": "/components/basic/question-tips/question-tips",
"tb-rule": "/components/form/tb-rule/tb-rule", "tb-rule": "/components/form/tb-rule/tb-rule",
"probability-prize-table": "/components/prize/probability-prize-table/probability-prize-table", "probability-prize-table": "/components/prize/probability-prize-table/probability-prize-table",
"list-table": "/components/list/list-table/list-table", "list-table": "/components/list/list-table/list-table",
"rank-config": "/components/rank/rank-config/rank-config", "rank-config": "/components/rank/rank-config/rank-config",
"rank-table": "/components/rank/rank-table/rank-table", "rank-table": "/components/rank/rank-table/rank-table",
"task-config": "/components/task/task-config/task-config", "task-config": "/components/task/task-config/task-config",
"tb-image-upload": "/components/form/tb-image-upload/tb-image-upload" "tb-image-upload": "/components/form/tb-image-upload/tb-image-upload",
"items-config": "/components/task/items-config/items-config"
} }
} }
\ No newline at end of file
import { TASK_RATE_TYPE } from '../const'
import flatten from 'lodash/flatten'
import { rankTableValidator } from "../../../utils/validate";
// 使用 async-validator 校验
// 文档地址: https://github.com/yiminghe/async-validator
export const descriptor = { export const descriptor = {
title: { <% for(var i = 0; i < configList.length; ++i) {%>
required: true, <%- !taskKeys.includes(configList[i].key) ? configList[i].validator + ',' : '' %><% } %>
validator: (rule, value) => !!value && value.length <= 12, taskMap: {
message: "请输入正确的活动名称" type: 'object',
}, required: false,
subtitle: { fields: {
required: true, <% for(var i = 0; i < configList.length; ++i) {%>
validator: (rule, value) => !!value && value.length <= 16, <%- taskKeys.includes(configList[i].key) ? configList[i].validator + ',' : '' %><% } %>
message: "请输入正确的活动副标题" }
},
timeRange: {
required: true
} }
}; }
export const formatValidator = descriptor => {
const validators = {}
export const formatValidator = (descriptor, validators) => {
validators = validators || {}
Object.keys(descriptor).forEach(key => { Object.keys(descriptor).forEach(key => {
validators[key] = { if(descriptor[key].fields) {
status: 'success', Object.keys(descriptor[key].fields).forEach(fieldKey => {
message: '' validators[`${key}.${fieldKey}`] = {
status: 'success',
message: ''
}
})
} else {
validators[key] = {
status: 'success',
message: ''
}
} }
}); });
return validators return validators
} }
\ No newline at end of file
taobao-mini-sdk @ 025197b3
Subproject commit 025197b38aaf883547384d73b5960782c9093c23
const ACTIVITY_BASE_CONFIG = "b_activity_config";
const ACTIVITY_PRIZE_CONFIG = "b_prize_config";
const ACTIVITY_SELLER_SAVE = "a_seller_info";
const ACTIVITY_INSTANCE = "miniapp_instantiate";
const USER_PRIZE = "c_awards_info";
const USER_INFO = "c_user"
module.exports = {
ACTIVITY_BASE_CONFIG,
ACTIVITY_PRIZE_CONFIG,
ACTIVITY_SELLER_SAVE,
ACTIVITY_INSTANCE,
USER_PRIZE,
USER_INFO
};
// const {
// formatTime
// } = require('../utils/utils');
// const secret = '99f00e460bfae520f85ae5f5a38e5b4a';
// const appKey = 28640163;
const getSellerInfoByContext = (context) => {
return {
// timestamp: formatTime(new Date(), "yyyy-MM-dd hh:mm:ss"),
// open_id: context.openId,
// 'appkey': appKey,
// 'appsecret': secret,
session: context.accessToken,
// REST_URL: 'http://gw.api.taobao.com/router/rest'
};
};
const getConsumerSeller = ({ accessToken, openId }) => {
return {
// timestamp: formatTime(new Date(), "yyyy-MM-dd hh:mm:ss"),
open_id: openId,
// 'appkey': appKey,
// 'appsecret': secret,
session: accessToken,
// REST_URL: 'http://gw.api.taobao.com/router/rest'
};
};
module.exports = {
getSellerInfoByContext,
getConsumerSeller,
};
const ActivityConfigService = require("../service/activityconfig.service");
const {
CODE_TYPES,
TASK_CHECK_TYPE,
TASK_TYPE_CHINA,
PRIZE_TYPE,
} = require("../utils/constants");
const ResultsModel = require("../utils/results.model");
let resultsModel = new ResultsModel();
const { DELETE_STATUS } = require("../utils/constants");
const ActivitySellerService = require("../service/activityseller.service");
let ActivityTopService = require("../service/activitytop.service");
let ActivityInstanceService = require("../service/activityinstance.service");
const { loginfo, passUrlList } = require("../utils/utils");
const regTestFn = (value, reg) => {
return reg.test(value);
};
const getIds = (data) => {
return data.reduce((s, v) => {
if (v._id) {
s = [...s, v._id];
}
return s;
}, []);
};
const urlCheck = (link, passUrlList) => {
if (!link.startsWith("http://") && !link.startsWith("https://")) {
return {
status: false,
message: "页面链接必须以https://或http://开头",
};
}
let passUrl = false;
passUrlList.some((i) => {
if (~link.indexOf(i)) {
passUrl = true;
return true;
}
return false;
});
if (!passUrl)
return {
status: false,
message: "域名校验不通过",
};
return {
status: true,
message: "",
};
};
//openId获取活动列表
const getActivityListByOpenId = async function (context) {
loginfo(context, "getActivityListByOpenId");
const { openId } = context;
let ActivityConfig = new ActivityConfigService(context);
let ActivityInstance = new ActivityInstanceService(context);
let ActivitySeller = new ActivitySellerService(context);
try {
let sellInfo = await ActivitySeller.findSellerInfo(openId);
console.log(sellInfo, "sellInfo");
if (sellInfo && sellInfo[0]) {
let result = await ActivityConfig.getActivityListByOpenId(
sellInfo && sellInfo[0].shopId,
context.data
);
let instanceInfo = await ActivityInstance.getMiniAppInstanceInfoByNick(
sellInfo[0].userNick
);
if (result) {
result.list.map((item) => {
item.activityId = item._id;
item.onlineUrl =
instanceInfo && instanceInfo[0] ? instanceInfo[0].online_url : "";
return item;
});
return resultsModel.success(result);
}
return resultsModel.error(CODE_TYPES.SYSTEM_ERROR, "查询活动列表失败");
} else {
return resultsModel.error(CODE_TYPES.SYSTEM_ERROR, "小程序未授权");
}
} catch (e) {
console.log("catch", "查询活动列表失败");
return resultsModel.error(CODE_TYPES.SYSTEM_ERROR, "查询活动列表失败");
}
};
//保存或编辑活动信息
const saveActivityInfoByHasId = async function (context) {
loginfo(context, "saveActivityInfoByHasId");
let ActivityConfig = new ActivityConfigService(context);
let ActivityTop = new ActivityTopService(context);
let nowTime = Date.now();
const { openId } = context;
let {
title = "",
subtitle = "",
activityId = "",
startTime,
endTime,
rule,
logoImg = "",
prizeInfoList = [],
taskList = [],
commandTitle,
beenInvitedText,
commandImg,
} = context.data;
let initialData;
if (activityId) {
initialData = await ActivityConfig.getActivityInfoByActivityId(activityId);
}
if (!title) {
return resultsModel.error(CODE_TYPES.PARAMS_ERROR, "活动名称为空");
} else if (title.length > 12) {
return resultsModel.error(
CODE_TYPES.PARAMS_ERROR,
"活动名称不可超过12个字"
);
}
if (!subtitle) {
return resultsModel.error(CODE_TYPES.PARAMS_ERROR, "活动副标题为空");
} else if (subtitle.length > 16) {
return resultsModel.error(
CODE_TYPES.PARAMS_ERROR,
"活动副标题不可超过16个字"
);
}
if (!logoImg) {
return resultsModel.error(CODE_TYPES.PARAMS_ERROR, "logo图片必须配置");
}
if (!commandTitle) {
return resultsModel.error(CODE_TYPES.PARAMS_ERROR, "邀请者淘口令必须配置");
}
if (!beenInvitedText) {
return resultsModel.error(CODE_TYPES.PARAMS_ERROR, "被邀请者文案必须配置");
}
if (!commandImg) {
return resultsModel.error(CODE_TYPES.PARAMS_ERROR, "淘口令图片必须配置");
}
if (taskList.length === 0) {
return resultsModel.error(CODE_TYPES.PARAMS_ERROR, "任务配置必须配置一项");
} else {
let canPassTask = { status: true, message: "" };
taskList = taskList.map((i) => {
if (!i.type) {
canPassTask = {
status: false,
message: "任务必须配置",
};
}
if (TASK_CHECK_TYPE.link.list.includes(i.type)) {
if (canPassTask.status) {
canPassTask = urlCheck(i.link, passUrlList);
}
}
if (TASK_CHECK_TYPE.itemIds.list.includes(i.type)) {
if (!i.itemIds) {
canPassTask = {
status: false,
message: TASK_TYPE_CHINA[i.type] + "必须配置",
};
}
}
if (TASK_CHECK_TYPE.value.list.includes(i.type)) {
if (!i.value) {
canPassTask = {
status: false,
message: TASK_TYPE_CHINA[i.type] + "任务值必须配置",
};
}
if (!regTestFn(i.value, TASK_CHECK_TYPE.value.reg)) {
canPassTask = {
status: false,
message:
TASK_TYPE_CHINA[i.type] +
"任务值在" +
TASK_CHECK_TYPE.value.regName,
};
}
}
if (TASK_CHECK_TYPE.times.list.includes(i.type)) {
if (!i.times) {
canPassTask = {
status: false,
message: TASK_TYPE_CHINA[i.type] + "任务次数必须配置",
};
}
}
if (TASK_CHECK_TYPE.title.list.includes(i.type)) {
if (!i.title) {
canPassTask = {
status: false,
message: TASK_TYPE_CHINA[i.type] + "任务标题必须配置",
};
}
}
if (TASK_CHECK_TYPE.taskRateType.list.includes(i.type)) {
if (!i.taskRateType) {
canPassTask = {
status: false,
message: TASK_TYPE_CHINA[i.type] + "任务类型必须配置",
};
}
}
i.value = +i.value;
i.times = +i.times || "";
i.taskRateType = +i.taskRateType || "";
return i;
});
if (!canPassTask.status)
return resultsModel.error(CODE_TYPES.PARAMS_ERROR, canPassTask.message);
}
if (prizeInfoList.length === 0) {
return resultsModel.error(CODE_TYPES.PARAMS_ERROR, "请配置排行榜奖品");
} else if (prizeInfoList.length > 8) {
return resultsModel.error(CODE_TYPES.PARAMS_ERROR, "奖品最多配置8个档位");
} else {
let canPassPrize = { status: true, message: "" };
prizeInfoList.forEach((item) => {
if ((item.type === PRIZE_TYPE.EQUITY && !item.ename) || !item.rank) {
canPassPrize.status = false;
canPassPrize.message = "奖品配置参数缺失";
}
});
let maxRank = ~prizeInfoList[prizeInfoList.length - 1].rank.indexOf("-")
? prizeInfoList[prizeInfoList.length - 1].rank.split("-")[1]
: prizeInfoList[prizeInfoList.length - 1].rank;
if (maxRank > 100)
canPassPrize = { status: false, message: "奖品排名配置不可超过100" };
if (!canPassPrize.status) {
return resultsModel.error(CODE_TYPES.PARAMS_ERROR, canPassPrize.message);
}
}
if (!rule) {
return resultsModel.error(CODE_TYPES.PARAMS_ERROR, "活动规则不可为空");
}
if (!startTime || !endTime) {
return resultsModel.error(CODE_TYPES.PARAMS_ERROR, "请配置活动时间");
} else if (!activityId && startTime < Date.now()) {
return resultsModel.error(
CODE_TYPES.PARAMS_ERROR,
"新建活动开始时间需小于当前时间"
);
} else if (startTime > endTime) {
return resultsModel.error(
CODE_TYPES.PARAMS_ERROR,
"开始时间不得大于结束时间"
);
} else if (
activityId &&
+initialData.baseConfig.startTime <= nowTime &&
nowTime <= +initialData.baseConfig.endTime
) {
if (+startTime !== +initialData.baseConfig.startTime) {
return resultsModel.error(
CODE_TYPES.PARAMS_ERROR,
"活动开始后不可更改活动开始时间"
);
}
}
let shopInfoResult = await ActivityTop.getShopId();
if (!shopInfoResult.success) {
return resultsModel.error(CODE_TYPES.SYSTEM_ERROR, "获取淘宝店铺信息失败");
}
console.log(shopInfoResult, "shopInfo");
const baseData = {
title,
subtitle,
startTime,
endTime,
rule,
shopId: shopInfoResult.data.sid,
openId,
beenInvitedText,
commandTitle,
commandImg,
logoImg,
taskList,
};
prizeInfoList = prizeInfoList.map((v, i) => {
return { ...v, level: i + 1 };
});
let result;
let allPrizeList = prizeInfoList;
try {
if (!activityId) {
result = await ActivityConfig.saveNewActivity(
baseData,
prizeInfoList,
openId
);
} else {
result = await ActivityConfig.updateBaseConfigInfo(activityId, baseData);
let allNewIds = getIds(allPrizeList);
let oldPrizeList = await ActivityConfig.getAllOldPrizeList(activityId);
let oldIds = getIds(oldPrizeList);
let deleteIds = [];
let bothIds = oldIds.reduce((s, i) => {
if (allNewIds.includes(i)) {
s = [...s, i];
} else {
deleteIds.push(i);
}
return s;
}, []);
for (let i = 0; i < deleteIds.length; i++) {
result = await ActivityConfig.updateDeleteStatusById(deleteIds[i]);
}
for (let i = 0; i < allPrizeList.length; i++) {
if (!allPrizeList[i]._id) {
result = await ActivityConfig.insertPrizeByActivityId(
activityId,
allPrizeList[i]
);
} else if (bothIds.includes(allPrizeList[i]._id)) {
result = await ActivityConfig.updateOnePrizeById(
allPrizeList[i]._id,
allPrizeList[i]
);
}
}
}
if (result || result === 0) {
return resultsModel.success(true);
} else {
console.log(result, "保存活动失败");
return resultsModel.error(CODE_TYPES.SYSTEM_ERROR, "保存活动失败");
}
} catch (e) {
console.log(e, "保存活动失败");
return resultsModel.error(CODE_TYPES.SYSTEM_ERROR, "保存活动失败");
}
};
//删除活动
const deleteActivityById = async function (context) {
loginfo(context, "deleteActivityById");
let ActivityConfig = new ActivityConfigService(context);
const { activityId = "" } = context.data;
try {
if (activityId) {
let result = await ActivityConfig.deleteActivityByActivityId(activityId);
if (result === 0 || result) {
return resultsModel.success(true);
} else {
return resultsModel.error(CODE_TYPES.SYSTEM_ERROR, "删除活动失败");
}
} else {
return resultsModel.error(CODE_TYPES.PARAMS_ERROR, "删除活动id不存在");
}
} catch (e) {
return resultsModel.error(CODE_TYPES.SYSTEM_ERROR, "删除活动失败");
}
};
//获取活动信息
const getActivityInfo = async function (context) {
loginfo(context, "getActivityInfoByActivityId");
let ActivityConfig = new ActivityConfigService(context);
const { activityId = "" } = context.data;
try {
if (activityId) {
let result = await ActivityConfig.getActivityInfoByActivityId(activityId);
let prizeInfoList = result.prizeConfig;
let activityInfo = {
activityId,
...result.baseConfig,
prizeInfoList,
};
return resultsModel.success(activityInfo);
} else {
return resultsModel.error(CODE_TYPES.PARAMS_ERROR, "当前活动不存在");
}
} catch (e) {
return resultsModel.error(CODE_TYPES.SYSTEM_ERROR, "获取活动配置信息失败");
}
};
module.exports = {
getActivityListByOpenId,
saveActivityInfoByHasId,
deleteActivityById,
getActivityInfo,
};
const {
formatTime
} = require('../utils/utils');
const {
CODE_TYPES,
EIGHT_HOURS
} = require('../utils/constants');
const ResultsModel = require('../utils/results.model');
let resultsModel = new ResultsModel();
//生成规则
module.exports = async (context) => {
console.log(JSON.stringify(context.data), 'context.data')
let {
title = '', startTime = '', endTime = '', prizeInfoList = []
} = context.data;
if (!title) {
return resultsModel.error(CODE_TYPES.PARAMS_ERROR, '活动名称为空');
} else if (title.length > 12) {
return resultsModel.error(CODE_TYPES.PARAMS_ERROR, '活动名称不可超过12个字');
}
if (!startTime || !endTime) {
return resultsModel.error(CODE_TYPES.PARAMS_ERROR, '请配置活动时间');
} else if (startTime > endTime) {
return resultsModel.error(CODE_TYPES.PARAMS_ERROR, '开始时间不得大于结束时间');
}
if (prizeInfoList.length === 0) {
return resultsModel.error(CODE_TYPES.PARAMS_ERROR, '奖品至少配置3名');
} else if (prizeInfoList.length > 8) {
return resultsModel.error(CODE_TYPES.PARAMS_ERROR, '奖品最多配置8个档位');
} else {
let canPassPrize = true;
prizeInfoList.forEach(item => {
if (!item.ename || !item.rank) {
canPassPrize = false;
}
})
if (!canPassPrize) {
return resultsModel.error(CODE_TYPES.PARAMS_ERROR, '奖品配置不正确');
}
}
let resultRule = '';
let startTimeDate = formatTime(new Date(+startTime + EIGHT_HOURS), "yyyy-MM-dd hh:mm:ss");
let endTimeDate = formatTime(new Date(+endTime + EIGHT_HOURS), "yyyy-MM-dd hh:mm:ss");
resultRule = `1.活动时间:${startTimeDate}--${endTimeDate};\n2.活动结束根据排行榜排名获得对应的奖励,每个人取活动中单局最高分;\n3.每天3次免费参与资格,超过次数后邀请群内好友参与游戏可获得额外次数(每个用户可助力一次);\n4.参与签到可获得道具,每局结束游戏后可使用道具;\n5.完成任务每天可获得额外的复活机会,每局只能使用一张复活卡;\n\n`
let prizeStr = prizeInfoList.reduce((s, v) => {
let rankArr = v.rank.split('-');
if (rankArr[0] == rankArr[1]) {
return s += `第${rankArr[0]}名: ${v.name}\n`
} else {
return s += `第${v.rank}名: ${v.name}\n`
}
}, '奖品:\n')
resultRule += prizeStr;
return resultsModel.success(resultRule);
}
\ No newline at end of file
const { loginfo } = require("../utils/utils");
const { CODE_TYPES } = require("../utils/constants");
const ResultsModel = require("../utils/results.model");
let resultsModel = new ResultsModel();
const ActivityTopService = require("../service/activitytop.service");
//通过状态获取top商品列表
const findItemListByStatusAction = async function (context) {
loginfo(context, "findItemListByStatus");
let ActivityTop = new ActivityTopService(context);
try {
let result = await ActivityTop.getItemListByStatus();
return result;
} catch (e) {
console.log(e, "获取top商品列表失败");
return resultsModel.error(CODE_TYPES.SYSTEM_ERROR, "获取top商品列表失败");
}
};
//通过itemIds获取商品列表
const findItemListByIdsAction = async (context) => {
loginfo(context, "findItemListByIdsAction");
let ActivityTop = new ActivityTopService(context);
try {
let result = ActivityTop.getItemListByIds();
return result;
} catch (e) {
console.log(e, "获取商品列表失败");
return resultsModel.error(CODE_TYPES.SYSTEM_ERROR, "获取商品列表失败");
}
};
//通过ename获取权益信息
const getBenefitByEname = async (context) => {
loginfo(context, "getBenefitByEname");
let ActivityTop = new ActivityTopService(context);
try {
let result = await ActivityTop.getPrizeByEname();
return result;
} catch (e) {
console.log(e, "获取ename权益信息失败");
return resultsModel.error(CODE_TYPES.SYSTEM_ERROR, "获取ename权益信息失败");
}
};
//测试getTemplateInstantiate
const getTemplateInstantiate = async (context) => {
loginfo(context, "getTemplateInstantiate");
let ActivityTop = new ActivityTopService(context);
try {
let result = await ActivityTop.getTemplateInstantiate();
return result;
} catch (e) {
console.log(e, "获取getTemplateInstantiate失败");
return resultsModel.error(
CODE_TYPES.SYSTEM_ERROR,
"获取getTemplateInstantiate失败"
);
}
};
module.exports = {
findItemListByIdsAction,
findItemListByStatusAction,
getBenefitByEname,
getTemplateInstantiate,
};
const ActivitySellerService = require("../service/activityseller.service");
const { CODE_TYPES, TEMPLATE_INFO } = require("../utils/constants");
const ActivityTopService = require("../service/activitytop.service");
const ActivityInstanceService = require("../service/activityinstance.service");
const { loginfo } = require("../utils/utils");
const ResultsModel = require("../utils/results.model");
let resultsModel = new ResultsModel();
//保存授权信息
module.exports = async (context) => {
loginfo(context, "sellerInfo");
let {
openId,
accessToken,
appKey,
userNick,
appOwnerOpenId,
consumeMiniAppId,
} = context;
let ActivitySeller = new ActivitySellerService(context);
let ActivityTop = new ActivityTopService(context);
let ActivityInstance = new ActivityInstanceService(context);
try {
let primaryAccountNick = userNick;
let isPrimaryAccount = true;
if (~userNick.indexOf(":")) {
let userNickArr = userNick.split(":");
isPrimaryAccount = false;
primaryAccountNick = userNickArr[0];
if (!isPrimaryAccount) {
let sellerInfo = await ActivitySeller.getSellerInfoByUserNick(
primaryAccountNick
);
if (sellerInfo) {
accessToken = sellerInfo.accessToken;
} else {
return resultsModel.error(
CODE_TYPES.SYSTEM_ERROR,
"请用主账号进入后台进行授权"
);
}
}
}
let hasResult = await ActivitySeller.findSellerInfo(openId);
let subInfo = await ActivityTop.getSubRelationship(primaryAccountNick);
if (hasResult && hasResult[0] && isPrimaryAccount) {
await ActivitySeller.updateSellerInfo(openId, {
accessToken,
});
await ActivityInstance.updateInstanceInfo(openId, {
accessToken,
});
// return resultsModel.success({ deadline: subInfo.deadline || "" });
} else {
let shopInfoResult = await ActivityTop.getShopId();
if (!shopInfoResult.success) {
return resultsModel.error(
CODE_TYPES.SYSTEM_ERROR,
"获取淘宝店铺信息失败"
);
}
try {
await ActivitySeller.saveSellerInfo({
accessToken,
openId,
appKey,
shopId: shopInfoResult.data.sid,
userNick,
appOwnerOpenId,
});
// return resultsModel.success({ deadline: subInfo.deadline || "" });
} catch (e) {
console.log(e, "保存授权信息失败");
return resultsModel.error(CODE_TYPES.SYSTEM_ERROR, "保存授权信息失败");
}
}
let instanceOldInfo = await ActivityInstance.getMiniAppInstanceInfoByNick(
primaryAccountNick
);
if (!instanceOldInfo) {
if (!isPrimaryAccount) {
return resultsModel.error(
CODE_TYPES.SYSTEM_ERROR,
"请用主账号进入后台进行授权"
);
}
let instanceInfo = await ActivityTop.getTemplateInstantiate();
const { app_id, app_version } = instanceInfo;
if (instanceInfo) {
let onlineInstance = await ActivityTop.pushOnlineInstance({
app_id,
app_version,
});
await ActivityInstance.saveInstanceInfo({
...instanceInfo,
clients: onlineInstance.online_results.miniapp_instance_app_online_dto.reduce(
(s, v) => {
return (s += v.client + ",");
},
""
),
...onlineInstance.app_info,
accessToken,
template_version: TEMPLATE_INFO.template_version,
template_id: TEMPLATE_INFO.template_id,
openId,
appKey,
consumeMiniAppId,
userNick,
appOwnerOpenId,
});
} else {
console.log("实例化信息获取失败");
}
} else {
if (TEMPLATE_INFO.template_version !== instanceOldInfo.template_version) {
const { clients, app_id, template_id } = instanceOldInfo;
let updateInfo = {
clients,
app_id,
template_id,
ext_json: {
name: "online",
},
template_version: TEMPLATE_INFO.template_version,
};
let updateInstanceInfo = await ActivityTop.updateMiniInstance(
updateInfo
);
let onlineInstance = await ActivityTop.pushOnlineInstance({
app_id: updateInstanceInfo.app_id,
app_version: updateInstanceInfo.app_version,
});
await ActivityInstance.updateInstanceInfo({
template_version: TEMPLATE_INFO.template_version,
...onlineInstance.app_info,
app_version: updateInstanceInfo.app_version,
pre_view_url: updateInstanceInfo.pre_view_url,
});
}
}
return resultsModel.success({ deadline: subInfo.deadline || "" });
} catch (e) {
console.log(e, "获取授权信息失败");
return resultsModel.error(CODE_TYPES.SYSTEM_ERROR, "获取授权信息失败");
}
};
/**
* 中奖名单 及导出中奖名单
*/
const RankopenprizeService = require('../service/rankopenprize.service');
const ResultsModel = require('../utils/results.model');
const {
CODE_TYPES
} = require('../utils/constants');
const xlsx = require('node-xlsx');
let resultsModel = new ResultsModel();
// 活动中奖名单
const findWinnerInfoList = async (context) => {
let {
activityId
} = context.data;
if (!activityId) {
return resultsModel.error(CODE_TYPES.PARAMS_ERROR, `缺少activityId`);
}
let rankopenprizeService = new RankopenprizeService(context);
// 获取活动中奖列表
let awardslist = await rankopenprizeService.getAwardslistByActivityId(activityId);
console.log(`awardslist: ${JSON.stringify(awardslist)}`);
let winnersObj = {};
awardslist.forEach((v, index, arr) => {
if (!winnersObj[v.rank]) {
winnersObj[v.rank] = [];
}
winnersObj[v.rank].push({
userNick: v.userNick,
id: v.openId
});
});
console.log(`winnersObj: ${JSON.stringify(winnersObj)}`);
let results = [];
new Map(Object.entries(winnersObj)).forEach((v, index, arr) => {
results.push({
rank: index,
winnerDetailList: v
});
});
return resultsModel.success(results);
}
// 导出活动中奖名单
const exportAwardsList = async (context) => {
let {
cloud
} = context;
let {
activityId,
title
} = context.data;
if (!activityId) {
return resultsModel.error(CODE_TYPES.PARAMS_ERROR, `缺少activityId`);
}
if (!title) {
return resultsModel.error(CODE_TYPES.PARAMS_ERROR, `缺少title`);
}
let rankopenprizeService = new RankopenprizeService(context);
// 获取活动中奖列表
let awardslist = await rankopenprizeService.getAwardslistByActivityId(activityId);
console.log(`awardslist: ${JSON.stringify(awardslist)}`);
let xlsxData = [
['序列', '名次', '昵称', '中奖名称']
];
awardslist.forEach((v, index, arr) => {
xlsxData.push([index + 1, v.rank, v.userNick, v.prizeName]);
});
let buffer = xlsx.build([{
name: title + new Date().getTime(),
data: xlsxData
}]);
console.log(`xlsxData: ${JSON.stringify(xlsxData)}`);
try {
let result = await cloud.file.uploadFile({
fileContent: buffer,
fileName: title + new Date().getTime() + '.xlsx'
});
// result.url 需进行处理
if (result.url) {
result.url = result.url.replace('http', 'https').replace('-internal', '');
}
return resultsModel.success(result);
} catch (e) {
console.log('上传文件出错', e);
// 打印日志
return resultsModel.error(CODE_TYPES.SYSTEM_ERROR, `上传文件错误`);
}
}
module.exports = {
findWinnerInfoList,
exportAwardsList
}
\ No newline at end of file
const RankscanService = require("../service/activityconfig.service");
const ActivityprizeService = require("../service/activityprize.service");
const RankscoreService = require("../service/rankscore.service");
const RankopenprizeService = require("../service/rankopenprize.service");
const ResultsModel = require("../utils/results.model");
const { Utils, EIGHT_HOURS } = require("../utils/constants");
let resultsModel = new ResultsModel();
// 声明排行榜扫描服务
let rankscanService = null;
// 声明奖品服务
let activityprizeService = null;
// 声明分数排行榜服务
let rankscoreService = null;
// 声明待开奖服务
let rankopenprizeService = null;
// 查询该活动的奖品列表 及 发奖数
const getPrizeListAndAwards = async (activityId) => {
let prizeList = await activityprizeService.getPrizeListByActivityId(
activityId
);
console.log(prizeList);
// 若不存在奖品列表,则为脏数据,不做处理
if (!prizeList.length) {
console.log(`活动Id为${activityId}不存在对应的奖品信息`);
return {
prizeList: [],
totalAwards: 0,
};
}
// 获取总共发奖的个数
let totalAwards = prizeList.reduce((total, curVal, curIndex, arr) => {
// 当没有rank名次,直接返回
if (!curVal.rank) {
return total;
}
let awards = ~curVal.rank.indexOf("-")
? +curVal.rank.split("-")[1]
: +curVal.rank;
if (awards > total) {
total = awards;
}
return total;
}, 0);
return {
prizeList,
totalAwards,
};
};
// 获取待开奖列表
const getWaitAwardsList = (prizeList, topscoreList, totalAwards, shopId) => {
let waitAwardslist = [];
// 若分数排行榜没有数据,或发奖数为0,返回[]
if (!totalAwards || !topscoreList.length) {
return waitAwardslist;
}
prizeList.forEach((v, index, arr) => {
if (!v.rank) {
return;
}
let rankPeriod = ~v.rank.indexOf("-")
? v.rank.split("-")
: [v.rank, v.rank];
// 截取排行区间的分数排行列表
let ranklist = topscoreList.slice(
+rankPeriod[0] - 1,
Math.min(+rankPeriod[1], totalAwards)
);
// 整合开奖数据
ranklist.map((rank) => {
waitAwardslist.push({
activityId: v.activityId,
openId: rank.openId,
rankRange: v.rank,
rank: rank.rank,
ename: v.ename,
startTime: v.startTime,
endTime: v.endTime,
prizeId: v._id,
prizeName: v.name,
userNick: rank.userNick,
rankTime: rank.updateTime,
image: v.image,
maxScore: rank.maxScore,
shopId: shopId,
type: v.type || "",
amount: v.amount || "",
createDay: Utils.default.dateFormatter(
new Date(Date.now() + EIGHT_HOURS),
"yyyy/MM/dd"
),
});
});
});
return waitAwardslist;
};
// 设置活动开奖
const setActivity2openprize = async (waitAwardslist, _id) => {
// 插入排行榜开奖记录表 rank_open_prize 若失败,则变更
let results = await rankopenprizeService.addWaitAwardsList(waitAwardslist);
console.log(`result: ${JSON.stringify(results)}`);
if (results) {
await rankscanService.update2Success(_id);
console.log(`开奖成功`);
return true;
} else {
await rankscanService.update2Fail(_id, `批量插入rank_open_prize表不成功`);
console.log(`开奖失败`);
return false;
}
};
/**
* 定时触发开奖
*/
const endingNotify = async (context) => {
// 初始化排行榜扫描服务
rankscanService = new RankscanService(context);
// 初始化返回结果
let results = {
success: [],
fails: [],
};
// 获取服务器时间
let serverTime = Date.now();
// 触发开奖列表
let notifyList = await rankscanService.getNodifyList(serverTime);
console.log(notifyList.length);
if (!notifyList.length) {
console.log(`没有待开奖的活动`);
return resultsModel.success(results);
}
// 初始化奖品服务
activityprizeService = new ActivityprizeService(context);
// 分数排行榜
rankscoreService = new RankscoreService(context);
// 待开奖服务
rankopenprizeService = new RankopenprizeService(context);
// 遍历列表
for (let i = 0; i < notifyList.length; i++) {
let { _id, shopId } = notifyList[i];
// 将该条记录变更为处理中
let updateResult = await rankscanService.update2Process(_id);
console.log(`updateResult: ${updateResult}`);
if (!updateResult) {
console.log(`将rank_scan该活动的开奖状态变更为处理中失败`);
continue;
}
// 查询该活动的奖品列表 及 发奖数
let { prizeList, totalAwards } = await getPrizeListAndAwards(_id);
// console.log(
// `prizeList: ${JSON.stringify(prizeList)}; totalAwards: ${totalAwards}`
// );
// 没查找到奖品列表, 继续下个活动循环
if (!prizeList.length) {
// 开奖失败,记录日志
await rankscanService.update2Fail(
_id,
`活动不存在对应的奖品列表,开奖失败`
);
results.fails.push(_id);
continue;
}
// 查找排行榜分数榜里的前totalAwards个记录
let topscoreList = await rankscoreService.getToplistByActivityId(
_id,
totalAwards
);
topscoreList = topscoreList.map((v, i) => {
return { ...v, rank: i + 1 };
});
console.log(`topscoreList: ${JSON.stringify(topscoreList)}`);
// 根据分数排行榜列表及奖品列表整合数据,待开奖列表
let waitAwardslist = getWaitAwardsList(
prizeList,
topscoreList,
totalAwards,
shopId
);
// if (!waitAwardslist.length) {
// }
console.log(`waitAwardslist: ${JSON.stringify(waitAwardslist)}`);
// 开奖
let issuccess = await setActivity2openprize(waitAwardslist, _id);
issuccess ? results.success.push(_id) : results.fails.push(_id);
// end
}
return resultsModel.success(results);
};
module.exports = {
endingNotify,
};
const { BaseDao } = require("../utils/constants");
module.exports = BaseDao;
const { endingNotify } = require("./controller/endingNodify.controller");
const {
findWinnerInfoList,
exportAwardsList,
} = require("./controller/awards.controller");
const {
getActivityListByOpenId,
saveActivityInfoByHasId,
deleteActivityById,
getActivityInfo,
} = require("./controller/activity.controller");
const saveSellerInfo = require("./controller/activityseller.controller");
const generateRuleAction = require("./controller/activitygenerateRule.controller");
const {
findItemListByStatusAction,
findItemListByIdsAction,
getBenefitByEname,
} = require("./controller/activitygettbitem.controller");
// 定时开奖
exports.endingNotify = endingNotify;
// 活动中奖名单
exports.findWinnerInfoList = findWinnerInfoList;
// 导出中奖名单
exports.exportAwardsList = exportAwardsList;
exports.getActivityList = getActivityListByOpenId;
exports.saveActivityInfo = saveActivityInfoByHasId;
exports.delActivity = deleteActivityById;
exports.getActivityDetail = getActivityInfo;
exports.sellerSave = saveSellerInfo;
exports.generateRule = generateRuleAction;
exports.findItemListByStatus = findItemListByStatusAction;
exports.findItemListByIds = findItemListByIdsAction;
exports.queryBenefitByEname = getBenefitByEname;
exports.subSearch = async (context) => {
const cloud = context.cloud;
let res = await cloud.topApi.invoke({
api: "taobao.vas.subscribe.get",
data: {
article_code: "FW_GOODS-1001086450",
nick: "duiba2",
},
});
return res;
};
{
"name": "duiba",
"version": "1.0.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"adler-32": {
"version": "1.2.0",
"resolved": "https://registry.npm.taobao.org/adler-32/download/adler-32-1.2.0.tgz",
"integrity": "sha1-aj5r8KY5ALoVZSgIyxXGgT0aXyU=",
"requires": {
"exit-on-epipe": "~1.0.1",
"printj": "~1.1.0"
}
},
"buffer-from": {
"version": "1.1.1",
"resolved": "https://registry.npm.taobao.org/buffer-from/download/buffer-from-1.1.1.tgz",
"integrity": "sha1-MnE7wCj3XAL9txDXx7zsHyxgcO8="
},
"cfb": {
"version": "1.1.4",
"resolved": "https://registry.npm.taobao.org/cfb/download/cfb-1.1.4.tgz",
"integrity": "sha1-gf017eTJGdjwliqUWC4d+vcFHio=",
"requires": {
"adler-32": "~1.2.0",
"commander": "^2.16.0",
"crc-32": "~1.2.0",
"printj": "~1.1.2"
}
},
"codepage": {
"version": "1.14.0",
"resolved": "https://registry.npm.taobao.org/codepage/download/codepage-1.14.0.tgz",
"integrity": "sha1-jL4lSBMjVZ19MHVxsP/5HnodL5k=",
"requires": {
"commander": "~2.14.1",
"exit-on-epipe": "~1.0.1"
},
"dependencies": {
"commander": {
"version": "2.14.1",
"resolved": "https://registry.npm.taobao.org/commander/download/commander-2.14.1.tgz?cache=0&sync_timestamp=1592632075120&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcommander%2Fdownload%2Fcommander-2.14.1.tgz",
"integrity": "sha1-IjUSPjevjKPGXfRbAm29NXsBuao="
}
}
},
"commander": {
"version": "2.17.1",
"resolved": "https://registry.npm.taobao.org/commander/download/commander-2.17.1.tgz?cache=0&sync_timestamp=1592632075120&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcommander%2Fdownload%2Fcommander-2.17.1.tgz",
"integrity": "sha1-vXerfebelCBc6sxy8XFtKfIKd78="
},
"crc-32": {
"version": "1.2.0",
"resolved": "https://registry.npm.taobao.org/crc-32/download/crc-32-1.2.0.tgz",
"integrity": "sha1-yy224puIUI4y2d0OwWk+e0Ghggg=",
"requires": {
"exit-on-epipe": "~1.0.1",
"printj": "~1.1.0"
}
},
"exit-on-epipe": {
"version": "1.0.1",
"resolved": "https://registry.npm.taobao.org/exit-on-epipe/download/exit-on-epipe-1.0.1.tgz",
"integrity": "sha1-C92S6H1ShdJn2qgXHQ6wYVlolpI="
},
"frac": {
"version": "1.1.2",
"resolved": "https://registry.npm.taobao.org/frac/download/frac-1.1.2.tgz",
"integrity": "sha1-PXT39keMiKG1AgMG10fcYxPHTQs="
},
"node-xlsx": {
"version": "0.15.0",
"resolved": "https://registry.npm.taobao.org/node-xlsx/download/node-xlsx-0.15.0.tgz",
"integrity": "sha1-HxsNetzlxwboa/2WpaoABb+KncM=",
"requires": {
"buffer-from": "^1.1.0",
"xlsx": "^0.14.1"
}
},
"printj": {
"version": "1.1.2",
"resolved": "https://registry.npm.taobao.org/printj/download/printj-1.1.2.tgz",
"integrity": "sha1-2Q3rKXWoufYA+zoclOP0xTx4oiI="
},
"ssf": {
"version": "0.10.3",
"resolved": "https://registry.npm.taobao.org/ssf/download/ssf-0.10.3.tgz",
"integrity": "sha1-jq4fwpyQpVLnkhII+BiS1vd6yys=",
"requires": {
"frac": "~1.1.2"
}
},
"taobao-mini-sdk": {
"version": "git+http://luofangping@duiba.com.cn:duiba123@gitlab2.dui88.com/huhu/taobao-mini-sdk.git#7cde981223c800143ae99e1c200a3597b76713d1",
"from": "git+http://luofangping@duiba.com.cn:duiba123@gitlab2.dui88.com/huhu/taobao-mini-sdk.git"
},
"xlsx": {
"version": "0.14.5",
"resolved": "https://registry.npm.taobao.org/xlsx/download/xlsx-0.14.5.tgz?cache=0&sync_timestamp=1593422715008&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fxlsx%2Fdownload%2Fxlsx-0.14.5.tgz",
"integrity": "sha1-NjfpFNeRvcpzgoFuFz99cl7Q4NI=",
"requires": {
"adler-32": "~1.2.0",
"cfb": "^1.1.2",
"codepage": "~1.14.0",
"commander": "~2.17.1",
"crc-32": "~1.2.0",
"exit-on-epipe": "~1.0.1",
"ssf": "~0.10.2"
}
}
}
}
{
"name": "duiba",
"version": "1.0.0",
"description": "",
"main": "index.js",
"author": "",
"license": "ISC",
"sdkVersion": "*",
"dependencies": {
"node-xlsx": "^0.15.0",
"taobao-mini-sdk": "^0.1.2"
},
"config": {
"notNeedLogin": [
"endingNotify"
]
}
}
\ No newline at end of file
const BaseDao = require("../dao/base.dao");
const {
ACTIVITY_BASE_CONFIG,
ACTIVITY_PRIZE_CONFIG,
} = require("../config/db_config");
const { DELETE_STATUS, OPEN_PRIZE_STATUS } = require("../utils/constants");
module.exports = class ActivityConfigService {
constructor(context) {
this.activityconfigDao = new BaseDao(context, ACTIVITY_BASE_CONFIG);
this.activityconfigPrizeDao = new BaseDao(context, ACTIVITY_PRIZE_CONFIG);
}
//保存新建活动
async saveNewActivity(data, prize, openId) {
try {
let result = await this.activityconfigDao.insertOne({
...data,
createTime: Date.now(),
updateTime: Date.now(),
deleteStatus: DELETE_STATUS.EXIST,
openPrizeStatus: OPEN_PRIZE_STATUS.WAIT_AWARD,
});
console.log(result, "保存基础配置result");
if (result) {
try {
prize.map((item) => {
item.activityId = result;
item.openId = openId;
item.createTime = Date.now();
item.updateTime = Date.now();
item.deleteStatus = DELETE_STATUS.EXIST;
return item;
});
return await this.activityconfigPrizeDao.insertMany(prize);
} catch (e) {
console.log(e, "保存奖品配置出错");
// 如果奖品未保存删除之前的活动
await this.activityconfigDao.deleteMany({
_id: result,
});
}
}
} catch (e) {
//保存活动失败
console.log(e, "保存活动失败");
}
}
// 更新活动基本信息
async updateBaseConfigInfo(id, data) {
return await this.activityconfigDao.update(
{
_id: id,
},
{
$set: {
...data,
updateTime: Date.now(),
deleteStatus: DELETE_STATUS.EXIST,
},
}
);
}
// 通过id获取奖品信息
async getPrizeInfoById(id) {
let result = await this.activityconfigPrizeDao.find({
_id: id,
});
if (result && result[0]) {
return result[0];
}
return false;
}
// 奖品置为删除状态
async updateDeleteStatusById(id) {
return await this.activityconfigPrizeDao.update(
{
_id: id,
},
{
$set: {
deleteStatus: DELETE_STATUS.DELETE,
},
}
);
}
// 更新单条数据
async updateOnePrizeById(id, data) {
return await this.activityconfigPrizeDao.update(
{
_id: id,
},
{
$set: {
...data,
updateTime: Date.now(),
deleteStatus: DELETE_STATUS.EXIST,
},
}
);
}
// 插入单条奖品数据
async insertPrizeByActivityId(activityId, data) {
return await this.activityconfigPrizeDao.insertOne({
...data,
activityId,
createTime: Date.now(),
updateTime: Date.now(),
deleteStatus: DELETE_STATUS.EXIST,
});
}
// 获取奖品所有配置
async getAllOldPrizeList(activityId) {
return await this.activityconfigPrizeDao.find({
activityId,
});
}
//更新活动配置
async updateActivity(activityId, data, prizeNoId) {
console.log(
activityId,
data,
prizeNoId,
"activityId, data, prizeNoId, oldPrizeIds"
);
try {
let originalData = await this.activityconfigDao.findOne({
_id: activityId,
});
let result = await this.activityconfigDao.update(
{
_id: activityId,
},
{
$set: {
...data,
createTime: originalData.createTime,
updateTime: Date.now(),
},
}
);
if (result) {
try {
let prizeOldIdsByActivity = (
await this.activityconfigPrizeDao.find({
activityId,
})
).reduce((s, v) => {
return (s = [...s, v._id]);
}, []);
let prizeResult = await this.activityconfigPrizeDao.insertMany(
prizeNoId
);
if (prizeResult) {
//删除之前的奖品
let deleteOldPrizeList = prizeOldIdsByActivity.reduce((s, item) => {
return (s = [
...s,
this.activityconfigPrizeDao.deleteMany({
_id: item,
}),
]);
}, []);
return await Promise.all(deleteOldPrizeList);
}
} catch (e) {
await this.activityconfigDao.update(
{
_id: activityId,
},
{
$set: {
...originalData[0],
},
}
);
}
}
} catch (e) {
//更新失败
}
}
//通过openId去获取当前商家活动列表
async getActivityListByOpenId(shopId, { pageSize = 10, pageNo = 1 }) {
return {
list: await this.activityconfigDao.find(
{
shopId,
deleteStatus: DELETE_STATUS.EXIST,
},
{
projection: {
startTime: 1,
endTime: 1,
title: 1,
},
sort: {
createTime: -1,
},
limit: pageSize,
skip: (pageNo - 1) * pageSize,
}
),
total: await this.activityconfigDao.count({
shopId,
deleteStatus: DELETE_STATUS.EXIST,
}),
pageSize,
pageNo,
};
}
//通过activityId去获取活动配置信息
async getActivityInfoByActivityId(activityId) {
return {
baseConfig: await this.activityconfigDao.findOne(
{
_id: activityId,
deleteStatus: DELETE_STATUS.EXIST,
},
{
projection: {
commandImg: 1,
rule: 1,
taskList: 1,
title: 1,
logoImg: 1,
prizeInfoList: 1,
subtitle: 1,
commandTitle: 1,
startTime: 1,
endTime: 1,
beenInvitedText: 1,
},
}
),
prizeConfig: await this.activityconfigPrizeDao.find(
{
activityId,
deleteStatus: DELETE_STATUS.EXIST,
},
{
sort: {
level: 1,
},
}
),
};
}
//通过activityId去删除活动
async deleteActivityByActivityId(activityId) {
try {
let result = await this.activityconfigDao.update(
{
_id: activityId,
},
{
$set: {
deleteStatus: DELETE_STATUS.DELETE,
},
}
);
if (result) {
return await this.activityconfigPrizeDao.update(
{
activityId,
},
{
$set: {
deleteStatus: DELETE_STATUS.DELETE,
},
}
);
}
} catch (e) {
console.log(e, "删除活动失败");
}
}
// 查询待开奖列表
async getNodifyList(serverTime) {
let list = await this.activityconfigDao.find({
endTime: {
$lt: serverTime,
},
openPrizeStatus: {
$in: [OPEN_PRIZE_STATUS.WAIT_AWARD, OPEN_PRIZE_STATUS.FAIL],
},
deleteStatus: DELETE_STATUS.EXIST,
});
console.log(list);
return list;
}
// 更新openPrizeStatus为处理中
async update2Process(_id) {
try {
await this.activityconfigDao.update(
{
_id,
},
{
$set: {
openPrizeStatus: OPEN_PRIZE_STATUS.PROCESSING,
updateTime: Date.now(),
},
}
);
return true;
} catch (e) {
// 日志记录
console.log(e);
return false;
}
}
// 更新openPrizeStatus为成功
async update2Success(_id) {
try {
await this.activityconfigDao.update(
{
_id,
},
{
$set: {
openPrizeStatus: OPEN_PRIZE_STATUS.SUCCESS,
openPrizeMsg: "",
updateTime: Date.now(),
},
}
);
return true;
} catch (e) {
// 日志记录
console.log(e);
return false;
}
}
// 更新openPrizeStatus为失败
async update2Fail(_id, message) {
try {
await this.activityconfigDao.update(
{
_id,
},
{
$set: {
openPrizeStatus: OPEN_PRIZE_STATUS.FAIL,
openPrizeMsg: message || "",
updateTime: Date.now(),
},
}
);
return true;
} catch (e) {
// 日志记录
console.log(e);
return false;
}
}
};
const BaseDao = require("../dao/base.dao");
const { ACTIVITY_INSTANCE } = require("../config/db_config");
module.exports = class ActivitySellerService {
constructor(context) {
this.activityinstanceDao = new BaseDao(context, ACTIVITY_INSTANCE);
}
//保存商家授权信息
async saveInstanceInfo(instanceInfo) {
return await this.activityinstanceDao.insertOne({
...instanceInfo,
updateTime: Date.now(),
createTime: Date.now(),
});
}
//查找商家授权信息
async findInstanceInfo(openId) {
return await this.activityinstanceDao.find({
openId,
});
}
//更新商家授权信息
async updateInstanceInfo(openId, updateinfo) {
return await this.activityinstanceDao.update(
{
openId,
},
{
$set: {
...updateinfo,
updateTime: Date.now(),
},
}
);
}
async getMiniAppInstanceInfoByNick(userNick) {
let res = await this.activityinstanceDao.find({
userNick,
});
if (res && res[0]) {
return res[0];
}
return false;
}
};
const BaseDao = require("../dao/base.dao");
const { OPEN_PRIZE_STATUS, DELETE_STATUS } = require("../utils/constants");
const { ACTIVITY_PRIZE_CONFIG } = require("../config/db_config");
const DBName = ACTIVITY_PRIZE_CONFIG;
class ActivityprizeService {
constructor(context) {
this.activityprizeDao = new BaseDao(context, DBName);
}
// 根据活动id查询奖品列表
async getPrizeListByActivityId(activityId) {
console.log(13, activityId);
return await this.activityprizeDao.find({
activityId,
deleteStatus: DELETE_STATUS.EXIST,
});
}
}
module.exports = ActivityprizeService;
const BaseDao = require("../dao/base.dao");
const { ACTIVITY_SELLER_SAVE } = require("../config/db_config");
module.exports = class ActivitySellerService {
constructor(context) {
this.activitysellerDao = new BaseDao(context, ACTIVITY_SELLER_SAVE);
}
//保存商家授权信息
async saveSellerInfo(sellerInfo) {
return await this.activitysellerDao.insertOne({
...sellerInfo,
updateTime: Date.now(),
createTime: Date.now(),
});
}
//查找商家授权信息
async findSellerInfo(openId) {
return await this.activitysellerDao.find({
openId,
});
}
//查找商家授权信息
async getSellerInfoByUserNick(userNick) {
let res = await this.activitysellerDao.find({
userNick,
});
if (res && res[0]) {
return res[0];
}
return false;
}
//更新商家授权信息
async updateSellerInfo(openId, sellerInfo) {
console.log(openId, sellerInfo, "openId, sellerInfo");
return await this.activitysellerDao.update(
{
openId: openId,
},
{
$set: {
...sellerInfo,
updateTime: Date.now(),
},
}
);
}
};
const {
ACTIVITY_SELLER_SAVE,
ACTIVITY_BASE_CONFIG,
} = require("../config/db_config");
const {
getConsumerSeller,
getSellerInfoByContext,
} = require("../config/seller_config");
const {
CODE_TYPES,
GOODSINFO,
B_APP_NAME,
TEMPLATE_INFO,
TBAPIS,
APP_SUB_CODE,
} = require("../utils/constants");
const ResultsModel = require("../utils/results.model");
const { MathRand } = require("../utils/utils");
let resultsModel = new ResultsModel();
const BaseDao = require("../dao/base.dao");
class ActivityTopService {
constructor(context) {
this.activitySellerDao = new BaseDao(context, ACTIVITY_SELLER_SAVE);
this.activityBaseDao = new BaseDao(context, ACTIVITY_BASE_CONFIG);
this.context = context;
}
//获取商家授权session
async getAccessToken(activityId) {
let result = await this.activityBaseDao.find({
_id: activityId,
});
if (result[0]) {
let shopId = result[0].shopId;
let sellResult = await this.activitySellerDao.find(
{
shopId,
},
{
sort: {
createTime: 1,
},
}
);
console.log(sellResult, "sellResult");
if (sellResult[0]) {
let { accessToken } = sellResult[0];
return {
session: accessToken,
};
}
}
}
//通过openId去查找session
async getAccessTokenByOpenId() {
let openId = this.context.openId;
let result = await this.activitySellerDao.find({
openId,
});
if (result[0]) {
let shopId = result[0].shopId;
let sellResult = await this.activitySellerDao.find(
{
shopId,
},
{
sort: {
createTime: 1,
},
}
);
if (sellResult[0]) {
let { accessToken } = sellResult[0];
return {
session: accessToken,
};
}
} else {
return { session: this.context.accessToken };
}
}
//淘宝top接口获取商品列表
async getItemListByIds(activityId, itemIds) {
let sellerConfig;
if (activityId) {
let businessSeller = await this.getAccessToken(activityId);
sellerConfig = getConsumerSeller(businessSeller);
} else {
sellerConfig = await this.getAccessTokenByOpenId();
itemIds = this.context.data.itemIds;
}
console.log(sellerConfig, "sellerConfig");
try {
let result = await TBAPIS.getItemListByItemIds(
this.context,
sellerConfig.session,
itemIds,
{ fields: GOODSINFO }
);
// let result = await this.context.cloud.topApi.invoke({
// api: "taobao.items.seller.list.get",
// data: {
// ...sellerConfig,
// fields: GOODSINFO,
// num_iids: itemIds,
// },
// });
// console.log(JSON.stringify(result), '获取商品通过ids')
if (result) {
let itemsData = {
list:
(result &&
result.items &&
result.items.item.reduce((s, v) => {
return (s = [
...s,
{
itemId: v.num_iid,
name: v.title,
price: v.price,
detailUrl: v.detail_url,
picUrl: v.pic_url,
},
]);
}, [])) ||
[],
totalCount: result.items.item.length,
};
return resultsModel.success(itemsData);
}
return resultsModel.error(CODE_TYPES.SYSTEM_ERROR, "获取商家ids列表失败");
} catch (e) {
console.log(e, "获取ids商品列表失败");
return resultsModel.error(CODE_TYPES.SYSTEM_ERROR, "获取商家ids列表失败");
}
}
//淘宝top接口获取权益商品信息
async getPrizeByEname(activityId, ename) {
let sellerConfig;
if (activityId) {
let businessSeller = await this.getAccessToken(activityId);
sellerConfig = getConsumerSeller(businessSeller);
} else {
sellerConfig = await this.getAccessTokenByOpenId();
ename = this.context.data.ename;
}
console.log(sellerConfig, "sellerConfig");
try {
let benefitData = await TBAPIS.getPrizeByEname(
this.context,
sellerConfig.session,
ename,
B_APP_NAME
);
console.log(benefitData, benefitData.result, "benefitData.result.");
if (benefitData.result.success) {
const { result } = benefitData;
let data =
result.datas &&
result.datas["oright_dto"].reduce((s, v) => {
return (s = [
...s,
{
benefitName: v.benefit_name,
rightTypeId: v.right_type_id == 3 ? 1 : v.right_type_id,
startTime: new Date(v.start_date).getTime(),
endTime: new Date(v.end_date).getTime(),
amount: v.amount ? v.amount / 100 + "" : "",
},
]);
}, []);
console.log(JSON.stringify(result), "alibaba.benefit.query");
return resultsModel.success(data);
}
return resultsModel.error(
CODE_TYPES.SYSTEM_ERROR,
"获取ename商品信息失败"
);
} catch (e) {
console.log(e, "权益获取失败");
return resultsModel.error(
CODE_TYPES.SYSTEM_ERROR,
"获取ename商品信息失败"
);
}
}
//淘宝top接口获取店铺会员链接
async getVipUrlByActivity(activityId) {
let businessSeller = await this.getAccessToken(activityId);
let consumerSellerInfo = getConsumerSeller(businessSeller);
try {
let result = await this.context.cloud.topApi.invoke({
api: "taobao.crm.member.joinurl.get",
data: {
...consumerSellerInfo,
extra_info: {
source: "isvapp",
activityId: activityId,
entrance: "duiba",
},
},
});
if (result) {
return resultsModel.success(result);
}
console.log(JSON.stringify(result), "获取商家会员链接");
return resultsModel.error(
CODE_TYPES.SYSTEM_ERROR,
"获取商家会员链接失败"
);
} catch (e) {
console.log(e, "获取商家会员链接失败");
return resultsModel.error(
CODE_TYPES.SYSTEM_ERROR,
"获取商家会员链接失败"
);
}
}
//淘宝top接口获取店铺信息
async getShopId() {
let sellerInfo = await this.getAccessTokenByOpenId();
console.log(sellerInfo, "getShopId sellerInfo");
try {
let result = await TBAPIS.getShopInfo(this.context, {
session: sellerInfo.session,
fields: "sid,title,pic_path",
});
console.log(result, "getShopId result");
if (result) {
return resultsModel.success(result.shop);
} else {
return resultsModel.error(
CODE_TYPES.SYSTEM_ERROR,
"获取淘宝top店铺信息失败"
);
}
} catch (e) {
console.log(e, "获取店铺信息失败");
return resultsModel.error(
CODE_TYPES.SYSTEM_ERROR,
"获取淘宝top店铺信息失败"
);
}
}
async getItemListByStatus() {
let sellerConfig = await this.getAccessTokenByOpenId();
const {
approveStatus = "onsale",
title = "",
pageNo = 1,
pageSize = 10,
} = this.context.data;
let data = {
fields: GOODSINFO,
page_no: pageNo,
q: title,
page_size: pageSize,
...sellerConfig,
};
console.log(data, "data");
try {
let result =
approveStatus === "onsale"
? await TBAPIS.getItemListOnSale(this.context, data)
: await TBAPIS.getItemListInStock(this.context, data);
if (result) {
// console.log(
// JSON.stringify(result),
// `comming ${approveStatus}`,
// "success"
// );
let { items, total_results } = result;
let itemsData = {
pageNo,
pageSize,
totalPages: Math.ceil(total_results / pageSize),
totalCount: total_results,
list:
(items &&
items.item &&
items.item.reduce((s, v) => {
return (s = [
...s,
{
itemId: v.num_iid,
name: v.title,
price: v.price,
approveStatus: v.approveStatus || approveStatus,
picUrl: v.pic_url,
},
]);
}, [])) ||
[],
};
return resultsModel.success(itemsData);
}
return resultsModel.error(
CODE_TYPES.SYSTEM_ERROR,
"获取商家在售列表失败"
);
} catch (e) {
console.log(e, "获取商家在售列表失败");
return resultsModel.error(
CODE_TYPES.SYSTEM_ERROR,
"获取商家在售列表失败"
);
}
}
async getTemplateInstantiate() {
let sellerConfig = await this.getAccessTokenByOpenId();
let data = {
description:
"此应用用于商家引导活动,商家可设置对应的奖品,在一定时间 内出奖,提升店铺用户活跃以及引导购买",
ext_json: {
name: "online",
},
icon:
"https://ossgw.alicdn.com/taobao-miniapp/img/0193eaa9cc037b568acd9ccfe68a8499.jpg",
name: "店铺漂流" + MathRand(),
...TEMPLATE_INFO,
...sellerConfig,
};
console.log("getTemplateInstantiateParams", data);
try {
let result = await TBAPIS.getTemplateInstantiate(this.context, data);
if (result) {
console.log(JSON.stringify(result), "getTemplateInstantiate");
return result;
}
return false;
} catch (e) {
console.log(e, "获取getTemplateInstantiate失败");
return false;
}
}
//模板小程序上线
async pushOnlineInstance(instanceInfo) {
let sellerConfig = await this.getAccessTokenByOpenId();
let data = {
...TEMPLATE_INFO,
...instanceInfo,
...sellerConfig,
};
console.log("pushOnlineInstanceParams", data);
try {
let result = await TBAPIS.pushInstanceOnline(this.context, data);
if (result) {
console.log(JSON.stringify(result), "pushOnlineInstance");
return result;
}
return false;
} catch (e) {
console.log(e, "pushOnlineInstance失败");
return false;
}
}
async getSubRelationship(nick) {
const cloud = this.context.cloud;
let res = await cloud.topApi.invoke({
api: "taobao.vas.subscribe.get",
data: {
article_code: APP_SUB_CODE,
nick,
},
});
if (
res &&
res["article_user_subscribes"] &&
res["article_user_subscribes"]["article_user_subscribe"]
)
return res["article_user_subscribes"]["article_user_subscribe"][0];
return false;
}
//模板小程序更新
async updateMiniInstance(instanceInfo) {
let sellerConfig = await this.getAccessTokenByOpenId();
let data = {
...TEMPLATE_INFO,
...instanceInfo,
...sellerConfig,
};
try {
let result = await TBAPIS.updateMiniInstance(this.context, data);
if (result) {
console.log(JSON.stringify(result), "updateMiniInstance");
return result;
}
return false;
} catch (e) {
console.log(e, "updateMiniInstance失败");
return false;
}
}
}
module.exports = ActivityTopService;
// 排行榜开奖记录
const BaseDao = require("../dao/base.dao");
const { DRAW_STATUS } = require("../utils/constants");
const { USER_PRIZE } = require("../config/db_config");
const DBName = USER_PRIZE;
class RankopenprizeService {
constructor(context) {
this.rankopenprizeDao = new BaseDao(context, DBName);
}
// 添加排行榜待开奖列表
async addWaitAwardsList(list) {
if (!list.length) {
return true;
}
list.map((v) => {
(v.drawStatus = DRAW_STATUS.WAITAWARD), (v.message = "");
});
try {
await this.rankopenprizeDao.insertMany(list);
return true;
} catch (e) {
console.log(`添加排行榜待开奖列表出错:${e}`);
return false;
}
}
// 根据活动id查找中奖名单
async getAwardslistByActivityId(activityId) {
if (!activityId) {
return false;
}
return await this.rankopenprizeDao.find(
{
activityId: activityId,
},
{
sort: {
score: -1,
rankTime: -1,
},
}
);
}
}
module.exports = RankopenprizeService;
const BaseDao = require("../dao/base.dao");
const { USER_INFO } = require("../config/db_config");
const DBName = USER_INFO;
class RankscoreService {
constructor(context) {
this.rankscoreDao = new BaseDao(context, DBName);
}
// 根据活动id查询分数排行榜
async getToplistByActivityId(activityId, totalAwards) {
let list = await this.rankscoreDao.find(
{
activityId: activityId,
maxScore: { $ne: 0 },
},
{
sort: {
maxScore: -1,
updateScoreTime: 1,
},
limit: +totalAwards,
}
);
console.log(`getToplistByActivityId: ${JSON.stringify(list)}`);
return list;
}
}
module.exports = RankscoreService;
const { BaseDao, TBAPI, Utils } = require("taobao-mini-sdk").default;
// 活动开奖状态码
const OPEN_PRIZE_STATUS = {
// 待开奖
WAIT_AWARD: 1,
// 开奖中
PROCESSING: 2,
// 开奖成功
SUCCESS: 3,
// 开奖失败
FAIL: 4,
};
// 领取奖品状态
const DRAW_STATUS = {
// 待领取
WAITAWARD: 1,
// 处理中
PROCESSING: 2,
// 领取成功
SUCCESS: 3,
// 领取失败
FAIL: 4,
// 已过期
EXPIRED: 5,
// 重新领取
RETRY: 6,
};
// 日志类型: error,info
const LOGGER_TYPE = {
ERROR: 1,
INFO: 2,
};
const PRIZE_TYPE = {
EQUITY: 1,
CREDITS: 2,
OBJECT: 3,
THANK: 5,
};
// code类型
const CODE_TYPES = {
PARAMS_ERROR: {
code: "100000",
defaultMsg: `参数错误`,
},
SYSTEM_ERROR: {
code: "500000",
defaultMsg: `系统错误`,
},
SUCCESS: {
code: "000000",
defaultMsg: `成功`,
},
// TODO 补充业务类型错误, 固定以2开头,如B端业务错误:200001,200002,C端业务错误:210001,210002
};
const SHARE_TOTAL_COUNT = 5; //验证要求5人后,完成分享任务
const B_APP_NAME = "promotioncenter-3000000002693435"; // B端的APP NAME
const GOODSINFO =
"detail_url,approve_status,num_iid,title,nick,type,cid,pic_url,num,props,valid_thru,list_time,price,has_discount,has_invoice,has_warranty,has_showcase,modified,delist_time,postage_id,seller_cids,outer_id,sold_quantity";
const EIGHT_HOURS = 60 * 60 * 8 * 1000;
const DELETE_STATUS = {
DELETE: 2,
EXIST: 1,
};
const TEMPLATE_INFO = {
clients: "taobao,tmall",
template_id: 3000000002590532,
template_version: "0.0.3",
};
const TASK_TYPE_CHINA = {
beMembership: "成为会员",
attentionStore: "关注店铺",
sign: "签到",
exchangeCredits: "兑换积分",
inviteFriends: "邀请好友",
orderGoods: "下单商品",
browseGoods: "浏览商品",
jumpLink: "跳转链接",
collectGoods: "收藏商品",
};
const TASK_CHECK_TYPE = {
value: {
list: [
"beMembership",
"attentionStore",
"sign",
"exchangeCredits",
"inviteFriends",
"orderGoods",
"jumpLink",
"collectGoods",
],
reg: /[1-9]/,
regName: "1-9之内",
},
times: {
list: [
"exchangeCredits",
"inviteFriends",
"orderGoods",
"browseGoods",
"jumpLink",
"collectGoods",
],
},
title: {
list: [
"inviteFriends",
"orderGoods",
"browseGoods",
"jumpLink",
"collectGoods",
],
},
itemIds: {
list: ["orderGoods", "browseGoods", "collectGoods"],
},
taskRateType: {
list: ["inviteFriends", "orderGoods", "browseGoods", "collectGoods"],
},
link: { list: ["jumpLink"] },
};
//店铺漂流记订购码
const APP_SUB_CODE = "FW_GOODS-1001086450";
module.exports = {
OPEN_PRIZE_STATUS,
DRAW_STATUS,
LOGGER_TYPE,
CODE_TYPES,
SHARE_TOTAL_COUNT,
DELETE_STATUS,
GOODSINFO,
B_APP_NAME,
EIGHT_HOURS,
TEMPLATE_INFO,
BaseDao,
TBAPIS: TBAPI.default,
Utils,
TASK_CHECK_TYPE,
TASK_TYPE_CHINA,
APP_SUB_CODE,
PRIZE_TYPE,
};
const errorCode = {
"000000": 'ok',
"000001": '请填写活动名称',
"000002": '请填写活动副标题',
"000003": '活动名称不得大于12个字符',
"000004": '活动副标题不得大于16个字符',
"000005": '任务配置至少选择一项',
"000006": '浏览链接配置错误',
"000007": '奖品至少配置三名',
"000008": "浏览宝贝最多选择20个商品",
"000010": '请先生成规则',
"000011": '请配置活动时间',
"000012": '新建活动开始时间需小于当前时间',
"000013": '开始时间不得大于结束时间',
"000014": '奖品最多配置8个档位',
"000015": '查询列表错误',
"000016": '查询列表总数错误',
"000017": '更新奖品列表出错',
"000020": '删除活动失败',
"000021": '保存活动失败',
"000022": "删除活动id不存在",
"000023": '当前活动不存在',
"000024": '获取授权信息失败',
"000025": '保存授权信息失败',
"000026": '获取商家在售列表失败',
"000027": '获取商家ids列表失败',
"000030": '获取ename商品信息失败',
"000031": '奖品配置不正确'
}
module.exports = {
errorCode
}
\ No newline at end of file
class ResultsModel {
constructor() {
}
// 不填errorType,默认为系统错误
error(errorType, message) {
if (!errorType) {
errorType = { code: '500000', defaultMsg: '系统错误' };
}
return {
success: false,
code: errorType.errorCode,
message: message || errorType.defaultMsg
}
}
success(data) {
return {
success: true,
code: 10000,
data: data,
message: `成功`
}
}
}
module.exports = ResultsModel
\ No newline at end of file
function loginfo(context, handler) {
const {
fcName,
data,
env
} = context;
console.log(`函数名:${fcName}---函数handler:${handler}---当前环境:${env}---请求参数:${JSON.stringify(data)}`)
}
const passUrlList = [
'1688.cn',
'taobao.cn',
'taobao.com',
'taobao.net',
'tb.cn',
'tmall.com',
'zhifu.com',
'zhifubao.com',
'juhuasuan.com',
'tmall.hk',
'tmall.com.hk',
'dingtalk.com',
'yushanfang.com',
'guoguo-app.com',
'umeng.com'
]
/**
* 传入时间戳(毫秒)
* 根据时间戳转换成number型日期进行差值结算,比如:2020318-2020317
*/
function isNewDay(time) {
let date = new Date(time);
let dateNum = +(date.getFullYear() + "" + (date.getMonth() + 1) + "" + date.getDate());
let nowdate = new Date(Date.now());
let nowdateNum = +(nowdate.getFullYear() + "" + (nowdate.getMonth() + 1) + "" + nowdate.getDate());
return nowdateNum - dateNum > 0
}
const formatTime = function dateFormat(thisDate, fmt = "yyyy-MM-dd hh:mm:ss") {
var o = {
"M+": thisDate.getMonth() + 1,
"d+": thisDate.getDate(),
"h+": thisDate.getHours(),
"m+": thisDate.getMinutes(),
"s+": thisDate.getSeconds(),
"q+": Math.floor((thisDate.getMonth() + 3) / 3),
"S": thisDate.getMilliseconds()
};
if (/(y+)/.test(fmt))
fmt = fmt.replace(RegExp.$1, (thisDate.getFullYear() + "").substr(4 - RegExp.$1.length));
for (var k in o)
if (new RegExp("(" + k + ")").test(fmt))
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
return fmt;
}
function MathRand() {
var Num = "";
for (var i = 0; i < 6; i++) {
Num += Math.floor(Math.random() * 10);
}
return Num;
}
module.exports = {
loginfo,
MathRand,
passUrlList,
isNewDay,
formatTime
}
\ No newline at end of file
exports.main = async (context) => {
let res = await context.cloud.db.collection("activity_base_config").find({
endTime: {
$gte: Date.now(),
},
});
return res;
};
{
"name": "test",
"version": "1.0.0",
"description": "",
"main": "index.js",
"author": "",
"license": "ISC",
"sdkVersion": "*",
"dependencies": {
},
"config": {
"notNeedLogin": [
]
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment