|
@@ -2,91 +2,107 @@
|
|
<div class=" w-full app-pageContainer relative" style="overflow: hidden; height: calc(var(--vh, 1vh) * 100);">
|
|
<div class=" w-full app-pageContainer relative" style="overflow: hidden; height: calc(var(--vh, 1vh) * 100);">
|
|
<TitleH5 titleName=" 创建场景" />
|
|
<TitleH5 titleName=" 创建场景" />
|
|
<!-- 第一步场景基本信息 -->
|
|
<!-- 第一步场景基本信息 -->
|
|
- <div class="overflow-y-auto" style="height: calc(100% - 49px - 60px);">
|
|
|
|
- <div v-show="active == 1" class="px-6 pb-4 mx-auto w-full">
|
|
|
|
- <div>
|
|
|
|
- <div class="py-4 flex flex-col">
|
|
|
|
- <div class="w-20 h-20">
|
|
|
|
- <div v-if="!character.id" @click="showPopup1 = true"
|
|
|
|
- class="w-20 h-20 bg-gray-100 rounded-full cursor-pointer flex flex-col justify-center items-center text-sm hover:bg-gray-200">
|
|
|
|
- <p>选择</p>
|
|
|
|
- <p>角色</p>
|
|
|
|
- </div>
|
|
|
|
- <img v-else class="w-20 h-20 rounded-full cursor-pointer object-cover shadow" @click="showPopup1 = true"
|
|
|
|
- :src="baseApi + character.picture" alt="">
|
|
|
|
|
|
+ <div class="overflow-y-auto flex flex-col justify-between" style="height: calc(100% - 49px - 60px);">
|
|
|
|
+ <el-form :model="form" :rules="rules" ref="form" label-position="top" label-width="60px" class="form">
|
|
|
|
+ <div v-show="active == 1" class="px-6 pb-4 mx-auto w-full">
|
|
|
|
+ <div>
|
|
|
|
+ <div class="py-4 flex flex-col">
|
|
|
|
+ <el-form-item prop="characterId">
|
|
|
|
+ <div class="w-20 h-20">
|
|
|
|
+ <div v-if="!character.id" @click="showPopup1 = true"
|
|
|
|
+ class="w-20 h-20 bg-gray-100 rounded-full cursor-pointer flex flex-col justify-center items-center text-sm hover:bg-gray-200">
|
|
|
|
+ <p>选择</p>
|
|
|
|
+ <p>角色</p>
|
|
|
|
+ </div>
|
|
|
|
+ <img v-else class="w-20 h-20 rounded-full cursor-pointer object-cover shadow" @click="showPopup1 = true"
|
|
|
|
+ :src="baseApi + character.picture" alt="">
|
|
|
|
+ </div>
|
|
|
|
+ </el-form-item>
|
|
|
|
+ <div class="mt-1.5 text-2xl">{{ character.id ? character.characterName : '请选择角色' }}</div>
|
|
|
|
+ <div class="mt-1 text-gray-400 text-sm">定义角色所属的上下文,为角色补充创作的故事或设定。</div>
|
|
</div>
|
|
</div>
|
|
- <div class="mt-1.5 text-2xl">{{ character.id ? character.characterName : '请选择角色' }}</div>
|
|
|
|
- <div class="mt-1 text-gray-400 text-sm">定义角色所属的上下文,为角色补充创作的故事或设定。</div>
|
|
|
|
- </div>
|
|
|
|
|
|
|
|
- <div class="py-4">
|
|
|
|
- <div>场景名称</div>
|
|
|
|
- <div class="mt-1 text-gray-400 text-sm">场景的标题</div>
|
|
|
|
- <el-input class="mt-4" v-model="form.sceneName" placeholder="例如:第一次约会" maxlength="10"
|
|
|
|
- show-word-limit></el-input>
|
|
|
|
- </div>
|
|
|
|
|
|
+ <div class="py-4">
|
|
|
|
+ <div>场景名称</div>
|
|
|
|
+ <div class="mt-1 text-gray-400 text-sm">场景的标题</div>
|
|
|
|
+ <el-form-item prop="sceneName">
|
|
|
|
+ <el-input class="mt-4" v-model="form.sceneName" placeholder="例如:第一次约会" maxlength="10"
|
|
|
|
+ show-word-limit></el-input>
|
|
|
|
+ </el-form-item>
|
|
|
|
+ </div>
|
|
|
|
|
|
- <div class="py-4">
|
|
|
|
- <div>场景描述</div>
|
|
|
|
- <div class="mt-1 text-gray-400 text-sm">
|
|
|
|
- 详细的场景描述,可以为角色补充创作的故事或设定,可以指定互动发生的位置和时间。
|
|
|
|
|
|
+ <div class="py-4">
|
|
|
|
+ <div>场景描述</div>
|
|
|
|
+ <div class="mt-1 text-gray-400 text-sm">
|
|
|
|
+ 详细的场景描述,可以为角色补充创作的故事或设定,可以指定互动发生的位置和时间。
|
|
|
|
+ </div>
|
|
|
|
+ <el-form-item prop="sceneDescription">
|
|
|
|
+ <el-input class="mt-4" v-model="form.sceneDescription"
|
|
|
|
+ placeholder="例:{char} 成为 {user} 的女朋友已有一段時間了,今天你们决定开始同居。" type="textarea" maxlength="400"
|
|
|
|
+ :autosize="{ minRows: 4 }" show-word-limit></el-input>
|
|
|
|
+ </el-form-item>
|
|
</div>
|
|
</div>
|
|
- <el-input class="mt-4" v-model="form.sceneDescription"
|
|
|
|
- placeholder="例:{char} 成为 {user} 的女朋友已有一段時間了,今天你们决定开始同居。" type="textarea" maxlength="400"
|
|
|
|
- :autosize="{ minRows: 4 }" show-word-limit></el-input>
|
|
|
|
- </div>
|
|
|
|
- <div class="py-4">
|
|
|
|
- <div>欢迎语</div>
|
|
|
|
- <div class="mt-1 text-gray-400 text-sm">
|
|
|
|
- 请填写欢迎语和指定的发言角色,這将会是进入场景时收到的第一句话,将会印象场景的剧情走向
|
|
|
|
|
|
+ <div class="py-4">
|
|
|
|
+ <div>欢迎语</div>
|
|
|
|
+ <div class="mt-1 text-gray-400 text-sm">
|
|
|
|
+ 请填写欢迎语和指定的发言角色,這将会是进入场景时收到的第一句话,将会印象场景的剧情走向
|
|
|
|
+ </div>
|
|
|
|
+ <el-form-item prop="sceneWelcome">
|
|
|
|
+ <el-input class="mt-4" v-model="form.sceneWelcome" placeholder="例如:他的声音里充满了恼怒,问道: “你是我新來的保姆吗?”"
|
|
|
|
+ type="textarea" maxlength="400" :autosize="{ minRows: 4 }" show-word-limit></el-input>
|
|
|
|
+ </el-form-item>
|
|
</div>
|
|
</div>
|
|
- <el-input class="mt-4" v-model="form.sceneWelcome" placeholder="例如:他的声音里充满了恼怒,问道: “你是我新來的保姆吗?”"
|
|
|
|
- type="textarea" maxlength="400" :autosize="{ minRows: 4 }" show-word-limit></el-input>
|
|
|
|
- </div>
|
|
|
|
- <div class="py-4">
|
|
|
|
- <div>模型</div>
|
|
|
|
- <div class="flex items-start py-3">
|
|
|
|
- <el-radio-group class="radio" v-model="form.modelId">
|
|
|
|
- <el-radio-button v-for="(item, index) in modelList" :key="index" :label="item.id">
|
|
|
|
- {{ item.model }}
|
|
|
|
- </el-radio-button>
|
|
|
|
- </el-radio-group>
|
|
|
|
|
|
+ <div class="py-4">
|
|
|
|
+ <div>模型</div>
|
|
|
|
+ <div class="flex items-start py-3">
|
|
|
|
+ <el-form-item prop="modelId">
|
|
|
|
+ <el-radio-group class="radio" v-model="form.modelId">
|
|
|
|
+ <el-radio-button v-for="(item, index) in modelList" :key="index" :label="item.id">
|
|
|
|
+ {{ item.model }}
|
|
|
|
+ </el-radio-button>
|
|
|
|
+ </el-radio-group>
|
|
|
|
+ </el-form-item>
|
|
|
|
+ </div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
- </div>
|
|
|
|
- <!-- 第二步背景 -->
|
|
|
|
- <div v-show="active == 2" class="w-full">
|
|
|
|
- <img v-if="uploadList.length > 0" class=" w-full h-full object-cover" :src="baseApi + uploadList[bgActive].url"
|
|
|
|
- alt="">
|
|
|
|
- <div
|
|
|
|
- class="absolute h-full bg-white p-4 bottom-1/2 right-1/2 transform translate-x-1/2 translate-y-1/2 rounded-lg border border-gray-200">
|
|
|
|
- <el-tabs v-model="tabActive2">
|
|
|
|
- <el-tab-pane label="上传背景" name="1">
|
|
|
|
- <div class="flex flex-col">
|
|
|
|
- <div>直接使用上传的图像</div>
|
|
|
|
- <div class="mt-1 text-gray-400 text-sm">直接使用上传的图像</div>
|
|
|
|
- <el-upload class=" w-full text-center mt-4" drag :action="uploadUrl" :headers="headers"
|
|
|
|
- :before-upload="handleBeforeUpload" :on-success="handleUploadSuccess" :on-error="handleUploadError"
|
|
|
|
- :show-file-list="false" :limit="10">
|
|
|
|
- <i class="el-icon-upload"></i>
|
|
|
|
- <div class="el-upload__text"><em>点击上传</em></div>
|
|
|
|
- <div class="el-upload__tip" slot="tip">只能上传jpg/png文件,且不超过5M</div>
|
|
|
|
- </el-upload>
|
|
|
|
- <div>背景</div>
|
|
|
|
- <div class="mt-2 grid grid-cols-4 gap-1 gap-y-2">
|
|
|
|
- <div v-for="(item, index) in uploadList" :key="index" @click="bgActive = index">
|
|
|
|
- <img class=" rounded object-cover cursor-pointer border" :class="bgActive === index ? 'bgActive' : ''"
|
|
|
|
- style="width: 120px; height: 90px;" :src="baseApi + item.url" alt="">
|
|
|
|
- </div>
|
|
|
|
|
|
+ <!-- 第二步背景 -->
|
|
|
|
+ <div v-if="active == 2" class="w-full">
|
|
|
|
+ <img v-if="uploadList.length > 0" class=" w-full h-full object-cover" :src="baseApi + uploadList[bgActive].url"
|
|
|
|
+ alt="">
|
|
|
|
+ <div
|
|
|
|
+ class="absolute h-full bg-white p-4 bottom-1/2 right-1/2 transform translate-x-1/2 translate-y-1/2 rounded-lg border border-gray-200">
|
|
|
|
+ <el-tabs v-model="tabActive2">
|
|
|
|
+ <el-tab-pane label="上传背景" name="1">
|
|
|
|
+ <div class="flex flex-col">
|
|
|
|
+ <div>直接使用上传的图像</div>
|
|
|
|
+ <div class="mt-1 text-gray-400 text-sm">直接使用上传的图像</div>
|
|
|
|
+ <el-form-item prop="background" :rules="{ required: true, message: '请上传背景图', trigger: 'change' }">
|
|
|
|
+ <el-upload class=" w-full text-center mt-4" drag :action="uploadUrl" :headers="headers"
|
|
|
|
+ :before-upload="handleBeforeUpload" :on-success="handleUploadSuccess" :on-error="handleUploadError"
|
|
|
|
+ :show-file-list="false" :limit="10">
|
|
|
|
+ <i class="el-icon-upload"></i>
|
|
|
|
+ <div class="el-upload__text"><em>点击上传</em></div>
|
|
|
|
+ <div class="el-upload__tip" slot="tip">只能上传jpg/png文件,且不超过5M</div>
|
|
|
|
+ </el-upload>
|
|
|
|
+ <div>背景</div>
|
|
|
|
+ <div class="mt-2 grid grid-cols-4 gap-1 gap-y-2">
|
|
|
|
+ <div v-for="( item, index ) in uploadList " :key="index" @click="bgActive = index">
|
|
|
|
+ <img class=" rounded object-cover cursor-pointer border"
|
|
|
|
+ :class="bgActive === index ? 'bgActive' : ''" style="width: 120px; height: 90px;"
|
|
|
|
+ :src="baseApi + item.url" alt="">
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </el-form-item>
|
|
</div>
|
|
</div>
|
|
- </div>
|
|
|
|
- </el-tab-pane>
|
|
|
|
- </el-tabs>
|
|
|
|
|
|
+ </el-tab-pane>
|
|
|
|
+ </el-tabs>
|
|
|
|
+ </div>
|
|
</div>
|
|
</div>
|
|
- </div>
|
|
|
|
|
|
+ </el-form>
|
|
|
|
+
|
|
<div class="bottomA flex justify-end items-center pr-6">
|
|
<div class="bottomA flex justify-end items-center pr-6">
|
|
- <el-button v-if="active == 1" type="primary" :disabled="nextDisabled" @click="next()">下一步</el-button>
|
|
|
|
|
|
+ <el-button v-if="active == 1" type="primary" @click="next()">下一步</el-button>
|
|
<el-button v-if="active == 2" @click="active--">上一步</el-button>
|
|
<el-button v-if="active == 2" @click="active--">上一步</el-button>
|
|
|
|
|
|
<el-dropdown @command="handleCommand" trigger="click">
|
|
<el-dropdown @command="handleCommand" trigger="click">
|
|
@@ -99,7 +115,8 @@
|
|
<el-dropdown-item command="1">非公开</el-dropdown-item>
|
|
<el-dropdown-item command="1">非公开</el-dropdown-item>
|
|
</el-dropdown-menu>
|
|
</el-dropdown-menu>
|
|
</el-dropdown>
|
|
</el-dropdown>
|
|
- <el-button v-if="active == 2" :disabled="uploadList.length == 0" type="primary" @click="submit">发布</el-button>
|
|
|
|
|
|
+ <el-button :loading="submitLoading" v-if="active == 2" :disabled="uploadList.length == 0" type="primary"
|
|
|
|
+ @click="submit">发布</el-button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!-- 选择角色对话框 -->
|
|
<!-- 选择角色对话框 -->
|
|
@@ -109,7 +126,7 @@
|
|
<el-tabs v-model="tabActive" @tab-click="handleClickTab">
|
|
<el-tabs v-model="tabActive" @tab-click="handleClickTab">
|
|
<el-tab-pane label="我的角色" name="1">
|
|
<el-tab-pane label="我的角色" name="1">
|
|
<div class=" grid grid-cols-3 gap-8">
|
|
<div class=" grid grid-cols-3 gap-8">
|
|
- <div v-for="(item, index) in userCharacterList" :key="index" @click="selectCharacter(item)">
|
|
|
|
|
|
+ <div v-for="( item, index ) in userCharacterList " :key="index" @click="selectCharacter(item)">
|
|
<img class="rounded-full object-cover cursor-pointer w-20 h-20" :src="baseApi + item.picture" alt="">
|
|
<img class="rounded-full object-cover cursor-pointer w-20 h-20" :src="baseApi + item.picture" alt="">
|
|
<div class="characterName text-center w-20">{{ item.characterName }}</div>
|
|
<div class="characterName text-center w-20">{{ item.characterName }}</div>
|
|
</div>
|
|
</div>
|
|
@@ -117,7 +134,7 @@
|
|
</el-tab-pane>
|
|
</el-tab-pane>
|
|
<el-tab-pane label="热门角色" name="2">
|
|
<el-tab-pane label="热门角色" name="2">
|
|
<div class=" grid grid-cols-3 gap-8 justify-items-center">
|
|
<div class=" grid grid-cols-3 gap-8 justify-items-center">
|
|
- <div v-for="(item, index) in characterList" :key="index" @click="selectCharacter(item)">
|
|
|
|
|
|
+ <div v-for="( item, index ) in characterList " :key="index" @click="selectCharacter(item)">
|
|
<img class="rounded-full object-cover cursor-pointer w-20 h-20" :src="baseApi + item.picture" alt="">
|
|
<img class="rounded-full object-cover cursor-pointer w-20 h-20" :src="baseApi + item.picture" alt="">
|
|
<div class="characterName text-center w-20">{{ item.characterName }}</div>
|
|
<div class="characterName text-center w-20">{{ item.characterName }}</div>
|
|
</div>
|
|
</div>
|
|
@@ -146,6 +163,7 @@ export default {
|
|
},
|
|
},
|
|
data() {
|
|
data() {
|
|
return {
|
|
return {
|
|
|
|
+ submitLoading: false,
|
|
active: 1,
|
|
active: 1,
|
|
showPopup1: false,
|
|
showPopup1: false,
|
|
tabActive: '1',
|
|
tabActive: '1',
|
|
@@ -182,7 +200,25 @@ export default {
|
|
},
|
|
},
|
|
uploadList: [],
|
|
uploadList: [],
|
|
fileSize: 5,
|
|
fileSize: 5,
|
|
- bgActive: 0
|
|
|
|
|
|
+ bgActive: 0,
|
|
|
|
+ rules: {
|
|
|
|
+ characterId: [
|
|
|
|
+ { required: true, message: "请选择角色", trigger: "change" },
|
|
|
|
+ ],
|
|
|
|
+ sceneName: [
|
|
|
|
+ { required: true, message: "请输入场景名称", trigger: "change" },
|
|
|
|
+ ],
|
|
|
|
+ sceneDescription: [
|
|
|
|
+ { required: true, message: "请输入场景描述", trigger: "change" },
|
|
|
|
+ ],
|
|
|
|
+ sceneWelcome: [
|
|
|
|
+ { required: true, message: "请输入欢迎语", trigger: "change" },
|
|
|
|
+ ],
|
|
|
|
+ modelId: [
|
|
|
|
+ { required: true, message: "请选择模型", trigger: "change" },
|
|
|
|
+ ],
|
|
|
|
+
|
|
|
|
+ }
|
|
}
|
|
}
|
|
},
|
|
},
|
|
mounted() {
|
|
mounted() {
|
|
@@ -264,31 +300,56 @@ export default {
|
|
},
|
|
},
|
|
// 下一步
|
|
// 下一步
|
|
next() {
|
|
next() {
|
|
- this.active++
|
|
|
|
|
|
+ // this.active++
|
|
|
|
+
|
|
|
|
+ this.$refs.form.validate((valid, object) => {
|
|
|
|
+ if (valid) {
|
|
|
|
+ this.active++
|
|
|
|
+ } else {
|
|
|
|
+ let keys = Object.keys(object)
|
|
|
|
+ this.$modal.msgError(object[keys[0]][0].message);
|
|
|
|
+ }
|
|
|
|
+ })
|
|
},
|
|
},
|
|
submit() {
|
|
submit() {
|
|
- this.form.background = this.uploadList[this.bgActive].url
|
|
|
|
- if (this.form.sceneId) {
|
|
|
|
- // 修改
|
|
|
|
- editSceneApi(this.form).then(res => {
|
|
|
|
- console.log(res, 'res>>>>>');
|
|
|
|
- this.$message({
|
|
|
|
- type: 'success',
|
|
|
|
- message: '修改成功!'
|
|
|
|
- });
|
|
|
|
- this.$router.push('/profile')
|
|
|
|
- })
|
|
|
|
- } else {
|
|
|
|
- // 新增
|
|
|
|
- addSceneApi(this.form).then(res => {
|
|
|
|
- console.log(res, 'res>>>>>');
|
|
|
|
- this.$message({
|
|
|
|
- type: 'success',
|
|
|
|
- message: '发布成功!'
|
|
|
|
- });
|
|
|
|
- this.$router.push('/profile')
|
|
|
|
- })
|
|
|
|
|
|
+ if (this.uploadList.length > 0) {
|
|
|
|
+ this.form.background = this.uploadList[this.bgActive].url
|
|
}
|
|
}
|
|
|
|
+ this.$refs.form.validate((valid, object) => {
|
|
|
|
+ if (valid) {
|
|
|
|
+ this.submitLoading = true
|
|
|
|
+ if (this.form.sceneId) {
|
|
|
|
+ // 修改
|
|
|
|
+ editSceneApi(this.form).then(res => {
|
|
|
|
+ console.log(res, 'res>>>>>');
|
|
|
|
+ this.$message({
|
|
|
|
+ type: 'success',
|
|
|
|
+ message: '修改成功!'
|
|
|
|
+ });
|
|
|
|
+ this.submitLoading = false
|
|
|
|
+ this.$router.push('/profile')
|
|
|
|
+ }).catch(() => {
|
|
|
|
+ this.submitLoading = false
|
|
|
|
+ })
|
|
|
|
+ } else {
|
|
|
|
+ // 新增
|
|
|
|
+ addSceneApi(this.form).then(res => {
|
|
|
|
+ console.log(res, 'res>>>>>');
|
|
|
|
+ this.$message({
|
|
|
|
+ type: 'success',
|
|
|
|
+ message: '发布成功!'
|
|
|
|
+ });
|
|
|
|
+ this.submitLoading = false
|
|
|
|
+ this.$router.push('/profile')
|
|
|
|
+ }).catch(() => {
|
|
|
|
+ this.submitLoading = false
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ let keys = Object.keys(object)
|
|
|
|
+ this.$modal.msgError(object[keys[0]][0].message);
|
|
|
|
+ }
|
|
|
|
+ })
|
|
},
|
|
},
|
|
handleClickTab(tab, event) {
|
|
handleClickTab(tab, event) {
|
|
|
|
|