资源中枢
459
src/App.js
|
|
@ -52,6 +52,19 @@ const SoftwareFactory = Loadable({
|
|||
loader: () => import('./factory/index'),
|
||||
loading: Loading,
|
||||
})
|
||||
|
||||
const SoftwareFactoryResource = Loadable({
|
||||
loader: () => import('./factory/resource/index'),
|
||||
loading: Loading,
|
||||
})
|
||||
|
||||
|
||||
const SoftwareFactoryScene = Loadable({
|
||||
loader: () => import('./factory/scene/index'),
|
||||
loading: Loading,
|
||||
})
|
||||
|
||||
|
||||
//forge安全设置
|
||||
const Security = Loadable({
|
||||
loader: () => import('./forge/SecuritySetting/Index'),
|
||||
|
|
@ -129,12 +142,12 @@ const LoginRegisterPage = Loadable({
|
|||
|
||||
|
||||
const AboutUs = Loadable({
|
||||
loader: () => import("./forge/AboutUs/AboutUs"),
|
||||
loading: Loading,
|
||||
loader: () => import("./forge/AboutUs/AboutUs"),
|
||||
loading: Loading,
|
||||
})
|
||||
|
||||
const Teaching = Loadable({
|
||||
loader : () => import("./forge/TeachingPractice/Teaching"),
|
||||
loader: () => import("./forge/TeachingPractice/Teaching"),
|
||||
loading: Loading,
|
||||
})
|
||||
|
||||
|
|
@ -147,7 +160,7 @@ const ConfigurateBot = Loadable({
|
|||
loading: Loading,
|
||||
});
|
||||
const SoftBot = Loadable({
|
||||
loader : () => import("./softbot"),
|
||||
loader: () => import("./softbot"),
|
||||
loading: Loading,
|
||||
})
|
||||
|
||||
|
|
@ -181,7 +194,7 @@ const GovernanceIframe = Loadable({
|
|||
});
|
||||
|
||||
// 此处仅维护前端可能的一级路由,不用进行项目或者组织判断的字段。
|
||||
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","softwareFactory", "development", "governance"];
|
||||
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", "softwareFactory", "development", "governance"];
|
||||
|
||||
class App extends Component {
|
||||
constructor(props) {
|
||||
|
|
@ -204,17 +217,17 @@ class App extends Component {
|
|||
|
||||
const login = cookie.load("login");
|
||||
let path = this.props.history.location.pathname;
|
||||
if(login && (path === "/login" || path === "/register" || path === "/resetPassword" || path.indexOf("/bindlogin") >-1 )){
|
||||
if (login && (path === "/login" || path === "/register" || path === "/resetPassword" || path.indexOf("/bindlogin") > -1)) {
|
||||
this.props.history.push(`/${login}`);
|
||||
}
|
||||
// 添加路由监听,决定组织还是个人
|
||||
this.unlisten = this.props.history.listen((location,action) => {
|
||||
this.unlisten = this.props.history.listen((location, action) => {
|
||||
let newPathname = location.pathname.split('/')[1];
|
||||
if (location.pathname === '/' && action === 'POP') { // 浏览器回退/前进
|
||||
this.setState({
|
||||
pathName: null,
|
||||
pathType: null
|
||||
});
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (newPathname !== this.state.pathName) {
|
||||
|
|
@ -224,7 +237,7 @@ class App extends Component {
|
|||
}
|
||||
|
||||
shouldComponentUpdate(nextProps, nextState) {
|
||||
if(!nextProps.location.pathname==='/'){
|
||||
if (!nextProps.location.pathname === '/') {
|
||||
return true;
|
||||
}
|
||||
// 阻止个人与组织切换时(组件渲染)请求导致的404
|
||||
|
|
@ -246,7 +259,7 @@ class App extends Component {
|
|||
})
|
||||
}
|
||||
});
|
||||
}else{
|
||||
} else {
|
||||
this.setState({
|
||||
pathType: pathname,
|
||||
pathName: pathname,
|
||||
|
|
@ -354,166 +367,186 @@ class App extends Component {
|
|||
|
||||
render() {
|
||||
const { pathType, pathName, mygetHelmetapi } = this.state;
|
||||
|
||||
|
||||
return (
|
||||
<ConfigProvider locale={zhCN}>
|
||||
<MuiThemeProvider theme={theme}>
|
||||
<LoginDialog {...this.props} {...this.state} Modifyloginvalue={() => this.Modifyloginvalue()}></LoginDialog>
|
||||
{/* <GlccModal /> */}
|
||||
{/* {!pathName || (pathName && pathName.toLowerCase() !== 'glcc') ? <SiderBar {...this.props}/> : <SiderBarHelp/>} */}
|
||||
{pathName && pathName.toLowerCase() === 'glcc' && <SiderBarHelp/>}
|
||||
{pathName && pathName.toLowerCase() === 'glcc' && <SiderBarHelp />}
|
||||
{/* <Router> */}
|
||||
{
|
||||
pathType ?
|
||||
<Switch>
|
||||
{/* iframe页面 */}
|
||||
<Route path="/hiagent"
|
||||
render={
|
||||
(props) => (<Iframe {...this.props} {...props} {...this.state} />)
|
||||
}
|
||||
></Route>
|
||||
{/* wiki预览 */}
|
||||
<Route path="/:owner/:proIdentity/:projectId/wiki/preview" render={
|
||||
(props) => {
|
||||
return (<WikiPreview {...this.props} {...props} {...this.state} />)
|
||||
}
|
||||
} />
|
||||
pathType ?
|
||||
<Switch>
|
||||
{/* iframe页面 */}
|
||||
<Route path="/hiagent"
|
||||
render={
|
||||
(props) => (<Iframe {...this.props} {...props} {...this.state} />)
|
||||
}
|
||||
></Route>
|
||||
{/* wiki预览 */}
|
||||
<Route path="/:owner/:proIdentity/:projectId/wiki/preview" render={
|
||||
(props) => {
|
||||
return (<WikiPreview {...this.props} {...props} {...this.state} />)
|
||||
}
|
||||
} />
|
||||
|
||||
{/* svg */}
|
||||
<Route path="/:owner/:projectsId/badge/:type" render={
|
||||
(props) => {
|
||||
return (<Badge {...this.props} {...props} {...this.state} />)
|
||||
}
|
||||
} />
|
||||
{/* svg */}
|
||||
<Route path="/:owner/:projectsId/badge/:type" render={
|
||||
(props) => {
|
||||
return (<Badge {...this.props} {...props} {...this.state} />)
|
||||
}
|
||||
} />
|
||||
|
||||
{/* webIDE */}
|
||||
{/* <Route path="/:owner/:projectsId/webIDE/tree/:branchName"
|
||||
{/* webIDE */}
|
||||
{/* <Route path="/:owner/:projectsId/webIDE/tree/:branchName"
|
||||
render={
|
||||
(props) => (<WebIDE {...this.props} {...props} {...this.state} />)
|
||||
}
|
||||
></Route> */}
|
||||
|
||||
{/* 项目PR */}
|
||||
<Route path="/:owner/:projectsId/compare"
|
||||
render={
|
||||
(props) => (<ProjectDetail {...this.props} {...props} {...this.state} />)
|
||||
}
|
||||
></Route>
|
||||
{/* 项目PR */}
|
||||
<Route path="/:owner/:projectsId/compare"
|
||||
render={
|
||||
(props) => (<ProjectDetail {...this.props} {...props} {...this.state} />)
|
||||
}
|
||||
></Route>
|
||||
|
||||
{/*项目*/}
|
||||
<Route
|
||||
path={"/:owner/:projectId/devops/:opsId/detail"}
|
||||
render={
|
||||
(props) => {
|
||||
return (<OpsDetail {...this.props} {...props} {...this.state} />)
|
||||
}
|
||||
}>
|
||||
</Route>
|
||||
{/* 上架bot配置 */}
|
||||
<Route
|
||||
path="/settings/mybot/configuration/:id"
|
||||
render={(p) => (
|
||||
<ConfigurateBot {...this.props} {...p}/>
|
||||
)}
|
||||
></Route>
|
||||
<Route
|
||||
path={"/zone/:deptId"}
|
||||
render={
|
||||
(props) => {
|
||||
return (<Information {...this.props} {...props} {...this.state} />)
|
||||
}
|
||||
}>
|
||||
</Route>
|
||||
<Route
|
||||
path={"/softwareFactory"}
|
||||
render={
|
||||
(props) => {
|
||||
return (<SoftwareFactory {...this.props} {...props} {...this.state} />)
|
||||
}
|
||||
}>
|
||||
</Route>
|
||||
<Route
|
||||
path={"/settings"}
|
||||
render={
|
||||
(props) => {
|
||||
return (<Security {...this.props} {...props} {...this.state} />)
|
||||
}
|
||||
}>
|
||||
</Route>
|
||||
{/*403*/}
|
||||
<Route path="/403" component={Shixunauthority} />
|
||||
{/*项目*/}
|
||||
<Route
|
||||
path={"/:owner/:projectId/devops/:opsId/detail"}
|
||||
render={
|
||||
(props) => {
|
||||
return (<OpsDetail {...this.props} {...props} {...this.state} />)
|
||||
}
|
||||
}>
|
||||
</Route>
|
||||
{/* 上架bot配置 */}
|
||||
<Route
|
||||
path="/settings/mybot/configuration/:id"
|
||||
render={(p) => (
|
||||
<ConfigurateBot {...this.props} {...p} />
|
||||
)}
|
||||
></Route>
|
||||
<Route
|
||||
path={"/zone/:deptId"}
|
||||
render={
|
||||
(props) => {
|
||||
return (<Information {...this.props} {...props} {...this.state} />)
|
||||
}
|
||||
}>
|
||||
</Route>
|
||||
|
||||
<Route path="/500" component={http500} />
|
||||
<Route
|
||||
path={"/softwareFactory/resource"}
|
||||
render={
|
||||
(props) => {
|
||||
return (<SoftwareFactoryResource {...this.props} {...props} {...this.state} />)
|
||||
}
|
||||
}>
|
||||
</Route>
|
||||
|
||||
{/*404*/}
|
||||
<Route path="/nopage" component={Shixunnopage} />
|
||||
<Route path="/development" component={Development} />
|
||||
<Route
|
||||
path={"/softwareFactory/scene/:sceneId"}
|
||||
render={
|
||||
(props) => {
|
||||
return (<SoftwareFactoryScene {...this.props} {...props} {...this.state} />)
|
||||
}
|
||||
}>
|
||||
</Route>
|
||||
|
||||
{/* 查询 */}
|
||||
<Route path="/search" component={Search} mygetHelmetapi={mygetHelmetapi}/>
|
||||
<Route
|
||||
path={"/softwareFactory"}
|
||||
render={
|
||||
(props) => {
|
||||
return (<SoftwareFactory {...this.props} {...props} {...this.state} />)
|
||||
}
|
||||
}>
|
||||
</Route>
|
||||
|
||||
{/* 项目标签列表页 */}
|
||||
<Route path="/explore/topic/:id/:name" component={Topic} mygetHelmetapi={mygetHelmetapi}/>
|
||||
<Route
|
||||
path={"/settings"}
|
||||
render={
|
||||
(props) => {
|
||||
return (<Security {...this.props} {...props} {...this.state} />)
|
||||
}
|
||||
}>
|
||||
</Route>
|
||||
{/*403*/}
|
||||
<Route path="/403" component={Shixunauthority} />
|
||||
|
||||
<Route exact path="/explore/all"
|
||||
render={
|
||||
(props) => (
|
||||
<ProjectIndex {...this.props} {...props} />
|
||||
)
|
||||
}
|
||||
/>
|
||||
<Route exact path="/explore"
|
||||
render={
|
||||
(props) => (
|
||||
<Store {...this.props} {...props} />
|
||||
)
|
||||
}
|
||||
/>
|
||||
<Route path={"/:OIdentifier/enterprise"}
|
||||
render={
|
||||
(props) => {
|
||||
return (<OrganizeIndex {...props} {...this.props} {...this.state} />)
|
||||
}
|
||||
}>
|
||||
</Route>
|
||||
{/* 关联账号 */}
|
||||
<Route
|
||||
path="/bindlogin/:type"
|
||||
render={(props) =><Relaction {...this.props} {...props} mygetHelmetapi={mygetHelmetapi}/>}
|
||||
></Route>
|
||||
<Route path="/500" component={http500} />
|
||||
|
||||
{/* 登录 */}
|
||||
<Route
|
||||
path="/login"
|
||||
render={(props) =><LoginRegisterPage {...this.props} {...props} mygetHelmetapi={mygetHelmetapi}/>}
|
||||
></Route>
|
||||
|
||||
{/* 注册 */}
|
||||
<Route
|
||||
path="/register"
|
||||
render={(props) =><LoginRegisterPage {...this.props} {...props} mygetHelmetapi={mygetHelmetapi}/>}
|
||||
></Route>
|
||||
{/*404*/}
|
||||
<Route path="/nopage" component={Shixunnopage} />
|
||||
<Route path="/development" component={Development} />
|
||||
|
||||
{/* 忘记密码 */}
|
||||
<Route
|
||||
path="/resetPassword"
|
||||
render={(props) =><LoginRegisterPage {...this.props} {...props} mygetHelmetapi={mygetHelmetapi}/>}
|
||||
></Route>
|
||||
{/* 查询 */}
|
||||
<Route path="/search" component={Search} mygetHelmetapi={mygetHelmetapi} />
|
||||
|
||||
{/* 关于我们 */}
|
||||
<Route
|
||||
path = "/aboutus"
|
||||
render = {(props)=><AboutUs {...this.props} {...props}/>}
|
||||
></Route>
|
||||
{/* 项目标签列表页 */}
|
||||
<Route path="/explore/topic/:id/:name" component={Topic} mygetHelmetapi={mygetHelmetapi} />
|
||||
|
||||
{/* 教学实践 */}
|
||||
<Route
|
||||
path="/educoder"
|
||||
render={(props) => <Teaching {...this.props} {...props} />}
|
||||
></Route>
|
||||
<Route exact path="/explore/all"
|
||||
render={
|
||||
(props) => (
|
||||
<ProjectIndex {...this.props} {...props} />
|
||||
)
|
||||
}
|
||||
/>
|
||||
<Route exact path="/explore"
|
||||
render={
|
||||
(props) => (
|
||||
<Store {...this.props} {...props} />
|
||||
)
|
||||
}
|
||||
/>
|
||||
<Route path={"/:OIdentifier/enterprise"}
|
||||
render={
|
||||
(props) => {
|
||||
return (<OrganizeIndex {...props} {...this.props} {...this.state} />)
|
||||
}
|
||||
}>
|
||||
</Route>
|
||||
{/* 关联账号 */}
|
||||
<Route
|
||||
path="/bindlogin/:type"
|
||||
render={(props) => <Relaction {...this.props} {...props} mygetHelmetapi={mygetHelmetapi} />}
|
||||
></Route>
|
||||
|
||||
{/*glcc */}
|
||||
{/* <Route
|
||||
{/* 登录 */}
|
||||
<Route
|
||||
path="/login"
|
||||
render={(props) => <LoginRegisterPage {...this.props} {...props} mygetHelmetapi={mygetHelmetapi} />}
|
||||
></Route>
|
||||
|
||||
{/* 注册 */}
|
||||
<Route
|
||||
path="/register"
|
||||
render={(props) => <LoginRegisterPage {...this.props} {...props} mygetHelmetapi={mygetHelmetapi} />}
|
||||
></Route>
|
||||
|
||||
{/* 忘记密码 */}
|
||||
<Route
|
||||
path="/resetPassword"
|
||||
render={(props) => <LoginRegisterPage {...this.props} {...props} mygetHelmetapi={mygetHelmetapi} />}
|
||||
></Route>
|
||||
|
||||
{/* 关于我们 */}
|
||||
<Route
|
||||
path="/aboutus"
|
||||
render={(props) => <AboutUs {...this.props} {...props} />}
|
||||
></Route>
|
||||
|
||||
{/* 教学实践 */}
|
||||
<Route
|
||||
path="/educoder"
|
||||
render={(props) => <Teaching {...this.props} {...props} />}
|
||||
></Route>
|
||||
|
||||
{/*glcc */}
|
||||
{/* <Route
|
||||
path="/glcc/:id"
|
||||
render={(props) => <Glcc {...this.props} {...props} />}
|
||||
></Route>
|
||||
|
|
@ -522,80 +555,80 @@ class App extends Component {
|
|||
render={(props) => <Glcc {...this.props} {...props} />}
|
||||
></Route> */}
|
||||
|
||||
{/* soft市场页 */}
|
||||
<Route
|
||||
path="/softbot"
|
||||
render={(props) => (
|
||||
<SoftBot {...this.props} {...props} />
|
||||
)}
|
||||
></Route>
|
||||
{/* soft市场页 */}
|
||||
<Route
|
||||
path="/softbot"
|
||||
render={(props) => (
|
||||
<SoftBot {...this.props} {...props} />
|
||||
)}
|
||||
></Route>
|
||||
|
||||
{/* 组织 */}
|
||||
<Route path={"/organize"}
|
||||
render={
|
||||
(props) => {
|
||||
return (<OrganizeIndex {...props} {...this.props} {...this.state} />)
|
||||
}
|
||||
}>
|
||||
</Route>
|
||||
|
||||
{/*新建项目等*/}
|
||||
<Route
|
||||
path={"/projects"}
|
||||
render={
|
||||
(props) => {
|
||||
return (<Projects {...this.props} {...props} {...this.state} />)
|
||||
}
|
||||
}>
|
||||
</Route>
|
||||
<Route
|
||||
path={"/governance"}
|
||||
render={
|
||||
(props) => {
|
||||
return (<GovernanceIframe {...this.props} {...props} {...this.state} />)
|
||||
}
|
||||
}>
|
||||
</Route>
|
||||
{/* 组织 */}
|
||||
<Route path={"/organize"}
|
||||
render={
|
||||
(props) => {
|
||||
return (<OrganizeIndex {...props} {...this.props} {...this.state} />)
|
||||
}
|
||||
}>
|
||||
</Route>
|
||||
|
||||
{/* 判断为用户/组织,并进入对应页面 */}
|
||||
{
|
||||
pathType === 'User' ?
|
||||
<Route exact path="/:username"
|
||||
{/*新建项目等*/}
|
||||
<Route
|
||||
path={"/projects"}
|
||||
render={
|
||||
(props) => {
|
||||
return (<Projects {...this.props} {...props} {...this.state} />)
|
||||
}
|
||||
}>
|
||||
</Route>
|
||||
<Route
|
||||
path={"/governance"}
|
||||
render={
|
||||
(props) => {
|
||||
return (<GovernanceIframe {...this.props} {...props} {...this.state} />)
|
||||
}
|
||||
}>
|
||||
</Route>
|
||||
|
||||
{/* 判断为用户/组织,并进入对应页面 */}
|
||||
{
|
||||
pathType === 'User' ?
|
||||
<Route exact path="/:username"
|
||||
render={
|
||||
(props) => {
|
||||
return (<InfosIndex {...this.props} {...this.state} />)
|
||||
}
|
||||
}
|
||||
/> : pathType === 'Organization' ? <Route path={"/:OIdentifier"}
|
||||
render={
|
||||
(props) => {
|
||||
return (<OrganizeIndex {...props} {...this.props} {...this.state} />)
|
||||
}
|
||||
}>
|
||||
</Route> : pathType === '404' ? <Route component={Shixunnopage} /> :
|
||||
""
|
||||
}
|
||||
{/* 个人主页 */}
|
||||
<Route path="/:username"
|
||||
render={
|
||||
(props) => {
|
||||
return (<InfosIndex {...this.props} {...this.state} />)
|
||||
}
|
||||
}></Route>
|
||||
|
||||
|
||||
<Route component={Shixunnopage} />
|
||||
</Switch>
|
||||
:
|
||||
<Route exact path="/"
|
||||
render={
|
||||
(props) => {
|
||||
return (<InfosIndex {...this.props} {...this.state} />)
|
||||
}
|
||||
(props) => (
|
||||
<Home {...props} {...this.props} {...this.state} />
|
||||
)
|
||||
}
|
||||
/> : pathType === 'Organization' ? <Route path={"/:OIdentifier"}
|
||||
render={
|
||||
(props) => {
|
||||
return (<OrganizeIndex {...props} {...this.props} {...this.state} />)
|
||||
}
|
||||
}>
|
||||
</Route> : pathType === '404' ? <Route component={Shixunnopage} />:
|
||||
""
|
||||
}
|
||||
{/* 个人主页 */}
|
||||
<Route path="/:username"
|
||||
render={
|
||||
(props) => {
|
||||
return (<InfosIndex {...this.props} {...this.state} />)
|
||||
}
|
||||
}></Route>
|
||||
|
||||
|
||||
<Route component={Shixunnopage} />
|
||||
</Switch>
|
||||
:
|
||||
<Route exact path="/"
|
||||
render={
|
||||
(props) => (
|
||||
<Home {...props} {...this.props} {...this.state}/>
|
||||
)
|
||||
}
|
||||
/>
|
||||
/>
|
||||
}
|
||||
|
||||
|
||||
</MuiThemeProvider>
|
||||
</ConfigProvider>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
export const factoryZoneId = 201
|
||||
|
|
@ -22,4 +22,29 @@ export function getProjectsLists(id,params){
|
|||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取资源列表
|
||||
* @param {*} params
|
||||
* @returns
|
||||
*/
|
||||
export function getSourceList(params){
|
||||
return fetch({
|
||||
url:`/zone/open/${params.id}/resource/list`,
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取资源领域列表
|
||||
* @param {*} id
|
||||
* @returns
|
||||
*/
|
||||
export function getSourceZoneList(id){
|
||||
return fetch({
|
||||
url:`/zone/open/${id}/resourceDomain/list`,
|
||||
method: 'get',
|
||||
})
|
||||
}
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
.shiny-button {
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
border: 2px solid transparent;
|
||||
background-clip: padding-box, border-box;
|
||||
background-image: linear-gradient(to bottom right, #0b0333, #091221), linear-gradient(125deg, hsla(0, 0%, 100%, 0) 45%, hsla(0, 0%, 100%, .6) 50%, hsla(0, 0%, 100%, 0) 53%);
|
||||
background-origin: border-box;
|
||||
background-position: 0, -50%;
|
||||
background-size: 100%, 200%;
|
||||
|
||||
&::after {
|
||||
animation: glint 4s linear infinite backwards;
|
||||
animation-delay: -3s;
|
||||
background-image: linear-gradient(125deg, hsla(0, 0%, 100%, 0) 30%, hsla(0, 0%, 100%, .4) 50%, hsla(0, 0%, 100%, 0) 52%);
|
||||
content: " ";
|
||||
height: 200%;
|
||||
left: -120%;
|
||||
position: absolute;
|
||||
top: -50%;
|
||||
width: 200%;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
animation: border-glint 2s linear;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes border-glint {
|
||||
|
||||
0% {
|
||||
background-position: 0, 115%;
|
||||
}
|
||||
|
||||
25% {
|
||||
background-position: 0, 75%;
|
||||
}
|
||||
|
||||
75% {
|
||||
background-position: 0, -15%;
|
||||
}
|
||||
|
||||
100% {
|
||||
background-position: 0, -15%;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes glint {
|
||||
0% {
|
||||
left: -120%;
|
||||
}
|
||||
|
||||
8% {
|
||||
left: 50%;
|
||||
}
|
||||
|
||||
100% {
|
||||
left: 50%;
|
||||
}
|
||||
}
|
||||
|
|
@ -69,7 +69,7 @@ function News(props) {
|
|||
</div>
|
||||
<div className="news-1">
|
||||
<div className="news-1-left">
|
||||
<Carousel ref={carouselEL} afterChange={setCurrent}>
|
||||
<Carousel autoplay ref={carouselEL} afterChange={setCurrent}>
|
||||
{mainList.map(item => {
|
||||
return <div className="news-1-item">
|
||||
<div className="news-1-item-img">
|
||||
|
|
@ -85,9 +85,9 @@ function News(props) {
|
|||
</Carousel>
|
||||
</div>
|
||||
<div className="news-1-right">
|
||||
<h4>专区新闻</h4>
|
||||
<h4>热门新闻</h4>
|
||||
<div className="news-1-right-img">
|
||||
<img src={news.headImg || backList[getRandomNum() - 1]} alt="" />
|
||||
<img src={news.headImg || backList[1]} alt="" />
|
||||
</div>
|
||||
<div className="news-1-right-title">
|
||||
<h5>{news.name}</h5>
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ const Scene = ({ zoneId }) => {
|
|||
return <div className="scene-item" key={index}>
|
||||
<h3>{scene.name}</h3>
|
||||
<p>{scene.value}</p>
|
||||
<Link to={`/`}>
|
||||
<Link to={`/softwareFactory/scene/${index + 1}`}>
|
||||
<span>查看详情</span>
|
||||
<KFIcon type="icon-icon_blackarrow_hover" font={40}/>
|
||||
</Link>
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ function Index(props) {
|
|||
<div className="banner-content-button">立即体验</div>
|
||||
</Link>
|
||||
</div>
|
||||
<div className="banner-data">
|
||||
{/* <div className="banner-data">
|
||||
{
|
||||
bannerData.map(e => {
|
||||
return <div className="data-item" key={e.name}>
|
||||
|
|
@ -104,12 +104,33 @@ function Index(props) {
|
|||
</div>
|
||||
})
|
||||
}
|
||||
</div>
|
||||
</div> */}
|
||||
</div>
|
||||
<div className={`factory-video factory-module ${isVisible ? 'animate-active' : ''}`} ref={contentRef}>
|
||||
<h1 className="module-title">软件工厂 宣传视频</h1>
|
||||
<video src=""></video>
|
||||
</div>
|
||||
|
||||
|
||||
<div className='test'>
|
||||
<div className='custom-bulge'></div>
|
||||
<div className='custom-bulge1'></div>
|
||||
<div className='custom-bulge2'></div>
|
||||
<div className='custom-bulge3'></div>
|
||||
{/* <div className='custom-bulge5'></div> */}
|
||||
<div className='custom-bulge6'></div>
|
||||
</div>
|
||||
<div className='test2'>
|
||||
<div className='custom-bulge'></div>
|
||||
<div className='custom-bulge1'></div>
|
||||
{/* <div className='custom-bulge2'></div> */}
|
||||
<div className='custom-bulge3'></div>
|
||||
<div className='custom-bulge5'></div>
|
||||
<div className='custom-bulge6'></div>
|
||||
</div>
|
||||
|
||||
{/* <div class="shiny-button--JZkaI7wUAAp4lJdY cursor-pointer">免费使用</div> */}
|
||||
|
||||
<News zoneId={zoneId} />
|
||||
<Feature />
|
||||
<Resource zoneId={zoneId} ref={resourceRef} />
|
||||
|
|
@ -118,4 +139,4 @@ function Index(props) {
|
|||
</div>
|
||||
)
|
||||
}
|
||||
export default TPMIndexHOC(Index)
|
||||
export default TPMIndexHOC(Index)
|
||||
|
|
|
|||
|
|
@ -187,4 +187,335 @@
|
|||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
// .custom-bulge {
|
||||
// width: 300px;
|
||||
// height: 150px;
|
||||
// background: #2ecc71;
|
||||
// clip-path: path('M0,150 Q150,0 300,150 L300,150 L0,150 Z');
|
||||
// /* 起点(0,150) → 控制点(150,0) → 终点(300,150) */
|
||||
// }
|
||||
.test {
|
||||
position: relative;
|
||||
.custom-bulge3 {
|
||||
animation: custom-bulge-animation1 5s linear infinite;
|
||||
animation-delay: 4s;
|
||||
}
|
||||
|
||||
.custom-bulge4 {
|
||||
animation: custom-bulge-animation3 6s linear infinite;
|
||||
animation-delay: 1.4s;
|
||||
}
|
||||
|
||||
.custom-bulge5 {
|
||||
animation: custom-bulge-animation4 5.5s linear infinite;
|
||||
animation-delay: 2.8s;
|
||||
}
|
||||
|
||||
.custom-bulge6 {
|
||||
animation: custom-bulge-animation4 7s linear infinite;
|
||||
animation-delay: 0.6.4s;
|
||||
}
|
||||
}
|
||||
.custom-bulge {
|
||||
height: 150px;
|
||||
background: linear-gradient(360deg, rgba(67, 97, 238, 0.2) 0%, rgba(114, 9, 183, 0.3) 100%);
|
||||
clip-path: path('M0,150 C100,140 200,50 300,50 C400,50 500,140 600,150 L600,150 L0,150 Z');
|
||||
animation: custom-bulge-animation 6s linear infinite;
|
||||
}
|
||||
|
||||
.custom-bulge1 {
|
||||
height: 150px;
|
||||
background: linear-gradient(360deg, rgba(67, 97, 238, 0.2) 0%, rgba(114, 9, 183, 0.3) 100%);
|
||||
|
||||
clip-path: path('M0,150 C100,150 200,100 300,100 C400,100 500,150 600,150 L600,150 L0,150 Z');
|
||||
animation: custom-bulge-animation1 7s linear infinite;
|
||||
animation-delay: 1s;
|
||||
}
|
||||
|
||||
.custom-bulge2 {
|
||||
height: 50px;
|
||||
background: linear-gradient(360deg, rgba(67, 97, 238, 0.2) 0%, rgba(114, 9, 183, 0.3) 100%);
|
||||
clip-path: path('M0,50 C100,45 270,10 300,10 C330,10 500,45 600,50 L600,50 L0,50 Z');
|
||||
animation: custom-bulge-animation2 4s linear infinite;
|
||||
animation-delay: 3s;
|
||||
}
|
||||
.test2 {
|
||||
margin-bottom: 200px;
|
||||
transform: rotate(180deg);
|
||||
div {
|
||||
right: 0;
|
||||
}
|
||||
.custom-bulge {
|
||||
animation: custom-bulge-animation-b 6s linear infinite;
|
||||
animation-delay: 2s ;
|
||||
}
|
||||
|
||||
.custom-bulge1 {
|
||||
animation: custom-bulge-animation1-b 7s linear infinite;
|
||||
}
|
||||
|
||||
.custom-bulge2 {
|
||||
animation: custom-bulge-animation2-b 4s linear infinite;
|
||||
animation-delay: 1.2s;
|
||||
}
|
||||
.custom-bulge3 {
|
||||
animation: custom-bulge-animation1-b 5s linear infinite;
|
||||
animation-delay: 3s;
|
||||
}
|
||||
|
||||
.custom-bulge4 {
|
||||
animation: custom-bulge-animation3-b 6s linear infinite;
|
||||
animation-delay: 4s;
|
||||
}
|
||||
|
||||
.custom-bulge5 {
|
||||
animation: custom-bulge-animation4-b 5.5s linear infinite;
|
||||
animation-delay: 4s;
|
||||
}
|
||||
|
||||
.custom-bulge6 {
|
||||
animation: custom-bulge-animation4-b 7s linear infinite;
|
||||
animation-delay: 0.4s;
|
||||
}
|
||||
}
|
||||
.custom-bulge, .custom-bulge1, .custom-bulge2, .custom-bulge3, .custom-bulge4, .custom-bulge5, .custom-bulge6 {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
width: 600px;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.custom-bulge3, .custom-bulge4, .custom-bulge5, .custom-bulge6 {
|
||||
width: 600px;
|
||||
height: 150px;
|
||||
background: linear-gradient(360deg, rgba(67, 97, 238, 0.2) 0%, rgba(114, 9, 183, 0.3) 100%);
|
||||
clip-path: path('M0,150 C100,150 200,140 300,140 C400,140 500,150 600,150 L600,150 L0,150 Z');
|
||||
}
|
||||
|
||||
@keyframes custom-bulge-animation {
|
||||
0% {
|
||||
opacity: 0;
|
||||
}
|
||||
50% {
|
||||
opacity: 0.2;
|
||||
clip-path: path('M0,150 C100,140 250,20 300,30 C350,20 500,140 600,150 L600,150 L0,150 Z');
|
||||
transform: translate(50%, 0);
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
transform: translate(100%, 0);
|
||||
clip-path: path('M0,150 C100,140 250,120 300,130 C350,120 500,140 600,150 L600,150 L0,150 Z');
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes custom-bulge-animation1 {
|
||||
0% {
|
||||
opacity: 0;
|
||||
}
|
||||
50% {
|
||||
opacity: 0.25;
|
||||
transform: translate(50%, 0);
|
||||
clip-path: path('M0,150 C100,140 200,50 300,50 C400,50 500,140 600,150 L600,150 L0,150 Z');
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
transform: translate(100%, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@keyframes custom-bulge-animation2 {
|
||||
0% {
|
||||
opacity: 0;
|
||||
}
|
||||
50% {
|
||||
opacity: 0.25;
|
||||
transform: translate(50%, 0);
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
transform: translate(100%, 0);
|
||||
clip-path: path('M0,50 C100,45 270,45 300,45 C330,45 500,45 600,50 L600,50 L0,50 Z');
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes custom-bulge-animation3 {
|
||||
0% {
|
||||
opacity: 0;
|
||||
}
|
||||
50% {
|
||||
opacity: 0.2;
|
||||
transform: translate(50%, 0);
|
||||
clip-path: path('M0,150 C100,120 270,50 300,60 C330,50 500,120 600,150 L600,150 L0,150 Z');
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
transform: translate(100%, 0);
|
||||
clip-path: path('M0,150 C100,145 270,145 300,145 C330,145 500,145 600,150 L600,150 L0,150 Z');
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes custom-bulge-animation4 {
|
||||
0% {
|
||||
opacity: 0;
|
||||
}
|
||||
50% {
|
||||
opacity: 0.2;
|
||||
transform: translate(50%, 0);
|
||||
clip-path: path('M0,150 C100,120 270,130 300,130 C330,130 500,120 600,150 L600,150 L0,150 Z');
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
transform: translate(100%, 0);
|
||||
clip-path: path('M0,150 C100,145 270,145 300,145 C330,145 500,145 600,150 L600,150 L0,150 Z');
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes custom-bulge-animation-b {
|
||||
0% {
|
||||
opacity: 0;
|
||||
}
|
||||
50% {
|
||||
opacity: 0.2;
|
||||
clip-path: path('M0,150 C100,140 250,20 300,30 C350,20 500,140 600,150 L600,150 L0,150 Z');
|
||||
transform: translate(-50%, 0);
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
transform: translate(-100%, 0);
|
||||
clip-path: path('M0,150 C100,140 250,120 300,130 C350,120 500,140 600,150 L600,150 L0,150 Z');
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes custom-bulge-animation1-b {
|
||||
0% {
|
||||
opacity: 0;
|
||||
}
|
||||
50% {
|
||||
opacity: 0.25;
|
||||
transform: translate(-50%, 0);
|
||||
clip-path: path('M0,150 C100,140 200,50 300,50 C400,50 500,140 600,150 L600,150 L0,150 Z');
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
transform: translate(-100%, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@keyframes custom-bulge-animation2-b {
|
||||
0% {
|
||||
opacity: 0;
|
||||
}
|
||||
50% {
|
||||
opacity: 0.25;
|
||||
transform: translate(-50%, 0);
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
transform: translate(-100%, 0);
|
||||
clip-path: path('M0,50 C100,45 270,45 300,45 C330,45 500,45 600,50 L600,50 L0,50 Z');
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes custom-bulge-animation3-b {
|
||||
0% {
|
||||
opacity: 0;
|
||||
}
|
||||
50% {
|
||||
opacity: 0.2;
|
||||
transform: translate(-50%, 0);
|
||||
clip-path: path('M0,150 C100,120 270,50 300,60 C330,50 500,120 600,150 L600,150 L0,150 Z');
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
transform: translate(-100%, 0);
|
||||
clip-path: path('M0,150 C100,145 270,145 300,145 C330,145 500,145 600,150 L600,150 L0,150 Z');
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes custom-bulge-animation4-b {
|
||||
0% {
|
||||
opacity: 0;
|
||||
}
|
||||
50% {
|
||||
opacity: 0.2;
|
||||
transform: translate(-50%, 0);
|
||||
clip-path: path('M0,150 C100,120 270,130 300,130 C330,130 500,120 600,150 L600,150 L0,150 Z');
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
transform: translate(-100%, 0);
|
||||
clip-path: path('M0,150 C100,145 270,145 300,145 C330,145 500,145 600,150 L600,150 L0,150 Z');
|
||||
}
|
||||
}
|
||||
|
||||
.shiny-button--JZkaI7wUAAp4lJdY {
|
||||
align-items: center;
|
||||
animation: border-glint--K_SFVkOnnAzSsAUT 4s
|
||||
linear infinite backwards;
|
||||
animation-delay: 1s;
|
||||
background-clip: padding-box, border-box;
|
||||
background-color: #212635;
|
||||
background-image: linear-gradient(to bottom right, #0b0333, #212635), linear-gradient(125deg, hsla(0, 0%, 100%, 0) 45%, hsla(0, 0%, 100%, .6) 50%, hsla(0, 0%, 100%, 0) 53%);
|
||||
background-origin: border-box;
|
||||
background-position: 0, -250px;
|
||||
background-size: 100%, 200%;
|
||||
border: 3px solid transparent;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 4px 16px 0 rgba(0, 0, 0, .14);
|
||||
color: #fff;
|
||||
display: flex;
|
||||
font-size: 22px;
|
||||
font-weight: 600;
|
||||
height: 60px;
|
||||
justify-content: center;
|
||||
line-height: 32px;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
width: 180px;
|
||||
z-index: 1;
|
||||
&::after {
|
||||
animation: glint--T_al5iHMf8JL_lRa 4s
|
||||
linear infinite backwards;
|
||||
animation-delay: -3s;
|
||||
background-image: linear-gradient(125deg, hsla(0, 0%, 100%, 0) 30%, hsla(0, 0%, 100%, .4) 50%, hsla(0, 0%, 100%, 0) 52%);
|
||||
content: " ";
|
||||
height: 200%;
|
||||
left: -120%;
|
||||
position: absolute;
|
||||
top: -50%;
|
||||
width: 200%;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes border-glint--K_SFVkOnnAzSsAUT {
|
||||
|
||||
0% {
|
||||
background-position: 0, -250px;
|
||||
}
|
||||
25% {
|
||||
background-position: 0, -200px;
|
||||
}
|
||||
|
||||
75% {
|
||||
background-position: 0, 50px;
|
||||
}
|
||||
100% {
|
||||
background-position: 0, 50px;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes glint--T_al5iHMf8JL_lRa {
|
||||
0% {
|
||||
left: -120%;
|
||||
}
|
||||
8% {
|
||||
left: 50%;
|
||||
}
|
||||
100% {
|
||||
left: 50%;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
import React from 'react';
|
||||
import './index.scss';
|
||||
|
||||
function ActionItem(props) {
|
||||
const childrenArray = React.Children.toArray(props.children);
|
||||
const contentChild = childrenArray[0];
|
||||
const buttonsChild = childrenArray[1];
|
||||
|
||||
// 获取 padding 值,处理各种格式
|
||||
const getPaddingValue = (padding) => {
|
||||
if (!padding) return '1.5px';
|
||||
|
||||
// 如果是数字,添加 px
|
||||
if (!isNaN(padding) && !padding.includes('px') && !padding.includes('%') && !padding.includes('rem') && !padding.includes('em')) {
|
||||
return `${padding}px`;
|
||||
}
|
||||
|
||||
return padding;
|
||||
};
|
||||
|
||||
const paddingValue = getPaddingValue(props.padding);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`action-item ${props.className || ''}`}
|
||||
style={{
|
||||
'--item-padding': paddingValue,
|
||||
borderRadius: props.borderRadius || '12px',
|
||||
backgroundColor: props.backgroundColor || '',
|
||||
}}
|
||||
>
|
||||
<div className="action-item_content">
|
||||
{contentChild || null}
|
||||
</div>
|
||||
|
||||
<div className="action-item_buttons">
|
||||
{buttonsChild || null}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default ActionItem;
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
.action-item {
|
||||
--item-padding: 1.5px; // 默认值
|
||||
|
||||
width: fit-content;
|
||||
height: fit-content;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
|
||||
// 应用 CSS 变量到 padding
|
||||
padding: var(--item-padding);
|
||||
|
||||
&:before {
|
||||
content: "";
|
||||
display: block;
|
||||
left: 50%;
|
||||
padding-bottom: 200%;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 200%;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
&_content {
|
||||
z-index: 1;
|
||||
width: fit-content;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
&_buttons {
|
||||
z-index: 2;
|
||||
position: absolute;
|
||||
bottom: calc(-100% - var(--item-padding)); // 隐藏时完全移出
|
||||
transition: bottom 0.3s ease-in-out;
|
||||
width: 100%;
|
||||
left: 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.action-item_buttons {
|
||||
bottom: var(--item-padding); // 上浮到 padding 位置
|
||||
}
|
||||
|
||||
@keyframes rotate {
|
||||
0% {
|
||||
transform: translate(-50%, -50%) rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
transform: translate(-50%, -50%) rotate(-1turn);
|
||||
}
|
||||
}
|
||||
|
||||
&:before {
|
||||
animation: rotate 8s linear infinite;
|
||||
background: conic-gradient(
|
||||
from 180deg at 50% 50%,
|
||||
#9a8bff 0deg,
|
||||
#ffac8b 45deg,
|
||||
transparent 90deg,
|
||||
transparent 180deg,
|
||||
#9a8bff 180deg,
|
||||
#ffac8b 225deg,
|
||||
transparent 270deg
|
||||
);
|
||||
z-index: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,190 @@
|
|||
import React, { useEffect, useState, useRef } from 'react';
|
||||
import './index.scss';
|
||||
import { getSourceList, getSourceZoneList } from '../../api'
|
||||
// import { factoryZoneId } from '../../../constants/factory'
|
||||
import KFIcon from '../../../components/KFIcon';
|
||||
import bg1 from '../../../images/factory/resource/tools-top-1.webp';
|
||||
import bg2 from '../../../images/factory/resource/tools-top-2.webp';
|
||||
import bg3 from '../../../images/factory/resource/tools-top-3.webp';
|
||||
|
||||
import bg4 from '../../../images/factory/resource/tools-bottom-1.webp';
|
||||
import bg5 from '../../../images/factory/resource/tools-bottom-2.webp';
|
||||
|
||||
import ActionItem from '../components/ActionItem';
|
||||
import '../../common.scss'
|
||||
|
||||
const bgList = [bg1, bg2, bg3]
|
||||
|
||||
const bg2List = [bg4, bg5]
|
||||
|
||||
const factoryZoneId = 199
|
||||
|
||||
function Index(props) {
|
||||
|
||||
const [topList, setTopList] = useState([]);
|
||||
const [contentList, setContentList] = useState([]);
|
||||
const [fullList, setFullList] = useState([]);
|
||||
const [zoneList, setZoneList] = useState([]);
|
||||
const [newList, setNewList] = useState([]);
|
||||
const [selectedType, setSelectedType] = useState(null);
|
||||
|
||||
useEffect(() => {
|
||||
getFullList();
|
||||
getTypeList();
|
||||
}, []);
|
||||
|
||||
const getFullList = () => {
|
||||
|
||||
getSourceList({ id: factoryZoneId }).then(res => {
|
||||
setTopList(res.data.rows.slice(0, 3));
|
||||
setNewList(res.data.rows.slice(0, 2));
|
||||
setContentList(res.data.rows.slice(3, 9));
|
||||
setFullList(res.data.rows.slice(9));
|
||||
});
|
||||
};
|
||||
|
||||
const getTypeList = () => {
|
||||
getSourceZoneList(factoryZoneId).then(response => {
|
||||
if (response && response.data) {
|
||||
setZoneList(response.data.rows);
|
||||
}
|
||||
}).catch(error => { })
|
||||
}
|
||||
|
||||
const getBackgroundImage = (index) => {
|
||||
const row = Math.floor(index / 4); // 行号
|
||||
const col = index % 4; // 列号(行内位置)
|
||||
|
||||
// 偶数行:背景图索引为 0,1,0,1...
|
||||
// 奇数行:背景图索引为 1,0,1,0...
|
||||
return row % 2 === 0
|
||||
? bg2List[col % 2] // 偶数行:0,1,0,1
|
||||
: bg2List[(col + 1) % 2]; // 奇数行:1,0,1,0
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="tools">
|
||||
<div className="tools-top">
|
||||
{
|
||||
topList.map((item, index) => {
|
||||
return (
|
||||
<div className="tools-top-item" key={index}>
|
||||
<img src={bgList[index]} alt="" className="item-bg" />
|
||||
<div className="item-info">
|
||||
<h5 className="item-title">
|
||||
{item.name}
|
||||
</h5>
|
||||
<span className="item-tag">{item.domainName}</span>
|
||||
<p className="item-desc">{item.summary}</p>
|
||||
</div>
|
||||
<button>立即下载</button>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
}
|
||||
</div>
|
||||
|
||||
<div className="tools-types">
|
||||
<div>工具分类</div>
|
||||
{
|
||||
zoneList.map((item, index) => {
|
||||
return (
|
||||
<span className={`type-item ${selectedType === item.id ? 'active' : ''}`} key={index} onClick={() => setSelectedType(item.id)}>{item.name}</span>
|
||||
)
|
||||
})
|
||||
}
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div className="tools-content">
|
||||
<div className="tools-content-hot">
|
||||
<div className="tools-content-hot-title">
|
||||
<h5>热门工具</h5>
|
||||
<span data-text="更强工具、更易落地、更高效率">更强工具、更易落地、更高效率</span>
|
||||
</div>
|
||||
<div className="tools-content-hot-list">
|
||||
{
|
||||
contentList.map((item, index) => {
|
||||
const createUser = item.createUser
|
||||
return <ActionItem className="hot-item-wrapper" key={index} padding="1px" borderRadius="16px">
|
||||
<div className="hot-item">
|
||||
<img src={createUser.avatar} alt="" className="item-img"></img>
|
||||
<div className="item-info">
|
||||
<h5 className="item-title">{item.name}</h5>
|
||||
<p className="item-desc">
|
||||
{item.summary}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div className="two-btn">
|
||||
<button className="shiny-button">查看</button>
|
||||
<button className="shiny-button">下载</button>
|
||||
</div>
|
||||
</ActionItem>
|
||||
})
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<div className="tools-content-new">
|
||||
<div className="tools-content-new-title">
|
||||
<h5>最新工具</h5>
|
||||
<span data-text="更强工具、更易落地、更高效率">更强工具、更易落地、更高效率</span>
|
||||
</div>
|
||||
<div className="tools-content-new-list">
|
||||
{
|
||||
newList.map((item, index) => {
|
||||
const createUser = item.createUser
|
||||
return <div className="new-item">
|
||||
<img src={createUser.avatar} alt="" className="item-img"></img>
|
||||
<div className="item-info">
|
||||
<h5 className="item-title">{item.name}</h5>
|
||||
<p className="item-desc">
|
||||
{item.summary}
|
||||
</p>
|
||||
<button>下载</button>
|
||||
</div>
|
||||
</div>
|
||||
})
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="tools-bottom">
|
||||
{
|
||||
fullList.map((item, index) => {
|
||||
const createUser = item.createUser
|
||||
return <ActionItem className="content-bottom-wrapper" key={index} backgroundColor="rgba(241, 247, 255, 0.48)" padding="1px" borderRadius="16px">
|
||||
<div className="content-bottom-item">
|
||||
|
||||
<img src={getBackgroundImage(index)} alt="" className="item-bg" />
|
||||
<div className="item-top">
|
||||
<img src={createUser.avatar} alt="" className="item-img"></img>
|
||||
<h5 className="item-title">{item.name}</h5>
|
||||
</div>
|
||||
<div className="item-desc">
|
||||
{item.summary}
|
||||
</div>
|
||||
<div className="item-data">
|
||||
<span><i className="iconfont icon-liulanliang mr5 font-12" />{item.downloadCount}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="content-bottom-btn">
|
||||
<div className="two-btn">
|
||||
<button className="shiny-button">查看</button>
|
||||
<button className="shiny-button">下载</button>
|
||||
</div>
|
||||
</div>
|
||||
</ActionItem>
|
||||
})
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default Index
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,471 @@
|
|||
.tools {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
margin-top: -50px;
|
||||
|
||||
&-top {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
|
||||
&-item {
|
||||
width: 516px;
|
||||
height: 230px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 32px 28px 38px 28px;
|
||||
margin-right: 26px;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
border-radius: 16px;
|
||||
color: #091221;
|
||||
|
||||
.item-bg {
|
||||
width: 518px;
|
||||
height: 232px;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
z-index: -1;
|
||||
transition: transform 0.3s ease-in-out;
|
||||
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.item-bg {
|
||||
transform: scale(1.1);
|
||||
}
|
||||
}
|
||||
|
||||
.item-info {
|
||||
font-size: 15px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
|
||||
h5 {
|
||||
line-height: 30px;
|
||||
font-family: alibabareg;
|
||||
font-size: 22px;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
color: #091221;
|
||||
align-items: center;
|
||||
margin-right: 150px;
|
||||
}
|
||||
|
||||
.item-tag {
|
||||
position: absolute;
|
||||
display: inline-block;
|
||||
right: 0;
|
||||
padding: 0 8px;
|
||||
background: rgba(255, 255, 255, 0.57);
|
||||
border-radius: 4px;
|
||||
height: 26px;
|
||||
line-height: 26px;
|
||||
font-family: Alibabareg;
|
||||
font-size: 13px;
|
||||
background: rgba(22, 76, 228, 0.07);
|
||||
color: #164ce4;
|
||||
}
|
||||
|
||||
p {
|
||||
line-height: 24px;
|
||||
font-family: alibabareg;
|
||||
margin-top: 13px;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
margin-right: 150px;
|
||||
}
|
||||
}
|
||||
|
||||
button {
|
||||
cursor: pointer;
|
||||
margin-top: auto;
|
||||
width: 104px;
|
||||
height: 36px;
|
||||
background: rgba(255, 255, 255, 0.42);
|
||||
border: 1px solid;
|
||||
border-color: #091221;
|
||||
border-radius: 9px;
|
||||
line-height: 36px;
|
||||
font-family: alibaba;
|
||||
font-weight: 500;
|
||||
color: #091221;
|
||||
font-size: 14px;
|
||||
|
||||
&:hover {
|
||||
border: 1px solid;
|
||||
border-color: #164ce4;
|
||||
color: #164ce4;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
&:nth-child(2) {
|
||||
color: #ffffff;
|
||||
|
||||
h5 {
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.item-tag {
|
||||
color: #ffffff;
|
||||
background: rgba(255, 255, 255, 0.13);
|
||||
}
|
||||
|
||||
button {
|
||||
border: none;
|
||||
background: #ffffff;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-types {
|
||||
margin-top: 23px;
|
||||
width: 1600px;
|
||||
height: 88px;
|
||||
background: #ffffffa6;
|
||||
border-radius: 16px;
|
||||
padding: 32px 30px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
div {
|
||||
line-height: 22px;
|
||||
font-family: alibaba;
|
||||
font-weight: 500;
|
||||
color: #091221;
|
||||
font-size: 16px;
|
||||
position: relative;
|
||||
margin-right: 41px;
|
||||
|
||||
&::after {
|
||||
top: 50%;
|
||||
right: -20.5px;
|
||||
transform: translate(0, -50%);
|
||||
position: absolute;
|
||||
content: "";
|
||||
width: 1px;
|
||||
height: 14px;
|
||||
border: 1px solid;
|
||||
border-color: rgba(9, 18, 33, 0.14);
|
||||
}
|
||||
}
|
||||
|
||||
.type-item {
|
||||
cursor: pointer;
|
||||
margin-right: 18px;
|
||||
line-height: 22px;
|
||||
font-family: alibabareg;
|
||||
color: #091221;
|
||||
font-size: 16px;
|
||||
display: inline-block;
|
||||
padding: 5px 8px;
|
||||
}
|
||||
|
||||
.active {
|
||||
background: rgba(22, 76, 228, 0.04);
|
||||
border-radius: 6px;
|
||||
}
|
||||
}
|
||||
|
||||
.item-title {
|
||||
line-height: 30px;
|
||||
font-family: alibaba;
|
||||
font-weight: 500;
|
||||
color: #091221;
|
||||
font-size: 22px;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.item-desc {
|
||||
margin-top: 18px;
|
||||
line-height: 21px;
|
||||
font-family: alibabareg;
|
||||
color: #091221;
|
||||
font-size: 15px;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 1;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.two-btn {
|
||||
width: 438px;
|
||||
height: 83px;
|
||||
background: linear-gradient(180deg, rgba(248, 251, 255, 0.13) 0%, rgba(248, 251, 255, 0.93) 23.71%, #f8fbff 100%);
|
||||
border-radius: 0px 0px 16px 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
button {
|
||||
width: 125px;
|
||||
height: 36px;
|
||||
line-height: 36px;
|
||||
cursor: pointer;
|
||||
border-radius: 9px;
|
||||
line-height: 20px;
|
||||
font-family: alibaba;
|
||||
font-weight: 500;
|
||||
color: #ffffff;
|
||||
font-size: 14px;
|
||||
text-align: center;
|
||||
background-color: #091221;
|
||||
}
|
||||
|
||||
button:nth-child(2) {
|
||||
margin-left: 21px;
|
||||
color: #091221;
|
||||
background-color: #ffffff;
|
||||
background-image: none;
|
||||
border: 1px solid #091221;
|
||||
}
|
||||
}
|
||||
|
||||
&-content {
|
||||
margin-top: 33px;
|
||||
width: 1600px;
|
||||
display: flex;
|
||||
|
||||
&-hot,
|
||||
&-new {
|
||||
height: 564px;
|
||||
background: #ffffff;
|
||||
border-radius: 16px;
|
||||
padding: 40px 30px;
|
||||
|
||||
&-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
h5 {
|
||||
line-height: 33px;
|
||||
font-family: alibaba;
|
||||
font-weight: 500;
|
||||
color: #091221;
|
||||
font-size: 24px;
|
||||
margin-bottom: 0;
|
||||
margin-right: 14px;
|
||||
}
|
||||
|
||||
span {
|
||||
background: linear-gradient(88.34deg, #e3efff 0.19%, #e6e2ff 99.89%);
|
||||
border-radius: 4px;
|
||||
display: inline-block;
|
||||
padding: 7px 8px;
|
||||
color: linear-gradient(89.28deg, #164ce4 2.18%, #a13dd9 95.44%);
|
||||
font-size: 12px;
|
||||
line-height: 12px;
|
||||
position: relative;
|
||||
color: transparent;
|
||||
z-index: 1;
|
||||
|
||||
&::before {
|
||||
content: attr(data-text);
|
||||
/* 显示相同的文本 */
|
||||
position: absolute;
|
||||
top: 7px;
|
||||
left: 8px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(89.28deg, #164ce4 2.18%, #a13dd9 95.44%);
|
||||
-webkit-background-clip: text;
|
||||
background-clip: text;
|
||||
color: transparent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-list {
|
||||
margin-top: 25px;
|
||||
|
||||
.item-img {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
border-radius: 50%;
|
||||
margin-right: 23px;
|
||||
}
|
||||
|
||||
.item-desc {
|
||||
-webkit-line-clamp: 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-hot {
|
||||
width: 1058px;
|
||||
flex-shrink: 0;
|
||||
margin-right: 26px;
|
||||
|
||||
&-list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
|
||||
.hot-item {
|
||||
width: 441px;
|
||||
height: 150px;
|
||||
border-radius: 16px;
|
||||
display: flex;
|
||||
padding: 28px;
|
||||
background: #ffffff;
|
||||
|
||||
.item-info {
|
||||
width: 320px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-new {
|
||||
flex-grow: 1;
|
||||
|
||||
&-list {
|
||||
.new-item {
|
||||
width: 456px;
|
||||
height: 209px;
|
||||
display: flex;
|
||||
padding: 31px 32px;
|
||||
transition: background-size 0.3s ease-in-out;
|
||||
overflow: hidden;
|
||||
border-radius: 16px;
|
||||
|
||||
&:nth-child(1) {
|
||||
background-image: url('../../../images/factory/resource/tools-new-1.webp');
|
||||
}
|
||||
|
||||
&:nth-child(2) {
|
||||
margin-top: 20px;
|
||||
background-image: url('../../../images/factory/resource/tools-new-2.webp');
|
||||
}
|
||||
|
||||
background-repeat: no-repeat;
|
||||
background-size: 100% 100%;
|
||||
background-position: center;
|
||||
|
||||
&:hover {
|
||||
background-size: 110% 110%;
|
||||
}
|
||||
|
||||
.item-info {
|
||||
width: 320px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
button {
|
||||
cursor: pointer;
|
||||
margin-top: auto;
|
||||
width: 84px;
|
||||
height: 36px;
|
||||
background: #ffffff;
|
||||
border: 1px solid;
|
||||
border-color: #ffffff;
|
||||
border-radius: 9px;
|
||||
line-height: 36px;
|
||||
font-family: alibaba;
|
||||
font-weight: 500;
|
||||
color: #091221;
|
||||
font-size: 14px;
|
||||
|
||||
&:hover {
|
||||
background: #164ce4;
|
||||
color: #ffffff;
|
||||
border-color: #164ce4;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-bottom {
|
||||
margin-top: 25px;
|
||||
width: 1600px;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
background: #ffffff;
|
||||
border-radius: 16px;
|
||||
padding: 40px 30px;
|
||||
|
||||
.content-bottom-wrapper {
|
||||
margin-bottom: 26px;
|
||||
}
|
||||
|
||||
.content-bottom-item {
|
||||
width: 366.25px;
|
||||
height: 220px;
|
||||
border: 1px solid;
|
||||
border-color: rgba(19, 53, 91, 0.11);
|
||||
border-radius: 16px;
|
||||
z-index: 1;
|
||||
position: relative;
|
||||
padding: 35px 30px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
// 增加个有白底的透明色,防止透出底下的流光
|
||||
background: linear-gradient(rgba(241, 247, 255, 0.48), rgba(241, 247, 255, 0.48)), #ffffff;
|
||||
|
||||
.item-bg {
|
||||
position: absolute;
|
||||
width: 366.25px;
|
||||
height: 220px;
|
||||
left: 0;
|
||||
top: 0;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
.item-top {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
img {
|
||||
width: 38px;
|
||||
height: 38px;
|
||||
border-radius: 50%;
|
||||
margin-right: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
.item-desc {
|
||||
-webkit-line-clamp: 2;
|
||||
margin-top: 26px;
|
||||
}
|
||||
|
||||
.item-data {
|
||||
margin-top: auto;
|
||||
|
||||
span {
|
||||
line-height: 18px;
|
||||
font-family: alibabareg;
|
||||
color: #5d6a80;
|
||||
font-size: 13px;
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.content-bottom-btn {
|
||||
width: 366.25px;
|
||||
height: 94px;
|
||||
background: linear-gradient(180deg, rgba(248, 251, 255, 0) 0%, #f3f6ff 23.71%, #f8fbff 100%);
|
||||
border-radius: 0px 0px 16px 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
import React, { useEffect, useState, useRef } from 'react';
|
||||
import './index.scss';
|
||||
import { getSourceList } from '../../api'
|
||||
// import { factoryZoneId } from '../../../constants/factory'
|
||||
import dot from '../../../images/factory/resource/version-dot.webp'
|
||||
import versionNew from '../../../images/factory/resource/version-new.webp'
|
||||
import '../../common.scss'
|
||||
|
||||
const factoryZoneId = 199
|
||||
|
||||
function Index(props) {
|
||||
|
||||
const [versionList, setVersionList] = useState([]);
|
||||
|
||||
useEffect(() => {
|
||||
getFullList();
|
||||
}, []);
|
||||
|
||||
const getFullList = () => {
|
||||
|
||||
getSourceList({ id: factoryZoneId }).then(res => {
|
||||
setVersionList(res.data.rows.slice(0, 4));
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
return (
|
||||
<div className="version">
|
||||
<div className="version-top">
|
||||
<h5>我是版本的标题文案占一行</h5>
|
||||
<p>复现困难、诊断成本高等问题。在2025 CCF中国开源大会上,滴滴正式将HUATUO本AI核心通识课课程是一门全面且深入的入门课程</p>
|
||||
</div>
|
||||
<div className="version-content">
|
||||
{
|
||||
versionList.map((item, index) => {
|
||||
return <div key={item.id} className="version-item">
|
||||
<div className="version-item-left">
|
||||
<img src={dot} alt="" />
|
||||
<div></div>
|
||||
</div>
|
||||
<div className="version-item-right">
|
||||
<div className="version-item-title">
|
||||
<h4>{item.name}</h4>
|
||||
{index === 0 && <img className="new-tag" src={versionNew} />}
|
||||
</div>
|
||||
|
||||
<div className="version-item-content">
|
||||
{item.summary}
|
||||
</div>
|
||||
<button className={index === 0 ? "shiny-button" : "version-btn"}>立即下载</button>
|
||||
</div>
|
||||
</div>
|
||||
})
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default Index
|
||||
|
|
@ -0,0 +1,137 @@
|
|||
.version {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
margin-top: -50px;
|
||||
|
||||
.version-top {
|
||||
width: 1600px;
|
||||
height: 120px;
|
||||
padding: 21px 52px;
|
||||
background-image: url('../../../images/factory/resource/version-top.webp');
|
||||
background-repeat: no-repeat;
|
||||
background-size: 100% 100%;
|
||||
|
||||
h5 {
|
||||
line-height: 27px;
|
||||
font-family: alibaba;
|
||||
font-weight: 500;
|
||||
color: #ffffff;
|
||||
font-size: 20px;
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
|
||||
p {
|
||||
line-height: 20px;
|
||||
font-family: alibabareg;
|
||||
color: #ffffff;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
.version-content {
|
||||
width: 1600px;
|
||||
display: flex;
|
||||
margin-top: 59px;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 90px;
|
||||
|
||||
.version-item {
|
||||
width: 348px;
|
||||
display: flex;
|
||||
|
||||
&-left {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
margin-right: 29px;
|
||||
|
||||
img {
|
||||
width: 42px;
|
||||
height: 42px;
|
||||
}
|
||||
|
||||
div {
|
||||
margin-top: -21px;
|
||||
height: 237px;
|
||||
border-left: 1px dashed rgba(22, 76, 228, 0.31);
|
||||
}
|
||||
}
|
||||
|
||||
&-right {
|
||||
flex-grow: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.version-item-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 250px;
|
||||
h4 {
|
||||
line-height: 33px;
|
||||
font-family: alibaba;
|
||||
font-weight: 700;
|
||||
color: #091221;
|
||||
font-size: 24px;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
}
|
||||
.new-tag {
|
||||
width: 37.49px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.version-item-content {
|
||||
margin-top: 17px;
|
||||
width: 100%;
|
||||
height: 136px;
|
||||
background: linear-gradient(92.56deg, #f8fbff 0.8%, rgba(255, 255, 255, 0) 99%);
|
||||
border: 1px solid;
|
||||
border-color: #ffffff;
|
||||
border-radius: 17px;
|
||||
line-height: 34px;
|
||||
font-family: alibabareg;
|
||||
color: #091221;
|
||||
font-size: 15px;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 3;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
word-break: break-all;
|
||||
padding: 22px;
|
||||
}
|
||||
|
||||
button {
|
||||
cursor: pointer;
|
||||
margin-top: auto;
|
||||
width: 104px;
|
||||
height: 36px;
|
||||
background-color: rgba(255, 255, 255, 0.42);
|
||||
border: 1px solid;
|
||||
border-color: #091221;
|
||||
border-radius: 9px;
|
||||
line-height: 20px;
|
||||
font-family: alibaba;
|
||||
font-weight: 500;
|
||||
color: #091221;
|
||||
font-size: 14px;
|
||||
}
|
||||
.shiny-button {
|
||||
background-color:#091221;
|
||||
color: #ffffff;
|
||||
border: 2px solid transparent;
|
||||
}
|
||||
}
|
||||
|
||||
&:not(:first-child) {
|
||||
button:hover {
|
||||
border-color: #164ce4;
|
||||
color: #164ce4;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
import React, { useEffect, useState, useRef } from 'react';
|
||||
import './index.scss';
|
||||
import { TPMIndexHOC } from "../../modules/tpm/TPMIndexHOC";
|
||||
import KFIcon from '../../components/KFIcon/index';
|
||||
import searchBg from '../../images/factory/resource/search-bg.webp'
|
||||
import { Route, Switch } from "react-router-dom";
|
||||
import Loadable from "react-loadable";
|
||||
import Loading from "../../Loading";
|
||||
|
||||
|
||||
|
||||
const FactoryVersion = Loadable({
|
||||
loader: () => import("./factoryVersion/index"),
|
||||
loading: Loading,
|
||||
});
|
||||
|
||||
const SoftwareProject = Loadable({
|
||||
loader: () => import("./softwareProject/index"),
|
||||
loading: Loading,
|
||||
});
|
||||
|
||||
const DevelopmentTools = Loadable({
|
||||
loader: () => import("./developmentTools/index"),
|
||||
loading: Loading,
|
||||
});
|
||||
|
||||
|
||||
const zoneId = 199
|
||||
|
||||
const typeMap = [
|
||||
{ name: '工厂版本', key: 'factoryVersion', icon: 'icon-gongchangbanben' },
|
||||
{ name: '软件项目', key:'softwareProject', icon: 'icon-ruanjianxiangmu' },
|
||||
{ name: '开发工具', key: 'developmentTools', icon: 'icon-kaifagongju' },
|
||||
]
|
||||
|
||||
function Index(props) {
|
||||
|
||||
const [selectedType, setSelectedType] = useState(typeMap[0].key)
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
props.history.push(`/softWareFactory/resource/${selectedType}`);
|
||||
}, [selectedType]);
|
||||
|
||||
useEffect(() => {
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<div className="resource">
|
||||
<div className="resource-header">
|
||||
<div className="circle-wrapper">
|
||||
<div className="circle-item"></div>
|
||||
<div className="circle-item"></div>
|
||||
<div className="circle-item"></div>
|
||||
<div className="circle-item"></div>
|
||||
</div>
|
||||
<h2><span>资源中枢,</span>释放共享复用的生态力量</h2>
|
||||
<div className="search-box">
|
||||
<input className="search-input" type="text" placeholder="搜索资源" />
|
||||
<div className="search-icon">
|
||||
<KFIcon type="icon-sousuo" font={22} />
|
||||
</div>
|
||||
</div>
|
||||
<img className="search-bg" src={ searchBg } alt="" />
|
||||
<div className="switch-box">
|
||||
{
|
||||
typeMap.map(item => (
|
||||
<div key={item.key} className={selectedType === item.key? "switch-item switch-item-active" : "switch-item"} onClick={() => setSelectedType(item.key)}>
|
||||
<KFIcon type={item.icon} font={22} />
|
||||
<span>{item.name}</span>
|
||||
</div>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<div className="resource-body">
|
||||
<Switch>
|
||||
<Route
|
||||
path="/softWareFactory/resource/factoryVersion"
|
||||
render={(p) => (
|
||||
<FactoryVersion {...props} {...p}/>
|
||||
)} />
|
||||
<Route
|
||||
path="/softWareFactory/resource/softwareProject"
|
||||
render={(p) => (
|
||||
<SoftwareProject {...props} {...p}/>
|
||||
)} />
|
||||
<Route
|
||||
path="/softWareFactory/resource/developmentTools"
|
||||
render={(p) => (
|
||||
<DevelopmentTools {...props} {...p}/>
|
||||
)} />
|
||||
</Switch>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default TPMIndexHOC(Index)
|
||||
|
|
@ -0,0 +1,178 @@
|
|||
.resource {
|
||||
background-color: #f1f6fd;
|
||||
|
||||
&-header {
|
||||
height: 410px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
background-image: url("../../images/factory/resource/header-bg.png");
|
||||
background-repeat: no-repeat;
|
||||
background-size: 100% 100%;
|
||||
position: relative;
|
||||
|
||||
.circle-wrapper {
|
||||
width: 1600px;
|
||||
position: absolute;
|
||||
height: 410px;
|
||||
overflow: hidden;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
z-index: 1;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
$circle-count: 4;
|
||||
$animation-duration: 8s;
|
||||
|
||||
.circle-item {
|
||||
opacity: 0;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
border-radius: 50%;
|
||||
border: 1px solid rgba(100, 150, 255, 0.3);
|
||||
|
||||
// 使用循环创建多个圆圈
|
||||
@for $i from 1 through $circle-count {
|
||||
&:nth-child(#{$i}) {
|
||||
$size: 800px + ($i * 2px);
|
||||
$delay: (
|
||||
$i - 1) * ($animation-duration / $circle-count
|
||||
);
|
||||
|
||||
width: $size;
|
||||
height: $size;
|
||||
animation: circleSpread $animation-duration infinite ease-in-out $delay;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes circleSpread {
|
||||
0% {
|
||||
opacity: 0;
|
||||
filter: blur(0px);
|
||||
transform: translate(-50%, -50%) scale(1);
|
||||
}
|
||||
|
||||
20% {
|
||||
opacity: 0.8;
|
||||
filter: blur(0.5px);
|
||||
}
|
||||
|
||||
50% {
|
||||
opacity: 0.5;
|
||||
filter: blur(1.5px);
|
||||
}
|
||||
|
||||
80% {
|
||||
opacity: 0.1;
|
||||
filter: blur(3px);
|
||||
}
|
||||
|
||||
100% {
|
||||
width: 1200px;
|
||||
height: 1200px;
|
||||
opacity: 0;
|
||||
filter: blur(5px);
|
||||
transform: translate(-50%, -50%) scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
h2 {
|
||||
line-height: 55px;
|
||||
font-family: alibaba;
|
||||
font-weight: 700;
|
||||
color: #091221;
|
||||
font-size: 40px;
|
||||
text-align: center;
|
||||
margin-top: 67px;
|
||||
|
||||
span {
|
||||
color: #164ce4;
|
||||
}
|
||||
}
|
||||
|
||||
.search-bg {
|
||||
width: 644.85px;
|
||||
height: 120px;
|
||||
margin-top: -75px;
|
||||
}
|
||||
|
||||
.search-box {
|
||||
margin-top: 25px;
|
||||
width: 567px;
|
||||
height: 55px;
|
||||
background: #ffffff;
|
||||
border: 1px solid;
|
||||
border-color: rgba(22, 76, 228, 0.05);
|
||||
border-radius: 14px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
z-index: 1;
|
||||
|
||||
.search-input {
|
||||
margin-left: 30px;
|
||||
width: 400px;
|
||||
height: 40px;
|
||||
border: none;
|
||||
line-height: 40px;
|
||||
font-family: alibabareg;
|
||||
font-size: 15px;
|
||||
|
||||
&::placeholder {
|
||||
color: #a2abbd;
|
||||
}
|
||||
}
|
||||
|
||||
.search-icon {
|
||||
width: 39px;
|
||||
height: 39px !important;
|
||||
background: #091221;
|
||||
border-radius: 8px;
|
||||
flex-shrink: 0;
|
||||
color: #ffffff;
|
||||
text-align: center;
|
||||
line-height: 46px;
|
||||
margin-right: 8px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.switch-box {
|
||||
display: flex;
|
||||
|
||||
.switch-item {
|
||||
width: 178px;
|
||||
height: 54px;
|
||||
border-radius: 35px;
|
||||
box-shadow: 0px 0px 15px rgba(0, 74, 168, 0.05);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
line-height: normal;
|
||||
font-family: alibaba;
|
||||
font-weight: 500;
|
||||
color: #091221;
|
||||
font-size: 22px;
|
||||
margin-right: 44px;
|
||||
cursor: pointer;
|
||||
|
||||
i {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
color: #164ce4;
|
||||
}
|
||||
}
|
||||
|
||||
.switch-item-active {
|
||||
background: #ffffff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,192 @@
|
|||
import React, { useEffect, useState, useRef } from 'react';
|
||||
import './index.scss';
|
||||
import { getProjectsLists } from '../../api'
|
||||
import { factoryZoneId } from '../../../constants/factory'
|
||||
import KFIcon from '../../../components/KFIcon';
|
||||
|
||||
import bg1 from '../../../images/factory/resource/project-top-1.webp';
|
||||
import bg2 from '../../../images/factory/resource/project-top-2.webp';
|
||||
import bg3 from '../../../images/factory/resource/project-top-3.png';
|
||||
|
||||
import bg4 from '../../../images/factory/resource/project-content-1.webp';
|
||||
import bg5 from '../../../images/factory/resource/project-content-2.webp';
|
||||
import bg6 from '../../../images/factory/resource/project-content-3.webp';
|
||||
import bg7 from '../../../images/factory/resource/project-content-4.webp';
|
||||
import contentRight from '../../../images/factory/resource/project-content-right.webp';
|
||||
import bg8 from '../../../images/factory/resource/project-bottom-1.webp'
|
||||
|
||||
import ActionItem from '../components/ActionItem';
|
||||
import '../../common.scss'
|
||||
|
||||
|
||||
const bgList = [bg1, bg2, bg3]
|
||||
const contentBgList = [bg4, bg5, bg6, bg7]
|
||||
|
||||
function Index(props) {
|
||||
|
||||
const [topList, setTopList] = useState([]);
|
||||
const [contentList, setContentList] = useState([]);
|
||||
const [fullList, setFullList] = useState([]);
|
||||
|
||||
useEffect(() => {
|
||||
getFullList();
|
||||
getTopList();
|
||||
}, []);
|
||||
|
||||
const getTopList = () => {
|
||||
getProjectsLists(factoryZoneId, { isHomepage: 1 }).then(res => {
|
||||
console.log(res.data.rows);
|
||||
|
||||
setTopList(res.data.rows.slice(0, 3)); // 获取前三个项目作为 topList
|
||||
});
|
||||
};
|
||||
|
||||
const getFullList = () => {
|
||||
getProjectsLists(factoryZoneId, { isHomepage: 0 }).then(res => {
|
||||
// 前面四个项目作为 contentList
|
||||
setContentList(res.data.rows.slice(0, 4));
|
||||
// 后面项目作为 fullList
|
||||
setFullList(res.data.rows.slice(4));
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="project">
|
||||
<div className="project-top">
|
||||
{
|
||||
topList.map((item, index) => {
|
||||
const project = item.projectProperties
|
||||
return (
|
||||
<div className="project-top-item" key={index}>
|
||||
<img src={bgList[index]} alt="" className="item-bg" />
|
||||
<img src={project.authorImageUrl} alt="" className="item-img"></img>
|
||||
<div className="item-info">
|
||||
<h5 className="item-title">{project.name}</h5>
|
||||
<p className="item-desc">{project.description}</p>
|
||||
<div className="item-bottom">
|
||||
<div className="item-bottom-tags">
|
||||
{
|
||||
project.topics && project.topics.split(',').splice(0, 3).map((topic, index) => {
|
||||
return (
|
||||
<span key={index} className="item-tag">{topic}</span>
|
||||
)
|
||||
})
|
||||
}
|
||||
</div>
|
||||
<div className="item-bottom-data">
|
||||
|
||||
{
|
||||
project.praisesCount > 0 && <span><i className="iconfont icon-liulanliang mr5 font-12" />{project.praisesCount}</span>
|
||||
}
|
||||
{
|
||||
project.forkedCount > 0 && <span><i className="iconfont icon-shoucang mr5 font-12" />{project.forkedCount}</span>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
}
|
||||
</div>
|
||||
<div className="project-content">
|
||||
|
||||
<h2>全部软件项目</h2>
|
||||
<div className="project-content-top">
|
||||
<div className="project-content-top-left">
|
||||
<p>xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx</p>
|
||||
<div className="content-top-list">
|
||||
{
|
||||
contentList.map((item, index) => {
|
||||
const project = item.projectProperties
|
||||
project.praisesCount = 3
|
||||
project.forkedCount = 3
|
||||
return <div key={index} className="content-top-item">
|
||||
<img className="item-bg" src={contentBgList[index]} alt="" />
|
||||
<div className="item-top">
|
||||
<img src={project.authorImageUrl} alt="" className="item-img"></img>
|
||||
<h5 className="item-title">{project.name}</h5>
|
||||
</div>
|
||||
<div className="item-tags">
|
||||
{
|
||||
project.topics && project.topics.split(',').splice(0, 3).map((topic, index) => {
|
||||
return (
|
||||
<span key={index} className="item-tag">{topic}</span>
|
||||
)
|
||||
})
|
||||
}
|
||||
</div>
|
||||
<div className="item-desc">
|
||||
{project.description}
|
||||
</div>
|
||||
<div className="item-data">
|
||||
|
||||
{
|
||||
project.praisesCount > 0 && <span><i className="iconfont icon-liulanliang mr5 font-12" />{project.praisesCount}</span>
|
||||
}
|
||||
{
|
||||
project.forkedCount > 0 && <span><i className="iconfont icon-shoucang mr5 font-12" />{project.forkedCount}</span>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
})
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<img className="project-content-top-right" src={contentRight} alt="" />
|
||||
</div>
|
||||
|
||||
<div className="project-content-bottom">
|
||||
{
|
||||
fullList.map((item, index) => {
|
||||
const project = item.projectProperties
|
||||
project.praisesCount = 3
|
||||
project.forkedCount = 3
|
||||
return <ActionItem className="content-bottom-wrapper" key={index} backgroundColor="rgba(19, 53, 91, 0.11)" padding="1px" borderRadius="16px">
|
||||
<div className="content-bottom-item">
|
||||
{
|
||||
index % 2 === 0 && <img className="item-bg" src={bg8} alt="" />
|
||||
}
|
||||
|
||||
<div className="item-top">
|
||||
<img src={project.authorImageUrl} alt="" className="item-img"></img>
|
||||
<h5 className="item-title">{project.name}</h5>
|
||||
</div>
|
||||
<div className="item-desc">
|
||||
{project.description}
|
||||
</div>
|
||||
<div className="item-tags">
|
||||
{
|
||||
project.topics && project.topics.split(',').splice(0, 3).map((topic, index) => {
|
||||
return (
|
||||
<span key={index} className="item-tag">{topic}</span>
|
||||
)
|
||||
})
|
||||
}
|
||||
</div>
|
||||
|
||||
<div className="item-data">
|
||||
|
||||
{
|
||||
project.praisesCount > 0 && <span><i className="iconfont icon-liulanliang mr5 font-12" />{project.praisesCount}</span>
|
||||
}
|
||||
{
|
||||
project.forkedCount > 0 && <span><i className="iconfont icon-shoucang mr5 font-12" />{project.forkedCount}</span>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<div className="content-bottom-btn">
|
||||
<button className="shiny-button">查看详情</button>
|
||||
</div>
|
||||
</ActionItem>
|
||||
})
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default Index
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,369 @@
|
|||
.project {
|
||||
margin-top: -50px;
|
||||
&-top {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
|
||||
&-item {
|
||||
width: 516px;
|
||||
height: 230px;
|
||||
display: flex;
|
||||
padding: 50px 38px 38px 38px;
|
||||
color: #ffffff;
|
||||
margin-right: 26px;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
border-radius: 16px;
|
||||
cursor: pointer;
|
||||
|
||||
.item-bg {
|
||||
width: 516px;
|
||||
height: 230px;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
z-index: -1;
|
||||
transition: transform 0.3s ease-in-out;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.item-bg {
|
||||
transform: scale(1.1);
|
||||
}
|
||||
}
|
||||
|
||||
.item-img {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
border-radius: 50%;
|
||||
margin-right: 16px;
|
||||
}
|
||||
|
||||
.item-info {
|
||||
font-size: 15px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-grow: 1;
|
||||
|
||||
h5 {
|
||||
line-height: 30px;
|
||||
font-family: alibabareg;
|
||||
font-size: 22px;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
p {
|
||||
line-height: 24px;
|
||||
font-family: alibabareg;
|
||||
margin-top: 13px;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
.item-bottom {
|
||||
margin-top: auto;
|
||||
display: flex;
|
||||
|
||||
.item-bottom-tags {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.item-tag {
|
||||
display: inline-block;
|
||||
margin-right: 10px;
|
||||
padding: 0 8px;
|
||||
height: 32px;
|
||||
background: rgba(255, 255, 255, 0.57);
|
||||
border-radius: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
.item-bottom-data {
|
||||
margin-left: auto;
|
||||
|
||||
span {
|
||||
line-height: 18px;
|
||||
font-family: alibabareg;
|
||||
color: #ffffff;
|
||||
font-size: 13px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
span:not(:last-child) {
|
||||
margin-right: 15px;
|
||||
padding-right: 15px;
|
||||
|
||||
&::after {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 50%;
|
||||
transform: translate(0, -50%);
|
||||
content: "";
|
||||
width: 1px;
|
||||
height: 9px;
|
||||
background: rgba(255, 255, 255, 0.22);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-content {
|
||||
margin-top: 60px;
|
||||
background: linear-gradient(180deg, #ffffff 0%, #ffffff 80.62%, rgba(255, 255, 255, 0.13) 100%);
|
||||
border-radius: 80px 80px 0px 0px;
|
||||
padding-top: 28px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
||||
h2 {
|
||||
line-height: 55px;
|
||||
font-family: alibaba;
|
||||
font-weight: 700;
|
||||
color: #091221;
|
||||
font-size: 40px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.item-top {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
img {
|
||||
width: 38px;
|
||||
height: 38px;
|
||||
border-radius: 50%;
|
||||
margin-right: 14px;
|
||||
}
|
||||
|
||||
.item-title {
|
||||
line-height: 30px;
|
||||
font-family: alibaba;
|
||||
font-weight: 500;
|
||||
color: #091221;
|
||||
font-size: 22px;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.item-desc {
|
||||
margin-top: 18px;
|
||||
line-height: 21px;
|
||||
font-family: alibabareg;
|
||||
color: #091221;
|
||||
font-size: 15px;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 1;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.item-tags {
|
||||
margin-top: 22px;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
|
||||
.item-tag {
|
||||
display: inline-block;
|
||||
padding: 0 8px;
|
||||
margin-right: 8px;
|
||||
height: 32px;
|
||||
background: rgba(22, 76, 228, 0.05);
|
||||
border-radius: 4px;
|
||||
line-height: 32px;
|
||||
font-family: alibabareg;
|
||||
color: #091221;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.item-data {
|
||||
margin-top: auto;
|
||||
|
||||
span {
|
||||
line-height: 18px;
|
||||
font-family: alibabareg;
|
||||
color: #5d6a80;
|
||||
font-size: 13px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
span:not(:last-child) {
|
||||
margin-right: 15px;
|
||||
padding-right: 15px;
|
||||
|
||||
&::after {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 50%;
|
||||
transform: translate(0, -50%);
|
||||
content: "";
|
||||
width: 1px;
|
||||
height: 9px;
|
||||
background: rgba(9, 18, 33, 0.22);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-top {
|
||||
width: 1600px;
|
||||
background: linear-gradient(110.74deg, #f5f5fd 2.03%, #ddf0ff 98.5%);
|
||||
border-radius: 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 58px 0 32px 0;
|
||||
margin-top: 25px;
|
||||
|
||||
&-left {
|
||||
padding: 0 0 0 53px;
|
||||
|
||||
.content-top-list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
margin-top: 38px;
|
||||
|
||||
.content-top-item {
|
||||
width: 420px;
|
||||
height: 219px;
|
||||
border-radius: 16px;
|
||||
background: #ffffff;
|
||||
margin-bottom: 28px;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
padding: 23px 29px 29px 29px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
cursor: pointer;
|
||||
|
||||
.item-bg {
|
||||
position: absolute;
|
||||
width: 420px;
|
||||
height: 219px;
|
||||
left: 0;
|
||||
top: 0;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
&:nth-child(2n+1) {
|
||||
margin-right: 32px;
|
||||
}
|
||||
|
||||
// 最后两个元素添加margin-bottom: 28px;
|
||||
&:nth-last-child(-n+2) {
|
||||
margin-bottom: 0;
|
||||
|
||||
.item-tag {
|
||||
background: rgba(255, 255, 255, 0.84);
|
||||
color: #091221;
|
||||
}
|
||||
|
||||
.item-desc {
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.item-data {
|
||||
span {
|
||||
color: #ffffff
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
box-shadow: 0px 0px 12px rgba(22, 76, 228, 0.06);
|
||||
|
||||
.item-title {
|
||||
color: #164ce4;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-right {
|
||||
width: 672px;
|
||||
height: 516px;
|
||||
}
|
||||
}
|
||||
|
||||
&-bottom {
|
||||
margin-top: 40px;
|
||||
width: 1600px;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
|
||||
.content-bottom-wrapper {
|
||||
margin-bottom: 26px;
|
||||
}
|
||||
|
||||
.content-bottom-item {
|
||||
width: 381.25px;
|
||||
height: 256px;
|
||||
background: linear-gradient(rgba(241, 247, 255, 0.48), rgba(241, 247, 255, 0.48)), #ffffff;
|
||||
border: 1px solid;
|
||||
border-color: rgba(19, 53, 91, 0.11);
|
||||
border-radius: 16px;
|
||||
z-index: 1;
|
||||
position: relative;
|
||||
padding: 35px 30px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.item-bg {
|
||||
position: absolute;
|
||||
width: 381.25px;
|
||||
height: 256px;
|
||||
left: 0;
|
||||
top: 0;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
.item-desc {
|
||||
-webkit-line-clamp: 2;
|
||||
margin-top: 26px;
|
||||
}
|
||||
|
||||
.item-tags {
|
||||
margin-top: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.content-bottom-btn {
|
||||
width: 378px;
|
||||
height: 94px;
|
||||
background: linear-gradient(180deg, rgba(248, 251, 255, 0) 0%, #f3f6ff 23.71%, #f8fbff 100%);
|
||||
border-radius: 0px 0px 16px 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
button {
|
||||
cursor: pointer;
|
||||
width: 320px;
|
||||
height: 36px;
|
||||
background-color: #091221;
|
||||
border-radius: 9px;
|
||||
line-height: 20px;
|
||||
font-family: alibaba;
|
||||
font-weight: 500;
|
||||
color: #ffffff;
|
||||
font-size: 14px;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
import React, { useEffect, useState, useRef } from 'react';
|
||||
import './index.scss';
|
||||
import { TPMIndexHOC } from '../../modules/tpm/TPMIndexHOC';
|
||||
import imageBack1 from '../../images/factory/back1.png'
|
||||
import sceneIcon from '../../images/factory/scene/scene-icon.webp'
|
||||
import { Link } from 'react-router-dom';
|
||||
import RenderHtml from '../../components/render-html';
|
||||
|
||||
|
||||
|
||||
const Detail = {
|
||||
name: '临近空间装备',
|
||||
desc: '我是文案我是文案占2行我是文案我是文案占2行我是文案我是文案占2行我是文案我是文案占2行',
|
||||
img: imageBack1,
|
||||
content: '5aSn5qih5Z6L5oiQ5pys5pWI55uK5a+55q+U77yaRGVlcFNlZWsgMi41IFZTIENsYXVkZSAzLjUgU29ubmV0IFZTIEdQVC00bwoKCi0gWyAxMjQ0XQotIOWPkeWZtuWxseixhuaguQoKMS4gMTI0MzE0CjIuIDIuNTQyNTIKCgojIyMgMwoKfCBjb2wgfCBjb2wgfCBjb2wgfCBjb2wgfAp8IC0gfCAtIHwgLSB8IC0gfAp8IGNvbnRlbnQgfCBjb250ZW50IHwgY29udGVudCB8IGNvbnRlbnQgfAp8IGNvbnRlbnQgfCBjb250ZW50IHwgY29udGVudCB8IGNvbnRlbnQgfAp8IGNvbnRlbnQgfCBjb250ZW50IHwgY29udGVudCB8IGNvbnRlbnQgfAoKIVtdKGh0dHBzOi8vdGVzdGdldHdheS50cnVzdGllLm5ldC9hcGkvZmlsZS9vcGVuL2Rvd25sb2FkLzUzOTMpCg=='
|
||||
}
|
||||
|
||||
const otherList = [
|
||||
'"小智廉"应用',
|
||||
'KJZZ保障',
|
||||
'XXXXXXXX',
|
||||
'我是应用场景的标题',
|
||||
'我是应用场景的标题',
|
||||
'我是应用场景的标题',
|
||||
]
|
||||
|
||||
function Index(props) {
|
||||
|
||||
const [detail, setDetail] = useState(Detail)
|
||||
const [ content , setContent]=useState();
|
||||
|
||||
useEffect(() => {
|
||||
setContent(Base64.decode(detail.content));
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="scene">
|
||||
<div className="scene-header">
|
||||
<div className="header-content">
|
||||
<img className="scene-icon" src={sceneIcon} alt="" />
|
||||
<h3>{detail.name}</h3>
|
||||
<p>{detail.desc}</p>
|
||||
<div className="header-img">
|
||||
<div className="header-img-wrapper">
|
||||
<img src={detail.img} alt="" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="scene-content">
|
||||
<div className="scene-content-wrapper">
|
||||
{
|
||||
content && <RenderHtml className="informations_detail imageLayerParent" value={content} url={props.history.location} />
|
||||
}
|
||||
</div>
|
||||
<div className="scene-content-others">
|
||||
<div>
|
||||
<h4>相关场景</h4>
|
||||
<ul>
|
||||
{
|
||||
otherList.map((item, index) => {
|
||||
return (
|
||||
<li key={index}><Link to="#">{item}</Link></li>
|
||||
)
|
||||
})
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default TPMIndexHOC(Index)
|
||||
|
|
@ -0,0 +1,122 @@
|
|||
.scene {
|
||||
.scene-header {
|
||||
height: 450px;
|
||||
width: 100%;
|
||||
background-image: url("../../images/factory/scene/bg1.webp");
|
||||
background-repeat: no-repeat;
|
||||
background-size: 100% 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.header-content {
|
||||
width: 1600px;
|
||||
height: 300px;
|
||||
background: url("../../images/factory/scene/bg2.webp"), #fff;
|
||||
background-repeat: no-repeat;
|
||||
background-size: 100% 100%;
|
||||
position: relative;
|
||||
border-radius: 16px;
|
||||
box-shadow: 0px 0px 10px rgba(0, 74, 168, 0.03);
|
||||
padding: 60px;
|
||||
|
||||
.scene-icon {
|
||||
width: 146.5px;
|
||||
height: 29px;
|
||||
}
|
||||
|
||||
h3 {
|
||||
line-height: 47px;
|
||||
font-family: alibaba;
|
||||
font-weight: 700;
|
||||
color: #091221;
|
||||
font-size: 34px;
|
||||
margin-top: 27px;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-top: 19px;
|
||||
max-width: 594px;
|
||||
line-height: 32px;
|
||||
font-family: alibabareg;
|
||||
color: #091221;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.header-img {
|
||||
position: absolute;
|
||||
top: -30px;
|
||||
right: 0;
|
||||
width: 600px;
|
||||
height: 360px;
|
||||
background: linear-gradient(180deg, #ffffff 0%, #f1f7ff 100%);
|
||||
border-radius: 10px;
|
||||
box-shadow: 0px 0px 18px rgba(0, 74, 168, 0.05);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
&-wrapper {
|
||||
width: 526px;
|
||||
height: 300px;
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
border-radius: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.header-img .header-img-wrapper img {
|
||||
transform: scale(1.1);
|
||||
transition: transform .4s cubic-bezier(.25, .46, .45, .94);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.scene-content {
|
||||
width: 1600px;
|
||||
height: 100%;
|
||||
margin: 52px auto;
|
||||
|
||||
.scene-content-wrapper {
|
||||
width: 1245px;
|
||||
float: left;
|
||||
padding-bottom: 60px;
|
||||
}
|
||||
|
||||
.scene-content-others {
|
||||
width: 300px;
|
||||
float: right;
|
||||
|
||||
div {
|
||||
background: #f2f6fa;
|
||||
border-radius: 12px;
|
||||
padding: 35px 30px;
|
||||
|
||||
h4 {
|
||||
line-height: 22px;
|
||||
font-family: alibaba;
|
||||
font-weight: 500;
|
||||
color: #091221;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
li {
|
||||
line-height: 20px;
|
||||
font-family: alibabareg;
|
||||
color: #091221;
|
||||
font-size: 14px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 596 KiB |
|
After Width: | Height: | Size: 9.1 KiB |
|
After Width: | Height: | Size: 5.1 KiB |
|
After Width: | Height: | Size: 5.0 KiB |
|
After Width: | Height: | Size: 8.2 KiB |
|
After Width: | Height: | Size: 9.3 KiB |
|
After Width: | Height: | Size: 220 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 6.5 KiB |
|
After Width: | Height: | Size: 290 KiB |
|
After Width: | Height: | Size: 68 KiB |
|
After Width: | Height: | Size: 6.1 KiB |
|
After Width: | Height: | Size: 4.9 KiB |
|
After Width: | Height: | Size: 7.3 KiB |
|
After Width: | Height: | Size: 8.1 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 5.8 KiB |
|
After Width: | Height: | Size: 5.3 KiB |
|
After Width: | Height: | Size: 3.2 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 35 KiB |
|
After Width: | Height: | Size: 516 KiB |
|
After Width: | Height: | Size: 3.5 KiB |
|
|
@ -1,8 +1,8 @@
|
|||
@font-face {
|
||||
font-family: "iconfont"; /* Project id 5081288 */
|
||||
src: url('iconfont.woff2?t=1764899187997') format('woff2'),
|
||||
url('iconfont.woff?t=1764899187997') format('woff'),
|
||||
url('iconfont.ttf?t=1764899187997') format('truetype');
|
||||
src: url('iconfont.woff2?t=1765507764789') format('woff2'),
|
||||
url('iconfont.woff?t=1765507764789') format('woff'),
|
||||
url('iconfont.ttf?t=1765507764789') format('truetype');
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
|
|
@ -13,6 +13,26 @@
|
|||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.icon-xiazai:before {
|
||||
content: "\e794";
|
||||
}
|
||||
|
||||
.icon-sousuo:before {
|
||||
content: "\e793";
|
||||
}
|
||||
|
||||
.icon-kaifagongju:before {
|
||||
content: "\e790";
|
||||
}
|
||||
|
||||
.icon-ruanjianxiangmu:before {
|
||||
content: "\e791";
|
||||
}
|
||||
|
||||
.icon-gongchangbanben:before {
|
||||
content: "\e792";
|
||||
}
|
||||
|
||||
.icon-icon_blackarrow_hover:before {
|
||||
content: "\e78f";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,41 @@
|
|||
"css_prefix_text": "icon-",
|
||||
"description": "",
|
||||
"glyphs": [
|
||||
{
|
||||
"icon_id": "46331570",
|
||||
"name": "下载",
|
||||
"font_class": "xiazai",
|
||||
"unicode": "e794",
|
||||
"unicode_decimal": 59284
|
||||
},
|
||||
{
|
||||
"icon_id": "46274605",
|
||||
"name": "搜索",
|
||||
"font_class": "sousuo",
|
||||
"unicode": "e793",
|
||||
"unicode_decimal": 59283
|
||||
},
|
||||
{
|
||||
"icon_id": "46274559",
|
||||
"name": "开发工具",
|
||||
"font_class": "kaifagongju",
|
||||
"unicode": "e790",
|
||||
"unicode_decimal": 59280
|
||||
},
|
||||
{
|
||||
"icon_id": "46274558",
|
||||
"name": "软件项目",
|
||||
"font_class": "ruanjianxiangmu",
|
||||
"unicode": "e791",
|
||||
"unicode_decimal": 59281
|
||||
},
|
||||
{
|
||||
"icon_id": "46274557",
|
||||
"name": "工厂版本",
|
||||
"font_class": "gongchangbanben",
|
||||
"unicode": "e792",
|
||||
"unicode_decimal": 59282
|
||||
},
|
||||
{
|
||||
"icon_id": "46273104",
|
||||
"name": "icon_blackarrow_hover",
|
||||
|
|
|
|||