// src/utils/router.js
import React from 'react';
import { Router, Route, IndexRoute, hashHistory } from 'react-router';
// 導入布局組件
import cklayout from '../components/layout/cklayout';
import hglayout from '../components/layout/hglayout';
import twinlayout from '../components/layout/twinlayout';
// 導入頁(yè)面組件
import Home from '../components/Home';
import ckgd from '../components/ckfp/ckgd/ckgd';
import jxfp from '../components/ckfp/jxfp/jxfp';
import txrp from '../components/txrp/txrp';
import txhx from '../components/txhx/txhx';
const RouterConfig = () => (
<Router history={hashHistory}>
{/* 出口關(guān)單布局路由 */}
<Route path="/" component={cklayout}>
<IndexRoute component={Home} />
<Route path="ckgd" component={ckgd} />
</Route>
{/* 橫向布局路由 - 出口發(fā)票模塊 */}
<Route name="ckfp" path="ckfp" component={hglayout}>
<Route name="出口關(guān)單" path="ckgd" component={ckgd} />
<Route name="進(jìn)項發(fā)票" path="jxfp" component={jxfp}>
<Route name="普通發(fā)票管理" path="ptfpgl" component={ptfpgl} />
<Route name="海關(guān)繳款書(shū)" path="hgjkfp" component={hgjkfp} />
</Route>
<Route name="銷(xiāo)項發(fā)票" path="xxckfp" component={xxckfp} />
<Route name="退稅率查詢(xún)" path="tslcx" component={tslcx} />
</Route>
{/* 雙欄布局路由 - 退稅申報模塊 */}
<Route name="txrp" path="/txrp" component={twinlayout}>
<Route name="出口貨物明細采集" path="ckhwmxcj" component={ckhwmxcj} />
<Route name="貨物資料采集" path="hwzlcj" component={hwzlcj} />
<Route name="收匯情況采集" path="shqkcj" component={shqkcj} />
<Route name="數據申報" path="sjsb" component={sjsb} />
<Route name="數據查詢(xún)" path="sjcx" component={sjcx} />
</Route>
{/* 核銷(xiāo)模塊路由 */}
<Route name="txhx" path="/txhx" component={twinlayout}>
<Route name="計劃分配率采集" path="jhfplcj" component={jhfplcj} />
<Route name="核銷(xiāo)申報" path="hxsb" component={hxsb} />
<Route name="反饋讀入" path="fkdr" component={fkdr} />
<Route name="數據查詢(xún)" path="sjcx" component={sjcx} />
</Route>
{/* 外貿其他申報路由 */}
<Route name="wmqtsb" path="/wmqtsb" component={twinlayout}>
<Route name="出口收匯申報" path="ckshsb" component={ckshsb} />
<Route name="出口不收匯申報" path="ckbshsb" component={ckbshsb} />
</Route>
</Router>
);
export default RouterConfig;
// 路由權限控制
const requireAuth = (nextState, replace) => {
const token = sessionStorage.getItem('token');
if (!token) {
replace({
pathname: '/login',
state: { nextPathname: nextState.location.pathname }
});
}
};
// 路由配置添加權限控制
<Route path="/ckgd" component={ckgd} onEnter={requireAuth} />
// src/utils/store.js
import { createStore, applyMiddleware, compose } from 'redux';
import { persistStore, persistReducer } from 'redux-persist';
import storage from 'redux-persist/lib/storage';
import promiseMiddleware from 'redux-promise-middleware';
import rootReducer from '../reducers';
// 持久化配置
const persistConfig = {
key: 'root',
storage,
whitelist: ['user'] // 只持久化用戶(hù)相關(guān)狀態(tài)
};
const persistedReducer = persistReducer(persistConfig, rootReducer);
// Redux DevTools擴展支持
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
// 創(chuàng )建store
const store = createStore(
persistedReducer,
composeEnhancers(
applyMiddleware(promiseMiddleware)
)
);
// 創(chuàng )建持久化存儲
const persistor = persistStore(store);
export { store, persistor };
// src/reducers/index.js
import { combineReducers } from 'redux';
import user from './userReducer';
import common from './commonReducer';
// 合并所有reducer
const rootReducer = combineReducers({
user,
common
// 可以繼續添加其他業(yè)務(wù)模塊的reducer
});
export default rootReducer;
// src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { PersistGate } from 'redux-persist/integration/react';
import { store, persistor } from './utils/store';
import RouterConfig from './utils/router';
import './index.less';
// 渲染應用
ReactDOM.render(
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
<RouterConfig />
</PersistGate>
</Provider>,
document.getElementById('root')
);
// src/setupProxy.js
const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function(app) {
// 開(kāi)發(fā)環(huán)境代理配置
app.use('/tms', createProxyMiddleware({
target: 'http://117.78.0.163:8521',
changeOrigin: true,
pathRewrite: {
'^/tms': '/tms'
},
onProxyReq: (proxyReq, req, res) => {
// 可以在這里添加請求頭等處理
console.log('Proxying request:', req.url);
}
}));
// 其他API代理
app.use('/api', createProxyMiddleware({
target: 'http://localhost:8080',
changeOrigin: true
}));
};
// 環(huán)境判斷和配置
const getConfig = () => {
const host = window.location.host;
const port = window.location.port;
if (host === "localhost:3000" || port === "3000") {
return {
apiBaseUrl: "http://117.78.0.163:8521/",
env: 'development'
};
} else if (host.includes("117.78.0.163")) {
return {
apiBaseUrl: "/",
env: 'production'
};
} else {
return {
apiBaseUrl: "/",
env: 'production'
};
}
};
export const config = getConfig();
// webpack.config.js 相關(guān)配置
module.exports = {
// 入口配置
entry: './src/index.js',
// 輸出配置
output: {
path: path.resolve(__dirname, 'build'),
filename: 'static/js/[name].[contenthash:8].js',
publicPath: '/'
},
// 模塊解析
resolve: {
extensions: ['.js', '.jsx', '.json'],
alias: {
'@': path.resolve(__dirname, 'src')
}
},
// 模塊規則
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader'
}
},
{
test: /\.less$/,
use: [
'style-loader',
'css-loader',
'less-loader'
]
}
]
}
};
// src/index.less
@import '~antd/dist/antd.less';
// 主題變量覆蓋
@primary-color: #1890ff;
@border-radius-base: 4px;
// 全局樣式
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
// 布局樣式
.app-layout {
min-height: 100vh;
.app-header {
background: #fff;
padding: 0 24px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
.app-content {
padding: 24px;
background: #f0f2f5;
}
}
// CSS模塊化配置
{
test: /\.module\.less$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
modules: {
localIdentName: '[name]__[local]--[hash:base64:5]'
}
}
},
'less-loader'
]
}
{
"extends": [
"eslint:recommended",
"plugin:react/recommended"
],
"parser": "babel-eslint",
"env": {
"browser": true,
"es6": true
},
"rules": {
"react/prop-types": "warn",
"no-console": "warn",
"indent": ["error", 4]
}
}
{
"semi": true,
"trailingComma": "none",
"singleQuote": true,
"printWidth": 100,
"tabWidth": 4
}
這些配置為React應用提供了完整的開(kāi)發(fā)環(huán)境支持,包括路由管理、狀態(tài)管理、構建配置和開(kāi)發(fā)工具集成。