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() {
|
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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user