|
@@ -0,0 +1,1550 @@
|
|
|
|
|
+<template>
|
|
|
|
|
+ <!-- AI发展历程 -->
|
|
|
|
|
+ <div class="home-container">
|
|
|
|
|
+ <!-- 展开收起侧边栏 -->
|
|
|
|
|
+ <div class="icon-expand">
|
|
|
|
|
+ <el-icon
|
|
|
|
|
+ @click="toggleDrawer"
|
|
|
|
|
+ :style="{ color: drawerVisible ? 'white' : '#B6B0D8' }"
|
|
|
|
|
+ >
|
|
|
|
|
+ <component :is="drawerVisible ? Fold : Expand" />
|
|
|
|
|
+ <!-- <Tickets /> -->
|
|
|
|
|
+ </el-icon>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <transition name="drawer-slide">
|
|
|
|
|
+ <div class="main-content" v-if="drawerVisible">
|
|
|
|
|
+ <!-- 添加抽屉 -->
|
|
|
|
|
+ <div class="drawer-box">
|
|
|
|
|
+ <el-row class="tac">
|
|
|
|
|
+ <el-col :span="12">
|
|
|
|
|
+ <h3 class="mb-2">
|
|
|
|
|
+ <el-icon><Memo /></el-icon>
|
|
|
|
|
+ 课程小节
|
|
|
|
|
+ </h3>
|
|
|
|
|
+ <el-menu
|
|
|
|
|
+ :default-active="currentIndex"
|
|
|
|
|
+ @open="handleOpen"
|
|
|
|
|
+ @close="handleClose"
|
|
|
|
|
+ @select="handleSelect"
|
|
|
|
|
+ :default-openeds="['1']"
|
|
|
|
|
+ >
|
|
|
|
|
+ <template v-for="item in menuItems" :key="item.index">
|
|
|
|
|
+ <el-menu-item v-if="!item.children" :index="item.index">{{
|
|
|
|
|
+ item.title
|
|
|
|
|
+ }}</el-menu-item>
|
|
|
|
|
+ <el-sub-menu v-else :index="item.index">
|
|
|
|
|
+ <template #title>
|
|
|
|
|
+ <span>{{ item.title }}</span>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ <el-menu-item-group v-if="item.children">
|
|
|
|
|
+ <template
|
|
|
|
|
+ v-for="child in item.children"
|
|
|
|
|
+ :key="child.index"
|
|
|
|
|
+ >
|
|
|
|
|
+ <el-menu-item :index="child.index">{{
|
|
|
|
|
+ child.title
|
|
|
|
|
+ }}</el-menu-item>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-menu-item-group>
|
|
|
|
|
+ </el-sub-menu>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-menu>
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+ </el-row>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </transition>
|
|
|
|
|
+
|
|
|
|
|
+ <div class="content-box">
|
|
|
|
|
+ <div class="box-1">
|
|
|
|
|
+ <div class="inner-box left-box">
|
|
|
|
|
+ <div class="box-icon" @click="goBack">
|
|
|
|
|
+ <el-icon class="left-icon"><ArrowLeftBold /></el-icon>
|
|
|
|
|
+ {{ boxIconTitle }}
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="inner-box right-box">
|
|
|
|
|
+ <div class="top-right-box">
|
|
|
|
|
+ <el-input
|
|
|
|
|
+ v-model="SearchInput"
|
|
|
|
|
+ class="search-input"
|
|
|
|
|
+ placeholder="搜索"
|
|
|
|
|
+ >
|
|
|
|
|
+ <template #prefix>
|
|
|
|
|
+ <el-icon class="el-input__icon"><search /></el-icon>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-input>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="box-2">
|
|
|
|
|
+ <!-- 课程标题 autoplay自动播放 @ended="playNextVideo"-->
|
|
|
|
|
+ <div class="small-title">
|
|
|
|
|
+ <span>{{ smallTitle }}</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="box-blockly">
|
|
|
|
|
+ <div id="blocklyDiv" style="height: 100%; width: 100%; background-color: #cccccc"></div>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- blockly工具栏 -->
|
|
|
|
|
+ <!-- 使用 template 标签包裹 XML 内容 -->
|
|
|
|
|
+ <template >
|
|
|
|
|
+ <xml id="toolbox" style="display: none">
|
|
|
|
|
+<!-- <category name="逻辑" colour="%{BKY_LOGIC_HUE}">
|
|
|
|
|
+ <block type="controls_if"></block>
|
|
|
|
|
+ <block type="logic_compare"></block>
|
|
|
|
|
+ <block type="logic_operation"></block>
|
|
|
|
|
+ <block type="logic_negate"></block>
|
|
|
|
|
+ <block type="logic_boolean"></block>
|
|
|
|
|
+ </category>
|
|
|
|
|
+ <sep></sep>
|
|
|
|
|
+ <category name="数学" colour="%{BKY_MATH_HUE}">
|
|
|
|
|
+ <block type="math_number">
|
|
|
|
|
+ <field name="NUM">123</field>
|
|
|
|
|
+ </block>
|
|
|
|
|
+ <block type="math_number">
|
|
|
|
|
+ <field name="NUM">213312</field>
|
|
|
|
|
+ </block>
|
|
|
|
|
+ <block type="math_arithmetic"></block>
|
|
|
|
|
+ <block type="math_single"></block>
|
|
|
|
|
+ </category>-->
|
|
|
|
|
+ <category name="逻辑" categorystyle="logic_category">
|
|
|
|
|
+ <block type="controls_if"></block>
|
|
|
|
|
+ <block type="logic_compare"></block>
|
|
|
|
|
+ <block type="logic_operation"></block>
|
|
|
|
|
+ <block type="logic_negate"></block>
|
|
|
|
|
+ <block type="logic_boolean"></block>
|
|
|
|
|
+ <block type="logic_null" disabled="true"></block>
|
|
|
|
|
+ <block type="logic_ternary"></block>
|
|
|
|
|
+ </category>
|
|
|
|
|
+ <category name="循环" categorystyle="loop_category">
|
|
|
|
|
+ <block type="controls_repeat_ext">
|
|
|
|
|
+ <value name="TIMES">
|
|
|
|
|
+ <shadow type="math_number">
|
|
|
|
|
+ <field name="NUM">10</field>
|
|
|
|
|
+ </shadow>
|
|
|
|
|
+ </value>
|
|
|
|
|
+ </block>
|
|
|
|
|
+ <block type="controls_repeat" disabled="true"></block>
|
|
|
|
|
+ <block type="controls_whileUntil"></block>
|
|
|
|
|
+ <block type="controls_for">
|
|
|
|
|
+ <value name="FROM">
|
|
|
|
|
+ <shadow type="math_number">
|
|
|
|
|
+ <field name="NUM">1</field>
|
|
|
|
|
+ </shadow>
|
|
|
|
|
+ </value>
|
|
|
|
|
+ <value name="TO">
|
|
|
|
|
+ <shadow type="math_number">
|
|
|
|
|
+ <field name="NUM">10</field>
|
|
|
|
|
+ </shadow>
|
|
|
|
|
+ </value>
|
|
|
|
|
+ <value name="BY">
|
|
|
|
|
+ <shadow type="math_number">
|
|
|
|
|
+ <field name="NUM">1</field>
|
|
|
|
|
+ </shadow>
|
|
|
|
|
+ </value>
|
|
|
|
|
+ </block>
|
|
|
|
|
+ <block type="controls_forEach"></block>
|
|
|
|
|
+ <block type="controls_flow_statements"></block>
|
|
|
|
|
+ </category>
|
|
|
|
|
+ <category name="数值" categorystyle="math_category">
|
|
|
|
|
+ <block type="math_number" gap="32">
|
|
|
|
|
+ <field name="NUM">123</field>
|
|
|
|
|
+ </block>
|
|
|
|
|
+ <block type="math_arithmetic">
|
|
|
|
|
+ <value name="A">
|
|
|
|
|
+ <shadow type="math_number">
|
|
|
|
|
+ <field name="NUM">1</field>
|
|
|
|
|
+ </shadow>
|
|
|
|
|
+ </value>
|
|
|
|
|
+ <value name="B">
|
|
|
|
|
+ <shadow type="math_number">
|
|
|
|
|
+ <field name="NUM">1</field>
|
|
|
|
|
+ </shadow>
|
|
|
|
|
+ </value>
|
|
|
|
|
+ </block>
|
|
|
|
|
+ <block type="math_single">
|
|
|
|
|
+ <value name="NUM">
|
|
|
|
|
+ <shadow type="math_number">
|
|
|
|
|
+ <field name="NUM">9</field>
|
|
|
|
|
+ </shadow>
|
|
|
|
|
+ </value>
|
|
|
|
|
+ </block>
|
|
|
|
|
+ <block type="math_trig">
|
|
|
|
|
+ <value name="NUM">
|
|
|
|
|
+ <shadow type="math_number">
|
|
|
|
|
+ <field name="NUM">45</field>
|
|
|
|
|
+ </shadow>
|
|
|
|
|
+ </value>
|
|
|
|
|
+ </block>
|
|
|
|
|
+ <block type="math_constant"></block>
|
|
|
|
|
+ <block type="math_number_property">
|
|
|
|
|
+ <value name="NUMBER_TO_CHECK">
|
|
|
|
|
+ <shadow type="math_number">
|
|
|
|
|
+ <field name="NUM">0</field>
|
|
|
|
|
+ </shadow>
|
|
|
|
|
+ </value>
|
|
|
|
|
+ </block>
|
|
|
|
|
+ <block type="math_round">
|
|
|
|
|
+ <value name="NUM">
|
|
|
|
|
+ <shadow type="math_number">
|
|
|
|
|
+ <field name="NUM">3.1</field>
|
|
|
|
|
+ </shadow>
|
|
|
|
|
+ </value>
|
|
|
|
|
+ </block>
|
|
|
|
|
+ <block type="math_on_list"></block>
|
|
|
|
|
+ <block type="math_modulo">
|
|
|
|
|
+ <value name="DIVIDEND">
|
|
|
|
|
+ <shadow type="math_number">
|
|
|
|
|
+ <field name="NUM">64</field>
|
|
|
|
|
+ </shadow>
|
|
|
|
|
+ </value>
|
|
|
|
|
+ <value name="DIVISOR">
|
|
|
|
|
+ <shadow type="math_number">
|
|
|
|
|
+ <field name="NUM">10</field>
|
|
|
|
|
+ </shadow>
|
|
|
|
|
+ </value>
|
|
|
|
|
+ </block>
|
|
|
|
|
+ <block type="math_constrain">
|
|
|
|
|
+ <value name="VALUE">
|
|
|
|
|
+ <shadow type="math_number">
|
|
|
|
|
+ <field name="NUM">50</field>
|
|
|
|
|
+ </shadow>
|
|
|
|
|
+ </value>
|
|
|
|
|
+ <value name="LOW">
|
|
|
|
|
+ <shadow type="math_number">
|
|
|
|
|
+ <field name="NUM">1</field>
|
|
|
|
|
+ </shadow>
|
|
|
|
|
+ </value>
|
|
|
|
|
+ <value name="HIGH">
|
|
|
|
|
+ <shadow type="math_number">
|
|
|
|
|
+ <field name="NUM">100</field>
|
|
|
|
|
+ </shadow>
|
|
|
|
|
+ </value>
|
|
|
|
|
+ </block>
|
|
|
|
|
+ <block type="math_random_int">
|
|
|
|
|
+ <value name="FROM">
|
|
|
|
|
+ <shadow type="math_number">
|
|
|
|
|
+ <field name="NUM">1</field>
|
|
|
|
|
+ </shadow>
|
|
|
|
|
+ </value>
|
|
|
|
|
+ <value name="TO">
|
|
|
|
|
+ <shadow type="math_number">
|
|
|
|
|
+ <field name="NUM">100</field>
|
|
|
|
|
+ </shadow>
|
|
|
|
|
+ </value>
|
|
|
|
|
+ </block>
|
|
|
|
|
+ <block type="math_random_float"></block>
|
|
|
|
|
+ <block type="math_atan2">
|
|
|
|
|
+ <value name="X">
|
|
|
|
|
+ <shadow type="math_number">
|
|
|
|
|
+ <field name="NUM">1</field>
|
|
|
|
|
+ </shadow>
|
|
|
|
|
+ </value>
|
|
|
|
|
+ <value name="Y">
|
|
|
|
|
+ <shadow type="math_number">
|
|
|
|
|
+ <field name="NUM">1</field>
|
|
|
|
|
+ </shadow>
|
|
|
|
|
+ </value>
|
|
|
|
|
+ </block>
|
|
|
|
|
+ </category>
|
|
|
|
|
+ <category name="文本" categorystyle="text_category">
|
|
|
|
|
+ <block type="text"></block>
|
|
|
|
|
+ <block type="text_join"></block>
|
|
|
|
|
+ <block type="text_append">
|
|
|
|
|
+ <value name="TEXT">
|
|
|
|
|
+ <shadow type="text"></shadow>
|
|
|
|
|
+ </value>
|
|
|
|
|
+ </block>
|
|
|
|
|
+ <block type="text_length">
|
|
|
|
|
+ <value name="VALUE">
|
|
|
|
|
+ <shadow type="text">
|
|
|
|
|
+ <field name="TEXT">abc</field>
|
|
|
|
|
+ </shadow>
|
|
|
|
|
+ </value>
|
|
|
|
|
+ </block>
|
|
|
|
|
+ <block type="text_isEmpty">
|
|
|
|
|
+ <value name="VALUE">
|
|
|
|
|
+ <shadow type="text">
|
|
|
|
|
+ <field name="TEXT"></field>
|
|
|
|
|
+ </shadow>
|
|
|
|
|
+ </value>
|
|
|
|
|
+ </block>
|
|
|
|
|
+ <block type="text_indexOf">
|
|
|
|
|
+ <value name="VALUE">
|
|
|
|
|
+ <block type="variables_get">
|
|
|
|
|
+ <field name="VAR">text</field>
|
|
|
|
|
+ </block>
|
|
|
|
|
+ </value>
|
|
|
|
|
+ <value name="FIND">
|
|
|
|
|
+ <shadow type="text">
|
|
|
|
|
+ <field name="TEXT">abc</field>
|
|
|
|
|
+ </shadow>
|
|
|
|
|
+ </value>
|
|
|
|
|
+ </block>
|
|
|
|
|
+ <block type="text_charAt">
|
|
|
|
|
+ <value name="VALUE">
|
|
|
|
|
+ <block type="variables_get">
|
|
|
|
|
+ <field name="VAR">text</field>
|
|
|
|
|
+ </block>
|
|
|
|
|
+ </value>
|
|
|
|
|
+ </block>
|
|
|
|
|
+ <block type="text_getSubstring">
|
|
|
|
|
+ <value name="STRING">
|
|
|
|
|
+ <block type="variables_get">
|
|
|
|
|
+ <field name="VAR">text</field>
|
|
|
|
|
+ </block>
|
|
|
|
|
+ </value>
|
|
|
|
|
+ </block>
|
|
|
|
|
+ <block type="text_changeCase">
|
|
|
|
|
+ <value name="TEXT">
|
|
|
|
|
+ <shadow type="text">
|
|
|
|
|
+ <field name="TEXT">abc</field>
|
|
|
|
|
+ </shadow>
|
|
|
|
|
+ </value>
|
|
|
|
|
+ </block>
|
|
|
|
|
+ <block type="text_trim">
|
|
|
|
|
+ <value name="TEXT">
|
|
|
|
|
+ <shadow type="text">
|
|
|
|
|
+ <field name="TEXT">abc</field>
|
|
|
|
|
+ </shadow>
|
|
|
|
|
+ </value>
|
|
|
|
|
+ </block>
|
|
|
|
|
+ <block type="text_count">
|
|
|
|
|
+ <value name="SUB">
|
|
|
|
|
+ <shadow type="text"></shadow>
|
|
|
|
|
+ </value>
|
|
|
|
|
+ <value name="TEXT">
|
|
|
|
|
+ <shadow type="text"></shadow>
|
|
|
|
|
+ </value>
|
|
|
|
|
+ </block>
|
|
|
|
|
+ <block type="text_replace">
|
|
|
|
|
+ <value name="FROM">
|
|
|
|
|
+ <shadow type="text"></shadow>
|
|
|
|
|
+ </value>
|
|
|
|
|
+ <value name="TO">
|
|
|
|
|
+ <shadow type="text"></shadow>
|
|
|
|
|
+ </value>
|
|
|
|
|
+ <value name="TEXT">
|
|
|
|
|
+ <shadow type="text"></shadow>
|
|
|
|
|
+ </value>
|
|
|
|
|
+ </block>
|
|
|
|
|
+ <block type="text_reverse">
|
|
|
|
|
+ <value name="TEXT">
|
|
|
|
|
+ <shadow type="text"></shadow>
|
|
|
|
|
+ </value>
|
|
|
|
|
+ </block>
|
|
|
|
|
+ <label text="Input/Output:" web-class="ioLabel"></label>
|
|
|
|
|
+ <block type="text_print">
|
|
|
|
|
+ <value name="TEXT">
|
|
|
|
|
+ <shadow type="text">
|
|
|
|
|
+ <field name="TEXT">abc</field>
|
|
|
|
|
+ </shadow>
|
|
|
|
|
+ </value>
|
|
|
|
|
+ </block>
|
|
|
|
|
+ <block type="text_prompt_ext">
|
|
|
|
|
+ <value name="TEXT">
|
|
|
|
|
+ <shadow type="text">
|
|
|
|
|
+ <field name="TEXT">abc</field>
|
|
|
|
|
+ </shadow>
|
|
|
|
|
+ </value>
|
|
|
|
|
+ </block>
|
|
|
|
|
+ </category>
|
|
|
|
|
+ <category name="列表" categorystyle="list_category">
|
|
|
|
|
+ <block type="lists_create_with">
|
|
|
|
|
+ <mutation items="0"></mutation>
|
|
|
|
|
+ </block>
|
|
|
|
|
+ <block type="lists_create_with"></block>
|
|
|
|
|
+ <block type="lists_repeat">
|
|
|
|
|
+ <value name="NUM">
|
|
|
|
|
+ <shadow type="math_number">
|
|
|
|
|
+ <field name="NUM">5</field>
|
|
|
|
|
+ </shadow>
|
|
|
|
|
+ </value>
|
|
|
|
|
+ </block>
|
|
|
|
|
+ <block type="lists_length"></block>
|
|
|
|
|
+ <block type="lists_isEmpty"></block>
|
|
|
|
|
+ <block type="lists_indexOf">
|
|
|
|
|
+ <value name="VALUE">
|
|
|
|
|
+ <block type="variables_get">
|
|
|
|
|
+ <field name="VAR">list</field>
|
|
|
|
|
+ </block>
|
|
|
|
|
+ </value>
|
|
|
|
|
+ </block>
|
|
|
|
|
+ <block type="lists_getIndex">
|
|
|
|
|
+ <value name="VALUE">
|
|
|
|
|
+ <block type="variables_get">
|
|
|
|
|
+ <field name="VAR">list</field>
|
|
|
|
|
+ </block>
|
|
|
|
|
+ </value>
|
|
|
|
|
+ </block>
|
|
|
|
|
+ <block type="lists_setIndex">
|
|
|
|
|
+ <value name="LIST">
|
|
|
|
|
+ <block type="variables_get">
|
|
|
|
|
+ <field name="VAR">list</field>
|
|
|
|
|
+ </block>
|
|
|
|
|
+ </value>
|
|
|
|
|
+ </block>
|
|
|
|
|
+ <block type="lists_getSublist">
|
|
|
|
|
+ <value name="LIST">
|
|
|
|
|
+ <block type="variables_get">
|
|
|
|
|
+ <field name="VAR">list</field>
|
|
|
|
|
+ </block>
|
|
|
|
|
+ </value>
|
|
|
|
|
+ </block>
|
|
|
|
|
+ <block type="lists_split">
|
|
|
|
|
+ <value name="DELIM">
|
|
|
|
|
+ <shadow type="text">
|
|
|
|
|
+ <field name="TEXT">,</field>
|
|
|
|
|
+ </shadow>
|
|
|
|
|
+ </value>
|
|
|
|
|
+ </block>
|
|
|
|
|
+ <block type="lists_sort"></block>
|
|
|
|
|
+ <block type="lists_reverse"></block>
|
|
|
|
|
+ </category>
|
|
|
|
|
+ <sep></sep>
|
|
|
|
|
+ <category
|
|
|
|
|
+ name="Variables"
|
|
|
|
|
+ categorystyle="variable_category"
|
|
|
|
|
+ custom="VARIABLE"></category>
|
|
|
|
|
+ <category
|
|
|
|
|
+ name="Functions"
|
|
|
|
|
+ categorystyle="procedure_category"
|
|
|
|
|
+ custom="PROCEDURE"></category>
|
|
|
|
|
+ </xml>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <div class="box-code">
|
|
|
|
|
+ <el-button type="info" plain id="save-json" @click="saveJson()">保存 JSON</el-button>
|
|
|
|
|
+ <el-button type="info" plain id="save-xml" @click="saveXml()">保存 XML</el-button>
|
|
|
|
|
+ <el-button type="warning" plain id="import" @click="load()">重新加载</el-button>
|
|
|
|
|
+ <br/><br/>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 添加生成 JavaScript 和 Python 代码的按钮 -->
|
|
|
|
|
+ <el-button type="primary" plain id="to-code-py" @click="generateCode('javascript')">生成 JavaScript</el-button>
|
|
|
|
|
+ <el-button type="success" plain id="to-code-py" @click="generateCode('python')">生成 Python</el-button>
|
|
|
|
|
+ <br/><br/>
|
|
|
|
|
+ <!-- blockly代码区 -->
|
|
|
|
|
+ <textarea name="" id="textarea" class="box-code-textarea"></textarea>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+</template>
|
|
|
|
|
+
|
|
|
|
|
+<script setup>
|
|
|
|
|
+import { ref, onMounted } from 'vue'
|
|
|
|
|
+import { useRouter } from 'vue-router'
|
|
|
|
|
+import {
|
|
|
|
|
+ Expand,
|
|
|
|
|
+ Fold,
|
|
|
|
|
+ Memo,
|
|
|
|
|
+ Delete
|
|
|
|
|
+} from '@element-plus/icons-vue'
|
|
|
|
|
+import { Search, ArrowLeftBold } from '@element-plus/icons-vue'
|
|
|
|
|
+import {Message} from "@/utils/message/Message.js";
|
|
|
|
|
+import Blockly from 'blockly';
|
|
|
|
|
+import {javascriptGenerator} from 'blockly/javascript';
|
|
|
|
|
+// 引入 Python 代码生成器
|
|
|
|
|
+import {pythonGenerator} from 'blockly/python';
|
|
|
|
|
+// 引入想要转换的语言,语言有php python dart lua javascript
|
|
|
|
|
+// import 'blockly/javascript'
|
|
|
|
|
+// 引入语言包并使用
|
|
|
|
|
+import * as hans from 'blockly/msg/zh-hans'
|
|
|
|
|
+Blockly.setLocale(hans);
|
|
|
|
|
+
|
|
|
|
|
+const router = useRouter() // 获取当前路由对象
|
|
|
|
|
+// 搜索框
|
|
|
|
|
+const SearchInput = ref('')
|
|
|
|
|
+// 添加抽屉显示状态
|
|
|
|
|
+const drawerVisible = ref(true)
|
|
|
|
|
+// 添加切换抽屉显示状态的函数
|
|
|
|
|
+const toggleDrawer = () => {
|
|
|
|
|
+ drawerVisible.value = !drawerVisible.value
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 返回上一页
|
|
|
|
|
+const goBack = () => {
|
|
|
|
|
+ router.go(-1)
|
|
|
|
|
+}
|
|
|
|
|
+// 渲染页面标题
|
|
|
|
|
+const boxIconTitle = ref('')
|
|
|
|
|
+// 使用 ref 存储 workspace
|
|
|
|
|
+const workspace = ref(null)
|
|
|
|
|
+
|
|
|
|
|
+onMounted(async () => {
|
|
|
|
|
+ const typeId = router.currentRoute.value.query.typeId
|
|
|
|
|
+ console.log(typeId,"----")
|
|
|
|
|
+ if (typeId) {
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+ const title = router.currentRoute.value.query.typeName
|
|
|
|
|
+ if (title) {
|
|
|
|
|
+ boxIconTitle.value = String(title)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ workspace.value = Blockly.inject('blocklyDiv',
|
|
|
|
|
+ {
|
|
|
|
|
+ //工具栏
|
|
|
|
|
+ toolbox: document.getElementById('toolbox'),
|
|
|
|
|
+ //网格效果
|
|
|
|
|
+ grid:{spacing: 20,length: 3,colour: '#ccc',snap: true}
|
|
|
|
|
+ }
|
|
|
|
|
+ );
|
|
|
|
|
+ // 工作区监听代码生成器
|
|
|
|
|
+ // 修改为传递一个函数
|
|
|
|
|
+ workspace.value.addChangeListener(() => generateCode("python"));
|
|
|
|
|
+})
|
|
|
|
|
+
|
|
|
|
|
+//保存Json
|
|
|
|
|
+function saveJson() {
|
|
|
|
|
+ var output = document.getElementById('textarea');
|
|
|
|
|
+ var state = Blockly.serialization.workspaces.save(workspace.value);
|
|
|
|
|
+ output.value = JSON.stringify(state, null, 2);
|
|
|
|
|
+ output.focus();
|
|
|
|
|
+ output.select();
|
|
|
|
|
+ taChange();
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+//保存Xml
|
|
|
|
|
+function saveXml() {
|
|
|
|
|
+ var output = document.getElementById('textarea');
|
|
|
|
|
+ var xml = Blockly.Xml.workspaceToDom(workspace.value);
|
|
|
|
|
+ output.value = Blockly.Xml.domToPrettyText(xml);
|
|
|
|
|
+ output.focus();
|
|
|
|
|
+ output.select();
|
|
|
|
|
+ taChange();
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+//重新加载
|
|
|
|
|
+function load() {
|
|
|
|
|
+ var input = document.getElementById('textarea');
|
|
|
|
|
+ if (!input.value) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ var valid = saveIsValid(input.value);
|
|
|
|
|
+ if (valid.json) {
|
|
|
|
|
+ var state = JSON.parse(input.value);
|
|
|
|
|
+ Blockly.serialization.workspaces.load(state, workspace.value);
|
|
|
|
|
+ } else if (valid.xml) {
|
|
|
|
|
+ var xml = Blockly.utils.xml.textToDom(input.value);
|
|
|
|
|
+ Blockly.Xml.domToWorkspace(xml, workspace.value);
|
|
|
|
|
+ }
|
|
|
|
|
+ taChange();
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+//
|
|
|
|
|
+function taChange() {
|
|
|
|
|
+ var textarea = document.getElementById('textarea');
|
|
|
|
|
+ if (sessionStorage) {
|
|
|
|
|
+ sessionStorage.setItem('textarea', textarea.value);
|
|
|
|
|
+ }
|
|
|
|
|
+ var valid = saveIsValid(textarea.value);
|
|
|
|
|
+ document.getElementById('import').disabled = !valid.json && !valid.xml;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+function saveIsValid(save) {
|
|
|
|
|
+ var validJson = true;
|
|
|
|
|
+ try {
|
|
|
|
|
+ JSON.parse(save);
|
|
|
|
|
+ } catch (e) {
|
|
|
|
|
+ validJson = false;
|
|
|
|
|
+ }
|
|
|
|
|
+ var validXml = true;
|
|
|
|
|
+ try {
|
|
|
|
|
+ Blockly.utils.xml.textToDom(save);
|
|
|
|
|
+ } catch (e) {
|
|
|
|
|
+ validXml = false;
|
|
|
|
|
+ }
|
|
|
|
|
+ return {
|
|
|
|
|
+ json: validJson,
|
|
|
|
|
+ xml: validXml,
|
|
|
|
|
+ };
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 定义生成代码的函数
|
|
|
|
|
+const generateCode = (language) => {
|
|
|
|
|
+ if (!workspace.value) {
|
|
|
|
|
+ console.error('workspace 未正确初始化');
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ let generator;
|
|
|
|
|
+ if (language === 'javascript') {
|
|
|
|
|
+ generator = javascriptGenerator;
|
|
|
|
|
+ } else if (language === 'python') {
|
|
|
|
|
+ generator = pythonGenerator;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ console.error('不支持的语言类型');
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ const code = generator.workspaceToCode(workspace.value);
|
|
|
|
|
+ document.getElementById('textarea').value = code;
|
|
|
|
|
+};
|
|
|
|
|
+// 代码生成器
|
|
|
|
|
+const myUpdateFunction = () => {
|
|
|
|
|
+ // 修改此处,传入 workspace.value
|
|
|
|
|
+ const code = javascriptGenerator.workspaceToCode(workspace.value);
|
|
|
|
|
+ document.getElementById('textarea').value = code;
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// 获取 blockly 工作区中的 code 和 xml 结构
|
|
|
|
|
+const getBlockData = () => {
|
|
|
|
|
+ if (workspace.value) {
|
|
|
|
|
+ const code = Blockly.JavaScript.workspaceToCode(workspace.value);
|
|
|
|
|
+ const xml = Blockly.Xml.workspaceToDom(workspace.value)
|
|
|
|
|
+ const xmlText = Blockly.Xml.domToText(xml);
|
|
|
|
|
+ // 可以在这里返回或处理 code 和 xmlText
|
|
|
|
|
+ return { code, xmlText };
|
|
|
|
|
+ } else {
|
|
|
|
|
+ console.error('workspace 或 Blockly.JavaScript 未正确初始化');
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// 回显工作区中的 xml 结构
|
|
|
|
|
+const setBlockData = (xmlText) => {
|
|
|
|
|
+ if (workspace.value) {
|
|
|
|
|
+ clearBlockData();
|
|
|
|
|
+ const xml = Blockly.Xml.textToDom(xmlText);
|
|
|
|
|
+ Blockly.Xml.domToWorkspace(xml, workspace.value);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ console.error('workspace 未正确初始化');
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// 清空工作区
|
|
|
|
|
+const clearBlockData = () => {
|
|
|
|
|
+ if (workspace.value) {
|
|
|
|
|
+ workspace.value.clear();
|
|
|
|
|
+ } else {
|
|
|
|
|
+ console.error('workspace 未正确初始化');
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+// 菜单打开和关闭的处理函数
|
|
|
|
|
+const handleOpen = () => {}
|
|
|
|
|
+const handleClose = () => {}
|
|
|
|
|
+
|
|
|
|
|
+// 动态渲染树型结构
|
|
|
|
|
+const menuItems = ref([
|
|
|
|
|
+ { index: '1-1', title: '课前回顾' },
|
|
|
|
|
+ { index: '1-2', title: '课程引入' },
|
|
|
|
|
+ {
|
|
|
|
|
+ index: '1',
|
|
|
|
|
+ title: '知识讲解',
|
|
|
|
|
+ children: [
|
|
|
|
|
+ { index: '1-3', title: '图灵测试' },
|
|
|
|
|
+ { index: '1-4', title: '课堂提问' },
|
|
|
|
|
+ { index: '1-5', title: '达特茅斯会议' },
|
|
|
|
|
+ { index: '1-6', title: '课堂选择' },
|
|
|
|
|
+ { index: '1-7', title: '聊天机器人' },
|
|
|
|
|
+ { index: '1-8', title: '专家系统' },
|
|
|
|
|
+ { index: '1-9', title: '课堂互动' },
|
|
|
|
|
+ { index: '1-10', title: '互联网快速发展' },
|
|
|
|
|
+ { index: '1-11', title: '黄金时代' },
|
|
|
|
|
+ { index: '1-12', title: '课堂提问' },
|
|
|
|
|
+ { index: '1-13', title: '大模型时代' }
|
|
|
|
|
+ ]
|
|
|
|
|
+ },
|
|
|
|
|
+ { index: '1-14', title: '趣味实操' },
|
|
|
|
|
+ { index: '1-15', title: '课程总结' }
|
|
|
|
|
+])
|
|
|
|
|
+
|
|
|
|
|
+// 当前播放的索引
|
|
|
|
|
+const currentIndex = ref('1-1')
|
|
|
|
|
+
|
|
|
|
|
+// 渲染课程标题到视频上方
|
|
|
|
|
+const smallTitle = ref('课前回顾')
|
|
|
|
|
+const handleSelect = index => {
|
|
|
|
|
+ //测试账号禁用视频
|
|
|
|
|
+ if (disableVideo(index))return;
|
|
|
|
|
+
|
|
|
|
|
+ const findTitle = items => {
|
|
|
|
|
+ for (const item of items) {
|
|
|
|
|
+ if (item.index === index) {
|
|
|
|
|
+ return item.title
|
|
|
|
|
+ }
|
|
|
|
|
+ if (item.children) {
|
|
|
|
|
+ const result = findTitle(item.children)
|
|
|
|
|
+ if (result) {
|
|
|
|
|
+ return result
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return null
|
|
|
|
|
+ }
|
|
|
|
|
+ const title = findTitle(menuItems.value)
|
|
|
|
|
+ if (title) {
|
|
|
|
|
+ smallTitle.value = title
|
|
|
|
|
+ }
|
|
|
|
|
+ // 根据索引切换视频
|
|
|
|
|
+ if (videoMap[index]) {
|
|
|
|
|
+ videoSrc.value = videoMap[index]
|
|
|
|
|
+ currentIndex.value = index
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 展平所有菜单项索引
|
|
|
|
|
+const flattenMenuItems = () => {
|
|
|
|
|
+ const indices = []
|
|
|
|
|
+ const traverse = items => {
|
|
|
|
|
+ for (const item of items) {
|
|
|
|
|
+ if (!item.children) {
|
|
|
|
|
+ indices.push(item.index)
|
|
|
|
|
+ } else {
|
|
|
|
|
+ traverse(item.children)
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ traverse(menuItems.value)
|
|
|
|
|
+ return indices
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+//禁用视频
|
|
|
|
|
+const disableVideo = (index = currentIndex.value) => {
|
|
|
|
|
+ let dis = ["1-6","1-7","1-8","1-9","1-10","1-11","1-12","1-13","1-14","1-15"]
|
|
|
|
|
+
|
|
|
|
|
+ if (localStorage.getItem('userName') === "aiTest" &&
|
|
|
|
|
+ dis.indexOf(index) !== -1) {
|
|
|
|
|
+
|
|
|
|
|
+ if (videoRef.value) {
|
|
|
|
|
+ // 记录当前播放时间
|
|
|
|
|
+ videoRef.value.pause()
|
|
|
|
|
+ // 阻止用户跳转到新的时间点,将播放时间重置为之前的时间
|
|
|
|
|
+ videoRef.value.currentTime = 0;
|
|
|
|
|
+ }
|
|
|
|
|
+ //提示禁用// 显示消息框
|
|
|
|
|
+ Message().notifyWarning('您的账号并未开放此课程!', true);
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+ return false;
|
|
|
|
|
+}
|
|
|
|
|
+</script>
|
|
|
|
|
+
|
|
|
|
|
+<style scoped lang="scss">
|
|
|
|
|
+@use 'sass:math';
|
|
|
|
|
+@use 'sass:color'; // 引入 color 模块
|
|
|
|
|
+// 定义rpx转换函数
|
|
|
|
|
+@function rpx($px) {
|
|
|
|
|
+ @return math.div($px, 750) * 100vw;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 定义儿童风格的蓝紫色调
|
|
|
|
|
+$primary-color: rgba(106, 90, 205, 0.52); // 主色调:蓝紫色
|
|
|
|
|
+$secondary-color: rgba(147, 112, 219, 0.66); // 辅助色:亮蓝紫色
|
|
|
|
|
+$accent-color: rgb(133, 89, 220); // 强调色:暗蓝紫色
|
|
|
|
|
+$light-color: #e6e6fa; // 浅色背景:淡紫色
|
|
|
|
|
+$text-color: #483d8b; // 文本颜色:靛蓝色
|
|
|
|
|
+
|
|
|
|
|
+/* 添加过渡样式 */
|
|
|
|
|
+.drawer-slide-enter-active,
|
|
|
|
|
+.drawer-slide-leave-active {
|
|
|
|
|
+ transition: all 0.3s ease;
|
|
|
|
|
+}
|
|
|
|
|
+.drawer-slide-enter-from,
|
|
|
|
|
+.drawer-slide-leave-to {
|
|
|
|
|
+ transform: translateX(-100%);
|
|
|
|
|
+ opacity: 0;
|
|
|
|
|
+}
|
|
|
|
|
+.main-content {
|
|
|
|
|
+ width: rpx(135);
|
|
|
|
|
+ height: 100%;
|
|
|
|
|
+ position: relative;
|
|
|
|
|
+ background: linear-gradient(to bottom, #001169, #8a78d0);
|
|
|
|
|
+
|
|
|
|
|
+}
|
|
|
|
|
+.content-box {
|
|
|
|
|
+ flex: 1;
|
|
|
|
|
+ height: 100%;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-direction: column; /* 子元素上下排列 */
|
|
|
|
|
+ background: linear-gradient(
|
|
|
|
|
+ to bottom,
|
|
|
|
|
+ #e2ddfc,
|
|
|
|
|
+ #f1effd
|
|
|
|
|
+ ); /* 设置悬停、聚焦、点击状态下的背景色 */
|
|
|
|
|
+}
|
|
|
|
|
+.icon-expand {
|
|
|
|
|
+ width: rpx(30);
|
|
|
|
|
+ height: rpx(30);
|
|
|
|
|
+ z-index: 9999;
|
|
|
|
|
+ position: absolute;
|
|
|
|
|
+ cursor: pointer; // 添加鼠标指针样式
|
|
|
|
|
+}
|
|
|
|
|
+.icon-expand .el-icon {
|
|
|
|
|
+ font-size: rpx(15);
|
|
|
|
|
+ position: absolute;
|
|
|
|
|
+ color: white;
|
|
|
|
|
+ left: rpx(9);
|
|
|
|
|
+ margin-top: rpx(17);
|
|
|
|
|
+}
|
|
|
|
|
+.icon-expand .el-icon:active {
|
|
|
|
|
+ color: black;
|
|
|
|
|
+}
|
|
|
|
|
+.home-container {
|
|
|
|
|
+ position: fixed;
|
|
|
|
|
+ top: 0;
|
|
|
|
|
+ left: 0;
|
|
|
|
|
+ right: 0;
|
|
|
|
|
+ bottom: 0;
|
|
|
|
|
+ background: linear-gradient(to bottom, #001169, #b4a8e1);
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-direction: row;
|
|
|
|
|
+ gap: rpx(0);
|
|
|
|
|
+}
|
|
|
|
|
+.el-row {
|
|
|
|
|
+ margin: auto;
|
|
|
|
|
+ margin-top: rpx(40);
|
|
|
|
|
+}
|
|
|
|
|
+.tac ::v-deep(.el-menu) {
|
|
|
|
|
+ background-color: transparent;
|
|
|
|
|
+ border: none;
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/* 取消点击后的蓝色字体 el-sub-menu__title*/
|
|
|
|
|
+.tac ::v-deep(.el-menu-item.is-active),
|
|
|
|
|
+.tac ::v-deep(.el-sub-menu__title.is-active) {
|
|
|
|
|
+ color: white;
|
|
|
|
|
+}
|
|
|
|
|
+// 取消鼠标悬浮颜色
|
|
|
|
|
+.tac ::v-deep(.el-sub-menu__title) {
|
|
|
|
|
+ width: rpx(130);
|
|
|
|
|
+ height: rpx(20);
|
|
|
|
|
+ margin-bottom: rpx(5);
|
|
|
|
|
+ border-radius: rpx(6);
|
|
|
|
|
+}
|
|
|
|
|
+.el-menu ::v-deep(.el-sub-menu__title:hover),
|
|
|
|
|
+.el-menu ::v-deep(.el-sub-menu__title:focus),
|
|
|
|
|
+.el-menu ::v-deep(.el-sub-menu__title:active) {
|
|
|
|
|
+ background: linear-gradient(
|
|
|
|
|
+ to bottom,
|
|
|
|
|
+ #fee78a,
|
|
|
|
|
+ #ffce1b
|
|
|
|
|
+ );
|
|
|
|
|
+ background-color: transparent;
|
|
|
|
|
+}
|
|
|
|
|
+.mb-2 {
|
|
|
|
|
+ color: white;
|
|
|
|
|
+ margin-top: rpx(1);
|
|
|
|
|
+}
|
|
|
|
|
+.mb-2 .el-icon {
|
|
|
|
|
+ font-size: rpx(10);
|
|
|
|
|
+ margin-left: rpx(5);
|
|
|
|
|
+}
|
|
|
|
|
+.el-menu-item {
|
|
|
|
|
+ width: rpx(115);
|
|
|
|
|
+ height: rpx(20);
|
|
|
|
|
+ margin-bottom: rpx(5);
|
|
|
|
|
+ border-radius: rpx(6);
|
|
|
|
|
+ color: white;
|
|
|
|
|
+ font-size: rpx(7);
|
|
|
|
|
+
|
|
|
|
|
+}
|
|
|
|
|
+.el-menu ::v-deep(.el-sub-menu__title){
|
|
|
|
|
+ color: white;
|
|
|
|
|
+ width: rpx(115);
|
|
|
|
|
+ height: rpx(20);
|
|
|
|
|
+ margin-bottom: rpx(5);
|
|
|
|
|
+ font-size: rpx(7);
|
|
|
|
|
+}
|
|
|
|
|
+.el-menu ::v-deep(.el-sub-menu__title:hover),
|
|
|
|
|
+.el-menu ::v-deep(.el-sub-menu__title:focus),
|
|
|
|
|
+.el-menu ::v-deep(.el-sub-menu__title:active) {
|
|
|
|
|
+ background: linear-gradient(
|
|
|
|
|
+ to bottom,
|
|
|
|
|
+ #fee78a,
|
|
|
|
|
+ #ffce1b
|
|
|
|
|
+ );
|
|
|
|
|
+ color: black;
|
|
|
|
|
+ font-size: rpx(8);
|
|
|
|
|
+}
|
|
|
|
|
+.el-menu ::v-deep(.el-menu-item:hover),
|
|
|
|
|
+.el-menu ::v-deep(.el-menu-item:focus),
|
|
|
|
|
+.el-menu ::v-deep(.el-menu-item:active) {
|
|
|
|
|
+ background: linear-gradient(
|
|
|
|
|
+ to bottom,
|
|
|
|
|
+ #fee78a,
|
|
|
|
|
+ #ffce1b
|
|
|
|
|
+ );
|
|
|
|
|
+ color: black;
|
|
|
|
|
+ font-size: rpx(8);
|
|
|
|
|
+}
|
|
|
|
|
+.drawer-box {
|
|
|
|
|
+ position: absolute;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ height: 100%;
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ overflow-y: auto; /* 添加垂直滚动条 */
|
|
|
|
|
+ max-height: 100%; /* 设置最大高度 */
|
|
|
|
|
+ /* 添加滚动条样式 */
|
|
|
|
|
+ &::-webkit-scrollbar {
|
|
|
|
|
+ width: rpx(1);
|
|
|
|
|
+ }
|
|
|
|
|
+ &::-webkit-scrollbar-thumb {
|
|
|
|
|
+ background-color:#b4a8e1;
|
|
|
|
|
+ border-radius: rpx(5);
|
|
|
|
|
+ }
|
|
|
|
|
+ &::-webkit-scrollbar-track {
|
|
|
|
|
+ background-color: rgba(255, 255, 255, 0.2);
|
|
|
|
|
+ border-radius: rpx(5);
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+.drawer-box .toggle-button {
|
|
|
|
|
+ width: rpx(10);
|
|
|
|
|
+ height: rpx(50);
|
|
|
|
|
+ font-size: rpx(7);
|
|
|
|
|
+ background-color: rgba(17, 23, 29, 0.2);
|
|
|
|
|
+ border: none;
|
|
|
|
|
+ position: relative;
|
|
|
|
|
+ writing-mode: vertical-lr; // 文字垂直排列,从左到右
|
|
|
|
|
+ text-orientation: upright; // 文字保持正立
|
|
|
|
|
+}
|
|
|
|
|
+.toggle-button:hover {
|
|
|
|
|
+ left: 0;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+.toggle-button.is-active,
|
|
|
|
|
+.toggle-button:active,
|
|
|
|
|
+.toggle-button:focus {
|
|
|
|
|
+ background-color: rgba(165, 209, 247, 0.8);
|
|
|
|
|
+ color: white;
|
|
|
|
|
+ border: none; // 移除点击时的边框
|
|
|
|
|
+ outline: none; // 移除点击时的外边框
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.box-1 {
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ height: rpx(50);
|
|
|
|
|
+ margin-top: rpx(10);
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ justify-content: center;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ box-sizing: border-box;
|
|
|
|
|
+ font-size: rpx(15); // 默认字体大小
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.inner-box {
|
|
|
|
|
+ height: 100%;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ justify-content: center;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ font-size: rpx(16); // 默认字体大小
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.left-box {
|
|
|
|
|
+ position: relative;
|
|
|
|
|
+ justify-content: flex-start;
|
|
|
|
|
+ align-items: flex-start;
|
|
|
|
|
+ flex: 1; // 设置左侧盒子占比为 2
|
|
|
|
|
+ cursor: pointer; // 添加鼠标指针样式
|
|
|
|
|
+}
|
|
|
|
|
+.box-icon {
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ height: 100%;
|
|
|
|
|
+ flex: 1;
|
|
|
|
|
+ display: flex; // 添加 flex 布局
|
|
|
|
|
+ align-items: center; // 垂直居中
|
|
|
|
|
+ color: black; // 设置图标颜色为白色
|
|
|
|
|
+ padding-left: rpx(15);
|
|
|
|
|
+ font-size: rpx(10); // 设置图标大小,可按需调整
|
|
|
|
|
+}
|
|
|
|
|
+.box-icon .left-icon {
|
|
|
|
|
+ margin-left: rpx(10);
|
|
|
|
|
+ margin-right: rpx(5); // 设置图标和文字之间的间距 ;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.left-box span {
|
|
|
|
|
+ position: absolute;
|
|
|
|
|
+ font-size: rpx(11); // 默认字体大小
|
|
|
|
|
+ color: black;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.right-box {
|
|
|
|
|
+ flex: 1;
|
|
|
|
|
+ position: relative; // 添加相对定位;
|
|
|
|
|
+}
|
|
|
|
|
+.top-right-box {
|
|
|
|
|
+ position: absolute; // 添加绝对定位
|
|
|
|
|
+ margin-top: rpx(20); // 调整上边距离
|
|
|
|
|
+ margin-right: rpx(50); // 调整右边距离
|
|
|
|
|
+ width: 100%; // 设置盒子宽度,可按需调整
|
|
|
|
|
+ height: 60px; // 设置盒子高度,可按需调整
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ justify-content: flex-end;
|
|
|
|
|
+}
|
|
|
|
|
+.top-right-box {
|
|
|
|
|
+ ::v-deep(.el-input__wrapper) {
|
|
|
|
|
+ background-color: rgb(255, 255, 255, 0.5);
|
|
|
|
|
+ border-radius: rpx(12);
|
|
|
|
|
+ border: white 1px solid;
|
|
|
|
|
+ color: #aaa5c5;
|
|
|
|
|
+ }
|
|
|
|
|
+ ::v-deep(.el-input__icon) {
|
|
|
|
|
+ color: #aaa5c5; // 设置输入框图标颜色为白色
|
|
|
|
|
+ }
|
|
|
|
|
+ // 添加占位符样式
|
|
|
|
|
+ ::v-deep(.el-input__inner::placeholder) {
|
|
|
|
|
+ color: #aaa5c5;
|
|
|
|
|
+ }
|
|
|
|
|
+ // 添加输入框文字颜色样式
|
|
|
|
|
+ ::v-deep(.el-input__inner) {
|
|
|
|
|
+ color: black;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+// 搜索框
|
|
|
|
|
+.search-input {
|
|
|
|
|
+ width: rpx(100);
|
|
|
|
|
+ height: rpx(15);
|
|
|
|
|
+ font-size: rpx(7);
|
|
|
|
|
+}
|
|
|
|
|
+.box-2 {
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ flex: 1;
|
|
|
|
|
+ box-shadow: 0 4px 8px rgba(202, 52, 52, 0.1);
|
|
|
|
|
+ box-sizing: border-box;
|
|
|
|
|
+ display: flex; // 确保子元素水平排列
|
|
|
|
|
+ flex-wrap: wrap; // 允许子元素换行;
|
|
|
|
|
+ align-content: center; // 顶部对齐;
|
|
|
|
|
+ cursor: pointer; // 添加鼠标指针样式
|
|
|
|
|
+}
|
|
|
|
|
+.box-blockly {
|
|
|
|
|
+ width: 60%;
|
|
|
|
|
+ height: rpx(300);
|
|
|
|
|
+ padding: 0px 20px;
|
|
|
|
|
+ float: left;
|
|
|
|
|
+}
|
|
|
|
|
+.box-code{
|
|
|
|
|
+ width: 35%;
|
|
|
|
|
+ height: rpx(300);
|
|
|
|
|
+
|
|
|
|
|
+ .box-code-textarea{
|
|
|
|
|
+ height: 80%;
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/* 隐藏 Chrome 视频控件的渐变背景等默认样式 */
|
|
|
|
|
+video::-webkit-media-controls-panel {
|
|
|
|
|
+ background: transparent !important; /* 去掉背景渐变,设为透明 */
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.small-title {
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ margin-top: rpx(-20);
|
|
|
|
|
+ height: rpx(20);
|
|
|
|
|
+ color: black;
|
|
|
|
|
+ font-size: rpx(10);
|
|
|
|
|
+ justify-content: center; //使子元素水平居中
|
|
|
|
|
+}
|
|
|
|
|
+.video-switch {
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ // height: rpx(50);
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ margin-top: rpx(-20);
|
|
|
|
|
+ // background-color: saddlebrown;
|
|
|
|
|
+}
|
|
|
|
|
+.caret-right,
|
|
|
|
|
+.caret-left {
|
|
|
|
|
+ width: rpx(50);
|
|
|
|
|
+ margin: auto;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ margin-top: rpx(5);
|
|
|
|
|
+ margin-bottom: rpx(15);
|
|
|
|
|
+}
|
|
|
|
|
+.caret-left ::v-deep(.el-button.is-round),
|
|
|
|
|
+.caret-right ::v-deep(.el-button.is-round) {
|
|
|
|
|
+ width: rpx(50);
|
|
|
|
|
+ height: rpx(15);
|
|
|
|
|
+ color: #aaa5c5;
|
|
|
|
|
+ border-radius: none;
|
|
|
|
|
+ border: 1px white solid;
|
|
|
|
|
+ background-color: rgb(255, 255, 255, 0.5); // 进度条背景颜色,调浅为半透明白色
|
|
|
|
|
+ box-shadow: 0 4px 8px rgba(202, 52, 52, 0.1);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 儿童风格试题弹框样式
|
|
|
|
|
+.child-dialog {
|
|
|
|
|
+ .el-dialog__header {
|
|
|
|
|
+ display: none; // 隐藏原有的标题栏
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .el-dialog__body {
|
|
|
|
|
+ padding: rpx(20);
|
|
|
|
|
+ position: relative;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .el-dialog__footer {
|
|
|
|
|
+ border-top: none;
|
|
|
|
|
+ padding: rpx(10) rpx(20);
|
|
|
|
|
+ text-align: center;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .el-dialog__wrapper {
|
|
|
|
|
+ // 修改半透明背景色
|
|
|
|
|
+ background-color: rgba(0, 0, 0, 0.6);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .el-dialog {
|
|
|
|
|
+ border: none;
|
|
|
|
|
+ border-radius: rpx(20);
|
|
|
|
|
+ background: linear-gradient(
|
|
|
|
|
+ 135deg,
|
|
|
|
|
+ $light-color,
|
|
|
|
|
+ #d8bfd8
|
|
|
|
|
+ ); // 柔和的蓝紫色渐变
|
|
|
|
|
+ // 添加边框边晕效果
|
|
|
|
|
+ box-shadow: 0 0 20px 5px rgba($primary-color, 0.6),
|
|
|
|
|
+ 0 0 40px 10px rgba($primary-color, 0.4),
|
|
|
|
|
+ 0 0 60px 15px rgba($primary-color, 0.2);
|
|
|
|
|
+ overflow: hidden;
|
|
|
|
|
+ // 添加装饰元素
|
|
|
|
|
+ &::before {
|
|
|
|
|
+ content: '';
|
|
|
|
|
+ position: absolute;
|
|
|
|
|
+ top: 0;
|
|
|
|
|
+ left: 0;
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ height: rpx(10);
|
|
|
|
|
+ background: linear-gradient(
|
|
|
|
|
+ 90deg,
|
|
|
|
|
+ $primary-color,
|
|
|
|
|
+ $secondary-color,
|
|
|
|
|
+ $accent-color
|
|
|
|
|
+ );
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 问题标题样式
|
|
|
|
|
+.question-title {
|
|
|
|
|
+ background: linear-gradient(
|
|
|
|
|
+ 90deg,
|
|
|
|
|
+ rgba($primary-color, 0.2),
|
|
|
|
|
+ rgba($secondary-color, 0.2)
|
|
|
|
|
+ );
|
|
|
|
|
+ padding: rpx(15);
|
|
|
|
|
+ border-radius: rpx(12);
|
|
|
|
|
+ margin-bottom: rpx(20);
|
|
|
|
|
+ color: $accent-color;
|
|
|
|
|
+ font-weight: bold;
|
|
|
|
|
+ font-size: rpx(14);
|
|
|
|
|
+ box-shadow: 0 rpx(3) rpx(10) rgba($primary-color, 0.1);
|
|
|
|
|
+ position: relative;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+
|
|
|
|
|
+ .question-icon {
|
|
|
|
|
+ background-color: $accent-color;
|
|
|
|
|
+ color: white;
|
|
|
|
|
+ width: rpx(24);
|
|
|
|
|
+ height: rpx(24);
|
|
|
|
|
+ border-radius: 50%;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ justify-content: center;
|
|
|
|
|
+ margin-right: rpx(10);
|
|
|
|
|
+ font-weight: bold;
|
|
|
|
|
+ box-shadow: 0 rpx(2) rpx(5) rgba($accent-color, 0.3);
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 选项容器样式
|
|
|
|
|
+.options-container {
|
|
|
|
|
+ margin-bottom: rpx(20);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 问题选项样式
|
|
|
|
|
+.question-option {
|
|
|
|
|
+ margin: rpx(8) 0;
|
|
|
|
|
+ padding: rpx(10) rpx(15);
|
|
|
|
|
+ border-radius: rpx(12);
|
|
|
|
|
+ border: rpx(1) solid rgba($primary-color, 0.3);
|
|
|
|
|
+ transition: all 0.3s ease;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ background-color: white;
|
|
|
|
|
+ box-shadow: 0 rpx(2) rpx(5) rgba($primary-color, 0.05);
|
|
|
|
|
+
|
|
|
|
|
+ ::v-deep(.el-radio__label) {
|
|
|
|
|
+ color: $text-color;
|
|
|
|
|
+ margin-left: rpx(8);
|
|
|
|
|
+ flex: 1;
|
|
|
|
|
+ text-align: left;
|
|
|
|
|
+ // 增大字体大小
|
|
|
|
|
+ font-size: rpx(12);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 选中时的样式变化
|
|
|
|
|
+ .el-radio__input.is-checked + .el-radio__label {
|
|
|
|
|
+ font-weight: bold;
|
|
|
|
|
+ color: $accent-color;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ &:hover {
|
|
|
|
|
+ background-color: rgba($primary-color, 0.05);
|
|
|
|
|
+ border-color: rgba($primary-color, 0.5);
|
|
|
|
|
+ transform: translateY(-rpx(1));
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 暂无选项样式
|
|
|
|
|
+.no-options {
|
|
|
|
|
+ color: rgba($text-color, 0.7);
|
|
|
|
|
+ text-align: center;
|
|
|
|
|
+ padding: rpx(20);
|
|
|
|
|
+ font-size: rpx(12);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 底部按钮样式
|
|
|
|
|
+.child-button {
|
|
|
|
|
+ min-width: rpx(80);
|
|
|
|
|
+ height: rpx(30);
|
|
|
|
|
+ border-radius: rpx(15);
|
|
|
|
|
+ font-size: rpx(12);
|
|
|
|
|
+ font-weight: 500;
|
|
|
|
|
+ transition: all 0.3s ease;
|
|
|
|
|
+ box-shadow: 0 rpx(2) rpx(8) rgba(0, 0, 0, 0.1);
|
|
|
|
|
+
|
|
|
|
|
+ &.confirm {
|
|
|
|
|
+ background: linear-gradient(to right, $primary-color, $secondary-color);
|
|
|
|
|
+ border: none;
|
|
|
|
|
+ border-right: 15px;
|
|
|
|
|
+ color: white;
|
|
|
|
|
+
|
|
|
|
|
+ &:hover {
|
|
|
|
|
+ background: linear-gradient(
|
|
|
|
|
+ to right,
|
|
|
|
|
+ color.adjust($primary-color, $lightness: -5%),
|
|
|
|
|
+ color.adjust($secondary-color, $lightness: -5%)
|
|
|
|
|
+ );
|
|
|
|
|
+ box-shadow: 0 rpx(3) rpx(10) rgba($primary-color, 0.4);
|
|
|
|
|
+ transform: translateY(-rpx(1));
|
|
|
|
|
+ color: white;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ &.cancel {
|
|
|
|
|
+ background: white;
|
|
|
|
|
+ border: rpx(1) solid rgba($primary-color, 0.3);
|
|
|
|
|
+ color: $text-color;
|
|
|
|
|
+
|
|
|
|
|
+ &:hover {
|
|
|
|
|
+ background: rgba($primary-color, 0.05);
|
|
|
|
|
+ border-color: rgba($primary-color, 0.5);
|
|
|
|
|
+ transform: translateY(-rpx(1));
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// AI对话图标样式
|
|
|
|
|
+.ai-icon-container {
|
|
|
|
|
+ position: absolute;
|
|
|
|
|
+ bottom: rpx(20);
|
|
|
|
|
+ right: rpx(20);
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-direction: column;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ cursor: pointer;
|
|
|
|
|
+ transition: all 0.3s ease;
|
|
|
|
|
+
|
|
|
|
|
+ &:hover {
|
|
|
|
|
+ transform: translateY(-rpx(2));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .ai-icon {
|
|
|
|
|
+ width: rpx(30);
|
|
|
|
|
+ height: rpx(30);
|
|
|
|
|
+ margin-bottom: rpx(0);
|
|
|
|
|
+ filter: drop-shadow(0 rpx(2) rpx(4) rgba($primary-color, 0.3));
|
|
|
|
|
+ // 添加过渡动画
|
|
|
|
|
+ transition: transform 0.3s ease;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 悬浮时放大效果
|
|
|
|
|
+ .ai-icon:hover {
|
|
|
|
|
+ transform: scale(1.5);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .ai-text {
|
|
|
|
|
+ color: $text-color;
|
|
|
|
|
+ font-size: rpx(8);
|
|
|
|
|
+ background-color: rgba(255, 255, 255, 0.7);
|
|
|
|
|
+ padding: rpx(2) rpx(5);
|
|
|
|
|
+ border-radius: rpx(5);
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// AI消息样式
|
|
|
|
|
+.ai-message {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: flex-start;
|
|
|
|
|
+ margin-bottom: rpx(15);
|
|
|
|
|
+
|
|
|
|
|
+ .ai-avatar {
|
|
|
|
|
+ width: rpx(30);
|
|
|
|
|
+ height: rpx(30);
|
|
|
|
|
+ border-radius: 50%;
|
|
|
|
|
+ margin-right: rpx(10);
|
|
|
|
|
+ background-color: $primary-color;
|
|
|
|
|
+ padding: rpx(5);
|
|
|
|
|
+ box-shadow: 0 rpx(2) rpx(5) rgba($primary-color, 0.2);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .ai-text-content {
|
|
|
|
|
+ background-color: $light-color;
|
|
|
|
|
+ padding: rpx(8) rpx(12);
|
|
|
|
|
+ border-radius: rpx(10);
|
|
|
|
|
+ font-size: rpx(10);
|
|
|
|
|
+ color: $text-color;
|
|
|
|
|
+ max-width: 80%;
|
|
|
|
|
+ box-shadow: 0 rpx(1) rpx(3) rgba(0, 0, 0, 0.05);
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 用户输入框样式
|
|
|
|
|
+.user-input {
|
|
|
|
|
+ ::v-deep(.el-input__wrapper) {
|
|
|
|
|
+ border-radius: rpx(15);
|
|
|
|
|
+ border-color: rgba($primary-color, 0.3);
|
|
|
|
|
+ margin-right: 10px;
|
|
|
|
|
+
|
|
|
|
|
+ &:focus-within {
|
|
|
|
|
+ box-shadow: 0 0 0 rpx(1) rgba($primary-color, 0.5);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ ::v-deep(.el-input__inner) {
|
|
|
|
|
+ font-size: rpx(10);
|
|
|
|
|
+ color: $text-color;
|
|
|
|
|
+ text-indent: 1em;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+/* 定义淡入和缩放动画 */
|
|
|
|
|
+.fade-scale-enter-active,
|
|
|
|
|
+.fade-scale-leave-active {
|
|
|
|
|
+ transition: all 0.5s ease;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.fade-scale-enter-from,
|
|
|
|
|
+.fade-scale-leave-to {
|
|
|
|
|
+ opacity: 0.1;
|
|
|
|
|
+ transform: scale(0.9);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 自定义试题弹框背景
|
|
|
|
|
+.child-dialog-wrapper {
|
|
|
|
|
+ position: fixed;
|
|
|
|
|
+ top: 0;
|
|
|
|
|
+ left: 0;
|
|
|
|
|
+ right: 0;
|
|
|
|
|
+ bottom: 0;
|
|
|
|
|
+ background-color: rgba(0, 0, 0, 0.6); // 半透明背景
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ justify-content: center;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ z-index: 1000;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.child-dialog {
|
|
|
|
|
+ border: none;
|
|
|
|
|
+ border-radius: rpx(20);
|
|
|
|
|
+ background: linear-gradient(
|
|
|
|
|
+ 135deg,
|
|
|
|
|
+ $light-color,
|
|
|
|
|
+ #d8bfd8
|
|
|
|
|
+ ); // 柔和的蓝紫色渐变
|
|
|
|
|
+ box-shadow: 0 0 20px 5px rgba($primary-color, 0.6),
|
|
|
|
|
+ 0 0 40px 10px rgba($primary-color, 0.4),
|
|
|
|
|
+ 0 0 60px 15px rgba($primary-color, 0.2);
|
|
|
|
|
+ overflow: hidden;
|
|
|
|
|
+ padding: rpx(20);
|
|
|
|
|
+ width: 60%;
|
|
|
|
|
+ position: relative;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// AI对话弹框样式
|
|
|
|
|
+.ai-dialog-wrapper {
|
|
|
|
|
+ position: fixed;
|
|
|
|
|
+ top: 0;
|
|
|
|
|
+ left: 0;
|
|
|
|
|
+ right: 0;
|
|
|
|
|
+ bottom: 0;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ justify-content: flex-end;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ z-index: 1001;
|
|
|
|
|
+ pointer-events: none;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.ai-dialog {
|
|
|
|
|
+ border: none;
|
|
|
|
|
+ border-radius: rpx(20);
|
|
|
|
|
+ background: linear-gradient(135deg, $light-color, #d8bfd8);
|
|
|
|
|
+ box-shadow: 0 0 20px 5px rgba($primary-color, 0.6),
|
|
|
|
|
+ 0 0 40px 10px rgba($primary-color, 0.4),
|
|
|
|
|
+ 0 0 60px 15px rgba($primary-color, 0.2);
|
|
|
|
|
+ overflow: hidden;
|
|
|
|
|
+ padding: rpx(20);
|
|
|
|
|
+ width: 30%;
|
|
|
|
|
+ // 增加高度
|
|
|
|
|
+ height: 80%;
|
|
|
|
|
+ margin-right: rpx(50);
|
|
|
|
|
+ pointer-events: auto;
|
|
|
|
|
+ position: relative;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-direction: column;
|
|
|
|
|
+
|
|
|
|
|
+ &::before {
|
|
|
|
|
+ content: '';
|
|
|
|
|
+ position: absolute;
|
|
|
|
|
+ top: 0;
|
|
|
|
|
+ left: 0;
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ height: rpx(10);
|
|
|
|
|
+ background: linear-gradient(
|
|
|
|
|
+ 90deg,
|
|
|
|
|
+ $primary-color,
|
|
|
|
|
+ $secondary-color,
|
|
|
|
|
+ $accent-color
|
|
|
|
|
+ );
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.ai-dialog-header {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ justify-content: space-between;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ margin-bottom: rpx(15);
|
|
|
|
|
+
|
|
|
|
|
+ h3 {
|
|
|
|
|
+ color: $text-color;
|
|
|
|
|
+ font-size: rpx(12);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .close-btn {
|
|
|
|
|
+ padding: 0;
|
|
|
|
|
+ width: rpx(20);
|
|
|
|
|
+ height: rpx(20);
|
|
|
|
|
+ font-size: rpx(16);
|
|
|
|
|
+ line-height: 1;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.ai-dialog-content {
|
|
|
|
|
+ flex: 1;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-direction: column;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.ai-message-history {
|
|
|
|
|
+ flex: 1;
|
|
|
|
|
+ // 当内容超出容器高度时,显示垂直滚动条
|
|
|
|
|
+ overflow-y: auto;
|
|
|
|
|
+ margin-bottom: rpx(15);
|
|
|
|
|
+ // 可以根据实际情况调整最大高度
|
|
|
|
|
+ max-height: 50vh;
|
|
|
|
|
+ padding: 5px 10px;
|
|
|
|
|
+
|
|
|
|
|
+ .message {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: flex-start;
|
|
|
|
|
+ margin-bottom: rpx(10);
|
|
|
|
|
+
|
|
|
|
|
+ &.user {
|
|
|
|
|
+ flex-direction: row-reverse;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .avatar {
|
|
|
|
|
+ width: rpx(30);
|
|
|
|
|
+ height: rpx(30);
|
|
|
|
|
+ border-radius: 50%;
|
|
|
|
|
+ margin: 0 rpx(10);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .user {
|
|
|
|
|
+ width: 15px;
|
|
|
|
|
+ height: 15px;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .message-content {
|
|
|
|
|
+ background-color: $light-color;
|
|
|
|
|
+ padding: rpx(8) rpx(12);
|
|
|
|
|
+ border-radius: rpx(10);
|
|
|
|
|
+ font-size: rpx(10);
|
|
|
|
|
+ color: $text-color;
|
|
|
|
|
+ max-width: 80%;
|
|
|
|
|
+ box-shadow: 0 rpx(1) rpx(3) rgba(0, 0, 0, 0.05);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ // 滚动条整体样式
|
|
|
|
|
+ &::-webkit-scrollbar {
|
|
|
|
|
+ width: rpx(4); // 滚动条宽度
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 滚动条滑块样式
|
|
|
|
|
+ &::-webkit-scrollbar-thumb {
|
|
|
|
|
+ background-color: $primary-color; // 滑块颜色
|
|
|
|
|
+ border-radius: rpx(4); // 滑块圆角
|
|
|
|
|
+ transition: background-color 0.3s ease; // 颜色过渡效果
|
|
|
|
|
+
|
|
|
|
|
+ &:hover {
|
|
|
|
|
+ //background-color: darken($primary-color, 10%); // 悬停时滑块颜色加深
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 滚动条轨道样式
|
|
|
|
|
+ &::-webkit-scrollbar-track {
|
|
|
|
|
+ background-color: rgba($primary-color, 0.2); // 轨道颜色
|
|
|
|
|
+ border-radius: rpx(4); // 轨道圆角
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .message {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: flex-start;
|
|
|
|
|
+ margin-bottom: rpx(10);
|
|
|
|
|
+
|
|
|
|
|
+ &.user {
|
|
|
|
|
+ flex-direction: row-reverse;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .avatar {
|
|
|
|
|
+ width: rpx(30);
|
|
|
|
|
+ height: rpx(30);
|
|
|
|
|
+ border-radius: 50%;
|
|
|
|
|
+ margin: 0 rpx(10);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .message-content {
|
|
|
|
|
+ background-color: $light-color;
|
|
|
|
|
+ padding: rpx(8) rpx(12);
|
|
|
|
|
+ border-radius: rpx(10);
|
|
|
|
|
+ font-size: rpx(10);
|
|
|
|
|
+ color: $text-color;
|
|
|
|
|
+ max-width: 80%;
|
|
|
|
|
+ box-shadow: 0 rpx(1) rpx(3) rgba(0, 0, 0, 0.05);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 优化发送按钮样式
|
|
|
|
|
+.send-button {
|
|
|
|
|
+ //background: linear-gradient(90deg, $primary-color, $secondary-color);
|
|
|
|
|
+ border: none;
|
|
|
|
|
+ color: white;
|
|
|
|
|
+
|
|
|
|
|
+ &:hover {
|
|
|
|
|
+ //background: linear-gradient(90deg, darken($primary-color, 5%), darken($secondary-color, 5%));
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+.el-menu .el-menu-item.is-active {
|
|
|
|
|
+ background: linear-gradient(to bottom, #fee78a, #ffce1b);
|
|
|
|
|
+ color: black;
|
|
|
|
|
+ font-size: rpx(8);
|
|
|
|
|
+ box-shadow: 0 4px 8px rgba(3, 3, 3, 0.3);
|
|
|
|
|
+}
|
|
|
|
|
+</style>
|