| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270 |
- <template>
- <div class="app-container">
- <div style="padding-bottom: 20px">
- <span v-if="courseName!=null">{{ courseName }}</span>
- </div>
- <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
- <el-form-item label="小节名称" prop="title">
- <el-input
- v-model="queryParams.title"
- placeholder="请输入小节名称"
- clearable
- size="small"
- @keyup.enter.native="handleQuery"
- />
- </el-form-item>
- <el-form-item>
- <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
- <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
- </el-form-item>
- </el-form>
- <el-table border v-loading="loading" :data="userCourseVideoList" @selection-change="handleSelectionChange">
- <el-table-column type="selection" width="55" align="center" />
- <el-table-column label="视频ID" align="center" prop="videoId" />
- <el-table-column label="小节名称" align="center" show-overflow-tooltip prop="title" />
- <el-table-column label="视频文件名称" align="center" show-overflow-tooltip prop="fileName" >
- </el-table-column>
- <el-table-column label="视频时长" align="center" prop="duration">
- <template slot-scope="{ row }">
- {{ formatDuration(row.duration) }}
- </template>
- </el-table-column>
- <el-table-column label="排序" align="center" prop="courseSort" />
- <el-table-column label="上传时间" align="center" prop="createTime" />
- <el-table-column label="默认红包" align="center" prop="redPacketMoney" />
- <el-table-column label="公司红包" align="center" prop="companyRedPacketMoney" />
- <el-table-column label="是否上架" align="center" prop="isOnPut">
- <template slot-scope="{ row }">
- <el-tag v-if="row.isOnPut == 0">是</el-tag>
- <el-tag type="danger" v-if="row.isOnPut == 1">否</el-tag>
- </template>
- </el-table-column>
- <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
- <template slot-scope="scope">
- <el-button
- size="mini"
- type="text"
- @click="handleDetails(scope.row)"
- >查看</el-button>
- <!-- <el-button-->
- <!-- size="mini"-->
- <!-- type="text"-->
- <!-- v-hasPermi="['course:userCourseVideo:changeRewardConfig']"-->
- <!-- @click="updateAnswerReward(scope.row)"-->
- <!-- >设置答题奖励</el-button>-->
- <el-button
- size="mini"
- type="text"
- v-hasPermi="['course:userCourseVideo:edit']"
- @click="updateMoney(scope.row)"
- >设置红包金额</el-button>
- <!-- <el-button-->
- <!-- size="mini"-->
- <!-- type="text"-->
- <!-- v-hasPermi="['course:relation:edit']"-->
- <!-- @click="updateReward(scope.row)"-->
- <!-- >设置课程奖励</el-button>-->
- <el-button size="mini"
- type="text" @click="openTagDialog(scope.row)">
- 绑定看课标签
- </el-button>
- <el-button size="mini"
- type="text" v-if="projectFrom === 'hzyy'" @click="openDialog(scope.row)">
- 复制看课链接
- </el-button>
- </template>
- </el-table-column>
- </el-table>
- <pagination
- v-show="total>0"
- :total="total"
- :page.sync="queryParams.pageNum"
- :limit.sync="queryParams.pageSize"
- @pagination="getList"
- />
- <el-drawer
- :with-header="false"
- size="75%"
- :visible.sync="open" append-to-body>
- <userCourseVideoDetails ref="userCourseVideoDetails" />
- </el-drawer>
- <el-dialog title="设置红包金额" :visible.sync="moneyOpen" width="600px" append-to-body>
- <el-form ref="form" label-width="100px">
- <el-form-item label="红包金额" prop="corpId">
- <el-input-number v-model="redPacketMoneyForm.redPacketMoney" :min="0.1" :max="200" :step="0.1" ></el-input-number>
- </el-form-item>
- </el-form>
- <div slot="footer" class="dialog-footer">
- <el-button type="primary" @click="submitForm">确 定</el-button>
- <el-button @click="cancel">取 消</el-button>
- </div>
- </el-dialog>
- <el-dialog
- title="生成链接"
- :visible.sync="dialogVisible"
- width="400px"
- @close="resetRoomForm"
- append-to-body>
- <el-form :model="roomLinkForm" label-width="120px">
- <!-- 新增下拉框 -->
- <el-form-item label="销售企微选择">
- <el-select
- v-model="roomLinkForm.qwUserId"
- placeholder="请选择销售企微"
- style="width: 100%">
- <el-option
- v-for="item in qwUserList"
- :key="item.id"
- :label="formatOptionLabel(item)"
- :value="item.id">
- </el-option>
- </el-select>
- </el-form-item>
- </el-form>
- <div slot="footer" class="dialog-footer">
- <el-button @click="dialogVisible = false">取消</el-button>
- <el-button type="primary" @click="confirm">确认</el-button>
- </div>
- </el-dialog>
- <AutoTagDialog
- v-if="currentVideoId !== null"
- :visible.sync="tagDialogVisible"
- :title="tagDialogTitle"
- :videoId="currentVideoId"
- append-to-body
- />
- <el-dialog
- title="课程奖励选择"
- :visible.sync="rewardOpen"
- width="80%"
- append-to-body
- @close="handleRewardDialogClose"
- >
- <div class="reward-dialog">
- <div class="selection-info" v-if="rewardType === 1">
- <span>已选择 {{ selectedRewards.length }}/2 个奖励项目</span>
- <el-button
- type="text"
- @click="clearSelection"
- :disabled="selectedRewards.length === 0"
- >
- 清空选择
- </el-button>
- </div>
- <el-table
- border
- v-loading="rewardLoading"
- :data="rewardList"
- @selection-change="handleRewardSelectionChange"
- ref="rewardTable"
- >
- <el-table-column
- type="selection"
- width="55"
- align="center"
- :selectable="checkSelectable"
- />
- <el-table-column label="主键ID" align="center" prop="id" />
- <el-table-column label="奖励名称" align="center" prop="name" />
- <el-table-column label="奖励描述" align="center" prop="description" />
- <el-table-column label="奖励类型" align="center" prop="rewardType">
- <template slot-scope="scope">
- <dict-tag :options="rewardTypeOptions" :value="scope.row.rewardType"/>
- </template>
- </el-table-column>
- <el-table-column label="期望值" align="center" prop="expectedValue" />
- <el-table-column label="实际奖励内容" align="center" prop="actualRewards">
- <template slot-scope="scope">
- <el-button
- size="mini"
- type="text"
- icon="el-icon-view"
- @click="handleViewReward(scope.row)"
- >查看详情</el-button>
- </template>
- </el-table-column>
- <el-table-column label="创建时间" align="center" prop="createTime" />
- </el-table>
- <pagination
- v-show="rewardTotal>0"
- :total="rewardTotal"
- :page.sync="rewardQueryParams.pageNum"
- :limit.sync="rewardQueryParams.pageSize"
- @pagination="getRewardList"
- />
- </div>
- <div slot="footer" class="dialog-footer">
- <el-button @click="rewardOpen = false">取 消</el-button>
- <el-button
- type="primary"
- @click="submitRewardSelection"
- :disabled="selectedRewards.length === 0 || (rewardType !== 1 && selectedRewards.length > 1)"
- >
- 确 定
- </el-button>
- <el-dialog
- :title="`奖励详情 - ${currentReward.name || '未知奖励'}`"
- :visible.sync="detailVisible"
- width="700px"
- append-to-body
- >
- <div class="reward-detail-container">
- <!-- 基础信息 -->
- <el-descriptions :column="2" border class="base-info">
- <el-descriptions-item label="奖励名称">{{ currentReward.name || '-' }}</el-descriptions-item>
- <el-descriptions-item label="奖励类型">
- <dict-tag :options="rewardTypeOptions" :value="currentReward.rewardType"/>
- </el-descriptions-item>
- <el-descriptions-item label="状态">
- <dict-tag :options="statusOptions" :value="currentReward.status"/>
- </el-descriptions-item>
- <el-descriptions-item label="期望值">{{ currentReward.expectedValue || 0 }}</el-descriptions-item>
- <el-descriptions-item label="描述" :span="2">{{ currentReward.description || '-' }}</el-descriptions-item>
- </el-descriptions>
- <!-- 奖励内容详情 -->
- <div class="reward-content">
- <h4>奖励内容详情</h4>
- <!-- 宝箱类型奖励 -->
- <div v-if="currentReward.rewardType === 1" class="chest-reward">
- <el-table :data="parsedRewardItems" size="small" border stripe>
- <el-table-column label="数量" prop="amount" align="center">
- <template slot-scope="{row}">
- {{ row.amount || 1 }}
- </template>
- </el-table-column>
- <el-table-column label="概率" prop="probability"align="center">
- <template slot-scope="{row}">
- <el-tag v-if="row.probability" size="small">{{ row.probability }}</el-tag>
- <span v-else>-</span>
- </template>
- </el-table-column>
- </el-table>
- <div v-if="!parsedRewardItems || parsedRewardItems.length === 0" class="empty-tip">
- 暂无奖励配置
- </div>
- </div>
- <!-- 红包类型奖励 -->
- <div v-else-if="currentReward.rewardType === 2" class="redpacket-reward">
- <div class="reward-amount">
- <i class="el-icon-money" style="color: #e6a23c; font-size: 24px;"></i>
- <span class="amount-text">{{ rewardAmount }} 元</span>
- <el-tag type="warning" size="small">红包奖励</el-tag>
- </div>
- </div>
- <!-- 福币类型奖励 -->
- <div v-else-if="currentReward.rewardType === 3" class="points-reward">
- <div class="reward-amount">
- <i class="el-icon-coin" style="color: #67c23a; font-size: 24px;"></i>
- <span class="amount-text">{{ rewardAmount }} 福币</span>
- <el-tag type="success" size="small">福币奖励</el-tag>
- </div>
- </div>
- <!-- 转盘类型奖励 -->
- <div v-else-if="currentReward.rewardType === 4" class="chest-reward">
- <el-table :data="parsedRewardItems" size="small" border stripe>
- <el-table-column label="图标" prop="iconUrl" align="center" width="80">
- <template slot-scope="{row}">
- <el-image
- v-if="row.iconUrl"
- :src="row.iconUrl"
- :preview-src-list="[row.iconUrl]"
- fit="cover"
- style="width:32px;height:32px;border:1px solid #ebeef5;border-radius:4px;"
- />
- <span v-else>-</span>
- </template>
- </el-table-column>
- <el-table-column label="奖品名称" prop="name" align="center" />
- <el-table-column label="奖品类型" prop="type" align="center">
- <template slot-scope="{row}">
- <el-tag v-if="row.type" size="small">
- {{ getSpinItemTypeLabel(row.type) }}
- </el-tag>
- <span v-else>-</span>
- </template>
- </el-table-column>
- <el-table-column label="数量" prop="amount" align="center">
- <template slot-scope="{row}">
- <span v-if="row.amount">
- {{ row.amount }} {{ getSpinItemUnit(row.type) }}
- </span>
- <span v-else>-</span>
- </template>
- </el-table-column>
- <el-table-column label="概率" prop="probability" align="center">
- <template slot-scope="{row}">
- <el-tag v-if="row.probability" size="small">{{ row.probability }}</el-tag>
- <span v-else>-</span>
- </template>
- </el-table-column>
- </el-table>
- <div v-if="!parsedRewardItems || parsedRewardItems.length === 0" class="empty-tip">
- 暂无奖励配置
- </div>
- </div>
- <!-- 保底转盘类型奖励 -->
- <div v-else-if="currentReward.rewardType === 5" class="chest-reward">
- <el-table :data="parsedRewardItems" size="small" border stripe>
- <el-table-column label="图标" prop="iconUrl" align="center" width="80">
- <template slot-scope="{row}">
- <el-image
- v-if="row.iconUrl"
- :src="row.iconUrl"
- :preview-src-list="[row.iconUrl]"
- fit="cover"
- style="width:32px;height:32px;border:1px solid #ebeef5;border-radius:4px;"
- />
- <span v-else>-</span>
- </template>
- </el-table-column>
- <el-table-column label="奖品名称" prop="name" align="center" />
- <el-table-column label="奖品类型" prop="type" align="center">
- <template slot-scope="{row}">
- <el-tag v-if="row.type" size="small">
- {{ getSpinItemTypeLabel(row.type) }}
- </el-tag>
- <span v-else>-</span>
- </template>
- </el-table-column>
- <el-table-column label="数量" prop="amount" align="center">
- <template slot-scope="{row}">
- <span v-if="row.amount">
- {{ row.amount }} {{ getSpinItemUnit(row.type) }}
- </span>
- <span v-else>-</span>
- </template>
- </el-table-column>
- <el-table-column label="概率" prop="probability" align="center">
- <template slot-scope="{row}">
- <el-tag v-if="row.probability" size="small">{{ row.probability }}</el-tag>
- <span v-else>-</span>
- </template>
- </el-table-column>
- <el-table-column label="保底" prop="isGuarantee" align="center">
- <template slot-scope="{row}">
- <el-tag size="small" :type="row.isGuarantee ? 'success' : 'info'">{{ row.isGuarantee ? '是' : '否' }}</el-tag>
- </template>
- </el-table-column>
- </el-table>
- <div v-if="!parsedRewardItems || parsedRewardItems.length === 0" class="empty-tip">
- 暂无奖励配置
- </div>
- </div>
- <!-- 未知类型 -->
- <div v-else class="unknown-reward">
- <el-alert type="info" title="未知奖励类型" :closable="false"></el-alert>
- </div>
- </div>
- </div>
- <div slot="footer" class="dialog-footer">
- <el-button @click="detailVisible = false">关 闭</el-button>
- </div>
- </el-dialog>
- </div>
- </el-dialog>
- <!-- 答题奖励弹窗 -->
- <el-dialog
- :title="answerRewardDialog.title"
- :visible.sync="answerRewardDialog.open"
- width="700px"
- append-to-body
- >
- <el-form :model="answerRewardDialog.answerRewardForm" v-loading="answerRewardDialog.loading" label-width="120px">
- <div class="default-amounts">
- <!-- <div class="amount-item">-->
- <!-- <i class="el-icon-money amount-icon red"></i>-->
- <!-- <span class="label">默认红包奖励</span>-->
- <!-- <span class="value">{{answerRewardDialog.answerRewardForm.defaultRedPacketAmount || 0}} 元</span>-->
- <!-- <el-tag :type="answerRewardDialog.answerRewardForm.redPacketRuleId ? 'info' : 'warning'" size="mini">{{ answerRewardDialog.answerRewardForm.redPacketRuleId ? '已选择配置' : '配置生效中' }}</el-tag>-->
- <!-- </div>-->
- <div class="amount-item">
- <i class="el-icon-coin amount-icon green"></i>
- <span class="label">默认小程序福币奖励</span>
- <span class="value">{{answerRewardDialog.answerRewardForm.defaultPointNum || 0}} 福币</span>
- <el-tag :type="'success'" size="mini">{{ '生效中' }}</el-tag>
- </div>
- <div class="amount-item">
- <i class="el-icon-coin amount-icon green"></i>
- <span class="label">默认APP小程序福币奖励</span>
- <span class="value">{{answerRewardDialog.answerRewardForm.defaultAppPointNum || 0}} 福币</span>
- <el-tag :type="answerRewardDialog.answerRewardForm.pointRuleId ? 'info' : 'success'" size="mini">{{ answerRewardDialog.answerRewardForm.pointRuleId ? '已选择配置' : '生效中' }}</el-tag>
- </div>
- <div class="amount-item">
- <i class="el-icon-money amount-icon red"></i>
- <span class="label">默认转盘奖励</span>
- <span class="value" v-if="shouldShowTurntableRule">{{getTurntableRuleName(answerRewardDialog.answerRewardForm.defaultTurntableRuleId)}}</span>
- <span class="value" v-else>-</span>
- <el-tag :type="answerRewardDialog.answerRewardForm.turntableRuleId ? 'info' : 'success'" size="mini">{{ answerRewardDialog.answerRewardForm.turntableRuleId ? '已选择配置' : '生效中' }}</el-tag>
- </div>
- </div>
- <el-form-item label="红包配置">
- <el-select
- ref="customSelect2"
- v-model="answerRewardDialog.answerRewardForm.redPacketRuleId"
- placeholder="请选择红包"
- @click.native.stop="openRuleDialog(answerRewardDialog.answerRewardForm.redPacketRuleId, 2)"
- clearable
- style="width: 100%;">
- <el-option
- v-for="item in ruleList"
- :key="item.id"
- :label="item.name"
- :value="item.id">
- </el-option>
- </el-select>
- </el-form-item>
- <el-form-item label="福币配置">
- <el-select
- ref="customSelect3"
- v-model="answerRewardDialog.answerRewardForm.pointRuleId"
- placeholder="请选择福币"
- @click.native.stop="openRuleDialog(answerRewardDialog.answerRewardForm.pointRuleId, 3)"
- clearable
- style="width: 100%;">
- <el-option
- v-for="item in ruleList"
- :key="item.id"
- :label="item.name"
- :value="item.id">
- </el-option>
- </el-select>
- </el-form-item>
- <el-form-item label="随机转盘配置">
- <el-select
- ref="customSelect4"
- v-model="answerRewardDialog.answerRewardForm.turntableRuleId"
- placeholder="请选择转盘"
- @click.native.stop="openRuleDialog(answerRewardDialog.answerRewardForm.turntableRuleId, 4)"
- clearable
- style="width: 100%;">
- <el-option
- v-for="item in ruleList"
- :key="item.id"
- :label="item.name"
- :value="item.id">
- </el-option>
- </el-select>
- </el-form-item>
- <el-form-item label="保底转盘配置">
- <el-select
- ref="customSelect5"
- v-model="answerRewardDialog.answerRewardForm.turntableGuaranteeRuleId"
- placeholder="请选择保底转盘"
- @click.native.stop="openRuleDialog(answerRewardDialog.answerRewardForm.turntableGuaranteeRuleId, 5)"
- clearable
- style="width: 100%;">
- <el-option
- v-for="item in ruleList"
- :key="item.id"
- :label="item.name"
- :value="item.id">
- </el-option>
- </el-select>
- </el-form-item>
- </el-form>
- <div slot="footer" class="dialog-footer">
- <el-button @click="answerRewardDialog.open=false">取 消</el-button>
- <el-button type="primary" :loading="saving" :disabled="saving" @click="submitAnswerReward">确 定</el-button>
- </div>
- </el-dialog>
- </div>
- </template>
- <script>
- import {
- updatePacketMoney,
- getVideoListByCourseId,
- getAnswerRewardConfig,
- changeAnswerRewardConfig,
- } from "@/api/course/userCourseVideo";
- import userCourseVideoDetails from '../../components/course/userCourseVideoDetails.vue';
- import {listReward, getReward, listByIds} from "@/api/course/reward";
- import { listRelation, updateRelation, } from "@/api/course/relation";
- import {createLinkUrl, createRoomLinkUrl, queryQwIds} from "@/api/course/sopCourseLink";
- import AutoTagDialog from "@/views/components/tag/AutoTagDialog.vue";
- import {addTag, updateTag} from "@/api/tag/api";
- export default {
- name: "userCourseCatalog",
- components: {
- userCourseVideoDetails,
- AutoTagDialog
- },
- props: {
- video: {
- type: Object,
- required: false, // 改为非必需
- default: () => ({}) // 提供默认值
- },
- },
- data() {
- return {
- answerRewardDialog: {
- open: false,
- title: '设置答题奖励',
- loading: false,
- answerRewardForm: {
- videoId: null,
- redPacketRuleId: null,
- pointRuleId: null,
- turntableRuleId: null,
- turntableGuaranteeRuleId: null,
- defaultRedPacketAmount: null,
- defaultPointNum: null,
- defaultAppPointNum: null,
- defaultTurntableRuleId: null
- }
- },
- ruleList: [],
- // 转盘奖励-奖励类型选项
- spinItemTypeOptions: [],
- saving: false,
- currentReward: {},
- rewardOpen: false,
- rewardType: null,
- rewardLoading: false,
- rewardList: [],
- selectedRewards: [], // 选中的奖励项
- rewardsRelation: [], // 选中的奖励项
- rewardTotal: 0,
- rewardQueryParams: {
- pageNum: 1,
- pageSize: 10,
- videoId: null,
- rewardType:1
- },
- statusOptions:[],
- rewardTypeOptions:[],
- detailVisible: false,
- currentRow: null,
- // 假设这里有当前课程小节的数据传入,里面含id等
- tagGroups: [],
- tagsInGroup: [],
- tagDialogVisible: false,
- tagDialogTitle: "",
- tagDialogFormData: null,
- currentVideoId:null,
- projectFrom:process.env.VUE_APP_PROJECT_FROM,
- tagDialog: {
- videoId: null,
- groupId: null,
- watchTagId: null,
- finishTagId: null,
- tgId: null,
- watchingTgId: null,
- watchedTgId: null
- },
- linkForm:{
- days:null,
- courseId:null,
- videoId:null
- },
- roomLinkForm:{
- courseId:null,
- videoId:null,
- qwUserId:null,
- qwUserName:null,
- corpId:null,
- title:null,
- },
- dialogVisible: false, // 控制弹框显示
- //短链
- sortLink:'',
- //课题
- questionBank:{
- title:'',
- open:false,
- },
- moneyOpen:false,
- videoUrl: "",
- uploadTypeOptions: [
- { dictLabel: "线路一", dictValue: 2 },
- { dictLabel: "线路二", dictValue: 1 },
- { dictLabel: "线路三", dictValue: 3 },
- ],
- uploadLoading:false,
- courseId:null,
- videoName:'',
- title: "",
- redPacketMoneyForm:{
- redPacketMoney:null,
- voidId:null
- },
- // 是否显示弹出层
- open: false,
- uploadUrl:process.env.VUE_APP_BASE_API+"/common/uploadHuaWeiObs",
- baseUrl: process.env.VUE_APP_BASE_API,
- typeOptions:[],
- files:[],
- fileList: [],
- // 上传成功后的地址
- videoURL: '',
- // 进度条百分比
- progress: 0,
- // 上传视频获取成功后拿到的fileID【备用】
- fileId: '',
- courseName:null,
- userCourseVideoList:[],
- fetchingQwIds: false,
- qwUserList:[],
- total: 0,
- queryParams: {
- pageNum: 1,
- pageSize: 10,
- courseId:null,
- title:null
- },
- // 显示搜索条件
- showSearch: true,
- // 遮罩层
- loading: true,
- // 导出遮罩层
- exportLoading: false,
- // 选中数组
- ids: [],
- // 非单个禁用
- single: true,
- // 非多个禁用
- multiple: true,
- // 表单参数
- form: {},
- // 表单校验
- rules: {
- title: [
- { required: true, message: "小节名称不能为空", trigger: "change" }
- ],
- courseSort: [
- { required: true, message: "排序不能为空", trigger: "change" }
- ],
- }
- }
- },
- computed: {
- // 解析奖励项数据
- parsedRewardItems() {
- if (!this.currentReward.actualRewards) return null;
- try {
- const parsed = JSON.parse(this.currentReward.actualRewards);
- return Array.isArray(parsed) ? parsed : null;
- } catch (e) {
- console.error("解析奖励内容失败", e);
- return null;
- }
- },
- // 获取红包或福币金额
- rewardAmount() {
- if (!this.currentReward.actualRewards) return 0;
- try {
- const parsed = JSON.parse(this.currentReward.actualRewards);
- if (this.currentReward.rewardType === 2) {
- return parsed.amount || parsed.money || 0;
- } else if (this.currentReward.rewardType === 3) {
- return parsed.points || parsed.score || 0;
- }
- return 0;
- } catch (e) {
- return 0;
- }
- },
- // 只有在dialog打开时才显示转盘规则名称
- shouldShowTurntableRule() {
- return this.answerRewardDialog.open && this.answerRewardDialog.answerRewardForm.defaultTurntableRuleId
- }
- },
- created() {
- this.getDicts("sys_course_temp_type").then(response => {
- this.typeOptions = response.data;
- });
- this.getDicts("sys_reward_type").then((response) => {
- this.rewardTypeOptions = response.data;
- });
- this.getDicts("sys_user_status").then((response) => {
- this.statusOptions = response.data;
- });
- this.getDicts("spin_reward_type").then((response) => {
- this.spinItemTypeOptions = response.data;
- });
- },
- methods: {
- getTurntableRuleName(ruleId) {
- if (!ruleId) return '-'
- // 从ruleList中查找对应的规则名称
- const rule = this.ruleList.find(item => item.id === ruleId)
- if (rule) {
- return rule.name
- }
- // 如果ruleList中没有,则异步获取
- getReward(ruleId).then(response => {
- const {code,data} = response
- if (code === 200 && data) {
- if (!this.ruleList.find(item => item.id === ruleId)) {
- this.ruleList.push(data)
- }
- return data.name
- }
- }).catch(() => {
- console.error('获取转盘规则失败:', ruleId)
- })
- return '加载中...'
- },
- // 查看奖励详情
- handleViewReward(row) {
- this.currentReward = { ...row };
- this.detailVisible = true;
- },
- updateReward(row) {
- this.currentVideoId = row.videoId;
- this.rewardQueryParams.videoId = row.videoId;
- this.rewardOpen = true;
- this.rewardType = 1
- this.getRewardList();
- // 获取已设置的奖励(如果有)
- this.getCurrentRewards(row.videoId);
- },
- // 获取奖励列表
- getRewardList() {
- this.rewardLoading = true;
- listRelation({
- videoSectionId: this.currentVideoId,
- type: 1
- }).then(response => {
- this.rewardsRelation = response.rows;
- }).catch(() => {
- this.rewardLoading = false;
- });
- listReward(this.rewardQueryParams).then(response => {
- this.rewardList = response.rows;
- this.rewardTotal = response.total;
- this.rewardLoading = false;
- // 设置已选中的奖励
- this.$nextTick(() => {
- this.rewardList.forEach(row => {
- if (this.rewardsRelation.some(item => item.rewardId === row.id)) {
- this.$refs.rewardTable.toggleRowSelection(row, true);
- }
- });
- });
- }).catch(() => {
- this.rewardLoading = false;
- });
- },
- // 获取当前视频已设置的奖励
- getCurrentRewards(videoId) {
- // 这里假设有一个API可以获取视频已设置的奖励
- // 实际实现中需要根据后端API调整
- this.selectedRewards = []; // 先清空
- // 模拟数据,实际应从API获取
- /*
- getVideoRewards(videoId).then(response => {
- this.selectedRewards = response.data || [];
- });
- */
- },
- // 处理奖励选择变化
- handleRewardSelectionChange(selection) {
- // 限制最多选择两项
- if (selection.length > 2) {
- this.$refs.rewardTable.clearSelection();
- // 保留前两项
- const limitedSelection = selection.slice(0, 2);
- limitedSelection.forEach(item => {
- this.$refs.rewardTable.toggleRowSelection(item, true);
- });
- this.selectedRewards = limitedSelection;
- this.$message.warning('最多只能选择两个奖励项目');
- } else {
- this.selectedRewards = selection;
- }
- },
- updateAnswerReward(row) {
- this.answerRewardDialog.answerRewardForm = {}
- this.answerRewardDialog.open = true
- this.answerRewardDialog.loading = true
- getAnswerRewardConfig(row.videoId).then(response => {
- this.answerRewardDialog.answerRewardForm = response.data
- this.answerRewardDialog.answerRewardForm.videoId = row.videoId
- // 查询已配置列表
- let ids = []
- for (const [key, value] of Object.entries(response.data)) {
- if (key === "redPacketRuleId" || key === "pointRuleId" ||
- key === "turntableRuleId" || key === "turntableGuaranteeRuleId")
- if (value) {
- ids.push(value)
- }
- }
- if (ids.length > 0) {
- listByIds(ids).then(response => {
- this.ruleList = response.data
- this.answerRewardDialog.loading = false
- })
- } else {
- this.answerRewardDialog.loading = false
- }
- })
- },
- submitAnswerReward(){
- this.saving = true
- changeAnswerRewardConfig(this.answerRewardDialog.answerRewardForm).then(response => {
- const {code, msg} = response
- if (code === 200){
- this.msgSuccess("修改成功");
- this.getList()
- this.answerRewardDialog.open = false
- } else {
- this.msgError(msg);
- }
- this.saving = false
- })
- },
- openRuleDialog(id, type) {
- this.$nextTick(() => {
- this.$refs['customSelect' + type]?.blur();
- });
- this.rewardList =[]
- this.rewardOpen = true
- this.rewardLoading = true
- listReward({"rewardType": type, "status": 1}).then(response => {
- const {rows, total} = response
- this.rewardList = rows
- this.rewardTotal = total
- // 根据传入的规则ID,默认选中对应项
- const preselected = this.rewardList.filter(item => item.id === id)
- this.selectedRewards = preselected
- this.$nextTick(() => {
- if (this.$refs.rewardTable && preselected.length > 0) {
- // 先清空再选中,避免残留状态
- this.$refs.rewardTable.clearSelection()
- preselected.forEach(row => this.$refs.rewardTable.toggleRowSelection(row, true))
- }
- })
- this.rewardLoading = false
- })
- this.rewardType = type
- },
- // 获取转盘奖励类型标签
- getSpinItemTypeLabel(type) {
- const option = this.spinItemTypeOptions.find(item => item.dictValue === type.toString());
- return option ? option.dictLabel : type;
- },
- // 获取转盘奖励类型单位
- getSpinItemUnit(type) {
- const option = this.spinItemTypeOptions.find(item => item.dictValue === type.toString());
- const label = option ? option.dictLabel : '';
- if (label.includes("红包")) {
- return '元';
- } else if (label.includes("福币")) {
- return '福币';
- } else {
- return '';
- }
- },
- // 检查是否可选
- checkSelectable(row, index) {
- // 如果已选择两项且当前行未被选中,则禁用选择
- return this.selectedRewards.length < 2 ||
- this.selectedRewards.some(item => item.rewardId === row.rewardId);
- },
- // 清空选择
- clearSelection() {
- this.$refs.rewardTable.clearSelection();
- this.selectedRewards = [];
- },
- // 提交奖励选择
- submitRewardSelection() {
- if (this.selectedRewards.length === 0) {
- this.$message.warning('请至少选择一个奖励项目');
- return;
- }
- const rewardIds = this.selectedRewards.map(item => item.id);
- const rewardIdList = this.rewardsRelation.map(item => item.rewardId);
- if (this.rewardType === 1) {
- updateRelation({
- videoSectionId: this.currentVideoId,
- rewardIds: rewardIds,
- rewardIdList: rewardIdList
- }).then(response => {
- if (response.code === 200) {
- this.$message.success('奖励设置成功');
- }
- });
- } else {
- const ruleId = rewardIds[0]
- if (this.rewardType === 2) {
- this.answerRewardDialog.answerRewardForm.redPacketRuleId = ruleId
- }
- if (this.rewardType === 3) {
- this.answerRewardDialog.answerRewardForm.pointRuleId = ruleId
- }
- if (this.rewardType === 4) {
- this.answerRewardDialog.answerRewardForm.turntableRuleId = ruleId
- }
- if (this.rewardType === 5) {
- this.answerRewardDialog.answerRewardForm.turntableGuaranteeRuleId = ruleId
- }
- let rule = this.rewardList.find(item => item.id === ruleId)
- if (!this.ruleList.some(item => item.id === rule.id)) {
- this.ruleList.push(rule)
- }
- }
- this.rewardOpen = false
- },
- // 处理奖励弹窗关闭
- handleRewardDialogClose() {
- this.selectedRewards = [];
- this.currentVideoId = null;
- },
- formatOptionLabel(item) {
- return item.corpName ? `${item.qwUserName} (${item.corpName})` : item.qwUserName;
- },
- closeTagDialog(){
- this.tagDialogVisible = false;
- },
- openTagDialog(row) {
- this.currentRow = row;
- this.tagDialogVisible = true;
- this.currentVideoId = row.videoId;
- },
- updateTagsInGroup(groupId) {
- let tagGroup = this.tagGroups.find(e=> e.groupId === groupId);
- this.tagsInGroup = tagGroup.tag || [];
- // 切换组时清空标签选择
- this.tagDialog.watchTagId = null;
- this.tagDialog.finishTagId = null;
- this.tagDialog.tgId = tagGroup.id;
- },
- resetDialog() {
- this.tagDialog = {
- videoId: null,
- groupId: null,
- watchTagId: null,
- finishTagId: null,
- };
- this.tagGroups = [];
- this.tagsInGroup = [];
- },
- // 打开弹框
- openDialog(row) {
- if (!this.fetchingQwIds) {
- this.fetchingQwIds = true;
- queryQwIds().then(response => {
- if (response.code === 200){
- this.qwUserList = response.list;
- }
- }).finally(() => {
- this.fetchingQwIds = false;
- // 在请求完成后再显示弹框
- this.showDialog(row);
- });
- } else {
- // 如果已经在请求中,直接显示弹框
- this.showDialog(row);
- }
- },
- // 新增方法:显示弹框
- showDialog(row) {
- this.roomLinkForm.courseId = row.courseId;
- this.roomLinkForm.videoId = row.videoId;
- this.roomLinkForm.title = row.title;
- this.dialogVisible = true;
- },
- // 确认按钮操作
- confirm() {
- if (!this.roomLinkForm.qwUserId) {
- this.$message.error("请选择销售企微!");
- return;
- }
- // 获取选中的用户信息
- const selectedUser = this.qwUserList.find(user => user.id === this.roomLinkForm.qwUserId);
- if (selectedUser) {
- // 将用户信息填充到表单中
- this.roomLinkForm.qwUserName = selectedUser.qwUserName;
- this.roomLinkForm.corpId = selectedUser.corpId;
- console.log(this.roomLinkForm);
- // 调用创建链接的API
- createRoomLinkUrl(this.roomLinkForm).then(response => {
- if (response.code === 200){
- this.msgSuccess("创建成功");
- this.copyLink(response.link);
- console.log(response.link);
- }
- });
- }
- // 关闭弹框
- this.dialogVisible = false;
- },
- // 重置表单
- resetForm() {
- this.linkForm={
- days:null,
- courseId:null,
- videoId:null
- }
- },
- resetRoomForm() {
- this.roomLinkForm={
- courseId:null,
- videoId:null,
- qwUserId:null,
- }
- },
- handleCreateLink(){
- createLinkUrl(this.linkForm).then(response => {
- if (response.code === 200){
- this.copyLink(response.url);
- }
- });
- },
- copyLink(url) {
- const link = url;
- // navigator clipboard 需要https等安全上下文
- if (navigator.clipboard && window.isSecureContext) {
- // navigator clipboard 向剪贴板写文本
- navigator.clipboard.writeText(link).then(() => {
- this.$message.success('链接已复制到剪贴板');
- });
- } else {
- // document.execCommand('copy') 向剪贴板写文本
- let input = document.createElement('input')
- input.style.position = 'fixed'
- input.style.top = '-10000px'
- input.style.zIndex = '-999'
- document.body.appendChild(input)
- input.value = link
- input.focus()
- input.select()
- try {
- let result = document.execCommand('copy')
- document.body.removeChild(input)
- if (!result || result === 'unsuccessful') {
- this.$message.error('复制失败');
- console.log('复制失败')
- } else {
- this.$message.success('链接已复制到剪贴板');
- console.log('复制成功')
- }
- } catch (e) {
- document.body.removeChild(input)
- alert('当前浏览器不支持复制功能,请检查更新或更换其他浏览器操作')
- }
- }
- },
- formatDuration(seconds) {
- if (seconds === null || seconds === undefined) {
- return '未上传视频'; // 或者您可以根据具体需求返回其他默认值
- }
- const hours = Math.floor(seconds / 3600);
- const minutes = Math.floor((seconds % 3600) / 60);
- const remainingSeconds = seconds % 60;
- const formattedHours = hours > 0 ? hours.toString() + ':' : '';
- const formattedMinutes = minutes.toString().padStart(2, '0');
- const formattedSeconds = remainingSeconds.toString().padStart(2, '0');
- return `${formattedHours}${formattedMinutes}:${formattedSeconds}`;
- },
- getDetails(courseId,courseName) {
- this.courseName = courseName
- this.courseId = courseId;
- this.queryParams.courseId = courseId;
- this.getList();
- },
- getList() {
- this.loading = true;
- getVideoListByCourseId(this.queryParams).then(response => {
- this.userCourseVideoList = response.rows;
- this.total = response.total;
- this.loading = false;
- });
- },
- // 取消按钮
- cancel() {
- this.open = false;
- this.reset();
- },
- updateMoney(row){
- this.redPacketMoneyForm.redPacketMoney=row.companyRedPacketMoney;
- this.redPacketMoneyForm.videoId=row.videoId;
- this.moneyOpen=true;
- },
- submitForm(){
- updatePacketMoney(this.redPacketMoneyForm).then(response => {
- this.msgSuccess("修改成功");
- this.moneyOpen=false;
- this.getList()
- });
- },
- updateMoneycancel(){
- this.moneyOpen=false;
- },
- // 表单重置
- reset() {
- this.form = {
- videoId: null,
- title: null,
- description: null,
- url: null,
- thumbnail: null,
- duration: null,
- createTime: null,
- uploadType:null,
- lineOne:null,
- lineTwo:null,
- lineThree:null,
- fileName:null,
- userId: null,
- cateId: null,
- courseId: null,
- likes: null,
- views: null,
- comments: null,
- status: 0,
- courseSort: 1,
- isHot: null,
- isShow: null,
- isAudit: null,
- auditBy: null,
- auditTime: null,
- updateTime: null,
- source: null,
- isDel: null,
- shares: null,
- tags: null,
- productId: null,
- productJson: null,
- questionBankId:null,
- questionBankList:[],
- };
- this.videoURL = '';
- this.progress=0;
- this.resetForm("form");
- },
- /** 搜索按钮操作 */
- handleQuery() {
- this.queryParams.pageNum = 1;
- this.getList();
- },
- /** 重置按钮操作 */
- resetQuery() {
- this.resetForm("queryForm");
- this.queryParams.title = null;
- this.handleQuery();
- },
- // 多选框选中数据
- handleSelectionChange(selection) {
- this.ids = selection.map(item => item.courseId)
- this.single = selection.length!==1
- this.multiple = !selection.length
- },
- /** 修改按钮操作 */
- handleDetails(row) {
- this.open=true;
- setTimeout(() => {
- this.$refs.userCourseVideoDetails.getDetails(row.videoId);
- }, 500);
- }
- }
- }
- </script>
- <style>
- .avatar-uploader .el-upload {
- border: 1px dashed #d9d9d9;
- border-radius: 6px;
- cursor: pointer;
- position: relative;
- overflow: hidden;
- }
- .avatar-uploader .el-upload:hover {
- border-color: #409EFF;
- }
- .avatar-uploader-icon {
- font-size: 28px;
- color: #8c939d;
- width: 150px;
- height: 150px;
- line-height: 150px;
- text-align: center;
- }
- .default-amounts {
- display: flex;
- flex-direction: column;
- gap: 8px;
- margin-bottom: 8px;
- }
- .amount-item {
- display: inline-flex;
- align-items: center;
- gap: 8px;
- padding: 8px 10px;
- background: #fafafa;
- border: 1px solid #ebeef5;
- border-radius: 4px;
- }
- .amount-icon {
- font-size: 18px;
- }
- .amount-icon.red { color: #e6a23c; }
- .amount-icon.green { color: #67c23a; }
- .amount-item .label {
- color: #606266;
- }
- .amount-item .value {
- font-weight: 600;
- color: #303133;
- margin-right: 6px;
- }
- </style>
|