Browse Source

feat: 平台管理端增加多站点逻辑

周玉环 1 day ago
parent
commit
4046000743

+ 1 - 1
xinkeaboard-admin/config/router.config.js

@@ -54,7 +54,7 @@ export default [
   // app
   {
     path: '/',
-    component: '../layouts/BasicLayout',
+    component: '../layouts/index',
     Routes: ['src/pages/CheckLogin'],
     routes: [
       { path: '/', redirect: '/sysset_home/basic' },

+ 4 - 2
xinkeaboard-admin/src/components/GlobalHeader/RightContent.js

@@ -4,6 +4,7 @@ import { Tag, Menu, Icon, Tooltip } from 'antd';
 import moment from 'moment';
 import groupBy from 'lodash/groupBy';
 import HeaderDropdown from '../HeaderDropdown';
+import SiteSelector from '../SiteSelector';
 import styles from './index.less';
 import { sldComLanguage } from '@/utils/utils';
 import { specialFlag } from '@/utils/sldconfig';
@@ -101,7 +102,7 @@ export default class GlobalHeaderRight extends PureComponent {
 		}
 		return (
 			<div className={className}>
-				<Tooltip title={formatMessage({ id: `${sldComLanguage('同步')}` })}>
+				{/* <Tooltip title={formatMessage({ id: `${sldComLanguage('同步')}` })}>
 					<a
 						onClick={()=>this.handleSync()}
 						href={'javascript:void(0)'}
@@ -110,7 +111,8 @@ export default class GlobalHeaderRight extends PureComponent {
 					>
 						<Icon style={{ color: '#555', fontSize: 16 }} type="sync"/>
 					</a>
-				</Tooltip>
+				</Tooltip> */}
+				<SiteSelector></SiteSelector>
 				<HeaderDropdown overlay={menu}>
             <span className={`${styles.action} ${styles.account}`}>
               <span

+ 32 - 0
xinkeaboard-admin/src/components/SiteSelector/index.js

@@ -0,0 +1,32 @@
+import { Select } from "antd";
+import { Menu, Dropdown } from 'antd';
+import { connect } from "dva";
+import router from 'umi/router';
+
+const SiteSelector = ({ siteList, currentSite, dispatch }) => {
+  const handleChange = (value) => {
+    dispatch({ type: "global/setCurrentSite", payload: value });
+    const targetSite = siteList.find(item => item.value === value);
+    dispatch({ type: "global/setCurrentSiteName", payload: targetSite.title });
+  };
+  return (
+    siteList.length ?  (
+      <Select
+        value={currentSite}
+        style={{ width: 150 }}
+        onChange={handleChange}
+      >
+        {siteList.map((site) => (
+          <Select.Option key={site.name} value={site.value}>
+            {site.title}
+          </Select.Option>
+        ))}
+      </Select>
+    ) : null
+  );
+};
+
+export default connect(({ global }) => ({
+  siteList: global.siteList,
+  currentSite: global.currentSite,
+}))(SiteSelector);

+ 0 - 0
xinkeaboard-admin/src/components/SiteSelector/index.less


+ 1 - 13
xinkeaboard-admin/src/layouts/BasicLayout.js

@@ -3,11 +3,9 @@ import { Layout } from 'antd';
 import DocumentTitle from 'react-document-title';
 import isEqual from 'lodash/isEqual';
 import memoizeOne from 'memoize-one';
-import { connect } from 'dva';
 import { ContainerQuery } from 'react-container-query';
 import classNames from 'classnames';
 import pathToRegexp from 'path-to-regexp';
-import Media from 'react-media';
 import { formatMessage } from 'umi/locale';
 import Authorized from '@/utils/Authorized';
 import Footer from './Footer';
@@ -216,14 +214,4 @@ class BasicLayout extends React.PureComponent {
   }
 }
 
-export default connect(({ global, setting, menu }) => ({
-  collapsed: global.collapsed,
-  layout: setting.layout,
-  menuData: menu.menuData,
-  breadcrumbNameMap: menu.breadcrumbNameMap,
-  ...setting,
-}))(props => (
-  <Media query="(max-width: 599px)">
-    {isMobile => <BasicLayout {...props} isMobile={isMobile} />}
-  </Media>
-));
+export default BasicLayout;

+ 47 - 0
xinkeaboard-admin/src/layouts/index.js

@@ -0,0 +1,47 @@
+import React from 'react';
+import Media from 'react-media';
+import { connect } from 'dva';
+import PageLoading from '@/components/PageLoading';
+import BasicLayout from './BasicLayout';
+
+class LayoutWrapper extends React.PureComponent {
+  componentDidMount() {
+    const { dispatch, currentSite } = this.props;
+    dispatch({ type: 'global/get_site_list_data' });
+  }
+
+  render() {
+    const { currentSite } = this.props;
+
+    if (!currentSite) {
+      // 非 apply 页且未初始化完成 → Loading
+      return (
+        <div style={{ height: '100vh', display: 'flex', justifyContent: 'center', alignItems: 'center' }}>
+          <PageLoading />
+        </div>
+      );
+    }
+
+    //currentSite 已有值 → 渲染 BasicLayout(key 确保切换站点强制刷新)
+    return (
+      <Media query="(max-width: 599px)">
+        {isMobile => (
+          <BasicLayout
+            key={currentSite}
+            {...this.props}
+            isMobile={isMobile}
+          />
+        )}
+      </Media>
+    );
+  }
+}
+
+export default connect(({ global, setting, menu }) => ({
+  collapsed: global.collapsed,
+  currentSite: global.currentSite,
+  layout: setting.layout,
+  menuData: menu.menuData,
+  breadcrumbNameMap: menu.breadcrumbNameMap,
+  ...setting,
+}))(LayoutWrapper);

+ 2 - 0
xinkeaboard-admin/src/locales/en-US/content.js

@@ -558,6 +558,8 @@
 
   //src/pages/sysset/home/basic.js
  '金额(元)':'Amount (yuan)',
+ '待办事项':'To do',
+ '全部站点待办事项': 'All site procedures',
 
   //src/pages/sysset/notice_set/email.js
  '请输入测试邮件':'Please enter a test message',

+ 1 - 0
xinkeaboard-admin/src/locales/zh-CN/content.js

@@ -2258,6 +2258,7 @@ export default {
   '待确认退款单':'待确认退款单',
   '待处理结算单':'待处理结算单',
   '待办事项':'待办事项',
+  '全部站点待办事项': '全部站点办事项',
   '待分配询盘':'待分配询盘',
   '支付/下单金额趋势':'支付/下单金额趋势',
   '流量趋势':'流量趋势',

+ 44 - 0
xinkeaboard-admin/src/models/global.js

@@ -6,6 +6,20 @@ export default {
   state: {
     collapsed: false,
     notices: [],
+    siteList: [
+      {
+        title: '海外站',
+        value: '1',
+        name: 'sdsdsd'
+      },
+      {
+        title: '国内站',
+        value: '2',
+        name: 'sdsdsdsdsd'
+      }
+    ],
+    currentSite: '',
+    currentSiteName: ''
   },
 
   effects: {
@@ -70,9 +84,39 @@ export default {
         },
       });
     },
+    // 获取站点列表
+    * get_site_list_data({ payload, callback }, { call, put, select }) {
+      const siteList = yield select(state => state.global.siteList);
+      const response = siteList.length ? {data: siteList, state: 200} : yield call(sldCommonService, payload, 'get', 'v3/system/seller/setting/getSiteSettingList');
+      if (callback) callback(response);
+      yield put({ type: 'saveSiteList', payload: response.data });
+      const currentSite = yield select(state => state.global.currentSite);
+      if (!currentSite) {
+        yield put({type: 'setCurrentSite', payload: response.data[0]?.value})
+        yield put({type: 'setCurrentSiteName', payload: response.data[0]?.title})
+      }
+    },
   },
 
   reducers: {
+    saveSiteList(state, action) {
+      return {
+        ...state,
+        siteList: action.payload,
+      };
+    },
+    setCurrentSite(state, { payload }) {
+      return {
+        ...state,
+        currentSite: payload,
+      };
+    },
+    setCurrentSiteName(state, { payload }) {
+      return {
+        ...state,
+        currentSiteName: payload,
+      };
+    },
     changeLayoutCollapsed(state, { payload }) {
       return {
         ...state,

+ 5 - 2
xinkeaboard-admin/src/pages/sysset/home/basic.js

@@ -250,6 +250,7 @@ export default class Basic extends Component {
           },
         ],
       },//今日询盘概况
+      currentSiteName: props.global.currentSiteName
     };
   }
 
@@ -395,7 +396,7 @@ export default class Basic extends Component {
   };
 
   render() {
-    const { goods_data_one, loadedFlag, waitDealLoading, /*todayTradeData,*/ todayFlowData, todayGoodsData, todayMemberData, todayTradeLoadedFlag, todayFlowLoadedFlag, todayGoodsLoadedFlag, todayMemberLoadedFlag, todayTradeLoading, todayFlowLoading, todayGoodsLoading, todayMemberLoading,todayEnquiryData,todayEnquiryLoadedFlag,todayEnquiryLoading } = this.state;
+    const { currentSiteName, goods_data_one, loadedFlag, waitDealLoading, /*todayTradeData,*/ todayFlowData, todayGoodsData, todayMemberData, todayTradeLoadedFlag, todayFlowLoadedFlag, todayGoodsLoadedFlag, todayMemberLoadedFlag, todayTradeLoading, todayFlowLoading, todayGoodsLoading, todayMemberLoading,todayEnquiryData,todayEnquiryLoadedFlag,todayEnquiryLoading } = this.state;
     const todayData = [
       /*{ ...todayTradeData },*/
       { ...todayFlowData },
@@ -412,8 +413,9 @@ export default class Basic extends Component {
           autoHeightMax={document.body.clientHeight - 60}
         >
           <div className={`${styles.module_item}`}>
-            <div className={`${stat.label_panel}`}>
+            <div className={`${stat.label_panel} ${styles.label_panel}`}>
               {sldLlineRtextAddGoodsAddMargin(defaultSettings.primaryColor, `${sldComLanguage('待办事项')}`, 10, 0, 0)}
+              <span className={ styles.site_tip }>{ `( ${sldComLanguage('全部站点待办事项')} )` }</span>
             </div>
             <Spin spinning={waitDealLoading}>
               <div className={`${styles.stat_amount_new} ${global.flex_com_row_space_around_center}`}>
@@ -445,6 +447,7 @@ export default class Basic extends Component {
               </div>
             </Spin>
           </div>
+          <div className={styles.current_site}>{ currentSiteName }</div>
           <div className={`${styles.today_info_panel} ${global.flex_com_space_between}`}>
             {todayData.map((item, index) => (
               <div key={index} className={`${styles.today_info_item}`}>

+ 19 - 0
xinkeaboard-admin/src/pages/sysset/home/basic.less

@@ -371,6 +371,8 @@
   }
 
   .label_panel {
+    display: flex;
+    align-items: center;
     border-bottom: 1px solid #D8D8D8;
   }
 
@@ -437,3 +439,20 @@
 .saling_stat{
   background-color: #f0f2f5;
 }
+
+.current_site {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  height: 80px;
+  font-size: 25px;
+  font-weight: bold;
+  margin-top: 10px;
+  background-color: #fff;
+}
+
+.site_tip {
+  font-size: 13px;
+  color: rgb(153, 153, 153);
+  margin-left: 5px;
+}

+ 6 - 0
xinkeaboard-admin/src/utils/utils.js

@@ -1327,6 +1327,12 @@ export function getSldStatYTitle() {
  * data_type json json格式 默认是表单提交
  * */
 export function sldComRequest(method, url, params, data_type = '') {
+  const state = window.g_app._store.getState();
+  const currentSite = state.global.currentSite;
+  const currentPath = state.routing.location.pathname;
+  if (!currentPath.includes('/user/login')) {
+    params = Object.assign({}, params ?? {}, { webSite: currentSite })
+  }
   if (method == 'get') {
     let tmp_url = apiUrl + `${url}`;
     if (params != undefined) {

+ 16 - 16
xinkeaboard-seller/config/config.js

@@ -73,26 +73,26 @@ export default {
   },
   proxy: {
     "/api/": {
-      target: "http://54.46.9.88:8001/",
-      // target: 'http://192.168.0.158:8001/',
-      changeOrigin: true,
-      pathRewrite: { "^/api": "" },
-    },
-    '/api/v3/seller/seller/apply/saveApply': {
-      target: 'http://192.168.0.158:8001/',
-      changeOrigin: true,
-      pathRewrite: { "^/api": "" },
-    },
-    '/api/v3/seller/seller/apply/applyDetail': {
+      // target: "http://54.46.9.88:8001/",
       target: 'http://192.168.0.158:8001/',
       changeOrigin: true,
       pathRewrite: { "^/api": "" },
     },
-    '/api/v3/seller/seller/apply/process': {
-      target: 'http://192.168.0.158:8001/',
-      changeOrigin: true,
-      pathRewrite: { "^/api": "" },
-    }
+    // '/api/v3/seller/seller/apply/saveApply': {
+    //   target: 'http://192.168.0.158:8001/',
+    //   changeOrigin: true,
+    //   pathRewrite: { "^/api": "" },
+    // },
+    // '/api/v3/seller/seller/apply/applyDetail': {
+    //   target: 'http://192.168.0.158:8001/',
+    //   changeOrigin: true,
+    //   pathRewrite: { "^/api": "" },
+    // },
+    // '/api/v3/seller/seller/apply/process': {
+    //   target: 'http://192.168.0.158:8001/',
+    //   changeOrigin: true,
+    //   pathRewrite: { "^/api": "" },
+    // }
   },
   ignoreMomentLocale: true,
   lessLoaderOptions: {

+ 17 - 4
xinkeaboard-seller/src/pages/User/Login.js

@@ -70,7 +70,9 @@ export default class LoginPage extends Component {
     is_show_comfirepwd_err:false,
     comfirepwd_error_info:'',
     // 提交注册按钮加载loading
-    loading: false
+    loading: false,
+    // 登录按钮加载loading
+    loginLoading: false
   };
 
   register_captcha = '';//注册——图形验证码key
@@ -149,6 +151,7 @@ export default class LoginPage extends Component {
         //用户登录
         values.verifyKey = this.login_captcha;
         const { dispatch } = this.props;
+        this.setState({loginLoading: true})
         dispatch({
           type: 'login/login',
           payload: { ...values },
@@ -178,6 +181,7 @@ export default class LoginPage extends Component {
               failTip(res.msg);
               this.getCaptcha('login_captcha');
             }
+            this.setState({loginLoading: false})
           },
         });
       }
@@ -725,7 +729,8 @@ export default class LoginPage extends Component {
       register_error_info, 
       is_show_registe_err, 
       countDownM,
-      loading
+      loading,
+      loginLoading
     } = this.state;
     return (
       <div className={styles.full_screen}
@@ -792,10 +797,18 @@ export default class LoginPage extends Component {
                 </FormItem>
 
                 <div className={`${styles.sld_login_btn_wrap} ${global.flex_column_start_start}`}>
-                  <div className={`${styles.sld_login_btn} ${global.flex_row_center_center}`}
+                    <Button 
+                      className={`${styles.sld_login_btn} ${global.flex_row_center_center}`} 
+                      type="primary" 
+                      loading={loginLoading} 
+                      onClick={() => this.props.form.submit(this.handleSubmits)}
+                    >
+                      {sldComLanguage('立即登录')}
+                    </Button>
+                  {/* <div className={`${styles.sld_login_btn} ${global.flex_row_center_center}`}
                        onClick={() => this.props.form.submit(this.handleSubmits)}>
                     {sldComLanguage('立即登录')}
-                  </div>
+                  </div> */}
                   <div className={`${global.flex_row_between_center} ${styles.operate}`}>
                     <a onClick={this.handleForgetPwd}>{sldComLanguage('忘记密码')}</a>
                     <a onClick={this.handleRegister}>{sldComLanguage('立即注册')}</a>