Merge branch 'main' of ssh://18.167.251.121:10002/aidlab/FiDA_Front
This commit is contained in:
@@ -1,103 +1,200 @@
|
||||
<template>
|
||||
<div class="assist-input-wrapper flex flex-col">
|
||||
<textarea
|
||||
class="input"
|
||||
type="text"
|
||||
v-model="inputValue"
|
||||
:placeholder="$t('Input.placeholder')"
|
||||
/>
|
||||
<div class="operate flex align-center">
|
||||
<div class="attach flex flex-center">
|
||||
<img src="@/assets/icons/attach.svg" alt="" />
|
||||
<div class="scroll-content flex-col">
|
||||
<!-- 图片预览区域 -->
|
||||
<div v-if="uploadedImages.length > 0" class="image-preview-list flex wrap">
|
||||
<div v-for="(image, index) in uploadedImages" :key="index" class="image-preview-item">
|
||||
<img :src="image.url" :alt="image.name" class="preview-image" />
|
||||
<div class="image-remove-btn" @click="removeImage(index)">
|
||||
<SvgIcon name="delete" size="16" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<el-select v-model="typeValue" :placeholder="$t('Input.typePlaceholder')">
|
||||
<el-option
|
||||
v-for="item in typeOptions"
|
||||
class="input-option"
|
||||
:key="item.value"
|
||||
:label="$t(item.label)"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
<el-select v-model="areaValue" :placeholder="$t('Input.areaPlaceholder')">
|
||||
<el-option
|
||||
v-for="item in areaOptions"
|
||||
class="input-option"
|
||||
:key="item.value"
|
||||
:label="$t(item.label)"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
<div class="fida-style-select-wrapper">
|
||||
<el-select
|
||||
v-model="styleValue"
|
||||
:placeholder="$t('Input.stylePlaceholder')"
|
||||
@focus="openStylePopup"
|
||||
<!-- 编辑区域 -->
|
||||
<div
|
||||
ref="editorRef"
|
||||
class="editor"
|
||||
contenteditable="true"
|
||||
:placeholder="$t('Input.placeholder')"
|
||||
@input="handleEditorInput"
|
||||
@keydown="handleEditorKeydown"
|
||||
@paste="handleEditorPaste"
|
||||
>
|
||||
<!-- <Tag v-if="showReportTag" /> -->
|
||||
<div class="editor-tag report-btn flex-center" v-if="showReportTag" contenteditable="false">
|
||||
<SvgIcon class="light-icon" name="light" size="16" />
|
||||
<span>{{ $t('Input.trendingReport') }}</span>
|
||||
<SvgIcon
|
||||
class="close-icon"
|
||||
name="closeTransparent"
|
||||
size="24"
|
||||
color="#e6e6e6"
|
||||
@click="showReportTag = false"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="operate flex space-between">
|
||||
<div class="left flex align-center">
|
||||
<div class="attach flex flex-center" @click="triggerFileUpload">
|
||||
<img src="@/assets/icons/attach.svg" alt="" />
|
||||
</div>
|
||||
<input
|
||||
ref="fileInputRef"
|
||||
type="file"
|
||||
accept="image/*"
|
||||
style="display: none"
|
||||
@change="handleFileChange"
|
||||
/>
|
||||
<el-select v-model="typeValue" :placeholder="$t('Input.typePlaceholder')">
|
||||
<el-option
|
||||
v-for="item in typeOptions"
|
||||
class="input-option"
|
||||
:key="item.value"
|
||||
:label="$t(item.label)"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
<el-select v-model="areaValue" :placeholder="$t('Input.areaPlaceholder')">
|
||||
<el-option
|
||||
v-for="item in areaOptions"
|
||||
class="input-option"
|
||||
:key="item.value"
|
||||
:label="$t(item.label)"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
<div class="fida-style-select-wrapper">
|
||||
<el-select
|
||||
v-model="styleValue"
|
||||
:placeholder="$t('Input.stylePlaceholder')"
|
||||
@focus="openStylePopup"
|
||||
/>
|
||||
|
||||
<el-popover
|
||||
v-model:visible="stylePopupVisible"
|
||||
placement="top"
|
||||
:width="342"
|
||||
:show-arrow="false"
|
||||
trigger="click"
|
||||
popper-class="fida-style-select-popover"
|
||||
>
|
||||
<template #reference>
|
||||
<div class="fida-style-select-trigger"></div>
|
||||
</template>
|
||||
<div class="fida-style-popover-content flex flex-col">
|
||||
<div class="fida-style-popover-header">{{ $t('Input.chooseStyle') }}</div>
|
||||
<div class="fida-style-popover-grid">
|
||||
<div
|
||||
v-for="item in styleOptions"
|
||||
:key="item.value"
|
||||
class="fida-style-popover-item"
|
||||
:class="{ 'is-selected': tempSelectedValue === item.value }"
|
||||
@click="selectStyle(item.value)"
|
||||
>
|
||||
<span class="fida-option-label">{{ $t(item.label) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="fida-style-popover-footer flex flex-center">
|
||||
<button class="fida-confirm-btn" @click="confirmStyle">
|
||||
{{ $t('Input.confirm') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</el-popover>
|
||||
</div>
|
||||
<el-popover
|
||||
v-model:visible="stylePopupVisible"
|
||||
v-model:visible="settingPopupVisible"
|
||||
placement="top"
|
||||
:width="342"
|
||||
:show-arrow="false"
|
||||
trigger="click"
|
||||
popper-class="fida-style-select-popover"
|
||||
popper-class="fida-setting-popover"
|
||||
>
|
||||
<template #reference>
|
||||
<div class="fida-style-select-trigger"></div>
|
||||
<img src="@/assets/images/setting.png" class="setting-icon" />
|
||||
</template>
|
||||
<div class="fida-style-popover-content flex flex-col">
|
||||
<div class="fida-style-popover-header">{{ $t('Input.chooseStyle') }}</div>
|
||||
<div class="fida-style-popover-grid">
|
||||
<div class="fida-setting-popover-content flex flex-col">
|
||||
<div class="fida-setting-popover-header">{{ $t('Input.styleTitle') }}</div>
|
||||
<div class="fida-setting-slider-list">
|
||||
<div
|
||||
v-for="item in styleOptions"
|
||||
:key="item.value"
|
||||
class="fida-style-popover-item"
|
||||
:class="{ 'is-selected': tempSelectedValue === item.value }"
|
||||
@click="selectStyle(item.value)"
|
||||
v-for="item in settingOptions"
|
||||
:key="item.label"
|
||||
class="fida-setting-slider-item"
|
||||
>
|
||||
<span class="fida-option-label">{{ $t(item.label) }}</span>
|
||||
<div class="fida-slider-label">{{ $t(item.label) }}</div>
|
||||
<div class="fida-slider-row flex align-center">
|
||||
<el-slider
|
||||
class="setting-popover-slider"
|
||||
v-model="item.value"
|
||||
:show-tooltip="false"
|
||||
/>
|
||||
<span class="fida-slider-value">{{ item.value }}%</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="fida-style-popover-footer flex flex-center">
|
||||
<button class="fida-confirm-btn" @click="confirmStyle">
|
||||
{{ $t('Input.confirm') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</el-popover>
|
||||
</div>
|
||||
<el-popover
|
||||
v-model:visible="settingPopupVisible"
|
||||
placement="top"
|
||||
:width="342"
|
||||
:show-arrow="false"
|
||||
trigger="click"
|
||||
popper-class="fida-setting-popover"
|
||||
>
|
||||
<template #reference>
|
||||
<img src="@/assets/images/setting.png" class="setting-icon" />
|
||||
</template>
|
||||
<div class="fida-setting-popover-content flex flex-col">
|
||||
<div class="fida-setting-popover-header">{{ $t('Input.setting') }}</div>
|
||||
<div class="fida-setting-slider-list">
|
||||
<div v-for="item in settingOptions" :key="item.label" class="fida-setting-slider-item">
|
||||
<div class="fida-slider-label">{{ $t(item.label) }}</div>
|
||||
<div class="fida-slider-row flex align-center">
|
||||
<el-slider v-model="item.value" :show-tooltip="false" />
|
||||
<span class="fida-slider-value">{{ item.value }}%</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="right">
|
||||
<div class="create-btn flex flex-center">
|
||||
<img src="@/assets/images/shining.png" class="shining-icon" alt="" />
|
||||
<span class="create-btn-text">{{ $t('Input.createProject') }}</span>
|
||||
</div>
|
||||
</el-popover>
|
||||
</div>
|
||||
</div>
|
||||
<div class="report-btn flex flex-center" @click="toogltReportTag">
|
||||
<SvgIcon class="light-icon" name="light" size="16" />
|
||||
<span>{{ $t('Input.trendingReport') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, ref } from 'vue'
|
||||
import { computed, ref, watch, nextTick, onMounted } from 'vue'
|
||||
import { areaList } from '@/utils/area'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
// import Tag from './Tag.vue'
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
// 图片上传相关
|
||||
const fileInputRef = ref<HTMLInputElement | null>(null)
|
||||
const uploadedImages = ref<Array<{ url: string; name: string }>>([])
|
||||
|
||||
// 触发文件上传
|
||||
const triggerFileUpload = () => {
|
||||
fileInputRef.value?.click()
|
||||
}
|
||||
|
||||
// TODO 标签被删除后无法重新出现
|
||||
|
||||
// 处理文件选择
|
||||
const handleFileChange = (event: Event) => {
|
||||
const input = event.target as HTMLInputElement
|
||||
if (input.files) {
|
||||
Array.from(input.files).forEach((file) => {
|
||||
// 只处理图片文件
|
||||
if (file.type.startsWith('image/')) {
|
||||
const reader = new FileReader()
|
||||
reader.onload = (e) => {
|
||||
uploadedImages.value.push({
|
||||
url: e.target?.result as string,
|
||||
name: file.name
|
||||
})
|
||||
}
|
||||
reader.readAsDataURL(file)
|
||||
}
|
||||
})
|
||||
}
|
||||
// 清空input的value,允许重复选择同一文件
|
||||
input.value = ''
|
||||
}
|
||||
|
||||
// 移除图片
|
||||
const removeImage = (index: number) => {
|
||||
uploadedImages.value.splice(index, 1)
|
||||
}
|
||||
|
||||
const styleKeys: string[] = [
|
||||
'Coastal',
|
||||
@@ -111,8 +208,97 @@ const styleKeys: string[] = [
|
||||
'NordicNoir'
|
||||
]
|
||||
|
||||
// 标签相关(固定标签,v-show 控制显示)
|
||||
const showReportTag = ref(false)
|
||||
const editorRef = ref<HTMLDivElement | null>(null)
|
||||
const inputValue = ref<string>('')
|
||||
|
||||
const toogltReportTag = () => {
|
||||
console.log(showReportTag.value)
|
||||
|
||||
showReportTag.value = !showReportTag.value
|
||||
}
|
||||
|
||||
const handleEditorInput = () => {
|
||||
if (!editorRef.value) return
|
||||
|
||||
// 提取纯文本(排除标签)
|
||||
let text = ''
|
||||
const walker = document.createTreeWalker(editorRef.value, NodeFilter.SHOW_TEXT, null)
|
||||
|
||||
let node: Node | null
|
||||
while ((node = walker.nextNode())) {
|
||||
text += node.textContent
|
||||
}
|
||||
|
||||
// 移除末尾的空格(如果有的话)
|
||||
text = text.replace(/\s+$/, '')
|
||||
inputValue.value = text
|
||||
|
||||
// 自动调整高度
|
||||
autoResizeEditor()
|
||||
}
|
||||
|
||||
const handleEditorKeydown = (e: KeyboardEvent) => {
|
||||
// if (e.key === 'Backspace') {
|
||||
// const selection = window.getSelection()
|
||||
// if (selection && selection.rangeCount > 0) {
|
||||
// const range = selection.getRangeAt(0)
|
||||
// if (range.collapsed) {
|
||||
// const node = range.startContainer
|
||||
// const offset = range.startOffset
|
||||
// // 如果光标在文本节点开头,且前一个兄弟是标签
|
||||
// if (
|
||||
// offset === 0 &&
|
||||
// node.nodeType === Node.TEXT_NODE &&
|
||||
// node.previousSibling &&
|
||||
// (node.previousSibling as HTMLElement).classList.contains('editor-tag')
|
||||
// ) {
|
||||
// e.preventDefault()
|
||||
// nextTick(() => (showReportTag.value = false))
|
||||
// }
|
||||
// // 如果光标在编辑器开头,且第一个子节点是标签
|
||||
// else if (
|
||||
// offset === 0 &&
|
||||
// node === editorRef.value &&
|
||||
// editorRef.value.firstChild &&
|
||||
// (editorRef.value.firstChild as HTMLElement).classList.contains('editor-tag')
|
||||
// ) {
|
||||
// e.preventDefault()
|
||||
// nextTick(() => (showReportTag.value = false))
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
const handleEditorPaste = (e: ClipboardEvent) => {
|
||||
e.preventDefault()
|
||||
const text = e.clipboardData?.getData('text/plain') || ''
|
||||
document.execCommand('insertText', false, text)
|
||||
}
|
||||
|
||||
const autoResizeEditor = () => {
|
||||
const editor = editorRef.value
|
||||
if (editor) {
|
||||
editor.style.height = 'auto'
|
||||
const maxHeight = 20 * parseFloat(getComputedStyle(document.documentElement).fontSize || '16')
|
||||
editor.style.height = Math.min(editor.scrollHeight, maxHeight) + 'px'
|
||||
}
|
||||
}
|
||||
|
||||
// 监听 inputValue 外部变化
|
||||
watch(inputValue, () => {
|
||||
nextTick(() => {
|
||||
autoResizeEditor()
|
||||
})
|
||||
})
|
||||
|
||||
// 初始化编辑器高度
|
||||
onMounted(() => {
|
||||
autoResizeEditor()
|
||||
})
|
||||
|
||||
const typeValue = ref<string>('')
|
||||
const areaValue = ref<string>('')
|
||||
const styleValue = ref<string>('')
|
||||
@@ -170,32 +356,158 @@ const styleOptions = ref<any[]>(
|
||||
|
||||
<style lang="less" scoped>
|
||||
.assist-input-wrapper {
|
||||
height: 23.5rem;
|
||||
min-height: 23.5rem;
|
||||
max-height: 43.5rem;
|
||||
width: 106.3rem;
|
||||
border-radius: 2.8rem;
|
||||
background-color: #fff;
|
||||
border: 0.1rem solid #00000005;
|
||||
box-shadow: 0px 5px 14px 0px #0000001a;
|
||||
margin: 0 auto;
|
||||
padding: 3.4rem 1.7rem 1.7rem 2rem;
|
||||
.input {
|
||||
flex: 1;
|
||||
padding: 0;
|
||||
position: relative;
|
||||
|
||||
.report-btn {
|
||||
position: absolute;
|
||||
bottom: -7.4rem;
|
||||
height: 4.4rem;
|
||||
border-radius: 2.2rem;
|
||||
width: 20rem;
|
||||
background-color: #fff;
|
||||
border: 0.11rem solid #f6f4ef1a;
|
||||
column-gap: 1.2rem;
|
||||
cursor: pointer;
|
||||
.c-svg {
|
||||
width: 1.5rem;
|
||||
height: 1.9rem;
|
||||
}
|
||||
}
|
||||
|
||||
.scroll-content {
|
||||
overflow-y: visible;
|
||||
padding: 3.4rem 1.7rem 1.7rem;
|
||||
}
|
||||
|
||||
.editor {
|
||||
width: 100%;
|
||||
min-height: 5rem;
|
||||
max-height: 20rem;
|
||||
border: none;
|
||||
outline: none;
|
||||
padding: 0 1.4rem;
|
||||
padding: 0 1.4rem 1.4rem;
|
||||
font-size: 2rem;
|
||||
font-family: 'InterRegular';
|
||||
font-weight: 400;
|
||||
color: #000000;
|
||||
resize: none;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
line-height: 1.5;
|
||||
white-space: pre-wrap;
|
||||
word-wrap: break-word;
|
||||
|
||||
// 占位符
|
||||
&:empty::before {
|
||||
content: attr(placeholder);
|
||||
color: #999;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
// 标签样式
|
||||
.editor-tag {
|
||||
width: 21.8rem;
|
||||
height: 4.4rem;
|
||||
display: inline-flex;
|
||||
position: initial;
|
||||
bottom: initial;
|
||||
border: 0.11rem solid #0000001a;
|
||||
font-family: 'GeneralMedium';
|
||||
font-weight: 500;
|
||||
font-size: 1.8rem;
|
||||
column-gap: 0;
|
||||
span {
|
||||
margin: 0 0.7rem 0 1.2rem;
|
||||
}
|
||||
.c-svg.close-icon {
|
||||
width: 2.4rem;
|
||||
height: 2.4rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 标签容器(已废弃,保留兼容性)
|
||||
.tags-container {
|
||||
display: inline-flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.5rem;
|
||||
padding: 0 1.4rem 0.5rem;
|
||||
|
||||
.tag-item {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
|
||||
// 图片预览区域样式
|
||||
.image-preview-list {
|
||||
padding: 0 1.4rem 1rem;
|
||||
column-gap: 1rem;
|
||||
max-height: 15rem;
|
||||
overflow-y: auto;
|
||||
flex-shrink: 0;
|
||||
|
||||
.image-preview-item {
|
||||
position: relative;
|
||||
width: 8.6rem;
|
||||
height: 8.6rem;
|
||||
border-radius: 1.5rem;
|
||||
overflow: hidden;
|
||||
flex-shrink: 0;
|
||||
border: 0.1rem solid #cdcdcd;
|
||||
|
||||
.preview-image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
border-radius: 0.8rem;
|
||||
}
|
||||
|
||||
.image-remove-btn {
|
||||
position: absolute;
|
||||
top: 0.2rem;
|
||||
right: 0.2rem;
|
||||
width: 1.6rem;
|
||||
height: 1.6rem;
|
||||
color: #fff;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 1.2rem;
|
||||
cursor: pointer;
|
||||
opacity: 0;
|
||||
transition: opacity 0.2s ease;
|
||||
}
|
||||
|
||||
&:hover .image-remove-btn {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
.operate {
|
||||
column-gap: 2rem;
|
||||
flex-shrink: 0;
|
||||
margin-top: auto;
|
||||
padding: 0 1.7rem 1.7rem;
|
||||
|
||||
.left {
|
||||
column-gap: 2rem;
|
||||
}
|
||||
.attach {
|
||||
width: 4rem;
|
||||
height: 4rem;
|
||||
border: 1px solid rgba(0, 0, 0, 0.1);
|
||||
border-radius: 50%;
|
||||
cursor: pointer;
|
||||
}
|
||||
.el-select {
|
||||
width: 13.9rem;
|
||||
@@ -235,6 +547,21 @@ const styleOptions = ref<any[]>(
|
||||
height: 2.4rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
.create-btn {
|
||||
background-color: #ff7a51;
|
||||
height: 4rem;
|
||||
width: 13rem;
|
||||
color: #fff;
|
||||
border-radius: 4.2rem;
|
||||
font-family: 'Mazzard';
|
||||
font-weight: 600;
|
||||
font-size: 1.28rem;
|
||||
cursor: pointer;
|
||||
.shining-icon {
|
||||
width: 1.4rem;
|
||||
height: 1.4rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.input-option {
|
||||
@@ -336,12 +663,15 @@ const styleOptions = ref<any[]>(
|
||||
}
|
||||
|
||||
.fida-setting-popover {
|
||||
width: 34.2rem !important;
|
||||
padding: 0 !important;
|
||||
border-radius: 0.6rem !important;
|
||||
box-shadow: 0px 5px 20px 0px rgba(0, 0, 0, 0.15) !important;
|
||||
background-color: #fff !important;
|
||||
border: none !important;
|
||||
width: 25.6rem;
|
||||
height: 23.9rem;
|
||||
|
||||
box-shadow: 0px 11px 20px 0px #0000001a;
|
||||
border-radius: 0.6rem;
|
||||
}
|
||||
|
||||
// .fida-setting-popover-content {
|
||||
@@ -349,43 +679,70 @@ const styleOptions = ref<any[]>(
|
||||
// }
|
||||
|
||||
.fida-setting-popover-header {
|
||||
font-family: 'GeneralMedium';
|
||||
font-weight: 500;
|
||||
font-size: 1.6rem;
|
||||
font-weight: 400;
|
||||
font-size: 1.4rem;
|
||||
color: #000;
|
||||
margin-bottom: 2rem;
|
||||
margin-bottom: 2rem !important;
|
||||
}
|
||||
.fida-setting-popover-content {
|
||||
padding: 1.6rem 1.4rem 2.2rem !important;
|
||||
}
|
||||
|
||||
.fida-setting-slider-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 2rem;
|
||||
row-gap: 1rem;
|
||||
}
|
||||
|
||||
.fida-setting-slider-item {
|
||||
.fida-slider-label {
|
||||
font-family: 'GeneralMedium';
|
||||
font-weight: 500;
|
||||
font-size: 1.4rem;
|
||||
font-weight: 400;
|
||||
font-size: 1.2rem;
|
||||
color: #000;
|
||||
margin-bottom: 0.8rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
.fida-slider-row {
|
||||
gap: 1rem;
|
||||
column-gap: 2.6rem;
|
||||
.el-slider {
|
||||
flex: 1;
|
||||
}
|
||||
.fida-slider-value {
|
||||
font-family: 'GeneralMedium';
|
||||
font-weight: 500;
|
||||
font-weight: 400;
|
||||
font-size: 1.4rem;
|
||||
color: #000;
|
||||
min-width: 3.5rem;
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
// :deep(.el-slider) {
|
||||
|
||||
// }
|
||||
}
|
||||
.setting-popover-slider {
|
||||
--el-slider-height: 0.4rem;
|
||||
height: fit-content;
|
||||
.el-slider__runway {
|
||||
height: var(--el-slider-height);
|
||||
background-color: #e8e8e8;
|
||||
border-radius: 0.2rem;
|
||||
}
|
||||
.el-slider__bar {
|
||||
height: var(--el-slider-height);
|
||||
background-color: #000;
|
||||
border-radius: 0.2rem;
|
||||
}
|
||||
.el-slider__button-wrapper {
|
||||
width: fit-content;
|
||||
height: fit-content;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.el-slider__button {
|
||||
width: 1rem;
|
||||
height: 1rem;
|
||||
background-color: #000;
|
||||
border-radius: 50%;
|
||||
border: none;
|
||||
}
|
||||
.el-slider__stop {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -30,9 +30,11 @@
|
||||
flex-direction: column;
|
||||
> .bottom-view {
|
||||
flex: 1;
|
||||
// background-color: #fff;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
> * {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,10 @@
|
||||
<span class="icon"><svg-icon name="home" size="24" /></span>
|
||||
<span class="title" v-show="!isCollapse">{{ $t('Home.home') }}</span>
|
||||
</div> -->
|
||||
<div class="menu-item" @click="onCanvas">
|
||||
<!-- <span class="icon"><svg-icon name="home" size="24" /></span> -->
|
||||
<span class="title">画布</span>
|
||||
</div>
|
||||
<div class="menu-item" @click="onHistory" :class="{ active: showHistory }">
|
||||
<span class="icon"><svg-icon name="history" size="24" /></span>
|
||||
<span class="title" v-show="!isCollapse">{{ $t('Home.history') }}</span>
|
||||
@@ -25,15 +29,24 @@
|
||||
<div class="history-list" v-show="!isCollapse && showHistory">
|
||||
<div v-for="item in historyList" :key="item.name" class="history-item">
|
||||
<div v-if="item.title" class="title">{{ item.name }}</div>
|
||||
<div v-else class="box" @click="onClickHistoryItem(item)">
|
||||
<div
|
||||
v-else
|
||||
class="box"
|
||||
@click="onClickHistoryItem(item)"
|
||||
:class="{ active: item.id == id }"
|
||||
>
|
||||
<span>{{ item.name }}</span>
|
||||
<el-popover placement="right" trigger="click">
|
||||
<el-popover
|
||||
placement="right"
|
||||
trigger="click"
|
||||
popper-style="padding: 1rem 0.5rem;"
|
||||
>
|
||||
<template #reference>
|
||||
<span class="icon"><svg-icon name="more" size="16" /></span>
|
||||
<span @click.stop class="icon"><svg-icon name="more" size="16" /></span>
|
||||
</template>
|
||||
<div class="button-box">
|
||||
<div class="rename-btn">Rename</div>
|
||||
<div class="delete-btn">Delete</div>
|
||||
<div class="history-item-menu">
|
||||
<div class="rename" @click="onRenameHistoryItem(item)">Rename</div>
|
||||
<div class="delete" @click="onDeleteHistoryItem(item)">Delete</div>
|
||||
</div>
|
||||
</el-popover>
|
||||
</div>
|
||||
@@ -50,6 +63,7 @@
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
import { useGlobalStore } from '@/stores'
|
||||
const id = computed(() => route.params.id)
|
||||
const globalStore = useGlobalStore()
|
||||
const isCollapse = computed(() => globalStore.state.homeLeftNavCollapse)
|
||||
const onCollapse = () => {
|
||||
@@ -93,13 +107,27 @@
|
||||
const onHome = () => {
|
||||
console.log('onHome')
|
||||
}
|
||||
const onCanvas = () => {
|
||||
router.push({ name: 'canvas' })
|
||||
}
|
||||
const onHistory = () => {
|
||||
showHistory.value = !showHistory.value
|
||||
}
|
||||
const onClickHistoryItem = (item: any) => {
|
||||
console.log(item)
|
||||
router.push({ name: 'test', params: { id: item.id } })
|
||||
}
|
||||
const onRenameHistoryItem = (item: any) => {
|
||||
// const index = historyList.value.findIndex((i: any) => i.id == item.id)
|
||||
// if (index != -1) {
|
||||
// }
|
||||
}
|
||||
const onDeleteHistoryItem = (item: any) => {
|
||||
console.log(item)
|
||||
const index = historyList.value.findIndex((i: any) => i.id == item.id)
|
||||
if (index != -1) {
|
||||
historyList.value.splice(index, 1)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
@@ -131,7 +159,7 @@
|
||||
margin-right: 1rem;
|
||||
}
|
||||
> .logo-text {
|
||||
font-family: Mazzard;
|
||||
font-family: SemiBold;
|
||||
font-weight: 600;
|
||||
font-size: 3rem;
|
||||
margin-right: auto;
|
||||
@@ -204,14 +232,19 @@
|
||||
> .title {
|
||||
font-weight: 600;
|
||||
font-size: 1.6rem;
|
||||
font-family: SemiBold;
|
||||
}
|
||||
> .box {
|
||||
font-family: Regular;
|
||||
border-radius: 0.8rem;
|
||||
cursor: pointer;
|
||||
&.active,
|
||||
&:hover {
|
||||
background-color: rgba(0, 0, 0, 0.06);
|
||||
}
|
||||
&.active {
|
||||
font-family: SemiBold;
|
||||
}
|
||||
> .label {
|
||||
flex: 1;
|
||||
font-weight: 400;
|
||||
@@ -220,8 +253,28 @@
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
}
|
||||
> .icon {
|
||||
width: 2.5rem;
|
||||
height: 2.5rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.history-item-menu {
|
||||
user-select: none;
|
||||
> div {
|
||||
cursor: pointer;
|
||||
padding: 0.5rem 1rem;
|
||||
&:hover {
|
||||
background-color: rgba(0, 0, 0, 0.06);
|
||||
}
|
||||
}
|
||||
> .rename {
|
||||
color: #409eff;
|
||||
}
|
||||
> .delete {
|
||||
color: #ff4d4f;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="test">
|
||||
<p>老八秘制小汉堡 - {{ id }}</p>
|
||||
<p>Conversation Item - {{ id }}</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -13,10 +13,9 @@
|
||||
|
||||
<style lang="less" scoped>
|
||||
.test {
|
||||
flex: 1;
|
||||
margin: 10px;
|
||||
border-radius: 10px;
|
||||
// background-color: rgb(242, 130, 90);
|
||||
margin: 2rem;
|
||||
border-radius: 2rem;
|
||||
background-color: rgb(242, 130, 90);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
height: 4.3rem;
|
||||
margin-right: 1rem;
|
||||
background-color: rgba(255, 252, 244, 1);
|
||||
border: 1px solid rgba(233, 121, 60, 1);
|
||||
border: 1px solid #FFCF90;
|
||||
border-radius: 0.8rem;
|
||||
> .credits {
|
||||
flex: 1;
|
||||
@@ -78,7 +78,7 @@
|
||||
> .link {
|
||||
height: 100%;
|
||||
width: 0;
|
||||
border-right: 1px solid rgba(233, 121, 60, 1);
|
||||
border-right: 1px solid #FFCF90;
|
||||
}
|
||||
> .icon {
|
||||
cursor: pointer;
|
||||
|
||||
Reference in New Issue
Block a user