diff --git a/code/web/client/assets/color.less b/code/web/client/assets/color.less index 75f2642..6ddc7cb 100644 --- a/code/web/client/assets/color.less +++ b/code/web/client/assets/color.less @@ -1147,10 +1147,10 @@ tr > .ant-picker-cell-in-view.ant-picker-cell-range-hover-start:last-child::afte .ant-mentions-dropdown-menu-item-active {background-color: @item-hover-bg;} .ant-menu-item-danger.ant-menu-item {color: #ff4d4f;} .ant-menu-item-danger.ant-menu-item:hover, .ant-menu-item-danger.ant-menu-item-active {color: #ff4d4f;} -.ant-menu-item-danger.ant-menu-item:active {background: color(~`colorPalette("@{table-header-sort-bg}", 4)`);} +.ant-menu-item-danger.ant-menu-item:active {background: color(~`colorPalette("@{calendar-input-bg}", 1)`);} .ant-menu-item-danger.ant-menu-item-selected {color: #ff4d4f;} .ant-menu-item-danger.ant-menu-item-selected > a, .ant-menu-item-danger.ant-menu-item-selected > a:hover {color: #ff4d4f;} -.ant-menu:not(.ant-menu-horizontal) .ant-menu-item-danger.ant-menu-item-selected {background-color: color(~`colorPalette("@{table-header-sort-bg}", 4)`);} +.ant-menu:not(.ant-menu-horizontal) .ant-menu-item-danger.ant-menu-item-selected {background-color: color(~`colorPalette("@{calendar-input-bg}", 1)`);} .ant-menu-inline .ant-menu-item-danger.ant-menu-item::after {border-right-color: #ff4d4f;} .ant-menu-dark .ant-menu-item-danger.ant-menu-item, .ant-menu-dark .ant-menu-item-danger.ant-menu-item:hover, .ant-menu-dark .ant-menu-item-danger.ant-menu-item > a {color: #ff4d4f;} .ant-menu-dark.ant-menu-dark:not(.ant-menu-horizontal) .ant-menu-item-danger.ant-menu-item-selected {color: #fff;background-color: #ff4d4f;} @@ -1727,11 +1727,11 @@ tr.ant-table-expanded-row:hover > td {background: @table-expanded-row-bg;} .ant-tag-checkable:active, .ant-tag-checkable-checked {color: #fff;} .ant-tag-checkable-checked {background-color: @primary-color;} .ant-tag-checkable:active {background-color: color(~`colorPalette("@{primary-color}", 7)`);} -.ant-tag-pink {color: #c41d7f;background: color(~`colorPalette("@{picker-basic-cell-active-with-range-color}", 1)`);border-color: #ffadd2;} +.ant-tag-pink {color: #c41d7f;background: color(~`colorPalette("@{table-header-cell-split-color}", 4)`);border-color: #ffadd2;} .ant-tag-pink-inverse {color: #fff;background: #eb2f96;border-color: #eb2f96;} -.ant-tag-magenta {color: #c41d7f;background: color(~`colorPalette("@{picker-basic-cell-active-with-range-color}", 1)`);border-color: #ffadd2;} +.ant-tag-magenta {color: #c41d7f;background: color(~`colorPalette("@{table-header-cell-split-color}", 4)`);border-color: #ffadd2;} .ant-tag-magenta-inverse {color: #fff;background: #eb2f96;border-color: #eb2f96;} -.ant-tag-red {color: #cf1322;background: color(~`colorPalette("@{table-header-sort-bg}", 4)`);border-color: #ffa39e;} +.ant-tag-red {color: #cf1322;background: color(~`colorPalette("@{calendar-input-bg}", 1)`);border-color: #ffa39e;} .ant-tag-red-inverse {color: #fff;background: #f5222d;border-color: #f5222d;} .ant-tag-volcano {color: #d4380d;background: #fff2e8;border-color: #ffbb96;} .ant-tag-volcano-inverse {color: #fff;background: #fa541c;border-color: #fa541c;} @@ -1739,7 +1739,7 @@ tr.ant-table-expanded-row:hover > td {background: @table-expanded-row-bg;} .ant-tag-orange-inverse {color: #fff;background: #fa8c16;border-color: #fa8c16;} .ant-tag-yellow {color: #d4b106;background: #feffe6;border-color: #fffb8f;} .ant-tag-yellow-inverse {color: #fff;background: #fadb14;border-color: #fadb14;} -.ant-tag-gold {color: #d48806;background: #fffbe6;border-color: #ffe58f;} +.ant-tag-gold {color: #d48806;background: color(~`colorPalette("@{btn-shadow}", 1)`);border-color: #ffe58f;} .ant-tag-gold-inverse {color: #fff;background: #faad14;border-color: #faad14;} .ant-tag-cyan {color: #08979c;background: #e6fffb;border-color: #87e8de;} .ant-tag-cyan-inverse {color: #fff;background: #13c2c2;border-color: #13c2c2;} @@ -1747,11 +1747,11 @@ tr.ant-table-expanded-row:hover > td {background: @table-expanded-row-bg;} .ant-tag-lime-inverse {color: #fff;background: #a0d911;border-color: #a0d911;} .ant-tag-green {color: #389e0d;background: #f6ffed;border-color: #b7eb8f;} .ant-tag-green-inverse {color: #fff;background: #52c41a;border-color: #52c41a;} -.ant-tag-blue {color: #096dd9;background: #e6f7ff;border-color: #91d5ff;} +.ant-tag-blue {color: #096dd9;background: color(~`colorPalette("@{transfer-item-hover-bg}", 1)`);border-color: #91d5ff;} .ant-tag-blue-inverse {color: #fff;background: #1890ff;border-color: #1890ff;} .ant-tag-geekblue {color: #1d39c4;background: #f0f5ff;border-color: #adc6ff;} .ant-tag-geekblue-inverse {color: #fff;background: #2f54eb;border-color: #2f54eb;} -.ant-tag-purple {color: #531dab;background: color(~`colorPalette("@{layout-trigger-background}", 2)`);border-color: #d3adf7;} +.ant-tag-purple {color: #531dab;background: #f9f0ff;border-color: #d3adf7;} .ant-tag-purple-inverse {color: #fff;background: #722ed1;border-color: #722ed1;} .ant-tag-success {color: #52c41a;background: @success-color-deprecated-bg;border-color: @success-color-deprecated-border;} .ant-tag-processing {color: @primary-color;background: @info-color-deprecated-bg;border-color: @info-color-deprecated-border;} @@ -1988,7 +1988,7 @@ a.ant-typography.ant-typography-disabled:hover, .ant-typography a.ant-typography .ant-upload-list-picture .ant-upload-list-item-error, .ant-upload-list-picture-card .ant-upload-list-item-error {border-color: #ff4d4f;} .ant-upload-list-picture .ant-upload-list-item:hover .ant-upload-list-item-info, .ant-upload-list-picture-card .ant-upload-list-item:hover .ant-upload-list-item-info {background: transparent;} .ant-upload-list-picture .ant-upload-list-item-uploading, .ant-upload-list-picture-card .ant-upload-list-item-uploading {border-style: dashed;} -.ant-upload-list-picture .ant-upload-list-item-error .ant-upload-list-item-thumbnail .anticon svg path[fill='#e6f7ff'], .ant-upload-list-picture-card .ant-upload-list-item-error .ant-upload-list-item-thumbnail .anticon svg path[fill='#e6f7ff'] {fill: @error-color-deprecated-bg;} +.ant-upload-list-picture .ant-upload-list-item-error .ant-upload-list-item-thumbnail .anticon svg path[fill='color(~`colorPalette("@{transfer-item-hover-bg}", 1)`)'], .ant-upload-list-picture-card .ant-upload-list-item-error .ant-upload-list-item-thumbnail .anticon svg path[fill='color(~`colorPalette("@{transfer-item-hover-bg}", 1)`)'] {fill: @error-color-deprecated-bg;} .ant-upload-list-picture .ant-upload-list-item-error .ant-upload-list-item-thumbnail .anticon svg path[fill='#1890ff'], .ant-upload-list-picture-card .ant-upload-list-item-error .ant-upload-list-item-thumbnail .anticon svg path[fill='#1890ff'] {fill: #ff4d4f;} .ant-upload-list-picture-card .ant-upload-list-item-info::before {background-color: rgba(0, 0, 0, 0.5);} .ant-upload-list-picture-card .ant-upload-list-item-actions .anticon-eye, .ant-upload-list-picture-card .ant-upload-list-item-actions .anticon-download, .ant-upload-list-picture-card .ant-upload-list-item-actions .anticon-delete {color: rgba(255, 255, 255, 0.85);} diff --git a/code/web/client/src/layout/components/header/index.js b/code/web/client/src/layout/components/header/index.js index a969b18..e666f10 100644 --- a/code/web/client/src/layout/components/header/index.js +++ b/code/web/client/src/layout/components/header/index.js @@ -8,7 +8,7 @@ import lightVars from '$themes/light.json'; import exampleVars from '$themes/example.json' import styles from './style.css'; import { - MenuFoldOutlined, MenuUnfoldOutlined, UserOutlined, LogoutOutlined + MenuFoldOutlined, MenuUnfoldOutlined, UserOutlined, LogoutOutlined,SmileOutlined } from '@ant-design/icons'; const themeMap = { @@ -60,7 +60,9 @@ const Header = props => { {collapsed ? : }
- 安心云4.0 + + 安心云4.0 + {/* {user.orgName} */}
diff --git a/code/web/client/src/layout/containers/layout/index.js b/code/web/client/src/layout/containers/layout/index.js index 42ebd88..60b2506 100644 --- a/code/web/client/src/layout/containers/layout/index.js +++ b/code/web/client/src/layout/containers/layout/index.js @@ -56,9 +56,9 @@ const LayoutContainer = props => { useEffect(() => { NProgress.done(); - if (!user || !user.authorized) { - history.push('/signin'); - } + // if (!user || !user.authorized) { + // history.push('/search'); + // } if (msg) { message.destroy(); if (msg.done) { diff --git a/code/web/client/src/sections/search/actions/search.js b/code/web/client/src/sections/search/actions/search.js index 6cb79ea..cc500b5 100644 --- a/code/web/client/src/sections/search/actions/search.js +++ b/code/web/client/src/sections/search/actions/search.js @@ -3,13 +3,13 @@ import { basicAction } from '@peace/utils' import { ApiTable } from '$utils' -export function getMembersW(orgId) { +export function search(keyword){ return dispatch => basicAction({ type: 'get', dispatch: dispatch, - actionType: 'GET_MEMBERS', - url: `${ApiTable.getEnterprisesMembers.replace('{enterpriseId}', orgId)}`, - msg: { error: '获取用户列表失败' }, - reducer: { name: 'members' } + actionType: 'GET_SEARCH', + url: `${ApiTable.search.replace('{wd}', keyword)}`, + msg: { error: '搜索失败' }, + reducer: { name: 'searchRes' } }); -} +} \ No newline at end of file diff --git a/code/web/client/src/sections/search/components/SearchBar.js b/code/web/client/src/sections/search/components/SearchBar.js new file mode 100644 index 0000000..ad57761 --- /dev/null +++ b/code/web/client/src/sections/search/components/SearchBar.js @@ -0,0 +1,17 @@ +import React, { useEffect } from 'react'; +import { connect } from 'react-redux'; +import { Spin, Card, Input } from 'antd'; +import '../style.less'; + +// todo AutoComplete +const SerachBar= (props) => { + const { dispatch, actions, user, loading } = props + + return ( +
+ +
+ ) +} + +export default SerachBar; \ No newline at end of file diff --git a/code/web/client/src/sections/search/containers/index.js b/code/web/client/src/sections/search/containers/index.js index f931028..0f99bc8 100644 --- a/code/web/client/src/sections/search/containers/index.js +++ b/code/web/client/src/sections/search/containers/index.js @@ -1,5 +1,6 @@ 'use strict'; import Search from './search'; +import SearchRes from './searchRes'; -export { Search }; \ No newline at end of file +export { Search, SearchRes }; \ No newline at end of file diff --git a/code/web/client/src/sections/search/containers/search.js b/code/web/client/src/sections/search/containers/search.js index 242bb23..6cbe327 100644 --- a/code/web/client/src/sections/search/containers/search.js +++ b/code/web/client/src/sections/search/containers/search.js @@ -2,7 +2,8 @@ import React, { useEffect } from 'react'; import { connect } from 'react-redux'; import { Spin, Card, Input } from 'antd'; import '../style.less'; -import './style.less'; +import toplogo from './toplogo' +import { push } from 'react-router-redux' const Search = (props) => { const { dispatch, actions, user, loading } = props @@ -11,20 +12,41 @@ const Search = (props) => { // dispatch(actions.search.getMembersW(user.orgId)) }, []) + const SafeSearch = (v) => { + let kwd = '' + if (typeof v === "string") { + kwd = v; + } else { + kwd = v.target.value; + } + if (kwd) { + dispatch(push(`/s/${kwd}`)) + } + } + return (
- + {toplogo} + + {/* */}
) } function mapStateToProps(state) { - const { auth, global, members } = state; + const { auth, global } = state; return { - loading: members.isRequesting, user: auth.user, - actions: global.actions, - members: members.data + actions: global.actions }; } diff --git a/code/web/client/src/sections/search/containers/searchRes.js b/code/web/client/src/sections/search/containers/searchRes.js new file mode 100644 index 0000000..758021e --- /dev/null +++ b/code/web/client/src/sections/search/containers/searchRes.js @@ -0,0 +1,142 @@ +import React, { useEffect, useState } from 'react'; +import { connect } from 'react-redux'; +import { Affix, List, Input, Space, Empty } from 'antd'; +import '../style.less'; +import { + DatabaseOutlined, +} from '@ant-design/icons'; +import { push } from 'react-router-redux' + +const IconText = ({ icon, text }) => ( + + {React.createElement(icon)} + {text} + +); + +function getHighlightedText(text, highlight) { + // Split text on highlight term, include term itself into parts, ignore case + const parts = text.split(new RegExp(`(${highlight})`, 'gi')); + return {parts.map(part => part.toLowerCase() === highlight.toLowerCase() ? {part} : part)}; +} + +const searchRes = (props) => { + const { dispatch, actions, user, loading, searchDatas } = props + + const [controlSearchData, setControlSearchData] = useState([]) + + // params + const keyword = props.match?.params?.wd + + const [inputValue, setInputValue] = useState(keyword) + + useEffect(() => { + if (!!keyword && keyword.length > 0) { + dispatch(actions.search.search(keyword)) + } + }, [keyword]) + + useEffect(() => { + setControlSearchData(searchDatas) + }, [searchDatas]) + + const onSearch = (v) => { + console.log(`search for ${v}`) + dispatch(actions.search.search(v)) + } + + const onSearchEnv = (v) => { + console.log(`search for ${v.target.value}`) + dispatch(actions.search.search(v.target.value)) + } + + const SafeSearch = (v) => { + let kwd = '' + if (typeof v === "string") { + kwd = v; + } else { + kwd = v.target.value; + } + if (kwd) { + dispatch(push(`/s/${kwd}`)) + } else { + setControlSearchData([]) + } + } + + return ( +
+ setInputValue(e.target.value)} + /> + { + controlSearchData && controlSearchData.length > 0 ? + { + console.log(page); + }, + pageSize: 10, + }} + dataSource={controlSearchData} + footer={ +
+ Free-Sun 搜索结果 +
+ } + renderItem={(item) => ( + , + ]} + extra={ + item.ext?.img ? + img : null + } + > + {getHighlightedText(item.title, keyword)}} + description={item.ext?.desc ? item.ext.desc : undefined} + // description={item.content} + /> + {getHighlightedText(item.content, keyword)} + + )} + /> : + } + +
+ ) +} + +function mapStateToProps(state) { + const { auth, global, searchRes } = state; + console.log(searchRes) + return { + loading: searchRes.isRequesting, + user: auth.user, + actions: global.actions, + searchDatas: searchRes.data || [], + }; +} + +export default connect(mapStateToProps)(searchRes); diff --git a/code/web/client/src/sections/search/containers/toplogo.js b/code/web/client/src/sections/search/containers/toplogo.js new file mode 100644 index 0000000..ec91a6e --- /dev/null +++ b/code/web/client/src/sections/search/containers/toplogo.js @@ -0,0 +1,6 @@ +import React, { useEffect } from 'react'; +export default ( + + + +) \ No newline at end of file diff --git a/code/web/client/src/sections/search/routes.js b/code/web/client/src/sections/search/routes.js index 83ed93b..8b0a97c 100644 --- a/code/web/client/src/sections/search/routes.js +++ b/code/web/client/src/sections/search/routes.js @@ -1,12 +1,18 @@ 'use strict'; -import { Search, } from './containers'; +import { Search, SearchRes } from './containers'; export default [{ type: 'inner', route: { - path: '/search', + path: '/', key: 'search', breadcrumb: '搜索引擎', - component: Search + component: Search, + childRoutes: [{ + path: '/s/:wd', + key: 'searchRes', + breadcrumb: '搜索结果', + component: SearchRes, + }] } }]; \ No newline at end of file diff --git a/code/web/client/src/sections/search/style.less b/code/web/client/src/sections/search/style.less index 3323452..fee7fdd 100644 --- a/code/web/client/src/sections/search/style.less +++ b/code/web/client/src/sections/search/style.less @@ -1,3 +1,48 @@ #example:hover { font-size: larger; -} \ No newline at end of file +} +.search { + width: 500px; + font: 16px arial,sans-serif; + } + // .search:hover, .search:focus { + // outline: none; + // box-shadow: 0 3px 8px 0 rgba(0, 0, 0, 0.16), 0 0 0 1px rgba(0, 0, 0, 0.08); + // } + + .parent{ + display:flex; + flex-direction: column; + // justify-content: center; + justify-content: flex-start; + align-items: center; + } + + .parent-top{ + margin-left: 20%; + margin-bottom: 10%; + display:flex; + flex-wrap: nowrap; + flex-direction: column; + justify-content: flex-start; + align-items: flex-start; // 垂直居中展示 + } + + .search-top { + width: 75%; + height: 50px; + font: 16px arial,sans-serif; + // margin:auto; + } + + .search-empty{ + align-self: center; + } + + .search-content { + width: 75%; + } + + .search-list{ + width: 75%; + } \ No newline at end of file diff --git a/code/web/client/src/utils/webapi.js b/code/web/client/src/utils/webapi.js index 9334473..4fb4175 100644 --- a/code/web/client/src/utils/webapi.js +++ b/code/web/client/src/utils/webapi.js @@ -5,6 +5,8 @@ export const ApiTable = { login: 'login', logout: 'logout', + search: 'v1/search/{wd}', + getEnterprisesMembers: 'enterprises/{enterpriseId}/members', }; diff --git a/code/web/node_modules.rar b/code/web/node_modules.rar new file mode 100644 index 0000000..981d157 Binary files /dev/null and b/code/web/node_modules.rar differ