feat: 更新机器人图片设置模态框,重命名图片标签为自定义图片,移除激活状态图片设置,优化图片上传和删除逻辑,增强用户交互体验
This commit is contained in:
parent
689ecb4f0c
commit
874c3fade3
@ -31,8 +31,8 @@
|
||||
<div v-if="selectedRobot" class="image-settings-section">
|
||||
<a-divider>图片设置</a-divider>
|
||||
|
||||
<!-- 普通状态图片 -->
|
||||
<a-form-item label="普通状态图片">
|
||||
<!-- 自定义图片 -->
|
||||
<a-form-item label="自定义图片">
|
||||
<div class="image-upload-container">
|
||||
<a-upload
|
||||
:file-list="[]"
|
||||
@ -44,12 +44,12 @@
|
||||
<template #icon>
|
||||
<UploadOutlined />
|
||||
</template>
|
||||
选择普通状态图片
|
||||
选择自定义图片
|
||||
</a-button>
|
||||
</a-upload>
|
||||
|
||||
<div v-if="formData.images.normal" class="image-preview">
|
||||
<img :src="formData.images.normal" alt="普通状态" />
|
||||
<img :src="formData.images.normal" alt="自定义图片" />
|
||||
<div class="image-actions">
|
||||
<a-button size="small" @click="removeImage('normal')">删除</a-button>
|
||||
</div>
|
||||
@ -57,63 +57,11 @@
|
||||
</div>
|
||||
</a-form-item>
|
||||
|
||||
<!-- 激活状态图片 -->
|
||||
<a-form-item label="激活状态图片">
|
||||
<div class="image-upload-container">
|
||||
<a-upload
|
||||
:file-list="[]"
|
||||
:before-upload="(file) => handleImageUpload(file, 'active')"
|
||||
accept="image/*"
|
||||
:show-upload-list="false"
|
||||
>
|
||||
<a-button :loading="uploading.active">
|
||||
<template #icon>
|
||||
<UploadOutlined />
|
||||
</template>
|
||||
选择激活状态图片
|
||||
</a-button>
|
||||
</a-upload>
|
||||
|
||||
<div v-if="formData.images.active" class="image-preview">
|
||||
<img :src="formData.images.active" alt="激活状态" />
|
||||
<div class="image-actions">
|
||||
<a-button size="small" @click="removeImage('active')">删除</a-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a-form-item>
|
||||
|
||||
<!-- 图片尺寸设置 -->
|
||||
<a-form-item label="图片尺寸">
|
||||
<a-row :gutter="16">
|
||||
<a-col :span="12">
|
||||
<a-input-number
|
||||
v-model:value="formData.imageWidth"
|
||||
:min="20"
|
||||
:max="200"
|
||||
placeholder="宽度"
|
||||
style="width: 100%"
|
||||
/>
|
||||
<span class="size-label">宽度 (px)</span>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-input-number
|
||||
v-model:value="formData.imageHeight"
|
||||
:min="20"
|
||||
:max="200"
|
||||
placeholder="高度"
|
||||
style="width: 100%"
|
||||
/>
|
||||
<span class="size-label">高度 (px)</span>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form-item>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<a-form-item>
|
||||
<a-space>
|
||||
<a-button @click="resetImages">重置图片</a-button>
|
||||
<a-button danger @click="clearAllImages">清除所有图片</a-button>
|
||||
<a-button danger @click="clearAllImages">清除图片</a-button>
|
||||
</a-space>
|
||||
</a-form-item>
|
||||
</div>
|
||||
@ -125,9 +73,10 @@
|
||||
<script setup lang="ts">
|
||||
import { UploadOutlined } from '@ant-design/icons-vue';
|
||||
import { message } from 'ant-design-vue';
|
||||
import { computed, onMounted, ref, watch } from 'vue';
|
||||
import { computed, inject, onMounted, ref, watch } from 'vue';
|
||||
|
||||
import colorConfig from '../../services/color/color-config.service';
|
||||
import { EditorService } from '../../services/editor.service';
|
||||
|
||||
interface RobotInfo {
|
||||
name: string;
|
||||
@ -159,19 +108,19 @@ const emit = defineEmits<Emits>();
|
||||
const selectedRobot = ref<string>(props.selectedRobotName);
|
||||
const loading = ref(false);
|
||||
const uploading = ref({
|
||||
normal: false,
|
||||
active: false
|
||||
normal: false
|
||||
});
|
||||
|
||||
const formData = ref({
|
||||
images: {
|
||||
normal: '',
|
||||
active: ''
|
||||
},
|
||||
imageWidth: 42,
|
||||
imageHeight: 76
|
||||
normal: ''
|
||||
}
|
||||
});
|
||||
|
||||
// 获取编辑器服务实例
|
||||
const EDITOR_KEY = Symbol('editor-key');
|
||||
const editor = inject<{ value: EditorService }>(EDITOR_KEY);
|
||||
|
||||
// 计算属性
|
||||
const availableRobots = computed(() => props.robots);
|
||||
|
||||
@ -193,22 +142,18 @@ watch(selectedRobot, (newRobot) => {
|
||||
|
||||
// 监听props变化
|
||||
watch(() => props.selectedRobotName, (newName) => {
|
||||
console.log('模态框接收到selectedRobotName变化:', newName);
|
||||
if (newName && newName !== selectedRobot.value) {
|
||||
selectedRobot.value = newName;
|
||||
console.log('设置selectedRobot为:', newName);
|
||||
}
|
||||
});
|
||||
|
||||
// 监听open状态变化
|
||||
watch(() => props.open, (isOpen) => {
|
||||
console.log('模态框open状态变化:', isOpen);
|
||||
if (isOpen) {
|
||||
// 如果有选中的机器人名称,则设置并加载数据
|
||||
if (props.selectedRobotName) {
|
||||
selectedRobot.value = props.selectedRobotName;
|
||||
loadRobotImages(props.selectedRobotName);
|
||||
console.log('模态框打开,设置selectedRobot为:', props.selectedRobotName);
|
||||
}
|
||||
} else {
|
||||
// 关闭时重置所有状态
|
||||
@ -219,15 +164,10 @@ watch(() => props.open, (isOpen) => {
|
||||
// 加载机器人图片
|
||||
const loadRobotImages = (robotName: string) => {
|
||||
formData.value.images.normal = colorConfig.getRobotCustomImage(robotName, 'normal') || '';
|
||||
formData.value.images.active = colorConfig.getRobotCustomImage(robotName, 'active') || '';
|
||||
|
||||
// 加载图片尺寸配置
|
||||
formData.value.imageWidth = Number(colorConfig.getColor('robot.imageWidth')) || 42;
|
||||
formData.value.imageHeight = Number(colorConfig.getColor('robot.imageHeight')) || 76;
|
||||
};
|
||||
|
||||
// 处理图片上传
|
||||
const handleImageUpload = async (file: File, state: 'normal' | 'active') => {
|
||||
const handleImageUpload = async (file: File, state: 'normal') => {
|
||||
if (!selectedRobot.value) {
|
||||
message.error('请先选择机器人');
|
||||
return false;
|
||||
@ -250,7 +190,13 @@ const handleImageUpload = async (file: File, state: 'normal' | 'active') => {
|
||||
try {
|
||||
await colorConfig.saveRobotCustomImage(selectedRobot.value, state, file);
|
||||
formData.value.images[state] = colorConfig.getRobotCustomImage(selectedRobot.value, state) || '';
|
||||
message.success(`${state === 'normal' ? '普通状态' : '激活状态'}图片上传成功`);
|
||||
|
||||
// 刷新机器人pen元素以显示新图片
|
||||
if (editor?.value && typeof editor.value.updateRobotImage === 'function') {
|
||||
editor.value.updateRobotImage(selectedRobot.value);
|
||||
}
|
||||
|
||||
message.success('自定义图片上传成功');
|
||||
} catch (error) {
|
||||
console.error('图片上传失败:', error);
|
||||
message.error('图片上传失败,请重试');
|
||||
@ -262,12 +208,18 @@ const handleImageUpload = async (file: File, state: 'normal' | 'active') => {
|
||||
};
|
||||
|
||||
// 删除图片
|
||||
const removeImage = (state: 'normal' | 'active') => {
|
||||
const removeImage = (state: 'normal') => {
|
||||
if (!selectedRobot.value) return;
|
||||
|
||||
colorConfig.removeRobotCustomImage(selectedRobot.value, state);
|
||||
formData.value.images[state] = '';
|
||||
message.success(`${state === 'normal' ? '普通状态' : '激活状态'}图片已删除`);
|
||||
|
||||
// 刷新机器人pen元素以显示删除后的效果
|
||||
if (editor?.value && typeof editor.value.updateRobotImage === 'function') {
|
||||
editor.value.updateRobotImage(selectedRobot.value);
|
||||
}
|
||||
|
||||
message.success('自定义图片已删除');
|
||||
};
|
||||
|
||||
// 重置图片
|
||||
@ -276,18 +228,28 @@ const resetImages = () => {
|
||||
|
||||
colorConfig.removeRobotCustomImage(selectedRobot.value);
|
||||
formData.value.images.normal = '';
|
||||
formData.value.images.active = '';
|
||||
|
||||
// 刷新机器人pen元素以显示重置后的效果
|
||||
if (editor?.value && typeof editor.value.updateRobotImage === 'function') {
|
||||
editor.value.updateRobotImage(selectedRobot.value);
|
||||
}
|
||||
|
||||
message.success('图片已重置');
|
||||
};
|
||||
|
||||
// 清除所有图片
|
||||
// 清除图片
|
||||
const clearAllImages = () => {
|
||||
if (!selectedRobot.value) return;
|
||||
|
||||
colorConfig.removeRobotCustomImage(selectedRobot.value);
|
||||
formData.value.images.normal = '';
|
||||
formData.value.images.active = '';
|
||||
message.success('所有图片已清除');
|
||||
|
||||
// 刷新机器人pen元素以显示清除后的效果
|
||||
if (editor?.value && typeof editor.value.updateRobotImage === 'function') {
|
||||
editor.value.updateRobotImage(selectedRobot.value);
|
||||
}
|
||||
|
||||
message.success('图片已清除');
|
||||
};
|
||||
|
||||
// 保存设置
|
||||
@ -300,19 +262,9 @@ const handleSave = async () => {
|
||||
loading.value = true;
|
||||
|
||||
try {
|
||||
// 保存图片尺寸配置
|
||||
if (formData.value.imageWidth !== Number(colorConfig.getColor('robot.imageWidth'))) {
|
||||
colorConfig.setColor('robot.imageWidth', formData.value.imageWidth.toString());
|
||||
}
|
||||
if (formData.value.imageHeight !== Number(colorConfig.getColor('robot.imageHeight'))) {
|
||||
colorConfig.setColor('robot.imageHeight', formData.value.imageHeight.toString());
|
||||
}
|
||||
|
||||
emit('save', {
|
||||
robotName: selectedRobot.value,
|
||||
images: formData.value.images,
|
||||
imageWidth: formData.value.imageWidth,
|
||||
imageHeight: formData.value.imageHeight
|
||||
images: formData.value.images
|
||||
});
|
||||
|
||||
message.success('设置保存成功');
|
||||
@ -332,11 +284,8 @@ const handleCancel = () => {
|
||||
selectedRobot.value = '';
|
||||
formData.value = {
|
||||
images: {
|
||||
normal: '',
|
||||
active: ''
|
||||
},
|
||||
imageWidth: 42,
|
||||
imageHeight: 76
|
||||
normal: ''
|
||||
}
|
||||
};
|
||||
};
|
||||
</script>
|
||||
@ -385,11 +334,6 @@ const handleCancel = () => {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.size-label {
|
||||
font-size: 12px;
|
||||
color: #666;
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
.ant-form-item {
|
||||
margin-bottom: 16px;
|
||||
@ -398,4 +342,15 @@ const handleCancel = () => {
|
||||
.ant-divider {
|
||||
margin: 16px 0;
|
||||
}
|
||||
|
||||
/* 确保模态框层级低于机器人菜单 (机器人菜单 z-index: 9999) */
|
||||
:deep(.ant-modal) {
|
||||
z-index: 1000 !important;
|
||||
}
|
||||
|
||||
:deep(.ant-modal-mask) {
|
||||
z-index: 999 !important;
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
|
@ -890,10 +890,14 @@ class ColorConfigService {
|
||||
fillWarning: theme.robot['fill-warning'] || DEFAULT_COLORS.robot.fillWarning,
|
||||
strokeFault: theme.robot['stroke-fault'] || DEFAULT_COLORS.robot.strokeFault,
|
||||
fillFault: theme.robot['fill-fault'] || DEFAULT_COLORS.robot.fillFault,
|
||||
imageWidth: DEFAULT_COLORS.robot.imageWidth,
|
||||
imageHeight: DEFAULT_COLORS.robot.imageHeight,
|
||||
customImages: DEFAULT_COLORS.robot.customImages,
|
||||
useCustomImages: DEFAULT_COLORS.robot.useCustomImages
|
||||
imageWidth: theme.robot.imageWidth || DEFAULT_COLORS.robot.imageWidth,
|
||||
imageHeight: theme.robot.imageHeight || DEFAULT_COLORS.robot.imageHeight,
|
||||
customImages: theme.robot.customImages || DEFAULT_COLORS.robot.customImages,
|
||||
useCustomImages: theme.robot.useCustomImages !== undefined ?
|
||||
(typeof theme.robot.useCustomImages === 'string' ?
|
||||
theme.robot.useCustomImages === 'true' :
|
||||
theme.robot.useCustomImages) :
|
||||
DEFAULT_COLORS.robot.useCustomImages
|
||||
};
|
||||
}
|
||||
|
||||
@ -1109,10 +1113,20 @@ class ColorConfigService {
|
||||
*/
|
||||
public getRobotCustomImage(robotName: string, state: 'normal' | 'active'): string | null {
|
||||
const customImages = this.config.value.robot.customImages;
|
||||
|
||||
if (!customImages || !customImages[robotName]) {
|
||||
return null;
|
||||
}
|
||||
return customImages[robotName][state] || null;
|
||||
|
||||
// 优先获取请求状态的图片,如果不存在则回退到 normal 状态
|
||||
let result = customImages[robotName][state] || null;
|
||||
|
||||
// 如果请求的是 active 状态但没有 active 图片,回退到 normal 状态
|
||||
if (!result && state === 'active') {
|
||||
result = customImages[robotName]['normal'] || null;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1169,6 +1183,41 @@ class ColorConfigService {
|
||||
customImages[robotName].normal || customImages[robotName].active
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 调试方法:打印当前配置状态
|
||||
*/
|
||||
public debugConfig(): void {
|
||||
console.log('🔧 当前颜色配置状态:', {
|
||||
robot: {
|
||||
useCustomImages: this.config.value.robot.useCustomImages,
|
||||
imageWidth: this.config.value.robot.imageWidth,
|
||||
imageHeight: this.config.value.robot.imageHeight,
|
||||
customImages: this.config.value.robot.customImages
|
||||
},
|
||||
fullConfig: this.config.value
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 应用用户提供的完整配置
|
||||
* @param userConfig 用户配置对象
|
||||
*/
|
||||
public applyUserConfig(userConfig: any): void {
|
||||
console.log('📝 应用用户配置:', userConfig);
|
||||
|
||||
// 合并用户配置到当前配置
|
||||
this.config.value = this.mergeConfig(this.config.value, userConfig);
|
||||
|
||||
// 保存到本地存储
|
||||
this.saveToLocalStorage(this.config.value);
|
||||
|
||||
// 触发重新渲染
|
||||
this.triggerRender();
|
||||
|
||||
console.log('✅ 用户配置已应用并保存');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default new ColorConfigService();
|
||||
|
@ -1223,8 +1223,8 @@ export class EditorService extends Meta2d {
|
||||
|
||||
// 检查是否启用自定义图片且有机器人名称
|
||||
const useCustomImages = colorConfig.getColor('robot.useCustomImages') === 'true';
|
||||
let image: string;
|
||||
|
||||
let image: string;
|
||||
if (useCustomImages && robotName) {
|
||||
// 尝试获取自定义图片
|
||||
const customImage = colorConfig.getRobotCustomImage(robotName, active ? 'active' : 'normal');
|
||||
|
Loading…
x
Reference in New Issue
Block a user