diff --git a/public/config.js b/public/config.js
index 4d66b75..e5c224c 100644
--- a/public/config.js
+++ b/public/config.js
@@ -10,21 +10,21 @@ const config = {
],*/
// 本地调试接口
-/* Api: "http://project.blv-oa.com:898/api/",
- Ads: "http://project.blv-oa.com:898/",
- PicAds: "http://blv-rd.tech:10010/PanelSelectionPic/",
- ApiList: [
- "http://project.blv-oa.com:898/api/",
- "http://localhost:19368/api/",
- "http://www.boonlive-rcu.com:7000/api/",
- ], */
- // 新服务接口
- Api: "http://project.blv-oa.com:898/api/",
+ // Api: "http://project.blv-oa.com:898/api/",
+ // Ads: "http://project.blv-oa.com:898/",
+ // PicAds: "http://blv-rd.tech:10010/PanelSelectionPic/",
+ // ApiList: [
+ // "http://project.blv-oa.com:898/api/",
+ // "http://localhost:19368/api/",
+ // "http://www.boonlive-rcu.com:7000/api/",
+ // ],
+ // 新服务接口
+ Api: "http://project.blv-oa.com:898/api/",
Ads: "http://project.blv-oa.com:898/",
- PicAds: "http://blv-rd.tech:10010/PanelSelectionPic/",
+ PicAds: "http://blv-rd.tech:19055/PanelSelectionPic/",
ApiList: [
"http://project.blv-oa.com:898/api/",
- "http://blv-rd.tech:10010/api/",
+ "http://blv-rd.tech:19055/api/",
"http://www.boonlive-rcu.com:7000/api/",
],
}
diff --git a/src/pages/panelselection/index.vue b/src/pages/panelselection/index.vue
index 93b35c5..a7f7036 100644
--- a/src/pages/panelselection/index.vue
+++ b/src/pages/panelselection/index.vue
@@ -2,6 +2,19 @@
+
+
+
+
+
+
+
+
+
@@ -174,6 +187,7 @@
+ 复制组
修改
删除
@@ -192,8 +206,8 @@
-
+
@@ -1027,11 +1041,17 @@ const currentEditPanelUnit = ref(null);
// 面板修改列表变量
const mergedPanelUnitForm = ref([]);
const currentMergedPanelUnitRow = ref(null); // 当前选中的mergedPanelUnitForm表格行
+const panelUnitTable = ref(null); // 面板单元列表表格引用(用于新增后自动选中)
// 复制面板相关变量
const showCopyPanelDialog = ref(false);
const copyPanelUnitRow = ref(null);
const selectedCopyProjectId = ref(null);
const selectedCopyProjectGuid = ref(null);
+// 复制面板组相关变量
+const showCopyPanelGroupDialog = ref(false);
+const copyPanelGroupNode = ref(null);
+const copyTargetRoomOptions = ref([]);
+const selectedCopyTargetRoomGuid = ref(null);
const mergedPanelUnitTable = ref(null); // 表格引用
const iconDialogVisible = ref(false);
const chineseDialogVisible = ref(false);
@@ -2049,6 +2069,89 @@ const confirmCopyPanel = async () => {
}
};
+/**
+ * 打开复制面板组对话框(复制到同项目下的另一房型)
+ */
+const copyPanelGroup = (panelNode) => {
+ copyPanelGroupNode.value = panelNode;
+ selectedCopyTargetRoomGuid.value = null;
+
+ const projectNode = findProjectNode(panelNode?.projectId);
+ const rooms = (projectNode?.children || []).filter((n) => n && n.type === "room" && n.roomGuid);
+ copyTargetRoomOptions.value = rooms
+ .filter((r) => r.roomGuid !== panelNode?.roomGuid)
+ .map((r) => ({ guid: r.roomGuid, name: r.name }));
+
+ showCopyPanelGroupDialog.value = true;
+};
+
+/**
+ * 确认复制面板组
+ */
+const confirmCopyPanelGroup = async () => {
+ if (!copyPanelGroupNode.value || !copyPanelGroupNode.value.panelGuid) {
+ ElMessage.error("无效的面板组数据");
+ return;
+ }
+ if (!selectedCopyTargetRoomGuid.value) {
+ ElMessage.warning("请选择目标房型");
+ return;
+ }
+
+ try {
+ const rs = await localHttp.post("PanelSelection/CopyPanelListWithNewFields", {
+ OriginalGuid: copyPanelGroupNode.value.panelGuid,
+ TargetRoomGuid: selectedCopyTargetRoomGuid.value,
+ });
+
+ if (!rs?.data?.isok) {
+ ElMessage.error("复制面板组失败: " + (rs?.data?.message || "未知错误"));
+ return;
+ }
+
+ const newPanelGuid = rs.data.response;
+ if (!newPanelGuid || typeof newPanelGuid !== "string" || newPanelGuid.length !== 32) {
+ ElMessage.success("复制面板组成功");
+ showCopyPanelGroupDialog.value = false;
+ return;
+ }
+
+ // 更新前端树:把新面板组插入目标房型节点
+ const targetRoomNode = findRoomNode(copyPanelGroupNode.value.projectId, selectedCopyTargetRoomGuid.value);
+ if (targetRoomNode) {
+ const panelInfo = await getPanelInfoByGuid(newPanelGuid);
+ if (panelInfo) {
+ const roomNameSuffix = targetRoomNode?.name ? `_${targetRoomNode.name}` : "";
+ const newPanelNode = {
+ id: `panel-${selectedCopyTargetRoomGuid.value}-${newPanelGuid}${roomNameSuffix}`,
+ name: `${panelInfo.panel_list_name}(${panelInfo.gang_series})`,
+ type: "panel",
+ roomGuid: selectedCopyTargetRoomGuid.value,
+ panelGuid: newPanelGuid,
+ panelInfo,
+ projectId: copyPanelGroupNode.value.projectId,
+ };
+
+ targetRoomNode.children = targetRoomNode.children || [];
+ targetRoomNode.children.push(newPanelNode);
+
+ // 自动选中并加载
+ await nextTick();
+ if (projectTree.value?.setCurrentKey) {
+ projectTree.value.setCurrentKey(newPanelNode.id);
+ }
+ await handleNodeClick(newPanelNode);
+ }
+ }
+
+ ElMessage.success("面板组复制成功");
+ showCopyPanelGroupDialog.value = false;
+ } catch (error) {
+ console.error("复制面板组失败:", error);
+ ElMessage.error("复制面板组失败");
+ }
+};
+
/**
* 等待辅助函数: 轮询直到 predicate 返回 true 或超时
*/
@@ -2417,7 +2520,16 @@ const getPanelInfoByGuid = async (panelGuid) => {
"PanelSelection/WebPanelListQueryByGuid",
JSON.stringify({ GUID: panelGuid })
);
- return JSON.parse(rs.data.response)[0];
+ // 解析响应并做容错处理,避免 response 为 null 导致访问 [0] 报错
+ try {
+ const parsed = rs.data && rs.data.response ? JSON.parse(rs.data.response) : null;
+ if (Array.isArray(parsed) && parsed.length > 0) return parsed[0];
+ if (parsed && typeof parsed === "object") return parsed;
+ return null;
+ } catch (e) {
+ console.warn("解析面板组响应失败:", e);
+ return null;
+ }
} catch (error) {
console.error("查询面板组失败:", error);
return null;
@@ -3491,8 +3603,10 @@ const confirmAddPanel = async () => {
if (roomNode) {
const panelInfo = await getPanelInfoByGuid(newPanelGuid);
if (panelInfo) {
- roomNode.children.push({
- id: `panel-${currentRoomData.value.roomGuid}-${newPanelGuid}`,
+ // 让新节点的 id 与 buildProjectTree() 生成规则一致,便于后续 setCurrentKey/恢复
+ const roomNameSuffix = currentRoomData.value?.name ? `_${currentRoomData.value.name}` : "";
+ const newPanelNode = {
+ id: `panel-${currentRoomData.value.roomGuid}-${newPanelGuid}${roomNameSuffix}`,
name: `${panelInfo.panel_list_name}(${panelInfo.gang_series})`,
type: "panel",
roomGuid: currentRoomData.value.roomGuid,
@@ -3504,7 +3618,16 @@ const confirmAddPanel = async () => {
projectId: currentRoomData.value.projectId,
gang_material_id: selectedModel.value.ID,
logo_json: logoJsonValue,
- });
+ };
+
+ roomNode.children.push(newPanelNode);
+
+ // 新增成功后:自动选中刚新增的面板组节点,并加载其配置
+ await nextTick();
+ if (projectTree.value?.setCurrentKey) {
+ projectTree.value.setCurrentKey(newPanelNode.id);
+ }
+ await handleNodeClick(newPanelNode);
}
}
ElMessage.success("面板组新增成功");
@@ -5046,6 +5169,19 @@ const confirmAddPanelUnit = async () => {
// 刷新面板单元列表
await loadPanelUnitsByProject(projectGuid);
+ // 新增成功后:自动在列表里选中刚新增的面板单元,并加载其右侧配置
+ await nextTick();
+ const newRow = unitTableData.value.find((u) => u && u.guid === newGuid);
+ if (newRow) {
+ if (panelUnitTable.value?.setCurrentRow) {
+ panelUnitTable.value.setCurrentRow(newRow);
+ }
+ await handleUnitRowClick(newRow);
+ } else {
+ // 容错:至少把 GUID 设为当前
+ currentPanelUnit.value = newGuid;
+ }
+
// 重置对话框
resetPanelUnitDialog();
} else {
@@ -5233,22 +5369,40 @@ const openEnglishDialog = (location) => {
*/
const saveIconConfig = (iconData) => {
if (currentEditingLocation.value) {
+ const ensureSubItem = (group, key, type, defaultSize) => {
+ const hasObj = group && typeof group[key] === "object" && group[key] !== null;
+ if (!hasObj) group[key] = {};
+
+ // 从该行原始 locations 中尽量找到对应 type 的 locationId
+ const inferredLocationId =
+ group[key].locationId ||
+ group.locations?.find((l) => l && l.type === type)?.locationId ||
+ group.locations?.[0]?.locationId ||
+ Date.now();
+
+ const inferredLocationName =
+ group[key].locationName || group.originalLocationName || group.locationName;
+
+ // 补齐关键字段:buildMergedPanelUnitForm 依赖 type 来归类
+ if (group[key].type !== type) group[key].type = type;
+ if (!group[key].id) group[key].id = Date.now() + type;
+ if (!group[key].locationId) group[key].locationId = inferredLocationId;
+ if (!group[key].locationName) group[key].locationName = inferredLocationName;
+ if (type !== 1) {
+ if (!group[key].font) group[key].font = "";
+ if (!group[key].size) group[key].size = defaultSize;
+ }
+ if (group[key].indexNum === undefined || group[key].indexNum === null)
+ group[key].indexNum = 0;
+ if (group[key].keygroup === undefined || group[key].keygroup === null)
+ group[key].keygroup = 0;
+ if (group[key].lineNumber === undefined || group[key].lineNumber === null)
+ group[key].lineNumber = 0;
+ };
+
// 确保图标对象存在
- if (!currentEditingLocation.value.icon) {
- currentEditingLocation.value.icon = {
- id: currentEditingLocation.value.icon.id || Date.now(),
- locationId:
- currentEditingLocation.value.locations?.[0]?.locationId || Date.now(),
- content: "",
- type: 1,
- locationName:
- currentEditingLocation.value.icon.locationName ||
- currentEditingLocation.value.locationName,
- indexNum: currentEditingLocation.value.icon.indexNum || 0,
- keygroup: currentEditingLocation.value.icon.keygroup || 0,
- lineNumber: currentEditingLocation.value.icon.lineNumber || 0,
- };
- }
+ ensureSubItem(currentEditingLocation.value, "icon", 1, null);
+
// 更新图标配置
currentEditingLocation.value.icon = {
...currentEditingLocation.value.icon,
@@ -5267,64 +5421,21 @@ const saveIconConfig = (iconData) => {
// 新增:自动设置中文和英文内容
// 确保中文对象存在
- if (!currentEditingLocation.value.chinese) {
- currentEditingLocation.value.chinese = {
- id: currentEditingLocation.value.chinese.id || Date.now() + 1, // 确保ID不同
- locationId:
- currentEditingLocation.value.chinese.locationId || Date.now() + 1,
- content: "",
- type: 2,
- font: "", // TODO 默认字体
- size: 11, // 中文默认字号
- locationName:
- currentEditingLocation.value.chinese.locationName ||
- currentEditingLocation.value.locationName,
- indexNum: currentEditingLocation.value.chinese.indexNum || 0,
- keygroup: currentEditingLocation.value.chinese.keygroup || 0,
- lineNumber: currentEditingLocation.value.chinese.lineNumber || 0,
- };
- }
+ ensureSubItem(currentEditingLocation.value, "chinese", 2, 11);
// 确保英文对象存在
- if (!currentEditingLocation.value.english) {
- currentEditingLocation.value.english = {
- id: currentEditingLocation.value.english.id || Date.now() + 2, // 确保ID不同
- locationId:
- currentEditingLocation.value.english.locationId || Date.now() + 2,
- content: "",
- type: 3,
- font: "",
- size: 7, // 英文默认字号
- locationName:
- currentEditingLocation.value.english.locationName ||
- currentEditingLocation.value.locationName,
- indexNum: currentEditingLocation.value.english.indexNum || 0,
- keygroup: currentEditingLocation.value.english.keygroup || 0,
- lineNumber: currentEditingLocation.value.english.lineNumber || 0,
- };
- }
+ ensureSubItem(currentEditingLocation.value, "english", 3, 7);
// 使用图标数据的中英文名称自动填充内容
- if (iconData.NameCN) {
- currentEditingLocation.value.chinese.content = iconData.NameCN || "空";
- // 设置默认中文字体(如果当前没有设置)
- if (
- !currentEditingLocation.value.chinese.font &&
- fontList.value.length > 0
- ) {
- currentEditingLocation.value.chinese.font = "思源黑体";
- }
- }
+ currentEditingLocation.value.chinese.content = iconData?.NameCN ?? "空";
+ currentEditingLocation.value.english.content = iconData?.NameEn ?? "empty";
- if (iconData.NameEn) {
- currentEditingLocation.value.english.content = iconData.NameEn || "empty";
- // 设置默认英文字体(如果当前没有设置)
- if (
- !currentEditingLocation.value.english.font &&
- fontList.value.length > 0
- ) {
- currentEditingLocation.value.english.font = "Futura Std Medium";
- }
+ // 设置默认字体(如果当前没有设置)
+ if (!currentEditingLocation.value.chinese.font && fontList.value.length > 0) {
+ currentEditingLocation.value.chinese.font = "思源黑体";
+ }
+ if (!currentEditingLocation.value.english.font && fontList.value.length > 0) {
+ currentEditingLocation.value.english.font = "Futura Std Medium";
}
// 同步背光设置到中文和英文对象