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

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=
#微前端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将以乾坤子应用模式启动
#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=
#微前端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将以乾坤子应用模式启动
#VITE_GLOB_QIANKUN_MICRO_APP_NAME=jeecg-vue3

View File

@ -2,7 +2,7 @@
VITE_USE_MOCK = false
# 发布路径
VITE_PUBLIC_PATH = /biz103
VITE_PUBLIC_PATH = /biz101
# 是否启用gzip或brotli压缩
# 选项值: gzip | brotli | none
@ -13,10 +13,10 @@ VITE_BUILD_COMPRESS = 'gzip'
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=

View File

@ -101,5 +101,9 @@
img {
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,
pagination: {
current: 1,
pageSize: 50,
pageSizeOptions: ['50', '70', '100'],
pageSize: 15,
pageSizeOptions: ['15','50', '70', '100'],
},
actionColumn: {
width: 160,

View File

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

View File

@ -73,7 +73,7 @@
</a-form>
</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
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">
@ -89,8 +89,8 @@
<a-empty v-if="!treeLoading && treeLoading" />
<a-button v-if="!treeLoading && treeData.length < 1" type="link" class="btnPrivate" @click="addInstruction"
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"
expandAction="click" @select="handleTreeSelect">
<a-tree style="padding-top: 40px;min-height:80vh;" v-if="!treeLoading && treeData.length > 0"
:tree-data="treeData" v-model:expandedKeys="expandedKeys" expandAction="click" @select="handleTreeSelect">
<template #title="{ data }">
<!-- @click.stop="openMenu(data, data.children, $event)" -->
<!-- @contextmenu.prevent="openMenu(data, data.children, $event)" -->
@ -109,7 +109,7 @@
<template #overlay>
<a-menu>
<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>
<span style=" color:#1890FF;margin-left: 5px;">{{ item.label }}</span>
</a-menu-item>
@ -1165,4 +1165,5 @@ audio::-webkit-media-controls-time-remaining-display {
overflow-y: auto;
}
}
</style>

View File

@ -1,9 +1,10 @@
<template>
<a-spin :spinning="confirmLoading">
<div style="background-color: #fff;border-radius: 10px;box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);">
<JFormContainer :disabled="disabled">
<template #detail>
<a-form ref="formRef" class="antd-modal-form" :labelCol="labelCol" :wrapperCol="wrapperCol"
name="ConfigService2DirectiveForm">
<a-form ref="formRef" class="antd-modal-form" :labelCol="labelCol" :wrapperCol="wrapperCol" :colon="false"
name="ConfigService2DirectiveForm" style="padding: 20px 0px;">
<a-row v-show="!isEditMedia">
<a-col :span="12" v-show="false">
<a-form-item label="分类标签" v-bind="validateInfos.instructionTagId"
@ -36,27 +37,6 @@
:showCount="true" :disabled="!!formData.id"></a-input>
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="收费价格(元)" v-bind="validateInfos.tollPrice" id="ConfigServiceDirectiveForm-tollPrice"
name="tollPrice">
<a-input-number v-model:value="formData.tollPrice" placeholder="请输入收费价格" style="width: 100%" :min="0"
:max="99999.99" :precision="2" @keydown="onPriceKeydown" />
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="提成价格(元)" v-bind="validateInfos.comPrice" id="ConfigServiceDirectiveForm-comPrice"
name="comPrice">
<a-input-number v-model:value="formData.comPrice" placeholder="请输入提成价格" style="width: 100%" :min="0"
:max="99999.99" :precision="2" @keydown="onPriceKeydown" />
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="医保报销" v-bind="validateInfos.izReimbursement"
id="ConfigServiceDirectiveForm-izReimbursement" name="izReimbursement">
<j-dict-select-tag type='radio' v-model:value="formData.izReimbursement" dictCode="med_ins_reimb"
allowClear />
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="机构优惠" v-bind="validateInfos.izPreferential"
id="ConfigServiceDirectiveForm-izPreferential" name="izPreferential">
@ -71,30 +51,6 @@
placeholder="请选择周期类型" allowClear @upDictCode="upCycleTypeDictCode" :disabled="!!formData.id" />
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="服务时长(分钟)" v-bind="validateInfos.serviceDuration"
id="ConfigServiceDirectiveForm-serviceDuration" name="serviceDuration">
<a-input-number v-model:value="formData.serviceDuration" :min="5" :max="55" :step="5"
placeholder="请输入服务时长(分钟)" allow-clear />
</a-form-item>
</a-col>
</a-row>
<a-row v-show="!isEditMedia">
<a-col :span="24">
<a-form-item label="体型标签" id="ConfigServiceDirectiveForm-typeId" :labelCol="labelCol2"
:wrapperCol="wrapperCol2" name="typeId">
<span v-if="disabled && !formData.bodyTags">-</span>
<JCheckbox v-else v-model:value="formData.bodyTags" :orgCode="mainOrgCode" :dictCode="bodyTagDictCode"
@upDictCode="upBodyTagsDictCode" />
</a-form-item>
</a-col>
<a-col :span="24">
<a-form-item label="情绪标签" :labelCol="labelCol2" :wrapperCol="wrapperCol2" name="emoTags">
<span v-if="disabled && !formData.emotionTags">-</span>
<JCheckbox v-else v-model:value="formData.emotionTags" :orgCode="mainOrgCode"
:dictCode="emotionTagDictCode" @upDictCode="upEmotionTagsDictCode" />
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="是否启用" v-bind="validateInfos.izEnabled" id="ConfigServiceDirectiveForm-izEnabled"
name="izEnabled">
@ -102,8 +58,180 @@
placeholder="请选择是否启用"  allowClear />
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="收费价格(元)" v-bind="validateInfos.tollPrice" id="ConfigServiceDirectiveForm-tollPrice"
name="tollPrice">
<a-input-number v-model:value="formData.tollPrice" placeholder="请输入收费价格" style="width: 100%" :min="0"
:max="99999.99" :precision="2" @keydown="onPriceKeydown" />
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="医保报销" v-bind="validateInfos.izReimbursement"
id="ConfigServiceDirectiveForm-izReimbursement" name="izReimbursement">
<j-dict-select-tag type='radio' v-model:value="formData.izReimbursement" dictCode="med_ins_reimb"
allowClear />
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="提成价格(元)" v-bind="validateInfos.comPrice" id="ConfigServiceDirectiveForm-comPrice"
name="comPrice">
<a-input-number v-model:value="formData.comPrice" placeholder="请输入提成价格" style="width: 100%" :min="0"
:max="99999.99" :precision="2" @keydown="onPriceKeydown" />
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="服务时长" v-bind="validateInfos.serviceDuration"
id="ConfigServiceDirectiveForm-serviceDuration" name="serviceDuration">
<a-input-number v-model:value="formData.serviceDuration" :min="5" :max="55" :step="5" addon-after="分钟"
placeholder="请输入服务时长(分钟)" allow-clear @keydown="onDurationKeydown" />
</a-form-item>
</a-col>
</a-row>
<a-row>
<a-row v-show="!isEditMedia"
style="background-color: #f6faff ; border-top: 1px solid #F0F0F0;border-bottom: 1px solid #F0F0F0;">
<a-col :span="12" style="border-right: 1px solid #F0F0F0;padding-top: 20px;">
<a-form-item label="体型标签" id="ConfigServiceDirectiveForm-typeId" name="typeId">
<span v-if="disabled && !formData.bodyTags">-</span>
<JCheckbox v-else v-model:value="formData.bodyTags" :orgCode="mainOrgCode" :dictCode="bodyTagDictCode"
@upDictCode="upBodyTagsDictCode" />
</a-form-item>
</a-col>
<a-col :span="12" style="padding-top: 20px;">
<a-form-item label="情绪标签" name="emoTags">
<span v-if="disabled && !formData.emotionTags">-</span>
<JCheckbox v-else v-model:value="formData.emotionTags" :orgCode="mainOrgCode"
:dictCode="emotionTagDictCode" @upDictCode="upEmotionTagsDictCode" />
</a-form-item>
</a-col>
</a-row>
<a-row style="padding: 20px;">
<a-col :span="6">
<DirectiveRadioCom :directiveMediaBtnValue="directiveMediaBtnValue" @change="mediaBtnChanged">
</DirectiveRadioCom>
</a-col>
</a-row>
<a-row style="padding: 0px 20px;">
<a-col :span="24" v-show="directiveMediaBtnValue == 0">
<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-col :span="24" v-show="directiveMediaBtnValue == 1">
<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="./mp3type.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-col :span="24" v-show="directiveMediaBtnValue == 2">
<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="./mp4type.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-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>
@ -124,12 +252,14 @@
<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"></j-upload>
<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"></j-upload>
<j-upload v-model:value="formData.mp4File" accept=".mp4" :maxCount="1"
:beforeUpload="checkMp4"></j-upload>
</a-form-item>
</a-col>
</a-row>
@ -138,7 +268,7 @@
</JFormContainer>
<JFormContainer style="margin-top: -40px;" v-show="showMedia">
<template #detail>
<a-form ref="formRef" class="antd-modal-form" :labelCol="labelCol" :wrapperCol="wrapperCol"
<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">
@ -182,6 +312,7 @@
</a-form>
</template>
</JFormContainer>
</div>
</a-spin>
</template>
@ -199,7 +330,17 @@ import { Form } from 'ant-design-vue';
import JFormContainer from '/@/components/Form/src/container/JFormContainer.vue';
import { getFileAccessHttpUrl } from '/@/utils/common/compUtils';
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 key = e.key;
//
@ -217,6 +358,25 @@ const onPriceKeydown = (e: KeyboardEvent) => {
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({
formDisabled: { type: Boolean, default: false },
formData: { type: Object, default: () => ({}) },
@ -225,7 +385,22 @@ const props = defineProps({
mediaApiAddress: '',//
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 emotionTagDictCode = ref(`nu_config_emotion_tag,tag_name,id,del_flag = 0 and iz_enabled = 0 order by sort asc`)
const formRef = ref();
@ -258,10 +433,8 @@ const formData = reactive<Record<string, any>>({
immediateFile: '',
});
const { createMessage } = useMessage();
const labelCol = ref<any>({ xs: { span: 24 }, sm: { span: 6 } });
const wrapperCol = ref<any>({ xs: { span: 24 }, sm: { span: 16 } });
const labelCol2 = ref<any>({ xs: { span: 24 }, sm: { span: 3 } });
const wrapperCol2 = ref<any>({ xs: { span: 24 }, sm: { span: 20 } });
const labelCol = ref<any>({ xs: { span: 24 }, sm: { span: 5 } });
const wrapperCol = ref<any>({ xs: { span: 24 }, sm: { span: 19 } });
const confirmLoading = ref<boolean>(false);
const isEditMedia = ref(false)
const instructionTagName = ref('')
@ -578,6 +751,12 @@ function syncMediaForAllBizFunc() {
});
}
const directiveMediaBtnValue = ref(0)
function mediaBtnChanged(v_) {
directiveMediaBtnValue.value = v_
}
onMounted(() => {
})
@ -595,4 +774,119 @@ defineExpose({
.antd-modal-form {
padding: 14px;
}
: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>
</a-spin>
</j-modal> -->
<a-drawer :title="title" width="70vw" v-model:visible="visible" :closable="true"
:footer-style="{ textAlign: 'right' }" @close="handleCancel">
<a-drawer :title="title" width="80vw" v-model:visible="visible" :closable="true"
:footer-style="{ textAlign: 'right' }" @close="handleCancel" :bodyStyle="{ background: 'linear-gradient(135deg, #f1f7ff 0%, #f1f7ff 100%)' }">
<a-spin :spinning="loading">
<ConfigServiceDirectiveForm ref="registerForm" v-if="visible" @ok="submitCallback" :formDisabled="disableSubmit"
:formBpm="false" :mainOrgCode="mainOrgCode" :mediaApiAddress="mediaApiAddress" :opeType="opeType">
@ -273,4 +273,5 @@ defineExpose({
display: none !important;
}
</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