flat: 暂存
This commit is contained in:
@@ -18,6 +18,7 @@
|
||||
"postinstall": "electron-builder install-app-deps",
|
||||
"build:unpack": "npm run build && electron-builder --dir",
|
||||
"build:win": "npm run build && electron-builder --win",
|
||||
"build:win:x64": "npm run build && electron-builder --win --x64",
|
||||
"build:mac": "npm run build && electron-builder --mac",
|
||||
"build:linux": "npm run build && electron-builder --linux"
|
||||
},
|
||||
|
||||
@@ -34,7 +34,7 @@ function createWindow(): void {
|
||||
mainWindow.show();
|
||||
});
|
||||
|
||||
mainWindow.webContents.openDevTools();
|
||||
// mainWindow.webContents.openDevTools();
|
||||
|
||||
mainWindow.webContents.setWindowOpenHandler((details) => {
|
||||
shell.openExternal(details.url);
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
<template><a-layout class="app-container">
|
||||
|
||||
<template>
|
||||
<a-layout class="app-container">
|
||||
<a-layout-header class="header">
|
||||
<a-flex justify="space-between" align="center" style="height: 100%">
|
||||
<div class="logo-title">
|
||||
<!-- <WifiOutlined />
|
||||
直播中台控制系统 -->
|
||||
<!-- <WifiOutlined v-if="isLiveOn" style="color: #52c41a" /> -->
|
||||
<!-- 直播中台控制系统 -->
|
||||
</div>
|
||||
<a-space :size="20">
|
||||
<a-badge :dot="isConnected">
|
||||
<SettingOutlined class="action-icon" />
|
||||
</a-badge>
|
||||
<a-avatar size="default" style="background-color: #1677ff">
|
||||
<template #icon>
|
||||
<UserOutlined />
|
||||
@@ -17,334 +19,183 @@
|
||||
</a-flex>
|
||||
</a-layout-header>
|
||||
|
||||
<a-layout>
|
||||
|
||||
<a-layout-sider resizable width="300" :min-width="250" :max-width="500" class="sider">
|
||||
<div class="sider-top" style="overflow-y: auto;flex: 2;border-bottom: 1px solid #e8e8e8;max-height: calc(100% * 2 / 5);min-height: calc(100% * 2 / 5);">
|
||||
|
||||
<a-flex justify="space-between" align="center" style="margin-bottom: 16px">
|
||||
<a-space align="left" >
|
||||
<a-typography-title :level="5">
|
||||
岗位列表
|
||||
</a-typography-title>
|
||||
</a-space>
|
||||
<a-space align="right" >
|
||||
<a-button type="primary" @click="handleShow" :loading="modelLoading" >
|
||||
添加岗位
|
||||
<a-layout class="sub-layout">
|
||||
<a-layout-sider resizable :width="300" :min-width="250" :max-width="500" class="sider">
|
||||
<div class="sider-container">
|
||||
<div class="sider-section top-panel">
|
||||
<div class="section-header">
|
||||
<a-typography-title :level="5" style="margin: 0">岗位列表</a-typography-title>
|
||||
<a-button type="primary" size="small" @click="handleShow" :loading="modelLoading">
|
||||
<template #icon>
|
||||
<PlusOutlined />
|
||||
</template>添加
|
||||
</a-button>
|
||||
</a-space>
|
||||
</a-flex>
|
||||
|
||||
<a-list :data-source="positions" item-layout="horizontal">
|
||||
<template #renderItem="{ item, index }" >
|
||||
<a-list-item class="position-item" >
|
||||
<DeleteOutlined title="删除此项" @click.stop="deletedGw(index)"
|
||||
style="color: #1677ff; margin-right: 5px;margin-bottom: 3px;" />
|
||||
<a-list-item-meta :title="item.title" @click="setGwDetail(index)" >
|
||||
</a-list-item-meta>
|
||||
<RightOutlined @click="sendMessageGwAll(index)" />
|
||||
</a-list-item>
|
||||
</template>
|
||||
</a-list>
|
||||
|
||||
<a-divider />
|
||||
</div>
|
||||
<div ref="listScrollRef" class="sider-bottom" style="overflow-y: auto;flex: 3;max-height: calc(100% * 3 / 5);">
|
||||
|
||||
<a-typography-title :level="5">岗位详情</a-typography-title>
|
||||
|
||||
<a-list :data-source="dutyList" item-layout="horizontal">
|
||||
<div class="section-content">
|
||||
<a-list :data-source="positions" item-layout="horizontal" size="small">
|
||||
<template #renderItem="{ item, index }">
|
||||
<a-list-item @click="resetSayin" :ref="($el) => insertItemList($el)" class="position-item" :class="{ 'highlight-item': index === scrollIndex }">
|
||||
<h6 class="details-title" v-if="item.length === 5 " >
|
||||
<StarFilled style="color: #1677ff; margin-left:-20px;margin-right:5px;" />{{ item }}
|
||||
</h6>
|
||||
<a-list-item-meta v-else :title="item" >
|
||||
</a-list-item-meta>
|
||||
<a-list-item class="position-item" @click="setGwDetail(index)">
|
||||
<div class="item-main">
|
||||
<span class="item-title">{{ item.title }}</span>
|
||||
</div>
|
||||
<template #actions>
|
||||
<a-space>
|
||||
<DeleteOutlined class="delete-btn" @click.stop="deletedGw(index)" />
|
||||
<RightOutlined class="play-btn" @click.stop="sendMessageGwAll(index)" />
|
||||
</a-space>
|
||||
</template>
|
||||
</a-list-item>
|
||||
</template>
|
||||
</a-list>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sider-section bottom-panel">
|
||||
<div class="section-header sticky-header">
|
||||
<a-typography-title :level="5" style="margin: 0">岗位详情</a-typography-title>
|
||||
</div>
|
||||
<div ref="listScrollRef" class="section-content">
|
||||
<a-list :data-source="dutyList" item-layout="horizontal" size="small">
|
||||
<template #renderItem="{ item, index }">
|
||||
<a-list-item @click="resetSayin" :ref="($el) => insertItemList($el)"
|
||||
class="detail-item" :class="{ 'highlight-item': index === scrollIndex }">
|
||||
<div v-if="item.length === 5" class="special-duty">
|
||||
<StarFilled class="star-icon" />
|
||||
<span class="bold-text">{{ item }}</span>
|
||||
</div>
|
||||
<span v-else class="normal-duty">{{ item }}</span>
|
||||
</a-list-item>
|
||||
</template>
|
||||
</a-list>
|
||||
<a-empty v-if="dutyList.length === 0" :image="aEmpty.PRESENTED_IMAGE_SIMPLE"
|
||||
description="暂无详情" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a-layout-sider>
|
||||
|
||||
<a-layout class="main-content-layout">
|
||||
|
||||
<a-layout-content class="content-scroll-area">
|
||||
|
||||
<a-card title="直播控制" size="small">
|
||||
<a-row :gutter="[16, 16]">
|
||||
<a-col :xs="24" :sm="12" :md="8">
|
||||
<a-space direction="vertical" size="middle" style="display: flex">
|
||||
<a-card title="直播控制" size="small" :bordered="false" class="custom-card">
|
||||
<a-row :gutter="[12, 12]">
|
||||
<a-col :span="8">
|
||||
<a-button type="primary" block @click="startLive" :loading="loading || isLiveOn">
|
||||
<template #icon>
|
||||
<PlayCircleOutlined />
|
||||
</template>
|
||||
开始直播
|
||||
</template>开始直播
|
||||
</a-button>
|
||||
</a-col>
|
||||
<a-col :xs="24" :sm="12" :md="8">
|
||||
<a-button type="danger" block @click="stopLive" :loading="loading"
|
||||
:disabled="!isLiveOn">
|
||||
<a-col :span="8">
|
||||
<a-button danger block @click="stopLive" :loading="loading" :disabled="!isLiveOn">
|
||||
<template #icon>
|
||||
<StopOutlined />
|
||||
</template>
|
||||
结束直播
|
||||
</template>结束直播
|
||||
</a-button>
|
||||
</a-col>
|
||||
<a-col :xs="24" :sm="12" :md="8">
|
||||
<a-button block @click="fullScreenInsert" :disabled="!isLiveOn">
|
||||
<template #icon>
|
||||
<DesktopOutlined />
|
||||
</template>
|
||||
全屏插播
|
||||
</a-button>
|
||||
</a-col>
|
||||
<a-col :xs="24" :sm="12" :md="8">
|
||||
<a-button block @click="windowInsert" :disabled="!isLiveOn">
|
||||
<template #icon>
|
||||
<FullscreenOutlined />
|
||||
</template>
|
||||
窗口插播
|
||||
</a-button>
|
||||
</a-col>
|
||||
<a-col :xs="24" :sm="12" :md="8">
|
||||
<a-button block @click="audioInsert" :disabled="!isLiveOn">
|
||||
<template #icon>
|
||||
<HighlightOutlined />
|
||||
</template>
|
||||
音频插入
|
||||
</a-button>
|
||||
</a-col>
|
||||
<a-col :xs="24" :sm="12" :md="8">
|
||||
<a-button block @click="forceClose">
|
||||
<a-col :span="8">
|
||||
<a-button danger ghost block @click="forceClose">
|
||||
<template #icon>
|
||||
<VideoCameraOutlined />
|
||||
</template>
|
||||
强制关闭
|
||||
</template>强制关闭
|
||||
</a-button>
|
||||
</a-col>
|
||||
<a-col :span="8"><a-button block @click="fullScreenInsert"
|
||||
:disabled="!isLiveOn">全屏插播</a-button></a-col>
|
||||
<a-col :span="8"><a-button block @click="windowInsert"
|
||||
:disabled="!isLiveOn">窗口插播</a-button></a-col>
|
||||
<a-col :span="8"><a-button block @click="audioInsert"
|
||||
:disabled="!isLiveOn">音频插入</a-button></a-col>
|
||||
</a-row>
|
||||
</a-card>
|
||||
|
||||
<a-card title="讲解输出" size="small">
|
||||
<div class="placeholder-box">
|
||||
</div>
|
||||
</a-card>
|
||||
|
||||
<a-card title="AI模型管理" size="small">
|
||||
<a-card title="AI模型管理" size="small" :bordered="false" class="custom-card">
|
||||
<template #extra>
|
||||
<a-button type="link" size="small" @click="refreshModelStatus">
|
||||
<ReloadOutlined />刷新
|
||||
</a-button>
|
||||
</template>
|
||||
<a-flex justify="space-between" align="center" style="margin-bottom: 16px">
|
||||
<a-space>
|
||||
<a-typography-text>当前模型:</a-typography-text>
|
||||
<a-tag :color="modelStatus.exists ? 'green' : 'orange'">
|
||||
{{ modelStatus.modelName }}
|
||||
<template v-if="modelStatus.exists">
|
||||
<CheckCircleOutlined />
|
||||
</template>
|
||||
<template v-else>
|
||||
<ClockCircleOutlined />
|
||||
</template>
|
||||
</a-tag>
|
||||
<a-tag :color="modelStatus.ollamaRunning ? 'green' : 'red'">
|
||||
{{ modelStatus.ollamaRunning ? 'Ollama运行中' : 'Ollama未运行' }}
|
||||
</a-tag>
|
||||
</a-space>
|
||||
<a-space>
|
||||
<a-button type="primary" @click="loadModel" :loading="modelLoading"
|
||||
:disabled="modelLoading">
|
||||
<template #icon>
|
||||
<DownloadOutlined />
|
||||
</template>
|
||||
{{ modelLoading ? '加载中...' : '加载模型' }}
|
||||
</a-button>
|
||||
<a-button @click="refreshModelStatus" :disabled="modelLoading">
|
||||
<template #icon>
|
||||
<ReloadOutlined />
|
||||
</template>
|
||||
刷新状态
|
||||
</a-button>
|
||||
<a-tag :color="modelStatus.exists ? 'green' : 'orange'">{{ modelStatus.modelName
|
||||
}}</a-tag>
|
||||
<a-badge :status="modelStatus.ollamaRunning ? 'processing' : 'default'"
|
||||
:text="modelStatus.ollamaRunning ? 'Ollama运行中' : '服务未就绪'" />
|
||||
</a-space>
|
||||
<a-button type="primary" size="small" @click="loadModel"
|
||||
:loading="modelLoading">加载模型</a-button>
|
||||
</a-flex>
|
||||
|
||||
<!-- 文件拖拽区域 -->
|
||||
<div class="file-drop-zone" @drop="handleFileDrop" @dragover.prevent @dragenter.prevent
|
||||
<div class="file-drop-zone" @drop="handleFileDrop" @dragover.prevent
|
||||
:class="{ 'is-dragging': fileUploadLoading }">
|
||||
<p class="file-drop-icon">
|
||||
<InboxOutlined />
|
||||
</p>
|
||||
<p class="file-drop-text">拖拽图片、拖拽视频文件,自动展示</p>
|
||||
<p class="file-drop-hint">支持图片、视频格式</p>
|
||||
<InboxOutlined class="drop-icon" />
|
||||
<p class="drop-text">拖拽图片或视频至此处自动展示</p>
|
||||
</div>
|
||||
|
||||
<!-- 已上传文件列表 -->
|
||||
<div v-if="uploadedFiles.length > 0" class="uploaded-files-list">
|
||||
<div v-for="(file, index) in uploadedFiles" :key="index" class="file-item">
|
||||
<div v-if="uploadedFiles.length > 0" class="file-list-container">
|
||||
<div v-for="(file, index) in uploadedFiles" :key="index" class="file-item-row">
|
||||
<div class="file-info">
|
||||
<FileOutlined class="file-icon" />
|
||||
<span class="file-name">{{ file.name }}</span>
|
||||
<a-tag :color="getFileTagColor(file.type)" size="small">{{
|
||||
<FileOutlined /> <span class="file-name">{{ file.name }}</span>
|
||||
<a-tag size="small" :color="getFileTagColor(file.type)">{{
|
||||
getFileTypeText(file.type)
|
||||
}}</a-tag>
|
||||
</div>
|
||||
<a-button size="small" danger @click="removeFile(index)">
|
||||
<template #icon>
|
||||
<a-button type="text" danger size="small" @click="removeFile(index)">
|
||||
<DeleteOutlined />
|
||||
</template>
|
||||
删除
|
||||
</a-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a-space style="margin-top: 12px;">
|
||||
<a-button @click="clearAllFiles" :disabled="uploadedFiles.length === 0">
|
||||
<template #icon>
|
||||
<DeleteOutlined />
|
||||
</template>
|
||||
清空文件
|
||||
</a-button>
|
||||
<a-button @click="showFilesInLive" :disabled="uploadedFiles.length === 0 || !isLiveOn">
|
||||
<template #icon>
|
||||
<EyeOutlined />
|
||||
</template>
|
||||
在直播中展示
|
||||
</a-button>
|
||||
<a-space style="margin-top: 12px">
|
||||
<a-button size="small" @click="clearAllFiles"
|
||||
:disabled="uploadedFiles.length === 0">清空</a-button>
|
||||
<a-button size="small" type="primary" ghost @click="showFilesInLive"
|
||||
:disabled="uploadedFiles.length === 0 || !isLiveOn">在直播中展示</a-button>
|
||||
</a-space>
|
||||
</a-card>
|
||||
|
||||
</a-space>
|
||||
</a-layout-content>
|
||||
|
||||
<a-layout-footer class="input-footer">
|
||||
<a-space>
|
||||
<a-button danger size="small" block @click="polishText('inputValue')" :loading="polishLoading"
|
||||
:disabled="!inputValue.trim()">
|
||||
润色
|
||||
</a-button>
|
||||
</a-space>
|
||||
<a-space-compact block style="display: flex; margin-bottom: 8px; margin-top: 8px;">
|
||||
<a-textarea v-model:value="inputValue" placeholder="输入指令..."
|
||||
<div class="footer-inner">
|
||||
<a-flex gap="small" vertical>
|
||||
<div class="quick-commands">
|
||||
<span class="label">快捷指令:</span>
|
||||
<a-button v-for="cmd in ['欢迎新观众', '感谢陪伴', '互动提问', '行业分享']" :key="cmd" size="small"
|
||||
class="cmd-btn" @click="setQuickCommand(cmd)">{{ cmd }}</a-button>
|
||||
</div>
|
||||
<a-space-compact block>
|
||||
<a-textarea v-model:value="inputValue" placeholder="输入指令或内容..."
|
||||
:auto-size="{ minRows: 1, maxRows: 3 }" @press-enter="sendMessage" />
|
||||
<a-button type="primary" @click="sendMessage" :disabled="!isLiveOn">发送</a-button>
|
||||
<a-button type="primary" @click="sendMessage" :disabled="!isLiveOn"
|
||||
style="height: auto">发送</a-button>
|
||||
</a-space-compact>
|
||||
<a-space>
|
||||
<a-typography-text type="secondary">快捷指令:</a-typography-text>
|
||||
<a-button type="dashed" size="small" @click="setQuickCommand('欢迎新观众')">欢迎新观众</a-button>
|
||||
<a-button type="dashed" size="small" @click="setQuickCommand('感谢大家的陪伴')">感谢陪伴</a-button>
|
||||
<a-button type="dashed" size="small" @click="setQuickCommand('有什么问题可以随时提问')">互动提问</a-button>
|
||||
<a-button type="dashed" size="small"
|
||||
@click="setQuickCommand('今天给大家分享一些有趣的行业资讯')">行业分享</a-button>
|
||||
</a-space>
|
||||
<a-button size="small" class="polish-btn" @click="polishText('inputValue')"
|
||||
:loading="polishLoading">
|
||||
<RotateRightOutlined /> 智能润色
|
||||
</a-button>
|
||||
</a-flex>
|
||||
</div>
|
||||
</a-layout-footer>
|
||||
</a-layout>
|
||||
|
||||
</a-layout>
|
||||
</a-layout>
|
||||
|
||||
<!-- 可输入内容的模态框 -->
|
||||
<a-modal
|
||||
v-model:open="showModal"
|
||||
width="800px"
|
||||
ok-text="提交"
|
||||
cancel-text="取消"
|
||||
@ok="handleOk"
|
||||
@cancel="handleCancel"
|
||||
:maskClosable="false"
|
||||
:destroyOnClose="true"
|
||||
:confirmLoading="confirmLoading"
|
||||
>
|
||||
<template #title>
|
||||
<div class="modal-title-wrapper">
|
||||
<!-- 标题栏右侧按钮组 -->
|
||||
<div class="title-button-group">
|
||||
<a-row>
|
||||
<a-col :span="10">
|
||||
<!-- 原标题文字 -->
|
||||
<a-label style="font-weight: bolder;" >新增岗位信息</a-label>
|
||||
<!-- 暂时没有其他格式得,默认就是text
|
||||
<a-button
|
||||
:type="btn1Type"
|
||||
size="small"
|
||||
@click="typeChange('btn1')"
|
||||
style="margin-left:10px;"
|
||||
>
|
||||
文本
|
||||
</a-button>
|
||||
<a-button
|
||||
:type="btn2Type"
|
||||
size="small"
|
||||
@click="typeChange('btn2')"
|
||||
style="margin-left:5px;"
|
||||
>
|
||||
JSON
|
||||
</a-button>
|
||||
-->
|
||||
</a-col>
|
||||
<a-col :span="14">
|
||||
<!-- 在提交得时候自动进行转换 , 仅保留文字润色功能
|
||||
<a-button
|
||||
type="default"
|
||||
size="small"
|
||||
@click="transText"
|
||||
style="margin-left:13px;"
|
||||
>
|
||||
转换
|
||||
</a-button>
|
||||
-->
|
||||
<a-button
|
||||
type="default"
|
||||
size="small"
|
||||
@click="polishText('gangwei')"
|
||||
style="margin-left:5px;"
|
||||
>
|
||||
润色
|
||||
</a-button>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- 表单区域 -->
|
||||
<a-form
|
||||
ref="formRef"
|
||||
:model="formData"
|
||||
:rules="formRules"
|
||||
:label-col="{ span: 6 }"
|
||||
:wrapper-col="{ span: 50 }"
|
||||
layout="horizontal"
|
||||
>
|
||||
<a-row :gutter="16">
|
||||
<a-col :span="24">
|
||||
<!-- 单行输入框 -->
|
||||
<a-form-item label="" name="infoin">
|
||||
<a-textarea
|
||||
v-model:value="formData.infoin"
|
||||
placeholder="请输岗位信息"
|
||||
:rows="15"
|
||||
maxlength="2000"
|
||||
/>
|
||||
<a-modal v-model:open="showModal" title="新增岗位信息" width="600px" @ok="handleOk">
|
||||
<a-form ref="formRef" :model="formData" :rules="formRules" layout="vertical">
|
||||
<a-form-item label="详细信息" name="infoin">
|
||||
<a-textarea v-model:value="formData.infoin" :rows="10" placeholder="请输入岗位描述,系统将自动切分段落..." />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
|
||||
<a-col :span="0">
|
||||
<div style="width: 375px;height: 340px;overflow-y: scroll;">
|
||||
<!-- 多行文本框 -->
|
||||
<div v-for="(item, index) in formData.infoDetail"
|
||||
:key="index"
|
||||
>
|
||||
<textarea style="overflow: hidden;border: none;line-height: 1.1;height: auto;min-height: 10px;outline: none;width: 100%;flex: none;resize: none;margin: 0px;padding: 0px 5px;word-wrap: break-word;word-break: break-all;"
|
||||
v-model="formData.infoDetail[index]"
|
||||
readonly="true" class="auto-wrap-textarea" wrap="soft"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-button size="small" @click="polishText('gangwei')" :loading="polishLoading">
|
||||
<RotateRightOutlined />润色内容
|
||||
</a-button>
|
||||
</a-form>
|
||||
</a-modal>
|
||||
|
||||
</a-layout>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted, onUnmounted, computed, reactive, nextTick, watch } from 'vue';
|
||||
import { message, Modal, } from 'ant-design-vue';
|
||||
import { message, Modal, Empty as aEmpty } from 'ant-design-vue';
|
||||
import SocketClient from '@renderer/utils/socket';
|
||||
import {
|
||||
WifiOutlined,
|
||||
@@ -367,6 +218,8 @@ import {
|
||||
ClockCircleOutlined,
|
||||
FileOutlined,
|
||||
EyeOutlined,
|
||||
RotateRightOutlined,
|
||||
PlusOutlined
|
||||
} from '@ant-design/icons-vue';
|
||||
import { useUserStore } from '@renderer/stores/useUserStore';
|
||||
|
||||
@@ -1012,6 +865,7 @@ const polishTextBackStr = async (_inputStr) => {
|
||||
// const originalText = _inputStr+123;
|
||||
// console.log("originalText",originalText)
|
||||
// return originalText;
|
||||
const originalText = _inputStr;
|
||||
|
||||
try {
|
||||
console.log('开始润色文本:', originalText);
|
||||
@@ -1374,239 +1228,243 @@ onMounted(() => {
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 根容器:
|
||||
使用 100vh 充满窗口,并禁止窗口级别滚动。
|
||||
内部的 <a-layout> 会自动继承这个高度。
|
||||
*/
|
||||
<style scoped lang="scss">
|
||||
/* 布局基座 */
|
||||
.app-container {
|
||||
height: 100vh;
|
||||
overflow: hidden;
|
||||
/* 关键:禁止最外层滚动 */
|
||||
}
|
||||
|
||||
/* 顶部导航栏 */
|
||||
.header {
|
||||
background: #fff;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
padding: 0 20px;
|
||||
height: 60px;
|
||||
/* 缩小顶部栏高度 */
|
||||
line-height: 60px;
|
||||
flex-shrink: 0;
|
||||
/* 防止顶部栏被压缩 */
|
||||
height: 56px;
|
||||
line-height: 56px;
|
||||
z-index: 100;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
|
||||
-webkit-app-region: drag;
|
||||
}
|
||||
|
||||
.logo-title {
|
||||
font-size: 18px;
|
||||
/* 缩小字体 */
|
||||
font-weight: 600;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
.sub-layout {
|
||||
height: calc(100vh - 56px);
|
||||
}
|
||||
|
||||
.action-icon {
|
||||
font-size: 16px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* 左侧边栏:
|
||||
- ant-layout-sider 默认有 100% 高度
|
||||
- 我们需要让 *内部* 的内容可滚动
|
||||
*/
|
||||
/* 侧边栏结构优化 */
|
||||
.sider {
|
||||
background: #fff;
|
||||
background: #fff !important;
|
||||
border-right: 1px solid #f0f0f0;
|
||||
/* 关键:Sider 本身高度 100%,
|
||||
但内部内容可能溢出,所以用一个 wrapper 来滚动
|
||||
*/
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.sider-scroll-content {
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
padding: 16px;
|
||||
/* 缩小内边距 */
|
||||
}
|
||||
|
||||
.position-item {
|
||||
padding: 10px 8px;
|
||||
/* 缩小列表项间距 */
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
transition: background-color 0.3s;
|
||||
}
|
||||
|
||||
.position-item:hover {
|
||||
background-color: #f7f7f7;
|
||||
}
|
||||
|
||||
/* 岗位详情 */
|
||||
.details-title {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
margin-top: 16px;
|
||||
margin-bottom: 8px;
|
||||
:deep(.ant-layout-sider-children) {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
|
||||
.details-list {
|
||||
padding-left: 24px;
|
||||
/* 缩小缩进 */
|
||||
margin: 0;
|
||||
color: #555;
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
/* 右侧主布局:
|
||||
- 默认就是 flex: 1,自动撑满
|
||||
- 背景色放在这里,而不是 content-scroll-area
|
||||
*/
|
||||
.main-content-layout {
|
||||
background: #f0f2f5;
|
||||
/* 关键:确保内部的 content 和 footer 垂直排列 */
|
||||
.sider-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
/* 继承父级高度 */
|
||||
}
|
||||
|
||||
/* 右侧可滚动内容区:
|
||||
- flex: 1: 自动撑满所有可用空间
|
||||
- overflow-y: auto: 独立滚动
|
||||
*/
|
||||
.content-scroll-area {
|
||||
overflow-y: auto;
|
||||
padding: 16px;
|
||||
/* 缩小内边距 */
|
||||
flex: 1;
|
||||
/* 关键:撑满除 footer 外的空间 */
|
||||
.sider-section {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
|
||||
&.top-panel {
|
||||
flex: 4; // 岗位列表占 40%
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
}
|
||||
|
||||
/* 讲解输出占位符 */
|
||||
.placeholder-box {
|
||||
min-height: 120px;
|
||||
/* 缩小高度 */
|
||||
background: #fafafa;
|
||||
border: 1px dashed #d9d9d9;
|
||||
border-radius: 8px;
|
||||
&.bottom-panel {
|
||||
flex: 6; // 岗位详情占 60%
|
||||
background-color: #fafafa;
|
||||
}
|
||||
}
|
||||
|
||||
/* 底部输入框:
|
||||
- flex-shrink: 0: 确保不会被压缩
|
||||
- height: auto: 高度自适应
|
||||
*/
|
||||
.input-footer {
|
||||
background: #fff;
|
||||
.section-header {
|
||||
padding: 12px 16px;
|
||||
/* 缩小内边距 */
|
||||
border-top: 1px solid #f0f0f0;
|
||||
box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.05);
|
||||
height: auto;
|
||||
/* 关键:高度自适应 */
|
||||
flex-shrink: 0;
|
||||
/* 关键:防止被压缩 */
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
/* 文件拖拽区域样式 */
|
||||
.section-content {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
padding: 0 12px 12px;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
width: 4px;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-thumb {
|
||||
background: #e8e8e8;
|
||||
border-radius: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
/* 列表项交互样式 */
|
||||
.position-item {
|
||||
padding: 8px 12px !important;
|
||||
border-radius: 6px;
|
||||
margin-bottom: 4px;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
border: 1px solid transparent !important;
|
||||
|
||||
&:hover {
|
||||
background-color: #f0f7ff;
|
||||
border-color: #e6f4ff !important;
|
||||
}
|
||||
|
||||
.play-btn {
|
||||
color: #1677ff;
|
||||
|
||||
&:hover {
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
|
||||
.delete-btn {
|
||||
color: #bfbfbf;
|
||||
|
||||
&:hover {
|
||||
color: #ff4d4f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.detail-item {
|
||||
padding: 10px 12px !important;
|
||||
border-radius: 4px;
|
||||
margin-bottom: 2px;
|
||||
background: #fff;
|
||||
border-left: 3px solid transparent !important;
|
||||
|
||||
&.highlight-item {
|
||||
background-color: #e6f4ff !important;
|
||||
border-left-color: #1677ff !important;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
}
|
||||
|
||||
.special-duty {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: #1677ff;
|
||||
|
||||
.star-icon {
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.bold-text {
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
/* 主内容与卡片 */
|
||||
.main-content-layout {
|
||||
background: #f5f7fa;
|
||||
}
|
||||
|
||||
.content-scroll-area {
|
||||
padding: 16px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.custom-card {
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.03);
|
||||
|
||||
:deep(.ant-card-head) {
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
min-height: 40px;
|
||||
}
|
||||
}
|
||||
|
||||
/* 文件上传区 */
|
||||
.file-drop-zone {
|
||||
border: 2px dashed #d9d9d9;
|
||||
border: 1px dashed #d9d9d9;
|
||||
border-radius: 8px;
|
||||
padding: 24px;
|
||||
text-align: center;
|
||||
background-color: #fafafa;
|
||||
transition: all 0.3s ease;
|
||||
cursor: pointer;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
background: #fff;
|
||||
transition: all 0.3s;
|
||||
|
||||
.file-drop-zone:hover,
|
||||
.file-drop-zone.is-dragging {
|
||||
&.is-dragging,
|
||||
&:hover {
|
||||
border-color: #1677ff;
|
||||
background-color: #f0f8ff;
|
||||
background: #f0f7ff;
|
||||
}
|
||||
|
||||
.file-drop-icon {
|
||||
font-size: 48px;
|
||||
.drop-icon {
|
||||
font-size: 32px;
|
||||
color: #1677ff;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.file-drop-text {
|
||||
font-size: 16px;
|
||||
color: #262626;
|
||||
margin-bottom: 4px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.file-drop-hint {
|
||||
font-size: 14px;
|
||||
.drop-text {
|
||||
color: #8c8c8c;
|
||||
margin: 0;
|
||||
font-size: 13px;
|
||||
}
|
||||
}
|
||||
|
||||
/* 文件列表样式 */
|
||||
.uploaded-files-list {
|
||||
max-height: 200px;
|
||||
overflow-y: auto;
|
||||
.file-list-container {
|
||||
margin-top: 12px;
|
||||
border: 1px solid #f0f0f0;
|
||||
border-radius: 6px;
|
||||
margin-bottom: 12px;
|
||||
max-height: 150px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.file-item {
|
||||
.file-item-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 8px 12px;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
}
|
||||
padding: 6px 12px;
|
||||
background: #fff;
|
||||
border-bottom: 1px solid #f9f9f9;
|
||||
|
||||
.file-item:last-child {
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.file-item:hover {
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
.file-info {
|
||||
/* 底部区域 */
|
||||
.input-footer {
|
||||
background: #fff;
|
||||
padding: 12px 20px;
|
||||
border-top: 1px solid #f0f0f0;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.quick-commands {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
gap: 8px;
|
||||
|
||||
.label {
|
||||
color: #8c8c8c;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.file-icon {
|
||||
margin-right: 8px;
|
||||
color: #1677ff;
|
||||
flex-shrink: 0;
|
||||
.cmd-btn {
|
||||
font-size: 12px;
|
||||
border-radius: 10px;
|
||||
background: #f5f5f5;
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
|
||||
.file-name {
|
||||
font-size: 14px;
|
||||
color: #262626;
|
||||
margin-right: 8px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
flex: 1;
|
||||
}
|
||||
.polish-btn {
|
||||
align-self: flex-start;
|
||||
color: #722ed1;
|
||||
border-color: #d3adf7;
|
||||
|
||||
/* 确保卡片之间有间距 */
|
||||
.ant-card {
|
||||
margin-bottom: 16px;
|
||||
&:hover {
|
||||
background: #f9f0ff;
|
||||
}
|
||||
/* 新增:index=5 时的高亮样式(可根据需求自定义) */
|
||||
.highlight-item {
|
||||
background-color: #e6f7ff; /* 浅蓝色背景 */
|
||||
border-left: 3px solid #1677ff; /* 蓝色左侧边框强调 */
|
||||
padding-left: 15px !important; /* 调整内边距 */
|
||||
color: #1677ff; /* 文字变蓝 */
|
||||
}
|
||||
|
||||
</style>
|
||||
Reference in New Issue
Block a user