refactor: migrate from Vue CLI to Vite, update WebSocket handling, and clean up configuration

- Replaced vue.config.js with vite.config.js for Vite setup.
- Updated WebSocket implementation in webSocket.js for improved readability and performance.
- Removed unnecessary comments and cleaned up code formatting.
- Configured Vite plugins for auto-imports, SVG icons, and component resolution.
- Set up proxy configurations for API endpoints in Vite.
This commit is contained in:
bighuixiang
2025-06-18 14:31:35 +08:00
parent 9191678708
commit 3a52cc1e53
19 changed files with 20706 additions and 26139 deletions

4
.env
View File

@@ -1,4 +1,4 @@
# NODE_ENV = 'production' # NODE_ENV = 'production'
NODE_ENV = 'development' NODE_ENV = 'development'
# VUE_APP_BASE_URL = 'http://18.167.251.121:10086' # VITE_APP_BASE_URL = 'http://18.167.251.121:10086'
VUE_APP_BASE_URL = 'https://www.api.aida.com.hk' VITE_APP_BASE_URL = 'https://www.api.aida.com.hk'

View File

@@ -1,11 +1,11 @@
NODE_ENV = 'development' NODE_ENV = 'development'
# VUE_APP_BASE_URL = 'https://develop.api.aida.com.hk' # VITE_APP_BASE_URL = 'https://develop.api.aida.com.hk'
# VUE_APP_BASE_URL = 'https://api.aida.com.hk' # VITE_APP_BASE_URL = 'https://api.aida.com.hk'
# VUE_APP_BASE_URL = 'http://18.167.251.121:10086' # VITE_APP_BASE_URL = 'http://18.167.251.121:10086'
VUE_APP_BASE_URL = 'https://develop.api.aida.com.hk' VITE_APP_BASE_URL = 'https://develop.api.aida.com.hk'
# VUE_APP_BASE_URL = 'https://www.api.aida.com.hk' # VITE_APP_BASE_URL = 'https://www.api.aida.com.hk'
# 徐佩 # 徐佩
# VUE_APP_BASE_URL = 'http://192.168.31.118:5567' # VITE_APP_BASE_URL = 'http://192.168.31.118:5567'
# 海波 # 海波
# VUE_APP_BASE_URL = 'http://192.168.31.34:5567' # VITE_APP_BASE_URL = 'http://192.168.31.34:5567'

View File

@@ -1,7 +1,7 @@
NODE_ENV = 'production' NODE_ENV = 'production'
# VUE_APP_BASE_URL = 'https://aida.com.hk/test' # VITE_APP_BASE_URL = 'https://aida.com.hk/test'
# VUE_APP_BASE_URL = 'http://18.167.251.121:10088' # VITE_APP_BASE_URL = 'http://18.167.251.121:10088'
# VUE_APP_BASE_URL = 'https://api.aida.com.hk' # VITE_APP_BASE_URL = 'https://api.aida.com.hk'
VUE_APP_BASE_URL = 'https://develop.api.aida.com.hk' VITE_APP_BASE_URL = 'https://develop.api.aida.com.hk'

View File

@@ -1,4 +1,4 @@
NODE_ENV = 'production' NODE_ENV = 'production'
# VUE_APP_BASE_URL = 'http://18.167.251.121:10086' # VITE_APP_BASE_URL = 'http://18.167.251.121:10086'
# VUE_APP_BASE_URL = 'https://polyu.api.aida.com.hk' # VITE_APP_BASE_URL = 'https://polyu.api.aida.com.hk'
VUE_APP_BASE_URL = 'https://www.api.aida.com.hk' VITE_APP_BASE_URL = 'https://www.api.aida.com.hk'

View File

@@ -1,7 +1,7 @@
NODE_ENV = 'development' NODE_ENV = 'development'
VUE_APP_BASE_URL = 'https://test.api.aida.com.hk' VITE_APP_BASE_URL = 'https://test.api.aida.com.hk'
# VUE_APP_BASE_URL = 'https://api.aida.com.hk' # VITE_APP_BASE_URL = 'https://api.aida.com.hk'
# VUE_APP_BASE_URL = 'http://18.167.251.121:10086' # VITE_APP_BASE_URL = 'http://18.167.251.121:10086'
# VUE_APP_BASE_URL = 'http://192.168.1.9:5567' # VITE_APP_BASE_URL = 'http://192.168.1.9:5567'
# VUE_APP_BASE_URL = 'http://192.168.1.6:7766' # VITE_APP_BASE_URL = 'http://192.168.1.6:7766'

View File

@@ -1,7 +1,7 @@
NODE_ENV = 'production' NODE_ENV = 'production'
# VUE_APP_BASE_URL = 'https://aida.com.hk/test' # VITE_APP_BASE_URL = 'https://aida.com.hk/test'
# VUE_APP_BASE_URL = 'http://18.167.251.121:10088' # VITE_APP_BASE_URL = 'http://18.167.251.121:10088'
# VUE_APP_BASE_URL = 'https://api.aida.com.hk' # VITE_APP_BASE_URL = 'https://api.aida.com.hk'
# VUE_APP_BASE_URL = 'https://test.api.aida.com.hk' # VITE_APP_BASE_URL = 'https://test.api.aida.com.hk'
VUE_APP_BASE_URL = 'https://develop.api.aida.com.hk' VITE_APP_BASE_URL = 'https://develop.api.aida.com.hk'

14
components.d.ts vendored Normal file
View File

@@ -0,0 +1,14 @@
/* eslint-disable */
// @ts-nocheck
// Generated by unplugin-vue-components
// Read more: https://github.com/vuejs/core/pull/3399
// biome-ignore lint: disable
export {}
/* prettier-ignore */
declare module 'vue' {
export interface GlobalComponents {
RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView']
}
}

22674
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -3,13 +3,15 @@
"version": "0.1.0", "version": "0.1.0",
"private": true, "private": true,
"scripts": { "scripts": {
"serve": "vue-cli-service serve", "dev": "vite",
"build": "vue-cli-service build", "serve": "vite",
"serve:test": "vue-cli-service serve --mode test", "build": "vite build",
"build:test": "vue-cli-service build --mode test_build", "preview": "vite preview",
"serve:dev": "vue-cli-service serve --mode dev", "serve:test": "vite --mode test",
"build:dev": "vue-cli-service build --mode dev_build", "build:test": "vite build --mode test_build",
"lint": "vue-cli-service lint" "serve:dev": "vite --mode dev",
"build:dev": "vite build --mode dev_build",
"lint": "eslint src --ext .js,.ts,.vue --fix"
}, },
"dependencies": { "dependencies": {
"@ans1998/vue3-color": "^3.0.7", "@ans1998/vue3-color": "^3.0.7",
@@ -20,8 +22,8 @@
"core-js": "^3.8.3", "core-js": "^3.8.3",
"driver.js": "^1.3.1", "driver.js": "^1.3.1",
"echarts": "^5.5.1", "echarts": "^5.5.1",
"fabric-with-all": "^5.3.1",
"element-plus": "^2.4.2", "element-plus": "^2.4.2",
"fabric-with-all": "^5.3.1",
"file-saver": "^2.0.5", "file-saver": "^2.0.5",
"fingerprintjs2": "^2.1.4", "fingerprintjs2": "^2.1.4",
"gsap": "^3.12.5", "gsap": "^3.12.5",
@@ -45,6 +47,7 @@
"@types/three": "^0.174.0", "@types/three": "^0.174.0",
"@typescript-eslint/eslint-plugin": "^5.4.0", "@typescript-eslint/eslint-plugin": "^5.4.0",
"@typescript-eslint/parser": "^5.4.0", "@typescript-eslint/parser": "^5.4.0",
"@vitejs/plugin-vue": "^5.2.4",
"@vue/cli-plugin-babel": "~5.0.0", "@vue/cli-plugin-babel": "~5.0.0",
"@vue/cli-plugin-eslint": "~5.0.0", "@vue/cli-plugin-eslint": "~5.0.0",
"@vue/cli-plugin-router": "~5.0.0", "@vue/cli-plugin-router": "~5.0.0",
@@ -59,7 +62,11 @@
"less-loader": "^11.0.0", "less-loader": "^11.0.0",
"style-resources-loader": "^1.5.0", "style-resources-loader": "^1.5.0",
"typescript": "~4.5.5", "typescript": "~4.5.5",
"unplugin-auto-import": "^19.3.0",
"unplugin-element-plus": "^0.8.0", "unplugin-element-plus": "^0.8.0",
"unplugin-vue-components": "^28.7.0",
"vite": "^6.3.5",
"vite-plugin-svg-icons": "^2.0.1",
"vue-cli-plugin-style-resources-loader": "^0.1.5", "vue-cli-plugin-style-resources-loader": "^0.1.5",
"vue-lazyload": "^3.0.0-rc.2" "vue-lazyload": "^3.0.0-rc.2"
}, },

View File

@@ -1,11 +1,12 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang=""> <html lang="">
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<!-- <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> --> <!-- <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> -->
<meta name="viewport" content="width=device-width,initial-scale=1.0"> <meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico"> <link rel="icon" href="/favicon.ico">
<title>AiDA</title> <title>AiDA</title>
<!-- <link href="https://fonts.font.im/css?family=Roboto:400,500,700,700i" rel="stylesheet"> <!-- <link href="https://fonts.font.im/css?family=Roboto:400,500,700,700i" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700;900&display=swap" rel="stylesheet"> --> <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700;900&display=swap" rel="stylesheet"> -->
@@ -14,14 +15,17 @@
<link rel="stylesheet" href="/css/roboto.css"> <link rel="stylesheet" href="/css/roboto.css">
<link rel="stylesheet" href="/css/sloganFamily.css"> <link rel="stylesheet" href="/css/sloganFamily.css">
</head> </head>
<body> <body>
<!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/color-thief/2.3.0/color-thief.umd.js"></script> --> <!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/color-thief/2.3.0/color-thief.umd.js"></script> -->
<script src="/js/color-thief.js"></script> <script src="/js/color-thief.js"></script>
<script src="/js/aligning_guidelines.js"></script> <script src="/js/aligning_guidelines.js"></script>
<noscript> <noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong> <strong>We're sorry but AiDA doesn't work properly without JavaScript enabled. Please enable it to
continue.</strong>
</noscript> </noscript>
<div id="app"></div> <div id="app"></div>
<!-- built files will be auto injected --> <script type="module" src="/src/main.ts"></script>
</body> </body>
</html> </html>

89
src/auto-imports.d.ts vendored Normal file
View File

@@ -0,0 +1,89 @@
/* eslint-disable */
/* prettier-ignore */
// @ts-nocheck
// noinspection JSUnusedGlobalSymbols
// Generated by unplugin-auto-import
// biome-ignore lint: disable
export {}
declare global {
const EffectScope: typeof import('vue')['EffectScope']
const cloneDeep: typeof import('lodash-es')['cloneDeep']
const cloneDeepWith: typeof import('lodash-es')['cloneDeepWith']
const computed: typeof import('vue')['computed']
const createApp: typeof import('vue')['createApp']
const customRef: typeof import('vue')['customRef']
const debounce: typeof import('lodash-es')['debounce']
const defineAsyncComponent: typeof import('vue')['defineAsyncComponent']
const defineComponent: typeof import('vue')['defineComponent']
const effectScope: typeof import('vue')['effectScope']
const getCurrentInstance: typeof import('vue')['getCurrentInstance']
const getCurrentScope: typeof import('vue')['getCurrentScope']
const h: typeof import('vue')['h']
const inject: typeof import('vue')['inject']
const isArray: typeof import('lodash-es')['isArray']
const isBoolean: typeof import('lodash-es')['isBoolean']
const isDate: typeof import('lodash-es')['isDate']
const isFunction: typeof import('lodash-es')['isFunction']
const isNaN: typeof import('lodash-es')['isNaN']
const isNull: typeof import('lodash-es')['isNull']
const isNumber: typeof import('lodash-es')['isNumber']
const isObject: typeof import('lodash-es')['isObject']
const isProxy: typeof import('vue')['isProxy']
const isReactive: typeof import('vue')['isReactive']
const isReadonly: typeof import('vue')['isReadonly']
const isRef: typeof import('vue')['isRef']
const isString: typeof import('lodash-es')['isString']
const isUndefined: typeof import('lodash-es')['isUndefined']
const markRaw: typeof import('vue')['markRaw']
const nextTick: typeof import('vue')['nextTick']
const onActivated: typeof import('vue')['onActivated']
const onBeforeMount: typeof import('vue')['onBeforeMount']
const onBeforeRouteLeave: typeof import('vue-router')['onBeforeRouteLeave']
const onBeforeRouteUpdate: typeof import('vue-router')['onBeforeRouteUpdate']
const onBeforeUnmount: typeof import('vue')['onBeforeUnmount']
const onBeforeUpdate: typeof import('vue')['onBeforeUpdate']
const onDeactivated: typeof import('vue')['onDeactivated']
const onErrorCaptured: typeof import('vue')['onErrorCaptured']
const onMounted: typeof import('vue')['onMounted']
const onRenderTracked: typeof import('vue')['onRenderTracked']
const onRenderTriggered: typeof import('vue')['onRenderTriggered']
const onScopeDispose: typeof import('vue')['onScopeDispose']
const onServerPrefetch: typeof import('vue')['onServerPrefetch']
const onUnmounted: typeof import('vue')['onUnmounted']
const onUpdated: typeof import('vue')['onUpdated']
const onWatcherCleanup: typeof import('vue')['onWatcherCleanup']
const provide: typeof import('vue')['provide']
const reactive: typeof import('vue')['reactive']
const readonly: typeof import('vue')['readonly']
const ref: typeof import('vue')['ref']
const resolveComponent: typeof import('vue')['resolveComponent']
const shallowReactive: typeof import('vue')['shallowReactive']
const shallowReadonly: typeof import('vue')['shallowReadonly']
const shallowRef: typeof import('vue')['shallowRef']
const toRaw: typeof import('vue')['toRaw']
const toRef: typeof import('vue')['toRef']
const toRefs: typeof import('vue')['toRefs']
const toValue: typeof import('vue')['toValue']
const triggerRef: typeof import('vue')['triggerRef']
const unref: typeof import('vue')['unref']
const useAttrs: typeof import('vue')['useAttrs']
const useCssModule: typeof import('vue')['useCssModule']
const useCssVars: typeof import('vue')['useCssVars']
const useId: typeof import('vue')['useId']
const useLink: typeof import('vue-router')['useLink']
const useModel: typeof import('vue')['useModel']
const useRoute: typeof import('vue-router')['useRoute']
const useRouter: typeof import('vue-router')['useRouter']
const useSlots: typeof import('vue')['useSlots']
const useTemplateRef: typeof import('vue')['useTemplateRef']
const watch: typeof import('vue')['watch']
const watchEffect: typeof import('vue')['watchEffect']
const watchPostEffect: typeof import('vue')['watchPostEffect']
const watchSyncEffect: typeof import('vue')['watchSyncEffect']
}
// for type re-export
declare global {
// @ts-ignore
export type { Component, Slot, Slots, ComponentPublicInstance, ComputedRef, DirectiveBinding, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, MaybeRef, MaybeRefOrGetter, VNode, WritableComputedRef } from 'vue'
import('vue')
}

View File

@@ -306,7 +306,7 @@ export class BatchInitializeRedGreenModeCommand extends Command {
*/ */
async _setupBackgroundLayer(backgroundLayer, clothingImage) { async _setupBackgroundLayer(backgroundLayer, clothingImage) {
let backgroundObject = backgroundLayer.fabricObject; let backgroundObject = backgroundLayer.fabricObject;
const { object } = findObjectById(this.canvas, backgroundObject.id); let { object } = findObjectById(this.canvas, backgroundObject.id);
if (!object) { if (!object) {
// 创建白色背景矩形 // 创建白色背景矩形

View File

@@ -1,311 +1,488 @@
<template> <template>
<div class="chat" :class="{ active: !openChat }" @click.stop=""> <div class="chat" :class="{ active: !openChat }" @click.stop="">
<div class="top" :class="{active:!isChattingRecords}" @click="()=>{isChattingRecords=!isChattingRecords}"> <div
class="top"
:class="{ active: !isChattingRecords }"
@click="
() => {
isChattingRecords = !isChattingRecords;
}
"
>
<i class="fi fi-br-angle-small-down"></i> <i class="fi fi-br-angle-small-down"></i>
</div> </div>
<div v-show="!openChat" class="left" @click="()=>{openChat = !openChat;isChattingRecords=true}"> <div
v-show="!openChat"
class="left"
@click="
() => {
openChat = !openChat;
isChattingRecords = true;
}
"
>
<i class="fi fi-br-angle-small-down"></i> <i class="fi fi-br-angle-small-down"></i>
</div> </div>
<div class="chatBox"> <div class="chatBox">
<div class="chattingRecords" v-show="chatList.length > 0 && isChattingRecords"> <div
class="chattingRecords"
v-show="chatList.length > 0 && isChattingRecords"
>
<div class="itemBox" ref="chatBox"> <div class="itemBox" ref="chatBox">
<div class="item" v-for="item in chatList" :class="{user:item.role == 'user'}"> <div
class="item"
v-for="item in chatList"
:class="{ user: item.role == 'user' }"
>
<div class="textBox"> <div class="textBox">
<div class="icon"> <div class="icon">
<img src="@/assets/images/icon/favicon.png" alt=""> <img src="@/assets/images/icon/favicon.png" alt="" />
</div> </div>
<div class="text" v-show="item.content.think || item.content.message || item.content.img || item.content.color"> <div
class="text"
v-show="
item.content.think ||
item.content.message ||
item.content.img ||
item.content.color
"
>
<span class="content"> <span class="content">
<div class="showThink" :class="{active:item.content?.isThink}" v-show="item.content.think" @click="()=>item.content?.isThink?(item.content.isThink = false):(item.content.isThink = true)"> <div
class="showThink"
:class="{ active: item.content?.isThink }"
v-show="item.content.think"
@click="
() =>
item.content?.isThink
? (item.content.isThink = false)
: (item.content.isThink = true)
"
>
<div>已深度思考</div> <div>已深度思考</div>
<i class="fi fi-br-angle-small-down"></i> <i class="fi fi-br-angle-small-down"></i>
</div> </div>
<div class="think" v-show="item.content?.isThink">{{item.content.think}}</div> <div class="think" v-show="item.content?.isThink">
{{ item.content.think }}
</div>
<div class="txt">{{ item.content.message }}</div> <div class="txt">{{ item.content.message }}</div>
</span> </span>
<div class="fileBox"> <div class="fileBox">
<div v-if="item?.fileList?.length > 0" class="item" v-for="fileItem in item.fileList"> <div
v-if="item?.fileList?.length > 0"
class="item"
v-for="fileItem in item.fileList"
>
<div>{{ fileItem.name }}</div> <div>{{ fileItem.name }}</div>
</div> </div>
</div> </div>
<div class="imgBox"> <div class="imgBox">
<img v-if="item.content?.img?.length > 0" v-for="imgItem in item.content?.img" :src="imgItem.minioUrl" alt=""> <img
v-if="item.content?.img?.length > 0"
v-for="imgItem in item.content?.img"
:src="imgItem.minioUrl"
alt=""
/>
</div> </div>
<div class="colorBox"> <div class="colorBox">
<div v-if="item.content?.color?.length > 0" class="item" v-for="colorItem in item.content?.color"> <div
<div class="color" :style="{'background-color':`rgba(${colorItem.rgb.replace(/\s+/g, ',')})`}"></div> v-if="item.content?.color?.length > 0"
<div class="text">{{ colorItem.rgb.replace(/\s+/g, ',') }}</div> class="item"
v-for="colorItem in item.content?.color"
>
<div
class="color"
:style="{
'background-color': `rgba(${colorItem.rgb.replace(
/\s+/g,
','
)})`,
}"
></div>
<div class="text">
{{ colorItem.rgb.replace(/\s+/g, ",") }}
</div> </div>
</div> </div>
</div> </div>
<i class="fi fi-br-loading" v-if="!item.content.think && !item.content.message && !item.content.img && !item.content.color"></i> </div>
<i
class="fi fi-br-loading"
v-if="
!item.content.think &&
!item.content.message &&
!item.content.img &&
!item.content.color
"
></i>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div class="content" @click="openChattingRecords"> <div class="content" @click="openChattingRecords">
<textarea ref="textarea" @input="inputText($event)" @keydown.enter.prevent="sendChat" placeholder="Write your message"></textarea> <textarea
ref="textarea"
@input="inputText($event)"
@keydown.enter.prevent="sendChat"
placeholder="Write your message"
></textarea>
<div class="btn"> <div class="btn">
<div class="uploadBox"> <div class="uploadBox">
<div class="filList"> <div class="filList">
<div class="item" v-for="item,index in filList"> <div class="item" v-for="(item, index) in filList">
<div>{{ item.name }}</div> <div>{{ item.name }}</div>
<span class="icon iconfont icon-shanchu" @click="deleteFile(item,index)"></span> <span
class="icon iconfont icon-shanchu"
@click="deleteFile(item, index)"
></span>
</div> </div>
</div> </div>
<i class="fi fi-rs-paperclip-vertical"> <i class="fi fi-rs-paperclip-vertical">
<input type="file" @change="handleFileUpload($event)"> <input type="file" @change="handleFileUpload($event)" />
</i> </i>
<div class="enableThinking" :class="{active:enableThinking}" @click="()=>enableThinking = !enableThinking">Deep Thinking</div> <div
class="enableThinking"
:class="{ active: enableThinking }"
@click="() => (enableThinking = !enableThinking)"
>
Deep Thinking
</div>
</div> </div>
<div class="sendBox"> <div class="sendBox">
<div class="maxNum">{{ chatContent?.length }}/10000</div> <div class="maxNum">{{ chatContent?.length }}/10000</div>
<div class="send" :class="{active:chatContent?.length>0}" @click="sendChat"> <div
class="send"
:class="{ active: chatContent?.length > 0 }"
@click="sendChat"
>
<i class="fi fi-ss-paper-plane-top"></i> <i class="fi fi-ss-paper-plane-top"></i>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div v-show="openChat" class="right" @click="()=>{openChat = !openChat;isChattingRecords=false}"> <div
v-show="openChat"
class="right"
@click="
() => {
openChat = !openChat;
isChattingRecords = false;
}
"
>
<i class="fi fi-br-angle-small-down"></i> <i class="fi fi-br-angle-small-down"></i>
</div> </div>
</div> </div>
</template> </template>
<script lang="ts"> <script lang="ts">
import { defineComponent,computed,ref,inject,nextTick,createVNode,toRefs, reactive, watch} from 'vue' import {
import { ExclamationCircleOutlined } from '@ant-design/icons-vue'; defineComponent,
computed,
ref,
inject,
nextTick,
createVNode,
toRefs,
reactive,
watch,
} from "vue";
import { ExclamationCircleOutlined } from "@ant-design/icons-vue";
import { Https } from "@/tool/https"; import { Https } from "@/tool/https";
import { useStore } from "vuex"; import { useStore } from "vuex";
import { Modal,message,Upload,CascaderProps } from 'ant-design-vue'; import { Modal, message, Upload, CascaderProps } from "ant-design-vue";
import { useI18n } from 'vue-i18n' import { useI18n } from "vue-i18n";
import { setCookie, getCookie, WriteCookie } from "@/tool/cookie"; import { setCookie, getCookie, WriteCookie } from "@/tool/cookie";
import { useRouter,useRoute } from 'vue-router' import { useRouter, useRoute } from "vue-router";
export default defineComponent({ export default defineComponent({
components:{ components: {},
}, props: {},
props:{ emits: ["chatChange"],
},
emits:['chatChange'],
setup(props, { emit }) { setup(props, { emit }) {
const store = useStore(); const store = useStore();
const route = useRoute() const route = useRoute();
const data = reactive({ const data = reactive({
chatContent:'', chatContent: "",
openChat: true, openChat: true,
chatList:[ chatList: [] as any,
] as any,
isChattingRecords: false, isChattingRecords: false,
selectObject: computed(() => store.state.Workspace.probjects) as any, //选择的项目 selectObject: computed(() => store.state.Workspace.probjects) as any, //选择的项目
filList: [] as any, filList: [] as any,
setIsShowMark:inject('setIsShowMark') as any, setIsShowMark: inject("setIsShowMark") as any,
isFinish: true, isFinish: true,
enableThinking: false, //深度思考 enableThinking: false, //深度思考
}) });
const dataDom = reactive({ const dataDom = reactive({
textarea: null as any, textarea: null as any,
chatBox: null as any, chatBox: null as any,
}) });
watch(()=>data.selectObject.id,(newValue,oldValue)=>{ watch(
if(newValue && (data.selectObject.httpType == 'SERIES_DESIGN' || data.selectObject.httpType == 'SINGLE_DESIGN')){ () => data.selectObject.id,
data.chatList = [] (newValue, oldValue) => {
if(route.query?.create)return if (
newValue &&
(data.selectObject.httpType == "SERIES_DESIGN" ||
data.selectObject.httpType == "SINGLE_DESIGN")
) {
data.chatList = [];
if (route.query?.create) return;
nextTick(() => { nextTick(() => {
getChatHistory(newValue) getChatHistory(newValue);
}) });
} }
}) }
);
const inputText = (e: any) => { const inputText = (e: any) => {
if (e.target.value.length <= 1000) { if (e.target.value.length <= 1000) {
data.chatContent = e.target.value data.chatContent = e.target.value;
} else { } else {
e.target.value = data.chatContent e.target.value = data.chatContent;
} }
e.target.style.height = `${e.target.scrollHeight}px`; e.target.style.height = `${e.target.scrollHeight}px`;
} };
const sendChat = () => { const sendChat = () => {
if(!data.isFinish)return if (!data.isFinish) return;
if(!data.chatContent)return if (!data.chatContent) return;
let fileList let fileList;
if (data.filList) { if (data.filList) {
fileList = JSON.parse(JSON.stringify(data.filList)) fileList = JSON.parse(JSON.stringify(data.filList));
} else { } else {
fileList = [] fileList = [];
} }
let fileUrl = (fileList.filter((item:any)=>item.type == 'file').length > 0) ? fileList.filter((item:any)=>item.type == 'file')[0].minioPath : '' let fileUrl =
let imageUrlList = (fileList.filter((item:any)=>item.type == 'image').length > 0)? fileList.filter((item:any)=>item.type == 'image').map((item:any)=>item.minioPath).join(',') : '' fileList.filter((item: any) => item.type == "file").length > 0
data.chatList.push({content:{message:data.chatContent,think:''},role:'user',fileList:fileList}) ? fileList.filter((item: any) => item.type == "file")[0].minioPath
data.chatList.push({content:{message:'',think:''},role:'system'}) : "";
const eventSource = new EventSource(`${process.env.VUE_APP_BASE_URL}${Https.httpUrls.llmStream}?token=${getCookie('token')}&prompt=${data.chatContent}&projectId=${data.selectObject.id}&fileUrl=${fileUrl}&imageUrlList=${imageUrlList}&enableThinking=${data.enableThinking}`); let imageUrlList =
data.chatContent = '' fileList.filter((item: any) => item.type == "image").length > 0
dataDom.textarea.value = '' ? fileList
data.filList = [] .filter((item: any) => item.type == "image")
.map((item: any) => item.minioPath)
.join(",")
: "";
data.chatList.push({
content: { message: data.chatContent, think: "" },
role: "user",
fileList: fileList,
});
data.chatList.push({
content: { message: "", think: "" },
role: "system",
});
const eventSource = new EventSource(
`${import.meta.env.VITE_APP_BASE_URL}${
Https.httpUrls.llmStream
}?token=${getCookie("token")}&prompt=${data.chatContent}&projectId=${
data.selectObject.id
}&fileUrl=${fileUrl}&imageUrlList=${imageUrlList}&enableThinking=${
data.enableThinking
}`
);
data.chatContent = "";
dataDom.textarea.value = "";
data.filList = [];
eventSource.onmessage = function (event) { eventSource.onmessage = function (event) {
data.isFinish = false data.isFinish = false;
console.log('收到数据:', JSON.parse(event.data)); console.log("收到数据:", JSON.parse(event.data));
// if(event.data.status == 'DESIGN_SIGNAL'){ // if(event.data.status == 'DESIGN_SIGNAL'){
// emit('chatChange',{type:'design'}) // emit('chatChange',{type:'design'})
// }else if(event.data.status == 'RUNNING'){ // }else if(event.data.status == 'RUNNING'){
// data.chatList[data.chatList.length-1].content.message+=JSON.parse(event.data).content // data.chatList[data.chatList.length-1].content.message+=JSON.parse(event.data).content
// } // }
const container = dataDom.chatBox; const container = dataDom.chatBox;
if(container?.scrollHeight)container.scrollTop = container.scrollHeight; if (container?.scrollHeight)
container.scrollTop = container.scrollHeight;
const eventData = JSON.parse(event.data) const eventData = JSON.parse(event.data);
if(eventData.type == 'text'){ if (eventData.type == "text") {
data.chatList[data.chatList.length-1].content.message+=eventData.content data.chatList[data.chatList.length - 1].content.message +=
}else if(eventData.type == 'think'){ eventData.content;
data.chatList[data.chatList.length-1].content.think+=eventData.content } else if (eventData.type == "think") {
data.chatList[data.chatList.length - 1].content.think +=
eventData.content;
} else if (eventData.type == "tools_response") { } else if (eventData.type == "tools_response") {
let nameList = ['moodboard','printboard','sketchboard','generate_color_code'] let nameList = [
"moodboard",
"printboard",
"sketchboard",
"generate_color_code",
];
let nameData = { let nameData = {
moodboard:'moodBoard', moodboard: "moodBoard",
printboard:'printBoard', printboard: "printBoard",
sketchboard:'sketchBoard', sketchboard: "sketchBoard",
} as any } as any;
let getData = '' let getData = "";
if (nameList.indexOf(eventData.tools_name) > -1) { if (nameList.indexOf(eventData.tools_name) > -1) {
if(data.chatList[data.chatList.length - 1].content.message)data.chatList.push({content:{message:''},role:'system'}) if (data.chatList[data.chatList.length - 1].content.message)
if(eventData.tools_name == 'generate_color_code'){ data.chatList.push({ content: { message: "" }, role: "system" });
data.chatList[data.chatList.length-1].content.color = JSON.parse(JSON.parse(event.data).content).receiveCollectionElementList if (eventData.tools_name == "generate_color_code") {
getData = 'colorBoard' data.chatList[data.chatList.length - 1].content.color =
JSON.parse(
JSON.parse(event.data).content
).receiveCollectionElementList;
getData = "colorBoard";
} else { } else {
data.chatList[data.chatList.length-1].content.img = JSON.parse(JSON.parse(event.data).content).receiveCollectionElementList data.chatList[data.chatList.length - 1].content.img = JSON.parse(
getData = nameData[eventData.tools_name] JSON.parse(event.data).content
).receiveCollectionElementList;
getData = nameData[eventData.tools_name];
} }
data.chatList.push({content:{message:''},role:'system'}) data.chatList.push({ content: { message: "" }, role: "system" });
}else if(eventData.tools_name == 'design_control_signal'){ } else if (eventData.tools_name == "design_control_signal") {
emit('chatChange',{type:eventData.tools_name,design:true}) emit("chatChange", { type: eventData.tools_name, design: true });
} }
emit('chatChange',{type:eventData.type,module:getData}) emit("chatChange", { type: eventData.type, module: getData });
} }
//emit('chatChange',{type:JSON.parse(event.data).status}) //emit('chatChange',{type:JSON.parse(event.data).status})
}; };
eventSource.onerror = function (error) { eventSource.onerror = function (error) {
if (eventSource.readyState === EventSource.CLOSED) { if (eventSource.readyState === EventSource.CLOSED) {
data.chatList[data.chatList.length-1].content.message='服务器繁忙,请稍后再试。' data.chatList[data.chatList.length - 1].content.message =
"服务器繁忙,请稍后再试。";
} else { } else {
eventSource.close() eventSource.close();
data.isFinish = true data.isFinish = true;
} }
}; };
} };
const getChatHistory = (objectId: number) => { const getChatHistory = (objectId: number) => {
if(!data.isFinish)return if (!data.isFinish) return;
let value = { let value = {
projectId: objectId, projectId: objectId,
page: 1, page: 1,
pageSize: 100, pageSize: 100,
} };
Https.axiosPost(Https.httpUrls.getChatHistory, value).then((rv) => { Https.axiosPost(Https.httpUrls.getChatHistory, value).then((rv) => {
if (rv) { if (rv) {
rv.content.forEach((item: any, index: number) => { rv.content.forEach((item: any, index: number) => {
if(rv.content[rv.content.length - index -1].role == 'system'){ if (rv.content[rv.content.length - index - 1].role == "system") {
let text = rv.content[rv.content.length - index -1].content let text = rv.content[rv.content.length - index - 1].content;
if (rv.content[rv.content.length - index - 1].isImage == 2) { if (rv.content[rv.content.length - index - 1].isImage == 2) {
rv.content[rv.content.length - index - 1].content = { rv.content[rv.content.length - index - 1].content = {
img : JSON.parse(rv.content[rv.content.length - index -1].content) img: JSON.parse(
} rv.content[rv.content.length - index - 1].content
}else if(rv.content[rv.content.length - index -1].isImage==1){ ),
};
} else if (
rv.content[rv.content.length - index - 1].isImage == 1
) {
rv.content[rv.content.length - index - 1].content = { rv.content[rv.content.length - index - 1].content = {
color : JSON.parse(rv.content[rv.content.length - index -1].content) color: JSON.parse(
} rv.content[rv.content.length - index - 1].content
),
};
} else { } else {
let think = '' let think = "";
let message = '' let message = "";
if(text.split('[TEXT]').length > 1 && text.split('[THINK]').length > 1){ if (
think = text.split('[TEXT]')[0] text.split("[TEXT]").length > 1 &&
text.split('[TEXT]').forEach((text:any,index:number) => { text.split("[THINK]").length > 1
if(index == 0)return ) {
message += ('[TEXT]'+text) think = text.split("[TEXT]")[0];
text.split("[TEXT]").forEach((text: any, index: number) => {
if (index == 0) return;
message += "[TEXT]" + text;
}); });
} else { } else {
message = text message = text;
} }
rv.content[rv.content.length - index - 1].content = { rv.content[rv.content.length - index - 1].content = {
message: message, message: message,
think: think, think: think,
} };
} }
} else { } else {
let content = JSON.parse(rv.content[rv.content.length - index -1].content) let content = JSON.parse(
content.fileList = [] rv.content[rv.content.length - index - 1].content
);
content.fileList = [];
if (content.file || content.image) { if (content.file || content.image) {
let getName = (url: any) => { let getName = (url: any) => {
let minio = url.splice('?')[0] let minio = url.splice("?")[0];
return minio.splice('/')[minio.splice('/').length-1] return minio.splice("/")[minio.splice("/").length - 1];
} };
if (content.file) { if (content.file) {
content.file.forEach((item: any) => { content.file.forEach((item: any) => {
content.fileList.push({name:getName(item),type:'file',url:item}) content.fileList.push({
}) name: getName(item),
type: "file",
url: item,
});
});
} }
if (content.image) { if (content.image) {
content.image.forEach((item: any) => { content.image.forEach((item: any) => {
content.fileList.push({name:getName(item),type:'image',url:item}) content.fileList.push({
}) name: getName(item),
} type: "image",
} url: item,
rv.content[rv.content.length - index -1].content = content });
}
data.chatList.push(rv.content[rv.content.length - index -1])
}); });
} }
})
} }
rv.content[rv.content.length - index - 1].content = content;
}
data.chatList.push(rv.content[rv.content.length - index - 1]);
});
}
});
};
const openChattingRecords = () => { const openChattingRecords = () => {
data.isChattingRecords = true data.isChattingRecords = true;
// let setRecords = ()=>{ // let setRecords = ()=>{
// data.isChattingRecords = false // data.isChattingRecords = false
// document.removeEventListener('click',setRecords) // document.removeEventListener('click',setRecords)
// } // }
// document.addEventListener('click',setRecords) // document.addEventListener('click',setRecords)
} };
const handleFileUpload = (event: any) => { const handleFileUpload = (event: any) => {
if (event.target.files[0].size > 5 * 1024 * 1024) { // 5MB if (event.target.files[0].size > 5 * 1024 * 1024) {
message.info('The file size cannot exceed 5MB.'); // 5MB
return message.info("The file size cannot exceed 5MB.");
return;
} }
let type = event.target.files[0].type.startsWith('image/') let type = event.target.files[0].type.startsWith("image/");
if (type) { if (type) {
if(data.filList.filter((item:any)=>item.type == 'image').length >= 5){ if (
message.info('You can only upload five pictures.'); data.filList.filter((item: any) => item.type == "image").length >= 5
return ) {
message.info("You can only upload five pictures.");
return;
} }
} else { } else {
if(data.filList.filter((item:any)=>item.type == 'file').length >= 1){ if (
message.info('You can only upload one file.'); data.filList.filter((item: any) => item.type == "file").length >= 1
return ) {
message.info("You can only upload one file.");
return;
} }
} }
data.setIsShowMark(true) data.setIsShowMark(true);
const formData = new FormData(); const formData = new FormData();
formData.append('file', event.target.files[0]); formData.append("file", event.target.files[0]);
let config: any = { let config: any = {
headers:{'Content-Type':'multipart/form-data','Accept':'*/*' }, headers: { "Content-Type": "multipart/form-data", Accept: "*/*" },
params: formData, params: formData,
} };
Https.axiosPost(Https.httpUrls.llmUploadFile, formData, config) Https.axiosPost(Https.httpUrls.llmUploadFile, formData, config)
.then((rv: any) => { .then((rv: any) => {
let obj = { let obj = {
name: event.target.files[0].name, name: event.target.files[0].name,
type:type?'image':'file', type: type ? "image" : "file",
minioPath: rv[0], minioPath: rv[0],
url: rv[1], url: rv[1],
} };
data.filList.push(obj) data.filList.push(obj);
// data.filList.unshift(rv) // data.filList.unshift(rv)
data.setIsShowMark(false) data.setIsShowMark(false);
}
).catch(rv=>{
data.setIsShowMark(false)
}) })
} .catch((rv) => {
data.setIsShowMark(false);
});
};
const deleteFile = (item: any, index: number) => { const deleteFile = (item: any, index: number) => {
data.filList.splice(index,1) data.filList.splice(index, 1);
} };
return { return {
...toRefs(dataDom), ...toRefs(dataDom),
...toRefs(data), ...toRefs(data),
@@ -314,13 +491,12 @@ export default defineComponent({
openChattingRecords, openChattingRecords,
handleFileUpload, handleFileUpload,
deleteFile, deleteFile,
} };
}, },
provide() { provide() {
return { return {};
}
}, },
}) });
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
.chat { .chat {
@@ -331,7 +507,7 @@ export default defineComponent({
bottom: 3.2rem; bottom: 3.2rem;
top: auto; top: auto;
width: 50%; width: 50%;
transition: all .3s; transition: all 0.3s;
border-radius: 2.4rem; border-radius: 2.4rem;
display: flex; display: flex;
border: 1px solid #e5e5e5; border: 1px solid #e5e5e5;
@@ -363,7 +539,6 @@ export default defineComponent({
> .text { > .text {
> .content { > .content {
> .txt { > .txt {
} }
> .showThink { > .showThink {
display: none; display: none;
@@ -372,9 +547,9 @@ export default defineComponent({
> .fileBox { > .fileBox {
> .item { > .item {
height: 3rem; height: 3rem;
padding: .5rem 1rem; padding: 0.5rem 1rem;
background: #efeff1; background: #efeff1;
border-radius: .5rem; border-radius: 0.5rem;
margin-right: 1rem; margin-right: 1rem;
font-size: 1.4rem; font-size: 1.4rem;
line-height: 2rem; line-height: 2rem;
@@ -391,7 +566,6 @@ export default defineComponent({
> .icon { > .icon {
display: none; display: none;
} }
} }
} }
@@ -415,12 +589,11 @@ export default defineComponent({
// word-wrap: break-word; // word-wrap: break-word;
> .content { > .content {
> .txt { > .txt {
} }
> .showThink { > .showThink {
cursor: pointer; cursor: pointer;
display: flex; display: flex;
padding: .7rem 1.4rem; padding: 0.7rem 1.4rem;
margin-bottom: 1.2rem; margin-bottom: 1.2rem;
background: rgb(237 237 237); background: rgb(237 237 237);
border-radius: 1rem; border-radius: 1rem;
@@ -433,7 +606,7 @@ export default defineComponent({
} }
> i { > i {
display: flex; display: flex;
transition: all .3s; transition: all 0.3s;
} }
} }
> .think { > .think {
@@ -454,14 +627,14 @@ export default defineComponent({
width: 10rem; width: 10rem;
height: 10rem; height: 10rem;
cursor: pointer; cursor: pointer;
margin: .5rem; margin: 0.5rem;
} }
} }
> .colorBox { > .colorBox {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
> .item { > .item {
margin: .5rem; margin: 0.5rem;
border-radius: 1rem; border-radius: 1rem;
overflow: hidden; overflow: hidden;
border: 1px solid; border: 1px solid;
@@ -496,7 +669,6 @@ export default defineComponent({
} }
} }
} }
} }
} }
} }
@@ -527,9 +699,9 @@ export default defineComponent({
display: flex; display: flex;
> .item { > .item {
height: 3rem; height: 3rem;
padding: .5rem 1rem; padding: 0.5rem 1rem;
background: #efeff1; background: #efeff1;
border-radius: .5rem; border-radius: 0.5rem;
margin-right: 1rem; margin-right: 1rem;
font-size: 1.4rem; font-size: 1.4rem;
line-height: 2rem; line-height: 2rem;
@@ -547,17 +719,16 @@ export default defineComponent({
} }
> .enableThinking { > .enableThinking {
width: 10rem; width: 10rem;
padding: .2rem .4rem; padding: 0.2rem 0.4rem;
text-align: center; text-align: center;
font-size: 1.4rem; font-size: 1.4rem;
border: 1px solid #000; border: 1px solid #000;
border-radius: .4rem; border-radius: 0.4rem;
cursor: pointer; cursor: pointer;
margin-left: 1rem; margin-left: 1rem;
&.active { &.active {
background: #000; background: #000;
color: #fff; color: #fff;
} }
} }
} }
@@ -585,11 +756,11 @@ export default defineComponent({
> .maxNum { > .maxNum {
font-size: 1.2rem; font-size: 1.2rem;
margin-right: .8rem; margin-right: 0.8rem;
font-weight: 400; font-weight: 400;
} }
> .send { > .send {
opacity: .5; opacity: 0.5;
cursor: no-drop; cursor: no-drop;
&.active { &.active {
opacity: 1; opacity: 1;
@@ -600,7 +771,9 @@ export default defineComponent({
} }
} }
} }
> .right,> .left,>.top{ > .right,
> .left,
> .top {
display: flex; display: flex;
align-items: center; align-items: center;
cursor: pointer; cursor: pointer;
@@ -609,7 +782,7 @@ export default defineComponent({
> i { > i {
display: flex; display: flex;
font-size: 2rem; font-size: 2rem;
transition: all .3s; transition: all 0.3s;
} }
} }
> .top { > .top {

View File

@@ -5,7 +5,14 @@
<div class="title">How can I help you today?</div> <div class="title">How can I help you today?</div>
<div class="selectFlow"> <div class="selectFlow">
<div class="select"> <div class="select">
<div class="item" @click="setFlow(item)" :class="{active:item.title == selectFlow.title}" v-for="item in flowList">{{ item.title }}</div> <div
class="item"
@click="setFlow(item)"
:class="{ active: item.title == selectFlow.title }"
v-for="item in flowList"
>
{{ item.title }}
</div>
</div> </div>
<div class="describe"> <div class="describe">
<p v-for="item in selectFlow.describe">{{ item }}</p> <p v-for="item in selectFlow.describe">{{ item }}</p>
@@ -13,24 +20,50 @@
</div> </div>
<div class="chatOrSetting"> <div class="chatOrSetting">
<div class="select"> <div class="select">
<div class="item" @click="setChatOrSetting('chat')" :class="{active:chatOrSetting == 'chat'}">Chat</div> <div
<div class="item" @click="setChatOrSetting('setting')" :class="{active:chatOrSetting == 'setting'}">Setting</div> class="item"
@click="setChatOrSetting('chat')"
:class="{ active: chatOrSetting == 'chat' }"
>
Chat
</div>
<div
class="item"
@click="setChatOrSetting('setting')"
:class="{ active: chatOrSetting == 'setting' }"
>
Setting
</div>
</div> </div>
</div> </div>
<div class="chatBox" v-show="chatOrSetting == 'chat'"> <div class="chatBox" v-show="chatOrSetting == 'chat'">
<textarea ref="textarea" @input="inputText($event)" @keydown.enter.prevent="sendChat" placeholder="Write your message"></textarea> <textarea
ref="textarea"
@input="inputText($event)"
@keydown.enter.prevent="sendChat"
placeholder="Write your message"
></textarea>
<div class="btn"> <div class="btn">
<div class="uploadBox"> <div class="uploadBox">
<div class="filList"> <div class="filList">
<div class="item" v-for="item,index in filList"> <div class="item" v-for="(item, index) in filList">
<div>{{ item.name }}</div> <div>{{ item.name }}</div>
<span class="icon iconfont icon-shanchu" @click="deleteFile(item,index)"></span> <span
class="icon iconfont icon-shanchu"
@click="deleteFile(item, index)"
></span>
</div> </div>
</div> </div>
<i class="fi fi-rs-paperclip-vertical"> <i class="fi fi-rs-paperclip-vertical">
<input type="file" @change="handleFileUpload($event)"> <input type="file" @change="handleFileUpload($event)" />
</i> </i>
<div class="enableThinking" :class="{active:enableThinking}" @click="()=>enableThinking = !enableThinking">Deep Thinking</div> <div
class="enableThinking"
:class="{ active: enableThinking }"
@click="() => (enableThinking = !enableThinking)"
>
Deep Thinking
</div>
</div> </div>
<div class="sendBox"> <div class="sendBox">
<div class="maxNum">{{ chatContent.length }}/10000</div> <div class="maxNum">{{ chatContent.length }}/10000</div>
@@ -41,10 +74,19 @@
</div> </div>
</div> </div>
<div v-show="chatOrSetting != 'chat'" class="workspaceBox"> <div v-show="chatOrSetting != 'chat'" class="workspaceBox">
<workspace @setProject="setProject" :httpWorkflowType="selectFlow.value"></workspace> <workspace
@setProject="setProject"
:httpWorkflowType="selectFlow.value"
></workspace>
</div> </div>
<div class="hint" v-show="chatOrSetting == 'chat'"> <div class="hint" v-show="chatOrSetting == 'chat'">
<div class="item" v-for="item in hintList" @click="addChatContent(item)">{{ item }}</div> <div
class="item"
v-for="item in hintList"
@click="addChatContent(item)"
>
{{ item }}
</div>
</div> </div>
</div> </div>
</div> </div>
@@ -54,103 +96,129 @@
</div> </div>
</template> </template>
<script lang="ts"> <script lang="ts">
import { defineComponent,computed,ref,provide,nextTick,createVNode,toRefs, reactive, onMounted} from 'vue' import {
import { ExclamationCircleOutlined } from '@ant-design/icons-vue'; defineComponent,
computed,
ref,
provide,
nextTick,
createVNode,
toRefs,
reactive,
onMounted,
} from "vue";
import { ExclamationCircleOutlined } from "@ant-design/icons-vue";
import { Https } from "@/tool/https"; import { Https } from "@/tool/https";
import { useStore } from "vuex"; import { useStore } from "vuex";
import { Modal,message,Upload,CascaderProps } from 'ant-design-vue'; import { Modal, message, Upload, CascaderProps } from "ant-design-vue";
import { useI18n } from 'vue-i18n' import { useI18n } from "vue-i18n";
import {getCookie,clonAllCookie} from '@/tool/cookie' import { getCookie, clonAllCookie } from "@/tool/cookie";
import router from '@/router'; import router from "@/router";
import workspace from './workspace.vue' import workspace from "./workspace.vue";
export default defineComponent({ export default defineComponent({
components: { components: {
workspace, workspace,
}, },
props:{ props: {},
}, emits: ["newProject"],
emits:['newProject'],
setup(props, { emit }) { setup(props, { emit }) {
const store = useStore(); const store = useStore();
const data = reactive({ const data = reactive({
flowList: [ flowList: [
{ {
title:'Series Design', title: "Series Design",
value:'SERIES_DESIGN', value: "SERIES_DESIGN",
describe: [ describe: [
'Series Design focuses on the coordinated design of multi-category clothing, ideal for creating a unified fashion collection. You can use the Moodboard, Printboard, Colorboard, Sketchboard, and Mannequin sections in the Design Assests panel to organize your inspiration and design complementary clothing combinations. Finally, refine your designs in the Draft and Collection panels using tools like To Product Image, Relight, and Transfer Pose, then export to the Canvas to showcase your complete series design.', "Series Design focuses on the coordinated design of multi-category clothing, ideal for creating a unified fashion collection. You can use the Moodboard, Printboard, Colorboard, Sketchboard, and Mannequin sections in the Design Assests panel to organize your inspiration and design complementary clothing combinations. Finally, refine your designs in the Draft and Collection panels using tools like To Product Image, Relight, and Transfer Pose, then export to the Canvas to showcase your complete series design.",
] ],
}, },
{ {
title:'Single Design', title: "Single Design",
value:'SINGLE_DESIGN', value: "SINGLE_DESIGN",
describe: [ describe: [
'Single Design centers on the independent design of a single clothing category, such as a T-shirt, dress, or jacket, without considering coordination with other items. Use the Moodboard, Printboard, Colorboard, and Sketchboard in the Design Assests panel to gather inspiration and focus on crafting a unique piece. Once completed, optimize your design in the Draft and Collection panels with tools like To Product Image, Relight, and Transfer Pose, then export to the Canvas to display your individual creation.', "Single Design centers on the independent design of a single clothing category, such as a T-shirt, dress, or jacket, without considering coordination with other items. Use the Moodboard, Printboard, Colorboard, and Sketchboard in the Design Assests panel to gather inspiration and focus on crafting a unique piece. Once completed, optimize your design in the Draft and Collection panels with tools like To Product Image, Relight, and Transfer Pose, then export to the Canvas to display your individual creation.",
] ],
}, },
], ],
selectFlow: { selectFlow: {
title:'Series Design', title: "Series Design",
value:'SERIES_DESIGN', value: "SERIES_DESIGN",
describe: [ describe: [
'Series Design focuses on the coordinated design of multi-category clothing, ideal for creating a unified fashion collection. You can use the Moodboard, Printboard, Colorboard, Sketchboard, and Mannequin sections in the Design Assests panel to organize your inspiration and design complementary clothing combinations. Finally, refine your designs in the Draft and Collection panels using tools like To Product Image, Relight, and Transfer Pose, then export to the Canvas to showcase your complete series design.', "Series Design focuses on the coordinated design of multi-category clothing, ideal for creating a unified fashion collection. You can use the Moodboard, Printboard, Colorboard, Sketchboard, and Mannequin sections in the Design Assests panel to organize your inspiration and design complementary clothing combinations. Finally, refine your designs in the Draft and Collection panels using tools like To Product Image, Relight, and Transfer Pose, then export to the Canvas to showcase your complete series design.",
] ],
}, },
chatContent:'', chatContent: "",
hintList: [ hintList: [
'设计一套田园风衣服', "设计一套田园风衣服",
'设计一套夏日风衣服', "设计一套夏日风衣服",
'设计一套未来风格的衣服', "设计一套未来风格的衣服",
], ],
enableThinking: false, //深度思考 enableThinking: false, //深度思考
uploadFile: null as any, uploadFile: null as any,
loadingShow: false, loadingShow: false,
text:'', text: "",
filList: [] as any, filList: [] as any,
textarea: null as any, textarea: null as any,
chatOrSetting:'chat', chatOrSetting: "chat",
}) });
const dataDom = reactive({ const dataDom = reactive({});
})
const setFlow = (item: any) => { const setFlow = (item: any) => {
data.selectFlow = item data.selectFlow = item;
} };
const inputText = (e: any) => { const inputText = (e: any) => {
if (e.target.value.length <= 1000) { if (e.target.value.length <= 1000) {
data.chatContent = e.target.value data.chatContent = e.target.value;
} else { } else {
e.target.value = data.chatContent e.target.value = data.chatContent;
} }
e.target.style.height = `${e.target.scrollHeight}px`; e.target.style.height = `${e.target.scrollHeight}px`;
} };
const addChatContent = (item: any) => { const addChatContent = (item: any) => {
if((data.textarea.value?.length + item.length) > 10000)return if (data.textarea.value?.length + item.length > 10000) return;
data.chatContent += item data.chatContent += item;
data.textarea.value += item data.textarea.value += item;
} };
const sendChat = () => { const sendChat = () => {
if(!data.chatContent)return if (!data.chatContent) return;
data.loadingShow = true data.loadingShow = true;
let fileList = JSON.parse(JSON.stringify(data.filList)) let fileList = JSON.parse(JSON.stringify(data.filList));
let fileUrl = (fileList.filter((item:any)=>item.type == 'file').length > 0) ? fileList.filter((item:any)=>item.type == 'file')[0].minioPath : '' let fileUrl =
let imageUrlList = (fileList.filter((item:any)=>item.type == 'image').length > 0)? fileList.filter((item:any)=>item.type == 'image').map((item:any)=>item.minioPath).join(',') : '' fileList.filter((item: any) => item.type == "file").length > 0
Https.axiosGet(Https.httpUrls.chatCreateProject, {params:{prompt:data.chatContent,process:data.selectFlow.value,fileUrl:fileUrl,imageUrlList}}).then((rv)=>{ ? fileList.filter((item: any) => item.type == "file")[0].minioPath
: "";
let imageUrlList =
fileList.filter((item: any) => item.type == "image").length > 0
? fileList
.filter((item: any) => item.type == "image")
.map((item: any) => item.minioPath)
.join(",")
: "";
Https.axiosGet(Https.httpUrls.chatCreateProject, {
params: {
prompt: data.chatContent,
process: data.selectFlow.value,
fileUrl: fileUrl,
imageUrlList,
},
})
.then((rv) => {
if (rv) { if (rv) {
data.loadingShow = false data.loadingShow = false;
let value = { let value = {
id: rv, id: rv,
fileList: fileList, fileList: fileList,
chatContent: data.chatContent, chatContent: data.chatContent,
enableThinking: data.enableThinking, enableThinking: data.enableThinking,
};
emit("newProject", value);
} }
emit('newProject',value)
}
}).catch(()=>{
data.loadingShow = false
}) })
.catch(() => {
data.loadingShow = false;
});
// let projectId = '' // let projectId = ''
// const eventSource = new EventSource(`${process.env.VUE_APP_BASE_URL}${Https.httpUrls.llmStream}?token=${getCookie('token')}&prompt=${data.chatContent}&projectId=&fileUrl=${fileUrl}&imageUrlList=${imageUrlList}&enableThinking=${data.enableThinking}&process=${data.selectFlow.value}`); // const eventSource = new EventSource(`${import.meta.env.VITE_APP_BASE_URL}${Https.httpUrls.llmStream}?token=${getCookie('token')}&prompt=${data.chatContent}&projectId=&fileUrl=${fileUrl}&imageUrlList=${imageUrlList}&enableThinking=${data.enableThinking}&process=${data.selectFlow.value}`);
// eventSource.onmessage = function(event) { // eventSource.onmessage = function(event) {
// let eventData = JSON.parse(event.data) // let eventData = JSON.parse(event.data)
// if(eventData.status == "[PROJECT_CREATE_SIGNAL]"){ // if(eventData.status == "[PROJECT_CREATE_SIGNAL]"){
@@ -168,58 +236,63 @@ export default defineComponent({
// } // }
// data.loadingShow = false // data.loadingShow = false
// }; // };
} };
const handleFileUpload = (event: any) => { const handleFileUpload = (event: any) => {
if (event.target.files[0].size > 5 * 1024 * 1024) { // 5MB if (event.target.files[0].size > 5 * 1024 * 1024) {
message.info('The file size cannot exceed 5MB.'); // 5MB
return message.info("The file size cannot exceed 5MB.");
return;
} }
let type = event.target.files[0].type.startsWith('image/') let type = event.target.files[0].type.startsWith("image/");
if (type) { if (type) {
if(data.filList.filter((item:any)=>item.type == 'image').length >= 5){ if (
message.info('You can only upload five pictures.'); data.filList.filter((item: any) => item.type == "image").length >= 5
return ) {
message.info("You can only upload five pictures.");
return;
} }
} else { } else {
if(data.filList.filter((item:any)=>item.type == 'file').length >= 1){ if (
message.info('You can only upload one file.'); data.filList.filter((item: any) => item.type == "file").length >= 1
return ) {
message.info("You can only upload one file.");
return;
} }
} }
data.loadingShow = true data.loadingShow = true;
const formData = new FormData(); const formData = new FormData();
formData.append('file', event.target.files[0]); formData.append("file", event.target.files[0]);
let config: any = { let config: any = {
headers:{'Content-Type':'multipart/form-data','Accept':'*/*' }, headers: { "Content-Type": "multipart/form-data", Accept: "*/*" },
params: formData, params: formData,
} };
Https.axiosPost(Https.httpUrls.llmUploadFile, formData, config) Https.axiosPost(Https.httpUrls.llmUploadFile, formData, config)
.then((rv: any) => { .then((rv: any) => {
let obj = { let obj = {
name: event.target.files[0].name, name: event.target.files[0].name,
type:type?'image':'file', type: type ? "image" : "file",
minioPath: rv[0], minioPath: rv[0],
url: rv[1], url: rv[1],
} };
data.filList.push(obj) data.filList.push(obj);
data.loadingShow = false data.loadingShow = false;
}
).catch(rv=>{
data.loadingShow = false
}) })
} .catch((rv) => {
data.loadingShow = false;
});
};
const deleteFile = (item: any, index: number) => { const deleteFile = (item: any, index: number) => {
data.filList.splice(index,1) data.filList.splice(index, 1);
} };
const setChatOrSetting = (str: any) => { const setChatOrSetting = (str: any) => {
data.chatOrSetting = str data.chatOrSetting = str;
} };
const setProject = (item: any) => { const setProject = (item: any) => {
router.push(`home?history=${item.id}`) router.push(`home?history=${item.id}`);
} };
onMounted(() => { onMounted(() => {
store.commit('createProbject') store.commit("createProbject");
}) });
return { return {
...toRefs(dataDom), ...toRefs(dataDom),
...toRefs(data), ...toRefs(data),
@@ -231,13 +304,12 @@ export default defineComponent({
deleteFile, deleteFile,
setChatOrSetting, setChatOrSetting,
setProject, setProject,
} };
}, },
provide() { provide() {
return { return {};
}
}, },
}) });
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
.newProject { .newProject {
@@ -283,14 +355,14 @@ export default defineComponent({
border: 1px solid #0000001a; border: 1px solid #0000001a;
border-radius: 2.4rem; border-radius: 2.4rem;
display: flex; display: flex;
padding: .2rem; padding: 0.2rem;
border-radius: 2rem; border-radius: 2rem;
> div { > div {
white-space: nowrap; white-space: nowrap;
justify-content: space-between; justify-content: space-between;
border-radius: 2.2rem; border-radius: 2.2rem;
font-size: 1.6rem; font-size: 1.6rem;
padding: .6rem .8rem; padding: 0.6rem 0.8rem;
min-width: 25%; min-width: 25%;
text-align: center; text-align: center;
font-weight: 600; font-weight: 600;
@@ -304,7 +376,7 @@ export default defineComponent({
} }
> .describe { > .describe {
margin-top: 1.6rem; margin-top: 1.6rem;
margin-left: .8rem; margin-left: 0.8rem;
> p { > p {
margin: 0; margin: 0;
color: #71717a; color: #71717a;
@@ -321,14 +393,14 @@ export default defineComponent({
border: 1px solid #0000001a; border: 1px solid #0000001a;
border-radius: 2.4rem; border-radius: 2.4rem;
display: flex; display: flex;
padding: .2rem; padding: 0.2rem;
border-radius: 2rem; border-radius: 2rem;
> div { > div {
white-space: nowrap; white-space: nowrap;
justify-content: space-between; justify-content: space-between;
border-radius: 2.2rem; border-radius: 2.2rem;
font-size: 1.6rem; font-size: 1.6rem;
padding: .6rem .8rem; padding: 0.6rem 0.8rem;
min-width: 10rem; min-width: 10rem;
text-align: center; text-align: center;
font-weight: 600; font-weight: 600;
@@ -342,7 +414,7 @@ export default defineComponent({
} }
} }
> .chatBox { > .chatBox {
margin-top: .4rem; margin-top: 0.4rem;
border-radius: 2.4rem; border-radius: 2.4rem;
position: relative; position: relative;
background: #f5f5f5; background: #f5f5f5;
@@ -370,9 +442,9 @@ export default defineComponent({
display: flex; display: flex;
> .item { > .item {
height: 3rem; height: 3rem;
padding: .5rem 1rem; padding: 0.5rem 1rem;
background: #efeff1; background: #efeff1;
border-radius: .5rem; border-radius: 0.5rem;
margin-right: 1rem; margin-right: 1rem;
font-size: 1.4rem; font-size: 1.4rem;
line-height: 2rem; line-height: 2rem;
@@ -390,17 +462,16 @@ export default defineComponent({
} }
> .enableThinking { > .enableThinking {
width: 10rem; width: 10rem;
padding: .2rem .4rem; padding: 0.2rem 0.4rem;
margin-left: 1rem; margin-left: 1rem;
text-align: center; text-align: center;
font-size: 1.4rem; font-size: 1.4rem;
border: 1px solid #000; border: 1px solid #000;
border-radius: .4rem; border-radius: 0.4rem;
cursor: pointer; cursor: pointer;
&.active { &.active {
background: #000; background: #000;
color: #fff; color: #fff;
} }
} }
} }
@@ -428,7 +499,7 @@ export default defineComponent({
> .maxNum { > .maxNum {
font-size: 1.2rem; font-size: 1.2rem;
margin-right: .8rem; margin-right: 0.8rem;
font-weight: 400; font-weight: 400;
} }
} }

View File

@@ -1,19 +1,18 @@
import axios from 'axios' import axios from "axios";
// import qs from 'qs' // import qs from 'qs'
// import message from '@/components/public/message/src' // import message from '@/components/public/message/src'
import router from '@/router/index' import router from "@/router/index";
import {getCookie,clonAllCookie} from '@/tool/cookie' import { getCookie, clonAllCookie } from "@/tool/cookie";
// import cookie from '@/tools/cookie.js' // import cookie from '@/tools/cookie.js'
axios.defaults.timeout = 60000; //响应时间 axios.defaults.timeout = 60000; //响应时间
// axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8'; //配置请求头 // axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8'; //配置请求头
axios.defaults.headers.post["Content-Type"] = "application/json"; axios.defaults.headers.post["Content-Type"] = "application/json";
axios.defaults.headers.post["lang"] = "en"; //配置语言请求头
axios.defaults.headers.post['lang'] = 'en'; //配置语言请求头
axios.defaults.withCredentials = true; //跨域携带cookie axios.defaults.withCredentials = true; //跨域携带cookie
import { message } from 'ant-design-vue'; import { message } from "ant-design-vue";
import store from '@/store'; import store from "@/store";
// if(process.env.NODE_ENV == "development"){ // if(process.env.NODE_ENV == "development"){
// axios.defaults.baseURL = ""; //配置接口地址 // axios.defaults.baseURL = ""; //配置接口地址
// }else{ // }else{
@@ -25,117 +24,141 @@ import store from '@/store';
// }else{ // }else{
// httpIp = '' // httpIp = ''
// } // }
let httpIp = process.env.NODE_ENV == 'development' ? "" : ""; let httpIp = process.env.NODE_ENV == "development" ? "" : "";
// let httpIp = process.env.NODE_ENV == 'development' ? "https://192.168.1.8:10086" : ""; // let httpIp = process.env.NODE_ENV == 'development' ? "https://192.168.1.8:10086" : "";
axios.defaults.baseURL = httpIp; //配置接口地址 axios.defaults.baseURL = httpIp; //配置接口地址
// console.log(axios.defaults.baseURL); // console.log(axios.defaults.baseURL);
axios.defaults.baseURL = process.env.VUE_APP_BASE_URL; //配置接口地址 axios.defaults.baseURL = import.meta.env.VITE_APP_BASE_URL; //配置接口地址
// 创建取消令牌 // 创建取消令牌
const CancelToken = axios.CancelToken; const CancelToken = axios.CancelToken;
const source = CancelToken.source(); const source = CancelToken.source();
// console.log(process.env.VUE_APP_BASE_URL); // console.log(import.meta.env.VITE_APP_BASE_URL);
const filterHttpsUrl = ['/api/portfolio/page','/api/portfolio/detail','/api/account/preLogin','/api/account/schoolLogin','/api/account/enterpriseLogin','/api/account/login'] const filterHttpsUrl = [
"/api/portfolio/page",
"/api/portfolio/detail",
"/api/account/preLogin",
"/api/account/schoolLogin",
"/api/account/enterpriseLogin",
"/api/account/login",
];
//POST传参序列化(添加请求拦截器) //POST传参序列化(添加请求拦截器)
axios.interceptors.request.use((config) => { axios.interceptors.request.use(
(config) => {
//在发送请求之前做某件事 //在发送请求之前做某件事
// config.cancelToken = source.token // config.cancelToken = source.token
if(config.method === 'post' || config.method === 'put' || config.method === 'delete'){ if (
config.method === "post" ||
config.method === "put" ||
config.method === "delete"
) {
// config.data = qs.stringify(config.data); // config.data = qs.stringify(config.data);
// config.data = JSON.stringify(config.data); // config.data = JSON.stringify(config.data);
} }
// config.headers.Authorization = 'Bearer-eyJhbGciOiJIUzUxMiJ9.eyJqdGkiOiIyIiwic3ViIjoie1wiaWRcIjoyLFwidXNlcm5hbWVcIjpcImxpcnNcIn0iLCJpYXQiOjE2NjU3NDEwODcsImlzcyI6IkRXSiIsImF1dGhvcml0aWVzIjoiW10iLCJleHAiOjE2NzQzODEwODd9.ShM9R_NNFD7oo1OvxrEgg7PFeWinOuAKkuInUCMQupp66s64Hhv8tN0Wwr83nIN4rHPqtn95wmd4msWcvaFYJA'; // config.headers.Authorization = 'Bearer-eyJhbGciOiJIUzUxMiJ9.eyJqdGkiOiIyIiwic3ViIjoie1wiaWRcIjoyLFwidXNlcm5hbWVcIjpcImxpcnNcIn0iLCJpYXQiOjE2NjU3NDEwODcsImlzcyI6IkRXSiIsImF1dGhvcml0aWVzIjoiW10iLCJleHAiOjE2NzQzODEwODd9.ShM9R_NNFD7oo1OvxrEgg7PFeWinOuAKkuInUCMQupp66s64Hhv8tN0Wwr83nIN4rHPqtn95wmd4msWcvaFYJA';
if (filterHttpsUrl.indexOf(config.url) == -1) { if (filterHttpsUrl.indexOf(config.url) == -1) {
config.headers.Authorization = getCookie('token'); config.headers.Authorization = getCookie("token");
} else { } else {
config.headers.Authorization = ''; config.headers.Authorization = "";
} }
return config; return config;
},(error) =>{ },
(error) => {
return Promise.reject(error); return Promise.reject(error);
});
let isLoginTime = false
const binaryToUrl = (binary,type = 'application/octet-stream',res)=>{
let blob = new Blob([binary], {'content-type':res.headers['content-type']});
let url = URL.createObjectURL(blob);
return url
} }
);
let isLoginTime = false;
const binaryToUrl = (binary, type = "application/octet-stream", res) => {
let blob = new Blob([binary], {
"content-type": res.headers["content-type"],
});
let url = URL.createObjectURL(blob);
return url;
};
//返回状态判断(添加响应拦截器) //返回状态判断(添加响应拦截器)
axios.interceptors.response.use((res) =>{ axios.interceptors.response.use(
(res) => {
// if(res.data.data == null){ // if(res.data.data == null){
// message.warning(res.data.errMsg) // message.warning(res.data.errMsg)
// return Promise.reject(res.data); // return Promise.reject(res.data);
// }else // }else
if (res.config.env.binary) { if (res.config.env.binary) {
let url = binaryToUrl(res.data,res.config.env.binaryType,res) let url = binaryToUrl(res.data, res.config.env.binaryType, res);
return Promise.resolve({url,data:res.data}) return Promise.resolve({ url, data: res.data });
} }
if (res.data) { if (res.data) {
if (res.data.errCode === 0) { if (res.data.errCode === 0) {
// message.error(res.data.errMsg) // message.error(res.data.errMsg)
return Promise.resolve(res.data.data); return Promise.resolve(res.data.data);
} else if (res.data.errCode === 1) { } else if (res.data.errCode === 1) {
message.warning(res.data.errMsg) message.warning(res.data.errMsg);
return Promise.reject(res.data); return Promise.reject(res.data);
} else if (res.data.errCode === 2) { } else if (res.data.errCode === 2) {
return Promise.reject(res.data); return Promise.reject(res.data);
} else if (res.data.errCode === -1) { } else if (res.data.errCode === -1) {
message.error(res.data.errMsg) message.error(res.data.errMsg);
return Promise.reject(res.data); return Promise.reject(res.data);
} }
} else { } else {
if (res.data.errCode === 0) { if (res.data.errCode === 0) {
message.warning(res.data.errMsg) message.warning(res.data.errMsg);
return Promise.reject(res.data); return Promise.reject(res.data);
} else if (res.data.errCode === 1) { } else if (res.data.errCode === 1) {
message.warning(res.data.errMsg) message.warning(res.data.errMsg);
return Promise.reject(res.data); return Promise.reject(res.data);
} else if (res.data.errCode === 2) { } else if (res.data.errCode === 2) {
return Promise.reject(res.data); return Promise.reject(res.data);
} else if (res.data.errCode === -1) { } else if (res.data.errCode === -1) {
message.error(res.data.errMsg) message.error(res.data.errMsg);
return Promise.reject(res.data); return Promise.reject(res.data);
} }
} }
}, function(error) { },
if(error?.response?.status === 401 && router.currentRoute._value.name != 'setIdentification'){//如果是记录浏览器页面就不跳转login function (error) {
if (
error?.response?.status === 401 &&
router.currentRoute._value.name != "setIdentification"
) {
//如果是记录浏览器页面就不跳转login
// return // return
clonAllCookie() clonAllCookie();
if (!isLoginTime) { if (!isLoginTime) {
isLoginTime = true isLoginTime = true;
let isSystemUserRouteList = ['/Square']//如果是这两个页面就无需跳转未登录页 let isSystemUserRouteList = ["/Square"]; //如果是这两个页面就无需跳转未登录页
let sSystemUser = false let sSystemUser = false;
for (let index = 0; index < isSystemUserRouteList.length; index++) { for (let index = 0; index < isSystemUserRouteList.length; index++) {
if(router.currentRoute.value.path.indexOf(isSystemUserRouteList[index]) > -1){ if (
sSystemUser = true router.currentRoute.value.path.indexOf(
break isSystemUserRouteList[index]
) > -1
) {
sSystemUser = true;
break;
} }
} }
if (!sSystemUser) { if (!sSystemUser) {
router.replace('/') router.replace("/");
} }
message.warning('Please login and try again~') message.warning("Please login and try again~");
store.commit('createDetail') store.commit("createDetail");
store.commit('createProbject') store.commit("createProbject");
setTimeout(()=>[ setTimeout(() => [(isLoginTime = false)], 2000);
isLoginTime = false
],2000)
} }
// source.cancel('取消后续接口调用'); // source.cancel('取消后续接口调用');
return Promise.reject() return Promise.reject();
} }
let data_new = error?.response?.data let data_new = error?.response?.data;
// message.error(data_new?.errMsg || 'Error: server exception') // message.error(data_new?.errMsg || 'Error: server exception')
return Promise.reject(data_new); return Promise.reject(data_new);
}); }
);
export const Https = { export const Https = {
httpUrls: { httpUrls: {
interfaceUrl: '', interfaceUrl: "",
parseGoogleCredential:'/api/third/party/parseGoogleCredential',//谷歌登录注册 parseGoogleCredential: "/api/third/party/parseGoogleCredential", //谷歌登录注册
parseWeChatCode:'/api/third/party/parseWeChatCode',//微信登录 parseWeChatCode: "/api/third/party/parseWeChatCode", //微信登录
accountIsLogin:'/api/account/isLogin', //判断用户是否登录 accountIsLogin: "/api/account/isLogin", //判断用户是否登录
accountLogin: `/api/account/login`, //账号密码登录接口 accountLogin: `/api/account/login`, //账号密码登录接口
organizationNameSearch: `/api/account/organizationNameSearch`, //查询学校或者企业版名字 organizationNameSearch: `/api/account/organizationNameSearch`, //查询学校或者企业版名字
getUserLanguage: `/api/account/getUserLanguage`, //获取当前用户语言 getUserLanguage: `/api/account/getUserLanguage`, //获取当前用户语言
@@ -161,30 +184,28 @@ export const Https = {
endpoint: `api/third/party/your-secured-endpoint`, //获取唯一标识是否存在 endpoint: `api/third/party/your-secured-endpoint`, //获取唯一标识是否存在
designWorksRegister: "/api/account/designWorksRegister", //注册
designWorksRegisterCode: "/api/account/designWorksRegisterCode", //注册
designWorksRegister:'/api/account/designWorksRegister', //注册 preLogin: "/api/account/preLogin", //预先登入
designWorksRegisterCode:'/api/account/designWorksRegisterCode', //注册 schoolLogin: "/api/account/schoolLogin", //学校管理员登录
enterpriseLogin: "/api/account/enterpriseLogin", //企业管理员登录
preLogin:'/api/account/preLogin',//预先登入
schoolLogin:'/api/account/schoolLogin',//学校管理员登录
enterpriseLogin:'/api/account/enterpriseLogin',//企业管理员登录
accountSendEmail: `/api/account/sendEmail`, //发送邮件 accountSendEmail: `/api/account/sendEmail`, //发送邮件
accountResetPwd:'/api/account/resetPwd', //忘记密码修改 accountResetPwd: "/api/account/resetPwd", //忘记密码修改
accountLogout:'/api/account/logout',//登出 accountLogout: "/api/account/logout", //登出
accountBindEmail:'/api/account/bindEmail', //绑定邮箱 accountBindEmail: "/api/account/bindEmail", //绑定邮箱
bindGoogle:'/api/account/bindGoogle', //绑定谷歌 bindGoogle: "/api/account/bindGoogle", //绑定谷歌
bindWeChat:'/api/account/bindWeChat', //绑定微信 bindWeChat: "/api/account/bindWeChat", //绑定微信
unbindGoogle: `/api/account/unbindGoogle`, //取消绑定谷歌 unbindGoogle: `/api/account/unbindGoogle`, //取消绑定谷歌
unbindWeChat:'/api/account/unbindWeChat', //取消绑定微信 unbindWeChat: "/api/account/unbindWeChat", //取消绑定微信
elementGeneratePrint:'/api/element/generatePrint', //生成印花 elementGeneratePrint: "/api/element/generatePrint", //生成印花
elementSavePrint:'/api/element/savePrint',//保存印花 elementSavePrint: "/api/element/savePrint", //保存印花
getRgbByTcx:'/api/element/getRgbByTcx', // 通过hsv值获取潘通信息 getRgbByTcx: "/api/element/getRgbByTcx", // 通过hsv值获取潘通信息
getRgbByHsv:'/api/element/getRgbByHsv', //通过hsv值获取潘通信息 getRgbByHsv: "/api/element/getRgbByHsv", //通过hsv值获取潘通信息
designCollection: `/api/design/designCollection`, //设计 Conllection designCollection: `/api/design/designCollection`, //设计 Conllection
reDesignCollection: `/api/design/reDesignCollection`, //重新设计 Conllection reDesignCollection: `/api/design/reDesignCollection`, //重新设计 Conllection
countDesignProcess:'/api/design/countDesignProcess', //统计design进度 countDesignProcess: "/api/design/countDesignProcess", //统计design进度
getDesignResult:'/api/design/getDesignResult', //查询design结果 getDesignResult: "/api/design/getDesignResult", //查询design结果
designSort: `/api/design/sort`, //design排序 designSort: `/api/design/sort`, //design排序
collectionLikeUpdate: `/api/history/collectionLikeUpdate`, //赋值排序 collectionLikeUpdate: `/api/history/collectionLikeUpdate`, //赋值排序
@@ -218,8 +239,8 @@ export const Https = {
historyChoose: `/api/history/choose`, //History choose historyChoose: `/api/history/choose`, //History choose
getDesignDetail: `/api/design/detail/getDetail`, //查询design详情 getDesignDetail: `/api/design/detail/getDetail`, //查询design详情
designSingleWithGradient: `/api/design/detail/designSingleWithGradient`, //查询需要更新mask列表 designSingleWithGradient: `/api/design/detail/designSingleWithGradient`, //查询需要更新mask列表
getNextSysElement:'/api/design/detail/getNextSysElement',//切换系统的element getNextSysElement: "/api/design/detail/getNextSysElement", //切换系统的element
detailPrintDot:'/api/design/detail/printDot',//print打点预览 detailPrintDot: "/api/design/detail/printDot", //print打点预览
designSingle: `/api/design/detail/designSingle`, //单个design designSingle: `/api/design/detail/designSingle`, //单个design
queryLibraryPage: `/api/library/queryLibraryPage`, //Library分页列表 queryLibraryPage: `/api/library/queryLibraryPage`, //Library分页列表
libraryUpload: `/api/library/upload`, // Library文件上传 libraryUpload: `/api/library/upload`, // Library文件上传
@@ -258,8 +279,6 @@ export const Https = {
poselikeOrDisike: `/api/generate/likeOrDislike`, //postTransform like poselikeOrDisike: `/api/generate/likeOrDislike`, //postTransform like
getAllPose: `/api/generate/getAllPose`, //获取动作 getAllPose: `/api/generate/getAllPose`, //获取动作
//拼贴 //拼贴
genSketchRecon: `/api/generate/genSketchRecon`, genSketchRecon: `/api/generate/genSketchRecon`,
saveReconCanvas: `/api/generate/saveReconCanvas`, saveReconCanvas: `/api/generate/saveReconCanvas`,
@@ -268,11 +287,11 @@ export const Https = {
poseTransform: `/api/generate/poseTransform`, poseTransform: `/api/generate/poseTransform`,
poseTransformResult: `/api/generate/poseTransformResult`, poseTransformResult: `/api/generate/poseTransformResult`,
batchUpdateLibraryName:'/api/library/batchUpdateLibraryName',//Library修改用户文件名 batchUpdateLibraryName: "/api/library/batchUpdateLibraryName", //Library修改用户文件名
batchDeleteLibrary:'/api/library/batchDeleteLibrary',//删除library batchDeleteLibrary: "/api/library/batchDeleteLibrary", //删除library
queryLibraryTopAndBottomPage:'/api/library/queryLibraryTopAndBottomPage',//Library分页列表(查询top和bottom) queryLibraryTopAndBottomPage: "/api/library/queryLibraryTopAndBottomPage", //Library分页列表(查询top和bottom)
saveOrEditTemplatePoint:'/api/library/saveOrEditTemplatePoint',//保存或者编辑template打点 saveOrEditTemplatePoint: "/api/library/saveOrEditTemplatePoint", //保存或者编辑template打点
libraryModelsDot:'/api/library/modelsDot',//Models打点预览 libraryModelsDot: "/api/library/modelsDot", //Models打点预览
chatStreamTest: `/api/python/chatStream`, //机器人助力 chatStreamTest: `/api/python/chatStream`, //机器人助力
pictureLikeOrUnLike: `/api/python/pictureLikeOrUnLike`, //机器人生成图喜欢 pictureLikeOrUnLike: `/api/python/pictureLikeOrUnLike`, //机器人生成图喜欢
getBloodBars: `/api/python/getBloodBars`, //机器人血条 getBloodBars: `/api/python/getBloodBars`, //机器人血条
@@ -286,15 +305,15 @@ export const Https = {
getStyleList: `/api/workspace/styleList`, //获取所有风格列表 getStyleList: `/api/workspace/styleList`, //获取所有风格列表
workspaceList: `/api/workspace/list`, workspaceList: `/api/workspace/list`,
sketchAndPrintGenerate:'/api/generate/sketchAndPrint',//sketchGenerate生成图片 sketchAndPrintGenerate: "/api/generate/sketchAndPrint", //sketchGenerate生成图片
generatePrepare:'/api/generate/prepare',//开始生成generate图片 generatePrepare: "/api/generate/prepare", //开始生成generate图片
generateStopWaiting:'/api/generate/stopWaiting',//取消生成 generateStopWaiting: "/api/generate/stopWaiting", //取消生成
generateResult:'/api/generate/result',//获取生成结果 generateResult: "/api/generate/result", //获取生成结果
generateLike:'/api/generate/like',//喜欢ganerate图片 generateLike: "/api/generate/like", //喜欢ganerate图片
generateDislike:'/api/generate/dislike',//喜欢ganerate图片 generateDislike: "/api/generate/dislike", //喜欢ganerate图片
imageToSketch:'/api/generate/imageToSketch',//成品图转为线稿 imageToSketch: "/api/generate/imageToSketch", //成品图转为线稿
modifySketch:'/api/generate/modifySketch',//修改画布内容并且储存 modifySketch: "/api/generate/modifySketch", //修改画布内容并且储存
elementUpload: `/api/element/upload`, //上传图片 elementUpload: `/api/element/upload`, //上传图片
imageSegmentation: `/api/element/imageSegmentation`, //分割衣服 imageSegmentation: `/api/element/imageSegmentation`, //分割衣服
@@ -324,7 +343,6 @@ export const Https = {
addOrganization: `/api/inquiry/addOrganization`, //添加企业版或者教育版 addOrganization: `/api/inquiry/addOrganization`, //添加企业版或者教育版
queryOrganization: `/api/inquiry/queryOrganization`, //查询企业版或者教育版 queryOrganization: `/api/inquiry/queryOrganization`, //查询企业版或者教育版
//云生成 //云生成
designCloud: `/api/design/designCloud`, //创建云生成 designCloud: `/api/design/designCloud`, //创建云生成
cloudPage: `/api/design/cloudPage`, //创建云生成 cloudPage: `/api/design/cloudPage`, //创建云生成
@@ -369,7 +387,6 @@ export const Https = {
getTasksHistory: `/api/tasks/getAllTask`, //获取所有任务列表 getTasksHistory: `/api/tasks/getAllTask`, //获取所有任务列表
prepareForSR: `/api/python/prepareForSR`, //超分 prepareForSR: `/api/python/prepareForSR`, //超分
//作品广场 //作品广场
publish: `/api/portfolio/publish`, //发布作品到作品广场 publish: `/api/portfolio/publish`, //发布作品到作品广场
getPorfolio: `/api/portfolio/page`, //查询作品广场 getPorfolio: `/api/portfolio/page`, //查询作品广场
@@ -426,67 +443,73 @@ export const Https = {
getHistoryNotification: `/api/message/getHistoryNotification`, //获取历史消息 getHistoryNotification: `/api/message/getHistoryNotification`, //获取历史消息
oneClickRead: `/api/message/oneClickRead`, //全部设为已读 oneClickRead: `/api/message/oneClickRead`, //全部设为已读
personalHomepage: `/api/account/personalHomepage`, //获取个人主页信息 personalHomepage: `/api/account/personalHomepage`, //获取个人主页信息
}, },
axiosGet(url, config) { axiosGet(url, config) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
if(isLoginTime && url != '/api/portfolio/page') { if (isLoginTime && url != "/api/portfolio/page") {
resolve('') resolve("");
return return;
} }
axios.get(url,config).then(response => { axios
resolve(response) .get(url, config)
}).catch((error) => { .then((response) => {
reject(error) resolve(response);
}) })
.catch((error) => {
reject(error);
});
}); });
}, },
axiosPut(url, data) { axiosPut(url, data) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
if(isLoginTime && url != '/api/portfolio/page') { if (isLoginTime && url != "/api/portfolio/page") {
resolve('') resolve("");
return return;
} }
axios.put(url, data).then(response => { axios
resolve(response) .put(url, data)
}).catch((error) => { .then((response) => {
reject(error) resolve(response);
}) })
.catch((error) => {
reject(error);
});
}); });
}, },
axiosPost(url, data, config) { axiosPost(url, data, config) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
if(isLoginTime && url != '/api/portfolio/page') { if (isLoginTime && url != "/api/portfolio/page") {
resolve('') resolve("");
return return;
} }
axios.post(url, data,config).then(response => { axios
resolve(response) .post(url, data, config)
}).catch((error) => { .then((response) => {
reject(error) resolve(response);
}) })
.catch((error) => {
reject(error);
});
}); });
}, },
axiosDelete(url, newData) { axiosDelete(url, newData) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
if(isLoginTime && url != '/api/portfolio/page') { if (isLoginTime && url != "/api/portfolio/page") {
resolve('') resolve("");
return return;
} }
axios.delete(url,{data:newData}).then(response => { axios
resolve(response) .delete(url, { data: newData })
}).catch((error) => { .then((response) => {
reject(error) resolve(response);
}) })
.catch((error) => {
reject(error);
});
}); });
}, },
};
}

View File

@@ -1,36 +1,37 @@
import Fingerprint2 from 'fingerprintjs2';//获取浏览器唯一标识 import Fingerprint2 from "fingerprintjs2"; //获取浏览器唯一标识
const isEmail = (email) => { const isEmail = (email) => {
// let reg = /^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,})$/ // let reg = /^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,})$/
let reg = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/ let reg = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
let result = reg.test(email) let result = reg.test(email);
return result return result;
} };
const getUploadUrl = () => { const getUploadUrl = () => {
let url = process.env.VUE_APP_BASE_URL || '' let url = import.meta.env.VITE_APP_BASE_URL || "";
// let url = "http://18.167.251.121:10086" // let url = "http://18.167.251.121:10086"
return url return url;
} };
const getMinioUrl = (url) => { const getMinioUrl = (url) => {
const { pathname } = new URL(url); const { pathname } = new URL(url);
const result = pathname.slice(1); const result = pathname.slice(1);
return result return result;
} };
const rgbaToHex = (rgba)=> { // rgba转16进制 const rgbaToHex = (rgba) => {
let hex = '#'; // rgba转16进制
let hex = "#";
rgba.forEach((i, index) => { rgba.forEach((i, index) => {
if (index == 3) { if (index == 3) {
hex += Math.round(i * 255).toString(16) hex += Math.round(i * 255).toString(16);
} else { } else {
hex += Number(i).toString(16).padStart(2, '0'); hex += Number(i).toString(16).padStart(2, "0");
} }
}); });
return hex; return hex;
} };
function base64ToFile(urlData, name) { function base64ToFile(urlData, name) {
let arr = urlData.split(','); let arr = urlData.split(",");
let mime = arr[0].match(/:(.*?);/)[1]; let mime = arr[0].match(/:(.*?);/)[1];
let bstr = atob(arr[1]); let bstr = atob(arr[1]);
let n = bstr.length; let n = bstr.length;
@@ -39,12 +40,13 @@ function base64ToFile(urlData,name) {
u8arr[n] = bstr.charCodeAt(n); u8arr[n] = bstr.charCodeAt(n);
} }
return new File([u8arr], name, { return new File([u8arr], name, {
type: mime type: mime,
}); });
} }
function dataURLtoBlob(dataurl) {//吧data url转为blob对象 function dataURLtoBlob(dataurl) {
var arr = dataurl.split(','); //吧data url转为blob对象
var arr = dataurl.split(",");
var mime = arr[0].match(/:(.*?);/)[1]; var mime = arr[0].match(/:(.*?);/)[1];
var bstr = atob(arr[1]); var bstr = atob(arr[1]);
var n = bstr.length; var n = bstr.length;
@@ -55,37 +57,43 @@ function dataURLtoBlob(dataurl) {//吧data url转为blob对象
return new Blob([u8arr], { type: mime }); return new Blob([u8arr], { type: mime });
} }
function blobToFile(blob, fileName) {//给blob文件设置名字和日期 function blobToFile(blob, fileName) {
//给blob文件设置名字和日期
blob.lastModifiedDate = new Date(); blob.lastModifiedDate = new Date();
blob.name = fileName; blob.name = fileName;
return blob; return blob;
} }
//下载图片 //下载图片
function downloadIamge(imgsrc, name) { // 下载图片地址和图片名 function downloadIamge(imgsrc, name) {
var image = new Image() // 下载图片地址和图片名
var image = new Image();
// 解决跨域 Canvas 污染问题 // 解决跨域 Canvas 污染问题
image.setAttribute('crossOrigin', 'anonymous') image.setAttribute("crossOrigin", "anonymous");
image.onload = function () { image.onload = function () {
var canvas = document.createElement('canvas') var canvas = document.createElement("canvas");
canvas.width = image.width canvas.width = image.width;
canvas.height = image.height canvas.height = image.height;
var context = canvas.getContext('2d') var context = canvas.getContext("2d");
context.drawImage(image, 0, 0, image.width, image.height) context.drawImage(image, 0, 0, image.width, image.height);
var url = canvas.toDataURL('image/png') // 得到图片的base64编码数据 var url = canvas.toDataURL("image/png"); // 得到图片的base64编码数据
var a = document.createElement('a') // 生成一个a元素 var a = document.createElement("a"); // 生成一个a元素
var event = new MouseEvent('click') // 创建一个单击事件 var event = new MouseEvent("click"); // 创建一个单击事件
a.download = name || 'generate' // 设置图片名称 a.download = name || "generate"; // 设置图片名称
a.href = url // 将生成的URL设置为a.href属性 a.href = url; // 将生成的URL设置为a.href属性
a.target = '_blank' a.target = "_blank";
a.dispatchEvent(event) // 触发a的单击事件 a.dispatchEvent(event); // 触发a的单击事件
image.remove() image.remove();
} };
image.src = imgsrc image.src = imgsrc;
} }
function dataURLtoFile(dataurl, filename) {//吧url转为文件对象指定文件名称 function dataURLtoFile(dataurl, filename) {
var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1], //吧url转为文件对象指定文件名称
bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n); var arr = dataurl.split(","),
mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]),
n = bstr.length,
u8arr = new Uint8Array(n);
while (n--) { while (n--) {
u8arr[n] = bstr.charCodeAt(n); u8arr[n] = bstr.charCodeAt(n);
} }
@@ -93,42 +101,44 @@ function dataURLtoFile(dataurl, filename) {//吧url转为文件对象指定
return blobToFile(blob, filename); return blobToFile(blob, filename);
} }
const base64toFile = (dataurl, filename = 'file') => {//转换base64 const base64toFile = (dataurl, filename = "file") => {
let arr = dataurl.split(',') //转换base64
let mime = arr[0].match(/:(.*?);/)[1] let arr = dataurl.split(",");
let suffix = mime.split('/')[1] let mime = arr[0].match(/:(.*?);/)[1];
let bstr = atob(arr[1]) let suffix = mime.split("/")[1];
let n = bstr.length let bstr = atob(arr[1]);
let u8arr = new Uint8Array(n) let n = bstr.length;
let u8arr = new Uint8Array(n);
while (n--) { while (n--) {
u8arr[n] = bstr.charCodeAt(n) u8arr[n] = bstr.charCodeAt(n);
} }
return new File([u8arr], `${filename}.${suffix}`, { return new File([u8arr], `${filename}.${suffix}`, {
type: mime type: mime,
}) });
};
} function rgbToHsv([R, G, B]) {
//根据rgb获取hsv
function rgbToHsv([R, G, B]) {//根据rgb获取hsv R /= 255;
R /= 255 G /= 255;
G /= 255 B /= 255;
B /= 255 const max = Math.max(R, G, B);
const max = Math.max(R, G, B) const min = Math.min(R, G, B);
const min = Math.min(R, G, B) const delta = max - min;
const delta = max - min var H, S, V;
var H, S, V
if (delta === 0) { if (delta === 0) {
H = 0; H = 0;
} else if (max === R) { } else if (max === R) {
H = ((G - B) / delta) % 6; H = ((G - B) / delta) % 6;
} else if (max === G) { } else if (max === G) {
H = (B - R) / delta + 2; H = (B - R) / delta + 2;
} else { // max === B } else {
// max === B
H = (R - G) / delta + 4; H = (R - G) / delta + 4;
} }
H = Math.round(H * 60); // 范围为 0-360 H = Math.round(H * 60); // 范围为 0-360
if (H < 0) { if (H < 0) {
H = 360 + H H = 360 + H;
} }
if (max === 0) { if (max === 0) {
S = 0; S = 0;
@@ -137,10 +147,11 @@ function rgbToHsv([R, G, B]) {//根据rgb获取hsv
} }
S = Math.round(S * 100); // 范围为 0-100 S = Math.round(S * 100); // 范围为 0-100
V = Math.round(max * 100); // 范围为 0-100 V = Math.round(max * 100); // 范围为 0-100
return [H, S, V] return [H, S, V];
} }
const formatTime = (timestamp, fmt) => {//吧时间戳转为YYYY-MM-DD hh:mm:ss格式 const formatTime = (timestamp, fmt) => {
//吧时间戳转为YYYY-MM-DD hh:mm:ss格式
// date = new Date(), fmt = 'MM/dd/yyyy'; // date = new Date(), fmt = 'MM/dd/yyyy';
let date = new Date(); let date = new Date();
date.setTime(timestamp * 1000); date.setTime(timestamp * 1000);
@@ -150,38 +161,46 @@ const formatTime = (timestamp, fmt) => {//吧时间戳转为YYYY-MM-DD hh:mm:ss
} }
// console.log(formatRule) // console.log(formatRule)
let o = { let o = {
'M+': date.getMonth() + 1, // 月份 "M+": date.getMonth() + 1, // 月份
'D+': date.getDate(), // 日 "D+": date.getDate(), // 日
'h+': date.getHours(), // 小时 "h+": date.getHours(), // 小时
'm+': date.getMinutes(), // 分 "m+": date.getMinutes(), // 分
's+': date.getSeconds(), // 秒 "s+": date.getSeconds(), // 秒
'q+': Math.floor((date.getMonth() + 3) / 3), // 季度 "q+": Math.floor((date.getMonth() + 3) / 3), // 季度
'S+': date.getMilliseconds(), // 毫秒 "S+": date.getMilliseconds(), // 毫秒
'a': date.getHours() > 12 a: date.getHours() > 12 ? "PM" : "AM", // 上午还是下午
? 'PM'
: 'AM' // 上午还是下午
}; };
if (/(Y+)/.test(fmt)) { if (/(Y+)/.test(fmt)) {
fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length)); fmt = fmt.replace(
RegExp.$1,
(date.getFullYear() + "").substr(4 - RegExp.$1.length)
);
} }
if (/(a)/.test(fmt) && o['h+'] > 12) { if (/(a)/.test(fmt) && o["h+"] > 12) {
o['h+'] = o['h+'] - 12 o["h+"] = o["h+"] - 12;
} }
for (let k in o) { for (let k in o) {
if (new RegExp('(' + k + ')').test(fmt)) { if (new RegExp("(" + k + ")").test(fmt)) {
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) fmt = fmt.replace(
? (o[k]) RegExp.$1,
: (('00' + o[k]).substr(('' + o[k]).length))); RegExp.$1.length == 1 ? o[k] : ("00" + o[k]).substr(("" + o[k]).length)
);
} }
} }
return fmt; return fmt;
} };
const isMoible = () => {//判断是否是移动端 const isMoible = () => {
let is_mobile = navigator.userAgent.toLowerCase().match(/(ipad|ipod|iphone|android|coolpad|mmp|smartphone|midp|wap|xoom|symbian|j2me|blackberry|wince)/i) != null; //判断是否是移动端
let is_mobile =
navigator.userAgent
.toLowerCase()
.match(
/(ipad|ipod|iphone|android|coolpad|mmp|smartphone|midp|wap|xoom|symbian|j2me|blackberry|wince)/i
) != null;
// alert(navigator.userAgent.toLowerCase()) // alert(navigator.userAgent.toLowerCase())
var isiPad = (navigator.maxTouchPoints && navigator.maxTouchPoints > 1); var isiPad = navigator.maxTouchPoints && navigator.maxTouchPoints > 1;
// if (is_mobile) { // if (is_mobile) {
// return true//判断是否在正则内 // return true//判断是否在正则内
// } else if(window.matchMedia("(pointer:fine)").matches){ // } else if(window.matchMedia("(pointer:fine)").matches){
@@ -190,11 +209,11 @@ const isMoible = () => {//判断是否是移动端
// isiPad//判断触摸点 // isiPad//判断触摸点
// } // }
if (is_mobile) { if (is_mobile) {
return true//判断是否在正则内 return true; //判断是否在正则内
} else { } else {
return isiPad//判断触摸点 return isiPad; //判断触摸点
}
} }
};
let setPubDate = (date) => { let setPubDate = (date) => {
const timestamp = new Date(date); const timestamp = new Date(date);
@@ -225,16 +244,18 @@ let setPubDate = (date)=>{
} else { } else {
return `1 minute ago`; return `1 minute ago`;
} }
} };
function getBrowserInfo() {//获取是什么浏览器 function getBrowserInfo() {
//获取是什么浏览器
var agent = navigator.userAgent.toLowerCase(); var agent = navigator.userAgent.toLowerCase();
var userAgent = navigator.userAgent; var userAgent = navigator.userAgent;
var regStr_ie = /msie [\d.]+;/gi; var regStr_ie = /msie [\d.]+;/gi;
var regStr_ff = /firefox\/[\d.]+/gi var regStr_ff = /firefox\/[\d.]+/gi;
var regStr_chrome = /chrome\/[\d.]+/gi; var regStr_chrome = /chrome\/[\d.]+/gi;
var regStr_saf = /safari\/[\d.]+/gi; var regStr_saf = /safari\/[\d.]+/gi;
var isIE = userAgent.indexOf("compatible") > -1 && userAgent.indexOf("MSIE") > -1; //判断是否IE<11浏览器 var isIE =
userAgent.indexOf("compatible") > -1 && userAgent.indexOf("MSIE") > -1; //判断是否IE<11浏览器
var isEdge = userAgent.indexOf("Edge") > -1 && !isIE; //判断是否IE的Edge浏览器 var isEdge = userAgent.indexOf("Edge") > -1 && !isIE; //判断是否IE的Edge浏览器
//IE //IE
if (agent.indexOf("msie") > 0) { if (agent.indexOf("msie") > 0) {
@@ -253,13 +274,11 @@ function getBrowserInfo() {//获取是什么浏览器
return agent.match(regStr_saf); return agent.match(regStr_saf);
} }
} }
async function murmur(){//生成唯一标识 ,暂时没有使用 async function murmur() {
//生成唯一标识 ,暂时没有使用
return await new Promise((resolve, reject) => { return await new Promise((resolve, reject) => {
Fingerprint2.get(function (components) { Fingerprint2.get(function (components) {
const values = components.map(function ( const values = components.map(function (component, index) {
component,
index
) {
if (index === 0) { if (index === 0) {
//把微信浏览器里UA的wifi或4G等网络替换成空,不然切换网络会ID不一样 //把微信浏览器里UA的wifi或4G等网络替换成空,不然切换网络会ID不一样
return component.value.replace(/\bNetType\/\w+\b/, ""); return component.value.replace(/\bNetType\/\w+\b/, "");
@@ -268,9 +287,9 @@ async function murmur(){//生成唯一标识 ,暂时没有使用
}); });
// 生成最终id murmur // 生成最终id murmur
let murmur = Fingerprint2.x64hash128(values.join(""), 31); let murmur = Fingerprint2.x64hash128(values.join(""), 31);
resolve(murmur) resolve(murmur);
});
}); });
})
} }
/** /**
* @description: 计算canvas渐变起始坐标 * @description: 计算canvas渐变起始坐标
@@ -324,7 +343,7 @@ function calculateGradientCoordinate(width,height,angle) {
const alpha = Math.round( const alpha = Math.round(
(Math.asin(width / Math.sqrt(Math.pow(width, 2) + Math.pow(height, 2))) * (Math.asin(width / Math.sqrt(Math.pow(width, 2) + Math.pow(height, 2))) *
180) / 180) /
Math.PI, Math.PI
); );
// 当渐变轴分别于矩形的两条对角线重合情况下的四种结果 // 当渐变轴分别于矩形的两条对角线重合情况下的四种结果
@@ -428,45 +447,49 @@ function calculateGradientCoordinate(width,height,angle) {
const setGradual = (colorObj, colorWidth, colorHeight) => { const setGradual = (colorObj, colorWidth, colorHeight) => {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
let width = colorWidth || 320 let width = colorWidth || 320;
let height = colorHeight || 700 let height = colorHeight || 700;
const canvas = document.createElement("canvas"); const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d"); const ctx = canvas.getContext("2d");
canvas.width = width; canvas.width = width;
canvas.height = height; canvas.height = height;
let {x0, y0, x1, y1} = calculateGradientCoordinate(width,height,colorObj.angle) let { x0, y0, x1, y1 } = calculateGradientCoordinate(
width,
height,
colorObj.angle
);
const gradient = ctx.createLinearGradient(x0, y0, x1, y1); const gradient = ctx.createLinearGradient(x0, y0, x1, y1);
colorObj.gradientList.forEach(item => { colorObj.gradientList.forEach((item) => {
let left = item.left.split('%')[0]/100 let left = item.left.split("%")[0] / 100;
let rgba = `rgba(${item.rgba.r},${item.rgba.g},${item.rgba.b},${item.rgba.a})` let rgba = `rgba(${item.rgba.r},${item.rgba.g},${item.rgba.b},${item.rgba.a})`;
gradient.addColorStop(left, rgba); // 起始颜色 gradient.addColorStop(left, rgba); // 起始颜色
}); });
ctx.fillStyle = gradient; ctx.fillStyle = gradient;
ctx.fillRect(0, 0, width, height); ctx.fillRect(0, 0, width, height);
// let dataURL = canvas.toDataURL('image/jpg'); // let dataURL = canvas.toDataURL('image/jpg');
resolve(canvas.toDataURL('image/jpg')) resolve(canvas.toDataURL("image/jpg"));
}) });
} };
function segmentImage(markerImage, fullImage, size) { function segmentImage(markerImage, fullImage, size) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const markerCanvas = document.createElement('canvas'); const markerCanvas = document.createElement("canvas");
const fullCanvas = document.createElement('canvas'); const fullCanvas = document.createElement("canvas");
const nullCanvas = document.createElement('canvas'); const nullCanvas = document.createElement("canvas");
const ctx1 = markerCanvas.getContext('2d'); const ctx1 = markerCanvas.getContext("2d");
const ctx2 = fullCanvas.getContext('2d'); const ctx2 = fullCanvas.getContext("2d");
const ctx3 = nullCanvas.getContext('2d'); const ctx3 = nullCanvas.getContext("2d");
markerCanvas.width=size.width markerCanvas.width = size.width;
markerCanvas.height=size.height markerCanvas.height = size.height;
fullCanvas.height=size.height fullCanvas.height = size.height;
fullCanvas.width=size.width fullCanvas.width = size.width;
nullCanvas.height=size.height nullCanvas.height = size.height;
nullCanvas.width=size.width nullCanvas.width = size.width;
let targetFrontUrl = '' let targetFrontUrl = "";
let targetBackUrl = '' let targetBackUrl = "";
const marker = new Image(); const marker = new Image();
const full = new Image(); const full = new Image();
marker.crossOrigin = 'anonymous'; marker.crossOrigin = "anonymous";
full.crossOrigin = 'anonymous'; full.crossOrigin = "anonymous";
marker.onload = () => { marker.onload = () => {
ctx1.drawImage(marker, 0, 0, size.width, size.height); ctx1.drawImage(marker, 0, 0, size.width, size.height);
full.onload = () => { full.onload = () => {
@@ -477,7 +500,6 @@ function segmentImage(markerImage,fullImage,size){
}; };
marker.src = markerImage; marker.src = markerImage;
function segmentImageItem() { function segmentImageItem() {
const markerData = ctx1.getImageData(0, 0, size.width, size.height); const markerData = ctx1.getImageData(0, 0, size.width, size.height);
const fullData = ctx2.getImageData(0, 0, size.width, size.height); const fullData = ctx2.getImageData(0, 0, size.width, size.height);
@@ -491,8 +513,7 @@ function segmentImage(markerImage,fullImage,size){
// (Math.abs(b - color.b) < threshold) || (Math.abs(0 - color.b) < threshold) // (Math.abs(b - color.b) < threshold) || (Math.abs(0 - color.b) < threshold)
const isColorMatch = (r, g, b, color) => const isColorMatch = (r, g, b, color) =>
((color.r >= color.g) && r >= g) || (color.r >= color.g && r >= g) || (color.r < color.g && r < g);
((color.r < color.g) && r < g)
// (Math.abs(b - color.b) < threshold || Math.abs(0 - color.b) < threshold) // (Math.abs(b - color.b) < threshold || Math.abs(0 - color.b) < threshold)
@@ -503,7 +524,7 @@ function segmentImage(markerImage,fullImage,size){
const g = markerData.data[i + 1]; const g = markerData.data[i + 1];
const b = markerData.data[i + 2]; const b = markerData.data[i + 2];
let a = markerData.data[i + 3]; let a = markerData.data[i + 3];
a>1?a = 255:0 a > 1 ? (a = 255) : 0;
if (r >= g && a > 1) { if (r >= g && a > 1) {
// 将完整图像中对应的像素复制到第一个输出图像 // 将完整图像中对应的像素复制到第一个输出图像
output1.data[i] = fullData.data[i]; output1.data[i] = fullData.data[i];
@@ -548,23 +569,23 @@ function segmentImage(markerImage,fullImage,size){
} }
} }
const createImageURL = (imageData) => { const createImageURL = (imageData) => {
const canvas = document.createElement('canvas'); const canvas = document.createElement("canvas");
canvas.width = size.width; canvas.width = size.width;
canvas.height = size.height; canvas.height = size.height;
const ctx = canvas.getContext('2d'); const ctx = canvas.getContext("2d");
ctx.putImageData(imageData, 0, 0); ctx.putImageData(imageData, 0, 0);
let data = canvas.toDataURL('image/png') let data = canvas.toDataURL("image/png");
canvas.remove() canvas.remove();
return data; return data;
}; };
targetBackUrl =createImageURL(output2) targetBackUrl = createImageURL(output2);
targetFrontUrl =createImageURL(output1) targetFrontUrl = createImageURL(output1);
resolve({targetFrontUrl, targetBackUrl}) resolve({ targetFrontUrl, targetBackUrl });
markerCanvas.remove() markerCanvas.remove();
fullCanvas.remove() fullCanvas.remove();
nullCanvas.remove() nullCanvas.remove();
} }
}) });
} }
export { export {
isEmail, isEmail,
@@ -586,4 +607,4 @@ export {
setGradual, setGradual,
calculateGradientCoordinate, calculateGradientCoordinate,
segmentImage, segmentImage,
} };

View File

@@ -1,71 +1,77 @@
import { setCookie, getCookie, WriteCookie,clonAllCookie } from "@/tool/cookie"; import {
setCookie,
getCookie,
WriteCookie,
clonAllCookie,
} from "@/tool/cookie";
import MyEvent from "@/tool/myEvents"; import MyEvent from "@/tool/myEvents";
class MyWs { class MyWs {
constructor() { constructor() {
this.ws = null; this.ws = null;
// this.ws = new WebSocket(); // this.ws = new WebSocket();
let http = process.env.VUE_APP_BASE_URL.replace(/^https?:\/\//, '') let http = import.meta.env.VITE_APP_BASE_URL.replace(/^https?:\/\//, "");
this.messageUrl = http+'/notification' this.messageUrl = http + "/notification";
this.wsUrl = '' this.wsUrl = "";
this.reconnectionTime = null this.reconnectionTime = null;
this.times = 0 this.times = 0;
this.sendPINGTime = null this.sendPINGTime = null;
} }
linkWs(url) { linkWs(url) {
if(!(JSON.parse(getCookie("userInfo"))))return if (!JSON.parse(getCookie("userInfo"))) return;
if (this.ws && this.ws.readyState == 1) return if (this.ws && this.ws.readyState == 1) return;
if(!this.wsUrl)this.wsUrl = url +`/${JSON.parse(getCookie("userInfo")).userId}` if (!this.wsUrl)
this.ws = new WebSocket(this.wsUrl) this.wsUrl = url + `/${JSON.parse(getCookie("userInfo")).userId}`;
this.ws = new WebSocket(this.wsUrl);
this.ws.onmessage = (e) => { this.ws.onmessage = (e) => {
try { try {
let rv = JSON.parse(e.data) let rv = JSON.parse(e.data);
if(rv == "PONG")return if (rv == "PONG") return;
this.times = 0 this.times = 0;
MyWs.receiveText(rv) MyWs.receiveText(rv);
} catch (error) { } catch (error) {
console.error('websocket',error) console.error("websocket", error);
} }
} };
clearInterval(this.sendPINGTime) clearInterval(this.sendPINGTime);
this.sendPINGTime = setInterval(() => { this.sendPINGTime = setInterval(() => {
this.send({text:'PING'}) this.send({ text: "PING" });
// },1000) // },1000)
},1000*60*2) }, 1000 * 60 * 2);
this.ws.onclose = (e) => { this.ws.onclose = (e) => {
this.reconnection() this.reconnection();
} };
this.ws.onerror = (e) => { this.ws.onerror = (e) => {
this.reconnection() this.reconnection();
} };
} }
reconnection() { reconnection() {
this.times++ this.times++;
clearTimeout(this.reconnectionTime) clearTimeout(this.reconnectionTime);
if(this.times>=10)return if (this.times >= 10) return;
clearInterval(this.sendPINGTime) clearInterval(this.sendPINGTime);
this.reconnectionTime = setTimeout(() => { this.reconnectionTime = setTimeout(() => {
this.linkWs(this.wsUrl) this.linkWs(this.wsUrl);
},1000) }, 1000);
} }
static receiveText(data, call) { static receiveText(data, call) {
MyEvent.emit('getMessage',data) MyEvent.emit("getMessage", data);
} }
sendMessage(data) { sendMessage(data) {
if (this.ws && this.ws.readyState == 1) { if (this.ws && this.ws.readyState == 1) {
let obj = { let obj = {
cmd: 1, cmd: 1,
data: { data: {
name: '123', name: "123",
} },
} };
this.send(obj) this.send(obj);
obj = { obj = {
cmd: 4, cmd: 4,
data: { data: {
msg: data, msg: data,
} },
} };
this.send(obj) this.send(obj);
// obj = { // obj = {
// cmd: 6, // cmd: 6,
// data: { // data: {
@@ -77,18 +83,18 @@ class MyWs {
} }
send(obj) { send(obj) {
if (this.ws.readyState == 1) { if (this.ws.readyState == 1) {
this.ws.send(JSON.stringify(obj)) this.ws.send(JSON.stringify(obj));
} else { } else {
clearTimeout(this.sendPINGTime) clearTimeout(this.sendPINGTime);
this.reconnection() this.reconnection();
} }
} }
close() { close() {
if (this.ws && this.ws.readyState == 1) { if (this.ws && this.ws.readyState == 1) {
console.log("客户端 连接已关闭") console.log("客户端 连接已关闭");
this.ws.close() this.ws.close();
} }
} }
} }
export default new MyWs() export default new MyWs();

116
vite.config.js Normal file
View File

@@ -0,0 +1,116 @@
import { defineConfig, loadEnv } from "vite";
import vue from "@vitejs/plugin-vue";
import Components from "unplugin-vue-components/vite";
import { AntDesignVueResolver } from "unplugin-vue-components/resolvers";
import AutoImport from "unplugin-auto-import/vite";
import { createSvgIconsPlugin } from "vite-plugin-svg-icons";
import path from "path";
// https://vite.dev/config/
export default defineConfig(({ mode }) => {
// 加载环境变量
const env = loadEnv(mode, process.cwd(), "");
return {
resolve: {
alias: {
"@": path.resolve(__dirname, "src"),
},
},
plugins: [
vue(),
Components({
resolvers: [AntDesignVueResolver({ importStyle: false })],
}),
AutoImport({
imports: [
"vue",
"vue-router",
{
"lodash-es": [
"debounce",
"cloneDeep",
"cloneDeepWith",
"isBoolean",
"isString",
"isNumber",
"isArray",
"isDate",
"isFunction",
"isNaN",
"isNull",
"isObject",
"isUndefined",
],
},
],
dts: "src/auto-imports.d.ts",
}),
createSvgIconsPlugin({
// 指定需要缓存的图标文件夹
iconDirs: [path.resolve(process.cwd(), "src/assets/icons")],
// 指定symbolId格式
symbolId: "icon-[dir]-[name]",
}),
],
css: {
preprocessorOptions: {
less: {
modifyVars: {
"primary-color": "#ec6800",
},
javascriptEnabled: true,
// 全局导入less变量文件
additionalData: `@import "${path.resolve(
__dirname,
"src/assets/style/style.less"
)}";`,
},
},
},
server: {
host: "0.0.0.0", // 允许局域网内的IP访问
port: mode === "production" ? 8060 : 10086, // 根据环境设置端口
open: true, // 自动打开浏览器
strictPort: false, // 如果端口已被占用,则尝试下一个可用端口
proxy: {
"/api": {
target: "http://192.168.1.7:5567",
// target: 'https://develop.api.aida.com.hk',
changeOrigin: true,
},
"/xupei": {
target: "http://192.168.1.7:5567",
changeOrigin: true,
rewrite: (path) => path.replace(/^\/robot/, "/api"),
},
"/oldsis": {
target: "https://old.api.aida.com.hk",
changeOrigin: true,
rewrite: (path) => path.replace(/^\/oldsis/, "/api"),
},
},
},
build: {
sourcemap: false, // 对应vue.config.js中的productionSourceMap: false
outDir: "dist",
assetsDir: "assets",
// 分包策略
rollupOptions: {
output: {
manualChunks: {
vendor: ["vue", "vue-router", "vuex"],
antd: ["ant-design-vue"],
utils: ["axios", "lodash-es"],
},
},
},
},
// 定义全局常量替换
define: {
__VUE_OPTIONS_API__: true,
__VUE_PROD_DEVTOOLS__: false,
__VUE_PROD_HYDRATION_MISMATCH_DETAILS__: false,
},
};
});

View File

@@ -1,79 +0,0 @@
const {defineConfig} = require('@vue/cli-service')
const path = require('path');
const webpack = require('webpack')
module.exports = defineConfig({
transpileDependencies: ['vuetify'],
lintOnSave:false,//关闭语法检查
productionSourceMap: false,//打包不生成map文件减少文件大小
devServer: {
// hot: true, // 热更新
// port: '8060',
port: process.env.NODE_ENV === 'production'
? '8060'
: '10086',
proxy: {
// "/api": {
// // target: 'https://www.aida.com.hk', //后端接口地址
// target: process.env.VUE_APP_BASE_URL,
// changeOrigin: true, //是否允许跨越
// }
'/api':{
target:'http://192.168.1.7:5567',
// target:'https://develop.api.aida.com.hk',
changeOrigin:true,
},
'/xupei':{
target:'http://192.168.1.7:5567',
changeOrigin:true,
pathRewrite:{
'^/robot': 'api', // api替换成api
}
},
'/oldsis':{
target:'https://old.api.aida.com.hk',
changeOrigin:true,
pathRewrite:{
'^/oldsis': 'api', // api替换成api
}
}
},
// https:true,
},
pluginOptions: {
"style-resources-loader": {
preProcessor: "less",
patterns: [
// 存放less变量文件的路径
path.resolve(__dirname, "./src/assets/style/style.less")
]
}
},
css: {
loaderOptions: {
less: {
lessOptions: {
modifyVars: {
'primary-color': '#ec6800'
},
javascriptEnabled: true,
},
},
},
},
configureWebpack: {
plugins: [
require('unplugin-element-plus/webpack')({
// options
}),
],
},
})