diff --git a/public/css/iconfont.css b/public/css/iconfont.css index 1af2903d4..a349ccdff 100644 --- a/public/css/iconfont.css +++ b/public/css/iconfont.css @@ -1,8 +1,8 @@ @font-face { font-family: "iconfont"; /* Project id 2340181 */ - src: url('iconfont.woff2?t=1765938619495') format('woff2'), - url('iconfont.woff?t=1765938619495') format('woff'), - url('iconfont.ttf?t=1765938619495') format('truetype'); + src: url('iconfont.woff2?t=1778741577467') format('woff2'), + url('iconfont.woff?t=1778741577467') format('woff'), + url('iconfont.ttf?t=1778741577467') format('truetype'); } .iconfont { @@ -13,6 +13,218 @@ -moz-osx-font-smoothing: grayscale; } +.icon-xiala5:before { + content: "\e9df"; +} + +.icon-yulan:before { + content: "\e9f1"; +} + +.icon-arrright:before { + content: "\e9fc"; +} + +.icon-yunxiaogongju:before { + content: "\e9f6"; +} + +.icon-daimazhijian:before { + content: "\e9f7"; +} + +.icon-yidongkaifa:before { + content: "\e9f8"; +} + +.icon-qita:before { + content: "\e9f9"; +} + +.icon-meitichuli:before { + content: "\e9fb"; +} + +.icon-skill:before { + content: "\e9f3"; +} + +.icon-daimaku1:before { + content: "\e9f2"; +} + +.icon-dianzan5:before { + content: "\e9ee"; +} + +.icon-duomotaimoxing:before { + content: "\e9ef"; +} + +.icon-a-kexueyanjiuhejishufuwuye-1:before { + content: "\e9f0"; +} + +.icon-yinpin-1:before { + content: "\e9e2"; +} + +.icon-shujuji-4:before { + content: "\e9e4"; +} + +.icon-shujuji:before { + content: "\e9e5"; +} + +.icon-shujuyuanmoxing:before { + content: "\e9e6"; +} + +.icon-shujuji-3:before { + content: "\e9e7"; +} + +.icon-a-shujuji5:before { + content: "\e9e8"; +} + +.icon-a-shujuji-6:before { + content: "\e9e9"; +} + +.icon-shipinbofang-1:before { + content: "\e9ea"; +} + +.icon-moxingku:before { + content: "\e9eb"; +} + +.icon-a-shijianzhongbiao:before { + content: "\e9ec"; +} + +.icon-remenmoxing-2:before { + content: "\e9ed"; +} + +.icon-a-Dshujukukaifagongju:before { + content: "\e9cd"; +} + +.icon-ziranyuyanchuli-2:before { + content: "\e9db"; +} + +.icon-a-zu18214:before { + content: "\e9dc"; +} + +.icon-zizhushujuji:before { + content: "\e9dd"; +} + +.icon-yuyin-1:before { + content: "\e9de"; +} + +.icon-a-tuxiang-1:before { + content: "\e9e0"; +} + +.icon-xiazai3:before { + content: "\e9e1"; +} + +.icon-shijian1:before { + content: "\e9cb"; +} + +.icon-liulanliang:before { + content: "\e9cc"; +} + +.icon-guanbi2:before { + content: "\e9ca"; +} + +.icon-zhanshishangxian1:before { + content: "\e9d3"; +} + +.icon-tianxiexinxi:before { + content: "\e9d8"; +} + +.icon-tijiaoshenqing1:before { + content: "\e9d9"; +} + +.icon-guanliyuanshenhe1:before { + content: "\e9da"; +} + +.icon-sixin2:before { + content: "\e9e3"; +} + +.icon-dianzan4:before { + content: "\e9d6"; +} + +.icon-liulanshu:before { + content: "\e9d7"; +} + +.icon-tiezishu:before { + content: "\e9ce"; +} + +.icon-yanjiulingyu:before { + content: "\e9cf"; +} + +.icon-a-xiugai3:before { + content: "\e9d0"; +} + +.icon-yitijiaoderuzhuxinxi:before { + content: "\e9d1"; +} + +.icon-sixin:before { + content: "\e9d2"; +} + +.icon-gerenjianjie:before { + content: "\e9d4"; +} + +.icon-guanzhu1:before { + content: "\e9d5"; +} + +.icon-woyefatie:before { + content: "\e9c9"; +} + +.icon-yingyongmoban:before { + content: "\e9c8"; +} + +.icon-zhuangtai:before { + content: "\e9c5"; +} + +.icon-fuzhi-shanchu1:before { + content: "\e9c6"; +} + +.icon-mobanguanli:before { + content: "\e9c7"; +} + .icon-svg_jiantou1:before { content: "\e9c3"; } diff --git a/public/css/iconfont.js b/public/css/iconfont.js index 548738c34..ec5ee4347 100644 --- a/public/css/iconfont.js +++ b/public/css/iconfont.js @@ -1 +1 @@ -window._iconfont_svg_string_2340181='',(c=>{var a=(l=(l=document.getElementsByTagName("script"))[l.length-1]).getAttribute("data-injectcss"),l=l.getAttribute("data-disable-injectsvg");if(!l){var h,i,o,z,t,p=function(a,l){l.parentNode.insertBefore(a,l)};if(a&&!c.__iconfont__svg__cssinject__){c.__iconfont__svg__cssinject__=!0;try{document.write("")}catch(a){console&&console.log(a)}}h=function(){var a,l=document.createElement("div");l.innerHTML=c._iconfont_svg_string_2340181,(l=l.getElementsByTagName("svg")[0])&&(l.setAttribute("aria-hidden","true"),l.style.position="absolute",l.style.width=0,l.style.height=0,l.style.overflow="hidden",l=l,(a=document.body).firstChild?p(l,a.firstChild):a.appendChild(l))},document.addEventListener?~["complete","loaded","interactive"].indexOf(document.readyState)?setTimeout(h,0):(i=function(){document.removeEventListener("DOMContentLoaded",i,!1),h()},document.addEventListener("DOMContentLoaded",i,!1)):document.attachEvent&&(o=h,z=c.document,t=!1,m(),z.onreadystatechange=function(){"complete"==z.readyState&&(z.onreadystatechange=null,v())})}function v(){t||(t=!0,o())}function m(){try{z.documentElement.doScroll("left")}catch(a){return void setTimeout(m,50)}v()}})(window); \ No newline at end of file +window._iconfont_svg_string_2340181='',(c=>{var a=(l=(l=document.getElementsByTagName("script"))[l.length-1]).getAttribute("data-injectcss"),l=l.getAttribute("data-disable-injectsvg");if(!l){var h,i,o,z,t,p=function(a,l){l.parentNode.insertBefore(a,l)};if(a&&!c.__iconfont__svg__cssinject__){c.__iconfont__svg__cssinject__=!0;try{document.write("")}catch(a){console&&console.log(a)}}h=function(){var a,l=document.createElement("div");l.innerHTML=c._iconfont_svg_string_2340181,(l=l.getElementsByTagName("svg")[0])&&(l.setAttribute("aria-hidden","true"),l.style.position="absolute",l.style.width=0,l.style.height=0,l.style.overflow="hidden",l=l,(a=document.body).firstChild?p(l,a.firstChild):a.appendChild(l))},document.addEventListener?~["complete","loaded","interactive"].indexOf(document.readyState)?setTimeout(h,0):(i=function(){document.removeEventListener("DOMContentLoaded",i,!1),h()},document.addEventListener("DOMContentLoaded",i,!1)):document.attachEvent&&(o=h,z=c.document,t=!1,m(),z.onreadystatechange=function(){"complete"==z.readyState&&(z.onreadystatechange=null,v())})}function v(){t||(t=!0,o())}function m(){try{z.documentElement.doScroll("left")}catch(a){return void setTimeout(m,50)}v()}})(window); \ No newline at end of file diff --git a/public/css/iconfont.json b/public/css/iconfont.json index ac9ae795a..dec6613b2 100644 --- a/public/css/iconfont.json +++ b/public/css/iconfont.json @@ -5,6 +5,377 @@ "css_prefix_text": "icon-", "description": "", "glyphs": [ + { + "icon_id": "47540662", + "name": "下拉", + "font_class": "xiala5", + "unicode": "e9df", + "unicode_decimal": 59871 + }, + { + "icon_id": "47540661", + "name": "预览", + "font_class": "yulan", + "unicode": "e9f1", + "unicode_decimal": 59889 + }, + { + "icon_id": "40883122", + "name": "长箭头-copy", + "font_class": "arrright", + "unicode": "e9fc", + "unicode_decimal": 59900 + }, + { + "icon_id": "47487774", + "name": "云效工具", + "font_class": "yunxiaogongju", + "unicode": "e9f6", + "unicode_decimal": 59894 + }, + { + "icon_id": "47487775", + "name": "代码质检", + "font_class": "daimazhijian", + "unicode": "e9f7", + "unicode_decimal": 59895 + }, + { + "icon_id": "47487773", + "name": "移动开发", + "font_class": "yidongkaifa", + "unicode": "e9f8", + "unicode_decimal": 59896 + }, + { + "icon_id": "47487772", + "name": "其他", + "font_class": "qita", + "unicode": "e9f9", + "unicode_decimal": 59897 + }, + { + "icon_id": "47487770", + "name": "媒体处理", + "font_class": "meitichuli", + "unicode": "e9fb", + "unicode_decimal": 59899 + }, + { + "icon_id": "47487669", + "name": "skill", + "font_class": "skill", + "unicode": "e9f3", + "unicode_decimal": 59891 + }, + { + "icon_id": "47487670", + "name": "代码库", + "font_class": "daimaku1", + "unicode": "e9f2", + "unicode_decimal": 59890 + }, + { + "icon_id": "47470076", + "name": "点赞", + "font_class": "dianzan5", + "unicode": "e9ee", + "unicode_decimal": 59886 + }, + { + "icon_id": "47470075", + "name": "多模态模型", + "font_class": "duomotaimoxing", + "unicode": "e9ef", + "unicode_decimal": 59887 + }, + { + "icon_id": "47470074", + "name": "科学研究和技术服务业 -1", + "font_class": "a-kexueyanjiuhejishufuwuye-1", + "unicode": "e9f0", + "unicode_decimal": 59888 + }, + { + "icon_id": "47470091", + "name": "音频-1", + "font_class": "yinpin-1", + "unicode": "e9e2", + "unicode_decimal": 59874 + }, + { + "icon_id": "47470090", + "name": "数据集-4", + "font_class": "shujuji-4", + "unicode": "e9e4", + "unicode_decimal": 59876 + }, + { + "icon_id": "47470088", + "name": "数据集", + "font_class": "shujuji", + "unicode": "e9e5", + "unicode_decimal": 59877 + }, + { + "icon_id": "47470089", + "name": "数据源模型", + "font_class": "shujuyuanmoxing", + "unicode": "e9e6", + "unicode_decimal": 59878 + }, + { + "icon_id": "47470087", + "name": "数据集-3", + "font_class": "shujuji-3", + "unicode": "e9e7", + "unicode_decimal": 59879 + }, + { + "icon_id": "47470086", + "name": "数据集 (5)", + "font_class": "a-shujuji5", + "unicode": "e9e8", + "unicode_decimal": 59880 + }, + { + "icon_id": "47470083", + "name": "数据集 -6", + "font_class": "a-shujuji-6", + "unicode": "e9e9", + "unicode_decimal": 59881 + }, + { + "icon_id": "47470084", + "name": "视频播放-1", + "font_class": "shipinbofang-1", + "unicode": "e9ea", + "unicode_decimal": 59882 + }, + { + "icon_id": "47470081", + "name": "模型库", + "font_class": "moxingku", + "unicode": "e9eb", + "unicode_decimal": 59883 + }, + { + "icon_id": "47470080", + "name": "时间 钟表", + "font_class": "a-shijianzhongbiao", + "unicode": "e9ec", + "unicode_decimal": 59884 + }, + { + "icon_id": "47470079", + "name": "热门模型-2", + "font_class": "remenmoxing-2", + "unicode": "e9ed", + "unicode_decimal": 59885 + }, + { + "icon_id": "47470107", + "name": "D+数据库开发工具", + "font_class": "a-Dshujukukaifagongju", + "unicode": "e9cd", + "unicode_decimal": 59853 + }, + { + "icon_id": "47470101", + "name": "自然语言处理-2", + "font_class": "ziranyuyanchuli-2", + "unicode": "e9db", + "unicode_decimal": 59867 + }, + { + "icon_id": "47470102", + "name": "组 18214", + "font_class": "a-zu18214", + "unicode": "e9dc", + "unicode_decimal": 59868 + }, + { + "icon_id": "47470098", + "name": "自助数据集", + "font_class": "zizhushujuji", + "unicode": "e9dd", + "unicode_decimal": 59869 + }, + { + "icon_id": "47470095", + "name": "语音-1", + "font_class": "yuyin-1", + "unicode": "e9de", + "unicode_decimal": 59870 + }, + { + "icon_id": "47470094", + "name": "图像 -1", + "font_class": "a-tuxiang-1", + "unicode": "e9e0", + "unicode_decimal": 59872 + }, + { + "icon_id": "47470092", + "name": "下载", + "font_class": "xiazai3", + "unicode": "e9e1", + "unicode_decimal": 59873 + }, + { + "icon_id": "47464883", + "name": "时间", + "font_class": "shijian1", + "unicode": "e9cb", + "unicode_decimal": 59851 + }, + { + "icon_id": "47464882", + "name": "浏览量", + "font_class": "liulanliang", + "unicode": "e9cc", + "unicode_decimal": 59852 + }, + { + "icon_id": "47337195", + "name": "关闭", + "font_class": "guanbi2", + "unicode": "e9ca", + "unicode_decimal": 59850 + }, + { + "icon_id": "47202525", + "name": "展示上线", + "font_class": "zhanshishangxian1", + "unicode": "e9d3", + "unicode_decimal": 59859 + }, + { + "icon_id": "47202524", + "name": "填写信息", + "font_class": "tianxiexinxi", + "unicode": "e9d8", + "unicode_decimal": 59864 + }, + { + "icon_id": "47202523", + "name": "提交申请", + "font_class": "tijiaoshenqing1", + "unicode": "e9d9", + "unicode_decimal": 59865 + }, + { + "icon_id": "47202522", + "name": "管理员审核", + "font_class": "guanliyuanshenhe1", + "unicode": "e9da", + "unicode_decimal": 59866 + }, + { + "icon_id": "47195847", + "name": "私信", + "font_class": "sixin2", + "unicode": "e9e3", + "unicode_decimal": 59875 + }, + { + "icon_id": "47195594", + "name": "点赞", + "font_class": "dianzan4", + "unicode": "e9d6", + "unicode_decimal": 59862 + }, + { + "icon_id": "47195591", + "name": "浏览数", + "font_class": "liulanshu", + "unicode": "e9d7", + "unicode_decimal": 59863 + }, + { + "icon_id": "47195601", + "name": "帖子数", + "font_class": "tiezishu", + "unicode": "e9ce", + "unicode_decimal": 59854 + }, + { + "icon_id": "47195600", + "name": "研究领域", + "font_class": "yanjiulingyu", + "unicode": "e9cf", + "unicode_decimal": 59855 + }, + { + "icon_id": "47195597", + "name": "修改 (3)", + "font_class": "a-xiugai3", + "unicode": "e9d0", + "unicode_decimal": 59856 + }, + { + "icon_id": "47195598", + "name": "已提交的入驻信息", + "font_class": "yitijiaoderuzhuxinxi", + "unicode": "e9d1", + "unicode_decimal": 59857 + }, + { + "icon_id": "47195599", + "name": "私信", + "font_class": "sixin", + "unicode": "e9d2", + "unicode_decimal": 59858 + }, + { + "icon_id": "47195593", + "name": "个人简介", + "font_class": "gerenjianjie", + "unicode": "e9d4", + "unicode_decimal": 59860 + }, + { + "icon_id": "47195595", + "name": "关注", + "font_class": "guanzhu1", + "unicode": "e9d5", + "unicode_decimal": 59861 + }, + { + "icon_id": "47139445", + "name": "我也发帖", + "font_class": "woyefatie", + "unicode": "e9c9", + "unicode_decimal": 59849 + }, + { + "icon_id": "46808654", + "name": "应用模板", + "font_class": "yingyongmoban", + "unicode": "e9c8", + "unicode_decimal": 59848 + }, + { + "icon_id": "46593376", + "name": "状态", + "font_class": "zhuangtai", + "unicode": "e9c5", + "unicode_decimal": 59845 + }, + { + "icon_id": "46593375", + "name": "复制-删除", + "font_class": "fuzhi-shanchu1", + "unicode": "e9c6", + "unicode_decimal": 59846 + }, + { + "icon_id": "46593374", + "name": "模版管理", + "font_class": "mobanguanli", + "unicode": "e9c7", + "unicode_decimal": 59847 + }, { "icon_id": "46370299", "name": "svg_箭头1", diff --git a/public/css/iconfont.ttf b/public/css/iconfont.ttf index ae09e439f..ceaaa8256 100644 Binary files a/public/css/iconfont.ttf and b/public/css/iconfont.ttf differ diff --git a/public/css/iconfont.woff b/public/css/iconfont.woff index a1ebdfd2d..48789468d 100644 Binary files a/public/css/iconfont.woff and b/public/css/iconfont.woff differ diff --git a/public/css/iconfont.woff2 b/public/css/iconfont.woff2 index 2f02631b0..c16fe7a00 100644 Binary files a/public/css/iconfont.woff2 and b/public/css/iconfont.woff2 differ diff --git a/public/css/iconfont_color/demo.css b/public/css/iconfont_color/demo.css new file mode 100644 index 000000000..a67054a0a --- /dev/null +++ b/public/css/iconfont_color/demo.css @@ -0,0 +1,539 @@ +/* Logo 字体 */ +@font-face { + font-family: "iconfont logo"; + src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834'); + src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834#iefix') format('embedded-opentype'), + url('https://at.alicdn.com/t/font_985780_km7mi63cihi.woff?t=1545807318834') format('woff'), + url('https://at.alicdn.com/t/font_985780_km7mi63cihi.ttf?t=1545807318834') format('truetype'), + url('https://at.alicdn.com/t/font_985780_km7mi63cihi.svg?t=1545807318834#iconfont') format('svg'); +} + +.logo { + font-family: "iconfont logo"; + font-size: 160px; + font-style: normal; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +/* tabs */ +.nav-tabs { + position: relative; +} + +.nav-tabs .nav-more { + position: absolute; + right: 0; + bottom: 0; + height: 42px; + line-height: 42px; + color: #666; +} + +#tabs { + border-bottom: 1px solid #eee; +} + +#tabs li { + cursor: pointer; + width: 100px; + height: 40px; + line-height: 40px; + text-align: center; + font-size: 16px; + border-bottom: 2px solid transparent; + position: relative; + z-index: 1; + margin-bottom: -1px; + color: #666; +} + + +#tabs .active { + border-bottom-color: #f00; + color: #222; +} + +.tab-container .content { + display: none; +} + +/* 页面布局 */ +.main { + padding: 30px 100px; + width: 960px; + margin: 0 auto; +} + +.main .logo { + color: #333; + text-align: left; + margin-bottom: 30px; + line-height: 1; + height: 110px; + margin-top: -50px; + overflow: hidden; + *zoom: 1; +} + +.main .logo a { + font-size: 160px; + color: #333; +} + +.helps { + margin-top: 40px; +} + +.helps pre { + padding: 20px; + margin: 10px 0; + border: solid 1px #e7e1cd; + background-color: #fffdef; + overflow: auto; +} + +.icon_lists { + width: 100% !important; + overflow: hidden; + *zoom: 1; +} + +.icon_lists li { + width: 100px; + margin-bottom: 10px; + margin-right: 20px; + text-align: center; + list-style: none !important; + cursor: default; +} + +.icon_lists li .code-name { + line-height: 1.2; +} + +.icon_lists .icon { + display: block; + height: 100px; + line-height: 100px; + font-size: 42px; + margin: 10px auto; + color: #333; + -webkit-transition: font-size 0.25s linear, width 0.25s linear; + -moz-transition: font-size 0.25s linear, width 0.25s linear; + transition: font-size 0.25s linear, width 0.25s linear; +} + +.icon_lists .icon:hover { + font-size: 100px; +} + +.icon_lists .svg-icon { + /* 通过设置 font-size 来改变图标大小 */ + width: 1em; + /* 图标和文字相邻时,垂直对齐 */ + vertical-align: -0.15em; + /* 通过设置 color 来改变 SVG 的颜色/fill */ + fill: currentColor; + /* path 和 stroke 溢出 viewBox 部分在 IE 下会显示 + normalize.css 中也包含这行 */ + overflow: hidden; +} + +.icon_lists li .name, +.icon_lists li .code-name { + color: #666; +} + +/* markdown 样式 */ +.markdown { + color: #666; + font-size: 14px; + line-height: 1.8; +} + +.highlight { + line-height: 1.5; +} + +.markdown img { + vertical-align: middle; + max-width: 100%; +} + +.markdown h1 { + color: #404040; + font-weight: 500; + line-height: 40px; + margin-bottom: 24px; +} + +.markdown h2, +.markdown h3, +.markdown h4, +.markdown h5, +.markdown h6 { + color: #404040; + margin: 1.6em 0 0.6em 0; + font-weight: 500; + clear: both; +} + +.markdown h1 { + font-size: 28px; +} + +.markdown h2 { + font-size: 22px; +} + +.markdown h3 { + font-size: 16px; +} + +.markdown h4 { + font-size: 14px; +} + +.markdown h5 { + font-size: 12px; +} + +.markdown h6 { + font-size: 12px; +} + +.markdown hr { + height: 1px; + border: 0; + background: #e9e9e9; + margin: 16px 0; + clear: both; +} + +.markdown p { + margin: 1em 0; +} + +.markdown>p, +.markdown>blockquote, +.markdown>.highlight, +.markdown>ol, +.markdown>ul { + width: 80%; +} + +.markdown ul>li { + list-style: circle; +} + +.markdown>ul li, +.markdown blockquote ul>li { + margin-left: 20px; + padding-left: 4px; +} + +.markdown>ul li p, +.markdown>ol li p { + margin: 0.6em 0; +} + +.markdown ol>li { + list-style: decimal; +} + +.markdown>ol li, +.markdown blockquote ol>li { + margin-left: 20px; + padding-left: 4px; +} + +.markdown code { + margin: 0 3px; + padding: 0 5px; + background: #eee; + border-radius: 3px; +} + +.markdown strong, +.markdown b { + font-weight: 600; +} + +.markdown>table { + border-collapse: collapse; + border-spacing: 0px; + empty-cells: show; + border: 1px solid #e9e9e9; + width: 95%; + margin-bottom: 24px; +} + +.markdown>table th { + white-space: nowrap; + color: #333; + font-weight: 600; +} + +.markdown>table th, +.markdown>table td { + border: 1px solid #e9e9e9; + padding: 8px 16px; + text-align: left; +} + +.markdown>table th { + background: #F7F7F7; +} + +.markdown blockquote { + font-size: 90%; + color: #999; + border-left: 4px solid #e9e9e9; + padding-left: 0.8em; + margin: 1em 0; +} + +.markdown blockquote p { + margin: 0; +} + +.markdown .anchor { + opacity: 0; + transition: opacity 0.3s ease; + margin-left: 8px; +} + +.markdown .waiting { + color: #ccc; +} + +.markdown h1:hover .anchor, +.markdown h2:hover .anchor, +.markdown h3:hover .anchor, +.markdown h4:hover .anchor, +.markdown h5:hover .anchor, +.markdown h6:hover .anchor { + opacity: 1; + display: inline-block; +} + +.markdown>br, +.markdown>p>br { + clear: both; +} + + +.hljs { + display: block; + background: white; + padding: 0.5em; + color: #333333; + overflow-x: auto; +} + +.hljs-comment, +.hljs-meta { + color: #969896; +} + +.hljs-string, +.hljs-variable, +.hljs-template-variable, +.hljs-strong, +.hljs-emphasis, +.hljs-quote { + color: #df5000; +} + +.hljs-keyword, +.hljs-selector-tag, +.hljs-type { + color: #a71d5d; +} + +.hljs-literal, +.hljs-symbol, +.hljs-bullet, +.hljs-attribute { + color: #0086b3; +} + +.hljs-section, +.hljs-name { + color: #63a35c; +} + +.hljs-tag { + color: #333333; +} + +.hljs-title, +.hljs-attr, +.hljs-selector-id, +.hljs-selector-class, +.hljs-selector-attr, +.hljs-selector-pseudo { + color: #795da3; +} + +.hljs-addition { + color: #55a532; + background-color: #eaffea; +} + +.hljs-deletion { + color: #bd2c00; + background-color: #ffecec; +} + +.hljs-link { + text-decoration: underline; +} + +/* 代码高亮 */ +/* PrismJS 1.15.0 +https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript */ +/** + * prism.js default theme for JavaScript, CSS and HTML + * Based on dabblet (http://dabblet.com) + * @author Lea Verou + */ +code[class*="language-"], +pre[class*="language-"] { + color: black; + background: none; + text-shadow: 0 1px white; + font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; + text-align: left; + white-space: pre; + word-spacing: normal; + word-break: normal; + word-wrap: normal; + line-height: 1.5; + + -moz-tab-size: 4; + -o-tab-size: 4; + tab-size: 4; + + -webkit-hyphens: none; + -moz-hyphens: none; + -ms-hyphens: none; + hyphens: none; +} + +pre[class*="language-"]::-moz-selection, +pre[class*="language-"] ::-moz-selection, +code[class*="language-"]::-moz-selection, +code[class*="language-"] ::-moz-selection { + text-shadow: none; + background: #b3d4fc; +} + +pre[class*="language-"]::selection, +pre[class*="language-"] ::selection, +code[class*="language-"]::selection, +code[class*="language-"] ::selection { + text-shadow: none; + background: #b3d4fc; +} + +@media print { + + code[class*="language-"], + pre[class*="language-"] { + text-shadow: none; + } +} + +/* Code blocks */ +pre[class*="language-"] { + padding: 1em; + margin: .5em 0; + overflow: auto; +} + +:not(pre)>code[class*="language-"], +pre[class*="language-"] { + background: #f5f2f0; +} + +/* Inline code */ +:not(pre)>code[class*="language-"] { + padding: .1em; + border-radius: .3em; + white-space: normal; +} + +.token.comment, +.token.prolog, +.token.doctype, +.token.cdata { + color: slategray; +} + +.token.punctuation { + color: #999; +} + +.namespace { + opacity: .7; +} + +.token.property, +.token.tag, +.token.boolean, +.token.number, +.token.constant, +.token.symbol, +.token.deleted { + color: #905; +} + +.token.selector, +.token.attr-name, +.token.string, +.token.char, +.token.builtin, +.token.inserted { + color: #690; +} + +.token.operator, +.token.entity, +.token.url, +.language-css .token.string, +.style .token.string { + color: #9a6e3a; + background: hsla(0, 0%, 100%, .5); +} + +.token.atrule, +.token.attr-value, +.token.keyword { + color: #07a; +} + +.token.function, +.token.class-name { + color: #DD4A68; +} + +.token.regex, +.token.important, +.token.variable { + color: #e90; +} + +.token.important, +.token.bold { + font-weight: bold; +} + +.token.italic { + font-style: italic; +} + +.token.entity { + cursor: help; +} diff --git a/public/css/iconfont_color/iconfont.css b/public/css/iconfont_color/iconfont.css new file mode 100644 index 000000000..70fe14c36 --- /dev/null +++ b/public/css/iconfont_color/iconfont.css @@ -0,0 +1,101 @@ +@font-face { + font-family: "iconfont-color"; /* Project id 5169666 */ + /* Color fonts */ + src: + url('iconfont.woff2?t=1778741571506') format('woff2'), + url('iconfont.woff?t=1778741571506') format('woff'), + url('iconfont.ttf?t=1778741571506') format('truetype'); +} + +.iconfont-color { + font-family: "iconfont-color" !important; + font-size: 16px; + font-style: normal; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.icon-colorqita:before { + content: "\e7b3"; +} + +.icon-coloryidongkaifa:before { + content: "\e7b4"; +} + +.icon-colordaimazhijian:before { + content: "\e7b5"; +} + +.icon-coloryunxiaogongju:before { + content: "\e7b6"; +} + +.icon-coloryouxiyule:before { + content: "\e7b7"; +} + +.icon-colorskill:before { + content: "\e7b0"; +} + +.icon-colorshujuji:before { + content: "\e7b1"; +} + +.icon-colordaimaku1:before { + content: "\e7b2"; +} + +.icon-colormoxingku:before { + content: "\e7af"; +} + +.icon-coloryinpin:before { + content: "\e7ad"; +} + +.icon-colorremenmoxing-1:before { + content: "\e7a3"; +} + +.icon-colorkexueyanjiuhejishufuwuye:before { + content: "\e7ae"; +} + +.icon-colora-zu18210:before { + content: "\e7a6"; +} + +.icon-colora-zu18240:before { + content: "\e7a5"; +} + +.icon-colora-zuixin1:before { + content: "\e7a7"; +} + +.icon-colorziranyuyanchuli:before { + content: "\e7a8"; +} + +.icon-colorshichangtuiguang-01:before { + content: "\e7a4"; +} + +.icon-coloryuyin:before { + content: "\e7a9"; +} + +.icon-colortuxiang:before { + content: "\e7aa"; +} + +.icon-colora-zu18213:before { + content: "\e7ab"; +} + +.icon-colorshipinbofang:before { + content: "\e7ac"; +} + diff --git a/public/css/iconfont_color/iconfont.js b/public/css/iconfont_color/iconfont.js new file mode 100644 index 000000000..dc7470a27 --- /dev/null +++ b/public/css/iconfont_color/iconfont.js @@ -0,0 +1 @@ +window._iconfont_svg_string_5169666='',(h=>{var a=(l=(l=document.getElementsByTagName("script"))[l.length-1]).getAttribute("data-injectcss"),l=l.getAttribute("data-disable-injectsvg");if(!l){var t,i,o,e,v,c=function(a,l){l.parentNode.insertBefore(a,l)};if(a&&!h.__iconfont__svg__cssinject__){h.__iconfont__svg__cssinject__=!0;try{document.write("")}catch(a){console&&console.log(a)}}t=function(){var a,l=document.createElement("div");l.innerHTML=h._iconfont_svg_string_5169666,(l=l.getElementsByTagName("svg")[0])&&(l.setAttribute("aria-hidden","true"),l.style.position="absolute",l.style.width=0,l.style.height=0,l.style.overflow="hidden",l=l,(a=document.body).firstChild?c(l,a.firstChild):a.appendChild(l))},document.addEventListener?~["complete","loaded","interactive"].indexOf(document.readyState)?setTimeout(t,0):(i=function(){document.removeEventListener("DOMContentLoaded",i,!1),t()},document.addEventListener("DOMContentLoaded",i,!1)):document.attachEvent&&(o=t,e=h.document,v=!1,d(),e.onreadystatechange=function(){"complete"==e.readyState&&(e.onreadystatechange=null,n())})}function n(){v||(v=!0,o())}function d(){try{e.documentElement.doScroll("left")}catch(a){return void setTimeout(d,50)}n()}})(window); \ No newline at end of file diff --git a/public/css/iconfont_color/iconfont.json b/public/css/iconfont_color/iconfont.json new file mode 100644 index 000000000..582f7504b --- /dev/null +++ b/public/css/iconfont_color/iconfont.json @@ -0,0 +1,156 @@ +{ + "id": "5169666", + "name": "newForge-color", + "font_family": "iconfont-color", + "css_prefix_text": "icon-color", + "description": "gitlink/红山开源 带颜色的icon", + "glyphs": [ + { + "icon_id": "47487873", + "name": "其他", + "font_class": "qita", + "unicode": "e7b3", + "unicode_decimal": 59315 + }, + { + "icon_id": "47487872", + "name": "移动开发", + "font_class": "yidongkaifa", + "unicode": "e7b4", + "unicode_decimal": 59316 + }, + { + "icon_id": "47487870", + "name": "代码质检", + "font_class": "daimazhijian", + "unicode": "e7b5", + "unicode_decimal": 59317 + }, + { + "icon_id": "47487871", + "name": "云效工具", + "font_class": "yunxiaogongju", + "unicode": "e7b6", + "unicode_decimal": 59318 + }, + { + "icon_id": "47487869", + "name": "游戏娱乐", + "font_class": "youxiyule", + "unicode": "e7b7", + "unicode_decimal": 59319 + }, + { + "icon_id": "47487614", + "name": "skill", + "font_class": "skill", + "unicode": "e7b0", + "unicode_decimal": 59312 + }, + { + "icon_id": "47487615", + "name": "数据集", + "font_class": "shujuji", + "unicode": "e7b1", + "unicode_decimal": 59313 + }, + { + "icon_id": "47487613", + "name": "代码库", + "font_class": "daimaku1", + "unicode": "e7b2", + "unicode_decimal": 59314 + }, + { + "icon_id": "47487578", + "name": "模型库", + "font_class": "moxingku", + "unicode": "e7af", + "unicode_decimal": 59311 + }, + { + "icon_id": "47470053", + "name": "音频", + "font_class": "yinpin", + "unicode": "e7ad", + "unicode_decimal": 59309 + }, + { + "icon_id": "47470038", + "name": "热门模型-1", + "font_class": "remenmoxing-1", + "unicode": "e7a3", + "unicode_decimal": 59299 + }, + { + "icon_id": "47470036", + "name": "科学研究和技术服务业", + "font_class": "kexueyanjiuhejishufuwuye", + "unicode": "e7ae", + "unicode_decimal": 59310 + }, + { + "icon_id": "47470068", + "name": "组 18210", + "font_class": "a-zu18210", + "unicode": "e7a6", + "unicode_decimal": 59302 + }, + { + "icon_id": "47470067", + "name": "组 18240", + "font_class": "a-zu18240", + "unicode": "e7a5", + "unicode_decimal": 59301 + }, + { + "icon_id": "47470066", + "name": "最新 (1)", + "font_class": "a-zuixin1", + "unicode": "e7a7", + "unicode_decimal": 59303 + }, + { + "icon_id": "47470060", + "name": "自然语言处理", + "font_class": "ziranyuyanchuli", + "unicode": "e7a8", + "unicode_decimal": 59304 + }, + { + "icon_id": "47470052", + "name": "市场推广-01", + "font_class": "shichangtuiguang-01", + "unicode": "e7a4", + "unicode_decimal": 59300 + }, + { + "icon_id": "47470056", + "name": "语音", + "font_class": "yuyin", + "unicode": "e7a9", + "unicode_decimal": 59305 + }, + { + "icon_id": "47470055", + "name": "图像", + "font_class": "tuxiang", + "unicode": "e7aa", + "unicode_decimal": 59306 + }, + { + "icon_id": "47470057", + "name": "组 18213", + "font_class": "a-zu18213", + "unicode": "e7ab", + "unicode_decimal": 59307 + }, + { + "icon_id": "47470047", + "name": "视频播放", + "font_class": "shipinbofang", + "unicode": "e7ac", + "unicode_decimal": 59308 + } + ] +} diff --git a/public/css/iconfont_color/iconfont.ttf b/public/css/iconfont_color/iconfont.ttf new file mode 100644 index 000000000..fce36b9b2 Binary files /dev/null and b/public/css/iconfont_color/iconfont.ttf differ diff --git a/public/css/iconfont_color/iconfont.woff b/public/css/iconfont_color/iconfont.woff new file mode 100644 index 000000000..2303881be Binary files /dev/null and b/public/css/iconfont_color/iconfont.woff differ diff --git a/public/css/iconfont_color/iconfont.woff2 b/public/css/iconfont_color/iconfont.woff2 new file mode 100644 index 000000000..4af8dc443 Binary files /dev/null and b/public/css/iconfont_color/iconfont.woff2 differ diff --git a/public/index.html b/public/index.html index 01d00e5db..66a1920de 100755 --- a/public/index.html +++ b/public/index.html @@ -42,6 +42,7 @@ + diff --git a/src/App.css b/src/App.css index 919ca1414..ffcc59fd7 100644 --- a/src/App.css +++ b/src/App.css @@ -167,6 +167,38 @@ body { opacity: 0.4; } +.mt-10{ + margin-top: -10px; +} + +.df-center-between{ + display: flex; + justify-content: space-between; + align-items: center; +} + +.df-center{ + display: flex; + align-items: center; +} + +.df-between{ + display: flex; + justify-content: space-between; +} + +.df-start{ + display: flex; + align-items: flex-start; +} + +.grid-item-top { + display: grid; + align-items: center; + grid-template-columns: max-content 1fr; + align-items: flex-start; +} + @media screen and (max-width: 1366px) { body{ zoom: 0.75; diff --git a/src/App.js b/src/App.js index 3362b6e76..03a707459 100644 --- a/src/App.js +++ b/src/App.js @@ -246,8 +246,13 @@ const News = Loadable({ loading: Loading, }); +const AI = Loadable({ + loader: () => import("./ai"), + loading: Loading, +}); + // 此处仅维护前端可能的一级路由,不用进行项目或者组织判断的字段。 -const keyWord = ["explore", "settings", "setting", "mulan", "wiki", "issues", "setting", "trending", "code", "projects", "pulls", "mine", "login", "register", "email", "export", "nopage", "404", "403", "500", "501", "search", "organize", "login", "register", "resetPassword", "aboutus","educoder", "glcc","bindlogin", "softbot","zone", "hiagent","sf", "development", "governance", "forums", "news", "exploreStore", "factory", "zoneAdmin"]; +const keyWord = ["explore", "settings", "setting", "mulan", "wiki", "issues", "setting", "trending", "code", "projects", "pulls", "mine", "login", "register", "email", "export", "nopage", "404", "403", "500", "501", "search", "organize", "login", "register", "resetPassword", "aboutus","educoder", "glcc","bindlogin", "softbot","zone", "hiagent","sf", "development", "governance", "forums", "news", "exploreStore", "factory", "zoneAdmin", "ai"]; class App extends Component { constructor(props) { @@ -432,6 +437,11 @@ class App extends Component { { pathType ? + () + } + > {/* 社区动态页面 */} { + return { + const deleteFn = type === "codes" ? deleteProjectInZoneById : deleteSourceById; + deleteFn(id, roleByZone).then(res=>{ + if(res && res.data && res.data.code === 200){ + message.success(`操作成功`); + cancel(); + reload(Math.random()); + } + }) + }}> +
+ + 确定删除资源吗? +
该操作不可恢复,请确认后再操作
+
+
+} + +export const TakeDownModal = ({id, cancel, roleByZone, reload}) =>{ + return { + takeDownSourceById(id, roleByZone).then(res=>{ + if(res && res.data && res.data.code === 200){ + message.success(`操作成功`); + cancel(); + reload(Math.random()); + } + }) + }}> +
+ + 确定下架资源吗? +
下架后AI资源广场将隐藏该资源,但可重新申请上架
+
+
+} \ No newline at end of file diff --git a/src/ai/create/index.jsx b/src/ai/create/index.jsx new file mode 100644 index 000000000..39b4bf642 --- /dev/null +++ b/src/ai/create/index.jsx @@ -0,0 +1,475 @@ +import React, { useState, useEffect, Fragment } from "react"; +import { Input, Select, Upload, message, Form, Checkbox, Tree, Spin } from "antd"; +import './index.scss'; +import { aiCreateSteps, aiResouceType, aiResouceTypeKey, convertToTreeData } from "../static"; +import { Link } from "react-router-dom"; +import { AlignCenter } from "../../forge/Component/layout"; +import DorpChooseMenus from "../../forge/Component/licenseModal/dorpChooseMenus"; +import axios from "axios"; +import { addProjectInZone, addSkill, editSkill, getProjectsTypeLists, getSkillById, getSourceZoneList, parseFileBySkill } from "../../forge/Information/api"; +const { Option } = Select; + +function CreateResource(props) { + const { match: { params }, form, current_user, history, aiZoneInfo, roleByZone } = props || {}; + const { getFieldDecorator, getFieldsValue, setFieldsValue, validateFields } = form; + const type = params.type || aiResouceType[0].key; + const sourceId = params.id; //资源id,编辑状态不允许筛选一级分类 + const { user_id } = current_user || {} + const { id: aiZoneId } = aiZoneInfo || {} + + const [loading, setLoading] = useState(false); + const [resourceType, setResourceType] = useState("models"); + const [currentStep, setCurrentStep] = useState(0); + const [categoryList, setCategoryList] = useState(); + const [languageList, setLanguageList] = useState(); + const [gitignoreList, setGitignoreList] = useState(); + const [licensesList, setLicensesList] = useState(); + const [ownerList, setOwnerList] = useState(); + const [cate, setCate] = useState(); + const [info, setInfo] = useState(); + + const typeDetail = type && aiResouceType.find(i => i.key === type); + const { ignoreFlag, licenseFlag, categoreFlag, languageFlag, file } = getFieldsValue(); + const { file: fileByupload } = file || {} + const { response: responseByupload } = fileByupload || {} + const { fileTreeJson } = responseByupload || {} + + const skillTreeData = fileTreeJson && convertToTreeData(JSON.parse(fileTreeJson).children) + + // 自动滚动动画:每 5 秒切换到下一步 + useEffect(() => { + document.title = `发布新资源`; + const timer = setInterval(() => { + setCurrentStep((prev) => (prev + 1) % aiCreateSteps.length); + }, 5000); + + return () => clearInterval(timer); + }, []); + + useEffect(() => { + switch (type) { + case "codes": + axios.get(`/owners.json`).then(result => { + if (result && result.data && result.data.owners) { + setOwnerList(result.data.owners) + const owner = result.data.owners.filter(item => item.id === user_id); + owner[0] && setTimeout(() => { + setFieldsValue({ + user_id: owner[0].id + }) + }, 500); + } + }) + axios.get(`/project_categories.json`).then((result) => { + if (result && result.data) { + setCategoryList(result.data.project_categories) + } + }) + axios.get(`/project_languages.json`).then((result) => { + if (result && result.data) { + setLanguageList(result.data.project_languages) + } + }) + axios.get(`/ignores.json`).then((result) => { + if (result && result.data) { + setGitignoreList(result.data.ignores) + } + }) + axios.get(`/licenses.json`).then((result) => { + if (result && result.data) { + setLicensesList(result.data.licenses) + } + }) + aiZoneId && getProjectsTypeLists(aiZoneId).then(res => { + if (res && res.data && res.data.rows) { + setCate(res.data.rows) + } + }) + break; + default: + aiZoneId && getSourceZoneList(aiZoneId, { + domainCategory: aiResouceTypeKey[type] + }).then(res => { + if (res && res.data && res.data.rows) { + setCate(res.data.rows) + } + }) + break; + } + }, [type, aiZoneId]) + + useEffect(() => { + if (sourceId) { + getSkillById(sourceId).then(res => { + if (res && res.data && res.data.code === 200) { + const { fileIds, extendData, name, summary, domainId } = res.data.data || {} + setFieldsValue({ + file: { + file: { + response: { + fileId: fileIds, + skillMdContent: extendData.skill.content, + fileTreeJson: JSON.stringify(extendData.skill.fileTree) + } + } + }, + name, + summary, + domainId + }) + } + }) + } + }, [sourceId]) + + // 上传处理 + const beforeUpload = (file, size = 10) => { + const limitSize = file.size / 1024 / 1024 < size; + if (!limitSize) { + message.error(`文件大小必须小于${size}MB!`); + } + return limitSize; + }; + + function submit() { + const compelete = (response) => { + if (response && response.data && response.data.code === 200) { + message.success("操作成功"); + // ${type === "codes" ? '' : "/" + sourceId || response.data.data.id} + history.push(`/ai/${type}`); + } + } + validateFields((err, values) => { + if (!err) { + switch (type) { + case "codes": + axios.post(`/projects.json`, { + ...values, + ...info, + }).then(res => { + if (res && res.data && res.data.id) { + // 关联项目到专区 + addProjectInZone([{ + gitlinkProjectId: res.data.id, + projectTypeId: values.projectTypeId, + zoneId: aiZoneId + }]).then(response => { compelete(response) }) + } + }) + break; + case "skills": + const { fileId, skillMdContent } = responseByupload + const submitFn = sourceId ? editSkill : addSkill; + const param = { + ...values, + fileId, + fileTreeJson, + skillContent: skillMdContent, + zoneId: aiZoneId + } + !!sourceId && (param.id = sourceId) + submitFn(param, roleByZone).then(response => { compelete(response) }) + break; + default: + break; + } + } + }) + } + + const codeCheckBox = (checkKey, checkName, value, selectKey, list) => { + return + + {getFieldDecorator(checkKey)( + {checkName} + )} + + {value && + {getFieldDecorator(selectKey, { + rules: [{ + required: value, message: `请选择${checkName}` + }], + })( + { + const value2 = {} + value2[selectKey] = value.name; + setFieldsValue(value2); + const value1 = { ...info } + value1[selectKey + "_id"] = value.id; + setInfo(value1) + }} /> + )} + + } + + } + + return ( +
+ {/* 顶部导航 */} +
+
+ 发布 + 新资源 + 全新智算共享 +
+
+ 将您的模型、数据集、skill或代码库分享给社区 +
+
+ {aiResouceType.map((item) => ( + { + if (!!sourceId) { + e.preventDefault(); + e.stopPropagation(); + } + }} + > + +
{item.name}
+
{item.intro}
+ + ))} +
+
+ + {/* 主体内容 */} +
+
+
如何开始?
+
+ {aiCreateSteps.map((step, index) => ( +
+
{index + 1}
+
+
{step.title}
+
{step.description}
+
+ {index < aiCreateSteps.length - 1 && ( +
+ )} +
+ ))} +
+
+
+
+
基本信息
+
{typeDetail.createIntro}
+
+
+ {type === "codes" ? + + + {getFieldDecorator('user_id', { + rules: [{ + required: true, message: '请选择拥有者' + }], + })( + + )} + + / + + {getFieldDecorator('name', { + rules: [{ + required: true, message: '请填写项目名称' + }], + })( + // onBlur={this.changeName} + )} + + + 项目标识 (项目url标识部分)} + > + {getFieldDecorator('repository_name', { + rules: [{ + required: true, message: '请填写项目标识' + }], + })( + + )} + + + {getFieldDecorator('projectTypeId', { + rules: [{ + required: true, message: '请选择项目分类' + }], + })( + + )} + + + {getFieldDecorator('description', { + rules: [], + })( + + )} + + {codeCheckBox("ignoreFlag", ".gitignore", ignoreFlag, "ignore", gitignoreList)} + {codeCheckBox("licenseFlag", "开源许可证", licenseFlag, "license", licensesList)} + + {getFieldDecorator('private')( + 将项目设为私有(只有项目所有人或拥有权限的项目成员才能看到) + )} + + {codeCheckBox("categoreFlag", "项目类别", categoreFlag, "project_category", categoryList)} + {codeCheckBox("languageFlag", "项目语言", languageFlag, "project_language", languageList)} + : + + {getFieldDecorator('file', { + rules: [{ required: true, message: "请上传文件" }], + })( + fileByupload ? + + + : beforeUpload(file, 10)} + showUploadList={false} + customRequest={(options) => { + const { file, onSuccess } = options; + const form = new FormData(); + form.append('file', file); + setLoading(true); + parseFileBySkill(form, roleByZone).then((response) => { + if (response && response.data && response.data.code === 200) { + onSuccess(response.data.data) + const { summary, name } = response.data.data; + setFieldsValue({ + summary, + name + }) + } + }).finally(() => { + setLoading(false); + }) + }} + > +
+ + + +
请上传您的{typeDetail.name}文件(.zip)
+
请确保压缩包中包含SKILL.md,大小限制 10MB
+
+
+ )} +
+ + {getFieldDecorator('name', { + rules: [{ + required: true, message: '请填写资源名称' + }], + })( + + )} + + + {getFieldDecorator('summary', { + rules: [{ + required: true, message: '请填写简介内容' + }], + })( + + )} + + {/* 资源类型 */} + + {getFieldDecorator('domainId', { + rules: [{ + required: true, message: '请选择模型类别' + }], + })( + + )} + + +
} + + {/* 提交按钮 */} + + 提 交 + 取 消 + +
+
+
+
+ ); +} + +export default Form.create()(CreateResource); diff --git a/src/ai/create/index.scss b/src/ai/create/index.scss new file mode 100644 index 000000000..787e254a2 --- /dev/null +++ b/src/ai/create/index.scss @@ -0,0 +1,175 @@ +.ai_create_page { + background: #f8f9fc url('../image/bk2.png'); + background-repeat: no-repeat; + background-size: 100% auto; + + .ai_create_banner_tabs { + justify-content: center; + gap: 36px; + + .ai_create_banner_tab { + background: linear-gradient(87.55deg, #eef3fd 3.07%, #ffffff 98.94%); + border: 1px solid rgba(22, 76, 228, 0.1); + border-radius: 12px; + padding: 34px 92px; + + &:nth-child(4n+2) { + background: linear-gradient(87.55deg, #fdf5fd 3.07%, #ffffff 98.94%); + } + + &:nth-child(4n+3) { + background: linear-gradient(87.55deg, #eef3fd 3.07%, #ffffff 98.94%); + } + + &:nth-child(4n) { + background: linear-gradient(87.55deg, #ececff 3.07%, #f8f9fd 98.94%); + } + + &.active { + background-image: url('../image/card_bk2.png'); + background-size: 100% 100%; + border-color: white; + + &, + & .color3f4 { + color: white; + } + } + + &:hover:not(.active):not(.disabled) { + transition: all 0.3s ease; + transform: translateY(-10px); + border-color: #164ce4; + } + + &:not(.active), + &:not(.active):hover, + &:not(.active):focus { + color: inherit; + } + } + } + + // 工具类 + .mb30 { + margin-bottom: 30px; + } + + .mb40 { + margin-bottom: 40px; + } + + .mb5 { + margin-bottom: 5px; + } + + .mb8 { + margin-bottom: 8px; + } + + .ml10 { + margin-left: 10px; + } + + .mr20 { + margin-right: 20px; + } + + .mt40 { + margin-top: 40px; + } + + // 主体内容 + .ai_create_content { + padding: 68px 0; + } + + // 步骤引导组件样式 + .ai_create_content_left { + flex: 0 0 380px; + margin-right: 30px; + background: #ffffff; + border: 1px solid rgba(22, 76, 228, 0.1); + border-radius: 12px; + padding: 30px 35px; + + .steps-container { + .step-number { + width: 36px; + height: 36px; + border-radius: 50%; + background: #eef4fe; + border: 2px solid rgba(22, 76, 228, 0.1); + line-height: 36px; + text-align: center; + color: #aebbd0; + font-size: 16px; + font-family: "DouyinSansBold"; + position: relative; + } + } + + .step-item.active { + .step-number { + background-image: url('../image/icon4.png'); + background-size: 100% 100%; + color: white; + border: none; + } + } + + .step-item:not(:last-of-type) { + .step-number::before { + content: ''; + position: absolute; + top: 50px; + left: 15px; + width: 0px; + height: 58px; + border-left: 1px dashed rgba(174, 187, 208, 0.7); + } + } + } + + .ai_create_form_wrapper { + background: #ffffff; + border: 1px solid rgba(22, 76, 228, 0.1); + border-radius: 12px; + padding: 55px 60px; + } + + .btn-black, + .btn-outline { + font-size: 15px; + padding: 11px 54px; + border-radius: 10px; + } + + .ai_form { + width: 68.5%; + + .ant-upload.ant-upload-select { + width: 100%; + } + } + + .ai_create_upload { + padding: 30px 0; + border: 1px dashed rgba(22, 76, 228, 0.17); + border-radius: 6px; + + .ai_create_upload_icon { + display: inline-block; + width: 45px; + height: 45px; + background: #f3f4f8; + border-radius: 50%; + line-height: 45px; + } + } + .ai_tree_file{ + border: 1px solid #D9D9D9; + border-radius: 6px; + padding: 5px 10px; + } +} \ No newline at end of file diff --git a/src/ai/detail/index.jsx b/src/ai/detail/index.jsx new file mode 100644 index 000000000..0914038f4 --- /dev/null +++ b/src/ai/detail/index.jsx @@ -0,0 +1,314 @@ +import React, { useState, useEffect } from "react"; +import { Tabs, Tag, Spin, message, Divider, Tree, Tooltip } from "antd"; +import axios from "axios"; +import RenderHtml from "../../components/render-html"; +import "./index.scss"; +import { getlikedSource, getSkillById, likeAISource } from "../../forge/Information/api"; +import { convertToTreeData } from "../static"; +import skillIcon from '../image/icon7.png'; +import CommentsList from "../../components/commentsByZone"; + +const { TabPane } = Tabs; + +function Detail(props) { + // 路由参数 + const { history, match: { params }, current_user: { login }, current_user, showLoginDialog, showNotification } = props; + const { id } = params || {}; + + // 状态管理 + const [reload, setReload] = useState(undefined); + const [detail, setDetail] = useState({}); + const [files, setFiles] = useState(undefined); + const [comments, setComments] = useState(undefined); + const [loading, setLoading] = useState(true); + const [activeTab, setActiveTab] = useState("introduction"); + const [branch, setBranch] = useState("master"); + const [liked, setLiked] = useState(false); + + const { extendData: { skill: { content, fileTree } = {} } = {} } = detail; + + const skillTreeData = fileTree && convertToTreeData(fileTree.children) + const skillContent = String(content).replace(/^---\r?\n[\s\S]*?\r?\n---\r?\n/, ''); + + // 组件挂载和 ID 变化时加载数据 + useEffect(() => { + document.title = "AI资源"; + setLoading(true); + getDetail() + getIsLikedSource() + }, [id, reload]); // 依赖 id,当 id 变化时重新加载 + + + const getDetail = () => { + id && getSkillById(id).then(response => { + if (response && response.data && response.data.code === 200) { + const { name } = response.data.data + document.title = `${name}-AI资源`; + setDetail(response.data.data); + setLoading(false); + } + }) + } + + const getIsLikedSource = () => { + id && getlikedSource(id).then(response => { + if (response && response.data && response.data.code === 200) { + const { isLike } = response.data.rows[0] || {}; + setLiked(isLike); + } + }) + } + + // 处理分支切换 + const handleBranchChange = (value) => { + setBranch(value); + // 重新获取文件列表 + axios.get(`/api/ai/models/${id}/files.json`, { params: { branch: value } }) + .then(res => { + if (res && res.data) { + setFiles(res.data); + } + }) + .catch(error => { + console.error(error); + }); + }; + + // 格式化下载量 + const formatDownloads = (num) => { + if (num >= 10000) { + return (num / 10000).toFixed(1) + "万"; + } + return num; + }; + + // 格式化文件大小 + const formatFileSize = (size) => { + if (!size) return "0KB"; + const num = parseFloat(size); + if (isNaN(num)) return size; + if (num >= 1024) { + return (num / 1024).toFixed(2) + "MB"; + } + return Math.round(num) + "KB"; + }; + + if (loading) { + return ( +
+ +
+ ); + } + + if (!detail) { + return ( +
+
暂无数据
+
+ ); + } + + return ( +
+ {/* 顶部信息卡片 */} +
+
+
+ +
+
+
+
{detail.name}
+
{detail.summary || "暂无简介"}
+
+ {detail.tags && detail.tags.map((tag, index) => ( + + {tag} + + ))} + {detail.license && ( + + 开源协议:{detail.license} + + )} + {detail.domainName && ( + + {detail.domainName} + + )} +
+
+ +
+
+ +
+ + {detail.createUser && detail.createUser.userName || "未知作者"} + + + {moment(detail.updateTime).format('YYYY.MM.DD')} + + + {formatDownloads(detail.downloadCount)} + + + { + if (!login) { + showLoginDialog() + } + likeAISource(id).then(res => { + if (res && res.data && res.data.code === 200) { + message.success("操作成功") + getDetail(); + getIsLikedSource(); + } + }) + }}> + + {detail.likeCount} +
+
+
+
+
+
+ + {/* Tab 导航 */} +
+ setActiveTab(tab)} + centered + > + + + + +
+ +
+ {activeTab === "introduction" && ( +
+
+ {skillContent ? ( + + ) : ( +
暂无 README 内容
+ )} +
+
+ )} + + {activeTab === "files" && ( +
+ + {/*
+ + + {files?.lastCommit && ( +
+ + {files.lastCommit.message || "暂无提交信息"} + + + {files.lastCommit.author || "unknown"} + + + {files.lastCommit.sha?.substring(0, 7) || "unknown"} + + + {files.lastCommit.time || "刚刚"} + +
+ )} + +
+ {files?.commitCount || 0} 次提交 +
+
+ +
+ {files?.files && files.files.length > 0 ? ( + files.files.map((file, index) => ( +
+
+ + {file.name} + + {formatFileSize(file.size)} + +
+
+ + {file.lastMessage || "暂无信息"} + + + {timeAgo(file.updateTime || new Date())} + +
+ +
+ )) + ) : ( +
暂无文件
+ )} +
*/} +
+ )} + + {activeTab === "comments" && ( +
+ +
+ )} +
+
+ ); +} + +export default Detail; diff --git a/src/ai/detail/index.scss b/src/ai/detail/index.scss new file mode 100644 index 000000000..c1b8735c9 --- /dev/null +++ b/src/ai/detail/index.scss @@ -0,0 +1,348 @@ +.ai_detail_page { + background: #f8f9fc url('../image/bk2.png'); + background-repeat: no-repeat; + background-size: 100% auto; + padding-top: 45px; + padding-bottom: 50px; +} + +// 加载状态 +.ai_detail_loading, +.ai_detail_nodata { + display: flex; + align-items: center; + justify-content: center; + min-height: 500px; +} + +.ai_detail_nodata_text { + color: #76849b; + font-size: 14px; +} + +// 顶部信息卡片 +.ai_detail_header { + background-image: url('../image/bk3.png'); + background-size: 100% 100%; + padding: 14px 13px; + border-radius: 6px; + + .ai_detail_header_inner { + background: linear-gradient(90.39deg, #ffffff 1.15%, #ebf1ff 18.37%, #f4f3fd 98.25%); + border-radius: 6px; + padding: 30px; + + .btn-black, .btn-outline { + padding: 7px 32px; + border-radius:10px; + } + .btn-black{ + border: 1px solid #091221; + } + + .ai_detail_header_tag{ + color: #091221; + border-color:#d3e1fd; + background:#f5f9fd; + padding: 6px 16px 5px 16px; + font-size: 13px; + } + .likeBtn{ + color: inherit; + &:hover{ + color:#164ce4; + } + } + } +} + +.ai_detail_tabs { + .ant-tabs-bar { + border-bottom: none; + } + + .ant-tabs-ink-bar { + background: #164ce4; + border-radius: 10px; + height: 3px; + width: 20px !important; + left: 20px; + } + + .ant-tabs-tab { + padding: 12px 0px; + font-size: 15px; + color: #091221; + margin-right: 52px; + + &:hover { + color: #164ce4; + } + + &.ant-tabs-tab-active { + color: #164ce4; + font-weight: 600; + } + } +} + +// Tab 内容 +.ai_detail_tab_panel { + background: #ffffff; + border: 1px solid rgba(22, 76, 228, 0.1); + border-radius: 12px; + padding: 30px; + min-height: 365px; + + // 模型介绍 + // .ai_detail_readme { + // .markdown-body { + + // h1, + // h2, + // h3, + // h4, + // h5, + // h6 { + // color: #091221; + // margin-top: 24px; + // margin-bottom: 16px; + // font-weight: 600; + // line-height: 1.25; + // } + + // h1 { + // font-size: 28px; + // } + + // h2 { + // font-size: 24px; + // } + + // h3 { + // font-size: 20px; + // } + + // h4 { + // font-size: 18px; + // } + + // p { + // font-size: 15px; + // line-height: 1.8; + // color: #333; + // margin: 10px 0; + // } + + // a { + // color: #0e4aef; + // text-decoration: none; + + // &:hover { + // text-decoration: underline; + // } + // } + + // ul, + // ol { + // margin: 15px 0; + // padding-left: 30px; + + // li { + // font-size: 15px; + // line-height: 1.8; + // color: #333; + // } + // } + + // code { + // background: #f5f7fa; + // padding: 2px 6px; + // border-radius: 4px; + // font-family: "Courier New", monospace; + // font-size: 14px; + // color: #d63384; + // } + + // pre { + // background: #282c34; + // padding: 16px; + // border-radius: 8px; + // overflow-x: auto; + + // code { + // background: none; + // padding: 0; + // color: #abb2bf; + // } + // } + + // blockquote { + // border-left: 4px solid #0e4aef; + // padding: 12px 16px; + // margin: 16px 0; + // background: #f5f7fa; + // border-radius: 4px; + + // p { + // margin: 0; + // color: #666; + // } + // } + + // table { + // width: 100%; + // margin: 16px 0; + // border-collapse: collapse; + + // th, + // td { + // padding: 12px 16px; + // border: 1px solid #e1e4e8; + // text-align: left; + // } + + // th { + // background: #f5f7fa; + // font-weight: 600; + // color: #091221; + // } + + // td { + // color: #333; + // } + // } + + // img { + // max-width: 100%; + // height: auto; + // border-radius: 8px; + // margin: 16px 0; + // } + // } + // } + + // 模型文件 + .ai_detail_files_header { + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: 20px; + flex-wrap: wrap; + gap: 15px; + + .ai_detail_branch_select { + .ant-select-selector { + border-radius: 8px; + padding: 8px 12px; + } + } + + .ai_detail_commit_info { + display: flex; + align-items: center; + flex-wrap: wrap; + gap: 10px; + + .ai_detail_commit_message { + color: #091221; + font-size: 14px; + max-width: 400px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + + .ai_detail_commit_author { + color: #667eea; + font-size: 14px; + } + + .ai_detail_commit_sha { + font-family: "Courier New", monospace; + } + + .ai_detail_commit_time { + font-size: 14px; + } + } + + .ai_detail_commit_count { + font-size: 14px; + } + } + + .ai_detail_files_list { + .ai_detail_file_item { + display: flex; + align-items: center; + justify-content: space-between; + padding: 15px 20px; + margin-bottom: 10px; + background: #f8f9fd; + border-radius: 8px; + transition: all 0.3s; + + &:hover { + background: #f1f3ff; + border: 1px solid #667eea; + } + + .ai_detail_file_info { + display: flex; + align-items: center; + + .ai_detail_file_name { + color: #091221; + font-weight: 500; + } + + .ai_detail_file_size { + color: #76849b; + } + } + + .ai_detail_file_meta { + display: flex; + align-items: center; + flex: 1; + margin-right: 20px; + + .ai_detail_file_message { + color: #76849b; + max-width: 300px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + + .ai_detail_file_time { + color: #76849b; + } + } + + .ai_detail_file_download { + color: #0e4aef; + padding: 8px 16px; + border-radius: 6px; + transition: all 0.3s; + + &:hover { + background: #0e4aef; + color: #fff; + } + } + } + } + + // 交流反馈 + &.ai_detail_comments { + --primary-color: #466aff; + --light-color: rgba(70,106,255,0.85); + --more-light-color: rgba(70, 106, 255, 0.05); + --linear-back-color: linear-gradient(89.9deg,rgba(70, 106, 255, 0) 0%,rgba(70, 106, 255, 0.09) 100%); + --tag-back: rgba(70, 106, 255, 0.12); + --light-color-2: rgba(70,106,255,0.23); + --light-color-3: rgba(70,106,255,0.55); + } +} diff --git a/src/ai/image/bk1.png b/src/ai/image/bk1.png new file mode 100644 index 000000000..602386137 Binary files /dev/null and b/src/ai/image/bk1.png differ diff --git a/src/ai/image/bk2.png b/src/ai/image/bk2.png new file mode 100644 index 000000000..b2b8541bc Binary files /dev/null and b/src/ai/image/bk2.png differ diff --git a/src/ai/image/bk3.png b/src/ai/image/bk3.png new file mode 100644 index 000000000..8e35a835f Binary files /dev/null and b/src/ai/image/bk3.png differ diff --git a/src/ai/image/bk4.png b/src/ai/image/bk4.png new file mode 100644 index 000000000..89a1f5de4 Binary files /dev/null and b/src/ai/image/bk4.png differ diff --git a/src/ai/image/bk5.png b/src/ai/image/bk5.png new file mode 100644 index 000000000..ec048efaa Binary files /dev/null and b/src/ai/image/bk5.png differ diff --git a/src/ai/image/card_bk1.png b/src/ai/image/card_bk1.png new file mode 100644 index 000000000..baf4d21a5 Binary files /dev/null and b/src/ai/image/card_bk1.png differ diff --git a/src/ai/image/card_bk2.png b/src/ai/image/card_bk2.png new file mode 100644 index 000000000..078db5bcb Binary files /dev/null and b/src/ai/image/card_bk2.png differ diff --git a/src/ai/image/icon1.png b/src/ai/image/icon1.png new file mode 100644 index 000000000..02177ded8 Binary files /dev/null and b/src/ai/image/icon1.png differ diff --git a/src/ai/image/icon2.png b/src/ai/image/icon2.png new file mode 100644 index 000000000..e4b3f142e Binary files /dev/null and b/src/ai/image/icon2.png differ diff --git a/src/ai/image/icon3.png b/src/ai/image/icon3.png new file mode 100644 index 000000000..600c32f2a Binary files /dev/null and b/src/ai/image/icon3.png differ diff --git a/src/ai/image/icon4.png b/src/ai/image/icon4.png new file mode 100644 index 000000000..3d7226d87 Binary files /dev/null and b/src/ai/image/icon4.png differ diff --git a/src/ai/image/icon5.png b/src/ai/image/icon5.png new file mode 100644 index 000000000..ff32f8f76 Binary files /dev/null and b/src/ai/image/icon5.png differ diff --git a/src/ai/image/icon6.png b/src/ai/image/icon6.png new file mode 100644 index 000000000..81e6871e7 Binary files /dev/null and b/src/ai/image/icon6.png differ diff --git a/src/ai/image/icon7.png b/src/ai/image/icon7.png new file mode 100644 index 000000000..a71468245 Binary files /dev/null and b/src/ai/image/icon7.png differ diff --git a/src/ai/index.jsx b/src/ai/index.jsx new file mode 100644 index 000000000..051e71732 --- /dev/null +++ b/src/ai/index.jsx @@ -0,0 +1,94 @@ +import React, { useEffect, useState } from "react"; +import { ImageLayerOfCommentHOC } from "../modules/page/layers/ImageLayerOfCommentHOC"; +import { Route, Switch, withRouter } from "react-router"; +import { SnackbarHOC } from "educoder"; +import { CNotificationHOC } from "../modules/courses/common/CNotificationHOC"; +import { TPMIndexHOC } from "../modules/tpm/TPMIndexHOC"; +import Loadable from 'react-loadable'; +import Loading from "../Loading"; +import './index.scss'; +import { getCurrentRole, getMainInfos } from "../forge/Information/api"; + +const Detail = Loadable({ + loader: () => import("./detail"), + loading: Loading, +}) +const List = Loadable({ + loader: () => import("./list"), + loading: Loading, +}) +const Create = Loadable({ + loader: () => import("./create"), + loading: Loading, +}) +const MyResources = Loadable({ + loader: () => import("./my-resources"), + loading: Loading, +}) + +function AI(props) { + const { current_user: { login } } = props + + const [aiZoneInfo, setAiZoneInfo] = useState(undefined); + const [roleByZone, setRoleByZone] = useState("Member"); + + useEffect(() => { + getMainInfos("AI").then(res => { + if (res && res.data && res.data.data) { + setAiZoneInfo(res.data.data) + // login && getCurrentRole(res.data.data.id).then(res1 => { + // if (res1 && res1.data && res1.data.data) { } + // setRoleByZone(res1.data.data.role) + // }) + } + }) + + }, []) + + return
+ + ( + + )} + > + ( + + )} + > + ( + + )} + > + ( + + )} + > + ( + + )} + > + ( + + )} + > + +
+} +export default withRouter( + ImageLayerOfCommentHOC({ + imgSelector: ".imageLayerParent img, .imageLayerParent .imageTarget", + parentSelector: ".newMain", + })(CNotificationHOC()(SnackbarHOC()(TPMIndexHOC(AI)))) +); \ No newline at end of file diff --git a/src/ai/index.scss b/src/ai/index.scss new file mode 100644 index 000000000..4c9553714 --- /dev/null +++ b/src/ai/index.scss @@ -0,0 +1,78 @@ +@import url('../animations.scss'); + +.ai_resouce_page { + font-family: "alibabaReg"; + color: #091221; + + .ai_1600 { + width: 1600px; + margin: 0 auto; + } + + .color091 { + color: #091221; + } + + .color768 { + color: #76849b; + } + + .color3f4 { + color: #3f4f69; + } + + .color828 { + color: #8285a5; + } + + .coloraeb{ + color:#aebbd0; + } + + .mlat { + margin-left: auto; + } + + .mrat { + margin-right: auto; + } + + .shrink0{ + flex-shrink: 0 + } + + .ai_banner_title { + font-size: 52px; + font-family: "DouyinSansBold"; + + .carousel_text { + background-image: linear-gradient(0.27deg, #0e4aef 1.35%, #a74eff 87.93%); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; + } + } + + .btn-outline { + border: 1px solid #091221; + border-radius: 22px; + color: #091221; + font-size: 15px; + padding: 11px 20px; + } + + .btn-black { + background: #091221; + border-radius: 9px; + color: #ffffff; + } + + .arrowRight{ + .iconfont { + display: inline-block; + animation: arrow-move 1.2s ease-in-out infinite; + position: relative; + top: 2px; + } + } +} \ No newline at end of file diff --git a/src/ai/list/index.jsx b/src/ai/list/index.jsx new file mode 100644 index 000000000..4125a9c21 --- /dev/null +++ b/src/ai/list/index.jsx @@ -0,0 +1,253 @@ +import { Fragment, useEffect, useState } from "react"; +import './index.scss'; +import { aiResouceType, aiResouceTypeKey, iconByCateIndex, iconByCateName } from "../static"; +import icon1 from '../image/icon1.png'; +import icon2 from '../image/icon2.png'; +import icon3 from '../image/icon3.png'; +import icon5 from '../image/icon5.png'; +import icon6 from '../image/icon6.png'; +import { Divider, Input, Pagination } from "antd"; +import ActionItem from "../../factory/resource/components/ActionItem"; +import { Link } from "react-router-dom"; +import { getProjectsLists, getProjectsTypeLists, getSkillList, getSourceZoneList } from "../../forge/Information/api"; +import moment from "moment"; + +function List(props) { + const { match: { params }, history, aiZoneInfo, current_user } = props || {}; + const type = params.type || aiResouceType[0].key + const [activeCategory, setActiveCategory] = useState(); + const [page, setPage] = useState(1); + const [total, setTotal] = useState(20); + const [cate, setCate] = useState([]); + const [list, setList] = useState(); + const [search, setSearch] = useState(); + const { id: aiZoneId } = aiZoneInfo || {} + const typeDetail = type && aiResouceType.find(i => i.key === type); + + useEffect(() => { + document.title = `AI资源广场`; + }, []); + + useEffect(() => { + setActiveCategory(undefined); + switch (type) { + case "codes": + aiZoneId && getProjectsTypeLists(aiZoneId).then(res => { + if (res && res.data && res.data.rows) { + setCate(res.data.rows); + } + }) + break; + default: + aiZoneId && getSourceZoneList(aiZoneId, { + domainCategory: aiResouceTypeKey[type] + }).then(res => { + if (res && res.data && res.data.rows) { + setCate(res.data.rows); + } + }) + break; + } + }, [type, aiZoneId]) + + useEffect(() => { + switch (type) { + case "codes": + aiZoneId && getProjectsLists(aiZoneId, { + pageNum: page, + pageSize: 10, + projectTypeId: activeCategory, + name: search + }).then(res => { + if (res && res.data && res.data.rows) { + setList(res.data.rows.map(row => { + const { projectProperties, id } = row; + return { + id: id, + name: projectProperties.name, + image: projectProperties.authorImageUrl, + isNew: false, + url: projectProperties.fullName, + desc: projectProperties.description, + date: projectProperties.timeAgo, + forkedCount: projectProperties.forkedCount, + likes: projectProperties.praisesCount, + topics: projectProperties.topics ? projectProperties.topics.split(",") : [] + } + })) + setTotal(res.data.total) + } + }) + break; + case "skills": + getSkillList({ + auditStatus: 1, + domainId: activeCategory, + pageNum: page, + pageSize: 10, + name: search + }).then(res => { + if (res && res.data && res.data.rows) { + setList(res.data.rows.map(row => { + const { name, id, summary, updateTime, downloadCount, likeCount, domainName } = row; + return { + id: id, + name: name, + isNew: false, + desc: summary, + date: moment(updateTime).format('YYYY.MM.DD'), + downloads: downloadCount, + likes: likeCount, + domainName + } + })) + setTotal(res.data.total) + } + }) + default: + break; + } + }, [activeCategory, aiZoneId, page, search, type]) + + const aiCard = (model) => { + return + + {model.date} + + {Object.hasOwn(model, "downloads") && + + {model.downloads} + + } + {Object.hasOwn(model, "forkedCount") && + + {model.forkedCount} + + } + + {model.likes} + + } + + return ( +
+ {/* Banner 区域 */} +
+
+ AI资源广场 + 汇聚无限创意 +
+ + + +
+
+
+ 面向开发者提供可信、合规、高效的 AI 资产分发中心。涵盖百亿级模型权重库、千万量级专业数据集、托管代码仓及
智能skill中心。实现从资源检索、安全审计到业务集成的一体化研发生态。 +
+
+ {aiResouceType.map((item) => ( + + + + {item.name} + + ))} +
+
+ + {/* 主体内容区域 */} +
+ {/* 左侧分类筛选 */} +
+
全部{typeDetail.name}
+
+ {typeDetail.desc} +
+
    +
  • setActiveCategory(undefined)} + > + + 全部 +
  • + {cate.map((category, index) => { + const icons = iconByCateName[category.name] ? iconByCateName[category.name] : (iconByCateIndex[type] && iconByCateIndex[type][index]) || ["iconfont-color icon-colorkexueyanjiuhejishufuwuye", "iconfont icon-a-kexueyanjiuhejishufuwuye-1"] + return
  • setActiveCategory(category.id)} + > + + {category.name} +
  • + })} +
+
+ + {/* 右侧内容区 */} +
+ {/* 搜索和操作栏 */} +
+ } onSearch={(value) => { setPage(1); setSearch(value) }} /> + {current_user && current_user.login && } +
+ + {/* 模型列表 */} +
+ {list && list.map((model) => ( + +
+
+ {model.image && } + {model.icon && type !== "skills" && } +
+
{model.name}{model.isNew && }
+
{model.desc}
+
+ 查看 +
+ {type === "skills" ?
+ + {model.domainName} + {aiCard(model)} +
: + {type === "codes" ?
: } +
+ {aiCard(model)} + {type === "codes" ?
+ {model.topics && !!model.topics.length && + + {model.topics.map((topic, index) => { + return + {topic} + {index < model.topics.length - 1 && } + + })} + } + +
: 大语言模型} +
+
} +
+
+ ))} +
+ + {/* 分页 */} + { setPage(p) }} pageSize={10} total={total} showQuickJumper hideOnSinglePage /> +
+
+
+ ); +} + +export default List; diff --git a/src/ai/list/index.scss b/src/ai/list/index.scss new file mode 100644 index 000000000..1e43e2e82 --- /dev/null +++ b/src/ai/list/index.scss @@ -0,0 +1,287 @@ +.ai_home_page { + background: linear-gradient(180deg, #f8f8fe 0%, #f1f6fd 100%); + + // Banner 区域 + .ai_home_banner { + background-image: url('../image/bk1.png'); + background-size: 100% 100%; + padding: 50px 20px 80px 20px; + + .ai_home_banner_title { + + // 星星装饰 + .ai_home_banner_stars { + position: relative; + display: inline-block; + margin-left: 20px; + + .star_1, + .star_2 { + position: absolute; + animation: twinkle 2s infinite ease-in-out; + } + + .star_1 { + width: 35px; + top: -35px; + } + + .star_2 { + width: 20px; + animation-delay: 0.5s; + top: -46px; + left: 38px; + } + + .star_3 { + position: absolute; + top: -3px; + left: 25px; + } + + } + } + + // Tab 切换 + .ai_home_banner_tabs { + border: 1px solid #091221; + border-radius: 24px; + display: inline-flex; + justify-content: center; + } + + .ai_home_banner_tab { + font-weight: 600; + padding: 7px 36px; + + &, + &:hover, + &:focus { + color: #091221; + } + + i { + display: none; + color: inherit; + } + + &.active { + background: #091221; + border-radius: 22px; + color: white; + + i { + display: inline-block; + font-weight: normal; + } + } + + &:not(:first-of-type) { + margin-left: -18px; + } + + &:hover:not(.active) { + background: rgba(9, 18, 33, 0.05); + border-radius: 22px; + } + } + } + + // 主体内容区域 + .ai_home_content { + display: flex; + gap: 30px; + min-height: 60vh; + } + + // 左侧边栏 + .ai_home_sidebar { + flex: 0 0 340px; + height: fit-content; + + .ai_home_sidebar_list { + .ai_home_sidebar_item { + width: fit-content; + padding: 7px 33px; + cursor: pointer; + transition: all 0.2s; + border: 1px solid rgba(22, 76, 228, 0.1); + border-radius: 22px; + + &:hover { + border-color: #091221; + } + + &.active { + border-color: #091221; + background: #091221; + color: #fff; + } + } + } + } + + // 工具栏 + .ai_home_toolbar { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 30px; + gap: 20px; + flex-wrap: wrap; + + .ai_home_search { + background: linear-gradient(89.82deg, #ffffff 1.89%, #f8f9fd 99.99%); + border: 1px solid rgba(22, 76, 228, 0.1); + border-radius: 12px; + padding: 8px 15px; + + .ant-input-search-button { + width: 28px; + height: 28px; + background: #091221; + border-radius: 16px; + padding: 0; + border: none !important; + } + + input { + background: none !important; + border: none; + font-size: 15px; + + &::placeholder { + color: #76849b; + } + } + } + .ai_home_action_my{ + i{ + display: inline-block; + position: relative; + top: 1px; + } + &:hover{ + i{ + animation: arrow-move 1.2s ease-in-out infinite; + } + } + } + + } + + // 模型列表 + .ai_home_list { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 30px; + } + + .ai_home_list.skills_pattern .ai_home_card { + &:nth-child(4n+1) { + .action-item_content { + background: linear-gradient(88.92deg, #ececff 2.11%, #f8f9fd 99.79%); + } + } + + &:nth-child(4n) { + .action-item_content { + background: linear-gradient(88.92deg, #fdf5fd 2.11%, #f8f9fd 99.79%); + } + } + + .action-item_content { + background: linear-gradient(88.92deg, #eef3fd 2.11%, #f8f9fd 99.79%); + } + } + + .codes_pattern { + .ai_home_card { + .action-item_content { + padding: 13px 14px; + background: linear-gradient(88.92deg, #E3E9FE 2.11%, #ECF1FD 99.79%); + + &>div { + padding: 20px 26px; + background: linear-gradient(90.61deg, #ffffff 1.22%, rgba(255, 255, 255, 0.44) 18.41%, rgba(255, 255, 255, 0.66) 98.18%); + border-radius: 6px; + } + } + + &:nth-child(4n) .action-item_content { + background: linear-gradient(88.92deg, #eaeeff 2.11%, #F5F7FE 99.79%); + } + + &:nth-child(4n+1) .action-item_content { + background: linear-gradient(88.92deg, #ebecff 2.11%, #f1f1fd 99.79%); + } + + &:nth-child(4n+2) .action-item_content { + background: linear-gradient(88.92deg, #E8F4F9 2.11%, #F5F9FE 99.79%); + } + } + } + + + // 卡片 + .ai_home_card { + width: auto; + + &:hover { + .btn-black { + display: inline-block; + } + } + + &.action-item:hover:before { + background: conic-gradient(from 180deg at 50% 50%, + #587fee 0deg, + #9467e3 45deg, + transparent 90deg, + transparent 180deg, + #587fee 180deg, + #9467e3 225deg, + transparent 270deg); + } + + .action-item_content { + border: 1px solid rgba(22, 76, 228, 0.1); + background: white url('../image/card_bk1.png'); + background-blend-mode: multiply; + padding: 20px 32px; + width: auto; + border-radius: 11px; + } + + .ai_home_card_tag { + background: #f5f9fd; + border: 1px solid #d3e1fd; + border-radius: 4px; + color: #091221; + font-size: 13px; + line-height: 24px; + padding: 1px 9px; + } + + .icon-colora-zuixin1 { + vertical-align: middle; + } + + .btn-black { + padding: 0px 19px 4px 19px; + display: none; + transition: all 0.3s; + } + } + + .skills_bottom { + background: rgba(255, 255, 255, 0.7); + border-radius: 6px; + padding: 13px 16px; + margin-top: 17px; + } + + .ai_list_Pagination { + margin-top: 45px; + } +} \ No newline at end of file diff --git a/src/ai/my-resources/index.jsx b/src/ai/my-resources/index.jsx new file mode 100644 index 000000000..4651536d3 --- /dev/null +++ b/src/ai/my-resources/index.jsx @@ -0,0 +1,191 @@ +import { Fragment, useEffect, useState } from "react"; +import { Link } from "react-router-dom"; +import { Table, Pagination, Badge, message } from "antd"; +import './index.scss'; +import { aiResouceStatus, aiResouceType, aiResouceTypeKey } from "../static"; +import { drawSourceById, getMyCodeList, getMyResourceList, takeUpSourceById } from "../../forge/Information/api"; +import { DeleteModal, TakeDownModal } from "../component"; +import moment from "moment"; + +function MyResources(props) { + const pageSize = 10; + const { match: { params }, history, aiZoneInfo, roleByZone } = props || {}; + const type = params.type; + const { id: aiZoneId } = aiZoneInfo || {} + const [current, setCurrent] = useState(1); + const [total, setTotal] = useState(0); + const [reload, setReload] = useState(undefined); + const [list, setList] = useState([]); + const [deleteId, setDeleteId] = useState(); + const [downId, setDownId] = useState(); + + useEffect(() => { + document.title = `我的资源池` + }, []) + + useEffect(() => { + if(type === "codes" && aiZoneId) { + // 获取聚合的代码库列表 + getMyCodeList({ + zoneId: aiZoneId, + pageNum: current, + pageSize: pageSize, + }, roleByZone).then(res => { + if(res && res.data && res.data.code === 200){ + setList(res.data.rows); + setTotal(res.data.total) + } + }); + return + } + aiZoneId && getMyResourceList({ + auditStatus: "all", + zoneId: aiZoneId, + resourceCategory: aiResouceTypeKey[type], + pageNum: current, + pageSize: pageSize, + }, roleByZone).then(res => { + if(res && res.data && res.data.code === 200){ + setList(res.data.rows); + setTotal(res.data.total) + } + }) + }, [type, aiZoneId, current, reload]) + + const stats = [ + { key: 'likes', label: '累计获得点赞', value: '123' }, + { key: 'published', label: '已发布', value: '17' }, + { key: 'reviewing', label: '审核中', value: '25' }, + ]; + + const columns = [ + { + title: 资源名称, + dataIndex: type === "codes" ? "projectProperties.name" : 'name', + key: 'name', + render: (text, record) => { + return {text} + } + }, + { + title: '提交时间', + dataIndex: 'updateTime', + key: 'updateTime', + render: (text) => { + return moment(text).format('YYYY-MM-DD HH:mm') + } + }, + { + title: '状态', + key: 'auditStatus', + dataIndex: 'auditStatus', + render: (text, record) => { + const status = aiResouceStatus[text] || {}; + return + }, + }, + { + title: '操作', + key: 'action', + className: 'col-actions', + render: (text, record) => { + const { auditStatus, id } = record; + return type === "codes" ? {setDeleteId(id)}}>删除 : auditStatus === "1" ? {setDownId(id)}}>下架 : auditStatus === "0" ? { + drawSourceById(id).then(res=>{ + if(res && res.data && res.data.code === 200){ + message.success(`操作成功`); + setReload(Math.random()); + } + }) + }}>撤回 : + + {auditStatus === "3" && { + takeUpSourceById(id, roleByZone).then(res=>{ + if(res && res.data && res.data.code === 200){ + message.success(`操作成功`); + setReload(Math.random()); + } + }) + }}>上架} + 修改 + {setDeleteId(id)}}>删除 + + }, + }, + ]; + + // 分页变化处理 + const handlePageChange = (page) => { + setCurrent(page); + }; + + return ( +
+
+ {/* 左侧区域 */} +
+ {/* 标题区域 */} +
+ + + + 我的资源池 +
栈筑 AI 全能力
+
+
+ 聚合数据集、模型、Skill 场景能力与工程代码,模块化灵活编排,一站式搭建全链路智能 AI 应用 +
+ + {/* 分类标签 */} +
+ {aiResouceType.map((category) => ( + + {category.name} + + ))} +
+ + {/* 统计数据 */} +
+ {stats.map((stat) => ( +
+ {stat.value} +
{stat.label}
+
+ ))} +
+
+ + {/* 右侧区域 */} +
+
+ + {/* 分页 */} + `共 ${total} 条记录`} + className="black_active_Pagination edu-txt-right mt36" + /> + + + + {setDeleteId(undefined)}} roleByZone={roleByZone} reload={setReload}/> + {setDownId(undefined)}} roleByZone={roleByZone} reload={setReload}/> + + ); +} + +export default MyResources; diff --git a/src/ai/my-resources/index.scss b/src/ai/my-resources/index.scss new file mode 100644 index 000000000..54fcad6e9 --- /dev/null +++ b/src/ai/my-resources/index.scss @@ -0,0 +1,154 @@ +.my-resources-page { + background-image: url('../image/bk5.png'); + background-size: 100% auto; + background-repeat: no-repeat; + padding-top: 55px; + min-height: 91vh; + + .container { + display: flex; + gap: 75px; + } + + // 左侧区域 + .left-panel { + flex: 0 0 400px; + height: fit-content; + + // 返回按钮 + .back-btn { + display: inline-block; + transform: scaleX(-1) translateY(-7px); + margin-right: 12px; + } + + // 标题区域 + .header-section { + line-height: normal; + } + + // 分类标签 + .category-tabs { + display: flex; + margin-bottom: 30px; + border: 1px solid #091221; + border-radius: 24px; + + .category-tab { + flex: 1; + height: 44px; + line-height: 44px; + border-radius: 22px; + cursor: pointer; + transition: all 0.2s; + text-align: center; + + &:hover { + color: inherit; + background-color: rgba(9, 18, 33, 0.05); + } + + &.active { + background: #091221; + color: #fff; + } + } + } + + // 统计数据 + .stats-section { + display: flex; + + .stat-card { + margin-right: auto; + + span { + font-size: 44px; + font-family: "YouSheBiaoTiHei"; + line-height: normal; + } + } + } + } + + // 右侧区域 + .right-panel { + flex: 1; + width: 0; + background-image: url('../image/bk4.png'); + background-size: 100% 100%; + padding: 20px; + border: 2px solid #ffffff; + border-radius: 12px; + + .table-container .ant-table { + min-height: 650px; + background: white; + border: 1px solid; + border-color: rgba(22, 76, 228, 0.1); + border-radius: 12px; + overflow: hidden; + + table { + color: #091221; + font-size: 15px; + } + + .ant-table-tbody>tr>td { + border-bottom: none + } + + .ant-table-tbody>tr { + background: linear-gradient(89.78deg, rgba(236, 236, 255, 0.58) 1.89%, rgba(248, 249, 253, 0) 99.99%); + + &:nth-child(2n) { + background: linear-gradient(89.78deg, #eef3fd 1.89%, rgba(248, 249, 253, 0) 99.99%); + } + + td { + border-top: 25px solid white; + + &:first-of-type { + border-left: 12px solid white; + font-size: 16px; + font-weight: bold; + } + } + } + + .ant-table-thead>tr>th { + background: #f5f6ff; + color: #091221; + font-size: 15px; + font-weight: bold; + border-bottom-color: rgba(22, 76, 228, 0.1); + } + } + + .status-dot { + .ant-badge-status-text { + color: #091221; + font-size: 15px; + } + + .ant-badge-status-dot { + &::before { + content: ''; + position: absolute; + top: -2px; + left: -2px; + width: 10px; + height: 10px; + background-color: inherit; + z-index: 1; + opacity: 0.2; + border-radius: 50%; + } + } + + } + .col-actions a{ + color:#164ce4; + } + } +} \ No newline at end of file diff --git a/src/ai/static.js b/src/ai/static.js new file mode 100644 index 000000000..698e3cff9 --- /dev/null +++ b/src/ai/static.js @@ -0,0 +1,114 @@ +export const aiResouceType = [ + { key: "models", name: "模型库", icon: "moxingku", intro: "行业算法模型", desc: "收录多模态原生大模型矩阵,开箱即用灵活调度,全方位支撑企业 AI 业务研发与智能化升级", createIntro: "上传您的模型文件,审核通过后将同步展示在AI广场" }, + { key: "datasets", name: "数据集", icon: "shujuji", intro: "高精训练数据", desc: "精心策划的多模态数据集,覆盖 NLP、CV、语音、多模态等核心方向,助力模型快速迭代。", createIntro: "上传您的数据集文件,审核通过后将同步展示在AI广场" }, + { key: "skills", name: "Skills", icon: "skill", intro: "场景智能能力", desc: "标准化封装多维场景 Skill 能力,灵活组合调用,低成本快速搭建各类智能化 AI 业务应用。", createIntro: "上传您的skill文件,审核通过后将同步展示在AI广场" }, + { key: "codes", name: "代码库", icon: "daimaku1", intro: "通用开发源码", desc: "模块化沉淀全场景通用代码能力,积木式灵活编排复用,高效轻量化落地各类研发业务需求", createIntro: "上传您的代码库,审核通过后将同步展示在AI广场" } +] + +export const aiResouceTypeKey = { + models: "MODEL", + datasets: "DATASET", + skills: "SKILL" +} + +// 已发布:审核通过/上架 +export const aiResouceStatus = { + "0": {label: "待审核", color: "#ff9140"}, + "1": {label: "已发布", color: "#164ce4"}, + "2": {label: "已驳回", color: "#d82944"}, + "3": {label: "已下架", color: "#5C5A59"}, + "4": {label: "草稿", color: "#ff5e00"}, +} + +// 步骤引导数据 +export const aiCreateSteps = [ + { + title: "注册/登录账号", + description: "首先需要注册或登录您的账号,才能开始发布资源" + }, + { + title: "选择资源类型", + description: "选择您要发布的资源类型:模型、数据集、Skill 或代码库" + }, + { + title: "填写信息并发布", + description: "填写资源的详细信息,包括名称、简介、标签等,然后提交发布" + } +]; + +export const convertToTreeData = (data) => { + return data.map(node => { + return { + key: node.name, + title: node.name, + isLeaf: node.type === 'file', + children: node.children ? convertToTreeData(node.children) : undefined + }; + }); +}; + +// 分类图标 +export const iconByCateName = { + "开发工具": ["iconfont-color icon-colora-zu18240", "iconfont icon-a-Dshujukukaifagongju"], + "多模态": ["iconfont-color icon-colora-zu18210", "iconfont icon-duomotaimoxing"], + "自然语言处理": ["iconfont-color icon-colorziranyuyanchuli", "iconfont icon-ziranyuyanchuli-2"], + "语音": ["iconfont-color icon-coloryuyin", "iconfont icon-yuyin-1"], + "计算机视觉": ["iconfont-color icon-colora-zu18213", "iconfont icon-a-zu18214"], + "科学计算": ["iconfont-color icon-colorkexueyanjiuhejishufuwuye", "iconfont icon-a-kexueyanjiuhejishufuwuye-1"], + "文本": ["iconfont-color icon-colorziranyuyanchuli", "iconfont icon-ziranyuyanchuli-2"], + "图像": ["iconfont-color icon-colortuxiang", "iconfont icon-a-tuxiang-1"], + "音频": ["iconfont-color icon-coloryinpin", "iconfont icon-yinpin-1"], + "视频": ["iconfont-color icon-colorshipinbofang", "iconfont icon-shipinbofang-1"], + "开发工具": ["iconfont-color icon-colora-zu18240", "iconfont icon-a-Dshujukukaifagongju"], + "市场推广": ["iconfont-color icon-colora-zu18213", "iconfont icon-a-zu18214"], + "前端开发": ["iconfont-color icon-colordaimaku1", "iconfont icon-daimaku1"], + "媒体处理": ["iconfont-color icon-coloryouxiyule", "iconfont icon-meitichuli"], + "代码质检": ["iconfont-color icon-colordaimazhijian", "iconfont icon-daimazhijian"], + "移动开发": ["iconfont-color icon-coloryidongkaifa", "iconfont icon-yidongkaifa"], + "云效工具": ["iconfont-color icon-coloryunxiaogongju", "iconfont icon-yunxiaogongju"], + "其他": ["iconfont-color icon-colorqita", "iconfont icon-qita"], + "程序开发": ["iconfont-color icon-colora-zu18240", "iconfont icon-a-Dshujukukaifagongju"], + "操作系统": ["iconfont-color icon-colora-zu18213", "iconfont icon-a-zu18214"], + "人工智能": ["iconfont-color icon-colordaimaku1", "iconfont icon-daimaku1"], + "游戏娱乐": ["iconfont-color icon-coloryouxiyule", "iconfont icon-meitichuli"], + "程序设计": ["iconfont-color icon-colordaimazhijian", "iconfont icon-daimazhijian"], + "云原生": ["iconfont-color ", "iconfont "] +} + +export const iconByCateIndex = { + "models": [ + ["iconfont-color icon-colora-zu18210", "iconfont icon-duomotaimoxing"], + ["iconfont-color icon-colorziranyuyanchuli", "iconfont icon-ziranyuyanchuli-2"], + ["iconfont-color icon-coloryuyin", "iconfont icon-yuyin-1"], + ["iconfont-color icon-colora-zu18213", "iconfont icon-a-zu18214"], + ["iconfont-color icon-colorkexueyanjiuhejishufuwuye", "iconfont icon-a-kexueyanjiuhejishufuwuye-1"] + ], + "datasets": [ + ["iconfont-color icon-colora-zu18210", "iconfont icon-duomotaimoxing"], + ["iconfont-color icon-colorziranyuyanchuli", "iconfont icon-ziranyuyanchuli-2"], + ["iconfont-color icon-colortuxiang", "iconfont icon-a-tuxiang-1"], + ["iconfont-color icon-coloryinpin", "iconfont icon-yinpin-1"], + ["iconfont-color icon-colorkexueyanjiuhejishufuwuye", "iconfont icon-a-kexueyanjiuhejishufuwuye-1"], + ["iconfont-color icon-colorshipinbofang", "iconfont icon-shipinbofang-1"] + ], + "skills": [ + ["iconfont-color icon-colora-zu18240", "iconfont icon-a-Dshujukukaifagongju"], + ["iconfont-color icon-colora-zu18213", "iconfont icon-a-zu18214"], + ["iconfont-color icon-colordaimaku1", "iconfont icon-daimaku1"], + ["iconfont-color icon-coloryouxiyule", "iconfont icon-meitichuli"], + ["iconfont-color icon-colordaimazhijian", "iconfont icon-daimazhijian"], + ["iconfont-color icon-coloryidongkaifa", "iconfont icon-yidongkaifa"], + ["iconfont-color icon-coloryunxiaogongju", "iconfont icon-yunxiaogongju"], + ["iconfont-color icon-colorqita", "iconfont icon-qita"] + ], + "codes": [ + ["iconfont-color icon-colora-zu18240", "iconfont icon-a-Dshujukukaifagongju"], + ["iconfont-color icon-colora-zu18213", "iconfont icon-a-zu18214"], + ["iconfont-color icon-colordaimaku1", "iconfont icon-daimaku1"], + ["iconfont-color icon-coloryouxiyule", "iconfont icon-meitichuli"], + ["iconfont-color icon-colordaimazhijian", "iconfont icon-daimazhijian"], + ["iconfont-color icon-coloryidongkaifa", "iconfont icon-yidongkaifa"], + ["iconfont-color icon-coloryunxiaogongju", "iconfont icon-yunxiaogongju"], + ["iconfont-color icon-colorqita", "iconfont icon-qita"] + ] +} \ No newline at end of file diff --git a/src/animations.scss b/src/animations.scss index 775de76b7..f8e962011 100644 --- a/src/animations.scss +++ b/src/animations.scss @@ -50,4 +50,25 @@ to { transform: scale(1); } +} + +// 左右摆动动画 +@keyframes arrow-move { + 0%, 100% { transform: translateX(0); } + 50% { transform: translateX(4px); } +} + +// 星星闪烁动画 +@keyframes twinkle { + + 0%, + 100% { + opacity: 1; + transform: scale(1); + } + + 50% { + opacity: 0.7; + transform: scale(0.9); + } } \ No newline at end of file diff --git a/src/common/UrlTool.js b/src/common/UrlTool.js index 8ee87d0ce..cba911412 100644 --- a/src/common/UrlTool.js +++ b/src/common/UrlTool.js @@ -124,10 +124,10 @@ export function setImagesUrl(path){ } export function getUrl(path, goTest) { - // const local = 'http://172.20.32.202:8080' - // if (isDev) { - // return `${local}${path?path:''}` - // } + const local = 'http://172.20.32.203:4000' + if (isDev) { + return `${local}${path?path:''}` + } return `${path ? path: ''}`; } diff --git a/src/components/commentsByZone/CommentsList.jsx b/src/components/commentsByZone/CommentsList.jsx new file mode 100644 index 000000000..ab55f724c --- /dev/null +++ b/src/components/commentsByZone/CommentsList.jsx @@ -0,0 +1,260 @@ +import React, { useEffect, useState } from 'react'; +import { Button, Popconfirm, Input, message, Spin, Pagination } from 'antd'; +import { getImageUrl, timeAgo, isPhone } from 'educoder'; +import RenderHtml from '../render-html'; +import Attachment from '../../forge/Upload/attachment'; +import EditComment from './EditComment'; +import CheckProfile from '../../forge/Component/ProfileModal/Profile'; +import './comments.scss'; +import { Link } from 'react-router-dom'; +import { normalizeUrl } from '../../forge/common/util'; +import { COMMENT_PAGE_SIZE, COMMENT_CATEGORY } from './constants'; +import * as commentApi from './api'; + +/** + * 通用评论列表组件 + * @param {Object} props - 组件属性 + * @property {string} type - 评论类型:'news' | 'project' | 'resource' | 'skill' + * @property {string|number} id - 资源ID(文章ID、项目ID等) + * @property {Object} [extraParams] - 额外的业务参数 + * @property {string} [owner] - 所有者/组织名(用于 Markdown 渲染) + * @property {string} [projectsId] - 项目 ID(用于 Markdown 渲染) + * @property {Object} current_user - 当前用户信息 + * @property {string} current_user.login - 用户登录名 + * @property {boolean} current_user.admin - 是否平台管理员 + * @property {string} current_user.image_url - 用户头像URL + * @property {string} current_user.username - 用户姓名 + * @property {boolean} [isManager] - 是否为仓库/项目管理员 + * @property {Function} [showNotification] - 显示通知 + * @property {Function} [showLoginDialog] - 显示登录弹窗 + * @property {string} [author] - 评论作者(用于权限判断) + */ +function CommentsList(props){ + const {type, id, extraParams, owner, projectsId, current_user, isManager, showLoginDialog, author, showNotification} = props; + const {login, admin, image_url, username} = current_user; + + const [category, setCategory] = useState('comment'); + const [journals, setJournals] = useState(undefined); + // 是否展示新建/编辑评论markdown部分新建评论1 编辑父级评论2 回复评论3 编辑回复内容4 回复子机评论5 + const [showEdit, setShowEdit] = useState(false); + const [parentId, setParentId] = useState(undefined); + const [replyId, setReplyId] = useState(undefined); + // 修改评论id + const [updateId, setUpdateId] = useState(undefined); + // 操作日志展开效果 + const [open, setOpen] = useState(undefined); + // 加载中效果(缓冲css 线条效果) + const [spin, setSpin] = useState(false); + // 评论总数 + const [journalsCount, setJournalsCount] = useState(undefined); + // 分页 + const limit = COMMENT_PAGE_SIZE; + const [page, setPage] = useState(1); + const [totalCount, setTotalCount] = useState(undefined); + const [reload, setReload] = useState(undefined); + + // 根据 type 加载评论列表 + useEffect(()=>{ + setSpin(true); + let params = { + limit: limit, + page: page + }; + commentApi.getCommentList(type, id, page, limit).then(res=>{ + if(res && res.data && res.data.data){ + const {journals: journalList, total_comment_journals_count, total_count} = res.data.data; + if(category === COMMENT_CATEGORY.ALL){ + const array = []; + let start = undefined; + let isJournalCount = 0; + journalList.map((item, index)=>{ + !isJournalCount && (start = index); + item.is_journal_detail && (isJournalCount++); + if(!item.is_journal_detail && isJournalCount < 10){ + isJournalCount = 0; + return; + } + if(isJournalCount >= 10 && (!item.is_journal_detail || journalList.length-1 === index)){ + array.push({start, count: isJournalCount}); + isJournalCount = 0; + } + }); + array.map((item, i)=>{ + journalList[item.start].numCount = item.count-1; + for (let index = 0; index < item.count; index++) { + journalList[item.start+index].start = journalList[item.start].id; + journalList[item.start+index].closeAndSpan = true; + } + }); + } + setTotalCount(total_count); + setJournalsCount(total_comment_journals_count); + setJournals(journalList); + setSpin(false); + } + }).catch(err => { + console.error('获取评论列表失败:', err); + setSpin(false); + message.error('获取评论列表失败'); + }); + }, [type, id, reload, category, page]); + + // 刷新评论列表的回调 + const reloadComment = () => { + setReload(Math.random()); + }; + + function commentCtx(v){ + return ; + }; + + // 删除评论内容 + function deleteCommentFunc(commentId){ + commentApi.deleteComment(type, id, commentId).then(res=>{ + if(res && res.data && res.data.code === 200){ + reloadComment(); + message.success('删除成功'); + } + }).catch(err => { + console.error('删除评论失败:', err); + message.error('删除评论失败'); + }); + }; + + // markdown 取消操作 + function cancelMd(){ + setShowEdit(false); + }; + + // 创建不包含已解构属性的 props 对象传递给子组件 + const childProps = { + ...props, + type, + id, + extraParams, + owner, + projectsId, + current_user, + isManager, + showLoginDialog, + author, + showNotification, + reloadComment, + cancelMd + }; + + return( + (isPhone() && journalsCount === 0) ? '' :
+ {/* 评论快速入口-仅有评论且登录时展示 */} + {login && category !== COMMENT_CATEGORY.OPERATE && journalsCount > 0 && !isPhone() &&
0 && 'pt15'}`}>
} + {/* 评论/操作日志 展示列表 */} + +
+ {journals && (journals.length > 0 && journals.map(item => {return
+ {/* 评论 */} +
+ { + item.user.userName ? + + : + + } +
+ {/* 判断是否是编辑状态 */} + {(showEdit === 2 && updateId === item.id) ?
:
+
+
+
+ {item.user.userName ? {item.user.nickName}:{item.user.nickName}} + {timeAgo(item.created_at)} +
+ {login && !isPhone() &&
+ {/* 平台管理员/仓库管理员/发布评论者/issue创建者 */} + {(admin || isManager || login === item.user.userName || username === author) && 0 ? '子评论也将被一起删除。' : ''}`} + okText="是" + cancelText="否" + onConfirm={() => deleteCommentFunc(item.id)} + > + + } + {/* 仅评论者可修改 */} + {login === item.user.userName && } + {setParentId(item.id); setReplyId(item.id); setShowEdit(3)}}> +
} +
+
{commentCtx(item.notes)}
+ {item && item.attachments && item.attachments.length > 0 &&
} +
+
} + {showEdit === 3 && replyId === item.id &&
} + {/* 评论回复部分 */} + {item.children_journals.map(i =>{ + return
+ {(showEdit === 4 && updateId === i.id) ?
:
+
+
+ + {i.user.nickName} + {i.reply_user && 回复} + {i.reply_user && i.reply_user.name} + {timeAgo(i.created_at)} +
+ {login && !isPhone() &&
+ {/* 平台管理员/仓库管理员/发布评论者/回复评论者/issue创建者 */} + {(admin || isManager || login === i.user.userName || (i.reply_user && login === i.reply_user.login) || username === author) && deleteCommentFunc(i.id)} + > + + } + {/* 仅回复评论者可修改 */} + {login === i.user.userName && } + {setParentId(item.id);setReplyId(i.id); setShowEdit(5)}}> + + +
} +
+
{commentCtx(i.notes)}
+ {i && i.attachments && i.attachments.length > 0 &&
} +
} + {showEdit === 5 && replyId === i.id &&
} +
})} +
+
}))} +
+
+ {totalCount > limit &&
+ setPage(page)}/> +
} + {/* 添加评论 */} + {category !== COMMENT_CATEGORY.OPERATE && !isPhone() &&
+ {login ? showEdit === 1 ? :
+ +
+ {setShowEdit(1);}}> + + +
+
:
+ {/* 未登录用户 */} + {showLoginDialog()}}>登录并参与评论与回复 +
} +
} +
+ ); +}; + +export default CommentsList; diff --git a/src/components/commentsByZone/EditComment.jsx b/src/components/commentsByZone/EditComment.jsx new file mode 100644 index 000000000..dff9a7788 --- /dev/null +++ b/src/components/commentsByZone/EditComment.jsx @@ -0,0 +1,184 @@ +import React, { useState } from 'react'; +import { Button, Icon, message, Upload } from 'antd'; +import { getImageUrl, getZoneUrl } from 'educoder'; +import MDEditor from "../../modules/tpm/challengesnew/tpm-md-editor"; +import Attachments from "../../forge/Upload/attachment"; +import './comments.scss'; +import { Link } from 'react-router-dom'; +import * as commentApi from './api'; +import cookie from 'react-cookies'; + +/** + * 通用评论编辑组件 + * @param {Object} props - 组件属性 + * @property {string} type - 评论类型:'news' | 'project' | 'resource' | 'skill' + * @property {string|number} id - 资源ID + * @property {Object} [extraParams] - 额外的业务参数 + * @property {string} [owner] - 所有者/组织名(用于 Markdown 编辑器 @ 功能) + * @property {string} [projectsId] - 项目 ID(用于 Markdown 编辑器 @ 功能) + * @property {Object} current_user - 当前用户信息 + * @property {string} current_user.login - 用户登录名 + * @property {string} current_user.image_url - 用户头像URL + * @property {Function} cancelMd - 取消编辑回调 + * @property {Function} reloadComment - 刷新评论列表回调 + * @property {Function} showNotification - 显示通知 + * @property {string} [content] - 编辑时的原始内容 + * @property {Array} [defaultFileList] - 默认附件列表 + * @property {string} [parentId] - 父评论ID + * @property {string} [replyId] - 回复的评论ID + * @property {string} [updateId] - 正在编辑的评论ID + * @property {boolean} [showUserImg=true] - 是否显示用户头像 + */ +function EditComment(props) { + const { type, id, extraParams, current_user, current_user: { login, image_url }, owner, projectsId, cancelMd, reloadComment, showNotification, parentId, replyId, updateId, showUserImg = true, content: propContent, defaultFileList: propDefaultFileList } = props; + + const [content, setContent] = useState(propContent); + const [quillFlag, setQuillFlag] = useState(false); + // 确认评论按钮loading效果 + const [journalSpin, setJournalSpin] = useState(false); + const [fileList, setFileList] = useState(propDefaultFileList || []); + + // 评论点击函数 + function addJournals() { + if (!content) { + setQuillFlag(true); + return; + } + setJournalSpin(true); + const fileIds = fileList.map(file=>file.fileIdentifier || file.identifier).toString() + if (updateId) { + // 修改评论 + const params = { + id: updateId, + notes: content, + attachment_identifiers: fileIds, + }; + commentApi.editComment(type, id, params).then(res => { + if (res && res.data && res.data.code === 200) { + // 刷新评论列表 + reloadComment(); + message.success('编辑成功'); + cancelMd(); + setContent(undefined); + } + setJournalSpin(false); + }).catch(err => { + console.error('编辑评论失败:', err); + message.error('编辑评论失败'); + setJournalSpin(false); + }); + } else { + // 新建评论 + const params = { + parent_id: parentId, + reply_id: replyId, + notes: content, + attachment_identifiers: fileIds, + }; + commentApi.addComment(type, id, params).then(res => { + if (res && res.data && res.data.code === 200) { + // 刷新评论列表 + reloadComment(); + message.success('评论成功'); + cancelMd(); + setContent(undefined); + } + setJournalSpin(false); + }).catch(err => { + console.error('添加评论失败:', err); + message.error('添加评论失败'); + setJournalSpin(false); + }); + } + }; + + function beforeUpload(file) { + const isLt100M = file.size / 1024 / 1024 < 100; + if (!isLt100M) { + message.error(`文件大小必须小于${100}MB!`); + } + return isLt100M; + } + + function changeFileList(info) { + const { file } = info; + const { status, response } = file || {} + if (status === 'done' || status === 'removed') { + setFileList([ + ...fileList, + response + ]); + } + } + + return ( +
+ + + +
+ { setQuillFlag(false); setContent(value); }} + owner={owner} + projectsId={projectsId} + > +

+ {quillFlag && 请输入评论内容} +

+ + +

点击或拖拽文件到此区域上传,文件大小不超过 100MB

+
+ {fileList && fileList.length > 0 &&
+ {fileList.map(file => { + return
+ + {file.fileOriginName || file.title} + ({file.fileSize || file.filesize}) + { + const deletedList = fileList.filter(i => i.fileId !== file.fileId || i.id !== file.id); + setFileList(deletedList); + }}> +
+ })} +
} +

+ + +

+
+
+ ); +} + +export default EditComment; diff --git a/src/components/commentsByZone/api.js b/src/components/commentsByZone/api.js new file mode 100644 index 000000000..28427a85f --- /dev/null +++ b/src/components/commentsByZone/api.js @@ -0,0 +1,114 @@ +/** + * 通用评论 API 调用器 + * 根据 type 参数调用不同的业务接口 + */ + +import { COMMENT_TYPE } from './constants'; +import { + getJournalList, + addJournal, + editJournal, + deleteJournal, + uploadFileBySourceJournal +} from '../../forge/Information/api'; + +/** + * 获取评论列表 + * @param {string} type - 评论类型 + * @param {string|number} id - 资源 ID + * @param {Object} params - 分页参数 + * @returns {Promise} + */ +export async function getCommentList(type, id, page, limit) { + switch (type) { + case COMMENT_TYPE.RESOURCE: + return await getJournalList({ + journalized_id: id, + journalized_type: type, + pageNum: page, + pageSize: limit + }) + default: + throw new Error(`Unsupported comment type: ${type}`); + } +} + +/** + * 新增评论 + * @param {string} type - 评论类型 + * @param {string|number} id - 资源 ID + * @param {Object} data - 评论数据 + * @returns {Promise} + */ +export async function addComment(type, id, data) { + switch (type) { + case COMMENT_TYPE.RESOURCE: + return await addJournal({ + journalized_id: id, + journalized_type: type, + ...data + }) + default: + throw new Error(`Unsupported comment type: ${type}`); + } +} + +/** + * 编辑评论 + * @param {string} type - 评论类型 + * @param {string|number} id - 资源 ID + * @param {Object} data - 评论数据(包含 id 字段) + * @returns {Promise} + */ +export async function editComment(type, id, data) { + switch (type) { + case COMMENT_TYPE.RESOURCE: + return await editJournal({ + id: id, + ...data + }) + default: + throw new Error(`Unsupported comment type: ${type}`); + } +} + +/** + * 删除评论 + * @param {string} type - 评论类型 + * @param {string|number} id - 资源 ID + * @param {string|number} commentId - 评论 ID + * @returns {Promise} + */ +export async function deleteComment(type, id, commentId) { + switch (type) { + case COMMENT_TYPE.RESOURCE: + return await deleteJournal(commentId) + default: + throw new Error(`Unsupported comment type: ${type}`); + } +} + +/** + * @获取文件上传路径 + * pms-gitlink会传到ruby的文件服务 + * contentType: 如果文件上传路径为/api/file/common/upload,需要指定内容属于哪个模块,eg:products/projects/docs/ docs/{projectId} + */ +export async function uploadCommentFile(type, data) { + switch (type) { + case COMMENT_TYPE.RESOURCE: + return await uploadFileBySourceJournal(data) + default: + break; + } +} +export function uploadCommentFileData(type) { + switch (type) { + case COMMENT_TYPE.RESOURCE: + return { + hierarchy: "Journals", + type: "ai-resource" + } + default: + break; + } +} \ No newline at end of file diff --git a/src/components/commentsByZone/comments.scss b/src/components/commentsByZone/comments.scss new file mode 100644 index 000000000..b1fd5e16d --- /dev/null +++ b/src/components/commentsByZone/comments.scss @@ -0,0 +1,205 @@ +.typeActionBox{ + display: flex; + align-items: center; + font-size: 16px; + .line { + width: 3px; + height: 14px; + background: var(--primary-color); + margin-right: 13px; + } +} +.commentUserImg{ + height: 28px; + width: 28px; + border-radius: 50%; + object-fit: cover; +} +.issueCommentsBox{ + .operationLog, .commentContentBox{ + position: relative; + min-height: 62px; + display: flex; + >.flexCenter, >a{ + z-index: 2; + } + &::before, &::after{ + content: ''; + width: 1px; + height: 50%; + position: absolute; + background: #eee; + left: 12px; + z-index: 1; + } + &::after{ + background: #eee; + top: 50%; + } + } + .commentContentBox+.operationLog .operationCommentBor, .operationLog+.commentContentBox .commentOperationBor{ + border-top: 1px solid #eee; + width: 98.5%; + position: absolute; + left: 12px; + } + .operationLog+.commentContentBox{ + &>a, &>.commentContentRight{ + margin-top: 25px; + } + } + .timeAgo{ + color:#acb0bf; + } + .operationLog:last-child::after, .operationLog:first-child::before, .commentContentBox:last-child::after, &.justComment .commentContentBox::before, &.justComment .commentContentBox::after{ + display: none; + } + .operationLog:first-child, .commentContentBox+.operationLog{ + margin-top: -15px; + } + .commentContentBox:last-child::before{ + height: 35%; + } + .flexCenter{ + display: flex; + align-items: center; + justify-content: space-between; + } + .commentRenderHtml.markdown-body p{ + font-size: 14px !important; + } + .commentReply{ + padding: 15px 0 0 20px; + background-color: hsla(225, 31%, 95%, 0.41); + &>div{ + padding-bottom: 5px; + } + &+.commentReply>div{ + margin-top: -15px; + padding-top: 15px; + border-top: 1px dashed #eee; + } + } + .opBox{ + justify-content: flex-start; + } + .commentContentBox{ + display: flex; + align-items: flex-start; + } + .commentContentRight{ + flex: 1; + background-color:#fafafc; + border:1px solid rgba(42, 97, 255, 0.23); + border-radius:6px; + position: relative; + top: -6px; + padding: 10px 15px 16px; + width: 0; + &::before{ + content: ''; + display: block; + position: absolute; + top: 13px; + left: -14px; + width: 0; + height: 0; + overflow: hidden; + font-size: 0; + line-height: 0; + border: 7px; + border-style: solid; + border-color: transparent rgba(42, 97, 255, 0.23) transparent transparent; + } + &::after{ + content: ''; + display: block; + width: 0; + height: 0; + overflow: hidden; + font-size: 0; + line-height: 0; + border: 6px; + border-style: solid; + border-color: transparent #fafafc transparent transparent; + position: absolute; + top: 14px; + left: -11px; + } + } +} +.attachmentBox{ + margin-top: -8px; +} +.color-grey-89{ + color: #898d9d; +} +// 添加评论样式 +.unLoginComment{ + height:58px; + line-height: 58px; + background-color:var(--more-light-color); + border-radius:4px; + color: rgba(84, 87, 103, 1); + .loginBtn{ + color: var(--primary-color); + } +} +.quillFlagBox{ + color: red; + margin-bottom: 5px !important; + height: 28px; +} +.addComments{ + display: flex; + align-items: center; + background-color:var(--more-light-color); + border-radius:4px; + padding:7px 10px; + &>img{ + height: 28px; + width: 28px; + border-radius: 50%; + margin-right: 13px; + } +} +.addCommentBox{ + width: 100%; + height: 30px; + border: none; + &:focus { + border-color: var(--primary-color) !important; + } +} +.paginationIssueComment{ + text-align: center; +} +.gotoComment{ + background-color:rgba(241, 243, 252, 0.55); + border-radius:4px; + color: rgba(172, 176, 191, 1); + padding: 8px 20px; + margin-top: -10px; + &>a{color: var(--primary-color);} +} +.colorButton { + background-color: var(--primary-color); + border-color: var(--primary-color); + &:hover { + background-color: var(--light-color); + border-color: var(--primary-color); + } + &:focus { + background-color: var(--primary-color); + border-color: var(--primary-color); + } +} +.colorButton2 { + &:hover { + border-color: var(--primary-color); + color: var(--light-color); + } + &:focus { + color: var(--primary-color); + } +} diff --git a/src/components/commentsByZone/constants.js b/src/components/commentsByZone/constants.js new file mode 100644 index 000000000..0650c3c8a --- /dev/null +++ b/src/components/commentsByZone/constants.js @@ -0,0 +1,45 @@ +/** + * 评论组件类型枚举 + */ +export const COMMENT_TYPE = { + NEWS: 'news', // 资讯/文章评论 + PROJECT: 'project', // 项目评论 + RESOURCE: 'resource', // 资源评论 + SKILL: 'skill' // AI 技能评论 +}; + +/** + * 评论组件 Props 类型定义(JSDoc 用于 TypeScript/IDE 提示) + * @typedef {Object} CommentsListProps + * @property {string} type - 评论类型:'news' | 'project' | 'resource' | 'skill' + * @property {string|number} id - 资源 ID(文章 ID、项目 ID、资源 ID 等) + * @property {Object} [extraParams] - 额外的业务参数(根据不同 type 传递不同参数) + * @property {string} [owner] - 所有者/组织名(用于 Markdown 渲染) + * @property {string} [projectsId] - 项目 ID(用于 Markdown 渲染) + * @property {Object} current_user - 当前用户信息 + * @property {string} current_user.login - 用户登录名 + * @property {boolean} current_user.admin - 是否管理员 + * @property {string} current_user.image_url - 用户头像 URL + * @property {string} current_user.username - 用户姓名 + * @property {boolean} [isManager] - 是否为仓库/项目管理员 + * @property {string} [author] - 评论作者(用于权限判断) + * @property {Function} [reload] - 触发重新加载 + * @property {Function} [showNotification] - 显示通知 + * @property {Function} [showLoginDialog] - 显示登录弹窗 + * @property {Function} [onCommentAdded] - 评论添加回调 + * @property {Function} [onCommentDeleted] - 评论删除回调 + */ + +/** + * 评论列表分页大小 + */ +export const COMMENT_PAGE_SIZE = 50; + +/** + * 评论分类 + */ +export const COMMENT_CATEGORY = { + COMMENT: 'comment', // 仅评论 + ALL: 'all', // 评论 + 操作日志 + OPERATE: 'operate' // 仅操作日志 +}; diff --git a/src/components/commentsByZone/index.jsx b/src/components/commentsByZone/index.jsx new file mode 100644 index 000000000..a27ff2c1c --- /dev/null +++ b/src/components/commentsByZone/index.jsx @@ -0,0 +1,62 @@ +/** + * 通用评论组件入口 + * + * 基于 src/forge/Information/Component/comments 组件重构 + * 支持通过 type 参数区分不同的业务场景 + * + * 使用示例: + * + * import CommentsList, { COMMENT_TYPE } from '@/components/comments'; + * + * + * + * 不同业务模块传参示例: + * + * // News 模块 + * + * + * // Project 模块(待实现对应 API) + * + */ + +import CommentsList from './CommentsList'; +import EditComment from './EditComment'; +import { COMMENT_TYPE, COMMENT_PAGE_SIZE, COMMENT_CATEGORY } from './constants'; +import * as commentApi from './api'; + +export { + CommentsList, + EditComment, + COMMENT_TYPE, + COMMENT_PAGE_SIZE, + COMMENT_CATEGORY, + commentApi +}; + +export default CommentsList; diff --git a/src/forge/Head/announcementBanner/index.scss b/src/forge/Head/announcementBanner/index.scss index 687389a21..6b35051d6 100644 --- a/src/forge/Head/announcementBanner/index.scss +++ b/src/forge/Head/announcementBanner/index.scss @@ -1,3 +1,4 @@ +@import '../../../animations.scss'; .announcement-banner { position: relative; width: 100%; @@ -249,10 +250,6 @@ animation: arrow-move 1.2s ease-in-out infinite; } -@keyframes arrow-move { - 0%, 100% { transform: translateX(0); } - 50% { transform: translateX(4px); } -} /* 角落装饰 */ .announcement-banner .corner { diff --git a/src/forge/Information/api.js b/src/forge/Information/api.js index 84ec12934..130454016 100644 --- a/src/forge/Information/api.js +++ b/src/forge/Information/api.js @@ -178,10 +178,11 @@ export function getSourceTypeList(id){ method: 'get', }) } -export function getSourceZoneList(id){ +export function getSourceZoneList(id, params){ return fetch({ url:`/zone/open/${id}/resourceDomain/list`, method: 'get', + params }) } export function getSourceList(params){ @@ -447,3 +448,163 @@ export function setZoneVisits(data) { data }) } + +// AI资源广场,zoneFront接口都要审核 +export function addProjectInZone(data, role="Member") { + return fetch({ + url: role === "Manager" ? `/zone/project` : `/zone/zoneFront/addProject`, + method: 'POST', + data + }) +} + +// /zoneFront/removeProject/{ids}/project/{ids} +export function deleteProjectInZoneById(id, role="Member"){ + return fetch({ + url: role === "Manager" ? `/zone/project/${id}` : `/zone/zoneFront/removeProject/${id}`, + method:"delete" + }) +} + +export function addSkill(data, role="Member") { + return fetch({ + url: role === "Manager" ? `/zone/ai-resource/skill` : `/zone/zoneFront/skill`, + method: 'POST', + data + }) +} + +export function editSkill(data, role="Member") { + return fetch({ + url: role === "Manager" ? `/zone/ai-resource/skill` : `/zone/zoneFront/skill`, + method: 'PUT', + data + }) +} + +export function parseFileBySkill(data, role="Member") { + return fetch({ + url: role === "Manager" ? `/zone/ai-resource/skill/parse` : `/zone/zoneFront/skill/parse`, + method: 'POST', + data + }) +} + +export function deleteSourceById(id, role="Member"){ + return fetch({ + url: role === "Manager" ? `/zone/resource/${id}` : `/zone/zoneFront/removeResource/${id}`, + method:"delete" + }) +} + +export function takeDownSourceById(id, role="Member"){ + return fetch({ + url: role === "Manager" ? `/zone/resource/${id}/takeDown` : `/zone/zoneFront/${id}/takeDown`, + method:"PUT" + }) +} + +export function takeUpSourceById(id, role="Member"){ + return fetch({ + url: role === "Manager" ? `/zone/resource/${id}/takeUp` : `/zone/zoneFront/${id}/takeUp`, + method:"PUT" + }) +} +// +export function drawSourceById(id){ + return fetch({ + url: `/zoneFront/skillResource/${id}/withdraw`, + method:"PUT" + }) +} + +export function getMyResourceList(params, role="Member"){ + return fetch({ + url: role === "Manager" ? `/zone/resource/list` : `/zone/zoneFront/myResourceList`, + method: 'get', + params: role === "Manager" ? { + ...params, + isMine: true + } : params + }) +} + +export function getMyCodeList(params, role="Member"){ + return fetch({ + url: role === "Manager" ? `/zone/project/list` : `/zone/zoneFront/myProjectList`, + method: 'get', + params: role === "Manager" ? { + ...params, + isMine: true + } : params + }) +} + +export function getSkillList(params){ + return fetch({ + url:`/zone/open/ai-square/skill/list`, + method: 'get', + params + }) +} + +export function getSkillById(id){ + return fetch({ + url:`/zone/open/ai-square/skill/${id}`, + method: 'get' + }) +} + +export function likeAISource(id) { + return fetch({ + url: `/zone/zoneFront/${id}/like`, + method: 'POST', + }) +} + +export function getlikedSource(id) { + return fetch({ + url: `/zone/zoneFront/${id}/like`, + method: 'get', + }) +} + +export function getJournalList(params){ + return fetch({ + url:`/zone/open/journals`, + method: 'get', + params + }) +} + +export function addJournal(data) { + return fetch({ + url: `/zone/journals`, + method: 'POST', + data: data + }) +} + +export function editJournal(data) { + return fetch({ + url: `/zone/journals`, + method: 'PUT', + data: data + }) +} + +export function deleteJournal(id) { + return fetch({ + url: `/zone/journals/${id}`, + method: 'DELETE', + }) +} + +// 文件上传 +export function uploadFileBySourceJournal(data) { + return fetch({ + url: `/file/common/upload`, + method: 'POST', + data: data + }) +} \ No newline at end of file diff --git a/src/forge/Information/fetch.js b/src/forge/Information/fetch.js index 64fe63a70..964892ad3 100644 --- a/src/forge/Information/fetch.js +++ b/src/forge/Information/fetch.js @@ -1,5 +1,6 @@ import axios from 'axios'; import { message , notification } from 'antd'; +import cookie from 'react-cookies'; function beforeFetch(actionUrl){ if (window.location.href.indexOf('localhost') < 0) { @@ -15,7 +16,7 @@ function beforeFetch(actionUrl){ service.interceptors.request.use(request => { let deptId = sessionStorage.getItem('deptId') - // request.headers.Authorization = 'be06b98eb11dc58de93ab4d9de5b673ebae935bd' + request.headers.Authorization = cookie.load('autologin_trustie') if (deptId) { // 用于权限区分 request.headers['Dept-Id'] = deptId diff --git a/src/forge/Order/order.scss b/src/forge/Order/order.scss index 912ce6e80..6c5d0df5d 100644 --- a/src/forge/Order/order.scss +++ b/src/forge/Order/order.scss @@ -591,12 +591,7 @@ a.issue-type-button.active:hover { align-items: center; grid-template-columns: 1fr max-content; } -.grid-item-top { - display: grid; - align-items: center; - grid-template-columns: max-content 1fr; - align-items: flex-start; -} + .fwb { font-weight: bold; } diff --git a/src/forge/common/util.js b/src/forge/common/util.js index 4eb59b427..78801e647 100644 --- a/src/forge/common/util.js +++ b/src/forge/common/util.js @@ -19,7 +19,7 @@ export function timeFormat(SecondsStr){ export function normalizeUrl(url) { if (!url) return ''; const match = url.match(/:4000\/(.+)/); - if (match && match[1]) { + if (match && match[1] && window.location.hostname !== "localhost") { return `${window.location.protocol}//${window.location.hostname}:4000/${match[1]}`; } return url; diff --git a/src/global.scss b/src/global.scss index d13deda7b..8aea790b1 100644 --- a/src/global.scss +++ b/src/global.scss @@ -1,5 +1,5 @@ -$primary-color: #2149d4; +$primary-color: #164ce4; $primary-color-hover: #6684FE; $primary-color-active: #1A47FF; -$link-color: #2149d4; +$link-color: #164ce4; $link-black-color: #05101a; diff --git a/src/index.scss b/src/index.scss index f11ff1a40..a98137e62 100644 --- a/src/index.scss +++ b/src/index.scss @@ -301,4 +301,31 @@ i.color-orange05:hover { } } } + .ant-modal-close { + top: 0px !important + } +} + +// 黑色选中背景 Pagination +.black_active_Pagination{ + .ant-pagination-item-active{ + background:#091221; + border-color:#091221; + a{ + color:#fff !important; + } + } + .ant-pagination-item:hover, .ant-pagination-item:focus, .ant-pagination-item:active, .ant-pagination-next:hover .ant-pagination-item-link, .ant-pagination-prev:hover .ant-pagination-item-link{ + border-color:#091221; + a, i{ + color:#091221; + } + } + .ant-pagination-options-quick-jumper input:hover{ + border-color:#091221; + } + .ant-pagination-options-quick-jumper input:focus{ + border-color:#091221; + box-shadow: 0 0 0 2px rgba(9, 18, 33, 0.2); + } } \ No newline at end of file