From 1cf286b057555201674b1afd0638bda627f494bd Mon Sep 17 00:00:00 2001 From: JJBoy <291077997@qq.com> Date: Wed, 8 May 2024 21:12:24 +0800 Subject: [PATCH 001/195] =?UTF-8?q?=E3=80=90=E4=BF=AE=E5=A4=8D=E3=80=91?= =?UTF-8?q?=E5=95=86=E5=9F=8E=E7=AE=A1=E7=90=86=E9=A6=96=E9=A1=B5=E7=BB=9F?= =?UTF-8?q?=E8=AE=A1=E6=95=B0=E6=8D=AE=E6=98=BE=E7=A4=BA=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (cherry picked from commit 78dd2fa38a2d040c1c97d70cababc4f9265ac705) --- src/utils/index.ts | 2 +- src/views/mall/home/components/TradeTrendCard.vue | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/utils/index.ts b/src/utils/index.ts index 2590bce8..2c2fbbd0 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -313,7 +313,7 @@ export const fenToYuan = (price: string | number): string => { */ export const calculateRelativeRate = (value?: number, reference?: number) => { // 防止除0 - if (!reference) return 0 + if (!reference || reference == 0) return 0 return ((100 * ((value || 0) - reference)) / reference).toFixed(0) } diff --git a/src/views/mall/home/components/TradeTrendCard.vue b/src/views/mall/home/components/TradeTrendCard.vue index a8cab828..7930e212 100644 --- a/src/views/mall/home/components/TradeTrendCard.vue +++ b/src/views/mall/home/components/TradeTrendCard.vue @@ -186,7 +186,7 @@ const getOrderCountTrendComparison = async ( dates.push(item.value.date) if (series.length === 2) { series[0].data.push(fenToYuan(item?.value?.orderPayPrice || 0)) // 当前金额 - series[1].data.push(fenToYuan(item?.value?.orderPayCount || 0)) // 当前数量 + series[1].data.push(item?.value?.orderPayCount || 0) // 当前数量 } else { series[0].data.push(fenToYuan(item?.reference?.orderPayPrice || 0)) // 对照金额 series[1].data.push(fenToYuan(item?.value?.orderPayPrice || 0)) // 当前金额 From 1ce3343578a1a164e240605bca3ac2a7d3db55e3 Mon Sep 17 00:00:00 2001 From: DevDengChao <2325690622@qq.com> Date: Thu, 9 May 2024 15:02:45 +0800 Subject: [PATCH 002/195] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E5=A1=AB?= =?UTF-8?q?=E5=86=99=E5=95=86=E5=93=81=E5=B1=9E=E6=80=A7=E5=90=8E=E6=8C=89?= =?UTF-8?q?=E5=9B=9E=E8=BD=A6=E9=94=AE=E5=AF=BC=E8=87=B4=E9=A1=B5=E9=9D=A2?= =?UTF-8?q?=E5=88=B7=E6=96=B0=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/mall/product/spu/form/ProductPropertyAddForm.vue | 1 + 1 file changed, 1 insertion(+) diff --git a/src/views/mall/product/spu/form/ProductPropertyAddForm.vue b/src/views/mall/product/spu/form/ProductPropertyAddForm.vue index 9a8eee00..15c5a8d5 100644 --- a/src/views/mall/product/spu/form/ProductPropertyAddForm.vue +++ b/src/views/mall/product/spu/form/ProductPropertyAddForm.vue @@ -7,6 +7,7 @@ :model="formData" :rules="formRules" label-width="80px" + @keydown.enter.prevent="submitForm" > From 79f011fe172f9692307857d65f91df79c57291aa Mon Sep 17 00:00:00 2001 From: DevDengChao <2325690622@qq.com> Date: Fri, 10 May 2024 10:24:57 +0800 Subject: [PATCH 003/195] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E5=AE=9E?= =?UTF-8?q?=E4=BE=8B=E8=AE=A2=E5=8D=95=E5=AE=8C=E6=88=90=E6=94=AF=E4=BB=98?= =?UTF-8?q?=E5=90=8E=E8=B7=B3=E8=BD=AC=E5=88=B0=20404=20=E9=A1=B5=E9=9D=A2?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/pay/demo/order/index.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/views/pay/demo/order/index.vue b/src/views/pay/demo/order/index.vue index 374464eb..32f0de13 100644 --- a/src/views/pay/demo/order/index.vue +++ b/src/views/pay/demo/order/index.vue @@ -147,7 +147,7 @@ const handlePay = (row: any) => { name: 'PayCashier', query: { id: row.payOrderId, - returnUrl: encodeURIComponent('/pay/demo-order?id=' + row.id) + returnUrl: encodeURIComponent('/pay/demo/order?id=' + row.id) } }) } From e1d2305ddde681cafde4a0ca27fd9db2159d4854 Mon Sep 17 00:00:00 2001 From: DevDengChao <2325690622@qq.com> Date: Sat, 11 May 2024 10:35:27 +0800 Subject: [PATCH 004/195] =?UTF-8?q?fix:=20=E8=A1=A5=E5=85=85=E7=BC=BA?= =?UTF-8?q?=E5=A4=B1=E7=9A=84=E5=BE=AE=E4=BF=A1=20Native=20=E6=94=AF?= =?UTF-8?q?=E4=BB=98=E4=B8=8E=20WAP=20=E6=94=AF=E4=BB=98=E6=9E=9A=E4=B8=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/utils/constants.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/utils/constants.ts b/src/utils/constants.ts index f4d67b4e..cfa785b0 100644 --- a/src/utils/constants.ts +++ b/src/utils/constants.ts @@ -109,6 +109,14 @@ export const PayChannelEnum = { code: 'wx_app', name: '微信 APP 支付' }, + WX_NATIVE: { + code: 'wx_native', + name: '微信 Native 支付' + }, + WX_WAP: { + code: 'wx_wap', + name: '微信 WAP 网站支付' + }, WX_BAR: { code: 'wx_bar', name: '微信条码支付' From 0275cb6dd754b08995f624dbb9af7e8870255d08 Mon Sep 17 00:00:00 2001 From: DevDengChao <2325690622@qq.com> Date: Sat, 11 May 2024 10:39:18 +0800 Subject: [PATCH 005/195] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=20el-upload?= =?UTF-8?q?=20=E7=BB=84=E4=BB=B6=E6=8F=90=E7=A4=BA=20http-request=20?= =?UTF-8?q?=E5=B1=9E=E6=80=A7=E6=8A=A5=E9=94=99=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/components/channel/WeixinChannelForm.vue | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/views/pay/app/components/channel/WeixinChannelForm.vue b/src/views/pay/app/components/channel/WeixinChannelForm.vue index 34e92c69..cfd46bc0 100644 --- a/src/views/pay/app/components/channel/WeixinChannelForm.vue +++ b/src/views/pay/app/components/channel/WeixinChannelForm.vue @@ -80,7 +80,8 @@ :http-request="keyContentUpload" > - 点击上传 + + 点击上传 @@ -120,7 +121,8 @@ :http-request="privateKeyContentUpload" > - 点击上传 + + 点击上传 @@ -148,7 +150,8 @@ :http-request="privateCertContentUpload" > - 点击上传 + + 点击上传 @@ -310,7 +313,7 @@ const pemFileBeforeUpload = (file) => { /** * 读取 apiclient_key.pem 到 privateKeyContent 字段 */ -const privateKeyContentUpload = (event) => { +const privateKeyContentUpload = async (event) => { const readFile = new FileReader() readFile.onload = (e: any) => { formData.value.config.privateKeyContent = e.target.result @@ -321,7 +324,7 @@ const privateKeyContentUpload = (event) => { /** * 读取 apiclient_cert.pem 到 privateCertContent 字段 */ -const privateCertContentUpload = (event) => { +const privateCertContentUpload = async (event) => { const readFile = new FileReader() readFile.onload = (e: any) => { formData.value.config.privateCertContent = e.target.result @@ -332,7 +335,7 @@ const privateCertContentUpload = (event) => { /** * 读取 apiclient_cert.p12 到 keyContent 字段 */ -const keyContentUpload = (event) => { +const keyContentUpload = async (event) => { const readFile = new FileReader() readFile.onload = (e: any) => { formData.value.config.keyContent = e.target.result.split(',')[1] From 7883e3161d01b6dad8c7901941088ebeb2e7a927 Mon Sep 17 00:00:00 2001 From: DevDengChao <2325690622@qq.com> Date: Sat, 11 May 2024 10:59:26 +0800 Subject: [PATCH 006/195] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E5=BE=AE?= =?UTF-8?q?=E4=BF=A1=E5=8E=9F=E7=94=9F=E6=94=AF=E4=BB=98=E4=B8=8E=E7=BD=91?= =?UTF-8?q?=E7=AB=99=E6=94=AF=E4=BB=98=E6=97=A0=E6=B3=95=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/pay/app/index.vue | 199 +++++++++--------------------------- 1 file changed, 46 insertions(+), 153 deletions(-) diff --git a/src/views/pay/app/index.vue b/src/views/pay/app/index.vue index 2f4a9c1e..6b60d9b1 100644 --- a/src/views/pay/app/index.vue +++ b/src/views/pay/app/index.vue @@ -45,10 +45,17 @@ /> - 搜索 - 重置 + + + 搜索 + + + + 重置 + - 新增 + + 新增 @@ -70,12 +77,17 @@ - + - - - - - - - - - - - - diff --git a/src/views/ai/image/manager/index.vue b/src/views/ai/image/manager/index.vue index ef505036..d7ac6c81 100644 --- a/src/views/ai/image/manager/index.vue +++ b/src/views/ai/image/manager/index.vue @@ -163,7 +163,7 @@ From e3c46cab5305f3e8badaa84428100579797d21ff Mon Sep 17 00:00:00 2001 From: xiaohong <1315228474@qq.com> Date: Fri, 28 Jun 2024 09:26:58 +0800 Subject: [PATCH 019/195] =?UTF-8?q?feat:=20=E8=B0=83=E6=95=B4ai=20music=20?= =?UTF-8?q?=E9=A1=B5=E9=9D=A2=E6=96=87=E4=BB=B6=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/router/modules/remaining.ts | 2 +- src/views/ai/music/{ => components}/index.vue | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) rename src/views/ai/music/{ => components}/index.vue (82%) diff --git a/src/router/modules/remaining.ts b/src/router/modules/remaining.ts index ff2c5d92..6da3b0a4 100644 --- a/src/router/modules/remaining.ts +++ b/src/router/modules/remaining.ts @@ -79,7 +79,7 @@ const remainingRouter: AppRouteRecordRaw[] = [ children: [ { path: 'index', - component: () => import('@/views/ai//music/index.vue'), + component: () => import('@/views/ai/music/components/index.vue'), name: 'AIMusicIndex', meta: { title: 'AI 音乐', diff --git a/src/views/ai/music/index.vue b/src/views/ai/music/components/index.vue similarity index 82% rename from src/views/ai/music/index.vue rename to src/views/ai/music/components/index.vue index b48abb6b..21272522 100644 --- a/src/views/ai/music/index.vue +++ b/src/views/ai/music/components/index.vue @@ -8,8 +8,8 @@ From 6f9cb4f8f205ea9567d7865bf16ea73b4135a23e Mon Sep 17 00:00:00 2001 From: cherishsince Date: Fri, 28 Jun 2024 16:41:12 +0800 Subject: [PATCH 021/195] =?UTF-8?q?=E3=80=90=E8=A7=A3=E5=86=B3todo?= =?UTF-8?q?=E3=80=91=E5=A6=82=E6=9E=9C=E6=9C=89=E7=94=9F=E6=88=90=E4=B8=AD?= =?UTF-8?q?=E7=9A=84=E5=9B=BE=E7=89=87=EF=BC=8C=E8=BD=AE=E8=AF=A2=E6=94=B9?= =?UTF-8?q?=E6=88=90=20get=20=E6=8E=A5=E5=8F=A3=E5=8E=BB=E8=BD=AE=E8=AF=A2?= =?UTF-8?q?=EF=BC=8C=E4=B8=8D=E5=9F=BA=E4=BA=8E=20page=20=E8=BD=AE?= =?UTF-8?q?=E8=AF=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/ai/image/index.ts | 4 ++++ src/views/ai/image/ImageTask.vue | 35 ++++++++++++++++++++++++++++---- 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/src/api/ai/image/index.ts b/src/api/ai/image/index.ts index cb5a5afd..75103182 100644 --- a/src/api/ai/image/index.ts +++ b/src/api/ai/image/index.ts @@ -64,6 +64,10 @@ export const ImageApi = { getImageMy: async (id: number) => { return await request.get({ url: `/ai/image/get-my?id=${id}` }) }, + // 获取我的图片 + getImageMyIds: async (params) => { + return await request.get({ url: `/ai/image/get-my-ids`, params}) + }, // 生成图片 drawImage: async (data: ImageDrawReqVO) => { return await request.post({ url: `/ai/image/draw`, data }) diff --git a/src/views/ai/image/ImageTask.vue b/src/views/ai/image/ImageTask.vue index 38bf7483..992120bd 100644 --- a/src/views/ai/image/ImageTask.vue +++ b/src/views/ai/image/ImageTask.vue @@ -26,7 +26,7 @@ /> diff --git a/src/views/mall/promotion/kefu/components/KefuChatBox.vue b/src/views/mall/promotion/kefu/components/KefuChatBox.vue new file mode 100644 index 00000000..394c8424 --- /dev/null +++ b/src/views/mall/promotion/kefu/components/KefuChatBox.vue @@ -0,0 +1,77 @@ + + + + + diff --git a/src/views/mall/promotion/kefu/components/constants.ts b/src/views/mall/promotion/kefu/components/constants.ts new file mode 100644 index 00000000..015b46a7 --- /dev/null +++ b/src/views/mall/promotion/kefu/components/constants.ts @@ -0,0 +1,14 @@ +export const KeFuMessageContentTypeEnum = { + TEXT: 1, // 文本消息 + IMAGE: 2, // 图片消息 + VOICE: 3, // 语音消息 + VIDEO: 4, // 视频消息 + SYSTEM: 5, // 系统消息 + // ========== 商城特殊消息 ========== + PRODUCT: 10, // 商品消息 + ORDER: 11 // 订单消息" +} +export const UserTypeEnum = { + MEMBER: 1, // 会员 面向 c 端,普通用户 + ADMIN: 2 // 管理员 面向 b 端,管理后台 +} diff --git a/src/views/mall/promotion/kefu/components/emoji.ts b/src/views/mall/promotion/kefu/components/emoji.ts new file mode 100644 index 00000000..6ccd0cff --- /dev/null +++ b/src/views/mall/promotion/kefu/components/emoji.ts @@ -0,0 +1,91 @@ +export const emojiList = [ + { name: '[笑掉牙]', file: 'xiaodiaoya.png' }, + { name: '[可爱]', file: 'keai.png' }, + { name: '[冷酷]', file: 'lengku.png' }, + { name: '[闭嘴]', file: 'bizui.png' }, + { name: '[生气]', file: 'shengqi.png' }, + { name: '[惊恐]', file: 'jingkong.png' }, + { name: '[瞌睡]', file: 'keshui.png' }, + { name: '[大笑]', file: 'daxiao.png' }, + { name: '[爱心]', file: 'aixin.png' }, + { name: '[坏笑]', file: 'huaixiao.png' }, + { name: '[飞吻]', file: 'feiwen.png' }, + { name: '[疑问]', file: 'yiwen.png' }, + { name: '[开心]', file: 'kaixin.png' }, + { name: '[发呆]', file: 'fadai.png' }, + { name: '[流泪]', file: 'liulei.png' }, + { name: '[汗颜]', file: 'hanyan.png' }, + { name: '[惊悚]', file: 'jingshu.png' }, + { name: '[困~]', file: 'kun.png' }, + { name: '[心碎]', file: 'xinsui.png' }, + { name: '[天使]', file: 'tianshi.png' }, + { name: '[晕]', file: 'yun.png' }, + { name: '[啊]', file: 'a.png' }, + { name: '[愤怒]', file: 'fennu.png' }, + { name: '[睡着]', file: 'shuizhuo.png' }, + { name: '[面无表情]', file: 'mianwubiaoqing.png' }, + { name: '[难过]', file: 'nanguo.png' }, + { name: '[犯困]', file: 'fankun.png' }, + { name: '[好吃]', file: 'haochi.png' }, + { name: '[呕吐]', file: 'outu.png' }, + { name: '[龇牙]', file: 'ziya.png' }, + { name: '[懵比]', file: 'mengbi.png' }, + { name: '[白眼]', file: 'baiyan.png' }, + { name: '[饿死]', file: 'esi.png' }, + { name: '[凶]', file: 'xiong.png' }, + { name: '[感冒]', file: 'ganmao.png' }, + { name: '[流汗]', file: 'liuhan.png' }, + { name: '[笑哭]', file: 'xiaoku.png' }, + { name: '[流口水]', file: 'liukoushui.png' }, + { name: '[尴尬]', file: 'ganga.png' }, + { name: '[惊讶]', file: 'jingya.png' }, + { name: '[大惊]', file: 'dajing.png' }, + { name: '[不好意思]', file: 'buhaoyisi.png' }, + { name: '[大闹]', file: 'danao.png' }, + { name: '[不可思议]', file: 'bukesiyi.png' }, + { name: '[爱你]', file: 'aini.png' }, + { name: '[红心]', file: 'hongxin.png' }, + { name: '[点赞]', file: 'dianzan.png' }, + { name: '[恶魔]', file: 'emo.png' } +] + +export const emojiPage = {} +emojiList.forEach((item, index) => { + if (!emojiPage[Math.floor(index / 30) + 1]) { + emojiPage[Math.floor(index / 30) + 1] = [] + } + emojiPage[Math.floor(index / 30) + 1].push(item) +}) + +// 后端上传地址 +const staticUrl = import.meta.env.VITE_STATIC_URL + +// 处理表情 +export function replaceEmoji(data: string) { + let newData = data + if (typeof newData !== 'object') { + const reg = /\[(.+?)\]/g // [] 中括号 + const zhEmojiName = newData.match(reg) + if (zhEmojiName) { + zhEmojiName.forEach((item) => { + const emojiFile = selEmojiFile(item) + newData = newData.replace( + item, + `` + ) + }) + } + } + return newData +} + +function selEmojiFile(name: string) { + for (const index in emojiList) { + if (emojiList[index].name === name) { + return emojiList[index].file + } + } + return false +} diff --git a/src/views/mall/promotion/kefu/components/index.ts b/src/views/mall/promotion/kefu/components/index.ts new file mode 100644 index 00000000..afd2fd76 --- /dev/null +++ b/src/views/mall/promotion/kefu/components/index.ts @@ -0,0 +1,5 @@ +import KeFuConversationBox from './KeFuConversationBox.vue' +import KeFuChatBox from './KefuChatBox.vue' +import * as Constants from './constants' + +export { KeFuConversationBox, KeFuChatBox, Constants } diff --git a/src/views/mall/promotion/kefu/index.vue b/src/views/mall/promotion/kefu/index.vue new file mode 100644 index 00000000..52c6f2ba --- /dev/null +++ b/src/views/mall/promotion/kefu/index.vue @@ -0,0 +1,55 @@ + + + + + diff --git a/types/env.d.ts b/types/env.d.ts index 057b5268..63d9c3ee 100644 --- a/types/env.d.ts +++ b/types/env.d.ts @@ -19,6 +19,7 @@ interface ImportMetaEnv { readonly VITE_UPLOAD_URL: string readonly VITE_API_URL: string readonly VITE_BASE_PATH: string + readonly VITE_STATIC_URL: string readonly VITE_DROP_DEBUGGER: string readonly VITE_DROP_CONSOLE: string readonly VITE_SOURCEMAP: string From d3b4063b94b159dc8d2256fd11c5fc409e79d7c1 Mon Sep 17 00:00:00 2001 From: puhui999 Date: Mon, 1 Jul 2024 16:15:27 +0800 Subject: [PATCH 028/195] =?UTF-8?q?=E3=80=90=E6=96=B0=E5=A2=9E=E3=80=91?= =?UTF-8?q?=EF=BC=9Amall=20=E5=AE=A2=E6=9C=8D=E6=B6=88=E6=81=AF=E6=A0=B7?= =?UTF-8?q?=E5=BC=8F=E8=AE=BE=E8=AE=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mall/promotion/kefu/conversation/index.ts | 2 +- src/api/mall/promotion/kefu/message/index.ts | 70 ++++++++ .../promotion/kefu/components/KeFuChatBox.vue | 167 ++++++++++++++++++ .../kefu/components/KeFuConversationBox.vue | 8 +- .../promotion/kefu/components/KefuChatBox.vue | 77 -------- .../promotion/kefu/components/constants.ts | 4 - .../mall/promotion/kefu/components/index.ts | 2 +- src/views/mall/promotion/kefu/index.vue | 7 +- 8 files changed, 249 insertions(+), 88 deletions(-) create mode 100644 src/api/mall/promotion/kefu/message/index.ts create mode 100644 src/views/mall/promotion/kefu/components/KeFuChatBox.vue delete mode 100644 src/views/mall/promotion/kefu/components/KefuChatBox.vue diff --git a/src/api/mall/promotion/kefu/conversation/index.ts b/src/api/mall/promotion/kefu/conversation/index.ts index 17432b35..96a23706 100644 --- a/src/api/mall/promotion/kefu/conversation/index.ts +++ b/src/api/mall/promotion/kefu/conversation/index.ts @@ -16,7 +16,7 @@ export interface KeFuConversationRespVO { /** * 会话所属用户昵称 */ - nickname: string + userNickname: string /** * 最后聊天时间 */ diff --git a/src/api/mall/promotion/kefu/message/index.ts b/src/api/mall/promotion/kefu/message/index.ts new file mode 100644 index 00000000..3408f1e0 --- /dev/null +++ b/src/api/mall/promotion/kefu/message/index.ts @@ -0,0 +1,70 @@ +import request from '@/config/axios' + +export interface KeFuMessageRespVO { + /** + * 编号 + */ + id: number + /** + * 会话编号 + */ + conversationId: number + /** + * 发送人编号 + */ + senderId: number + /** + * 发送人头像 + */ + senderAvatar: string + /** + * 发送人类型 + */ + senderType: number + /** + * 接收人编号 + */ + receiverId: number + /** + * 接收人类型 + */ + receiverType: number + /** + * 消息类型 + */ + contentType: number + /** + * 消息 + */ + content: string + /** + * 是否已读 + */ + readStatus: boolean + /** + * 创建时间 + */ + createTime: Date +} + +// 客服会话 API +export const KeFuMessageApi = { + // 发送客服消息 + sendKeFuMessage: async (data: any) => { + return await request.put({ + url: '/promotion/kefu-message/send', + data + }) + }, + // 更新客服消息已读状态 + updateKeFuMessageReadStatus: async (data: any) => { + return await request.put({ + url: '/promotion/kefu-message/update-read-status', + data + }) + }, + // 获得消息分页数据 + getKeFuMessagePage: async (params: any) => { + return await request.get({ url: '/promotion/kefu-message/page', params }) + } +} diff --git a/src/views/mall/promotion/kefu/components/KeFuChatBox.vue b/src/views/mall/promotion/kefu/components/KeFuChatBox.vue new file mode 100644 index 00000000..ee41564b --- /dev/null +++ b/src/views/mall/promotion/kefu/components/KeFuChatBox.vue @@ -0,0 +1,167 @@ + + + + + diff --git a/src/views/mall/promotion/kefu/components/KeFuConversationBox.vue b/src/views/mall/promotion/kefu/components/KeFuConversationBox.vue index c94c01c3..595475be 100644 --- a/src/views/mall/promotion/kefu/components/KeFuConversationBox.vue +++ b/src/views/mall/promotion/kefu/components/KeFuConversationBox.vue @@ -10,7 +10,7 @@
-
{{ item.nickname }}
+
{{ item.userNickname }}
{ userId: 283, userAvatar: 'https://thirdwx.qlogo.cn/mmopen/vi_32/Q0j4TwGTfTKMezSxtOImrC9lbhwHiazYwck3xwrEcO7VJfG6WQo260whaeVNoByE5RreiaGsGfOMlIiaDhSaA991w/132', - nickname: '辉辉鸭' + i, + userNickname: '辉辉鸭' + i, lastMessageTime: getNowDateTime(), lastMessageContent: '[爱心][爱心]你好哇', lastMessageContentType: 1, @@ -54,12 +54,12 @@ const getConversationList = async () => { } defineExpose({ getConversationList }) const emits = defineEmits<{ - (e: 'change', v: number): void + (e: 'change', v: KeFuConversationRespVO): void }>() // 打开右侧消息 const openRightMessage = (item: KeFuConversationRespVO, index: number) => { activeConversationIndex.value = index - emits('change', item.id) + emits('change', item) } diff --git a/src/views/mall/promotion/kefu/components/KefuChatBox.vue b/src/views/mall/promotion/kefu/components/KefuChatBox.vue deleted file mode 100644 index 394c8424..00000000 --- a/src/views/mall/promotion/kefu/components/KefuChatBox.vue +++ /dev/null @@ -1,77 +0,0 @@ - - - - - diff --git a/src/views/mall/promotion/kefu/components/constants.ts b/src/views/mall/promotion/kefu/components/constants.ts index 015b46a7..f8599160 100644 --- a/src/views/mall/promotion/kefu/components/constants.ts +++ b/src/views/mall/promotion/kefu/components/constants.ts @@ -8,7 +8,3 @@ export const KeFuMessageContentTypeEnum = { PRODUCT: 10, // 商品消息 ORDER: 11 // 订单消息" } -export const UserTypeEnum = { - MEMBER: 1, // 会员 面向 c 端,普通用户 - ADMIN: 2 // 管理员 面向 b 端,管理后台 -} diff --git a/src/views/mall/promotion/kefu/components/index.ts b/src/views/mall/promotion/kefu/components/index.ts index afd2fd76..fcf6bd5b 100644 --- a/src/views/mall/promotion/kefu/components/index.ts +++ b/src/views/mall/promotion/kefu/components/index.ts @@ -1,5 +1,5 @@ import KeFuConversationBox from './KeFuConversationBox.vue' -import KeFuChatBox from './KefuChatBox.vue' +import KeFuChatBox from './KeFuChatBox.vue' import * as Constants from './constants' export { KeFuConversationBox, KeFuChatBox, Constants } diff --git a/src/views/mall/promotion/kefu/index.vue b/src/views/mall/promotion/kefu/index.vue index 52c6f2ba..1204b8dc 100644 --- a/src/views/mall/promotion/kefu/index.vue +++ b/src/views/mall/promotion/kefu/index.vue @@ -15,12 +15,17 @@ diff --git a/src/views/ai/image/manager/index.vue b/src/views/ai/image/manager/index.vue index f0e94faa..84403f35 100644 --- a/src/views/ai/image/manager/index.vue +++ b/src/views/ai/image/manager/index.vue @@ -121,7 +121,7 @@ :active-value="true" :inactive-value="false" @change="handleUpdatePublicStatusChange(scope.row)" - :disabled="scope.row.status !== 20" + :disabled="scope.row.status !== AiImageStatusEnum.SUCCESS" /> @@ -165,6 +165,7 @@ import { getIntDictOptions, DICT_TYPE, getStrDictOptions, getBoolDictOptions } f import { dateFormatter } from '@/utils/formatTime' import { ImageApi, ImageVO } from '@/api/ai/image' import * as UserApi from '@/api/system/user' +import { AiImageStatusEnum } from '@/views/ai/utils/constants' /** AI 绘画 列表 */ defineOptions({ name: 'AiImageManager' }) diff --git a/src/views/ai/music/manager/index.vue b/src/views/ai/music/manager/index.vue index ec3c12b0..342f8dd8 100644 --- a/src/views/ai/music/manager/index.vue +++ b/src/views/ai/music/manager/index.vue @@ -158,7 +158,7 @@ :active-value="true" :inactive-value="false" @change="handleUpdatePublicStatusChange(scope.row)" - :disabled="scope.row.status !== 20" + :disabled="scope.row.status !== AiMusicStatusEnum.SUCCESS" /> @@ -199,6 +199,7 @@ import { getIntDictOptions, getBoolDictOptions, DICT_TYPE } from '@/utils/dict' import { dateFormatter } from '@/utils/formatTime' import { MusicApi, MusicVO } from '@/api/ai/music' import * as UserApi from '@/api/system/user' +import { AiMusicStatusEnum } from '@/views/ai/utils/constants' /** AI 音乐 列表 */ defineOptions({ name: 'AiMusicManager' }) diff --git a/src/views/ai/utils/constants.ts b/src/views/ai/utils/constants.ts new file mode 100644 index 00000000..2e7b9ac5 --- /dev/null +++ b/src/views/ai/utils/constants.ts @@ -0,0 +1,41 @@ +/** + * Created by 芋道源码 + * + * AI 枚举类 + * + * 问题:为什么不放在 src/utils/constants.ts 呢? + * 回答:主要 AI 是可选模块,考虑到独立、解耦,所以放在了 /views/ai/utils/constants.ts + */ + +/** + * AI 平台的枚举 + */ +export const AiPlatformEnum = { + OPENAI: 'OpenAI', + Ollama: 'Ollama', + YI_YAN: 'YiYan', // 百度 + XING_HUO: 'XingHuo', // 讯飞 + QIAN_WEN: 'QianWen', // 阿里 + GEMIR: 'gemir', // 谷歌 + STABLE_DIFFUSION: 'StableDiffusion', // Stability AI + MIDJOURNEY: 'Midjourney', // Midjourney + SUNO: 'Suno' // Suno AI +} + +/** + * AI 图像生成状态的枚举 + */ +export const AiImageStatusEnum = { + IN_PROGRESS: 10, // 进行中 + SUCCESS: 20, // 已完成 + FAIL: 30 // 已失败 +} + +/** + * AI 音乐生成状态的枚举 + */ +export const AiMusicStatusEnum = { + IN_PROGRESS: 10, // 进行中 + SUCCESS: 20, // 已完成 + FAIL: 30 // 已失败 +} From b0b62eb2506d80726f22505a8109f5d4a28ee87c Mon Sep 17 00:00:00 2001 From: puhui999 Date: Wed, 3 Jul 2024 17:51:58 +0800 Subject: [PATCH 036/195] =?UTF-8?q?=E3=80=90=E4=BC=98=E5=8C=96=E3=80=91?= =?UTF-8?q?=EF=BC=9Amall=20=E5=AE=A2=E6=9C=8D=E8=A1=A8=E6=83=85=E5=8C=85?= =?UTF-8?q?=E5=AD=98=E6=94=BE=E5=88=B0=E6=9C=AC=E5=9C=B0=E4=BD=BF=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.local | 4 - .../kefu/components/EmojiSelectPopover.vue | 3 +- .../promotion/kefu/components/KeFuChatBox.vue | 4 +- .../kefu/components/KeFuConversationBox.vue | 3 +- .../mall/promotion/kefu/components/emoji.ts | 101 ++++++++++-------- .../promotion/kefu/components/images/a.png | Bin 0 -> 4237 bytes .../promotion/kefu/components/images/aini.png | Bin 0 -> 2309 bytes .../kefu/components/images/aixin.png | Bin 0 -> 4431 bytes .../kefu/components/images/baiyan.png | Bin 0 -> 3792 bytes .../kefu/components/images/bizui.png | Bin 0 -> 3768 bytes .../kefu/components/images/buhaoyisi.png | Bin 0 -> 4443 bytes .../kefu/components/images/bukesiyi.png | Bin 0 -> 3979 bytes .../kefu/components/images/dajing.png | Bin 0 -> 4298 bytes .../kefu/components/images/danao.png | Bin 0 -> 4568 bytes .../kefu/components/images/daxiao.png | Bin 0 -> 4382 bytes .../kefu/components/images/dianzan.png | Bin 0 -> 1878 bytes .../promotion/kefu/components/images/emo.png | Bin 0 -> 4956 bytes .../promotion/kefu/components/images/esi.png | Bin 0 -> 3873 bytes .../kefu/components/images/fadai.png | Bin 0 -> 3823 bytes .../kefu/components/images/fankun.png | Bin 0 -> 4236 bytes .../kefu/components/images/feiwen.png | Bin 0 -> 6873 bytes .../kefu/components/images/fennu.png | Bin 0 -> 4590 bytes .../kefu/components/images/ganga.png | Bin 0 -> 4396 bytes .../kefu/components/images/ganmao.png | Bin 0 -> 4727 bytes .../kefu/components/images/hanyan.png | Bin 0 -> 2966 bytes .../kefu/components/images/haochi.png | Bin 0 -> 3794 bytes .../kefu/components/images/hongxin.png | Bin 0 -> 3844 bytes .../kefu/components/images/huaixiao.png | Bin 0 -> 4234 bytes .../kefu/components/images/jingkong.png | Bin 0 -> 4272 bytes .../kefu/components/images/jingshu.png | Bin 0 -> 4702 bytes .../kefu/components/images/jingya.png | Bin 0 -> 4167 bytes .../kefu/components/images/kaixin.png | Bin 0 -> 4008 bytes .../promotion/kefu/components/images/keai.png | Bin 0 -> 4060 bytes .../kefu/components/images/keshui.png | Bin 0 -> 3975 bytes .../promotion/kefu/components/images/kun.png | Bin 0 -> 4460 bytes .../kefu/components/images/lengku.png | Bin 0 -> 4630 bytes .../kefu/components/images/liuhan.png | Bin 0 -> 3823 bytes .../kefu/components/images/liukoushui.png | Bin 0 -> 4072 bytes .../kefu/components/images/liulei.png | Bin 0 -> 4246 bytes .../kefu/components/images/mengbi.png | Bin 0 -> 3345 bytes .../kefu/components/images/mianwubiaoqing.png | Bin 0 -> 2928 bytes .../kefu/components/images/nanguo.png | Bin 0 -> 3882 bytes .../promotion/kefu/components/images/outu.png | Bin 0 -> 4403 bytes .../kefu/components/images/shengqi.png | Bin 0 -> 4629 bytes .../kefu/components/images/shuizhuo.png | Bin 0 -> 4641 bytes .../kefu/components/images/tianshi.png | Bin 0 -> 4192 bytes .../kefu/components/images/xiaodiaoya.png | Bin 0 -> 4326 bytes .../kefu/components/images/xiaoku.png | Bin 0 -> 4725 bytes .../kefu/components/images/xinsui.png | Bin 0 -> 4377 bytes .../kefu/components/images/xiong.png | Bin 0 -> 4525 bytes .../kefu/components/images/yiwen.png | Bin 0 -> 4615 bytes .../promotion/kefu/components/images/yun.png | Bin 0 -> 5991 bytes .../promotion/kefu/components/images/ziya.png | Bin 0 -> 4126 bytes 53 files changed, 62 insertions(+), 53 deletions(-) create mode 100644 src/views/mall/promotion/kefu/components/images/a.png create mode 100644 src/views/mall/promotion/kefu/components/images/aini.png create mode 100644 src/views/mall/promotion/kefu/components/images/aixin.png create mode 100644 src/views/mall/promotion/kefu/components/images/baiyan.png create mode 100644 src/views/mall/promotion/kefu/components/images/bizui.png create mode 100644 src/views/mall/promotion/kefu/components/images/buhaoyisi.png create mode 100644 src/views/mall/promotion/kefu/components/images/bukesiyi.png create mode 100644 src/views/mall/promotion/kefu/components/images/dajing.png create mode 100644 src/views/mall/promotion/kefu/components/images/danao.png create mode 100644 src/views/mall/promotion/kefu/components/images/daxiao.png create mode 100644 src/views/mall/promotion/kefu/components/images/dianzan.png create mode 100644 src/views/mall/promotion/kefu/components/images/emo.png create mode 100644 src/views/mall/promotion/kefu/components/images/esi.png create mode 100644 src/views/mall/promotion/kefu/components/images/fadai.png create mode 100644 src/views/mall/promotion/kefu/components/images/fankun.png create mode 100644 src/views/mall/promotion/kefu/components/images/feiwen.png create mode 100644 src/views/mall/promotion/kefu/components/images/fennu.png create mode 100644 src/views/mall/promotion/kefu/components/images/ganga.png create mode 100644 src/views/mall/promotion/kefu/components/images/ganmao.png create mode 100644 src/views/mall/promotion/kefu/components/images/hanyan.png create mode 100644 src/views/mall/promotion/kefu/components/images/haochi.png create mode 100644 src/views/mall/promotion/kefu/components/images/hongxin.png create mode 100644 src/views/mall/promotion/kefu/components/images/huaixiao.png create mode 100644 src/views/mall/promotion/kefu/components/images/jingkong.png create mode 100644 src/views/mall/promotion/kefu/components/images/jingshu.png create mode 100644 src/views/mall/promotion/kefu/components/images/jingya.png create mode 100644 src/views/mall/promotion/kefu/components/images/kaixin.png create mode 100644 src/views/mall/promotion/kefu/components/images/keai.png create mode 100644 src/views/mall/promotion/kefu/components/images/keshui.png create mode 100644 src/views/mall/promotion/kefu/components/images/kun.png create mode 100644 src/views/mall/promotion/kefu/components/images/lengku.png create mode 100644 src/views/mall/promotion/kefu/components/images/liuhan.png create mode 100644 src/views/mall/promotion/kefu/components/images/liukoushui.png create mode 100644 src/views/mall/promotion/kefu/components/images/liulei.png create mode 100644 src/views/mall/promotion/kefu/components/images/mengbi.png create mode 100644 src/views/mall/promotion/kefu/components/images/mianwubiaoqing.png create mode 100644 src/views/mall/promotion/kefu/components/images/nanguo.png create mode 100644 src/views/mall/promotion/kefu/components/images/outu.png create mode 100644 src/views/mall/promotion/kefu/components/images/shengqi.png create mode 100644 src/views/mall/promotion/kefu/components/images/shuizhuo.png create mode 100644 src/views/mall/promotion/kefu/components/images/tianshi.png create mode 100644 src/views/mall/promotion/kefu/components/images/xiaodiaoya.png create mode 100644 src/views/mall/promotion/kefu/components/images/xiaoku.png create mode 100644 src/views/mall/promotion/kefu/components/images/xinsui.png create mode 100644 src/views/mall/promotion/kefu/components/images/xiong.png create mode 100644 src/views/mall/promotion/kefu/components/images/yiwen.png create mode 100644 src/views/mall/promotion/kefu/components/images/yun.png create mode 100644 src/views/mall/promotion/kefu/components/images/ziya.png diff --git a/.env.local b/.env.local index 82a3f72a..005d2f0d 100644 --- a/.env.local +++ b/.env.local @@ -29,9 +29,5 @@ VITE_BASE_PATH=/ # 商城H5会员端域名 VITE_MALL_H5_DOMAIN='http://localhost:3000' -# TODO puhui999:这个可以不走 cdn 地址么? -# 客户端静态资源地址 空=默认使用服务端指定的CDN资源地址前缀 | local=本地 | http(s)://xxx.xxx=自定义静态资源地址前缀 -VITE_STATIC_URL = https://file.sheepjs.com - # 验证码的开关 VITE_APP_CAPTCHA_ENABLE=false diff --git a/src/views/mall/promotion/kefu/components/EmojiSelectPopover.vue b/src/views/mall/promotion/kefu/components/EmojiSelectPopover.vue index 03a963c6..4c777efb 100644 --- a/src/views/mall/promotion/kefu/components/EmojiSelectPopover.vue +++ b/src/views/mall/promotion/kefu/components/EmojiSelectPopover.vue @@ -26,8 +26,9 @@ diff --git a/src/views/mall/promotion/kefu/components/constants.ts b/src/views/mall/promotion/kefu/components/tools/constants.ts similarity index 100% rename from src/views/mall/promotion/kefu/components/constants.ts rename to src/views/mall/promotion/kefu/components/tools/constants.ts diff --git a/src/views/mall/promotion/kefu/components/emoji.ts b/src/views/mall/promotion/kefu/components/tools/emoji.ts similarity index 100% rename from src/views/mall/promotion/kefu/components/emoji.ts rename to src/views/mall/promotion/kefu/components/tools/emoji.ts From e89b274e3f66d8c0ac539b62e22f00d4577290e0 Mon Sep 17 00:00:00 2001 From: puhui999 Date: Thu, 4 Jul 2024 15:41:15 +0800 Subject: [PATCH 048/195] =?UTF-8?q?=E3=80=90=E4=BC=98=E5=8C=96=E3=80=91?= =?UTF-8?q?=EF=BC=9Amall=20=E5=AE=A2=E6=9C=8D=E6=B6=88=E6=81=AF=E7=BB=84?= =?UTF-8?q?=E4=BB=B6=E6=8A=BD=E7=A6=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../promotion/kefu/components/KeFuChatBox.vue | 52 +++---------------- .../components/message/ImageMessageItem.vue | 40 ++++++++++++++ .../components/message/TextMessageItem.vue | 29 +++++++++++ 3 files changed, 76 insertions(+), 45 deletions(-) create mode 100644 src/views/mall/promotion/kefu/components/message/ImageMessageItem.vue create mode 100644 src/views/mall/promotion/kefu/components/message/TextMessageItem.vue diff --git a/src/views/mall/promotion/kefu/components/KeFuChatBox.vue b/src/views/mall/promotion/kefu/components/KeFuChatBox.vue index cba5869b..da25c9d9 100644 --- a/src/views/mall/promotion/kefu/components/KeFuChatBox.vue +++ b/src/views/mall/promotion/kefu/components/KeFuChatBox.vue @@ -19,49 +19,18 @@ class="flex mb-20px w-[100%]" >
- - + - +
@@ -94,14 +63,14 @@ import { KeFuMessageApi, KeFuMessageRespVO } from '@/api/mall/promotion/kefu/mes import { KeFuConversationRespVO } from '@/api/mall/promotion/kefu/conversation' import EmojiSelectPopover from './tools/EmojiSelectPopover.vue' import PictureSelectUpload from './tools/PictureSelectUpload.vue' -import { Emoji, useEmoji } from './tools/emoji' +import TextMessageItem from './message/TextMessageItem.vue' +import ImageMessageItem from './message/ImageMessageItem.vue' +import { Emoji } from './tools/emoji' import { KeFuMessageContentTypeEnum } from './tools/constants' import { isEmpty } from '@/utils/is' import { UserTypeEnum } from '@/utils/constants' -import { createImageViewer } from '@/components/ImageViewer' defineOptions({ name: 'KeFuMessageBox' }) -const { replaceEmoji } = useEmoji() const messageTool = useMessage() const message = ref('') // 消息 const messageList = ref([]) // 消息列表 @@ -175,13 +144,6 @@ const scrollToBottom = async () => { scrollbarRef.value!.setScrollTop(innerRef.value!.clientHeight) } -/** 图预览 */ -const imagePreview = (imgUrl: string) => { - createImageViewer({ - urlList: [imgUrl] - }) -} - // TODO puhui999: 轮训相关,功能完善后移除 onBeforeUnmount(() => { if (!poller.value) { diff --git a/src/views/mall/promotion/kefu/components/message/ImageMessageItem.vue b/src/views/mall/promotion/kefu/components/message/ImageMessageItem.vue new file mode 100644 index 00000000..7b890cf1 --- /dev/null +++ b/src/views/mall/promotion/kefu/components/message/ImageMessageItem.vue @@ -0,0 +1,40 @@ + + + diff --git a/src/views/mall/promotion/kefu/components/message/TextMessageItem.vue b/src/views/mall/promotion/kefu/components/message/TextMessageItem.vue new file mode 100644 index 00000000..fd4b6edb --- /dev/null +++ b/src/views/mall/promotion/kefu/components/message/TextMessageItem.vue @@ -0,0 +1,29 @@ + + + From b6ff9ede11107e22c27daf8f95f5939b30f8f2f3 Mon Sep 17 00:00:00 2001 From: cherishsince Date: Thu, 4 Jul 2024 16:01:08 +0800 Subject: [PATCH 049/195] =?UTF-8?q?=E3=80=90=E8=A7=A3=E5=86=B3todo?= =?UTF-8?q?=E3=80=91handle=E5=91=BD=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/ai/image/ImageDetailDrawer.vue | 10 +++---- src/views/ai/image/ImageTask.vue | 20 +++++++------- src/views/ai/image/ImageTaskCard.vue | 20 +++++++------- src/views/ai/image/dall3/index.vue | 27 +++++++++---------- src/views/ai/image/index.vue | 14 +++++----- src/views/ai/image/midjourney/index.vue | 25 +++++++++-------- src/views/ai/image/stable-diffusion/index.vue | 2 +- 7 files changed, 57 insertions(+), 61 deletions(-) diff --git a/src/views/ai/image/ImageDetailDrawer.vue b/src/views/ai/image/ImageDetailDrawer.vue index fca087da..95ec146c 100644 --- a/src/views/ai/image/ImageDetailDrawer.vue +++ b/src/views/ai/image/ImageDetailDrawer.vue @@ -2,7 +2,7 @@ @@ -79,8 +79,8 @@ const props = defineProps({ }) /** 抽屉 - close */ -const handlerDrawerClose = async () => { - emits('handlerDrawerClose') +const handleDrawerClose = async () => { + emits('handleDrawerClose') } /** 获取 - 图片 detail */ @@ -90,7 +90,7 @@ const getImageDetail = async (id) => { } /** 任务 - detail */ -const handlerTaskDetail = async () => { +const handleTaskDetail = async () => { showDrawer.value = true } @@ -107,7 +107,7 @@ watch(id, async (newVal, oldVal) => { } }) // -const emits = defineEmits(['handlerDrawerClose']) +const emits = defineEmits(['handleDrawerClose']) // onMounted(async () => {}) diff --git a/src/views/ai/image/ImageTask.vue b/src/views/ai/image/ImageTask.vue index 9ddd7461..b4cbd253 100644 --- a/src/views/ai/image/ImageTask.vue +++ b/src/views/ai/image/ImageTask.vue @@ -6,8 +6,8 @@ v-for="image in imageList" :key="image" :image-detail="image" - @on-btn-click="handlerImageBtnClick" - @on-mj-btn-click="handlerImageMjBtnClick" + @on-btn-click="handleImageBtnClick" + @on-mj-btn-click="handleImageMjBtnClick" />
@@ -16,7 +16,7 @@ layout="prev, pager, next" :default-page-size="pageSize" :total="pageTotal" - @change="handlerPageChange" + @change="handlePageChange" />
@@ -24,7 +24,7 @@ diff --git a/src/views/ai/image/dall3/index.vue b/src/views/ai/image/dall3/index.vue index 69e767a3..1751eace 100644 --- a/src/views/ai/image/dall3/index.vue +++ b/src/views/ai/image/dall3/index.vue @@ -25,7 +25,7 @@ :type="(selectHotWord === hotWord ? 'primary' : 'default')" v-for="hotWord in hotWords" :key="hotWord" - @click="handlerHotWordClick(hotWord)" + @click="handleHotWordClick(hotWord)" > {{ hotWord }} @@ -45,7 +45,7 @@
{{model.name}}
@@ -64,7 +64,7 @@
{{imageStyle.name}}
@@ -78,7 +78,7 @@
+ @click="handleSizeClick(imageSize)">
@@ -91,7 +91,7 @@ size="large" round :loading="drawIn" - @click="handlerGenerateImage"> + @click="handleGenerateImage"> {{drawIn ? '生成中' : '生成内容'}}
@@ -183,10 +183,8 @@ const props = defineProps({}) // 定义 emits const emits = defineEmits(['onDrawStart', 'onDrawComplete']) -// TODO @fan:如果是简单注释,建议用 /** */,主要是现在项目里是这种风格哈,保持一致好点~ -// TODO @fan:handler 应该改成 handle 哈 /** 热词 - click */ -const handlerHotWordClick = async (hotWord: string) => { +const handleHotWordClick = async (hotWord: string) => { // 取消选中 if (selectHotWord.value == hotWord) { selectHotWord.value = '' @@ -199,22 +197,22 @@ const handlerHotWordClick = async (hotWord: string) => { } /** 模型 - click */ -const handlerModelClick = async (model: ImageModelVO) => { +const handleModelClick = async (model: ImageModelVO) => { selectModel.value = model.key } /** 样式 - click */ -const handlerStyleClick = async (imageStyle: ImageModelVO) => { +const handleStyleClick = async (imageStyle: ImageModelVO) => { selectImageStyle.value = imageStyle.key } /** size - click */ -const handlerSizeClick = async (imageSize: ImageSizeVO) => { +const handleSizeClick = async (imageSize: ImageSizeVO) => { selectImageSize.value = imageSize.key } /** 图片生产 */ -const handlerGenerateImage = async () => { +const handleGenerateImage = async () => { // 二次确认 await message.confirm(`确认生成内容?`) try { @@ -251,15 +249,14 @@ const settingValues = async (imageDetail: ImageVO) => { selectImageStyle.value = imageDetail.options?.style // const imageSize = imageSizeList.value.find(item => item.key === `${imageDetail.width}x${imageDetail.height}`) as ImageSizeVO - console.log('imageSize', imageSize) - await handlerSizeClick(imageSize) + await handleSizeClick(imageSize) } /** 暴露组件方法 */ defineExpose({ settingValues }) + From f70c8dcee2d95ca9cde2f0458e1329858581f7ce Mon Sep 17 00:00:00 2001 From: downeyin <853384781@qq.com> Date: Sat, 6 Jul 2024 23:12:40 +0800 Subject: [PATCH 065/195] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8DCRM=E5=90=88?= =?UTF-8?q?=E5=90=8C=E8=AF=A6=E6=83=85=E4=B8=AD=E5=9B=A2=E9=98=9F=E6=88=90?= =?UTF-8?q?=E5=91=98=E6=9C=AA=E5=B1=95=E7=A4=BA=E6=9D=83=E9=99=90=E7=BC=96?= =?UTF-8?q?=E8=BE=91=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/crm/contract/detail/index.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/views/crm/contract/detail/index.vue b/src/views/crm/contract/detail/index.vue index 0829e100..1369a355 100644 --- a/src/views/crm/contract/detail/index.vue +++ b/src/views/crm/contract/detail/index.vue @@ -36,7 +36,7 @@ ref="permissionListRef" :biz-id="contract.id!" :biz-type="BizTypeEnum.CRM_CONTRACT" - :show-action="false" + :show-action="!permissionListRef?.isPool || false" @quit-team="close" /> From 6f86ea96da367ab3b25fe04dc74ef9cdd8df9454 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sun, 7 Jul 2024 11:22:02 +0800 Subject: [PATCH 066/195] =?UTF-8?q?=E3=80=90=E4=BB=A3=E7=A0=81=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E3=80=91AI=EF=BC=9A=E6=8E=A5=E5=85=A5=E6=9B=B4?= =?UTF-8?q?=E5=A4=9A=20AI=20=E5=A4=A7=E6=A8=A1=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/ai/utils/constants.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/views/ai/utils/constants.ts b/src/views/ai/utils/constants.ts index 2e7b9ac5..337cfda3 100644 --- a/src/views/ai/utils/constants.ts +++ b/src/views/ai/utils/constants.ts @@ -11,12 +11,13 @@ * AI 平台的枚举 */ export const AiPlatformEnum = { + TONG_YI: 'TongYi', // 阿里 + YI_YAN: 'YiYan', // 百度 + DEEP_SEEK: 'DeepSeek', // DeepSeek + ZHI_PU: 'ZhiPu', // 智谱 AI + XING_HUO: 'XingHuo', // 讯飞 OPENAI: 'OpenAI', Ollama: 'Ollama', - YI_YAN: 'YiYan', // 百度 - XING_HUO: 'XingHuo', // 讯飞 - QIAN_WEN: 'QianWen', // 阿里 - GEMIR: 'gemir', // 谷歌 STABLE_DIFFUSION: 'StableDiffusion', // Stability AI MIDJOURNEY: 'Midjourney', // Midjourney SUNO: 'Suno' // Suno AI From 2871961582634a5627922f81e8908274a6a2397f Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sun, 7 Jul 2024 11:23:27 +0800 Subject: [PATCH 067/195] docs: update README --- README.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 738fc6d1..f69861f0 100644 --- a/README.md +++ b/README.md @@ -54,16 +54,16 @@ 推荐 VS Code 开发,配合插件如下: -| 插件名 | 功能 | -|-------------------------------|--------------------------| -| Vue - Official | Vue与TypeScript支持 | -| unocss | unocss for vscode | -| Iconify IntelliSense | Iconify 预览和搜索 | -| i18n Ally | 国际化智能提示 | -| Stylelint | Css 格式化 | -| Prettier | 代码格式化 | -| ESLint | 脚本代码检查 | -| DotENV | env 文件高亮 | +| 插件名 | 功能 | +|-------------------------------|---------------------| +| Vue - Official | Vue 与 TypeScript 支持 | +| unocss | unocss for vscode | +| Iconify IntelliSense | Iconify 预览和搜索 | +| i18n Ally | 国际化智能提示 | +| Stylelint | Css 格式化 | +| Prettier | 代码格式化 | +| ESLint | 脚本代码检查 | +| DotENV | env 文件高亮 | ## 🔥 后端架构 From f3777f63348fbaaea21ae5c311a64b3d0b88e843 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sun, 7 Jul 2024 17:22:16 +0800 Subject: [PATCH 068/195] =?UTF-8?q?=E3=80=90=E4=BB=A3=E7=A0=81=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E3=80=91AI=EF=BC=9A=E5=B0=86=E5=AF=B9=E8=AF=9D?= =?UTF-8?q?=E3=80=81=E8=81=8A=E5=A4=A9=E6=8C=AA=E5=88=B0=20index=20?= =?UTF-8?q?=E7=9B=AE=E5=BD=95=E4=B8=8B=EF=BC=8C=E6=9B=B4=E6=A8=A1=E5=9D=97?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/ai/chat/{ => index}/ChatEmpty.vue | 0 .../ai/chat/{ => index}/Conversation.vue | 2 +- src/views/ai/chat/{ => index}/Message.vue | 0 .../ai/chat/{ => index}/MessageLoading.vue | 0 .../ai/chat/{ => index}/MessageNewChat.vue | 0 .../components/ChatConversationUpdateForm.vue | 0 .../ai/chat/{ => index}/components/Header.vue | 0 src/views/ai/chat/{ => index}/index.vue | 2 +- .../{ => index}/role/RoleCategoryList.vue | 0 .../ai/chat/{ => index}/role/RoleList.vue | 0 src/views/ai/chat/{ => index}/role/index.vue | 2 +- .../image/{ => index}/ImageDetailDrawer.vue | 0 src/views/ai/image/{ => index}/ImageTask.vue | 0 .../ai/image/{ => index}/ImageTaskCard.vue | 0 .../ai/image/{ => index}/dall3/index.vue | 0 src/views/ai/image/{ => index}/index.vue | 0 .../ai/image/{ => index}/midjourney/index.vue | 0 .../{ => index}/stable-diffusion/index.vue | 33 ++++++++++++++----- .../ai/utils/{common-utils.ts => utils.ts} | 0 19 files changed, 27 insertions(+), 12 deletions(-) rename src/views/ai/chat/{ => index}/ChatEmpty.vue (100%) rename src/views/ai/chat/{ => index}/Conversation.vue (99%) rename src/views/ai/chat/{ => index}/Message.vue (100%) rename src/views/ai/chat/{ => index}/MessageLoading.vue (100%) rename src/views/ai/chat/{ => index}/MessageNewChat.vue (100%) rename src/views/ai/chat/{ => index}/components/ChatConversationUpdateForm.vue (100%) rename src/views/ai/chat/{ => index}/components/Header.vue (100%) rename src/views/ai/chat/{ => index}/index.vue (99%) rename src/views/ai/chat/{ => index}/role/RoleCategoryList.vue (100%) rename src/views/ai/chat/{ => index}/role/RoleList.vue (100%) rename src/views/ai/chat/{ => index}/role/index.vue (99%) rename src/views/ai/image/{ => index}/ImageDetailDrawer.vue (100%) rename src/views/ai/image/{ => index}/ImageTask.vue (100%) rename src/views/ai/image/{ => index}/ImageTaskCard.vue (100%) rename src/views/ai/image/{ => index}/dall3/index.vue (100%) rename src/views/ai/image/{ => index}/index.vue (100%) rename src/views/ai/image/{ => index}/midjourney/index.vue (100%) rename src/views/ai/image/{ => index}/stable-diffusion/index.vue (93%) rename src/views/ai/utils/{common-utils.ts => utils.ts} (100%) diff --git a/src/views/ai/chat/ChatEmpty.vue b/src/views/ai/chat/index/ChatEmpty.vue similarity index 100% rename from src/views/ai/chat/ChatEmpty.vue rename to src/views/ai/chat/index/ChatEmpty.vue diff --git a/src/views/ai/chat/Conversation.vue b/src/views/ai/chat/index/Conversation.vue similarity index 99% rename from src/views/ai/chat/Conversation.vue rename to src/views/ai/chat/index/Conversation.vue index 5976171b..be184cf8 100644 --- a/src/views/ai/chat/Conversation.vue +++ b/src/views/ai/chat/index/Conversation.vue @@ -98,7 +98,7 @@ diff --git a/src/views/ai/writer/components/Right.vue b/src/views/ai/writer/components/Right.vue new file mode 100644 index 00000000..a11b7c24 --- /dev/null +++ b/src/views/ai/writer/components/Right.vue @@ -0,0 +1,25 @@ + + + + + diff --git a/src/views/ai/writer/components/Tag.vue b/src/views/ai/writer/components/Tag.vue new file mode 100644 index 00000000..4a32e572 --- /dev/null +++ b/src/views/ai/writer/components/Tag.vue @@ -0,0 +1,32 @@ + + + + + diff --git a/src/views/ai/writer/index.vue b/src/views/ai/writer/index.vue new file mode 100644 index 00000000..3cb4a7d7 --- /dev/null +++ b/src/views/ai/writer/index.vue @@ -0,0 +1,20 @@ + + + + + From 1064bbe5700a73c7eb14f3bf4f61012d332a24f9 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sun, 7 Jul 2024 20:30:44 +0800 Subject: [PATCH 070/195] =?UTF-8?q?=E3=80=90=E4=BB=A3=E7=A0=81=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E3=80=91AI=EF=BC=9A=E8=81=8A=E5=A4=A9=E5=AF=B9?= =?UTF-8?q?=E8=AF=9D=20index.vue=20=E4=BB=A3=E7=A0=81=E6=A2=B3=E7=90=86=20?= =?UTF-8?q?20%?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/ai/chat/conversation/index.ts | 4 +- src/api/ai/chat/message/index.ts | 13 +- src/views/ai/chat/index/MessageNewChat.vue | 8 +- .../conversation/ConversationList.vue} | 5 +- .../ConversationUpdateForm.vue} | 10 +- src/views/ai/chat/index/index.vue | 368 +++++++++--------- 6 files changed, 198 insertions(+), 210 deletions(-) rename src/views/ai/chat/index/{Conversation.vue => components/conversation/ConversationList.vue} (99%) rename src/views/ai/chat/index/components/{ChatConversationUpdateForm.vue => conversation/ConversationUpdateForm.vue} (95%) diff --git a/src/api/ai/chat/conversation/index.ts b/src/api/ai/chat/conversation/index.ts index 9f5f70f2..acc21fc6 100644 --- a/src/api/ai/chat/conversation/index.ts +++ b/src/api/ai/chat/conversation/index.ts @@ -2,7 +2,7 @@ import request from '@/config/axios' // AI 聊天对话 VO export interface ChatConversationVO { - id: string // ID 编号 + id: number // ID 编号 userId: number // 用户编号 title: string // 对话标题 pinned: boolean // 是否置顶 @@ -23,7 +23,7 @@ export interface ChatConversationVO { // AI 聊天对话 API export const ChatConversationApi = { // 获得【我的】聊天对话 - getChatConversationMy: async (id: string) => { + getChatConversationMy: async (id: number) => { return await request.get({ url: `/ai/chat/conversation/get-my?id=${id}` }) }, diff --git a/src/api/ai/chat/message/index.ts b/src/api/ai/chat/message/index.ts index f9e807a1..90736266 100644 --- a/src/api/ai/chat/message/index.ts +++ b/src/api/ai/chat/message/index.ts @@ -19,22 +19,17 @@ export interface ChatMessageVO { userAvatar: string // 创建时间 } -export interface ChatMessageSendVO { - conversationId: string // 对话编号 - content: number // 聊天内容 -} - // AI chat 聊天 export const ChatMessageApi = { // 消息列表 - messageList: async (conversationId: string | null) => { + getChatMessageListByConversationId: async (conversationId: number | null) => { return await request.get({ url: `/ai/chat/message/list-by-conversation-id?conversationId=${conversationId}` }) }, - // 发送 send stream 消息 - // TODO axios 可以么? https://apifox.com/apiskills/how-to-create-axios-stream/ + // 发送 Stream 消息 + // 为什么不用 axios 呢?因为它不支持 SSE 调用 sendStream: async ( conversationId: number, content: string, @@ -70,7 +65,7 @@ export const ChatMessageApi = { }, // 删除消息 - 对话所有消息 - deleteByConversationId: async (conversationId: string) => { + deleteByConversationId: async (conversationId: number) => { return await request.delete({ url: `/ai/chat/message/delete-by-conversation-id?conversationId=${conversationId}` }) diff --git a/src/views/ai/chat/index/MessageNewChat.vue b/src/views/ai/chat/index/MessageNewChat.vue index aac5f905..727fb282 100644 --- a/src/views/ai/chat/index/MessageNewChat.vue +++ b/src/views/ai/chat/index/MessageNewChat.vue @@ -1,15 +1,16 @@ diff --git a/src/views/ai/writer/data.json b/src/views/ai/writer/data.json new file mode 100644 index 00000000..3f20951b --- /dev/null +++ b/src/views/ai/writer/data.json @@ -0,0 +1,11 @@ +{ + "write": { + "prompt": "vue", + "data": "Vue.js 是一种用于构建用户界面的渐进式 JavaScript 框架。它的核心库只关注视图层,易于上手,同时也便于与其他库或已有项目整合。\n\nVue.js 的特点包括:\n- 响应式的数据绑定:Vue.js 会自动将数据与 DOM 同步,使得状态管理变得更加简单。\n- 组件化:Vue.js 允许开发者通过小型、独立和通常可复用的组件构建大型应用。\n- 虚拟 DOM:Vue.js 使用虚拟 DOM 实现快速渲染,提高了性能。\n\n在 Vue.js 中,一个典型的应用结构可能包括:\n1. 根实例:每个 Vue 应用都需要一个根实例作为入口点。\n2. 组件系统:可以创建自定义的可复用组件。\n3. 指令:特殊的带有前缀 v- 的属性,为 DOM 元素提供特殊的行为。\n4. 插值:用于文本内容,将数据动态地插入到 HTML。\n5. 计算属性和侦听器:用于处理数据的复杂逻辑和响应数据变化。\n6. 条件渲染:根据条件决定元素的渲染。\n7. 列表渲染:用于显示列表数据。\n8. 事件处理:响应用户交互。\n9. 表单输入绑定:处理表单输入和验证。\n10. 组件生命周期钩子:在组件的不同阶段执行特定的函数。\n\nVue.js 还提供了官方的路由器 Vue Router 和状态管理库 Vuex,以支持构建复杂的单页应用(SPA)。\n\n在开发过程中,开发者通常会使用 Vue CLI,这是一个强大的命令行工具,用于快速生成 Vue 项目脚手架,集成了诸如 Babel、Webpack 等现代前端工具,以及热重载、代码检测等开发体验优化功能。\n\nVue.js 的生态系统还包括大量的第三方库和插件,如 Vuetify(UI 组件库)、Vue Test Utils(测试工具)等,这些都极大地丰富了 Vue.js 的开发生态。\n\n总的来说,Vue.js 是一个灵活、高效的前端框架,适合从小型项目到大型企业级应用的开发。它的易用性、灵活性和强大的社区支持使其成为许多开发者的首选框架之一。" + }, + "reply": { + "originalContent": "领导,我想请假", + "prompt": "不批", + "data": "您的请假申请已收悉,经核实和考虑,暂时无法批准您的请假申请。\n\n如有特殊情况或紧急事务,请及时与我联系。\n\n祝工作顺利。\n\n谢谢。" + } +} diff --git a/src/views/ai/writer/index.vue b/src/views/ai/writer/index.vue index 3cb4a7d7..8875830f 100644 --- a/src/views/ai/writer/index.vue +++ b/src/views/ai/writer/index.vue @@ -1,7 +1,13 @@ @@ -9,12 +15,47 @@ import Left from './components/Left.vue' import Right from './components/Right.vue' import { writeStream } from '@/api/ai/writer' + import dataJson from './data.json' - const msg = ref('') + const message = useMessage() + const msgResult = ref('') + const isWriting = ref(false) - const submit = async (params) => { - const res = await writeStream(params) + const abortController = ref() + + const stopStream = () => { + abortController.value?.abort() + isWriting.value = false + } + + const rightRef = ref>() + + // 点击示例触发 + const example = (type: keyof typeof dataJson) => { + msgResult.value = dataJson[type].data + } + + const submit = async (data) => { + abortController.value = new AbortController() + msgResult.value = '' + isWriting.value = true + writeStream({ + data, + onMessage: async (res) => { + const { code, data, msg } = JSON.parse(res.data) + if (code !== 0) { + message.alert(`写作异常! ${msg}`) + stopStream() + return + } + msgResult.value = msgResult.value + data + nextTick(() => { + rightRef.value?.scrollToBottom() + }) + }, + ctrl: abortController.value, + onClose: stopStream, + onError: stopStream + }) } - - From e9bb9403b4ade987b2d7071619dbd9bfa2c13565 Mon Sep 17 00:00:00 2001 From: puhui999 Date: Mon, 8 Jul 2024 12:00:34 +0800 Subject: [PATCH 073/195] =?UTF-8?q?=E3=80=90=E4=BC=98=E5=8C=96=E3=80=91spu?= =?UTF-8?q?=EF=BC=9A=E6=96=B0=E5=A2=9E=E5=95=86=E5=93=81=E5=B1=9E=E6=80=A7?= =?UTF-8?q?=E5=B1=9E=E6=80=A7=E5=80=BC=E4=B8=BA=E7=A9=BA=E6=A0=A1=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mall/product/spu/components/SkuList.vue | 36 ++++++++++++------- .../product/spu/form/ProductAttributes.vue | 12 +++---- src/views/mall/product/spu/form/SkuForm.vue | 14 ++++---- 3 files changed, 37 insertions(+), 25 deletions(-) diff --git a/src/views/mall/product/spu/components/SkuList.vue b/src/views/mall/product/spu/components/SkuList.vue index 2befe640..9bbd38e4 100644 --- a/src/views/mall/product/spu/components/SkuList.vue +++ b/src/views/mall/product/spu/components/SkuList.vue @@ -292,6 +292,7 @@ import { createImageViewer } from '@/components/ImageViewer' import { RuleConfig } from '@/views/mall/product/spu/components/index' import { PropertyAndValues } from './index' import { ElTable } from 'element-plus' +import { isEmpty } from '@/utils/is' defineOptions({ name: 'SkuList' }) const message = useMessage() // 消息弹窗 @@ -340,11 +341,22 @@ const imagePreview = (imgUrl: string) => { /** 批量添加 */ const batchAdd = () => { + validateProperty() formData.value!.skus!.forEach((item) => { copyValueToTarget(item, skuList.value[0]) }) } - +/** 校验商品属性属性值 */ +const validateProperty = () => { + // 校验商品属性属性值是否为空,有一个为空都不给过 + const warningInfo = '存在属性属性值为空,请先检查完善属性值后重试!!!' + for (const item of props.propertyList) { + if (!item.values || isEmpty(item.values)) { + message.warning(warningInfo) + throw new Error(warningInfo) + } + } +} /** 删除 sku */ const deleteSku = (row) => { const index = formData.value!.skus!.findIndex( @@ -358,6 +370,7 @@ const tableHeaders = ref<{ prop: string; label: string }[]>([]) // 多属性表 * 保存时,每个商品规格的表单要校验下。例如说,销售金额最低是 0.01 这种。 */ const validateSku = () => { + validateProperty() let warningInfo = '请检查商品各行相关属性配置,' let validate = true // 默认通过 for (const sku of formData.value!.skus!) { @@ -421,7 +434,7 @@ watch( const generateTableData = (propertyList: any[]) => { // 构建数据结构 const propertyValues = propertyList.map((item) => - item.values.map((v) => ({ + item.values.map((v: any) => ({ propertyId: item.id, propertyName: item.name, valueId: v.id, @@ -464,15 +477,14 @@ const generateTableData = (propertyList: any[]) => { */ const validateData = (propertyList: any[]) => { const skuPropertyIds: number[] = [] - formData.value!.skus!.forEach( - (sku) => - sku.properties - ?.map((property) => property.propertyId) - ?.forEach((propertyId) => { - if (skuPropertyIds.indexOf(propertyId!) === -1) { - skuPropertyIds.push(propertyId!) - } - }) + formData.value!.skus!.forEach((sku) => + sku.properties + ?.map((property) => property.propertyId) + ?.forEach((propertyId) => { + if (skuPropertyIds.indexOf(propertyId!) === -1) { + skuPropertyIds.push(propertyId!) + } + }) ) const propertyIds = propertyList.map((item) => item.id) return skuPropertyIds.length === propertyIds.length @@ -543,7 +555,7 @@ watch( return } // 添加新属性没有属性值也不做处理 - if (propertyList.some((item) => item.values!.length === 0)) { + if (propertyList.some((item) => !item.values || isEmpty(item.values))) { return } // 生成 table 数据,即 sku 列表 diff --git a/src/views/mall/product/spu/form/ProductAttributes.vue b/src/views/mall/product/spu/form/ProductAttributes.vue index 28962f47..ffe7397d 100644 --- a/src/views/mall/product/spu/form/ProductAttributes.vue +++ b/src/views/mall/product/spu/form/ProductAttributes.vue @@ -3,7 +3,7 @@
属性名: - + {{ item.name }}
@@ -12,8 +12,8 @@ {{ value.name }} @@ -44,7 +44,6 @@ From 2b0789112f345da0fc020d5ebd9dc2a5b286298f Mon Sep 17 00:00:00 2001 From: YunaiV Date: Mon, 8 Jul 2024 12:39:49 +0800 Subject: [PATCH 074/195] =?UTF-8?q?=E3=80=90=E4=BB=A3=E7=A0=81=E8=AF=84?= =?UTF-8?q?=E5=AE=A1=E3=80=91AI=EF=BC=9A=E5=86=99=E4=BD=9C=E7=9B=B8?= =?UTF-8?q?=E5=85=B3=E7=9A=84=E5=BB=BA=E8=AE=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/ai/writer/index.ts | 4 +- .../conversation/ConversationList.vue | 3 +- src/views/ai/writer/components/Left.vue | 176 +++++++++--------- src/views/ai/writer/components/Right.vue | 88 ++++----- src/views/ai/writer/components/Tag.vue | 27 ++- src/views/ai/writer/index.vue | 92 ++++----- 6 files changed, 201 insertions(+), 189 deletions(-) diff --git a/src/api/ai/writer/index.ts b/src/api/ai/writer/index.ts index 01664b3d..57c23b4f 100644 --- a/src/api/ai/writer/index.ts +++ b/src/api/ai/writer/index.ts @@ -3,7 +3,9 @@ import { fetchEventSource } from '@microsoft/fetch-event-source' import { getAccessToken } from '@/utils/auth' import { config } from '@/config/axios/config' +// TODO @hhhero:可以改成 WriteVO 哈,主要是保持一致 export interface WriteParams { + // TODO @hhhero:注释。每个属性的后面哈。会更简洁一点 /** * 1:撰写 2:回复 */ @@ -33,6 +35,7 @@ export interface WriteParams { */ language: number } + export const writeStream = ({ data, onClose, @@ -46,7 +49,6 @@ export const writeStream = ({ onClose?: (...args: any[]) => void ctrl: AbortController }) => { - // return request.post({ url: '/ai/write/generate-stream', data }) const token = getAccessToken() return fetchEventSource(`${config.base_url}/ai/write/generate-stream`, { method: 'post', diff --git a/src/views/ai/chat/index/components/conversation/ConversationList.vue b/src/views/ai/chat/index/components/conversation/ConversationList.vue index 911f0fbb..6a7e32fa 100644 --- a/src/views/ai/chat/index/components/conversation/ConversationList.vue +++ b/src/views/ai/chat/index/components/conversation/ConversationList.vue @@ -226,7 +226,7 @@ const conversationTimeGroup = async (list: ChatConversationVO[]) => { const threeDays = 3 * oneDay const sevenDays = 7 * oneDay const thirtyDays = 30 * oneDay - for (const conversation: ChatConversationVO of list) { + for (const conversation of list) { // 置顶 if (conversation.pinned) { groupMap['置顶'].push(conversation) @@ -247,7 +247,6 @@ const conversationTimeGroup = async (list: ChatConversationVO[]) => { groupMap['三十天前'].push(conversation) } } - console.log('----groupMap', groupMap) return groupMap } diff --git a/src/views/ai/writer/components/Left.vue b/src/views/ai/writer/components/Left.vue index af808b15..0369d9df 100644 --- a/src/views/ai/writer/components/Left.vue +++ b/src/views/ai/writer/components/Left.vue @@ -1,5 +1,5 @@ diff --git a/src/views/ai/writer/components/Right.vue b/src/views/ai/writer/components/Right.vue index 30b74cdc..94140011 100644 --- a/src/views/ai/writer/components/Right.vue +++ b/src/views/ai/writer/components/Right.vue @@ -35,52 +35,52 @@ diff --git a/src/views/ai/writer/components/Tag.vue b/src/views/ai/writer/components/Tag.vue index 4a32e572..d496b517 100644 --- a/src/views/ai/writer/components/Tag.vue +++ b/src/views/ai/writer/components/Tag.vue @@ -13,20 +13,19 @@ - diff --git a/src/views/ai/writer/index.vue b/src/views/ai/writer/index.vue index 8875830f..27276431 100644 --- a/src/views/ai/writer/index.vue +++ b/src/views/ai/writer/index.vue @@ -1,61 +1,67 @@ + From 1a6afa3263e8797c4d96d8ed93f433bc336660f0 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Mon, 8 Jul 2024 13:00:24 +0800 Subject: [PATCH 075/195] =?UTF-8?q?=E3=80=90=E4=BB=A3=E7=A0=81=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E3=80=91AI=EF=BC=9A=E8=81=8A=E5=A4=A9=E5=AF=B9?= =?UTF-8?q?=E8=AF=9D=20index.vue=20=E4=BB=A3=E7=A0=81=E6=A2=B3=E7=90=86=20?= =?UTF-8?q?40%=EF=BC=88message=20=E9=83=A8=E5=88=86=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/ai/chat/conversation/index.ts | 1 + .../index/components/message/MessageList.vue | 135 +++++++----------- .../components/message/MessageListEmpty.vue | 26 ++-- .../message/MessageNewConversation.vue | 5 +- 4 files changed, 65 insertions(+), 102 deletions(-) diff --git a/src/api/ai/chat/conversation/index.ts b/src/api/ai/chat/conversation/index.ts index acc21fc6..6ce4482f 100644 --- a/src/api/ai/chat/conversation/index.ts +++ b/src/api/ai/chat/conversation/index.ts @@ -12,6 +12,7 @@ export interface ChatConversationVO { temperature: number // 温度参数 maxTokens: number // 单条回复的最大 Token 数量 maxContexts: number // 上下文的最大 Message 数量 + createTime?: Date // 创建时间 // 额外字段 systemMessage?: string // 角色设定 modelName?: string // 模型名字 diff --git a/src/views/ai/chat/index/components/message/MessageList.vue b/src/views/ai/chat/index/components/message/MessageList.vue index fa6e8ab1..b48fc295 100644 --- a/src/views/ai/chat/index/components/message/MessageList.vue +++ b/src/views/ai/chat/index/components/message/MessageList.vue @@ -1,7 +1,7 @@ diff --git a/src/views/ai/chat/index/components/role/index.vue b/src/views/ai/chat/index/components/role/RoleRepository.vue similarity index 80% rename from src/views/ai/chat/index/components/role/index.vue rename to src/views/ai/chat/index/components/role/RoleRepository.vue index 8a9806cf..42f37494 100644 --- a/src/views/ai/chat/index/components/role/index.vue +++ b/src/views/ai/chat/index/components/role/RoleRepository.vue @@ -2,8 +2,8 @@ - diff --git a/src/views/ai/utils/constants.ts b/src/views/ai/utils/constants.ts index 337cfda3..8ceda73b 100644 --- a/src/views/ai/utils/constants.ts +++ b/src/views/ai/utils/constants.ts @@ -40,3 +40,173 @@ export const AiMusicStatusEnum = { SUCCESS: 20, // 已完成 FAIL: 30 // 已失败 } + +// ========== 【图片 UI】相关的枚举 ========== +export const ImageHotWords = [ + '中国旗袍', + '古装美女', + '卡通头像', + '机甲战士', + '童话小屋', + '中国长城' +] // 图片热词 + +export const ImageHotEnglishWords = [ + 'Chinese Cheongsam', + 'Ancient Beauty', + 'Cartoon Avatar', + 'Mech Warrior', + 'Fairy Tale Cottage', + 'The Great Wall of China' +] // 图片热词(英文) + +export interface ImageModelVO { + key: string + name: string +} + +export const StableDiffusionSamplers = ref([ + { + key: 'DDIM', + name: 'DDIM' + }, + { + key: 'DDPM', + name: 'DDPM' + }, + { + key: 'K_DPMPP_2M', + name: 'K_DPMPP_2M' + }, + { + key: 'K_DPMPP_2S_ANCESTRAL', + name: 'K_DPMPP_2S_ANCESTRAL' + }, + { + key: 'K_DPM_2', + name: 'K_DPM_2' + }, + { + key: 'K_DPM_2_ANCESTRAL', + name: 'K_DPM_2_ANCESTRAL' + }, + { + key: 'K_EULER', + name: 'K_EULER' + }, + { + key: 'K_EULER_ANCESTRAL', + name: 'K_EULER_ANCESTRAL' + }, + { + key: 'K_HEUN', + name: 'K_HEUN' + }, + { + key: 'K_LMS', + name: 'K_LMS' + } +]) + +export const StableDiffusionStylePresets = ref([ + { + key: '3d-model', + name: '3d-model' + }, + { + key: 'analog-film', + name: 'analog-film' + }, + { + key: 'anime', + name: 'anime' + }, + { + key: 'cinematic', + name: 'cinematic' + }, + { + key: 'comic-book', + name: 'comic-book' + }, + { + key: 'digital-art', + name: 'digital-art' + }, + { + key: 'enhance', + name: 'enhance' + }, + { + key: 'fantasy-art', + name: 'fantasy-art' + }, + { + key: 'isometric', + name: 'isometric' + }, + { + key: 'line-art', + name: 'line-art' + }, + { + key: 'low-poly', + name: 'low-poly' + }, + { + key: 'modeling-compound', + name: 'modeling-compound' + }, + // neon-punk origami photographic pixel-art tile-texture + { + key: 'neon-punk', + name: 'neon-punk' + }, + { + key: 'origami', + name: 'origami' + }, + { + key: 'photographic', + name: 'photographic' + }, + { + key: 'pixel-art', + name: 'pixel-art' + }, + { + key: 'tile-texture', + name: 'tile-texture' + } +]) + +export const StableDiffusionClipGuidancePresets = ref([ + { + key: 'NONE', + name: 'NONE' + }, + { + key: 'FAST_BLUE', + name: 'FAST_BLUE' + }, + { + key: 'FAST_GREEN', + name: 'FAST_GREEN' + }, + { + key: 'SIMPLE', + name: 'SIMPLE' + }, + { + key: 'SLOW', + name: 'SLOW' + }, + { + key: 'SLOWER', + name: 'SLOWER' + }, + { + key: 'SLOWEST', + name: 'SLOWEST' + } +]) diff --git a/src/views/ai/utils/utils.ts b/src/views/ai/utils/utils.ts index fc4f8e6c..ab45ae18 100644 --- a/src/views/ai/utils/utils.ts +++ b/src/views/ai/utils/utils.ts @@ -8,6 +8,6 @@ */ /** 判断字符串是否包含中文 */ -export const hasChinese = async (str) => { +export const hasChinese = (str: string) => { return /[\u4e00-\u9fa5]/.test(str) } From 9dfb869a4bb7d57a41292cf34e241f90d2d494de Mon Sep 17 00:00:00 2001 From: puhui999 Date: Tue, 9 Jul 2024 16:14:51 +0800 Subject: [PATCH 083/195] =?UTF-8?q?=E3=80=90=E6=96=B0=E5=A2=9E=E3=80=91mal?= =?UTF-8?q?l=20=E5=AE=A2=E6=9C=8D=E5=95=86=E5=93=81=E6=B6=88=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../promotion/kefu/components/KeFuChatBox.vue | 3 + .../components/message/ProductMessageItem.vue | 101 ++++++++++++++++++ 2 files changed, 104 insertions(+) create mode 100644 src/views/mall/promotion/kefu/components/message/ProductMessageItem.vue diff --git a/src/views/mall/promotion/kefu/components/KeFuChatBox.vue b/src/views/mall/promotion/kefu/components/KeFuChatBox.vue index ff577325..d7b9aeff 100644 --- a/src/views/mall/promotion/kefu/components/KeFuChatBox.vue +++ b/src/views/mall/promotion/kefu/components/KeFuChatBox.vue @@ -55,6 +55,8 @@ + + + + + + + + From ebc995ac4c0269b06cd4c2fb693f2bc8357db749 Mon Sep 17 00:00:00 2001 From: puhui999 Date: Tue, 9 Jul 2024 17:00:58 +0800 Subject: [PATCH 084/195] =?UTF-8?q?=E3=80=90=E4=BC=98=E5=8C=96=E3=80=91mal?= =?UTF-8?q?l=20=E5=AE=A2=E6=9C=8D=E5=95=86=E5=93=81=E6=B6=88=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/message/OrderMessageItem.vue | 36 ++++ .../kefu/components/message/ProductItem.vue | 194 ++++++++++++++++++ .../components/message/ProductMessageItem.vue | 83 +------- 3 files changed, 239 insertions(+), 74 deletions(-) create mode 100644 src/views/mall/promotion/kefu/components/message/OrderMessageItem.vue create mode 100644 src/views/mall/promotion/kefu/components/message/ProductItem.vue diff --git a/src/views/mall/promotion/kefu/components/message/OrderMessageItem.vue b/src/views/mall/promotion/kefu/components/message/OrderMessageItem.vue new file mode 100644 index 00000000..923d366b --- /dev/null +++ b/src/views/mall/promotion/kefu/components/message/OrderMessageItem.vue @@ -0,0 +1,36 @@ + + + diff --git a/src/views/mall/promotion/kefu/components/message/ProductItem.vue b/src/views/mall/promotion/kefu/components/message/ProductItem.vue new file mode 100644 index 00000000..6805f24f --- /dev/null +++ b/src/views/mall/promotion/kefu/components/message/ProductItem.vue @@ -0,0 +1,194 @@ + + + + + diff --git a/src/views/mall/promotion/kefu/components/message/ProductMessageItem.vue b/src/views/mall/promotion/kefu/components/message/ProductMessageItem.vue index 847369f8..923d366b 100644 --- a/src/views/mall/promotion/kefu/components/message/ProductMessageItem.vue +++ b/src/views/mall/promotion/kefu/components/message/ProductMessageItem.vue @@ -10,92 +10,27 @@ : '' ]" > -
- - - - {{ getMessageContent.spuName }} - - - {{ getMessageContent.introduction }} - - ¥{{ getMessageContent.price }} - -
+ - From 2204876076ba3c98f5cd32130c6798619624c04d Mon Sep 17 00:00:00 2001 From: cherishsince Date: Tue, 9 Jul 2024 17:05:07 +0800 Subject: [PATCH 085/195] =?UTF-8?q?=E3=80=90=E8=A7=A3=E5=86=B3todo?= =?UTF-8?q?=E3=80=91=E5=AF=B9=E8=AF=9D=E4=B8=AD=E4=B8=8D=E5=85=81=E8=AE=B8?= =?UTF-8?q?=E5=88=87=E6=8D=A2(=E8=87=AA=E5=8A=A8stop=20stream=20=E5=88=A0?= =?UTF-8?q?=E9=99=A4)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/ai/chat/index/index.vue | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/views/ai/chat/index/index.vue b/src/views/ai/chat/index/index.vue index 6b79f138..37dadaec 100644 --- a/src/views/ai/chat/index/index.vue +++ b/src/views/ai/chat/index/index.vue @@ -180,11 +180,6 @@ const handleConversationClick = async (conversation: ChatConversationVO) => { // 更新选中的对话 id activeConversationId.value = conversation.id activeConversation.value = conversation - // 处理进行中的对话 - // TODO @fan:这里,和上面的 “对话进行中,不允许切换” 是不是重叠了? - if (conversationInProgress.value) { - await stopStream() - } // 刷新 message 列表 await getMessageList() // 滚动底部 From b4b901586959c36c2c1e413d07fda9d596f3c5e9 Mon Sep 17 00:00:00 2001 From: cherishsince Date: Tue, 9 Jul 2024 17:14:38 +0800 Subject: [PATCH 086/195] =?UTF-8?q?=E3=80=90=E8=A7=A3=E5=86=B3todo?= =?UTF-8?q?=E3=80=91=E5=AF=B9=E8=AF=9D=E4=B8=AD=E4=B8=8D=E8=83=BD=E6=B8=85?= =?UTF-8?q?=E6=A5=9A=20chat=20=E6=B6=88=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/ai/chat/index/index.vue | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/views/ai/chat/index/index.vue b/src/views/ai/chat/index/index.vue index 37dadaec..c00617bc 100644 --- a/src/views/ai/chat/index/index.vue +++ b/src/views/ai/chat/index/index.vue @@ -198,7 +198,11 @@ const handlerConversationDelete = async (delConversation: ChatConversationVO) => } /** 清空选中的对话 */ const handleConversationClear = async () => { - // TODO @fan:需要加一个 对话进行中,不允许切换 + // 对话进行中,不允许切换 + if (conversationInProgress.value) { + message.alert('对话中,不允许切换!') + return false + } activeConversationId.value = null activeConversation.value = null activeMessageList.value = [] From cb68ef5fa7073d5fd510208130cacc1af4d2e97a Mon Sep 17 00:00:00 2001 From: cherishsince Date: Tue, 9 Jul 2024 17:17:45 +0800 Subject: [PATCH 087/195] =?UTF-8?q?=E3=80=90=E8=A7=A3=E5=86=B3todo?= =?UTF-8?q?=E3=80=91ai-layout=20100%=E9=AB=98=E5=AE=BD=E9=97=AE=E9=A2=98?= =?UTF-8?q?=EF=BC=8C=E5=8F=AA=E8=83=BD=E9=80=9A=E8=BF=87=20position:=20abs?= =?UTF-8?q?olute=20=E6=9D=A5=E7=89=B9=E6=AE=8A=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/ai/chat/index/index.vue | 1 - 1 file changed, 1 deletion(-) diff --git a/src/views/ai/chat/index/index.vue b/src/views/ai/chat/index/index.vue index c00617bc..9d9e98e1 100644 --- a/src/views/ai/chat/index/index.vue +++ b/src/views/ai/chat/index/index.vue @@ -570,7 +570,6 @@ onMounted(async () => { diff --git a/src/views/mall/promotion/kefu/components/message/ProductItem.vue b/src/views/mall/promotion/kefu/components/message/ProductItem.vue index 6805f24f..482ba6f8 100644 --- a/src/views/mall/promotion/kefu/components/message/ProductItem.vue +++ b/src/views/mall/promotion/kefu/components/message/ProductItem.vue @@ -116,6 +116,7 @@ const imagePrediv = (imgUrl: string) => { .ss-order-card-warp { padding: 20px; + border-radius: 10px; background-color: #e2e2e2; .img-box { diff --git a/src/views/mall/promotion/kefu/components/message/ProductMessageItem.vue b/src/views/mall/promotion/kefu/components/message/ProductMessageItem.vue index 923d366b..daf1b0bc 100644 --- a/src/views/mall/promotion/kefu/components/message/ProductMessageItem.vue +++ b/src/views/mall/promotion/kefu/components/message/ProductMessageItem.vue @@ -28,7 +28,7 @@ import ProductItem from './ProductItem.vue' import { UserTypeEnum } from '@/utils/constants' import { KeFuMessageRespVO } from '@/api/mall/promotion/kefu/message' -defineOptions({ name: 'ImageMessageItem' }) +defineOptions({ name: 'ProductMessageItem' }) const props = defineProps<{ message: KeFuMessageRespVO }>() From 326fc3d03f3a6e55416f03bc774c0647d984a35f Mon Sep 17 00:00:00 2001 From: cherishsince Date: Tue, 9 Jul 2024 17:41:58 +0800 Subject: [PATCH 089/195] =?UTF-8?q?=E3=80=90=E8=A7=A3=E5=86=B3todo?= =?UTF-8?q?=E3=80=91el-button=20icon=20=E6=94=B9=E4=B8=BA=20Icon=20?= =?UTF-8?q?=E4=BD=BF=E7=94=A8=20iconfy=20=E8=B5=84=E6=BA=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/assets/ai/clear.svg | 1 - src/views/ai/chat/index/index.vue | 11 +++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) delete mode 100644 src/assets/ai/clear.svg diff --git a/src/assets/ai/clear.svg b/src/assets/ai/clear.svg deleted file mode 100644 index e75a4e8a..00000000 --- a/src/assets/ai/clear.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/views/ai/chat/index/index.vue b/src/views/ai/chat/index/index.vue index 9d9e98e1..724c67ce 100644 --- a/src/views/ai/chat/index/index.vue +++ b/src/views/ai/chat/index/index.vue @@ -22,11 +22,14 @@ - + + + + + + + - - - From 5734faa5fcddafe28406983b049e904751b83f90 Mon Sep 17 00:00:00 2001 From: cherishsince Date: Tue, 9 Jul 2024 17:42:30 +0800 Subject: [PATCH 090/195] =?UTF-8?q?=E3=80=90todo=E3=80=91keydown.shift.ent?= =?UTF-8?q?er=20=E4=BF=AE=E6=94=B9=E4=B8=BA@=E8=8A=8B=E8=89=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/ai/chat/index/index.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/views/ai/chat/index/index.vue b/src/views/ai/chat/index/index.vue index 724c67ce..229b8959 100644 --- a/src/views/ai/chat/index/index.vue +++ b/src/views/ai/chat/index/index.vue @@ -365,7 +365,7 @@ const handlePromptInput = (event) => { isComposing.value = false }, 400) } -// TODO @fan:是不是可以通过 @keydown.enter、@keydown.shift.enter 来实现,回车发送、shift+回车换行;主要看看,是不是可以简化 isComposing 相关的逻辑 +// TODO @芋艿:是不是可以通过 @keydown.enter、@keydown.shift.enter 来实现,回车发送、shift+回车换行;主要看看,是不是可以简化 isComposing 相关的逻辑 const onCompositionstart = () => { isComposing.value = true } From 4cfc78566742c2892d56347919af00a6e4235871 Mon Sep 17 00:00:00 2001 From: cherishsince Date: Tue, 9 Jul 2024 17:51:08 +0800 Subject: [PATCH 091/195] =?UTF-8?q?=E3=80=90=E8=A7=A3=E5=86=B3todo?= =?UTF-8?q?=E3=80=91=E8=A7=92=E8=89=B2=E5=88=97=E8=A1=A8=20icon=20?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=B8=BA=E4=B8=BA=20Icon=20=E7=BB=84?= =?UTF-8?q?=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/ai/chat/index/components/role/RoleList.vue | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/views/ai/chat/index/components/role/RoleList.vue b/src/views/ai/chat/index/components/role/RoleList.vue index 01b1d179..b148b220 100644 --- a/src/views/ai/chat/index/components/role/RoleList.vue +++ b/src/views/ai/chat/index/components/role/RoleList.vue @@ -10,15 +10,13 @@ - @@ -43,9 +41,9 @@ - From 5730707be9681920a67f06f8ee094751c388b78b Mon Sep 17 00:00:00 2001 From: hhhero Date: Tue, 9 Jul 2024 00:44:27 +0800 Subject: [PATCH 100/195] =?UTF-8?q?[=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96]A?= =?UTF-8?q?I:=20=E5=86=99=E4=BD=9C=E6=B7=BB=E5=8A=A0=E6=B3=A8=E9=87=8A?= =?UTF-8?q?=EF=BC=8C=E5=A2=9E=E5=8A=A0=E5=8F=AF=E8=AF=BB=E6=80=A7=EF=BC=8C?= =?UTF-8?q?=E8=B0=83=E6=95=B4=E4=BB=A3=E7=A0=81=EF=BC=8C=E6=96=B9=E4=BE=BF?= =?UTF-8?q?=E5=90=8E=E7=BB=AD=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/ai/writer/index.ts | 41 +++-------- src/views/ai/utils/constants.ts | 8 +++ src/views/ai/utils/utils.ts | 13 ++++ src/views/ai/writer/components/Left.vue | 92 +++++++++++------------- src/views/ai/writer/components/Right.vue | 29 ++++---- src/views/ai/writer/data.json | 11 --- src/views/ai/writer/index.vue | 67 ----------------- src/views/ai/writer/index/index.vue | 67 +++++++++++++++++ 8 files changed, 154 insertions(+), 174 deletions(-) delete mode 100644 src/views/ai/writer/data.json delete mode 100644 src/views/ai/writer/index.vue create mode 100644 src/views/ai/writer/index/index.vue diff --git a/src/api/ai/writer/index.ts b/src/api/ai/writer/index.ts index 57c23b4f..9402d9a2 100644 --- a/src/api/ai/writer/index.ts +++ b/src/api/ai/writer/index.ts @@ -3,37 +3,14 @@ import { fetchEventSource } from '@microsoft/fetch-event-source' import { getAccessToken } from '@/utils/auth' import { config } from '@/config/axios/config' -// TODO @hhhero:可以改成 WriteVO 哈,主要是保持一致 -export interface WriteParams { - // TODO @hhhero:注释。每个属性的后面哈。会更简洁一点 - /** - * 1:撰写 2:回复 - */ - type: 1 | 2 - /** - * 写作内容提示 1。撰写 2回复 - */ - prompt: string - /** - * 原文 - */ - originalContent: string - /** - * 长度 - */ - length: number - /** - * 格式 - */ - format: number - /** - * 语气 - */ - tone: number - /** - * 语言 - */ - language: number +export interface WriteVO { + type: 1 | 2 // 1:撰写 2:回复 + prompt: string // 写作内容提示 1。撰写 2回复 + originalContent: string // 原文 + length: number // 长度 + format: number // 格式 + tone: number // 语气 + language: number // 语言 } export const writeStream = ({ @@ -43,7 +20,7 @@ export const writeStream = ({ onError, ctrl }: { - data: WriteParams + data: WriteVO onMessage?: (res: any) => void onError?: (...args: any[]) => void onClose?: (...args: any[]) => void diff --git a/src/views/ai/utils/constants.ts b/src/views/ai/utils/constants.ts index 337cfda3..442f83b5 100644 --- a/src/views/ai/utils/constants.ts +++ b/src/views/ai/utils/constants.ts @@ -40,3 +40,11 @@ export const AiMusicStatusEnum = { SUCCESS: 20, // 已完成 FAIL: 30 // 已失败 } + +/** + * AI 写作类型的枚举 + */ +export enum AiWriteTypeEnum { + WRITING = 1, // 撰写 + REPLY // 回复 +} diff --git a/src/views/ai/utils/utils.ts b/src/views/ai/utils/utils.ts index fc4f8e6c..d79e7609 100644 --- a/src/views/ai/utils/utils.ts +++ b/src/views/ai/utils/utils.ts @@ -11,3 +11,16 @@ export const hasChinese = async (str) => { return /[\u4e00-\u9fa5]/.test(str) } + +/** 写作点击示例时的数据 **/ +export const WriteExampleDataJson = { + write: { + prompt: 'vue', + data: 'Vue.js 是一种用于构建用户界面的渐进式 JavaScript 框架。它的核心库只关注视图层,易于上手,同时也便于与其他库或已有项目整合。\n\nVue.js 的特点包括:\n- 响应式的数据绑定:Vue.js 会自动将数据与 DOM 同步,使得状态管理变得更加简单。\n- 组件化:Vue.js 允许开发者通过小型、独立和通常可复用的组件构建大型应用。\n- 虚拟 DOM:Vue.js 使用虚拟 DOM 实现快速渲染,提高了性能。\n\n在 Vue.js 中,一个典型的应用结构可能包括:\n1. 根实例:每个 Vue 应用都需要一个根实例作为入口点。\n2. 组件系统:可以创建自定义的可复用组件。\n3. 指令:特殊的带有前缀 v- 的属性,为 DOM 元素提供特殊的行为。\n4. 插值:用于文本内容,将数据动态地插入到 HTML。\n5. 计算属性和侦听器:用于处理数据的复杂逻辑和响应数据变化。\n6. 条件渲染:根据条件决定元素的渲染。\n7. 列表渲染:用于显示列表数据。\n8. 事件处理:响应用户交互。\n9. 表单输入绑定:处理表单输入和验证。\n10. 组件生命周期钩子:在组件的不同阶段执行特定的函数。\n\nVue.js 还提供了官方的路由器 Vue Router 和状态管理库 Vuex,以支持构建复杂的单页应用(SPA)。\n\n在开发过程中,开发者通常会使用 Vue CLI,这是一个强大的命令行工具,用于快速生成 Vue 项目脚手架,集成了诸如 Babel、Webpack 等现代前端工具,以及热重载、代码检测等开发体验优化功能。\n\nVue.js 的生态系统还包括大量的第三方库和插件,如 Vuetify(UI 组件库)、Vue Test Utils(测试工具)等,这些都极大地丰富了 Vue.js 的开发生态。\n\n总的来说,Vue.js 是一个灵活、高效的前端框架,适合从小型项目到大型企业级应用的开发。它的易用性、灵活性和强大的社区支持使其成为许多开发者的首选框架之一。' + }, + reply: { + originalContent: '领导,我想请假', + prompt: '不批', + data: '您的请假申请已收悉,经核实和考虑,暂时无法批准您的请假申请。\n\n如有特殊情况或紧急事务,请及时与我联系。\n\n祝工作顺利。\n\n谢谢。' + } +} diff --git a/src/views/ai/writer/components/Left.vue b/src/views/ai/writer/components/Left.vue index 0369d9df..e7851649 100644 --- a/src/views/ai/writer/components/Left.vue +++ b/src/views/ai/writer/components/Left.vue @@ -24,7 +24,7 @@ - +
@@ -65,7 +65,7 @@ type="textarea" :rows="5" :maxlength="500" - v-model="writeForm.originalContent" + v-model="formData.originalContent" placeholder="请输入原文" showWordLimit /> @@ -75,20 +75,20 @@ type="textarea" :rows="5" :maxlength="500" - v-model="writeForm.prompt" + v-model="formData.prompt" placeholder="请输入回复内容" showWordLimit /> - + - + - + - +
重置 @@ -103,12 +103,13 @@ import { createReusableTemplate } from '@vueuse/core' import { ref } from 'vue' import Tag from './Tag.vue' -import { WriteParams } from '@/api/ai/writer' +import { WriteVO } from '@/api/ai/writer' import { omit } from 'lodash-es' import { getIntDictOptions } from '@/utils/dict' -import dataJson from '../data.json' +import { WriteExampleDataJson } from '@/views/ai/utils/utils' +import { AiWriteTypeEnum } from "@/views/ai/utils/constants"; -type TabType = WriteParams['type'] +type TabType = WriteVO['type'] const message = useMessage() @@ -117,25 +118,25 @@ defineProps<{ }>() const emits = defineEmits<{ - (e: 'submit', params: Partial) + (e: 'submit', params: Partial) (e: 'example', param: 'write' | 'reply') }>() const example = (type: 'write' | 'reply') => { - writeForm.value = { + formData.value = { ...initData, - ...omit(dataJson[type], ['data']) + ...omit(WriteExampleDataJson[type], ['data']) } emits('example', type) } -const selectedTab = ref(1) +const selectedTab = ref(AiWriteTypeEnum.WRITING) const tabs: { text: string value: TabType }[] = [ - { text: '撰写', value: 1 }, // TODO @hhhero:1、2 这个枚举到 constants 里。方便后续万一要调整 - { text: '回复', value: 2 } + { text: '撰写', value: AiWriteTypeEnum.WRITING }, + { text: '回复', value: AiWriteTypeEnum.REPLY } ] const [DefineTab, ReuseTab] = createReusableTemplate<{ active?: boolean @@ -143,7 +144,21 @@ const [DefineTab, ReuseTab] = createReusableTemplate<{ itemClick: () => void }>() -const initData: WriteParams = { +/** + * 可以在template里边定义可复用的组件,DefineLabel,ReuseLabel是采用的解构赋值,都是Vue组件 + * 直接通过组件的形式使用,中间是需要复用的组件代码,通过来使用定义的组件 + * DefineLabel里边的v-slot="{ label, hint, hintClick }“相当于是解构了组件的prop,需要注意的是boolean类型,需要显式的赋值比如 + * 事件也得以prop形式传入,不能是@event的形式,比如下面的hintClick需要 + * @see https://vueuse.org/createReusableTemplate + */ +const [DefineLabel, ReuseLabel] = createReusableTemplate<{ + label: string + class?: string + hint?: string + hintClick?: () => void +}>() + +const initData: WriteVO = { type: 1, prompt: '', originalContent: '', @@ -152,49 +167,26 @@ const initData: WriteParams = { length: 1, format: 1 } -// TODO @hhhero:这个字段,要不叫 formData,和其他模块保持一致。然后 initData 和它也更好对应上 -const writeForm = ref({ ...initData }) - -// TODO @hhhero:这种一次性的变量,要不直接 vue template 直接调用。目的是:让 ts 这块,更专注逻辑哈。 -const writeTags = { - // 长度 TODO @hhhero:注释放在和面哈; - // TODO @hhhero:一般 length 不用缩写哈。更完整会更容易阅读; - lenTags: getIntDictOptions('ai_write_length'), - // 格式 - - formatTags: getIntDictOptions('ai_write_format'), - // 语气 - - toneTags: getIntDictOptions('ai_write_tone'), - // 语言 - langTags: getIntDictOptions('ai_write_language') - // -} - -// TODO @hhhero:这个写法不错。要不写个简单的注释,我怕很多人不懂哈。 -const [DefineLabel, ReuseLabel] = createReusableTemplate<{ - label: string - class?: string - hint?: string - hintClick?: () => void -}>() - +const formData = ref({ ...initData }) +/** 切换tab **/ const switchTab = (value: TabType) => { selectedTab.value = value - writeForm.value = { ...initData } + formData.value = { ...initData } } const submit = () => { - if (selectedTab.value === 2 && !writeForm.value.originalContent) { + if (selectedTab.value === 2 && !formData.value.originalContent) { message.warning('请输入原文') return } - if (!writeForm.value.prompt) { + if (!formData.value.prompt) { message.warning(`请输入${selectedTab.value === 1 ? '写作' : '回复'}内容`) return } emits('submit', { - ...(selectedTab.value === 1 ? omit(writeForm.value, ['originalContent']) : writeForm.value), + /** 撰写的时候没有 originalContent 字段**/ + ...(selectedTab.value === 1 ? omit(formData.value, ['originalContent']) : formData.value), + /** 使用选中tab值覆盖当前的type类型 **/ type: selectedTab.value }) } diff --git a/src/views/ai/writer/components/Right.vue b/src/views/ai/writer/components/Right.vue index 94140011..4b27ef8c 100644 --- a/src/views/ai/writer/components/Right.vue +++ b/src/views/ai/writer/components/Right.vue @@ -5,9 +5,8 @@ 复制 @@ -23,7 +22,7 @@ props.msg && !props.isWriting) // 是否展示拷贝 -const inputId = computed(() => getCurrentInstance()?.uid) // TODO @hhhero:这个可以写个注释哈 -const copyMsg = () => { - copy(props.msg) +const showCopy = computed(() => props.content && !props.isWriting) // 是否展示复制按钮,在生成内容完成的时候展示 +const copyContent = () => { + copy(props.content) } +// 复制成功的时候copied.value为true watch(copied, (val) => { if (val) { message.success('复制成功') diff --git a/src/views/ai/writer/data.json b/src/views/ai/writer/data.json deleted file mode 100644 index 3f20951b..00000000 --- a/src/views/ai/writer/data.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "write": { - "prompt": "vue", - "data": "Vue.js 是一种用于构建用户界面的渐进式 JavaScript 框架。它的核心库只关注视图层,易于上手,同时也便于与其他库或已有项目整合。\n\nVue.js 的特点包括:\n- 响应式的数据绑定:Vue.js 会自动将数据与 DOM 同步,使得状态管理变得更加简单。\n- 组件化:Vue.js 允许开发者通过小型、独立和通常可复用的组件构建大型应用。\n- 虚拟 DOM:Vue.js 使用虚拟 DOM 实现快速渲染,提高了性能。\n\n在 Vue.js 中,一个典型的应用结构可能包括:\n1. 根实例:每个 Vue 应用都需要一个根实例作为入口点。\n2. 组件系统:可以创建自定义的可复用组件。\n3. 指令:特殊的带有前缀 v- 的属性,为 DOM 元素提供特殊的行为。\n4. 插值:用于文本内容,将数据动态地插入到 HTML。\n5. 计算属性和侦听器:用于处理数据的复杂逻辑和响应数据变化。\n6. 条件渲染:根据条件决定元素的渲染。\n7. 列表渲染:用于显示列表数据。\n8. 事件处理:响应用户交互。\n9. 表单输入绑定:处理表单输入和验证。\n10. 组件生命周期钩子:在组件的不同阶段执行特定的函数。\n\nVue.js 还提供了官方的路由器 Vue Router 和状态管理库 Vuex,以支持构建复杂的单页应用(SPA)。\n\n在开发过程中,开发者通常会使用 Vue CLI,这是一个强大的命令行工具,用于快速生成 Vue 项目脚手架,集成了诸如 Babel、Webpack 等现代前端工具,以及热重载、代码检测等开发体验优化功能。\n\nVue.js 的生态系统还包括大量的第三方库和插件,如 Vuetify(UI 组件库)、Vue Test Utils(测试工具)等,这些都极大地丰富了 Vue.js 的开发生态。\n\n总的来说,Vue.js 是一个灵活、高效的前端框架,适合从小型项目到大型企业级应用的开发。它的易用性、灵活性和强大的社区支持使其成为许多开发者的首选框架之一。" - }, - "reply": { - "originalContent": "领导,我想请假", - "prompt": "不批", - "data": "您的请假申请已收悉,经核实和考虑,暂时无法批准您的请假申请。\n\n如有特殊情况或紧急事务,请及时与我联系。\n\n祝工作顺利。\n\n谢谢。" - } -} diff --git a/src/views/ai/writer/index.vue b/src/views/ai/writer/index.vue deleted file mode 100644 index 27276431..00000000 --- a/src/views/ai/writer/index.vue +++ /dev/null @@ -1,67 +0,0 @@ - - - - diff --git a/src/views/ai/writer/index/index.vue b/src/views/ai/writer/index/index.vue new file mode 100644 index 00000000..655e806a --- /dev/null +++ b/src/views/ai/writer/index/index.vue @@ -0,0 +1,67 @@ + + + From 9e628ba59d186f24d6feab5f19f50c3ef935a041 Mon Sep 17 00:00:00 2001 From: hhhero Date: Wed, 10 Jul 2024 00:11:00 +0800 Subject: [PATCH 101/195] =?UTF-8?q?[=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96]A?= =?UTF-8?q?I:=20=E5=86=99=E4=BD=9C=E6=B7=BB=E5=8A=A0=E9=A2=84=E8=A7=88head?= =?UTF-8?q?er=EF=BC=8C=E8=B0=83=E6=95=B4=E7=94=9F=E6=88=90=E5=86=85?= =?UTF-8?q?=E5=AE=B9=E5=8C=BA=E5=9F=9F=E5=B8=83=E5=B1=80=EF=BC=8C=E5=B0=86?= =?UTF-8?q?=E5=8F=B3=E8=BE=B9=E9=93=BA=E6=BB=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/ai/writer/components/Left.vue | 10 ++- src/views/ai/writer/components/Right.vue | 49 ++++++++--- src/views/ai/writer/index/index.vue | 101 ++++++++++++----------- 3 files changed, 100 insertions(+), 60 deletions(-) diff --git a/src/views/ai/writer/components/Left.vue b/src/views/ai/writer/components/Left.vue index e7851649..b09982b0 100644 --- a/src/views/ai/writer/components/Left.vue +++ b/src/views/ai/writer/components/Left.vue @@ -91,7 +91,7 @@
- 重置 + 重置 生成
@@ -120,8 +120,10 @@ defineProps<{ const emits = defineEmits<{ (e: 'submit', params: Partial) (e: 'example', param: 'write' | 'reply') + (e: 'reset') }>() +/** 点击示例的时候,将定义好的文章作为示例展示出来 **/ const example = (type: 'write' | 'reply') => { formData.value = { ...initData, @@ -129,7 +131,11 @@ const example = (type: 'write' | 'reply') => { } emits('example', type) } - +/** 重置,将表单值作为初选值 **/ +const reset = () => { + formData.value = {...initData} + emits('reset') +} const selectedTab = ref(AiWriteTypeEnum.WRITING) const tabs: { text: string diff --git a/src/views/ai/writer/components/Right.vue b/src/views/ai/writer/components/Right.vue index 4b27ef8c..393a055b 100644 --- a/src/views/ai/writer/components/Right.vue +++ b/src/views/ai/writer/components/Right.vue @@ -1,24 +1,37 @@