This commit is contained in:
Leo
2026-01-03 12:13:23 +08:00
parent 5d037eaeee
commit 1a4e56bfed
3 changed files with 359 additions and 14 deletions

View File

@@ -118,3 +118,28 @@ export function getTbProductTypeMap() {
}) })
} }
// 获取当前IP地址公开接口
export function getCurrentIP() {
return request({
url: '/public/comment/ip',
method: 'get'
})
}
// 获取评论生成历史记录(公开接口)
export function getCommentHistory(query) {
return request({
url: '/public/comment/history',
method: 'get',
params: query
})
}
// 获取评论生成使用统计(公开接口)
export function getCommentUsageStatistics() {
return request({
url: '/public/comment/usage-statistics',
method: 'get'
})
}

View File

@@ -21,6 +21,11 @@ export default {
data() { data() {
return { return {
navItems: [ navItems: [
{
label: '首页',
path: '/public/home',
icon: 'el-icon-s-home'
},
{ {
label: '评论生成', label: '评论生成',
path: '/tools/comment-gen', path: '/tools/comment-gen',
@@ -70,9 +75,10 @@ export default {
display: flex; display: flex;
justify-content: space-around; justify-content: space-around;
align-items: center; align-items: center;
max-width: 600px; max-width: 800px;
margin: 0 auto; margin: 0 auto;
padding: 0 16px; padding: 0 8px;
gap: 4px;
} }
.nav-item { .nav-item {
@@ -81,7 +87,7 @@ export default {
align-items: center; align-items: center;
justify-content: center; justify-content: center;
cursor: pointer; cursor: pointer;
padding: 8px 16px; padding: 8px 8px;
border-radius: 8px; border-radius: 8px;
transition: all 0.3s ease; transition: all 0.3s ease;
flex: 1; flex: 1;
@@ -100,7 +106,7 @@ export default {
} }
.nav-item i { .nav-item i {
font-size: 22px; font-size: 20px;
margin-bottom: 4px; margin-bottom: 4px;
transition: transform 0.3s ease; transition: transform 0.3s ease;
} }
@@ -110,43 +116,51 @@ export default {
} }
.nav-label { .nav-label {
font-size: 12px; font-size: 11px;
font-weight: 500; font-weight: 500;
white-space: nowrap; white-space: nowrap;
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
max-width: 100%;
} }
/* 响应式设计 */ /* 响应式设计 */
@media (max-width: 480px) { @media (max-width: 480px) {
.nav-container {
padding: 0 4px;
gap: 2px;
}
.nav-item { .nav-item {
padding: 6px 12px; padding: 6px 4px;
} }
.nav-item i { .nav-item i {
font-size: 20px; font-size: 18px;
} }
.nav-label { .nav-label {
font-size: 11px; font-size: 10px;
} }
} }
@media (min-width: 768px) { @media (min-width: 768px) {
.nav-container { .nav-container {
max-width: 800px; max-width: 900px;
padding: 0 12px;
gap: 8px;
} }
.nav-item { .nav-item {
padding: 10px 20px; padding: 10px 12px;
} }
.nav-item i { .nav-item i {
font-size: 24px; font-size: 22px;
} }
.nav-label { .nav-label {
font-size: 13px; font-size: 12px;
} }
} }
</style> </style>

View File

@@ -3,9 +3,40 @@
<div class="mobile-card"> <div class="mobile-card">
<div class="mobile-header"> <div class="mobile-header">
<h3>评论生成公开</h3> <h3>评论生成公开</h3>
<div class="header-info">
<span class="ip-info">
<i class="el-icon-monitor"></i>
IP: {{ currentIP || '获取中...' }}
</span>
</div>
</div> </div>
<div class="mobile-form"> <div class="mobile-form">
<!-- 使用统计区域 -->
<div class="form-section usage-statistics-section">
<div class="form-label">
<i class="el-icon-data-line"></i>
使用统计
</div>
<div class="usage-stats-grid">
<div class="usage-stat-item">
<div class="usage-stat-number">{{ usageStatistics.today || 0 }}</div>
<div class="usage-stat-label">今天</div>
</div>
<div class="usage-stat-item">
<div class="usage-stat-number">{{ usageStatistics.last7Days || 0 }}</div>
<div class="usage-stat-label">近7天</div>
</div>
<div class="usage-stat-item">
<div class="usage-stat-number">{{ usageStatistics.last30Days || 0 }}</div>
<div class="usage-stat-label">近30天</div>
</div>
<div class="usage-stat-item">
<div class="usage-stat-number">{{ usageStatistics.total || 0 }}</div>
<div class="usage-stat-label">累计</div>
</div>
</div>
</div>
<!-- 产品类型选择区域 --> <!-- 产品类型选择区域 -->
<div class="form-section"> <div class="form-section">
<div class="form-label">型号/类型</div> <div class="form-label">型号/类型</div>
@@ -168,6 +199,46 @@
</div> </div>
</div> </div>
</div> </div>
<!-- 历史记录区域 -->
<div class="form-section history-section">
<div class="form-label">
<i class="el-icon-time"></i>
历史记录
<el-button
size="mini"
type="text"
icon="el-icon-refresh"
@click="loadHistory"
:loading="historyLoading"
style="margin-left: 8px;"
>
刷新
</el-button>
</div>
<div v-if="historyLoading" class="history-loading">
<i class="el-icon-loading"></i> 加载中...
</div>
<div v-else-if="historyList.length === 0" class="history-empty">
<i class="el-icon-document-remove"></i>
<p>暂无历史记录</p>
</div>
<div v-else class="history-list">
<div
v-for="(item, idx) in historyList"
:key="idx"
class="history-item"
>
<div class="history-item-header">
<span class="history-type">{{ item.productType || '-' }}</span>
<span class="history-time">{{ formatTime(item.createTime) }}</span>
</div>
<div class="history-item-info">
<span class="history-ip">IP: {{ item.ip || '-' }}</span>
</div>
</div>
</div>
</div>
</div> </div>
</div> </div>
@@ -179,6 +250,7 @@
<script> <script>
import { pinyin } from 'pinyin-pro' import { pinyin } from 'pinyin-pro'
import PublicFooterNav from '@/components/PublicFooterNav' import PublicFooterNav from '@/components/PublicFooterNav'
import { parseTime } from '@/utils/ruoyi'
export default { export default {
name: 'CommentGeneratorPublic', name: 'CommentGeneratorPublic',
@@ -196,7 +268,16 @@ export default {
lastGenerateTime: 0, lastGenerateTime: 0,
cooldownTime: 1000, // 5秒冷却时间 cooldownTime: 1000, // 5秒冷却时间
isButtonDisabled: false, isButtonDisabled: false,
activeLetter: 'ALL' activeLetter: 'ALL',
currentIP: '',
usageStatistics: {
today: 0,
last7Days: 0,
last30Days: 0,
total: 0
},
historyList: [],
historyLoading: false
} }
}, },
computed: { computed: {
@@ -254,6 +335,9 @@ export default {
}, },
mounted() { mounted() {
this.loadTypes() this.loadTypes()
this.loadCurrentIP()
this.loadUsageStatistics()
this.loadHistory()
// 启动定时器更新冷却时间显示 // 启动定时器更新冷却时间显示
this.cooldownTimer = setInterval(() => { this.cooldownTimer = setInterval(() => {
// 检查倒计时是否结束如果结束则清空lastGenerateTime // 检查倒计时是否结束如果结束则清空lastGenerateTime
@@ -273,6 +357,55 @@ export default {
} }
}, },
methods: { methods: {
async loadCurrentIP() {
try {
const res = await this.$axios({ url: '/public/comment/ip', method: 'get' })
if (res && (res.code === 200 || res.msg === '操作成功')) {
this.currentIP = res.data?.ip || res.data || '获取失败'
}
} catch(e) {
console.error('获取IP失败:', e)
this.currentIP = '获取失败'
}
},
async loadUsageStatistics() {
try {
const res = await this.$axios({ url: '/public/comment/usage-statistics', method: 'get' })
if (res && (res.code === 200 || res.msg === '操作成功')) {
this.usageStatistics = {
today: res.data?.today || 0,
last7Days: res.data?.last7Days || res.data?.last7days || 0,
last30Days: res.data?.last30Days || res.data?.last30days || 0,
total: res.data?.total || 0
}
}
} catch(e) {
console.error('获取使用统计失败:', e)
}
},
async loadHistory() {
this.historyLoading = true
try {
const res = await this.$axios({
url: '/public/comment/history',
method: 'get',
params: { pageNum: 1, pageSize: 20 }
})
if (res && (res.code === 200 || res.msg === '操作成功')) {
const list = res.data?.rows || res.data?.list || res.data || []
this.historyList = Array.isArray(list) ? list : []
}
} catch(e) {
console.error('获取历史记录失败:', e)
this.historyList = []
} finally {
this.historyLoading = false
}
},
formatTime(time) {
if (!time) return '-'
return parseTime(time, '{y}-{m}-{d} {h}:{i}:{s}')
},
async loadTypes() { async loadTypes() {
try { try {
const res = await this.$axios({ url: '/public/comment/types', method: 'get' }) const res = await this.$axios({ url: '/public/comment/types', method: 'get' })
@@ -354,6 +487,10 @@ export default {
// 解析统计信息 // 解析统计信息
this.statistics = res.data && res.data.statistics ? res.data.statistics : null this.statistics = res.data && res.data.statistics ? res.data.statistics : null
// 刷新使用统计和历史记录
this.loadUsageStatistics()
this.loadHistory()
this.$message.success('评论生成成功') this.$message.success('评论生成成功')
} else { } else {
this.$message.error(res && res.msg ? res.msg : '生成失败') this.$message.error(res && res.msg ? res.msg : '生成失败')
@@ -442,11 +579,30 @@ export default {
} }
.mobile-header h3 { .mobile-header h3 {
margin: 0; margin: 0 0 12px 0;
font-size: 18px; font-size: 18px;
font-weight: 600; font-weight: 600;
} }
.header-info {
margin-top: 8px;
}
.ip-info {
display: inline-flex;
align-items: center;
gap: 6px;
font-size: 13px;
opacity: 0.9;
background: rgba(255, 255, 255, 0.2);
padding: 4px 12px;
border-radius: 12px;
}
.ip-info i {
font-size: 14px;
}
/* 表单样式 */ /* 表单样式 */
.mobile-form { .mobile-form {
padding: 20px 16px; padding: 20px 16px;
@@ -461,6 +617,14 @@ export default {
font-weight: 600; font-weight: 600;
color: #303133; color: #303133;
margin-bottom: 12px; margin-bottom: 12px;
display: flex;
align-items: center;
gap: 6px;
}
.form-label i {
font-size: 16px;
color: #409eff;
} }
/* 选择器行样式 */ /* 选择器行样式 */
@@ -989,6 +1153,148 @@ export default {
font-size: 11px; font-size: 11px;
} }
} }
/* 使用统计样式 */
.usage-statistics-section {
background: linear-gradient(135deg, #f8f9ff 0%, #f0f4ff 100%);
border: 1px solid #e1e8ff;
border-radius: 12px;
padding: 16px;
margin-bottom: 24px;
}
.usage-stats-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 12px;
}
.usage-stat-item {
text-align: center;
background: #fff;
padding: 12px 8px;
border-radius: 8px;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05);
}
.usage-stat-number {
font-size: 20px;
font-weight: 700;
color: #409eff;
margin-bottom: 4px;
}
.usage-stat-label {
font-size: 12px;
color: #909399;
font-weight: 500;
}
/* 历史记录样式 */
.history-section {
margin-top: 24px;
border-top: 2px solid #f0f0f0;
padding-top: 24px;
}
.history-loading,
.history-empty {
text-align: center;
padding: 40px 20px;
color: #909399;
}
.history-loading i,
.history-empty i {
font-size: 32px;
margin-bottom: 12px;
display: block;
color: #c0c4cc;
}
.history-empty p {
margin: 0;
font-size: 14px;
}
.history-list {
max-height: 400px;
overflow-y: auto;
}
.history-item {
background: #fff;
border: 1px solid #e4e7ed;
border-radius: 8px;
padding: 12px;
margin-bottom: 8px;
transition: all 0.3s ease;
}
.history-item:hover {
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
transform: translateY(-1px);
}
.history-item-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 8px;
}
.history-type {
font-size: 14px;
font-weight: 600;
color: #303133;
}
.history-time {
font-size: 12px;
color: #909399;
}
.history-item-info {
display: flex;
align-items: center;
gap: 12px;
}
.history-ip {
font-size: 12px;
color: #606266;
}
/* 响应式适配 */
@media (max-width: 480px) {
.usage-stats-grid {
grid-template-columns: repeat(2, 1fr);
gap: 8px;
}
.usage-stat-item {
padding: 10px 6px;
}
.usage-stat-number {
font-size: 18px;
}
.usage-stat-label {
font-size: 11px;
}
.history-item-header {
flex-direction: column;
align-items: flex-start;
gap: 4px;
}
.ip-info {
font-size: 12px;
padding: 3px 10px;
}
}
</style> </style>