Commit fc86ebac60858ac345e9dfcfc4b103d0f9b70f1c

Authored by xp.Huang
2 parents 5b3b3a2f 2042e711

Merge branch 'main_dev' into 'main'

Main dev

See merge request yunteng/thingskit-scada!265
Showing 43 changed files with 323 additions and 105 deletions
  1 +FROM nginx:latest
  2 +
  3 +COPY ./dist/ /usr/share/nginx/html/
  4 +COPY default.conf /etc/nginx/conf.d/default.conf
  5 +
  6 +EXPOSE 8083
  1 +server {
  2 + listen 80;
  3 + listen [::]:80;
  4 + server_name 192.168.1.48;
  5 + #charset koi8-r;
  6 + #access_log /var/log/nginx/host.access.log main;
  7 +
  8 + root /usr/share/nginx/html;
  9 + index index.html index.htm;
  10 + try_files $uri $uri/ /index.html;
  11 +
  12 +
  13 +
  14 + location /api/ {
  15 + proxy_pass http://192.168.1.48:8080;
  16 + proxy_http_version 1.1;
  17 + proxy_set_header Upgrade $http_upgrade;
  18 + proxy_set_header Connection "Upgrade";
  19 + proxy_set_header Host $host;
  20 + proxy_cache_bypass $http_upgrade;
  21 + }
  22 +
  23 + location /yt/ {
  24 + proxy_pass http://192.168.1.48:8080;
  25 + proxy_http_version 1.1;
  26 + proxy_set_header Upgrade $http_upgrade;
  27 + proxy_set_header Connection "Upgrade";
  28 + proxy_set_header Host $host;
  29 + proxy_cache_bypass $http_upgrade;
  30 + }
  31 +
  32 + location /upload/ {
  33 + proxy_pass http://192.168.1.48:8080;
  34 + proxy_http_version 1.1;
  35 + proxy_set_header Upgrade $http_upgrade;
  36 + proxy_set_header Connection "Upgrade";
  37 + proxy_set_header Host $host;
  38 + proxy_cache_bypass $http_upgrade;
  39 + }
  40 +
  41 + #error_page 404 /404.html;
  42 +
  43 + # redirect server error pages to the static page /50x.html
  44 + #
  45 + error_page 500 502 503 504 /50x.html;
  46 + location = /50x.html {
  47 + root /usr/share/nginx/html;
  48 + }
  49 +}
@@ -4296,8 +4296,13 @@ App.prototype.loadFile = function (id, sameWindow, file, success, force) { @@ -4296,8 +4296,13 @@ App.prototype.loadFile = function (id, sameWindow, file, success, force) {
4296 document.getElementById('first-text-animation-text').querySelector('text').innerHTML = platformInfo?.name || window.PROJECT_ENV?.shortName 4296 document.getElementById('first-text-animation-text').querySelector('text').innerHTML = platformInfo?.name || window.PROJECT_ENV?.shortName
4297 document.getElementById('first-text-animation').style.display = 'block' 4297 document.getElementById('first-text-animation').style.display = 'block'
4298 if (this.appIcon) { 4298 if (this.appIcon) {
4299 - this.appIcon.style.backgroundImage = `url(${platformInfo?.logo || `${getProxyPrefix()}/logo.png`})` 4299 + this.appIcon.style.backgroundImage = `url(${this.getAppIcon()})`
4300 } 4300 }
  4301 +
  4302 + const favicon = this.getAppFavicon()
  4303 + const faviconEl = document.querySelector('link[rel~="icon"]')
  4304 + faviconEl.href = favicon
  4305 +
4301 const handleLoadContent = async () => { 4306 const handleLoadContent = async () => {
4302 /** 4307 /**
4303 * @typedef ConfigurationContentListItemType 4308 * @typedef ConfigurationContentListItemType
@@ -5672,16 +5677,36 @@ App.prototype.save = function (name, done) { @@ -5672,16 +5677,36 @@ App.prototype.save = function (name, done) {
5672 // const data = `${Graph.xmlDeclaration}\n${this.getFileData(true, null, null, null, true, true, null, null, null, false)}`; 5677 // const data = `${Graph.xmlDeclaration}\n${this.getFileData(true, null, null, null, true, true, null, null, null, false)}`;
5673 // this.currentFile.setData(data) 5678 // this.currentFile.setData(data)
5674 5679
5675 - const allCells = this.editor.graph.getModel().cells || {} 5680 + const graph = this.editor.graph
  5681 + const model = graph.model
  5682 + const pages = this.pages
  5683 +
  5684 + const currentPageContentId = this.ui.currentPage.getId()
  5685 + let originalPage
  5686 + const contentPageInfos = pages.map(page => {
  5687 + this.ui.selectPage(page)
  5688 + const cells = model.getChildCells(graph.getDefaultParent())
  5689 + const nodeIds = cells.map(cell => cell.getId())
  5690 + const contentId = this.ui.currentPage.getId()
  5691 +
  5692 + if (contentId === currentPageContentId)
  5693 + originalPage = page
  5694 +
  5695 + return {
  5696 + nodeIds,
  5697 + contentId
  5698 + }
  5699 + })
  5700 + originalPage && this.ui.selectPage(originalPage)
  5701 +
5676 await doSaveConfigurationContent({ 5702 await doSaveConfigurationContent({
5677 configurationContentList: [ 5703 configurationContentList: [
5678 { 5704 {
5679 id: currentFile.getHash(), 5705 id: currentFile.getHash(),
5680 content: this.currentFile.getData(), 5706 content: this.currentFile.getData(),
5681 - contentId: this.currentPage.getId(),  
5682 type: 1, 5707 type: 1,
5683 - nodeIds: Object.keys(allCells),  
5684 - name: this.currentPage.getName() 5708 + name: this.currentPage.getName(),
  5709 + contentPageInfos
5685 } 5710 }
5686 ], 5711 ],
5687 configurationName: currentFile.title, 5712 configurationName: currentFile.title,
@@ -6192,20 +6217,51 @@ App.prototype.convertFile = function (url, filename, mimeType, extension, succes @@ -6192,20 +6217,51 @@ App.prototype.convertFile = function (url, filename, mimeType, extension, succes
6192 } 6217 }
6193 } 6218 }
6194 6219
  6220 +App.prototype.isFromEdge = function () {
  6221 + const params = useParseParams()
  6222 + return params?.from === 'edge'
  6223 +}
  6224 +
  6225 +App.prototype.getAppIcon = function () {
  6226 + const platformInfo = getPlatformInfo()
  6227 +
  6228 + if (this.isFromEdge()) {
  6229 + if (platformInfo && platformInfo?.image) {
  6230 + return platformInfo?.image
  6231 + }
  6232 + return Editor.edgeLogoImage
  6233 + } else {
  6234 + if (platformInfo && platformInfo?.logo) {
  6235 + return platformInfo.logo
  6236 + }
  6237 +
  6238 + return Editor.logoImage
  6239 + }
  6240 +}
  6241 +
  6242 +App.prototype.getAppFavicon = function () {
  6243 + const platformInfo = getPlatformInfo()
  6244 + if (this.isFromEdge()) {
  6245 + if (platformInfo && platformInfo?.favicon) {
  6246 + return platformInfo?.favicon
  6247 + }
  6248 + return Editor.edgeLogoImage
  6249 + } else {
  6250 + if (platformInfo && platformInfo?.icon) {
  6251 + return platformInfo.icon
  6252 + }
  6253 + return Editor.logoImage
  6254 + }
  6255 +}
  6256 +
6195 /** 6257 /**
6196 * Adds the listener for automatically saving the diagram for local changes. 6258 * Adds the listener for automatically saving the diagram for local changes.
6197 */ 6259 */
6198 App.prototype.updateHeader = function () { 6260 App.prototype.updateHeader = function () {
6199 if (this.menubar != null) { 6261 if (this.menubar != null) {
6200 // TODO Thingskit 修改logo 6262 // TODO Thingskit 修改logo
6201 - Editor.logoImage = ''  
6202 - const platformInfo = getPlatformInfo()  
6203 - if (platformInfo && platformInfo?.logo) {  
6204 - const { logo } = platformInfo  
6205 - Editor.logoImage = logo  
6206 - }  
6207 6263
6208 - const logo = `url(${Editor.logoImage})` 6264 + const logo = `url(${this.getAppIcon()})`
6209 this.appIcon = document.createElement('a') 6265 this.appIcon = document.createElement('a')
6210 this.appIcon.style.display = 'block' 6266 this.appIcon.style.display = 'block'
6211 this.appIcon.style.position = 'absolute' 6267 this.appIcon.style.position = 'absolute'
@@ -1554,6 +1554,7 @@ var BackgroundImageDialog = function (editorUi, applyFn, img, color, showColor) @@ -1554,6 +1554,7 @@ var BackgroundImageDialog = function (editorUi, applyFn, img, color, showColor)
1554 widthInput.style.marginLeft = '8px'; 1554 widthInput.style.marginLeft = '8px';
1555 widthInput.style.marginRight = '16px'; 1555 widthInput.style.marginRight = '16px';
1556 widthInput.value = (img != null && !isPageLink) ? img.width : ''; 1556 widthInput.value = (img != null && !isPageLink) ? img.width : '';
  1557 + widthInput.setAttribute('disabled', true)
1557 1558
1558 div.appendChild(widthInput); 1559 div.appendChild(widthInput);
1559 1560
@@ -1565,6 +1566,7 @@ var BackgroundImageDialog = function (editorUi, applyFn, img, color, showColor) @@ -1565,6 +1566,7 @@ var BackgroundImageDialog = function (editorUi, applyFn, img, color, showColor)
1565 heightInput.style.marginLeft = '8px'; 1566 heightInput.style.marginLeft = '8px';
1566 heightInput.style.marginRight = '16px'; 1567 heightInput.style.marginRight = '16px';
1567 heightInput.value = (img != null && !isPageLink) ? img.height : ''; 1568 heightInput.value = (img != null && !isPageLink) ? img.height : '';
  1569 + heightInput.setAttribute('disabled', true)
1568 1570
1569 div.appendChild(heightInput); 1571 div.appendChild(heightInput);
1570 mxUtils.br(div); 1572 mxUtils.br(div);
@@ -140,7 +140,9 @@ @@ -140,7 +140,9 @@
140 /** 140 /**
141 * 141 *
142 */ 142 */
143 - Editor.logoImage = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcKICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIgogICB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiCiAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgeG1sOnNwYWNlPSJwcmVzZXJ2ZSIKICAgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAwIDAgMzA2LjE4NSAxMjAuMjk2IgogICB2aWV3Qm94PSIyNCAyNiA2OCA2OCIKICAgeT0iMHB4IgogICB4PSIwcHgiCiAgIHZlcnNpb249IjEuMSI+CiAgIAkgPGc+PGxpbmUKICAgICAgIHkyPSI3Mi4zOTQiCiAgICAgICB4Mj0iNDEuMDYxIgogICAgICAgeTE9IjQzLjM4NCIKICAgICAgIHgxPSI1OC4wNjkiCiAgICAgICBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiCiAgICAgICBzdHJva2Utd2lkdGg9IjMuNTUyOCIKICAgICAgIHN0cm9rZT0iI0ZGRkZGRiIKICAgICAgIGZpbGw9Im5vbmUiIC8+PGxpbmUKICAgICAgIHkyPSI3Mi4zOTQiCiAgICAgICB4Mj0iNzUuMDc2IgogICAgICAgeTE9IjQzLjM4NCIKICAgICAgIHgxPSI1OC4wNjgiCiAgICAgICBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiCiAgICAgICBzdHJva2Utd2lkdGg9IjMuNTAwOCIKICAgICAgIHN0cm9rZT0iI0ZGRkZGRiIKICAgICAgIGZpbGw9Im5vbmUiIC8+PGc+PHBhdGgKICAgICAgICAgZD0iTTUyLjc3Myw3Ny4wODRjMCwxLjk1NC0xLjU5OSwzLjU1My0zLjU1MywzLjU1M0gzNi45OTljLTEuOTU0LDAtMy41NTMtMS41OTktMy41NTMtMy41NTN2LTkuMzc5ICAgIGMwLTEuOTU0LDEuNTk5LTMuNTUzLDMuNTUzLTMuNTUzaDEyLjIyMmMxLjk1NCwwLDMuNTUzLDEuNTk5LDMuNTUzLDMuNTUzVjc3LjA4NHoiCiAgICAgICAgIGZpbGw9IiNGRkZGRkYiIC8+PC9nPjxnCiAgICAgICBpZD0iZzM0MTkiPjxwYXRoCiAgICAgICAgIGQ9Ik02Ny43NjIsNDguMDc0YzAsMS45NTQtMS41OTksMy41NTMtMy41NTMsMy41NTNINTEuOTg4Yy0xLjk1NCwwLTMuNTUzLTEuNTk5LTMuNTUzLTMuNTUzdi05LjM3OSAgICBjMC0xLjk1NCwxLjU5OS0zLjU1MywzLjU1My0zLjU1M0g2NC4yMWMxLjk1NCwwLDMuNTUzLDEuNTk5LDMuNTUzLDMuNTUzVjQ4LjA3NHoiCiAgICAgICAgIGZpbGw9IiNGRkZGRkYiIC8+PC9nPjxnPjxwYXRoCiAgICAgICAgIGQ9Ik04Mi43NTIsNzcuMDg0YzAsMS45NTQtMS41OTksMy41NTMtMy41NTMsMy41NTNINjYuOTc3Yy0xLjk1NCwwLTMuNTUzLTEuNTk5LTMuNTUzLTMuNTUzdi05LjM3OSAgICBjMC0xLjk1NCwxLjU5OS0zLjU1MywzLjU1My0zLjU1M2gxMi4yMjJjMS45NTQsMCwzLjU1MywxLjU5OSwzLjU1MywzLjU1M1Y3Ny4wODR6IgogICAgICAgICBmaWxsPSIjRkZGRkZGIiAvPjwvZz48L2c+PC9zdmc+'; 143 + // Editor.logoImage = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcKICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIgogICB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiCiAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgeG1sOnNwYWNlPSJwcmVzZXJ2ZSIKICAgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAwIDAgMzA2LjE4NSAxMjAuMjk2IgogICB2aWV3Qm94PSIyNCAyNiA2OCA2OCIKICAgeT0iMHB4IgogICB4PSIwcHgiCiAgIHZlcnNpb249IjEuMSI+CiAgIAkgPGc+PGxpbmUKICAgICAgIHkyPSI3Mi4zOTQiCiAgICAgICB4Mj0iNDEuMDYxIgogICAgICAgeTE9IjQzLjM4NCIKICAgICAgIHgxPSI1OC4wNjkiCiAgICAgICBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiCiAgICAgICBzdHJva2Utd2lkdGg9IjMuNTUyOCIKICAgICAgIHN0cm9rZT0iI0ZGRkZGRiIKICAgICAgIGZpbGw9Im5vbmUiIC8+PGxpbmUKICAgICAgIHkyPSI3Mi4zOTQiCiAgICAgICB4Mj0iNzUuMDc2IgogICAgICAgeTE9IjQzLjM4NCIKICAgICAgIHgxPSI1OC4wNjgiCiAgICAgICBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiCiAgICAgICBzdHJva2Utd2lkdGg9IjMuNTAwOCIKICAgICAgIHN0cm9rZT0iI0ZGRkZGRiIKICAgICAgIGZpbGw9Im5vbmUiIC8+PGc+PHBhdGgKICAgICAgICAgZD0iTTUyLjc3Myw3Ny4wODRjMCwxLjk1NC0xLjU5OSwzLjU1My0zLjU1MywzLjU1M0gzNi45OTljLTEuOTU0LDAtMy41NTMtMS41OTktMy41NTMtMy41NTN2LTkuMzc5ICAgIGMwLTEuOTU0LDEuNTk5LTMuNTUzLDMuNTUzLTMuNTUzaDEyLjIyMmMxLjk1NCwwLDMuNTUzLDEuNTk5LDMuNTUzLDMuNTUzVjc3LjA4NHoiCiAgICAgICAgIGZpbGw9IiNGRkZGRkYiIC8+PC9nPjxnCiAgICAgICBpZD0iZzM0MTkiPjxwYXRoCiAgICAgICAgIGQ9Ik02Ny43NjIsNDguMDc0YzAsMS45NTQtMS41OTksMy41NTMtMy41NTMsMy41NTNINTEuOTg4Yy0xLjk1NCwwLTMuNTUzLTEuNTk5LTMuNTUzLTMuNTUzdi05LjM3OSAgICBjMC0xLjk1NCwxLjU5OS0zLjU1MywzLjU1My0zLjU1M0g2NC4yMWMxLjk1NCwwLDMuNTUzLDEuNTk5LDMuNTUzLDMuNTUzVjQ4LjA3NHoiCiAgICAgICAgIGZpbGw9IiNGRkZGRkYiIC8+PC9nPjxnPjxwYXRoCiAgICAgICAgIGQ9Ik04Mi43NTIsNzcuMDg0YzAsMS45NTQtMS41OTksMy41NTMtMy41NTMsMy41NTNINjYuOTc3Yy0xLjk1NCwwLTMuNTUzLTEuNTk5LTMuNTUzLTMuNTUzdi05LjM3OSAgICBjMC0xLjk1NCwxLjU5OS0zLjU1MywzLjU1My0zLjU1M2gxMi4yMjJjMS45NTQsMCwzLjU1MywxLjU5OSwzLjU1MywzLjU1M1Y3Ny4wODR6IgogICAgICAgICBmaWxsPSIjRkZGRkZGIiAvPjwvZz48L2c+PC9zdmc+';
  144 + Editor.logoImage = 'data:image/png;base64,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';
  145 + Editor.edgeLogoImage = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iMjZweCIgaGVpZ2h0PSIyNnB4IiB2aWV3Qm94PSIwIDAgMjYgMjYiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CiAgICA8dGl0bGU+TG9nby1jZTE8L3RpdGxlPgogICAgPGRlZnM+CiAgICAgICAgPHBvbHlnb24gaWQ9InBhdGgtMSIgcG9pbnRzPSIwIDAgMjYgMCAyNiAyNiAwIDI2Ij48L3BvbHlnb24+CiAgICAgICAgPGxpbmVhckdyYWRpZW50IHgxPSI1MCUiIHkxPSIxMDAlIiB4Mj0iNTAlIiB5Mj0iMCUiIGlkPSJsaW5lYXJHcmFkaWVudC0zIj4KICAgICAgICAgICAgPHN0b3Agc3RvcC1jb2xvcj0iIzdGNTZEOSIgb2Zmc2V0PSIzNS4yMzgwMDA4JSI+PC9zdG9wPgogICAgICAgICAgICA8c3RvcCBzdG9wLWNvbG9yPSIjRTk2OUZGIiBvZmZzZXQ9IjgwLjIzODAwMjUlIj48L3N0b3A+CiAgICAgICAgPC9saW5lYXJHcmFkaWVudD4KICAgICAgICA8cG9seWdvbiBpZD0icGF0aC00IiBwb2ludHM9IjAgMCAzLjI1IDAgMy4yNSAzLjI1IDAgMy4yNSI+PC9wb2x5Z29uPgogICAgPC9kZWZzPgogICAgPGcgaWQ9IkFJb1RlZGdlIiBzdHJva2U9Im5vbmUiIHN0cm9rZS13aWR0aD0iMSIgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIj4KICAgICAgICA8ZyBpZD0iTWVkaXVtIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMTgsIC0yNCkiPgogICAgICAgICAgICA8ZyBpZD0i6aaW6aG1LS0tMSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCwgLTUpIj4KICAgICAgICAgICAgICAgIDxnIGlkPSLnu4QtMTEyNDEiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDE4LCAyNikiPgogICAgICAgICAgICAgICAgICAgIDxnIGlkPSJMb2dvLWNlMSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCwgMykiPgogICAgICAgICAgICAgICAgICAgICAgICA8cmVjdCBpZD0i6Lev5b6EIiB4PSIwIiB5PSIwIiB3aWR0aD0iMjYiIGhlaWdodD0iMjYiPjwvcmVjdD4KICAgICAgICAgICAgICAgICAgICAgICAgPG1hc2sgaWQ9Im1hc2stMiIgZmlsbD0id2hpdGUiPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgPHVzZSB4bGluazpocmVmPSIjcGF0aC0xIj48L3VzZT4KICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXNrPgogICAgICAgICAgICAgICAgICAgICAgICA8dXNlIGlkPSLot6/lvoQiIGZpbGwtb3BhY2l0eT0iMCIgZmlsbD0iIzAwMDAwMCIgeGxpbms6aHJlZj0iI3BhdGgtMSI+PC91c2U+CiAgICAgICAgICAgICAgICAgICAgICAgIDxnIGlkPSLnu4QtMTEwODIiIG1hc2s9InVybCgjbWFzay0yKSIgZmlsbD0idXJsKCNsaW5lYXJHcmFkaWVudC0zKSI+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLCAxLjc3MjkpIiBpZD0i6Lev5b6ELTEwMTIzIj4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMCwyMi40NTQzIEw0LjcyNzI1LDIyLjQ1NDMgTDEzLDguMjcyNTggTDIxLjI3MjcsMjIuNDU0MyBMMjUuOTk5OSwyMi40NTQzIEwxMywwIEwwLDIyLjQ1NDMgWiBNMTAuMjQyOCwyMi40NTQzIEwxMywxNy43MjcyIEwxNS43NTcxLDIyLjQ1NDMgTDIwLjUyNTgsMjIuNDU0MyBMMTMsOS40NTQzNSBMNS40NzQxNywyMi40NTQzIEwxMC4yNDI4LDIyLjQ1NDMgWiI+PC9wYXRoPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9nPgogICAgICAgICAgICAgICAgICAgICAgICA8L2c+CiAgICAgICAgICAgICAgICAgICAgICAgIDxnIGlkPSLnu4QtMTEwODQiIG1hc2s9InVybCgjbWFzay0yKSI+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxMS4zNzUsIDEzLjQ4NzUpIj4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cmVjdCBpZD0i6Lev5b6EIiBzdHJva2U9Im5vbmUiIGZpbGw9Im5vbmUiIHg9IjAiIHk9IjAiIHdpZHRoPSIzLjI1IiBoZWlnaHQ9IjMuMjUiPjwvcmVjdD4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWFzayBpZD0ibWFzay01IiBmaWxsPSJ3aGl0ZSI+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx1c2UgeGxpbms6aHJlZj0iI3BhdGgtNCI+PC91c2U+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXNrPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx1c2UgaWQ9Iui3r+W+hCIgc3Ryb2tlPSJub25lIiBmaWxsLW9wYWNpdHk9IjAiIGZpbGw9IiMwMDAwMDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIgeGxpbms6aHJlZj0iI3BhdGgtNCI+PC91c2U+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGcgaWQ9Iue7hC0xMTA4MyIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjEiIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCIgbWFzaz0idXJsKCNtYXNrLTUpIj4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMC42NzcsIDAuMTM1NSkiIGZpbGw9IiNGRkZGRkYiIGlkPSLot6/lvoQtMTAxMjQiPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTAuNDA2Mjc4NDE4LDEuMjUzMTcgTDAuNDA2Mjc4NDE4LDAuNTQxMzgyIEMwLjQwNjI3ODQxOCwwLjI0MjQzMiAwLjY0ODgwMTQxOCwwIDAuOTQ3OTY1NDE4LDAgQzEuMjQ3MTI3NDIsMCAxLjQ4OTY0NzQyLDAuMjQyNDMyIDEuNDg5NjQ3NDIsMC41NDEzODIgTDEuNDg5NjQ3NDIsMS4yNTMxNyBDMS45NTU1OTc0MiwxLjU3NzUxIDIuMDMzNzE3NDIsMi4yMzU5NiAxLjY1NjYxNzQyLDIuNjYwNzcgQzEuMjc5NTM3NDIsMy4wODUyMSAwLjYxNjM5MTQxOCwzLjA4NTIxIDAuMjM5MzE2NDE4LDIuNjYwNzcgQy0wLjEzNzc4OTU4MiwyLjIzNTk2IC0wLjA1OTY2NDQ4MTksMS41Nzc1MSAwLjQwNjI3ODQxOCwxLjI1MzE3IFogTTAuODEyNTI4NDE4LDEuNTA2NzEgQzAuNTQ5MTAwNDE4LDEuNTc1MiAwLjM3NzYyMjQxOCwxLjgyOTEgMC40MTE5NTQ0MTgsMi4wOTkxMiBDMC40NDYyMjU0MTgsMi4zNjkyNiAwLjY3NTY4NzQxOCwyLjU3MjAyIDAuOTQ3OTY1NDE4LDIuNTcyNjMwNTEgQzEuMjIwOTQ3NDIsMi41NzMgMS40NTE0NDc0MiwyLjM3MDI0IDEuNDg1ODM3NDIsMi4wOTk0OSBDMS41MjAyNTc0MiwxLjgyODM3IDEuMzQ3NzQ3NDIsMS41NzQ1OCAxLjA4MzM5NzQyLDEuNTA2NzEgTDEuMDgzMzk3NDIsMC41NDEzODIgTDAuODEyNTI4NDE4LDAuNTQxMzgyIEwwLjgxMjUyODQxOCwxLjUwNjcxIFoiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9nPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZz4KICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZz4KICAgICAgICAgICAgICAgICAgICAgICAgPC9nPgogICAgICAgICAgICAgICAgICAgIDwvZz4KICAgICAgICAgICAgICAgIDwvZz4KICAgICAgICAgICAgPC9nPgogICAgICAgIDwvZz4KICAgIDwvZz4KPC9zdmc+';
144 Editor.saveImage = 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0iYmxhY2siIHdpZHRoPSIxOHB4IiBoZWlnaHQ9IjE4cHgiPjxwYXRoIGQ9Ik0wIDBoMjR2MjRIMHoiIGZpbGw9Im5vbmUiLz48cGF0aCBkPSJNMTkgMTJ2N0g1di03SDN2N2MwIDEuMS45IDIgMiAyaDE0YzEuMSAwIDItLjkgMi0ydi03aC0yem0tNiAuNjdsMi41OS0yLjU4TDE3IDExLjVsLTUgNS01LTUgMS40MS0xLjQxTDExIDEyLjY3VjNoMnoiLz48L3N2Zz4='; 146 Editor.saveImage = 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0iYmxhY2siIHdpZHRoPSIxOHB4IiBoZWlnaHQ9IjE4cHgiPjxwYXRoIGQ9Ik0wIDBoMjR2MjRIMHoiIGZpbGw9Im5vbmUiLz48cGF0aCBkPSJNMTkgMTJ2N0g1di03SDN2N2MwIDEuMS45IDIgMiAyaDE0YzEuMSAwIDItLjkgMi0ydi03aC0yem0tNiAuNjdsMi41OS0yLjU4TDE3IDExLjVsLTUgNS01LTUgMS40MS0xLjQxTDExIDEyLjY3VjNoMnoiLz48L3N2Zz4=';
145 Editor.globeImage = 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0Ij48cGF0aCBkPSJNMTEuOTkgMkM2LjQ3IDIgMiA2LjQ4IDIgMTJzNC40NyAxMCA5Ljk5IDEwQzE3LjUyIDIyIDIyIDE3LjUyIDIyIDEyUzE3LjUyIDIgMTEuOTkgMnptNi45MyA2aC0yLjk1Yy0uMzItMS4yNS0uNzgtMi40NS0xLjM4LTMuNTYgMS44NC42MyAzLjM3IDEuOTEgNC4zMyAzLjU2ek0xMiA0LjA0Yy44MyAxLjIgMS40OCAyLjUzIDEuOTEgMy45NmgtMy44MmMuNDMtMS40MyAxLjA4LTIuNzYgMS45MS0zLjk2ek00LjI2IDE0QzQuMSAxMy4zNiA0IDEyLjY5IDQgMTJzLjEtMS4zNi4yNi0yaDMuMzhjLS4wOC42Ni0uMTQgMS4zMi0uMTQgMiAwIC42OC4wNiAxLjM0LjE0IDJINC4yNnptLjgyIDJoMi45NWMuMzIgMS4yNS43OCAyLjQ1IDEuMzggMy41Ni0xLjg0LS42My0zLjM3LTEuOS00LjMzLTMuNTZ6bTIuOTUtOEg1LjA4Yy45Ni0xLjY2IDIuNDktMi45MyA0LjMzLTMuNTZDOC44MSA1LjU1IDguMzUgNi43NSA4LjAzIDh6TTEyIDE5Ljk2Yy0uODMtMS4yLTEuNDgtMi41My0xLjkxLTMuOTZoMy44MmMtLjQzIDEuNDMtMS4wOCAyLjc2LTEuOTEgMy45NnpNMTQuMzQgMTRIOS42NmMtLjA5LS42Ni0uMTYtMS4zMi0uMTYtMiAwLS42OC4wNy0xLjM1LjE2LTJoNC42OGMuMDkuNjUuMTYgMS4zMi4xNiAyIDAgLjY4LS4wNyAxLjM0LS4xNiAyem0uMjUgNS41NmMuNi0xLjExIDEuMDYtMi4zMSAxLjM4LTMuNTZoMi45NWMtLjk2IDEuNjUtMi40OSAyLjkzLTQuMzMgMy41NnpNMTYuMzYgMTRjLjA4LS42Ni4xNC0xLjMyLjE0LTIgMC0uNjgtLjA2LTEuMzQtLjE0LTJoMy4zOGMuMTYuNjQuMjYgMS4zMS4yNiAycy0uMSAxLjM2LS4yNiAyaC0zLjM4eiIvPjwvc3ZnPg=='; 147 Editor.globeImage = 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0Ij48cGF0aCBkPSJNMTEuOTkgMkM2LjQ3IDIgMiA2LjQ4IDIgMTJzNC40NyAxMCA5Ljk5IDEwQzE3LjUyIDIyIDIyIDE3LjUyIDIyIDEyUzE3LjUyIDIgMTEuOTkgMnptNi45MyA2aC0yLjk1Yy0uMzItMS4yNS0uNzgtMi40NS0xLjM4LTMuNTYgMS44NC42MyAzLjM3IDEuOTEgNC4zMyAzLjU2ek0xMiA0LjA0Yy44MyAxLjIgMS40OCAyLjUzIDEuOTEgMy45NmgtMy44MmMuNDMtMS40MyAxLjA4LTIuNzYgMS45MS0zLjk2ek00LjI2IDE0QzQuMSAxMy4zNiA0IDEyLjY5IDQgMTJzLjEtMS4zNi4yNi0yaDMuMzhjLS4wOC42Ni0uMTQgMS4zMi0uMTQgMiAwIC42OC4wNiAxLjM0LjE0IDJINC4yNnptLjgyIDJoMi45NWMuMzIgMS4yNS43OCAyLjQ1IDEuMzggMy41Ni0xLjg0LS42My0zLjM3LTEuOS00LjMzLTMuNTZ6bTIuOTUtOEg1LjA4Yy45Ni0xLjY2IDIuNDktMi45MyA0LjMzLTMuNTZDOC44MSA1LjU1IDguMzUgNi43NSA4LjAzIDh6TTEyIDE5Ljk2Yy0uODMtMS4yLTEuNDgtMi41My0xLjkxLTMuOTZoMy44MmMtLjQzIDEuNDMtMS4wOCAyLjc2LTEuOTEgMy45NnpNMTQuMzQgMTRIOS42NmMtLjA5LS42Ni0uMTYtMS4zMi0uMTYtMiAwLS42OC4wNy0xLjM1LjE2LTJoNC42OGMuMDkuNjUuMTYgMS4zMi4xNiAyIDAgLjY4LS4wNyAxLjM0LS4xNiAyem0uMjUgNS41NmMuNi0xLjExIDEuMDYtMi4zMSAxLjM4LTMuNTZoMi45NWMtLjk2IDEuNjUtMi40OSAyLjkzLTQuMzMgMy41NnpNMTYuMzYgMTRjLjA4LS42Ni4xNC0xLjMyLjE0LTIgMC0uNjgtLjA2LTEuMzQtLjE0LTJoMy4zOGMuMTYuNjQuMjYgMS4zMS4yNiAycy0uMSAxLjM2LS4yNiAyaC0zLjM4eiIvPjwvc3ZnPg==';
146 Editor.commentImage = 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0Ij48cGF0aCBkPSJNMjEuOTkgNGMwLTEuMS0uODktMi0xLjk5LTJINGMtMS4xIDAtMiAuOS0yIDJ2MTJjMCAxLjEuOSAyIDIgMmgxNGw0IDQtLjAxLTE4ek0xOCAxNEg2di0yaDEydjJ6bTAtM0g2VjloMTJ2MnptMC0zSDZWNmgxMnYyeiIvPjxwYXRoIGQ9Ik0wIDBoMjR2MjRIMHoiIGZpbGw9Im5vbmUiLz48L3N2Zz4='; 148 Editor.commentImage = 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0Ij48cGF0aCBkPSJNMjEuOTkgNGMwLTEuMS0uODktMi0xLjk5LTJINGMtMS4xIDAtMiAuOS0yIDJ2MTJjMCAxLjEuOSAyIDIgMmgxNGw0IDQtLjAxLTE4ek0xOCAxNEg2di0yaDEydjJ6bTAtM0g2VjloMTJ2MnptMC0zSDZWNmgxMnYyeiIvPjxwYXRoIGQ9Ik0wIDBoMjR2MjRIMHoiIGZpbGw9Im5vbmUiLz48L3N2Zz4=';
@@ -167,26 +167,36 @@ LocalFile.prototype.saveFile = function (title, revision, success, error, useCur @@ -167,26 +167,36 @@ LocalFile.prototype.saveFile = function (title, revision, success, error, useCur
167 const handleSaveContent = async () => { 167 const handleSaveContent = async () => {
168 const { doSaveConfigurationContent, configurationId } = useContentData() 168 const { doSaveConfigurationContent, configurationId } = useContentData()
169 try { 169 try {
170 - const allCells = this.ui.editor.graph.getModel().cells || {}  
171 - // const allCells = this.shadowPages  
172 - // .map(item => {  
173 - // console.log(item)  
174 - // return this.ui.editor.graph.createCellLookup([item.root])  
175 - // })  
176 - // .map(obj => Object.values(obj))  
177 - // .reduce((prev, next) => [...prev, ...next], [])  
178 - 170 + const graph = this.ui.editor.graph
  171 + const model = graph.model
  172 + const pages = this.ui.pages
  173 +
  174 + const currentPageContentId = this.ui.currentPage.getId()
  175 + let originalPage
  176 + const contentPageInfos = pages.map(page => {
  177 + this.ui.selectPage(page)
  178 + const cells = model.getChildCells(graph.getDefaultParent())
  179 + const nodeIds = cells.map(cell => cell.getId())
  180 + const contentId = this.ui.currentPage.getId()
  181 +
  182 + if (contentId === currentPageContentId)
  183 + originalPage = page
  184 +
  185 + return {
  186 + nodeIds,
  187 + contentId
  188 + }
  189 + })
  190 + originalPage && this.ui.selectPage(originalPage)
  191 +
179 await doSaveConfigurationContent({ 192 await doSaveConfigurationContent({
180 configurationContentList: [ 193 configurationContentList: [
181 { 194 {
182 id: this.ui.configurationContentId, 195 id: this.ui.configurationContentId,
183 content: savedData, 196 content: savedData,
184 - // contentId: this.ui.configurationContentId,  
185 - contentId: this.ui.currentPage.getId(),  
186 type: 1, 197 type: 1,
187 - // nodeIds: Array.from(new Set(allCells)),  
188 - nodeIds: Object.keys(allCells),  
189 - name: this.ui.currentPage.getName() 198 + name: this.ui.currentPage.getName(),
  199 + contentPageInfos
190 } 200 }
191 ], 201 ],
192 configurationName: this.ui.currentFile.title, 202 configurationName: this.ui.currentFile.title,
@@ -1309,7 +1309,7 @@ operationPassword=操作密码 @@ -1309,7 +1309,7 @@ operationPassword=操作密码
1309 dataSource=数据源 1309 dataSource=数据源
1310 dataInteraction=数据交互 1310 dataInteraction=数据交互
1311 display=显示 1311 display=显示
1312 -actHidden=隐藏 1312 +acrHidden=隐藏
1313 flow=流动 1313 flow=流动
1314 stop=停止 1314 stop=停止
1315 actOpen=开启 1315 actOpen=开启
@@ -165,7 +165,15 @@ function getProxyPrefix() { @@ -165,7 +165,15 @@ function getProxyPrefix() {
165 return window.urlParams.isProxyMode ? window.urlParams.proxyPrefix : '' 165 return window.urlParams.isProxyMode ? window.urlParams.proxyPrefix : ''
166 } 166 }
167 167
168 -const drawioConfig = JSON.parse(localStorage.getItem('.drawio-config') || null) 168 +const drawioConfig = (
  169 + () => {
  170 + try {
  171 + return JSON.parse(localStorage.getItem('.drawio-config') || null)
  172 + } catch {
  173 + return {}
  174 + }
  175 + }
  176 +)()
169 177
170 const localLang = drawioConfig?.language 178 const localLang = drawioConfig?.language
171 179
@@ -13,7 +13,7 @@ enum Api { @@ -13,7 +13,7 @@ enum Api {
13 GET_DEVICE_BY_DEVICE_PROFILED_IDS = '/device/getListByDeviceProfileIds', 13 GET_DEVICE_BY_DEVICE_PROFILED_IDS = '/device/getListByDeviceProfileIds',
14 GET_THINGS_MODEL_SERVICES = '/things_model/get_services/', 14 GET_THINGS_MODEL_SERVICES = '/things_model/get_services/',
15 15
16 - RPC_COMMAND = '/rpc/', 16 + RPC_COMMAND = '/rpc',
17 GET_DEVICE_ACTIVE = '/plugins/telemetry/DEVICE/', 17 GET_DEVICE_ACTIVE = '/plugins/telemetry/DEVICE/',
18 RPC_ONEWAY = '/rpc/oneway', 18 RPC_ONEWAY = '/rpc/oneway',
19 RPC_TWOWAY = '/rpc/twoway', 19 RPC_TWOWAY = '/rpc/twoway',
@@ -25,28 +25,28 @@ export const doSaveNodeAllData = (data: SaveNodeDataParamsType) => { @@ -25,28 +25,28 @@ export const doSaveNodeAllData = (data: SaveNodeDataParamsType) => {
25 } 25 }
26 26
27 export const doSaveNodeAct = (params: SaveNodeActParamsType) => { 27 export const doSaveNodeAct = (params: SaveNodeActParamsType) => {
28 - const { configurationId, contentId, id, data } = params 28 + const { configurationId, contentId, configurationNodeId, data } = params
29 return defHttp.post({ 29 return defHttp.post({
30 url: Api.SAVE_NODE_ACT, 30 url: Api.SAVE_NODE_ACT,
31 - params: { configurationId, contentId, id }, 31 + params: { configurationId, contentId, configurationNodeId },
32 data, 32 data,
33 }) 33 })
34 } 34 }
35 35
36 export const doSaveNodeDataSource = (params: SaveNodeDataSourceParamsType) => { 36 export const doSaveNodeDataSource = (params: SaveNodeDataSourceParamsType) => {
37 - const { configurationId, contentId, id, data } = params 37 + const { configurationId, contentId, configurationNodeId, data } = params
38 return defHttp.post({ 38 return defHttp.post({
39 url: Api.SAVE_NODE_DATASOURCE, 39 url: Api.SAVE_NODE_DATASOURCE,
40 - params: { configurationId, contentId, id }, 40 + params: { configurationId, contentId, configurationNodeId },
41 data, 41 data,
42 }) 42 })
43 } 43 }
44 44
45 export const doSaveNodeEvent = (params: SaveNodeEventParamsType) => { 45 export const doSaveNodeEvent = (params: SaveNodeEventParamsType) => {
46 - const { configurationId, contentId, id, data } = params 46 + const { configurationId, contentId, configurationNodeId, data } = params
47 return defHttp.post({ 47 return defHttp.post({
48 url: Api.SAVE_NODE_EVENT, 48 url: Api.SAVE_NODE_EVENT,
49 - params: { configurationId, contentId, id }, 49 + params: { configurationId, contentId, configurationNodeId },
50 data, 50 data,
51 }) 51 })
52 } 52 }
@@ -11,9 +11,10 @@ export enum DeleteNodeDataTypeEnum { @@ -11,9 +11,10 @@ export enum DeleteNodeDataTypeEnum {
11 } 11 }
12 12
13 export interface BasicNodeBindType { 13 export interface BasicNodeBindType {
14 - id: string  
15 contentId: string 14 contentId: string
  15 + configurationNodeId: string
16 configurationId: string 16 configurationId: string
  17 + id?: string
17 } 18 }
18 19
19 export interface SaveNodeDataParamsType extends BasicNodeBindType { 20 export interface SaveNodeDataParamsType extends BasicNodeBindType {
@@ -45,6 +46,7 @@ export interface NodeDataBasicType { @@ -45,6 +46,7 @@ export interface NodeDataBasicType {
45 enabled: boolean 46 enabled: boolean
46 tenantId: string 47 tenantId: string
47 configurationId: string 48 configurationId: string
  49 + configurationNodeId: string
48 contentId: string 50 contentId: string
49 } 51 }
50 52
1 <script lang="ts" setup> 1 <script lang="ts" setup>
2 import { Button } from 'ant-design-vue' 2 import { Button } from 'ant-design-vue'
3 import { basicProps } from '../props' 3 import { basicProps } from '../props'
  4 +import { useTranslation } from '@/hooks/useTranslation'
4 defineProps(basicProps) 5 defineProps(basicProps)
5 const emit = defineEmits(['ok', 'cancel']) 6 const emit = defineEmits(['ok', 'cancel'])
  7 +
  8 +const { t } = useTranslation()
6 function handleOk(e: Event) { 9 function handleOk(e: Event) {
7 emit('ok', e) 10 emit('ok', e)
8 } 11 }
@@ -16,17 +19,11 @@ function handleCancel(e: Event) { @@ -16,17 +19,11 @@ function handleCancel(e: Event) {
16 <div> 19 <div>
17 <slot name="insertFooter" /> 20 <slot name="insertFooter" />
18 <Button v-if="showCancelBtn" v-bind="cancelButtonProps" @click="handleCancel"> 21 <Button v-if="showCancelBtn" v-bind="cancelButtonProps" @click="handleCancel">
19 - {{ cancelText }} 22 + {{ cancelText || t('cancel') }}
20 </Button> 23 </Button>
21 <slot name="centerFooter" /> 24 <slot name="centerFooter" />
22 - <Button  
23 - v-if="showOkBtn"  
24 - :type="okType"  
25 - :loading="confirmLoading"  
26 - v-bind="okButtonProps"  
27 - @click="handleOk"  
28 - >  
29 - {{ okText }} 25 + <Button v-if="showOkBtn" :type="okType" :loading="confirmLoading" v-bind="okButtonProps" @click="handleOk">
  26 + {{ okText || t('ok') }}
30 </Button> 27 </Button>
31 <slot name="appendFooter" /> 28 <slot name="appendFooter" />
32 </div> 29 </div>
@@ -3,9 +3,7 @@ import type { ButtonProps } from 'ant-design-vue/es/button/buttonTypes' @@ -3,9 +3,7 @@ import type { ButtonProps } from 'ant-design-vue/es/button/buttonTypes'
3 import type { ButtonType } from 'ant-design-vue/lib/button' 3 import type { ButtonType } from 'ant-design-vue/lib/button'
4 import type { VueNode } from 'ant-design-vue/es/_util/type' 4 import type { VueNode } from 'ant-design-vue/es/_util/type'
5 import type { ModalWrapperProps } from './typing' 5 import type { ModalWrapperProps } from './typing'
6 -import { useTranslation } from '@/hooks/useTranslation'  
7 6
8 -const { t } = useTranslation()  
9 export const modalProps = { 7 export const modalProps = {
10 open: { type: Boolean }, 8 open: { type: Boolean },
11 scrollTop: { type: Boolean, default: true }, 9 scrollTop: { type: Boolean, default: true },
@@ -14,8 +12,8 @@ export const modalProps = { @@ -14,8 +12,8 @@ export const modalProps = {
14 // open drag 12 // open drag
15 draggable: { type: Boolean, default: true }, 13 draggable: { type: Boolean, default: true },
16 centered: { type: Boolean }, 14 centered: { type: Boolean },
17 - cancelText: { type: String, default: t('cancel') },  
18 - okText: { type: String, default: t('ok') }, 15 + cancelText: { type: String },
  16 + okText: { type: String },
19 17
20 closeFunc: Function as PropType<() => Promise<boolean>>, 18 closeFunc: Function as PropType<() => Promise<boolean>>,
21 } 19 }
1 <script setup lang="ts"> 1 <script setup lang="ts">
2 import { ref, unref } from 'vue' 2 import { ref, unref } from 'vue'
3 import type { ComponentExposeType } from '../../..' 3 import type { ComponentExposeType } from '../../..'
  4 +import { usePublicFormContext } from '../../../usePublicFormContext'
4 import ImageSettingTable from './ImageSettingTable.vue' 5 import ImageSettingTable from './ImageSettingTable.vue'
5 import { formSchemas } from './config' 6 import { formSchemas } from './config'
6 import { BasicForm, useForm } from '@/components/Form' 7 import { BasicForm, useForm } from '@/components/Form'
7 import { FormLayoutEnum } from '@/components/Form/src/enum' 8 import { FormLayoutEnum } from '@/components/Form/src/enum'
8 import type { RangeItemType, VariableImageActDataType } from '@/api/node/model' 9 import type { RangeItemType, VariableImageActDataType } from '@/api/node/model'
  10 +import { NodeUtils } from '@/hooks/business/useNodeUtils'
  11 +import type { ImageSelectorDataType } from '@/core/Library/components/ImageSelector'
  12 +import { CellAttributeKeyEnum } from '@/enums/cellAttributeEnum'
9 13
10 const imageSettingTableElRef = ref<InstanceType<typeof ImageSettingTable>>() 14 const imageSettingTableElRef = ref<InstanceType<typeof ImageSettingTable>>()
11 15
  16 +const { getCellInfo } = usePublicFormContext()
  17 +
  18 +const nodeUtils = new NodeUtils()
  19 +
12 const [register, formActionType] = useForm({ 20 const [register, formActionType] = useForm({
13 schemas: formSchemas, 21 schemas: formSchemas,
14 showActionButtonGroup: false, 22 showActionButtonGroup: false,
@@ -16,6 +24,17 @@ const [register, formActionType] = useForm({ @@ -16,6 +24,17 @@ const [register, formActionType] = useForm({
16 baseColProps: { span: 12 }, 24 baseColProps: { span: 12 },
17 }) 25 })
18 26
  27 +function savaDefaultImageToNodeAttribute(defaultImages: ImageSelectorDataType) {
  28 + const node = nodeUtils.getCellById(unref(getCellInfo).id)
  29 +
  30 + if (!node)
  31 + return
  32 +
  33 + node.setAttribute(CellAttributeKeyEnum.DEFAULT_IMAGE, JSON.stringify(defaultImages))
  34 +
  35 + nodeUtils.refreshCell(node)
  36 +}
  37 +
19 const validate = async () => { 38 const validate = async () => {
20 await formActionType.validate() 39 await formActionType.validate()
21 await unref(imageSettingTableElRef)?.validate() 40 await unref(imageSettingTableElRef)?.validate()
@@ -24,6 +43,8 @@ const validate = async () => { @@ -24,6 +43,8 @@ const validate = async () => {
24 const getFieldsValue = (): VariableImageActDataType => { 43 const getFieldsValue = (): VariableImageActDataType => {
25 const value = formActionType.getFieldsValue() as VariableImageActDataType 44 const value = formActionType.getFieldsValue() as VariableImageActDataType
26 const tableValue = unref(imageSettingTableElRef)?.getFieldsValue() as RangeItemType[] 45 const tableValue = unref(imageSettingTableElRef)?.getFieldsValue() as RangeItemType[]
  46 +
  47 + savaDefaultImageToNodeAttribute(value.defaultImage)
27 return { 48 return {
28 ...value, 49 ...value,
29 rangeList: tableValue, 50 rangeList: tableValue,
@@ -51,11 +72,11 @@ defineExpose<ComponentExposeType>({ @@ -51,11 +72,11 @@ defineExpose<ComponentExposeType>({
51 </template> 72 </template>
52 73
53 <style lang="less" scoped> 74 <style lang="less" scoped>
54 - .variable-image-form {  
55 - >:deep(.ant-row) {  
56 - >.ant-col {  
57 - @apply px-4;  
58 - } 75 +.variable-image-form {
  76 + >:deep(.ant-row) {
  77 + >.ant-col {
  78 + @apply px-4;
59 } 79 }
60 } 80 }
  81 +}
61 </style> 82 </style>
@@ -17,7 +17,7 @@ export const tableColumns = (): BasicColumn[] => { @@ -17,7 +17,7 @@ export const tableColumns = (): BasicColumn[] => {
17 title: t('state'), 17 title: t('state'),
18 dataIndex: 'type', 18 dataIndex: 'type',
19 format(text) { 19 format(text) {
20 - return ActRangListItemTypeNameEnum[text as ActRangListItemTypeEnum] 20 + return t(ActRangListItemTypeNameEnum[text as ActRangListItemTypeEnum])
21 }, 21 },
22 }, 22 },
23 { 23 {
@@ -52,6 +52,7 @@ async function getResult() { @@ -52,6 +52,7 @@ async function getResult() {
52 objectModel: unref(objectModelTsl), 52 objectModel: unref(objectModelTsl),
53 deviceDetail: unref(deviceInfo), 53 deviceDetail: unref(deviceInfo),
54 value, 54 value,
  55 + way: unref(commandWay),
55 }) 56 })
56 57
57 const { createMessage } = useMessage() 58 const { createMessage } = useMessage()
@@ -37,7 +37,7 @@ export const getFormSchemas = (event: EventTypeEnum): FormSchema[] => { @@ -37,7 +37,7 @@ export const getFormSchemas = (event: EventTypeEnum): FormSchema[] => {
37 componentProps: { 37 componentProps: {
38 allowClear: false, 38 allowClear: false,
39 options: [ 39 options: [
40 - { label: EventTypeNameEnum[event], value: EventTypeEnum[event] }, 40 + { label: t(EventTypeNameEnum[event]), value: EventTypeEnum[event] },
41 ], 41 ],
42 }, 42 },
43 }, 43 },
@@ -177,8 +177,8 @@ defineExpose<ComponentExposeType>({ @@ -177,8 +177,8 @@ defineExpose<ComponentExposeType>({
177 :validate-status="getValidateStatus(record[TableColumnFieldEnum.DEVICE_PROFILE_ID])" 177 :validate-status="getValidateStatus(record[TableColumnFieldEnum.DEVICE_PROFILE_ID])"
178 > 178 >
179 <Select 179 <Select
180 - v-model:value="record[TableColumnFieldEnum.DEVICE_PROFILE_ID]" :options="productList" :field-names="{ label: 'name', value: 'profileId' }" placeholder="请选择产品"  
181 - class="w-full" 180 + v-model:value="record[TableColumnFieldEnum.DEVICE_PROFILE_ID]" :options="productList"
  181 + :field-names="{ label: 'name', value: 'profileId' }" placeholder="请选择产品" class="w-full"
182 @change="(value, option) => handleSelectProduct(value, option, record as TableRecordItemType)" 182 @change="(value, option) => handleSelectProduct(value, option, record as TableRecordItemType)"
183 /> 183 />
184 </FormItem> 184 </FormItem>
@@ -189,8 +189,8 @@ defineExpose<ComponentExposeType>({ @@ -189,8 +189,8 @@ defineExpose<ComponentExposeType>({
189 :validate-status="getValidateStatus(record[TableColumnFieldEnum.DEVICE_ID])" 189 :validate-status="getValidateStatus(record[TableColumnFieldEnum.DEVICE_ID])"
190 > 190 >
191 <Select 191 <Select
192 - v-model:value="record[TableColumnFieldEnum.DEVICE_ID]" :options="deviceList" :placeholder="t('chooseDevice')"  
193 - class="w-full" 192 + v-model:value="record[TableColumnFieldEnum.DEVICE_ID]" :options="deviceList"
  193 + :placeholder="t('chooseDevice')" class="w-full"
194 @change="(value, option) => handleSelectDevice(value, option, record as TableRecordItemType)" 194 @change="(value, option) => handleSelectDevice(value, option, record as TableRecordItemType)"
195 /> 195 />
196 </FormItem> 196 </FormItem>
@@ -198,8 +198,8 @@ defineExpose<ComponentExposeType>({ @@ -198,8 +198,8 @@ defineExpose<ComponentExposeType>({
198 <template v-if="column.key === TableColumnFieldEnum.WAY"> 198 <template v-if="column.key === TableColumnFieldEnum.WAY">
199 <RadioGroup 199 <RadioGroup
200 v-model:value="record[TableColumnFieldEnum.WAY]" :options="[ 200 v-model:value="record[TableColumnFieldEnum.WAY]" :options="[
201 - { label: CommandWayNameEnum.ONE_WAY, value: CommandWayEnum.ONE_WAY },  
202 - { label: CommandWayNameEnum.TWO_WAY, value: CommandWayEnum.TWO_WAY }, 201 + { label: t(CommandWayNameEnum.ONE_WAY), value: CommandWayEnum.ONE_WAY },
  202 + { label: t(CommandWayNameEnum.TWO_WAY), value: CommandWayEnum.TWO_WAY },
203 ]" 203 ]"
204 /> 204 />
205 </template> 205 </template>
@@ -2,6 +2,7 @@ import { isBoolean } from '@wry-smile/utils-is' @@ -2,6 +2,7 @@ import { isBoolean } from '@wry-smile/utils-is'
2 import type { BasicContentComponentProps } from '../..' 2 import type { BasicContentComponentProps } from '../..'
3 import type { PublicFormSettingType } from '../../..' 3 import type { PublicFormSettingType } from '../../..'
4 import { DataSourceTypeEnum, EventTypeEnum, EventTypeNameEnum } from '@/enums/datasource' 4 import { DataSourceTypeEnum, EventTypeEnum, EventTypeNameEnum } from '@/enums/datasource'
  5 +import { useTranslation } from '@/hooks/useTranslation'
5 6
6 export interface DynamicEffectItemType { 7 export interface DynamicEffectItemType {
7 label: string 8 label: string
@@ -10,29 +11,31 @@ export interface DynamicEffectItemType { @@ -10,29 +11,31 @@ export interface DynamicEffectItemType {
10 componentProps?: BasicContentComponentProps 11 componentProps?: BasicContentComponentProps
11 } 12 }
12 13
  14 +const { t } = useTranslation()
  15 +
13 export const getEventItem = (formSetting?: PublicFormSettingType): DynamicEffectItemType[] => { 16 export const getEventItem = (formSetting?: PublicFormSettingType): DynamicEffectItemType[] => {
14 const list = [ 17 const list = [
15 { 18 {
16 - label: EventTypeNameEnum.DOWN, 19 + label: t(EventTypeNameEnum.DOWN),
17 key: EventTypeEnum.DOWN, 20 key: EventTypeEnum.DOWN,
18 component: () => import('./MouseDownOrUpSetting/index.vue'), 21 component: () => import('./MouseDownOrUpSetting/index.vue'),
19 componentProps: { event: EventTypeEnum.DOWN, type: DataSourceTypeEnum.EVENT }, 22 componentProps: { event: EventTypeEnum.DOWN, type: DataSourceTypeEnum.EVENT },
20 }, 23 },
21 { 24 {
22 - label: EventTypeNameEnum.UP, 25 + label: t(EventTypeNameEnum.UP),
23 key: EventTypeEnum.UP, 26 key: EventTypeEnum.UP,
24 component: () => import('./MouseDownOrUpSetting/index.vue'), 27 component: () => import('./MouseDownOrUpSetting/index.vue'),
25 componentProps: { event: EventTypeEnum.UP, type: DataSourceTypeEnum.EVENT }, 28 componentProps: { event: EventTypeEnum.UP, type: DataSourceTypeEnum.EVENT },
26 29
27 }, 30 },
28 { 31 {
29 - label: EventTypeNameEnum.SINGLE, 32 + label: t(EventTypeNameEnum.SINGLE),
30 key: EventTypeEnum.SINGLE, 33 key: EventTypeEnum.SINGLE,
31 component: () => import('./SingleClickOrDoubleClickSetting/index.vue'), 34 component: () => import('./SingleClickOrDoubleClickSetting/index.vue'),
32 componentProps: { event: EventTypeEnum.SINGLE, type: DataSourceTypeEnum.EVENT }, 35 componentProps: { event: EventTypeEnum.SINGLE, type: DataSourceTypeEnum.EVENT },
33 }, 36 },
34 { 37 {
35 - label: EventTypeNameEnum.DOUBLE, 38 + label: t(EventTypeNameEnum.DOUBLE),
36 key: EventTypeEnum.DOUBLE, 39 key: EventTypeEnum.DOUBLE,
37 component: () => import('./SingleClickOrDoubleClickSetting/index.vue'), 40 component: () => import('./SingleClickOrDoubleClickSetting/index.vue'),
38 componentProps: { event: EventTypeEnum.DOUBLE, type: DataSourceTypeEnum.EVENT }, 41 componentProps: { event: EventTypeEnum.DOUBLE, type: DataSourceTypeEnum.EVENT },
@@ -7,9 +7,10 @@ import type { ModalProps } from '@/components/Modal' @@ -7,9 +7,10 @@ import type { ModalProps } from '@/components/Modal'
7 import { BasicModal, useModalInner } from '@/components/Modal' 7 import { BasicModal, useModalInner } from '@/components/Modal'
8 import type { ActTypeEnum, EventTypeEnum } from '@/enums/datasource' 8 import type { ActTypeEnum, EventTypeEnum } from '@/enums/datasource'
9 import { DataSourceTypeEnum } from '@/enums/datasource' 9 import { DataSourceTypeEnum } from '@/enums/datasource'
10 -import type { NodeDataActJsonType, NodeDataEventJsonType, SingleClickEventDataType } from '@/api/node/model' 10 +import type { NodeDataActJsonType, NodeDataEventJsonType } from '@/api/node/model'
11 import { useContentDataStoreWithOut } from '@/store/modules/contentData' 11 import { useContentDataStoreWithOut } from '@/store/modules/contentData'
12 import { useTranslation } from '@/hooks/useTranslation' 12 import { useTranslation } from '@/hooks/useTranslation'
  13 +import { BasicComponentEnum } from '@/core/Library/packages/Basic'
13 14
14 defineEmits(['register']) 15 defineEmits(['register'])
15 16
@@ -17,7 +18,7 @@ const { t } = useTranslation() @@ -17,7 +18,7 @@ const { t } = useTranslation()
17 18
18 const contentDataStore = useContentDataStoreWithOut() 19 const contentDataStore = useContentDataStoreWithOut()
19 20
20 -const { getNodeData, getNodeAllData, saveNodeAllData } = usePublicFormContext() 21 +const { getNodeData, getNodeAllData, saveNodeAllData, getCellInfo } = usePublicFormContext()
21 22
22 const contentComponent = shallowRef() 23 const contentComponent = shallowRef()
23 24
@@ -63,6 +64,10 @@ const handleOk = async () => { @@ -63,6 +64,10 @@ const handleOk = async () => {
63 await handleDoSaveEventData() 64 await handleDoSaveEventData()
64 65
65 await getNodeAllData() 66 await getNodeAllData()
  67 +
  68 + if (unref(getCellInfo).componentKey === BasicComponentEnum.VARIABLE_IMAGE)
  69 + window.DrawApp?.saveButton.click()
  70 +
66 closeModal() 71 closeModal()
67 contentComponent.value = null 72 contentComponent.value = null
68 } 73 }
@@ -93,7 +98,10 @@ const handleCancel = () => { @@ -93,7 +98,10 @@ const handleCancel = () => {
93 <template> 98 <template>
94 <BasicModal destroy-on-close v-bind="modalProps" @register="register" @ok="handleOk" @cancel="handleCancel"> 99 <BasicModal destroy-on-close v-bind="modalProps" @register="register" @ok="handleOk" @cancel="handleCancel">
95 <!-- <Spin :spinning="spinning"> --> 100 <!-- <Spin :spinning="spinning"> -->
96 - <component :is="contentComponent" v-bind="componentProps" ref="componentInstance" @vue:mounted="handleComponentMounted" /> 101 + <component
  102 + :is="contentComponent" v-bind="componentProps" ref="componentInstance"
  103 + @vue:mounted="handleComponentMounted"
  104 + />
97 <!-- </Spin> --> 105 <!-- </Spin> -->
98 <!-- --> 106 <!-- -->
99 </BasicModal> 107 </BasicModal>
@@ -219,10 +219,13 @@ createPublicFormContext(nodeDataActinType) @@ -219,10 +219,13 @@ createPublicFormContext(nodeDataActinType)
219 <Divider orientation="left"> 219 <Divider orientation="left">
220 {{ t('dataInteraction') }} 220 {{ t('dataInteraction') }}
221 </Divider> 221 </Divider>
222 - <DataEvents ref="dataEventsElRef" :before-click="handleBeforeOpenEventOrActModal" :form-setting="getFormSetting" /> 222 + <DataEvents
  223 + ref="dataEventsElRef" :before-click="handleBeforeOpenEventOrActModal"
  224 + :form-setting="getFormSetting"
  225 + />
223 <div 226 <div
224 - v-if="getCellInfo.category === PackageCategoryEnum.CONTROL" class="flex flex-col justify-center passwordInput"  
225 - :class="getFormSetting?.actSetting === false && 'mb-4'" 227 + v-if="getCellInfo.category === PackageCategoryEnum.CONTROL"
  228 + class="flex flex-col justify-center passwordInput" :class="getFormSetting?.actSetting === false && 'mb-4'"
226 > 229 >
227 <Checkbox v-model:checked="operationPassword.checked" :disabled="getSetPasswordStatus"> 230 <Checkbox v-model:checked="operationPassword.checked" :disabled="getSetPasswordStatus">
228 <div class="flex"> 231 <div class="flex">
@@ -254,10 +257,10 @@ createPublicFormContext(nodeDataActinType) @@ -254,10 +257,10 @@ createPublicFormContext(nodeDataActinType)
254 257
255 <style lang="less" scoped> 258 <style lang="less" scoped>
256 .form-container { 259 .form-container {
257 -@apply text-sm; 260 + @apply text-sm;
258 261
259 :deep(.ant-divider) { 262 :deep(.ant-divider) {
260 - @apply text-sm; 263 + @apply text-sm;
261 } 264 }
262 } 265 }
263 266
@@ -52,17 +52,23 @@ export function useNodeData({ cell, immediate = true }: UseNodeDataParamsType) { @@ -52,17 +52,23 @@ export function useNodeData({ cell, immediate = true }: UseNodeDataParamsType) {
52 } 52 }
53 53
54 const basicNodeBindData = (type: ActionType): BasicNodeBindType => { 54 const basicNodeBindData = (type: ActionType): BasicNodeBindType => {
55 - return {  
56 - id: type === ActionType.GET ? getSourceCellID () || getCellID () : getCellID(), 55 + const res: BasicNodeBindType = {
  56 + configurationNodeId: type === ActionType.GET ? getSourceCellID() || getCellID() : getCellID(),
57 contentId: window.DrawApp.currentPage.getId(), 57 contentId: window.DrawApp.currentPage.getId(),
58 configurationId, 58 configurationId,
59 } 59 }
  60 +
  61 + if (unref(nodeData)?.id)
  62 + res.id = unref(nodeData)?.id
  63 +
  64 + return res
60 } 65 }
61 66
62 const getCellInfo = computed(() => { 67 const getCellInfo = computed(() => {
63 return { 68 return {
64 [CellAttributeKeyEnum.CATEGORY]: cell.getAttribute(CellAttributeKeyEnum.CATEGORY), 69 [CellAttributeKeyEnum.CATEGORY]: cell.getAttribute(CellAttributeKeyEnum.CATEGORY),
65 [CellAttributeKeyEnum.COMPONENT_KEY]: cell.getAttribute(CellAttributeKeyEnum.COMPONENT_KEY), 70 [CellAttributeKeyEnum.COMPONENT_KEY]: cell.getAttribute(CellAttributeKeyEnum.COMPONENT_KEY),
  71 + id: cell.getId(),
66 } 72 }
67 }) 73 })
68 74
@@ -88,7 +88,7 @@ export function useNodeEvent(eventJson: NodeDataEventJsonType, dataSourceJson: N @@ -88,7 +88,7 @@ export function useNodeEvent(eventJson: NodeDataEventJsonType, dataSourceJson: N
88 88
89 if (nodeUtils.getNodeComponentKey(cell) === ControlComponentEnum.SWITCH) { 89 if (nodeUtils.getNodeComponentKey(cell) === ControlComponentEnum.SWITCH) {
90 const contentDataStore = useContentDataStoreWithOut() 90 const contentDataStore = useContentDataStoreWithOut()
91 - const currentData = contentDataStore.contentData.find(item => item.id === cell.getId()) 91 + const currentData = contentDataStore.contentData.find(item => item.configurationNodeId === cell.getId())
92 if (!currentData) return 92 if (!currentData) return
93 const { actJson } = currentData 93 const { actJson } = currentData
94 const { rangeList } = actJson.STATUS_SETTING 94 const { rangeList } = actJson.STATUS_SETTING
@@ -33,7 +33,7 @@ const initOptions = reactive<{ @@ -33,7 +33,7 @@ const initOptions = reactive<{
33 const { t } = useTranslation() 33 const { t } = useTranslation()
34 const fetchAlarmListConfig = computed(() => { 34 const fetchAlarmListConfig = computed(() => {
35 return contentDataStore?.contentData.find((item) => { 35 return contentDataStore?.contentData.find((item) => {
36 - return props.config.cellInfo?.id === item.id 36 + return props.config.cellInfo?.id === item.configurationNodeId
37 }) 37 })
38 }) 38 })
39 39
1 <script setup lang="ts"> 1 <script setup lang="ts">
2 import { ref } from 'vue' 2 import { ref } from 'vue'
3 -import type { RenderComponentExposeType } from '@/core/Library/types' 3 +import type { RenderComponentExposeType, RenderComponentProps } from '@/core/Library/types'
4 import type { CommandSource } from '@/core/websocket/processor' 4 import type { CommandSource } from '@/core/websocket/processor'
5 import { NodeUtils } from '@/hooks/business/useNodeUtils' 5 import { NodeUtils } from '@/hooks/business/useNodeUtils'
6 import { getMeetTheConditionsRange } from '@/core/Library/utils' 6 import { getMeetTheConditionsRange } from '@/core/Library/utils'
@@ -9,8 +9,29 @@ import type { VariableImageActDataType } from '@/api/node/model' @@ -9,8 +9,29 @@ import type { VariableImageActDataType } from '@/api/node/model'
9 import { useLatestMessageValue } from '@/core/Library/hook/useLatestMessageValue' 9 import { useLatestMessageValue } from '@/core/Library/hook/useLatestMessageValue'
10 import { useOnMessage } from '@/core/Library/hook/useOnMessage' 10 import { useOnMessage } from '@/core/Library/hook/useOnMessage'
11 import type { SubscriptionUpdateMsg } from '@/core/websocket/type/message' 11 import type { SubscriptionUpdateMsg } from '@/core/websocket/type/message'
  12 +import { CellAttributeKeyEnum } from '@/enums/cellAttributeEnum'
  13 +import { useJsonParse } from '@/hooks/business/useJSONParse'
  14 +import type { ImageSelectorDataType } from '@/core/Library/components/ImageSelector'
12 15
13 -const imgSrc = ref('data:image/svg+xml,%3Csvg xmlns="http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg" width="48" height="48" viewBox="0 0 48 48"%3E%3Cpath fill="%238CBCD6" d="M31 41H8c-2.2 0-4-1.8-4-4V11c0-2.2 1.8-4 4-4h32c2.2 0 4 1.8 4 4v17c0 7.2-5.8 13-13 13z"%2F%3E%3Ccircle cx="35" cy="16" r="3" fill="%23B3DDF5"%2F%3E%3Cpath fill="%239AC9E3" d="M20 16L9 32h22z"%2F%3E%3Cpath fill="%23B3DDF5" d="m31 22l-8 10h16z"%2F%3E%3Cpath fill="%23E57373" d="m47.7 29.1l-2.8-2.8c-.4-.4-1.1-.4-1.6 0L42 27.6l4.4 4.4l1.3-1.3c.4-.4.4-1.1 0-1.6z"%2F%3E%3Cpath fill="%23FF9800" d="M27.467 42.167L39.77 29.865l4.384 4.384L31.85 46.55z"%2F%3E%3Cpath fill="%23B0BEC5" d="m46.4 32.038l-2.192 2.192l-4.383-4.384l2.192-2.191z"%2F%3E%3Cpath fill="%23FFC107" d="M27.5 42.2L26 48l5.8-1.5z"%2F%3E%3Cpath fill="%2337474F" d="m26.7 45l-.7 3l3-.7z"%2F%3E%3C%2Fsvg%3E') 16 +const props = defineProps<RenderComponentProps>()
  17 +const nodeUtils = new NodeUtils()
  18 +
  19 +const imgSrc = ref(getDefaultImage() || 'data:image/svg+xml,%3Csvg xmlns="http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg" width="48" height="48" viewBox="0 0 48 48"%3E%3Cpath fill="%238CBCD6" d="M31 41H8c-2.2 0-4-1.8-4-4V11c0-2.2 1.8-4 4-4h32c2.2 0 4 1.8 4 4v17c0 7.2-5.8 13-13 13z"%2F%3E%3Ccircle cx="35" cy="16" r="3" fill="%23B3DDF5"%2F%3E%3Cpath fill="%239AC9E3" d="M20 16L9 32h22z"%2F%3E%3Cpath fill="%23B3DDF5" d="m31 22l-8 10h16z"%2F%3E%3Cpath fill="%23E57373" d="m47.7 29.1l-2.8-2.8c-.4-.4-1.1-.4-1.6 0L42 27.6l4.4 4.4l1.3-1.3c.4-.4.4-1.1 0-1.6z"%2F%3E%3Cpath fill="%23FF9800" d="M27.467 42.167L39.77 29.865l4.384 4.384L31.85 46.55z"%2F%3E%3Cpath fill="%23B0BEC5" d="m46.4 32.038l-2.192 2.192l-4.383-4.384l2.192-2.191z"%2F%3E%3Cpath fill="%23FFC107" d="M27.5 42.2L26 48l5.8-1.5z"%2F%3E%3Cpath fill="%2337474F" d="m26.7 45l-.7 3l3-.7z"%2F%3E%3C%2Fsvg%3E')
  20 +
  21 +function getDefaultImage() {
  22 + const cell = nodeUtils.getCellById(props.config.cellInfo!.id)
  23 +
  24 + if (!cell) return
  25 +
  26 + const defaultImage = cell.getAttribute(CellAttributeKeyEnum.DEFAULT_IMAGE)
  27 +
  28 + if (!defaultImage)
  29 + return
  30 +
  31 + const { imageSource, libPath, path } = useJsonParse(defaultImage).value as ImageSelectorDataType
  32 +
  33 + return imageSource === VariableImageSourceEnum.GALLERY ? libPath : path
  34 +}
14 35
15 const onReceiveActMessage = (commandSource: CommandSource, message: SubscriptionUpdateMsg) => { 36 const onReceiveActMessage = (commandSource: CommandSource, message: SubscriptionUpdateMsg) => {
16 const { node, data, type } = commandSource 37 const { node, data, type } = commandSource
@@ -50,6 +71,6 @@ defineExpose<RenderComponentExposeType>({ @@ -50,6 +71,6 @@ defineExpose<RenderComponentExposeType>({
50 71
51 <template> 72 <template>
52 <div class="w-full h-full flex justify-center items-center"> 73 <div class="w-full h-full flex justify-center items-center">
53 - <img class="w-full" :src="imgSrc"> 74 + <img class="w-full h-full object-contain" :src="imgSrc">
54 </div> 75 </div>
55 </template> 76 </template>
@@ -53,7 +53,8 @@ export const getVideoTypeByUrl = (url: string) => { @@ -53,7 +53,8 @@ export const getVideoTypeByUrl = (url: string) => {
53 export async function getPlayUrl( 53 export async function getPlayUrl(
54 params: VideoItemRecordType, 54 params: VideoItemRecordType,
55 ): Promise<Undefineable<{ url: string; type: StreamType }>> { 55 ): Promise<Undefineable<{ url: string; type: StreamType }>> {
56 - const { accessMode } = params 56 + let { accessMode } = params
  57 + accessMode = Number(accessMode)
57 if (accessMode === VideoAccessModeEnum.ManuallyEnter) { 58 if (accessMode === VideoAccessModeEnum.ManuallyEnter) {
58 const { videoUrl } = params 59 const { videoUrl } = params
59 if (params.videoUrl) { 60 if (params.videoUrl) {
@@ -99,7 +99,7 @@ const [register, { getFieldsValue, validate, setFieldsValue }] = useForm({ @@ -99,7 +99,7 @@ const [register, { getFieldsValue, validate, setFieldsValue }] = useForm({
99 { 99 {
100 field: VideoFormFieldsEnum.ACCESS_MODE, 100 field: VideoFormFieldsEnum.ACCESS_MODE,
101 label: t(VideoFormFieldsNameEnum.ACCESS_MODE), 101 label: t(VideoFormFieldsNameEnum.ACCESS_MODE),
102 - component: ComponentEnum.INPUT, 102 + component: ComponentEnum.INPUT_NUMBER,
103 ifShow: false, 103 ifShow: false,
104 }, 104 },
105 { 105 {
@@ -25,7 +25,7 @@ const loading = ref(false) @@ -25,7 +25,7 @@ const loading = ref(false)
25 // 存储视频数据 25 // 存储视频数据
26 const videoConfig = computed(() => { 26 const videoConfig = computed(() => {
27 return contentDataStore?.contentData.filter((item) => { 27 return contentDataStore?.contentData.filter((item) => {
28 - return props.config.cellInfo?.id === item.id 28 + return props.config.cellInfo?.id === item.configurationNodeId
29 }) 29 })
30 }) 30 })
31 31
1 export enum BasicComponentEnum { 1 export enum BasicComponentEnum {
2 TITLE = 'Title', 2 TITLE = 'Title',
3 VARIABLE = 'Variable', 3 VARIABLE = 'Variable',
  4 + VARIABLE_IMAGE = 'VariableImage',
4 } 5 }
5 6
6 export enum BasicComponentNameEnum { 7 export enum BasicComponentNameEnum {
7 TITLE = '标题', 8 TITLE = '标题',
8 VARIABLE = '变量', 9 VARIABLE = '变量',
  10 + VARIABLE_IMAGE = '变量图片',
  11 +
9 } 12 }
@@ -30,10 +30,10 @@ export default class Config implements CreateComponentType { @@ -30,10 +30,10 @@ export default class Config implements CreateComponentType {
30 } 30 }
31 31
32 export const dataSubscribers: ComponentConfigModuleType['dataSubscribers'] = (telemetryService, nodeData) => { 32 export const dataSubscribers: ComponentConfigModuleType['dataSubscribers'] = (telemetryService, nodeData) => {
33 - const { dataSourceJson, id } = nodeData 33 + const { dataSourceJson, configurationNodeId } = nodeData
34 const { deviceId, attr, chartOption } = dataSourceJson 34 const { deviceId, attr, chartOption } = dataSourceJson
35 const { agg, interval, effectScope = 0 } = chartOption! 35 const { agg, interval, effectScope = 0 } = chartOption!
36 - const subscribe = TelemetrySubscriber.createHistorySubscription(telemetryService, { id: deviceId, entityType: EntityType.DEVICE }, attr, telemetryService.getCommandSource(id, DataSourceTypeEnum.DATASOURCE, dataSourceJson)) 36 + const subscribe = TelemetrySubscriber.createHistorySubscription(telemetryService, { id: deviceId, entityType: EntityType.DEVICE }, attr, telemetryService.getCommandSource(configurationNodeId, DataSourceTypeEnum.DATASOURCE, dataSourceJson))
37 37
38 const subscriptionCommand = subscribe.subscriptionCommand as HistorySubscriptionCmd 38 const subscriptionCommand = subscribe.subscriptionCommand as HistorySubscriptionCmd
39 subscriptionCommand.agg = agg 39 subscriptionCommand.agg = agg
@@ -30,15 +30,15 @@ export default class Config implements CreateComponentType { @@ -30,15 +30,15 @@ export default class Config implements CreateComponentType {
30 } 30 }
31 31
32 export const dataSubscribers: ComponentConfigModuleType['dataSubscribers'] = (telemetryService, nodeData) => { 32 export const dataSubscribers: ComponentConfigModuleType['dataSubscribers'] = (telemetryService, nodeData) => {
33 - const { dataSourceJson, id } = nodeData 33 + const { dataSourceJson, configurationNodeId } = nodeData
34 const { deviceId, attr, chartOption } = dataSourceJson 34 const { deviceId, attr, chartOption } = dataSourceJson
35 const { agg, interval, effectScope = 0, queryType } = chartOption! 35 const { agg, interval, effectScope = 0, queryType } = chartOption!
36 36
37 let subscribe 37 let subscribe
38 if (queryType === SocketSubscriberEnum.HISTORY_CMDS) 38 if (queryType === SocketSubscriberEnum.HISTORY_CMDS)
39 - subscribe = TelemetrySubscriber.createHistorySubscription(telemetryService, { id: deviceId, entityType: EntityType.DEVICE }, attr, telemetryService.getCommandSource(id, DataSourceTypeEnum.DATASOURCE, dataSourceJson)) 39 + subscribe = TelemetrySubscriber.createHistorySubscription(telemetryService, { id: deviceId, entityType: EntityType.DEVICE }, attr, telemetryService.getCommandSource(configurationNodeId, DataSourceTypeEnum.DATASOURCE, dataSourceJson))
40 else 40 else
41 - subscribe = TelemetrySubscriber.createTimeseriesSubscription(telemetryService, { id: deviceId, entityType: EntityType.DEVICE }, attr, telemetryService.getCommandSource(id, DataSourceTypeEnum.DATASOURCE, dataSourceJson)) 41 + subscribe = TelemetrySubscriber.createTimeseriesSubscription(telemetryService, { id: deviceId, entityType: EntityType.DEVICE }, attr, telemetryService.getCommandSource(configurationNodeId, DataSourceTypeEnum.DATASOURCE, dataSourceJson))
42 42
43 const subscriptionCommand = subscribe.subscriptionCommand as HistorySubscriptionCmd 43 const subscriptionCommand = subscribe.subscriptionCommand as HistorySubscriptionCmd
44 subscriptionCommand.agg = agg 44 subscriptionCommand.agg = agg
@@ -101,4 +101,3 @@ createPublicFormContext(nodeDataActinType) @@ -101,4 +101,3 @@ createPublicFormContext(nodeDataActinType)
101 } 101 }
102 } 102 }
103 </style> 103 </style>
104 -  
  1 +import { isFromEdge } from './useParseParams'
1 import { getCurrentRolePermission } from '@/api/sys' 2 import { getCurrentRolePermission } from '@/api/sys'
2 import { useContentDataStoreWithOut } from '@/store/modules/contentData' 3 import { useContentDataStoreWithOut } from '@/store/modules/contentData'
3 import { isShareMode } from '@/utils/env' 4 import { isShareMode } from '@/utils/env'
@@ -6,6 +7,10 @@ export function useAuth() { @@ -6,6 +7,10 @@ export function useAuth() {
6 const contentDataStore = useContentDataStoreWithOut() 7 const contentDataStore = useContentDataStoreWithOut()
7 const getAuthInfo = async () => { 8 const getAuthInfo = async () => {
8 const result = { permissions: [] as string[], hasPreview: true, hasDesign: true } 9 const result = { permissions: [] as string[], hasPreview: true, hasDesign: true }
  10 +
  11 + if (isFromEdge())
  12 + return Object.assign(result, { hasDesignAuth: true, hasPreviewAuth: true })
  13 +
9 if (isShareMode()) return result 14 if (isShareMode()) return result
10 15
11 const permissions = await getCurrentRolePermission() 16 const permissions = await getCurrentRolePermission()
  1 +import { isFromEdge } from './useParseParams'
1 import type { PlatformInfo } from '#/store' 2 import type { PlatformInfo } from '#/store'
2 -import { PLATFORM_INFO_CACHE_KEY } from '@/enums/cacheEnum' 3 +import { APP_LOCAL_CACHE_KEY, EDGE_PLATFORM_INFO_CACHE_KEY, PLATFORM_INFO_CACHE_KEY } from '@/enums/cacheEnum'
3 import { createStorage } from '@/utils/cache' 4 import { createStorage } from '@/utils/cache'
4 import { getPlatformInfo as getPlatform } from '@/api/sys' 5 import { getPlatformInfo as getPlatform } from '@/api/sys'
5 6
6 -const storage = createStorage()  
7 -export const getPlatformInfo = () => storage.get(PLATFORM_INFO_CACHE_KEY) as PlatformInfo 7 +const storage = createStorage(localStorage)
  8 +export const getPlatformInfo = (): PlatformInfo => {
  9 + if (isFromEdge()) {
  10 + const common = storage.get(APP_LOCAL_CACHE_KEY)
  11 + return common?.[EDGE_PLATFORM_INFO_CACHE_KEY]?.value || {}
  12 + }
  13 + else {
  14 + return storage.get(PLATFORM_INFO_CACHE_KEY) as PlatformInfo
  15 + }
  16 +}
  17 +
8 export const setPlatformInfo = (info: Recordable) => storage.set(PLATFORM_INFO_CACHE_KEY, info) 18 export const setPlatformInfo = (info: Recordable) => storage.set(PLATFORM_INFO_CACHE_KEY, info)
9 19
10 export const usePlatform = async () => { 20 export const usePlatform = async () => {
@@ -67,7 +67,7 @@ export class EventHandler { @@ -67,7 +67,7 @@ export class EventHandler {
67 if (!cell) return 67 if (!cell) return
68 const id = cell.getId() 68 const id = cell.getId()
69 69
70 - const node = this.service.dataSource.find(item => item.id === id) 70 + const node = this.service.dataSource.find(item => item.configurationNodeId === id)
71 71
72 if (node && node.eventJson) { 72 if (node && node.eventJson) {
73 const instanceId = getAppInstanceId(cell) 73 const instanceId = getAppInstanceId(cell)
@@ -56,8 +56,8 @@ export class LightboxModeWebsocketService extends TelemetryWebsockerService { @@ -56,8 +56,8 @@ export class LightboxModeWebsocketService extends TelemetryWebsockerService {
56 * @returns 56 * @returns
57 */ 57 */
58 getNodeDataSubscribers(nodeData: NodeDataType) { 58 getNodeDataSubscribers(nodeData: NodeDataType) {
59 - const { dataSourceJson, actJson, id } = nodeData  
60 - const cell = this.nodeUtils.getCellById(id) 59 + const { dataSourceJson, actJson, configurationNodeId } = nodeData
  60 + const cell = this.nodeUtils.getCellById(configurationNodeId)
61 if (!cell) return [] 61 if (!cell) return []
62 const componentKey = this.nodeUtils.getNodeComponentKey(cell) 62 const componentKey = this.nodeUtils.getNodeComponentKey(cell)
63 const categoryKey = this.nodeUtils.getNodeCategory(cell) 63 const categoryKey = this.nodeUtils.getNodeCategory(cell)
@@ -77,7 +77,7 @@ export class LightboxModeWebsocketService extends TelemetryWebsockerService { @@ -77,7 +77,7 @@ export class LightboxModeWebsocketService extends TelemetryWebsockerService {
77 const { deviceId, attr } = actJson[key as ActTypeEnum] 77 const { deviceId, attr } = actJson[key as ActTypeEnum]
78 // 无entityId及属性时不订阅 78 // 无entityId及属性时不订阅
79 if (deviceId && attr) { 79 if (deviceId && attr) {
80 - const subscribe = TelemetrySubscriber.createTimeseriesSubscription(this, { id: deviceId, entityType: EntityType.DEVICE }, attr, this.getCommandSource(id, DataSourceTypeEnum.ACT, actJson[key as ActTypeEnum], key as ActTypeEnum)) 80 + const subscribe = TelemetrySubscriber.createTimeseriesSubscription(this, { id: deviceId, entityType: EntityType.DEVICE }, attr, this.getCommandSource(configurationNodeId, DataSourceTypeEnum.ACT, actJson[key as ActTypeEnum], key as ActTypeEnum))
81 subscribers.push(subscribe) 81 subscribers.push(subscribe)
82 } 82 }
83 } 83 }
@@ -86,7 +86,7 @@ export class LightboxModeWebsocketService extends TelemetryWebsockerService { @@ -86,7 +86,7 @@ export class LightboxModeWebsocketService extends TelemetryWebsockerService {
86 const { deviceId, attr } = dataSourceJson || {} 86 const { deviceId, attr } = dataSourceJson || {}
87 87
88 if (deviceId && attr) { 88 if (deviceId && attr) {
89 - const subscribe = TelemetrySubscriber.createTimeseriesSubscription(this, { id: deviceId, entityType: EntityType.DEVICE }, attr, this.getCommandSource(id, DataSourceTypeEnum.DATASOURCE, dataSourceJson)) 89 + const subscribe = TelemetrySubscriber.createTimeseriesSubscription(this, { id: deviceId, entityType: EntityType.DEVICE }, attr, this.getCommandSource(configurationNodeId, DataSourceTypeEnum.DATASOURCE, dataSourceJson))
90 subscribers.push(subscribe) 90 subscribers.push(subscribe)
91 } 91 }
92 92
@@ -24,7 +24,6 @@ export class MessageHandler { @@ -24,7 +24,6 @@ export class MessageHandler {
24 const telemetrySubscriber = this.service.subscribersMap.get(subscriptionId) 24 const telemetrySubscriber = this.service.subscribersMap.get(subscriptionId)
25 25
26 if (!telemetrySubscriber) return 26 if (!telemetrySubscriber) return
27 -  
28 const { commandSource } = telemetrySubscriber 27 const { commandSource } = telemetrySubscriber
29 const { dataType } = commandSource 28 const { dataType } = commandSource
30 if (dataType === DataSourceTypeEnum.DATASOURCE) 29 if (dataType === DataSourceTypeEnum.DATASOURCE)
@@ -23,7 +23,9 @@ export const APP_DARK_MODE_KEY = '__APP__DARK__MODE__' @@ -23,7 +23,9 @@ export const APP_DARK_MODE_KEY = '__APP__DARK__MODE__'
23 export const APP_LOCAL_CACHE_KEY = 'COMMON__LOCAL__KEY__' 23 export const APP_LOCAL_CACHE_KEY = 'COMMON__LOCAL__KEY__'
24 24
25 // base global session key 25 // base global session key
26 -export const PLATFORM_INFO_CACHE_KEY = 'PLATFORM_INFO' 26 +export const PLATFORM_INFO_CACHE_KEY = 'PLATFORMINFO'
  27 +
  28 +export const EDGE_PLATFORM_INFO_CACHE_KEY = 'PLATFORM__INFO'
27 29
28 export const APP_SESSION_CACHE_KEY = 'COMMON__SESSION__KEY__' 30 export const APP_SESSION_CACHE_KEY = 'COMMON__SESSION__KEY__'
29 31
@@ -3,4 +3,5 @@ export enum CellAttributeKeyEnum { @@ -3,4 +3,5 @@ export enum CellAttributeKeyEnum {
3 CATEGORY = 'category', 3 CATEGORY = 'category',
4 SHAPE_KEY = 'shapeKey', 4 SHAPE_KEY = 'shapeKey',
5 COPY_SOURCE = 'copySource', 5 COPY_SOURCE = 'copySource',
  6 + DEFAULT_IMAGE = 'defaultImage',
6 } 7 }
@@ -54,6 +54,10 @@ export class NodeUtils { @@ -54,6 +54,10 @@ export class NodeUtils {
54 model.setVisible(cell, value) 54 model.setVisible(cell, value)
55 } 55 }
56 56
  57 + refreshCell(cell: MxCell) {
  58 + this.graph.refresh(cell)
  59 + }
  60 +
57 getNodeComponentKey(node: string | MxCell): Nullable<ComponentKey> { 61 getNodeComponentKey(node: string | MxCell): Nullable<ComponentKey> {
58 const cell = isString(node) ? this.getCellById(node) : node 62 const cell = isString(node) ? this.getCellById(node) : node
59 const cellValue = cell.getValue() as Element 63 const cellValue = cell.getValue() as Element
  1 +import { isFromEdge } from '@/core/LoadData/module/useParseParams'
1 import { isDevMode } from '@/utils/env' 2 import { isDevMode } from '@/utils/env'
2 3
3 // System default cache time, in seconds 4 // System default cache time, in seconds
@@ -10,5 +11,5 @@ export const cacheCipher = { @@ -10,5 +11,5 @@ export const cacheCipher = {
10 } 11 }
11 12
12 // Whether the system cache is encrypted using aes 13 // Whether the system cache is encrypted using aes
13 -export const enableStorageEncryption = !isDevMode() 14 +export const enableStorageEncryption = !isFromEdge() && !isDevMode()
14 15
@@ -34,7 +34,7 @@ export const useContentDataStore = defineStore('app-content-data', { @@ -34,7 +34,7 @@ export const useContentDataStore = defineStore('app-content-data', {
34 actions: { 34 actions: {
35 35
36 getNodeDataById(id: string): Undefineable<NodeDataType> { 36 getNodeDataById(id: string): Undefineable<NodeDataType> {
37 - const data = this.contentData.find(item => item.id === id) 37 + const data = this.contentData.find(item => item.configurationNodeId === id)
38 return data 38 return data
39 }, 39 },
40 40
@@ -68,7 +68,7 @@ export const useContentDataStore = defineStore('app-content-data', { @@ -68,7 +68,7 @@ export const useContentDataStore = defineStore('app-content-data', {
68 const { cellInfo } = config 68 const { cellInfo } = config
69 const { id } = cellInfo || {} 69 const { id } = cellInfo || {}
70 if (!id) return null 70 if (!id) return null
71 - return this.contentData.find(item => item.id === id) || null 71 + return this.contentData.find(item => item.configurationNodeId === id) || null
72 }, 72 },
73 73
74 setPermissions(string: string[]) { 74 setPermissions(string: string[]) {
@@ -39,7 +39,7 @@ export function getShareRefreshToken(): string { @@ -39,7 +39,7 @@ export function getShareRefreshToken(): string {
39 } 39 }
40 40
41 export function getLocale() { 41 export function getLocale() {
42 - const { language } = (JSON.parse(localStorage.getItem('.drawio-config') || '') || {}) as DrawioConfig 42 + const { language } = (JSON.parse(localStorage.getItem('.drawio-config') || '{}') || {}) as DrawioConfig
43 43
44 return language 44 return language
45 } 45 }