| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870 |
- <template>
- <div class="app-container">
- <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="88px">
- <el-form-item label="直播组" prop="liveGroupType">
- <el-select
- v-model="queryParams.liveGroupType"
- placeholder="请选择直播组"
- filterable
- clearable
- size="small"
- style="width: 200px"
- @change="handleLiveGroupChange"
- >
- <el-option
- v-for="item in liveGroupTypeList"
- :key="item.id"
- :label="item.liveGroupType"
- :value="item.id"
- />
- </el-select>
- </el-form-item>
- <el-form-item label="直播名称" prop="liveId">
- <el-select
- v-model="queryParams.liveId"
- placeholder="请选择直播"
- filterable
- clearable
- size="small"
- style="width: 240px"
- >
- <el-option
- v-for="item in liveOptions"
- :key="item.liveId"
- :label="(item.liveName || '') + '(' + item.liveId + ')'"
- :value="item.liveId"
- />
- </el-select>
- </el-form-item>
- <el-form-item label="用户ID" prop="userId">
- <el-input
- v-model="queryParams.userId"
- placeholder="请输入用户ID"
- clearable
- size="small"
- @keyup.enter.native="handleQuery"
- />
- </el-form-item>
- <el-form-item label="用户昵称" prop="userName">
- <el-input
- v-model="queryParams.userName"
- placeholder="请输入用户昵称"
- clearable
- size="small"
- @keyup.enter.native="handleQuery"
- />
- </el-form-item>
- <el-form-item label="销售名称" prop="companyUserId">
- <el-select
- v-model="queryParams.companyUserId"
- clearable
- filterable
- remote
- placeholder="请输入销售名称"
- :remote-method="loadCompanyUserOptions"
- v-select-load-more="loadMoreCompanyUserOptions"
- :loading="companyUserOptionsLoading"
- @visible-change="handleCompanyUserDropdownVisible"
- size="small"
- style="width: 220px"
- >
- <el-option
- v-for="item in companyUserOptions"
- :key="item.dictValue"
- :label="item.dictLabel"
- :value="item.dictValue">
- </el-option>
- </el-select>
- </el-form-item>
- <el-form-item label="观看时间" prop="dateRange">
- <el-date-picker
- v-model="dateRange"
- type="datetimerange"
- size="small"
- value-format="yyyy-MM-dd HH:mm:ss"
- range-separator="-"
- start-placeholder="开始时间"
- end-placeholder="结束时间"
- :default-time="['00:00:00', '23:59:59']"
- />
- </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-row :gutter="10" class="mb8">
- <el-col :span="1.5">
- <el-button
- type="primary"
- plain
- size="mini"
- v-hasPermi="['app:user:bindTag']"
- @click="openBindTagPage(false, 0)"
- >批量添加标签
- </el-button>
- </el-col>
- <el-col :span="1.5">
- <el-button
- type="info"
- plain
- size="mini"
- v-hasPermi="['app:user:unbindTag']"
- @click="openUnbindTagPage(false, 1)"
- >批量移除标签
- </el-button>
- </el-col>
- <el-col :span="1.5">
- <el-button
- type="primary"
- plain
- size="mini"
- v-hasPermi="['app:user:batchBindTag']"
- @click="openBindTagPage(true, 0)"
- >批量添加标签(筛选条件)
- </el-button>
- </el-col>
- <el-col :span="1.5">
- <el-button
- type="info"
- plain
- size="mini"
- v-hasPermi="['app:user:batchUnbindTag']"
- @click="openUnbindTagPage(true, 1)"
- >批量移除标签(筛选条件)
- </el-button>
- </el-col>
- <el-col :span="1.5">
- <el-button
- type="success"
- plain
- size="mini"
- @click="openRemarkPage(false)"
- >批量修改备注
- </el-button>
- </el-col>
- <el-col :span="1.5">
- <el-button
- type="success"
- plain
- size="mini"
- @click="openRemarkPage(true)"
- >批量修改备注(筛选条件)
- </el-button>
- </el-col>
- <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
- </el-row>
- <el-table v-loading="loading" :data="list" border @selection-change="handleSelectionChange">
- <el-table-column type="selection" width="55" align="center" />
- <el-table-column label="用户ID" align="center" prop="userId" width="90" />
- <el-table-column label="用户昵称" align="center" prop="userName" min-width="120" show-overflow-tooltip />
- <el-table-column label="直播ID" align="center" prop="liveId" width="90" />
- <el-table-column label="直播名称" align="center" prop="liveName" min-width="140" show-overflow-tooltip />
- <el-table-column label="直播观看时长" align="center" min-width="120">
- <template slot-scope="scope">
- {{ formatDuration(scope.row.liveWatchDuration) }}
- </template>
- </el-table-column>
- <el-table-column label="回放观看时长" align="center" min-width="120">
- <template slot-scope="scope">
- {{ formatDuration(scope.row.playbackWatchDuration) }}
- </template>
- </el-table-column>
- <el-table-column label="是否完课" align="center" width="90">
- <template slot-scope="scope">
- <el-tag :type="scope.row.isCompleted === 1 ? 'success' : 'info'" size="mini">
- {{ scope.row.isCompleted === 1 ? '是' : '否' }}
- </el-tag>
- </template>
- </el-table-column>
- <el-table-column label="订单数" align="center" prop="orderCount" width="80" />
- <el-table-column label="订单金额" align="center" prop="orderAmount" width="100" />
- <el-table-column label="公司" align="center" prop="companyName" min-width="120" show-overflow-tooltip />
- <el-table-column label="销售" align="center" prop="salesName" min-width="100" show-overflow-tooltip />
- <el-table-column prop="rewardType" label="领取类型" min-width="220" align="center">
- <template slot-scope="scope">
- <div v-if="hasClaimedReward(scope.row.rewardType)">
- <dict-tag :options="liveRewardTypeList" :value="scope.row.rewardType"/>
- <el-button
- v-if="hasRedOrPointsReward(scope.row.rewardType)"
- type="text"
- size="small"
- style="margin-left: 8px;"
- @click="handleOpenRedPacketLog(scope.row)"
- >红包/积分领取详细</el-button>
- <el-button
- v-if="hasCouponReward(scope.row.rewardType)"
- type="text"
- size="small"
- style="margin-left: 8px;"
- @click="handleOpenCouponLog(scope.row)"
- >核销卷领取详情</el-button>
- </div>
- <span v-else>
- <dict-tag
- v-if="scope.row.rewardType === 0 || scope.row.rewardType === '0' || scope.row.rewardType === 99 || scope.row.rewardType === '99'"
- :options="liveRewardTypeList"
- :value="scope.row.rewardType"
- />
- <span v-else>未领取</span>
- </span>
- </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
- title="红包领取详情"
- :visible.sync="redPacketLogDrawerVisible"
- direction="rtl"
- size="60%"
- >
- <el-table
- :data="redPacketLogList"
- v-loading="redPacketLogLoading"
- border
- style="width: 100%"
- >
- <el-table-column type="index" label="序号" width="60" align="center"></el-table-column>
- <el-table-column prop="liveId" label="直播间id" min-width="120"></el-table-column>
- <el-table-column prop="userId" label="用户id" min-width="120"></el-table-column>
- <el-table-column prop="amount" label="金额" min-width="120" align="center">
- <template slot-scope="scope">
- {{ scope.row.amount != null ? scope.row.amount : '-' }}
- </template>
- </el-table-column>
- <el-table-column prop="status" label="状态" min-width="100" align="center">
- <template slot-scope="scope">
- <el-tag v-if="scope.row.status == 1" type="success">已领取</el-tag>
- <el-tag v-else-if="scope.row.status == 0" type="info">未领取</el-tag>
- <el-tag v-else type="info">{{ scope.row.status }}</el-tag>
- </template>
- </el-table-column>
- <el-table-column prop="createTime" label="领取时间" min-width="160" align="center"></el-table-column>
- <el-table-column prop="remark" label="备注" min-width="160" align="center"></el-table-column>
- </el-table>
- <pagination
- v-show="redPacketLogTotal > 0"
- :total="redPacketLogTotal"
- :page.sync="redPacketLogQueryParams.pageNum"
- :limit.sync="redPacketLogQueryParams.pageSize"
- :page-sizes="[10, 20, 50]"
- @pagination="loadRedPacketLogList"
- style="margin-top: 20px;"
- />
- </el-drawer>
- <!-- 核销卷领取详情侧边栏 -->
- <el-drawer
- title="核销卷领取详情"
- :visible.sync="couponLogDrawerVisible"
- direction="rtl"
- size="60%"
- >
- <el-table
- :data="couponLogList"
- v-loading="couponLogLoading"
- border
- style="width: 100%"
- >
- <el-table-column type="index" label="序号" width="60" align="center"></el-table-column>
- <el-table-column prop="nickName" label="会员昵称" min-width="120"></el-table-column>
- <el-table-column prop="couponTitle" label="优惠券名称" min-width="120"></el-table-column>
- <el-table-column prop="limitTime" label="优惠券有效期" min-width="160" align="center"></el-table-column>
- <el-table-column prop="startTime" label="开始时间" min-width="160" align="center"></el-table-column>
- <el-table-column prop="updateTime" label="更新时间" min-width="160" align="center"></el-table-column>
- <el-table-column prop="status" label="状态" min-width="100" align="center">
- <template slot-scope="scope">
- <el-tag v-if="scope.row.status == 1" type="success">已使用</el-tag>
- <el-tag v-else-if="scope.row.status == 0" type="info">未使用</el-tag>
- <el-tag v-else type="info">{{ scope.row.status }}</el-tag>
- </template>
- </el-table-column>
- </el-table>
- <pagination
- v-show="couponLogTotal > 0"
- :total="couponLogTotal"
- :page.sync="couponLogQueryParams.pageNum"
- :limit.sync="couponLogQueryParams.pageSize"
- :page-sizes="[10, 20, 50]"
- @pagination="loadCouponLogList"
- style="margin-top: 20px;"
- />
- </el-drawer>
- <!-- 批量添加/移除标签 -->
- <el-dialog :title="tagConfig.title" :visible.sync="tagConfig.visible" width="800px" append-to-body>
- <div>搜索标签:
- <el-input
- v-model="tagConfig.queryParams.groupName"
- placeholder="请输入标签名称"
- clearable
- size="small"
- style="width: 200px;margin-right: 10px"
- />
- <el-button type="primary" icon="el-icon-search" size="mini" @click="handleSearchTags">搜索</el-button>
- <el-button type="primary" icon="el-icon-refresh" size="mini" @click="cancelSearchTags">重置</el-button>
- </div>
- <div class="dialog-body">
- <div v-for="groupItem in tagConfig.tagGroupList" :key="groupItem.id">
- <div style="font-size: 20px;margin-top: 20px;margin-bottom: 20px;">
- <span class="name-background">{{ groupItem.name }}</span>
- </div>
- <div class="tag-container">
- <a
- v-for="tagItem in groupItem.tags"
- :key="tagItem.id"
- class="tag-box"
- @click="tagSelection(tagItem)"
- :class="{ 'tag-selected': tagItem.isSelected }"
- >
- {{ tagItem.name }}
- </a>
- </div>
- </div>
- </div>
- <pagination
- v-show="tagConfig.total > 0"
- :total="tagConfig.total"
- :page.sync="tagConfig.queryParams.pageNum"
- :limit.sync="tagConfig.queryParams.pageSize"
- @pagination="getTagGroupList"
- />
- <div slot="footer" class="dialog-footer">
- <el-button type="primary" @click="bindOrUnbindTagSubmit">确 定</el-button>
- <el-button @click="bindTagCancel">取 消</el-button>
- </div>
- </el-dialog>
- <!-- 批量修改备注 -->
- <el-dialog :title="remarkConfig.title" :visible.sync="remarkConfig.visible" width="600px" append-to-body>
- <el-form label-width="90px">
- <el-form-item label="备注类型">
- <el-radio-group v-model="remarkConfig.remarkType">
- <el-radio :label="1">用户名称添加在新备注前</el-radio>
- <el-radio :label="2">用户名称添加在新备注后</el-radio>
- <el-radio :label="3">不添加用户名称</el-radio>
- </el-radio-group>
- </el-form-item>
- <el-form-item label="备注内容">
- <el-input
- v-model="remarkConfig.remark"
- type="textarea"
- :rows="3"
- placeholder="请输入备注信息"
- maxlength="30"
- show-word-limit
- />
- </el-form-item>
- </el-form>
- <div slot="footer" class="dialog-footer">
- <el-button type="primary" :loading="remarkConfig.loading" @click="submitRemark">确 定</el-button>
- <el-button @click="cancelRemark">取 消</el-button>
- </div>
- </el-dialog>
- </div>
- </template>
- <script>
- import { liveWatchUserList } from '@/api/live/liveWatchUser'
- import { getCompanyUserListLikeName } from '@/api/company/companyUser'
- import { listLiveRedPacketLog } from '@/api/live/liveRedPacketLog'
- import { getCourseCouponUserListVO } from '@/api/course/courseCouponUser'
- import { listTagGroupForUserBindTag } from '@/api/app/tag/tagGroup'
- import { bindTagV2, unbindTagV2 } from '@/api/app/tag/bindTag'
- import { batchUpdateFriendRemark } from '@/api/course/courseWatchLog'
- import { getLiveGroupTypeList, getLiveOptions } from '@/api/app/live'
- export default {
- name: 'LiveWatchUser',
- data() {
- return {
- loading: false,
- showSearch: true,
- total: 0,
- list: [],
- ids: [],
- liveGroupTypeList: [],
- liveOptions: [],
- liveRewardTypeList: [],
- dateRange: [],
- companyUserOptionsLoading: false,
- companyUserOptions: [],
- companyUserOptionsParams: {
- name: undefined,
- hasNextPage: false,
- pageNum: 1,
- pageSize: 10
- },
- queryParams: {
- pageNum: 1,
- pageSize: 10,
- liveGroupType: null,
- liveId: null,
- userId: null,
- userName: null,
- companyId: null,
- companyUserId: null,
- bTime: null,
- eTime: null
- },
- tagConfig: {
- visible: false,
- enableFilter: false,
- title: null,
- opType: 0,
- queryParams: {
- groupName: null,
- pageNum: 1,
- pageSize: 10
- },
- total: 0,
- tagGroupList: [],
- selected: []
- },
- redPacketLogDrawerVisible: false,
- redPacketLogList: [],
- redPacketLogLoading: false,
- redPacketLogTotal: 0,
- redPacketLogQueryParams: {
- pageNum: 1,
- pageSize: 10,
- liveId: null,
- userId: null
- },
- couponLogDrawerVisible: false,
- couponLogList: [],
- couponLogLoading: false,
- couponLogTotal: 0,
- couponLogQueryParams: {
- pageNum: 1,
- pageSize: 10,
- userId: null,
- liveId: null,
- sendType: 2
- },
- remarkConfig: {
- visible: false,
- enableFilter: false,
- title: '批量修改备注',
- remarkType: 1,
- remark: '',
- loading: false
- }
- }
- },
- computed: {
- currentCompanyId() {
- const user = this.$store.state.user && this.$store.state.user.user
- return user ? user.companyId : null
- }
- },
- created() {
- this.getDicts('live_watch_reward_type').then(res => {
- this.liveRewardTypeList = res.data || []
- })
- this.loadLiveGroupTypeList()
- this.loadLiveOptions()
- this.getList()
- },
- methods: {
- loadLiveGroupTypeList() {
- getLiveGroupTypeList({ pageNum: 1, pageSize: 999 }).then(res => {
- this.liveGroupTypeList = res.rows || res.data || []
- }).catch(() => {
- this.liveGroupTypeList = []
- })
- },
- loadCompanyUserOptions(query) {
- this.companyUserOptions = []
- this.companyUserOptionsParams.pageNum = 1
- this.companyUserOptionsParams.name = query
- this.companyUserOptionsLoading = true
- this.getCompanyUserListLikeName()
- },
- getCompanyUserListLikeName() {
- getCompanyUserListLikeName(this.companyUserOptionsParams).then(response => {
- const page = (response && response.data) || {}
- this.companyUserOptions = [...this.companyUserOptions, ...(page.list || [])]
- this.companyUserOptionsParams.hasNextPage = !!page.hasNextPage
- }).finally(() => {
- this.companyUserOptionsLoading = false
- })
- },
- loadMoreCompanyUserOptions() {
- if (!this.companyUserOptionsParams.hasNextPage) {
- return
- }
- this.companyUserOptionsParams.pageNum += 1
- this.getCompanyUserListLikeName()
- },
- handleCompanyUserDropdownVisible(visible) {
- if (visible && this.companyUserOptions.length === 0) {
- this.loadCompanyUserOptions('')
- }
- },
- loadLiveOptions(liveGroupType) {
- const params = {}
- if (liveGroupType != null && liveGroupType !== '') {
- params.liveGroupType = liveGroupType
- }
- getLiveOptions(params).then(res => {
- this.liveOptions = res.data || []
- }).catch(() => {
- this.liveOptions = []
- })
- },
- handleLiveGroupChange(val) {
- this.queryParams.liveId = null
- this.loadLiveOptions(val)
- },
- handleSelectionChange(selection) {
- this.ids = [...new Set(selection.map(item => item.userId).filter(id => id != null))]
- },
- openBindTagPage(enableFilter = false, opType = 0) {
- this.tagConfig.enableFilter = enableFilter
- this.tagConfig.opType = opType
- if (!enableFilter && (!this.ids || this.ids.length === 0)) {
- this.$message.closeAll()
- return this.$message('请选择需要添加标签的用户')
- }
- this.getTagGroupList()
- this.tagConfig.title = '批量添加标签' + (enableFilter ? '(筛选条件)' : '')
- this.tagConfig.visible = true
- },
- openUnbindTagPage(enableFilter = false, opType = 1) {
- this.tagConfig.enableFilter = enableFilter
- this.tagConfig.opType = opType
- if (!enableFilter && (!this.ids || this.ids.length === 0)) {
- this.$message.closeAll()
- return this.$message('请选择需要移除标签的用户')
- }
- this.getTagGroupList()
- this.tagConfig.title = '批量移除标签' + (enableFilter ? '(筛选条件)' : '')
- this.tagConfig.visible = true
- },
- handleSearchTags() {
- this.tagConfig.queryParams.pageNum = 1
- this.getTagGroupList()
- },
- cancelSearchTags() {
- this.tagConfig.queryParams = {
- groupName: null,
- pageNum: 1,
- pageSize: 10
- }
- this.getTagGroupList()
- },
- tagSelection(row) {
- row.isSelected = !row.isSelected
- if (row.isSelected) {
- this.tagConfig.selected.push({ tagId: row.id, tagName: row.name })
- } else {
- this.tagConfig.selected = this.tagConfig.selected.filter(item => item.tagId !== row.id)
- }
- this.$forceUpdate()
- },
- resetBindTag() {
- this.tagConfig = {
- visible: false,
- enableFilter: false,
- title: null,
- opType: 0,
- queryParams: {
- groupName: null,
- pageNum: 1,
- pageSize: 10
- },
- total: 0,
- tagGroupList: [],
- selected: []
- }
- },
- buildFsUserParam() {
- const q = this.buildQuery()
- return {
- userId: q.userId,
- nickName: q.userName,
- companyId: q.companyId,
- companyUserId: q.companyUserId
- }
- },
- bindOrUnbindTagSubmit() {
- const opType = this.tagConfig.opType
- if (!this.tagConfig.selected || this.tagConfig.selected.length === 0) {
- return this.$message('请选择标签')
- }
- const tmpParam = {
- enableFilter: this.tagConfig.enableFilter,
- tagId: this.tagConfig.selected.map(item => item.tagId),
- userId: this.ids,
- fsUserParam: this.buildFsUserParam()
- }
- if (opType === 0) {
- bindTagV2(tmpParam)
- .then(() => {
- this.tagConfig.visible = false
- this.resetBindTag()
- this.msgSuccess('正在添加中!')
- setTimeout(() => this.getList(), 500)
- })
- .catch(() => {
- this.msgError('添加标签失败!')
- })
- } else {
- unbindTagV2(tmpParam)
- .then(() => {
- this.tagConfig.visible = false
- this.resetBindTag()
- this.msgSuccess('正在移除中!')
- setTimeout(() => this.getList(), 500)
- })
- .catch(() => {
- this.msgError('移除标签失败!')
- })
- }
- },
- bindTagCancel() {
- this.resetBindTag()
- },
- openRemarkPage(enableFilter = false) {
- if (!enableFilter && (!this.ids || this.ids.length === 0)) {
- this.$message.closeAll()
- return this.$message('请选择需要修改备注的用户')
- }
- if (enableFilter && (!this.total || this.total <= 0)) {
- this.$message.closeAll()
- return this.$message('当前筛选条件下没有数据')
- }
- this.remarkConfig.enableFilter = enableFilter
- this.remarkConfig.remarkType = 1
- this.remarkConfig.remark = ''
- this.remarkConfig.loading = false
- this.remarkConfig.title = '批量修改备注' + (enableFilter ? '(筛选条件)' : '')
- this.remarkConfig.visible = true
- },
- cancelRemark() {
- this.remarkConfig.visible = false
- this.remarkConfig.enableFilter = false
- this.remarkConfig.remarkType = 1
- this.remarkConfig.remark = ''
- this.remarkConfig.loading = false
- },
- async submitRemark() {
- const remark = (this.remarkConfig.remark || '').trim()
- if (!remark) {
- return this.$message.error('请输入备注内容')
- }
- if (remark.length > 30) {
- return this.$message.error('备注内容不能超过30个字符')
- }
- this.remarkConfig.loading = true
- try {
- let userIds = []
- if (this.remarkConfig.enableFilter) {
- const queryParams = this.buildQuery()
- queryParams.pageNum = 1
- queryParams.pageSize = this.total > 0 ? this.total : 10000
- const response = await liveWatchUserList(queryParams)
- const rows = response.data || []
- userIds = [...new Set(rows.map(item => item.userId).filter(id => id != null))]
- } else {
- userIds = this.ids
- }
- if (!userIds || userIds.length === 0) {
- this.remarkConfig.loading = false
- return this.$message.error('没有可修改备注的用户')
- }
- await batchUpdateFriendRemark({
- remarkType: this.remarkConfig.remarkType,
- remark,
- userId: userIds
- })
- this.msgSuccess('正在修改备注中!')
- this.cancelRemark()
- setTimeout(() => {
- this.getList()
- }, 500)
- } catch (e) {
- this.msgError('修改备注失败!')
- } finally {
- this.remarkConfig.loading = false
- }
- },
- getTagGroupList() {
- listTagGroupForUserBindTag(this.tagConfig.queryParams).then(response => {
- this.tagConfig.tagGroupList = response.rows || []
- this.tagConfig.total = response.total || 0
- const selectedIds = new Set(this.tagConfig.selected.map(i => i.tagId))
- this.tagConfig.tagGroupList.forEach(group => {
- (group.tags || []).forEach(tag => {
- this.$set(tag, 'isSelected', selectedIds.has(tag.id))
- })
- })
- })
- },
- hasClaimedReward(type) {
- if (type == null || type === '') return false
- const t = Number(type)
- if (Number.isNaN(t) || t === 0 || t === 99) return false
- return true
- },
- hasRedOrPointsReward(type) {
- const t = Number(type)
- if (Number.isNaN(t) || t >= 97) return false
- return (t & 1) !== 0 || (t & 2) !== 0
- },
- hasCouponReward(type) {
- const t = Number(type)
- if (Number.isNaN(t) || t >= 97) return false
- return (t & 4) !== 0
- },
- handleOpenRedPacketLog(row) {
- this.redPacketLogDrawerVisible = true
- this.redPacketLogQueryParams.liveId = row.liveId
- this.redPacketLogQueryParams.userId = row.userId
- this.redPacketLogQueryParams.pageNum = 1
- this.loadRedPacketLogList()
- },
- handleOpenCouponLog(row) {
- this.couponLogDrawerVisible = true
- this.couponLogQueryParams.userId = row.userId
- this.couponLogQueryParams.liveId = row.liveId
- this.couponLogQueryParams.pageNum = 1
- this.loadCouponLogList()
- },
- loadCouponLogList() {
- this.couponLogLoading = true
- getCourseCouponUserListVO({
- pageNum: this.couponLogQueryParams.pageNum,
- pageSize: this.couponLogQueryParams.pageSize,
- userId: this.couponLogQueryParams.userId,
- sendType: this.couponLogQueryParams.sendType,
- liveId: this.couponLogQueryParams.liveId
- }).then(response => {
- this.couponLogList = response.rows || []
- this.couponLogTotal = response.total || 0
- this.couponLogLoading = false
- }).catch(() => {
- this.couponLogLoading = false
- })
- },
- loadRedPacketLogList() {
- this.redPacketLogLoading = true
- listLiveRedPacketLog({
- pageNum: this.redPacketLogQueryParams.pageNum,
- pageSize: this.redPacketLogQueryParams.pageSize,
- liveId: this.redPacketLogQueryParams.liveId,
- userId: this.redPacketLogQueryParams.userId
- }).then(response => {
- if (response.code === 200) {
- this.redPacketLogList = response.rows || []
- this.redPacketLogTotal = response.total || 0
- }
- this.redPacketLogLoading = false
- }).catch(() => {
- this.redPacketLogLoading = false
- })
- },
- buildQuery() {
- const params = { ...this.queryParams }
- params.companyId = this.currentCompanyId
- if (this.dateRange && this.dateRange.length === 2) {
- params.bTime = this.dateRange[0]
- params.eTime = this.dateRange[1]
- } else {
- params.bTime = null
- params.eTime = null
- }
- ;['liveId', 'userId', 'companyId', 'companyUserId', 'liveGroupType'].forEach(key => {
- if (params[key] === '' || params[key] === undefined) {
- params[key] = null
- } else if (params[key] != null) {
- params[key] = Number(params[key])
- }
- })
- if (params.userName === '') params.userName = null
- return params
- },
- getList() {
- this.loading = true
- liveWatchUserList(this.buildQuery()).then(res => {
- this.list = res.data || []
- this.total = res.total || 0
- }).finally(() => {
- this.loading = false
- })
- },
- handleQuery() {
- this.queryParams.pageNum = 1
- this.getList()
- },
- resetQuery() {
- this.dateRange = []
- this.resetForm('queryForm')
- this.queryParams.pageNum = 1
- this.queryParams.pageSize = 10
- this.queryParams.liveGroupType = null
- this.queryParams.liveId = null
- this.companyUserOptions = []
- this.loadLiveOptions()
- this.handleQuery()
- },
- formatDuration(seconds) {
- const s = Number(seconds) || 0
- if (s < 60) return s + '秒'
- const m = Math.floor(s / 60)
- const remain = s % 60
- if (m < 60) return remain ? `${m}分${remain}秒` : `${m}分钟`
- const h = Math.floor(m / 60)
- const rm = m % 60
- return rm ? `${h}小时${rm}分` : `${h}小时`
- }
- }
- }
- </script>
- <style lang="scss" scoped>
- .dialog-body {
- height: 400px;
- overflow: auto;
- }
- .tag-container {
- display: flex;
- flex-wrap: wrap;
- gap: 8px;
- }
- .name-background {
- display: inline-block;
- background-color: #abece6;
- padding: 4px 8px;
- border-radius: 4px;
- }
- .tag-box {
- padding: 8px 12px;
- border: 1px solid #989797;
- border-radius: 4px;
- cursor: pointer;
- display: inline-block;
- }
- .tag-selected {
- background-color: #00bc98;
- color: #fff;
- border-color: #00bc98;
- }
- </style>
|