1
This commit is contained in:
@@ -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'
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,11 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
navItems: [
|
||||
{
|
||||
label: '首页',
|
||||
path: '/public/home',
|
||||
icon: 'el-icon-s-home'
|
||||
},
|
||||
{
|
||||
label: '评论生成',
|
||||
path: '/tools/comment-gen',
|
||||
@@ -70,9 +75,10 @@ export default {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
max-width: 600px;
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
padding: 0 16px;
|
||||
padding: 0 8px;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.nav-item {
|
||||
@@ -81,7 +87,7 @@ export default {
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
padding: 8px 16px;
|
||||
padding: 8px 8px;
|
||||
border-radius: 8px;
|
||||
transition: all 0.3s ease;
|
||||
flex: 1;
|
||||
@@ -100,7 +106,7 @@ export default {
|
||||
}
|
||||
|
||||
.nav-item i {
|
||||
font-size: 22px;
|
||||
font-size: 20px;
|
||||
margin-bottom: 4px;
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
@@ -110,43 +116,51 @@ export default {
|
||||
}
|
||||
|
||||
.nav-label {
|
||||
font-size: 12px;
|
||||
font-size: 11px;
|
||||
font-weight: 500;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
/* 响应式设计 */
|
||||
@media (max-width: 480px) {
|
||||
.nav-container {
|
||||
padding: 0 4px;
|
||||
gap: 2px;
|
||||
}
|
||||
|
||||
.nav-item {
|
||||
padding: 6px 12px;
|
||||
padding: 6px 4px;
|
||||
}
|
||||
|
||||
.nav-item i {
|
||||
font-size: 20px;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.nav-label {
|
||||
font-size: 11px;
|
||||
font-size: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.nav-container {
|
||||
max-width: 800px;
|
||||
max-width: 900px;
|
||||
padding: 0 12px;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.nav-item {
|
||||
padding: 10px 20px;
|
||||
padding: 10px 12px;
|
||||
}
|
||||
|
||||
.nav-item i {
|
||||
font-size: 24px;
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
.nav-label {
|
||||
font-size: 13px;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -3,9 +3,40 @@
|
||||
<div class="mobile-card">
|
||||
<div class="mobile-header">
|
||||
<h3>评论生成(公开)</h3>
|
||||
<div class="header-info">
|
||||
<span class="ip-info">
|
||||
<i class="el-icon-monitor"></i>
|
||||
IP: {{ currentIP || '获取中...' }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<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-label">型号/类型</div>
|
||||
@@ -168,6 +199,46 @@
|
||||
</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>
|
||||
|
||||
@@ -179,6 +250,7 @@
|
||||
<script>
|
||||
import { pinyin } from 'pinyin-pro'
|
||||
import PublicFooterNav from '@/components/PublicFooterNav'
|
||||
import { parseTime } from '@/utils/ruoyi'
|
||||
|
||||
export default {
|
||||
name: 'CommentGeneratorPublic',
|
||||
@@ -196,7 +268,16 @@ export default {
|
||||
lastGenerateTime: 0,
|
||||
cooldownTime: 1000, // 5秒冷却时间
|
||||
isButtonDisabled: false,
|
||||
activeLetter: 'ALL'
|
||||
activeLetter: 'ALL',
|
||||
currentIP: '',
|
||||
usageStatistics: {
|
||||
today: 0,
|
||||
last7Days: 0,
|
||||
last30Days: 0,
|
||||
total: 0
|
||||
},
|
||||
historyList: [],
|
||||
historyLoading: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@@ -254,6 +335,9 @@ export default {
|
||||
},
|
||||
mounted() {
|
||||
this.loadTypes()
|
||||
this.loadCurrentIP()
|
||||
this.loadUsageStatistics()
|
||||
this.loadHistory()
|
||||
// 启动定时器更新冷却时间显示
|
||||
this.cooldownTimer = setInterval(() => {
|
||||
// 检查倒计时是否结束,如果结束则清空lastGenerateTime
|
||||
@@ -273,6 +357,55 @@ export default {
|
||||
}
|
||||
},
|
||||
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() {
|
||||
try {
|
||||
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.loadUsageStatistics()
|
||||
this.loadHistory()
|
||||
|
||||
this.$message.success('评论生成成功')
|
||||
} else {
|
||||
this.$message.error(res && res.msg ? res.msg : '生成失败')
|
||||
@@ -442,11 +579,30 @@ export default {
|
||||
}
|
||||
|
||||
.mobile-header h3 {
|
||||
margin: 0;
|
||||
margin: 0 0 12px 0;
|
||||
font-size: 18px;
|
||||
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 {
|
||||
padding: 20px 16px;
|
||||
@@ -461,6 +617,14 @@ export default {
|
||||
font-weight: 600;
|
||||
color: #303133;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/* 使用统计样式 */
|
||||
.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>
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user