Commit 79ed990b authored by 秦海涛's avatar 秦海涛

update

parent 91c83b35
.item-dialog-content {
background: #FFFFFF;
max-height: 507px;
display: flex;
flex-direction: column;
}
.modal-content-btn.choose-modal-footer {
justify-content:space-between;
align-items:center;
}
.choose-content-tab {
padding:10px 20px;
flex-grow:1;
overflow-y:scroll;
height:350px;
}
.choose-content-tab .choose-content-tab-view{
padding:20px 0 5px;
}
.choose-content-tab-baby{
border:1px solid #ccc;
position:relative;
margin:10px 10px 0 0;
}
.choose-content-tab-baby:hover {
border:1px solid #3386F1;
}
.choose-content-tab-image-wrap {
padding:10px;
font-size:0;
}
.choose-content-tab-image-wrap image{
width:134px;
height:134px;
}
.choose-content-tab-baby-wrap{
display:flex;
max-height:300px;
overflow:scroll;
flex-wrap:wrap;
}
.choose-content-tab-baby-info{
background:#EBF3FF;
padding:10px;
}
.choose-content-tab-baby Checkbox{
position:absolute;
right:10px;
top:9px;
}
.choose-content-tab-baby-info-title{
width:134px;
white-space: nowrap;
font-size:12px;
color:#333333;
overflow: hidden;
text-overflow:ellipsis;
margin-bottom:10px;
}
.choose-content-tab-baby-info-prize {
display:flex;
font-size:12px;
justify-content:space-between;
}
.choose-content-tab-baby-info-prize .prize-now{
color: #333;
}
.choose-content-tab-baby-info-prize .prize-now text{
color:#FFA033;
}
.choose-content-tab-baby-info-prize .prize-old{
color:#999999;
text-decoration:line-through;
}
.choose-content-pagination{
display:flex;
justify-content:flex-end;
margin:10px 20px 10px 0;
}
.choose-modal-footer-number{
margin:0 5px;
color:#3386F1;
}
.choose-no-baby{
font-size:14px;
color: #333;
}
.items-dialog-btns {
display: flex;
justify-content: flex-end;
}
.items-dialog-btns_confirm {
margin-right: 10px;
}
\ No newline at end of file
<dialog-wrap
title="选择宝贝"
visible="{{showBaby}}"
hasMask="{{true}}"
onClose="closeBaby"
width="738"
>
<view class="modal-content">
<tab onChange="changeTableItem" class="choose-content-tab">
<tab-item
title="全部宝贝"
key="all"
>
<view class="choose-content-tab-view">
<select onChange="changeStatus" value="{{searchInfo.approveStatus}}" showSearch>
<option value="onsale">出售中</option>
<!-- <option value="instock">仓库中</option> -->
</select>
<text style="margin-left:20px;font-size:12px">标题关键字</text>
<input style="width:120px;margin:0 10px" value="{{searchInfo.title}}" onChange="changeSearchKeyWords" placeholder="标题关键字"/>
<button onTap="searchBabyList" size="medium" type="primary" size="small">搜索</button>
</view>
<view class="choose-content-tab-baby-wrap">
<view class="choose-content-tab-baby" onTap="changeCheckStatus" data-index={{index}} data-item="{{item}}" a:for-index="index" a:for-item="item" a:for="{{babyDialogInfo.list}}">
<view class="choose-content-tab-image-wrap">
<image src="{{item.picUrl}}"></image>
</view>
<view class="choose-content-tab-baby-info">
<view class="choose-content-tab-baby-info-title">{{item.name}}</view>
<view class="choose-content-tab-baby-info-prize"><text class="prize-now">¥<text>{{item.price}}</text></text></view>
</view>
<checkbox class="block" checked="{{chooseId.includes(item.itemId)}}" data-name="{{index}}" data-item="{{item}}"></checkbox>
</view>
</view>
<view class="choose-content-pagination">
<pagination showJump="{{false}}" defaultCurrent="{{babyDialogInfo.pageNo}}" data-type="all" pageSize="{{babyDialogInfo.pageSize}}" onChange="changePagination" pageShowCount="{{5}}" total="{{babyDialogInfo.totalCount}}" a:if="{{babyDialogInfo.totalPages > 1}}" shape="arrow-only" />
</view>
<view class="choose-no-baby" a:if="{{!babyDialogInfo.list.length}}">暂无宝贝,请前去添加</view>
</tab-item>
<tab-item
key="choose"
title="{{`已选择(${chooseId.length})`}}"
>
<view class="choose-content-tab-view">
<view a:if="{{chooseId.length > 0}}" class="choose-content-tab-baby-wrap">
<view class="choose-content-tab-baby" data-item="{{item}}" onTap="changeNoCheckBaby" a:for-index="index" a:for="{{chooseArr}}">
<view class="choose-content-tab-image-wrap">
<image src="{{item.picUrl}}"></image>
</view>
<view class="choose-content-tab-baby-info">
<view class="choose-content-tab-baby-info-title">{{item.name}}</view>
<view class="choose-content-tab-baby-info-prize"><text class="prize-now">¥<text>{{item.price}}</text></text></view>
</view>
<checkbox class="block" checked="true" data-name="{{index}}"></checkbox>
</view>
</view>
<view class="choose-no-baby" a:else>暂无选择的宝贝,请去选择</view>
</view>
</tab-item>
</tab>
<view class="modal-content-btn choose-modal-footer">
<view>已选择<text class="choose-modal-footer-number">{{chooseId.length}}</text>个宝贝</view>
<view class="items-dialog-btns">
<button type="primary" classs="items-dialog-btns_confirm" onTap="sureBabyDialog">确定</button>
<button onTap="closeBaby">取消</button>
</view>
</view>
</view>
</dialog-wrap>
\ No newline at end of file
import API from "/api";
Component({
mixins: [],
data: {
dialogTop: "",
chooseArr: [],
chooseId: [],
firstGetList: false,
searchInfo: {
approveStatus: "onsale",
title: "",
pageNo: 1,
pageSize: 8,
},
babyDialogInfo: {
list: [],
pageNo: 1,
pageSize: 8,
totalCount: "",
totalPages: "",
},
},
props: {
onClose: () => {},
showBaby: false,
browseItemIds: "",
onUpdateBabyChoose: () => {},
},
didMount() {
this.initPosition();
const { searchInfo } = this.data;
this.getBabyList(searchInfo);
},
didUnmount() {},
methods: {
initPosition() {
const { scrollTop } = this.$page.data;
this.setData({
dialogTop: scrollTop * 2,
});
},
getBabyList(info, chooseId) {
API.findItemListByStatus({
...info,
}).then((res) => {
if (res.success) {
const { browseItemIds } = this.props;
this.setData({
chooseId: chooseId
? chooseId
: browseItemIds
? browseItemIds.split(",").map((i) => +i)
: [],
babyDialogInfo: {
...this.data.babyDialogInfo,
...res.data,
list: res.data.list ? res.data.list : [],
},
});
}
});
},
getHasChooseBaby(itemIds) {
API.findItemListByIds({ itemIds })
.then((res) => {
if (res.success) {
this.setData({
chooseArr: res.data.list,
});
} else {
my.showToast({
type: "fail",
content: res.message,
});
}
})
.catch((err) => {
console.log(err);
});
},
changeTableItem(e) {
const { value } = e.detail;
const { chooseId } = this.data;
if (value === ".$choose") {
if (!chooseId.length) {
this.setData({
chooseArr: [],
});
} else {
let itemIds = chooseId.join(",");
this.getHasChooseBaby(itemIds);
}
}
},
searchBabyList() {
const { searchInfo } = this.data;
this.getBabyList(searchInfo, this.data.chooseId);
},
changePagination(e) {
this.setData({
searchInfo: {
...this.data.searchInfo,
pageNo: e.detail.value,
},
});
this.getBabyList(this.data.searchInfo, this.data.chooseId);
},
closeBaby() {
this.props.onClose("baby");
},
changeCheckStatus(e) {
const { chooseId } = this.data;
if (chooseId.length >= 20) {
my.showToast({
type: "fail",
content: "最多选择20个宝贝",
});
}
const { item } = e.target.dataset;
console.log(item, "item");
if (chooseId.includes(item.itemId)) {
this.setData({
chooseId: chooseId,
});
} else {
this.setData({
chooseId: [item.itemId],
});
}
},
sureBabyDialog() {
const { chooseId } = this.data;
console.log(chooseId, "chooseId");
this.props.onUpdateBabyChoose(chooseId.join());
this.closeBaby();
},
changeSearchKeyWords(e) {
this.setData({
searchInfo: {
...this.data.searchInfo,
title: e.detail.value,
},
});
},
changeStatus(e) {
this.setData({
searchInfo: {
...this.data.searchInfo,
approveStatus: e.detail.value,
},
});
},
changeNoCheckBaby(e) {
const { chooseId } = this.data;
const { item } = e.target.dataset;
this.setData(
{
chooseId: chooseId.filter((i) => {
return i !== item.itemId;
}),
},
() => {
this.getHasChooseBaby(this.data.chooseId.join(","));
}
);
},
},
});
{
"component": true,
"usingComponents": {
"dialog-wrap": "../../basic/dialiog-wrap/dialiog-wrap"
}
}
\ No newline at end of file
......@@ -24,17 +24,24 @@
<radio size="small" value="{{3}}" >不限次</radio>
</radio-group>
</form-item>
<form-item a:if="{{taskRateType === 2}}">
<form-item style="width:100%;" a:if="{{taskRateType === 2}}">
<view class="task-day-limit">
<view>每天最多完成</view>
<view style="margin: 0 6px;"><select value="{{times}}" onChange="onTimesChange" dataSource="{{dataSource}}"/>
</view>次任务</view>
<view style="margin: 0 6px;">
<select value="{{times}}" onChange="onTimesChange" dataSource="{{dataSource}}"/>
</view>
次任务
</view>
</form-item>
<form-item label="跳转链接" a:if="{{!noLink}}">
<form-item label="跳转链接" a:if="{{hasLink}}">
<input style="width: 250px" onChange="onChange" data-name="link" defaultValue="{{link}}" name="link" placeholder="请输入跳转链接"/>
</form-item>
<form-item label="商品编辑" a:if="{{hasItems}}" style="width:100%;">
<items-config itemIds="{{itemIds}}" onUpdate="onItemIdsChange"/>
</form-item>
<form-item label="任务奖励">
<input onChange="onChange" data-name="value" defaultValue="{{value}}" name="value" addonTextAfter="{{unit}}"/>
</form-item>
......
......@@ -13,26 +13,44 @@ Component({
{ label: 7, value:7 },
{ label: 8, value:8 },
{ label: 9, value:9 },
{ label: 10, value:10 }
{ label: 10, value:10 },
],
taskRateType: 1,
times: 1,
times: '',
title: '',
link: '',
itemIds: '',
value: ''
},
props: {
visible: false,
noLink: false,
hasLink: false,
hasItems: false,
type: '',
unit: '',
taskData: {
title: '',
taskRateType: 1,
times: '',
value: '',
itemIds: ''
},
onClose: () => {},
onUpdate: () => {}
},
didMount() {},
didMount() {
this.initData();
},
didUpdate() {},
didUnmount() {},
methods: {
initData() {
Object.keys(this.props.taskData).forEach(key => {
this.setData({
[key]: this.props.taskData[key]
})
});
},
onCloseDialog() {
this.props.onClose();
},
......@@ -42,6 +60,11 @@ Component({
times: value
})
},
onItemIdsChange(ids) {
this.setData({
itemIds:ids
})
},
onTaskRateTypeChange(e) {
const { value } = e.detail;
this.setData({
......@@ -57,10 +80,13 @@ Component({
},
validateLink(link) {
if(!link) return false;
return true;
if(link.startsWith('http://') || link.startsWith('https://')) {
return passUrlList.some(url => link.indexOf(url) !== -1);
}
return false;
},
onSaveTask() {
const { title, link, value, taskRateType, times } = this.data;
const { title, link, value, taskRateType, times, itemIds } = this.data;
if(!title) {
my.showToast({
type: 'fail',
......@@ -69,7 +95,7 @@ Component({
return;
}
if(!this.props.noLink && !this.validateLink(link)) {
if(this.props.hasLink && !this.validateLink(link)) {
my.showToast({
type: 'fail',
content: '请输入正确的链接地址'
......@@ -77,7 +103,15 @@ Component({
return;
}
if(!value) {
if(this.props.hasItems && itemIds) {
my.showToast({
type: 'fail',
content: '请输入选择商品'
})
return;
}
if(!value || !Number.isInteger(+value)) {
my.showToast({
type: 'fail',
content: '请输入正确的任务奖励'
......@@ -85,7 +119,11 @@ Component({
return;
}
this.props.onUpdate && this.props.onUpdate({ title, link, value, taskRateType, times, type: this.props.type })
let taskData = { title, link, value, taskRateType, times, itemIds, type: this.props.type };
this.props.onUpdate && this.props.onUpdate(taskData);
this.onCloseDialog();
}
},
......
{
"component": true,
"usingComponents": {
"dialog-wrap": "../../basic/dialiog-wrap/dialiog-wrap"
"dialog-wrap": "../../basic/dialiog-wrap/dialiog-wrap",
"items-config": "/components/task/items-config/items-config"
}
}
\ No newline at end of file
<view class="tb-imageUpload-wrap">
<image style="width:90px;height:90px;border:1px solid #ccc;margin-right:10px" src="{{prizeInitData.image}}"></image>
<image style="width:90px;height:90px;border:1px solid #ccc;margin-right:10px" src="{{url}}"></image>
<view class="tb-imageUpload-btn">
<view>图片</view>
<text>尺寸为{{imageLimit[0]}}px * {{imageLimit[1]}}px,格式为jpg/png</text>
......
import { chooseImage, getImageInfo, validateRangeNumber } from "/utils";
const { cloud } = getApp();
const { function: fc } = cloud;
Component({
mixins: [],
......@@ -7,7 +8,8 @@ Component({
props: {
imageLimit: [200, 200],
onSuccess: () => {},
onError: () => {}
onError: () => {},
url: '',
},
didMount() {},
didUpdate() {},
......@@ -35,9 +37,10 @@ Component({
fileName: path.split("/").pop(),
});
onSuccess && onSuccess(url)
} catch (error) {
console.error(error);
onError({}, error)
}
},
},
......
.items-config {
display: flex;
align-items: center;
height: 30px;
}
\ No newline at end of file
<view class="items-config">
<text style="font-size: 12px">{{itemIds ? `已选择${(itemIds + '').split(',')}个商品` : ''}} </text>
<button type="primary" text size="small" onTap="onOpenDialog">{{itemIds ? '更换商品' : '选择商品'}}</button>
<items-dialog
onUpdateBabyChoose="onUpdateBabyChoose"
browseItemIds="{{itemIds + ''}}"
a:if="{{visible}}"
showBaby="{{visible}}" onClose="onCloseDialog"/>
</view>
\ No newline at end of file
Component({
mixins: [],
data: {
visible: false
},
props: {
itemIds: '',
dataName: '',
onUpdate: () => {}
},
didMount() {},
didUpdate() {},
didUnmount() {},
methods: {
onOpenDialog() {
this.setData({
visible: true
})
},
onUpdateBabyChoose(ids) {
const { onUpdate, dataName } = this.props;
onUpdate && onUpdate(ids, dataName);
},
onCloseDialog() {
this.setData({
visible: false
})
}
},
});
{
"component": true,
"usingComponents": {
"items-dialog": "/components/dialog/items-dialog/items-dialog"
}
}
\ No newline at end of file
<view class="url-task">
<button size="small" type="primary" text="{{true}}" onTap="onOpenDialog" >{{taskData.title || '编辑任务'}}</button>
<task-dialog visible="{{visible}}" onClose="onClose" onUpdate="onUpdate" unit="炸弹" noLink="{{noLink}}"/>
<task-dialog
visible="{{visible}}"
a:if="{{visible}}"
onClose="onClose"
onUpdate="onUpdate"
unit="{{unit}}"
hasItems="{{hasItems}}"
hasLink="{{hasLink}}"
taskData="{{taskData}}"
/>
</view>
Component({
mixins: [],
data: {
visible: false,
visible: false
},
props: {
hasLink: false,
unit: '',
onUpdate: ()=> {},
taskData: {
title: ''
title: '',
taskRateType: 1,
times: '',
value: ''
},
dataName: ''
},
props: {
noLink: false
didMount() {
},
didMount() {},
didUpdate() {},
didUnmount() {},
methods: {
......@@ -24,9 +31,8 @@ Component({
})
},
onUpdate(taskData) {
this.setData({
taskData
})
const { onUpdate, dataName } = this.props;
onUpdate && onUpdate(taskData, dataName);
}
},
});
......@@ -72,6 +72,8 @@
<form-item
class="edit-content-form-item"
label="关注店铺"
validateState="{{formState['taskMap.attentionStore'].status}}"
help="{{formState['taskMap.attentionStore'].message}}"
asterisk="{{false}}">
<tb-config-input
textBefore="获得"
......@@ -87,38 +89,130 @@
<form-item
class="edit-content-form-item"
label="成为会员"
validateState="{{formState['taskMap.beMembership'].status}}"
help="{{formState['taskMap.beMembership'].message}}"
asterisk="{{false}}">
<tb-config-input
textBefore="获得"
textAfter="体力值"
validateRange="{{[1, 99]}}"
value="{{limitValue}}"
onChange="onConfigInputChange",
value="{{taskMap.beMembership.value}}"
dataName="taskMap.beMembership.value"
onChange="onTaskInputChange",
placeholder="1-99"
/>
</form-item>
<form-item
class="edit-content-form-item"
label="签到"
validateState="{{formState['taskMap.sign'].status}}"
help="{{formState['taskMap.sign'].message}}"
asterisk="{{false}}">
<tb-config-input
textBefore="每日签到获得"
textAfter="体力值"
validateRange="{{[1, 99]}}"
value="{{taskMap.sign.value}}"
dataName="taskMap.sign.value"
onChange="onTaskInputChange",
placeholder="1-99"
/>
</form-item>
<form-item
class="edit-content-form-item"
label="兑换参与次数"
validateState="{{formState['taskMap.exchangeCredits'].status}}"
help="{{formState['taskMap.exchangeCredits'].message}}"
asterisk="{{false}}">
<tb-config-input
textBefore="可消耗"
textAfter="积分兑换参与次数"
validateRange="{{[1, 99]}}"
value="{{taskMap.exchangeCredits.value}}"
dataName="taskMap.exchangeCredits.value"
onChange="onTaskInputChange",
placeholder="1-99"
/>
<view style="margin: 10px 0 0 0">
<tb-config-input
textBefore="每天最多可兑换"
textAfter="次"
validateRange="{{[1, 10]}}"
value="{{taskMap.exchangeCredits.times}}"
dataName="taskMap.exchangeCredits.times"
onChange="onTaskInputChange",
placeholder="1-10"
/>
</view>
</form-item>
<form-item
class="edit-content-form-item"
label="邀请好友"
validateState="{{formState['taskMap.inviteFriends'].status}}"
help="{{formState['taskMap.inviteFriends'].message}}"
asterisk="{{false}}">
<task-config noLink="{{true}}" type="inviteFriends"/>
<task-config
unit="体力值"
type="inviteFriends"
taskData="{{taskMap.inviteFriends}}"
dataName="taskMap.inviteFriends"
onUpdate="onTaskDialogChange"
/>
</form-item>
<form-item
class="edit-content-form-item"
label="浏览指定页面"
validateState="{{formState['taskMap.jumpLink'].status}}"
help="{{formState['taskMap.jumpLink'].message}}"
asterisk="{{false}}">
<task-config
unit="体力值"
type="jumpLink"
hasLink
taskData="{{taskMap.jumpLink}}"
dataName="taskMap.jumpLink"
onUpdate="onTaskDialogChange"
/>
</form-item>
<form-item
class="edit-content-form-item"
label="收藏商品"
validateState="{{formState['taskMap.collectGoods'].status}}"
help="{{formState['taskMap.collectGoods'].message}}"
asterisk="{{false}}">
<task-config
unit="体力值"
type="collectGoods"
hasLink
hasItems
taskData="{{taskMap.collectGoods}}"
dataName="taskMap.collectGoods"
onUpdate="onTaskDialogChange"
/>
</form-item>
<form-item
class="edit-content-form-item"
label="寻宝屋商品"
validateState="{{formState['taskMap.browseGoods'].status}}"
help="{{formState['taskMap.browseGoods'].message}}"
asterisk="{{false}}">
<task-config type="jumpLink"/>
<items-config itemIds="{{taskMap.browseGoods.itemIds}}" dataName="taskMap.browseGoods" onUpdate="onTaskChange"/>
</form-item>
<form-item
validateState="{{formState.logoImage.status}}"
help="{{formState.logoImage.message}}"
validateState="{{formState.image.status}}"
help="{{formState.image.message}}"
class="edit-content-form-item"
label="logo图片"
asterisk="{{false}}">
<tb-image-upload/>
<tb-image-upload url="{{image}}" onSuccess="onImageChange"/>
</form-item>
......@@ -161,7 +255,7 @@
class="edit-content-form-item"
label="淘口令图片"
asterisk="{{false}}">
<tb-image-upload/>
<tb-image-upload url="{{commandImg}}" onSuccess="onImageChange"/>
</form-item>
<view class="submit-btn">
......
......@@ -13,23 +13,9 @@ const THANKS_TYPE = 5
var validator = new schema(descriptor);
/**
*
* 1.任务相关
* 体力值 power
* 参与次数 gameTimes
* 粮食(牧草、水滴等) food
* 金币 coins
* 道具(炸弹、复活卡等) tools
*
*/
Component({
data: {
labelCol: {
fixedSpan: 5
},
labelCol: { fixedSpan: 5 },
id: '',
title: '',
subtitle: '',
......@@ -37,9 +23,9 @@ Component({
endTime: '',
timeRange: [],
rule: '',
limitValue: '',
prizeInfoList: [],
commandTitle: '',
commandImg: '',
beenInvitedText: '',
taskList:[
{
......@@ -103,13 +89,51 @@ Component({
taskMap: {
attentionStore: {
value: '',
}
},
beMembership: {
value:''
},
sign: {
value: ''
},
exchangeCredits: {
value: '',
times: '',
},
inviteFriends: {
title: '', // 任务标题
taskRateType: 1, // 任务频率类型
times: 3, // 任务为每日限次次数值
value: '', // 任务奖励
},
browseGoods: {
title: "",
taskRateType: 1,
times: 3,
value: '',
link: ''
},
collectGoods: {
title: "",
taskRateType: 1,
times: 3,
value: '90',
itemIds: "",
},
jumpLink: {
title: "",
taskRateType: 3,
link: "",//跳转链接
times: 3,
value: '',
},
},
image: '',
isEnd: false,
isStart: false,
originalStartTime: '',
prizeDialogData: {},
formState: formatValidator(validator.rules)
formState: formatValidator(descriptor)
},
props: {},
didMount() {
......@@ -136,7 +160,9 @@ Component({
originalStartTime: +rest.startTime,
isStart: +rest.startTime < Date.now(),
isEnd: +rest.endTime < Date.now(),
prizeInfoList: prizeInfoList && prizeInfoList.length > 0 ? prizeInfoList : this.data.prizeInfoList
prizeInfoList: prizeInfoList && prizeInfoList.length > 0 ? prizeInfoList : this.data.prizeInfoList,
taskList: rest.taskList,
taskMap: this.formatTaskListToMap(rest.taskList)
})
} catch (error) {
......@@ -146,33 +172,48 @@ Component({
onChange(e) {
const { value } = e.detail;
const { name } = e.target.dataset;
this.setDataByKey(name, value);
this.setData({
[name]: value
})
},
setDataByKey(name, val) {
const keys = name.split('.');
if(keys.length === 1) {
this.setData({
[{keys[0]]: val
[keys[0]]: val
})
}
if(keys.length === 2) {
let targetKey = this.data[{keys[0]];
let targetKey = this.data[keys[0]];
targetKey[keys[1]] = val;
let newVal = Object.assign({}, targetKey)
this.setData({
[{keys[0]]: targetKey
[keys[0]]: newVal
})
}
if(keys.length === 3) {
let targetKey = this.data[{keys[0]];
targetKey[keys[1]][eys[2]] = val;
let targetKey = this.data[keys[0]];
targetKey[keys[1]][keys[2]] = val;
let newVal = Object.assign({}, targetKey)
this.setData({
[{keys[0]]: targetKey
[keys[0]]: newVal
})
}
},
onTaskInputChange(e) {
const { name } = e.target.dataset;
let { taskMap } = this.data;
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({
image
})
},
onTimeChange(timeRange, error) {
const { formState } = this.data;
......@@ -201,6 +242,7 @@ Component({
const _this = this;
return new Promise((resolve, reject) => {
validator.validate(data, (errors, fields) => {
console.log(errors, fields)
const { formState } = _this.data;
_this.setFormTips(formState, errors, target)
if(errors) {
......@@ -236,18 +278,6 @@ Component({
},
// 提交信息
async onSubmit() {
const {
id,
activityId,
startTime,
endTime,
rule,
prizeInfoList,
joinTimesEveryday,
joinNeedCredits
} = this.data;
console.log(this.data)
const isValidForm = await this.validateForm(this.data);
......@@ -255,55 +285,6 @@ Component({
console.log('成功')
return;
if (!prizeInfoList.length) {
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 {
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)
......@@ -317,7 +298,6 @@ Component({
}).catch(err => {
console.log(err)
})
}
},
showFailToast(text) {
my.showToast({
......@@ -326,21 +306,60 @@ Component({
})
},
// 格式化参数
formatActivityParams({
formatActivityParams(params) {
const {
id,
activityId,
startTime,
endTime,
rule,
joinTimesEveryday,
joinNeedCredits,
prizeInfoList
}) {
prizeInfoList,
taskList,
taskMap,
commandTitle,
commandImg,
beenInvitedText,
} = params;
return {
activityId,
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 => {
let task = {
type,
...taskMap[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) => {
return total = addFloat(total, +next.probablity)
}, 0)
let prizeInfoListCopy = prizeInfoList.concat()
let prizeInfoListCopy = prizeInfoList.concat().map((v, index) => ({ ...v, level: index }));
if (totalPercent < 100) {
let thanksType = {
......@@ -350,15 +369,7 @@ Component({
}
prizeInfoListCopy.push(thanksType)
}
return {
activityId,
startTime: new Date(startTime).getTime(),
endTime: new Date(endTime).getTime(),
rule,
prizeInfoList: prizeInfoListCopy.map((v, index) => ({ ...v, level: index })),
joinTimesEveryday,
joinNeedCredits
}
return prizeInfoListCopy
},
cancelEdit() {
this.backList()
......@@ -426,24 +437,6 @@ Component({
},
backList() {
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
......@@ -11,6 +11,7 @@
"rank-config": "/components/rank/rank-config/rank-config",
"rank-table": "/components/rank/rank-table/rank-table",
"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'
export const descriptor = {
title: {
required: true,
......@@ -16,17 +19,74 @@ export const descriptor = {
},
timeRange: {
required: true
},
image: {
required: true,
message: "请上传正确的图片"
},
taskMap: {
type: 'object',
required: true,
fields: {
attentionStore: {
validator: (rule, val) => {
return !!val.value
},
message: '请输入关注店铺任务的奖励'
},
beMembership: {
validator: (rule, val) => !!val.value,
message: '请输入成为会员任务的奖励'
},
sign: {
validator: (rule, val) => !!val.value,
message: '请输入签到任务的奖励'
},
inviteFriends: {
validator: (rule, val) => !!(val.title && val.value),
message: '请输入邀请任务'
},
jumpLink: {
validator: (rule, val) => {
return !!(val.title && val.value && val.link);
},
message: '请输入浏览指定页面任务'
},
browseGoods: {
validator: (rule, val) => {
return !!(val.title && val.value && val.link);
},
message: '请输入寻宝屋商品任务'
},
exchangeCredits: {
validator: (rule, val) => {
return !!(val.value && val.times);
},
message: '请输入兑换次数任务'
}
}
}
};
export const formatValidator = descriptor => {
const validators = {}
export const formatValidator = (descriptor, validators) => {
validators = validators || {}
Object.keys(descriptor).forEach(key => {
if(descriptor[key].fields) {
Object.keys(descriptor[key].fields).forEach(fieldKey => {
validators[`${key}.${fieldKey}`] = {
status: 'success',
message: ''
}
})
} else {
validators[key] = {
status: 'success',
message: ''
}
}
});
return validators
}
\ No newline at end of file
......@@ -17,6 +17,7 @@ export const descriptor = {
export const formatValidator = descriptor => {
const validators = {}
Object.keys(descriptor).forEach(key => {
validators[key] = {
status: 'success',
......
export const activityType = 2;
\ No newline at end of file
//任务频率类型常量
export const TASK_RATE_TYPE = {
FOREVER: 1,
EVERYDAY: 2,
NOLIMIT: 3,
};
\ No newline at end of file
{
"runtime": "nodejs8",
"version": "1.0"
}
\ No newline at end of file
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,
};
This diff is collapsed.
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
}
\ No newline at end of file
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");
const {
openId,
accessToken,
appKey,
userNick,
appOwnerOpenId,
consumeMiniAppId,
} = context;
let ActivitySeller = new ActivitySellerService(context);
let ActivityTop = new ActivityTopService(context);
let ActivityInstance = new ActivityInstanceService(context);
try {
let hasResult = await ActivitySeller.findSellerInfo(context.openId);
let instanceOldInfo = await ActivityInstance.getMiniAppInstanceInfo(
context.openId
);
console.log(instanceOldInfo, "insabsajs");
if (!instanceOldInfo || !instanceOldInfo[0]) {
let instanceInfo = await ActivityTop.getTemplateInstantiate();
console.log(instanceInfo, "instanceInfo");
const { app_id, app_version } = instanceInfo;
if (instanceInfo) {
let onlineInstance = await ActivityTop.pushOnlineInstance({
app_id,
app_version,
});
console.log(
onlineInstance,
"onlineInstance",
onlineInstance.online_results
);
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,
openId,
appKey,
consumeMiniAppId,
userNick,
appOwnerOpenId,
});
} else {
return resultsModel.error(
CODE_TYPES.SYSTEM_ERROR,
"获取实例化信息失败"
);
}
} else {
console.log(instanceOldInfo[0]);
if (
TEMPLATE_INFO.template_version !== instanceOldInfo[0].template_version
) {
const { clients, app_id, template_id } = instanceOldInfo[0];
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,
});
}
}
if (hasResult && hasResult[0]) {
await ActivitySeller.updateSellerInfo(context.openId, {
accessToken,
});
await ActivityInstance.updateInstanceInfo(context.openId, {
accessToken,
});
return resultsModel.success(true);
} else {
let shopInfoResult = await ActivityTop.getShopId();
if (!shopInfoResult.success) {
return resultsModel.error(
CODE_TYPES.SYSTEM_ERROR,
"获取淘宝店铺信息失败"
);
}
try {
let result = await ActivitySeller.saveSellerInfo({
accessToken,
openId,
appKey,
shopId: shopInfoResult.data.sid,
userNick,
appOwnerOpenId,
});
return resultsModel.success(result);
} catch (e) {
console.log(e, "保存授权信息失败");
return resultsModel.error(CODE_TYPES.SYSTEM_ERROR, "保存授权信息失败");
}
}
} 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 + 1];
// 截取排行区间的分数排行列表
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;
{
"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: openId
}, {
$set: {
...updateinfo,
updateTime: Date.now()
}
})
}
async getMiniAppInstanceInfo(openId) {
return await this.activityinstanceDao.find({
openId
})
}
}
\ No newline at end of file
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 updateSellerInfo(openId, sellerInfo) {
console.log(openId, sellerInfo, 'openId, sellerInfo')
return await this.activitysellerDao.update({
openId: openId
}, {
$set: {
...sellerInfo,
updateTime: Date.now()
}
})
}
}
\ No newline at end of file
This diff is collapsed.
// 排行榜开奖记录
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,
};
// 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",
"browseGoods",
"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"] },
};
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,
};
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
{
"runtime": "nodejs8",
"version": "1.0"
}
\ No newline at end of file
const ACTIVITY_BASE_CONFIG = 'activity_base_config';
const ACTIVITY_PRIZE_CONFIG = 'activity_prize_config';
const ACTIVITY_SELLER_SAVE = 'activity_seller_save';
module.exports = {
ACTIVITY_BASE_CONFIG,
ACTIVITY_PRIZE_CONFIG,
ACTIVITY_SELLER_SAVE
}
\ No newline at end of file
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
};
\ No newline at end of file
const ActivityConfigService = require('../service/activityconfig.service')
const {
CODE_TYPES
} = require('../utils/constants')
const ResultsModel = require('../utils/results.model')
let resultsModel = new ResultsModel()
const {
DELETE_STATUS
} = require("../utils/constants");
let ActivityTopService = require('../service/activitytop.service');
const {
loginfo,
passUrlList
} = require('../utils/utils')
const Url = require('url')
//openId获取活动列表
const getActivityListByOpenId = async function (context) {
loginfo(context, 'getActivityListByOpenId')
let ActivityConfig = new ActivityConfigService(context);
try {
let result = await ActivityConfig.getActivityListByOpenId(
context.openId,
context.data
)
if (result) {
result.list.map(item => {
item.activityId = item._id;
return item;
})
return resultsModel.success(result)
}
return resultsModel.error(CODE_TYPES.SYSTEM_ERROR, '查询活动列表失败')
} catch (e) {
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);
const {
openId
} = context
let {
title,
subtitle,
activityId = '',
startTime,
endTime,
specifyPageUrl = '',
rule,
browseItemIds = '',
prizeInfoList = [],
attentionStore = false,
beMembership = false,
inviteFriends = false
} = 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 (!subtitle) {
return resultsModel.error(CODE_TYPES.PARAMS_ERROR, '活动副标题为空')
} else if (subtitle.length > 16) {
return resultsModel.error(CODE_TYPES.PARAMS_ERROR, '活动副标题不可超过16个字')
}
if (
!attentionStore &&
!beMembership &&
!inviteFriends &&
browseItemIds.length === 0 &&
specifyPageUrl.length === 0
) {
return resultsModel.error(CODE_TYPES.PARAMS_ERROR, '任务配置至少选择一项')
} else if (browseItemIds.split(',').length > 20) {
return resultsModel.error(CODE_TYPES.PARAMS_ERROR, '浏览宝贝最多选择20个商品')
}
if (specifyPageUrl) {
const specifyPageUrlParse = Url.parse(specifyPageUrl)
let urlHasPass = false
passUrlList.forEach(item => {
if (~specifyPageUrlParse.host.indexOf(item)) {
urlHasPass = true
}
})
console.log(specifyPageUrlParse.protocol, urlHasPass)
if (!specifyPageUrlParse.protocol || !urlHasPass) {
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 (+prizeInfoList[prizeInfoList.length - 1].rank.split('-') > 100) canPassPrize = false;
if (!canPassPrize) {
return resultsModel.error(CODE_TYPES.PARAMS_ERROR, '奖品配置不正确');
}
}
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, '开始时间不得大于结束时间')
}
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,
taskInfo: {
specifyPageUrl,
browseItemIds,
attentionStore,
beMembership,
inviteFriends
}
}
let result
console.log('activityId', activityId)
try {
if (!activityId) {
result = await ActivityConfig.saveNewActivity(
baseData,
prizeInfoList,
openId
)
} else {
let prizeInfoListNoId = prizeInfoList.map(item => {
item.activityId = activityId
item.updateTime = Date.now()
item.createTime = Date.now()
item.deleteStatus = DELETE_STATUS.EXIST
delete item._id
return item
})
// console.log(prizeInfoListNoId, 'prizeInfoListNoId')
result = await ActivityConfig.updateActivity(
activityId,
baseData,
prizeInfoListNoId
)
}
if (result) {
return resultsModel.success(true)
} else {
return resultsModel.error(CODE_TYPES.SYSTEM_ERROR, '保存活动失败')
}
} catch (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)
const {
taskInfo,
...rest
} = result.baseConfig
let prizeInfoList = result.prizeConfig.sort((a, b) => {
return a.rank.split('-')[0] - b.rank.split('-')[0]
})
let activityInfo = {
...taskInfo,
activityId,
...rest,
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
}
\ No newline at end of file
const {
formatTime
} = require('../utils/utils');
const {
CODE_TYPES
} = 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), "yyyy-MM-dd hh:mm:ss");
let endTimeDate = formatTime(new Date(+endTime), "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权益信息失败');
}
}
module.exports = {
findItemListByIdsAction,
findItemListByStatusAction,
getBenefitByEname
}
\ No newline at end of file
const ActivitySellerService = require('../service/activityseller.service');
const {
CODE_TYPES
} = require('../utils/constants');
const {
getSellerInfoByContext
} = require('../config/seller_config');
const ActivityTopService = require('../service/activitytop.service');
const {
loginfo
} = require('../utils/utils');
const ResultsModel = require('../utils/results.model');
let resultsModel = new ResultsModel();
//保存授权信息
module.exports = async (context) => {
loginfo(context, 'sellerInfo');
const {
openId,
accessToken,
appKey,
userNick,
appOwnerOpenId
} = context;
let ActivitySeller = new ActivitySellerService(context);
let ActivityTop = new ActivityTopService(context);
try {
let hasResult = await ActivitySeller.findSellerInfo(context.openId);
console.log(hasResult, 'hasSellerResult');
if (hasResult && hasResult[0]) {
await ActivitySeller.updateSellerInfo(context.openId, {
accessToken,
appKey,
userNick,
appOwnerOpenId
})
return resultsModel.success(true);
} else {
let shopInfoResult = await ActivityTop.getShopId();
if (!shopInfoResult.success) {
return resultsModel.error(CODE_TYPES.SYSTEM_ERROR, '获取淘宝店铺信息失败')
}
try {
let result = await ActivitySeller.saveSellerInfo({
accessToken,
openId,
appKey,
shopId: shopInfoResult.data.sid,
userNick,
appOwnerOpenId
})
return resultsModel.success(result);
} catch (e) {
console.log(e, '保存授权信息失败');
return resultsModel.error(CODE_TYPES.SYSTEM_ERROR, '保存授权信息失败');
}
}
} catch (e) {
console.log(e, '获取授权信息失败');
return resultsModel.error(CODE_TYPES.SYSTEM_ERROR, '获取授权信息失败');
}
}
\ No newline at end of file
/**
* 中奖名单 及导出中奖名单
*/
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/rankscan.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');
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.split('-')[1];
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.split('-');
// 截取排行区间的分数排行列表
let ranklist = topscoreList.slice(+rankPeriod[0] - 1, Math.min(+rankPeriod[1], totalAwards));
// 整合开奖数据
ranklist.map(rank => {
waitAwardslist.push({
activityId: v.activityId,
openId: rank.openId,
rank: v.rank,
ename: v.ename,
startTime: v.startTime,
endTime: v.endTime,
prizeId: v.goodsId,
prizeName: v.name,
userNick: rank.userNick,
rankTime: rank.updateTime,
image: v.image,
score: rank.score,
shopId: shopId
});
});
});
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 {
activityId,
_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(activityId);
console.log(`prizeList: ${JSON.stringify(prizeList)}; totalAwards: ${totalAwards}`);
// 没查找到奖品列表, 继续下个活动循环
if (!prizeList.length) {
// 开奖失败,记录日志
await rankscanService.update2Fail(_id, `活动不存在对应的奖品列表,开奖失败`);
results.fails.push(activityId);
continue;
}
// 查找排行榜分数榜里的前totalAwards个记录
let topscoreList = await rankscoreService.getToplistByActivityId(activityId, totalAwards);
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(activityId) : results.fails.push(activityId);
// end
}
return resultsModel.success(results);
}
module.exports = {
endingNotify
}
\ No newline at end of file
const ResultsModel = require('../utils/results.model');
const { CODE_TYPES } = require('../utils/constants');
const GameService = require("../service/game.service");
/**
* 获取游戏规则标题等相关配置
* @param {*} context
*/
const getGameInfo = async (context) => {
const { activityId,
nickName='暂无昵称' } = context.data;
if (!activityId) {
return new ResultsModel().error(CODE_TYPES.PARAMS_ERROR);
}
const gameService = new GameService(context);
return await gameService.getGameInfo(activityId,nickName);
}
module.exports = {
getGameInfo
}
\ No newline at end of file
const ResultsModel = require('../utils/results.model');
const { CODE_TYPES } = require('../utils/constants');
const ActivityprizeService = require("../service/activityprize.service");
const PrizeService = require("../service/prize.service");
/**
* 获取排行版下方奖品展示
* @param {*} context
*/
const getRankPrize = async (context) => {
let activityId = context.data.activityId;
if (!activityId) {
return new ResultsModel().error(CODE_TYPES.PARAMS_ERROR);
}
const activityprizeService = new ActivityprizeService(context);
let result = await activityprizeService.getPrizeListByActivityId(activityId);
let resultData = result.sort((a,b)=>{
return +a.rank.split("-")[0]>+b.rank.split("-")[0];
})
return new ResultsModel().success(resultData)
}
/**
* 获取我的奖品信息
* @param {*} context
*/
const getMyPrize = async (context) => {
let activityId = context.data.activityId;
if (!activityId) {
return new ResultsModel().error(CODE_TYPES.PARAMS_ERROR);
}
const prizeService = new PrizeService(context);
return await prizeService.getMyPrize(activityId);
}
/**
* 领奖
* @param {*} context
*/
const collectionPrize = async (context) => {
let {activityId, ename } = context.data;
if (!activityId || !ename) {
return new ResultsModel().error(CODE_TYPES.PARAMS_ERROR);
}
const prizeService = new PrizeService(context);
return await prizeService.collectionPrize(activityId,ename);
}
const getPrizeList = async(context)=>{
let {activityId } = context.data;
if (!activityId ) {
return new ResultsModel().error(CODE_TYPES.PARAMS_ERROR);
}
const prizeService = new PrizeService(context);
return await prizeService.getPrizeList(activityId);
}
module.exports = {
getRankPrize,
getMyPrize,
collectionPrize,
getPrizeList
}
const ResultsModel = require('../utils/results.model');
const { CODE_TYPES } = require('../utils/constants');
const RankService = require("../service/rank.service");
/**
* 提交分数
* @param {*} context
*/
const doScoreSubmit = async (context)=>{
let{
activityId,
score,
nickName,
avatar
} = context.data;
if(!activityId || !score || !nickName || !avatar)
{
return new ResultsModel().error(CODE_TYPES.PARAMS_ERROR);
}
const rankService=new RankService(context);
return await rankService.doScoreSubmit(activityId,score,nickName,avatar);
}
/**
* 获取排行
* @param {*} context
*/
const getRankList = async(context)=>{
let{
activityId,
page=1,
limit=10
} = context.data;
if(!activityId)
{
return new ResultsModel().error(CODE_TYPES.PARAMS_ERROR);
}
const rankService=new RankService(context);
return await rankService.getRankList(activityId,page,limit);
}
module.exports={
doScoreSubmit,getRankList
}
\ No newline at end of file
const ResultsModel = require('../utils/results.model');
const { CODE_TYPES } = require('../utils/constants');
const ShareService = require("../service/share.service");
/**
* 获取分享id
* @param {*} context
*/
const getShareId = async (context)=>{
let{
activityId
} = context.data;
if(!activityId )
{
return new ResultsModel().error(CODE_TYPES.PARAMS_ERROR);
}
const shareService=new ShareService(context);
return await shareService.getShareId(activityId);
}
/**
* 验证分享
* @param {*} context
*/
const doShareComplete = async(context)=>{
let{
activityId,
shareId
} = context.data;
if(!activityId || !shareId)
{
return new ResultsModel().error(CODE_TYPES.PARAMS_ERROR);
}
const shareService=new ShareService(context);
return await shareService.doShareComplete(activityId,shareId);
}
module.exports={
getShareId,doShareComplete
}
\ No newline at end of file
const ResultsModel = require('../utils/results.model');
const { CODE_TYPES } = require('../utils/constants');
const StatExportService = require('../service/statexport.service');
const statTotalData = async(context)=>{
let activityId=context.data.activityId;
if(!activityId)
{
return new ResultsModel().error(CODE_TYPES.PARAMS_ERROR);
}
const statExportService=new StatExportService(context);
return await statExportService.statTotalData(activityId);
}
const statJoinData = async(context)=>{
let activityId=context.data.activityId;
if(!activityId)
{
return new ResultsModel().error(CODE_TYPES.PARAMS_ERROR);
}
const statExportService=new StatExportService(context);
return await statExportService.statJoinData(activityId);
}
const statTaskData = async(context)=>{
let activityId=context.data.activityId;
if(!activityId)
{
return new ResultsModel().error(CODE_TYPES.PARAMS_ERROR);
}
const statExportService=new StatExportService(context);
return await statExportService.statTaskData(activityId);
}
const statItemData = async(context)=>{
let activityId=context.data.activityId;
if(!activityId)
{
return new ResultsModel().error(CODE_TYPES.PARAMS_ERROR);
}
const statExportService=new StatExportService(context);
return await statExportService.statItemData(activityId);
}
const statPrizeData = async(context)=>{
let activityId=context.data.activityId;
if(!activityId)
{
return new ResultsModel().error(CODE_TYPES.PARAMS_ERROR);
}
const statExportService=new StatExportService(context);
return await statExportService.statPrizeData(activityId);
}
module.exports = {statTotalData,statJoinData,statTaskData,statItemData,statPrizeData}
\ No newline at end of file
const ResultsModel = require('../utils/results.model');
const { CODE_TYPES } = require('../utils/constants');
const StatItemService = require('../service/statitem.service');
const itemShow = async(context)=>{
let activityId=context.data.activityId;
if(!activityId)
{
return new ResultsModel().error(CODE_TYPES.PARAMS_ERROR);
}
const statItemService=new StatItemService(context);
return await statItemService.itemShow(activityId);
}
const itemTap = async(context)=>{
let activityId=context.data.activityId;
if(!activityId)
{
return new ResultsModel().error(CODE_TYPES.PARAMS_ERROR);
}
const statItemService=new StatItemService(context);
return await statItemService.itemTap(activityId);
}
module.exports = {itemShow,itemTap}
\ No newline at end of file
const ResultsModel = require('../utils/results.model');
const { CODE_TYPES } = require('../utils/constants');
const TaskService = require("../service/task.service");
/**
* 获取任务列表
* @param {} context
*/
const getTaskList=async(context)=>{
let{
activityId
} = context.data;
if(!activityId )
{
return new ResultsModel().error(CODE_TYPES.PARAMS_ERROR);
}
const taskService=new TaskService(context);
return await taskService.getTaskList(activityId);
}
/**
* 完成任务
* @param {*} context
*/
const doTaskComplete= async(context)=>{
let{
activityId,
taskName
} = context.data;
if(!activityId )
{
return new ResultsModel().error(CODE_TYPES.PARAMS_ERROR);
}
const taskService=new TaskService(context);
return await taskService.doTaskComplete(activityId,taskName);
}
/**
* 检查会员
* @param {*} context
*/
const checkMember= async(context)=>{
let{
activityId
} = context.data;
if(!activityId )
{
return new ResultsModel().error(CODE_TYPES.PARAMS_ERROR);
}
const taskService=new TaskService(context);
return await taskService.checkMember(activityId);
}
module.exports={
getTaskList,doTaskComplete,checkMember
}
\ No newline at end of file
const ResultsModel = require('../utils/results.model');
const { CODE_TYPES } = require('../utils/constants');
const UserService = require("../service/user.service");
/**
* 用户登录
*/
const login = async (context) => {
let { activityId,
avatar,
nickName,
isFavor
} = context.data;
if (!activityId || !avatar || !nickName || isFavor == undefined) {
return new ResultsModel().error(CODE_TYPES.PARAMS_ERROR);
}
let userService = new UserService(context);
return await userService.login(activityId, nickName, avatar,isFavor);
}
/**
* 获取体力值
* @param {*} context
*/
const getPower = async (context) => {
let activityId = context.data.activityId;
if (!activityId) new ResultsModel().error(CODE_TYPES.PARAMS_ERROR_2C);
let userService = new UserService(context);
return await userService.getPower(activityId);
}
/**
* 开始游戏
* @param {*} context
*/
const startGame = async (context) => {
let {activityId,nickName='暂无昵称'} = context.data;
if (!activityId ) new ResultsModel().error(CODE_TYPES.PARAMS_ERROR_2C);
let userService = new UserService(context);
return await userService.startGame(activityId,nickName);
}
module.exports = {
login,
getPower,
startGame
}
\ No newline at end of file
class BaseDao {
constructor(context, dbName) {
this.db = context.cloud.db;
this.dbName = dbName;
this.openId = context.openId;
this.context = context;
}
async find(query, options) {
console.log(`query: ${JSON.stringify(query)}`)
console.log(`options: ${JSON.stringify(options)}`)
return await this.db.collection(this.dbName).find(query, options);
}
async findOne(query, options) {
console.log(`query: ${JSON.stringify(query)}`)
console.log(`options: ${JSON.stringify(options)}`)
const result = await this.db.collection(this.dbName).find(query, options);
if(result.length)return result[0];
return null;
}
// 更新数据
async update(query, options) {
return await this.db.collection(this.dbName).updateMany(query, options);
}
//插入单条数据
async insertOne(options) {
return await this.db.collection(this.dbName).insertOne(options);
}
async count(query) {
return await this.db.collection(this.dbName).count(query);
}
async deleteMany(query) {
return await this.db.collection(this.dbName).deleteMany(query);
}
// options Array
async insertMany(options) {
return await this.db.collection(this.dbName).insertMany(options);
}
}
module.exports = BaseDao;
\ No newline at end of file
const ACTIVITY_BASE_CONFIG = 'activity_base_config';
const ACTIVITY_PRIZE_CONFIG = 'activity_prize_config';
const ACTIVITY_SELLER_SAVE = 'activity_seller_save';
module.exports = {
ACTIVITY_BASE_CONFIG,
ACTIVITY_PRIZE_CONFIG,
ACTIVITY_SELLER_SAVE
}
\ No newline at end of file
const {
endingNotify
} = require('./controller/endingNodify.controller');
const {
findWinnerInfoList,
exportAwardsList
} = require('./controller/awards.controller');
const {
login,
getPower,
startGame
} = require('./controller/user.controller');
const {
doScoreSubmit,
getRankList
} = require('./controller/rank.controller');
const {
getShareId,
doShareComplete
} = require('./controller/share.controller');
const {
getTaskList,
doTaskComplete,
checkMember
} = require('./controller/task.controller');
const {
getGameInfo
} = require('./controller/game.controller');
const {
getRankPrize,
getMyPrize,
collectionPrize,
getPrizeList
} = require('./controller/prize.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,
getVipUrlAction
} = require("./controller/activitygettbitem.controller");
const {
statTotalData,
statJoinData,
statTaskData,
statItemData,
statPrizeData
} = require("./controller/statexport.controller");
const{
itemShow,
itemTap
}=require("./controller/statitem.controller");
//数据统计相关
exports.statTotalData = statTotalData;
exports.statJoinData = statJoinData;
exports.statTaskData = statTaskData;
exports.statItemData = statItemData;
exports.statPrizeData=statPrizeData;
exports.itemShow = itemShow;
exports.itemTap=itemTap;
// 定时开奖
exports.endingNotify = endingNotify;
// 活动中奖名单
exports.findWinnerInfoList = findWinnerInfoList;
// 导出中奖名单
exports.exportAwardsList = exportAwardsList;
exports.login = login;
exports.getPower = getPower;
exports.startGame = startGame;
exports.doScoreSubmit = doScoreSubmit;
exports.getRankList = getRankList;
exports.getShareId = getShareId;
exports.doShareComplete = doShareComplete;
exports.getTaskList = getTaskList;
exports.doTaskComplete = doTaskComplete;
exports.checkMember=checkMember;
exports.getGameInfo = getGameInfo;
exports.getRankPrize = getRankPrize;
exports.getMyPrize = getMyPrize;
exports.collectionPrize = collectionPrize;
exports.getPrizeList = getPrizeList;
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;
This diff is collapsed.
{
"name": "duiba",
"version": "1.0.0",
"description": "",
"main": "index.js",
"author": "",
"license": "ISC",
"sdkVersion": "*",
"dependencies": {
"node-xlsx": "^0.15.0"
},
"config": {
"notNeedLogin": ["endingNotify"]
}
}
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
};
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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