From 75f3fd6e67851b9079e0b82c8cd94bf7649fe8bd Mon Sep 17 00:00:00 2001
From: king <18310653075@163.com>
Date: 星期一, 08 三月 2021 18:53:44 +0800
Subject: [PATCH] 2021-03-08

---
 src/pc/components/navbar/normal-navbar/index.jsx                         |   18 
 src/menu/picturecontroller/index.jsx                                     |    4 
 src/menu/components/card/cardcellcomponent/dragaction/index.scss         |    2 
 src/pc/components/navbar/normal-navbar/linksetting/linktable/index.scss  |   20 +
 src/menu/components/card/cardcellcomponent/dragaction/index.jsx          |    6 
 src/menu/components/card/cardcellcomponent/elementform/index.jsx         |  147 ++++---
 src/pc/components/navbar/normal-navbar/linksetting/index.jsx             |   61 +++
 src/locales/zh-CN/model.js                                               |    2 
 src/menu/components/card/cardcellcomponent/dragaction/card.jsx           |    6 
 src/locales/en-US/model.js                                               |    2 
 src/pc/components/navbar/normal-navbar/linksetting/index.scss            |   11 
 src/pc/components/navbar/normal-navbar/linksetting/linktable/index.jsx   |  160 ++++++++
 src/tabviews/custom/components/card/cardcellList/index.jsx               |    4 
 src/menu/components/card/cardcellcomponent/index.jsx                     |   49 +
 src/views/pcdesign/index.jsx                                             |  115 +++---
 src/templates/zshare/formconfig.jsx                                      |    2 
 src/menu/components/share/actioncomponent/formconfig.jsx                 |   89 ++++
 src/pc/components/navbar/normal-navbar/linksetting/linkform/index.jsx    |  172 +++++++++
 src/pc/components/navbar/normal-navbar/menusetting/menuform/index.jsx    |   14 
 src/menu/components/share/actioncomponent/index.jsx                      |    4 
 src/menu/components/card/cardcellcomponent/formconfig.jsx                |   50 ++
 src/pc/components/navbar/normal-navbar/linksetting/linkform/index.scss   |    0 
 src/menu/components/share/actioncomponent/actionform/index.jsx           |   10 
 src/menu/picturecontroller/editform/index.jsx                            |   18 
 src/pc/components/navbar/normal-navbar/wrapsetting/settingform/index.jsx |   19 +
 src/pc/components/navbar/normal-navbar/index.scss                        |    4 
 src/templates/menuconfig/editthdmenu/menuform/index.jsx                  |    3 
 src/pc/components/navbar/normal-navbar/menusetting/index.scss            |    4 
 src/tabviews/zshare/fileupload/index.jsx                                 |    8 
 src/menu/components/card/cardcellcomponent/elementform/index.scss        |   15 
 src/tabviews/zshare/fileupload/index.scss                                |   10 
 src/components/Image/index.jsx                                           |    1 
 32 files changed, 850 insertions(+), 180 deletions(-)

diff --git a/src/components/Image/index.jsx b/src/components/Image/index.jsx
index 30631d4..508c7be 100644
--- a/src/components/Image/index.jsx
+++ b/src/components/Image/index.jsx
@@ -22,6 +22,7 @@
   }
 
   setSize = (width, height) => {
+    if (!this.ImageWrapDom) return
     const { clientWidth, clientHeight } = this.ImageWrapDom
 
     if (!clientWidth || !clientHeight || !width || !height) return
diff --git a/src/locales/en-US/model.js b/src/locales/en-US/model.js
index e80e10e..2d2ef4b 100644
--- a/src/locales/en-US/model.js
+++ b/src/locales/en-US/model.js
@@ -155,7 +155,7 @@
   'model.form.excelOut': 'Export excel',
   'model.form.newpage': 'The new page',
   'model.form.newpage.type': 'Page type',
-  'model.form.newpage.url': 'Page address',
+  'model.pageUrl': 'Page address',
   'model.form.prompt': 'Prompt',
   'model.form.exec': 'Direct execution',
   'model.form.paramJoint': 'Joint param',
diff --git a/src/locales/zh-CN/model.js b/src/locales/zh-CN/model.js
index fe25e94..c50cd3a 100644
--- a/src/locales/zh-CN/model.js
+++ b/src/locales/zh-CN/model.js
@@ -155,7 +155,7 @@
   'model.form.excelOut': '瀵煎嚭Excel',
   'model.form.newpage': '鏂伴〉闈�',
   'model.form.newpage.type': '椤甸潰绫诲瀷',
-  'model.form.newpage.url': '椤甸潰鍦板潃',
+  'model.pageUrl': '椤甸潰鍦板潃',
   'model.form.prompt': '鎻愮ず妗�',
   'model.form.exec': '鐩存帴鎵ц',
   'model.form.paramJoint': '鎷兼帴鍙傛暟',
diff --git a/src/menu/components/card/cardcellcomponent/dragaction/card.jsx b/src/menu/components/card/cardcellcomponent/dragaction/card.jsx
index 4bb5745..96b6549 100644
--- a/src/menu/components/card/cardcellcomponent/dragaction/card.jsx
+++ b/src/menu/components/card/cardcellcomponent/dragaction/card.jsx
@@ -19,7 +19,7 @@
 const Video = asyncComponent(() => import('@/components/video'))
 const MarkColumn = asyncIconComponent(() => import('@/menu/components/share/markcomponent'))
 
-const Card = ({ id, parent, fields, card, moveCard, findCard, editCard, delCard, copyCard, changeStyle, updateMarks }) => {
+const Card = ({ id, parent, fields, card, moveCard, findCard, editCard, delCard, copyCard, changeStyle, updateMarks, doubleClickCard }) => {
   const originalIndex = findCard(id).index
   const [{ isDragging }, drag] = useDrag({
     item: { type: 'action', id, originalIndex },
@@ -55,7 +55,7 @@
     } else if (card.eleType === 'text' || card.eleType === 'number') {
       let val = `${card.prefix || ''}${card.datatype === 'static' ? (card.value || '') : (card.field || '')}${card.postfix || ''}`
       return (
-        <div className={'ant-mk-text line' + card.height} style={{height: card.innerHeight || 21}}>{val}</div>
+        <div className={'ant-mk-text line' + (card.height || '')} style={{height: card.innerHeight || 'auto'}}>{val}</div>
       )
     } else if (card.eleType === 'icon') {
       return (<Icon type={card.icon}/>)
@@ -150,7 +150,7 @@
       </div>
     } trigger="hover">
       <div ref={node => drag(drop(node))} className={'ant-col card-cell ant-col-' + card.width}>
-        <div style={_style} onClick={clickComponent} id={card.uuid}>
+        <div style={_style} onClick={clickComponent} onDoubleClick={() => doubleClickCard(id)} id={card.uuid}>
           {getContent()}
         </div>
       </div>
diff --git a/src/menu/components/card/cardcellcomponent/dragaction/index.jsx b/src/menu/components/card/cardcellcomponent/dragaction/index.jsx
index c90814c..eda8cc2 100644
--- a/src/menu/components/card/cardcellcomponent/dragaction/index.jsx
+++ b/src/menu/components/card/cardcellcomponent/dragaction/index.jsx
@@ -80,6 +80,11 @@
 
   const doubleClickCard = id => {
     const { card } = findCard(id)
+
+    if (card.eleType !== 'button' && card.eleType !== 'text' && card.eleType !== 'picture') {
+      return
+    }
+    
     handleSubConfig(card)
   }
 
@@ -129,6 +134,7 @@
               editCard={editCard}
               updateMarks={updateMarks}
               changeStyle={changeStyle}
+              doubleClickCard={doubleClickCard}
               delCard={delCard}
               findCard={findCard}
             />
diff --git a/src/menu/components/card/cardcellcomponent/dragaction/index.scss b/src/menu/components/card/cardcellcomponent/dragaction/index.scss
index 1d8b187..2b2ec2c 100644
--- a/src/menu/components/card/cardcellcomponent/dragaction/index.scss
+++ b/src/menu/components/card/cardcellcomponent/dragaction/index.scss
@@ -4,7 +4,7 @@
     font-weight: inherit;
     text-decoration: inherit;
   }
-  .ant-mk-text:not(.line1) {
+  .ant-mk-text:not(.line1):not(.line) {
     word-break: break-word;
     display: -webkit-box;
     -webkit-box-orient: vertical;
diff --git a/src/menu/components/card/cardcellcomponent/elementform/index.jsx b/src/menu/components/card/cardcellcomponent/elementform/index.jsx
index f3507e3..c116d50 100644
--- a/src/menu/components/card/cardcellcomponent/elementform/index.jsx
+++ b/src/menu/components/card/cardcellcomponent/elementform/index.jsx
@@ -7,6 +7,7 @@
 import asyncComponent from '@/utils/asyncComponent'
 import './index.scss'
 
+const { TextArea } = Input
 const ColorSketch = asyncComponent(() => import('@/mob/colorsketch'))
 const SourceComponent = asyncComponent(() => import('@/menu/components/share/sourcecomponent'))
 
@@ -79,7 +80,7 @@
           item.required = card.eleType !== 'qrcode'
         }
         if (item.key === 'linkurl') {
-          item.type = card.link === 'dynamic' ? 'select' : 'text'
+          item.type = card.link === 'dynamic' ? 'select' : 'textarea'
         }
 
         return item
@@ -100,7 +101,13 @@
       }
 
       if (['text', 'picture'].includes(eleType) && link) {
-        _options.push('linkurl', 'joint')
+        if (link === 'dynamic' || link === 'static' || link === 'custom') {
+          _options.push('linkurl', 'joint')
+        } else if (link === 'page') {
+          _options.push('copyMenuId', 'joint')
+        } else if (link === 'linkpage') {
+          _options.push('linkmenu', 'joint')
+        }
       }
     } else if (eleType === 'icon') {
       if (datatype === 'dynamic') {
@@ -121,7 +128,7 @@
    */
   selectChange = (key, value, option) => {
     const { config } = this.props
-    const { datatype } = this.state
+    const { datatype, eleType } = this.state
 
     if (key === 'eleType') {
       let _options = this.getOptions(value, datatype, '')
@@ -185,6 +192,18 @@
       if (this.props.form.getFieldValue('value') !== undefined) {
         this.props.form.setFieldsValue({value: option.props.title})
       }
+    } else if (key === 'link') {
+      let _options = this.getOptions(eleType, this.state.datatype, value)
+      this.setState({
+        link: value,
+        formlist: this.state.formlist.map(item => {
+          item.hidden = !_options.includes(item.key)
+          if (item.key === 'linkurl') {
+            item.type = value === 'dynamic' ? 'select' : 'textarea'
+          }
+          return item
+        })
+      })
     }
   }
 
@@ -210,7 +229,7 @@
         formlist: this.state.formlist.map(item => {
           item.hidden = !_options.includes(item.key)
           if (item.key === 'linkurl') {
-            item.type = value === 'dynamic' ? 'select' : 'text'
+            item.type = value === 'dynamic' ? 'select' : 'textarea'
           }
           return item
         })
@@ -231,15 +250,13 @@
     const fields = []
 
     this.state.formlist.forEach((item, index) => {
-      if (item.hidden) return
+      if (item.hidden || item.forbid) return
 
       if (item.type === 'text') { // 鏂囨湰鎼滅储
-        let rules = []
-
         fields.push(
           <Col span={12} key={index}>
             <Form.Item label={item.tooltip ?
-              <Tooltip placement="topLeft" overlayClassName={item.tooltipClass} title={item.tooltip}>
+              <Tooltip placement="topLeft" title={item.tooltip}>
                 <Icon type="question-circle" />
                 {item.label}
               </Tooltip> : item.label
@@ -254,39 +271,17 @@
                   {
                     max: formRule.input.max,
                     message: formRule.input.message
-                  },
-                  ...rules
+                  }
                 ]
               })(<Input placeholder="" autoComplete="off" disabled={item.readonly} onPressEnter={this.handleSubmit} />)}
             </Form.Item>
           </Col>
         )
-      } else if (item.type === 'number') {
+      } else if (item.type === 'textarea') { // 鏂囨湰鎼滅储
         fields.push(
-          <Col span={12} key={index}>
+          <Col span={24} className="textarea" key={index}>
             <Form.Item label={item.tooltip ?
-              <Tooltip placement="topLeft" overlayClassName={item.tooltipClass} title={item.tooltip}>
-                <Icon type="question-circle" />
-                {item.label}
-              </Tooltip> : item.label
-            }>
-              {getFieldDecorator(item.key, {
-                initialValue: item.initVal,
-                rules: [
-                  {
-                    required: item.readonly ? false : !!item.required,
-                    message: this.props.dict['form.required.input'] + item.label + '!'
-                  }
-                ]
-              })(<InputNumber min={item.min || 0} max={item.max || 10000} precision={item.precision || 0} onPressEnter={this.handleSubmit} />)}
-            </Form.Item>
-          </Col>
-        )
-      } else if (item.type === 'select') { // 涓嬫媺鎼滅储
-        fields.push(
-          <Col span={12} key={index}>
-            <Form.Item label={item.tooltip ?
-              <Tooltip placement="topLeft" overlayClassName={item.tooltipClass} title={item.tooltip}>
+              <Tooltip placement="topLeft" title={item.tooltip}>
                 <Icon type="question-circle" />
                 {item.label}
               </Tooltip> : item.label
@@ -295,10 +290,52 @@
                 initialValue: item.initVal || '',
                 rules: [
                   {
-                    required: !!item.required,
-                    message: this.props.dict['form.required.select'] + item.label + '!'
+                    required: item.readonly ? false : !!item.required,
+                    message: this.props.dict['form.required.input'] + item.label + '!'
+                  },
+                  {
+                    max: formRule.input.max,
+                    message: formRule.input.message
                   }
                 ]
+              })(<TextArea rows={2} disabled={item.readonly} />)}
+            </Form.Item>
+          </Col>
+        )
+      } else if (item.type === 'number') {
+        fields.push(
+          <Col span={12} key={index}>
+            <Form.Item label={item.tooltip ?
+              <Tooltip placement="topLeft" title={item.tooltip}>
+                <Icon type="question-circle" />
+                {item.label}
+              </Tooltip> : item.label
+            }>
+              {getFieldDecorator(item.key, {
+                initialValue: item.initVal,
+                rules: [{
+                  required: item.readonly ? false : !!item.required,
+                  message: this.props.dict['form.required.input'] + item.label + '!'
+                }]
+              })(<InputNumber min={item.min || 0} max={item.max || 10000} precision={item.precision || 0} onPressEnter={this.handleSubmit} />)}
+            </Form.Item>
+          </Col>
+        )
+      } else if (item.type === 'select') { // 涓嬫媺鎼滅储
+        fields.push(
+          <Col span={12} key={index}>
+            <Form.Item label={item.tooltip ?
+              <Tooltip placement="topLeft" title={item.tooltip}>
+                <Icon type="question-circle" />
+                {item.label}
+              </Tooltip> : item.label
+            }>
+              {getFieldDecorator(item.key, {
+                initialValue: item.initVal || '',
+                rules: [{
+                  required: !!item.required,
+                  message: this.props.dict['form.required.select'] + item.label + '!'
+                }]
               })(
                 <Select
                   showSearch
@@ -319,24 +356,25 @@
       } else if (item.type === 'radio') {
         fields.push(
           <Col span={12} key={index}>
-            <Form.Item label={item.label}>
+            <Form.Item label={item.tooltip ?
+              <Tooltip placement="topLeft" title={item.tooltip}>
+                <Icon type="question-circle" />
+                {item.label}
+              </Tooltip> : item.label
+            }>
               {getFieldDecorator(item.key, {
                 initialValue: item.initVal,
-                rules: [
-                  {
-                    required: !!item.required,
-                    message: this.props.dict['form.required.select'] + item.label + '!'
-                  }
-                ]
+                rules: [{
+                  required: !!item.required,
+                  message: this.props.dict['form.required.select'] + item.label + '!'
+                }]
               })(
                 <Radio.Group onChange={(e) => {this.onChange(e, item.key)}} disabled={item.readonly}>
-                  {
-                    item.options.map(option => {
-                      return (
-                        <Radio key={option.value} value={option.value}>{option.text}</Radio>
-                      )
-                    })
-                  }
+                  {item.options.map(option => {
+                    return (
+                      <Radio key={option.value} value={option.value}>{option.text}</Radio>
+                    )
+                  })}
                 </Radio.Group>
               )}
             </Form.Item>
@@ -390,15 +428,6 @@
         if (!err) {
           values.uuid = this.props.card.uuid
           values.marks = this.props.card.marks || null
-
-          // if (values.eleType === 'picture' && values.datatype === 'static' && !values.url) {
-          //   notification.warning({
-          //     top: 92,
-          //     message: '灏氭湭娣诲姞鍥剧墖鎴栧浘鐗囦笂浼犲け璐ワ紝璇烽噸鏂版坊鍔狅紒',
-          //     duration: 5
-          //   })
-          //   return
-          // }
 
           resolve(values)
         } else {
diff --git a/src/menu/components/card/cardcellcomponent/elementform/index.scss b/src/menu/components/card/cardcellcomponent/elementform/index.scss
index 58fef06..f969efa 100644
--- a/src/menu/components/card/cardcellcomponent/elementform/index.scss
+++ b/src/menu/components/card/cardcellcomponent/elementform/index.scss
@@ -10,8 +10,19 @@
       margin-right: 5px;
     }
   }
-  .ant-col {
-    height: 65px;
+  >.ant-row {
+    >.ant-col {
+      height: 65px;
+    }
+    .ant-col.textarea {
+      height: 80px;
+      .ant-form-item-label {
+        width: 14.2%;
+      }
+      .ant-form-item-control-wrapper {
+        width: 85.8%;
+      }
+    }
   }
   .color-form {
     .ant-form-item-control {
diff --git a/src/menu/components/card/cardcellcomponent/formconfig.jsx b/src/menu/components/card/cardcellcomponent/formconfig.jsx
index 1dc6f8c..2552a71 100644
--- a/src/menu/components/card/cardcellcomponent/formconfig.jsx
+++ b/src/menu/components/card/cardcellcomponent/formconfig.jsx
@@ -25,6 +25,22 @@
   if (type === 'table') {
     _options.push({value: 'sequence', text: '搴忓彿'})
   }
+  let appMenus = []
+  const isApp = sessionStorage.getItem('appType') === 'pc'
+
+  if (isApp) {
+    appMenus = sessionStorage.getItem('appMenus')
+    if (appMenus) {
+      try {
+        appMenus = JSON.parse(appMenus)
+        appMenus = appMenus.map(item => ({value: item.MenuID, text: item.MenuName}))
+      } catch {
+        appMenus = []
+      }
+    } else {
+      appMenus = []
+    }
+  }
 
   let forms = [
     {
@@ -138,7 +154,9 @@
       key: 'link',
       label: '閾炬帴',
       initVal: card.link || '',
+      tooltip: '鍔ㄦ�佸湴鍧�涓虹粦瀹氬瓧娈靛�笺��',
       required: false,
+      forbid: isApp,
       options: [
         { value: '', text: '鏃�' },
         { value: 'dynamic', text: '鍔ㄦ��' },
@@ -147,6 +165,38 @@
     },
     {
       type: 'select',
+      key: 'link',
+      label: '閾炬帴',
+      initVal: card.link || '',
+      required: false,
+      forbid: !isApp,
+      options: [
+        { value: '', text: '鏃�' },
+        { value: 'page', text: '鑿滃崟' },
+        { value: 'linkpage', text: '鍏宠仈鑿滃崟' },
+        { value: 'custom', text: '閾炬帴' }
+      ]
+    },
+    {
+      type: 'select',
+      key: 'linkmenu',
+      label: '鍏宠仈鑿滃崟',
+      initVal: card.linkmenu || '',
+      required: true,
+      forbid: !isApp,
+      options: appMenus
+    },
+    {
+      type: 'select',
+      key: 'copyMenuId',
+      label: '澶嶅埗鑿滃崟',
+      initVal: card.copyMenuId || '',
+      required: false,
+      forbid: !isApp,
+      options: appMenus
+    },
+    {
+      type: 'select',
       key: 'linkurl',
       label: '閾炬帴鍦板潃',
       initVal: card.linkurl || '',
diff --git a/src/menu/components/card/cardcellcomponent/index.jsx b/src/menu/components/card/cardcellcomponent/index.jsx
index fcb32ec..286bed6 100644
--- a/src/menu/components/card/cardcellcomponent/index.jsx
+++ b/src/menu/components/card/cardcellcomponent/index.jsx
@@ -176,7 +176,7 @@
 
       let fontSize = 14
       let lineHeight = 1.5
-      let line = _card.height || 1
+      let line = _card.height || null
 
       if (_card.style.fontSize) {
         fontSize = parseInt(_card.style.fontSize)
@@ -185,7 +185,9 @@
         lineHeight = parseFloat(_card.style.lineHeight)
       }
 
-      _card.innerHeight = fontSize * lineHeight * line
+      if (line) {
+        _card.innerHeight = fontSize * lineHeight * line
+      }
     } else if (_card.eleType === 'barcode') {
       _card.style = style
 
@@ -351,7 +353,7 @@
           } else if (res.eleType === 'text' || res.eleType === 'number') {
             let fontSize = 14
             let lineHeight = 1.5
-            let line = res.height || 1
+            let line = res.height || null
       
             if (res.style && res.style.fontSize) {
               fontSize = parseInt(res.style.fontSize)
@@ -359,7 +361,10 @@
             if (res.style && res.style.lineHeight) {
               lineHeight = parseFloat(res.style.lineHeight)
             }
-            res.innerHeight = fontSize * lineHeight * line
+
+            if (line) {
+              res.innerHeight = fontSize * lineHeight * line
+            }
 
             if (res.eleType === 'text' && res.link && !res.style.color) {
               res.style.color = '#2440B3'
@@ -498,21 +503,33 @@
     const { cards } = this.props
     let btn = fromJS(item).toJS()
 
-    if (btn.eleType !== 'button' || (sessionStorage.getItem('style-control') && sessionStorage.getItem('style-control') !== 'false')) return
+    if ((sessionStorage.getItem('style-control') && sessionStorage.getItem('style-control') !== 'false')) return
 
-    if (btn.OpenType === 'pop') {
-      if (!btn.modal) {
-        btn.modal = {
-          setting: { title: btn.label, width: 60, cols: '2', container: 'view', focus: '', finish: 'close', clickouter: 'unclose', display: 'modal' },
-          tables: [],
-          groups: [],
-          fields: []
+    if (btn.eleType === 'button') {
+      if (btn.OpenType === 'pop') {
+        if (!btn.modal) {
+          btn.modal = {
+            setting: { title: btn.label, width: 60, cols: '2', container: 'view', focus: '', finish: 'close', clickouter: 'unclose', display: 'modal' },
+            tables: [],
+            groups: [],
+            fields: []
+          }
         }
+  
+        MKEmitter.emit('changeModal', cards, btn)
+      } else if (btn.OpenType === 'popview') {
+        MKEmitter.emit('changePopview', cards, btn)
+      } else if (btn.OpenType === 'innerpage' && btn.pageTemplate === 'page') {
+        MKEmitter.emit('changeEditMenu', {MenuID: btn.uuid, copyMenuId: btn.copyMenuId})
+      } else if (btn.OpenType === 'innerpage' && btn.pageTemplate === 'linkpage') {
+        MKEmitter.emit('changeEditMenu', {MenuID: btn.linkmenu})
       }
-
-      MKEmitter.emit('changeModal', cards, btn)
-    } else if (btn.OpenType === 'popview') {
-      MKEmitter.emit('changePopview', cards, btn)
+    } else {
+      if (btn.link === 'page') {
+        MKEmitter.emit('changeEditMenu', {MenuID: btn.uuid, copyMenuId: btn.copyMenuId})
+      } else if (btn.link === 'linkpage') {
+        MKEmitter.emit('changeEditMenu', {MenuID: btn.linkmenu})
+      }
     }
   }
 
diff --git a/src/menu/components/share/actioncomponent/actionform/index.jsx b/src/menu/components/share/actioncomponent/actionform/index.jsx
index bd7648b..3d5b9a6 100644
--- a/src/menu/components/share/actioncomponent/actionform/index.jsx
+++ b/src/menu/components/share/actioncomponent/actionform/index.jsx
@@ -15,7 +15,7 @@
   excelOut: ['label', 'OpenType', 'intertype', 'show', 'icon', 'class', 'execSuccess', 'execError', 'syncComponent', 'resetPageIndex', 'pagination', 'search', 'width'],
   popview: ['label', 'Ot', 'OpenType', 'show', 'icon', 'class', 'popClose', 'resetPageIndex', 'width'],
   tab: ['label', 'Ot', 'OpenType', 'show', 'icon', 'class', 'linkmenu', 'width'],
-  innerpage: ['label', 'Ot', 'OpenType', 'pageTemplate', 'show', 'icon', 'class', 'width'],
+  innerpage: ['label', 'Ot', 'OpenType', 'pageTemplate', 'show', 'icon', 'class', 'width', 'open'],
   funcbutton: ['label', 'OpenType', 'funcType', 'show', 'icon', 'class', 'width']
 }
 
@@ -89,8 +89,8 @@
 
     let _opentype = card.OpenType                // 鎵撳紑鏂瑰紡
     let _intertype = card.intertype || 'system'  // 鎺ュ彛绫诲瀷
-    let _funcType = card.funcType || 'print'     // 鍔熻兘鎸夐挳榛樿绫诲瀷
-    let _procMode = card.procMode || 'system'     // 鍙傛暟璇锋眰鏂瑰紡
+    let _funcType = card.funcType || ''          // 鍔熻兘鎸夐挳榛樿绫诲瀷
+    let _procMode = card.procMode || 'system'    // 鍙傛暟璇锋眰鏂瑰紡
 
     let _options = this.getOptions(_opentype, _intertype, _funcType, card.pageTemplate, _procMode)
 
@@ -143,6 +143,10 @@
     if (_opentype === 'innerpage') {         // 鏂伴〉闈紝鍙�夋ā鏉�(鑷畾涔夋椂锛屽彲濉叆澶栭儴閾炬帴)
       if (_pageTemplate === 'custom') {
         _options.push('url', 'joint')
+      } else if (_pageTemplate === 'page') {
+        _options.push('copyMenuId', 'joint')
+      } else if (_pageTemplate === 'linkpage') {
+        _options.push('linkmenu', 'joint')
       }
     } else if (_opentype === 'excelOut') {    // 瀵煎叆瀵煎嚭
       if (_intertype === 'outer') {
diff --git a/src/menu/components/share/actioncomponent/formconfig.jsx b/src/menu/components/share/actioncomponent/formconfig.jsx
index f5941c6..8043242 100644
--- a/src/menu/components/share/actioncomponent/formconfig.jsx
+++ b/src/menu/components/share/actioncomponent/formconfig.jsx
@@ -12,6 +12,7 @@
  * @param {*} type           鎸夐挳绫诲瀷锛岀敤浜庡尯鍒嗗彲閫夌殑鎵撳紑鏂瑰紡
  */
 export function getActionForm (card, functip, setting, usefulFields, type, menulist = [], modules = []) {
+  let appMenus = []
   let opentypes = [
     {
       value: 'pop',
@@ -43,6 +44,43 @@
     }
   ]
 
+  let pageTemps = [
+    { value: 'billprint', text: '鍗曟嵁鎵撳嵃' },
+    { value: 'pay', text: Formdict['model.pay'] },
+    { value: 'custom', text: Formdict['header.form.custom'] }
+  ]
+  const isApp = sessionStorage.getItem('appType') === 'pc'
+
+  let funTypes = [
+    { value: 'changeuser', text: Formdict['header.form.func.changeuser'] },
+    { value: 'print', text: '鏍囩鎵撳嵃' }
+  ]
+  
+  if (isApp) {
+    opentypes = opentypes.filter(item => item.value !== 'tab')
+    pageTemps = [
+      { value: 'page', text: '鑿滃崟' },
+      { value: 'linkpage', text: '鍏宠仈鑿滃崟' },
+      { value: 'billprint', text: '鍗曟嵁鎵撳嵃' },
+      { value: 'pay', text: Formdict['model.pay'] },
+      { value: 'custom', text: '閾炬帴' }
+    ]
+    funTypes = [
+      { value: 'changeuser', text: Formdict['header.form.func.changeuser'] },
+    ]
+    appMenus = sessionStorage.getItem('appMenus')
+    if (appMenus) {
+      try {
+        appMenus = JSON.parse(appMenus)
+        appMenus = appMenus.map(item => ({value: item.MenuID, text: item.MenuName}))
+      } catch {
+        appMenus = []
+      }
+    } else {
+      appMenus = []
+    }
+  }
+  
   if (type === 'chart') {
     opentypes = opentypes.filter(item => item.value === 'excelIn' || item.value === 'excelOut')
   }
@@ -69,15 +107,9 @@
       type: 'radio',
       key: 'funcType',
       label: Formdict['header.form.funcType'],
-      initVal: card.funcType || 'print',
+      initVal: card.funcType || (isApp ? 'changeuser' : ''),
       required: true,
-      options: [{
-        value: 'changeuser',
-        text: Formdict['header.form.func.changeuser']
-      }, {
-        value: 'print',
-        text: '鏍囩鎵撳嵃'
-      }]
+      options: funTypes
     },
     {
       type: 'select',
@@ -158,21 +190,43 @@
       label: Formdict['model.form.newpage.type'],
       initVal: card.pageTemplate || '',
       required: true,
+      options: pageTemps
+    },
+    {
+      type: 'radio',
+      key: 'open',
+      label: '閾炬帴鏂瑰紡',
+      initVal: card.open || 'blank',
+      required: true,
+      forbid: !isApp,
       options: [{
-        value: 'billprint',
-        text: '鍗曟嵁鎵撳嵃'
+        value: 'blank',
+        text: '鏂扮獥鍙�'
       }, {
-        value: 'pay',
-        text: Formdict['model.pay']
-      }, {
-        value: 'custom',
-        text: Formdict['header.form.custom']
+        value: 'self',
+        text: '褰撳墠绐楀彛'
       }]
     },
     {
-      type: 'text',
+      type: 'select',
+      key: 'linkmenu',
+      label: '鍏宠仈鑿滃崟',
+      initVal: card.linkmenu || '',
+      required: true,
+      options: appMenus
+    },
+    {
+      type: 'select',
+      key: 'copyMenuId',
+      label: '澶嶅埗鑿滃崟',
+      initVal: card.copyMenuId || '',
+      required: false,
+      options: appMenus
+    },
+    {
+      type: 'textarea',
       key: 'url',
-      label: Formdict['model.form.newpage.url'],
+      label: Formdict['model.pageUrl'],
       initVal: card.url || '',
       required: true
     },
@@ -273,6 +327,7 @@
       label: Formdict['model.form.linkmenu'],
       initVal: card.linkmenu || [],
       required: true,
+      forbid: isApp,
       options: menulist
     },
     {
diff --git a/src/menu/components/share/actioncomponent/index.jsx b/src/menu/components/share/actioncomponent/index.jsx
index 5a26528..e42041d 100644
--- a/src/menu/components/share/actioncomponent/index.jsx
+++ b/src/menu/components/share/actioncomponent/index.jsx
@@ -406,6 +406,10 @@
     
     if (element.OpenType === 'pop' || element.OpenType === 'popview' || element.execMode === 'pop') {
       this.props.setSubConfig(element)
+    } else if (element.OpenType === 'innerpage' && element.pageTemplate === 'page') {
+      MKEmitter.emit('changeEditMenu', {MenuID: element.uuid, copyMenuId: element.copyMenuId})
+    } else if (element.OpenType === 'innerpage' && element.pageTemplate === 'linkpage') {
+      MKEmitter.emit('changeEditMenu', {MenuID: element.linkmenu})
     } else {
       notification.warning({
         top: 92,
diff --git a/src/menu/picturecontroller/editform/index.jsx b/src/menu/picturecontroller/editform/index.jsx
index 0d4db6b..e12d46d 100644
--- a/src/menu/picturecontroller/editform/index.jsx
+++ b/src/menu/picturecontroller/editform/index.jsx
@@ -31,8 +31,22 @@
               duration: 5
             })
             return
-          } else if (values.urls && values.urls[0]) {
+          } else if (values.urls && values.urls[0] && values.urls[0].status !== 'done') {
+            notification.warning({
+              top: 92,
+              message: '鏂囦欢涓婁紶涓紝璇风◢鍚庯紒',
+              duration: 5
+            })
+            return
+          } else if (values.urls && values.urls[0] && values.urls[0].response) {
             values.linkurl = values.urls[0].response
+          } else {
+            notification.warning({
+              top: 92,
+              message: '鏈幏鍙栧埌鏂囦欢璺緞锛�',
+              duration: 5
+            })
+            return
           }
           resolve(values)
         } else {
@@ -141,7 +155,7 @@
           <Col span={24}>
             <Form.Item label="澶囨敞">
               {getFieldDecorator('remark', {
-                initialValue: card.remark,
+                initialValue: card.remark || '',
                 rules: [
                   {
                     max: 50,
diff --git a/src/menu/picturecontroller/index.jsx b/src/menu/picturecontroller/index.jsx
index 7d887b7..cb45a35 100644
--- a/src/menu/picturecontroller/index.jsx
+++ b/src/menu/picturecontroller/index.jsx
@@ -248,7 +248,7 @@
                 </Col>
               </Row>
               <Row gutter={16} style={{height: '340px'}}>
-                {piclist.length && piclist.map(item => (
+                {piclist.length > 0 && piclist.map(item => (
                   <Col span={4} key={item.id}>
                     <div className="image-video-box">
                       <div className="image-video-box-body">
@@ -279,7 +279,7 @@
                 </Col>
               </Row>
               <Row gutter={16} style={{height: '340px'}}>
-                {vidlist.length && vidlist.map(item => (
+                {vidlist.length > 0 && vidlist.map(item => (
                   <Col span={4} key={item.id}>
                     <div className="image-video-box">
                       <div className="image-video-box-body">
diff --git a/src/pc/components/navbar/normal-navbar/index.jsx b/src/pc/components/navbar/normal-navbar/index.jsx
index 35ef413..388f226 100644
--- a/src/pc/components/navbar/normal-navbar/index.jsx
+++ b/src/pc/components/navbar/normal-navbar/index.jsx
@@ -1,23 +1,21 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
 import { is, fromJS } from 'immutable'
-import { Icon, Popover, Menu } from 'antd'
+import { Icon, Popover, Menu, Button } from 'antd'
 
 import asyncIconComponent from '@/utils/asyncIconComponent'
 
 import MKEmitter from '@/utils/events.js'
-// import Utils from '@/utils/utils.js'
 import zhCN from '@/locales/zh-CN/model.js'
 import enUS from '@/locales/en-US/model.js'
 import './index.scss'
 
 const WrapComponent = asyncIconComponent(() => import('./wrapsetting'))
 const MenuComponent = asyncIconComponent(() => import('./menusetting'))
-// const CardComponent = asyncComponent(() => import('../cardcomponent'))
+const LinkComponent = asyncIconComponent(() => import('./linksetting'))
 const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent'))
 const UserComponent = asyncIconComponent(() => import('@/menu/components/share/usercomponent'))
 
-// const { confirm } = Modal
 const { SubMenu } = Menu
 
 class NormalNavbar extends Component {
@@ -158,7 +156,10 @@
   }
 
   changeMenu = (menu) => {
-    MKEmitter.emit('changeEditMenu', menu)
+    MKEmitter.emit('changeEditMenu', {
+      MenuID: menu.property === 'linkmenu' ? menu.linkMenuId : menu.MenuID,
+      copyMenuId: menu.property === 'menu' ? menu.copyMenuId : '',
+    })
   }
 
   changeLogoMenu = () => {
@@ -182,6 +183,7 @@
         <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
           <div className="mk-popover-control">
             <MenuComponent config={card} updateConfig={this.updateComponent} />
+            <LinkComponent config={card} updateConfig={this.updateComponent} />
             <WrapComponent config={card} updateConfig={this.updateComponent} />
             <CopyComponent type="normalnarbar" card={card}/>
             <Icon className="style" title="璋冩暣鏍峰紡" onClick={this.changeStyle} type="font-colors" />
@@ -238,7 +240,11 @@
               })}
             </Menu>
           </div>
-          <div className="link">asdfds</div>
+          <div className="link">
+            {card.links.map(link => {
+              return <Button type="link" key={link.MenuID} onDoubleClick={() => this.changeMenu(link)}>{link.name}</Button>
+            })}
+          </div>
         </div>
       </div>
     )
diff --git a/src/pc/components/navbar/normal-navbar/index.scss b/src/pc/components/navbar/normal-navbar/index.scss
index f099ebb..ebd7439 100644
--- a/src/pc/components/navbar/normal-navbar/index.scss
+++ b/src/pc/components/navbar/normal-navbar/index.scss
@@ -49,6 +49,10 @@
       flex: 1;
       display: inline-block;
       text-align: right;
+      color: inherit;
+      button {
+        color: inherit;
+      }
     }
   }
   .card-control {
diff --git a/src/pc/components/navbar/normal-navbar/linksetting/index.jsx b/src/pc/components/navbar/normal-navbar/linksetting/index.jsx
new file mode 100644
index 0000000..28bc15c
--- /dev/null
+++ b/src/pc/components/navbar/normal-navbar/linksetting/index.jsx
@@ -0,0 +1,61 @@
+import React, {Component} from 'react'
+import PropTypes from 'prop-types'
+import { is, fromJS } from 'immutable'
+import { Icon, Modal } from 'antd'
+
+import zhCN from '@/locales/zh-CN/model.js'
+import enUS from '@/locales/en-US/model.js'
+import LinkTable from './linktable'
+import './index.scss'
+
+class DataSource extends Component {
+  static propTpyes = {
+    config: PropTypes.any,
+    updateConfig: PropTypes.func
+  }
+
+  state = {
+    dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,
+    visible: false
+  }
+
+  shouldComponentUpdate (nextProps, nextState) {
+    return !is(fromJS(this.props), fromJS(nextProps)) || !is(fromJS(this.state), fromJS(nextState))
+  }
+
+  verifySubmit = () => {
+    const { config } = this.props
+
+    this.props.updateConfig({...config, links: this.mTable.state.data || []})
+    this.setState({visible: false})
+  }
+
+  render () {
+    const { config } = this.props
+    const { visible, dict } = this.state
+
+    return (
+      <div className="model-link-setting-wrap">
+        <Icon type="link" title="閾炬帴" onClick={() => this.setState({ visible: true })}/>
+        <Modal
+          wrapClassName="popview-modal"
+          title="閾炬帴缂栬緫"
+          visible={visible}
+          width={950}
+          maskClosable={false}
+          okText={dict['model.submit']}
+          onOk={this.verifySubmit}
+          onCancel={() => { this.setState({ visible: false }) }}
+          destroyOnClose
+        >
+          <LinkTable
+            links={config.links || []}
+            ref={(ref) => { this.mTable = ref }}
+          />
+        </Modal>
+      </div>
+    )
+  }
+}
+
+export default DataSource
\ No newline at end of file
diff --git a/src/pc/components/navbar/normal-navbar/linksetting/index.scss b/src/pc/components/navbar/normal-navbar/linksetting/index.scss
new file mode 100644
index 0000000..e12d9e9
--- /dev/null
+++ b/src/pc/components/navbar/normal-navbar/linksetting/index.scss
@@ -0,0 +1,11 @@
+.model-link-setting-wrap {
+  display: inline-block;
+
+  >.anticon-link {
+    color: rgb(38, 194, 129);
+  }
+
+  >.anticon-edit {
+    color: #1890ff;
+  }
+}
\ No newline at end of file
diff --git a/src/pc/components/navbar/normal-navbar/linksetting/linkform/index.jsx b/src/pc/components/navbar/normal-navbar/linksetting/linkform/index.jsx
new file mode 100644
index 0000000..a07f0a8
--- /dev/null
+++ b/src/pc/components/navbar/normal-navbar/linksetting/linkform/index.jsx
@@ -0,0 +1,172 @@
+import React, {Component} from 'react'
+import PropTypes from 'prop-types'
+import { Form, Row, Col, Input, Radio, Tooltip, Icon, Select } from 'antd'
+
+import './index.scss'
+
+const { TextArea } = Input
+
+class SettingForm extends Component {
+  static propTpyes = {
+    menu: PropTypes.object,    // 鍗$墖琛屼俊鎭�
+    inputSubmit: PropTypes.func  // 鍥炶溅浜嬩欢
+  }
+
+  state = {
+    property: this.props.menu.property || 'link',
+    linkIntId: this.props.menu.linkIntId || '',
+    appMenus: [],
+  }
+
+  UNSAFE_componentWillMount () {
+    let appMenus = sessionStorage.getItem('appMenus')
+    if (appMenus) {
+      try {
+        appMenus = JSON.parse(appMenus)
+      } catch {
+        appMenus = []
+      }
+    } else {
+      appMenus = []
+    }
+
+    this.setState({appMenus})
+  }
+
+  componentDidMount() {
+    const { menu } = this.props
+
+    if (!menu.MenuID) {
+      let _form = document.getElementById('name')
+      _form && _form.select()
+    }
+  }
+
+  handleConfirm = () => {
+    // 琛ㄥ崟鎻愪氦鏃舵鏌ヨ緭鍏ュ�兼槸鍚︽纭�
+    return new Promise((resolve, reject) => {
+      this.props.form.validateFieldsAndScroll((err, values) => {
+        if (!err) {
+          if (values.linkmenuid) {
+            values.linkIntId = this.state.linkIntId || ''
+          }
+          resolve(values)
+        } else {
+          reject(err)
+        }
+      })
+    })
+  }
+
+  handleSubmit = (e) => {
+    e.preventDefault()
+
+    if (this.props.inputSubmit) {
+      this.props.inputSubmit()
+    }
+  }
+
+  changeProperty = (e) => {
+    let val = e.target.value
+
+    this.setState({property: val})
+  }
+
+  changeLinkMenu = (val, { props }) => {
+    this.setState({linkIntId: props.intid})
+  }
+
+  render() {
+    const { menu } = this.props
+    const { getFieldDecorator } = this.props.form
+    const { property, appMenus } = this.state
+
+    const formItemLayout = {
+      labelCol: {
+        xs: { span: 24 },
+        sm: { span: 8 }
+      },
+      wrapperCol: {
+        xs: { span: 24 },
+        sm: { span: 16 }
+      }
+    }
+
+    return (
+      <Form {...formItemLayout}>
+        <Row gutter={24}>
+          <Col span={22}>
+            <Form.Item label="閾炬帴鍚嶇О">
+              {getFieldDecorator('name', {
+                initialValue: menu.name,
+                rules: [
+                  {
+                    required: true,
+                    message: '璇疯緭鍏ラ摼鎺ュ悕绉�!'
+                  }
+                ]
+              })(<Input placeholder={''} autoComplete="off" onPressEnter={this.handleSubmit} />)}
+            </Form.Item>
+          </Col>
+          <Col span={22}>
+            <Form.Item label="閾炬帴灞炴��">
+              {getFieldDecorator('property', {
+                initialValue: menu.property || 'link'
+              })(
+                <Radio.Group onChange={this.changeProperty}>
+                  <Radio value="link">閾炬帴</Radio>
+                  <Radio value="linkmenu">鍏宠仈鑿滃崟</Radio>
+                </Radio.Group>
+              )}
+            </Form.Item>
+          </Col>
+          {property === 'link' ? <Col span={22}>
+            <Form.Item label="閾炬帴鍦板潃">
+              {getFieldDecorator('link', {
+                initialValue: menu.link || '',
+                rules: [{
+                  required: true,
+                  message: '璇疯緭鍏ラ摼鎺ュ湴鍧�!'
+                }]
+              })(<TextArea rows={2} />)}
+            </Form.Item>
+          </Col> : null}
+          <Col span={22}>
+            <Form.Item label="鎵撳紑鏂瑰紡">
+              {getFieldDecorator('open', {
+                initialValue: menu.open || 'blank'
+              })(
+                <Radio.Group>
+                  <Radio value="blank">鏂扮獥鍙�</Radio>
+                  <Radio value="self">褰撳墠绐楀彛</Radio>
+                </Radio.Group>
+              )}
+            </Form.Item>
+          </Col>
+          {property === 'linkmenu' ? <Col span={22}>
+            <Form.Item label={
+              <Tooltip placement="topLeft" title="鍏宠仈褰撳墠app涓凡鏈夌殑鑿滃崟銆�">
+                <Icon type="question-circle" style={{color: '#c49f47', marginRight: '3px'}}/>
+                鍏宠仈鑿滃崟
+              </Tooltip>
+            }>
+              {getFieldDecorator('linkMenuId', {
+                initialValue: menu.linkMenuId || '',
+                rules: [{
+                  required: true,
+                  message: '璇烽�夋嫨鍏宠仈鑿滃崟!'
+                }]
+              })(
+                <Select onChange={this.changeLinkMenu}>
+                  {appMenus.map(item => (<Select.Option key={item.MenuID} intid={item.menuid_int} value={item.MenuID}>{item.MenuName}</Select.Option>))}
+                </Select>
+              )}
+            </Form.Item>
+          </Col> : null}
+        </Row>
+      </Form>
+    )
+  }
+}
+
+export default Form.create()(SettingForm)
\ No newline at end of file
diff --git a/src/pc/components/navbar/normal-navbar/linksetting/linkform/index.scss b/src/pc/components/navbar/normal-navbar/linksetting/linkform/index.scss
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/pc/components/navbar/normal-navbar/linksetting/linkform/index.scss
diff --git a/src/pc/components/navbar/normal-navbar/linksetting/linktable/index.jsx b/src/pc/components/navbar/normal-navbar/linksetting/linktable/index.jsx
new file mode 100644
index 0000000..f4a693c
--- /dev/null
+++ b/src/pc/components/navbar/normal-navbar/linksetting/linktable/index.jsx
@@ -0,0 +1,160 @@
+import React, {Component} from 'react'
+import PropTypes from 'prop-types'
+import { is, fromJS } from 'immutable'
+import { Table, Button, Modal, Icon } from 'antd'
+
+import LinkForm from '../linkform'
+import Utils from '@/utils/utils.js'
+import './index.scss'
+
+const { confirm } = Modal
+
+class LinkTable extends Component {
+  static propTpyes = {
+    links: PropTypes.object,    // 鍗$墖琛屼俊鎭�
+  }
+
+  state = {
+    data: [],
+    editMenu: null,
+    columns: [
+      { title: '閾炬帴鍚嶇О', dataIndex: 'name', key: 'name' },
+      { title: '閾炬帴灞炴��', dataIndex: 'property', key: 'property',  render: text => {
+        const trans = {link: '閾炬帴', linkmenu: '鍏宠仈鑿滃崟'}
+
+        return trans[text]
+      }},
+      { title: '閾炬帴鍦板潃', dataIndex: 'link', key: 'link'},
+      { title: '鎵撳紑鏂瑰紡', dataIndex: 'open', key: 'open',  render: (text, record) => {
+        const trans = {blank: '鏂扮獥鍙�', self: '褰撳墠绐楀彛'}
+
+        return trans[text]
+      }},
+      { title: '鎿嶄綔', key: 'operation', align: 'center', width: '190px', render: (text, record) =>
+        (<div>
+          <Button type="link" style={{padding: '0 5px', marginRight: '5px'}} onClick={() => this.editMenu(record)}>缂栬緫</Button>
+          <Button type="link" style={{color: '#ff4d4f', padding: '0 5px', marginRight: '5px'}} onClick={() => this.delMenu(record)}>鍒犻櫎</Button>
+          <Icon type="arrow-up" style={{color: '#26C281', cursor: 'pointer', padding: '0 5px', marginRight: '5px'}} onClick={() => this.moveUp(record)}/>
+          <Icon type="arrow-down" style={{color: '#ff4d4f', cursor: 'pointer', padding: '0 5px'}} onClick={() => this.moveDown(record)}/>
+        </div>)
+      }
+    ]
+  }
+
+  UNSAFE_componentWillMount () {
+    const { links } = this.props
+
+    this.setState({data: fromJS(links).toJS()})
+  }
+
+  shouldComponentUpdate (nextProps, nextState) {
+    return !is(fromJS(this.state), fromJS(nextState))
+  }
+
+  moveUp = (record) => {
+    let data = fromJS(this.state.data).toJS()
+
+    let dragIndex = data.findIndex(c => c.MenuID === record.MenuID)
+    let hoverIndex = dragIndex - 1
+
+    if (hoverIndex === -1) return
+
+    data.splice(hoverIndex, 0, ...data.splice(dragIndex, 1))
+    this.setState({data})
+  }
+
+  moveDown = (record) => {
+    let data = fromJS(this.state.data).toJS()
+
+    let dragIndex = data.findIndex(c => c.MenuID === record.MenuID)
+    let hoverIndex = dragIndex + 1
+
+    if (hoverIndex === data.length) return
+
+    data.splice(hoverIndex, 0, ...data.splice(dragIndex, 1))
+    this.setState({data})
+  }
+
+  delMenu = (record) => {
+    const { data } = this.state
+    const _this = this
+
+    confirm({
+      title: '纭畾鍒犻櫎鍚楋紵',
+      content: '',
+      onOk() {
+        _this.setState({data: data.filter(item => item.MenuID !== record.MenuID)})
+      },
+      onCancel() {}
+    })
+  }
+
+  editMenu = (record) => {
+    this.setState({editMenu: record, visible: true})
+  }
+
+  plusMenu = () => {
+    let _menu = {
+      name: '閾炬帴'
+    }
+
+    this.setState({editMenu: _menu, visible: true})
+  }
+
+  menuSubmit = () => {
+    const { editMenu, data } = this.state
+
+    this.menuRef.handleConfirm().then(res => {
+      let _menu = {...editMenu, ...res}
+      if (!_menu.MenuID) {
+        _menu.MenuID = Utils.getuuid()
+        this.setState({data: [...data, _menu], editMenu: null, visible: false})
+      } else {
+        this.setState({
+          editMenu: null,
+          visible: false,
+          data: data.map(item => {
+            if (item.MenuID === _menu.MenuID) {
+              return _menu
+            } else {
+              return item
+            }
+          })
+        })
+      }
+    })
+  }
+
+  render() {
+    const { columns, data, visible, editMenu } = this.state
+
+    return (
+      <div className="link-control-wrap">
+        <Button className="link-plus mk-green" onClick={this.plusMenu}>娣诲姞</Button>
+        <Table
+          rowKey="MenuID"
+          columns={columns}
+          dataSource={data}
+          pagination={false}
+        />
+        <Modal
+          title="缂栬緫"
+          visible={visible}
+          width={600}
+          maskClosable={false}
+          onOk={this.menuSubmit}
+          onCancel={() => { this.setState({ visible: false }) }}
+          destroyOnClose
+        >
+          <LinkForm
+            menu={editMenu}
+            inputSubmit={this.menuSubmit}
+            wrappedComponentRef={(inst) => this.menuRef = inst}
+          />
+        </Modal>
+      </div>
+    )
+  }
+}
+
+export default LinkTable
\ No newline at end of file
diff --git a/src/pc/components/navbar/normal-navbar/linksetting/linktable/index.scss b/src/pc/components/navbar/normal-navbar/linksetting/linktable/index.scss
new file mode 100644
index 0000000..0fa8d83
--- /dev/null
+++ b/src/pc/components/navbar/normal-navbar/linksetting/linktable/index.scss
@@ -0,0 +1,20 @@
+.link-control-wrap {
+  position: relative;
+
+  .link-plus {
+    float: right;
+    position: relative;
+    z-index: 1;
+    margin-bottom: 5px;
+  }
+  .ant-empty {
+    margin: 5px 0;
+  }
+  thead tr {
+    background: #fbfbfb;
+  }
+
+  .ant-table-body {
+    margin: 0!important;
+  }
+}
\ No newline at end of file
diff --git a/src/pc/components/navbar/normal-navbar/menusetting/index.scss b/src/pc/components/navbar/normal-navbar/menusetting/index.scss
index 04372e6..3a906d8 100644
--- a/src/pc/components/navbar/normal-navbar/menusetting/index.scss
+++ b/src/pc/components/navbar/normal-navbar/menusetting/index.scss
@@ -1,6 +1,10 @@
 .model-menu-setting-wrap {
   display: inline-block;
 
+  >.anticon-menu {
+    color: purple;
+  }
+
   >.anticon-edit {
     color: #1890ff;
   }
diff --git a/src/pc/components/navbar/normal-navbar/menusetting/menuform/index.jsx b/src/pc/components/navbar/normal-navbar/menusetting/menuform/index.jsx
index a0411c6..19e747f 100644
--- a/src/pc/components/navbar/normal-navbar/menusetting/menuform/index.jsx
+++ b/src/pc/components/navbar/normal-navbar/menusetting/menuform/index.jsx
@@ -116,8 +116,20 @@
                 <Radio.Group onChange={this.changeProperty}>
                   <Radio value="menu">鑿滃崟</Radio>
                   <Radio value="link">閾炬帴</Radio>
-                  {menu.level === 1 || menu.level === 2 ? <Radio value="classify">鍒嗙被</Radio> : null}
                   <Radio value="linkmenu">鍏宠仈鑿滃崟</Radio>
+                  {menu.level === 1 || menu.level === 2 ? <Radio value="classify">鍒嗙被</Radio> : null}
+                </Radio.Group>
+              )}
+            </Form.Item>
+          </Col>
+          <Col span={22}>
+            <Form.Item label="闅愯棌">
+              {getFieldDecorator('hidden', {
+                initialValue: menu.hidden || 'false'
+              })(
+                <Radio.Group>
+                  <Radio value="false">鍚�</Radio>
+                  <Radio value="true">鏄�</Radio>
                 </Radio.Group>
               )}
             </Form.Item>
diff --git a/src/pc/components/navbar/normal-navbar/wrapsetting/settingform/index.jsx b/src/pc/components/navbar/normal-navbar/wrapsetting/settingform/index.jsx
index e8a8e8f..9361e39 100644
--- a/src/pc/components/navbar/normal-navbar/wrapsetting/settingform/index.jsx
+++ b/src/pc/components/navbar/normal-navbar/wrapsetting/settingform/index.jsx
@@ -1,6 +1,6 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
-import { Form, Row, Col, Input, Tooltip, Icon, InputNumber, Select } from 'antd'
+import { Form, Row, Col, Input, Tooltip, Icon, InputNumber, Select, Radio } from 'antd'
 
 import asyncComponent from '@/utils/asyncComponent'
 import './index.scss'
@@ -167,6 +167,23 @@
                 )}
               </Form.Item>
             </Col>
+            <Col span={12}>
+              <Form.Item label={
+                <Tooltip placement="topLeft" title="瀛樺湪鐧诲綍涓斿彇鍒扮櫥褰曚俊鎭椂锛屾樉绀虹敤鎴峰ご鍍忋�佺敤鎴峰悕鍙婇��鍑恒��">
+                  <Icon type="question-circle" />
+                  鐢ㄦ埛淇℃伅
+                </Tooltip>
+              }>
+                {getFieldDecorator('user', {
+                  initialValue: wrap.user || 'hidden'
+                })(
+                  <Radio.Group>
+                    <Radio value="hidden">闅愯棌</Radio>
+                    <Radio value="show">鏄剧ず</Radio>
+                  </Radio.Group>
+                )}
+              </Form.Item>
+            </Col>
           </Row>
         </Form>
       </div>
diff --git a/src/tabviews/custom/components/card/cardcellList/index.jsx b/src/tabviews/custom/components/card/cardcellList/index.jsx
index 2f90830..e9604b6 100644
--- a/src/tabviews/custom/components/card/cardcellList/index.jsx
+++ b/src/tabviews/custom/components/card/cardcellList/index.jsx
@@ -304,7 +304,7 @@
       return (
         <Col key={card.uuid} span={card.width}>
           <div style={_style} onClick={(e) => {this.openNewView(e, card)}}>
-            <div className={'ant-mk-text line' + card.height} style={{height: card.innerHeight || 21}}>{val}</div>
+            <div className={'ant-mk-text line' + card.height} style={{height: card.innerHeight || 'auto'}}>{val}</div>
           </div>
         </Col>
       )
@@ -356,7 +356,7 @@
       return (
         <Col key={card.uuid} span={card.width}>
           <div style={_style}>
-            <div className={'ant-mk-text line' + card.height} style={{height: card.innerHeight || 21}}>{val}</div>
+            <div className={'ant-mk-text line' + card.height} style={{height: card.innerHeight || 'auto'}}>{val}</div>
           </div>
         </Col>
       )
diff --git a/src/tabviews/zshare/fileupload/index.jsx b/src/tabviews/zshare/fileupload/index.jsx
index e8cf594..df0cf6f 100644
--- a/src/tabviews/zshare/fileupload/index.jsx
+++ b/src/tabviews/zshare/fileupload/index.jsx
@@ -68,8 +68,12 @@
   }
 
   onDelete = (msg) => {
-    let filelist = this.state.filelist.filter(v => !v.url && !v.response)
-
+    let filelist = this.state.filelist.map(item => {
+      if (!item.url && !item.response && !item.status) {
+        item.status = 'error'
+      }
+      return item
+    })
     this.setState({filelist, showprogress: false})
     this.props.onChange(filelist)
 
diff --git a/src/tabviews/zshare/fileupload/index.scss b/src/tabviews/zshare/fileupload/index.scss
index 00b4ba5..5841f7b 100644
--- a/src/tabviews/zshare/fileupload/index.scss
+++ b/src/tabviews/zshare/fileupload/index.scss
@@ -16,6 +16,14 @@
 }
 .fileupload-form-container.limit-fileupload {
   > .ant-upload {
-    display: none;
+    display: inline;
+    >.ant-upload {
+      >input {
+        display: none;
+      }
+      >button {
+        display: none;
+      }
+    }
   }
 }
\ No newline at end of file
diff --git a/src/templates/menuconfig/editthdmenu/menuform/index.jsx b/src/templates/menuconfig/editthdmenu/menuform/index.jsx
index 4448a11..c86cde8 100644
--- a/src/templates/menuconfig/editthdmenu/menuform/index.jsx
+++ b/src/templates/menuconfig/editthdmenu/menuform/index.jsx
@@ -3,6 +3,7 @@
 import { Form, Row, Col, Input, Select } from 'antd'
 import './index.scss'
 
+const { TextArea } = Input
 
 class MainSearch extends Component {
   static propTpyes = {
@@ -158,7 +159,7 @@
                     message: '鍦板潃鏈�闀夸负1024涓瓧绗�!'
                   }
                 ]
-              })(<Input placeholder="" autoComplete="off" />)}
+              })(<TextArea rows={2} />)}
             </Form.Item>
           </Col> : null}
         </Row>
diff --git a/src/templates/zshare/formconfig.jsx b/src/templates/zshare/formconfig.jsx
index b9da890..7278035 100644
--- a/src/templates/zshare/formconfig.jsx
+++ b/src/templates/zshare/formconfig.jsx
@@ -826,7 +826,7 @@
     {
       type: 'text',
       key: 'url',
-      label: Formdict['model.form.newpage.url'],
+      label: Formdict['model.pageUrl'],
       initVal: card.url || '',
       required: true
     },
diff --git a/src/views/pcdesign/index.jsx b/src/views/pcdesign/index.jsx
index f270f84..be7a609 100644
--- a/src/views/pcdesign/index.jsx
+++ b/src/views/pcdesign/index.jsx
@@ -1,6 +1,7 @@
 import React, { Component } from 'react'
 import { connect } from 'react-redux'
 import { DndProvider } from 'react-dnd'
+import { withRouter } from 'react-router'
 import { is, fromJS } from 'immutable'
 import moment from 'moment'
 import HTML5Backend from 'react-dnd-html5-backend'
@@ -81,18 +82,26 @@
           localedict: sessionStorage.getItem('lang') !== 'en-US' ? antdZhCN : antdEnUS,
           dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS
         })
+        this.getAppMessage()
       } else if (param.type === 'view') {
         this.setState({
           MenuId: param.MenuID
+        }, () => {
+          this.getMenuParam()
         })
       }
-      this.getAppMessage()
     } catch {
       notification.warning({
         top: 92,
         message: '鑿滃崟淇℃伅瑙f瀽閿欒锛�',
         duration: 5
       })
+    }
+  }
+
+  UNSAFE_componentWillReceiveProps(nextProps) {
+    if (this.props.match.params.param !== nextProps.match.params.param) {
+      window.location.reload()
     }
   }
 
@@ -142,8 +151,7 @@
       return
     }
 
-    this.props.history.replace('/pcdesign/' + window.btoa(window.encodeURIComponent(JSON.stringify({MenuID: menu.MenuID, type: 'view'}))))
-    window.location.reload()
+    this.props.history.push('/pcdesign/' + window.btoa(window.encodeURIComponent(JSON.stringify({MenuID: menu.MenuID, copyMenuId: menu.copyMenuId || '', type: 'view'}))))
   }
 
   getAppMessage = () => {
@@ -161,67 +169,58 @@
       }
 
       let homeId = ''
-      if (this.state.MenuId) {
-        let appViewList = res.data && res.data.length > 0 ? res.data : []
-
-        homeId = this.state.MenuId
-
-        sessionStorage.setItem('appViewList', JSON.stringify(appViewList))
-      } else {
-        let appViewList = []
-        if (res.data && res.data.length > 0) {
-          appViewList = res.data
-          appViewList.forEach(item => {
-            if (item.keys_type === 'index') {
-              homeId = item.keys_id
-            }
-          })
-        }
-
-        if (!homeId) {
-          homeId = Utils.getuuid()
-
-          let param = {
-            func: 's_kei_link_keyids_addupt',
-            BID: sessionStorage.getItem('appId'),
-            exec_type: 'y',
-            LText: ''
+      let appViewList = []
+      if (res.data && res.data.length > 0) {
+        appViewList = res.data
+        appViewList.forEach(item => {
+          if (item.keys_type === 'index') {
+            homeId = item.keys_id
           }
+        })
+      }
 
-          appViewList.unshift({
-            appkey: window.GLOB.appkey || '',
-            bid: sessionStorage.getItem('appId') || '',
-            kei_no: sessionStorage.getItem('kei_no') || '',
-            keys_id: homeId,
-            keys_type: 'index',
-            remark: '棣栭〉'
-          })
+      if (!homeId) {
+        homeId = Utils.getuuid()
 
-          param.LText = appViewList.map(item => `select '${item.keys_id}','${item.keys_type}','${item.kei_no}','${item.appkey}','${item.bid}','${sessionStorage.getItem('CloudUserID')}','${item.remark}'`)
-          param.LText = param.LText.join(' union all ')
-          param.LText = Utils.formatOptions(param.LText)
-    
-          param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
-          param.secretkey = Utils.encrypt('', param.timestamp)
-
-          Api.getSystemConfig(param).then(result => {
-            if (!result.status) {
-              notification.warning({
-                top: 92,
-                message: result.message,
-                duration: 5
-              })
-            }
-          })
+        let param = {
+          func: 's_kei_link_keyids_addupt',
+          BID: sessionStorage.getItem('appId'),
+          exec_type: 'y',
+          LText: ''
         }
 
+        appViewList.unshift({
+          appkey: window.GLOB.appkey || '',
+          bid: sessionStorage.getItem('appId') || '',
+          kei_no: sessionStorage.getItem('kei_no') || '',
+          keys_id: homeId,
+          keys_type: 'index',
+          remark: '棣栭〉'
+        })
+
+        param.LText = appViewList.map(item => `select '${item.keys_id}','${item.keys_type}','${item.kei_no}','${item.appkey}','${item.bid}','${sessionStorage.getItem('CloudUserID')}','${item.remark}'`)
+        param.LText = param.LText.join(' union all ')
+        param.LText = Utils.formatOptions(param.LText)
+  
+        param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
+        param.secretkey = Utils.encrypt('', param.timestamp)
+
+        Api.getSystemConfig(param).then(result => {
+          if (!result.status) {
+            notification.warning({
+              top: 92,
+              message: result.message,
+              duration: 5
+            })
+          } else {
+            sessionStorage.setItem('appViewList', JSON.stringify(appViewList))
+            this.props.history.replace('/pcdesign/' + window.btoa(window.encodeURIComponent(JSON.stringify({MenuID: homeId, type: 'view'}))))
+          }
+        })
+      } else {
         sessionStorage.setItem('appViewList', JSON.stringify(appViewList))
+        this.props.history.replace('/pcdesign/' + window.btoa(window.encodeURIComponent(JSON.stringify({MenuID: homeId, type: 'view'}))))
       }
-      this.props.history.replace('/pcdesign/' + window.btoa(window.encodeURIComponent(JSON.stringify({MenuID: homeId, type: 'view'}))))
-      
-      this.setState({MenuId: homeId}, () => {
-        this.getMenuParam()
-      })
     })
   }
 
@@ -1221,4 +1220,4 @@
   }
 }
 
-export default connect(mapStateToProps, mapDispatchToProps)(MenuDesign)
\ No newline at end of file
+export default withRouter(connect(mapStateToProps, mapDispatchToProps)(MenuDesign))
\ No newline at end of file

--
Gitblit v1.8.0