diff --git a/changlog.md b/changlog.md index 81b9e39a6..0bd49118c 100644 --- a/changlog.md +++ b/changlog.md @@ -1,5 +1,10 @@ # 功能升级日志 +## 2.12.8 +- 😄 新增:我的画廊 +- 🐞 修复:重试按钮、停止按钮功能 #15 + + ## 2.12.7 - 😄 新增:vercel 增加 AUTH_SECRET_KEY 可以访问输入验证 #15 - 🐞 修复:OPENAI_API_MODEL 默认模型 同时支持 vercel #16 diff --git a/package.json b/package.json index b763307c5..c05dc48dc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "chatgpt-web-midjourney-proxy", - "version": "2.12.7", + "version": "2.12.8", "private": false, "description": "ChatGPT Web Midjourney Proxy", "author": "Dooy ", @@ -41,7 +41,8 @@ "pinia": "^2.0.33", "vue": "^3.2.47", "vue-i18n": "^9.2.2", - "vue-router": "^4.1.6" + "vue-router": "^4.1.6", + "vue-waterfall-plugin-next": "^2.3.1" }, "devDependencies": { "@antfu/eslint-config": "^0.35.3", @@ -58,6 +59,7 @@ "axios": "^1.3.4", "crypto-js": "^4.1.1", "eslint": "^8.35.0", + "http-proxy-middleware": "^2.0.6", "husky": "^8.0.3", "less": "^4.1.3", "lint-staged": "^13.1.2", @@ -69,7 +71,6 @@ "typescript": "~4.9.5", "vite": "^4.2.0", "vite-plugin-pwa": "^0.14.4", - "http-proxy-middleware": "^2.0.6", "vue-tsc": "^1.2.0" }, "lint-staged": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 696d1a310..265535900 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -40,6 +40,9 @@ dependencies: vue-router: specifier: ^4.1.6 version: 4.1.6(vue@3.2.47) + vue-waterfall-plugin-next: + specifier: ^2.3.1 + version: 2.3.1(@types/lodash-es@4.17.6)(vue@3.2.47) devDependencies: '@antfu/eslint-config': @@ -1595,6 +1598,19 @@ packages: vue: 3.2.47 dev: false + /@ctrl/tinycolor@3.6.1: + resolution: {integrity: sha512-SITSV6aIXsuVNV3f3O0f2n/cgyEDWoSqtZMYiAmcsYHydcKrOz3gUxB/iXd/Qf08+IZX4KpgNbvUdMBmWz+kcA==} + engines: {node: '>=10'} + dev: false + + /@element-plus/icons-vue@1.1.4(vue@3.2.47): + resolution: {integrity: sha512-Iz/nHqdp1sFPmdzRwHkEQQA3lKvoObk8azgABZ81QUOpW9s/lUyQVUSh0tNtEPZXQlKwlSh7SPgoVxzrE0uuVQ==} + peerDependencies: + vue: ^3.2.0 + dependencies: + vue: 3.2.47 + dev: false + /@emotion/hash@0.8.0: resolution: {integrity: sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==} dev: false @@ -1977,6 +1993,10 @@ packages: fastq: 1.15.0 dev: true + /@popperjs/core@2.11.8: + resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==} + dev: false + /@rollup/plugin-babel@5.3.1(@babel/core@7.21.0)(rollup@2.79.1): resolution: {integrity: sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==} engines: {node: '>= 10.0.0'} @@ -2192,6 +2212,10 @@ packages: resolution: {integrity: sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==} dev: true + /@types/web-bluetooth@0.0.14: + resolution: {integrity: sha512-5d2RhCard1nQUC3aHcq/gHzWYO6K0WJmAbjO7mQJgCQKtZpgXxv1rOM6O/dBDhDYYVutk1sciOgNSe+5YyfM8A==} + dev: false + /@types/web-bluetooth@0.0.16: resolution: {integrity: sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ==} dev: false @@ -2453,6 +2477,24 @@ packages: /@vue/shared@3.2.47: resolution: {integrity: sha512-BHGyyGN3Q97EZx0taMQ+OLNuZcW3d37ZEVmEAyeoA9ERdGvm9Irc/0Fua8SNyOtV1w6BS4q25wbMzJujO9HIfQ==} + /@vueuse/core@8.9.4(vue@3.2.47): + resolution: {integrity: sha512-B/Mdj9TK1peFyWaPof+Zf/mP9XuGAngaJZBwPaXBvU3aCTZlx3ltlrFFFyMV4iGBwsjSCeUCgZrtkEj9dS2Y3Q==} + peerDependencies: + '@vue/composition-api': ^1.1.0 + vue: ^2.6.0 || ^3.2.0 + peerDependenciesMeta: + '@vue/composition-api': + optional: true + vue: + optional: true + dependencies: + '@types/web-bluetooth': 0.0.14 + '@vueuse/metadata': 8.9.4 + '@vueuse/shared': 8.9.4(vue@3.2.47) + vue: 3.2.47 + vue-demi: 0.13.11(vue@3.2.47) + dev: false + /@vueuse/core@9.13.0(vue@3.2.47): resolution: {integrity: sha512-pujnclbeHWxxPRqXWmdkKV5OX4Wk4YeK7wusHqRwU0Q7EFusHoqNA/aPhB6KCh9hEqJkLAJo7bb0Lh9b+OIVzw==} dependencies: @@ -2465,10 +2507,29 @@ packages: - vue dev: false + /@vueuse/metadata@8.9.4: + resolution: {integrity: sha512-IwSfzH80bnJMzqhaapqJl9JRIiyQU0zsRGEgnxN6jhq7992cPUJIRfV+JHRIZXjYqbwt07E1gTEp0R0zPJ1aqw==} + dev: false + /@vueuse/metadata@9.13.0: resolution: {integrity: sha512-gdU7TKNAUVlXXLbaF+ZCfte8BjRJQWPCa2J55+7/h+yDtzw3vOoGQDRXzI6pyKyo6bXFT5/QoPE4hAknExjRLQ==} dev: false + /@vueuse/shared@8.9.4(vue@3.2.47): + resolution: {integrity: sha512-wt+T30c4K6dGRMVqPddexEVLa28YwxW5OFIPmzUHICjphfAuBFTTdDoyqREZNDOFJZ44ARH1WWQNCUK8koJ+Ag==} + peerDependencies: + '@vue/composition-api': ^1.1.0 + vue: ^2.6.0 || ^3.2.0 + peerDependenciesMeta: + '@vue/composition-api': + optional: true + vue: + optional: true + dependencies: + vue: 3.2.47 + vue-demi: 0.13.11(vue@3.2.47) + dev: false + /@vueuse/shared@9.13.0(vue@3.2.47): resolution: {integrity: sha512-UrnhU+Cnufu4S6JLCPZnkWh0WwZGUp72ktOF2DFptMlOs3TOdVv8xJN53zhHGARmVOsz5KqOls09+J1NR6sBKw==} dependencies: @@ -2531,6 +2592,10 @@ packages: uri-js: 4.4.1 dev: true + /animate.css@4.1.1: + resolution: {integrity: sha512-+mRmCTv6SbCmtYJCN4faJMNFVNN5EuCTTprDTAo7YzIGji2KADmakjVA3+8mVDkZ2Bf09vayB35lSQIex2+QaQ==} + dev: false + /ansi-escapes@4.3.2: resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} engines: {node: '>=8'} @@ -3131,6 +3196,10 @@ packages: engines: {node: '>=0.11'} dev: false + /dayjs@1.11.10: + resolution: {integrity: sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==} + dev: false + /de-indent@1.0.2: resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==} dev: true @@ -3277,6 +3346,29 @@ packages: resolution: {integrity: sha512-h70iRscrNluMZPVICXYl5SSB+rBKo22XfuIS1ER0OQxQZpKTnFpuS6coj7wY9M/3trv7OR88rRMOlKmRvDty7Q==} dev: true + /element-plus@2.1.4(@types/lodash-es@4.17.6)(vue@3.2.47): + resolution: {integrity: sha512-pcwgDbKUrzyWbixYB/zIbLPLBQ/NPGPJnGXJ+jYozUSthPW4SuriaUGJKgbAE6PDBAtw3IodiT2E2GbiaZLxww==} + peerDependencies: + vue: ^3.2.0 + dependencies: + '@ctrl/tinycolor': 3.6.1 + '@element-plus/icons-vue': 1.1.4(vue@3.2.47) + '@popperjs/core': 2.11.8 + '@vueuse/core': 8.9.4(vue@3.2.47) + async-validator: 4.2.5 + dayjs: 1.11.10 + escape-html: 1.0.3 + lodash: 4.17.21 + lodash-es: 4.17.21 + lodash-unified: 1.0.3(@types/lodash-es@4.17.6)(lodash-es@4.17.21)(lodash@4.17.21) + memoize-one: 6.0.0 + normalize-wheel-es: 1.2.0 + vue: 3.2.47 + transitivePeerDependencies: + - '@types/lodash-es' + - '@vue/composition-api' + dev: false + /emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} dev: true @@ -3408,6 +3500,10 @@ packages: engines: {node: '>=6'} dev: true + /escape-html@1.0.3: + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + dev: false + /escape-string-regexp@1.0.5: resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} engines: {node: '>=0.8.0'} @@ -4893,6 +4989,18 @@ packages: resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==} dev: false + /lodash-unified@1.0.3(@types/lodash-es@4.17.6)(lodash-es@4.17.21)(lodash@4.17.21): + resolution: {integrity: sha512-WK9qSozxXOD7ZJQlpSqOT+om2ZfcT4yO+03FuzAHD0wF6S0l0090LRPDx3vhTTLZ8cFKpBn+IOcVXK6qOcIlfQ==} + peerDependencies: + '@types/lodash-es': '*' + lodash: '*' + lodash-es: '*' + dependencies: + '@types/lodash-es': 4.17.6 + lodash: 4.17.21 + lodash-es: 4.17.21 + dev: false + /lodash.camelcase@4.3.0: resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} dev: true @@ -5043,6 +5151,10 @@ packages: resolution: {integrity: sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==} dev: false + /memoize-one@6.0.0: + resolution: {integrity: sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==} + dev: false + /memorystream@0.3.1: resolution: {integrity: sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==} engines: {node: '>= 0.10.0'} @@ -5287,6 +5399,10 @@ packages: engines: {node: '>=0.10.0'} dev: true + /normalize-wheel-es@1.2.0: + resolution: {integrity: sha512-Wj7+EJQ8mSuXr2iWfnujrimU35R2W4FAErEyTmJoJ7ucwTn2hOUSsRehMb5RSYkxXGTM7Y9QpvPmp++w5ftoJw==} + dev: false + /npm-run-all@4.1.5: resolution: {integrity: sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==} engines: {node: '>= 4'} @@ -6765,6 +6881,18 @@ packages: typescript: 4.9.5 dev: true + /vue-waterfall-plugin-next@2.3.1(@types/lodash-es@4.17.6)(vue@3.2.47): + resolution: {integrity: sha512-0Wd7s/IgiUo1cezDr+H9FhcIinE/N+BxIhStD+3azlUnyqFyUOXzLC/a1wMFx6RQiYgY3fSAL+PwnVTyLxrHdw==} + dependencies: + animate.css: 4.1.1 + element-plus: 2.1.4(@types/lodash-es@4.17.6)(vue@3.2.47) + vue-router: 4.1.6(vue@3.2.47) + transitivePeerDependencies: + - '@types/lodash-es' + - '@vue/composition-api' + - vue + dev: false + /vue@3.2.47: resolution: {integrity: sha512-60188y/9Dc9WVrAZeUVSDxRQOZ+z+y5nO2ts9jWXSTkMvayiWxCWOWtBQoYjLeccfXkiiPZWAHcV+WTPhkqJHQ==} dependencies: diff --git a/src/views/chat/components/Message/index.vue b/src/views/chat/components/Message/index.vue index 8342dcad0..ae0052911 100644 --- a/src/views/chat/components/Message/index.vue +++ b/src/views/chat/components/Message/index.vue @@ -9,7 +9,7 @@ import { t } from '@/locales' import { useBasicLayout } from '@/hooks/useBasicLayout' import { copyToClip } from '@/utils/copy' import { homeStore } from '@/store' -import { getSeed } from '@/api' +import { getSeed, mlog } from '@/api' interface Props { dateTime?: string @@ -18,6 +18,7 @@ interface Props { error?: boolean loading?: boolean chat:Chat.Chat + index:number } interface Emit { @@ -84,6 +85,7 @@ function handleRegenerate() { emit('regenerate') } + async function handleCopy(txt?:string) { try { await copyToClip( txt|| props.text || '') @@ -125,7 +127,13 @@ const sendReload = () => { // if(seed>0 ) await handleCopy(`${seed}`); // } - +function handleRegenerate2() { + messageRef.value?.scrollIntoView() + //emit('regenerate') + mlog('重新发送!'); + homeStore.setMyData({act:'gpt.resubmit', actData:{ index:props.index , uuid:props.chat.uuid } }); +} + diff --git a/src/views/mj/aiGallery.vue b/src/views/mj/aiGallery.vue new file mode 100644 index 000000000..bbd4f3dae --- /dev/null +++ b/src/views/mj/aiGallery.vue @@ -0,0 +1,33 @@ + + + \ No newline at end of file diff --git a/src/views/mj/aiGalleryItem.vue b/src/views/mj/aiGalleryItem.vue new file mode 100644 index 000000000..222d5d110 --- /dev/null +++ b/src/views/mj/aiGalleryItem.vue @@ -0,0 +1,162 @@ + + + + \ No newline at end of file diff --git a/src/views/mj/aiGpt.vue b/src/views/mj/aiGpt.vue index 1852f30f6..309f15423 100644 --- a/src/views/mj/aiGpt.vue +++ b/src/views/mj/aiGpt.vue @@ -4,19 +4,21 @@ import { useRoute } from 'vue-router' import { useChat } from '../chat/hooks/useChat' import { gptConfigStore, homeStore, useChatStore } from '@/store' import { getInitChat, mlog, subModel,getSystemMessage , localSaveAny, canVisionModel } from '@/api' +import { isNumber } from '@/utils/is' const emit = defineEmits(['finished']); const { addChat , updateChatSome } = useChat() const chatStore = useChatStore() -const st=ref({uuid:'1002'}); +const st=ref({uuid:'1002', index:-1 }); const controller = ref( );;// new AbortController(); const dataSources = computed(() => chatStore.getChatByUuid(+st.value.uuid)) const textRz= ref([]); -const goFinish= ()=>{ +const goFinish= ( )=>{ + //let dindex = st.value.index>=0? st.value.index : dataSources.value.length - 1; //return ; - updateChatSome( +st.value.uuid, dataSources.value.length - 1, { dateTime: new Date().toLocaleString(),loading: false }) + updateChatSome( +st.value.uuid, st.value.index , { dateTime: new Date().toLocaleString(),loading: false }) //scrollToBottom(); emit('finished'); @@ -28,10 +30,12 @@ const goFinish= ()=>{ // }, 200 ); } -const getMessage= ()=>{ +const getMessage= (start=1000)=>{ let i=0; let rz = []; - for( let ii=dataSources.value.length-3 ; ii>=0 ; ii-- ){ //let o of dataSources.value + let istart = (isNumber( start)&& start>=0 )? Math.min(start , dataSources.value.length - 3): dataSources.value.length - 3; + mlog('istart',istart, start); + for( let ii= istart ; ii>=0 ; ii-- ){ //let o of dataSources.value if(i>=gptConfigStore.myData.talkCount) break; i++; @@ -47,7 +51,7 @@ const getMessage= ()=>{ watch( ()=>textRz.value, (n)=>{ //mlog('🐞 textRz',n); if(n.length==0) return ; - updateChatSome( +st.value.uuid, dataSources.value.length - 1, { dateTime: new Date().toLocaleString(),text: n.join('') }) + updateChatSome( +st.value.uuid, st.value.index , { dateTime: new Date().toLocaleString(),text: n.join('') }) //scrollToBottom(); homeStore.setMyData({act:'scrollToBottomIfAtBottom'}) //homeStore.setMyData({act:'scrollToBottom'}) @@ -95,7 +99,7 @@ watch(()=>homeStore.myData.act, async (n)=>{ outMsg.logo= gptConfigStore.myData.gpts.logo ; } addChat( +uuid2, outMsg ) - + st.value.index= dataSources.value.length - 1; if(textRz.value.length>=0) textRz.value = [ ]; homeStore.setMyData({act:'scrollToBottom'}) @@ -145,6 +149,41 @@ watch(()=>homeStore.myData.act, async (n)=>{ }else if(n=='abort'){ controller.value && controller.value.abort(); + }else if(n=='gpt.resubmit'){ + const dd:any = homeStore.myData.actData; + let uuid2 = dd.uuid?? uuid; + st.value.uuid = uuid2 ; + st.value.index = +dd.index + mlog('gpt.resubmit', dd ) ; + let historyMesg= getMessage( (+dd.index)-1 ); // + mlog('gpt.resubmit historyMesg', historyMesg ); + let nobj = dataSources.value[ dd.index ]; + //mlog('gpt.resubmit model', nobj.model ); + let model = nobj.model + //return ; + + controller.value = new AbortController(); + let message= [ { "role": "system", "content": getSystemMessage() }, + ...historyMesg ]; + textRz.value=[]; + + subModel( {message,model + ,onMessage:(d)=>{ + mlog('🐞消息2',d); + textRz.value.push(d.text); + } + ,onError:(e:any)=>{ + mlog('onError',e) + const emsg = (JSON.stringify( e.reason? JSON.parse( e.reason ):e,null,2)); + if(e.message!='canceled' && emsg.indexOf('aborted')==-1 ) textRz.value.push("\n错误:\n```\n"+emsg+"\n```\n"); + goFinish(); + } + ,signal:controller.value.signal, + }).then(()=>goFinish() ).catch(e=>{ + if(e.message!='canceled') textRz.value.push("\n错误:\n```\n"+(e.reason??JSON.stringify(e,null,2)) +"\n```\n") + goFinish(); + }); + } }) diff --git a/src/views/mj/aiSider.vue b/src/views/mj/aiSider.vue index 13da07b10..a264c09ef 100644 --- a/src/views/mj/aiSider.vue +++ b/src/views/mj/aiSider.vue @@ -38,8 +38,20 @@ const goHome =computed( () => { AI Chat + + + + + ChatGPT Store + +