Merge branch 'main' of ssh://18.167.251.121:10002/aidlab/FiDA_Front
This commit is contained in:
5
src/assets/icons/c-delete.svg
Normal file
5
src/assets/icons/c-delete.svg
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<svg width="13" height="14" viewBox="0 0 13 14" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M5.77778 6.3C5.77778 5.9134 5.45443 5.6 5.05556 5.6C4.65668 5.6 4.33333 5.9134 4.33333 6.3V9.8C4.33333 10.1866 4.65668 10.5 5.05556 10.5C5.45443 10.5 5.77778 10.1866 5.77778 9.8V6.3Z" fill="#FFEAE2"/>
|
||||||
|
<path d="M8.66667 6.3C8.66667 5.9134 8.34332 5.6 7.94444 5.6C7.54557 5.6 7.22222 5.9134 7.22222 6.3V9.8C7.22222 10.1866 7.54557 10.5 7.94444 10.5C8.34332 10.5 8.66667 10.1866 8.66667 9.8V6.3Z" fill="#FFEAE2"/>
|
||||||
|
<path d="M6.97498 0C8.3006 0 9.45611 0.874433 9.77762 2.1209L9.95278 2.8H11.5453C11.5515 2.79992 11.5578 2.79992 11.564 2.8H12.2778C12.6767 2.8 13 3.1134 13 3.5C13 3.8866 12.6767 4.2 12.2778 4.2H12.2045L11.3977 11.4983C11.2405 12.9211 10.0017 14 8.5253 14H4.4747C2.99834 14 1.75954 12.9211 1.60225 11.4983L0.79547 4.2H0.722222C0.32335 4.2 0 3.8866 0 3.5C0 3.1134 0.32335 2.8 0.722222 2.8H1.43598C1.44223 2.79992 1.44846 2.79992 1.45467 2.8H3.04722L3.22238 2.1209C3.54389 0.874431 4.6994 0 6.02502 0H6.97498ZM9.40399 4.2C9.39353 4.20022 9.3831 4.20022 9.37269 4.2H3.6273C3.6169 4.20022 3.60647 4.20022 3.59601 4.2H2.24818L3.03848 11.3491C3.11712 12.0605 3.73652 12.6 4.4747 12.6H8.5253C9.26348 12.6 9.88288 12.0605 9.96152 11.3491L10.7518 4.2H9.40399ZM4.62369 2.46045L4.53611 2.8H8.46387L8.37629 2.46045C8.21554 1.83722 7.63778 1.4 6.97497 1.4H6.025C5.3622 1.4 4.78444 1.83722 4.62369 2.46045Z" fill="#FFEAE2"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.4 KiB |
@@ -30,7 +30,7 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import flowCanvas from './FlowCanvas/flow-canvas.vue'
|
import flowCanvas from './FlowCanvas/flow-canvas.vue'
|
||||||
import card from './FlowCanvas/components/cards/index.vue'
|
import card from './FlowCanvas/components/nodes/cards/index.vue'
|
||||||
import { computed, ref, markRaw, onMounted, reactive, nextTick } from 'vue'
|
import { computed, ref, markRaw, onMounted, reactive, nextTick } from 'vue'
|
||||||
const data = reactive({
|
const data = reactive({
|
||||||
x: 100,
|
x: 100,
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
:position="handle.position"
|
:position="handle.position"
|
||||||
:connectable="false"
|
:connectable="false"
|
||||||
/>
|
/>
|
||||||
<div class="item">
|
<div class="item" @mousedown="(e) => stateManager.setActiveNodeID(node.id)">
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</div>
|
</div>
|
||||||
<div class="add" @mousedown.stop v-if="isAdd" @click="onAdd">
|
<div class="add" @mousedown.stop v-if="isAdd" @click="onAdd">
|
||||||
|
|||||||
@@ -156,7 +156,7 @@
|
|||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
.card {
|
.card {
|
||||||
width: 250px;
|
width: 244px;
|
||||||
height: auto;
|
height: auto;
|
||||||
--border-radius: 16px;
|
--border-radius: 16px;
|
||||||
border-radius: var(--border-radius);
|
border-radius: var(--border-radius);
|
||||||
@@ -164,6 +164,9 @@
|
|||||||
box-shadow: 0 15px 21px 0 rgba(0, 0, 0, 0.05);
|
box-shadow: 0 15px 21px 0 rgba(0, 0, 0, 0.05);
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
&.active {
|
||||||
|
box-shadow: 0 15px 21px 0 rgba(0, 0, 0, 0.05), 0 0 0 2px #fae5d8;
|
||||||
|
}
|
||||||
> .header {
|
> .header {
|
||||||
border-radius: var(--border-radius) var(--border-radius) 0 0;
|
border-radius: var(--border-radius) var(--border-radius) 0 0;
|
||||||
height: 50px;
|
height: 50px;
|
||||||
@@ -173,7 +176,7 @@
|
|||||||
padding: 0 16px;
|
padding: 0 16px;
|
||||||
position: relative;
|
position: relative;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
> .delete-icon{
|
> .delete-icon {
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,11 @@
|
|||||||
<template>
|
<template>
|
||||||
<!-- 结果图片 -->
|
<!-- 结果图片 -->
|
||||||
<div
|
<div class="text" @mousedown="onMouseDown">
|
||||||
class="text"
|
|
||||||
:class="{ edit }"
|
|
||||||
@click="onClick"
|
|
||||||
@mousedown="onMouseDown"
|
|
||||||
@dblclick="onDoubleClick"
|
|
||||||
>
|
|
||||||
<div
|
<div
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
class="input"
|
class="input"
|
||||||
ref="inputRef"
|
ref="inputRef"
|
||||||
:contenteditable="edit"
|
:contenteditable="active"
|
||||||
@input="onInput"
|
@input="onInput"
|
||||||
@blur="onBlur"
|
@blur="onBlur"
|
||||||
@paste.prevent
|
@paste.prevent
|
||||||
@@ -20,8 +14,12 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { reactive, ref, onMounted, nextTick } from 'vue'
|
import { reactive, ref, onMounted, nextTick, watch } from 'vue'
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
|
active: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
data: {
|
data: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: () => ({})
|
default: () => ({})
|
||||||
@@ -31,7 +29,6 @@
|
|||||||
const data = reactive({
|
const data = reactive({
|
||||||
text: props.data?.text || '点击编辑文本'
|
text: props.data?.text || '点击编辑文本'
|
||||||
})
|
})
|
||||||
const edit = ref(false)
|
|
||||||
const time = ref(null)
|
const time = ref(null)
|
||||||
const inputRef = ref<any>()
|
const inputRef = ref<any>()
|
||||||
const onInput = () => {
|
const onInput = () => {
|
||||||
@@ -39,27 +36,26 @@
|
|||||||
data.text = text
|
data.text = text
|
||||||
emit('update-data', data)
|
emit('update-data', data)
|
||||||
}
|
}
|
||||||
const onBlur = () => {
|
// watch(
|
||||||
edit.value = false
|
// () => props.active,
|
||||||
}
|
// (newVal) => {
|
||||||
const onClick = () => {
|
// if (!newVal) return
|
||||||
if (edit.value) return
|
// nextTick(() => {
|
||||||
edit.value = true
|
// // 光标定位到文本末尾
|
||||||
nextTick(() => {
|
// const range = document.createRange()
|
||||||
// 光标定位到文本末尾
|
// const selection = window.getSelection()
|
||||||
const range = document.createRange()
|
// range.selectNodeContents(inputRef.value)
|
||||||
const selection = window.getSelection()
|
// range.collapse(false)
|
||||||
range.selectNodeContents(inputRef.value)
|
// selection.removeAllRanges()
|
||||||
range.collapse(false)
|
// selection.addRange(range)
|
||||||
selection.removeAllRanges()
|
// })
|
||||||
selection.addRange(range)
|
// }
|
||||||
})
|
// )
|
||||||
}
|
|
||||||
const onDoubleClick = () => {
|
|
||||||
clearTimeout(time.value)
|
|
||||||
}
|
|
||||||
const onMouseDown = (e: MouseEvent) => {
|
const onMouseDown = (e: MouseEvent) => {
|
||||||
if (edit.value) e.stopPropagation()
|
if (props.active) e.stopPropagation()
|
||||||
|
}
|
||||||
|
const onBlur = () => {
|
||||||
|
// emit('update-data', data)
|
||||||
}
|
}
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
inputRef.value.innerHTML = data.text
|
inputRef.value.innerHTML = data.text
|
||||||
@@ -73,7 +69,7 @@
|
|||||||
user-select: none;
|
user-select: none;
|
||||||
border: 1px solid transparent;
|
border: 1px solid transparent;
|
||||||
padding: 2px;
|
padding: 2px;
|
||||||
&.edit {
|
&.active {
|
||||||
border-color: #000;
|
border-color: #000;
|
||||||
> .input {
|
> .input {
|
||||||
cursor: text;
|
cursor: text;
|
||||||
|
|||||||
@@ -27,6 +27,8 @@
|
|||||||
>
|
>
|
||||||
<component
|
<component
|
||||||
:is="components[node.data.component]"
|
:is="components[node.data.component]"
|
||||||
|
:class="{ active: stateManager.activeNodeID.value === node.id }"
|
||||||
|
:active="stateManager.activeNodeID.value === node.id"
|
||||||
:node="node"
|
:node="node"
|
||||||
:config="node.data"
|
:config="node.data"
|
||||||
:data="node.data.data"
|
:data="node.data.data"
|
||||||
@@ -127,7 +129,11 @@
|
|||||||
stateManager.nodes.value = layout(
|
stateManager.nodes.value = layout(
|
||||||
stateManager.nodes.value,
|
stateManager.nodes.value,
|
||||||
stateManager.edges.value,
|
stateManager.edges.value,
|
||||||
direction
|
direction,
|
||||||
|
{
|
||||||
|
nodesep: nodeManager.nodesep,
|
||||||
|
ranksep: nodeManager.ranksep
|
||||||
|
}
|
||||||
)
|
)
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
fitView({ maxZoom: 1 })
|
fitView({ maxZoom: 1 })
|
||||||
@@ -187,6 +193,15 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
nodeManager.createResultNode({
|
||||||
|
data: {
|
||||||
|
disableDelete: true,
|
||||||
|
isHeader: false,
|
||||||
|
data: {
|
||||||
|
url: props.config.url
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
<style lang="less">
|
<style lang="less">
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ export class EventManager {
|
|||||||
}
|
}
|
||||||
/** 处理点击 */
|
/** 处理点击 */
|
||||||
handleClick(event: any) {
|
handleClick(event: any) {
|
||||||
|
this.stateManager.setActiveNodeID("")
|
||||||
const tool = this.stateManager.tool.value
|
const tool = this.stateManager.tool.value
|
||||||
if (tool === TOOLS.TEXT) {
|
if (tool === TOOLS.TEXT) {
|
||||||
const { x, y, zoom } = this.vueFlow.value.viewport
|
const { x, y, zoom } = this.vueFlow.value.viewport
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ interface NodeOptions {
|
|||||||
export class NodeManager {
|
export class NodeManager {
|
||||||
stateManager: any
|
stateManager: any
|
||||||
vueFlow: any
|
vueFlow: any
|
||||||
|
nodesep = 100 // 节点间距
|
||||||
|
ranksep = 100 // 层级间距
|
||||||
constructor(options) {
|
constructor(options) {
|
||||||
this.stateManager = options.stateManager;
|
this.stateManager = options.stateManager;
|
||||||
this.vueFlow = options.vueFlow
|
this.vueFlow = options.vueFlow
|
||||||
@@ -37,7 +39,7 @@ export class NodeManager {
|
|||||||
(!snode ?
|
(!snode ?
|
||||||
{ x: positionX, y: positionY } :
|
{ x: positionX, y: positionY } :
|
||||||
{
|
{
|
||||||
x: snode.position.x + snode.dimensions.width + 50 + positionX,
|
x: snode.position.x + snode.dimensions.width + this.nodesep + positionX,
|
||||||
y: snode.position.y + positionY
|
y: snode.position.y + positionY
|
||||||
})
|
})
|
||||||
const data = options?.data || {}
|
const data = options?.data || {}
|
||||||
@@ -100,18 +102,18 @@ export class NodeManager {
|
|||||||
}
|
}
|
||||||
return this.createNode(options_)
|
return this.createNode(options_)
|
||||||
}
|
}
|
||||||
|
|
||||||
copyNodeById(id: string) {
|
copyNodeById(id: string) {
|
||||||
const node = this.stateManager.getNodeById(id)
|
const node = this.stateManager.getNodeById(id)
|
||||||
const flowNode = this.stateManager.flowManager.getNodeById(id)
|
const flowNode = this.stateManager.flowManager.getNodeById(id)
|
||||||
console.log(node,this.stateManager.flowManager.getNodeById(id))
|
console.log(node, this.stateManager.flowManager.getNodeById(id))
|
||||||
if (!node) return console.warn(`copyNodeById: ${id}找不到对应节点`)
|
if (!node) return console.warn(`copyNodeById: ${id}找不到对应节点`)
|
||||||
const node_ = {
|
const node_ = {
|
||||||
...JSON.parse(JSON.stringify(node)),
|
...JSON.parse(JSON.stringify(node)),
|
||||||
id: createId(),
|
id: createId(),
|
||||||
position: {
|
position: {
|
||||||
x: node.position.x,
|
x: node.position.x,
|
||||||
y: node.position.y + (flowNode?.dimensions?.height || 0) + 50,
|
y: node.position.y + (flowNode?.dimensions?.height || 0) + this.ranksep,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
delete node_.data?.superiorID
|
delete node_.data?.superiorID
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ export interface NodesItem {
|
|||||||
}
|
}
|
||||||
export class StateManager {
|
export class StateManager {
|
||||||
vueFlow: any
|
vueFlow: any
|
||||||
|
activeNodeID: any
|
||||||
nodes: any
|
nodes: any
|
||||||
nodes_: any
|
nodes_: any
|
||||||
edges: any
|
edges: any
|
||||||
@@ -49,6 +50,7 @@ export class StateManager {
|
|||||||
this.historyList = ref([])
|
this.historyList = ref([])
|
||||||
this.historyIndex = ref(0)
|
this.historyIndex = ref(0)
|
||||||
|
|
||||||
|
this.activeNodeID = ref("")
|
||||||
this.nodes = ref<NodesItem[]>([]);
|
this.nodes = ref<NodesItem[]>([]);
|
||||||
this.nodes_ = computed(() => {
|
this.nodes_ = computed(() => {
|
||||||
return this.nodes.value.map((node, index) => {
|
return this.nodes.value.map((node, index) => {
|
||||||
@@ -90,6 +92,8 @@ export class StateManager {
|
|||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
/** 设置激活节点 */
|
||||||
|
setActiveNodeID(id: string) { this.activeNodeID.value = id }
|
||||||
/** 添加节点 */
|
/** 添加节点 */
|
||||||
addNode(node: NodesItem) {
|
addNode(node: NodesItem) {
|
||||||
this.nodes.value.push(node);
|
this.nodes.value.push(node);
|
||||||
|
|||||||
@@ -14,7 +14,9 @@ export function useLayout() {
|
|||||||
|
|
||||||
const previousDirection = ref('LR')
|
const previousDirection = ref('LR')
|
||||||
|
|
||||||
function layout(nodes, edges, direction = 'LR') {
|
function layout(nodes, edges, direction = 'LR', options) {
|
||||||
|
const nodesep = options?.nodesep || 50 // 节点间距
|
||||||
|
const ranksep = options?.ranksep || 50 // 层级间距
|
||||||
// 验证和规范化方向参数
|
// 验证和规范化方向参数
|
||||||
const validDirections = ['TB', 'BT', 'LR', 'RL']
|
const validDirections = ['TB', 'BT', 'LR', 'RL']
|
||||||
const layoutDirection = validDirections.includes(direction) ? direction : 'LR'
|
const layoutDirection = validDirections.includes(direction) ? direction : 'LR'
|
||||||
@@ -28,7 +30,11 @@ export function useLayout() {
|
|||||||
|
|
||||||
// 根据方向判断是否为水平布局
|
// 根据方向判断是否为水平布局
|
||||||
const isHorizontal = layoutDirection === 'LR' || layoutDirection === 'RL'
|
const isHorizontal = layoutDirection === 'LR' || layoutDirection === 'RL'
|
||||||
dagreGraph.setGraph({ rankdir: layoutDirection })
|
dagreGraph.setGraph({
|
||||||
|
rankdir: layoutDirection,
|
||||||
|
nodesep,
|
||||||
|
ranksep,
|
||||||
|
})
|
||||||
|
|
||||||
previousDirection.value = layoutDirection
|
previousDirection.value = layoutDirection
|
||||||
|
|
||||||
@@ -47,7 +53,7 @@ export function useLayout() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dagre.layout(dagreGraph)
|
dagre.layout(dagreGraph)
|
||||||
|
|
||||||
// set nodes with updated positions
|
// set nodes with updated positions
|
||||||
return nodes.map((node) => {
|
return nodes.map((node) => {
|
||||||
const nodeWithPosition = dagreGraph.node(node.id)
|
const nodeWithPosition = dagreGraph.node(node.id)
|
||||||
@@ -125,20 +131,20 @@ export function findAndAddChild(items, targetId, newChild) {
|
|||||||
*/
|
*/
|
||||||
export function findAndRemoveChild(items, targetId) {
|
export function findAndRemoveChild(items, targetId) {
|
||||||
for (let i = 0; i < items.length; i++) {
|
for (let i = 0; i < items.length; i++) {
|
||||||
const item = items[i]
|
const item = items[i]
|
||||||
|
|
||||||
// 如果找到目标节点,从当前数组中删除
|
// 如果找到目标节点,从当前数组中删除
|
||||||
if (item.id === targetId) {
|
if (item.id === targetId) {
|
||||||
items.splice(i, 1)
|
items.splice(i, 1)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// 递归搜索子节点
|
// 递归搜索子节点
|
||||||
if (item.children && item.children.length > 0) {
|
if (item.children && item.children.length > 0) {
|
||||||
const found = findAndRemoveChild(item.children, targetId)
|
const found = findAndRemoveChild(item.children, targetId)
|
||||||
if (found) return true
|
if (found) return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@@ -1,174 +1,179 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="assist-input-wrapper flex flex-col" :class="{ agent: isAgentMode }">
|
<div class="assist-input-wrapper flex flex-col" :class="{ agent: isAgentMode }">
|
||||||
<div class="scroll-content flex-col">
|
<div class="animate-container flex-1 flex flex-col">
|
||||||
<!-- 图片预览区域 -->
|
<div class="scroll-content flex-col">
|
||||||
<div v-if="uploadedImages.length > 0" class="image-preview-list flex wrap">
|
<!-- 图片预览区域 -->
|
||||||
<div
|
<div v-if="uploadedImages.length > 0" class="image-preview-list flex wrap">
|
||||||
v-for="(image, index) in uploadedImages"
|
<div
|
||||||
:key="index"
|
v-for="(image, index) in uploadedImages"
|
||||||
class="image-preview-item"
|
:key="index"
|
||||||
>
|
class="image-preview-item"
|
||||||
<img :src="image.url" :alt="image.name" class="preview-image" />
|
>
|
||||||
<div class="image-remove-btn" @click="removeImage(index)">
|
<img :src="image.url" :alt="image.name" class="preview-image" />
|
||||||
<SvgIcon name="delete" size="16" />
|
<div class="image-remove-btn" @click="removeImage(index)">
|
||||||
|
<SvgIcon name="delete" size="16" />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- 编辑区域 -->
|
||||||
|
<div
|
||||||
|
ref="editorRef"
|
||||||
|
class="editor"
|
||||||
|
contenteditable="true"
|
||||||
|
:placeholder="$t('Input.placeholder')"
|
||||||
|
@input="handleEditorInput"
|
||||||
|
@paste="handleEditorPaste"
|
||||||
|
@keydown="handleKeyDown"
|
||||||
|
></div>
|
||||||
</div>
|
</div>
|
||||||
<!-- 编辑区域 -->
|
<div class="operate flex align-center space-between">
|
||||||
<div
|
<div class="left flex align-center">
|
||||||
ref="editorRef"
|
<div class="attach flex flex-center" @click="triggerFileUpload">
|
||||||
class="editor"
|
<img src="@/assets/icons/attach.svg" alt="" />
|
||||||
contenteditable="true"
|
</div>
|
||||||
:placeholder="$t('Input.placeholder')"
|
<input
|
||||||
@input="handleEditorInput"
|
ref="fileInputRef"
|
||||||
@paste="handleEditorPaste"
|
type="file"
|
||||||
@keydown="handleKeyDown"
|
accept="image/*"
|
||||||
></div>
|
style="display: none"
|
||||||
</div>
|
@change="handleFileChange"
|
||||||
<div class="operate flex align-center 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-if="!isAgentMode"
|
|
||||||
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-if="!isAgentMode"
|
|
||||||
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 v-if="!isAgentMode" class="fida-style-select-wrapper">
|
|
||||||
<el-select
|
<el-select
|
||||||
v-model="styleValue"
|
v-if="!isAgentMode"
|
||||||
:placeholder="$t('Input.stylePlaceholder')"
|
v-model="typeValue"
|
||||||
@focus="openStylePopup"
|
: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-if="!isAgentMode"
|
||||||
|
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 v-if="!isAgentMode" 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 flex flex-center"
|
||||||
|
:class="{ 'is-selected': tempSelectedValue === item.value }"
|
||||||
|
@click="selectStyle(item.value)"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
:src="getStyleImage(typeValue, item.value)"
|
||||||
|
class="style-bg"
|
||||||
|
/>
|
||||||
|
<span class="fida-option-label flex flex-center">{{
|
||||||
|
item.label
|
||||||
|
}}</span>
|
||||||
|
<img
|
||||||
|
v-show="tempSelectedValue === item.value"
|
||||||
|
src="@/assets/images/checked.png"
|
||||||
|
class="checked-item-icon"
|
||||||
|
/>
|
||||||
|
</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
|
<el-popover
|
||||||
v-model:visible="stylePopupVisible"
|
v-model:visible="settingPopupVisible"
|
||||||
placement="top"
|
placement="top"
|
||||||
:width="342"
|
:width="342"
|
||||||
:show-arrow="false"
|
:show-arrow="false"
|
||||||
trigger="click"
|
trigger="click"
|
||||||
popper-class="fida-style-select-popover"
|
popper-class="fida-setting-popover"
|
||||||
>
|
>
|
||||||
<template #reference>
|
<template #reference>
|
||||||
<div class="fida-style-select-trigger"></div>
|
<img src="@/assets/images/setting.png" class="setting-icon" />
|
||||||
</template>
|
</template>
|
||||||
<div class="fida-style-popover-content flex flex-col">
|
<div class="fida-setting-popover-content flex flex-col">
|
||||||
<div class="fida-style-popover-header">
|
<div class="fida-setting-popover-header">
|
||||||
{{ $t('Input.chooseStyle') }}
|
{{ $t('Input.styleTitle') }}
|
||||||
</div>
|
</div>
|
||||||
<div class="fida-style-popover-grid">
|
<div class="fida-setting-slider-list">
|
||||||
<div
|
<div
|
||||||
v-for="item in styleOptions"
|
v-for="item in settingOptions"
|
||||||
:key="item.value"
|
:key="item.label"
|
||||||
class="fida-style-popover-item flex flex-center"
|
class="fida-setting-slider-item"
|
||||||
:class="{ 'is-selected': tempSelectedValue === item.value }"
|
|
||||||
@click="selectStyle(item.value)"
|
|
||||||
>
|
>
|
||||||
<img
|
<div class="fida-slider-label">{{ $t(item.label) }}</div>
|
||||||
:src="getStyleImage(typeValue, item.value)"
|
<div class="fida-slider-row flex align-center">
|
||||||
class="style-bg"
|
<el-slider
|
||||||
/>
|
class="setting-popover-slider"
|
||||||
<span class="fida-option-label flex flex-center">{{
|
v-model="item.value"
|
||||||
item.label
|
:show-tooltip="false"
|
||||||
}}</span>
|
/>
|
||||||
<img
|
<span class="fida-slider-value">{{ item.value }}%</span>
|
||||||
v-show="tempSelectedValue === item.value"
|
</div>
|
||||||
src="@/assets/images/checked.png"
|
|
||||||
class="checked-item-icon"
|
|
||||||
/>
|
|
||||||
</div>
|
</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>
|
</div>
|
||||||
</el-popover>
|
</el-popover>
|
||||||
</div>
|
</div>
|
||||||
<el-popover
|
<div class="right">
|
||||||
v-model:visible="settingPopupVisible"
|
<div
|
||||||
placement="top"
|
class="create-btn flex flex-center"
|
||||||
:width="342"
|
v-if="!isAgentMode"
|
||||||
:show-arrow="false"
|
@click="handleCreateProject"
|
||||||
trigger="click"
|
>
|
||||||
popper-class="fida-setting-popover"
|
<img src="@/assets/images/shining.png" class="shining-icon" alt="" />
|
||||||
>
|
<span class="create-btn-text">{{ $t('Input.createProject') }}</span>
|
||||||
<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.styleTitle') }}</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
|
|
||||||
class="setting-popover-slider"
|
|
||||||
v-model="item.value"
|
|
||||||
:show-tooltip="false"
|
|
||||||
/>
|
|
||||||
<span class="fida-slider-value">{{ item.value }}%</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</el-popover>
|
|
||||||
</div>
|
|
||||||
<div class="right">
|
|
||||||
<div
|
|
||||||
class="create-btn flex flex-center"
|
|
||||||
v-if="!isAgentMode"
|
|
||||||
@click="handleCreateProject"
|
|
||||||
>
|
|
||||||
<img src="@/assets/images/shining.png" class="shining-icon" alt="" />
|
|
||||||
<span class="create-btn-text">{{ $t('Input.createProject') }}</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div v-else class="sender-btn flex flex-center" @click="handleSendAgent">
|
<div v-else class="sender-btn flex flex-center" @click="handleSendAgent">
|
||||||
<img
|
<img
|
||||||
v-show="!generating"
|
v-show="!generating"
|
||||||
src="@/assets/images/sender.png"
|
src="@/assets/images/sender.png"
|
||||||
alt=""
|
alt=""
|
||||||
class="sender-icon"
|
class="sender-icon"
|
||||||
/>
|
/>
|
||||||
<div v-show="generating" class="sender-pause" />
|
<div v-show="generating" class="sender-pause" />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="!isAgentMode" class="report-btn flex flex-center" @click="toogltReportTag">
|
<div v-if="!isAgentMode" class="report-btn flex flex-center" @click="toogltReportTag">
|
||||||
<SvgIcon class="light-icon" name="light" size="16" />
|
<SvgIcon class="light-icon" name="light" size="16" />
|
||||||
<span>{{ $t('Input.trendingReport') }}</span>
|
<span>{{ $t('Input.trendingReport') }}</span>
|
||||||
@@ -618,24 +623,22 @@
|
|||||||
min-height: 23.5rem;
|
min-height: 23.5rem;
|
||||||
max-height: 43.5rem;
|
max-height: 43.5rem;
|
||||||
width: 106.3rem;
|
width: 106.3rem;
|
||||||
border-radius: 2.8rem;
|
|
||||||
background-color: #fff;
|
|
||||||
border: 0.1rem solid #00000005;
|
|
||||||
box-shadow: 0px 0.5rem 1.4rem 0px #0000001a;
|
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
&:not(.agent):hover {
|
&:not(.agent) .animate-container {
|
||||||
box-shadow: 0px 0.5rem 3.36rem 2.2rem #f1ede999;
|
box-shadow: 0px 0.5rem 1.4rem 0px #0000001a;
|
||||||
transition: all 0.3s ease;
|
transition: all 0.3s ease;
|
||||||
top: -1rem;
|
border-radius: 2.8rem;
|
||||||
|
background-color: #fff;
|
||||||
.report-btn {
|
border: 0.1rem solid #00000005;
|
||||||
bottom: -8.4rem;
|
&:not(.agent):hover {
|
||||||
|
box-shadow: 0px 0.5rem 3.36rem 2.2rem #f1ede999;
|
||||||
|
transform: translateY(-1rem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.scroll-content {
|
.scroll-content {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
|||||||
Reference in New Issue
Block a user