Merge remote-tracking branch 'refs/remotes/origin/dev-281'
This commit is contained in:
@@ -12,18 +12,31 @@ import (
|
||||
// GormMysql 初始化Mysql数据库
|
||||
// Author [piexlmax](https://github.com/piexlmax)
|
||||
// Author [SliverHorn](https://github.com/SliverHorn)
|
||||
// Author [ByteZhou-2018](https://github.com/ByteZhou-2018)
|
||||
func GormMysql() *gorm.DB {
|
||||
m := global.GVA_CONFIG.Mysql
|
||||
return initMysqlDatabase(m)
|
||||
}
|
||||
|
||||
// GormMysqlByConfig 通过传入配置初始化Mysql数据库
|
||||
func GormMysqlByConfig(m config.Mysql) *gorm.DB {
|
||||
return initMysqlDatabase(m)
|
||||
}
|
||||
|
||||
// initMysqlDatabase 初始化Mysql数据库的辅助函数
|
||||
func initMysqlDatabase(m config.Mysql) *gorm.DB {
|
||||
if m.Dbname == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
mysqlConfig := mysql.Config{
|
||||
DSN: m.Dsn(), // DSN data source name
|
||||
DefaultStringSize: 191, // string 类型字段的默认长度
|
||||
SkipInitializeWithVersion: false, // 根据版本自动配置
|
||||
}
|
||||
|
||||
if db, err := gorm.Open(mysql.New(mysqlConfig), internal.Gorm.Config(m.Prefix, m.Singular)); err != nil {
|
||||
return nil
|
||||
panic(err)
|
||||
} else {
|
||||
db.InstanceSet("gorm:table_options", "ENGINE="+m.Engine)
|
||||
sqlDB, _ := db.DB()
|
||||
@@ -32,24 +45,3 @@ func GormMysql() *gorm.DB {
|
||||
return db
|
||||
}
|
||||
}
|
||||
|
||||
// GormMysqlByConfig 初始化Mysql数据库用过传入配置
|
||||
func GormMysqlByConfig(m config.Mysql) *gorm.DB {
|
||||
if m.Dbname == "" {
|
||||
return nil
|
||||
}
|
||||
mysqlConfig := mysql.Config{
|
||||
DSN: m.Dsn(), // DSN data source name
|
||||
DefaultStringSize: 191, // string 类型字段的默认长度
|
||||
SkipInitializeWithVersion: false, // 根据版本自动配置
|
||||
}
|
||||
if db, err := gorm.Open(mysql.New(mysqlConfig), internal.Gorm.Config(m.Prefix, m.Singular)); err != nil {
|
||||
panic(err)
|
||||
} else {
|
||||
db.InstanceSet("gorm:table_options", "ENGINE=InnoDB")
|
||||
sqlDB, _ := db.DB()
|
||||
sqlDB.SetMaxIdleConns(m.MaxIdleConns)
|
||||
sqlDB.SetMaxOpenConns(m.MaxOpenConns)
|
||||
return db
|
||||
}
|
||||
}
|
||||
|
@@ -15,32 +15,25 @@ import (
|
||||
// 如果需要Oracle库 放开import里的注释 把下方 mysql.Config 改为 oracle.Config ; mysql.New 改为 oracle.New
|
||||
func GormOracle() *gorm.DB {
|
||||
m := global.GVA_CONFIG.Oracle
|
||||
if m.Dbname == "" {
|
||||
return nil
|
||||
}
|
||||
oracleConfig := mysql.Config{
|
||||
DSN: m.Dsn(), // DSN data source name
|
||||
DefaultStringSize: 191, // string 类型字段的默认长度
|
||||
}
|
||||
if db, err := gorm.Open(mysql.New(oracleConfig), internal.Gorm.Config(m.Prefix, m.Singular)); err != nil {
|
||||
panic(err)
|
||||
} else {
|
||||
sqlDB, _ := db.DB()
|
||||
sqlDB.SetMaxIdleConns(m.MaxIdleConns)
|
||||
sqlDB.SetMaxOpenConns(m.MaxOpenConns)
|
||||
return db
|
||||
}
|
||||
return initOracleDatabase(m)
|
||||
}
|
||||
|
||||
// GormOracleByConfig 初始化Oracle数据库用过传入配置
|
||||
func GormOracleByConfig(m config.Oracle) *gorm.DB {
|
||||
return initOracleDatabase(m)
|
||||
}
|
||||
|
||||
// initOracleDatabase 初始化Oracle数据库的辅助函数
|
||||
func initOracleDatabase(m config.Oracle) *gorm.DB {
|
||||
if m.Dbname == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
oracleConfig := mysql.Config{
|
||||
DSN: m.Dsn(), // DSN data source name
|
||||
DefaultStringSize: 191, // string 类型字段的默认长度
|
||||
}
|
||||
|
||||
if db, err := gorm.Open(mysql.New(oracleConfig), internal.Gorm.Config(m.Prefix, m.Singular)); err != nil {
|
||||
panic(err)
|
||||
} else {
|
||||
|
@@ -13,25 +13,16 @@ import (
|
||||
// Author [SliverHorn](https://github.com/SliverHorn)
|
||||
func GormPgSql() *gorm.DB {
|
||||
p := global.GVA_CONFIG.Pgsql
|
||||
if p.Dbname == "" {
|
||||
return nil
|
||||
}
|
||||
pgsqlConfig := postgres.Config{
|
||||
DSN: p.Dsn(), // DSN data source name
|
||||
PreferSimpleProtocol: false,
|
||||
}
|
||||
if db, err := gorm.Open(postgres.New(pgsqlConfig), internal.Gorm.Config(p.Prefix, p.Singular)); err != nil {
|
||||
return nil
|
||||
} else {
|
||||
sqlDB, _ := db.DB()
|
||||
sqlDB.SetMaxIdleConns(p.MaxIdleConns)
|
||||
sqlDB.SetMaxOpenConns(p.MaxOpenConns)
|
||||
return db
|
||||
}
|
||||
return initPgSqlDatabase(p)
|
||||
}
|
||||
|
||||
// GormPgSqlByConfig 初始化 Postgresql 数据库 通过参数
|
||||
// GormPgSqlByConfig 初始化 Postgresql 数据库 通过指定参数
|
||||
func GormPgSqlByConfig(p config.Pgsql) *gorm.DB {
|
||||
return initPgSqlDatabase(p)
|
||||
}
|
||||
|
||||
// initPgSqlDatabase 初始化 Postgresql 数据库的辅助函数
|
||||
func initPgSqlDatabase(p config.Pgsql) *gorm.DB {
|
||||
if p.Dbname == "" {
|
||||
return nil
|
||||
}
|
||||
|
@@ -11,22 +11,16 @@ import (
|
||||
// GormSqlite 初始化Sqlite数据库
|
||||
func GormSqlite() *gorm.DB {
|
||||
s := global.GVA_CONFIG.Sqlite
|
||||
if s.Dbname == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
if db, err := gorm.Open(sqlite.Open(s.Dsn()), internal.Gorm.Config(s.Prefix, s.Singular)); err != nil {
|
||||
panic(err)
|
||||
} else {
|
||||
sqlDB, _ := db.DB()
|
||||
sqlDB.SetMaxIdleConns(s.MaxIdleConns)
|
||||
sqlDB.SetMaxOpenConns(s.MaxOpenConns)
|
||||
return db
|
||||
}
|
||||
return initSqliteDatabase(s)
|
||||
}
|
||||
|
||||
// GormSqliteByConfig 初始化Sqlite数据库用过传入配置
|
||||
func GormSqliteByConfig(s config.Sqlite) *gorm.DB {
|
||||
return initSqliteDatabase(s)
|
||||
}
|
||||
|
||||
// initSqliteDatabase 初始化Sqlite数据库辅助函数
|
||||
func initSqliteDatabase(s config.Sqlite) *gorm.DB {
|
||||
if s.Dbname == "" {
|
||||
return nil
|
||||
}
|
||||
|
@@ -2,10 +2,11 @@ package system
|
||||
|
||||
import (
|
||||
"context"
|
||||
model "github.com/flipped-aurora/gin-vue-admin/server/model/system"
|
||||
"github.com/flipped-aurora/gin-vue-admin/server/model/system/request"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
model "github.com/flipped-aurora/gin-vue-admin/server/model/system"
|
||||
"github.com/flipped-aurora/gin-vue-admin/server/model/system/request"
|
||||
)
|
||||
|
||||
func Test_autoCodePackage_Create(t *testing.T) {
|
||||
@@ -53,9 +54,10 @@ func Test_autoCodePackage_Create(t *testing.T) {
|
||||
|
||||
func Test_autoCodePackage_templates(t *testing.T) {
|
||||
type args struct {
|
||||
ctx context.Context
|
||||
entity model.SysAutoCodePackage
|
||||
info request.AutoCode
|
||||
ctx context.Context
|
||||
entity model.SysAutoCodePackage
|
||||
info request.AutoCode
|
||||
isPackage bool
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
@@ -78,6 +80,7 @@ func Test_autoCodePackage_templates(t *testing.T) {
|
||||
Abbreviation: "user",
|
||||
HumpPackageName: "user",
|
||||
},
|
||||
isPackage: false,
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
@@ -85,7 +88,7 @@ func Test_autoCodePackage_templates(t *testing.T) {
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
s := &autoCodePackage{}
|
||||
gotCode, gotEnter, gotCreates, err := s.templates(tt.args.ctx, tt.args.entity, tt.args.info)
|
||||
gotCode, gotEnter, gotCreates, err := s.templates(tt.args.ctx, tt.args.entity, tt.args.info, tt.args.isPackage)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("templates() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
|
@@ -82,6 +82,7 @@ func (i *initMenu) InitializeData(ctx context.Context) (next context.Context, er
|
||||
{MenuLevel: 0, Hidden: false, ParentId: 15, Path: "exportTemplate", Name: "exportTemplate", Component: "view/systemTools/exportTemplate/exportTemplate.vue", Sort: 5, Meta: Meta{Title: "导出模板", Icon: "reading"}},
|
||||
{MenuLevel: 0, Hidden: false, ParentId: 24, Path: "anInfo", Name: "anInfo", Component: "plugin/announcement/view/info.vue", Sort: 5, Meta: Meta{Title: "公告管理[示例]", Icon: "scaleToOriginal"}},
|
||||
{MenuLevel: 0, Hidden: false, ParentId: 3, Path: "sysParams", Name: "sysParams", Component: "view/superAdmin/params/sysParams.vue", Sort: 7, Meta: Meta{Title: "参数管理", Icon: "compass"}},
|
||||
{MenuLevel: 0, Hidden: false, ParentId: 15, Path: "picture", Name: "picture", Component: "view/systemTools/autoCode/picture.vue", Sort: 6, Meta: Meta{Title: "AI页面绘制", Icon: "picture-filled"}},
|
||||
}
|
||||
if err = db.Create(&entities).Error; err != nil {
|
||||
return ctx, errors.Wrap(err, SysBaseMenu{}.TableName()+"表数据初始化失败!")
|
||||
|
@@ -5,7 +5,6 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/flipped-aurora/gin-vue-admin/server/global"
|
||||
"github.com/mojocn/base64Captcha"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
@@ -23,8 +22,10 @@ type RedisStore struct {
|
||||
Context context.Context
|
||||
}
|
||||
|
||||
func (rs *RedisStore) UseWithCtx(ctx context.Context) base64Captcha.Store {
|
||||
rs.Context = ctx
|
||||
func (rs *RedisStore) UseWithCtx(ctx context.Context) *RedisStore {
|
||||
if ctx == nil {
|
||||
rs.Context = ctx
|
||||
}
|
||||
return rs
|
||||
}
|
||||
|
||||
|
@@ -173,6 +173,17 @@ export const eye = (data) => {
|
||||
}
|
||||
|
||||
|
||||
export const createWeb = (data) => {
|
||||
return service({
|
||||
url: '/autoCode/llmAuto',
|
||||
method: 'post',
|
||||
data: { ...data, mode: 'painter' },
|
||||
timeout: 1000 * 60 * 10
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
export const addFunc = (data) => {
|
||||
return service({
|
||||
url: '/autoCode/addFunc',
|
||||
|
@@ -16,6 +16,7 @@
|
||||
"/src/view/example/breakpoint/breakpoint.vue": "BreakPoint",
|
||||
"/src/view/example/customer/customer.vue": "Customer",
|
||||
"/src/view/example/index.vue": "Example",
|
||||
"/src/view/example/upload/scanUpload.vue": "scanUpload",
|
||||
"/src/view/example/upload/upload.vue": "Upload",
|
||||
"/src/view/init/index.vue": "Init",
|
||||
"/src/view/layout/aside/asideComponent/asyncSubmenu.vue": "AsyncSubmenu",
|
||||
@@ -53,8 +54,10 @@
|
||||
"/src/view/superAdmin/user/user.vue": "User",
|
||||
"/src/view/system/state.vue": "State",
|
||||
"/src/view/systemTools/autoCode/component/fieldDialog.vue": "FieldDialog",
|
||||
"/src/view/systemTools/autoCode/component/iframeRenderer.vue": "IframeRenderer",
|
||||
"/src/view/systemTools/autoCode/component/previewCodeDialog.vue": "PreviewCodeDialog",
|
||||
"/src/view/systemTools/autoCode/index.vue": "AutoCode",
|
||||
"/src/view/systemTools/autoCode/picture.vue": "Picture",
|
||||
"/src/view/systemTools/autoCodeAdmin/index.vue": "AutoCodeAdmin",
|
||||
"/src/view/systemTools/autoPkg/autoPkg.vue": "AutoPkg",
|
||||
"/src/view/systemTools/exportTemplate/exportTemplate.vue": "ExportTemplate",
|
||||
|
@@ -99,6 +99,27 @@ export const useAppStore = defineStore('app', () => {
|
||||
config.transition_type = e
|
||||
}
|
||||
|
||||
const baseCoinfg = {
|
||||
weakness: false,
|
||||
grey: false,
|
||||
primaryColor: '#3b82f6',
|
||||
showTabs: true,
|
||||
darkMode: 'auto',
|
||||
layout_side_width: 256,
|
||||
layout_side_collapsed_width: 80,
|
||||
layout_side_item_height: 48,
|
||||
show_watermark: true,
|
||||
side_mode: 'normal',
|
||||
// 页面过渡动画配置
|
||||
transition_type: 'slide'
|
||||
}
|
||||
|
||||
const resetConfig = () => {
|
||||
for (let baseCoinfgKey in baseCoinfg) {
|
||||
config[baseCoinfgKey] = baseCoinfg[baseCoinfgKey]
|
||||
}
|
||||
}
|
||||
|
||||
// 监听色弱模式和灰色模式
|
||||
watchEffect(() => {
|
||||
document.documentElement.classList.toggle('html-weakenss', config.weakness)
|
||||
@@ -128,6 +149,7 @@ export const useAppStore = defineStore('app', () => {
|
||||
toggleConfigSideItemHeight,
|
||||
toggleConfigWatermark,
|
||||
toggleSideMode,
|
||||
toggleTransition
|
||||
toggleTransition,
|
||||
resetConfig
|
||||
}
|
||||
})
|
||||
|
@@ -9,7 +9,7 @@
|
||||
<template #header>
|
||||
<div class="flex justify-between items-center">
|
||||
<span class="text-lg">系统配置</span>
|
||||
<el-button type="primary" @click="saveConfig">保存配置</el-button>
|
||||
<el-button type="primary" @click="resetConfig">重置配置</el-button>
|
||||
</div>
|
||||
</template>
|
||||
<div class="flex flex-col">
|
||||
@@ -144,6 +144,8 @@
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { setSelfSetting } from '@/api/user'
|
||||
import Title from './title.vue'
|
||||
import { watch } from 'vue';
|
||||
|
||||
const appStore = useAppStore()
|
||||
const { config, device } = storeToRefs(appStore)
|
||||
defineOptions({
|
||||
@@ -185,24 +187,24 @@
|
||||
]
|
||||
|
||||
const saveConfig = async () => {
|
||||
/*const input = document.createElement("textarea");
|
||||
input.value = JSON.stringify(config.value);
|
||||
// 添加回车
|
||||
input.value = input.value.replace(/,/g, ",\n");
|
||||
document.body.appendChild(input);
|
||||
input.select();
|
||||
document.execCommand("copy");
|
||||
document.body.removeChild(input);
|
||||
ElMessage.success("复制成功, 请自行保存到本地文件中");*/
|
||||
const res = await setSelfSetting(config.value)
|
||||
console.log(config.value)
|
||||
if (res.code === 0) {
|
||||
localStorage.setItem('originSetting', JSON.stringify(config.value))
|
||||
ElMessage.success('保存成功')
|
||||
drawer.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const customColor = ref('')
|
||||
|
||||
const resetConfig = () => {
|
||||
appStore.resetConfig()
|
||||
}
|
||||
|
||||
|
||||
watch(config, async () => {
|
||||
await saveConfig();
|
||||
}, { deep: true });
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
@@ -0,0 +1,99 @@
|
||||
<template>
|
||||
<iframe
|
||||
ref="iframe"
|
||||
class="w-full border-0"
|
||||
:style="{ height: iframeHeight + 'px' }"
|
||||
></iframe>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted, watch } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
html: {
|
||||
type: String,
|
||||
required: true
|
||||
}
|
||||
})
|
||||
|
||||
const iframe = ref(null)
|
||||
const iframeHeight = ref(400) // Default height
|
||||
|
||||
const renderContent = () => {
|
||||
if (!iframe.value) return
|
||||
|
||||
const doc = iframe.value.contentDocument || iframe.value.contentWindow.document
|
||||
|
||||
const htmlTemplate = `
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<!-- Production version of Vue -->
|
||||
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"><\/script>
|
||||
<!-- Element Plus -->
|
||||
<link rel="stylesheet" href="https://unpkg.com/element-plus/dist/index.css" />
|
||||
<script src="https://unpkg.com/element-plus/dist/index.full.min.js"><\/script>
|
||||
<!-- Tailwind CSS -->
|
||||
<script src="https://cdn.tailwindcss.com"><\/script>
|
||||
<style>
|
||||
body { margin: 0; padding: 10px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script>
|
||||
// Initialize Vue app
|
||||
const app = Vue.createApp({
|
||||
template: \`${props.html.replace(/`/g, '\\`')}\`,
|
||||
data() {
|
||||
return {}
|
||||
}
|
||||
});
|
||||
|
||||
// Use Element Plus
|
||||
app.use(ElementPlus);
|
||||
|
||||
// Mount the application
|
||||
app.mount('#app');
|
||||
|
||||
// Adjust iframe height
|
||||
setTimeout(() => {
|
||||
const height = document.body.scrollHeight;
|
||||
window.parent.postMessage({
|
||||
type: 'resize',
|
||||
height: height
|
||||
}, '*');
|
||||
}, 100);
|
||||
<\/script>
|
||||
</body>
|
||||
</html>
|
||||
`
|
||||
|
||||
doc.open()
|
||||
doc.write(htmlTemplate)
|
||||
doc.close()
|
||||
}
|
||||
|
||||
// Listen for height updates from iframe
|
||||
onMounted(() => {
|
||||
window.addEventListener('message', (event) => {
|
||||
if (event.data && event.data.type === 'resize') {
|
||||
iframeHeight.value = event.data.height + 20 // Add padding
|
||||
}
|
||||
})
|
||||
|
||||
// Render with slight delay to ensure iframe is ready
|
||||
setTimeout(() => {
|
||||
renderContent()
|
||||
}, 50)
|
||||
})
|
||||
|
||||
// Re-render when HTML changes
|
||||
watch(() => props.html, () => {
|
||||
setTimeout(() => {
|
||||
renderContent()
|
||||
}, 50)
|
||||
})
|
||||
</script>
|
141
web/src/view/systemTools/autoCode/picture.vue
Normal file
141
web/src/view/systemTools/autoCode/picture.vue
Normal file
@@ -0,0 +1,141 @@
|
||||
<template>
|
||||
<div>
|
||||
<warning-bar
|
||||
href="https://www.bilibili.com/video/BV1kv4y1g7nT?p=3"
|
||||
title="此功能为开发环境使用,不建议发布到生产,具体使用效果请点我观看。"
|
||||
/>
|
||||
<div class="gva-search-box">
|
||||
<div class="text-lg mb-2 text-gray-600">
|
||||
使用AI创建<a
|
||||
class="text-blue-600 text-sm ml-4"
|
||||
href="https://plugin.gin-vue-admin.com/#/layout/userInfo/center"
|
||||
target="_blank"
|
||||
>获取AiPath</a
|
||||
>
|
||||
</div>
|
||||
<div class="relative">
|
||||
<el-input
|
||||
v-model="prompt"
|
||||
:maxlength="2000"
|
||||
:placeholder="placeholder"
|
||||
:rows="8"
|
||||
resize="none"
|
||||
type="textarea"
|
||||
@blur="handleBlur"
|
||||
@focus="handleFocus"
|
||||
/>
|
||||
<div class="flex absolute right-2 bottom-2">
|
||||
<el-tooltip effect="light">
|
||||
<template #content>
|
||||
<div>
|
||||
【完全免费】前往<a
|
||||
class="text-blue-600"
|
||||
href="https://plugin.gin-vue-admin.com/#/layout/userInfo/center"
|
||||
target="_blank"
|
||||
>插件市场个人中心</a
|
||||
>申请AIPath,填入config.yaml的ai-path属性即可使用。
|
||||
</div>
|
||||
</template>
|
||||
<el-button
|
||||
type="primary"
|
||||
@click="llmAutoFunc()"
|
||||
>
|
||||
<el-icon size="18">
|
||||
<ai-gva/>
|
||||
</el-icon>
|
||||
生成
|
||||
</el-button>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div v-if="!outPut">
|
||||
<el-empty :image-size="200"/>
|
||||
</div>
|
||||
<div v-if="outPut">
|
||||
<div v-for="(snippet, index) in htmlFromLLM" :key="index" class="mb-6 p-4 border">
|
||||
<el-button type="primary" :icon="Upload" class="px-2 py-1" @click="copySnippet(snippet)" plain>复制</el-button>
|
||||
<div class="mt-2">
|
||||
<iframe-renderer :html="snippet" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { createWeb
|
||||
} from '@/api/autoCode'
|
||||
import {ref} from 'vue'
|
||||
import WarningBar from '@/components/warningBar/warningBar.vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
|
||||
|
||||
defineOptions({
|
||||
name: 'Picture'
|
||||
})
|
||||
|
||||
import IframeRenderer from '@/view/systemTools/autoCode/component/iframeRenderer.vue'
|
||||
|
||||
const handleFocus = () => {
|
||||
document.addEventListener('keydown', handleKeydown);
|
||||
}
|
||||
|
||||
const handleBlur = () => {
|
||||
document.removeEventListener('keydown', handleKeydown);
|
||||
}
|
||||
|
||||
const handleKeydown = (event) => {
|
||||
if ((event.ctrlKey || event.metaKey) && event.key === 'Enter') {
|
||||
llmAutoFunc()
|
||||
}
|
||||
}
|
||||
|
||||
// 复制方法:把某个字符串写进剪贴板
|
||||
const copySnippet = (htmlString) => {
|
||||
navigator.clipboard.writeText(htmlString)
|
||||
.then(() => {
|
||||
ElMessage({
|
||||
message: '复制成功',
|
||||
type: 'success',
|
||||
})
|
||||
})
|
||||
.catch(err => {
|
||||
ElMessage({
|
||||
message: '复制失败',
|
||||
type: 'warning',
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
const prompt = ref('')
|
||||
|
||||
// 判断是否返回的标志
|
||||
const outPut = ref(false)
|
||||
// 容纳llm返回的html
|
||||
const htmlFromLLM = ref([])
|
||||
|
||||
const llmAutoFunc = async () => {
|
||||
const res = await createWeb({web: prompt.value, command: 'createWeb'})
|
||||
if (res.code === 0) {
|
||||
outPut.value = true
|
||||
// 使用mock数据模拟大模型返回值
|
||||
htmlFromLLM.value.push(res.data)
|
||||
}
|
||||
}
|
||||
|
||||
const placeholder = ref(`"✨ 请详细描述您想要的页面,例如:
|
||||
• 页面用途(企业官网/电商页面/个人博客等)
|
||||
• 需要包含的主要内容板块
|
||||
• 偏好的风格(简约/科技感/温馨/专业等)
|
||||
• 需要特别强调的元素
|
||||
• 参考网站或配色建议
|
||||
|
||||
示例:'需要一个科技公司的产品介绍页,包含banner轮播图、三栏功能特点展示、客户案例模块,喜欢深蓝色调,参考苹果官网的简洁风格'"`)
|
||||
|
||||
|
||||
|
||||
</script>
|
Reference in New Issue
Block a user