mirror of
https://github.com/yangjian102621/geekai.git
synced 2025-09-21 10:46:39 +08:00
feat: add system config for enable rand background image for index page
This commit is contained in:
parent
f0959b5df6
commit
99fd596862
@ -227,7 +227,6 @@ func needLogin(c *gin.Context) bool {
|
||||
c.Request.URL.Path == "/api/sd/client" ||
|
||||
c.Request.URL.Path == "/api/dall/imgWall" ||
|
||||
c.Request.URL.Path == "/api/dall/client" ||
|
||||
c.Request.URL.Path == "/api/config/get" ||
|
||||
c.Request.URL.Path == "/api/product/list" ||
|
||||
c.Request.URL.Path == "/api/menu/list" ||
|
||||
c.Request.URL.Path == "/api/markMap/client" ||
|
||||
@ -237,6 +236,7 @@ func needLogin(c *gin.Context) bool {
|
||||
c.Request.URL.Path == "/api/payment/doPay" ||
|
||||
c.Request.URL.Path == "/api/payment/payWays" ||
|
||||
strings.HasPrefix(c.Request.URL.Path, "/api/test") ||
|
||||
strings.HasPrefix(c.Request.URL.Path, "/api/config/") ||
|
||||
strings.HasPrefix(c.Request.URL.Path, "/api/function/") ||
|
||||
strings.HasPrefix(c.Request.URL.Path, "/api/sms/") ||
|
||||
strings.HasPrefix(c.Request.URL.Path, "/api/captcha/") ||
|
||||
|
@ -126,11 +126,16 @@ type RedisConfig struct {
|
||||
const LicenseKey = "Geek-AI-License"
|
||||
|
||||
type License struct {
|
||||
Key string `json:"key"` // 许可证书密钥
|
||||
MachineId string `json:"machine_id"` // 机器码
|
||||
UserNum int `json:"user_num"` // 用户数量
|
||||
ExpiredAt int64 `json:"expired_at"` // 过期时间
|
||||
IsActive bool `json:"is_active"` // 是否激活
|
||||
Key string `json:"key"` // 许可证书密钥
|
||||
MachineId string `json:"machine_id"` // 机器码
|
||||
ExpiredAt int64 `json:"expired_at"` // 过期时间
|
||||
IsActive bool `json:"is_active"` // 是否激活
|
||||
Configs LicenseConfig `json:"configs"`
|
||||
}
|
||||
|
||||
type LicenseConfig struct {
|
||||
UserNum int `json:"user_num"` // 用户数量
|
||||
DeCopy bool `json:"de_copy"` // 去版权
|
||||
}
|
||||
|
||||
func (c RedisConfig) Url() string {
|
||||
@ -207,4 +212,6 @@ type SystemConfig struct {
|
||||
ContextDeep int `json:"context_deep,omitempty"`
|
||||
|
||||
SdNegPrompt string `json:"sd_neg_prompt"` // SD 默认反向提示词
|
||||
|
||||
RandBg bool `json:"rand_bg"` // 前端首页是否启用随机背景
|
||||
}
|
||||
|
@ -87,7 +87,7 @@ func (h *UserHandler) Save(c *gin.Context) {
|
||||
// 检测最大注册人数
|
||||
var totalUser int64
|
||||
h.DB.Model(&model.User{}).Count(&totalUser)
|
||||
if h.licenseService.GetLicense().UserNum > 0 && int(totalUser) >= h.licenseService.GetLicense().UserNum {
|
||||
if h.licenseService.GetLicense().Configs.UserNum > 0 && int(totalUser) >= h.licenseService.GetLicense().Configs.UserNum {
|
||||
resp.ERROR(c, "当前注册用户数已达上限,请请升级 License")
|
||||
return
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ package handler
|
||||
|
||||
import (
|
||||
"geekai/core"
|
||||
"geekai/service"
|
||||
"geekai/store/model"
|
||||
"geekai/utils"
|
||||
"geekai/utils/resp"
|
||||
@ -19,10 +20,11 @@ import (
|
||||
|
||||
type ConfigHandler struct {
|
||||
BaseHandler
|
||||
licenseService *service.LicenseService
|
||||
}
|
||||
|
||||
func NewConfigHandler(app *core.AppServer, db *gorm.DB) *ConfigHandler {
|
||||
return &ConfigHandler{BaseHandler: BaseHandler{App: app, DB: db}}
|
||||
func NewConfigHandler(app *core.AppServer, db *gorm.DB, licenseService *service.LicenseService) *ConfigHandler {
|
||||
return &ConfigHandler{BaseHandler: BaseHandler{App: app, DB: db}, licenseService: licenseService}
|
||||
}
|
||||
|
||||
// Get 获取指定的系统配置
|
||||
@ -44,3 +46,9 @@ func (h *ConfigHandler) Get(c *gin.Context) {
|
||||
|
||||
resp.SUCCESS(c, value)
|
||||
}
|
||||
|
||||
// License 获取 License 配置
|
||||
func (h *ConfigHandler) License(c *gin.Context) {
|
||||
license := h.licenseService.GetLicense()
|
||||
resp.SUCCESS(c, license.Configs)
|
||||
}
|
||||
|
@ -71,7 +71,7 @@ func (h *UserHandler) Register(c *gin.Context) {
|
||||
// 检测最大注册人数
|
||||
var totalUser int64
|
||||
h.DB.Model(&model.User{}).Count(&totalUser)
|
||||
if h.licenseService.GetLicense().UserNum > 0 && int(totalUser) >= h.licenseService.GetLicense().UserNum {
|
||||
if h.licenseService.GetLicense().Configs.UserNum > 0 && int(totalUser) >= h.licenseService.GetLicense().Configs.UserNum {
|
||||
resp.ERROR(c, "当前注册用户数已达上限,请请升级 License")
|
||||
return
|
||||
}
|
||||
|
@ -295,6 +295,7 @@ func main() {
|
||||
fx.Invoke(func(s *core.AppServer, h *handler.ConfigHandler) {
|
||||
group := s.Engine.Group("/api/config/")
|
||||
group.GET("get", h.Get)
|
||||
group.GET("license", h.License)
|
||||
}),
|
||||
|
||||
// 管理后台控制器
|
||||
|
@ -46,12 +46,13 @@ func NewLicenseService(server *core.AppServer, levelDB *store.LevelDB) *LicenseS
|
||||
}
|
||||
|
||||
type License struct {
|
||||
Name string `json:"name"`
|
||||
License string `json:"license"`
|
||||
MachineId string `json:"mid"`
|
||||
ActiveAt int64 `json:"active_at"`
|
||||
ExpiredAt int64 `json:"expired_at"`
|
||||
UserNum int `json:"user_num"`
|
||||
Name string `json:"name"`
|
||||
License string `json:"license"`
|
||||
MachineId string `json:"mid"`
|
||||
ActiveAt int64 `json:"active_at"`
|
||||
ExpiredAt int64 `json:"expired_at"`
|
||||
UserNum int `json:"user_num"`
|
||||
Configs types.LicenseConfig `json:"configs"`
|
||||
}
|
||||
|
||||
// ActiveLicense 激活 License
|
||||
@ -80,7 +81,7 @@ func (s *LicenseService) ActiveLicense(license string, machineId string) error {
|
||||
s.license = &types.License{
|
||||
Key: license,
|
||||
MachineId: machineId,
|
||||
UserNum: res.Data.UserNum,
|
||||
Configs: res.Data.Configs,
|
||||
ExpiredAt: res.Data.ExpiredAt,
|
||||
IsActive: true,
|
||||
}
|
||||
@ -140,7 +141,7 @@ func (s *LicenseService) fetchLicense() (*types.License, error) {
|
||||
return &types.License{
|
||||
Key: res.Data.License,
|
||||
MachineId: res.Data.MachineId,
|
||||
UserNum: res.Data.UserNum,
|
||||
Configs: res.Data.Configs,
|
||||
ExpiredAt: res.Data.ExpiredAt,
|
||||
IsActive: true,
|
||||
}, nil
|
||||
|
@ -11,8 +11,8 @@
|
||||
</div>
|
||||
|
||||
<div class="navbar">
|
||||
|
||||
<el-tooltip
|
||||
v-if="!licenseConfig.de_copy"
|
||||
class="box-item"
|
||||
effect="light"
|
||||
content="部署文档"
|
||||
@ -23,6 +23,7 @@
|
||||
</el-tooltip>
|
||||
|
||||
<el-tooltip
|
||||
v-if="!licenseConfig.de_copy"
|
||||
class="box-item"
|
||||
effect="light"
|
||||
content="项目源码"
|
||||
@ -140,6 +141,7 @@ import {removeUserToken} from "@/store/session";
|
||||
import LoginDialog from "@/components/LoginDialog.vue";
|
||||
import {useSharedStore} from "@/store/sharedata";
|
||||
import ConfigDialog from "@/components/ConfigDialog.vue";
|
||||
import {showMessageError} from "@/utils/dialog";
|
||||
|
||||
const router = useRouter();
|
||||
const logo = ref('/images/logo.png');
|
||||
@ -152,6 +154,7 @@ const loginUser = ref({})
|
||||
const version = ref(process.env.VUE_APP_VERSION)
|
||||
const routerViewKey = ref(0)
|
||||
const showConfigDialog = ref(false)
|
||||
const licenseConfig = ref({})
|
||||
|
||||
const store = useSharedStore();
|
||||
const show = ref(false)
|
||||
@ -191,6 +194,12 @@ onMounted(() => {
|
||||
ElMessage.error("获取系统菜单失败:" + e.message)
|
||||
})
|
||||
|
||||
httpGet("/api/config/license").then(res => {
|
||||
licenseConfig.value = res.data
|
||||
}).catch(e => {
|
||||
showMessageError("获取 License 配置:" + e.message)
|
||||
})
|
||||
|
||||
init()
|
||||
})
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="index-page" :style="{height: winHeight+'px'}">
|
||||
<div class="bg"></div>
|
||||
<div :class="bgClass"></div>
|
||||
<div class="menu-box">
|
||||
<el-menu
|
||||
mode="horizontal"
|
||||
@ -11,7 +11,8 @@
|
||||
<div class="title">{{ title }}</div>
|
||||
</div>
|
||||
<div class="menu-item">
|
||||
<a href="https://ai.r9it.com/docs/install/" target="_blank">
|
||||
<span v-if="!licenseConfig.de_copy">
|
||||
<a href="https://ai.r9it.com/docs/install/" target="_blank">
|
||||
<el-button type="primary" round>
|
||||
<i class="iconfont icon-book"></i>
|
||||
<span>部署文档</span>
|
||||
@ -24,6 +25,7 @@
|
||||
<span>项目源码</span>
|
||||
</el-button>
|
||||
</a>
|
||||
</span>
|
||||
<el-button @click="router.push('/login')" round>登录</el-button>
|
||||
<el-button @click="router.push('/register')" round>注册</el-button>
|
||||
</div>
|
||||
@ -52,7 +54,7 @@
|
||||
<!-- <div id="animation-container"></div>-->
|
||||
</div>
|
||||
|
||||
<div class="footer">
|
||||
<div class="footer" v-if="!licenseConfig.de_copy">
|
||||
<footer-bar />
|
||||
</div>
|
||||
</div>
|
||||
@ -77,73 +79,31 @@ if (isMobile()) {
|
||||
const title = ref("Geek-AI 创作系统")
|
||||
const logo = ref("/images/logo.png")
|
||||
const slogan = ref("我辈之人,先干为敬,陪您先把 AI 用起来")
|
||||
const licenseConfig = ref({})
|
||||
// const size = Math.max(window.innerWidth * 0.5, window.innerHeight * 0.8)
|
||||
const winHeight = window.innerHeight - 150
|
||||
const bgClass = ref('fixed-bg')
|
||||
|
||||
onMounted(() => {
|
||||
httpGet("/api/config/get?key=system").then(res => {
|
||||
title.value = res.data.title
|
||||
logo.value = res.data.logo
|
||||
if (res.data.rand_bg) {
|
||||
bgClass.value = "rand-bg"
|
||||
}
|
||||
}).catch(e => {
|
||||
ElMessage.error("获取系统配置失败:" + e.message)
|
||||
})
|
||||
|
||||
httpGet("/api/config/license").then(res => {
|
||||
licenseConfig.value = res.data
|
||||
}).catch(e => {
|
||||
ElMessage.error("获取 License 配置:" + e.message)
|
||||
})
|
||||
init()
|
||||
})
|
||||
|
||||
const init = () => {
|
||||
// // 创建场景
|
||||
// // 创建场景
|
||||
// const scene = new THREE.Scene();
|
||||
//
|
||||
// // 创建相机
|
||||
// const camera = new THREE.PerspectiveCamera(30, 1, 0.1, 1000);
|
||||
// camera.position.z = 3.88;
|
||||
//
|
||||
// // 创建渲染器
|
||||
// const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
|
||||
// renderer.setSize(size, size);
|
||||
// renderer.setClearColor(0x000000, 0);
|
||||
// const container = document.getElementById('animation-container');
|
||||
// container.appendChild(renderer.domElement);
|
||||
//
|
||||
// // 加载地球纹理
|
||||
// const loader = new THREE.TextureLoader();
|
||||
// loader.load(
|
||||
// '/images/land_ocean_ice_cloud_2048.jpg',
|
||||
// function (texture) {
|
||||
// // 创建地球球体
|
||||
// const geometry = new THREE.SphereGeometry(1, 32, 32);
|
||||
// const material = new THREE.MeshPhongMaterial({
|
||||
// map: texture,
|
||||
// bumpMap: texture, // 使用同一张纹理作为凹凸贴图
|
||||
// bumpScale: 0.05, // 调整凹凸贴图的影响程度
|
||||
// specularMap: texture, // 高光贴图
|
||||
// specular: new THREE.Color('#01193B'), // 高光颜色
|
||||
// });
|
||||
// const earth = new THREE.Mesh(geometry, material);
|
||||
// scene.add(earth);
|
||||
//
|
||||
// // 添加环境光和点光源
|
||||
// const ambientLight = new THREE.AmbientLight(0xffffff, 0.3);
|
||||
// scene.add(ambientLight);
|
||||
// const pointLight = new THREE.PointLight(0xffffff, 0.8);
|
||||
// pointLight.position.set(5, 5, 5);
|
||||
// scene.add(pointLight);
|
||||
//
|
||||
// // 创建动画
|
||||
// const animate = function () {
|
||||
// requestAnimationFrame(animate);
|
||||
//
|
||||
// // 使地球自转和公转
|
||||
// earth.rotation.y += 0.0006;
|
||||
//
|
||||
// renderer.render(scene, camera);
|
||||
// };
|
||||
//
|
||||
// // 执行动画
|
||||
// animate();
|
||||
// }
|
||||
// );
|
||||
}
|
||||
</script>
|
||||
|
||||
@ -158,14 +118,25 @@ const init = () => {
|
||||
align-items baseline
|
||||
padding-top 150px
|
||||
|
||||
.bg {
|
||||
.fixed-bg {
|
||||
position absolute
|
||||
top 0
|
||||
left 0
|
||||
width 100vw
|
||||
height 100vh
|
||||
background-image url("~@/assets/img/ai-bg.jpg")
|
||||
//filter: blur(8px);
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
}
|
||||
|
||||
.rand-bg {
|
||||
position absolute
|
||||
top 0
|
||||
left 0
|
||||
width 100vw
|
||||
height 100vh
|
||||
background-image url("https://api.dujin.org/bing/1920.php")
|
||||
filter: blur(8px);
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
}
|
||||
|
@ -48,7 +48,7 @@
|
||||
|
||||
<reset-pass @hide="showResetPass = false" :show="showResetPass"/>
|
||||
|
||||
<footer class="footer">
|
||||
<footer class="footer" v-if="!licenseConfig.de_copy">
|
||||
<footer-bar/>
|
||||
</footer>
|
||||
</div>
|
||||
@ -74,6 +74,7 @@ const username = ref(process.env.VUE_APP_USER);
|
||||
const password = ref(process.env.VUE_APP_PASS);
|
||||
const showResetPass = ref(false)
|
||||
const logo = ref("/images/logo.png")
|
||||
const licenseConfig = ref({})
|
||||
|
||||
// 获取系统配置
|
||||
httpGet("/api/config/get?key=system").then(res => {
|
||||
@ -83,6 +84,11 @@ httpGet("/api/config/get?key=system").then(res => {
|
||||
showMessageError("获取系统配置失败:" + e.message)
|
||||
})
|
||||
|
||||
httpGet("/api/config/license").then(res => {
|
||||
licenseConfig.value = res.data
|
||||
}).catch(e => {
|
||||
showMessageError("获取 License 配置:" + e.message)
|
||||
})
|
||||
|
||||
checkSession().then(() => {
|
||||
if (isMobile()) {
|
||||
|
@ -160,7 +160,7 @@
|
||||
</el-result>
|
||||
</div>
|
||||
|
||||
<footer class="footer">
|
||||
<footer class="footer" v-if="!licenseConfig.de_copy">
|
||||
<footer-bar/>
|
||||
</footer>
|
||||
</div>
|
||||
@ -199,6 +199,7 @@ const enableUser = ref(false)
|
||||
const enableRegister = ref(false)
|
||||
const activeName = ref("mobile")
|
||||
const wxImg = ref("/images/wx.png")
|
||||
const licenseConfig = ref({})
|
||||
|
||||
httpGet("/api/config/get?key=system").then(res => {
|
||||
if (res.data) {
|
||||
@ -225,6 +226,12 @@ httpGet("/api/config/get?key=system").then(res => {
|
||||
ElMessage.error("获取系统配置失败:" + e.message)
|
||||
})
|
||||
|
||||
httpGet("/api/config/license").then(res => {
|
||||
licenseConfig.value = res.data
|
||||
}).catch(e => {
|
||||
showMessageError("获取 License 配置:" + e.message)
|
||||
})
|
||||
|
||||
// 注册操作
|
||||
const submitRegister = () => {
|
||||
if (data.value.username === '') {
|
||||
|
@ -133,6 +133,8 @@
|
||||
<template #default="scope">
|
||||
<div class="context-msg-content">
|
||||
<el-input
|
||||
type="textarea"
|
||||
:rows="2"
|
||||
v-model="scope.row.content"
|
||||
autocomplete="off"
|
||||
/>
|
||||
|
@ -44,6 +44,20 @@
|
||||
</el-tooltip>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="随机背景">
|
||||
<el-switch v-model="system['rand_bg']"/>
|
||||
<el-tooltip
|
||||
effect="dark"
|
||||
content="打开之后前端首页将使用随机壁纸作为背景图"
|
||||
raw-content
|
||||
placement="right"
|
||||
>
|
||||
<el-icon>
|
||||
<InfoFilled/>
|
||||
</el-icon>
|
||||
</el-tooltip>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="注册方式" prop="register_ways">
|
||||
<el-checkbox-group v-model="system['register_ways']">
|
||||
<el-checkbox value="mobile">手机注册</el-checkbox>
|
||||
@ -298,16 +312,22 @@
|
||||
<el-descriptions
|
||||
v-if="license.is_active"
|
||||
class="margin-top"
|
||||
title="授权信息"
|
||||
:column="3"
|
||||
title="已授权信息"
|
||||
:column="1"
|
||||
border
|
||||
>
|
||||
<el-descriptions-item :span="3" :width="150">
|
||||
<el-descriptions-item>
|
||||
<template #label>
|
||||
<div class="cell-item">License Key</div>
|
||||
</template>
|
||||
{{ license.key }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item>
|
||||
<template #label>
|
||||
<div class="cell-item">机器码</div>
|
||||
</template>
|
||||
{{ license.machine_id }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item>
|
||||
<template #label>
|
||||
<div class="cell-item">到期时间</div>
|
||||
@ -318,13 +338,15 @@
|
||||
<template #label>
|
||||
<div class="cell-item">用户人数</div>
|
||||
</template>
|
||||
{{ license.user_num }}
|
||||
{{ license.configs?.user_num }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item>
|
||||
<template #label>
|
||||
<div class="cell-item">机器码</div>
|
||||
<div class="cell-item">去版权</div>
|
||||
</template>
|
||||
{{ license.machine_id }}
|
||||
<el-icon class="selected" v-if="license.configs?.de_copy"><Select /></el-icon>
|
||||
<el-icon class="closed" v-else><CloseBold /></el-icon>
|
||||
<span class="text">去版权之后前端页面将不会显示版权信息和源码地址</span>
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
|
||||
@ -348,7 +370,7 @@ import {onMounted, reactive, ref} from "vue";
|
||||
import {httpGet, httpPost} from "@/utils/http";
|
||||
import Compressor from "compressorjs";
|
||||
import {ElMessage} from "element-plus";
|
||||
import {InfoFilled, UploadFilled} from "@element-plus/icons-vue";
|
||||
import {InfoFilled, UploadFilled,Select,CloseBold} from "@element-plus/icons-vue";
|
||||
import MdEditor from "md-editor-v3";
|
||||
import 'md-editor-v3/lib/style.css';
|
||||
import Menu from "@/views/admin/Menu.vue";
|
||||
@ -536,6 +558,23 @@ const onUploadImg = (files, callback) => {
|
||||
|
||||
.el-descriptions {
|
||||
margin-bottom 20px
|
||||
.el-icon {
|
||||
font-size 18px
|
||||
}
|
||||
.selected {
|
||||
color #0bc15f
|
||||
}
|
||||
|
||||
.closed {
|
||||
color #da0d54
|
||||
}
|
||||
.text {
|
||||
margin-left 10px
|
||||
font-size 12px
|
||||
color #999999
|
||||
position: relative;
|
||||
top -5px
|
||||
}
|
||||
}
|
||||
|
||||
.el-alert {
|
||||
|
Loading…
Reference in New Issue
Block a user