mirror of
https://github.com/yangjian102621/geekai.git
synced 2025-09-17 16:56:38 +08:00
fixed conflicts
This commit is contained in:
commit
9a503ddc72
@ -1,5 +1,9 @@
|
|||||||
# 更新日志
|
# 更新日志
|
||||||
|
|
||||||
|
## v4.0.6
|
||||||
|
|
||||||
|
* Bug修复:修复PC端画廊页面的瀑布流组件样式错乱问题
|
||||||
|
|
||||||
## v4.0.5
|
## v4.0.5
|
||||||
|
|
||||||
* 功能优化:已授权系统在后台显示授权信息
|
* 功能优化:已授权系统在后台显示授权信息
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
SHELL=/usr/bin/env bash
|
SHELL=/usr/bin/env bash
|
||||||
NAME := chatgpt-plus
|
NAME := geekai
|
||||||
all: amd64 arm64
|
all: amd64 arm64
|
||||||
|
|
||||||
amd64:
|
amd64:
|
||||||
|
@ -207,10 +207,13 @@ func authorizeMiddleware(s *AppServer, client *redis.Client) gin.HandlerFunc {
|
|||||||
|
|
||||||
func needLogin(c *gin.Context) bool {
|
func needLogin(c *gin.Context) bool {
|
||||||
if c.Request.URL.Path == "/api/user/login" ||
|
if c.Request.URL.Path == "/api/user/login" ||
|
||||||
|
c.Request.URL.Path == "/api/user/logout" ||
|
||||||
c.Request.URL.Path == "/api/user/resetPass" ||
|
c.Request.URL.Path == "/api/user/resetPass" ||
|
||||||
c.Request.URL.Path == "/api/admin/login" ||
|
c.Request.URL.Path == "/api/admin/login" ||
|
||||||
|
c.Request.URL.Path == "/api/admin/logout" ||
|
||||||
c.Request.URL.Path == "/api/admin/login/captcha" ||
|
c.Request.URL.Path == "/api/admin/login/captcha" ||
|
||||||
c.Request.URL.Path == "/api/user/register" ||
|
c.Request.URL.Path == "/api/user/register" ||
|
||||||
|
c.Request.URL.Path == "/api/user/session" ||
|
||||||
c.Request.URL.Path == "/api/chat/history" ||
|
c.Request.URL.Path == "/api/chat/history" ||
|
||||||
c.Request.URL.Path == "/api/chat/detail" ||
|
c.Request.URL.Path == "/api/chat/detail" ||
|
||||||
c.Request.URL.Path == "/api/chat/list" ||
|
c.Request.URL.Path == "/api/chat/list" ||
|
||||||
|
@ -144,6 +144,7 @@ func (h *ChatHandler) ChatHandle(c *gin.Context) {
|
|||||||
for {
|
for {
|
||||||
_, msg, err := client.Receive()
|
_, msg, err := client.Receive()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
logger.Debugf("close connection: %s", client.Conn.RemoteAddr())
|
||||||
client.Close()
|
client.Close()
|
||||||
h.App.ChatClients.Delete(sessionId)
|
h.App.ChatClients.Delete(sessionId)
|
||||||
h.App.ChatSession.Delete(sessionId)
|
h.App.ChatSession.Delete(sessionId)
|
||||||
|
@ -188,6 +188,11 @@ func (h *FunctionHandler) Dall3(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if user.Power < h.App.SysConfig.DallPower {
|
||||||
|
resp.ERROR(c, "创建 DALL-E 绘图任务失败,算力不足")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// create dall task
|
// create dall task
|
||||||
prompt := utils.InterfaceToString(params["prompt"])
|
prompt := utils.InterfaceToString(params["prompt"])
|
||||||
job := model.DallJob{
|
job := model.DallJob{
|
||||||
|
@ -13,21 +13,22 @@ import (
|
|||||||
"geekai/core"
|
"geekai/core"
|
||||||
"geekai/core/types"
|
"geekai/core/types"
|
||||||
"geekai/store"
|
"geekai/store"
|
||||||
"github.com/imroc/req/v3"
|
|
||||||
"github.com/shirou/gopsutil/host"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/imroc/req/v3"
|
||||||
|
"github.com/shirou/gopsutil/host"
|
||||||
)
|
)
|
||||||
|
|
||||||
type LicenseService struct {
|
type LicenseService struct {
|
||||||
config types.ApiConfig
|
config types.ApiConfig
|
||||||
levelDB *store.LevelDB
|
levelDB *store.LevelDB
|
||||||
license types.License
|
license *types.License
|
||||||
urlWhiteList []string
|
urlWhiteList []string
|
||||||
machineId string
|
machineId string
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewLicenseService(server *core.AppServer, levelDB *store.LevelDB) * LicenseService {
|
func NewLicenseService(server *core.AppServer, levelDB *store.LevelDB) *LicenseService {
|
||||||
var license types.License
|
var license types.License
|
||||||
var machineId string
|
var machineId string
|
||||||
_ = levelDB.Get(types.LicenseKey, &license)
|
_ = levelDB.Get(types.LicenseKey, &license)
|
||||||
@ -35,18 +36,20 @@ func NewLicenseService(server *core.AppServer, levelDB *store.LevelDB) * License
|
|||||||
if err == nil {
|
if err == nil {
|
||||||
machineId = info.HostID
|
machineId = info.HostID
|
||||||
}
|
}
|
||||||
|
logger.Infof("License: %+v", license)
|
||||||
return &LicenseService{
|
return &LicenseService{
|
||||||
config: server.Config.ApiConfig,
|
config: server.Config.ApiConfig,
|
||||||
levelDB: levelDB,
|
levelDB: levelDB,
|
||||||
license: license,
|
license: &license,
|
||||||
machineId: machineId,
|
machineId: machineId,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type License struct {
|
type License struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Value string `json:"license"`
|
License string `json:"license"`
|
||||||
Mid string `json:"mid"`
|
Mid string `json:"mid"`
|
||||||
|
ActiveAt int64 `json:"active_at"`
|
||||||
ExpiredAt int64 `json:"expired_at"`
|
ExpiredAt int64 `json:"expired_at"`
|
||||||
UserNum int `json:"user_num"`
|
UserNum int `json:"user_num"`
|
||||||
}
|
}
|
||||||
@ -67,14 +70,14 @@ func (s *LicenseService) ActiveLicense(license string, machineId string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if response.IsErrorState() {
|
if response.IsErrorState() {
|
||||||
return fmt.Errorf( "发送激活请求失败:%v", response.Status)
|
return fmt.Errorf("发送激活请求失败:%v", response.Status)
|
||||||
}
|
}
|
||||||
|
|
||||||
if res.Code != types.Success {
|
if res.Code != types.Success {
|
||||||
return fmt.Errorf("激活失败:%v", res.Message)
|
return fmt.Errorf("激活失败:%v", res.Message)
|
||||||
}
|
}
|
||||||
|
|
||||||
s.license = types.License{
|
s.license = &types.License{
|
||||||
Key: license,
|
Key: license,
|
||||||
MachineId: machineId,
|
MachineId: machineId,
|
||||||
UserNum: res.Data.UserNum,
|
UserNum: res.Data.UserNum,
|
||||||
@ -91,50 +94,81 @@ func (s *LicenseService) ActiveLicense(license string, machineId string) error {
|
|||||||
// SyncLicense 定期同步 License
|
// SyncLicense 定期同步 License
|
||||||
func (s *LicenseService) SyncLicense() {
|
func (s *LicenseService) SyncLicense() {
|
||||||
go func() {
|
go func() {
|
||||||
|
retryCounter := 0
|
||||||
for {
|
for {
|
||||||
var res struct {
|
license, err := s.fetchLicense()
|
||||||
Code types.BizCode `json:"code"`
|
|
||||||
Message string `json:"message"`
|
|
||||||
Data struct {
|
|
||||||
License License `json:"license"`
|
|
||||||
Urls []string `json:"urls"`
|
|
||||||
}
|
|
||||||
}
|
|
||||||
apiURL := fmt.Sprintf("%s/%s", s.config.ApiURL, "api/license/check")
|
|
||||||
response, err := req.C().R().
|
|
||||||
SetBody(map[string]string{"license": s.license.Key, "machine_id": s.machineId}).
|
|
||||||
SetSuccessResult(&res).Post(apiURL)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf("发送激活请求失败: %v", err)
|
retryCounter++
|
||||||
goto next
|
if retryCounter < 5 {
|
||||||
}
|
logger.Error(err)
|
||||||
if response.IsErrorState() {
|
}
|
||||||
logger.Errorf("激活失败:%v", response.Status)
|
|
||||||
goto next
|
|
||||||
}
|
|
||||||
if res.Code != types.Success {
|
|
||||||
logger.Errorf("激活失败:%v", res.Message)
|
|
||||||
s.license.IsActive = false
|
s.license.IsActive = false
|
||||||
goto next
|
} else {
|
||||||
|
s.license = license
|
||||||
}
|
}
|
||||||
|
|
||||||
s.license = types.License{
|
urls, err := s.fetchUrlWhiteList()
|
||||||
Key: res.Data.License.Value,
|
if err == nil {
|
||||||
MachineId: res.Data.License.Mid,
|
s.urlWhiteList = urls
|
||||||
UserNum: res.Data.License.UserNum,
|
|
||||||
ExpiredAt: res.Data.License.ExpiredAt,
|
|
||||||
IsActive: true,
|
|
||||||
}
|
}
|
||||||
s.urlWhiteList = res.Data.Urls
|
|
||||||
logger.Debugf("同步 License 成功:%v\n%v", s.license, s.urlWhiteList)
|
|
||||||
next:
|
|
||||||
time.Sleep(time.Second * 10)
|
time.Sleep(time.Second * 10)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *LicenseService) fetchLicense() (*types.License, error) {
|
||||||
|
var res struct {
|
||||||
|
Code types.BizCode `json:"code"`
|
||||||
|
Message string `json:"message"`
|
||||||
|
Data License `json:"data"`
|
||||||
|
}
|
||||||
|
apiURL := fmt.Sprintf("%s/%s", s.config.ApiURL, "api/license/check")
|
||||||
|
response, err := req.C().R().
|
||||||
|
SetBody(map[string]string{"license": s.license.Key, "machine_id": s.machineId}).
|
||||||
|
SetSuccessResult(&res).Post(apiURL)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("发送激活请求失败: %v", err)
|
||||||
|
}
|
||||||
|
if response.IsErrorState() {
|
||||||
|
return nil, fmt.Errorf("激活失败:%v", response.Status)
|
||||||
|
}
|
||||||
|
if res.Code != types.Success {
|
||||||
|
return nil, fmt.Errorf("激活失败:%v", res.Message)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &types.License{
|
||||||
|
Key: res.Data.License,
|
||||||
|
MachineId: res.Data.Mid,
|
||||||
|
UserNum: res.Data.UserNum,
|
||||||
|
ExpiredAt: res.Data.ExpiredAt,
|
||||||
|
IsActive: true,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *LicenseService) fetchUrlWhiteList() ([]string, error) {
|
||||||
|
var res struct {
|
||||||
|
Code types.BizCode `json:"code"`
|
||||||
|
Message string `json:"message"`
|
||||||
|
Data []string `json:"data"`
|
||||||
|
}
|
||||||
|
apiURL := fmt.Sprintf("%s/%s", s.config.ApiURL, "api/license/urls")
|
||||||
|
response, err := req.C().R().SetSuccessResult(&res).Get(apiURL)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("发送请求失败: %v", err)
|
||||||
|
}
|
||||||
|
if response.IsErrorState() {
|
||||||
|
return nil, fmt.Errorf("发送请求失败:%v", response.Status)
|
||||||
|
}
|
||||||
|
if res.Code != types.Success {
|
||||||
|
return nil, fmt.Errorf("获取白名单失败:%v", res.Message)
|
||||||
|
}
|
||||||
|
|
||||||
|
return res.Data, nil
|
||||||
|
}
|
||||||
|
|
||||||
// GetLicense 获取许可信息
|
// GetLicense 获取许可信息
|
||||||
func (s *LicenseService) GetLicense() types.License {
|
func (s *LicenseService) GetLicense() *types.License {
|
||||||
return s.license
|
return s.license
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -158,4 +192,4 @@ func (s *LicenseService) IsValidApiURL(uri string) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return fmt.Errorf("当前 API 地址 %s 不在白名单列表当中。", uri)
|
return fmt.Errorf("当前 API 地址 %s 不在白名单列表当中。", uri)
|
||||||
}
|
}
|
||||||
|
@ -14,15 +14,15 @@ npm run build
|
|||||||
cd ../build
|
cd ../build
|
||||||
|
|
||||||
# remove docker image if exists
|
# remove docker image if exists
|
||||||
docker rmi -f registry.cn-shenzhen.aliyuncs.com/geekmaster/chatgpt-plus-api:$version-$arch
|
docker rmi -f registry.cn-shenzhen.aliyuncs.com/geekmaster/geekai-api:$version-$arch
|
||||||
# build docker image for chatgpt-plus-go
|
# build docker image for Geek-AI API
|
||||||
docker build -t registry.cn-shenzhen.aliyuncs.com/geekmaster/chatgpt-plus-api:$version-$arch -f dockerfile-api-go ../
|
docker build -t registry.cn-shenzhen.aliyuncs.com/geekmaster/geekai-api:$version-$arch -f dockerfile-api-go ../
|
||||||
|
|
||||||
# build docker image for chatgpt-plus-vue
|
# build docker image for Geek-AI-web
|
||||||
docker rmi -f registry.cn-shenzhen.aliyuncs.com/geekmaster/chatgpt-plus-web:$version-$arch
|
docker rmi -f registry.cn-shenzhen.aliyuncs.com/geekmaster/geekai-web:$version-$arch
|
||||||
docker build --platform linux/amd64 -t registry.cn-shenzhen.aliyuncs.com/geekmaster/chatgpt-plus-web:$version-$arch -f dockerfile-vue ../
|
docker build -t registry.cn-shenzhen.aliyuncs.com/geekmaster/geekai-web:$version-$arch -f dockerfile-vue ../
|
||||||
|
|
||||||
if [ "$3" = "push" ];then
|
if [ "$3" = "push" ];then
|
||||||
docker push registry.cn-shenzhen.aliyuncs.com/geekmaster/chatgpt-plus-api:$version-$arch
|
docker push registry.cn-shenzhen.aliyuncs.com/geekmaster/geekai-api:$version-$arch
|
||||||
docker push registry.cn-shenzhen.aliyuncs.com/geekmaster/chatgpt-plus-web:$version-$arch
|
docker push registry.cn-shenzhen.aliyuncs.com/geekmaster/geekai-web:$version-$arch
|
||||||
fi
|
fi
|
||||||
|
@ -4,9 +4,9 @@ FROM registry.cn-hangzhou.aliyuncs.com/geekmaster/alpine:3.18.2
|
|||||||
MAINTAINER yangjian<yangjian102621@163.com>
|
MAINTAINER yangjian<yangjian102621@163.com>
|
||||||
|
|
||||||
WORKDIR /var/www/app
|
WORKDIR /var/www/app
|
||||||
COPY ./api/bin/chatgpt-plus-linux /var/www/app
|
COPY ./api/bin/geekai-linux /var/www/app
|
||||||
|
|
||||||
EXPOSE 5678
|
EXPOSE 5678
|
||||||
|
|
||||||
# 容器启动时执行的命令
|
# 容器启动时执行的命令
|
||||||
CMD ["./chatgpt-plus-linux"]
|
CMD ["./geekai-linux"]
|
||||||
|
@ -66,4 +66,14 @@ html, body {
|
|||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.van-toast--fail {
|
||||||
|
background #fef0f0
|
||||||
|
color #f56c6c
|
||||||
|
}
|
||||||
|
|
||||||
|
.van-toast--success {
|
||||||
|
background #D6FBCC
|
||||||
|
color #07C160
|
||||||
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
.chat-list-wrapper {
|
.chat-list-wrapper {
|
||||||
padding 10px 0 10px 0
|
padding 10px 0 10px 0
|
||||||
background #F5F5F5;
|
background var(--van-background);
|
||||||
overflow hidden
|
overflow hidden
|
||||||
|
|
||||||
|
|
||||||
@ -81,7 +81,7 @@
|
|||||||
|
|
||||||
.van-theme-dark {
|
.van-theme-dark {
|
||||||
.mobile-chat {
|
.mobile-chat {
|
||||||
.message-list-box {
|
.chat-list-wrapper {
|
||||||
background #232425;
|
background #232425;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -74,6 +74,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
color var(--van-text-color)
|
||||||
.pt-6 {
|
.pt-6 {
|
||||||
padding 15px 10px
|
padding 15px 10px
|
||||||
}
|
}
|
||||||
|
@ -80,6 +80,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
color var(--van-text-color)
|
||||||
|
|
||||||
.pt-6 {
|
.pt-6 {
|
||||||
padding 15px 10px
|
padding 15px 10px
|
||||||
}
|
}
|
||||||
|
@ -38,11 +38,11 @@
|
|||||||
import {ref} from "vue";
|
import {ref} from "vue";
|
||||||
import lodash from 'lodash'
|
import lodash from 'lodash'
|
||||||
import {validateEmail, validateMobile} from "@/utils/validate";
|
import {validateEmail, validateMobile} from "@/utils/validate";
|
||||||
import {ElMessage} from "element-plus";
|
|
||||||
import {httpGet, httpPost} from "@/utils/http";
|
import {httpGet, httpPost} from "@/utils/http";
|
||||||
import CaptchaPlus from "@/components/CaptchaPlus.vue";
|
import CaptchaPlus from "@/components/CaptchaPlus.vue";
|
||||||
import SlideCaptcha from "@/components/SlideCaptcha.vue";
|
import SlideCaptcha from "@/components/SlideCaptcha.vue";
|
||||||
import {isMobile} from "@/utils/libs";
|
import {isMobile} from "@/utils/libs";
|
||||||
|
import {showMessageError, showMessageOK} from "@/utils/dialog";
|
||||||
|
|
||||||
// eslint-disable-next-line no-undef
|
// eslint-disable-next-line no-undef
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
@ -66,13 +66,13 @@ const handleRequestCaptCode = () => {
|
|||||||
thumbBase64.value = data.thumb
|
thumbBase64.value = data.thumb
|
||||||
captKey.value = data.key
|
captKey.value = data.key
|
||||||
}).catch(e => {
|
}).catch(e => {
|
||||||
ElMessage.error('获取人机验证数据失败:' + e.message)
|
showMessageError('获取人机验证数据失败:' + e.message)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleConfirm = (dots) => {
|
const handleConfirm = (dots) => {
|
||||||
if (lodash.size(dots) <= 0) {
|
if (lodash.size(dots) <= 0) {
|
||||||
return ElMessage.error('请进行人机验证再操作')
|
return showMessageError('请进行人机验证再操作')
|
||||||
}
|
}
|
||||||
|
|
||||||
let dotArr = []
|
let dotArr = []
|
||||||
@ -88,14 +88,14 @@ const handleConfirm = (dots) => {
|
|||||||
showCaptcha.value = false
|
showCaptcha.value = false
|
||||||
sendMsg()
|
sendMsg()
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
ElMessage.error('人机验证失败')
|
showMessageError('人机验证失败')
|
||||||
handleRequestCaptCode()
|
handleRequestCaptCode()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const loadCaptcha = () => {
|
const loadCaptcha = () => {
|
||||||
if (!validateMobile(props.receiver) && !validateEmail(props.receiver)) {
|
if (!validateMobile(props.receiver) && !validateEmail(props.receiver)) {
|
||||||
return ElMessage.error("请输入合法的手机号/邮箱地址")
|
return showMessageError("请输入合法的手机号/邮箱地址")
|
||||||
}
|
}
|
||||||
|
|
||||||
showCaptcha.value = true
|
showCaptcha.value = true
|
||||||
@ -114,7 +114,7 @@ const sendMsg = () => {
|
|||||||
|
|
||||||
canSend.value = false
|
canSend.value = false
|
||||||
httpPost('/api/sms/code', {receiver: props.receiver, key: captKey.value, dots: dots.value}).then(() => {
|
httpPost('/api/sms/code', {receiver: props.receiver, key: captKey.value, dots: dots.value}).then(() => {
|
||||||
ElMessage.success('验证码发送成功')
|
showMessageOK('验证码发送成功')
|
||||||
let time = 120
|
let time = 120
|
||||||
btnText.value = time
|
btnText.value = time
|
||||||
const handler = setInterval(() => {
|
const handler = setInterval(() => {
|
||||||
@ -129,7 +129,7 @@ const sendMsg = () => {
|
|||||||
}, 1000)
|
}, 1000)
|
||||||
}).catch(e => {
|
}).catch(e => {
|
||||||
canSend.value = true
|
canSend.value = true
|
||||||
ElMessage.error('验证码发送失败:' + e.message)
|
showMessageError('验证码发送失败:' + e.message)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,7 +145,7 @@ const getSlideCaptcha = () => {
|
|||||||
bgImg.value = res.data.bgImg
|
bgImg.value = res.data.bgImg
|
||||||
captKey.value = res.data.key
|
captKey.value = res.data.key
|
||||||
}).catch(e => {
|
}).catch(e => {
|
||||||
ElMessage.error('获取人机验证数据失败:' + e.message)
|
showMessageError('获取人机验证数据失败:' + e.message)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
43
web/src/utils/dialog.js
Normal file
43
web/src/utils/dialog.js
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
/**
|
||||||
|
* Util lib functions
|
||||||
|
*/
|
||||||
|
import {showConfirmDialog, showFailToast, showSuccessToast, showToast} from "vant";
|
||||||
|
import {isMobile} from "@/utils/libs";
|
||||||
|
import {ElMessage} from "element-plus";
|
||||||
|
|
||||||
|
export function showLoginDialog(router) {
|
||||||
|
showConfirmDialog({
|
||||||
|
title: '登录',
|
||||||
|
message:
|
||||||
|
'此操作需要登录才能进行,前往登录?',
|
||||||
|
}).then(() => {
|
||||||
|
router.push("/login")
|
||||||
|
}).catch(() => {
|
||||||
|
// on cancel
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function showMessageOK(message) {
|
||||||
|
if (isMobile()) {
|
||||||
|
showSuccessToast(message)
|
||||||
|
} else {
|
||||||
|
ElMessage.success(message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function showMessageInfo(message) {
|
||||||
|
if (isMobile()) {
|
||||||
|
showToast(message)
|
||||||
|
} else {
|
||||||
|
ElMessage.info(message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function showMessageError(message) {
|
||||||
|
if (isMobile()) {
|
||||||
|
showFailToast(message)
|
||||||
|
} else {
|
||||||
|
ElMessage.error(message)
|
||||||
|
}
|
||||||
|
}
|
@ -6,7 +6,7 @@
|
|||||||
// * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
// * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
import {getAdminToken, getSessionId, getUserToken} from "@/store/session";
|
import {getAdminToken, getSessionId, getUserToken, removeAdminToken, removeUserToken} from "@/store/session";
|
||||||
|
|
||||||
axios.defaults.timeout = 180000
|
axios.defaults.timeout = 180000
|
||||||
axios.defaults.baseURL = process.env.VUE_APP_API_HOST
|
axios.defaults.baseURL = process.env.VUE_APP_API_HOST
|
||||||
@ -29,9 +29,14 @@ axios.interceptors.response.use(
|
|||||||
let data = response.data;
|
let data = response.data;
|
||||||
if (data.code === 0) {
|
if (data.code === 0) {
|
||||||
return response
|
return response
|
||||||
} else {
|
} else if (data.code === 400) {
|
||||||
return Promise.reject(response.data)
|
if (response.request.responseURL.indexOf("/api/admin") !== -1) {
|
||||||
|
removeAdminToken()
|
||||||
|
} else {
|
||||||
|
removeUserToken()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return Promise.reject(response.data)
|
||||||
}, error => {
|
}, error => {
|
||||||
return Promise.reject(error)
|
return Promise.reject(error)
|
||||||
})
|
})
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
<span class="name">{{ scope.item.name }}</span>
|
<span class="name">{{ scope.item.name }}</span>
|
||||||
<div class="opt">
|
<div class="opt">
|
||||||
<div v-if="hasRole(scope.item.key)">
|
<div v-if="hasRole(scope.item.key)">
|
||||||
<el-button size="small" type="success" @click="useRole(scope.item.id)">使用</el-button>
|
<el-button size="small" type="success" @click="useRole(scope.item)">使用</el-button>
|
||||||
<el-button size="small" type="danger" @click="updateRole(scope.item,'remove')">移除</el-button>
|
<el-button size="small" type="danger" @click="updateRole(scope.item,'remove')">移除</el-button>
|
||||||
</div>
|
</div>
|
||||||
<el-button v-else size="small"
|
<el-button v-else size="small"
|
||||||
@ -110,8 +110,8 @@ const hasRole = (roleKey) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const useRole = (roleId) => {
|
const useRole = (role) => {
|
||||||
router.push({name: "chat", params: {role_id: roleId}})
|
router.push(`/chat?role_id=${role.id}`)
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -330,7 +330,10 @@ onMounted(() => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
socket.value = null
|
if (socket.value !== null) {
|
||||||
|
socket.value.close()
|
||||||
|
socket.value = null
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// 初始化数据
|
// 初始化数据
|
||||||
@ -355,8 +358,8 @@ const initData = () => {
|
|||||||
// 加载角色列表
|
// 加载角色列表
|
||||||
httpGet(`/api/role/list`).then((res) => {
|
httpGet(`/api/role/list`).then((res) => {
|
||||||
roles.value = res.data;
|
roles.value = res.data;
|
||||||
if (router.currentRoute.value.params.role_id) {
|
if (router.currentRoute.value.query.role_id) {
|
||||||
roleId.value = parseInt(router.currentRoute.value.params["role_id"])
|
roleId.value = parseInt(router.currentRoute.value.query.role_id)
|
||||||
} else {
|
} else {
|
||||||
roleId.value = roles.value[0]['id']
|
roleId.value = roles.value[0]['id']
|
||||||
}
|
}
|
||||||
|
@ -105,7 +105,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h2>创作记录</h2>
|
<h2>创作记录</h2>
|
||||||
<div class="finish-job-list" v-loading="loading" element-loading-background="rgba(0, 0, 0, 0.5)">
|
<div class="finish-job-list">
|
||||||
<div v-if="finishedJobs.length > 0">
|
<div v-if="finishedJobs.length > 0">
|
||||||
<ItemList :items="finishedJobs" :width="240" :gap="16">
|
<ItemList :items="finishedJobs" :width="240" :gap="16">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
@ -272,7 +272,6 @@ const initData = () => {
|
|||||||
fetchFinishJobs(1)
|
fetchFinishJobs(1)
|
||||||
connect()
|
connect()
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
loading.value = false
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -341,6 +340,9 @@ const connect = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const fetchRunningJobs = () => {
|
const fetchRunningJobs = () => {
|
||||||
|
if (!isLogin.value) {
|
||||||
|
return
|
||||||
|
}
|
||||||
// 获取运行中的任务
|
// 获取运行中的任务
|
||||||
httpGet(`/api/dall/jobs?status=0`).then(res => {
|
httpGet(`/api/dall/jobs?status=0`).then(res => {
|
||||||
const jobs = res.data
|
const jobs = res.data
|
||||||
@ -367,10 +369,11 @@ const fetchRunningJobs = () => {
|
|||||||
const page = ref(1)
|
const page = ref(1)
|
||||||
const pageSize = ref(15)
|
const pageSize = ref(15)
|
||||||
const isOver = ref(false)
|
const isOver = ref(false)
|
||||||
const loading = ref(false)
|
|
||||||
// 获取已完成的任务
|
// 获取已完成的任务
|
||||||
const fetchFinishJobs = (page) => {
|
const fetchFinishJobs = (page) => {
|
||||||
loading.value = true
|
if (!isLogin.value) {
|
||||||
|
return
|
||||||
|
}
|
||||||
httpGet(`/api/dall/jobs?status=1&page=${page}&page_size=${pageSize.value}`).then(res => {
|
httpGet(`/api/dall/jobs?status=1&page=${page}&page_size=${pageSize.value}`).then(res => {
|
||||||
if (res.data.length < pageSize.value) {
|
if (res.data.length < pageSize.value) {
|
||||||
isOver.value = true
|
isOver.value = true
|
||||||
@ -380,9 +383,7 @@ const fetchFinishJobs = (page) => {
|
|||||||
} else {
|
} else {
|
||||||
finishedJobs.value = finishedJobs.value.concat(res.data)
|
finishedJobs.value = finishedJobs.value.concat(res.data)
|
||||||
}
|
}
|
||||||
loading.value = false
|
|
||||||
}).catch(e => {
|
}).catch(e => {
|
||||||
loading.value = false
|
|
||||||
ElMessage.error("获取任务失败:" + e.message)
|
ElMessage.error("获取任务失败:" + e.message)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -493,7 +493,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h2>创作记录</h2>
|
<h2>创作记录</h2>
|
||||||
<div class="finish-job-list" v-loading="loading" element-loading-background="rgba(0, 0, 0, 0.5)">
|
<div class="finish-job-list">
|
||||||
<div v-if="finishedJobs.length > 0">
|
<div v-if="finishedJobs.length > 0">
|
||||||
<ItemList :items="finishedJobs" :width="240" :gap="16">
|
<ItemList :items="finishedJobs" :width="240" :gap="16">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
@ -593,7 +593,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import {nextTick, onMounted, onUnmounted, ref} from "vue"
|
import {onMounted, onUnmounted, ref} from "vue"
|
||||||
import {ChromeFilled, Delete, DocumentCopy, InfoFilled, Picture, Plus, UploadFilled} from "@element-plus/icons-vue";
|
import {ChromeFilled, Delete, DocumentCopy, InfoFilled, Picture, Plus, UploadFilled} from "@element-plus/icons-vue";
|
||||||
import Compressor from "compressorjs";
|
import Compressor from "compressorjs";
|
||||||
import {httpGet, httpPost} from "@/utils/http";
|
import {httpGet, httpPost} from "@/utils/http";
|
||||||
@ -761,7 +761,10 @@ onMounted(() => {
|
|||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
clipboard.value.destroy()
|
clipboard.value.destroy()
|
||||||
socket.value = null
|
if (socket.value !== null) {
|
||||||
|
socket.value.close()
|
||||||
|
socket.value = null
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// 初始化数据
|
// 初始化数据
|
||||||
@ -779,10 +782,6 @@ const initData = () => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
onUnmounted(() => {
|
|
||||||
clipboard.value.destroy()
|
|
||||||
})
|
|
||||||
|
|
||||||
const mjPower = ref(1)
|
const mjPower = ref(1)
|
||||||
const mjActionPower = ref(1)
|
const mjActionPower = ref(1)
|
||||||
httpGet("/api/config/get?key=system").then(res => {
|
httpGet("/api/config/get?key=system").then(res => {
|
||||||
@ -794,6 +793,10 @@ httpGet("/api/config/get?key=system").then(res => {
|
|||||||
|
|
||||||
// 获取运行中的任务
|
// 获取运行中的任务
|
||||||
const fetchRunningJobs = () => {
|
const fetchRunningJobs = () => {
|
||||||
|
if (!isLogin.value) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
httpGet(`/api/mj/jobs?status=0`).then(res => {
|
httpGet(`/api/mj/jobs?status=0`).then(res => {
|
||||||
const jobs = res.data
|
const jobs = res.data
|
||||||
const _jobs = []
|
const _jobs = []
|
||||||
@ -833,9 +836,11 @@ const handleScrollEnd = () => {
|
|||||||
const page = ref(1)
|
const page = ref(1)
|
||||||
const pageSize = ref(15)
|
const pageSize = ref(15)
|
||||||
const isOver = ref(false)
|
const isOver = ref(false)
|
||||||
const loading = ref(false)
|
|
||||||
const fetchFinishJobs = (page) => {
|
const fetchFinishJobs = (page) => {
|
||||||
loading.value = true
|
if (!isLogin.value) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// 获取已完成的任务
|
// 获取已完成的任务
|
||||||
httpGet(`/api/mj/jobs?status=1&page=${page}&page_size=${pageSize.value}`).then(res => {
|
httpGet(`/api/mj/jobs?status=1&page=${page}&page_size=${pageSize.value}`).then(res => {
|
||||||
const jobs = res.data
|
const jobs = res.data
|
||||||
@ -862,9 +867,7 @@ const fetchFinishJobs = (page) => {
|
|||||||
} else {
|
} else {
|
||||||
finishedJobs.value = finishedJobs.value.concat(jobs)
|
finishedJobs.value = finishedJobs.value.concat(jobs)
|
||||||
}
|
}
|
||||||
nextTick(() => loading.value = false)
|
|
||||||
}).catch(e => {
|
}).catch(e => {
|
||||||
loading.value = false
|
|
||||||
ElMessage.error("获取任务失败:" + e.message)
|
ElMessage.error("获取任务失败:" + e.message)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -315,7 +315,7 @@
|
|||||||
<el-empty :image-size="100" v-else/>
|
<el-empty :image-size="100" v-else/>
|
||||||
</div>
|
</div>
|
||||||
<h2>创作记录</h2>
|
<h2>创作记录</h2>
|
||||||
<div class="finish-job-list" v-loading="loading" element-loading-background="rgba(0, 0, 0, 0.5)">
|
<div class="finish-job-list">
|
||||||
<div v-if="finishedJobs.length > 0">
|
<div v-if="finishedJobs.length > 0">
|
||||||
<ItemList :items="finishedJobs" :width="240" :gap="16">
|
<ItemList :items="finishedJobs" :width="240" :gap="16">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
@ -616,7 +616,10 @@ onMounted(() => {
|
|||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
clipboard.value.destroy()
|
clipboard.value.destroy()
|
||||||
socket.value = null
|
if (socket.value !== null) {
|
||||||
|
socket.value.close()
|
||||||
|
socket.value = null
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
@ -629,11 +632,14 @@ const initData = () => {
|
|||||||
fetchFinishJobs()
|
fetchFinishJobs()
|
||||||
connect()
|
connect()
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
loading.value = false
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const fetchRunningJobs = () => {
|
const fetchRunningJobs = () => {
|
||||||
|
if (!isLogin.value) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// 获取运行中的任务
|
// 获取运行中的任务
|
||||||
httpGet(`/api/sd/jobs?status=0`).then(res => {
|
httpGet(`/api/sd/jobs?status=0`).then(res => {
|
||||||
const jobs = res.data
|
const jobs = res.data
|
||||||
@ -668,10 +674,11 @@ const handleScrollEnd = () => {
|
|||||||
const page = ref(1)
|
const page = ref(1)
|
||||||
const pageSize = ref(15)
|
const pageSize = ref(15)
|
||||||
const isOver = ref(false)
|
const isOver = ref(false)
|
||||||
const loading = ref(false)
|
|
||||||
// 获取已完成的任务
|
// 获取已完成的任务
|
||||||
const fetchFinishJobs = (page) => {
|
const fetchFinishJobs = (page) => {
|
||||||
loading.value = true
|
if (!isLogin.value) {
|
||||||
|
return
|
||||||
|
}
|
||||||
httpGet(`/api/sd/jobs?status=1&page=${page}&page_size=${pageSize.value}`).then(res => {
|
httpGet(`/api/sd/jobs?status=1&page=${page}&page_size=${pageSize.value}`).then(res => {
|
||||||
if (res.data.length < pageSize.value) {
|
if (res.data.length < pageSize.value) {
|
||||||
isOver.value = true
|
isOver.value = true
|
||||||
@ -681,9 +688,7 @@ const fetchFinishJobs = (page) => {
|
|||||||
} else {
|
} else {
|
||||||
finishedJobs.value = finishedJobs.value.concat(res.data)
|
finishedJobs.value = finishedJobs.value.concat(res.data)
|
||||||
}
|
}
|
||||||
loading.value = false
|
|
||||||
}).catch(e => {
|
}).catch(e => {
|
||||||
loading.value = false
|
|
||||||
ElMessage.error("获取任务失败:" + e.message)
|
ElMessage.error("获取任务失败:" + e.message)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -5,9 +5,9 @@
|
|||||||
<h2>AI 绘画作品墙</h2>
|
<h2>AI 绘画作品墙</h2>
|
||||||
<div class="settings">
|
<div class="settings">
|
||||||
<el-radio-group v-model="imgType" @change="changeImgType">
|
<el-radio-group v-model="imgType" @change="changeImgType">
|
||||||
<el-radio label="mj" size="large">MidJourney</el-radio>
|
<el-radio value="mj" size="large">MidJourney</el-radio>
|
||||||
<el-radio label="sd" size="large">Stable Diffusion</el-radio>
|
<el-radio value="sd" size="large">Stable Diffusion</el-radio>
|
||||||
<el-radio label="dall" size="large">DALL-E</el-radio>
|
<el-radio value="dall" size="large">DALL-E</el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -72,7 +72,7 @@
|
|||||||
</template>
|
</template>
|
||||||
</v3-waterfall>
|
</v3-waterfall>
|
||||||
|
|
||||||
<v3-waterfall v-if="imgType === 'dall'"
|
<v3-waterfall v-else-if="imgType === 'dall'"
|
||||||
id="waterfall"
|
id="waterfall"
|
||||||
:list="data['dall']"
|
:list="data['dall']"
|
||||||
srcKey="img_thumb"
|
srcKey="img_thumb"
|
||||||
@ -338,7 +338,6 @@ const getNext = () => {
|
|||||||
loading.value = true
|
loading.value = true
|
||||||
page.value = page.value + 1
|
page.value = page.value + 1
|
||||||
let url = ""
|
let url = ""
|
||||||
console.log(imgType.value)
|
|
||||||
switch (imgType.value) {
|
switch (imgType.value) {
|
||||||
case "mj":
|
case "mj":
|
||||||
url = "/api/mj/imgWall"
|
url = "/api/mj/imgWall"
|
||||||
|
@ -56,13 +56,13 @@
|
|||||||
import {ref} from "vue";
|
import {ref} from "vue";
|
||||||
import {Lock, UserFilled} from "@element-plus/icons-vue";
|
import {Lock, UserFilled} from "@element-plus/icons-vue";
|
||||||
import {httpGet, httpPost} from "@/utils/http";
|
import {httpGet, httpPost} from "@/utils/http";
|
||||||
import {ElMessage} from "element-plus";
|
|
||||||
import {useRouter} from "vue-router";
|
import {useRouter} from "vue-router";
|
||||||
import FooterBar from "@/components/FooterBar.vue";
|
import FooterBar from "@/components/FooterBar.vue";
|
||||||
import {isMobile} from "@/utils/libs";
|
import {isMobile} from "@/utils/libs";
|
||||||
import {checkSession} from "@/action/session";
|
import {checkSession} from "@/action/session";
|
||||||
import {setUserToken} from "@/store/session";
|
import {setUserToken} from "@/store/session";
|
||||||
import ResetPass from "@/components/ResetPass.vue";
|
import ResetPass from "@/components/ResetPass.vue";
|
||||||
|
import {showMessageError} from "@/utils/dialog";
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const title = ref('Geek-AI');
|
const title = ref('Geek-AI');
|
||||||
@ -76,7 +76,7 @@ httpGet("/api/config/get?key=system").then(res => {
|
|||||||
logo.value = res.data.logo
|
logo.value = res.data.logo
|
||||||
title.value = res.data.title
|
title.value = res.data.title
|
||||||
}).catch(e => {
|
}).catch(e => {
|
||||||
ElMessage.error("获取系统配置失败:" + e.message)
|
showMessageError("获取系统配置失败:" + e.message)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
@ -97,10 +97,10 @@ const handleKeyup = (e) => {
|
|||||||
|
|
||||||
const login = function () {
|
const login = function () {
|
||||||
if (username.value.trim() === '') {
|
if (username.value.trim() === '') {
|
||||||
return ElMessage.error("请输入用户民")
|
return showMessageError("请输入用户民")
|
||||||
}
|
}
|
||||||
if (password.value.trim() === '') {
|
if (password.value.trim() === '') {
|
||||||
return ElMessage.error('请输入密码');
|
return showMessageError('请输入密码');
|
||||||
}
|
}
|
||||||
|
|
||||||
httpPost('/api/user/login', {username: username.value.trim(), password: password.value.trim()}).then((res) => {
|
httpPost('/api/user/login', {username: username.value.trim(), password: password.value.trim()}).then((res) => {
|
||||||
@ -112,11 +112,10 @@ const login = function () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}).catch((e) => {
|
}).catch((e) => {
|
||||||
ElMessage.error('登录失败,' + e.message)
|
showMessageError('登录失败,' + e.message)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="stylus" scoped>
|
<style lang="stylus" scoped>
|
||||||
|
@ -264,9 +264,10 @@ const connect = (userId) => {
|
|||||||
|
|
||||||
_socket.addEventListener('close', () => {
|
_socket.addEventListener('close', () => {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
if (socket.value !== null) {
|
checkSession().then(() => {
|
||||||
connect(userId)
|
connect(userId)
|
||||||
}
|
}).catch(() => {
|
||||||
|
})
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,6 +180,7 @@ import SendMsg from "@/components/SendMsg.vue";
|
|||||||
import {arrayContains} from "@/utils/libs";
|
import {arrayContains} from "@/utils/libs";
|
||||||
import {setUserToken} from "@/store/session";
|
import {setUserToken} from "@/store/session";
|
||||||
import {validateEmail, validateMobile} from "@/utils/validate";
|
import {validateEmail, validateMobile} from "@/utils/validate";
|
||||||
|
import {showMessageError, showMessageOK} from "@/utils/dialog";
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const title = ref('Geek-AI 用户注册');
|
const title = ref('Geek-AI 用户注册');
|
||||||
@ -227,37 +228,37 @@ httpGet("/api/config/get?key=system").then(res => {
|
|||||||
// 注册操作
|
// 注册操作
|
||||||
const submitRegister = () => {
|
const submitRegister = () => {
|
||||||
if (data.value.username === '') {
|
if (data.value.username === '') {
|
||||||
return ElMessage.error('请输入用户名');
|
return showMessageError('请输入用户名');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (activeName.value === 'mobile' && !validateMobile(data.value.username)) {
|
if (activeName.value === 'mobile' && !validateMobile(data.value.username)) {
|
||||||
return ElMessage.error('请输入合法的手机号');
|
return showMessageError('请输入合法的手机号');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (activeName.value === 'email' && !validateEmail(data.value.username)) {
|
if (activeName.value === 'email' && !validateEmail(data.value.username)) {
|
||||||
return ElMessage.error('请输入合法的邮箱地址');
|
return showMessageError('请输入合法的邮箱地址');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.value.password.length < 8) {
|
if (data.value.password.length < 8) {
|
||||||
return ElMessage.error('密码的长度为8-16个字符');
|
return showMessageError('密码的长度为8-16个字符');
|
||||||
}
|
}
|
||||||
if (data.value.repass !== data.value.password) {
|
if (data.value.repass !== data.value.password) {
|
||||||
return ElMessage.error('两次输入密码不一致');
|
return showMessageError('两次输入密码不一致');
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((activeName.value === 'mobile' || activeName.value === 'email') && data.value.code === '') {
|
if ((activeName.value === 'mobile' || activeName.value === 'email') && data.value.code === '') {
|
||||||
return ElMessage.error('请输入验证码');
|
return showMessageError('请输入验证码');
|
||||||
}
|
}
|
||||||
data.value.reg_way = activeName.value
|
data.value.reg_way = activeName.value
|
||||||
httpPost('/api/user/register', data.value).then((res) => {
|
httpPost('/api/user/register', data.value).then((res) => {
|
||||||
setUserToken(res.data)
|
setUserToken(res.data)
|
||||||
ElMessage.success({
|
showMessageOK({
|
||||||
"message": "注册成功,即将跳转到对话主界面...",
|
"message": "注册成功,即将跳转到对话主界面...",
|
||||||
onClose: () => router.push("/chat"),
|
onClose: () => router.push("/chat"),
|
||||||
duration: 1000
|
duration: 1000
|
||||||
})
|
})
|
||||||
}).catch((e) => {
|
}).catch((e) => {
|
||||||
ElMessage.error('注册失败,' + e.message)
|
showMessageError('注册失败,' + e.message)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,6 +134,7 @@ import ChatReply from "@/components/mobile/ChatReply.vue";
|
|||||||
import {getSessionId, getUserToken} from "@/store/session";
|
import {getSessionId, getUserToken} from "@/store/session";
|
||||||
import {checkSession} from "@/action/session";
|
import {checkSession} from "@/action/session";
|
||||||
import Clipboard from "clipboard";
|
import Clipboard from "clipboard";
|
||||||
|
import {showLoginDialog} from "@/utils/dialog";
|
||||||
|
|
||||||
const winHeight = ref(0)
|
const winHeight = ref(0)
|
||||||
const navBarRef = ref(null)
|
const navBarRef = ref(null)
|
||||||
@ -178,6 +179,7 @@ httpGet('/api/model/list').then(res => {
|
|||||||
}
|
}
|
||||||
for (let i = 0; i < models.value.length; i++) {
|
for (let i = 0; i < models.value.length; i++) {
|
||||||
models.value[i].text = models.value[i].name
|
models.value[i].text = models.value[i].name
|
||||||
|
models.value[i].mValue = models.value[i].value
|
||||||
models.value[i].value = models.value[i].id
|
models.value[i].value = models.value[i].id
|
||||||
}
|
}
|
||||||
modelValue.value = getModelValue(modelId.value)
|
modelValue.value = getModelValue(modelId.value)
|
||||||
@ -223,7 +225,10 @@ onMounted(() => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
socket.value = null
|
if (socket.value !== null) {
|
||||||
|
socket.value.close()
|
||||||
|
socket.value = null
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const newChat = (item) => {
|
const newChat = (item) => {
|
||||||
@ -275,35 +280,38 @@ md.use(mathjaxPlugin)
|
|||||||
|
|
||||||
const onLoad = () => {
|
const onLoad = () => {
|
||||||
if (chatId.value) {
|
if (chatId.value) {
|
||||||
httpGet('/api/chat/history?chat_id=' + chatId.value).then(res => {
|
checkSession().then(() => {
|
||||||
// 加载状态结束
|
httpGet('/api/chat/history?chat_id=' + chatId.value).then(res => {
|
||||||
finished.value = true;
|
// 加载状态结束
|
||||||
const data = res.data
|
finished.value = true;
|
||||||
if (data && data.length > 0) {
|
const data = res.data
|
||||||
for (let i = 0; i < data.length; i++) {
|
if (data && data.length > 0) {
|
||||||
if (data[i].type === "prompt") {
|
for (let i = 0; i < data.length; i++) {
|
||||||
|
if (data[i].type === "prompt") {
|
||||||
|
chatData.value.push(data[i]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
data[i].orgContent = data[i].content;
|
||||||
|
data[i].content = md.render(processContent(data[i].content))
|
||||||
chatData.value.push(data[i]);
|
chatData.value.push(data[i]);
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
data[i].orgContent = data[i].content;
|
nextTick(() => {
|
||||||
data[i].content = md.render(processContent(data[i].content))
|
hl.configure({ignoreUnescapedHTML: true})
|
||||||
chatData.value.push(data[i]);
|
const blocks = document.querySelector("#message-list-box").querySelectorAll('pre code');
|
||||||
}
|
blocks.forEach((block) => {
|
||||||
|
hl.highlightElement(block)
|
||||||
|
})
|
||||||
|
|
||||||
nextTick(() => {
|
scrollListBox()
|
||||||
hl.configure({ignoreUnescapedHTML: true})
|
|
||||||
const blocks = document.querySelector("#message-list-box").querySelectorAll('pre code');
|
|
||||||
blocks.forEach((block) => {
|
|
||||||
hl.highlightElement(block)
|
|
||||||
})
|
})
|
||||||
|
}
|
||||||
scrollListBox()
|
connect(chatId.value, roleId.value, modelId.value);
|
||||||
})
|
}).catch(() => {
|
||||||
}
|
error.value = true
|
||||||
connect(chatId.value, roleId.value, modelId.value);
|
})
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
error.value = true
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -443,8 +451,7 @@ const connect = function (chat_id, role_id, model_id) {
|
|||||||
checkSession().then(() => {
|
checkSession().then(() => {
|
||||||
connect(chat_id, role_id, model_id)
|
connect(chat_id, role_id, model_id)
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
loading.value = true
|
showLoginDialog(router)
|
||||||
setTimeout(() => connect(chat_id, role_id, model_id), 3000)
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -549,7 +556,7 @@ const getRoleById = function (rid) {
|
|||||||
const getModelValue = (model_id) => {
|
const getModelValue = (model_id) => {
|
||||||
for (let i = 0; i < models.value.length; i++) {
|
for (let i = 0; i < models.value.length; i++) {
|
||||||
if (models.value[i].id === model_id) {
|
if (models.value[i].id === model_id) {
|
||||||
return models.value[i].value
|
return models.value[i].mValue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
|
@ -57,16 +57,6 @@ bus.on('changeTheme', (value) => {
|
|||||||
background #1c1c1e
|
background #1c1c1e
|
||||||
}
|
}
|
||||||
|
|
||||||
.van-toast--fail {
|
|
||||||
background #fef0f0
|
|
||||||
color #f56c6c
|
|
||||||
}
|
|
||||||
|
|
||||||
.van-toast--success {
|
|
||||||
background #D6FBCC
|
|
||||||
color #07C160
|
|
||||||
}
|
|
||||||
|
|
||||||
.van-nav-bar {
|
.van-nav-bar {
|
||||||
position fixed
|
position fixed
|
||||||
width 100%
|
width 100%
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="mobile-image container">
|
<div class="mobile-image container">
|
||||||
<van-tabs v-model:active="activeName" class="my-tab" animated sticky>
|
<van-tabs v-model:active="activeName" class="my-tab" animated sticky>
|
||||||
<van-tab title="MidJourney" name="mj">
|
<van-tab title="MJ" name="mj">
|
||||||
<image-mj/>
|
<image-mj/>
|
||||||
</van-tab>
|
</van-tab>
|
||||||
<van-tab title="Stable-Diffusion" name="sd">
|
<van-tab title="SD" name="sd">
|
||||||
<image-sd/>
|
<image-sd/>
|
||||||
</van-tab>
|
</van-tab>
|
||||||
<van-tab title="DALL-E" name="dall">
|
<van-tab title="DALL" name="dall">
|
||||||
<van-empty description="功能正在开发中"/>
|
<van-empty description="功能正在开发中"/>
|
||||||
</van-tab>
|
</van-tab>
|
||||||
</van-tabs>
|
</van-tabs>
|
||||||
|
@ -95,6 +95,7 @@ onMounted(() => {
|
|||||||
checkSession().then((user) => {
|
checkSession().then((user) => {
|
||||||
isLogin.value = true
|
isLogin.value = true
|
||||||
roles.value = user.chat_roles
|
roles.value = user.chat_roles
|
||||||
|
}).catch(() => {
|
||||||
})
|
})
|
||||||
fetchApps()
|
fetchApps()
|
||||||
})
|
})
|
||||||
|
@ -276,14 +276,7 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import {nextTick, onMounted, onUnmounted, ref} from "vue";
|
import {nextTick, onMounted, onUnmounted, ref} from "vue";
|
||||||
import {
|
import {showConfirmDialog, showFailToast, showImagePreview, showNotify, showSuccessToast, showToast} from "vant";
|
||||||
showConfirmDialog,
|
|
||||||
showFailToast,
|
|
||||||
showNotify,
|
|
||||||
showToast,
|
|
||||||
showImagePreview,
|
|
||||||
showSuccessToast
|
|
||||||
} from "vant";
|
|
||||||
import {httpGet, httpPost} from "@/utils/http";
|
import {httpGet, httpPost} from "@/utils/http";
|
||||||
import Compressor from "compressorjs";
|
import Compressor from "compressorjs";
|
||||||
import {getSessionId} from "@/store/session";
|
import {getSessionId} from "@/store/session";
|
||||||
@ -364,8 +357,11 @@ onMounted(() => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
socket.value = null
|
|
||||||
clipboard.value.destroy()
|
clipboard.value.destroy()
|
||||||
|
if (socket.value !== null) {
|
||||||
|
socket.value.close()
|
||||||
|
socket.value = null
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const mjPower = ref(1)
|
const mjPower = ref(1)
|
||||||
|
@ -221,7 +221,8 @@ import {checkSession} from "@/action/session";
|
|||||||
import {useRouter} from "vue-router";
|
import {useRouter} from "vue-router";
|
||||||
import {getSessionId} from "@/store/session";
|
import {getSessionId} from "@/store/session";
|
||||||
import {
|
import {
|
||||||
showConfirmDialog, showDialog,
|
showConfirmDialog,
|
||||||
|
showDialog,
|
||||||
showFailToast,
|
showFailToast,
|
||||||
showImagePreview,
|
showImagePreview,
|
||||||
showNotify,
|
showNotify,
|
||||||
@ -357,7 +358,10 @@ onMounted(() => {
|
|||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
clipboard.value.destroy()
|
clipboard.value.destroy()
|
||||||
socket.value = null
|
if (socket.value !== null) {
|
||||||
|
socket.value.close()
|
||||||
|
socket.value = null
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<div class="img-wall container">
|
<div class="img-wall container">
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<van-tabs v-model:active="activeName" animated sticky>
|
<van-tabs v-model:active="activeName" animated sticky>
|
||||||
<van-tab title="MidJourney" name="mj">
|
<van-tab title="MJ" name="mj">
|
||||||
<van-list
|
<van-list
|
||||||
v-model:error="data['mj'].error"
|
v-model:error="data['mj'].error"
|
||||||
v-model:loading="data['mj'].loading"
|
v-model:loading="data['mj'].loading"
|
||||||
@ -23,7 +23,7 @@
|
|||||||
</van-cell>
|
</van-cell>
|
||||||
</van-list>
|
</van-list>
|
||||||
</van-tab>
|
</van-tab>
|
||||||
<van-tab title="StableDiffusion" name="sd">
|
<van-tab title="SD" name="sd">
|
||||||
<van-list
|
<van-list
|
||||||
v-model:error="data['sd'].error"
|
v-model:error="data['sd'].error"
|
||||||
v-model:loading="data['sd'].loading"
|
v-model:loading="data['sd'].loading"
|
||||||
@ -43,7 +43,7 @@
|
|||||||
</van-cell>
|
</van-cell>
|
||||||
</van-list>
|
</van-list>
|
||||||
</van-tab>
|
</van-tab>
|
||||||
<van-tab title="DALLE3" name="dalle3">
|
<van-tab title="DALL" name="dalle3">
|
||||||
<van-empty description="功能正在开发中"/>
|
<van-empty description="功能正在开发中"/>
|
||||||
</van-tab>
|
</van-tab>
|
||||||
</van-tabs>
|
</van-tabs>
|
||||||
@ -57,8 +57,7 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import {onMounted, onUnmounted, ref} from "vue";
|
import {onMounted, onUnmounted, ref} from "vue";
|
||||||
import {httpGet} from "@/utils/http";
|
import {httpGet} from "@/utils/http";
|
||||||
import {showConfirmDialog, showDialog, showFailToast, showImagePreview, showNotify} from "vant";
|
import {showConfirmDialog, showFailToast, showImagePreview, showNotify} from "vant";
|
||||||
import {Delete} from "@element-plus/icons-vue";
|
|
||||||
import Clipboard from "clipboard";
|
import Clipboard from "clipboard";
|
||||||
import {ElMessage} from "element-plus";
|
import {ElMessage} from "element-plus";
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user