Commit 3093a118 authored by 邓晓峰's avatar 邓晓峰

feat: add mockMiddlewares

parent 5bcdf471
Pipeline #22617 skipped with stages
......@@ -2,8 +2,8 @@ export default {
navTheme: 'dark',
layout: 'side',
contentWidth: 'Fluid',
fixedHeader: false,
fixSiderbar: false,
fixedHeader: true,
fixSiderbar: true,
menu: {
locale: true,
},
......@@ -11,5 +11,5 @@ export default {
headerHeight: 48,
title: '熊猫智慧城市监控管理解决方案',
iconfontUrl: '',
primaryColor: '#1890ff',
primaryColor: '#1890ff'
};
......@@ -5,7 +5,7 @@ export default {
dev: [
{
name: 'web4_console',
entry: `//${window.location.hostname}:3020/civweb4`,
entry: `//${window.location.hostname}:3020/civweb4/`,
container: '#micro-container',
activeRule: genActiveRule('/civbase/civweb4'),
props: {},
......
module.exports = {
mock: true,
dev: {
'/CityInterface': {
// target: 'http://192.168.10.151:8055',
// target: 'https://panda-water.cn',
target: 'https://panda-water.cn',
// target: 'http://192.168.19.102:8055',
target: 'https://panda-water.com',
// target: 'https://panda-water.com',
// target: 'http://192.168.10.150:8050',
// target: 'http://192.168.19.103:8112',
// target: 'http://192.168.12.8:8098',
......@@ -21,9 +22,9 @@ module.exports = {
'/cityinterface': {
// target: 'http://192.168.10.151:8055',
// target: 'http://192.168.10.150:8050',
// target: 'https://panda-water.cn',
target: 'https://panda-water.cn',
// target: 'http://192.168.19.102:8055',
target: 'https://panda-water.com',
// target: 'https://panda-water.com',
// target: 'http://192.168.12.8:8098',
// target: 'http://192.168.10.20:8888',
changeOrigin: true,
......@@ -52,9 +53,9 @@ module.exports = {
// target: 'http://192.168.12.8:8098',
// target: 'http://192.168.10.20:8888',
// target: 'http://192.168.10.151:8055',
// target: 'https://panda-water.cn',
target: 'https://panda-water.cn',
// target: 'http://192.168.19.102:8055',
target: 'https://panda-water.com',
// target: 'https://panda-water.com',
// target: 'http://192.168.10.150:8050',
changeOrigin: true,
headers: {
......
......@@ -49,7 +49,7 @@ module.exports = require('./webpack.base.babel')({
fs: 'empty',
net: 'empty',
tls: 'empty',
child_process: 'empty'
child_process: 'empty',
},
performance: {
hints: false,
......
......@@ -2,7 +2,7 @@
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const WebpackPwaManifest = require('webpack-pwa-manifest');
const OfflinePlugin = require('offline-plugin');
// const OfflinePlugin = require('offline-plugin');
const { HashedModuleIdsPlugin } = require('webpack');
const TerserPlugin = require('terser-webpack-plugin');
const CompressionPlugin = require('compression-webpack-plugin');
......@@ -85,25 +85,25 @@ module.exports = require('./webpack.base.babel')({
}),
// Put it in the end to capture all the HtmlWebpackPlugin's
// assets manipulations and do leak its manipulations to HtmlWebpackPlugin
// // assets manipulations and do leak its manipulations to HtmlWebpackPlugin
// new OfflinePlugin({
// relativePaths: false,
// publicPath: '/',
// appShell: '/',
//
// // No need to cache .htaccess. See http://mxs.is/googmp,
// // this is applied before any match in `caches` section
// excludes: ['.htaccess'],
//
// caches: {
// main: [':rest:'],
//
// // All chunks marked as `additional`, loaded after main section
// // and do not prevent SW to install. Change to `optional` if
// // do not want them to be preloaded at all (cached only when first loaded)
// additional: ['*.chunk.js'],
// },
//
// // Removes warning for about `additional` section usage
// safeToUseOptionalCaches: true,
// }),
......@@ -115,26 +115,26 @@ module.exports = require('./webpack.base.babel')({
minRatio: 0.8,
}),
// new WebpackPwaManifest({
// name: '运维管理平台',
// short_name: '运维管理平台',
// description: '运维管理平台',
// background_color: '#fafafa',
// theme_color: '#b1624d',
// inject: true,
// ios: true,
// icons: [
// {
// src: path.resolve('src/images/icon-512x512.png'),
// sizes: [72, 96, 128, 144, 192, 384, 512],
// },
// {
// src: path.resolve('src/images/icon-512x512.png'),
// sizes: [120, 152, 167, 180],
// ios: true,
// },
// ],
// }),
new WebpackPwaManifest({
name: '熊猫智慧城市监控管理解决方案',
short_name: '熊猫智慧城市监控管理解决方案',
description: '熊猫智慧城市监控管理解决方案',
background_color: '#fafafa',
theme_color: '#b1624d',
inject: true,
ios: true,
icons: [
{
src: path.resolve('src/images/icon-512x512.png'),
sizes: [72, 96, 128, 144, 192, 384, 512],
},
{
src: path.resolve('src/images/icon-512x512.png'),
sizes: [120, 152, 167, 180],
ios: true,
},
],
}),
new HashedModuleIdsPlugin({
hashFunction: 'sha256',
......
const getNotices = (req, res) => {
res.json([
{
id: '000000001',
avatar:
'https://gw.alipayobjects.com/zos/rmsportal/ThXAXghbEsBCCSDihZxY.png',
title: '你收到了 14 份新周报',
datetime: '2017-08-09',
type: 'notification',
},
{
module.exports = {
'GET /api/notices': {
id: '000000002',
avatar:
'https://gw.alipayobjects.com/zos/rmsportal/OKJXDXrmkNshAMvwtvhu.png',
title: '你推荐的 曲妮妮 已通过第三轮面试',
datetime: '2017-08-08',
type: 'notification',
},
{
id: '000000003',
avatar:
'https://gw.alipayobjects.com/zos/rmsportal/kISTdvpyTAhtGxpovNWd.png',
title: '这种模板可以区分多种通知类型',
datetime: '2017-08-07',
read: true,
type: 'notification',
},
{
id: '000000004',
avatar:
'https://gw.alipayobjects.com/zos/rmsportal/GvqBnKhFgObvnSGkDsje.png',
title: '左侧图标用于区分不同的类型',
datetime: '2017-08-07',
type: 'notification',
},
{
id: '000000005',
avatar:
'https://gw.alipayobjects.com/zos/rmsportal/ThXAXghbEsBCCSDihZxY.png',
title: '内容不要超过两行字,超出时自动截断',
datetime: '2017-08-07',
type: 'notification',
},
{
id: '000000006',
avatar:
'https://gw.alipayobjects.com/zos/rmsportal/fcHMVNCjPOsbUGdEduuv.jpeg',
title: '曲丽丽 评论了你',
......@@ -51,61 +9,4 @@ const getNotices = (req, res) => {
type: 'message',
clickClose: true,
},
{
id: '000000007',
avatar:
'https://gw.alipayobjects.com/zos/rmsportal/fcHMVNCjPOsbUGdEduuv.jpeg',
title: '朱偏右 回复了你',
description: '这种模板用于提醒谁与你发生了互动,左侧放『谁』的头像',
datetime: '2017-08-07',
type: 'message',
clickClose: true,
},
{
id: '000000008',
avatar:
'https://gw.alipayobjects.com/zos/rmsportal/fcHMVNCjPOsbUGdEduuv.jpeg',
title: '标题',
description: '这种模板用于提醒谁与你发生了互动,左侧放『谁』的头像',
datetime: '2017-08-07',
type: 'message',
clickClose: true,
},
{
id: '000000009',
title: '任务名称',
description: '任务需要在 2017-01-12 20:00 前启动',
extra: '未开始',
status: 'todo',
type: 'event',
},
{
id: '000000010',
title: '第三方紧急代码变更',
description: '冠霖提交于 2017-01-06,需在 2017-01-07 前完成代码变更任务',
extra: '马上到期',
status: 'urgent',
type: 'event',
},
{
id: '000000011',
title: '信息安全考试',
description: '指派竹尔于 2017-01-09 前完成更新并发布',
extra: '已耗时 8 天',
status: 'doing',
type: 'event',
},
{
id: '000000012',
title: 'ABCD 版本发布',
description: '冠霖提交于 2017-01-06,需在 2017-01-07 前完成代码变更任务',
extra: '进行中',
status: 'processing',
type: 'event',
},
]);
};
export default {
'GET /api/notices': getNotices,
};
This diff is collapsed.
......@@ -79,14 +79,18 @@
]
},
"pre-commit": "lint:staged",
"mock": true,
"resolutions": {
"babel-core": "7.0.0-bridge.0"
},
"dependencies": {
"@babel/polyfill": "7.4.3",
"@babel/runtime": "^7.10.5",
"promise.prototype.finally": "^3.1.2",
"@wisdom-utils/components": "0.0.6",
"@wisdom-utils/utils": "0.0.26",
"@wisdom-utils/utils": "0.0.27",
"@wisdom-utils/vapp-browser-vm": "^0.0.11",
"@wisdom-utils/vapp-browser-vm-plugins": "^0.0.13",
"animate.css": "^4.1.1",
"chalk": "2.4.2",
"compression": "1.7.4",
......@@ -117,7 +121,6 @@
"react-dom": "16.12.0",
"react-draggable": "^4.4.3",
"react-helmet": "6.0.0-beta",
"react-intl": "2.8.0",
"react-redux": "7.0.2",
"react-router-dom": "5.1.0",
"react-use": "^15.3.4",
......@@ -131,7 +134,7 @@
},
"devDependencies": {
"@ant-design/icons": "^4.0.0",
"@ant-design/pro-layout": "^6.10.7",
"@ant-design/pro-layout": "^6.11.1",
"@ant-design/pro-skeleton": "^1.0.0-beta.2",
"@ant-design/pro-table": "^2.5.3",
"@ant-design/pro-utils": "^1.10.4",
......@@ -149,6 +152,8 @@
"@commitlint/config-conventional": "^9.1.2",
"@umijs/fabric": "^2.2.0",
"@umijs/hooks": "^1.9.3",
"body-parser": "^1.19.0",
"multer": "^1.4.2",
"add-asset-html-webpack-plugin": "3.1.3",
"antd": "^4.10.1",
"babel-core": "7.0.0-bridge.0",
......@@ -227,6 +232,7 @@
"react-app-polyfill": "0.2.2",
"react-dom": "^16.8.6",
"react-helmet-async": "^1.0.4",
"react-intl": "^2.8.0",
"react-router-config": "^5.1.1",
"react-sticky": "^6.0.3",
"react-test-renderer": "16.8.6",
......
/* eslint consistent-return:0 import/order:0 */
const express = require('express');
const logger = require('./logger');
......@@ -8,12 +7,17 @@ const port = require('./port');
const setup = require('./middlewares/frontendMiddleware');
const isDev = process.env.NODE_ENV !== 'production';
const pkg = require('../package.json');
const proxyConfig = require('../config/proxy');
const mockMiddewares = require('./mock');
const ngrok =
(isDev && process.env.ENABLE_TUNNEL) || argv.tunnel
? require('ngrok')
: false;
const { resolve } = require('path');
const app = express();
if (proxyConfig.mock) {
app.use('/api/*', mockMiddewares);
}
setup(app, {
outputPath: resolve(process.cwd(), pkg.name.toLocaleLowerCase()),
......@@ -30,6 +34,8 @@ app.get('*.js', (req, res, next) => {
next();
});
// Start your app.
app.listen(port, host, async err => {
if (err) {
......
"use strict";
var path = require('path');
var express = require('express');
var compression = require('compression');
var pkg = require('../../package.json');
module.exports = function addProdMiddlewares(app, options) {
var publicPath = options.publicPath || pkg.name.toLocaleLowerCase() || '/';
var outputPath = options.outputPath || path.resolve(process.cwd(), pkg.name.toLocaleLowerCase()); // compression middleware compresses your server responses which makes them
// smaller (applies also to assets). You can read more about that technique
// and other good practices on official Express.js docs http://mxs.is/googmy
app.use(compression());
app.use(publicPath, express["static"](outputPath));
app.get('*', function (req, res) {
return res.sendFile(path.resolve(outputPath, 'index.html'));
});
};
\ No newline at end of file
"use strict";
/* eslint-disable global-require */
/**
* Front-end middleware
*/
var proxyConfig = require('../../config/proxy');
var fs = require('fs');
var path = require('path');
var apiMocker = require('connect-api-mocker');
module.exports = function (app, options) {
var isProd = process.env.NODE_ENV === 'production';
var _require = require('http-proxy-middleware'),
createProxyMiddleware = _require.createProxyMiddleware;
if (isProd) {
var addProdMiddlewares = require('./addProdMiddlewares');
addProdMiddlewares(app, options);
} else {
var webpackConfig = require('../../internals/webpack/webpack.dev.babel');
var addDevMiddlewares = require('./addDevMiddlewares');
Object.keys(proxyConfig.dev).forEach(function (item) {
app.use(createProxyMiddleware(item, proxyConfig.dev[item]));
});
addDevMiddlewares(app, webpackConfig);
}
return app;
};
\ No newline at end of file
const { chokidar, signale, createDebug } = require('@umijs/utils');
const utils = require('./util');
const debug = createDebug('preset-build-in:mock:createMiddleware');
function createMiddleware(opts) {
const { mockData, mockWatcherPaths, updateMockData } = opts;
let data = mockData;
const errors = [];
debug('mockWatcherPaths', mockWatcherPaths);
const watcher = chokidar.watch(mockWatcherPaths, {
ignoreInitial: true,
});
watcher
.on('ready', () => debug('Initial scan complete. Ready for changes'))
.on('all', async (event, file) => {
debug(`[${event}] ${file}, reload mock data`);
errors.splice(0, errors.length);
utils.cleanRequireCache(mockWatcherPaths);
// refresh data
// eslint-disable-next-line no-const-assign
data = await updateMockData().mockData;
if (!errors.length) {
signale.success(`Mock files parse success`);
}
});
process.once('SIGINT', async () => {
await watcher.close();
});
return {
middleware: (req, res, next) => {
const match = data && utils.matchMock(req, data);
if (match) {
return match.handler(req, res, next);
}
return next();
},
};
}
module.exports = createMiddleware
const utils = require('./util');
const createMiddleware = require('./createMiddleware');
function mockMiddewares(req, res, next) {
const mockResult = utils.getMockData('./');
const { middleware } = createMiddleware({
...mockResult,
updateMockData: async () => {
const result = utils.getMockData('./');
return result;
},
});
return middleware(req, res, next);
}
module.exports = mockMiddewares;
const {
winPath,
createDebug,
glob,
parseRequireDeps,
} = require('@umijs/utils');
const pathHeler = require('path');
const fs = require('fs');
const assert = require('assert');
const bodyParser = require('body-parser');
const pathToRegexp = require('path-to-regexp');
const multer = require('multer');
const VALID_METHODS = ['get', 'post', 'put', 'patch', 'delete'];
const BODY_PARSED_METHODS = ['post', 'put', 'patch', 'delete'];
const debug = createDebug('preset-build-in:mock:utils');
const registerBabel = paths => {
// support
// clear require cache and set babel register
const requireDeps = paths.reduce((memo, file) => {
memo = memo.concat(parseRequireDeps(file));
return memo;
}, []);
requireDeps.forEach(f => {
if (require.cache[f]) {
delete require.cache[f];
}
});
};
const getMockData = cwd => {
const mockPaths = [
// eslint-disable-next-line no-undef
...glob.sync('mock/*.[jt]s'),
]
.map(p => pathHeler.resolve(cwd, p))
.filter(p => p && fs.existsSync(p))
.map(p => winPath(p));
debug(`load mock data including files ${JSON.stringify(mockPaths)}`);
// eslint-disable-next-line no-undef
registerBabel(mockPaths);
//
// // eslint-disable-next-line no-use-before-define,no-undef
const mockData = normalizeConfig(getMockConfig(mockPaths));
//
const mockWatcherPaths = [...(mockPaths || [])]
.filter(p => p && fs.existsSync(p))
.map(p => winPath(p));
return {
mockData,
mockPaths,
mockWatcherPaths,
};
};
function parseKey(key) {
let method = 'get';
// eslint-disable-next-line no-shadow
let path = key;
if (/\s+/.test(key)) {
const splited = key.split(/\s+/);
method = splited[0].toLowerCase();
// eslint-disable-next-line prefer-destructuring
path = splited[1];
}
assert(
VALID_METHODS.includes(method),
`Invalid method ${method} for path ${path}, please check your mock files.`,
);
return {
method,
path,
};
}
function getMockConfig(files) {
return files.reduce((memo, mockFile) => {
try {
const m = require(mockFile); // eslint-disable-line
memo = {
...memo,
...(m.default || m),
};
return memo;
} catch (e) {
throw new Error(e.stack);
}
}, {});
}
function normalizeConfig(config) {
return Object.keys(config).reduce((memo, key) => {
const handler = config[key];
const type = typeof handler;
assert(
type === 'function' || type === 'object',
`mock value of ${key} should be function or object, but got ${type}`,
);
// eslint-disable-next-line no-shadow
const { method, path } = parseKey(key);
const keys = [];
const re = pathToRegexp(path, keys);
memo.push({
method,
path,
re,
handler: createHandler(method, path, handler),
});
return memo;
}, []);
}
// eslint-disable-next-line no-shadow
function createHandler(method, path, handler) {
return function(req, res, next) {
if (BODY_PARSED_METHODS.includes(method)) {
bodyParser.json({ limit: '5mb', strict: false })(req, res, () => {
bodyParser.urlencoded({ limit: '5mb', extended: true })(
req,
res,
() => {
sendData();
},
);
});
} else {
sendData();
}
function sendData() {
if (typeof handler === 'function') {
multer().any()(req, res, () => {
handler(req, res, next);
});
} else {
res.json(handler);
}
}
};
}
function decodeParam(val) {
if (typeof val !== 'string' || val.length === 0) {
return val;
}
try {
return decodeURIComponent(val);
} catch (err) {
if (err instanceof URIError) {
err.message = `Failed to decode param ' ${val} '`;
// @ts-ignore
err.status = 400;
// @ts-ignore
err.statusCode = 400;
}
throw err;
}
}
function cleanRequireCache(paths) {
Object.keys(require.cache).forEach(file => {
if (paths.some(p => winPath(file).indexOf(p) > -1)) {
delete require.cache[file];
}
});
}
function matchMock(req, mockData) {
const { method } = req;
const targetMethod = method.toLowerCase();
// eslint-disable-next-line no-underscore-dangle
const resolvepath = req._parsedUrl.path;
for (const mock of mockData) {
// eslint-disable-next-line no-shadow
const { method, re, keys } = mock;
if (method === targetMethod) {
// eslint-disable-next-line no-underscore-dangle
const match = re.exec(resolvepath);
if (match) {
const params = {};
for (let i = 1; i < match.length; i += 1) {
const key = keys[i - 1];
const prop = key.name;
const val = decodeParam(match[i]);
// @ts-ignore
// eslint-disable-next-line no-undef
if (val !== undefined || !hasOwnProdperty.call(params, prop)) {
params[prop] = val;
}
}
req.params = params;
return mock;
}
}
}
}
function getFlatRoutes(routes) {
return routes.reduce((memo, route) => {
// eslint-disable-next-line no-shadow
const { routes, path } = route;
if (path && !path.includes('?')) {
memo.push(route);
}
if (routes) {
memo = memo.concat(
getFlatRoutes({
routes,
}),
);
}
return memo;
}, []);
}
function getConflictPaths({ mockData, routes }) {
const conflictPaths = [];
getFlatRoutes({ routes }).forEach(route => {
const { path, redirect } = route;
if (path && !path.startsWith(':') && !redirect) {
const req = {
path: !path.startsWith('/') ? `/${path}` : path,
method: 'get',
};
const matched = matchMock(req, mockData);
if (matched) {
conflictPaths.push({ path: matched.path });
}
}
});
return conflictPaths;
}
module.exports = {
getMockData,
matchMock,
cleanRequireCache,
};
import baseService from './service/base';
import { message } from 'antd';
import { service, request } from '@wisdom-utils/utils';
import { getRootContext } from '@wisdom-utils/vapp-browser-vm/lib/vm';
import AppService from './service/base';
import notificationService from './service/notification';
// eslint-disable-next-line no-return-await
request.reportCodeError = true;
export { baseService, notificationService };
request.setResponseHandler(response => {
if (response.code === 401) {
return window.location.reload();
}
return response;
});
request.setErrorHandler((resData, { config }) => {
if (!config.noErrorTip) {
message.error(resData.message);
}
});
const appService = service(AppService);
const noticeService = service(notificationService);
export { appService, noticeService };
import { service, jsonp, request } from '@wisdom-utils/utils';
import { jsonp } from '@wisdom-utils/utils';
import constants from '../constants';
export const API = {
AUTHORIZATION_TOKEN: '/Publish/Identity/AuthorizationToken',
......@@ -27,9 +27,12 @@ export const API = {
FILE_DOWNLOAD: '/cityinterface/rest/services/filedownload.svc/download',
GET_VERSION: '/CityInterface/rest/services/OMs.svc/U_GetVersion',
UPDATE_AVATAR: '/CityInterface/rest/services/OMs.svc/U_EditUser',
UPLOAD_FILE_URL:
'/cityinterface/rest/services/filedownload.svc/uploadfile/个人信息/{path}/{filename}',
AVATAR_FILE_URL: '/cityinterface/rest/services/filedownload.svc/download',
};
const services = service({
const services = {
authorizationToken: {
url: API.AUTHORIZATION_TOKEN,
method: constants.REQUEST_METHOD_GET,
......@@ -132,7 +135,7 @@ const services = service({
method: constants.REQUEST_METHOD_GET,
type: constants.REQUEST_HTTP,
},
});
};
export const searchAutoCity = keywords => {
const url = 'https://restapi.amap.com/v3/assistant/inputtips';
......
import { service } from '@wisdom-utils/utils';
import constants from '../constants';
const API = {
GET_INFORMATION:
'/CityInterface/rest/services/CountyProduct.svc/SCADAOper/GetInformationInfo',
......@@ -12,7 +10,7 @@ const API = {
'/CityInterface/rest/services/WisdomUnion.svc/CustomerManage/AddOption',
};
const notificationService = service({
const notificationService = {
getInformationInfo: {
url: API.GET_INFORMATION,
method: constants.REQUEST_METHOD_GET,
......@@ -33,6 +31,6 @@ const notificationService = service({
method: constants.REQUEST_METHOD_POST,
type: constants.REQUEST_HTTP,
},
});
};
export default notificationService;
......@@ -6,6 +6,7 @@ import 'antd/dist/antd.less';
import 'file-loader?name=.htaccess!./.htaccess'; // eslint-disable-line import/extensions
import 'kit_utils/lib/format';
import 'sanitize.css/sanitize.css';
import './locales/zh-CN';
import React from 'react';
import ReactDOM from 'react-dom';
import { ErrorBoundary } from '@ant-design/pro-utils';
......@@ -18,11 +19,14 @@ import defaultSettings from '../config/defaultSetting';
import Container from './components/Container';
import configureStore from './configureStore';
import App from './containers/App';
import './loader';
import './vm';
import { actionCreators } from './containers/App/store';
import { initMicroApps } from './micro';
import history from './utils/history';
import { isString } from './utils/utils';
import services from './api/service/base';
import i18n from './utils/share';
import { appService } from './api';
const isHttps = document.location.protocol === 'https:';
const { pwa } = defaultSettings;
// eslint-disable-next-line no-restricted-globals
......@@ -32,6 +36,7 @@ window.createStoreage = new Storeage(namespace);
const initialState = Immutable.Map();
const store = configureStore(initialState, history);
const MOUNT_NODE = document.getElementById('app');
window.i18n = i18n;
const render = () => {
// eslint-disable-next-line react-hooks/rules-of-hooks
......@@ -78,48 +83,36 @@ const initGlobalConfig = () => {
store.dispatch(actionCreators.getConfig(config));
render({ appContent: '', loading: true });
} else {
services
.queryConfig({ client: params.getParams('client') || 'city' })
.then(res => {
if (res) {
const data = res;
store.dispatch(actionCreators.getConfig(Object.assign({}, data)));
// eslint-disable-next-line no-shadow
try {
services
.getWateWayConfig()
// eslint-disable-next-line no-shadow
.then(res => {
appService.getWateWayConfig().then(res => {
const hasGateWay =
res && res.data && isString(res.data)
? JSON.parse(res.data)
: res.data;
// eslint-disable-next-line no-debugger
res && res.data && isString(res.data) ? JSON.parse(res.data) : res.data;
if (res.code === 0) {
store.dispatch(
actionCreators.getConfig(
Object.assign({}, data, {
Object.assign({}, window.globalConfig, {
hasGateWay,
apiGatewayDomain: `${
window.location.origin
}/Publish/GateWay`,
apiGatewayDomain: `${window.location.origin}/Publish/GateWay`,
}),
),
);
}
})
.catch(error => {
store.dispatch(actionCreators.getConfigError(error));
store.dispatch(
actionCreators.getConfig(Object.assign({}, data)),
);
});
} catch (e) {
console.log(e);
// eslint-disable-next-line no-empty
} finally {
appService
.queryConfig({ client: params.getParams('client') || 'city' })
.then(res => {
if (res) {
const data = res;
if (!data.client) {
delete data.client;
}
store.dispatch(
actionCreators.getConfig(
Object.assign({}, window.globalConfig, data),
),
);
// eslint-disable-next-line no-shadow
}
return res;
})
// eslint-disable-next-line no-shadow
.then(res => {
......@@ -129,23 +122,25 @@ const initGlobalConfig = () => {
store.dispatch(actionCreators.getConfigError(error));
});
}
if (config.token) {
initMicroApps(loader);
}
};
initGlobalConfig();
initLocale();
window.share &&
window.share.event &&
window.share.event.on('triggerMicro', () => {
initMicroApps(loader);
});
initGlobalConfig();
initLocale();
// initGlobalConfig();
if (pwa) {
const appPWA = window.i18n.getI18n('app');
window.addEventListener('sw.offline', () => {
message.warning('当前处于离线状态');
message.warning(appPWA.get('pwa.offline'));
});
window.addEventListener('sw.updated', event => {
......@@ -178,12 +173,12 @@ if (pwa) {
reloadSW();
}}
>
刷新
{appPWA.get('pwa.serviceworker.updated.ok')}
</Button>
);
notification.open({
message: '有新内容',
description: '请点击“刷新”按钮或者手动刷新页面',
message: appPWA.get('pwa.serviceworker.updated'),
description: appPWA.get('pwa.serviceworker.updated.hint'),
btn,
key,
onClose: async () => null,
......
......@@ -7,18 +7,19 @@ const checkPermissions = (
target,
Exception,
) => {
const client = (window.globalConfig && window.globalConfig.client) || 'city';
const filterPath = [
{ name: '/', path: '/' },
{ name: '/', path: `/?client=${window.globalConfig.client || 'city'}` },
{ name: '/', path: `/?client=${client}` },
{
name: 'civbase',
path: `/civbase/?client=${window.globalConfig.client || 'city'}`,
path: `/civbase/?client=${client}`,
},
{ name: 'industry', path: '/industry' },
{ name: 'civweb4', path: `/civweb4/` },
{
name: 'civweb4',
path: `/civweb4/?client=${window.globalConfig.client || 'city'}`,
path: `/civweb4/?client=${client}`,
},
{ name: '404', path: '/404' },
{ name: '403', path: '/403' },
......
......@@ -13,15 +13,18 @@ import {
import Cookies from 'js-cookie';
import { withRouter } from 'react-router-dom';
import styles from './index.less';
import services, { changePassword } from '../../api/service/base';
// eslint-disable-next-line import/named
import { API } from '../../api/service/base';
import { appService } from '../../api';
import i18n from '../../utils/share';
const app = i18n.getI18n('component');
const formItemLayout = {
labelCol: {
xs: { span: 4 },
sm: { span: 4 },
},
};
const UPLOAD_FILE_URL =
'/cityinterface/rest/services/filedownload.svc/uploadfile/个人信息/{path}/{filename}';
/* eslint-disable */
const getIOT = () =>
window.globalConfig.loginTemplate === 'Dark - IOTMultiLogin.html';
......@@ -46,7 +49,7 @@ class AvatarDropdown extends React.Component {
popVisible: false,
path: null,
version: null,
action: UPLOAD_FILE_URL
action: API.UPLOAD_FILE_URL
}
}
loginout = event => {
......@@ -114,21 +117,21 @@ class AvatarDropdown extends React.Component {
newpassword: res.newPwd,
token: window.globalConfig.token,
};
changePassword(params)
appService.changePassword(params)
.then(res => {
if (res.success) {
message.success('修改密码成功');
message.success(app.get('account.password.update.success'));
setTimeout(() => {
this.setState({
visible: false,
});
}, 300);
} else {
message.error('原密码输入错误');
message.error(app.get('account.oldpassword.errorMessage'));
}
})
.catch(error => {
message.error('修改密码失败');
message.error(app.get('account.password.update.fail'));
});
})
.catch(error => {
......@@ -190,7 +193,7 @@ class AvatarDropdown extends React.Component {
}
componentDidMount() {
services.getVersion({
appService.getVersion({
ignoreSite: true
}).then(res => {
if(res.success) {
......@@ -199,7 +202,7 @@ class AvatarDropdown extends React.Component {
})
}
}).catch(error => {
message.error("获取版本号错误,请联系相关开发人员")
message.error(app.get('getVersion.errorMessage'))
})
}
......@@ -263,7 +266,6 @@ class AvatarDropdown extends React.Component {
console.log('onStart', file, file.name);
},
onSuccess(res, file) {
debugger
if(res.success) {
const avatarPath = "/个人信息/" + self.state.path + '/' + file.name;
const params = {
......@@ -278,19 +280,19 @@ class AvatarDropdown extends React.Component {
WXid: props.global.get("userInfo.WXid")
}
services.updateAvatar(params).then(res => {
appService.updateAvatar(params).then(res => {
if(res.success) {
message.success("头像修改成功");
message.success(app.get('avatar.update.success'));
self.setState({
currentUser: {
name: self.state.currentUser.name,
avatar: `/cityinterface/rest/services/filedownload.svc/download${avatarPath}`,
action: UPLOAD_FILE_URL
avatar: `${API.AVATAR_FILE_URL}${avatarPath}`,
action: API.UPLOAD_FILE_URL
}
})
}
}).catch(e => {
message.error("头像修改失败")
message.error(app.get('avatar.update.fail'))
})
} else {
message.error(res.message);
......@@ -323,30 +325,30 @@ class AvatarDropdown extends React.Component {
<ul>
<li>
<span />
<span className={styles.label}>账号</span>
<span className={styles.label}>{app.get('avatar.account')}</span>
<span className={styles.value}>{userInfo.loginName}</span>
</li>
<li>
<span />
<span className={styles.label}>姓名</span>
<span className={styles.label}>{app.get('avatar.name')}</span>
<span className={styles.value}>{userInfo.fullName}</span>
</li>
<li>
<span />
<span className={styles.label}>部门</span>
<span className={styles.label}>{app.get('avatar.depart')}</span>
<span className={styles.value}>
{userInfo && userInfo.depart && userInfo.depart.name}
</span>
</li>
<li>
<span />
<span className={styles.label}>角色</span>
<span className={styles.label}>{app.get('avatar.role')}</span>
<span className={styles.value}>{this.getRoles()}</span>
</li>
{site ? (
<li>
<span />
<span className={styles.label}>企业编号</span>
<span className={styles.label}>{app.get('siteCode')}</span>
<span className={styles.value}>{userInfo.site}</span>
</li>
) : null}
......@@ -354,10 +356,10 @@ class AvatarDropdown extends React.Component {
</div>
<div className={styles.exit}>
{userInfo && userInfo.site === '' && (
<a onClick={event => this.showModal(event)}>修改密码</a>
<a onClick={event => this.showModal(event)}>{app.get('password.update')}</a>
)}
<a onClick={this.loginout}>退出登录</a>
<a onClick={this.loginout}>{app.get('exit.login')}</a>
</div>
</div>
</div>
......
......@@ -10,7 +10,8 @@ import styles from './index.less';
import { findPathByWidget, isJSON } from '../../utils/utils';
import { actionCreators } from '../../containers/App/store';
import service from '../../api/service/notification';
import i18n from '../../utils/share';
const app = i18n.getI18n('component');
class NoticeIconView extends Component {
constructor(props) {
super(props);
......@@ -211,8 +212,8 @@ class NoticeIconView extends Component {
>
<NoticeIcon.Tab
list={this.state.noticeData}
title="通知"
emptyText="你已查看所有通知"
title={app.get('noticeIcon.title')}
emptyText={app.get('noticeIocn.allClear')}
confirmRead={this.notifier.confirmRead}
handlerSysDetail={this.handlerSysDetail}
loadMore={this.notifier.loadMore}
......@@ -221,7 +222,7 @@ class NoticeIconView extends Component {
</NoticeIcon>
{this.state.platformVisible && this.state.alarmMessage && (
<Modal
title="报警消息"
title={app.get('noticeIcon.modal.alarm.title')}
visible={this.state.platformVisible}
zIndex={5000}
className={styles.platformModal}
......@@ -251,7 +252,7 @@ class NoticeIconView extends Component {
this.state.alarmMessage.messageContent.title}
</a>
<span
title="点击标为已读"
title={app.get('noticeIcon.messsage.statused')}
onClick={event =>
this.handlerMointer(
event,
......@@ -321,7 +322,7 @@ class NoticeIconView extends Component {
{this.state.sysTopVisible && this.state.sysMessage && (
<Modal
title="系统通知"
title={app.get('noticeIcon.model.system.title')}
visible
zIndex={8000}
className={styles.noticeModal}
......
......@@ -6,7 +6,7 @@ import { connect } from 'react-redux';
import { withRouter } from 'react-router-dom';
import Icon from '@ant-design/icons';
import { useIntl } from '../hooks';
import { actionCreators } from '../../containers/App/store';
import HeaderSearch from '../HeaderSearch';
import Avatar from './AvatarDropdown';
......@@ -103,6 +103,9 @@ const GlobalHeaderRight = props => {
if (theme === 'dark' && layout === 'top') {
className = `${styles.right} ${styles.dark}`;
}
const {formatMessage} = useIntl('component');
/* eslint-disable */
const handleSearch = value => {
// eslint-disable-next-line no-undef
......@@ -175,7 +178,7 @@ const GlobalHeaderRight = props => {
<div className={className}>
<HeaderSearch
className={`${styles.action} ${styles.search}`}
placeholder="搜索菜单"
placeholder={formatMessage('search.menu.placeholder')}
defaultValue=""
options={options}
{...props}
......@@ -184,10 +187,10 @@ const GlobalHeaderRight = props => {
onSearch={handleSearch}
/>
<div className={styles.nav}>
<HomeIcon onClick={goHome} title="首页" />
<OrderIcon onClick={handleOrder} title="工单" />
<HomeIcon onClick={goHome} title={formatMessage('header.icon.home')} />
<OrderIcon onClick={handleOrder} title={formatMessage('header.icon.order')} />
</div>
<NoticeIconView title="消息" />
<NoticeIconView title={formatMessage('header.icon.alarm')} />
<Avatar menu global={props.global} updateCurrentIndex={props.updateCurrentIndex}/>
{/* <SelectLang className={styles.action} /> */}
</div>
......
......@@ -31,22 +31,26 @@
margin-left: 8px;
}
}
:global(.ant-select-selection-search .ant-input-affix-wrapper) {
:global {
.ant-select-selection-search {
.ant-input-affix-wrapper {
border: 1px solid #b1b9c7;
border-radius: 28px;
width: 320px !important;
color: #555555;
}
:global(.ant-input-affix-wrapper) {
}
.ant-input-affix-wrapper {
padding-right: 12px;
width: 320px;
min-width: 120px;
max-width: 320px;
border-radius: 28px;
}
:global(.anticon-search) {
.anticon-search {
color: #888888;
}
}
}
.searchPanel {
......
import React, { useState } from 'react';
import classNames from 'classnames';
......
......@@ -16,12 +16,13 @@ import {
NEW_MESSAGE,
PASSWORD,
PLATFORM_LEVEL,
REQUEST_SERVICE, SYS_LEVEL,
REQUEST_SERVICE,
SYS_LEVEL,
USERNAME,
VIDEO_LEVEL,
} from './constants';
import createMessage from './message';
import service from '../../api/service/notification';
import { noticeService } from '../../api';
import { isJSON } from '../../utils/utils';
/* eslint-disable */
// eslint-disable-next-line no-undef
......@@ -131,7 +132,7 @@ class Notifier {
if (isAll) hisIDs = this.messageCache.messages.map(item => item.id);
const self = this;
// eslint-disable-next-line no-undef
service.postInformationStatus({
noticeService.postInformationStatus({
userID: this.userInfo.OID,
hisID: hisIDs.join(','),
isAll: isAll ? 1 : '',
......@@ -499,7 +500,7 @@ class Notifier {
// 工具类
async loadHisMessages(pageIndex, pageSize) {
const self = this;
return service.getInformationInfo({
return noticeService.getInformationInfo({
userID: self.getUserInfo().OID,
pageIndex,
pageSize,
......@@ -532,7 +533,7 @@ class Notifier {
async getMqttSiteCode() {
const self = this;
return service.getMqttSiteCode({ 'request.preventCache': Date.now() }).then(
return noticeService.getMqttSiteCode({ 'request.preventCache': Date.now() }).then(
res => {
if (res && res.say.statusCode === ERR_OK) {
let mqttConfig = {
......
import useIntl from './useIntl';
import useRootContext from './useRootContext';
export { useIntl, useRootContext };
import * as React from 'react';
import i18n from '../../../utils/share';
export default function useIntl(namespace) {
const language = i18n.getI18n(namespace);
return {
formatMessage: id => language.get(id),
};
}
import { getRootContext } from '@wisdom-utils/vapp-browser-vm/lib/vm';
window.getRootContext = getRootContext;
export default function useRootContext() {
return getRootContext();
};
export const SERVICE_APP_GET_UI_META = 'app.getUIMeta';
export const SERVICE_APP_LOGIN_MODE = {
password: 'password',
dingding: 'dingding',
weixin: 'weixin',
phone: 'phone',
}
export const SERVICE_APP_CLOSE_ALL_TABS = 'app.close.tabs';
......@@ -3,14 +3,18 @@ import { Helmet } from 'react-helmet';
import { connect } from 'react-redux';
import { renderRoutes } from 'react-router-config';
import { BrowserRouter as Router, Switch } from 'react-router-dom';
import defaultSetting from '../../../config/defaultSetting';
import { dyRoutes } from '../../routes/config';
function App(props) {
return (
<>
<Helmet title={`${props.global && props.global.title}`}>
<title>{`${props.global && props.global.title}`}</title>
<Helmet
title={`${(props.global && props.global.title) ||
defaultSetting.title}`}
>
<title>{`${(props.global && props.global.title) ||
defaultSetting.title}`}</title>
<link
rel="shortcut icon"
href={`https://panda-water.cn/web4/${props.global &&
......
......@@ -39,6 +39,7 @@ const recentProductStorage = new Storage(
const currentProduct = new Store(
`__global__recent_productIndex__micro_${window.location.hostname}`,
);
Cookies.set('loginMode', 'pdw');
export const initialState = fromJS({
globalConfig: {},
globalConfigError: '',
......@@ -89,7 +90,7 @@ const appReducer = (state = initialState, action) => {
// eslint-disable-next-line no-undef
createStoreage.set('globalConfig', window.globalConfig);
// eslint-disable-next-line no-undef,no-case-declarations
const config = createStoreage.get('globalConfig');
const config = window.globalConfig;
// eslint-disable-next-line no-case-declarations
const generMenu = generRoutes(config.widgets || []);
// eslint-disable-next-line no-case-declarations
......
This diff was suppressed by a .gitattributes entry.
......@@ -9,6 +9,7 @@
<meta name="mobile-web-app-capable" content="yes" />
<!-- <link rel="icon" href="/favicon.ico" /> -->
<script src="//cdn-service.datav.aliyun.com/datav-static/2.37.6_4/libs/event.js"></script>
<script crossorigin src="//g.alicdn.com/bone/libs/1.2.3/??isomorphic-fetch@2.js"></script>
<script type="text/javascript">
window.share = {
event: new EventEmitter(),
......@@ -108,7 +109,6 @@
>
<!-- The app hooks into this div -->
<div id="app"></div>
<!-- Open Sans Font -->
<!-- <link href="https://fonts.googleapis.com/css?family=Open+Sans:400,700" rel="stylesheet"> -->
<!-- A lot of magic happens in this file. HtmlWebpackPlugin automatically injects all assets (e.g. bundle.js, main.css) with the correct HTML tags, which is why they are missing in this file. Don't add any assets here! (Check out webpack.dev.babel.js and webpack.prod.babel.js if you want to know more) -->
......
......@@ -9,16 +9,14 @@ import React, {
import { Anchor, Button, Popover, Radio, Result, Spin } from 'antd';
import classNames from 'classnames';
import { dom } from 'kit_utils';
import _ from 'lodash';
import { connect } from 'react-redux';
import { renderRoutes } from 'react-router-config';
import { useHistory } from 'react-router-dom';
import { useMountedState } from 'react-use';
import { LeftOutlined, MenuFoldOutlined } from '@ant-design/icons';
import ProLayout from '@ant-design/pro-layout';
import ProLayout, { getPageTitle } from '@ant-design/pro-layout';
import { getMatchMenu } from '@umijs/route-utils';
import pkg from '../../package.json';
import RightContent from '../components/GlobalHeader/RightContent';
import { Panel } from '../components/SliderPanel';
......@@ -29,7 +27,7 @@ import { findPathByLeafId, getBaseName } from '../utils/utils';
import SecurityLayout from './SecurityLayout';
import Site from './Site';
import styles from './UserLayout.less';
import defaultSetting from '../../config/defaultSetting';
const baseURI = isProd
? window.location.origin
: `http://${window.location.hostname}:3020`;
......@@ -302,7 +300,6 @@ const BasicLayout = props => {
const [siteLoading, setSiteLoading] = useState(false);
const [complexCollapsed, setComplexCollapsed] = useState(false);
const isMounted = useMountedState();
const [siteAction, setSiteAction] = useState(
() => new Site(props, setSiteLoading),
);
......@@ -359,7 +356,7 @@ const BasicLayout = props => {
}, [props.currentMenuIndex]);
useEffect(() => {
if (_.isEmpty(props.global.get('token'))) {
if (!props.global.token) {
history.replace(`/user/login?client=${props.global.get('client')}`);
return;
}
......@@ -378,7 +375,7 @@ const BasicLayout = props => {
}, [props.pathname]);
useMemo(() => {
window.share.event.on('listenerRemoveSigleTab', url => {
window.share.event.on(' ', url => {
const config = findPathByLeafId(
`${props.location.pathname}`,
[currentRoutes],
......@@ -499,6 +496,10 @@ const BasicLayout = props => {
}
};
const title = getPageTitle({
title: props.global && props.global.get('title') || defaultSetting.title
});
const renderComplexLayout = children => {
const complexConfig = props.complexConfig.toJS
? props.complexConfig.toJS()
......@@ -506,7 +507,7 @@ const BasicLayout = props => {
return (
<ProLayout
logo={false}
title={props.global && props.global.get('title')}
title={title}
headerRender={false}
rightContentRender={() => null}
collapsedButtonRender={false}
......@@ -616,6 +617,7 @@ const BasicLayout = props => {
);
};
const { openKeys } = props;
return (
<SecurityLayout loading updateCurrentIndex={props.updateCurrentIndex}>
<ProLayout
......@@ -625,7 +627,7 @@ const BasicLayout = props => {
: 'assets/images/logo/单独图案-白色.svg'
}`}
siderWidth="145px"
title={props.global && props.global.get('title')}
title={title}
onCollapse={collapse => handlerCollapsed(collapse)}
onMenuHeaderClick={event => handleLogo(event)}
menuExtraRender={props.menu.length > 0 ? extraRender.render : null}
......@@ -721,6 +723,7 @@ const BasicLayout = props => {
menuDataRef.current = menuData || [];
return menuData || [];
}}
settings={defaultSetting}
{...others}
{...settings}
>
......
......@@ -2,7 +2,7 @@ import React from 'react';
import { connect } from 'react-redux';
import { Redirect } from 'react-router-dom';
import PageLoading from '@ant-design/pro-layout';
import { getBaseName } from '../utils/utils';
class SecurityLayout extends React.Component {
......@@ -21,18 +21,20 @@ class SecurityLayout extends React.Component {
const { children, global, loading } = this.props;
const isLogin =
global.token !== null ||
(global.qrcodeData &&
((global.qrcodeData &&
global.qrcodeData.state !== '' &&
global.qrcodeData.code !== '');
global.qrcodeData.code !== '') ||
!global.userInfo);
// eslint-disable-next-line no-undef
// if(Cookie.get("token")==="") {
// return (
// <Redirect to={`/user/login?client=${global.client}`} />
// );
// }
// if((!isLogin && loading) || !isReady) {
// return <PageLoading/>
// }
if((!isLogin && loading) || !isReady) {
return <PageLoading/>
}
if (
!isLogin &&
window.location.pathname !== `/${getBaseName()}/user/login`
......
......@@ -9,7 +9,7 @@ import CitySelector from '../components/CitySelector';
import Login from '../pages/user/login/login';
import cityJson from './city.json';
import styles from './UserLayout.less';
import services from '../api/service/base';
import { appService } from '../api';
const { Link } = Anchor;
......@@ -37,7 +37,7 @@ class Site {
this.globalConfig.userInfo.site
) {
// eslint-disable-next-line no-undef
services.getCity().then(res => {
appService.getCity().then(res => {
// eslint-disable-next-line no-restricted-globals
if (res && !isNaN(res.cid)) {
const cityResult = JSON.parse(cityJson);
......@@ -57,7 +57,7 @@ class Site {
const self = this;
return new Promise((resolve, reject) => {
// eslint-disable-next-line no-undef
services
appService
.getAllGroupsInfoForUser({
loginName,
'request.preventCache': new Date().getTime(),
......@@ -182,7 +182,7 @@ class Site {
if (city) {
// eslint-disable-next-line no-undef
services
appService
.getWeather({
city,
'request.preventCache': new Date().getTime(),
......@@ -347,7 +347,7 @@ class Site {
const { loginName } = this.globalConfig.userInfo;
this.setLoading(true);
// eslint-disable-next-line no-undef
services
appService
.generateTokenQuick({
loginName,
ignoreSite: true,
......@@ -367,7 +367,7 @@ class Site {
beforeChangeCheck(token, site) {
// eslint-disable-next-line no-undef
services
appService
.getUserInfo({
token,
subOID: 'subOID',
......
......@@ -101,6 +101,9 @@
padding: 0 14px;
// margin-bottom: 0px;
}
:global(.@{ant-prefix}-layout-sider-collapsed .@{ant-prefix}-menu-item.@{ant-prefix}-menu-item-only-child) {
padding-left: 0px!important;
}
:global(.@{ant-prefix}-layout-sider-collapsed
.@{ant-prefix}-menu-inline-collapsed
.@{ant-prefix}-menu-item-only-child.@{ant-prefix}-menu-item-selected) {
......@@ -349,8 +352,29 @@
display: none;
}
//:global(.@{ant-prefix}-layout-sider-collapsed
//// .@{ant-prefix}-menu-dark.@{ant-prefix}-menu-vertical
//// .@{ant-prefix}-menu-item) {
//// display: flex;
//// align-items: center;
//// justify-content: space-between;
//// text-align: center;
//// padding: 0;
////}
////:global(.@{ant-prefix}-layout-sider-collapsed
//// .@{ant-prefix}-menu-dark.@{ant-prefix}-menu-vertical
//// .@{ant-prefix}-pro-sider-collapsed-button) {
//// display: block;
////}
////
////:global(.@{ant-prefix}-layout-sider-collapsed
//// .@{ant-prefix}-menu-vertical
//// .@{ant-prefix}-menu-item) {
//// line-height: 14px;
////}
:global(.@{ant-prefix}-layout-sider-collapsed
.@{ant-prefix}-menu-dark.@{ant-prefix}-menu-vertical
.@{ant-prefix}-menu-dark
.@{ant-prefix}-menu-item) {
display: flex;
align-items: center;
......@@ -359,13 +383,12 @@
padding: 0;
}
:global(.@{ant-prefix}-layout-sider-collapsed
.@{ant-prefix}-menu-dark.@{ant-prefix}-menu-vertical
.@{ant-prefix}-menu-dark
.@{ant-prefix}-pro-sider-collapsed-button) {
display: block;
}
:global(.@{ant-prefix}-layout-sider-collapsed
.@{ant-prefix}-menu-vertical
.@{ant-prefix}-menu-item) {
line-height: 14px;
}
......@@ -391,7 +414,7 @@
}
:global(.@{ant-prefix}-menu-inline-collapsed
.@{ant-prefix}-menu-submenu.@{ant-prefix}-menu-submenu-vertical
.@{ant-prefix}-menu-submenu
.@{ant-prefix}-menu-submenu-title) {
display: flex;
align-items: center;
......@@ -404,8 +427,15 @@
line-height: 24px;
}
//:global(.@{ant-prefix}-menu-inline-collapsed
// .@{ant-prefix}-menu-submenu.@{ant-prefix}-menu-submenu-vertical
// .@{ant-prefix}-menu-submenu-title
// img) {
// margin-right: 0px !important;
//}
:global(.@{ant-prefix}-menu-inline-collapsed
.@{ant-prefix}-menu-submenu.@{ant-prefix}-menu-submenu-vertical
.@{ant-prefix}-menu-submenu
.@{ant-prefix}-menu-submenu-title
img) {
margin-right: 0px !important;
......@@ -439,9 +469,8 @@
.panda-pro-layouts-user-layout-minixName) {
font-size: 12px !important;
}
:global(.@{ant-prefix}-menu-inline-collapsed
.@{ant-prefix}-menu-submenu.@{ant-prefix}-menu-submenu-vertical
.@{ant-prefix}-menu-submenu
.@{ant-prefix}-menu-submenu-title
.@{ant-prefix}-pro-menu-item) {
top: 0 !important;
......@@ -450,6 +479,16 @@
overflow: hidden;
white-space: nowrap;
}
//:global(.@{ant-prefix}-menu-inline-collapsed
// .@{ant-prefix}-menu-submenu.@{ant-prefix}-menu-submenu-vertical
// .@{ant-prefix}-menu-submenu-title
// .@{ant-prefix}-pro-menu-item) {
// top: 0 !important;
// font-size: 12px !important;
// text-overflow: ellipsis;
// overflow: hidden;
// white-space: nowrap;
//}
.complexLayout {
:global {
.@{ant-prefix}-pro-sider-menu {
......
import {
BrowserVMLoader,
setLogStatus,
} from '@wisdom-utils/vapp-browser-vm/lib/loader';
import plugins from '@wisdom-utils/vapp-browser-vm-plugins';
setLogStatus(false);
(async () => {
const loader = new BrowserVMLoader({
plugins,
});
await loader.waitReady();
})();
import globalHeader from './zh-CN/globalHeader';
import pwa from './zh-CN/pwa';
import pages from './zh-CN/pages';
import settings from './zh-CN/settings';
const packs = {
globalHeader,
pwa,
pages,
settings,
}
function registerLanguge() {
Object.keys(packs).forEach(pack => {
const script = document.createElement('script');
script.type = 'json/i18n';
script.innerHTML = JSON.stringify(packs[pack]);
document.head.appendChild(script);
});
}
registerLanguge();
export default {
'component.noticeIcon.clear': '清空',
'component.noticeIcon.cleared': '清空了',
'component.noticeIcon.empty': '暂无数据',
'component.noticeIcon.view-more': '查看更多',
'component.noticeIcon.title': '通知',
'component.noticeIocn.allClear': '你已查看所有通知',
'component.noticeIcon.modal.alarm.title': '报警消息',
'component.noticeIcon.model.system.title': '系统通知',
'component.noticeIcon.messsage.statused': '点击标为已读',
'component.avatar.account': '账号',
'component.avatar.name': '姓名',
'component.avatar.depart': '部门',
'component.avatar.role': '角色',
'component.siteCode': '企业编号',
'component.avatar.update.success': '头像修改成功',
'component.avatar.update.fail': '头像修改失败',
'component.account.password.update.success': '修改密码成功',
'component.account.oldpassword.errorMessage': '原密码输入错误',
'component.account.password.update.fail': '修改密码失败',
'component.getVersion.errorMessage': '获取版本号错误,请联系相关开发人员',
'component.password.update': '修改密码',
'component.exit.login': '退出登录',
'component.search.menu.placeholder': '搜索菜单',
'component.header.icon.home': '首页',
'component.header.icon.order': '工单',
'component.header.icon.alarm': '报警',
};
export default {
'pages.login.welcome': '欢迎登录',
'pages.login.accountLogin.errorMessage': '账户或密码错误',
'pages.login.username.placeholder': '请输入用户名',
'pages.login.username.required': '请输入用户名!',
'pages.login.password.placeholder': '请输入密码',
'pages.login.password.required': '请输入密码!',
'pages.login.phoneLogin.errorMessage': '验证码填写错误,请重新获取',
'pages.login.phoneLogin.errorCodeMessage': '获取验证码失败',
'pages.login.phoneNumber.placeholder': '请输入手机号!',
'pages.login.phoneNumber.required': '手机号是必填项!',
'pages.login.phoneNumber.invalid': '不合法的手机号!',
'pages.login.captcha.placeholder': '请输入短信验证码!',
'pages.login.phoneLogin.getVerificationCode': '获取验证码',
'pages.login.phoneLogin.sendCationCode': '验证码已发送',
'pages.getCaptchaSecondText': '秒后重新获取',
'pages.login.rememberMe': '下次自动登录',
'pages.login.forgotPassword': '忘记密码 ?',
'pages.login.submit': '登录',
'pages.login.accountLogin.tab': '账号密码登录',
'pages.login.phoneLogin.tab': '手机号登录',
'pages.login.weChart.tab': '微信扫码登录',
};
export default {
'app.pwd.offline': '当前处于离线状态',
'app.pwa.serviceworker.updated': '有新内容',
'app.pwa.serviceworker.updated.hint': '请点击“刷新”按钮或者手动刷新页面',
'app.pwa.serviceworker.updated.ok': '刷新',
};
export default {
'app.settings.bootpage.title': '熊猫智慧城市监控管理解决方案',
}
......@@ -8,7 +8,8 @@ import { actionCreators } from '../../containers/App/store';
import SecurityLayout from '../../layouts/SecurityLayout';
import LoginAction from '../user/login/login';
import styles from './index.less';
import i18n from '../../utils/share';
const pages = i18n.getI18n('app');
const industries = ['供水', '排水', '消防', '暖通', '节水', '实验室'];
const renderIndustries = (config, callback) =>
industries.map(item => (
......@@ -79,7 +80,7 @@ const BootPage = props => {
<img src="https://panda-water.cn/web4/assets/images/bootPage/熊猫图标.png" />
<div className={styles.bootPageTitle}>
<span className={styles.bootPageZh}>
熊猫智慧城市监控管理解决方案
{pages.get('settings.bootpage.title')}
</span>
<span className={styles.bootPageEn}>
Panda Smart City Monitoring Management Platform & Solution
......
......@@ -7,7 +7,8 @@ import styles from './index.less';
import LoginContext from './LoginContext';
import ItemMap from './map';
import services from '../../../../../api/service/base';
import i18n from '../../../../../utils/share';
const pages = i18n.getI18n('pages');
const FormItem = Form.Item;
// eslint-disable-next-line no-undef
const Logger = logger('loginForm');
......@@ -62,7 +63,7 @@ const LoginItem = props => {
}
})
.catch(error => {
message.error('获取验证码失败');
message.error(pages.get('login.phoneLogin.errorCodeMessage'));
});
}, []);
......@@ -98,7 +99,7 @@ const LoginItem = props => {
return Promise.resolve();
}
// eslint-disable-next-line prefer-promise-reject-errors
return Promise.reject('验证码填写错误,请重新获取');
return Promise.reject(pages.get('login.phoneLogin.errorMessage'));
};
// eslint-disable-next-line no-shadow
const rules = [
......@@ -130,7 +131,9 @@ const LoginItem = props => {
});
}}
>
{timing ? `验证码已发送(${count})` : '获取短信验证码'}
{timing
? `${pages.get('login.phoneLogin.sendCationCode')}(${count})`
: pages.get('login.phoneLogin.getVerificationCode')}
</Button>
</>
)}
......
......@@ -7,7 +7,8 @@ import styles from './index.less';
import LoginContext from './LoginContext';
import LoginItem from './LoginItem';
import LoginSubmit from './LoginSubmit';
import i18n from '../../../../../utils/share';
const pages = i18n.getI18n('pages');
const Login = props => {
const { className } = props;
const otherChildren = [];
......@@ -20,7 +21,7 @@ const Login = props => {
return (
<LoginContext.Provider>
<div className={classNames(className, styles.login)}>
<div className={styles.desc}>欢迎登录</div>
<div className={styles.desc}>{pages.get('login.welcome')}</div>
<Form
form={props.from}
onFinish={values => {
......
......@@ -16,7 +16,7 @@ import LoginForm from './components/Login';
import WxLogin from './components/WxLogin';
import LoginAction from './login';
import styles from './style.less';
import i18n from '../../../utils/share';
const { UserName, Password, Mobile, Captcha, Submit } = LoginForm;
const Display = {
Account: 'Account',
......@@ -28,6 +28,7 @@ const LoginWay = {
WeChart: 'iotWechat',
Mobile: 'iotPhone',
};
const pages = i18n.getI18n('pages');
const LoginMessage = ({ content }) => (
<Alert
style={{
......@@ -215,29 +216,31 @@ const useRenderQcode = props => {
});
return element;
};
/* eslint-disable */
const Account = props => (
<LoginForm onSubmit={props.onSubmit}>
{props.status === 'error' &&
props.type === 'account' &&
!props.submitting && <LoginMessage content="账户或密码错误" />}
!props.submitting && (
<LoginMessage content={pages.get('login.accountLogin.errorMessage')} />
)}
<UserName
name="userName"
placeholder="请输入你的用户名"
placeholder={pages.get('login.username.placeholder')}
rules={[
{
required: true,
message: '请输入用户名!',
message: pages.get('login.username.required'),
},
]}
/>
<Password
name="password"
placeholder="请输入你的密码"
placeholder={pages.get('login.password.placeholder')}
rules={[
{
required: true,
message: '请输入密码!',
message: pages.get('login.password.required'),
},
]}
/>
......@@ -246,10 +249,10 @@ const Account = props => (
checked={props.autoLogin}
onChange={e => props.setAutoLogin(e.target.checked)}
>
下次自动登录
{pages.get('login.rememberMe')}
</Checkbox>
</div>
<Submit loading={props.submitting}>登录</Submit>
<Submit loading={props.submitting}>{pages.get('login.submit')}</Submit>
</LoginForm>
);
......@@ -339,7 +342,7 @@ const IotComponent = props => {
display: props.type === Display.Account ? 'none' : 'block',
}}
>
账号密码登录
{pages.get('login.accountLogin.tab')}
</a>
<a
onClick={() => handlerType('WeChart')}
......@@ -347,7 +350,7 @@ const IotComponent = props => {
display: props.type === Display.WeChart ? 'none' : 'block',
}}
>
微信扫码登录
{pages.get('login.weChart.tab')}
</a>
<a
onClick={() => handlerType('Mobile')}
......@@ -355,7 +358,7 @@ const IotComponent = props => {
display: props.type === Display.Mobile ? 'none' : 'block',
}}
>
手机验证码登录
{pages.get('login.phoneLogin.tab')}
</a>
</div>
</div>
......@@ -381,6 +384,10 @@ const Login = forwardRef((props, _ref) => {
() => new LoginAction(props, setVisible, true),
);
useEffect(() => {
action.globalConfig = props.global;
}, [props.global]);
const handleSubmit = values => {
/* eslint-disable */
action &&
......@@ -419,13 +426,11 @@ const Login = forwardRef((props, _ref) => {
if (props.loginMode === LoginWay.WeChart) {
action &&
action.events.on('loginSuccess', event => {
console.log('登录成功');
props.history.push(`/?client=${props.global.client}`);
window.share.event.emit('triggerMicro', props.global);
});
action &&
action.events.on('loginError', event => {
console.log('登录失败');
setVisible(false);
setSubmitting(false);
});
......
......@@ -2,9 +2,10 @@ import { message } from 'antd';
import { decode, encode } from 'js-base64';
import Cookies from 'js-cookie';
import sha1 from 'sha1';
import services from '../../../api/service/base';
import { appService } from '../../../api';
import 'kit_logger';
import SlideVerify from '../../../components/SlideVerify';
import { SERVICE_APP_LOGIN_MODE } from '../../../constants';
// eslint-disable-next-line no-undef
const Logger = logger('login');
......@@ -64,7 +65,7 @@ class Login {
this.globalConfig.token = token;
const self = this;
// eslint-disable-next-line no-undef
services
appService
.getUserInfo({
token: this.globalConfig.token,
subOID: 'subOID',
......@@ -102,7 +103,7 @@ class Login {
if (this.globalConfig.userInfo.site) {
// eslint-disable-next-line no-undef
services
appService
.writeLogs({
origin: window.location.origin,
client: this.globalConfig.client,
......@@ -152,9 +153,9 @@ class Login {
getWebConfig(token, getIndustry) {
const self = this;
// eslint-disable-next-line no-undef
services
appService
.getWebSiteConfig({
client: this.globalConfig.client,
client: self.globalConfig.client,
token,
'request.preventCache': Date.now(),
})
......@@ -192,7 +193,7 @@ class Login {
self.globalConfig.userInfo.site.length > 0
) {
// eslint-disable-next-line no-undef,no-underscore-dangle
services
appService
.getWebSiteConfig(
{
client: self.globalConfig.client,
......@@ -244,9 +245,10 @@ class Login {
}
})
.catch(error => {
Logger.log(error);
console.log(error)
// Logger.log(error);
this.handleLoginError();
Logger.log('获取网络配置失败');
// Logger.log('获取网络配置失败');
});
}
......@@ -428,7 +430,7 @@ class Login {
qrcodeLogin(code) {
const self = this;
// eslint-disable-next-line no-undef
services
appService
.generatetokenByqrcode({
f: 'json',
expiration: self.globalConfig.expiration || 43200000,
......@@ -472,8 +474,7 @@ class Login {
const password = decode(pwd.substring(0, pwd.length - 3));
const self = this;
// eslint-disable-next-line no-undef
services
appService
.generateToken({
f: 'json',
expiration: this.globalConfig.expiration, // token过期时间(单位:秒)
......@@ -488,7 +489,7 @@ class Login {
const tk = response.token;
this.globalConfig.token = tk;
// eslint-disable-next-line no-undef,no-debugger
services
appService
.getUserInfo(
{
token: tk,
......@@ -566,7 +567,7 @@ class Login {
if (self.isSignIn || !!industry) {
// eslint-disable-next-line no-undef
services.getUserInfo(
appService.getUserInfo(
{
token,
subOID: 'subOID',
......@@ -638,32 +639,18 @@ class Login {
}
}
login(usr, pwd, userPhone, isRememberPWD) {
this.events.removeAllListeners('loginError');
transformLoginHander(response, isRememberPWD) {
const self = this;
debugger
services.generateToken(
{
f: 'json',
expiration: this.globalConfig.expiration, // token过期时间(单位:秒)
client: 'referer',
username: usr,
password: pwd ? sha1(pwd).toUpperCase() : '',
referer: this.globalConfig.client,
skipMenuTest: 1,
userPhone,
'request.preventCache': Date.now(),
ignoreSite: true,
},
)
.then(response => {
if (response && response.token) {
const { token } = response;
const token = response && ( response.token ? response.token: ( response.access_token !== null && response.user_token !== null) ? response.user_token: '');
if (token) {
Cookies.set('token', token);
const exp = 86400000;
this.globalConfig.token = token;
self.globalConfig.token = token;
if(response.access_token!== "") {
self.globalConfig.access_token = response.access_token;
}
if (isRememberPWD) {
Cookies.set(this.globalConfig.client, token, {
Cookies.set(self.globalConfig.client, token, {
expires: exp / (24 * 60 * 60 * 1000),
path: '/',
});
......@@ -673,15 +660,62 @@ class Login {
path: '/',
});
}
this.isSignIn = true;
this.updateConfig && this.updateConfig(this.globalConfig);
this.getUserInfoAndConfig();
self.isSignIn = true;
self.updateConfig && self.updateConfig(self.globalConfig);
self.getUserInfoAndConfig();
} else {
self.hasTry = true;
self.events.emit('loginError', response);
message.error(response.error.message);
self.callback && self.callback(false);
}
}
login(usr, pwd, userPhone, isRememberPWD, mode = SERVICE_APP_LOGIN_MODE.password) {
this.events.removeAllListeners('loginError');
const self = this;
if(window.globalConfig && window.globalConfig.hasGateWay) {
usr = userPhone ? userPhone: usr;
appService.authorizationToken({
loginName: usr,
password: pwd ? sha1(pwd).toUpperCase(): '',
type: mode
}).then(res => {
if(res.code === 0) {
const data = res.data;
self.updateConfig && self.updateConfig(Object.assign({}, self.globalConfig, {
access_token: data.access_token,
token: data.user_token,
}));
return data
} else {
message.error({
duration: 2000,
content: `授权失败:${res.msg}`
});
self.events.emit('loginError', res.msg);
return Promise.reject(res)
}
}).then((res) => {
self.transformLoginHander(res, isRememberPWD)
})
} else {
appService.generateToken(
{
f: 'json',
expiration: this.globalConfig.expiration, // token过期时间(单位:秒)
client: 'referer',
username: usr,
password: pwd ? sha1(pwd).toUpperCase() : '',
referer: this.globalConfig.client,
skipMenuTest: 1,
userPhone,
'request.preventCache': Date.now(),
ignoreSite: true,
},
)
.then(response => {
self.transformLoginHander(response, isRememberPWD)
})
.catch(error => {
self.hasTry = true;
......@@ -691,6 +725,9 @@ class Login {
});
}
}
loginHandler(user, pwd, userPhone, isRememberPWD, ref) {
const self = this;
if (user && pwd) {
......@@ -707,7 +744,7 @@ class Login {
}
phoneLoginFormHandler(userPhone, captcha) {
this.login('', '', userPhone);
this.login('', '', userPhone, '', SERVICE_APP_LOGIN_MODE.phone);
}
slideVerify(ref, onSuccess, onFail, onRefresh) {
......
import 'core-js/features/array/flat';
import 'core-js/features/array/flat-map';
import 'core-js/features/object/from-entries';
import promiseFinally from 'promise.prototype.finally';
promiseFinally.shim();
import { isUrl } from '@ant-design/pro-utils';
import { FILTER_FOLER_REG } from './constants';
import { transformURL } from './utils';
export const isURL = function(url) {
// eslint-disable-next-line no-useless-escape
return /^(http|https)?:\/\/([\w-]+\.)+[\w-]+(\/[\w- .\/?%&=]*)?/.test(url);
}
/* eslint-disable */
export const guid = function(prefix) {
let date = new Date().getTime();
......@@ -68,7 +71,7 @@ const generRotes = (widgets, parent, level = 0) => {
url = getURL(url);
}
if(isUrl(item.url)) {
if(isURL(item.url)) {
url = item.url
}
......@@ -79,7 +82,7 @@ const generRotes = (widgets, parent, level = 0) => {
component: 'BasicLayout',
path: baseURL !== '' ? transformURL(url) : '',
href: url,
target: isUrl(url) ? '_blank' : '',
target: isURL(url) ? '_blank' : '',
key: guid('panda'),
hideInMenu: l > 3,
application: item.product,
......
import _ from 'lodash';
/* eslint-disable */
function defineProperty(obj, key, value) {
return key in obj ? Object.defineProperty(obj, value, {
value: value,
enumerable: !0,
configurable: !0,
writable: !0
}) : obj[key] = value,
obj
}
const isSymbol = "function" === typeof Symbol && "symbol" === typeof Symbol.iterator ? function(value) {
return typeof value
} : function(value) {
return value && "function" === typeof Symbol && value.constructor === Symbol && value !== Symbol.prototype ? "symbol" : typeof value
};
function I18n() {
this._attr = {};
this.prepareI18n();
}
I18n.prototype.prepareI18n = function() {
let ret = {};
const i18ns = document.querySelectorAll("script[type=\"json/i18n\"]");
Array.prototype.forEach.call(i18ns, i18ns => {
try {
ret = Object.assign({}, ret, JSON.parse(i18ns.textContent))
} catch (e) {
console && console.warn && console.warn("\u6587\u6848\u89E3\u6790\u5931\u8D25\uFF0C\u8282\u70B9\u5185\u5BB9\uFF1A\n%s", item.outerHTML)
}
})
this.set("i18n", ret);
}
I18n.prototype.getI18n = function(key, value) {
const name = key + (value ? "_plain": "");
if(this.i18nMap || (this.i18nMap = {}), !this.i18nMap[name] && this.get("i18n")) {
if(value) {
let ret = {};
let i18 = this.get("i18n");
Object.keys(i18).forEach(item => {
0 == item.indexOf(key + ".") && (ret[item.replace(key +".", "")] = i18[item])
});
this.i18nMap[name] = ret;
} else {
const obj = {
namespace: key,
parsePage: !1,
locale: "zh_CN",
langPacks: {},
region:"CN",
source: this.get("source") || null
}
obj.langPacks[obj.locale] = this.get("i18n");
this.i18nMap[name] = new Intl(obj)
}
}
return this.i18nMap[name] || null;
}
I18n.prototype.set = function(key, value) {
_.set(this._attr, key, value);
return _.get(this._attr, key)
}
I18n.prototype.get = function(key) {
return _.get(this._attr, key)
}
function Intl(option) {
this._config = option;
this._setNamespace(option.namespace)
this._setLocale(option.locale)
this._setDefaultLocale(option.defaultLocale)
this._setDefaultValue(option.defaultValue)
this._setLangPacks(option.parsePage ? this._parsePage(): {});
this._setLangPacks(option.langPacks);
this._setData(option.data)
}
Intl.prototype._inspectValue = function(value) {
return value && "string" === typeof value ? value : ""
}
Intl.prototype._parsePage = function() {
let ret = {};
const i18ns = document.querySelectorAll("script[type=\"json/i18n\"]");
return Array.prototype.forEach.call(i18ns, item => {
const locale = this._inspectValue(item.getAttribute("locale"));
try {
const content = JSON.parse(item.textContent);
ret[locale] ? Object.assign(ret[locale], content): ret[locale] = content
}catch (e) {
console && console.warn && console.warn("\u6587\u6848\u89E3\u6790\u5931\u8D25\uFF0C\u8282\u70B9\u5185\u5BB9\uFF1A\n%s", b.outerHTML)
}
}), ret;
}
Intl.prototype._setNamespace = function(name) {
this._namespace = this._inspectValue(name)
}
Intl.prototype._setLocale = function(locale) {
this._locale = this._inspectValue(locale)
}
Intl.prototype._setDefaultLocale = function(locale) {
this._defaultLocale = this._inspectValue(locale)
}
Intl.prototype._setDefaultValue = function(value) {
this._defaultValue = this._inspectValue(value)
}
Intl.prototype._setLangPacks = function(pack) {
this._langPacks || (this._langPacks = {});
"object" !== ("undefined" === typeof pack ? "undefined" : isSymbol(pack)) && (pack = {});
Object.keys(pack).forEach(item => {
const data = pack[item];
item = item || this._getLocal();
this._langPacks[item] ? Object.assign(this._langPacks[item], data): this._langPacks[item] = data
})
}
Intl.prototype._setData = function(data) {
this._data || (this._data = {});
Object.assign(this._data, data);
}
Intl.prototype._getCookieLocal = function() {
return ("zh_CN").replace(/_/, "-").toLowerCase()
}
Intl.prototype._getBrowserLanguage = function() {
return (navigator.language || navigator.browserLanguage || "").replace(/_/, "-").toLowerCase()
}
Intl.prototype._getLocal = function() {
const locale = this._locale || this._defaultLocale || this._getCookieLocal() || this._getBrowserLanguage() || "zh-cn";
return locale
}
Intl.prototype._getLangPack = function(key) {
key= key && "undefined" !== typeof key ? key : this._getLocal();
return this._langPacks[key]
}
Intl.prototype._getName = function(name) {
const namespace = this._namespace;
return "" === namespace ? name : namespace + "." + name
}
Intl.prototype._getValue = function(key, value) {
if ("string" !== typeof key)
return console && console.warn && console.warn("\u6587\u6848\u7D22\u5F15 [%s] \u4E0D\u5408\u7B26\u8981\u6C42\u3002", key), !1;
const pack = this._getLangPack(value)
const name = this._getName(key);
return pack ? pack[name] : void 0
}
Intl.prototype._getCopy = function(a, b) {
if ("string" === typeof a) {
var c = "__i18n-react-split__"
, e = {}
, f = this
, g = a.replace(/\{\s*(?:([^}\s]+)\s+)?([^}\s]+)(?:\s+([^}]+))*\s*\}/g, function(a, g, h, i) {
var j;
if (b && (j = b[h]),
"undefined" === typeof j && (j = f._data[h] || "--"),
g) {
var k = Helpers[g];
if (k)
try {
j = k.bind(f)(h, j, i)
} catch (a) {
console && console.warn && console.warn("\u8F85\u52A9\u65B9\u6CD5 [%s] \u6267\u884C\u5F02\u5E38\uFF0C\u8BF7\u68C0\u67E5\u65B9\u6CD5\u4F53\u4EE3\u7801\u3002", g)
}
else
console && console.warn && console.warn("\u8F85\u52A9\u65B9\u6CD5 [%s] \u4E0D\u5B58\u5728\uFF0C\u8BF7\u786E\u8BA4\u6587\u6848\u5B9A\u4E49\u662F\u5426\u6B63\u786E\u3002", g)
} else
j && "symbol" === d(j.$$typeof) && (e[h] = j,
j = c + h + c);
return "" + j || a
});
return -1 < g.indexOf(c) ? g.split(c).map(function(a, b) {
return e[a] ? cloneElement(e[a], {
key: b
}) : a
}).filter(function(a) {
return !!a
}) : g
}
return a
}
Intl.prototype.parsePage = function() {
const parsePack = this._parsePage();
this._setLangPacks(parsePack)
}
Intl.prototype.has = function(key, value) {
const data = this._getValue(key, value);
return "undefined" !== typeof data
}
Intl.prototype.get = function(obj, key, value) {
try {
key && "object" === ("undefined" === typeof key ? "undefined" : isSymbol(key)) && (value = key, key = this._getLocal());
const original = this.getOriginal(obj, key);
return original && value ? this._getCopy(original, value) : original
} catch (c) {
console.warn("i18n not found", obj, key, this._locale)
}
}
Intl.prototype.getKeys = function(key) {
let ret = []
let namespace = "" + key
const region = this._config.region.toUpperCase()
const source = (this._config.source || "").toUpperCase();
ret.push(namespace)
namespace = namespace + "_" + region
ret.push(namespace);
return ret;
}
Intl.prototype.getOriginal = function(key, c) {
c = c || this._getLocal();
for (var d = void 0, e = void 0, data = this.getKeys(key), g = data[data.length - 1]; data.length && (e = data.pop(),
d = this._getValue(e, c),
!d); )
;
return e && e !== g && this._setLangPacks(defineProperty({}, c, defineProperty({}, this._namespace + "." + g, d))),
!d && console && console.warn && console.warn("[" + this._namespace + "].[" + key + "] not found in [" + c + "]"),
d
}
Intl.prototype.getLocale = function() {
return this._getLocal()
}
Intl.prototype.setConfig = function(config) {
"object" !== ("undefined" === typeof config ? "undefined" : isSymbol(config)) && (config = {}),
Object.keys(config).forEach((item) => {
const data = "_set" + item.replace(/^(.)/, function(match) {
return match.toUpperCase()
});
this[data] && this[data](config[item])
})
}
export default new I18n();
import '@babel/polyfill';
import './polyfills';
import {
initializeBrowserVM,
setLogStatus,
} from '@wisdom-utils/vapp-browser-vm/lib/vm';
import plugins from '@wisdom-utils/vapp-browser-vm-plugins';
setLogStatus(false);
(async () => {
await initializeBrowserVM({ plugins });
})();
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment