服务指令编辑页样式调整(非最终)

This commit is contained in:
1378012178@qq.com 2025-08-11 17:04:01 +08:00
parent fb82a56496
commit c4c86718c7
14 changed files with 707 additions and 302 deletions

View File

@ -6,19 +6,19 @@ VITE_PUBLIC_PATH = /
# 跨域代理,您可以配置多个 ,请注意,没有换行符 # 跨域代理,您可以配置多个 ,请注意,没有换行符
VITE_PROXY = [["/nursing-unit_102","http://localhost:8092/nursing-unit_102"],["/upload","http://localhost:3300/upload"]] VITE_PROXY = [["/nursing-unit_101","http://localhost:8091/nursing-unit_101"],["/upload","http://localhost:3300/upload"]]
#后台接口全路径地址(必填) #后台接口全路径地址(必填)
VITE_GLOB_DOMAIN_URL=http://localhost:8092/nursing-unit_102 VITE_GLOB_DOMAIN_URL=http://localhost:8091/nursing-unit_101
#后台接口父地址(必填) #后台接口父地址(必填)
VITE_GLOB_API_URL=/nursing-unit_102 VITE_GLOB_API_URL=/nursing-unit_101
# 接口前缀 # 接口前缀
VITE_GLOB_API_URL_PREFIX= VITE_GLOB_API_URL_PREFIX=
#微前端qiankun应用,命名必须以VITE_APP_SUB_开头,jeecg-app-1为子应用的项目名称,也是子应用的路由父路径 #微前端qiankun应用,命名必须以VITE_APP_SUB_开头,jeecg-app-1为子应用的项目名称,也是子应用的路由父路径
VITE_APP_SUB_jeecg-app-1 = '//localhost:8092' VITE_APP_SUB_jeecg-app-1 = '//localhost:8091'
# 填写后将作为乾坤子应用启动主应用注册时AppName需保持一致放开 VITE_GLOB_QIANKUN_MICRO_APP_NAME 参数表示jeecg-vue3将以乾坤子应用模式启动 # 填写后将作为乾坤子应用启动主应用注册时AppName需保持一致放开 VITE_GLOB_QIANKUN_MICRO_APP_NAME 参数表示jeecg-vue3将以乾坤子应用模式启动
#VITE_GLOB_QIANKUN_MICRO_APP_NAME=jeecg-vue3 #VITE_GLOB_QIANKUN_MICRO_APP_NAME=jeecg-vue3

View File

@ -6,19 +6,19 @@ VITE_PUBLIC_PATH = /
# 跨域代理,您可以配置多个 ,请注意,没有换行符 # 跨域代理,您可以配置多个 ,请注意,没有换行符
VITE_PROXY = [["/nursing-unit_101","http://localhost:8091/nursing-unit_101"],["/upload","http://localhost:3300/upload"]] VITE_PROXY = [["/nursing-unit_102","http://localhost:8092/nursing-unit_102"],["/upload","http://localhost:3300/upload"]]
#后台接口全路径地址(必填) #后台接口全路径地址(必填)
VITE_GLOB_DOMAIN_URL=http://localhost:8091/nursing-unit_101 VITE_GLOB_DOMAIN_URL=http://localhost:8092/nursing-unit_102
#后台接口父地址(必填) #后台接口父地址(必填)
VITE_GLOB_API_URL=/nursing-unit_101 VITE_GLOB_API_URL=/nursing-unit_102
# 接口前缀 # 接口前缀
VITE_GLOB_API_URL_PREFIX= VITE_GLOB_API_URL_PREFIX=
#微前端qiankun应用,命名必须以VITE_APP_SUB_开头,jeecg-app-1为子应用的项目名称,也是子应用的路由父路径 #微前端qiankun应用,命名必须以VITE_APP_SUB_开头,jeecg-app-1为子应用的项目名称,也是子应用的路由父路径
VITE_APP_SUB_jeecg-app-1 = '//localhost:8091' VITE_APP_SUB_jeecg-app-1 = '//localhost:8092'
# 填写后将作为乾坤子应用启动主应用注册时AppName需保持一致放开 VITE_GLOB_QIANKUN_MICRO_APP_NAME 参数表示jeecg-vue3将以乾坤子应用模式启动 # 填写后将作为乾坤子应用启动主应用注册时AppName需保持一致放开 VITE_GLOB_QIANKUN_MICRO_APP_NAME 参数表示jeecg-vue3将以乾坤子应用模式启动
#VITE_GLOB_QIANKUN_MICRO_APP_NAME=jeecg-vue3 #VITE_GLOB_QIANKUN_MICRO_APP_NAME=jeecg-vue3

View File

@ -2,7 +2,7 @@
VITE_USE_MOCK = false VITE_USE_MOCK = false
# 发布路径 # 发布路径
VITE_PUBLIC_PATH = /biz103 VITE_PUBLIC_PATH = /biz101
# 是否启用gzip或brotli压缩 # 是否启用gzip或brotli压缩
# 选项值: gzip | brotli | none # 选项值: gzip | brotli | none
@ -13,10 +13,10 @@ VITE_BUILD_COMPRESS = 'gzip'
VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE = false VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE = false
#后台接口父地址(必填) #后台接口父地址(必填)
VITE_GLOB_API_URL=/nursingunit103 VITE_GLOB_API_URL=/nursingunit101
#后台接口全路径地址(必填) #后台接口全路径地址(必填)
VITE_GLOB_DOMAIN_URL=https://www.focusnu.com/nursingunit103 VITE_GLOB_DOMAIN_URL=https://www.focusnu.com/nursingunit101
# 接口父路径前缀 # 接口父路径前缀
VITE_GLOB_API_URL_PREFIX= VITE_GLOB_API_URL_PREFIX=

View File

@ -7,99 +7,103 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { watch, ref } from 'vue'; import { watch, ref } from 'vue';
import { theme } from 'ant-design-vue'; import { theme } from 'ant-design-vue';
import { ConfigProvider } from 'ant-design-vue'; import { ConfigProvider } from 'ant-design-vue';
import { AppProvider } from '/@/components/Application'; import { AppProvider } from '/@/components/Application';
import { useTitle } from '/@/hooks/web/useTitle'; import { useTitle } from '/@/hooks/web/useTitle';
import { useLocale } from '/@/locales/useLocale'; import { useLocale } from '/@/locales/useLocale';
import { useAppStore } from '/@/store/modules/app'; import { useAppStore } from '/@/store/modules/app';
import { useRootSetting } from '/@/hooks/setting/useRootSetting'; import { useRootSetting } from '/@/hooks/setting/useRootSetting';
import { ThemeEnum } from '/@/enums/appEnum'; import { ThemeEnum } from '/@/enums/appEnum';
import { changeTheme } from '/@/logics/theme/index'; import { changeTheme } from '/@/logics/theme/index';
const appStore = useAppStore(); const appStore = useAppStore();
// //
import 'dayjs/locale/zh-cn'; import 'dayjs/locale/zh-cn';
// support Multi-language // support Multi-language
const { getAntdLocale } = useLocale(); const { getAntdLocale } = useLocale();
useTitle(); useTitle();
/** /**
* 2024-04-07 * 2024-04-07
* liaozhiyang * liaozhiyang
* 暗黑模式下默认文字白色白天模式默认文字 #333 * 暗黑模式下默认文字白色白天模式默认文字 #333
* */ * */
const modeAction = (data) => { const modeAction = (data) => {
if (data.token) { if (data.token) {
if (getDarkMode.value === ThemeEnum.DARK) { if (getDarkMode.value === ThemeEnum.DARK) {
Object.assign(data.token, { colorTextBase: 'fff' }); Object.assign(data.token, { colorTextBase: 'fff' });
} else { } else {
Object.assign(data.token, { colorTextBase: '#333' }); Object.assign(data.token, { colorTextBase: '#333' });
}
} }
}; }
// update-begin--author:liaozhiyang---date:20231218---forQQYUN-6366antd4.x };
const appTheme: any = ref({}); // update-begin--author:liaozhiyang---date:20231218---forQQYUN-6366antd4.x
const { getDarkMode } = useRootSetting(); const appTheme: any = ref({});
watch( const { getDarkMode } = useRootSetting();
() => getDarkMode.value, watch(
(newValue) => { () => getDarkMode.value,
delete appTheme.value.algorithm; (newValue) => {
if (newValue === ThemeEnum.DARK) { delete appTheme.value.algorithm;
appTheme.value.algorithm = theme.darkAlgorithm; if (newValue === ThemeEnum.DARK) {
} appTheme.value.algorithm = theme.darkAlgorithm;
// update-begin--author:liaozhiyang---date:20240322---forQQYUN-8570 }
if (import.meta.env.PROD) { // update-begin--author:liaozhiyang---date:20240322---forQQYUN-8570
changeTheme(appStore.getProjectConfig.themeColor); if (import.meta.env.PROD) {
} changeTheme(appStore.getProjectConfig.themeColor);
// update-end--author:liaozhiyang---date:20240322---forQQYUN-8570 }
modeAction(appTheme.value); // update-end--author:liaozhiyang---date:20240322---forQQYUN-8570
appTheme.value = { modeAction(appTheme.value);
...appTheme.value, appTheme.value = {
}; ...appTheme.value,
}, };
{ immediate: true } },
); { immediate: true }
watch( );
appStore.getProjectConfig, watch(
(newValue) => { appStore.getProjectConfig,
const primary = newValue.themeColor; (newValue) => {
const result = { const primary = newValue.themeColor;
...appTheme.value, const result = {
...{ ...appTheme.value,
token: { ...{
colorPrimary: primary, token: {
wireframe: true, colorPrimary: primary,
fontSize: 14, wireframe: true,
colorTextBase: '#333', fontSize: 14,
colorSuccess: '#55D187', colorTextBase: '#333',
colorInfo: primary, colorSuccess: '#55D187',
borderRadius: 4, colorInfo: primary,
sizeStep: 4, borderRadius: 4,
sizeUnit: 4, sizeStep: 4,
colorWarning: '#EFBD47', sizeUnit: 4,
colorError: '#ED6F6F', colorWarning: '#EFBD47',
fontFamily: colorError: '#ED6F6F',
'-apple-system,BlinkMacSystemFont,Segoe UI,PingFang SC,Hiragino Sans GB,Microsoft YaHei,Helvetica Neue,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol', fontFamily:
}, '-apple-system,BlinkMacSystemFont,Segoe UI,PingFang SC,Hiragino Sans GB,Microsoft YaHei,Helvetica Neue,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol',
}, },
}; },
appTheme.value = result; };
modeAction(result); appTheme.value = result;
}, modeAction(result);
{ immediate: true } },
); { immediate: true }
setTimeout(() => { );
appStore.getProjectConfig?.themeColor && changeTheme(appStore.getProjectConfig.themeColor); setTimeout(() => {
}, 300); appStore.getProjectConfig?.themeColor && changeTheme(appStore.getProjectConfig.themeColor);
// update-end--author:liaozhiyang---date:20231218---forQQYUN-6366antd4.x }, 300);
// update-end--author:liaozhiyang---date:20231218---forQQYUN-6366antd4.x
</script> </script>
<style lang="less"> <style lang="less">
// update-begin--author:liaozhiyang---date:20230803---forQQYUN-5839windihtml2canvas // update-begin--author:liaozhiyang---date:20230803---forQQYUN-5839windihtml2canvas
img { img {
display: inline-block; display: inline-block;
} }
// update-end--author:liaozhiyang---date:20230803---forQQYUN-5839windihtml2canvas
</style> .nu-menu-item :hover {
color: #69c0ff !important;
}
// update-end--author:liaozhiyang---date:20230803---forQQYUN-5839windihtml2canvas</style>

View File

@ -97,8 +97,8 @@ const { prefixCls, tableContext, onExportXls, onImportXls } = useListPage({
useSearchForm: false, useSearchForm: false,
pagination: { pagination: {
current: 1, current: 1,
pageSize: 50, pageSize: 15,
pageSizeOptions: ['50', '70', '100'], pageSizeOptions: ['15','50', '70', '100'],
}, },
actionColumn: { actionColumn: {
width: 160, width: 160,

View File

@ -97,8 +97,8 @@ const { prefixCls, tableContext, onExportXls, onImportXls } = useListPage({
useSearchForm: false, useSearchForm: false,
pagination: { pagination: {
current: 1, current: 1,
pageSize: 50, pageSize: 15,
pageSizeOptions: ['50', '70', '100'], pageSizeOptions: ['15','50', '70', '100'],
}, },
actionColumn: { actionColumn: {
width: 160, width: 160,

View File

@ -73,10 +73,10 @@
</a-form> </a-form>
</div> </div>
<div> <div>
<div style="width:350px;float: left;max-height:77vh; overflow:auto;position: relative;"> <div style="width:350px;float: left;max-height:80vh; overflow:auto;position: relative;">
<div <div
style="position: absolute; top: 8px; right: 8px; z-index: 1; background: white; padding: 0px; border-radius: 4px;"> style="position: absolute; top: 8px; right: 8px; z-index: 1; background: white; padding: 0px; border-radius: 4px;">
<a-radio-group v-model:value="filterIzEnabled" @change="searchQuery"> <a-radio-group v-model:value="filterIzEnabled" @change="searchQuery">
<a-radio-button value="all">全部</a-radio-button> <a-radio-button value="all">全部</a-radio-button>
<a-radio-button value="enabled">启用</a-radio-button> <a-radio-button value="enabled">启用</a-radio-button>
</a-radio-group> </a-radio-group>
@ -89,8 +89,8 @@
<a-empty v-if="!treeLoading && treeLoading" /> <a-empty v-if="!treeLoading && treeLoading" />
<a-button v-if="!treeLoading && treeData.length < 1" type="link" class="btnPrivate" @click="addInstruction" <a-button v-if="!treeLoading && treeData.length < 1" type="link" class="btnPrivate" @click="addInstruction"
preIcon="ant-design:plus-outlined">新增分类标签</a-button> preIcon="ant-design:plus-outlined">新增分类标签</a-button>
<a-tree style="padding-top: 40px;" v-if="!treeLoading && treeData.length > 0" :tree-data="treeData" v-model:expandedKeys="expandedKeys" <a-tree style="padding-top: 40px;min-height:80vh;" v-if="!treeLoading && treeData.length > 0"
expandAction="click" @select="handleTreeSelect"> :tree-data="treeData" v-model:expandedKeys="expandedKeys" expandAction="click" @select="handleTreeSelect">
<template #title="{ data }"> <template #title="{ data }">
<!-- @click.stop="openMenu(data, data.children, $event)" --> <!-- @click.stop="openMenu(data, data.children, $event)" -->
<!-- @contextmenu.prevent="openMenu(data, data.children, $event)" --> <!-- @contextmenu.prevent="openMenu(data, data.children, $event)" -->
@ -109,7 +109,7 @@
<template #overlay> <template #overlay>
<a-menu> <a-menu>
<a-menu-item v-for="item in menuItems(data)" :key="item.key" :disabled="!item.canAdd" <a-menu-item v-for="item in menuItems(data)" :key="item.key" :disabled="!item.canAdd"
@click="() => { closeAllMenus(); item.action(data) }"> class="nu-menu-item" @click="() => { closeAllMenus(); item.action(data) }">
<Icon style="color:#1890FF;" :icon="item.icon" class="action-icon"></Icon> <Icon style="color:#1890FF;" :icon="item.icon" class="action-icon"></Icon>
<span style=" color:#1890FF;margin-left: 5px;">{{ item.label }}</span> <span style=" color:#1890FF;margin-left: 5px;">{{ item.label }}</span>
</a-menu-item> </a-menu-item>
@ -228,7 +228,7 @@
</a-drawer> </a-drawer>
<!-- 体型标签 --> <!-- 体型标签 -->
<a-drawer title="体型标签" width="60vw" :open="bodyTagOpen" @close="onBodyTagClose" > <a-drawer title="体型标签" width="60vw" :open="bodyTagOpen" @close="onBodyTagClose">
<template #footer> <template #footer>
<a-button type="primary" @click="onBodyTagClose" style="float: right;">关闭</a-button> <a-button type="primary" @click="onBodyTagClose" style="float: right;">关闭</a-button>
</template> </template>
@ -236,7 +236,7 @@
</a-drawer> </a-drawer>
<!-- 情绪标签 --> <!-- 情绪标签 -->
<a-drawer title="情绪标签" width="60vw" :open="emotionTagOpen" @close="onEmotionTagClose" > <a-drawer title="情绪标签" width="60vw" :open="emotionTagOpen" @close="onEmotionTagClose">
<template #footer> <template #footer>
<a-button type="primary" @click="onEmotionTagClose" style="float: right;">关闭</a-button> <a-button type="primary" @click="onEmotionTagClose" style="float: right;">关闭</a-button>
</template> </template>
@ -1165,4 +1165,5 @@ audio::-webkit-media-controls-time-remaining-display {
overflow-y: auto; overflow-y: auto;
} }
} }
</style> </style>

View File

@ -1,187 +1,318 @@
<template> <template>
<a-spin :spinning="confirmLoading"> <a-spin :spinning="confirmLoading">
<JFormContainer :disabled="disabled"> <div style="background-color: #fff;border-radius: 10px;box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);">
<template #detail> <JFormContainer :disabled="disabled">
<a-form ref="formRef" class="antd-modal-form" :labelCol="labelCol" :wrapperCol="wrapperCol" <template #detail>
name="ConfigService2DirectiveForm"> <a-form ref="formRef" class="antd-modal-form" :labelCol="labelCol" :wrapperCol="wrapperCol" :colon="false"
<a-row v-show="!isEditMedia"> name="ConfigService2DirectiveForm" style="padding: 20px 0px;">
<a-col :span="12" v-show="false"> <a-row v-show="!isEditMedia">
<a-form-item label="分类标签" v-bind="validateInfos.instructionTagId" <a-col :span="12" v-show="false">
id="ConfigServiceDirectiveForm-instructionTagId" name="instructionTagId"> <a-form-item label="分类标签" v-bind="validateInfos.instructionTagId"
<j-dict-select-tag v-model:value="formData.instructionTagId" :orgCode="mainOrgCode" id="ConfigServiceDirectiveForm-instructionTagId" name="instructionTagId">
:dictCode="`nu_config_service_instruction_tag,instruction_name,id,del_flag = 0 and iz_enabled = 0 order by sort asc`" <j-dict-select-tag v-model:value="formData.instructionTagId" :orgCode="mainOrgCode"
placeholder="请选择分类标签" allowClear @upDictCode="upInstructionDictCode" :disabled="!!formData.id" /> :dictCode="`nu_config_service_instruction_tag,instruction_name,id,del_flag = 0 and iz_enabled = 0 order by sort asc`"
</a-form-item> placeholder="请选择分类标签" allowClear @upDictCode="upInstructionDictCode" :disabled="!!formData.id" />
</a-col> </a-form-item>
<a-col :span="12" v-show="false"> </a-col>
<a-form-item label="服务类别" v-bind="validateInfos.categoryId" id="ConfigServiceDirectiveForm-categoryId" <a-col :span="12" v-show="false">
name="categoryId"> <a-form-item label="服务类别" v-bind="validateInfos.categoryId" id="ConfigServiceDirectiveForm-categoryId"
<j-dict-select-tag type="list" v-model:value="formData.categoryId" :disabled="!!formData.id" name="categoryId">
:orgCode="mainOrgCode" :dictCode="categoryDictCode" placeholder="请选择服务类别" allow-clear <j-dict-select-tag type="list" v-model:value="formData.categoryId" :disabled="!!formData.id"
@upDictCode="upCategoryDictCode" /> :orgCode="mainOrgCode" :dictCode="categoryDictCode" placeholder="请选择服务类别" allow-clear
</a-form-item> @upDictCode="upCategoryDictCode" />
</a-col> </a-form-item>
<a-col :span="12" v-show="false"> </a-col>
<a-form-item label="服务类型" v-bind="validateInfos.typeId" id="ConfigServiceDirectiveForm-typeId" <a-col :span="12" v-show="false">
name="typeId"> <a-form-item label="服务类型" v-bind="validateInfos.typeId" id="ConfigServiceDirectiveForm-typeId"
<j-dict-select-tag type="list" v-model:value="formData.typeId" :dictCode="typeDictCode" name="typeId">
:orgCode="mainOrgCode" :disabled="!!formData.id" placeholder="请选择服务类型" allowClear <j-dict-select-tag type="list" v-model:value="formData.typeId" :dictCode="typeDictCode"
@upDictCode="upTypeDictCode" /> :orgCode="mainOrgCode" :disabled="!!formData.id" placeholder="请选择服务类型" allowClear
</a-form-item> @upDictCode="upTypeDictCode" />
</a-col> </a-form-item>
<a-col :span="12"> </a-col>
<a-form-item label="服务指令名称" v-bind="validateInfos.directiveName" <a-col :span="12">
id="ConfigServiceDirectiveForm-directiveName" name="directiveName"> <a-form-item label="服务指令名称" v-bind="validateInfos.directiveName"
<a-input v-model:value="formData.directiveName" placeholder="请输入服务指令名称" allow-clear :maxlength="20" id="ConfigServiceDirectiveForm-directiveName" name="directiveName">
:showCount="true" :disabled="!!formData.id"></a-input> <a-input v-model:value="formData.directiveName" placeholder="请输入服务指令名称" allow-clear :maxlength="20"
</a-form-item> :showCount="true" :disabled="!!formData.id"></a-input>
</a-col> </a-form-item>
<a-col :span="12"> </a-col>
<a-form-item label="收费价格(元)" v-bind="validateInfos.tollPrice" id="ConfigServiceDirectiveForm-tollPrice" <a-col :span="12">
name="tollPrice"> <a-form-item label="机构优惠" v-bind="validateInfos.izPreferential"
<a-input-number v-model:value="formData.tollPrice" placeholder="请输入收费价格" style="width: 100%" :min="0" id="ConfigServiceDirectiveForm-izPreferential" name="izPreferential">
:max="99999.99" :precision="2" @keydown="onPriceKeydown" /> <j-dict-select-tag type='radio' v-model:value="formData.izPreferential"
</a-form-item> dictCode="institutional_discount" allowClear />
</a-col> </a-form-item>
<a-col :span="12"> </a-col>
<a-form-item label="提成价格(元)" v-bind="validateInfos.comPrice" id="ConfigServiceDirectiveForm-comPrice" <a-col :span="12">
name="comPrice"> <a-form-item label="周期类型" v-bind="validateInfos.cycleType" id="ConfigServiceDirectiveForm-cycleType"
<a-input-number v-model:value="formData.comPrice" placeholder="请输入提成价格" style="width: 100%" :min="0" name="cycleType">
:max="99999.99" :precision="2" @keydown="onPriceKeydown" /> <j-dict-select-tag type="list" v-model:value="formData.cycleType" dictCode="period_type"
</a-form-item> placeholder="请选择周期类型" allowClear @upDictCode="upCycleTypeDictCode" :disabled="!!formData.id" />
</a-col> </a-form-item>
<a-col :span="12"> </a-col>
<a-form-item label="医保报销" v-bind="validateInfos.izReimbursement" <a-col :span="12">
id="ConfigServiceDirectiveForm-izReimbursement" name="izReimbursement"> <a-form-item label="是否启用" v-bind="validateInfos.izEnabled" id="ConfigServiceDirectiveForm-izEnabled"
<j-dict-select-tag type='radio' v-model:value="formData.izReimbursement" dictCode="med_ins_reimb" name="izEnabled">
allowClear /> <j-dict-select-tag type='radio' v-model:value="formData.izEnabled" dictCode="iz_enabled"
</a-form-item> placeholder="请选择是否启用"  allowClear />
</a-col> </a-form-item>
<a-col :span="12"> </a-col>
<a-form-item label="机构优惠" v-bind="validateInfos.izPreferential" <a-col :span="12">
id="ConfigServiceDirectiveForm-izPreferential" name="izPreferential"> <a-form-item label="收费价格(元)" v-bind="validateInfos.tollPrice" id="ConfigServiceDirectiveForm-tollPrice"
<j-dict-select-tag type='radio' v-model:value="formData.izPreferential" name="tollPrice">
dictCode="institutional_discount" allowClear /> <a-input-number v-model:value="formData.tollPrice" placeholder="请输入收费价格" style="width: 100%" :min="0"
</a-form-item> :max="99999.99" :precision="2" @keydown="onPriceKeydown" />
</a-col> </a-form-item>
<a-col :span="12"> </a-col>
<a-form-item label="周期类型" v-bind="validateInfos.cycleType" id="ConfigServiceDirectiveForm-cycleType" <a-col :span="12">
name="cycleType"> <a-form-item label="医保报销" v-bind="validateInfos.izReimbursement"
<j-dict-select-tag type="list" v-model:value="formData.cycleType" dictCode="period_type" id="ConfigServiceDirectiveForm-izReimbursement" name="izReimbursement">
placeholder="请选择周期类型" allowClear @upDictCode="upCycleTypeDictCode" :disabled="!!formData.id" /> <j-dict-select-tag type='radio' v-model:value="formData.izReimbursement" dictCode="med_ins_reimb"
</a-form-item> allowClear />
</a-col> </a-form-item>
<a-col :span="12"> </a-col>
<a-form-item label="服务时长(分钟)" v-bind="validateInfos.serviceDuration" <a-col :span="12">
id="ConfigServiceDirectiveForm-serviceDuration" name="serviceDuration"> <a-form-item label="提成价格(元)" v-bind="validateInfos.comPrice" id="ConfigServiceDirectiveForm-comPrice"
<a-input-number v-model:value="formData.serviceDuration" :min="5" :max="55" :step="5" name="comPrice">
placeholder="请输入服务时长(分钟)" allow-clear /> <a-input-number v-model:value="formData.comPrice" placeholder="请输入提成价格" style="width: 100%" :min="0"
</a-form-item> :max="99999.99" :precision="2" @keydown="onPriceKeydown" />
</a-col> </a-form-item>
</a-row> </a-col>
<a-row v-show="!isEditMedia"> <a-col :span="12">
<a-col :span="24"> <a-form-item label="服务时长" v-bind="validateInfos.serviceDuration"
<a-form-item label="体型标签" id="ConfigServiceDirectiveForm-typeId" :labelCol="labelCol2" id="ConfigServiceDirectiveForm-serviceDuration" name="serviceDuration">
:wrapperCol="wrapperCol2" name="typeId"> <a-input-number v-model:value="formData.serviceDuration" :min="5" :max="55" :step="5" addon-after="分钟"
<span v-if="disabled && !formData.bodyTags">-</span> placeholder="请输入服务时长(分钟)" allow-clear @keydown="onDurationKeydown" />
<JCheckbox v-else v-model:value="formData.bodyTags" :orgCode="mainOrgCode" :dictCode="bodyTagDictCode" </a-form-item>
@upDictCode="upBodyTagsDictCode" /> </a-col>
</a-form-item> </a-row>
</a-col> <a-row v-show="!isEditMedia"
<a-col :span="24"> style="background-color: #f6faff ; border-top: 1px solid #F0F0F0;border-bottom: 1px solid #F0F0F0;">
<a-form-item label="情绪标签" :labelCol="labelCol2" :wrapperCol="wrapperCol2" name="emoTags"> <a-col :span="12" style="border-right: 1px solid #F0F0F0;padding-top: 20px;">
<span v-if="disabled && !formData.emotionTags">-</span> <a-form-item label="体型标签" id="ConfigServiceDirectiveForm-typeId" name="typeId">
<JCheckbox v-else v-model:value="formData.emotionTags" :orgCode="mainOrgCode" <span v-if="disabled && !formData.bodyTags">-</span>
:dictCode="emotionTagDictCode" @upDictCode="upEmotionTagsDictCode" /> <JCheckbox v-else v-model:value="formData.bodyTags" :orgCode="mainOrgCode" :dictCode="bodyTagDictCode"
</a-form-item> @upDictCode="upBodyTagsDictCode" />
</a-col> </a-form-item>
<a-col :span="12"> </a-col>
<a-form-item label="是否启用" v-bind="validateInfos.izEnabled" id="ConfigServiceDirectiveForm-izEnabled" <a-col :span="12" style="padding-top: 20px;">
name="izEnabled"> <a-form-item label="情绪标签" name="emoTags">
<j-dict-select-tag type='radio' v-model:value="formData.izEnabled" dictCode="iz_enabled" <span v-if="disabled && !formData.emotionTags">-</span>
placeholder="请选择是否启用"  allowClear /> <JCheckbox v-else v-model:value="formData.emotionTags" :orgCode="mainOrgCode"
</a-form-item> :dictCode="emotionTagDictCode" @upDictCode="upEmotionTagsDictCode" />
</a-col> </a-form-item>
</a-row> </a-col>
<a-row> </a-row>
<a-col :span="12" v-show="showMedia"> <a-row style="padding: 20px;">
<a-form-item label="服务指令图片" v-bind="validateInfos.previewFile"> <a-col :span="6">
<span v-if="disabled && !formData.previewFile">暂无文件</span> <DirectiveRadioCom :directiveMediaBtnValue="directiveMediaBtnValue" @change="mediaBtnChanged">
<JImageUpload v-else-if="opeType == 'dmlook'" :fileMax="1" </DirectiveRadioCom>
:value="mediaApiAddress + formData.previewFile"> </a-col>
</JImageUpload> </a-row>
<JImageUpload v-else :fileMax="1" v-model:value="formData.previewFile"></JImageUpload> <a-row style="padding: 0px 20px;">
</a-form-item> <a-col :span="24" v-show="directiveMediaBtnValue == 0">
</a-col> <a-upload-dragger name="file" v-model:fileList="fileList" :multiple="false" :show-upload-list="false"
<a-col :span="12"> :before-upload="beforeUpload" style="background-color: #F6FAFF;">
<a-form-item label="服务指令描述" v-bind="validateInfos.serviceContent" <div class="upload-area">
id="ConfigServiceDirectiveForm-serviceContent" name="serviceContent"> <p class="upload-text">点击或者拖拽上传</p>
<a-textarea v-model:value="formData.serviceContent" :autosize="true" placeholder="请输入服务指令描述" <div class="upload-icon">
:maxlength="200" :showCount="true" /> <img src="./pictype.png" alt="MP3 icon" style="width: 40px; height: 40px;" />
</a-form-item> </div>
</a-col> <p class="upload-hint">
</a-row> <span>文件大小不超过10MB</span>
<a-row v-show="!disabled && showMedia"> <span class="divider">|</span>
<a-col :span="12"> <a-tooltip placement="top">
<a-form-item label="指令音频文件" v-bind="validateInfos.mp3File" id="ConfigServiceDirectiveForm-mp3File"> <template #title>
<j-upload v-model:value="formData.mp3File" accept=".mp3" :maxCount="1"></j-upload> 这里是格式说明的具体内容
</a-form-item> </template>
</a-col> <span>
<a-col :span="12"> <QuestionCircleOutlined style="margin-right: 0px;" />
<a-form-item label="指令视频文件" v-bind="validateInfos.mp4File" id="ConfigServiceDirectiveForm-mp4File"> 格式说明
<j-upload v-model:value="formData.mp4File" accept=".mp4" :maxCount="1"></j-upload> </span>
</a-form-item> </a-tooltip>
</a-col> </p>
</a-row> </div>
</a-form> </a-upload-dragger>
</template> </a-col>
</JFormContainer> <a-col :span="24" v-show="directiveMediaBtnValue == 1">
<JFormContainer style="margin-top: -40px;" v-show="showMedia"> <a-upload-dragger name="file" v-model:fileList="fileList" :multiple="false" :show-upload-list="false"
<template #detail> :before-upload="beforeUpload" style="background-color: #F6FAFF;">
<a-form ref="formRef" class="antd-modal-form" :labelCol="labelCol" :wrapperCol="wrapperCol" <div class="upload-area">
name="ConfigServiceDirectiveForm"> <p class="upload-text">点击或者拖拽上传</p>
<a-row> <div class="upload-icon">
<a-col :span="12" v-if="!!formData.mp3File"> <img src="./mp3type.png" alt="MP3 icon" style="width: 40px; height: 40px;" />
<a-form-item label="指令音频预览" id="ConfigServiceDirectiveForm-mp3File"> </div>
<audio controls disabled="false"> <p class="upload-hint">
<source <span>文件大小不超过10MB</span>
:src="opeType == 'dmlook' ? mediaApiAddress + formData.mp3File : getFileAccessHttpUrl(formData.mp3File)"> <span class="divider">|</span>
</audio> <a-tooltip placement="top">
</a-form-item> <template #title>
</a-col> 这里是格式说明的具体内容
<a-col :span="12" v-if="disabled && !formData.mp3File"> </template>
<a-form-item label="指令音频预览"> <span>
<span>暂无文件</span> <QuestionCircleOutlined style="margin-right: 0px;" />
</a-form-item> 格式说明
</a-col> </span>
<a-col :span="12" v-if="!!formData.mp4File" :push="!!formData.mp3File ? 0 : 12"> </a-tooltip>
<a-form-item label="指令视频预览" id="ConfigServiceDirectiveForm-mp4File"> </p>
<video controls> </div>
<source </a-upload-dragger>
:src="opeType == 'dmlook' ? mediaApiAddress + formData.mp4File : getFileAccessHttpUrl(formData.mp4File)"> </a-col>
</video> <a-col :span="24" v-show="directiveMediaBtnValue == 2">
</a-form-item> <a-upload-dragger name="file" v-model:fileList="fileList" :multiple="false" :show-upload-list="false"
</a-col> :before-upload="beforeUpload" style="background-color: #F6FAFF;">
<a-col :span="12" v-if="disabled && !formData.mp3File"> <div class="upload-area">
<a-form-item label="指令视频预览"> <p class="upload-text">点击或者拖拽上传</p>
<span>暂无文件</span> <div class="upload-icon">
</a-form-item> <img src="./mp4type.png" alt="MP3 icon" style="width: 40px; height: 40px;" />
</a-col> </div>
</a-row> <p class="upload-hint">
<a-row> <span>文件大小不超过10MB</span>
<a-col :span="12"> <span class="divider">|</span>
<a-form-item label="即时指令图标" v-bind="validateInfos.immediateFile"> <a-tooltip placement="top">
<span v-if="disabled && !formData.immediateFile">暂无文件</span> <template #title>
<JImageUpload v-else-if="opeType == 'dmlook'" :fileMax="1" 这里是格式说明的具体内容
:value="mediaApiAddress + formData.immediateFile"> </template>
</JImageUpload> <span>
<JImageUpload v-else :fileMax="1" v-model:value="formData.immediateFile"></JImageUpload> <QuestionCircleOutlined style="margin-right: 0px;" />
</a-form-item> 格式说明
</a-col> </span>
</a-row> </a-tooltip>
</a-form> </p>
</template> </div>
</JFormContainer> </a-upload-dragger>
</a-col>
<a-col :span="24" v-show="directiveMediaBtnValue == 3">
<a-upload-dragger name="file" v-model:fileList="fileList" :multiple="false" :show-upload-list="false"
:before-upload="beforeUpload" style="background-color: #F6FAFF;">
<div class="upload-area">
<p class="upload-text">点击或者拖拽上传</p>
<div class="upload-icon">
<img src="./pictype.png" alt="MP3 icon" style="width: 40px; height: 40px;" />
</div>
<p class="upload-hint">
<span>文件大小不超过10MB</span>
<span class="divider">|</span>
<a-tooltip placement="top">
<template #title>
这里是格式说明的具体内容
</template>
<span>
<QuestionCircleOutlined style="margin-right: 0px;" />
格式说明
</span>
</a-tooltip>
</p>
</div>
</a-upload-dragger>
</a-col>
</a-row>
<a-row style="padding: 20px;">
<a-col :span="2">
<!-- 相对定位的容器 -->
<div class="description-container">
<a-button @click="toggleDescription">服务指令描述</a-button>
<div v-show="showDescription" class="description-box">
<div class="box-header">
<span class="title">服务指令描述</span>
<span class="collapse-icon" @click="toggleDescription">
<DownOutlined style="margin-right: 3px;" />收起
</span>
</div>
<div>
<a-textarea v-model:value="formData.serviceContent" placeholder="请输入服务指令描述" :maxlength="200"
:rows="3" :autosize="{ minRows: 3 }" :showCount="true" />
</div>
<!-- <div style="margin-top: 60px;">
<a-button type="primary" class="confirm-btn">确认</a-button>
</div> -->
</div>
</div>
</a-col>
</a-row>
<a-row style="margin-top: 20px;">
<a-col :span="12" v-show="showMedia">
<a-form-item label="服务指令图片" v-bind="validateInfos.previewFile">
<span v-if="disabled && !formData.previewFile">暂无文件</span>
<JImageUpload v-else-if="opeType == 'dmlook'" :fileMax="1"
:value="mediaApiAddress + formData.previewFile">
</JImageUpload>
<JImageUpload v-else :fileMax="1" v-model:value="formData.previewFile"></JImageUpload>
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="服务指令描述" v-bind="validateInfos.serviceContent"
id="ConfigServiceDirectiveForm-serviceContent" name="serviceContent">
<a-textarea v-model:value="formData.serviceContent" :autosize="true" placeholder="请输入服务指令描述"
:maxlength="200" :showCount="true" />
</a-form-item>
</a-col>
</a-row>
<a-row v-show="!disabled && showMedia">
<a-col :span="12">
<a-form-item label="指令音频文件" v-bind="validateInfos.mp3File" id="ConfigServiceDirectiveForm-mp3File">
<j-upload v-model:value="formData.mp3File" accept=".mp3" :maxCount="1"
:beforeUpload="checkMp3"></j-upload>
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="指令视频文件" v-bind="validateInfos.mp4File" id="ConfigServiceDirectiveForm-mp4File">
<j-upload v-model:value="formData.mp4File" accept=".mp4" :maxCount="1"
:beforeUpload="checkMp4"></j-upload>
</a-form-item>
</a-col>
</a-row>
</a-form>
</template>
</JFormContainer>
<JFormContainer style="margin-top: -40px;" v-show="showMedia">
<template #detail>
<a-form ref="formRef" class="antd-modal-form" :labelCol="labelCol" :wrapperCol="wrapperCol" :colon="false"
name="ConfigServiceDirectiveForm">
<a-row>
<a-col :span="12" v-if="!!formData.mp3File">
<a-form-item label="指令音频预览" id="ConfigServiceDirectiveForm-mp3File">
<audio controls disabled="false">
<source
:src="opeType == 'dmlook' ? mediaApiAddress + formData.mp3File : getFileAccessHttpUrl(formData.mp3File)">
</audio>
</a-form-item>
</a-col>
<a-col :span="12" v-if="disabled && !formData.mp3File">
<a-form-item label="指令音频预览">
<span>暂无文件</span>
</a-form-item>
</a-col>
<a-col :span="12" v-if="!!formData.mp4File" :push="!!formData.mp3File ? 0 : 12">
<a-form-item label="指令视频预览" id="ConfigServiceDirectiveForm-mp4File">
<video controls>
<source
:src="opeType == 'dmlook' ? mediaApiAddress + formData.mp4File : getFileAccessHttpUrl(formData.mp4File)">
</video>
</a-form-item>
</a-col>
<a-col :span="12" v-if="disabled && !formData.mp3File">
<a-form-item label="指令视频预览">
<span>暂无文件</span>
</a-form-item>
</a-col>
</a-row>
<a-row>
<a-col :span="12">
<a-form-item label="即时指令图标" v-bind="validateInfos.immediateFile">
<span v-if="disabled && !formData.immediateFile">暂无文件</span>
<JImageUpload v-else-if="opeType == 'dmlook'" :fileMax="1"
:value="mediaApiAddress + formData.immediateFile">
</JImageUpload>
<JImageUpload v-else :fileMax="1" v-model:value="formData.immediateFile"></JImageUpload>
</a-form-item>
</a-col>
</a-row>
</a-form>
</template>
</JFormContainer>
</div>
</a-spin> </a-spin>
</template> </template>
@ -199,7 +330,17 @@ import { Form } from 'ant-design-vue';
import JFormContainer from '/@/components/Form/src/container/JFormContainer.vue'; import JFormContainer from '/@/components/Form/src/container/JFormContainer.vue';
import { getFileAccessHttpUrl } from '/@/utils/common/compUtils'; import { getFileAccessHttpUrl } from '/@/utils/common/compUtils';
import { env } from 'process'; import { env } from 'process';
import DirectiveRadioCom from './DirectiveRadioCom.vue'
import { QuestionCircleOutlined } from '@ant-design/icons-vue';
import { DownOutlined } from '@ant-design/icons-vue';
const showDescription = ref(false);
//
const toggleDescription = () => {
showDescription.value = !showDescription.value;
};
const fileList = ref([])
const onPriceKeydown = (e: KeyboardEvent) => { const onPriceKeydown = (e: KeyboardEvent) => {
const key = e.key; const key = e.key;
// //
@ -217,6 +358,25 @@ const onPriceKeydown = (e: KeyboardEvent) => {
e.preventDefault(); e.preventDefault();
} }
}; };
const onDurationKeydown = (e: KeyboardEvent) => {
const key = e.key;
//
if (['Backspace', 'Delete', 'ArrowLeft', 'ArrowRight', 'Tab'].includes(key)) return;
//
if (!/[\d.]/.test(key)) {
e.preventDefault();
return;
}
const input = e.target as HTMLInputElement;
const { value, selectionStart: s, selectionEnd: t } = input;
const next = value.slice(0, s!) + key + value.slice(t!);
// 52
if (!/^\d{0,2}$/.test(next)) {
e.preventDefault();
}
};
const props = defineProps({ const props = defineProps({
formDisabled: { type: Boolean, default: false }, formDisabled: { type: Boolean, default: false },
formData: { type: Object, default: () => ({}) }, formData: { type: Object, default: () => ({}) },
@ -225,7 +385,22 @@ const props = defineProps({
mediaApiAddress: '',// mediaApiAddress: '',//
opeType: 'look', opeType: 'look',
}); });
const checkMp3 = (file) => {
const isPDF = file.type === 'application/mp3' || file.name.endsWith('.mp3');
if (!isPDF) {
createMessage.error('只能上传 mp3 文件!');
return false; //
}
return true;
};
const checkMp4 = (file) => {
const isPDF = file.type === 'application/mp4' || file.name.endsWith('.mp4');
if (!isPDF) {
createMessage.error('只能上传 PDF mp4');
return false; //
}
return true;
};
const bodyTagDictCode = ref(`nu_config_body_tag,tag_name,id,del_flag = 0 and iz_enabled = 0 order by sort asc`) const bodyTagDictCode = ref(`nu_config_body_tag,tag_name,id,del_flag = 0 and iz_enabled = 0 order by sort asc`)
const emotionTagDictCode = ref(`nu_config_emotion_tag,tag_name,id,del_flag = 0 and iz_enabled = 0 order by sort asc`) const emotionTagDictCode = ref(`nu_config_emotion_tag,tag_name,id,del_flag = 0 and iz_enabled = 0 order by sort asc`)
const formRef = ref(); const formRef = ref();
@ -258,10 +433,8 @@ const formData = reactive<Record<string, any>>({
immediateFile: '', immediateFile: '',
}); });
const { createMessage } = useMessage(); const { createMessage } = useMessage();
const labelCol = ref<any>({ xs: { span: 24 }, sm: { span: 6 } }); const labelCol = ref<any>({ xs: { span: 24 }, sm: { span: 5 } });
const wrapperCol = ref<any>({ xs: { span: 24 }, sm: { span: 16 } }); const wrapperCol = ref<any>({ xs: { span: 24 }, sm: { span: 19 } });
const labelCol2 = ref<any>({ xs: { span: 24 }, sm: { span: 3 } });
const wrapperCol2 = ref<any>({ xs: { span: 24 }, sm: { span: 20 } });
const confirmLoading = ref<boolean>(false); const confirmLoading = ref<boolean>(false);
const isEditMedia = ref(false) const isEditMedia = ref(false)
const instructionTagName = ref('') const instructionTagName = ref('')
@ -578,6 +751,12 @@ function syncMediaForAllBizFunc() {
}); });
} }
const directiveMediaBtnValue = ref(0)
function mediaBtnChanged(v_) {
directiveMediaBtnValue.value = v_
}
onMounted(() => { onMounted(() => {
}) })
@ -595,4 +774,119 @@ defineExpose({
.antd-modal-form { .antd-modal-form {
padding: 14px; padding: 14px;
} }
</style>
:deep .ant-checkbox-wrapper {
margin-top: 5px;
margin-bottom: 10px;
width: 30%;
}
.upload-area {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.upload-icon {
margin-bottom: 16px;
}
.upload-text {
font-size: 16px;
color: rgba(0, 0, 0, 0.85);
margin-bottom: 8px;
}
.upload-hint {
font-size: 12px;
color: rgba(0, 0, 0, 0.45);
display: flex;
align-items: center;
gap: 8px;
}
.divider {
color: rgba(0, 0, 0, 0.2);
}
.description-container {
position: relative;
z-index: 1000;
}
.description-box {
position: absolute;
bottom: 100%;
left: 0;
background: #f6faff;
border-radius: 4px;
padding: 12px;
width: 43vw;
box-shadow: 0 3px 10px rgba(0, 0, 0, 0.1);
margin-bottom: 8px;
}
.box-header {
display: flex;
justify-content: space-between;
align-items: center;
padding-bottom: 8px;
margin-bottom: 12px;
}
.title {
font-weight: bold;
font-size: 16px;
}
.collapse-icon {
color: #1890ff;
cursor: pointer;
}
.content {
background: #fff;
border-radius: 4px;
padding: 12px;
position: relative;
}
.instruction {
color: #8c8c8c;
margin-bottom: 30px;
}
.confirm-btn {
position: absolute;
right: 12px;
bottom: 12px;
background: #1890ff;
border-radius: 20px;
}
/* 渐隐渐现动画 */
.slide-fade-enter-active {
transition: opacity 0.3s ease-out;
}
.slide-fade-leave-active {
transition: opacity 0.3s cubic-bezier(0.5, 0, 0.8, 1);
}
/* 进入时从透明开始 */
.slide-fade-enter-from {
opacity: 0;
}
/* 离开时渐变到透明 */
.slide-fade-leave-to {
opacity: 0;
}
/* 确保容器初始状态无变形 */
.slide-fade-enter-to,
.slide-fade-leave-from {
opacity: 1;
}
</style>

View File

@ -15,8 +15,8 @@
:formBpm="false" :mainOrgCode="mainOrgCode"></ConfigServiceDirectiveForm> :formBpm="false" :mainOrgCode="mainOrgCode"></ConfigServiceDirectiveForm>
</a-spin> </a-spin>
</j-modal> --> </j-modal> -->
<a-drawer :title="title" width="70vw" v-model:visible="visible" :closable="true" <a-drawer :title="title" width="80vw" v-model:visible="visible" :closable="true"
:footer-style="{ textAlign: 'right' }" @close="handleCancel"> :footer-style="{ textAlign: 'right' }" @close="handleCancel" :bodyStyle="{ background: 'linear-gradient(135deg, #f1f7ff 0%, #f1f7ff 100%)' }">
<a-spin :spinning="loading"> <a-spin :spinning="loading">
<ConfigServiceDirectiveForm ref="registerForm" v-if="visible" @ok="submitCallback" :formDisabled="disableSubmit" <ConfigServiceDirectiveForm ref="registerForm" v-if="visible" @ok="submitCallback" :formDisabled="disableSubmit"
:formBpm="false" :mainOrgCode="mainOrgCode" :mediaApiAddress="mediaApiAddress" :opeType="opeType"> :formBpm="false" :mainOrgCode="mainOrgCode" :mediaApiAddress="mediaApiAddress" :opeType="opeType">
@ -273,4 +273,5 @@ defineExpose({
display: none !important; display: none !important;
} }
</style> </style>
<style lang="less" scoped></style> <style lang="less" scoped>
</style>

View File

@ -0,0 +1,105 @@
<template>
<div class="tab-container" :class="{ compact }">
<div
v-for="(tab, index) in tabs"
:key="index"
class="tab-item"
:class="{ active: activeTab === index }"
@click="handleTabClick(index)"
>
<span class="tab-text">{{ tab }}</span>
<div v-if="index < tabs.length - 1" class="tab-divider"></div>
</div>
</div>
</template>
<script setup>
import { ref, watch } from 'vue'
const props = defineProps({
directiveMediaBtnValue: {
type: Number,
default: 0
},
compact: {
type: Boolean,
default: false
}
})
const emit = defineEmits(['update:directiveMediaBtnValue', 'change'])
const tabs = ['服务指令图片', '指令音频文件', '指令视频文件', '即时指令图标']
const activeTab = ref(props.directiveMediaBtnValue)
watch(() => props.directiveMediaBtnValue, (newVal) => {
activeTab.value = newVal
})
const handleTabClick = (index) => {
activeTab.value = index
emit('update:directiveMediaBtnValue', index)
emit('change', index)
}
</script>
<style scoped>
.tab-container {
display: inline-flex;
background-color: #f1f7ff;
padding: 4px;
border-radius: 8px;
white-space: nowrap;
}
.tab-item {
position: relative;
padding: 6px 12px;
cursor: pointer;
color: #666;
font-size: 13px;
transition: all 0.3s ease;
display: flex;
align-items: center;
}
.tab-text {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 100px;
}
.tab-item:hover {
background-color: rgba(255, 255, 255, 0.5);
}
.tab-item.active {
background-color: #fff;
color: #333;
font-weight: 500;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
border-radius: 4px;
z-index: 1;
}
/* .tab-divider {
position: absolute;
right: 0;
top: 20%;
height: 60%;
width: 1px;
background-color: rgba(0, 0, 0, 0.1);
z-index: 2;
} */
/* 紧凑模式 */
.tab-container.compact .tab-item {
padding: 4px 8px;
font-size: 12px;
}
.tab-container.compact .tab-text {
max-width: 80px;
}
</style>

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB