增加转盘和分享奖励配置

This commit is contained in:
zhl 2021-06-07 19:58:53 +08:00
parent 1d1eb63778
commit 7a7a73252a
6 changed files with 847 additions and 3 deletions

View File

@ -95,3 +95,47 @@ export const saveGameTheme = (data: any) =>
method: 'post',
data
})
/**
*
* @param data
*/
export const getShopLotteryCfg = (data: any) =>
request({
url: '/api/shop/lottery',
method: 'post',
data
})
/**
*
* @param data
*/
export const updateShopLotteryCfg = (data: any) =>
request({
url: '/api/shop/lottery_update',
method: 'post',
data
})
/**
*
* @param data
*/
export const getShopShareCfg = (data: any) =>
request({
url: '/api/shop/share',
method: 'post',
data
})
/**
*
* @param data
*/
export const updateShopShareCfg = (data: any) =>
request({
url: '/api/shop/share_update',
method: 'post',
data
})

View File

@ -96,7 +96,9 @@ export default {
shop_member: 'Member Manage',
shop_statistics: 'Statistics',
game_statistics: 'Game Statistics',
shop_puzzles: 'Custom Puzzles'
shop_puzzles: 'Custom Puzzles',
shop_lottery: 'Lottery Setting',
shop_share: 'Share Setting'
},
navbar: {
logOut: 'Log Out',

View File

@ -96,7 +96,9 @@ export default {
shop_member: '成员管理',
shop_statistics: '统计',
game_statistics: '游戏数据',
shop_puzzles: '自定义题库'
shop_puzzles: '自定义题库',
shop_lottery: '抽奖转盘',
shop_share: '分享设置'
},
navbar: {
logOut: '退出登录',

View File

@ -115,7 +115,27 @@ const shopRoutes: RouteConfig = {
icon: 'theme2',
hidden: true
}
}
},
{
path: 'lottery_setting',
component: () => import('@/views/shop/shop_lottery.vue'),
name: 'ShopLottery',
meta: {
title: 'shop_lottery',
permissions: ['shop:edit'],
icon: 'game'
}
},
{
path: 'share_setting',
component: () => import('@/views/shop/shop_share.vue'),
name: 'ShopShare',
meta: {
title: 'shop_share',
permissions: ['shop:edit'],
icon: 'game'
}
},
]
}

View File

@ -0,0 +1,411 @@
<template>
<div class="app-container">
<el-alert
title="转盘一共需要配置8个项目"
type="success"
description="如果不满8个, 保存时, 会自动填充空的数据, 请自己修改留空项的出现概率"
effect="dark"
>
</el-alert>
<div class="action-bar">
<el-select
v-model="shop"
:placeholder="'选择'+$t('main.shop')"
name="shop"
required
v-if="userLevel === 1"
class="w100"
>
<el-option
v-for="item in allDepts"
:key="item._id"
:label="item.name"
:value="item._id"
/>
</el-select>
<el-button
type="primary"
icon="el-icon-edit"
style="margin-left: 10px"
@click="handleCreateReward"
>
添加
</el-button>
</div>
<el-table
:data="rewards"
border
fit
highlight-current-row
>
<el-table-column
label="概率"
prop="rank"
>
</el-table-column>
<el-table-column
label="奖励"
prop="coupon"
:formatter = "formatCoupon"
>
</el-table-column>
<el-table-column
align="center"
width="180"
label="操作"
fixed="right"
>
<template slot-scope="scope">
<el-button
type="primary"
size="small"
icon="el-icon-edit"
@click="handleEdit(scope)"
>
编辑
</el-button>
<el-button
type="danger"
size="small"
style="margin-left: 10px"
@click="deleteRank(scope)"
>
{{ $t('permission.delete') }}
</el-button>
</template>
</el-table-column>
</el-table>
<div class="footer-bar">
<el-button
type="primary"
:loading="saveing"
@click="submitForm"
>
保存
</el-button>
<el-button @click="onCancel">
取消
</el-button>
</div>
<el-dialog
:visible.sync="dialogVisible"
title="编辑奖励"
>
<el-form
:model="record"
ref="modalForm"
:rules="modalRules"
label-width="120px"
label-position="left"
>
<el-form-item label="概率" prop="rank" v-if="record.type!==2">
<el-input
v-model="record.rank"
placeholder="概率"
type="number"
style="width: 30%"
/>
</el-form-item>
<el-form-item label="奖励" prop="coupon">
<el-select
v-model="record.coupon"
placeholder="选择奖励"
name="coupon"
required
class="w100"
>
<el-option key="empty" label="留空" value="empty"></el-option>
<el-option key="lottery_ticket" label="抽奖券" value="lottery_ticket"></el-option>
<el-option
v-for="item in coupons"
:key="item._id"
:label="item.name"
:value="item._id"
/>
</el-select>
</el-form-item>
<el-form-item label="数量" prop="count">
<el-input
v-model="record.count"
placeholder="数量"
type="number"
/>
</el-form-item>
<el-form-item>
<el-button
type="primary"
@click="saveReward"
v-permission="['shop:edit']"
>
保存
</el-button>
<el-button @click="closeModal">
取消
</el-button>
</el-form-item>
</el-form>
</el-dialog>
</div>
</template>
<script lang="ts">
import { Component, Vue, Watch } from 'vue-property-decorator'
import UploadImage from '@/components/UploadImage/index.vue'
import { cloneDeep } from 'lodash'
import { defaultRewardData, IRewardData } from '@/api/activity'
import { getShopLotteryCfg, getShops, updateShopLotteryCfg } from '@/api/shop'
import { UserModule } from '@/store/modules/user'
import { EVENT_COUPON_UPDATE, EVENT_SHOP_UPDATE, EventBus } from '@/utils/event-bus'
import { IShopData } from '@/api/types'
import { getCoupons, ICouponData } from '@/api/coupon'
@Component({
name: 'ShopLottery',
components: {
UploadImage
}
})
export default class extends Vue {
private rewards: any[] = []
private dialogType = 'new'
private dialogVisible = false
private shop = ''
private allDepts: IShopData[] = []
private record: IRewardData = { type: 0, count: 1, rewardType: 0 }
private coupons: ICouponData[] = []
private saveing = false
$refs!: {
modalForm: HTMLFormElement
}
private modalRules = {
rank: [{ required: true, message: '请输入抽取概率', trigger: 'blur' }
],
coupon: [{ required: true, message: '请选择奖励', trigger: 'blur' }]
}
get userLevel() {
return UserModule.level
}
async created() {
if (UserModule.level === 1) {
await this.getRemoteDeptList()
EventBus.$on(EVENT_SHOP_UPDATE, () => {
this.getRemoteDeptList()
})
} else {
this.shop = UserModule.department
await this.fetchData()
}
EventBus.$on(EVENT_COUPON_UPDATE, () => {
if (this.postForm.shop) {
this.getCouponList(this.postForm.shop)
}
})
}
beforeDestory() {
if (UserModule.level === 1) {
EventBus.$off(EVENT_SHOP_UPDATE)
}
}
@Watch('shop')
private onShopChange() {
if (!this.shop) {
return
}
this.getCouponList(this.shop)
this.fetchData()
}
private formatCoupon(row: number, column: number, cellValue: string, index: number) {
let result = `未知(${cellValue})`
const data = this.rewards[index]
for (const dep of this.coupons) {
if (dep._id === cellValue) {
result = dep.name
break
}
}
if (cellValue === 'lottery_ticket') {
return `抽奖券 x ${data.count}`
} else if (cellValue === 'empty') {
return '留空'
}
return `${result} x ${data.count}`
}
private handleCreateReward() {
this.record = Object.assign({}, defaultRewardData)
this.record.id = this.rewards.length
this.dialogType = 'new'
this.dialogVisible = true
}
private handleEdit(scope: any) {
this.dialogType = 'edit'
this.dialogVisible = true
this.record = cloneDeep(scope.row)
}
private async deleteRank(scope: any) {
const { $index } = scope
try {
await this.$confirm('Confirm to remove the record?', 'Warning', {
confirmButtonText: 'Confirm',
cancelButtonText: 'Cancel',
type: 'warning'
})
this.rewards.splice($index, 1)
this.$message({
type: 'success',
message: '删除成功, 请点击保存'
})
} catch (err) {
}
}
private closeModal() {
this.dialogVisible = false
this.$refs.modalForm.clearValidate()
}
private async getRemoteDeptList() {
const { data } = await getShops({})
if (!data.records) return
this.allDepts = data.records
if (this.allDepts.length > 0 && !this.shop) {
this.shop = this.allDepts[0]._id
}
}
private saveReward() {
const isEdit = this.dialogType === 'edit';
(this.$refs.modalForm as HTMLFormElement).validate(async(valid: boolean) => {
if (!valid) {
this.$message.error('请按要求填写表单')
return false
}
if (this.record.coupon === 'lottery_ticket') {
this.record.rewardType = 1
} else {
this.record.rewardType = 0
}
if (isEdit) {
for (let index = 0; index < this.rewards.length; index++) {
if (this.rewards[index].id === this.record.id) {
this.rewards.splice(index, 1, Object.assign({}, this.record))
break
}
}
} else {
this.rewards.push(this.record)
}
this.dialogVisible = false
this.$notify({
title: 'Success',
dangerouslyUseHTMLString: true,
message: `
奖励成功保存, 请点击保存
`,
type: 'success'
})
})
}
private async getCouponList(shop: string) {
const { data } = await getCoupons({ shop })
this.coupons = data.records
}
private async fetchData() {
console.log('get remote shop cfg')
const { data } = await getShopLotteryCfg({ shop: this.shop })
this.rewards = data
}
private async onCancel() {
try {
await this.$confirm('确认不保存当前修改的信息?', 'Warning', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
this.$store.dispatch('delView', this.$route)
this.$router.go(-1)
} catch (e) {
}
}
private async submitForm() {
try {
if (this.rewards.length === 0) {
this.$message({
message: '好歹填一个不留空的配置项吧',
type: 'error'
})
return false
}
let count = 0
let rank = 0
for (const _r of this.rewards) {
if (_r.coupon !== 'empty') {
count++
rank += _r.rank
}
}
if (count === 0) {
this.$message({
message: '好歹填一个不留空的配置项吧',
type: 'error'
})
return false
}
if (this.rewards.length > 8) {
this.$message({
message: '配置项不能多于8个, 请删除几个后再保存',
type: 'error'
})
return false
}
for (let i = this.rewards.length; i < 8; i++) {
this.rewards.push({
coupon: 'empty',
rank: rank,
count: 1
})
}
this.saveing = true
const { data } = await updateShopLotteryCfg({ shop: this.shop, cfgs: this.rewards })
this.postForm = data
this.saveing = false
this.$notify({
title: 'Success',
message: '保存成功',
type: 'success',
duration: 2000
})
} catch (err) {
console.error('Submit Error!')
this.saveing = false
return false
}
}
}
</script>
<style lang="scss" >
.action-bar{
margin-bottom: 8px;
margin-top: 8px;
}
.footer-bar {
margin-top: 8px;
}
</style>

View File

@ -0,0 +1,365 @@
<template>
<div class="app-container">
<div class="action-bar">
<el-select
v-model="shop"
:placeholder="'选择'+$t('main.shop')"
name="shop"
required
v-if="userLevel === 1"
class="w100"
>
<el-option
v-for="item in allDepts"
:key="item._id"
:label="item.name"
:value="item._id"
/>
</el-select>
<el-button
type="primary"
icon="el-icon-edit"
style="margin-left: 10px"
@click="handleCreateReward"
>
添加
</el-button>
</div>
<el-table
:data="rewards"
border
fit
highlight-current-row
>
<el-table-column
label="人数"
prop="rank"
>
</el-table-column>
<el-table-column
label="奖励"
prop="coupon"
:formatter = "formatCoupon"
>
</el-table-column>
<el-table-column
align="center"
width="180"
label="操作"
fixed="right"
>
<template slot-scope="scope">
<el-button
type="primary"
size="small"
icon="el-icon-edit"
@click="handleEdit(scope)"
>
编辑
</el-button>
<el-button
type="danger"
size="small"
style="margin-left: 10px"
@click="deleteRank(scope)"
>
{{ $t('permission.delete') }}
</el-button>
</template>
</el-table-column>
</el-table>
<div class="footer-bar">
<el-button
type="primary"
:loading="saveing"
@click="submitForm"
>
保存
</el-button>
<el-button @click="onCancel">
取消
</el-button>
</div>
<el-dialog
:visible.sync="dialogVisible"
title="编辑奖励"
>
<el-form
:model="record"
ref="modalForm"
:rules="modalRules"
label-width="120px"
label-position="left"
>
<el-form-item label="人数" prop="rank" v-if="record.type!==2">
<el-input
v-model="record.rank"
placeholder="分数"
type="number"
oninput="this.value = this.value.replace(/[^0-9]/g, '');"
style="width: 30%"
/>
</el-form-item>
<el-form-item label="奖励" prop="coupon">
<el-select
v-model="record.coupon"
placeholder="选择奖励"
name="coupon"
required
class="w100"
>
<el-option key="lottery_ticket" label="抽奖券" value="lottery_ticket"></el-option>
<el-option
v-for="item in coupons"
:key="item._id"
:label="item.name"
:value="item._id"
/>
</el-select>
</el-form-item>
<el-form-item label="数量" prop="count">
<el-input
v-model="record.count"
placeholder="数量"
type="number"
/>
</el-form-item>
<el-form-item>
<el-button
type="primary"
@click="saveReward"
v-permission="['shop:edit']"
>
保存
</el-button>
<el-button @click="closeModal">
取消
</el-button>
</el-form-item>
</el-form>
</el-dialog>
</div>
</template>
<script lang="ts">
import { Component, Vue, Watch } from 'vue-property-decorator'
import UploadImage from '@/components/UploadImage/index.vue'
import { cloneDeep } from 'lodash'
import { defaultRewardData, IRewardData } from '@/api/activity'
import { getShopLotteryCfg, getShops, getShopShareCfg, updateShopLotteryCfg, updateShopShareCfg } from '@/api/shop'
import { UserModule } from '@/store/modules/user'
import { EVENT_COUPON_UPDATE, EVENT_SHOP_UPDATE, EventBus } from '@/utils/event-bus'
import { IShopData } from '@/api/types'
import { getCoupons, ICouponData } from '@/api/coupon'
@Component({
name: 'ShopShare',
components: {
UploadImage
}
})
export default class extends Vue {
private rewards: any[] = []
private dialogType = 'new'
private dialogVisible = false
private shop = ''
private allDepts: IShopData[] = []
private record: IRewardData = { type: 0, count: 1, rewardType: 0 }
private coupons: ICouponData[] = []
private saveing = false
$refs!: {
modalForm: HTMLFormElement
}
private modalRules = {
rank: [{ required: true, message: '请输入人数', trigger: 'blur' }
],
coupon: [{ required: true, message: '请选择奖励', trigger: 'blur' }]
}
get userLevel() {
return UserModule.level
}
async created() {
if (UserModule.level === 1) {
await this.getRemoteDeptList()
EventBus.$on(EVENT_SHOP_UPDATE, () => {
this.getRemoteDeptList()
})
} else {
this.shop = UserModule.department
await this.fetchData()
}
EventBus.$on(EVENT_COUPON_UPDATE, () => {
if (this.postForm.shop) {
this.getCouponList(this.postForm.shop)
}
})
}
beforeDestory() {
if (UserModule.level === 1) {
EventBus.$off(EVENT_SHOP_UPDATE)
}
}
@Watch('shop')
private onShopChange() {
if (!this.shop) {
return
}
this.getCouponList(this.shop)
this.fetchData()
}
private formatCoupon(row: number, column: number, cellValue: string, index: number) {
let result = `未知(${cellValue})`
const data = this.rewards[index]
for (const dep of this.coupons) {
if (dep._id === cellValue) {
result = dep.name
break
}
}
if (cellValue === 'lottery_ticket') {
return `抽奖券 x ${data.count}`
}
return `${result} x ${data.count}`
}
private handleCreateReward() {
this.record = Object.assign({}, defaultRewardData)
this.record.id = this.rewards.length
this.dialogType = 'new'
this.dialogVisible = true
}
private handleEdit(scope: any) {
this.dialogType = 'edit'
this.dialogVisible = true
this.record = cloneDeep(scope.row)
}
private async deleteRank(scope: any) {
const { $index } = scope
try {
await this.$confirm('Confirm to remove the record?', 'Warning', {
confirmButtonText: 'Confirm',
cancelButtonText: 'Cancel',
type: 'warning'
})
this.rewards.splice($index, 1)
this.$message({
type: 'success',
message: '删除成功, 请点击保存'
})
} catch (err) {
}
}
private closeModal() {
this.dialogVisible = false
this.$refs.modalForm.clearValidate()
}
private async getRemoteDeptList() {
const { data } = await getShops({})
if (!data.records) return
this.allDepts = data.records
if (this.allDepts.length > 0 && !this.shop) {
this.shop = this.allDepts[0]._id
}
}
private saveReward() {
const isEdit = this.dialogType === 'edit';
(this.$refs.modalForm as HTMLFormElement).validate(async(valid: boolean) => {
if (!valid) {
this.$message.error('请按要求填写表单')
return false
}
if (this.record.coupon === 'lottery_ticket') {
this.record.rewardType = 1
} else {
this.record.rewardType = 0
}
if (isEdit) {
for (let index = 0; index < this.rewards.length; index++) {
if (this.rewards[index].id === this.record.id) {
this.rewards.splice(index, 1, Object.assign({}, this.record))
break
}
}
} else {
this.rewards.push(this.record)
}
this.dialogVisible = false
this.$notify({
title: 'Success',
dangerouslyUseHTMLString: true,
message: `
奖励成功保存, 请点击保存
`,
type: 'success'
})
})
}
private async getCouponList(shop: string) {
const { data } = await getCoupons({ shop })
this.coupons = data.records
}
private async fetchData() {
console.log('get remote shop cfg')
const { data } = await getShopShareCfg({ shop: this.shop })
this.rewards = data
}
private async onCancel() {
try {
await this.$confirm('确认不保存当前修改的信息?', 'Warning', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
this.$store.dispatch('delView', this.$route)
this.$router.go(-1)
} catch (e) {
}
}
private async submitForm() {
try {
this.saveing = true
const { data } = await updateShopShareCfg({ shop: this.shop, cfgs: this.rewards })
this.postForm = data
this.saveing = false
this.$notify({
title: 'Success',
message: '保存成功',
type: 'success',
duration: 2000
})
} catch (err) {
console.error('Submit Error!')
this.saveing = false
return false
}
}
}
</script>
<style lang="scss" >
.action-bar{
margin-bottom: 8px;
}
.footer-bar {
margin-top: 8px;
}
</style>