461 lines
9.8 KiB
Plaintext
461 lines
9.8 KiB
Plaintext
<script setup>
|
||
import { reactive } from 'vue'
|
||
import { useUI } from '../../../utils/use-ui'
|
||
import { addLiveActivity } from '@/api/tui-kit'
|
||
import { useBarrageState } from '@/uni_modules/tuikit-atomic-x/state/BarrageState';
|
||
import { LIVE_BUSINESS } from '@/constants/live-keys'
|
||
|
||
|
||
const { showToast } = useUI()
|
||
|
||
const props = defineProps({
|
||
modelValue: {
|
||
type: Boolean,
|
||
default: false
|
||
},
|
||
/**
|
||
* 创建人类型:1-主播 2-管理员 3-系统
|
||
*/
|
||
creatorType: {
|
||
type: String,
|
||
default: ''
|
||
},
|
||
/**
|
||
* 直播间ID
|
||
*/
|
||
roomId: {
|
||
type: String,
|
||
default: ''
|
||
},
|
||
/**
|
||
* 群 id
|
||
*/
|
||
groupID: {
|
||
type: String,
|
||
default: ''
|
||
}
|
||
})
|
||
|
||
|
||
const { sendCustomMessage } = useBarrageState(props.roomId);
|
||
|
||
const emit = defineEmits(['update:modelValue'])
|
||
|
||
/**
|
||
* 根据用户输入的结束时间(分钟)计算开始时间和结束时间,并格式化为 yyyy-MM-dd HH:mm:ss
|
||
*/
|
||
const calculateTimeRange = endMinutes => {
|
||
// 获取当前时间(毫秒)
|
||
const now = new Date().getTime()
|
||
|
||
// 计算结束时间(毫秒)
|
||
const endTimeMs = now + endMinutes * 60 * 1000
|
||
|
||
// 创建 Date 对象
|
||
const startDate = new Date(now)
|
||
const endDate = new Date(endTimeMs)
|
||
|
||
// 格式化函数:将 Date 转为 'yyyy-MM-dd HH:mm:ss'
|
||
const formatDateTime = date => {
|
||
const pad = num => num.toString().padStart(2, '0')
|
||
const year = date.getFullYear()
|
||
const month = pad(date.getMonth() + 1) // getMonth() 返回 0-11
|
||
const day = pad(date.getDate())
|
||
const hours = pad(date.getHours())
|
||
const minutes = pad(date.getMinutes())
|
||
const seconds = pad(date.getSeconds())
|
||
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
|
||
}
|
||
|
||
return {
|
||
startTime: formatDateTime(startDate),
|
||
endTime: formatDateTime(endDate)
|
||
}
|
||
}
|
||
|
||
const close = () => {
|
||
emit('update:modelValue', false)
|
||
}
|
||
|
||
const formData = reactive({
|
||
title: '',
|
||
// startTime: '',
|
||
// endTime: '',
|
||
// 结束时间
|
||
endTime: '',
|
||
roomId: '',
|
||
rewardValue: '',
|
||
maxParticipants: '',
|
||
isRepeat: 0
|
||
})
|
||
|
||
const submitForm = async () => {
|
||
if (!formData.title) {
|
||
showToast('请填写标题')
|
||
return
|
||
}
|
||
if (!formData.endTime) {
|
||
showToast('请填写结束时间')
|
||
return
|
||
}
|
||
if (!formData.rewardValue) {
|
||
showToast('请填写奖励值')
|
||
return
|
||
}
|
||
if (!formData.maxParticipants) {
|
||
showToast('请填写参与人数')
|
||
return
|
||
}
|
||
// 参与人数不能为0
|
||
if (Number(formData.maxParticipants) === 0) {
|
||
showToast('参与人数不能为0')
|
||
return
|
||
}
|
||
// 参与人数必须是整数
|
||
if (!Number.isInteger(Number(formData.maxParticipants))) {
|
||
showToast('参与人数必须是整数')
|
||
return
|
||
}
|
||
// 参与人数不能大于1000
|
||
if (Number(formData.maxParticipants) > 1000) {
|
||
showToast('参与人数不能大于1000')
|
||
return
|
||
}
|
||
|
||
const data = {
|
||
title: formData.title,
|
||
startTime: calculateTimeRange(Number(formData.endTime)).startTime,
|
||
endTime: calculateTimeRange(Number(formData.endTime)).endTime,
|
||
rewardValue: Number(formData.rewardValue),
|
||
maxParticipants: Number(formData.maxParticipants),
|
||
isRepeat: formData.isRepeat,
|
||
creatorType: props.creatorType,
|
||
roomId: props.roomId
|
||
}
|
||
|
||
const res = await addLiveActivity(data)
|
||
console.log('=====发送活动====',res.data)
|
||
sendCustomMessage({
|
||
liveID: props.roomId,
|
||
businessID: LIVE_BUSINESS.SIGN,
|
||
data: JSON.stringify(res.data)
|
||
});
|
||
formData.title = ''
|
||
formData.endTime = ''
|
||
formData.rewardValue = ''
|
||
formData.maxParticipants = ''
|
||
close()
|
||
}
|
||
</script>
|
||
|
||
<template>
|
||
<view class="bottom-drawer-container" v-if="modelValue">
|
||
<view class="drawer-overlay" @tap="close"></view>
|
||
<view
|
||
class="bottom-drawer"
|
||
:class="{ 'drawer-open': modelValue }"
|
||
@click.stop
|
||
>
|
||
<view class="drawer-header">
|
||
<text class="drawer-title">添加活动</text>
|
||
<text class="drawer-done" @tap="submitForm">完成</text>
|
||
</view>
|
||
|
||
<view class="setting-item">
|
||
<text class="setting-label">标题</text>
|
||
<view class="live-list-quick-join">
|
||
<input
|
||
v-model="formData.title"
|
||
placeholder="请输入标题"
|
||
class="quick-join-input"
|
||
/>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="setting-item">
|
||
<text class="setting-label">结束时间(分钟)</text>
|
||
<view class="live-list-quick-join">
|
||
<input
|
||
v-model="formData.endTime"
|
||
type="number"
|
||
placeholder="请输入结束时间(分钟)"
|
||
class="quick-join-input"
|
||
/>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="setting-item">
|
||
<text class="setting-label">奖励值(积分)</text>
|
||
<view class="live-list-quick-join">
|
||
<input
|
||
v-model="formData.rewardValue"
|
||
type="number"
|
||
placeholder="请输入奖励值"
|
||
class="quick-join-input"
|
||
/>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="setting-item">
|
||
<text class="setting-label">参与人数</text>
|
||
<view class="live-list-quick-join">
|
||
<input
|
||
v-model="formData.maxParticipants"
|
||
type="number"
|
||
placeholder="请输入参与人数"
|
||
class="quick-join-input"
|
||
/>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<style lang="scss" scoped>
|
||
.bottom-drawer-container {
|
||
position: fixed;
|
||
bottom: 0;
|
||
left: 0;
|
||
right: 0;
|
||
top: 0;
|
||
z-index: 1000;
|
||
}
|
||
|
||
.drawer-overlay {
|
||
position: absolute;
|
||
top: 0;
|
||
left: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
background-color: rgba(0, 0, 0, 0.4);
|
||
}
|
||
|
||
.bottom-drawer {
|
||
position: absolute;
|
||
bottom: 0;
|
||
left: 0;
|
||
right: 0;
|
||
background: rgba(34, 38, 46, 1);
|
||
border-top-left-radius: 32rpx;
|
||
border-top-right-radius: 32rpx;
|
||
transform: translateY(100%);
|
||
transition-property: transform;
|
||
transition-duration: 0.3s;
|
||
transition-timing-function: ease;
|
||
padding: 32rpx;
|
||
}
|
||
|
||
.drawer-open {
|
||
transform: translateY(0);
|
||
}
|
||
|
||
.drawer-header {
|
||
flex-direction: row;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
margin-bottom: 32rpx;
|
||
}
|
||
|
||
.drawer-title {
|
||
font-size: 32rpx;
|
||
color: #ffffff;
|
||
font-weight: 500;
|
||
}
|
||
|
||
.drawer-done {
|
||
font-size: 32rpx;
|
||
color: #2b65fb;
|
||
}
|
||
|
||
.setting-item {
|
||
flex-direction: row;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
height: 88rpx;
|
||
border-bottom-width: 1px;
|
||
border-bottom-color: rgba(255, 255, 255, 0.1);
|
||
|
||
.live-list-quick-join {
|
||
flex-direction: row;
|
||
align-items: center;
|
||
margin: 0 32rpx 24rpx 32rpx;
|
||
}
|
||
|
||
.quick-join-input {
|
||
flex: 1;
|
||
width: 360rpx;
|
||
height: 64rpx;
|
||
border-radius: 999rpx;
|
||
padding: 10rpx 20rpx;
|
||
margin-top: 20rpx;
|
||
font-size: 28rpx;
|
||
text-align: right;
|
||
color: white;
|
||
}
|
||
}
|
||
|
||
.setting-label {
|
||
font-size: 28rpx;
|
||
color: #ffffff;
|
||
}
|
||
|
||
.setting-value {
|
||
flex-direction: row;
|
||
align-items: center;
|
||
}
|
||
|
||
.setting-text {
|
||
font-size: 28rpx;
|
||
color: rgba(255, 255, 255, 0.5);
|
||
margin-right: 8rpx;
|
||
}
|
||
|
||
.setting-arrow {
|
||
width: 24rpx;
|
||
height: 24rpx;
|
||
}
|
||
|
||
.volume-settings {
|
||
margin-top: 32rpx;
|
||
}
|
||
|
||
.section-title {
|
||
font-size: 28rpx;
|
||
color: rgba(255, 255, 255, 0.5);
|
||
margin-bottom: 24rpx;
|
||
}
|
||
|
||
.slider-item {
|
||
margin-bottom: 24rpx;
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
|
||
.slider-label {
|
||
font-size: 28rpx;
|
||
color: #ffffff;
|
||
margin-bottom: 16rpx;
|
||
}
|
||
|
||
/* 自定义控制区域样式 */
|
||
.custom-slider {
|
||
flex: 1;
|
||
flex-direction: row;
|
||
align-items: center;
|
||
margin: 0 20rpx;
|
||
}
|
||
|
||
.control-btn {
|
||
width: 60rpx;
|
||
height: 60rpx;
|
||
border-radius: 30rpx;
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
border: 2rpx solid #2b6ad6;
|
||
}
|
||
|
||
.minus-btn {
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
background-color: rgba(43, 106, 214, 0.1);
|
||
}
|
||
|
||
.plus-btn {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
background-color: #2b6ad6;
|
||
}
|
||
|
||
.btn-text {
|
||
font-size: 32rpx;
|
||
font-weight: bold;
|
||
color: #ffffff;
|
||
}
|
||
|
||
.plus-btn .btn-text {
|
||
color: #ffffff;
|
||
}
|
||
|
||
.progress-section {
|
||
flex: 1;
|
||
margin: 0 20rpx;
|
||
align-items: center;
|
||
flex-direction: row;
|
||
justify-content: center;
|
||
}
|
||
|
||
.progress-bar {
|
||
width: 400rpx;
|
||
height: 8rpx;
|
||
background-color: rgba(255, 255, 255, 0.3);
|
||
border-radius: 4rpx;
|
||
position: relative;
|
||
overflow: hidden;
|
||
margin-right: 16rpx;
|
||
}
|
||
|
||
.progress-fill {
|
||
height: 8rpx;
|
||
background-color: #2b6ad6;
|
||
border-radius: 4rpx;
|
||
}
|
||
|
||
.current-value {
|
||
font-size: 24rpx;
|
||
color: #ffffff;
|
||
font-weight: 600;
|
||
text-align: center;
|
||
z-index: 10;
|
||
}
|
||
|
||
.voice-effects,
|
||
.reverb-effects {
|
||
margin-top: 32rpx;
|
||
}
|
||
|
||
.effects-grid {
|
||
flex-direction: row;
|
||
flex-wrap: wrap;
|
||
margin: 0 -8rpx;
|
||
}
|
||
|
||
.effect-item {
|
||
margin: 8rpx;
|
||
/* background-color: rgba(255, 255, 255, 0.1); */
|
||
|
||
justify-content: center;
|
||
align-items: center;
|
||
}
|
||
|
||
.effect-active {
|
||
background-color: rgba(43, 101, 251, 0.2);
|
||
border-width: 2rpx;
|
||
border-color: #2b65fb;
|
||
}
|
||
|
||
.effect-icon-container {
|
||
width: 112rpx;
|
||
height: 112rpx;
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
border-radius: 16rpx;
|
||
background-color: rgba(255, 255, 255, 0.1);
|
||
margin-bottom: 12rpx;
|
||
}
|
||
|
||
.effect-icon {
|
||
width: 48rpx;
|
||
height: 48rpx;
|
||
margin-bottom: 8rpx;
|
||
}
|
||
|
||
.effect-name {
|
||
font-size: 24rpx;
|
||
color: #ffffff;
|
||
}
|
||
</style>
|