You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

app.tsx 16KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492
  1. import { useState, useEffect, useRef } from 'react';
  2. import type { RequestConfig } from "@umijs/max";
  3. import { Layout, Modal, Dropdown, Image, Flex, Col, ConfigProvider, Button, Space } from "antd";
  4. import { HomeOutlined, LogoutOutlined, FileTextOutlined } from '@ant-design/icons';
  5. import { baseUrl } from './constants/index'
  6. import routes from '../config/routes'
  7. import { history, useModel } from '@umijs/max';
  8. import { filterRoutesByAccess, findAccessIndex } from './utils/RouteHelper'
  9. import LoginIndex from '@/components/Login/Index/index'
  10. import FooterIndex from '@/components/Common/Footer/index'
  11. export async function getInitialState(): Promise<{ permissions: object }> {
  12. const role = localStorage.getItem('role');
  13. let permissions = {}
  14. switch (role) {
  15. case 'personal':
  16. permissions = {
  17. managejobseeker: true,
  18. managejobseekerhome: true,
  19. managejobseekerresume: true,
  20. managejobseekerdetail: true,
  21. managejobseekerrecommend: true,
  22. managejobseekerresetting: true,
  23. talentjobdetail: true,
  24. talentCompanydetail: true, talentResumedetail: true, talentfairdetail: true, talentinformationdetail: true
  25. }
  26. break;
  27. case 'company':
  28. permissions = {
  29. company: true,
  30. companyhome: true,
  31. companydepartment: true,
  32. companypost: true,
  33. companyresume: true,
  34. companysearch: true,
  35. companyfair: true,
  36. companysetting: true,
  37. talentjobdetail: true,
  38. talentCompanydetail: true, talentResumedetail: true, talentfairdetail: true, talentinformationdetail: true
  39. }
  40. break;
  41. default:
  42. permissions = {
  43. talent: true,
  44. talenthome: true,
  45. talentsearch: true,
  46. talentfair: true,
  47. talentinformation: true,
  48. talentdownload: true,
  49. talentabout: true,
  50. talentjobdetail: true,
  51. talentCompanydetail: true, talentResumedetail: true, talentfairdetail: true, talentinformationdetail: true,
  52. sciencetechnologypark: true,
  53. sciencetechnologyparkhome: true,
  54. sciencetechnologyparkabout: true,
  55. sciencetechnologyparknews: true,
  56. sciencetechnologyparkcompany: true,
  57. sciencetechnologyparknotice: true,
  58. sciencetechnologyparkconversion: true,
  59. sciencetechnologyparkactivity: true,
  60. sciencetechnologyparkconstruct: true,
  61. sciencetechnologyparkpartymembercenter: true,
  62. partner: true,
  63. }
  64. };
  65. return { permissions };
  66. }
  67. export const layout = () => {
  68. const [openPreview, setOpenPreview] = useState(false);
  69. const { initialState, loading, error, refresh, setInitialState } = useModel('@@initialState');
  70. return {
  71. title: '菊城人才网',
  72. logo: '/images/onlylogo.jpg',
  73. headerTitleRender: (logo, title, props) => {
  74. return (
  75. <>
  76. <a href="/talent/home">
  77. <Flex align='center' >
  78. {logo}
  79. <div style={{ margin: '0 40px 0 8px', fontSize: 18, color: '#000000' }}>菊城人才网</div>
  80. </Flex>
  81. </a>
  82. </>
  83. );
  84. },
  85. menuRender: false,
  86. layout: 'top',
  87. token: {
  88. pageContainer: {
  89. paddingBlockPageContainerContent: 40,
  90. paddingInlinePageContainerContent: 414,
  91. colorBgPageContainer: '#f5f5f5'
  92. },
  93. header: {
  94. colorTextMenuSelected: '#19be6e',
  95. heightLayoutHeader: 90,
  96. },
  97. },
  98. onPageChange: (location) => {
  99. const role = localStorage.getItem('role');
  100. switch (role) {
  101. case 'personal':
  102. setInitialState((s) => ({
  103. ...s,
  104. permissions: {
  105. managejobseeker: true,
  106. managejobseekerhome: true,
  107. managejobseekerdetail: true,
  108. managejobseekerresume: true,
  109. managejobseekerrecommend: true,
  110. managejobseekerresetting: true,
  111. talentjobdetail: true,
  112. talentCompanydetail: true, talentResumedetail: true, talentfairdetail: true, talentinformationdetail: true
  113. },
  114. }));
  115. break;
  116. case 'company':
  117. setInitialState((s) => ({
  118. ...s,
  119. permissions: {
  120. managecompany: true,
  121. managecompanyhome: true,
  122. managecompanypost: true,
  123. managecompanyresume: true,
  124. managecompanyrecommend: true,
  125. managecompanyinfo: true,
  126. managecompanydepartment: true,
  127. managecompanysetting: true,
  128. talentjobdetail: true,
  129. talentCompanydetail: true, talentResumedetail: true, talentfairdetail: true, talentinformationdetail: true
  130. },
  131. }));
  132. break;
  133. default:
  134. setInitialState((s) => ({
  135. ...s,
  136. permissions: {
  137. talent: true,
  138. talenthome: true,
  139. talentsearchjob: true,
  140. talentsearchcompany: true,
  141. talentfair: true,
  142. talentinformation: true,
  143. talentdownload: true,
  144. talentabout: true,
  145. talentjobdetail: true,
  146. talentCompanydetail: true, talentResumedetail: true, talentfairdetail: true, talentinformationdetail: true,
  147. sciencetechnologypark: true,
  148. sciencetechnologyparkhome: true,
  149. sciencetechnologyparkabout: true,
  150. sciencetechnologyparknews: true,
  151. sciencetechnologyparkcompany: true,
  152. sciencetechnologyparknotice: true,
  153. sciencetechnologyparkconversion: true,
  154. sciencetechnologyparkactivity: true,
  155. sciencetechnologyparkconstruct: true,
  156. sciencetechnologyparkpartymembercenter: true,
  157. sciencetechnologyparkformationdetail: true,
  158. partner: true,
  159. },
  160. }));
  161. }
  162. },
  163. menuDataRender: () => {
  164. if (localStorage.getItem('path') == '/talent/search/job' ||
  165. localStorage.getItem('path') == '/talent/search/company' ||
  166. localStorage.getItem('path') == '/talent/home' ||
  167. localStorage.getItem('path') == '/talent/fair' ||
  168. localStorage.getItem('path') == '/talent/information' ||
  169. localStorage.getItem('path') == '/talent/about') {
  170. localStorage.setItem('role', 'common')
  171. }
  172. if (localStorage.getItem('path') == '/manage/jobseeker/resume' ||
  173. localStorage.getItem('path') == '/manage/jobseeker/home' ||
  174. localStorage.getItem('path') == '/manage/jobseeker/recommend' ||
  175. localStorage.getItem('path') == '/manage/jobseeker/setting') {
  176. localStorage.setItem('role', 'personal')
  177. }
  178. if (localStorage.getItem('path') == '/manage/company/home' ||
  179. localStorage.getItem('path') == '/manage/company/info' ||
  180. localStorage.getItem('path') == '/manage/company/post' ||
  181. localStorage.getItem('path') == '/manage/company/resume' ||
  182. localStorage.getItem('path') == '/manage/company/recommend' ||
  183. localStorage.getItem('path') == '/manage/company/department' ||
  184. localStorage.getItem('path') == '/manage/company/setting'
  185. ) {
  186. localStorage.setItem('role', 'company')
  187. }
  188. const role = localStorage.getItem('role');
  189. console.log(routes)
  190. switch (role) {
  191. case 'personal':
  192. routes[4].flatMenu = true;
  193. setInitialState((s) => ({
  194. ...s,
  195. permissions: {
  196. managejobseeker: true,
  197. managejobseekerhome: true,
  198. managejobseekerresume: true,
  199. managejobseekerrecommend: true,
  200. managejobseekerresetting: true,
  201. talentjobdetail: true,
  202. talentCompanydetail: true, talentResumedetail: true, talentfairdetail: true, talentinformationdetail: true
  203. }
  204. }));
  205. return [routes[4]]
  206. case 'company':
  207. routes[5].flatMenu = true;
  208. setInitialState((s) => ({
  209. ...s,
  210. permissions: {
  211. managecompany: true,
  212. managecompanyhome: true,
  213. managecompanypost: true,
  214. managecompanyresume: true,
  215. managecompanyrecommend: true,
  216. managecompanyinfo: true,
  217. managecompanydepartment: true,
  218. managecompanysetting: true,
  219. talentjobdetail: true,
  220. talentCompanydetail: true, talentResumedetail: true, talentfairdetail: true, talentinformationdetail: true
  221. },
  222. }));
  223. return [routes[5]]
  224. default:
  225. setInitialState((s) => ({
  226. ...s,
  227. permissions: {
  228. talent: true,
  229. talenthome: true,
  230. talentsearch: true,
  231. talentfair: true,
  232. talentinformation: true,
  233. talentdownload: true,
  234. talentabout: true,
  235. talentjobdetail: true,
  236. talentCompanydetail: true, talentResumedetail: true, talentfairdetail: true, talentinformationdetail: true,
  237. sciencetechnologypark: true,
  238. sciencetechnologyparkhome: true,
  239. sciencetechnologyparkabout: true,
  240. sciencetechnologyparknews: true,
  241. sciencetechnologyparkcompany: true,
  242. sciencetechnologyparknotice: true,
  243. sciencetechnologyparkconversion: true,
  244. sciencetechnologyparkactivity: true,
  245. sciencetechnologyparkconstruct: true,
  246. sciencetechnologyparkpartymembercenter: true,
  247. sciencetechnologyparkformationdetail: true,
  248. partner: true,
  249. },
  250. }));
  251. if (localStorage.getItem('idx') != null && localStorage.getItem('idx') != -1) {
  252. let idx = localStorage.getItem('idx')
  253. if (Number(idx) == 1) {
  254. routes[Number(idx)].flatMenu = true;
  255. routes[2].flatMenu = false;
  256. }
  257. if (Number(idx) == 2) {
  258. routes[Number(idx)].flatMenu = true;
  259. routes[1].flatMenu = false;
  260. }
  261. if (Number(idx) == 3) {
  262. routes[2].flatMenu = true;
  263. }
  264. } else {
  265. routes[1].flatMenu = false;
  266. routes[2].flatMenu = true;
  267. }
  268. return [routes[0], routes[1], routes[2], routes[3]]
  269. // return [routes[0], routes[3]]
  270. }
  271. },
  272. footerRender: () => {
  273. return (<>
  274. <ConfigProvider theme={{
  275. components: {
  276. Layout: {
  277. footerPadding: 0
  278. },
  279. },
  280. }}>
  281. <Layout.Footer style={{ background: '#f0f2f5' }} id='about'>
  282. <FooterIndex></FooterIndex>
  283. </Layout.Footer>
  284. </ConfigProvider>
  285. </>)
  286. },
  287. avatarProps: {
  288. src: 'https://gw.alipayobjects.com/zos/antfincdn/efFD%24IOql2/weixintupian_20170331104822.jpg',
  289. size: 'small',
  290. title: '王二狗',
  291. render: (props, dom) => {
  292. let roleItem: any = []
  293. if (localStorage.getItem('companyid')) {
  294. roleItem = [
  295. {
  296. key: 'company',
  297. icon: <FileTextOutlined />,
  298. label: '企业中心',
  299. },
  300. {
  301. key: 'talent',
  302. icon: <HomeOutlined />,
  303. label: '求职首页',
  304. },
  305. {
  306. key: 'logout',
  307. icon: <LogoutOutlined />,
  308. label: '退出登录',
  309. }
  310. ]
  311. } else {
  312. roleItem = [
  313. {
  314. key: 'resume',
  315. icon: <FileTextOutlined />,
  316. label: '我的简历',
  317. },
  318. {
  319. key: 'talent',
  320. icon: <HomeOutlined />,
  321. label: '求职首页',
  322. },
  323. {
  324. key: 'logout',
  325. icon: <LogoutOutlined />,
  326. label: '退出登录',
  327. }
  328. ]
  329. }
  330. return (
  331. <>
  332. {
  333. localStorage.getItem('token') ? <Dropdown
  334. menu={{
  335. items: roleItem,
  336. onClick: ({ key }) => {
  337. console.log(key);
  338. switch (key) {
  339. case 'resume':
  340. localStorage.setItem('role', 'personal')
  341. history.replace('/manage/jobseeker/home');
  342. window.location.reload()
  343. break;
  344. case 'company':
  345. localStorage.setItem('role', 'company')
  346. history.replace('/manage/company/home');
  347. window.location.reload()
  348. break;
  349. case 'talent':
  350. localStorage.setItem('role', 'common')
  351. history.replace('/talent/home');
  352. window.location.reload()
  353. break;
  354. case 'logout':
  355. localStorage.clear();
  356. localStorage.setItem('role', 'common')
  357. history.replace('/');
  358. window.location.reload()
  359. break;
  360. }
  361. }
  362. }}
  363. >
  364. {dom}
  365. </Dropdown> : <Button onClick={() => {
  366. setOpenPreview(true)
  367. }}>登录</Button>
  368. }
  369. {/* 登录 */}
  370. <Modal
  371. open={openPreview}
  372. centered
  373. footer={null}
  374. onCancel={() => setOpenPreview(false)}
  375. destroyOnClose
  376. maskClosable={false}
  377. style={{ minWidth: 540 }}
  378. >
  379. <LoginIndex type={''} loginChangeStatus={(isLogin: boolean) => {
  380. console.log(isLogin)
  381. setOpenPreview(isLogin)
  382. }}></LoginIndex>
  383. </Modal>
  384. </>
  385. );
  386. }
  387. }
  388. };
  389. };
  390. export const onRouteChange = ({ location }) => {
  391. localStorage.setItem('path', location.pathname)
  392. let routes_idx = findAccessIndex(routes, location?.pathname)
  393. if (routes_idx) {
  394. localStorage.setItem('idx', routes_idx.parentIndex.toString())
  395. }
  396. }
  397. export const request: RequestConfig = {
  398. baseURL: baseUrl,
  399. errorConfig: {
  400. // 错误抛出
  401. errorThrower: (res) => {
  402. const { success, data, errorCode, errorMessage, showType } = res;
  403. if (!success) {
  404. }
  405. },
  406. },
  407. // 配置请求头
  408. requestInterceptors: [
  409. (config: object) => {
  410. // 拦截请求配置,进行个性化处理。
  411. const token = localStorage.getItem('token');
  412. if (token) {
  413. config.headers.Authorization = `${token}`;
  414. }
  415. return config;
  416. },
  417. ],
  418. // 配置响应拦截
  419. responseInterceptors: [
  420. (response) => {
  421. const msgModel = (val: String, code: number) => {
  422. Modal.error({
  423. title: val,
  424. centered: true
  425. });
  426. }
  427. // 拦截响应数据,进行个性化处理
  428. const { data } = response;
  429. switch (data.code) {
  430. case -1:
  431. msgModel(data.msg, data.code)
  432. break;
  433. case 0:
  434. break;
  435. case 1:
  436. return response;
  437. break;
  438. case 401:
  439. msgModel(data.msg, data.code)
  440. localStorage.clear();
  441. history.push('/');
  442. break;
  443. case 403:
  444. msgModel(data.msg, data.code)
  445. break;
  446. case 404:
  447. break;
  448. case 600:
  449. if (data.errors && Object.keys(data.errors).length > 0) {
  450. msgModel(data.errors, data.code)
  451. } else {
  452. msgModel(data.msg, data.code)
  453. }
  454. case 601:
  455. if (data.errors && Object.keys(data.errors).length > 0) {
  456. msgModel(data.errors, data.code)
  457. } else {
  458. msgModel(data.msg, data.code)
  459. }
  460. }
  461. return response;
  462. }
  463. ]
  464. }