|
|
@@ -123,11 +123,12 @@
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
|
|
|
- <el-table-column label="操作" width="200" fixed="right">
|
|
|
+ <el-table-column label="操作" width="260" fixed="right">
|
|
|
<template slot-scope="{ row }">
|
|
|
<!-- 草稿箱:可编辑 -->
|
|
|
<template v-if="row.status === 'draft' && !row.auditStatus">
|
|
|
<el-button size="mini" type="primary" @click="$router.push('/article-edit?id=' + row.id)">编辑</el-button>
|
|
|
+ <el-button size="mini" @click="openReadRecords(row)">阅读记录</el-button>
|
|
|
<el-dropdown trigger="hover" @command="(cmd) => handleActionCmd(row, cmd)">
|
|
|
<el-button size="mini">
|
|
|
更多<i class="el-icon-arrow-down el-icon--right"></i>
|
|
|
@@ -143,6 +144,7 @@
|
|
|
<!-- 待审核:审核操作 -->
|
|
|
<template v-else-if="row.status === 'draft' && row.auditStatus === 'pending'">
|
|
|
<el-button size="mini" type="primary" @click="$router.push('/article-edit?id=' + row.id + '&readonly=1')">查看</el-button>
|
|
|
+ <el-button size="mini" @click="openReadRecords(row)">阅读记录</el-button>
|
|
|
<el-dropdown trigger="hover" @command="(cmd) => handleActionCmd(row, cmd)">
|
|
|
<el-button size="mini">
|
|
|
更多<i class="el-icon-arrow-down el-icon--right"></i>
|
|
|
@@ -157,6 +159,7 @@
|
|
|
<!-- 已驳回:查看 + 重新编辑 -->
|
|
|
<template v-else-if="row.status === 'rejected'">
|
|
|
<el-button size="mini" type="primary" @click="$router.push('/article-edit?id=' + row.id + '&readonly=1')">查看</el-button>
|
|
|
+ <el-button size="mini" @click="openReadRecords(row)">阅读记录</el-button>
|
|
|
<el-dropdown trigger="hover" @command="(cmd) => handleActionCmd(row, cmd)">
|
|
|
<el-button size="mini">
|
|
|
更多<i class="el-icon-arrow-down el-icon--right"></i>
|
|
|
@@ -170,6 +173,7 @@
|
|
|
<!-- 发布中:编辑 + 下架 + 精选 -->
|
|
|
<template v-else-if="row.status === 'published'">
|
|
|
<el-button size="mini" type="primary" @click="$router.push('/article-edit?id=' + row.id)">编辑</el-button>
|
|
|
+ <el-button size="mini" @click="openReadRecords(row)">阅读记录</el-button>
|
|
|
<el-dropdown trigger="hover" @command="(cmd) => handleActionCmd(row, cmd)">
|
|
|
<el-button size="mini">
|
|
|
更多<i class="el-icon-arrow-down el-icon--right"></i>
|
|
|
@@ -184,6 +188,7 @@
|
|
|
<!-- 已撤回:查看 + 重新发布 -->
|
|
|
<template v-else-if="row.status === 'withdrawn'">
|
|
|
<el-button size="mini" type="primary" @click="$router.push('/article-edit?id=' + row.id + '&readonly=1')">查看</el-button>
|
|
|
+ <el-button size="mini" @click="openReadRecords(row)">阅读记录</el-button>
|
|
|
<el-dropdown trigger="hover" @command="(cmd) => handleActionCmd(row, cmd)">
|
|
|
<el-button size="mini">
|
|
|
更多<i class="el-icon-arrow-down el-icon--right"></i>
|
|
|
@@ -197,6 +202,7 @@
|
|
|
<!-- 其他 -->
|
|
|
<template v-else>
|
|
|
<el-button size="mini" type="primary" @click="$router.push('/article-edit?id=' + row.id + '&readonly=1')">查看</el-button>
|
|
|
+ <el-button size="mini" @click="openReadRecords(row)">阅读记录</el-button>
|
|
|
<el-dropdown trigger="hover" @command="(cmd) => handleActionCmd(row, cmd)">
|
|
|
<el-button size="mini">
|
|
|
更多<i class="el-icon-arrow-down el-icon--right"></i>
|
|
|
@@ -225,6 +231,46 @@
|
|
|
</el-card>
|
|
|
</div>
|
|
|
|
|
|
+ <!-- 阅读记录弹窗 -->
|
|
|
+ <el-dialog title="文章阅读记录" :visible.sync="readRecordVisible" width="800px" destroy-on-close>
|
|
|
+ <div v-loading="readRecordLoading" style="min-height: 200px;">
|
|
|
+ <el-table :data="readRecordList" border stripe size="small">
|
|
|
+ <el-table-column prop="nickname" label="孩子昵称" width="120">
|
|
|
+ <template slot-scope="{ row }">
|
|
|
+ {{ row.nickname || '-' }}
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="duration_seconds" label="累计时长" width="120">
|
|
|
+ <template slot-scope="{ row }">
|
|
|
+ {{ formatDuration(row.duration_seconds) }}
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="read_date" label="最后阅读日期" width="130">
|
|
|
+ <template slot-scope="{ row }">
|
|
|
+ {{ row.read_date || '-' }}
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="read_at" label="最后阅读时间" width="170">
|
|
|
+ <template slot-scope="{ row }">
|
|
|
+ {{ formatTime(row.read_at) }}
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
+ <el-pagination
|
|
|
+ v-if="readRecordTotal > 0"
|
|
|
+ layout="total, prev, pager, next"
|
|
|
+ :current-page="readRecordPage"
|
|
|
+ :page-size="readRecordSize"
|
|
|
+ :total="readRecordTotal"
|
|
|
+ @current-change="onReadRecordPageChange"
|
|
|
+ style="margin-top: 16px; text-align: right;"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ <span slot="footer">
|
|
|
+ <el-button @click="readRecordVisible = false">关闭</el-button>
|
|
|
+ </span>
|
|
|
+ </el-dialog>
|
|
|
+
|
|
|
<!-- 驳回弹窗 -->
|
|
|
<el-dialog title="驳回原因" :visible.sync="rejectDialogVisible" width="400px">
|
|
|
<el-input
|
|
|
@@ -254,7 +300,8 @@ import {
|
|
|
adminArticleCreate,
|
|
|
adminArticleSubmitReview,
|
|
|
adminArticleWithdraw,
|
|
|
- adminArticleReDraft
|
|
|
+ adminArticleReDraft,
|
|
|
+ adminArticleReadingRecords
|
|
|
} from '@/api/article.js'
|
|
|
|
|
|
import { getTagList } from '@/api/dimension.js'
|
|
|
@@ -297,7 +344,14 @@ export default {
|
|
|
tagOptions: [],
|
|
|
rejectDialogVisible: false,
|
|
|
rejectReason: '',
|
|
|
- currentAuditRow: null
|
|
|
+ currentAuditRow: null,
|
|
|
+ readRecordVisible: false,
|
|
|
+ readRecordArticleId: null,
|
|
|
+ readRecordList: [],
|
|
|
+ readRecordTotal: 0,
|
|
|
+ readRecordPage: 1,
|
|
|
+ readRecordSize: 20,
|
|
|
+ readRecordLoading: false
|
|
|
}
|
|
|
},
|
|
|
created() {
|
|
|
@@ -503,6 +557,44 @@ export default {
|
|
|
if (!t) return '-'
|
|
|
return t.replace ? t.replace('T', ' ').substring(0, 19) : t
|
|
|
},
|
|
|
+ formatDuration(seconds) {
|
|
|
+ if (!seconds) return '0秒'
|
|
|
+ var min = Math.floor(seconds / 60)
|
|
|
+ var sec = seconds % 60
|
|
|
+ if (min > 0 && sec > 0) return min + '分' + sec + '秒'
|
|
|
+ if (min > 0) return min + '分钟'
|
|
|
+ return sec + '秒'
|
|
|
+ },
|
|
|
+ openReadRecords(row) {
|
|
|
+ this.readRecordArticleId = row.id
|
|
|
+ this.readRecordPage = 1
|
|
|
+ this.readRecordList = []
|
|
|
+ this.readRecordTotal = 0
|
|
|
+ this.readRecordVisible = true
|
|
|
+ this.loadReadRecords()
|
|
|
+ },
|
|
|
+ async loadReadRecords() {
|
|
|
+ this.readRecordLoading = true
|
|
|
+ try {
|
|
|
+ const res = await adminArticleReadingRecords({
|
|
|
+ articleId: this.readRecordArticleId,
|
|
|
+ page: this.readRecordPage,
|
|
|
+ size: this.readRecordSize
|
|
|
+ })
|
|
|
+ if (res.data) {
|
|
|
+ this.readRecordList = res.data.records || []
|
|
|
+ this.readRecordTotal = res.data.total || 0
|
|
|
+ }
|
|
|
+ } catch (e) {
|
|
|
+ this.$message.error('加载阅读记录失败')
|
|
|
+ } finally {
|
|
|
+ this.readRecordLoading = false
|
|
|
+ }
|
|
|
+ },
|
|
|
+ onReadRecordPageChange(page) {
|
|
|
+ this.readRecordPage = page
|
|
|
+ this.loadReadRecords()
|
|
|
+ },
|
|
|
handleActionCmd(row, cmd) {
|
|
|
switch (cmd) {
|
|
|
case 'submitReview': this.handleSubmitReview(row); break;
|