Commit 6ef260fc by pangchong

feat(editor): 支持工卡主数据桥接及路径前缀处理

- 在桥接接口中新增 getMainData 方法,支持获取工卡主数据信息
- 添加 currentJobCardMainData 响应式状态用于保存主数据信息
- 优化图片路径解析,结合工卡主数据中的路径前缀cepDir处理相对路径
- 编辑器加载时优先调用 getMainData 获取主数据,再获取工卡XML数据
- 在常量和类型定义中增加工卡主数据结构MainData及相关接口
- utils桥接层新增对应接口实现,支持远程调用TD_JC_MAIN_DATA接口
- 文档中补充主数据与路径前缀的支持说明
- 更新代理Cookie值以配合新环境需求
parent 53648049
......@@ -1048,7 +1048,8 @@ export const FAQ_DATABASE: FaqItem[] = [
steps: [
'【自动拉取】:通过 URL 参数或 Bridge 接口自动拉取远程工卡 XML 并在编辑器中呈现。',
'【在线保存】:支持直接调用保存接口将编辑后的工卡及模板持久化至远程服务器。',
'【图片上传】:附图上传直接与远程图片服务器(TD_JC_CEP_UPLOAD_IMG)联动。'
'【图片上传】:附图上传直接与远程图片服务器(TD_JC_CEP_UPLOAD_IMG)联动。',
'【主数据与路径前缀】:支持通过 TD_JC_MAIN_DATA 接口获取工卡主数据及附图资源路径前缀(cepDir)。'
],
relatedQuestions: ['faq_import_xml', 'faq_export_xml']
},
......
......@@ -21,6 +21,20 @@ export interface TemplateResponse {
data: TemplateItem[]
}
export interface MainData {
cepDir?: string
[key: string]: any
}
export interface MainDataResponse {
code: number | string
msg?: string
total?: number
data: MainData
msgData?: any[]
page?: number
}
const localBridge = {
getTemplateList: async (page: number, rows: number): Promise<TemplateResponse> => {
return {
......@@ -41,6 +55,15 @@ const localBridge = {
getEditorData: async (): Promise<string> => {
return ''
},
getMainData: async (jcpkid?: string): Promise<MainDataResponse> => {
return {
code: 200,
msg: 'Success',
total: 0,
data: { cepDir: '' }
}
}
}
......@@ -49,6 +72,29 @@ const defaultGetTemplateList = execute('GET_TEMPLATE_LIST', localBridge.getTempl
const defaultSaveTemplate = execute('SAVE_AS_TEMPLATE', localBridge.saveTemplate, (name, content) => ({ content }))
const defaultUploadImage = execute('UPLOAD_EDITOR_FILE', localBridge.uploadImage, (file) => ({ file }))
const defaultGetEditorData = execute('GET_EDITOR_DATA', localBridge.getEditorData, () => ({}))
const defaultGetMainData = execute('GET_MAIN_DATA', localBridge.getMainData, () => ({}))
/**
* 检查当前定制环境或宿主系统是否配置了指定的桥接方法
*/
export const hasBridgeMethod = (methodName: string): boolean => {
if (customBridge && typeof customBridge[methodName] === 'function') {
return true
}
const win = window as any
if (typeof win[methodName] === 'function' || (win.bridge && typeof win.bridge[methodName] === 'function')) {
return true
}
try {
if (window.parent && window.parent !== window) {
const parentWin = window.parent as any
if (typeof parentWin[methodName] === 'function' || (parentWin.bridge && typeof parentWin.bridge[methodName] === 'function')) {
return true
}
}
} catch (e) {}
return false
}
/**
* 获取模板列表
......@@ -91,6 +137,17 @@ export const getEditorData = (...args: any[]) => {
}
/**
* 获取工卡主数据 / 工卡信息
*/
export const getMainData = (...args: any[]) => {
if (customBridge && customBridge.getMainData) {
return customBridge.getMainData(...args)
}
return defaultGetMainData(...(args as [string?]))
}
/**
* 注册编辑器的桥接事件监听器 (用于集成模式下响应父级提取 XML/PDF 数据的请求)
* 返回一个清理函数,用于组件卸载时注销所有监听器
*/
......
......@@ -1478,6 +1478,7 @@ import type { XmlNode } from '@/types/xmlNode'
import TableEditor from '../TableEditor/index.vue'
import { useDocNodeRenderer, getSplitListChildren, getCepTaskNumber, isAllEinDataSameEffect, getDiffWordClass } from './functionals'
import { translatingNodeId } from '@/views/editor/components/NodeTree/functionals'
import { currentJobCardMainData } from '@/views/editor/constants'
const getGraphicKey = (node: XmlNode): string => {
let key = node.attributes?.KEY || node.attributes?.GRAPHICKEY || node.attributes?.ID || ''
......@@ -1532,15 +1533,29 @@ const getRefTargetId = (node: XmlNode): string | null => {
const getImgSrc = (gnbr: string) => {
if (!gnbr) return ''
if (gnbr.startsWith('http://') || gnbr.startsWith('https://')) {
return gnbr
const [base, query] = gnbr.trim().split('?')
const queryStr = query !== undefined ? `?${query}` : ''
let path = base
if (!/\.(png|jpe?g|gif|svg|webp|bmp|cgm|tiff?|ico)$/i.test(path)) {
path = `${path}.png`
}
if (gnbr.startsWith('/')) {
return gnbr
const target = `${path}${queryStr}`
if (target.startsWith('http://') || target.startsWith('https://')) {
return target
}
if (target.startsWith('/')) {
return target
}
const cepDir = currentJobCardMainData.value?.cepDir || ''
if (cepDir) {
return cepDir.endsWith('/') ? `${cepDir}${target}` : `${cepDir}/${target}`
}
return gnbr
return target
}
const getInheritedTitle = () => {
if (props.node.tagName !== 'SHEET') return ''
if (props.node.children.some((c) => c.tagName === 'TITLE' || c.tagName === 'TITLEC')) {
......
/**
* XML 编辑器静态常量定义
* XML 编辑器静态常量与工卡信息接口类型定义
*/
export interface JobCardMainData {
cepDir?: string
[key: string]: any
}
/**
* 当前工卡的主数据信息响应式状态(由桥接接口 getMainData 初始化注入)
*/
export const currentJobCardMainData = ref<JobCardMainData | null>(null)
......@@ -4,6 +4,7 @@ import type { XmlNode } from '@/types/xmlNode'
import dtdJson from '@/assets/json/dtd.json'
import { VIRTUAL_LAYOUT_TAGS } from '@/configs/xmlTags'
import { DEFAULT_XML_FILE } from '@/configs'
import { currentJobCardMainData } from '../constants'
// 导入通用及定制环境目录下的本地默认模板 XML 文本
const xmlModules = import.meta.glob(['../../../assets/file/*.xml', '../../../*/assets/file/*.xml'], {
query: '?raw',
......@@ -33,6 +34,21 @@ export function useEditor() {
let xmlContent =
(customXmlKey && xmlModules[customXmlKey]) || xmlModules[commonXmlKey] || xmlModules['../../../assets/file/default.xml'] || ''
// 1. 如果配置了工卡主数据桥接接口,首先调用该接口获取工卡信息
if (hasBridgeMethod('getMainData')) {
try {
const mainDataRes = await getMainData()
if (mainDataRes) {
console.log('获取到的工卡主数据:\n', mainDataRes)
currentJobCardMainData.value = mainDataRes.data || mainDataRes
}
} catch (err) {
console.warn('获取工卡主数据失败:', err)
}
}
// 2. 然后再调用 getEditorData 获取工卡 XML 初始化数据
try {
const remoteXml = await getEditorData()
if (remoteXml) {
......
......@@ -13,6 +13,20 @@ export interface TemplateResponse {
data: TemplateItem[]
}
export interface MainData {
cepDir?: string
[key: string]: any
}
export interface MainDataResponse {
code: number | string
msg?: string
total?: number
data: MainData
msgData?: any[]
page?: number
}
// 本地接口的具体实现
const localBridge = {
getTemplateList: async (page: number, rows: number): Promise<any> => {
......@@ -52,6 +66,12 @@ const localBridge = {
}
}
return ''
},
getMainData: async (): Promise<MainDataResponse> => {
return await apiService.postForm<MainDataResponse>('/plugins/TD_JC_MAIN_DATA', {
jcpkid: '13054174'
})
}
}
......@@ -74,3 +94,8 @@ export const uploadImage = execute('UPLOAD_EDITOR_FILE', localBridge.uploadImage
* 获取工卡 XML 数据
*/
export const getEditorData = execute('GET_EDITOR_DATA', localBridge.getEditorData, () => ({}))
/**
* 获取工卡主数据 / 工卡信息 (TD_JC_MAIN_DATA)
*/
export const getMainData = execute('GET_MAIN_DATA', localBridge.getMainData, () => ({}))
......@@ -68,7 +68,7 @@ export default defineConfig(({ mode }) => {
changeOrigin: true,
secure: false,
headers: {
Cookie: '_udid=5bf34532-a66b-477d-81dc-8c0f4079f6bc; JSESSIONID=48C6C0153A0F552336259B30A2D4D8DC; _amro_sk=b51dbda2-701b-4a17-983d-3770fad9966f'
Cookie: '_udid=7927a0ca-972a-4e44-948a-c2edfd510fdb; JSESSIONID=C4A682632B2A7670516350D782474347; _amro_sk=31047732-4a3e-4681-b99a-16e99ee22810'
}
},
'/mnt': {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment