From 0a45d62278e2984737eb669065cd3e633cc2eccf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=8D=92?= Date: Sun, 31 Aug 2025 15:29:05 +0800 Subject: [PATCH 1/6] 1 --- src/permission.js | 2 +- src/plugins/index.js | 3 +++ src/router/index.js | 22 ++++++-------------- src/views/public/CommentGenerator.vue | 30 +++++++++++++++++++++------ 4 files changed, 34 insertions(+), 23 deletions(-) diff --git a/src/permission.js b/src/permission.js index b66190b..dedb360 100644 --- a/src/permission.js +++ b/src/permission.js @@ -9,7 +9,7 @@ import { isRelogin } from '@/utils/request' NProgress.configure({ showSpinner: false }) -const whiteList = ['/login', '/register'] +const whiteList = ['/login', '/register','/public/comment'] const isWhiteList = (path) => { return whiteList.some(pattern => isPathMatch(pattern, path)) diff --git a/src/plugins/index.js b/src/plugins/index.js index d000f2d..5860293 100644 --- a/src/plugins/index.js +++ b/src/plugins/index.js @@ -3,6 +3,7 @@ import auth from './auth' import cache from './cache' import modal from './modal' import download from './download' +import request from '@/utils/request' export default { install(Vue) { @@ -16,5 +17,7 @@ export default { Vue.prototype.$modal = modal // 下载文件 Vue.prototype.$download = download + // 全局请求实例(供 this.$axios 使用) + Vue.prototype.$axios = request } } diff --git a/src/router/index.js b/src/router/index.js index 40b621f..c0dd3bb 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -116,6 +116,12 @@ export const constantRoutes = [ } ] }, + // 公开评论独立页(不使用 Layout,无侧边栏) + { + path: '/public/comment', + component: () => import('@/views/public/CommentGenerator'), + hidden: true + }, { path: '/jdorder', component: Layout, @@ -146,22 +152,6 @@ export const constantRoutes = [ } ] }, - // 公共页面(免登录)可直接通过服务端 Anonymous 注解放行接口,这里仍挂在主框架下展示 - { - path: '/public', - component: Layout, - redirect: 'noredirect', - name: 'Public', - meta: { title: '公共工具', icon: 'link' }, - children: [ - { - path: 'comment', - component: () => import('@/views/public/CommentGenerator'), - name: 'CommentGeneratorPublic', - meta: { title: '评论生成(公开)', icon: 'message' } - } - ] - }, { path: '/sloworder', component: Layout, diff --git a/src/views/public/CommentGenerator.vue b/src/views/public/CommentGenerator.vue index 996140d..3b74b32 100644 --- a/src/views/public/CommentGenerator.vue +++ b/src/views/public/CommentGenerator.vue @@ -5,7 +5,7 @@ - + 刷新 @@ -13,10 +13,18 @@ 生成评论 - -
- 复制结果 +
+ +
{{ c.commentText }}
+
+ +
+
+ 复制文本 +
+
+
暂无数据
@@ -27,7 +35,7 @@ export default { name: 'CommentGeneratorPublic', data() { - return { form: { productType: '' }, loading: false, result: null, typeOptions: [] } + return { form: { productType: '' }, loading: false, result: null, typeOptions: [], comments: [] } }, computed: { pretty() { @@ -39,7 +47,11 @@ export default { async loadTypes() { try { const res = await this.$axios({ url: '/public/comment/types', method: 'get' }) - if (res && (res.code === 200 || res.msg === '操作成功')) this.typeOptions = res.data || [] + if (res && (res.code === 200 || res.msg === '操作成功')) { + // 后端返回 [{name,value}] 或纯数组,这里统一转成 [{name}] + const arr = Array.isArray(res.data) ? res.data : [] + this.typeOptions = arr.map(it => ({ name: it.name || it })) + } } catch(e) {} }, async generate() { @@ -50,6 +62,12 @@ export default { this.loading = false if (res && (res.code === 200 || res.msg === '操作成功')) { this.result = res.data + // 结果渲染 + const list = (res.data && res.data.list && Array.isArray(res.data.list)) ? res.data.list : [] + this.comments = list.map(it => ({ + commentText: (it && it.commentText) ? it.commentText : '', + images: Array.isArray(it && it.images) ? it.images : [] + })) } else { this.$message.error(res && res.msg ? res.msg : '生成失败') } From 0255e5d99de5a48fe045efc3a09e58bb7216e8fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=8D=92?= Date: Fri, 5 Sep 2025 18:56:28 +0800 Subject: [PATCH 2/6] 1 --- src/views/system/jdorder/orderList.vue | 28 +++++++++++++++----------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/src/views/system/jdorder/orderList.vue b/src/views/system/jdorder/orderList.vue index 0f357dd..dda89a2 100644 --- a/src/views/system/jdorder/orderList.vue +++ b/src/views/system/jdorder/orderList.vue @@ -39,33 +39,37 @@ - - - + + - - + + + + - - - - - + + + + proPriceAmount + + + + + + Date: Sat, 6 Sep 2025 16:23:48 +0800 Subject: [PATCH 3/6] 1 --- src/views/public/CommentGenerator.vue | 857 +++++++++++++++++++++++++- 1 file changed, 823 insertions(+), 34 deletions(-) diff --git a/src/views/public/CommentGenerator.vue b/src/views/public/CommentGenerator.vue index 3b74b32..2c00ce8 100644 --- a/src/views/public/CommentGenerator.vue +++ b/src/views/public/CommentGenerator.vue @@ -1,33 +1,165 @@ @@ -35,14 +167,48 @@ export default { name: 'CommentGeneratorPublic', data() { - return { form: { productType: '' }, loading: false, result: null, typeOptions: [], comments: [] } + return { + form: { productType: '' }, + loading: false, + result: null, + typeOptions: [], + comments: [], + statistics: null, + lastGenerateTime: 0, + cooldownTime: 5000, // 5秒冷却时间 + isButtonDisabled: false + } }, computed: { pretty() { try { return this.result ? JSON.stringify(this.result, null, 2) : '' } catch(e) { return '' } + }, + isGenerateButtonDisabled() { + // 如果正在加载、手动禁用、没有选择产品类型,或者在冷却时间内,则禁用按钮 + return this.loading || + this.isButtonDisabled || + !this.form.productType || + (Date.now() - this.lastGenerateTime < this.cooldownTime && this.lastGenerateTime > 0) + }, + remainingCooldownTime() { + if (this.lastGenerateTime === 0) return 0 + const remaining = Math.max(0, this.cooldownTime - (Date.now() - this.lastGenerateTime)) + return Math.ceil(remaining / 1000) + } + }, + mounted() { + this.loadTypes() + // 启动定时器更新冷却时间显示 + this.cooldownTimer = setInterval(() => { + // 强制更新计算属性 + this.$forceUpdate() + }, 1000) + }, + beforeDestroy() { + if (this.cooldownTimer) { + clearInterval(this.cooldownTimer) } }, - mounted() { this.loadTypes() }, methods: { async loadTypes() { try { @@ -55,23 +221,81 @@ export default { } catch(e) {} }, async generate() { - if (!this.form.productType) { this.$message.error('请选择型号'); return } + // 检查按钮是否被禁用 + if (this.isGenerateButtonDisabled) { + if (this.remainingCooldownTime > 0) { + this.$message.warning(`请等待 ${this.remainingCooldownTime} 秒后再试`) + } else if (!this.form.productType) { + this.$message.error('请选择型号') + } + return + } + + // 记录点击时间 + this.lastGenerateTime = Date.now() this.loading = true + this.isButtonDisabled = false + try { - const res = await this.$axios({ url: '/public/comment/generate', method: 'post', data: { productType: this.form.productType } }) + const res = await this.$axios({ + url: '/public/comment/generate', + method: 'post', + data: { productType: this.form.productType }, + timeout: 30000 // 30秒超时 + }) + this.loading = false + if (res && (res.code === 200 || res.msg === '操作成功')) { this.result = res.data - // 结果渲染 + + // 检查是否有有效数据 const list = (res.data && res.data.list && Array.isArray(res.data.list)) ? res.data.list : [] + + if (list.length === 0) { + this.$message.warning('接口返回数据为空,请稍后重试') + this.isButtonDisabled = true + // 10秒后重新启用按钮 + setTimeout(() => { + this.isButtonDisabled = false + }, 10000) + return + } + + // 结果渲染 this.comments = list.map(it => ({ commentText: (it && it.commentText) ? it.commentText : '', images: Array.isArray(it && it.images) ? it.images : [] })) + + // 解析统计信息 + this.statistics = res.data && res.data.statistics ? res.data.statistics : null + + this.$message.success('评论生成成功') } else { this.$message.error(res && res.msg ? res.msg : '生成失败') + this.isButtonDisabled = true + // 5秒后重新启用按钮 + setTimeout(() => { + this.isButtonDisabled = false + }, 5000) } - } catch(e) { this.loading = false; this.$message.error('生成失败') } + } catch(e) { + this.loading = false + console.error('生成评论失败:', e) + + if (e.code === 'ECONNABORTED') { + this.$message.error('请求超时,请检查网络连接') + } else { + this.$message.error('生成失败,请稍后重试') + } + + this.isButtonDisabled = true + // 5秒后重新启用按钮 + setTimeout(() => { + this.isButtonDisabled = false + }, 5000) + } }, copy(text) { if (!text) return @@ -82,12 +306,577 @@ export default { try { document.execCommand('copy'); this.$message.success('已复制') } catch(e) { this.$message.error('复制失败') } document.body.removeChild(ta) } + }, + getUsagePercentage() { + if (!this.statistics || !this.statistics.total || this.statistics.total === 0) { + return 0 + } + const used = this.statistics.used || 0 + const total = this.statistics.total + return Math.round((used / total) * 100) + }, + getButtonText() { + if (this.loading) { + return '生成中...' + } + if (this.remainingCooldownTime > 0) { + return `等待中 (${this.remainingCooldownTime}s)` + } + if (this.isButtonDisabled) { + return '暂时禁用' + } + if (!this.form.productType) { + return '请先选择型号' + } + return '生成评论' } } } From 2fb0f26b6d01c5174d6b3c31eda41e46e7fc565b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=8D=92?= Date: Sat, 6 Sep 2025 18:07:26 +0800 Subject: [PATCH 4/6] 1 --- src/api/system/jdorder.js | 13 +++++++++++-- src/views/system/jdorder/orderList.vue | 10 ++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/api/system/jdorder.js b/src/api/system/jdorder.js index d108ecf..46cccd0 100644 --- a/src/api/system/jdorder.js +++ b/src/api/system/jdorder.js @@ -3,7 +3,7 @@ import request from '@/utils/request' // JD订单列表 export function listJDOrders(query) { return request({ - url: '/jarvis/jdorder/list', + url: '/system/jdorder/list', method: 'get', params: query }) @@ -12,7 +12,7 @@ export function listJDOrders(query) { // JD订单详情 export function getJDOrder(id) { return request({ - url: `/jarvis/jdorder/${id}`, + url: `/system/jdorder/${id}`, method: 'get' }) } @@ -119,4 +119,13 @@ export function transferWithGift(data) { method: 'post', data }) +} + +// 导出JD订单列表 +export function exportJDOrders(query) { + return request({ + url: '/system/jdorder/export', + method: 'post', + params: query + }) } \ No newline at end of file diff --git a/src/views/system/jdorder/orderList.vue b/src/views/system/jdorder/orderList.vue index dda89a2..9e58e31 100644 --- a/src/views/system/jdorder/orderList.vue +++ b/src/views/system/jdorder/orderList.vue @@ -34,6 +34,7 @@ 搜索 重置 + 导出 @@ -137,6 +138,15 @@ export default { const num = Number(n) if (Number.isNaN(num)) return n return num.toFixed(2) + }, + /** 导出按钮操作 */ + handleExport() { + const params = { ...this.queryParams } + if (this.dateRange && this.dateRange.length === 2) { + params.beginTime = this.dateRange[0] + params.endTime = this.dateRange[1] + } + this.download('/system/jdorder/export', params, `京东订单数据_${new Date().getTime()}.xlsx`) } } } From dea68663efc6675e76b437a2b9098ec4863f1e32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=8D=92?= Date: Sun, 7 Sep 2025 17:35:42 +0800 Subject: [PATCH 5/6] 1 --- src/views/public/CommentGenerator.vue | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/views/public/CommentGenerator.vue b/src/views/public/CommentGenerator.vue index 2c00ce8..5e837f0 100644 --- a/src/views/public/CommentGenerator.vue +++ b/src/views/public/CommentGenerator.vue @@ -175,7 +175,7 @@ export default { comments: [], statistics: null, lastGenerateTime: 0, - cooldownTime: 5000, // 5秒冷却时间 + cooldownTime: 3000, // 5秒冷却时间 isButtonDisabled: false } }, @@ -200,6 +200,13 @@ export default { this.loadTypes() // 启动定时器更新冷却时间显示 this.cooldownTimer = setInterval(() => { + // 检查倒计时是否结束,如果结束则清空lastGenerateTime + if (this.lastGenerateTime > 0) { + const remaining = this.cooldownTime - (Date.now() - this.lastGenerateTime) + if (remaining <= 0) { + this.lastGenerateTime = 0 + } + } // 强制更新计算属性 this.$forceUpdate() }, 1000) From 24105e09726cc01ab1ac6f470edd72924a52fae3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=8D=92?= Date: Sun, 7 Sep 2025 17:50:37 +0800 Subject: [PATCH 6/6] 1 --- src/views/public/CommentGenerator.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/views/public/CommentGenerator.vue b/src/views/public/CommentGenerator.vue index 5e837f0..8345600 100644 --- a/src/views/public/CommentGenerator.vue +++ b/src/views/public/CommentGenerator.vue @@ -175,7 +175,7 @@ export default { comments: [], statistics: null, lastGenerateTime: 0, - cooldownTime: 3000, // 5秒冷却时间 + cooldownTime: 1000, // 5秒冷却时间 isButtonDisabled: false } },