From d76045be1cd5a030ed68269246d7ae1956a5ff06 Mon Sep 17 00:00:00 2001
From: king <18310653075@163.com>
Date: 星期三, 15 十二月 2021 11:00:26 +0800
Subject: [PATCH] 2021-12-15

---
 src/menu/components/chart/antv-bar/chartcompile/index.jsx            |    3 
 src/tabviews/custom/components/chart/antv-dashboard/index.scss       |   72 +------
 src/tabviews/custom/components/chart/antv-scatter/index.jsx          |   46 ++++
 src/tabviews/custom/components/chart/antv-bar-line/index.jsx         |   48 +++++
 src/menu/components/chart/antv-dashboard/chartcompile/index.jsx      |    3 
 src/menu/components/chart/antv-pie/chartcompile/formconfig.jsx       |   14 +
 src/tabviews/custom/components/chart/antv-dashboard/index.jsx        |   51 +++++
 src/tabviews/custom/components/chart/antv-scatter/index.scss         |   20 ++
 src/tabviews/custom/components/chart/antv-bar-line/index.scss        |   19 ++
 src/menu/components/chart/antv-scatter/chartcompile/index.jsx        |    2 
 src/tabviews/custom/components/chart/antv-pie/index.scss             |   58 +-----
 public/options.json                                                  |   12 
 src/pc/components/login/normal-login/options.jsx                     |    2 
 src/views/rolemanage/index.jsx                                       |    8 
 src/menu/components/chart/antv-scatter/chartcompile/formconfig.jsx   |   14 +
 src/menu/components/chart/antv-bar/index.jsx                         |    1 
 src/views/pcdesign/index.scss                                        |    3 
 src/menu/components/chart/chart-custom/chartcompile/index.jsx        |    2 
 src/menu/components/chart/antv-dashboard/chartcompile/formconfig.jsx |   30 +++
 src/menu/components/chart/antv-bar/chartcompile/formconfig.jsx       |   14 +
 src/menu/components/chart/antv-pie/chartcompile/index.jsx            |    2 
 src/views/design/sidemenu/config.jsx                                 |   14 
 src/tabviews/custom/components/chart/antv-pie/index.jsx              |   44 ++++
 src/views/menudesign/index.scss                                      |    3 
 src/views/appmanage/submutilform/index.jsx                           |    2 
 25 files changed, 353 insertions(+), 134 deletions(-)

diff --git a/public/options.json b/public/options.json
index 6fd5cc5..2e37e81 100644
--- a/public/options.json
+++ b/public/options.json
@@ -1,17 +1,17 @@
 {
-  "appId": "202108312122504607B107A83F55B40C98CCF",
-  "appkey": "20210831212235413F287EC3BF489424496C8",
+  "appId": "201912040924165801464FF1788654BC5AC73",
+  "appkey": "20191106103859640976D6E924E464D029CF0",
   "mainSystemApi": "http://sso.mk9h.cn/cloud/webapi/dostars",
   "systemType": "",
-  "externalDatabase": "",
+  "externalDatabase": "false",
   "lineColor": "",
   "filter": "false",
   "defaultApp": "",
   "defaultLang": "zh-CN",
   "WXAppID": "",
   "debugger": false,
-  "licenseKey": "7EFE13KIKKILIJ7C8CFC",
+  "licenseKey": "",
   "probation": "",
-  "host": "http://demo.mk9h.cn",
-  "service": "erp_new/"
+  "host": "http://qingqiumarket.cn",
+  "service": "MKWMS/"
 }
\ No newline at end of file
diff --git a/src/menu/components/chart/antv-bar/chartcompile/formconfig.jsx b/src/menu/components/chart/antv-bar/chartcompile/formconfig.jsx
index 5be7778..56f54d3 100644
--- a/src/menu/components/chart/antv-bar/chartcompile/formconfig.jsx
+++ b/src/menu/components/chart/antv-bar/chartcompile/formconfig.jsx
@@ -405,6 +405,20 @@
         text: '闅愯棌'
       }]
     }, {
+      type: 'radio',
+      key: 'download',
+      label: '瀵煎嚭鍥剧墖',
+      initVal: card.download || 'forbid',
+      required: false,
+      forbid: appType === 'mob',
+      options: [{
+        value: 'forbid',
+        text: '绂佺敤'
+      }, {
+        value: 'enable',
+        text: '鍚敤'
+      }]
+    }, {
       type: 'number',
       key: 'barSize',
       label: '鏌卞舰瀹藉害',
diff --git a/src/menu/components/chart/antv-bar/chartcompile/index.jsx b/src/menu/components/chart/antv-bar/chartcompile/index.jsx
index ee2421e..cd66b94 100644
--- a/src/menu/components/chart/antv-bar/chartcompile/index.jsx
+++ b/src/menu/components/chart/antv-bar/chartcompile/index.jsx
@@ -601,6 +601,7 @@
   }
 
   render() {
+    const { config } = this.props
     const { view, visible, datatype, plot, ramp, colorColumns, rampColorColumns, statColorColumns, rampStatColorColumns, cusColumns, baseFormlist } = this.state
     const formItemLayout = {
       labelCol: {
@@ -618,7 +619,7 @@
         <EditOutlined title="缂栬緫" onClick={this.showDrawer}/>
         <Modal
           wrapClassName="popview-modal menu-chart-edit-modal"
-          title="鍥捐〃缂栬緫"
+          title={config.type === 'bar' ? '鏌辩姸鍥剧紪杈�' : '鎶樼嚎鍥剧紪杈�'}
           visible={visible}
           width={950}
           maskClosable={false}
diff --git a/src/menu/components/chart/antv-bar/index.jsx b/src/menu/components/chart/antv-bar/index.jsx
index f06a656..b439765 100644
--- a/src/menu/components/chart/antv-bar/index.jsx
+++ b/src/menu/components/chart/antv-bar/index.jsx
@@ -1350,6 +1350,7 @@
         </Popover>
         <NormalHeader config={card} updateComponent={this.updateComponent}/>
         <div className="canvas" id={card.uuid + 'canvas'} ref={ref => this.wrap = ref}></div>
+        {card.plot.download === 'enable' ? <Icon type="download"/> : null}
         {appType !== 'mob' ? <ActionComponent
           type="chart"
           config={card}
diff --git a/src/menu/components/chart/antv-dashboard/chartcompile/formconfig.jsx b/src/menu/components/chart/antv-dashboard/chartcompile/formconfig.jsx
index 222db5a..9a90e00 100644
--- a/src/menu/components/chart/antv-dashboard/chartcompile/formconfig.jsx
+++ b/src/menu/components/chart/antv-dashboard/chartcompile/formconfig.jsx
@@ -75,6 +75,7 @@
  * @param {Array}  columns    // 鏄剧ず鍒�
  */
 export function getOptionForm (card, columns) {
+  let appType = sessionStorage.getItem('appType')
   let yfields = columns.filter(item => /^(Int|Decimal)/ig.test(item.datatype))
 
   return [
@@ -128,6 +129,20 @@
         value: 'false',
         text: '涓嶄娇鐢�'
       }]
+    }, {
+      type: 'radio',
+      key: 'download',
+      label: '瀵煎嚭鍥剧墖',
+      initVal: card.download || 'forbid',
+      required: false,
+      forbid: appType === 'mob',
+      options: [{
+        value: 'forbid',
+        text: '绂佺敤'
+      }, {
+        value: 'enable',
+        text: '鍚敤'
+      }]
     },
     {
       type: 'color',
@@ -152,6 +167,7 @@
  * @param {Array}  columns    // 鏄剧ず鍒�
  */
 export function getRadioOptionForm (card, columns) {
+  let appType = sessionStorage.getItem('appType')
   let xfields = columns.filter(item => /^Nvarchar/ig.test(item.datatype))
   let yfields = columns.filter(item => /^(Int|Decimal)/ig.test(item.datatype))
 
@@ -216,6 +232,20 @@
         value: 'false',
         text: '涓嶄娇鐢�'
       }]
+    }, {
+      type: 'radio',
+      key: 'download',
+      label: '瀵煎嚭鍥剧墖',
+      initVal: card.download || 'forbid',
+      required: false,
+      forbid: appType === 'mob',
+      options: [{
+        value: 'forbid',
+        text: '绂佺敤'
+      }, {
+        value: 'enable',
+        text: '鍚敤'
+      }]
     },
     {
       type: 'color',
diff --git a/src/menu/components/chart/antv-dashboard/chartcompile/index.jsx b/src/menu/components/chart/antv-dashboard/chartcompile/index.jsx
index 3e526c1..09bf509 100644
--- a/src/menu/components/chart/antv-dashboard/chartcompile/index.jsx
+++ b/src/menu/components/chart/antv-dashboard/chartcompile/index.jsx
@@ -283,6 +283,7 @@
   }
 
   render() {
+    const { config } = this.props
     const { visible, plot, colorColumns, view, baseFormlist } = this.state
     const formItemLayout = {
       labelCol: {
@@ -300,7 +301,7 @@
         <EditOutlined title="缂栬緫" onClick={this.showDrawer} />
         <Modal
           wrapClassName="popview-modal menu-chart-edit-modal"
-          title="鍥捐〃缂栬緫"
+          title={config.subtype === 'ratioboard' ? '鍗犳瘮鍥剧紪杈�' : '浠〃鐩樼紪杈�'}
           visible={visible}
           width={850}
           maskClosable={false}
diff --git a/src/menu/components/chart/antv-pie/chartcompile/formconfig.jsx b/src/menu/components/chart/antv-pie/chartcompile/formconfig.jsx
index c07b6f2..aaa4b33 100644
--- a/src/menu/components/chart/antv-pie/chartcompile/formconfig.jsx
+++ b/src/menu/components/chart/antv-pie/chartcompile/formconfig.jsx
@@ -282,6 +282,20 @@
         text: '绱姞'
       }]
     }, {
+      type: 'radio',
+      key: 'download',
+      label: '瀵煎嚭鍥剧墖',
+      initVal: card.download || 'forbid',
+      required: false,
+      forbid: appType === 'mob',
+      options: [{
+        value: 'forbid',
+        text: '绂佺敤'
+      }, {
+        value: 'enable',
+        text: '鍚敤'
+      }]
+    }, {
       type: 'number',
       key: 'splitLine',
       label: '鍒嗛殧绾�',
diff --git a/src/menu/components/chart/antv-pie/chartcompile/index.jsx b/src/menu/components/chart/antv-pie/chartcompile/index.jsx
index e9ec92e..be8bb9a 100644
--- a/src/menu/components/chart/antv-pie/chartcompile/index.jsx
+++ b/src/menu/components/chart/antv-pie/chartcompile/index.jsx
@@ -326,7 +326,7 @@
         <EditOutlined title="缂栬緫" onClick={this.showDrawer} />
         <Modal
           wrapClassName="popview-modal menu-chart-edit-modal"
-          title="鍥捐〃缂栬緫"
+          title="楗煎浘缂栬緫"
           visible={visible}
           width={850}
           maskClosable={false}
diff --git a/src/menu/components/chart/antv-scatter/chartcompile/formconfig.jsx b/src/menu/components/chart/antv-scatter/chartcompile/formconfig.jsx
index bd73720..cf6c5da 100644
--- a/src/menu/components/chart/antv-scatter/chartcompile/formconfig.jsx
+++ b/src/menu/components/chart/antv-scatter/chartcompile/formconfig.jsx
@@ -127,6 +127,20 @@
         value: 'false',
         text: '闅愯棌'
       }]
+    }, {
+      type: 'radio',
+      key: 'download',
+      label: '瀵煎嚭鍥剧墖',
+      initVal: card.download || 'forbid',
+      required: false,
+      forbid: appType === 'mob',
+      options: [{
+        value: 'forbid',
+        text: '绂佺敤'
+      }, {
+        value: 'enable',
+        text: '鍚敤'
+      }]
     },
     {
       type: 'text',
diff --git a/src/menu/components/chart/antv-scatter/chartcompile/index.jsx b/src/menu/components/chart/antv-scatter/chartcompile/index.jsx
index 9658562..5a82c37 100644
--- a/src/menu/components/chart/antv-scatter/chartcompile/index.jsx
+++ b/src/menu/components/chart/antv-scatter/chartcompile/index.jsx
@@ -245,7 +245,7 @@
         <EditOutlined title="缂栬緫" onClick={this.showDrawer} />
         <Modal
           wrapClassName="popview-modal menu-chart-edit-modal"
-          title="鍥捐〃缂栬緫"
+          title="鏁g偣鍥剧紪杈�"
           visible={visible}
           width={850}
           maskClosable={false}
diff --git a/src/menu/components/chart/chart-custom/chartcompile/index.jsx b/src/menu/components/chart/chart-custom/chartcompile/index.jsx
index e59b022..5596191 100644
--- a/src/menu/components/chart/chart-custom/chartcompile/index.jsx
+++ b/src/menu/components/chart/chart-custom/chartcompile/index.jsx
@@ -93,7 +93,7 @@
         <Icon type="edit" style={{color: '#1890ff'}} title="缂栬緫" onClick={this.showDrawer} />
         <Modal
           wrapClassName="popview-modal custom-chart-edit-modal"
-          title="鍥捐〃缂栬緫"
+          title="鑷畾涔夊浘琛ㄧ紪杈�"
           visible={visible}
           width={950}
           maskClosable={false}
diff --git a/src/pc/components/login/normal-login/options.jsx b/src/pc/components/login/normal-login/options.jsx
index 4d5b6aa..bfb426f 100644
--- a/src/pc/components/login/normal-login/options.jsx
+++ b/src/pc/components/login/normal-login/options.jsx
@@ -114,7 +114,7 @@
       field: 'tempId',
       label: '鐭俊妯℃澘',
       initval: wrap.tempId || '',
-      tooltip: '鐭俊妯℃澘鍙湪绠$悊绯荤粺 HS-濂囦簯鐭俊妯℃澘 澶勬坊鍔犮��',
+      tooltip: '鐭俊妯℃澘鍙湪 浜戠郴缁�->搴旂敤鏈嶅姟->寮�鍙戣�呬腑蹇�->鐭俊妯℃澘 澶勬坊鍔犮��',
       required: true,
       options: msgTemps
     },
diff --git a/src/tabviews/custom/components/chart/antv-bar-line/index.jsx b/src/tabviews/custom/components/chart/antv-bar-line/index.jsx
index 1c7f5cc..1395851 100644
--- a/src/tabviews/custom/components/chart/antv-bar-line/index.jsx
+++ b/src/tabviews/custom/components/chart/antv-bar-line/index.jsx
@@ -4,6 +4,7 @@
 import { Chart } from '@antv/g2'
 import DataSet from '@antv/data-set'
 import { Spin, Empty, notification } from 'antd'
+import { DownloadOutlined } from '@ant-design/icons'
 import moment from 'moment'
 
 import asyncComponent from './asyncButtonComponent'
@@ -41,6 +42,7 @@
     search: null,              // 鎼滅储鏉′欢
     vFields: [],               // 鏁板�煎瓧娈�
     vstFields: null,           // 缁熻鏁版嵁鍊煎瓧娈典俊鎭�
+    chart: null
   }
 
   UNSAFE_componentWillMount () {
@@ -1053,6 +1055,8 @@
     }
     
     chart.render()
+
+    this.setState({chart})
   }
 
   /**
@@ -1418,6 +1422,8 @@
     }
 
     chart.render()
+
+    this.setState({chart})
   }
 
   /**
@@ -1691,12 +1697,51 @@
     }
 
     chart.render()
+
+    this.setState({chart})
   }
 
   refreshSearch = (list) => {
     this.setState({search: list}, () => {
       this.loadData()
     })
+  }
+
+  downloadImage = () => {
+    const { chart, config } = this.state
+    const link = document.createElement('a');
+    const filename = `${config.name}${moment().format('YYYY-MM-DD HH_mm_ss')}.png`;
+    const canvas = chart.getCanvas();
+    canvas.get('timeline').stopAllAnimations();
+  
+    setTimeout(() => {
+      const canvas = chart.getCanvas();
+      const canvasDom = canvas.get('el');
+      const dataURL = canvasDom.toDataURL('image/png');
+
+      if (window.Blob && window.URL) {
+        const arr = dataURL.split(',');
+        const mime = arr[0].match(/:(.*?);/)[1];
+        const bstr = atob(arr[1]);
+        let n = bstr.length;
+        const u8arr = new Uint8Array(n);
+        while (n--) {
+          u8arr[n] = bstr.charCodeAt(n);
+        }
+        const blobObj = new Blob([u8arr], { type: mime });
+        if (window.navigator.msSaveBlob) {
+          window.navigator.msSaveBlob(blobObj, filename);
+        } else {
+          link.addEventListener('click', () => {
+            link.download = filename;
+            link.href = window.URL.createObjectURL(blobObj);
+          });
+        }
+      }
+      const e = document.createEvent('MouseEvents');
+      e.initEvent('click', false, false);
+      link.dispatchEvent(e);
+    }, 16);
   }
 
   render() {
@@ -1712,7 +1757,8 @@
         }
         <NormalHeader config={config} BID={BID} menuType={this.props.menuType} refresh={this.refreshSearch} />
         <div className="canvas-wrap" ref={ref => this.wrap = ref}>
-          <div className="chart-action">
+          {config.plot.download === 'enable' && this.state.chart && !empty ? <DownloadOutlined onClick={this.downloadImage} className="system-color download"/> : null}
+          <div className={'chart-action' + (config.plot.download === 'enable' ? ' downable' : '')}>
             {config.action.map(item => {
               if (item.OpenType === 'excelOut') {
                 return (
diff --git a/src/tabviews/custom/components/chart/antv-bar-line/index.scss b/src/tabviews/custom/components/chart/antv-bar-line/index.scss
index 093ce92..04b5487 100644
--- a/src/tabviews/custom/components/chart/antv-bar-line/index.scss
+++ b/src/tabviews/custom/components/chart/antv-bar-line/index.scss
@@ -21,12 +21,31 @@
         float: right;
       }
     }
+    .download {
+      position: absolute;
+      z-index: 1;
+      right: 10px;
+      top: 8px;
+      opacity: 0;
+      transition: opacity 0.3s;
+      cursor: pointer;
+      font-size: 16px;
+    }
+    .chart-action.downable {
+      right: 35px;
+    }
+  }
+  .canvas-wrap:hover {
+    .download {
+      opacity: 1;
+    }
   }
 
   .canvas {
     margin: 0;
     padding: 15px 10px 10px;
     letter-spacing: 0px;
+    height: 100%;
   }
   .canvas.empty {
     div {
diff --git a/src/tabviews/custom/components/chart/antv-dashboard/index.jsx b/src/tabviews/custom/components/chart/antv-dashboard/index.jsx
index df4fba4..63d21b7 100644
--- a/src/tabviews/custom/components/chart/antv-dashboard/index.jsx
+++ b/src/tabviews/custom/components/chart/antv-dashboard/index.jsx
@@ -3,17 +3,15 @@
 import { is, fromJS } from 'immutable'
 import { Chart, registerShape } from '@antv/g2'
 import { Spin, notification } from 'antd'
+import { DownloadOutlined } from '@ant-design/icons'
 import moment from 'moment'
 
 import Api from '@/api'
 import Utils from '@/utils/utils.js'
-// import asyncComponent from '@/utils/asyncComponent'
 import UtilsDM from '@/utils/utils-datamanage.js'
 import MKEmitter from '@/utils/events.js'
 import NormalHeader from '@/tabviews/custom/components/share/normalheader'
 import './index.scss'
-
-// const NormalHeader = asyncComponent(() => import('@/tabviews/custom/components/share/normalheader'))
 
 registerShape('point', 'pointer', {
   draw(cfg, container) {
@@ -70,6 +68,7 @@
     sync: false,               // 鏄惁缁熶竴璇锋眰鏁版嵁
     plot: null,                // 鍥捐〃璁剧疆
     data: {},                  // 鏁版嵁
+    chart: null
   }
 
   UNSAFE_componentWillMount () {
@@ -436,6 +435,8 @@
       }
     })
     chart.render()
+
+    this.setState({chart})
   }
 
   /**
@@ -594,10 +595,49 @@
     }
 
     chart.render()
+
+    this.setState({chart})
+  }
+
+  downloadImage = () => {
+    const { chart, config } = this.state
+    const link = document.createElement('a');
+    const filename = `${config.name}${moment().format('YYYY-MM-DD HH_mm_ss')}.png`;
+    const canvas = chart.getCanvas();
+    canvas.get('timeline').stopAllAnimations();
+  
+    setTimeout(() => {
+      const canvas = chart.getCanvas();
+      const canvasDom = canvas.get('el');
+      const dataURL = canvasDom.toDataURL('image/png');
+
+      if (window.Blob && window.URL) {
+        const arr = dataURL.split(',');
+        const mime = arr[0].match(/:(.*?);/)[1];
+        const bstr = atob(arr[1]);
+        let n = bstr.length;
+        const u8arr = new Uint8Array(n);
+        while (n--) {
+          u8arr[n] = bstr.charCodeAt(n);
+        }
+        const blobObj = new Blob([u8arr], { type: mime });
+        if (window.navigator.msSaveBlob) {
+          window.navigator.msSaveBlob(blobObj, filename);
+        } else {
+          link.addEventListener('click', () => {
+            link.download = filename;
+            link.href = window.URL.createObjectURL(blobObj);
+          });
+        }
+      }
+      const e = document.createEvent('MouseEvents');
+      e.initEvent('click', false, false);
+      link.dispatchEvent(e);
+    }, 16);
   }
 
   render() {
-    const { config, loading, empty } = this.state
+    const { config, loading } = this.state
 
     return (
       <div className="custom-dashboard-plot-box" style={config.style}>
@@ -609,7 +649,8 @@
         }
         <NormalHeader config={config} />
         <div className="canvas-wrap" ref={ref => this.wrap = ref}>
-          <div className={'canvas' + (empty ? ' empty' : '')} id={this.state.chartId}></div>
+          {config.plot.download === 'enable' && this.state.chart ? <DownloadOutlined onClick={this.downloadImage} className="system-color download"/> : null}
+          <div className="canvas" id={this.state.chartId}></div>
         </div>
       </div>
     )
diff --git a/src/tabviews/custom/components/chart/antv-dashboard/index.scss b/src/tabviews/custom/components/chart/antv-dashboard/index.scss
index 10db44d..89aa840 100644
--- a/src/tabviews/custom/components/chart/antv-dashboard/index.scss
+++ b/src/tabviews/custom/components/chart/antv-dashboard/index.scss
@@ -12,14 +12,21 @@
     margin: 0 0px;
     position: relative;
     flex: 1;
-    .chart-action {
+    .download {
       position: absolute;
-      top: 2px;
-      right: 5px;
       z-index: 1;
+      right: 10px;
+      top: 10px;
+      opacity: 0;
+      transition: opacity 0.3s;
+      cursor: pointer;
+      font-size: 16px;
     }
-    .chart-action.with-title {
-      top: 35px;
+  }
+
+  .canvas-wrap:hover {
+    .download {
+      opacity: 1;
     }
   }
 
@@ -27,21 +34,9 @@
     margin: 0;
     padding: 15px;
     letter-spacing: 0px;
+    height: 100%;
   }
-  .canvas.empty {
-    div {
-      opacity: 0;
-    }
-  }
-  .ant-empty {
-    position: absolute;
-    top: calc(50% - 34px);
-    left: calc(50% - 92px);
 
-    .ant-empty-image {
-      height: 60px;
-    }
-  }
   .loading-mask {
     position: absolute;
     left: 0px;
@@ -60,47 +55,6 @@
       height: 100%;
       opacity: 0.5;
       background: #ffffff;
-    }
-  }
-  > .ant-select {
-    width: 150px;
-    float: right;
-    position: relative;
-    z-index: 1;
-    .ant-select-selection {
-      min-height: 24px;
-      height: 28px;
-      li {
-        background: unset;
-        border: 0;
-        width: 99%;
-        padding: 0;
-        margin-right: 0;
-        cursor: pointer;
-
-        .type-label {
-          overflow: hidden;
-          word-break: break-word;
-          white-space: nowrap;
-          text-overflow: ellipsis;
-        }
-      }
-      li + li {
-        margin-top: 0;
-        width: 1%;
-        opacity: 0;
-      }
-    }
-  }
-  > .ant-select.ant-select-focused {
-    .ant-select-selection {
-      li {
-        width: 50%;
-      }
-      li + li {
-        width: 49%;
-        opacity: 1;
-      }
     }
   }
   .g2-tooltip-list{
diff --git a/src/tabviews/custom/components/chart/antv-pie/index.jsx b/src/tabviews/custom/components/chart/antv-pie/index.jsx
index 51eb7ce..e5aa7e7 100644
--- a/src/tabviews/custom/components/chart/antv-pie/index.jsx
+++ b/src/tabviews/custom/components/chart/antv-pie/index.jsx
@@ -5,6 +5,7 @@
 import { connect } from 'react-redux'
 import DataSet, { DataView } from '@antv/data-set'
 import { Spin, Empty, notification } from 'antd'
+import { DownloadOutlined } from '@ant-design/icons'
 import moment from 'moment'
 
 import Api from '@/api'
@@ -35,6 +36,7 @@
     plot: null,                // 鍥捐〃璁剧疆
     data: null,                // 鏁版嵁
     search: null,              // 鎼滅储鏉′欢
+    chart: null
   }
 
   UNSAFE_componentWillMount () {
@@ -728,6 +730,8 @@
       })
     }
     chart.render()
+
+    this.setState({chart})
   }
 
   /**
@@ -989,12 +993,51 @@
       })
     }
     chart.render()
+
+    this.setState({chart})
   }
 
   refreshSearch = (list) => {
     this.setState({search: list}, () => {
       this.loadData()
     })
+  }
+
+  downloadImage = () => {
+    const { chart, config } = this.state
+    const link = document.createElement('a');
+    const filename = `${config.name}${moment().format('YYYY-MM-DD HH_mm_ss')}.png`;
+    const canvas = chart.getCanvas();
+    canvas.get('timeline').stopAllAnimations();
+  
+    setTimeout(() => {
+      const canvas = chart.getCanvas();
+      const canvasDom = canvas.get('el');
+      const dataURL = canvasDom.toDataURL('image/png');
+
+      if (window.Blob && window.URL) {
+        const arr = dataURL.split(',');
+        const mime = arr[0].match(/:(.*?);/)[1];
+        const bstr = atob(arr[1]);
+        let n = bstr.length;
+        const u8arr = new Uint8Array(n);
+        while (n--) {
+          u8arr[n] = bstr.charCodeAt(n);
+        }
+        const blobObj = new Blob([u8arr], { type: mime });
+        if (window.navigator.msSaveBlob) {
+          window.navigator.msSaveBlob(blobObj, filename);
+        } else {
+          link.addEventListener('click', () => {
+            link.download = filename;
+            link.href = window.URL.createObjectURL(blobObj);
+          });
+        }
+      }
+      const e = document.createEvent('MouseEvents');
+      e.initEvent('click', false, false);
+      link.dispatchEvent(e);
+    }, 16);
   }
 
   render() {
@@ -1010,6 +1053,7 @@
         }
         <NormalHeader config={config} BID={BID} menuType={this.props.menuType} refresh={this.refreshSearch} />
         <div className="canvas-wrap" ref={ref => this.wrap = ref}>
+          {config.plot.download === 'enable' && this.state.chart && !empty ? <DownloadOutlined onClick={this.downloadImage} className="system-color download"/> : null}
           <div className={'canvas' + (empty ? ' empty' : '')} id={this.state.chartId}></div>
         </div>
         {empty ? <Empty description={false}/> : null}
diff --git a/src/tabviews/custom/components/chart/antv-pie/index.scss b/src/tabviews/custom/components/chart/antv-pie/index.scss
index 5db4d2f..223d368 100644
--- a/src/tabviews/custom/components/chart/antv-pie/index.scss
+++ b/src/tabviews/custom/components/chart/antv-pie/index.scss
@@ -12,14 +12,20 @@
     margin: 0 0px;
     position: relative;
     flex: 1;
-    .chart-action {
+    .download {
       position: absolute;
-      top: 2px;
-      right: 5px;
       z-index: 1;
+      right: 10px;
+      top: 10px;
+      opacity: 0;
+      transition: opacity 0.3s;
+      cursor: pointer;
+      font-size: 16px;
     }
-    .chart-action.with-title {
-      top: 35px;
+  }
+  .canvas-wrap:hover {
+    .download {
+      opacity: 1;
     }
   }
 
@@ -27,6 +33,7 @@
     margin: 0;
     padding: 15px;
     letter-spacing: 0px;
+    height: 100%;
   }
   .canvas.empty {
     div {
@@ -60,47 +67,6 @@
       height: 100%;
       opacity: 0.5;
       background: #ffffff;
-    }
-  }
-  > .ant-select {
-    width: 150px;
-    float: right;
-    position: relative;
-    z-index: 1;
-    .ant-select-selection {
-      min-height: 24px;
-      height: 28px;
-      li {
-        background: unset;
-        border: 0;
-        width: 99%;
-        padding: 0;
-        margin-right: 0;
-        cursor: pointer;
-
-        .type-label {
-          overflow: hidden;
-          word-break: break-word;
-          white-space: nowrap;
-          text-overflow: ellipsis;
-        }
-      }
-      li + li {
-        margin-top: 0;
-        width: 1%;
-        opacity: 0;
-      }
-    }
-  }
-  > .ant-select.ant-select-focused {
-    .ant-select-selection {
-      li {
-        width: 50%;
-      }
-      li + li {
-        width: 49%;
-        opacity: 1;
-      }
     }
   }
   .g2-tooltip-list{
diff --git a/src/tabviews/custom/components/chart/antv-scatter/index.jsx b/src/tabviews/custom/components/chart/antv-scatter/index.jsx
index 99fb8fb..074d4ea 100644
--- a/src/tabviews/custom/components/chart/antv-scatter/index.jsx
+++ b/src/tabviews/custom/components/chart/antv-scatter/index.jsx
@@ -3,18 +3,17 @@
 import { is, fromJS } from 'immutable'
 import { Chart } from '@antv/g2'
 import { Spin, Empty, notification } from 'antd'
+import { DownloadOutlined } from '@ant-design/icons'
 import moment from 'moment'
 
 import Api from '@/api'
 import Utils from '@/utils/utils.js'
-// import asyncComponent from '@/utils/asyncComponent'
 import asyncBtnComponent from './asyncButtonComponent'
 import UtilsDM from '@/utils/utils-datamanage.js'
 import MKEmitter from '@/utils/events.js'
 import NormalHeader from '@/tabviews/custom/components/share/normalheader'
 import './index.scss'
 
-// const NormalHeader = asyncComponent(() => import('@/tabviews/custom/components/share/normalheader'))
 const ExcelOutButton = asyncBtnComponent(() => import('@/tabviews/zshare/actionList/exceloutbutton'))
 const ExcelInButton = asyncBtnComponent(() => import('@/tabviews/zshare/actionList/excelInbutton'))
 
@@ -37,6 +36,7 @@
     plot: null,                // 鍥捐〃璁剧疆
     data: null,                // 鏁版嵁
     search: null,              // 鎼滅储鏉′欢
+    chart: null
   }
 
   UNSAFE_componentWillMount () {
@@ -376,12 +376,51 @@
       })
     }
     chart.render()
+
+    this.setState({chart})
   }
 
   refreshSearch = (list) => {
     this.setState({search: list}, () => {
       this.loadData()
     })
+  }
+
+  downloadImage = () => {
+    const { chart, config } = this.state
+    const link = document.createElement('a');
+    const filename = `${config.name}${moment().format('YYYY-MM-DD HH_mm_ss')}.png`;
+    const canvas = chart.getCanvas();
+    canvas.get('timeline').stopAllAnimations();
+  
+    setTimeout(() => {
+      const canvas = chart.getCanvas();
+      const canvasDom = canvas.get('el');
+      const dataURL = canvasDom.toDataURL('image/png');
+
+      if (window.Blob && window.URL) {
+        const arr = dataURL.split(',');
+        const mime = arr[0].match(/:(.*?);/)[1];
+        const bstr = atob(arr[1]);
+        let n = bstr.length;
+        const u8arr = new Uint8Array(n);
+        while (n--) {
+          u8arr[n] = bstr.charCodeAt(n);
+        }
+        const blobObj = new Blob([u8arr], { type: mime });
+        if (window.navigator.msSaveBlob) {
+          window.navigator.msSaveBlob(blobObj, filename);
+        } else {
+          link.addEventListener('click', () => {
+            link.download = filename;
+            link.href = window.URL.createObjectURL(blobObj);
+          });
+        }
+      }
+      const e = document.createEvent('MouseEvents');
+      e.initEvent('click', false, false);
+      link.dispatchEvent(e);
+    }, 16);
   }
 
   render() {
@@ -397,7 +436,8 @@
         }
         <NormalHeader config={config} BID={BID} menuType={this.props.menuType} refresh={this.refreshSearch} />
         <div className="canvas-wrap" ref={ref => this.wrap = ref}>
-          <div className="chart-action">
+          {config.plot.download === 'enable' && this.state.chart && !empty ? <DownloadOutlined onClick={this.downloadImage} className="system-color download"/> : null}
+          <div className={'chart-action' + (config.plot.download === 'enable' ? ' downable' : '')}>
             {config.action.map(item => {
               if (item.OpenType === 'excelOut') {
                 return (
diff --git a/src/tabviews/custom/components/chart/antv-scatter/index.scss b/src/tabviews/custom/components/chart/antv-scatter/index.scss
index 1f52198..eaad237 100644
--- a/src/tabviews/custom/components/chart/antv-scatter/index.scss
+++ b/src/tabviews/custom/components/chart/antv-scatter/index.scss
@@ -21,12 +21,32 @@
         float: right;
       }
     }
+    .download {
+      position: absolute;
+      z-index: 1;
+      right: 10px;
+      top: 8px;
+      opacity: 0;
+      transition: opacity 0.3s;
+      cursor: pointer;
+      font-size: 16px;
+    }
+    .chart-action.downable {
+      right: 35px;
+    }
+  }
+
+  .canvas-wrap:hover {
+    .download {
+      opacity: 1;
+    }
   }
 
   .canvas {
     margin: 0;
     padding: 15px 10px 10px;
     letter-spacing: 0px;
+    height: 100%;
   }
   .canvas.empty {
     div {
diff --git a/src/views/appmanage/submutilform/index.jsx b/src/views/appmanage/submutilform/index.jsx
index bb23ae7..3a49a97 100644
--- a/src/views/appmanage/submutilform/index.jsx
+++ b/src/views/appmanage/submutilform/index.jsx
@@ -185,7 +185,7 @@
           </Col> : null}
           {typename !== 'pc' && user_binding.includes('sms_vcode') ? <Col span={12}>
             <Form.Item label={
-              <Tooltip placement="topLeft" title="鐭俊妯℃澘鍙湪绠$悊绯荤粺 HS-濂囦簯鐭俊妯℃澘 澶勬坊鍔犮��">
+              <Tooltip placement="topLeft" title="鐭俊妯℃澘鍙湪 浜戠郴缁�->搴旂敤鏈嶅姟->寮�鍙戣�呬腑蹇�->鐭俊妯℃澘 澶勬坊鍔犮��">
                 <QuestionCircleOutlined className="mk-form-tip" />
                 鐭俊妯℃澘
               </Tooltip>
diff --git a/src/views/design/sidemenu/config.jsx b/src/views/design/sidemenu/config.jsx
index 804b697..a9c12b3 100644
--- a/src/views/design/sidemenu/config.jsx
+++ b/src/views/design/sidemenu/config.jsx
@@ -185,13 +185,13 @@
   //   MenuID: '15900310928174dro07ihfckghpb5h13',
   //   MenuNo: 'bd_msn_sms_tempM',
   //   MenuName: '澶т簬鐭俊妯℃澘',
-  }, {
-    src: '',
-    PageParam: {OpenType: 'newtab', Template: 'ManageTable'},
-    type: 'ManageTable',
-    MenuID: '1599613340050c8nu6rbst9d4emnnbsq',
-    MenuNo: 's_sms_qxM',
-    MenuName: '濂囦簯鐭俊妯℃澘',
+  // }, {
+  //   src: '',
+  //   PageParam: {OpenType: 'newtab', Template: 'ManageTable'},
+  //   type: 'ManageTable',
+  //   MenuID: '1599613340050c8nu6rbst9d4emnnbsq',
+  //   MenuNo: 's_sms_qxM',
+  //   MenuName: '濂囦簯鐭俊妯℃澘',
   }]
 }, {
   MenuID: 'systemPayManage',
diff --git a/src/views/menudesign/index.scss b/src/views/menudesign/index.scss
index e4f1088..b19dd66 100644
--- a/src/views/menudesign/index.scss
+++ b/src/views/menudesign/index.scss
@@ -1,3 +1,6 @@
+body {
+  overflow-x: hidden;
+}
 .pc-menu-view {
   background: #000;
   min-height: 100vh;
diff --git a/src/views/pcdesign/index.scss b/src/views/pcdesign/index.scss
index ff44ef5..16c5edc 100644
--- a/src/views/pcdesign/index.scss
+++ b/src/views/pcdesign/index.scss
@@ -1,3 +1,6 @@
+body {
+  overflow-x: hidden;
+}
 .mk-pc-view {
   background: #000;
   min-height: 100vh;
diff --git a/src/views/rolemanage/index.jsx b/src/views/rolemanage/index.jsx
index 8451584..8277f73 100644
--- a/src/views/rolemanage/index.jsx
+++ b/src/views/rolemanage/index.jsx
@@ -809,6 +809,14 @@
     if (app.typename === 'pc') {
       route = 'pcdesign'
     }
+    if (item.type === 'navbar') {
+      notification.warning({
+        top: 92,
+        message: '瀵艰埅鏍忎笉鍙崟鐙紪杈戯紝璇峰湪鍚湁瀵艰埅鏍忕殑椤甸潰涓慨鏀广��',
+        duration: 5
+      })
+      return
+    }
 
     window.open(window.location.href.replace(/#.+/ig, `#/${route}/${window.btoa(window.encodeURIComponent(JSON.stringify({...app, MenuID: item.MenuID, type: 'app'})))}`))
   }

--
Gitblit v1.8.0