Commit 7bc8cef5 authored by 秦海涛's avatar 秦海涛

update

parent fbd674d0
...@@ -9,6 +9,8 @@ const API = { ...@@ -9,6 +9,8 @@ const API = {
delActivity: (params) => request("delActivity", "POST", params), delActivity: (params) => request("delActivity", "POST", params),
// 授权信息保存 sellerSave // 授权信息保存 sellerSave
sellerSave: (params) => request("sellerSave", "POST", params), sellerSave: (params) => request("sellerSave", "POST", params),
// 生成活动规则 generateRule
generateRule: params => request('generateRule', 'POST', params),
// 获取中奖名单 findWinnerInfoList // 获取中奖名单 findWinnerInfoList
findWinnerInfoList: (params) => request("findWinnerInfoList", "POST", params), findWinnerInfoList: (params) => request("findWinnerInfoList", "POST", params),
// 获取活动列表云函数 getActivityList // 获取活动列表云函数 getActivityList
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
min-width: 180px; min-width: 180px;
min-height: calc(100vh - 50px); min-height: calc(100vh - 50px);
background-color: #fff; background-color: #fff;
position: relative;
} }
.db-infos { .db-infos {
width: 100%; width: 100%;
...@@ -32,3 +33,45 @@ ...@@ -32,3 +33,45 @@
.db-menu-list_active { .db-menu-list_active {
background:rgba(235,243,255,1); background:rgba(235,243,255,1);
} }
.db-side-bar .expireTime {
color: red;
margin-top: 12px;
display: block;
}
.db-side-bar .renevwal {
font-size: 13px;
width:150px;
height:38px;
line-height:38px;
color: white;
display: block;
margin: 0 auto;
text-align: center;
background:rgba(51,134,241,1);
border-radius:19px;
}
.db-side-bar .bottom {
width:150px;
left: 50%;
transform: translateX(-50%);
text-align: center;
position: absolute;
bottom: 38px
}
.db-side-bar .help {
color: rgb(51, 134, 241);
margin-top: 20px;
font-size: 14px;
text-align:center;
display: flex;
justify-content: space-between;
}
.db-side-bar .help text {
cursor: pointer;
}
\ No newline at end of file
...@@ -10,4 +10,20 @@ ...@@ -10,4 +10,20 @@
</view> </view>
</view> </view>
<view class="bottom">
<view style="margin-bottom: 20px; font-size: 14px" a:if="{{time}}">
<view style="font-size: 16px; color: #333333">{{time}} 到期</view>
<text a:if="{{diffDay <= 10 && diffDay > 0}}" class="expireTime" style="color: #FFA033">剩余{{diffDay}}天到期</text>
<text a:if="{{diffDay === 0}}" class="expireTime">今天到期</text>
<text a:if="{{diffDay < 0 }}" class="expireTime">已过期</text>
</view>
<view class="renevwal" onTap="renevwal" type="primary">软件续费</view>
<view class="help">
<text onTap="service">联系客服</text>
<text style="color: #D7DBE0">|</text>
<text onTap="help">帮助文档</text>
</view>
</view>
</view> </view>
\ No newline at end of file
const { cloud } = getApp()
const { function: fc } = cloud
import dayjs from 'dayjs';
Component({ Component({
mixins: [], mixins: [],
data: {}, data: {
dingNumber: '30549862',
diffDay: '',
time: ''
},
props: { props: {
info: () => { info: () => {
return { return {
...@@ -9,16 +17,83 @@ Component({ ...@@ -9,16 +17,83 @@ Component({
logo: '//yun.duiba.com.cn/duiba_miniProgram/logo.png' logo: '//yun.duiba.com.cn/duiba_miniProgram/logo.png'
} }
}, },
deadline: '',
activeKey: '', activeKey: '',
onMenuChange: () => {} onMenuChange: () => {}
}, },
didMount() {}, didMount() {
didUpdate() {}, this.setValidTime()
},
didUpdate(props, newProps) {
console.log(props, newProps);
},
didUnmount() {}, didUnmount() {},
methods: { methods: {
handleMenuClick(event) { handleMenuClick(event) {
let { key, path } = event.target.dataset; let { key, path } = event.target.dataset;
this.props.onMenuChange({ key, path }); this.props.onMenuChange({ key, path });
},
setValidTime() {
const { deadline } = this.props;
let time
let diffDay
if (deadline) {
diffDay = dayjs(deadline).diff(+new Date(), 'd')
time = dayjs(deadline).format('YYYY-MM-DD')
this.setData({ diffDay, time })
}
},
help() {
my.qn.navigateToWebPage({
url: "https://www.yuque.com/pangkaifeng/gfpf5s",
success: res => {
},
fail: res => {
} }
})
},
renevwal() {
my.qn.navigateToWebPage({
url: "https://fuwu.taobao.com/ser/detail.htm?service_code=FW_GOODS-1001068300&tracelog=search&from_key=%E6%98%9F%E7%90%83%E5%A4%A7%E4%BD%9C%E6%88%98",
success: res => {
},
fail: res => {
}
})
},
service() {
// my.qn.navigateToWebPage({
// url: "http://amos.alicdn.com/getcid.aw?v=2&uid=%E6%9D%AD%E5%B7%9E%E5%85%91%E5%95%8A&site=cntaobao&s=1&groupid=0&charset=utf-8",
// success: res => {
// },
// fail: res => {
// }
// })
const { dingNumber } = this.data
my.alert({
title: '钉钉商家群',
content: dingNumber,
buttonText: '复制',
success: () => {
my.setClipboard({
text: dingNumber,
success: () => {
my.showToast({
type: 'success',
content: '复制成功'
})
}
})
},
})
},
}, },
}); });
...@@ -11,9 +11,8 @@ ...@@ -11,9 +11,8 @@
<form-item style="width:100%" size="large" class="probablity-prize-content-formItem" label="奖品类型" required> <form-item style="width:100%" size="large" class="probablity-prize-content-formItem" label="奖品类型" required>
<view class="probablity-prize-content-formitem-choosePrize-wrap"> <view class="probablity-prize-content-formitem-choosePrize-wrap">
<select onChange="onPrizeTypeChange" defaultValue="{{isEdit ? prizeDialogData.record.type : prizeInitData.type}}"> <select onChange="onPrizeTypeChange" defaultValue="{{isEdit ? prizeDialogData.record.type : prizeInitData.type}}">
<option value="1">优惠券</option> <option value="{{1}}">优惠券</option>
<option value="3">实物</option> <option value="{{3}}">实物</option>
<option value="2">积分</option>
</select> </select>
</view> </view>
</form-item> </form-item>
......
...@@ -13,7 +13,6 @@ const THANKS_TYPE = 4; ...@@ -13,7 +13,6 @@ const THANKS_TYPE = 4;
const INIT_DATA = { const INIT_DATA = {
ename: "", ename: "",
id: "",
stock: "", stock: "",
type: 1, type: 1,
image: "", image: "",
...@@ -128,7 +127,7 @@ Component({ ...@@ -128,7 +127,7 @@ Component({
prizeInitData: { prizeInitData: {
...that.data.prizeInitData, ...that.data.prizeInitData,
name: benefitName, name: benefitName,
type: rightTypeId, type: +rightTypeId,
startTime, startTime,
endTime, endTime,
stock: stock stock: stock
...@@ -150,24 +149,24 @@ Component({ ...@@ -150,24 +149,24 @@ Component({
plugin.setBridge(bridge); plugin.setBridge(bridge);
}, },
// 编辑更换类型时重置数据 // 编辑更换类型时重置数据
resetPrizeData(type) { resetPrizeData(type, rank) {
this.setData({ this.setData({
prizeInitData: { prizeInitData: {
...INIT_DATA, ...INIT_DATA,
type type,
rank
}, },
}); });
}, },
onPrizeTypeChange(e) { onPrizeTypeChange(e) {
let value = e.detail.value; let value = e.detail.value;
const { type } = this.data.prizeInitData; const { type, rank } = this.data.prizeInitData;
let initData = { let initData = {
ename: "", ename: "",
id: "",
stock: "", stock: "",
useStock: "", useStock: "",
type: value, type: +value,
image: "", image: "",
credits: "", credits: "",
probablity: "", probablity: "",
...@@ -175,7 +174,7 @@ Component({ ...@@ -175,7 +174,7 @@ Component({
limitStock: 0 limitStock: 0
}; };
if(type !== value) { if(type !== value) {
this.resetPrizeData(value); this.resetPrizeData(+value, rank);
return; return;
} }
this.setData({ this.setData({
...@@ -237,6 +236,7 @@ Component({ ...@@ -237,6 +236,7 @@ Component({
let imgBool = ~path.indexOf(".png") || ~path.indexOf(".jpg"); let imgBool = ~path.indexOf(".png") || ~path.indexOf(".jpg");
if (height !== imageLimit[1] || width !== imageLimit[0] || !imgBool) { if (height !== imageLimit[1] || width !== imageLimit[0] || !imgBool) {
this.showItemTips("imageTips", "error", "请按要求上传图片"); this.showItemTips("imageTips", "error", "请按要求上传图片");
return;
} else { } else {
this.showItemTips("imageTips", "success", ""); this.showItemTips("imageTips", "success", "");
} }
...@@ -376,20 +376,20 @@ Component({ ...@@ -376,20 +376,20 @@ Component({
} }
const isEquietyPass = const isEquietyPass =
type == EQUITY_TYPE && type == EQUITY_TYPE &&
name && name.trim() &&
isImagePass && isImagePass &&
ename && ename &&
probablityTips.status !== "error"; probablityTips.status !== "error";
const isObjectPass = const isObjectPass =
type == OBJECT_TYPE && type == OBJECT_TYPE &&
name && name.trim() &&
stockPass && stockPass &&
isImagePass && isImagePass &&
probablityTips.status !== "error" && probablityTips.status !== "error" &&
prizeNumberTips.status !== "error" prizeNumberTips.status !== "error"
const isCreditsPass = const isCreditsPass =
type == CREDITS_TYPE && type == CREDITS_TYPE &&
name && name.trim() &&
credits && credits &&
isImagePass && isImagePass &&
probablityTips.status !== "error" && probablityTips.status !== "error" &&
...@@ -410,6 +410,7 @@ Component({ ...@@ -410,6 +410,7 @@ Component({
}; };
if(isEdit) { if(isEdit) {
console.log(prizeData, '--prizeData--')
onUpdate && onUpdate(prizeData, prizeDialogData.index); onUpdate && onUpdate(prizeData, prizeDialogData.index);
} else { } else {
onAdd && onAdd(prizeData) onAdd && onAdd(prizeData)
......
...@@ -5,27 +5,27 @@ ...@@ -5,27 +5,27 @@
width="800" width="800"
> >
<view class="rank-dialog-wrap"> <view class="rank-dialog-wrap">
<view class="other-winner-list"> <!-- <view class="other-winner-list">
<button type="text">导出其它中奖名单</button> <button type="text">导出其它中奖名单</button>
</view> </view> -->
<tab shape="wrapped"> <!-- <tab shape="wrapped">
<tab-item <tab-item
a:for="{{tabs}}" a:for="{{tabs}}"
title="{{item.tab}}" title="{{item.tab}}"
key="{{item.key}}" key="{{item.key}}"
> > -->
<view class="now-winner-list"> <view class="now-winner-list">
<button type="primary">导出本期中奖名单</button> <button type="primary">导出中奖名单</button>
</view> </view>
<table dataSource="{{dataSource}}"> <table dataSource="{{dataSource}}">
<table-column a:for="{{columns}}" title="{{item.title}}" dataIndex="{{item.prop}}"/> <table-column a:for="{{columns}}" a:key="*this" title="{{item.title}}" dataIndex="{{item.prop}}"/>
</table> </table>
<view class="rank-pagination"> <view class="rank-pagination">
<text class="rank-pagination-text">共{{pageInfo.total}}条</text> <text class="rank-pagination-text">共{{pageInfo.total}}条</text>
<pagination shape="arrow-only" hideOnlyOnePage="true" defaultCurrent="1" current="{{pageInfo.pageNo}}" pageSize="{{pageInfo.pageSize}}" onChange="changePagination" pageShowCount="100" total="{{pageInfo.total}}" /> <pagination shape="arrow-only" hideOnlyOnePage="true" defaultCurrent="1" current="{{pageInfo.pageNo}}" pageSize="{{pageInfo.pageSize}}" onChange="changePagination" pageShowCount="100" total="{{pageInfo.total}}" />
</view> </view>
</tab-item> <!-- </tab-item>
</tab> </tab> -->
</view> </view>
</dialog-wrap> </dialog-wrap>
\ No newline at end of file
import {
findWinnerInfoList,
uploadDataCreateFile,
} from "/api";
import { appId } from "/config";
import { setClipboard } from "/utils";
Component({ Component({
mixins: [], mixins: [],
data: { data: {
...@@ -45,9 +53,52 @@ Component({ ...@@ -45,9 +53,52 @@ Component({
total: 0 total: 0
} }
}, },
props: {}, props: {
avtivityId: '',
},
didMount() {}, didMount() {},
didUpdate() {}, didUpdate() {},
didUnmount() {}, didUnmount() {},
methods: {}, methods: {
async getWinnerList() {
const { avtivityId } = this.props;
const { data } = await findWinnerInfoList({
avtivityId
})
this.setData({
dataSource: data
})
},
// 导出中奖名单
async exportWinnerList(evt) {
const { avtivityId } = this.props;
const { type } = evt.target.dataset;
my.showLoading({ content: "生成文件中..." });
try {
const { success, data, message } = await uploadDataCreateFile({
activityId,
isObject: false,
});
my.hideLoading();
if (success) {
await setClipboard({ text: data.url.replace(/amp;/g, "") });
this.setData({
exportDialogVisible: true,
exportUrl: data.url.replace(/amp;/g, "")
})
} else {
my.showToast({
type: "fail",
content: message,
});
}
} catch (error) {
my.hideLoading();
console.log(error, "exportList-error");
}
},
},
}); });
...@@ -119,7 +119,7 @@ Component({ ...@@ -119,7 +119,7 @@ Component({
return; return;
} }
let taskData = { title, link, value, taskRateType, times, itemIds, type: this.props.type }; let taskData = { ...this.props.taskData, title, link, value, taskRateType, times, itemIds, type: this.props.type };
this.props.onUpdate && this.props.onUpdate(taskData); this.props.onUpdate && this.props.onUpdate(taskData);
......
...@@ -17,3 +17,8 @@ ...@@ -17,3 +17,8 @@
margin-bottom:5px; margin-bottom:5px;
color:#666666 color:#666666
} }
.upload-image-error {
font-size: 12px;
color: red;
margin: 10px 0 0 0;
}
\ No newline at end of file
...@@ -7,3 +7,4 @@ ...@@ -7,3 +7,4 @@
<button onTap="uploadImage" type="primary">上传图片</button> <button onTap="uploadImage" type="primary">上传图片</button>
</view> </view>
</view> </view>
<view class="upload-image-error" a:if="{{isError}}">请上传尺寸为{{imageLimit[0]}}px * {{imageLimit[1]}}px的图片</view>
\ No newline at end of file
...@@ -4,7 +4,9 @@ const { function: fc } = cloud; ...@@ -4,7 +4,9 @@ const { function: fc } = cloud;
Component({ Component({
mixins: [], mixins: [],
data: {}, data: {
isError: false
},
props: { props: {
imageLimit: [200, 200], imageLimit: [200, 200],
onSuccess: () => {}, onSuccess: () => {},
...@@ -17,7 +19,7 @@ Component({ ...@@ -17,7 +19,7 @@ Component({
didUnmount() {}, didUnmount() {},
methods: { methods: {
async uploadImage() { async uploadImage() {
const { onSuccess, onError, dataName } = this.props; const { onSuccess, onError, dataName, imageLimit } = this.props;
try { try {
const res = await chooseImage(); const res = await chooseImage();
...@@ -28,9 +30,16 @@ Component({ ...@@ -28,9 +30,16 @@ Component({
}); });
let imgBool = ~path.indexOf(".png") || ~path.indexOf(".jpg"); let imgBool = ~path.indexOf(".png") || ~path.indexOf(".jpg");
if (height !== 300 || width !== 300 || !imgBool) { if (height !== imageLimit[1] || width !== imageLimit[0] || !imgBool) {
onError && onError({height, width, type, path }) onError && onError({height, width, type, path })
this.setData({
isError: true
})
return;
} }
this.setData({
isError: false
})
const { url } = await cloud.file.uploadFile({ const { url } = await cloud.file.uploadFile({
filePath: res.apFilePaths[0], filePath: res.apFilePaths[0],
......
...@@ -14,10 +14,11 @@ ...@@ -14,10 +14,11 @@
<table-column title="操作" dataIndex="id" alignHeader="left"> <table-column title="操作" dataIndex="id" alignHeader="left">
<view slot-scope="x"> <view slot-scope="x">
<button a:if="{{buttons.includes('edit')}}" class="tb-list-edit" onTap="handleClickEdit" type="primary" text="true" data-x="{{x}}" >编辑活动</button> <button a:if="{{buttons.includes('edit')}}" class="tb-list-edit" onTap="handleClickEdit" type="primary" text="true" data-x="{{x}}" >编辑活动</button>
<button a:if="{{buttons.includes('export')}}" class="tb-list-edit" type="primary" text="true" data-x="{{x}}" data-type="object" onTap="exportWinnerList">导出实物中奖名单</button> <button a:if="{{buttons.includes('export')}}" class="tb-list-edit" type="primary" text="true" data-x="{{x}}" disabled="{{!x.record.isEnd}}" data-type="object" onTap="exportWinnerList">查看中奖名单</button>
<button a:if="{{buttons.includes('delete')}}" class="tb-list-edit" type="primary" text="true" data-x="{{x}}" onTap="handleTapDelete">删除</button> <button a:if="{{buttons.includes('delete')}}" class="tb-list-edit" type="primary" text="true" data-x="{{x}}" onTap="handleTapDelete">删除</button>
<button a:if="{{buttons.includes('copyLink')}}" class="tb-list-edit" type="primary" text="true" data-x="{{x}}" onTap="onCopyLink">复制活动链接</button> <button a:if="{{buttons.includes('copyLink')}}" class="tb-list-edit" type="primary" text="true" data-x="{{x}}" onTap="onCopyLink">复制活动链接</button>
<button a:if="{{buttons.includes('copyNewActivity')}}" class="tb-list-edit" type="primary" text="true" data-x="{{x}}" onTap="onCreateNewActivity">复制新活动</button> <button a:if="{{buttons.includes('copyNewActivity')}}" class="tb-list-edit" type="primary" text="true" data-x="{{x}}" onTap="onCreateNewActivity">复制新活动</button>
<button class="tb-list-edit" type="primary" text="true" data-x="{{x}}" onTap="toDataPage">活动数据</button>
</view> </view>
</table-column> </table-column>
</table> </table>
......
...@@ -66,6 +66,8 @@ Component({ ...@@ -66,6 +66,8 @@ Component({
let formatList = list.map((i) => { let formatList = list.map((i) => {
return { return {
...i, ...i,
isEnd: +i.endTime < Date.now(),
isStart: +i.startTime < Date.now(),
startTime: dayjs(+i.startTime).format("YYYY-MM-DD HH:mm:ss"), startTime: dayjs(+i.startTime).format("YYYY-MM-DD HH:mm:ss"),
endTime: dayjs(+i.endTime).format("YYYY-MM-DD HH:mm:ss"), endTime: dayjs(+i.endTime).format("YYYY-MM-DD HH:mm:ss"),
}; };
...@@ -119,6 +121,10 @@ Component({ ...@@ -119,6 +121,10 @@ Component({
type: "fail", type: "fail",
}); });
} }
},
toDataPage(evt) {
const { activityId } = evt.target.dataset.x.record;
this.$page.$router.push(`/activity/data/${activityId}`);
}, },
// 点击列表删除 // 点击列表删除
handleTapDelete(evt) { handleTapDelete(evt) {
......
...@@ -27,10 +27,23 @@ ...@@ -27,10 +27,23 @@
font-size: 12px; font-size: 12px;
margin: 0 4px 0 0; margin: 0 4px 0 0;
} }
.rank-add-icons {
width: 42px;
height: 42px;
border: 1px dashed #C9CED4;
display: flex;
justify-content: center;
align-items: center;
margin: 0 6px 0 0;
}
.tb-rank-table-prize-image { .tb-rank-table-prize-image {
display: flex; display: flex;
align-items: center; align-items: center;
} }
.tb-rank-table-prize-image_empty {
display: flex;
align-items: center;
}
.edit-content-formItem-addTableList { .edit-content-formItem-addTableList {
height: 54px; height: 54px;
......
...@@ -13,12 +13,19 @@ ...@@ -13,12 +13,19 @@
<view a:if="{{x.record.image}}"> <view a:if="{{x.record.image}}">
<image style="width:42px;height:42px;margin: 0 6px 0 0" src="{{x.record.image}}"></image> <image style="width:42px;height:42px;margin: 0 6px 0 0" src="{{x.record.image}}"></image>
</view> </view>
<view class="tb-rank-table-prize-image_empty" a:else>
<view class="rank-add-icons" onTap="onEditPrize" data-x="{{x}}" >
<icon size="xs" type="add" style="color: #ccc;" />
</view>
<view>奖品名称</view>
</view>
<view>{{x.record.name}} </view> <view>{{x.record.name}} </view>
</view> </view>
</table-column> </table-column>
<table-column title="操作"> <table-column title="操作">
<text class="tb-rank-table-operate" onTap="onEditPrize" data-x="{{x}}" data-name="edit" slot-scope="x">编辑</text> <text class="tb-rank-table-operate" onTap="onEditPrize" data-x="{{x}}" data-name="edit" slot-scope="x">{{x.record.name ? `编辑`: ''}}</text>
<text slot-scope="x" class="tb-rank-table-operate edit-content-formItem-delete" onTap="handleDeleteClick" data-x="{{x}}" slot-scope="x">删除</text> <text slot-scope="x" class="tb-rank-table-operate edit-content-formItem-delete" onTap="handleDeleteClick" data-x="{{x}}" slot-scope="x" >{{(x.record.name && !fixedRank.includes(x.record.rank)) ? `删除`: ''}}</text>
</table-column> </table-column>
</table> </table>
<view class="tb-rank-table-add {{list.length >= limit && 'tb-rank-table-add_disabled'}}" onTap="addPrize"> <view class="tb-rank-table-add {{list.length >= limit && 'tb-rank-table-add_disabled'}}" onTap="addPrize">
...@@ -31,6 +38,7 @@ ...@@ -31,6 +38,7 @@
visible="{{dialogVisible}}" visible="{{dialogVisible}}"
isEdit="{{isEdit}}" isEdit="{{isEdit}}"
prizeDialogData="{{prizeDialogData}}" prizeDialogData="{{prizeDialogData}}"
imageLimit="{{imageLimit}}"
onClose="onCloseDialog" onClose="onCloseDialog"
type="rank" type="rank"
onUpdate="onPrizeUpdate" onUpdate="onPrizeUpdate"
......
...@@ -7,6 +7,8 @@ Component({ ...@@ -7,6 +7,8 @@ Component({
}, },
props: { props: {
limit: 20, limit: 20,
imageLimit: [ 200, 200],
fixedRank: [],
list: [], list: [],
onChange: () => {} onChange: () => {}
}, },
...@@ -63,7 +65,13 @@ Component({ ...@@ -63,7 +65,13 @@ Component({
onPrizeAdd(data) { onPrizeAdd(data) {
const { list, onChange } = this.props; const { list, onChange } = this.props;
onChange && onChange([...list, data]) let newList = [...list, data].sort((a, b) => {
let prevRank = a.rank.split('-')[0]
let nextRank = b.rank.split('-')[0]
return prevRank - nextRank;
})
onChange && onChange(newList)
} }
}, },
}); });
...@@ -35,3 +35,9 @@ ...@@ -35,3 +35,9 @@
.submit-btn Button { .submit-btn Button {
margin-left: 20px; margin-left: 20px;
} }
.form-flex {
display: flex;
}
.form-check {
margin-right: 10px;
}
\ No newline at end of file
...@@ -47,7 +47,7 @@ ...@@ -47,7 +47,7 @@
label="活动副标题" label="活动副标题"
asterisk="{{false}}"> asterisk="{{false}}">
<tb-input <tb-input
placeholder="请输入活动副标题" placeholder="漂流寻宝赢取100元现金红包"
maxLength="16" maxLength="16"
value="{{subtitle}}" value="{{subtitle}}"
dataName="subtitle" dataName="subtitle"
...@@ -65,7 +65,13 @@ ...@@ -65,7 +65,13 @@
validateState="{{formState.prizeInfoList.status}}" validateState="{{formState.prizeInfoList.status}}"
help="{{formState.prizeInfoList.message}}" help="{{formState.prizeInfoList.message}}"
asterisk="{{false}}"> asterisk="{{false}}">
<rank-table list="{{prizeInfoList}}" onChange="onPrizeListChange"/> <rank-table
list="{{prizeInfoList}}"
onChange="onPrizeListChange"
limit="{{8}}"
fixedRank="{{['1', '2', '3']}}"
imageLimit="{{[250, 250]}}"
/>
</form-item> </form-item>
...@@ -77,6 +83,8 @@ ...@@ -77,6 +83,8 @@
validateState="{{formState['taskMap.beMembership'].status}}" validateState="{{formState['taskMap.beMembership'].status}}"
help="{{formState['taskMap.beMembership'].message}}" help="{{formState['taskMap.beMembership'].message}}"
asterisk="{{false}}"> asterisk="{{false}}">
<view class="form-flex">
<checkbox class="form-check" checked="{{taskMap.beMembership.checked}}" data-name="taskMap.beMembership.checked" onChange="onCheckChange"></checkbox>
<tb-config-input <tb-config-input
textBefore="获得" textBefore="获得"
textAfter="体力值" textAfter="体力值"
...@@ -86,6 +94,7 @@ ...@@ -86,6 +94,7 @@
onChange="onTaskInputChange", onChange="onTaskInputChange",
placeholder="1-99" placeholder="1-99"
/> />
</view>
</form-item> </form-item>
<form-item <form-item
...@@ -94,6 +103,8 @@ ...@@ -94,6 +103,8 @@
validateState="{{formState['taskMap.inviteFriends'].status}}" validateState="{{formState['taskMap.inviteFriends'].status}}"
help="{{formState['taskMap.inviteFriends'].message}}" help="{{formState['taskMap.inviteFriends'].message}}"
asterisk="{{false}}"> asterisk="{{false}}">
<view class="form-flex">
<checkbox class="form-check" checked="{{taskMap.inviteFriends.checked}}" data-name="taskMap.inviteFriends.checked" onChange="onCheckChange"></checkbox>
<task-config <task-config
unit="体力值" unit="体力值"
type="inviteFriends" type="inviteFriends"
...@@ -101,6 +112,7 @@ ...@@ -101,6 +112,7 @@
dataName="taskMap.inviteFriends" dataName="taskMap.inviteFriends"
onUpdate="onTaskChange" onUpdate="onTaskChange"
/> />
</view>
</form-item> </form-item>
<form-item <form-item
...@@ -109,6 +121,8 @@ ...@@ -109,6 +121,8 @@
validateState="{{formState['taskMap.jumpLink'].status}}" validateState="{{formState['taskMap.jumpLink'].status}}"
help="{{formState['taskMap.jumpLink'].message}}" help="{{formState['taskMap.jumpLink'].message}}"
asterisk="{{false}}"> asterisk="{{false}}">
<view class="form-flex">
<checkbox class="form-check" checked="{{taskMap.jumpLink.checked}}" data-name="taskMap.jumpLink.checked" onChange="onCheckChange"></checkbox>
<task-config <task-config
unit="体力值" unit="体力值"
type="jumpLink" type="jumpLink"
...@@ -117,6 +131,7 @@ ...@@ -117,6 +131,7 @@
dataName="taskMap.jumpLink" dataName="taskMap.jumpLink"
onUpdate="onTaskChange" onUpdate="onTaskChange"
/> />
</view>
</form-item> </form-item>
<form-item <form-item
...@@ -125,16 +140,20 @@ ...@@ -125,16 +140,20 @@
validateState="{{formState['taskMap.browseGoods'].status}}" validateState="{{formState['taskMap.browseGoods'].status}}"
help="{{formState['taskMap.browseGoods'].message}}" help="{{formState['taskMap.browseGoods'].message}}"
asterisk="{{false}}"> asterisk="{{false}}">
<view class="form-flex">
<checkbox class="form-check" checked="{{taskMap.browseGoods.checked}}" disabled="{{true}}"></checkbox>
<items-config itemIds="{{taskMap.browseGoods.itemIds}}" dataName="taskMap.browseGoods.itemIds" onUpdate="onTaskChange"/> <items-config itemIds="{{taskMap.browseGoods.itemIds}}" dataName="taskMap.browseGoods.itemIds" onUpdate="onTaskChange"/>
</view>
</form-item> </form-item>
<form-item <form-item
validateState="{{formState.logoImage.status}}" validateState="{{formState.logoImg.status}}"
help="{{formState.logoImage.message}}" help="{{formState.logoImg.message}}"
class="edit-content-form-item" class="edit-content-form-item"
label="logo图片" label="logo图片"
asterisk="{{false}}"> asterisk="{{false}}">
<tb-image-upload url="{{logoImage}}" dataName="logoImage" onSuccess="onChangeByDataName"/> <tb-image-upload url="{{logoImg}}" dataName="logoImg" onSuccess="onChangeByDataName" imageLimit="{{[200, 90]}}"/>
</form-item> </form-item>
...@@ -148,7 +167,7 @@ ...@@ -148,7 +167,7 @@
asterisk="{{false}}"> asterisk="{{false}}">
<tb-input <tb-input
placeholder="请输入邀请者淘口令名称" placeholder="请输入邀请者淘口令名称"
maxLength="12" maxLength="20"
value="{{commandTitle}}" value="{{commandTitle}}"
dataName="commandTitle" dataName="commandTitle"
hasLimitHint="{{true}}" hasLimitHint="{{true}}"
...@@ -163,7 +182,7 @@ ...@@ -163,7 +182,7 @@
asterisk="{{false}}"> asterisk="{{false}}">
<tb-input <tb-input
placeholder="请输入被邀请者文案" placeholder="请输入被邀请者文案"
maxLength="12" maxLength="30"
value="{{beenInvitedText}}" value="{{beenInvitedText}}"
dataName="beenInvitedText" dataName="beenInvitedText"
hasLimitHint="{{true}}" hasLimitHint="{{true}}"
...@@ -177,7 +196,7 @@ ...@@ -177,7 +196,7 @@
class="edit-content-form-item" class="edit-content-form-item"
label="淘口令图片" label="淘口令图片"
asterisk="{{false}}"> asterisk="{{false}}">
<tb-image-upload url="{{commandImg}}" dataName="commandImg" onSuccess="onChangeByDataName"/> <tb-image-upload url="{{commandImg}}" dataName="commandImg" onSuccess="onChangeByDataName" imageLimit="{{[400, 300]}}"/>
</form-item> </form-item>
<tb-label title="规则配置"/> <tb-label title="规则配置"/>
......
...@@ -3,7 +3,8 @@ import schema from 'async-validator'; ...@@ -3,7 +3,8 @@ import schema from 'async-validator';
import { descriptor, formatValidator } from './validate'; import { descriptor, formatValidator } from './validate';
import { import {
getActivityDetail, getActivityDetail,
saveActivityInfo saveActivityInfo,
generateRule
} from '/api' } from '/api'
import { import {
addFloat addFloat
...@@ -23,75 +24,114 @@ Component({ ...@@ -23,75 +24,114 @@ Component({
endTime: '', endTime: '',
timeRange: [], timeRange: [],
rule: '', rule: '',
prizeInfoList: [], prizeInfoList: [
commandTitle: '',
commandImg: '',
beenInvitedText: '',
taskList:[
{
type: "beMembership",//会员
value: 20,//完成任务获得值
},
{
type: "attentionStore",
value: 20,
},
{
type: "sign",
value: 20,
},
{ {
type: "exchangeCredits", ename: "",
value: 20, id: "",
times: 1, stock: "",
type: 1,
image: "",
credits: "",
name: "",
limitStock: 0,
useStock: 0,
rank: "1"
}, },
{ {
type: "inviteFriends", ename: "",
title: "标题",//任务标题 id: "",
taskRateType: 1,//任务频率类型 stock: "",
times: 3,//任务为每日限次次数值 type: 1,
value: 30, image: "",
credits: "",
name: "",
limitStock: 0,
useStock: 0,
rank: "2"
}, },
{ {
type: "orderGoods", ename: "",
title: "标题", id: "",
taskRateType: 2, stock: "",
times: 3, type: 1,
value: 90, image: "",
itemIds: "111,222,333",//商品类型任务商品id credits: "",
}, name: "",
{ limitStock: 0,
type: "browseGoods", useStock: 0,
title: "标题", rank: "3"
taskRateType: 3,
times: 3,
value: 90,
itemIds: "111,222,333",
},
{
type: "jumpLink",
title: "标题",
taskRateType: 3,
link: "http://www.taobao.com",//跳转链接
times: 3,
value: 90,
},
{
type: "collectGoods",
title: "标题",
taskRateType: 1,
times: 3,
value: 90,
itemIds: "111,222,333",
} }
], ],
commandTitle: '',
commandImg: '',
logoImg: '',
beenInvitedText: '',
taskList:[
// {
// type: "beMembership",//会员
// value: 20,//完成任务获得值
// },
// {
// type: "attentionStore",
// value: 20,
// },
// {
// type: "sign",
// value: 20,
// },
// {
// type: "exchangeCredits",
// value: 20,
// times: 1,
// },
// {
// type: "inviteFriends",
// title: "标题",//任务标题
// taskRateType: 1,//任务频率类型
// times: 3,//任务为每日限次次数值
// value: 30,
// },
// {
// type: "orderGoods",
// title: "标题",
// taskRateType: 2,
// times: 3,
// value: 90,
// itemIds: "111,222,333",//商品类型任务商品id
// },
// {
// type: "browseGoods",
// title: "标题",
// taskRateType: 3,
// times: 3,
// value: 90,
// itemIds: "111,222,333",
// },
// {
// type: "jumpLink",
// title: "标题",
// taskRateType: 3,
// link: "http://www.taobao.com",//跳转链接
// times: 3,
// value: 90,
// },
// {
// type: "collectGoods",
// title: "标题",
// taskRateType: 1,
// times: 3,
// value: 90,
// itemIds: "111,222,333",
// }
],
taskMap: { taskMap: {
// attentionStore: { // attentionStore: {
// value: '', // value: '',
// }, // },
beMembership: { beMembership: {
value:'' value:'',
checked: false
}, },
// sign: { // sign: {
// value: '' // value: ''
...@@ -105,6 +145,7 @@ Component({ ...@@ -105,6 +145,7 @@ Component({
taskRateType: 1, // 任务频率类型 taskRateType: 1, // 任务频率类型
times: 3, // 任务为每日限次次数值 times: 3, // 任务为每日限次次数值
value: '', // 任务奖励 value: '', // 任务奖励
checked: false
}, },
browseGoods: { browseGoods: {
title: "寻宝屋商品", title: "寻宝屋商品",
...@@ -112,7 +153,8 @@ Component({ ...@@ -112,7 +153,8 @@ Component({
times: 3, times: 3,
value: '', value: '',
link: '', link: '',
itemIds: '' itemIds: '',
checked: true
}, },
// collectGoods: { // collectGoods: {
// title: "", // title: "",
...@@ -127,6 +169,7 @@ Component({ ...@@ -127,6 +169,7 @@ Component({
link: "",//跳转链接 link: "",//跳转链接
times: 3, times: 3,
value: '', value: '',
checked: false
}, },
}, },
image: '', image: '',
...@@ -211,6 +254,11 @@ Component({ ...@@ -211,6 +254,11 @@ Component({
const { value } = e.detail; const { value } = e.detail;
this.setDataByKey(name, value); this.setDataByKey(name, value);
}, },
onCheckChange(e) {
const { name } = e.target.dataset;
const { value } = e.detail;
this.setDataByKey(name, value);
},
onTaskChange(data, key) { onTaskChange(data, key) {
console.log(data, key) console.log(data, key)
this.setDataByKey(key, data); this.setDataByKey(key, data);
...@@ -355,6 +403,7 @@ Component({ ...@@ -355,6 +403,7 @@ Component({
formatTaskMapToList(taskMap) { formatTaskMapToList(taskMap) {
let list = []; let list = [];
Object.keys(taskMap).forEach(type => { Object.keys(taskMap).forEach(type => {
if(!taskMap[type].checked) return;
let task = { let task = {
type, type,
...taskMap[type] ...taskMap[type]
...@@ -432,6 +481,49 @@ Component({ ...@@ -432,6 +481,49 @@ Component({
} }
}, },
//生成规则
generateRule() {
const {
title,
startTime,
endTime,
prizeInfoList
} = this.data;
if (title && startTime && endTime && prizeInfoList.length) {
let bool = true;
prizeInfoList.forEach(i => {
if (!i.image || !i.name) {
bool = false
}
})
if (!bool) {
this.showFailToast('请检查奖品配置是否正确')
return
}
console.log({
title,
startTime: startTime,
endTime: endTime,
prizeInfoList
}, 'time');
generateRule({
title,
startTime: new Date(startTime).getTime(),
endTime: new Date(endTime).getTime(),
prizeInfoList
}).then(res => {
if (res.success) {
this.setData({
rule: res.data,
hasEditChangePrize: false
})
}
})
} else {
this.showFailToast('请填写完整信息')
}
},
onCloseDialog(data) { onCloseDialog(data) {
switch (data) { switch (data) {
case "group": case "group":
......
...@@ -7,12 +7,18 @@ import { rankTableValidator } from "../../../utils/validate"; ...@@ -7,12 +7,18 @@ import { rankTableValidator } from "../../../utils/validate";
export const descriptor = { export const descriptor = {
title: { title: {
required: true, required: true,
validator: (rule, value) => !!value && value.length <= 12, validator: (rule, value) => {
value = value.trim();
return !!value && value.length <= 12
},
message: "请输入正确的活动名称" message: "请输入正确的活动名称"
}, },
subtitle: { subtitle: {
required: true, required: true,
validator: (rule, value) => !!value && value.length <= 16, validator: (rule, value) => {
value = value.trim();
return !!value && value.length <= 16
},
message: "请输入正确的活动副标题" message: "请输入正确的活动副标题"
}, },
prizeInfoList: { prizeInfoList: {
...@@ -22,16 +28,24 @@ export const descriptor = { ...@@ -22,16 +28,24 @@ export const descriptor = {
timeRange: { timeRange: {
required: true required: true
}, },
logoImage: { logoImg: {
required: true, required: true,
message: '请配置图片' message: '请配置图片'
}, },
commandTitle: { commandTitle: {
required: true, required: true,
validator: (rule, value) => {
value = value.trim();
return !!value;
},
message: '请输入淘口令名称' message: '请输入淘口令名称'
}, },
beenInvitedText: { beenInvitedText: {
required: true, required: true,
validator: (rule, value) => {
value = value.trim();
return !!value;
},
message: '请输入被邀请者文案' message: '请输入被邀请者文案'
}, },
commandImg: { commandImg: {
...@@ -40,6 +54,10 @@ export const descriptor = { ...@@ -40,6 +54,10 @@ export const descriptor = {
}, },
rule: { rule: {
required: true, required: true,
validator: (rule, value) => {
value = value.trim();
return !!value;
},
message: '请输入活动规则' message: '请输入活动规则'
}, },
taskMap: { taskMap: {
...@@ -47,15 +65,22 @@ export const descriptor = { ...@@ -47,15 +65,22 @@ export const descriptor = {
required: true, required: true,
fields: { fields: {
beMembership: { beMembership: {
validator: (rule, val) => !!val.value, validator: (rule, val, cb, source) => {
if(!source.beMembership.checked) return true;
return !!val.value
},
message: '请输入成为会员任务的奖励' message: '请输入成为会员任务的奖励'
}, },
inviteFriends: { inviteFriends: {
validator: (rule, val) => !!(val.title && val.value), validator: (rule, val, cb, source) => {
if(!source.inviteFriends.checked) return true;
return !!(val.title && val.value)
},
message: '请输入邀请任务' message: '请输入邀请任务'
}, },
jumpLink: { jumpLink: {
validator: (rule, val) => { validator: (rule, val, cb, source) => {
if(!source.jumpLink.checked) return true;
return !!(val.title && val.value && val.link); return !!(val.title && val.value && val.link);
}, },
message: '请输入浏览指定页面任务' message: '请输入浏览指定页面任务'
......
...@@ -2,5 +2,6 @@ ...@@ -2,5 +2,6 @@
<router-view> <router-view>
<list slot="list" /> <list slot="list" />
<add slot="add" /> <add slot="add" />
<data slot="data" />
</router-view> </router-view>
</view> </view>
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
"usingComponents": { "usingComponents": {
"router-view": "miniapp-router/router-view/router-view", "router-view": "miniapp-router/router-view/router-view",
"list": "../list/list", "list": "../list/list",
"add": "../add/add" "add": "../add/add",
"data": "../data/data"
} }
} }
\ No newline at end of file
.data-section-wrap {
background: #fff;
}
.data-title {
font-size: 14px;
font-weight: 600;
padding-bottom: 15px;
border-bottom: 1px solid #eee;
padding: 10px 16px;
}
.data-people {
display: flex;
justify-content: space-between;
padding: 0 30px;
}
.data-people-every {
padding: 10px;
}
.data-people-every-child {
padding: 20px 0;
}
.data-people-every-child-title {
font-weight: 600;
font-size: 16px;
font-family: fantasy;
padding-bottom: 10px;
text-align: center;
color: #333;
}
.data-people-every-child-tips {
font-weight: 600;
height: 20px;
font-size: 12px;
text-align: center;
color: #666;
}
.data-people-every-child-num {
font-size: 30px;
color: #3386F1;
text-align: center;
}
.new-section {
margin-top: 40px;
background-color: #fff;
}
.data-table {
font-size: 10px;
margin-top: 20px;
}
.data-title-select {
display: flex;
justify-content: space-between;
}
.data-table-wrap {
padding: 0 16px;
}
\ No newline at end of file
<view class="data-section-wrap">
<view class="edit-breadcrumb">
<text class="edit-title" onTap="goToActivityList">我的活动</text><text class="edit-title edit-title-separate">/</text><text class="edit-title">「 店铺漂流记 」 活动数据</text>
</view>
<view class="data-title">活动累计数据</view>
<view class="data-people">
<view class="data-people-every" a:for="{{accumulateData}}">
<view class="data-people-every-child">
<view class="data-people-every-child-title">{{item[0].name}}</view>
<view class="data-people-every-child-tips">{{item[0].tips ? item[0].tips : ''}}</view>
<view class="data-people-every-child-num">{{item[0].num}}</view>
</view>
<view class="data-people-every-child">
<view class="data-people-every-child-title">{{item[1].name}}</view>
<view class="data-people-every-child-tips">{{item[1].tips ? item[1].tips : ''}}</view>
<view class="data-people-every-child-num">{{item[1].num}}</view>
</view>
</view>
</view>
<view>
<view class="data-title">游戏参与数据</view>
<view class="data-table-wrap">
<table dataSource="{{userJoinData}}" class="data-table" hasBorder="{{false}}">
<table-column title="日期" alignHeader="left" align="left" dataIndex="date"/>
<table-column title="打开人数" alignHeader="left" align="left" dataIndex="openUV"/>
<table-column title="打开次数" alignHeader="left" align="left" dataIndex="openCount"/>
<table-column title="参与人数" alignHeader="left" align="left" dataIndex="joinUV"/>
<table-column title="参与次数" alignHeader="left" align="left" dataIndex="joinCount"/>
<table-column title="人均参与次数" alignHeader="left" align="left" dataIndex="joinRate"/>
</table>
</view>
</view>
</view>
<view class="new-section">
<view class="data-title">游戏任务数据</view>
<view class="data-table-wrap">
<table dataSource="{{userTaskData}}" class="data-table" hasBorder="{{false}}">
<table-column title="日期" alignHeader="left" align="left" dataIndex="date"/>
<table-column title="新增会员数量" alignHeader="left" align="left" dataIndex="beMemeberCount"/>
<table-column title="关注店铺数量" alignHeader="left" align="left" dataIndex="attentionStoreCount"/>
<table-column title="发起邀请人数" alignHeader="left" align="left" dataIndex="doShareCount"/>
<table-column title="成功邀请人数" alignHeader="left" align="left" dataIndex="friendsCount"/>
<table-column title="浏览指定页面人数" alignHeader="left" align="left" dataIndex="pageUrlUV"/>
<table-column title="浏览指定页面次数" alignHeader="left" align="left" dataIndex="pageUrlCount"/>
</table>
</view>
</view>
<view class="new-section">
<view class="data-title data-title-select"><text>商品以及发奖数据</text>
</view>
<view class="data-table-wrap">
<table dataSource="{{openPrizeData}}" class="data-table" hasBorder="{{false}}">
<table-column title="日期" alignHeader="left" align="left" dataIndex="date"/>
<table-column title="商品曝光数量" alignHeader="left" align="left" dataIndex="itemShowCount"/>
<table-column title="商品点击次数" alignHeader="left" align="left" dataIndex="itemTapCount"/>
<table-column title="商品点击人数" alignHeader="left" align="left" dataIndex="itemTapUV"/>
</table>
</view>
</view>
import moment from 'moment';
const {
cloud
} = getApp();
const {
function: fc
} = cloud;
import { getStatTotalData, getStatJoinData, getStatTaskDataData, getStatItemData } from '../../../api';
Component({
mixins: [],
data: {
userJoinData: [],
userTaskData: [],
openPrizeData: [],
taskData: [],
accumulateData: [
[{
name: '活动打开次数',
type: 'totalOpenCount',
num: 0
}, {
name: '新增关注数',
type: 'newAttentionStoreCount',
num: 0
}],
[{
name: '活动参与次数',
type: 'totalJoinCount',
num: 0
}, {
name: '商品曝光数量',
type: 'itemShowCount',
num: 0
}],
[{
name: '新增会员数',
type: 'newMemberCount',
num: 0
}]
]
},
props: {},
didMount() {
let {
id
} = this.$page.$router.params;
// my.showLoading()
this.getAccumulateData(id)
this.getUserJoinData(id)
this.getTaskData(id)
this.getOpenPrizeData(id);
},
didUpdate() {},
didUnmount() {},
methods: {
invokeFn(name, params, handler) {
return new Promise((resolve, reject) => {
fc.invoke(name, params, handler).then(res => {
if (res.success) {
resolve(res.data);
} else {
this.showFailToast(res.message);
}
}).catch(err => {
reject(err);
})
})
},
async getOpenPrizeData(id) {
const { data, message, success } = await getStatItemData({ activityId: id });
if(success) {
this.setData({
openPrizeData: Object.keys(data).map(v => {
return {
...data[v],
date: v
}
})
})
}
},
async getAccumulateData(id) {
const { data, success, message } = await getStatTotalData({ activityId: id });
if(success) {
const { totalOpenCount, newAttentionStoreCount, totalJoinCount, itemShowCount, newMemberCount } = data;
this.setData({
accumulateData: [
[{
name: '活动打开次数',
type: 'totalOpenCount',
num: totalOpenCount
}, {
name: '新增关注数',
type: 'newAttentionStoreCount',
num: newAttentionStoreCount
}],
[{
name: '活动参与次数',
type: 'totalJoinCount',
num: totalJoinCount
}, {
name: '商品曝光数量',
type: 'itemShowCount',
num: itemShowCount
}],
[{
name: '新增会员数',
type: 'newMemberCount',
num: newMemberCount
}]
]
})
}
},
goToActivityList() {
this.$page.$router.push('/activity/list')
},
showFailToast(content) {
my.showToast({
type: 'fail',
content: content
})
},
async getUserJoinData(id) {
const { data, success, message } = await getStatJoinData({ activityId: id });
if(success) {
this.setData({
userJoinData: Object.keys(data).map(v => {
return {
...data[v],
date: v
}
})
})
}
// this.invokeFn('duiba', {
// activityOutId: id
// }, 'backstage.reportData.userJoinData').then(data => {
// this.setData({
// userJoinData: data
// })
// })
},
async getTaskData(id, type = 'groupInvite') {
const { data, message, success } = await getStatTaskDataData({ activityId: id });
if(success) {
this.setData({
userTaskData: Object.keys(data).map(v => {
return {
...data[v],
date: v
}
})
})
}
}
},
});
\ No newline at end of file
{
"component": true
}
\ No newline at end of file
export const basePath = `/activity/add`; export const basePath = `/activity/list`;
export default { export default {
routes: [ routes: [
...@@ -18,6 +18,10 @@ export default { ...@@ -18,6 +18,10 @@ export default {
path: "/add", path: "/add",
component: "add", component: "add",
}, },
{
path: '/data/:id',
component: 'data'
},
{ {
path: "/edit/:id", path: "/edit/:id",
component: "add", component: "add",
......
...@@ -51,6 +51,7 @@ export const rankTableValidator = (rule, value, callback, source, options) => { ...@@ -51,6 +51,7 @@ export const rankTableValidator = (rule, value, callback, source, options) => {
// rank字段不存在或为0 // rank字段不存在或为0
if(value.some(v => !v.rank)) return new Error('名次配置错误, 请检查'); if(value.some(v => !v.rank)) return new Error('名次配置错误, 请检查');
if(value.some(v => !v.name)) return new Error('名次配置错误, 请检查');
const rankArr = (value.map(v => v.rank.split('-'))); const rankArr = (value.map(v => v.rank.split('-')));
......
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