新增“赠送道具券”功能

This commit is contained in:
hzj 2025-11-07 16:08:26 +08:00
parent b0a3669433
commit 9fdae9a338
4 changed files with 364 additions and 60 deletions

View File

@ -1,151 +1,159 @@
import request from '@/utils/request'
import request from "@/utils/request";
// 道具资源-分页列表
export function pagePropsSource(params) {
return request({
url: '/props/source/record/page',
method: 'get',
url: "/props/source/record/page",
method: "get",
params
})
});
}
// 道具资源-添加
export function addPropsSource(data) {
return request({
url: '/props/source/record/add',
method: 'post',
url: "/props/source/record/add",
method: "post",
data
})
});
}
// 道具资源-修改
export function updatePropsSource(data) {
return request({
url: '/props/source/record/update',
method: 'post',
url: "/props/source/record/update",
method: "post",
data
})
});
}
// 道具资源-上下架
export function offShelfPropsSource(id, offShelf) {
return request({
url: `/props/source/record/off/shelf`,
method: 'get',
method: "get",
params: { id, offShelf }
})
});
}
// 获取资源列表-平台+类型获取
export function listSysOriginTypeList(sysOrigin, type) {
return request({
url: '/props/source/record/sys-origin/type/list',
method: 'get',
url: "/props/source/record/sys-origin/type/list",
method: "get",
params: { sysOrigin, type }
})
});
}
// 获取资源列表-类型获取-排除家族资源-根据平台
export function listNotFamilyBySysOriginType(sysOrigin, type) {
return request({
url: '/props/source/record/sys-origin/type/list/exclude-family',
method: 'get',
url: "/props/source/record/sys-origin/type/list/exclude-family",
method: "get",
params: { sysOrigin, type }
})
});
}
// 活动道具奖励配置-分页
export function pagePropsActivityRewardGroup(params) {
return request({
url: '/props/activity/reward/group/page',
method: 'get',
url: "/props/activity/reward/group/page",
method: "get",
params
})
});
}
// 根据资源组ID获得活动道具奖励配置
export function getByGroupId(id) {
return request({
url: '/props/activity/reward/group/' + id,
method: 'get'
})
url: "/props/activity/reward/group/" + id,
method: "get"
});
}
// 活动道具奖励配置-修改/添加
export function saveOrUpdatePropsActivityRewardGroup(data) {
return request({
url: '/props/activity/reward/group/save-or-update',
method: 'post',
url: "/props/activity/reward/group/save-or-update",
method: "post",
data
})
});
}
// 活动道具奖励配置-上下架
export function offPropsActivityRewardGroup(id, offShelf) {
return request({
url: `/props/activity/reward/group/off/shelf/${id}/${offShelf}`,
method: 'get'
})
method: "get"
});
}
// 活动道具规则-分页
export function pagePropsActivityRuleConfig(params) {
return request({
url: '/props/activity/rule/config/page',
method: 'get',
url: "/props/activity/rule/config/page",
method: "get",
params
})
});
}
// 活动道具规则-添加或修改
export function savePropsActivityRuleConfig(data) {
return request({
url: '/props/activity/rule/config/save-or-update',
method: 'post',
url: "/props/activity/rule/config/save-or-update",
method: "post",
data
})
});
}
// 活动道具规则-删除
export function delPropsActivityRuleConfig(id) {
return request({
url: `/props/activity/rule/config/del/${id}`,
method: 'get'
})
method: "get"
});
}
// 上架中的活动道具组
export function getGroupActivityList() {
return request({
url: `/props/activity/reward/group/get/activity/list`,
method: 'get'
})
method: "get"
});
}
// 赠送道具给用户
export function sendPropsGiveUser(data) {
return request({
url: '/props/give/send',
method: 'post',
url: "/props/give/send",
method: "post",
data
})
});
}
// 赠送道具券给用户
export function sendPropsTicketGiveUser(data) {
return request({
url: "/props/give/grant-coupon",
method: "post",
data
});
}
// 道具商店-分页
export function pagePropsStore(params) {
return request({
url: '/props/store/page',
method: 'get',
url: "/props/store/page",
method: "get",
params
})
});
}
// 道具商店-添加或修改
export function addOrUpdatePropsStore(data) {
return request({
url: '/props/store/add-or-update',
method: 'post',
url: "/props/store/add-or-update",
method: "post",
data
})
});
}

View File

@ -733,6 +733,13 @@ const propsTypes = [
{ value: "CUSTOMIZE", name: "自定义(只读)" }
];
// 道具类型
const propsTicket = [
{ value: "AVATAR_FRAME", name: "头像框" },
{ value: "RIDE", name: "座驾" },
{ value: "NOBLE_VIP", name: "贵族" }
];
// 道具商品类型
const propsCommodityTypes = [
{ value: "AVATAR_FRAME", name: "头像框" },

View File

@ -1,31 +1,35 @@
<template>
<div class="app-container">
<el-row :gutter="10">
<!-- 赠送道具 -->
<el-col v-if="buttonPermissions.includes('send:props')">
<send-props />
</el-col>
<!-- 赠送徽章 -->
<el-col v-if="buttonPermissions.includes('send:props:badge')">
<send-badge />
</el-col>
<!-- 赠送道具券 -->
<el-col v-if="buttonPermissions.includes('send:props:coupon')">
<send-ticket />
</el-col>
</el-row>
</div>
</template>
<script>
import SendProps from './send-props'
import SendBadge from './send-badge'
import { mapGetters } from 'vuex'
import SendProps from "./send-props";
import SendBadge from "./send-badge";
import SendTicket from "./send-ticket";
import { mapGetters } from "vuex";
export default {
components: { SendProps, SendBadge },
components: { SendProps, SendBadge, SendTicket },
data() {
return {}
return {};
},
computed: {
...mapGetters(['buttonPermissions'])
...mapGetters(["buttonPermissions"])
},
created() {
}
}
created() {}
};
</script>

View File

@ -0,0 +1,285 @@
<template>
<div class="send-props">
<el-alert
title="赠送道具券"
style="margin-bottom: 10px;"
:closable="false"
/>
<el-form
ref="form"
:model="propsGiveForm"
:rules="formRules"
label-width="85px"
>
<el-form-item label="接收人" prop="receiverAccounts">
<el-input
v-model="propsGiveForm.receiverAccounts"
placeholder="请输入用户 【短账号】 ,多个短账号用英文','分割;(一批最多15个)短账号"
/>
</el-form-item>
<el-form-item label="选择系统" prop="sysOrigin">
<el-form-item>
<el-select
v-model="propsGiveForm.sysOrigin"
placeholder="系统"
style="width:100%;"
class="filter-item"
@change="changeSysOrigin"
>
<el-option
v-for="item in permissionsSysOriginPlatforms"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
</el-form-item>
<el-form-item label="选择类型" prop="secondaryType">
<el-select
v-model="propsGiveForm.secondaryType"
placeholder="类型"
style="width:100%;"
class="filter-item"
@change="changePropsType"
>
<el-option
v-for="item in propsTicket"
:key="item.value"
:label="item.name"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="选择资源" prop="propId">
<div v-if="selectProps.cover" class="payer-source">
<div class="paler-icon">
<svgaplayer type="popover" :url="selectProps.sourceUrl || ''" />
</div>
<img :src="selectProps.cover" alt="cover" />
</div>
<props-source-select-popover
v-loading="
propsTypeMap[propsGiveForm.secondaryType]
? propsTypeMap[propsGiveForm.secondaryType].loading
: false
"
:data="
propsTypeMap[propsGiveForm.secondaryType]
? propsTypeMap[propsGiveForm.secondaryType].list
: []
"
:property="selectPopoverProperty"
:visible="visiblePopover"
:show-filter="true"
@select="selectPropsSourcePopover"
/>
</el-form-item>
<el-form-item
v-if="propsGiveForm.secondaryType == 'NOBLE_VIP'"
label="贵族来源"
prop="vipOrigin"
>
<el-select
v-model="propsGiveForm.vipOrigin"
placeholder="贵族来源"
style="width:100%;"
class="filter-item"
>
<el-option label="系统赠送" value="SYSTEM_GIVE" />
<el-option label="购买或朋友赠送" value="BUY_OR_GIVE" />
<el-option label="活动奖励" value="ACTIVITY_AWARD" />
</el-select>
</el-form-item>
<el-form-item label="有效天数" prop="validDays">
<el-input
v-model="propsGiveForm.validDays"
type="number"
placeholder="输入正数为赠送,负数为回收"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" :loading="submitLoading" @click="onGiveSubmit"
>发送</el-button
>
</el-form-item>
</el-form>
</div>
</template>
<script>
import {
listNotFamilyBySysOriginType,
sendPropsTicketGiveUser
} from "@/api/props";
import { propsTicket } from "@/constant/type";
import PropsSourceSelectPopover from "@/components/data/PropsSourceSelectPopover";
import { mapGetters } from "vuex";
export default {
name: "SendProps",
components: { PropsSourceSelectPopover },
data() {
const commonRules = [
{ required: true, message: "必填字段不可为空", trigger: "blur" }
];
const propsTypeMap = {};
propsTicket.forEach(item => {
propsTypeMap[item.value] = {
list: [],
loading: false,
loadData: false
};
});
return {
propsTicket,
visiblePopover: false,
propsTypeMap,
selectPopoverProperty: {
label: "name",
cover: "cover",
svgaUrl: "sourceUrl",
value: "id"
},
selectProps: {},
submitLoading: false,
formRules: {
receiverAccounts: commonRules,
validDays: [
{ required: true, message: "有效天数不能为空", trigger: "blur" },
{
validator: (rule, value, callback) => {
if (value === "" || isNaN(value)) {
callback(new Error("请输入有效数字"));
} else {
callback();
}
},
trigger: "blur"
}
],
propId: commonRules,
secondaryType: commonRules,
sysOrigin: commonRules
},
propsGiveForm: {
sysOrigin: "",
receiverAccounts: "",
userIds: [],
type: "PROPS",
propId: "",
validDays: "",
secondaryType: "",
vipOrigin: null
},
userInfo: {}
};
},
computed: {
...mapGetters(["permissionsSysOriginPlatforms"])
},
created() {
this.propsTicket = this.propsTicket.filter(
item => !(item.value === "CUSTOMIZE" || item.value === "FRAGMENTS")
);
},
methods: {
changeSysOrigin(val) {
const that = this;
that.propsGiveForm.secondaryType = "";
that.selectProps = {};
},
changePropsType(val) {
const that = this;
that.propsGiveForm.vipOrigin = null;
if (!that.propsGiveForm.sysOrigin) {
return;
}
that.selectProps = {};
that.propsGiveForm.propId = "";
const propsTypeItem = that.propsTypeMap[val];
propsTypeItem.list = [];
// ,
// if (propsTypeItem && propsTypeItem.loadData === true) {
// return
// }
propsTypeItem.loading = true;
listNotFamilyBySysOriginType(that.propsGiveForm.sysOrigin, val)
.then(res => {
propsTypeItem.loading = false;
propsTypeItem.loadData = true;
propsTypeItem.list = res.body || [];
})
.catch(er => {
propsTypeItem.loading = false;
console.error(er);
});
},
selectPropsSourcePopover(item) {
this.selectProps = item;
this.propsGiveForm.propId = item.id;
},
onGiveSubmit() {
const that = this;
that.$refs.form.validate(valid => {
if (!valid) {
console.error("error submit!!");
return;
}
// receiverAccounts userIds
const formToSend = { ...that.propsGiveForm };
if (formToSend.receiverAccounts) {
formToSend.userIds = formToSend.receiverAccounts
.split(",")
.map(id => id.trim())
.filter(id => id);
} else {
formToSend.userIds = [];
}
that.submitLoading = true;
sendPropsTicketGiveUser(formToSend)
.then(res => {
if (res.errorCode === 0) {
if (res.body) {
that.$opsMessage.fail(
"无效短账号: " +
res.body +
" 请处理后再将当前批次所有短账号重新发送."
);
that.submitLoading = false;
return;
}
that.$opsMessage.success();
that.selectProps = {};
that.propsGiveForm.propId = "";
that.submitLoading = false;
return;
}
that.$opsMessage.fail(res.errorMsg);
that.submitLoading = false;
})
.catch(er => {
that.submitLoading = false;
console.error(er);
});
});
}
}
};
</script>
<style scoped lang="scss">
.payer-source {
position: relative;
.paler-icon {
position: absolute;
left: 0px;
top: -10px;
}
img {
width: 100px;
height: 100px;
}
}
</style>