Просмотр исходного кода

feat(merge): merge xyh

Next xyh
Lind 3 лет назад
Родитель
Сommit
1bad6e086b

+ 198 - 102
public/icons/iconfont.css

@@ -1,9 +1,9 @@
 @font-face {
   font-family: "iconfont"; /* Project id 3183515 */
-  src: url('iconfont.woff2?t=1649052654664') format('woff2'),
-       url('iconfont.woff?t=1649052654664') format('woff'),
-       url('iconfont.ttf?t=1649052654664') format('truetype'),
-       url('iconfont.svg?t=1649052654664#iconfont') format('svg');
+  src: url('iconfont.woff2?t=1649842068082') format('woff2'),
+       url('iconfont.woff?t=1649842068082') format('woff'),
+       url('iconfont.ttf?t=1649842068082') format('truetype'),
+       url('iconfont.svg?t=1649842068082#iconfont') format('svg');
 }
 
 .iconfont {
@@ -14,199 +14,295 @@
   -moz-osx-font-smoothing: grayscale;
 }
 
-.icon-shujumoni:before {
-  content: "\e665";
+.icon-denggao:before {
+  content: "\e68a";
 }
 
-.icon-tongzhiguanli:before {
-  content: "\e666";
+.icon-gengduo:before {
+  content: "\e68e";
 }
 
-.icon-rizhifuwu:before {
-  content: "\e667";
+.icon-jinyong:before {
+  content: "\e68f";
 }
 
-.icon-keshihua:before {
-  content: "\e668";
+.icon-fenpingzhanshi1:before {
+  content: "\e690";
 }
 
-.icon-yuanchengshengji:before {
-  content: "\e669";
+.icon-jiebang:before {
+  content: "\e691";
 }
 
-.icon-shebei:before {
-  content: "\e66a";
+.icon-tiaoshi:before {
+  content: "\e692";
 }
 
-.icon-wangluozujian:before {
-  content: "\e66b";
+.icon-shangyi:before {
+  content: "\e693";
 }
 
-.icon-shipinwangguan:before {
-  content: "\e66c";
+.icon-lujing:before {
+  content: "\e694";
 }
 
-.icon-wumoxing:before {
-  content: "\e66d";
+.icon-rili:before {
+  content: "\e697";
 }
 
-.icon-wangguanzishebei:before {
-  content: "\e66e";
+.icon-shanchu:before {
+  content: "\e698";
 }
 
-.icon-zhihuishequ:before {
-  content: "\e66f";
+.icon-renyuan:before {
+  content: "\e699";
 }
 
-.icon-chanpinfenlei:before {
-  content: "\e670";
+.icon-xiazai:before {
+  content: "\e69a";
 }
 
-.icon-zhengshuguanli:before {
-  content: "\e671";
+.icon-shezhi:before {
+  content: "\e69c";
 }
 
-.icon-zhihuigongye:before {
-  content: "\e672";
+.icon-bianji:before {
+  content: "\e69d";
 }
 
-.icon-chanpin:before {
-  content: "\e673";
+.icon-zhankai-2:before {
+  content: "\e69f";
 }
 
-.icon-changjingliandong:before {
-  content: "\e674";
+.icon-xiayi:before {
+  content: "\e6a0";
 }
 
-.icon-zhilianshebei:before {
-  content: "\e676";
+.icon-chuli:before {
+  content: "\e6a4";
 }
 
-.icon-zidingyiguize:before {
-  content: "\e677";
+.icon-zichan:before {
+  content: "\e6a5";
 }
 
-.icon-zhihuichengshi:before {
-  content: "\e678";
+.icon-zhongxinxiafa:before {
+  content: "\e6a6";
 }
 
-.icon-chajianguanli:before {
-  content: "\e679";
+.icon-tianjia:before {
+  content: "\e6a7";
 }
 
-.icon-zhihuiyuanqu:before {
-  content: "\e67a";
+.icon-chakan:before {
+  content: "\e6a8";
 }
 
-.icon-Subtract:before {
-  content: "\e664";
+.icon-zuidahua:before {
+  content: "\e6a9";
 }
 
-.icon-a-Frame2125:before {
-  content: "\e660";
+.icon-anniuguanli:before {
+  content: "\e6aa";
 }
 
-.icon-setting1:before {
-  content: "\e661";
+.icon-zhankai-1:before {
+  content: "\e6ab";
 }
 
-.icon-a-Frame2126:before {
-  content: "\e662";
+.icon-tongzhijilu:before {
+  content: "\e6ac";
 }
 
-.icon-caozuo1:before {
-  content: "\e663";
+.icon-shuxingpeizhi:before {
+  content: "\e6ad";
 }
 
-.icon-tiaoshi:before {
-  content: "\e65f";
+.icon-xiaoxi:before {
+  content: "\e6ae";
 }
 
-.icon-caozuo:before {
-  content: "\e65a";
+.icon-fabu:before {
+  content: "\e688";
 }
 
-.icon-colum-height1:before {
-  content: "\e65b";
+.icon-guojijilian:before {
+  content: "\e68b";
 }
 
-.icon-reload1:before {
-  content: "\e65c";
+.icon-quanxianguanli:before {
+  content: "\e68c";
 }
 
-.icon-setting:before {
-  content: "\e65d";
+.icon-jiaoseguanli:before {
+  content: "\e68d";
 }
 
-.icon-a-Group1451:before {
-  content: "\e65e";
+.icon-xuanzetongdao1:before {
+  content: "\e695";
 }
 
-.icon-colum-height-1:before {
-  content: "\e649";
+.icon-a-Frame3323:before {
+  content: "\e696";
 }
 
-.icon-bianji:before {
-  content: "\e64a";
+.icon-yonghuguanli:before {
+  content: "\e69e";
+}
+
+.icon-bumenguanli:before {
+  content: "\e6a1";
+}
+
+.icon-caidanguanli:before {
+  content: "\e6a2";
+}
+
+.icon-bangzhu:before {
+  content: "\e6a3";
+}
+
+.icon-xuanzetongdao:before {
+  content: "\e687";
+}
+
+.icon-Vector:before {
+  content: "\e685";
+}
+
+.icon-Union:before {
+  content: "\e686";
+}
+
+.icon-shebeigaojing:before {
+  content: "\e680";
+}
+
+.icon-chanpinfenlei1:before {
+  content: "\e681";
+}
+
+.icon-bianyuanwangguan:before {
+  content: "\e682";
+}
+
+.icon-wuguanli:before {
+  content: "\e683";
+}
+
+.icon-yunyunjieru:before {
+  content: "\e684";
 }
 
-.icon-bianji-1:before {
-  content: "\e64b";
+.icon-yunweiguanli:before {
+  content: "\e67c";
 }
 
-.icon-colum-height:before {
-  content: "\e64c";
+.icon-wulianwang:before {
+  content: "\e67d";
 }
 
-.icon-fullscreen-1:before {
-  content: "\e64d";
+.icon-shebeiguanli:before {
+  content: "\e67e";
 }
 
-.icon-reload-1:before {
-  content: "\e64e";
+.icon-xitongguanli1:before {
+  content: "\e67f";
 }
 
-.icon-reload:before {
-  content: "\e64f";
+.icon-xitongguanli:before {
+  content: "\e675";
 }
 
-.icon-setting-1:before {
-  content: "\e650";
+.icon-yunweiguanli-1:before {
+  content: "\e67b";
 }
 
-.icon-setting-2:before {
-  content: "\e651";
+.icon-shujumoni:before {
+  content: "\e665";
+}
+
+.icon-tongzhiguanli:before {
+  content: "\e666";
+}
+
+.icon-rizhifuwu:before {
+  content: "\e667";
+}
+
+.icon-keshihua:before {
+  content: "\e668";
+}
+
+.icon-yuanchengshengji:before {
+  content: "\e669";
+}
+
+.icon-shebei:before {
+  content: "\e66a";
+}
+
+.icon-wangluozujian:before {
+  content: "\e66b";
+}
+
+.icon-shipinwangguan:before {
+  content: "\e66c";
+}
+
+.icon-wumoxing:before {
+  content: "\e66d";
+}
+
+.icon-wangguanzishebei:before {
+  content: "\e66e";
 }
 
-.icon-setting-4:before {
-  content: "\e652";
+.icon-zhihuishequ:before {
+  content: "\e66f";
 }
 
-.icon-setting-3:before {
-  content: "\e653";
+.icon-chanpinfenlei:before {
+  content: "\e670";
 }
 
-.icon-setting-7:before {
-  content: "\e654";
+.icon-zhengshuguanli:before {
+  content: "\e671";
 }
 
-.icon-setting-9:before {
-  content: "\e655";
+.icon-zhihuigongye:before {
+  content: "\e672";
 }
 
-.icon-fullscreen:before {
-  content: "\e656";
+.icon-chanpin:before {
+  content: "\e673";
 }
 
-.icon-setting-6:before {
-  content: "\e657";
+.icon-changjingliandong:before {
+  content: "\e674";
 }
 
-.icon-setting-5:before {
-  content: "\e658";
+.icon-zhilianshebei:before {
+  content: "\e676";
 }
 
-.icon-setting-8:before {
-  content: "\e659";
+.icon-zidingyiguize:before {
+  content: "\e677";
+}
+
+.icon-zhihuichengshi:before {
+  content: "\e678";
+}
+
+.icon-chajianguanli:before {
+  content: "\e679";
+}
+
+.icon-zhihuiyuanqu:before {
+  content: "\e67a";
+}
+
+.icon-a-Frame2126:before {
+  content: "\e662";
 }
 

Разница между файлами не показана из-за своего большого размера
+ 1 - 1
public/icons/iconfont.js


+ 357 - 189
public/icons/iconfont.json

@@ -6,6 +6,363 @@
   "description": "",
   "glyphs": [
     {
+      "icon_id": "28953788",
+      "name": "等高",
+      "font_class": "denggao",
+      "unicode": "e68a",
+      "unicode_decimal": 59018
+    },
+    {
+      "icon_id": "28953789",
+      "name": "更多",
+      "font_class": "gengduo",
+      "unicode": "e68e",
+      "unicode_decimal": 59022
+    },
+    {
+      "icon_id": "28953790",
+      "name": "禁用",
+      "font_class": "jinyong",
+      "unicode": "e68f",
+      "unicode_decimal": 59023
+    },
+    {
+      "icon_id": "28953791",
+      "name": "分屏展示",
+      "font_class": "fenpingzhanshi1",
+      "unicode": "e690",
+      "unicode_decimal": 59024
+    },
+    {
+      "icon_id": "28953792",
+      "name": "解绑",
+      "font_class": "jiebang",
+      "unicode": "e691",
+      "unicode_decimal": 59025
+    },
+    {
+      "icon_id": "28953793",
+      "name": "调试",
+      "font_class": "tiaoshi",
+      "unicode": "e692",
+      "unicode_decimal": 59026
+    },
+    {
+      "icon_id": "28953794",
+      "name": "上移",
+      "font_class": "shangyi",
+      "unicode": "e693",
+      "unicode_decimal": 59027
+    },
+    {
+      "icon_id": "28953795",
+      "name": "路径",
+      "font_class": "lujing",
+      "unicode": "e694",
+      "unicode_decimal": 59028
+    },
+    {
+      "icon_id": "28953796",
+      "name": "日历",
+      "font_class": "rili",
+      "unicode": "e697",
+      "unicode_decimal": 59031
+    },
+    {
+      "icon_id": "28953797",
+      "name": "删除",
+      "font_class": "shanchu",
+      "unicode": "e698",
+      "unicode_decimal": 59032
+    },
+    {
+      "icon_id": "28953798",
+      "name": "人员",
+      "font_class": "renyuan",
+      "unicode": "e699",
+      "unicode_decimal": 59033
+    },
+    {
+      "icon_id": "28953799",
+      "name": "下载",
+      "font_class": "xiazai",
+      "unicode": "e69a",
+      "unicode_decimal": 59034
+    },
+    {
+      "icon_id": "28953801",
+      "name": "设置",
+      "font_class": "shezhi",
+      "unicode": "e69c",
+      "unicode_decimal": 59036
+    },
+    {
+      "icon_id": "28953802",
+      "name": "编辑",
+      "font_class": "bianji",
+      "unicode": "e69d",
+      "unicode_decimal": 59037
+    },
+    {
+      "icon_id": "28953803",
+      "name": "展开-2",
+      "font_class": "zhankai-2",
+      "unicode": "e69f",
+      "unicode_decimal": 59039
+    },
+    {
+      "icon_id": "28953804",
+      "name": "下移",
+      "font_class": "xiayi",
+      "unicode": "e6a0",
+      "unicode_decimal": 59040
+    },
+    {
+      "icon_id": "28953805",
+      "name": "处理",
+      "font_class": "chuli",
+      "unicode": "e6a4",
+      "unicode_decimal": 59044
+    },
+    {
+      "icon_id": "28953806",
+      "name": "资产",
+      "font_class": "zichan",
+      "unicode": "e6a5",
+      "unicode_decimal": 59045
+    },
+    {
+      "icon_id": "28953807",
+      "name": "重新下发",
+      "font_class": "zhongxinxiafa",
+      "unicode": "e6a6",
+      "unicode_decimal": 59046
+    },
+    {
+      "icon_id": "28953808",
+      "name": "添加",
+      "font_class": "tianjia",
+      "unicode": "e6a7",
+      "unicode_decimal": 59047
+    },
+    {
+      "icon_id": "28953809",
+      "name": "查看",
+      "font_class": "chakan",
+      "unicode": "e6a8",
+      "unicode_decimal": 59048
+    },
+    {
+      "icon_id": "28953810",
+      "name": "最大化",
+      "font_class": "zuidahua",
+      "unicode": "e6a9",
+      "unicode_decimal": 59049
+    },
+    {
+      "icon_id": "28953811",
+      "name": "按钮管理",
+      "font_class": "anniuguanli",
+      "unicode": "e6aa",
+      "unicode_decimal": 59050
+    },
+    {
+      "icon_id": "28953812",
+      "name": "展开-1",
+      "font_class": "zhankai-1",
+      "unicode": "e6ab",
+      "unicode_decimal": 59051
+    },
+    {
+      "icon_id": "28953813",
+      "name": "通知记录",
+      "font_class": "tongzhijilu",
+      "unicode": "e6ac",
+      "unicode_decimal": 59052
+    },
+    {
+      "icon_id": "28953814",
+      "name": "属性配置",
+      "font_class": "shuxingpeizhi",
+      "unicode": "e6ad",
+      "unicode_decimal": 59053
+    },
+    {
+      "icon_id": "28953815",
+      "name": "消息",
+      "font_class": "xiaoxi",
+      "unicode": "e6ae",
+      "unicode_decimal": 59054
+    },
+    {
+      "icon_id": "28953044",
+      "name": "发布",
+      "font_class": "fabu",
+      "unicode": "e688",
+      "unicode_decimal": 59016
+    },
+    {
+      "icon_id": "28953047",
+      "name": "国际级联",
+      "font_class": "guojijilian",
+      "unicode": "e68b",
+      "unicode_decimal": 59019
+    },
+    {
+      "icon_id": "28953048",
+      "name": "权限管理",
+      "font_class": "quanxianguanli",
+      "unicode": "e68c",
+      "unicode_decimal": 59020
+    },
+    {
+      "icon_id": "28953049",
+      "name": "角色管理",
+      "font_class": "jiaoseguanli",
+      "unicode": "e68d",
+      "unicode_decimal": 59021
+    },
+    {
+      "icon_id": "28953057",
+      "name": "选择通道",
+      "font_class": "xuanzetongdao1",
+      "unicode": "e695",
+      "unicode_decimal": 59029
+    },
+    {
+      "icon_id": "28953058",
+      "name": "消息",
+      "font_class": "a-Frame3323",
+      "unicode": "e696",
+      "unicode_decimal": 59030
+    },
+    {
+      "icon_id": "28953066",
+      "name": "用户管理",
+      "font_class": "yonghuguanli",
+      "unicode": "e69e",
+      "unicode_decimal": 59038
+    },
+    {
+      "icon_id": "28953069",
+      "name": "部门管理",
+      "font_class": "bumenguanli",
+      "unicode": "e6a1",
+      "unicode_decimal": 59041
+    },
+    {
+      "icon_id": "28953070",
+      "name": "菜单管理",
+      "font_class": "caidanguanli",
+      "unicode": "e6a2",
+      "unicode_decimal": 59042
+    },
+    {
+      "icon_id": "28953071",
+      "name": "帮助",
+      "font_class": "bangzhu",
+      "unicode": "e6a3",
+      "unicode_decimal": 59043
+    },
+    {
+      "icon_id": "28947787",
+      "name": "选择通道",
+      "font_class": "xuanzetongdao",
+      "unicode": "e687",
+      "unicode_decimal": 59015
+    },
+    {
+      "icon_id": "28860823",
+      "name": "通知模板",
+      "font_class": "Vector",
+      "unicode": "e685",
+      "unicode_decimal": 59013
+    },
+    {
+      "icon_id": "28860824",
+      "name": "通知配置",
+      "font_class": "Union",
+      "unicode": "e686",
+      "unicode_decimal": 59014
+    },
+    {
+      "icon_id": "28752699",
+      "name": "设备告警",
+      "font_class": "shebeigaojing",
+      "unicode": "e680",
+      "unicode_decimal": 59008
+    },
+    {
+      "icon_id": "28752700",
+      "name": "产品分类",
+      "font_class": "chanpinfenlei1",
+      "unicode": "e681",
+      "unicode_decimal": 59009
+    },
+    {
+      "icon_id": "28752701",
+      "name": "边缘网关",
+      "font_class": "bianyuanwangguan",
+      "unicode": "e682",
+      "unicode_decimal": 59010
+    },
+    {
+      "icon_id": "28752702",
+      "name": "物管理",
+      "font_class": "wuguanli",
+      "unicode": "e683",
+      "unicode_decimal": 59011
+    },
+    {
+      "icon_id": "28752703",
+      "name": "云云接入",
+      "font_class": "yunyunjieru",
+      "unicode": "e684",
+      "unicode_decimal": 59012
+    },
+    {
+      "icon_id": "28752271",
+      "name": "运维管理",
+      "font_class": "yunweiguanli",
+      "unicode": "e67c",
+      "unicode_decimal": 59004
+    },
+    {
+      "icon_id": "28752272",
+      "name": "物联网",
+      "font_class": "wulianwang",
+      "unicode": "e67d",
+      "unicode_decimal": 59005
+    },
+    {
+      "icon_id": "28752273",
+      "name": "设备管理",
+      "font_class": "shebeiguanli",
+      "unicode": "e67e",
+      "unicode_decimal": 59006
+    },
+    {
+      "icon_id": "28752274",
+      "name": "系统管理",
+      "font_class": "xitongguanli1",
+      "unicode": "e67f",
+      "unicode_decimal": 59007
+    },
+    {
+      "icon_id": "28752000",
+      "name": "系统管理",
+      "font_class": "xitongguanli",
+      "unicode": "e675",
+      "unicode_decimal": 58997
+    },
+    {
+      "icon_id": "28752004",
+      "name": "运维管理-1",
+      "font_class": "yunweiguanli-1",
+      "unicode": "e67b",
+      "unicode_decimal": 59003
+    },
+    {
       "icon_id": "28693148",
       "name": "数据模拟",
       "font_class": "shujumoni",
@@ -153,200 +510,11 @@
       "unicode_decimal": 59002
     },
     {
-      "icon_id": "27891438",
-      "name": "重新下发",
-      "font_class": "Subtract",
-      "unicode": "e664",
-      "unicode_decimal": 58980
-    },
-    {
-      "icon_id": "27891166",
-      "name": "消息",
-      "font_class": "a-Frame2125",
-      "unicode": "e660",
-      "unicode_decimal": 58976
-    },
-    {
-      "icon_id": "27891167",
-      "name": "下载",
-      "font_class": "setting1",
-      "unicode": "e661",
-      "unicode_decimal": 58977
-    },
-    {
       "icon_id": "27891168",
       "name": "发布",
       "font_class": "a-Frame2126",
       "unicode": "e662",
       "unicode_decimal": 58978
-    },
-    {
-      "icon_id": "27891170",
-      "name": "通知记录",
-      "font_class": "caozuo1",
-      "unicode": "e663",
-      "unicode_decimal": 58979
-    },
-    {
-      "icon_id": "27891146",
-      "name": "调试",
-      "font_class": "tiaoshi",
-      "unicode": "e65f",
-      "unicode_decimal": 58975
-    },
-    {
-      "icon_id": "27612044",
-      "name": "更多",
-      "font_class": "caozuo",
-      "unicode": "e65a",
-      "unicode_decimal": 58970
-    },
-    {
-      "icon_id": "27612045",
-      "name": "展开",
-      "font_class": "colum-height1",
-      "unicode": "e65b",
-      "unicode_decimal": 58971
-    },
-    {
-      "icon_id": "27612046",
-      "name": "展开",
-      "font_class": "reload1",
-      "unicode": "e65c",
-      "unicode_decimal": 58972
-    },
-    {
-      "icon_id": "27612049",
-      "name": "展开",
-      "font_class": "setting",
-      "unicode": "e65d",
-      "unicode_decimal": 58973
-    },
-    {
-      "icon_id": "27612050",
-      "name": "帮助",
-      "font_class": "a-Group1451",
-      "unicode": "e65e",
-      "unicode_decimal": 58974
-    },
-    {
-      "icon_id": "27611908",
-      "name": "上移",
-      "font_class": "colum-height-1",
-      "unicode": "e649",
-      "unicode_decimal": 58953
-    },
-    {
-      "icon_id": "27611909",
-      "name": "编辑",
-      "font_class": "bianji",
-      "unicode": "e64a",
-      "unicode_decimal": 58954
-    },
-    {
-      "icon_id": "27611910",
-      "name": "处理",
-      "font_class": "bianji-1",
-      "unicode": "e64b",
-      "unicode_decimal": 58955
-    },
-    {
-      "icon_id": "27611911",
-      "name": "等高",
-      "font_class": "colum-height",
-      "unicode": "e64c",
-      "unicode_decimal": 58956
-    },
-    {
-      "icon_id": "27611912",
-      "name": "下移",
-      "font_class": "fullscreen-1",
-      "unicode": "e64d",
-      "unicode_decimal": 58957
-    },
-    {
-      "icon_id": "27611913",
-      "name": "解绑",
-      "font_class": "reload-1",
-      "unicode": "e64e",
-      "unicode_decimal": 58958
-    },
-    {
-      "icon_id": "27611914",
-      "name": "刷新",
-      "font_class": "reload",
-      "unicode": "e64f",
-      "unicode_decimal": 58959
-    },
-    {
-      "icon_id": "27611915",
-      "name": "添加",
-      "font_class": "setting-1",
-      "unicode": "e650",
-      "unicode_decimal": 58960
-    },
-    {
-      "icon_id": "27611916",
-      "name": "资产",
-      "font_class": "setting-2",
-      "unicode": "e651",
-      "unicode_decimal": 58961
-    },
-    {
-      "icon_id": "27611917",
-      "name": "删除",
-      "font_class": "setting-4",
-      "unicode": "e652",
-      "unicode_decimal": 58962
-    },
-    {
-      "icon_id": "27611918",
-      "name": "人员",
-      "font_class": "setting-3",
-      "unicode": "e653",
-      "unicode_decimal": 58963
-    },
-    {
-      "icon_id": "27611919",
-      "name": "查看",
-      "font_class": "setting-7",
-      "unicode": "e654",
-      "unicode_decimal": 58964
-    },
-    {
-      "icon_id": "27611920",
-      "name": "禁用",
-      "font_class": "setting-9",
-      "unicode": "e655",
-      "unicode_decimal": 58965
-    },
-    {
-      "icon_id": "27611921",
-      "name": "最大化",
-      "font_class": "fullscreen",
-      "unicode": "e656",
-      "unicode_decimal": 58966
-    },
-    {
-      "icon_id": "27611922",
-      "name": "日历",
-      "font_class": "setting-6",
-      "unicode": "e657",
-      "unicode_decimal": 58967
-    },
-    {
-      "icon_id": "27611924",
-      "name": "属性配置",
-      "font_class": "setting-5",
-      "unicode": "e658",
-      "unicode_decimal": 58968
-    },
-    {
-      "icon_id": "27611925",
-      "name": "按钮管理",
-      "font_class": "setting-8",
-      "unicode": "e659",
-      "unicode_decimal": 58969
     }
   ]
 }

Разница между файлами не показана из-за своего большого размера
+ 97 - 49
public/icons/iconfont.svg


BIN
public/icons/iconfont.ttf


BIN
public/icons/iconfont.woff


BIN
public/icons/iconfont.woff2


+ 5 - 0
src/components/Player/index.tsx

@@ -9,12 +9,14 @@ export type PlayerProps = {
   poster?: string;
   timeout?: number;
   className?: string;
+  loading?: boolean;
   onDestroy?: () => void;
   onMessage?: (msg: any) => void;
   onError?: (err: any) => void;
   onTimeUpdate?: (time: any) => void;
   onPause?: () => void;
   onPlay?: () => void;
+  protocol?: 'mp4' | 'flv' | 'hls';
   onFullscreen?: () => void;
   onSnapOutside?: (base64: any) => void;
   onSnapInside?: (base64: any) => void;
@@ -101,7 +103,10 @@ export default (props: PlayerProps) => {
         player.current = r;
         EventInit();
       }}
+      fluent
+      protocol={props.protocol || 'mp4'}
       class={props.className}
+      loading={props.loading}
       live={'live' in props ? props.live !== false : true}
       autoplay={'autoplay' in props ? props.autoplay !== false : true}
       muted={'muted' in props ? props.muted !== false : true}

+ 21 - 2
src/components/ProTableCard/index.tsx

@@ -1,7 +1,7 @@
 import type { ProTableProps } from '@jetlinks/pro-table';
 import ProTable from '@jetlinks/pro-table';
 import type { ParamsType } from '@ant-design/pro-provider';
-import React, { useState } from 'react';
+import React, { useEffect, useState } from 'react';
 import { isFunction } from 'lodash';
 import { Empty, Pagination, Space } from 'antd';
 import { AppstoreOutlined, BarsOutlined } from '@ant-design/icons';
@@ -35,6 +35,7 @@ const ProTableCard = <
   const [current, setCurrent] = useState(1); // 当前页
   const [pageIndex, setPageIndex] = useState(0);
   const [pageSize, setPageSize] = useState(Default_Size * 2); // 每页条数
+  const [column, setColumn] = useState(props.gridColumn || 4);
 
   /**
    * 处理 Card
@@ -46,7 +47,7 @@ const ProTableCard = <
         {dataSource && dataSource.length ? (
           <div
             className={'pro-table-card-items'}
-            style={{ gridTemplateColumns: `repeat(${props.gridColumn || 4}, 1fr)` }}
+            style={{ gridTemplateColumns: `repeat(${column}, 1fr)` }}
           >
             {dataSource.map((item) =>
               cardRender && isFunction(cardRender) ? cardRender(item) : null,
@@ -61,6 +62,24 @@ const ProTableCard = <
     );
   };
 
+  const windowChange = () => {
+    if (window.innerWidth < 1600) {
+      setColumn(props.gridColumn && props.gridColumn < 3 ? props.gridColumn : 3);
+    }
+
+    if (window.innerWidth > 1600) {
+      setColumn(props.gridColumn && props.gridColumn < 4 ? props.gridColumn : 4);
+    }
+  };
+
+  useEffect(() => {
+    window.addEventListener('resize', windowChange);
+    windowChange();
+    return () => {
+      window.removeEventListener('resize', windowChange);
+    };
+  }, []);
+
   return (
     <div className={'pro-table-card'}>
       <ProTable<T, U, ValueType>

+ 1 - 1
src/pages/device/Instance/Detail/Diagnose/index.less

@@ -6,7 +6,7 @@
   width: 100%;
   padding: 10px;
   background-repeat: no-repeat;
-  background-size: '100% 100%';
+  background-size: 100% 100%;
   cursor: pointer;
 }
 

+ 1 - 1
src/pages/media/Device/Channel/index.tsx

@@ -152,7 +152,7 @@ export default () => {
             onClick={() => {
               history.push(
                 `${getMenuPathByCode(MENUS_CODE['media/Device/Playback'])}?id=${
-                  record.channelId
+                  record.deviceId
                 }&channelId=${record.channelId}`,
               );
             }}

+ 73 - 1
src/pages/media/Device/Playback/index.less

@@ -1,3 +1,4 @@
+@import '~antd/es/style/themes/default.less';
 @borderColor: #d9d9d9;
 
 .playback-warp {
@@ -7,6 +8,7 @@
 
   .playback-left {
     display: flex;
+    flex-direction: column;
     flex-grow: 1;
     width: 0;
 
@@ -16,7 +18,7 @@
   }
 
   .playback-right {
-    width: 280px;
+    width: 300px;
     margin-left: 24px;
 
     .playback-calendar {
@@ -44,6 +46,76 @@
         align-items: center;
         justify-content: center;
       }
+
+      .playback-list-items {
+        width: 100%;
+
+        .ant-list-item {
+          padding-left: 12px;
+        }
+      }
+    }
+  }
+
+  .time-line-warp {
+    padding: 10px 0;
+
+    .time-line-clock {
+      display: flex;
+      align-items: stretch;
+      justify-content: space-between;
+      width: 100%;
+
+      > div {
+        color: #666;
+        font-size: 12px;
+      }
+    }
+
+    .time-line-content {
+      position: relative;
+      padding-bottom: 20px;
+
+      .time-line-progress {
+        position: relative;
+        height: 16px;
+        overflow: hidden;
+        background-color: #d9d9d9;
+        border-radius: 2px;
+
+        > div {
+          position: absolute;
+          top: 0;
+          left: 0;
+          height: 100%;
+          background-color: #52c41a;
+          cursor: pointer;
+        }
+      }
+      .time-line-btn {
+        position: absolute;
+        top: -2px;
+        left: 0;
+        width: 3px;
+        height: 19px;
+        background-color: @primary-color;
+        border-radius: 2px;
+        visibility: hidden;
+      }
+
+      .time-line {
+        position: absolute;
+        bottom: -8px;
+        left: -30px;
+        width: 60px;
+        padding: 2px 0;
+        font-size: 12px;
+        text-align: center;
+        background-color: #d9d9d9;
+        border-radius: 2px;
+        box-shadow: 0 0 12px rgba(#000, 0.15);
+        visibility: hidden;
+      }
     }
   }
 }

+ 208 - 62
src/pages/media/Device/Playback/index.tsx

@@ -1,15 +1,23 @@
 // 回放
 import { PageContainer } from '@ant-design/pro-layout';
 import LivePlayer from '@/components/Player';
-import { useEffect, useState } from 'react';
-import { Select, Calendar, Empty, List } from 'antd';
+import { useCallback, useEffect, useState } from 'react';
+import { Select, Calendar, Empty, List, Tooltip } from 'antd';
 import { useLocation } from 'umi';
 import Service from './service';
 import './index.less';
 import { recordsItemType } from '@/pages/media/Device/Playback/typings';
 import * as moment from 'moment';
+import type { Moment } from 'moment';
 import classNames from 'classnames';
-import { CloudDownloadOutlined, PauseCircleOutlined, PlayCircleOutlined } from '@ant-design/icons';
+import {
+  CloudDownloadOutlined,
+  DownloadOutlined,
+  EyeOutlined,
+  PauseCircleOutlined,
+  PlayCircleOutlined,
+} from '@ant-design/icons';
+import TimeLine from './timeLine';
 
 const service = new Service('media');
 
@@ -17,41 +25,53 @@ export default () => {
   const [url, setUrl] = useState('');
   const [type, setType] = useState('local');
   const [historyList, setHistoryList] = useState<recordsItemType[]>([]);
-  const [time, setTime] = useState<any>('');
+  const [time, setTime] = useState<Moment | undefined>(undefined);
   const [playTime, setPlayTime] = useState(0);
+  // const [loading, setLoading] = useState(false)
+  const [cloudTime, setCloudTime] = useState<any>();
+  const [playing, setPlaying] = useState(false);
   const location = useLocation();
 
   const param = new URLSearchParams(location.search);
   const deviceId = param.get('id');
   const channelId = param.get('channelId');
 
-  const queryLocalRecords = async (date: any) => {
+  const queryLocalRecords = async (date: Moment) => {
+    setPlaying(false);
+    setUrl('');
     if (deviceId && channelId && date) {
       const params = {
         startTime: date.format('YYYY-MM-DD 00:00:00'),
         endTime: date.format('YYYY-MM-DD 23:59:59'),
       };
-      let list: recordsItemType[] = [];
+      const list: recordsItemType[] = [];
       const localResp = await service.queryRecordLocal(deviceId, channelId, params);
 
-      if (localResp.status === 200) {
-        list = localResp.result;
+      if (localResp.status === 200 && localResp.result.length) {
+        const serviceResp = await service.recordsInServer(deviceId, channelId, {
+          ...params,
+          includeFiles: false,
+        });
+        if (serviceResp.status === 200 && serviceResp.result) {
+          const newList = list.map((item) => {
+            return {
+              ...item,
+              isServer: serviceResp.result.some(
+                (serverFile: any) => serverFile.streamStartTime === item.startTime,
+              ),
+            };
+          });
+          setHistoryList(newList);
+        } else {
+          setHistoryList(list);
+        }
       }
-
-      const serviceResp = await service.recordsInServer(deviceId, channelId, {
-        ...params,
-        includeFiles: false,
-      });
-
-      if (serviceResp.status === 200) {
-        list = [...list, ...serviceResp.result];
-      }
-
-      setHistoryList(list);
     }
   };
 
-  const queryServiceRecords = async (date: any) => {
+  const queryServiceRecords = async (date: Moment) => {
+    setPlaying(false);
+    setUrl('');
     if (deviceId && channelId && date) {
       const params = {
         startTime: date.format('YYYY-MM-DD 00:00:00'),
@@ -67,6 +87,90 @@ export default () => {
     }
   };
 
+  const downLoadCloud = useCallback(
+    (item: recordsItemType) => {
+      setHistoryList(
+        historyList.map((historyItem) => {
+          if (historyItem.startTime === item.startTime) {
+            return {
+              ...item,
+              isServer: true,
+            };
+          }
+          return item;
+        }),
+      );
+    },
+    [historyList],
+  );
+
+  const cloudView = useCallback((startTime: number, endTime: number) => {
+    setType('cloud');
+    setCloudTime({
+      startTime,
+      endTime,
+    });
+    queryServiceRecords(time!);
+  }, []);
+
+  const downloadClick = async (item: recordsItemType) => {
+    const downloadUrl = service.downLoadFile(item.id);
+    const downNode = document.createElement('a');
+    downNode.href = downloadUrl;
+    downNode.download = `${channelId}-${moment(item.startTime).format('YYYY-MM-DD-HH-mm-ss')}.mp4`;
+    downNode.style.display = 'none';
+    document.body.appendChild(downNode);
+    downNode.click();
+    document.body.removeChild(downNode);
+  };
+
+  const DownloadIcon = useCallback(
+    (item: recordsItemType) => {
+      let title = '下载到云端';
+      let IconNode = (
+        <a
+          onClick={() => {
+            downLoadCloud(item);
+          }}
+        >
+          <CloudDownloadOutlined />
+        </a>
+      );
+      if (type === 'local') {
+        if (item.isServer) {
+          title = '查看';
+          IconNode = (
+            <a
+              onClick={() => {
+                cloudView(item.startTime, item.endTime);
+              }}
+            >
+              <EyeOutlined />
+            </a>
+          );
+        }
+      } else {
+        title = '下载录像文件';
+        IconNode = (
+          <a
+            onClick={() => {
+              downloadClick(item);
+            }}
+            download
+          >
+            <DownloadOutlined />
+          </a>
+        );
+      }
+
+      return {
+        title,
+        IconNode,
+      };
+    },
+    [type],
+  );
+
   useEffect(() => {
     setTime(moment(new Date()));
     queryLocalRecords(moment(new Date()));
@@ -76,7 +180,48 @@ export default () => {
     <PageContainer>
       <div className={'playback-warp'}>
         <div className={'playback-left'}>
-          <LivePlayer url={url} className={'playback-media'} />
+          <LivePlayer
+            url={url}
+            className={'playback-media'}
+            live={type === 'local'}
+            onPlay={() => {
+              setPlaying(true);
+            }}
+            onPause={() => {
+              setPlaying(false);
+            }}
+            onDestroy={() => {
+              setPlaying(false);
+            }}
+            onError={() => {
+              setPlaying(false);
+            }}
+          />
+          <TimeLine
+            type={type}
+            data={historyList}
+            dateTime={time}
+            onChange={(times) => {
+              if (times) {
+                setPlayTime(Number(times.endTime.valueOf()));
+                setUrl(
+                  type === 'local'
+                    ? service.playbackLocal(
+                        times.deviceId,
+                        times.channelId,
+                        'mp4',
+                        moment(times.startTime).format('YYYY-MM-DD HH:mm:ss'),
+                        moment(times.endTime).format('YYYY-MM-DD HH:mm:ss'),
+                      )
+                    : service.playbackStart(times.deviceId),
+                );
+              } else {
+                setUrl('');
+              }
+            }}
+            playing={playing}
+            localToServer={cloudTime}
+          />
         </div>
         <div className={'playback-right'}>
           <Select
@@ -89,9 +234,9 @@ export default () => {
             onSelect={(key: string) => {
               setType(key);
               if (key === 'cloud') {
-                queryServiceRecords(time);
+                queryServiceRecords(time!);
               } else {
-                queryLocalRecords(time);
+                queryLocalRecords(time!);
               }
             }}
           />
@@ -113,56 +258,57 @@ export default () => {
           <div className={classNames('playback-list', { 'no-list': !historyList.length })}>
             {historyList && historyList.length ? (
               <List
+                className={'playback-list-items'}
                 itemLayout="horizontal"
                 dataSource={historyList}
                 renderItem={(item) => {
-                  const startTime = moment(item.startTime);
-                  const startH = startTime.hours();
-                  const startM = startTime.minutes();
-                  const startS = startTime.seconds();
-
-                  const endTime = moment(item.endTime);
-                  const endH = endTime.hours();
-                  const endM = endTime.minutes();
-                  const endS = endTime.seconds();
+                  const startTime = moment(item.startTime || item.mediaStartTime).format(
+                    'HH:mm:ss',
+                  );
+                  const endTime = moment(item.endTime || item.mediaEndTime).format('HH:mm:ss');
+                  const downloadObj = DownloadIcon(item);
+                  const timeId = item.endTime || item.mediaEndTime;
 
+                  console.log(timeId, playTime);
                   return (
                     <List.Item
                       actions={[
-                        <a
-                          key="list-loadmore-edit"
-                          onClick={() => {
-                            if (!playTime) {
-                              setPlayTime(item.startTime);
-                              if (deviceId && channelId) {
-                                setUrl(
-                                  service.playbackLocal(
-                                    deviceId,
-                                    channelId,
-                                    'mp4',
-                                    item.startTime,
-                                    item.endTime,
-                                  ),
-                                );
-                              }
-                            } else {
-                              setPlayTime(0);
-                            }
-                          }}
+                        <Tooltip
+                          key="play-btn"
+                          title={item.startTime === playTime ? '暂停' : '播放'}
                         >
-                          {item.startTime === playTime ? (
-                            <PauseCircleOutlined />
-                          ) : (
-                            <PlayCircleOutlined />
-                          )}
-                        </a>,
-                        <a key="list-loadmore-more">
-                          <CloudDownloadOutlined />
-                        </a>,
+                          <a
+                            onClick={() => {
+                              if (!playTime) {
+                                setPlayTime(item.startTime);
+                                if (item.filePath) {
+                                  service.playbackStart(item.id);
+                                } else if (deviceId && channelId) {
+                                  setUrl(
+                                    service.playbackLocal(
+                                      deviceId,
+                                      channelId,
+                                      'mp4',
+                                      moment(item.startTime).format('YYYY-MM-DD HH:mm:ss'),
+                                      moment(item.endTime).format('YYYY-MM-DD HH:mm:ss'),
+                                    ),
+                                  );
+                                }
+                              } else {
+                                setPlayTime(0);
+                              }
+                            }}
+                          >
+                            {timeId === playTime ? <PauseCircleOutlined /> : <PlayCircleOutlined />}
+                          </a>
+                        </Tooltip>,
+                        <Tooltip key={'download'} title={downloadObj.title}>
+                          {downloadObj.IconNode}
+                        </Tooltip>,
                       ]}
                     >
                       <div style={{ textAlign: 'center', paddingLeft: 10 }}>
-                        {`${startH}:${startM}:${startS}`} ~ {`${endH}:${endM}:${endS}`}
+                        {`${startTime}`} ~ {`${endTime}`}
                       </div>
                     </List.Item>
                   );

+ 13 - 3
src/pages/media/Device/Playback/service.ts

@@ -8,6 +8,13 @@ class Service extends BaseService<recordsItemType> {
   ptzStart = (deviceId: string, channelId: string, type: string) =>
     `${this.uri}/device/${deviceId}/${channelId}/live.${type}?:X_Access_Token=${Token.get()}`;
 
+  // 查询设备通道详情
+  queryDetail = (deviceId: string, data: any) =>
+    request(`${this.uri}/device/${deviceId}/channel/_query`, {
+      method: 'POST',
+      data,
+    });
+
   // 查询本地回放记录
   queryRecordLocal = (deviceId: string, channelId: string, data?: any) =>
     request(`${this.uri}/device/${deviceId}/${channelId}/records/in-local`, {
@@ -20,8 +27,8 @@ class Service extends BaseService<recordsItemType> {
     deviceId: string,
     channelId: string,
     suffix: string,
-    startTime: number,
-    endTime: number,
+    startTime: string,
+    endTime: string,
     speed: number = 1,
   ) =>
     `${
@@ -48,7 +55,10 @@ class Service extends BaseService<recordsItemType> {
 
   // 播放云端回放
   playbackStart = (recordId: string) =>
-    request(`${this.uri}/record/${recordId}.mp4`, { method: 'GET' });
+    `${this.uri}/record/${recordId}.mp4?:X_Access_Token=${Token.get()}`;
+
+  downLoadFile = (recordId: string) =>
+    `${this.uri}/record/${recordId}.mp4?download=true&:X_Access_Token=${Token.get()}`;
 }
 
 export default Service;

+ 205 - 0
src/pages/media/Device/Playback/timeLine.tsx

@@ -0,0 +1,205 @@
+import { message } from 'antd';
+import moment from 'moment';
+import type { Moment } from 'moment';
+import { useEffect, useState, useRef } from 'react';
+import './index.less';
+import { recordsItemType } from '@/pages/media/Device/Playback/typings';
+import { useSize } from 'ahooks';
+import classNames from 'classnames';
+
+export type TimeChangeType = {
+  endTime: Moment;
+  startTime: Moment;
+  deviceId: string;
+  channelId: string;
+};
+
+interface Props {
+  onChange: (times: TimeChangeType | undefined) => void;
+  data: recordsItemType[];
+  dateTime?: Moment;
+  type: string;
+  playing: boolean;
+  server?: any;
+  localToServer?: {
+    endTime: number;
+    startTime: number;
+  };
+  getPlayList?: (data: any) => void;
+}
+
+const Progress = (props: Props) => {
+  const [startT, setStartT] = useState<number>(
+    new Date(moment(props.dateTime).startOf('day').format('YYYY-MM-DD HH:mm:ss')).getTime(),
+  ); // 获取选中当天开始时间戳
+  const endT = new Date(
+    moment(props.dateTime).endOf('day').format('YYYY-MM-DD HH:mm:ss'),
+  ).getTime(); // 获取选中当天结束时间戳
+
+  const [list, setList] = useState<any[]>([]);
+  const [time, setTime] = useState<number>(startT);
+
+  const LineContent = useRef<HTMLDivElement>(null);
+  const LineContentSize = useSize(LineContent);
+
+  const setTimeAndPosition = (ob: number) => {
+    const oBtn = document.getElementById('btn');
+    const oTime = document.getElementById('time');
+
+    if (oBtn && oTime && LineContentSize.width) {
+      oBtn.style.visibility = 'visible';
+      oBtn.style.left = `${ob * LineContentSize.width}px`;
+      oTime.style.visibility = 'visible';
+      oTime.style.left = `${ob * LineContentSize.width - 15}px`;
+    }
+  };
+
+  useEffect(() => {
+    setStartT(
+      new Date(moment(props.dateTime).startOf('day').format('YYYY-MM-DD HH:mm:ss')).getTime(),
+    );
+  }, [props.dateTime]);
+
+  const onChange = (startTime: number, endTime: number, deviceId: string, channelId: string) => {
+    props.onChange({
+      startTime: moment(startTime),
+      endTime: moment(endTime),
+      deviceId,
+      channelId,
+    });
+  };
+
+  useEffect(() => {
+    const { data, localToServer, type } = props;
+    if (data && Array.isArray(data) && data.length > 0) {
+      setList([...data]);
+      if (type === 'local') {
+        // 播放第一个
+        onChange(data[0].startTime, data[0].endTime, data[0].deviceId, data[0].channelId);
+        setTime(startT);
+      } else if (type === 'cloud') {
+        // 是否从本地跳转到云端播放
+        if (localToServer && Object.keys(localToServer).length > 0) {
+          // 获取跳转播放段
+          const playItem = data.find((item) => {
+            return (
+              item.mediaEndTime <= localToServer.endTime &&
+              item.mediaStartTime >= localToServer.startTime
+            );
+          });
+          if (playItem) {
+            //播放片段
+            onChange(
+              playItem.mediaStartTime,
+              playItem.mediaEndTime,
+              playItem.id,
+              playItem.channelId,
+            );
+            setTime(playItem.mediaStartTime);
+          } else {
+            props.onChange(undefined);
+            setTime(localToServer.startTime);
+            message.error('没有可播放的视频资源');
+          }
+        } else {
+          setTime(data[0].mediaStartTime);
+          onChange(data[0].mediaStartTime, data[0].mediaEndTime, data[0].id, data[0].channelId);
+        }
+      }
+    } else if (localToServer && localToServer.startTime) {
+      // 本地跳转云端但是无资源
+      props.onChange(undefined);
+      message.error('没有可播放的视频资源');
+      setTime(startT);
+      setList([]);
+    } else {
+      // 啥都没有
+      setTime(startT);
+      setList([]);
+      props.onChange(undefined);
+    }
+  }, [props.data]);
+
+  useEffect(() => {
+    // if(props.server && Object.keys(props.server).length > 0){
+    //   if(props.type === 'local'){
+    //     setTime(props.server.startTime)
+    //     props.play({ start: props.server.startTime, end: props.server.endTime })
+    //   } else {
+    //     setTime(props.server.mediaStartTime)
+    //     props.play(props.server)
+    //   }
+    // }
+  }, [props.server]);
+
+  const getLineItemStyle = (
+    startTime: number,
+    endTime: number,
+  ): { left: string; width: string } => {
+    const start = startTime - startT > 0 ? startTime - startT : 0;
+    const _width = LineContentSize.width!;
+    const itemWidth = ((endTime - startTime) / (24 * 3600000)) * _width;
+    return {
+      left: `${(start / (24 * 3600000)) * _width}px`,
+      width: `${itemWidth < 1 ? 1 : itemWidth}px`,
+    };
+  };
+
+  useEffect(() => {
+    let timerId: any = null;
+    if (props.playing) {
+      timerId = setInterval(() => {
+        // eslint-disable-next-line @typescript-eslint/no-shadow
+        setTime((time) => time + 1000);
+      }, 1000);
+    }
+    return () => timerId && clearInterval(timerId);
+  }, [props.playing]);
+
+  useEffect(() => {
+    if (time >= startT && time <= endT && props.data && props.data.length) {
+      setTimeAndPosition((time - startT) / 3600000 / 24);
+    }
+  }, [time]);
+
+  return (
+    <div className={'time-line-warp'}>
+      <div className={'time-line-clock'}>
+        {Array.from(Array(25), (v, k) => k).map((item) => {
+          return <div key={item}>{item}</div>;
+        })}
+      </div>
+      <div className={'time-line-content'} ref={LineContent}>
+        <div className={'time-line-progress'}>
+          {list.map((item, index) => {
+            const { left, width } = getLineItemStyle(
+              item.startTime || item.mediaStartTime,
+              item.endTime || item.mediaEndTime,
+            );
+
+            return (
+              <div
+                key={`time_${index}`}
+                onClick={(event) => {
+                  const pos = LineContent.current?.getBoundingClientRect();
+                  if (pos && item.endTime) {
+                    const dt = event.clientX - pos.x;
+                    const start = (dt / pos.width) * 24 * 3600000 + startT;
+                    const _start = start < item.startTime ? item.startTime : start;
+                    onChange(_start, item.endTime, item.deviceId, item.channelId);
+                  }
+                }}
+                style={{ left, width }}
+              ></div>
+            );
+          })}
+        </div>
+        <div id="btn" className={classNames('time-line-btn')}></div>
+        <div id="time" className={classNames('time-line')}>
+          {moment(time).format('HH:mm:ss')}
+        </div>
+      </div>
+    </div>
+  );
+};
+export default Progress;

+ 5 - 0
src/pages/media/Device/Playback/typings.d.ts

@@ -6,5 +6,10 @@ export type recordsItemType = {
   name: string;
   secrecy: string;
   startTime: number;
+  mediaEndTime: number;
+  mediaStartTime: number;
+  filePath: string;
   type: string;
+  id: string;
+  isServer?: boolean;
 };

+ 15 - 5
src/pages/media/Device/Save/index.tsx

@@ -1,4 +1,4 @@
-import { useEffect, useState } from 'react';
+import { useCallback, useEffect, useState } from 'react';
 import { Button, Col, Form, Input, message, Modal, Radio, Row, Select } from 'antd';
 import { useIntl } from 'umi';
 import { RadioCard, UploadImage } from '@/components';
@@ -25,6 +25,7 @@ export default (props: SaveProps) => {
   const [productVisible, setProductVisible] = useState(false);
   const [accessType, setAccessType] = useState(DefaultAccessType);
   const [productList, setProductList] = useState<any[]>([]);
+  const [oldPassword, setOldPassword] = useState('');
 
   const getProductList = async (productParams: any) => {
     const resp = await service.queryProductList(productParams);
@@ -44,6 +45,7 @@ export default (props: SaveProps) => {
 
   useEffect(() => {
     if (visible) {
+      setOldPassword('');
       if (props.model === 'edit') {
         form.setFieldsValue(data);
         const _accessType = data?.provider || DefaultAccessType;
@@ -60,10 +62,13 @@ export default (props: SaveProps) => {
     }
   }, [visible]);
 
-  const handleSave = async () => {
+  const handleSave = useCallback(async () => {
     const formData = await form.validateFields();
     if (formData) {
       const { provider, ...extraFormData } = formData;
+      if (formData.password === oldPassword) {
+        delete extraFormData.password;
+      }
       setLoading(true);
       const resp =
         provider === DefaultAccessType
@@ -81,7 +86,7 @@ export default (props: SaveProps) => {
         message.error('操作失败');
       }
     }
-  };
+  }, [props.model, oldPassword]);
 
   const intlFormat = (
     id: string,
@@ -107,8 +112,6 @@ export default (props: SaveProps) => {
     );
   };
 
-  console.log(productList);
-
   return (
     <>
       <Modal
@@ -208,6 +211,13 @@ export default (props: SaveProps) => {
                     options={productList}
                     placeholder={'请选择所属产品'}
                     style={{ width: props.model === 'edit' ? '100%' : 'calc(100% - 36px)' }}
+                    onSelect={(_: any, node: any) => {
+                      const pasd = node.configuration ? node.configuration.access_pwd : '';
+                      form.setFieldsValue({
+                        password: pasd,
+                      });
+                      setOldPassword(pasd);
+                    }}
                   />
                 </Form.Item>
                 {props.model !== 'edit' && (

+ 27 - 3
src/pages/system/Menu/components/Icons/icon.ts

@@ -7,7 +7,6 @@ export default [
   'icon-shebei',
   'icon-wangluozujian',
   'icon-shipinwangguan',
-  'icon-wumoxing',
   'icon-wangguanzishebei',
   'icon-zhihuishequ',
   'icon-chanpinfenlei',
@@ -20,6 +19,31 @@ export default [
   'icon-zhihuichengshi',
   'icon-chajianguanli',
   'icon-zhihuiyuanqu',
-  'icon-Subtract',
-  'icon-a-Frame2125',
+  'icon-fenpingzhanshi1',
+  'icon-rili',
+  'icon-renyuan',
+  'icon-shezhi',
+  'icon-chuli',
+  'icon-anniuguanli',
+  'icon-tongzhijilu',
+  'icon-shuxingpeizhi',
+  'icon-xiaoxi',
+  'icon-guojijilian',
+  'icon-quanxianguanli',
+  'icon-jiaoseguanli',
+  'icon-xuanzetongdao1',
+  'icon-yonghuguanli',
+  'icon-bumenguanli',
+  'icon-caidanguanli',
+  'icon-Vector',
+  'icon-Union',
+  'icon-shebeigaojing',
+  'icon-chanpinfenlei1',
+  'icon-bianyuanwangguan',
+  'icon-wuguanli',
+  'icon-yunyunjieru',
+  'icon-wulianwang',
+  'icon-shebeiguanli',
+  'icon-xitongguanli1',
+  'icon-yunweiguanli-1',
 ];

+ 1 - 1
src/pages/system/Menu/index.tsx

@@ -137,7 +137,7 @@ export default observer(() => {
           onClick={() => {
             pageJump(record.id, record.parentId || '');
           }}
-          disabled={getButtonPermission('system/Menu', ['view'])}
+          disabled={getButtonPermission('system/Menu', ['view', 'update'])}
         >
           <Tooltip
             title={intl.formatMessage({