Commit 050ea14e by wangshufen

repos init

parent eeaa75a8
{
"presets":["react-app"],
"plugins": [
["import", { "libraryName": "antd", "libraryDirectory": "es", "style": "css" }],
["transform-decorators-legacy"]
]
}
\ No newline at end of file
# See https://help.github.com/ignore-files/ for more about ignoring files.
# dependencies
/node_modules
# testing
/coverage
# production
/build
/.idea
# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*
computingPlatform
\ No newline at end of file
'use strict';
const fs = require('fs');
const path = require('path');
const paths = require('./paths');
// Make sure that including paths.js after env.js will read .env variables.
delete require.cache[require.resolve('./paths')];
const NODE_ENV = process.env.NODE_ENV;
if (!NODE_ENV) {
throw new Error(
'The NODE_ENV environment variable is required but was not specified.'
);
}
// https://github.com/bkeepers/dotenv#what-other-env-files-can-i-use
var dotenvFiles = [
`${paths.dotenv}.${NODE_ENV}.local`,
`${paths.dotenv}.${NODE_ENV}`,
// Don't include `.env.local` for `test` environment
// since normally you expect tests to produce the same
// results for everyone
NODE_ENV !== 'test' && `${paths.dotenv}.local`,
paths.dotenv,
].filter(Boolean);
// Load environment variables from .env* files. Suppress warnings using silent
// if this file is missing. dotenv will never modify any environment variables
// that have already been set. Variable expansion is supported in .env files.
// https://github.com/motdotla/dotenv
// https://github.com/motdotla/dotenv-expand
dotenvFiles.forEach(dotenvFile => {
if (fs.existsSync(dotenvFile)) {
require('dotenv-expand')(
require('dotenv').config({
path: dotenvFile,
})
);
}
});
// We support resolving modules according to `NODE_PATH`.
// This lets you use absolute paths in imports inside large monorepos:
// https://github.com/facebookincubator/create-react-app/issues/253.
// It works similar to `NODE_PATH` in Node itself:
// https://nodejs.org/api/modules.html#modules_loading_from_the_global_folders
// Note that unlike in Node, only *relative* paths from `NODE_PATH` are honored.
// Otherwise, we risk importing Node.js core modules into an app instead of Webpack shims.
// https://github.com/facebookincubator/create-react-app/issues/1023#issuecomment-265344421
// We also resolve them to make sure all tools using them work consistently.
const appDirectory = fs.realpathSync(process.cwd());
process.env.NODE_PATH = (process.env.NODE_PATH || '')
.split(path.delimiter)
.filter(folder => folder && !path.isAbsolute(folder))
.map(folder => path.resolve(appDirectory, folder))
.join(path.delimiter);
// Grab NODE_ENV and REACT_APP_* environment variables and prepare them to be
// injected into the application via DefinePlugin in Webpack configuration.
const REACT_APP = /^REACT_APP_/i;
function getClientEnvironment(publicUrl) {
const raw = Object.keys(process.env)
.filter(key => REACT_APP.test(key))
.reduce(
(env, key) => {
env[key] = process.env[key];
return env;
},
{
// Useful for determining whether we’re running in production mode.
// Most importantly, it switches React into the correct mode.
NODE_ENV: process.env.NODE_ENV || 'development',
// Useful for resolving the correct path to static assets in `public`.
// For example, <img src={process.env.PUBLIC_URL + '/img/logo.png'} />.
// This should only be used as an escape hatch. Normally you would put
// images into the `src` and `import` them in code to get their paths.
PUBLIC_URL: publicUrl,
}
);
// Stringify all values so we can feed into Webpack DefinePlugin
const stringified = {
'process.env': Object.keys(raw).reduce((env, key) => {
env[key] = JSON.stringify(raw[key]);
return env;
}, {}),
};
return { raw, stringified };
}
module.exports = getClientEnvironment;
'use strict';
// This is a custom Jest transformer turning style imports into empty objects.
// http://facebook.github.io/jest/docs/en/webpack.html
module.exports = {
process() {
return 'module.exports = {};';
},
getCacheKey() {
// The output is always the same.
return 'cssTransform';
},
};
'use strict';
const path = require('path');
// This is a custom Jest transformer turning file imports into filenames.
// http://facebook.github.io/jest/docs/en/webpack.html
module.exports = {
process(src, filename) {
return `module.exports = ${JSON.stringify(path.basename(filename))};`;
},
};
'use strict';
const path = require('path');
const fs = require('fs');
const url = require('url');
// Make sure any symlinks in the project folder are resolved:
// https://github.com/facebookincubator/create-react-app/issues/637
const appDirectory = fs.realpathSync(process.cwd());
const resolveApp = relativePath => path.resolve(appDirectory, relativePath);
const envPublicUrl = process.env.PUBLIC_URL;
function ensureSlash(path, needsSlash) {
const hasSlash = path.endsWith('/');
if (hasSlash && !needsSlash) {
return path.substr(path, path.length - 1);
} else if (!hasSlash && needsSlash) {
return `${path}/`;
} else {
return path;
}
}
const getPublicUrl = appPackageJson =>
envPublicUrl || require(appPackageJson).homepage;
// We use `PUBLIC_URL` environment variable or "homepage" field to infer
// "public path" at which the app is served.
// Webpack needs to know it to put the right <script> hrefs into HTML even in
// single-page apps that may serve index.html for nested URLs like /todos/42.
// We can't use a relative path in HTML because we don't want to load something
// like /todos/42/static/js/bundle.7289d.js. We have to know the root.
function getServedPath(appPackageJson) {
const publicUrl = getPublicUrl(appPackageJson);
const servedUrl =
envPublicUrl || (publicUrl ? url.parse(publicUrl).pathname : '/');
return ensureSlash(servedUrl, true);
}
// config after eject: we're in ./config/
module.exports = {
dotenv: resolveApp('.env'),
appBuild: resolveApp('build'),
appPublic: resolveApp('public'),
appHtml: resolveApp('public/index.html'),
appIndexJs: resolveApp('src/index.js'),
appPackageJson: resolveApp('package.json'),
appSrc: resolveApp('src'),
yarnLockFile: resolveApp('yarn.lock'),
testsSetup: resolveApp('src/setupTests.js'),
appNodeModules: resolveApp('node_modules'),
publicUrl: getPublicUrl(resolveApp('package.json')),
servedPath: getServedPath(resolveApp('package.json')),
};
'use strict';
if (typeof Promise === 'undefined') {
// Rejection tracking prevents a components issue where React gets into an
// inconsistent state due to an error, but it gets swallowed by a Promise,
// and the user has no idea what causes React's erratic future behavior.
require('promise/lib/rejection-tracking').enable();
window.Promise = require('promise/lib/es6-extensions.js');
}
// fetch() polyfill for making API calls.
require('whatwg-fetch');
// Object.assign() is commonly used with React.
// It will use the native implementation if it's present and isn't buggy.
Object.assign = require('object-assign');
// In tests, polyfill requestAnimationFrame since jsdom doesn't provide it yet.
// We don't polyfill it in the browser--this is user's responsibility.
if (process.env.NODE_ENV === 'test') {
require('raf').polyfill(global);
}
'use strict';
const autoprefixer = require('autoprefixer');
const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin');
const InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin');
const WatchMissingNodeModulesPlugin = require('react-dev-utils/WatchMissingNodeModulesPlugin');
const eslintFormatter = require('react-dev-utils/eslintFormatter');
const ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin');
const getClientEnvironment = require('./env');
const paths = require('./paths');
// Webpack uses `publicPath` to determine where the app is being served from.
// In development, we always serve from the root. This makes config easier.
const publicPath = '/';
// `publicUrl` is just like `publicPath`, but we will provide it to our app
// as %PUBLIC_URL% in `index.html` and `process.env.PUBLIC_URL` in JavaScript.
// Omit trailing slash as %PUBLIC_PATH%/xyz looks better than %PUBLIC_PATH%xyz.
const publicUrl = '';
// Get environment variables to inject into our app.
const env = getClientEnvironment(publicUrl);
// This is the development configuration.
// It is focused on developer experience and fast rebuilds.
// The production configuration is different and lives in a separate file.
module.exports = {
// You may want 'eval' instead if you prefer to see the compiled output in DevTools.
// See the discussion in https://github.com/facebookincubator/create-react-app/issues/343.
devtool: 'cheap-module-source-map',
// These are the "entry points" to our application.
// This means they will be the "root" imports that are included in JS bundle.
// The first two entry points enable "hot" CSS and auto-refreshes for JS.
entry: [
// We ship a few polyfills by default:
require.resolve('./polyfills'),
// Include an alternative client for WebpackDevServer. A client's job is to
// connect to WebpackDevServer by a socket and get notified about changes.
// When you save a file, the client will either apply hot updates (in case
// of CSS changes), or refresh the page (in case of JS changes). When you
// make a syntax error, this client will display a syntax error overlay.
// Note: instead of the default WebpackDevServer client, we use a custom one
// to bring better experience for Create React App users. You can replace
// the line below with these two lines if you prefer the stock client:
// require.resolve('webpack-dev-server/client') + '?/',
// require.resolve('webpack/hot/dev-server'),
require.resolve('react-dev-utils/webpackHotDevClient'),
// Finally, this is your app's code:
paths.appIndexJs,
// We include the app code last so that if there is a runtime error during
// initialization, it doesn't blow up the WebpackDevServer client, and
// changing JS code would still trigger a refresh.
],
output: {
// Add /* filename */ comments to generated require()s in the output.
pathinfo: true,
// This does not produce a real file. It's just the virtual path that is
// served by WebpackDevServer in development. This is the JS bundle
// containing code from all our entry points, and the Webpack runtime.
filename: 'static/js/bundle.js',
// There are also additional JS chunk files if you use code splitting.
chunkFilename: 'static/js/[name].chunk.js',
// This is the URL that app is served from. We use "/" in development.
publicPath: publicPath,
// Point sourcemap entries to original disk location (format as URL on Windows)
devtoolModuleFilenameTemplate: info =>
path.resolve(info.absoluteResourcePath).replace(/\\/g, '/'),
},
resolve: {
// This allows you to set a fallback for where Webpack should look for modules.
// We placed these paths second because we want `node_modules` to "win"
// if there are any conflicts. This matches Node resolution mechanism.
// https://github.com/facebookincubator/create-react-app/issues/253
modules: ['node_modules', paths.appNodeModules].concat(
// It is guaranteed to exist because we tweak it in `env.js`
process.env.NODE_PATH.split(path.delimiter).filter(Boolean)
),
// These are the reasonable defaults supported by the Node ecosystem.
// We also include JSX as a components component filename extension to support
// some tools, although we do not recommend using it, see:
// https://github.com/facebookincubator/create-react-app/issues/290
// `web` extension prefixes have been added for better support
// for React Native Web.
extensions: ['.web.js', '.mjs', '.js', '.json', '.web.jsx', '.jsx'],
alias: {
// Support React Native Web
// https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/
'react-native': 'react-native-web',
},
plugins: [
// Prevents users from importing files from outside of src/ (or node_modules/).
// This often causes confusion because we only process files within src/ with babel.
// To fix this, we prevent you from importing files out of src/ -- if you'd like to,
// please link the files into your node_modules/ and let module-resolution kick in.
// Make sure your source files are compiled, as they will not be processed in any way.
new ModuleScopePlugin(paths.appSrc, [paths.appPackageJson]),
],
},
module: {
strictExportPresence: true,
rules: [
// TODO: Disable require.ensure as it's not a standard language feature.
// We are waiting for https://github.com/facebookincubator/create-react-app/issues/2176.
// { parser: { requireEnsure: false } },
// First, run the linter.
// It's important to do this before Babel processes the JS.
{
test: /\.(js|jsx|mjs)$/,
enforce: 'pre',
use: [
{
options: {
formatter: eslintFormatter,
eslintPath: require.resolve('eslint'),
},
loader: require.resolve('eslint-loader'),
},
],
include: paths.appSrc,
},
{
// "oneOf" will traverse all following loaders until one will
// match the requirements. When no loader matches it will fall
// back to the "file" loader at the end of the loader list.
oneOf: [
// "url" loader works like "file" loader except that it embeds assets
// smaller than specified limit in bytes as data URLs to avoid requests.
// A missing `test` is equivalent to a match.
{
test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/],
loader: require.resolve('url-loader'),
options: {
limit: 10000,
name: 'static/media/[name].[hash:8].[ext]',
},
},
// Process JS with Babel.
{
test: /\.(js|jsx|mjs)$/,
include: paths.appSrc,
loader: require.resolve('babel-loader'),
options: {
// This is a feature of `babel-loader` for webpack (not Babel itself).
// It enables caching results in ./node_modules/.cache/babel-loader/
// directory for faster rebuilds.
cacheDirectory: true,
},
},
// "postcss" loader applies autoprefixer to our CSS.
// "css" loader resolves paths in CSS and adds assets as dependencies.
// "style" loader turns CSS into JS modules that inject <style> tags.
// In production, we use a plugin to extract that CSS to a file, but
// in development "style" loader enables hot editing of CSS.
{
test: /\.css$/,
use: [
require.resolve('style-loader'),
{
loader: require.resolve('css-loader'),
options: {
importLoaders: 1,
},
},
{
loader: require.resolve('postcss-loader'),
options: {
// Necessary for external CSS imports to work
// https://github.com/facebookincubator/create-react-app/issues/2677
ident: 'postcss',
plugins: () => [
require('postcss-flexbugs-fixes'),
autoprefixer({
browsers: [
'>1%',
'last 4 versions',
'Firefox ESR',
'not ie < 9', // React doesn't support IE8 anyway
],
flexbox: 'no-2009',
}),
],
},
},
],
},
// "file" loader makes sure those assets get served by WebpackDevServer.
// When you `import` an asset, you get its (virtual) filename.
// In production, they would get copied to the `build` folder.
// This loader doesn't use a "test" so it will catch all modules
// that fall through the other loaders.
{
// Exclude `js` files to keep "css" loader working as it injects
// its runtime that would otherwise processed through "file" loader.
// Also exclude `html` and `json` extensions so they get processed
// by webpacks internal loaders.
exclude: [/\.(js|jsx|mjs)$/, /\.html$/, /\.json$/],
loader: require.resolve('file-loader'),
options: {
name: 'static/media/[name].[hash:8].[ext]',
},
},
],
},
// ** STOP ** Are you adding a new loader?
// Make sure to add the new loader(s) before the "file" loader.
],
},
plugins: [
// Makes some environment variables available in index.html.
// The public URL is available as %PUBLIC_URL% in index.html, e.g.:
// <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
// In development, this will be an empty string.
new InterpolateHtmlPlugin(env.raw),
// Generates an `index.html` file with the <script> injected.
new HtmlWebpackPlugin({
inject: true,
template: paths.appHtml,
}),
// Add module names to factory functions so they appear in browser profiler.
new webpack.NamedModulesPlugin(),
// Makes some environment variables available to the JS code, for example:
// if (process.env.NODE_ENV === 'development') { ... }. See `./env.js`.
new webpack.DefinePlugin(env.stringified),
// This is necessary to emit hot updates (currently CSS only):
new webpack.HotModuleReplacementPlugin(),
// Watcher doesn't work well if you mistype casing in a path so we use
// a plugin that prints an error when you attempt to do this.
// See https://github.com/facebookincubator/create-react-app/issues/240
new CaseSensitivePathsPlugin(),
// If you require a missing module and then `npm install` it, you still have
// to restart the development server for Webpack to discover it. This plugin
// makes the discovery automatic so you don't have to restart.
// See https://github.com/facebookincubator/create-react-app/issues/186
new WatchMissingNodeModulesPlugin(paths.appNodeModules),
// Moment.js is an extremely popular library that bundles large locale files
// by default due to how Webpack interprets its code. This is a practical
// solution that requires the user to opt into importing specific locales.
// https://github.com/jmblog/how-to-optimize-momentjs-with-webpack
// You can remove this if you don't use Moment.js:
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
],
// Some libraries import Node modules but don't use them in the browser.
// Tell Webpack to provide empty mocks for them so importing them works.
node: {
dgram: 'empty',
fs: 'empty',
net: 'empty',
tls: 'empty',
child_process: 'empty',
},
// Turn off performance hints during development because we don't do any
// splitting or minification in interest of speed. These warnings become
// cumbersome.
performance: {
hints: false,
},
};
'use strict';
const autoprefixer = require('autoprefixer');
const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const ManifestPlugin = require('webpack-manifest-plugin');
const InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin');
const SWPrecacheWebpackPlugin = require('sw-precache-webpack-plugin');
const eslintFormatter = require('react-dev-utils/eslintFormatter');
const ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin');
const paths = require('./paths');
const getClientEnvironment = require('./env');
// Webpack uses `publicPath` to determine where the app is being served from.
// It requires a trailing slash, or the file assets will get an incorrect path.
const publicPath = paths.servedPath;
// Some apps do not use client-side routing with pushState.
// For these, "homepage" can be set to "." to enable relative asset paths.
const shouldUseRelativeAssetPaths = publicPath === './';
// Source maps are resource heavy and can cause out of memory issue for large source files.
const shouldUseSourceMap = process.env.GENERATE_SOURCEMAP !== 'false';
// `publicUrl` is just like `publicPath`, but we will provide it to our app
// as %PUBLIC_URL% in `index.html` and `process.env.PUBLIC_URL` in JavaScript.
// Omit trailing slash as %PUBLIC_URL%/xyz looks better than %PUBLIC_URL%xyz.
const publicUrl = publicPath.slice(0, -1);
// Get environment variables to inject into our app.
const env = getClientEnvironment(publicUrl);
// Assert this just to be safe.
// Development builds of React are slow and not intended for production.
if (env.stringified['process.env'].NODE_ENV !== '"production"') {
throw new Error('Production builds must have NODE_ENV=production.');
}
// Note: defined here because it will be used more than once.
const cssFilename = 'static/css/[name].[contenthash:8].css';
// ExtractTextPlugin expects the build output to be flat.
// (See https://github.com/webpack-contrib/extract-text-webpack-plugin/issues/27)
// However, our output is structured with css, js and media folders.
// To have this structure working with relative paths, we have to use custom options.
const extractTextPluginOptions = shouldUseRelativeAssetPaths
? // Making sure that the publicPath goes back to to build folder.
{ publicPath: Array(cssFilename.split('/').length).join('../') }
: {};
// This is the production configuration.
// It compiles slowly and is focused on producing a fast and minimal bundle.
// The development configuration is different and lives in a separate file.
module.exports = {
// Don't attempt to continue if there are any errors.
bail: true,
// We generate sourcemaps in production. This is slow but gives good results.
// You can exclude the *.map files from the build during deployment.
devtool: shouldUseSourceMap ? 'source-map' : false,
// In production, we only want to load the polyfills and the app code.
entry: [require.resolve('./polyfills'), paths.appIndexJs],
output: {
// The build folder.
path: paths.appBuild,
// Generated JS file names (with nested folders).
// There will be one main bundle, and one file per asynchronous chunk.
// We don't currently advertise code splitting but Webpack supports it.
filename: 'static/js/[name].[chunkhash:8].js',
chunkFilename: 'static/js/[name].[chunkhash:8].chunk.js',
// We inferred the "public path" (such as / or /my-project) from homepage.
publicPath: publicPath,
// Point sourcemap entries to original disk location (format as URL on Windows)
devtoolModuleFilenameTemplate: info =>
path
.relative(paths.appSrc, info.absoluteResourcePath)
.replace(/\\/g, '/'),
},
resolve: {
// This allows you to set a fallback for where Webpack should look for modules.
// We placed these paths second because we want `node_modules` to "win"
// if there are any conflicts. This matches Node resolution mechanism.
// https://github.com/facebookincubator/create-react-app/issues/253
modules: ['node_modules', paths.appNodeModules].concat(
// It is guaranteed to exist because we tweak it in `env.js`
process.env.NODE_PATH.split(path.delimiter).filter(Boolean)
),
// These are the reasonable defaults supported by the Node ecosystem.
// We also include JSX as a components component filename extension to support
// some tools, although we do not recommend using it, see:
// https://github.com/facebookincubator/create-react-app/issues/290
// `web` extension prefixes have been added for better support
// for React Native Web.
extensions: ['.web.js', '.mjs', '.js', '.json', '.web.jsx', '.jsx'],
alias: {
// Support React Native Web
// https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/
'react-native': 'react-native-web',
},
plugins: [
// Prevents users from importing files from outside of src/ (or node_modules/).
// This often causes confusion because we only process files within src/ with babel.
// To fix this, we prevent you from importing files out of src/ -- if you'd like to,
// please link the files into your node_modules/ and let module-resolution kick in.
// Make sure your source files are compiled, as they will not be processed in any way.
new ModuleScopePlugin(paths.appSrc, [paths.appPackageJson]),
],
},
module: {
strictExportPresence: true,
rules: [
// TODO: Disable require.ensure as it's not a standard language feature.
// We are waiting for https://github.com/facebookincubator/create-react-app/issues/2176.
// { parser: { requireEnsure: false } },
// First, run the linter.
// It's important to do this before Babel processes the JS.
{
test: /\.(js|jsx|mjs)$/,
enforce: 'pre',
use: [
{
options: {
formatter: eslintFormatter,
eslintPath: require.resolve('eslint'),
},
loader: require.resolve('eslint-loader'),
},
],
include: paths.appSrc,
},
{
// "oneOf" will traverse all following loaders until one will
// match the requirements. When no loader matches it will fall
// back to the "file" loader at the end of the loader list.
oneOf: [
// "url" loader works just like "file" loader but it also embeds
// assets smaller than specified size as data URLs to avoid requests.
{
test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/],
loader: require.resolve('url-loader'),
options: {
limit: 10000,
name: 'static/media/[name].[hash:8].[ext]',
},
},
// Process JS with Babel.
{
test: /\.(js|jsx|mjs)$/,
include: paths.appSrc,
loader: require.resolve('babel-loader'),
options: {
compact: true,
},
},
// The notation here is somewhat confusing.
// "postcss" loader applies autoprefixer to our CSS.
// "css" loader resolves paths in CSS and adds assets as dependencies.
// "style" loader normally turns CSS into JS modules injecting <style>,
// but unlike in development configuration, we do something different.
// `ExtractTextPlugin` first applies the "postcss" and "css" loaders
// (second argument), then grabs the result CSS and puts it into a
// separate file in our build process. This way we actually ship
// a single CSS file in production instead of JS code injecting <style>
// tags. If you use code splitting, however, any async bundles will still
// use the "style" loader inside the async code so CSS from them won't be
// in the main CSS file.
{
test: /\.css$/,
loader: ExtractTextPlugin.extract(
Object.assign(
{
fallback: {
loader: require.resolve('style-loader'),
options: {
hmr: false,
},
},
use: [
{
loader: require.resolve('css-loader'),
options: {
importLoaders: 1,
minimize: true,
sourceMap: shouldUseSourceMap,
},
},
{
loader: require.resolve('postcss-loader'),
options: {
// Necessary for external CSS imports to work
// https://github.com/facebookincubator/create-react-app/issues/2677
ident: 'postcss',
plugins: () => [
require('postcss-flexbugs-fixes'),
autoprefixer({
browsers: [
'>1%',
'last 4 versions',
'Firefox ESR',
'not ie < 9', // React doesn't support IE8 anyway
],
flexbox: 'no-2009',
}),
],
},
},
],
},
extractTextPluginOptions
)
),
// Note: this won't work without `new ExtractTextPlugin()` in `plugins`.
},
// "file" loader makes sure assets end up in the `build` folder.
// When you `import` an asset, you get its filename.
// This loader doesn't use a "test" so it will catch all modules
// that fall through the other loaders.
{
loader: require.resolve('file-loader'),
// Exclude `js` files to keep "css" loader working as it injects
// it's runtime that would otherwise processed through "file" loader.
// Also exclude `html` and `json` extensions so they get processed
// by webpacks internal loaders.
exclude: [/\.(js|jsx|mjs)$/, /\.html$/, /\.json$/],
options: {
name: 'static/media/[name].[hash:8].[ext]',
},
},
// ** STOP ** Are you adding a new loader?
// Make sure to add the new loader(s) before the "file" loader.
],
},
],
},
plugins: [
// Makes some environment variables available in index.html.
// The public URL is available as %PUBLIC_URL% in index.html, e.g.:
// <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
// In production, it will be an empty string unless you specify "homepage"
// in `package.json`, in which case it will be the pathname of that URL.
new InterpolateHtmlPlugin(env.raw),
// Generates an `index.html` file with the <script> injected.
new HtmlWebpackPlugin({
inject: true,
template: paths.appHtml,
minify: {
removeComments: true,
collapseWhitespace: true,
removeRedundantAttributes: true,
useShortDoctype: true,
removeEmptyAttributes: true,
removeStyleLinkTypeAttributes: true,
keepClosingSlash: true,
minifyJS: true,
minifyCSS: true,
minifyURLs: true,
},
}),
// Makes some environment variables available to the JS code, for example:
// if (process.env.NODE_ENV === 'production') { ... }. See `./env.js`.
// It is absolutely essential that NODE_ENV was set to production here.
// Otherwise React will be compiled in the very slow development mode.
new webpack.DefinePlugin(env.stringified),
// Minify the code.
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false,
// Disabled because of an issue with Uglify breaking seemingly valid code:
// https://github.com/facebookincubator/create-react-app/issues/2376
// Pending further investigation:
// https://github.com/mishoo/UglifyJS2/issues/2011
comparisons: false,
},
mangle: {
safari10: true,
},
output: {
comments: false,
// Turned on because emoji and regex is not minified properly using default
// https://github.com/facebookincubator/create-react-app/issues/2488
ascii_only: true,
},
sourceMap: shouldUseSourceMap,
}),
// Note: this won't work without ExtractTextPlugin.extract(..) in `loaders`.
new ExtractTextPlugin({
filename: cssFilename,
}),
// Generate a manifest file which contains a mapping of all asset filenames
// to their corresponding output file so that tools can pick it up without
// having to parse `index.html`.
new ManifestPlugin({
fileName: 'asset-manifest.json',
}),
// Generate a service worker script that will precache, and keep up to date,
// the HTML & assets that are part of the Webpack build.
new SWPrecacheWebpackPlugin({
// By default, a cache-busting query parameter is appended to requests
// used to populate the caches, to ensure the responses are fresh.
// If a URL is already hashed by Webpack, then there is no concern
// about it being stale, and the cache-busting can be skipped.
dontCacheBustUrlsMatching: /\.\w{8}\./,
filename: 'service-worker.js',
logger(message) {
if (message.indexOf('Total precache size is') === 0) {
// This message occurs for every build and is a bit too noisy.
return;
}
if (message.indexOf('Skipping static resource') === 0) {
// This message obscures real errors so we ignore it.
// https://github.com/facebookincubator/create-react-app/issues/2612
return;
}
console.log(message);
},
minify: true,
// For unknown URLs, fallback to the index page
navigateFallback: publicUrl + '/index.html',
// Ignores URLs starting from /__ (useful for Firebase):
// https://github.com/facebookincubator/create-react-app/issues/2237#issuecomment-302693219
navigateFallbackWhitelist: [/^(?!\/__).*/],
// Don't precache sourcemaps (they're large) and build asset manifest:
staticFileGlobsIgnorePatterns: [/\.map$/, /asset-manifest\.json$/],
}),
// Moment.js is an extremely popular library that bundles large locale files
// by default due to how Webpack interprets its code. This is a practical
// solution that requires the user to opt into importing specific locales.
// https://github.com/jmblog/how-to-optimize-momentjs-with-webpack
// You can remove this if you don't use Moment.js:
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
],
// Some libraries import Node modules but don't use them in the browser.
// Tell Webpack to provide empty mocks for them so importing them works.
node: {
dgram: 'empty',
fs: 'empty',
net: 'empty',
tls: 'empty',
child_process: 'empty',
},
};
'use strict';
const errorOverlayMiddleware = require('react-dev-utils/errorOverlayMiddleware');
const noopServiceWorkerMiddleware = require('react-dev-utils/noopServiceWorkerMiddleware');
const ignoredFiles = require('react-dev-utils/ignoredFiles');
const config = require('./webpack.config.dev');
const paths = require('./paths');
const protocol = process.env.HTTPS === 'true' ? 'https' : 'http';
const host = process.env.HOST || '0.0.0.0';
module.exports = function(proxy, allowedHost) {
return {
// WebpackDevServer 2.4.3 introduced a security fix that prevents remote
// websites from potentially accessing local content through DNS rebinding:
// https://github.com/webpack/webpack-dev-server/issues/887
// https://medium.com/webpack/webpack-dev-server-middleware-security-issues-1489d950874a
// However, it made several existing use cases such as development in cloud
// environment or subdomains in development significantly more complicated:
// https://github.com/facebookincubator/create-react-app/issues/2271
// https://github.com/facebookincubator/create-react-app/issues/2233
// While we're investigating better solutions, for now we will take a
// compromise. Since our WDS configuration only serves files in the `public`
// folder we won't consider accessing them a vulnerability. However, if you
// use the `proxy` feature, it gets more dangerous because it can expose
// remote code execution vulnerabilities in backends like Django and Rails.
// So we will disable the host check normally, but enable it if you have
// specified the `proxy` setting. Finally, we let you override it if you
// really know what you're doing with a special environment variable.
disableHostCheck:
!proxy || process.env.DANGEROUSLY_DISABLE_HOST_CHECK === 'true',
// Enable gzip compression of generated files.
compress: true,
// Silence WebpackDevServer's own logs since they're generally not useful.
// It will still show compile warnings and errors with this setting.
clientLogLevel: 'none',
// By default WebpackDevServer serves physical files from current directory
// in addition to all the virtual build products that it serves from memory.
// This is confusing because those files won’t automatically be available in
// production build folder unless we copy them. However, copying the whole
// project directory is dangerous because we may expose sensitive files.
// Instead, we establish a convention that only files in `public` directory
// get served. Our build script will copy `public` into the `build` folder.
// In `index.html`, you can get URL of `public` folder with %PUBLIC_URL%:
// <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
// In JavaScript code, you can access it with `process.env.PUBLIC_URL`.
// Note that we only recommend to use `public` folder as an escape hatch
// for files like `favicon.ico`, `manifest.json`, and libraries that are
// for some reason broken when imported through Webpack. If you just want to
// use an image, put it in `src` and `import` it from JavaScript instead.
contentBase: paths.appPublic,
// By default files from `contentBase` will not trigger a page reload.
watchContentBase: true,
// Enable hot reloading server. It will provide /sockjs-node/ endpoint
// for the WebpackDevServer client so it can learn when the files were
// updated. The WebpackDevServer client is included as an entry point
// in the Webpack development configuration. Note that only changes
// to CSS are currently hot reloaded. JS changes will refresh the browser.
hot: true,
// It is important to tell WebpackDevServer to use the same "root" path
// as we specified in the config. In development, we always serve from /.
publicPath: config.output.publicPath,
// WebpackDevServer is noisy by default so we emit custom message instead
// by listening to the compiler events with `compiler.plugin` calls above.
quiet: true,
// Reportedly, this avoids CPU overload on some systems.
// https://github.com/facebookincubator/create-react-app/issues/293
// src/node_modules is not ignored to support absolute imports
// https://github.com/facebookincubator/create-react-app/issues/1065
watchOptions: {
ignored: ignoredFiles(paths.appSrc),
},
// Enable HTTPS if the HTTPS environment variable is set to 'true'
https: protocol === 'https',
host: host,
overlay: false,
historyApiFallback: {
// Paths with dots should still use the history fallback.
// See https://github.com/facebookincubator/create-react-app/issues/387.
disableDotRule: true,
},
public: allowedHost,
proxy,
before(app) {
// This lets us open files from the runtime error overlay.
app.use(errorOverlayMiddleware());
// This service worker file is effectively a 'no-op' that will reset any
// previous service worker registered for the same host:port combination.
// We do this in development to avoid hitting the production cache if
// it used the same host and port.
// https://github.com/facebookincubator/create-react-app/issues/2272#issuecomment-302832432
app.use(noopServiceWorkerMiddleware());
},
};
};
This source diff could not be displayed because it is too large. You can view the blob instead.
{
"name": "syzh",
"version": "0.1.0",
"private": true,
"dependencies": {
"@antv/data-set": "^0.8.9",
"@babel/polyfill": "^7.2.5",
"animate.css": "^3.6.1",
"antd": "^3.6.2",
"autoprefixer": "7.1.6",
"axios": "^0.18.0",
"babel-core": "6.26.0",
"babel-eslint": "7.2.3",
"babel-jest": "20.0.3",
"babel-loader": "7.1.2",
"babel-preset-react-app": "^3.1.1",
"babel-runtime": "6.26.0",
"bizcharts": "^3.1.10",
"bodymovin": "^4.13.0",
"case-sensitive-paths-webpack-plugin": "2.1.1",
"chalk": "1.1.3",
"css-loader": "0.28.7",
"dotenv": "4.0.0",
"dotenv-expand": "4.2.0",
"draft-js": "^0.10.5",
"draftjs-to-html": "^0.8.4",
"draftjs-to-markdown": "^0.5.1",
"eslint": "4.10.0",
"eslint-config-react-app": "^2.1.0",
"eslint-loader": "1.9.0",
"eslint-plugin-flowtype": "2.39.1",
"eslint-plugin-import": "2.8.0",
"eslint-plugin-jsx-a11y": "5.1.1",
"eslint-plugin-react": "7.4.0",
"extract-text-webpack-plugin": "3.0.2",
"file-loader": "1.1.5",
"fs-extra": "3.0.1",
"gsap": "^2.0.1",
"html-to-draftjs": "^1.4.0",
"html-webpack-plugin": "2.29.0",
"jsme-react": "^0.0.9",
"mobx": "^5.0.3",
"mobx-react": "^5.2.3",
"molstar-react": "^0.5.0",
"nprogress": "^0.2.0",
"object-assign": "4.1.1",
"postcss-flexbugs-fixes": "3.2.0",
"postcss-loader": "2.0.8",
"promise": "8.0.1",
"raf": "3.4.0",
"react": "^18.1.0",
"react-dev-utils": "^5.0.1",
"react-dom": "^16.4.1",
"react-draft-wysiwyg": "^1.12.13",
"react-loadable": "^5.4.0",
"react-router-dom": "^4.3.1",
"react-scripts": "^3.4.4",
"resolve": "1.6.0",
"screenfull": "^3.3.2",
"shufflejs": "^5.1.2",
"style-loader": "0.19.0",
"sw-precache-webpack-plugin": "0.11.4",
"url-loader": "0.6.2",
"webpack": "3.8.1",
"webpack-dev-server": "2.9.4",
"webpack-manifest-plugin": "1.3.2",
"whatwg-fetch": "2.0.3"
},
"scripts": {
"start": "node scripts/start.js",
"build": "node scripts/build.js",
"test": "node scripts/test.js --env=jsdom"
},
"jest": {
"collectCoverageFrom": [
"src/**/*.{js,jsx,mjs}"
],
"setupFiles": [
"<rootDir>/config/polyfills.js"
],
"testMatch": [
"<rootDir>/src/**/__tests__/**/*.{js,jsx,mjs}",
"<rootDir>/src/**/?(*.)(spec|test).{js,jsx,mjs}"
],
"testEnvironment": "node",
"testURL": "http://localhost",
"transform": {
"^.+\\.(js|jsx|mjs)$": "<rootDir>/node_modules/babel-jest",
"^.+\\.css$": "<rootDir>/config/jest/cssTransform.js",
"^(?!.*\\.(js|jsx|mjs|css|json)$)": "<rootDir>/config/jest/fileTransform.js"
},
"transformIgnorePatterns": [
"[/\\\\]node_modules[/\\\\].+\\.(js|jsx|mjs)$"
],
"moduleNameMapper": {
"^react-native$": "react-native-web"
},
"moduleFileExtensions": [
"web.js",
"js",
"json",
"web.jsx",
"jsx",
"node",
"mjs"
]
},
"babel": {
"presets": [
"react-app"
]
},
"eslintConfig": {
"extends": "react-app"
},
"devDependencies": {
"babel-plugin-import": "^1.8.0",
"babel-plugin-transform-decorators-legacy": "^1.3.5",
"qs": "^6.10.3"
},
"homepage": "."
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="theme-color" content="#000000">
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
<title>雅深智慧</title>
</head>
<body>
<noscript>
You need to enable JavaScript to run this app.
</noscript>
<div id="root"></div>
</body>
</html>
{
"short_name": "React App",
"name": "Create React App Sample",
"icons": [
{
"src": "favicon.ico",
"sizes": "64x64 32x32 24x24 16x16",
"type": "image/x-icon"
}
],
"start_url": "./index.html",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}
'use strict';
// Do this as the first thing so that any code reading it knows the right env.
process.env.BABEL_ENV = 'production';
process.env.NODE_ENV = 'production';
// Makes the script crash on unhandled rejections instead of silently
// ignoring them. In the future, promise rejections that are not handled will
// terminate the Node.js process with a non-zero exit code.
process.on('unhandledRejection', err => {
throw err;
});
// Ensure environment variables are read.
require('../config/env');
const path = require('path');
const chalk = require('chalk');
const fs = require('fs-extra');
const webpack = require('webpack');
const config = require('../config/webpack.config.prod');
const paths = require('../config/paths');
const checkRequiredFiles = require('react-dev-utils/checkRequiredFiles');
const formatWebpackMessages = require('react-dev-utils/formatWebpackMessages');
const printHostingInstructions = require('react-dev-utils/printHostingInstructions');
const FileSizeReporter = require('react-dev-utils/FileSizeReporter');
const printBuildError = require('react-dev-utils/printBuildError');
const measureFileSizesBeforeBuild =
FileSizeReporter.measureFileSizesBeforeBuild;
const printFileSizesAfterBuild = FileSizeReporter.printFileSizesAfterBuild;
const useYarn = fs.existsSync(paths.yarnLockFile);
// These sizes are pretty large. We'll warn for bundles exceeding them.
const WARN_AFTER_BUNDLE_GZIP_SIZE = 512 * 1024;
const WARN_AFTER_CHUNK_GZIP_SIZE = 1024 * 1024;
// Warn and crash if required files are missing
if (!checkRequiredFiles([paths.appHtml, paths.appIndexJs])) {
process.exit(1);
}
// First, read the current file sizes in build directory.
// This lets us display how much they changed later.
measureFileSizesBeforeBuild(paths.appBuild)
.then(previousFileSizes => {
// Remove all content but keep the directory so that
// if you're in it, you don't end up in Trash
fs.emptyDirSync(paths.appBuild);
// Merge with the public folder
copyPublicFolder();
// Start the webpack build
return build(previousFileSizes);
})
.then(
({ stats, previousFileSizes, warnings }) => {
if (warnings.length) {
console.log(chalk.yellow('Compiled with warnings.\n'));
console.log(warnings.join('\n\n'));
console.log(
'\nSearch for the ' +
chalk.underline(chalk.yellow('keywords')) +
' to learn more about each warning.'
);
console.log(
'To ignore, add ' +
chalk.cyan('// eslint-disable-next-line') +
' to the line before.\n'
);
} else {
console.log(chalk.green('Compiled successfully.\n'));
}
console.log('File sizes after gzip:\n');
printFileSizesAfterBuild(
stats,
previousFileSizes,
paths.appBuild,
WARN_AFTER_BUNDLE_GZIP_SIZE,
WARN_AFTER_CHUNK_GZIP_SIZE
);
console.log();
const appPackage = require(paths.appPackageJson);
const publicUrl = paths.publicUrl;
const publicPath = config.output.publicPath;
const buildFolder = path.relative(process.cwd(), paths.appBuild);
printHostingInstructions(
appPackage,
publicUrl,
publicPath,
buildFolder,
useYarn
);
},
err => {
console.log(chalk.red('Failed to compile.\n'));
printBuildError(err);
process.exit(1);
}
);
// Create the production build and print the deployment instructions.
function build(previousFileSizes) {
console.log('Creating an optimized production build...');
let compiler = webpack(config);
return new Promise((resolve, reject) => {
compiler.run((err, stats) => {
if (err) {
return reject(err);
}
const messages = formatWebpackMessages(stats.toJson({}, true));
if (messages.errors.length) {
// Only keep the first error. Others are often indicative
// of the same problem, but confuse the reader with noise.
if (messages.errors.length > 1) {
messages.errors.length = 1;
}
return reject(new Error(messages.errors.join('\n\n')));
}
if (
process.env.CI &&
(typeof process.env.CI !== 'string' ||
process.env.CI.toLowerCase() !== 'false') &&
messages.warnings.length
) {
console.log(
chalk.yellow(
'\nTreating warnings as errors because process.env.CI = true.\n' +
'Most CI servers set it automatically.\n'
)
);
return reject(new Error(messages.warnings.join('\n\n')));
}
return resolve({
stats,
previousFileSizes,
warnings: messages.warnings,
});
});
});
}
function copyPublicFolder() {
fs.copySync(paths.appPublic, paths.appBuild, {
dereference: true,
filter: file => file !== paths.appHtml,
});
}
'use strict';
// Do this as the first thing so that any code reading it knows the right env.
process.env.BABEL_ENV = 'development';
process.env.NODE_ENV = 'development';
// Makes the script crash on unhandled rejections instead of silently
// ignoring them. In the future, promise rejections that are not handled will
// terminate the Node.js process with a non-zero exit code.
process.on('unhandledRejection', err => {
throw err;
});
// Ensure environment variables are read.
require('../config/env');
const fs = require('fs');
const chalk = require('chalk');
const webpack = require('webpack');
const WebpackDevServer = require('webpack-dev-server');
const clearConsole = require('react-dev-utils/clearConsole');
const checkRequiredFiles = require('react-dev-utils/checkRequiredFiles');
const {
choosePort,
createCompiler,
prepareProxy,
prepareUrls,
} = require('react-dev-utils/WebpackDevServerUtils');
const openBrowser = require('react-dev-utils/openBrowser');
const paths = require('../config/paths');
const config = require('../config/webpack.config.dev');
const createDevServerConfig = require('../config/webpackDevServer.config');
const useYarn = fs.existsSync(paths.yarnLockFile);
const isInteractive = process.stdout.isTTY;
// Warn and crash if required files are missing
if (!checkRequiredFiles([paths.appHtml, paths.appIndexJs])) {
process.exit(1);
}
// Tools like Cloud9 rely on this.
const DEFAULT_PORT = parseInt(process.env.PORT, 10) || 3000;
const HOST = process.env.HOST || '0.0.0.0';
if (process.env.HOST) {
console.log(
chalk.cyan(
`Attempting to bind to HOST environment variable: ${chalk.yellow(
chalk.bold(process.env.HOST)
)}`
)
);
console.log(
`If this was unintentional, check that you haven't mistakenly set it in your shell.`
);
console.log(`Learn more here: ${chalk.yellow('http://bit.ly/2mwWSwH')}`);
console.log();
}
// We attempt to use the default port but if it is busy, we offer the user to
// run on a different port. `choosePort()` Promise resolves to the next free port.
choosePort(HOST, DEFAULT_PORT)
.then(port => {
if (port == null) {
// We have not found a port.
return;
}
const protocol = process.env.HTTPS === 'true' ? 'https' : 'http';
const appName = require(paths.appPackageJson).name;
const urls = prepareUrls(protocol, HOST, port);
// Create a webpack compiler that is configured with custom messages.
const compiler = createCompiler(webpack, config, appName, urls, useYarn);
// Load proxy config
const proxySetting = require(paths.appPackageJson).proxy;
const proxyConfig = prepareProxy(proxySetting, paths.appPublic);
// Serve webpack assets generated by the compiler over a web sever.
const serverConfig = createDevServerConfig(
proxyConfig,
urls.lanUrlForConfig
);
const devServer = new WebpackDevServer(compiler, serverConfig);
// Launch WebpackDevServer.
devServer.listen(port, HOST, err => {
if (err) {
return console.log(err);
}
if (isInteractive) {
clearConsole();
}
console.log(chalk.cyan('Starting the development server...\n'));
openBrowser(urls.localUrlForBrowser);
});
['SIGINT', 'SIGTERM'].forEach(function(sig) {
process.on(sig, function() {
devServer.close();
process.exit();
});
});
})
.catch(err => {
if (err && err.message) {
console.log(err.message);
}
process.exit(1);
});
'use strict';
// Do this as the first thing so that any code reading it knows the right env.
process.env.BABEL_ENV = 'test';
process.env.NODE_ENV = 'test';
process.env.PUBLIC_URL = '';
// Makes the script crash on unhandled rejections instead of silently
// ignoring them. In the future, promise rejections that are not handled will
// terminate the Node.js process with a non-zero exit code.
process.on('unhandledRejection', err => {
throw err;
});
// Ensure environment variables are read.
require('../config/env');
const jest = require('jest');
let argv = process.argv.slice(2);
// Watch unless on CI or in coverage mode
if (!process.env.CI && argv.indexOf('--coverage') < 0) {
argv.push('--watch');
}
jest.run(argv);
body {
margin: 0;
padding: 0;
font-family: sans-serif;
}
/*HeaderBar*/
.trigger{
font-size: 18px;
line-height: 64px;
cursor: pointer;
}
.trigger:hover{
color: #1890ff;
}
.header-ul{
display: flex;
width: 200px;
}
.header-ul li {
flex-grow: 1;
text-align: center;
}
.header-ul>li img{
width: 35px;
height: 35px;
border-radius: 100px;
}
.menu{
line-height: 2em;
padding: 0 10px;
}
.menu-group li{
padding: 0 24px;
line-height: 2em;
}
#page .card-item{
margin-bottom: 10px;
border-radius: 3px;
line-height: 2em;
}
#page .card-ul{
list-style: inside circle;
}
/*GalleryDemo*/
.aspect {
position: relative;
width: 100%;
height: 0;
padding-bottom: 100%;
overflow: hidden;
}
.aspect--1x2{
padding-bottom: calc(112.5% + 8px);
}
.aspect--1x1 {
padding-bottom: 56.25%;
/*padding的百分比是按父级的width计算的*/
}
.aspect--2x1 {
padding-bottom: 28.125%;
}
.aspect__inner{
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
.vertical-center-modal {
display: flex;
align-items: center;
justify-content: center;
}
.vertical-center-modal .ant-modal {
top: 0;
}
/*美化webkit内核滚动条*/
::-webkit-scrollbar {
width: 8px;
height: 8px;
}
::-webkit-scrollbar-thumb {
background-color: #777;
}
/*更改antd的primary button样式*/
.ant-btn-primary{
background: #36bafb;
border-color: #36bafb;
}
\ No newline at end of file
import React, {Component} from 'react';
import PrivateRoute from './components/PrivateRoute'
import {Route,Switch} from 'react-router-dom'
import Login from './routes/Login/index'
import Docking from './routes/Home/Docking/index'
// import Login from './routes/Login2/index'
import Index from './routes/Index/index'
import './App.css'
import './assets/font/iconfont.css'
class App extends Component {
render() {
return (
<Switch>
<Route path='/login' component={Docking}/>
<PrivateRoute path='/' component={Index}/>
</Switch>
)
}
}
export default App;
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
it('renders without crashing', () => {
const div = document.createElement('div');
ReactDOM.render(<App />, div);
ReactDOM.unmountComponentAtNode(div);
});
*{margin: 0;padding: 0;list-style: none;}
/*
KISSY CSS Reset
理念:1. reset 的目的不是清除浏览器的默认样式,这仅是部分工作。清除和重置是紧密不可分的。
2. reset 的目的不是让默认样式在所有浏览器下一致,而是减少默认样式有可能带来的问题。
3. reset 期望提供一套普适通用的基础样式。但没有银弹,推荐根据具体需求,裁剪和修改后再使用。
特色:1. 适应中文;2. 基于最新主流浏览器。
维护:玉伯<lifesinger@gmail.com>, 正淳<ragecarrier@gmail.com>
*/
/** 清除内外边距 **/
body, h1, h2, h3, h4, h5, h6, hr, p, blockquote, /* structural elements 结构元素 */
dl, dt, dd, ul, ol, li, /* list elements 列表元素 */
pre, /* text formatting elements 文本格式元素 */
form, fieldset, legend, button, input, textarea, /* form elements 表单元素 */
th, td /* table elements 表格元素 */ {
margin: 0;
padding: 0;
}
/** 设置默认字体 **/
body,
button, input, select, textarea /* for ie */ {
font: 12px/1.5 tahoma, arial, \5b8b\4f53, sans-serif;
}
h1, h2, h3, h4, h5, h6 { font-size: 100%; }
address, cite, dfn, em, var { font-style: normal; } /* 将斜体扶正 */
code, kbd, pre, samp { font-family: courier new, courier, monospace; } /* 统一等宽字体 */
small { font-size: 12px; } /* 小于 12px 的中文很难阅读,让 small 正常化 */
/** 重置列表元素 **/
ul, ol { list-style: none; }
/** 重置文本格式元素 **/
a { text-decoration: none; }
a:hover { text-decoration: underline; }
/** 重置表单元素 **/
legend { color: #000; } /* for ie6 */
fieldset, img { border: 0; } /* img 搭车:让链接里的 img 无边框 */
button, input, select, textarea { font-size: 100%; } /* 使得表单元素在 ie 下能继承字体大小 */
/* 注:optgroup 无法扶正 */
/** 重置表格元素 **/
table { border-collapse: collapse; border-spacing: 0; }
/* 清除浮动 */
.ks-clear:after, .clear:after {
content: '\20';
display: block;
height: 0;
clear: both;
}
.ks-clear, .clear {
*zoom: 1;
}
.main {
padding: 30px 100px;
width: 960px;
margin: 0 auto;
}
.main h1{font-size:36px; color:#333; text-align:left;margin-bottom:30px; border-bottom: 1px solid #eee;}
.helps{margin-top:40px;}
.helps pre{
padding:20px;
margin:10px 0;
border:solid 1px #e7e1cd;
background-color: #fffdef;
overflow: auto;
}
.icon_lists{
width: 100% !important;
}
.icon_lists li{
float:left;
width: 100px;
height:180px;
text-align: center;
list-style: none !important;
}
.icon_lists .icon{
font-size: 42px;
line-height: 100px;
margin: 10px 0;
color:#333;
-webkit-transition: font-size 0.25s ease-out 0s;
-moz-transition: font-size 0.25s ease-out 0s;
transition: font-size 0.25s ease-out 0s;
}
.icon_lists .icon:hover{
font-size: 100px;
}
.markdown {
color: #666;
font-size: 14px;
line-height: 1.8;
}
.highlight {
line-height: 1.5;
}
.markdown img {
vertical-align: middle;
max-width: 100%;
}
.markdown h1 {
color: #404040;
font-weight: 500;
line-height: 40px;
margin-bottom: 24px;
}
.markdown h2,
.markdown h3,
.markdown h4,
.markdown h5,
.markdown h6 {
color: #404040;
margin: 1.6em 0 0.6em 0;
font-weight: 500;
clear: both;
}
.markdown h1 {
font-size: 28px;
}
.markdown h2 {
font-size: 22px;
}
.markdown h3 {
font-size: 16px;
}
.markdown h4 {
font-size: 14px;
}
.markdown h5 {
font-size: 12px;
}
.markdown h6 {
font-size: 12px;
}
.markdown hr {
height: 1px;
border: 0;
background: #e9e9e9;
margin: 16px 0;
clear: both;
}
.markdown p,
.markdown pre {
margin: 1em 0;
}
.markdown > p,
.markdown > blockquote,
.markdown > .highlight,
.markdown > ol,
.markdown > ul {
width: 80%;
}
.markdown ul > li {
list-style: circle;
}
.markdown > ul li,
.markdown blockquote ul > li {
margin-left: 20px;
padding-left: 4px;
}
.markdown > ul li p,
.markdown > ol li p {
margin: 0.6em 0;
}
.markdown ol > li {
list-style: decimal;
}
.markdown > ol li,
.markdown blockquote ol > li {
margin-left: 20px;
padding-left: 4px;
}
.markdown code {
margin: 0 3px;
padding: 0 5px;
background: #eee;
border-radius: 3px;
}
.markdown pre {
border-radius: 6px;
background: #f7f7f7;
padding: 20px;
}
.markdown pre code {
border: none;
background: #f7f7f7;
margin: 0;
}
.markdown strong,
.markdown b {
font-weight: 600;
}
.markdown > table {
border-collapse: collapse;
border-spacing: 0px;
empty-cells: show;
border: 1px solid #e9e9e9;
width: 95%;
margin-bottom: 24px;
}
.markdown > table th {
white-space: nowrap;
color: #333;
font-weight: 600;
}
.markdown > table th,
.markdown > table td {
border: 1px solid #e9e9e9;
padding: 8px 16px;
text-align: left;
}
.markdown > table th {
background: #F7F7F7;
}
.markdown blockquote {
font-size: 90%;
color: #999;
border-left: 4px solid #e9e9e9;
padding-left: 0.8em;
margin: 1em 0;
font-style: italic;
}
.markdown blockquote p {
margin: 0;
}
.markdown .anchor {
opacity: 0;
transition: opacity 0.3s ease;
margin-left: 8px;
}
.markdown .waiting {
color: #ccc;
}
.markdown h1:hover .anchor,
.markdown h2:hover .anchor,
.markdown h3:hover .anchor,
.markdown h4:hover .anchor,
.markdown h5:hover .anchor,
.markdown h6:hover .anchor {
opacity: 1;
display: inline-block;
}
.markdown > br,
.markdown > p > br {
clear: both;
}
.hljs {
display: block;
background: white;
padding: 0.5em;
color: #333333;
overflow-x: auto;
}
.hljs-comment,
.hljs-meta {
color: #969896;
}
.hljs-string,
.hljs-variable,
.hljs-template-variable,
.hljs-strong,
.hljs-emphasis,
.hljs-quote {
color: #df5000;
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-type {
color: #a71d5d;
}
.hljs-literal,
.hljs-symbol,
.hljs-bullet,
.hljs-attribute {
color: #0086b3;
}
.hljs-section,
.hljs-name {
color: #63a35c;
}
.hljs-tag {
color: #333333;
}
.hljs-title,
.hljs-attr,
.hljs-selector-id,
.hljs-selector-class,
.hljs-selector-attr,
.hljs-selector-pseudo {
color: #795da3;
}
.hljs-addition {
color: #55a532;
background-color: #eaffea;
}
.hljs-deletion {
color: #bd2c00;
background-color: #ffecec;
}
.hljs-link {
text-decoration: underline;
}
pre{
background: #fff;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>IconFont</title>
<link rel="stylesheet" href="demo.css">
<link rel="stylesheet" href="iconfont.css">
</head>
<body>
<div class="main markdown">
<h1>IconFont 图标</h1>
<ul class="icon_lists clear">
<li>
<i class="icon iconfont icon-fenlei"></i>
<div class="name">分类</div>
<div class="fontclass">.icon-fenlei</div>
</li>
<li>
<i class="icon iconfont icon-fenlei1"></i>
<div class="name">分类</div>
<div class="fontclass">.icon-fenlei1</div>
</li>
<li>
<i class="icon iconfont icon-shouye"></i>
<div class="name">首页</div>
<div class="fontclass">.icon-shouye</div>
</li>
<li>
<i class="icon iconfont icon-suo"></i>
<div class="name"></div>
<div class="fontclass">.icon-suo</div>
</li>
<li>
<i class="icon iconfont icon-shouye1"></i>
<div class="name">首页</div>
<div class="fontclass">.icon-shouye1</div>
</li>
<li>
<i class="icon iconfont icon-user"></i>
<div class="name">User</div>
<div class="fontclass">.icon-user</div>
</li>
<li>
<i class="icon iconfont icon-emiyanzhengma"></i>
<div class="name">emi验证码</div>
<div class="fontclass">.icon-emiyanzhengma</div>
</li>
<li>
<i class="icon iconfont icon-user1"></i>
<div class="name">user</div>
<div class="fontclass">.icon-user1</div>
</li>
<li>
<i class="icon iconfont icon-User"></i>
<div class="name">User</div>
<div class="fontclass">.icon-User</div>
</li>
<li>
<i class="icon iconfont icon-lajitong1"></i>
<div class="name">垃圾桶</div>
<div class="fontclass">.icon-lajitong1</div>
</li>
<li>
<i class="icon iconfont icon-yanzhengmatianchong"></i>
<div class="name">验证码填充</div>
<div class="fontclass">.icon-yanzhengmatianchong</div>
</li>
<li>
<i class="icon iconfont icon-suo1"></i>
<div class="name"></div>
<div class="fontclass">.icon-suo1</div>
</li>
<li>
<i class="icon iconfont icon-securityCode-b"></i>
<div class="name">验证码</div>
<div class="fontclass">.icon-securityCode-b</div>
</li>
</ul>
<h2 id="font-class-">font-class引用</h2>
<hr>
<p>font-class是unicode使用方式的一种变种,主要是解决unicode书写不直观,语意不明确的问题。</p>
<p>与unicode使用方式相比,具有如下特点:</p>
<ul>
<li>兼容性良好,支持ie8+,及所有现代浏览器。</li>
<li>相比于unicode语意明确,书写更直观。可以很容易分辨这个icon是什么。</li>
<li>因为使用class来定义图标,所以当要替换图标时,只需要修改class里面的unicode引用。</li>
<li>不过因为本质上还是使用的字体,所以多色图标还是不支持的。</li>
</ul>
<p>使用步骤如下:</p>
<h3 id="-fontclass-">第一步:引入项目下面生成的fontclass代码:</h3>
<pre><code class="lang-js hljs javascript"><span class="hljs-comment">&lt;link rel="stylesheet" type="text/css" href="./iconfont.css"&gt;</span></code></pre>
<h3 id="-">第二步:挑选相应图标并获取类名,应用于页面:</h3>
<pre><code class="lang-css hljs">&lt;<span class="hljs-selector-tag">i</span> <span class="hljs-selector-tag">class</span>="<span class="hljs-selector-tag">iconfont</span> <span class="hljs-selector-tag">icon-xxx</span>"&gt;&lt;/<span class="hljs-selector-tag">i</span>&gt;</code></pre>
<blockquote>
<p>"iconfont"是你项目下的font-family。可以通过编辑项目查看,默认是"iconfont"。</p>
</blockquote>
</div>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>IconFont</title>
<link rel="stylesheet" href="demo.css">
<script src="iconfont.js"></script>
<style type="text/css">
.icon {
/* 通过设置 font-size 来改变图标大小 */
width: 1em; height: 1em;
/* 图标和文字相邻时,垂直对齐 */
vertical-align: -0.15em;
/* 通过设置 color 来改变 SVG 的颜色/fill */
fill: currentColor;
/* path 和 stroke 溢出 viewBox 部分在 IE 下会显示
normalize.css 中也包含这行 */
overflow: hidden;
}
</style>
</head>
<body>
<div class="main markdown">
<h1>IconFont 图标</h1>
<ul class="icon_lists clear">
<li>
<svg class="icon" aria-hidden="true">
<use xlink:href="#icon-fenlei"></use>
</svg>
<div class="name">分类</div>
<div class="fontclass">#icon-fenlei</div>
</li>
<li>
<svg class="icon" aria-hidden="true">
<use xlink:href="#icon-fenlei1"></use>
</svg>
<div class="name">分类</div>
<div class="fontclass">#icon-fenlei1</div>
</li>
<li>
<svg class="icon" aria-hidden="true">
<use xlink:href="#icon-shouye"></use>
</svg>
<div class="name">首页</div>
<div class="fontclass">#icon-shouye</div>
</li>
<li>
<svg class="icon" aria-hidden="true">
<use xlink:href="#icon-suo"></use>
</svg>
<div class="name"></div>
<div class="fontclass">#icon-suo</div>
</li>
<li>
<svg class="icon" aria-hidden="true">
<use xlink:href="#icon-shouye1"></use>
</svg>
<div class="name">首页</div>
<div class="fontclass">#icon-shouye1</div>
</li>
<li>
<svg class="icon" aria-hidden="true">
<use xlink:href="#icon-user"></use>
</svg>
<div class="name">User</div>
<div class="fontclass">#icon-user</div>
</li>
<li>
<svg class="icon" aria-hidden="true">
<use xlink:href="#icon-emiyanzhengma"></use>
</svg>
<div class="name">emi验证码</div>
<div class="fontclass">#icon-emiyanzhengma</div>
</li>
<li>
<svg class="icon" aria-hidden="true">
<use xlink:href="#icon-user1"></use>
</svg>
<div class="name">user</div>
<div class="fontclass">#icon-user1</div>
</li>
<li>
<svg class="icon" aria-hidden="true">
<use xlink:href="#icon-User"></use>
</svg>
<div class="name">User</div>
<div class="fontclass">#icon-User</div>
</li>
<li>
<svg class="icon" aria-hidden="true">
<use xlink:href="#icon-lajitong1"></use>
</svg>
<div class="name">垃圾桶</div>
<div class="fontclass">#icon-lajitong1</div>
</li>
<li>
<svg class="icon" aria-hidden="true">
<use xlink:href="#icon-yanzhengmatianchong"></use>
</svg>
<div class="name">验证码填充</div>
<div class="fontclass">#icon-yanzhengmatianchong</div>
</li>
<li>
<svg class="icon" aria-hidden="true">
<use xlink:href="#icon-suo1"></use>
</svg>
<div class="name"></div>
<div class="fontclass">#icon-suo1</div>
</li>
<li>
<svg class="icon" aria-hidden="true">
<use xlink:href="#icon-securityCode-b"></use>
</svg>
<div class="name">验证码</div>
<div class="fontclass">#icon-securityCode-b</div>
</li>
</ul>
<h2 id="symbol-">symbol引用</h2>
<hr>
<p>这是一种全新的使用方式,应该说这才是未来的主流,也是平台目前推荐的用法。相关介绍可以参考这篇<a href="">文章</a>
这种用法其实是做了一个svg的集合,与另外两种相比具有如下特点:</p>
<ul>
<li>支持多色图标了,不再受单色限制。</li>
<li>通过一些技巧,支持像字体那样,通过<code>font-size</code>,<code>color</code>来调整样式。</li>
<li>兼容性较差,支持 ie9+,及现代浏览器。</li>
<li>浏览器渲染svg的性能一般,还不如png。</li>
</ul>
<p>使用步骤如下:</p>
<h3 id="-symbol-">第一步:引入项目下面生成的symbol代码:</h3>
<pre><code class="lang-js hljs javascript"><span class="hljs-comment">&lt;script src="./iconfont.js"&gt;&lt;/script&gt;</span></code></pre>
<h3 id="-css-">第二步:加入通用css代码(引入一次就行):</h3>
<pre><code class="lang-js hljs javascript">&lt;style type=<span class="hljs-string">"text/css"</span>&gt;
.icon {
width: <span class="hljs-number">1</span>em; height: <span class="hljs-number">1</span>em;
vertical-align: <span class="hljs-number">-0.15</span>em;
fill: currentColor;
overflow: hidden;
}
&lt;<span class="hljs-regexp">/style&gt;</span></code></pre>
<h3 id="-">第三步:挑选相应图标并获取类名,应用于页面:</h3>
<pre><code class="lang-js hljs javascript">&lt;svg <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"icon"</span> aria-hidden=<span class="hljs-string">"true"</span>&gt;<span class="xml"><span class="hljs-tag">
&lt;<span class="hljs-name">use</span> <span class="hljs-attr">xlink:href</span>=<span class="hljs-string">"#icon-xxx"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">use</span>&gt;</span>
</span>&lt;<span class="hljs-regexp">/svg&gt;
</span></code></pre>
</div>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>IconFont</title>
<link rel="stylesheet" href="demo.css">
<style type="text/css">
@font-face {font-family: "iconfont";
src: url('iconfont.eot'); /* IE9*/
src: url('iconfont.eot#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('iconfont.woff') format('woff'), /* chrome, firefox */
url('iconfont.ttf') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/
url('iconfont.svg#iconfont') format('svg'); /* iOS 4.1- */
}
.iconfont {
font-family:"iconfont" !important;
font-size:16px;
font-style:normal;
-webkit-font-smoothing: antialiased;
-webkit-text-stroke-width: 0.2px;
-moz-osx-font-smoothing: grayscale;
}
</style>
</head>
<body>
<div class="main markdown">
<h1>IconFont 图标</h1>
<ul class="icon_lists clear">
<li>
<i class="icon iconfont">&#xe60a;</i>
<div class="name">分类</div>
<div class="code">&amp;#xe60a;</div>
</li>
<li>
<i class="icon iconfont">&#xe611;</i>
<div class="name">分类</div>
<div class="code">&amp;#xe611;</div>
</li>
<li>
<i class="icon iconfont">&#xe612;</i>
<div class="name">首页</div>
<div class="code">&amp;#xe612;</div>
</li>
<li>
<i class="icon iconfont">&#xe625;</i>
<div class="name"></div>
<div class="code">&amp;#xe625;</div>
</li>
<li>
<i class="icon iconfont">&#xe60b;</i>
<div class="name">首页</div>
<div class="code">&amp;#xe60b;</div>
</li>
<li>
<i class="icon iconfont">&#xe743;</i>
<div class="name">User</div>
<div class="code">&amp;#xe743;</div>
</li>
<li>
<i class="icon iconfont">&#xe61b;</i>
<div class="name">emi验证码</div>
<div class="code">&amp;#xe61b;</div>
</li>
<li>
<i class="icon iconfont">&#xe600;</i>
<div class="name">user</div>
<div class="code">&amp;#xe600;</div>
</li>
<li>
<i class="icon iconfont">&#xe67b;</i>
<div class="name">User</div>
<div class="code">&amp;#xe67b;</div>
</li>
<li>
<i class="icon iconfont">&#xe610;</i>
<div class="name">垃圾桶</div>
<div class="code">&amp;#xe610;</div>
</li>
<li>
<i class="icon iconfont">&#xe636;</i>
<div class="name">验证码填充</div>
<div class="code">&amp;#xe636;</div>
</li>
<li>
<i class="icon iconfont">&#xe644;</i>
<div class="name"></div>
<div class="code">&amp;#xe644;</div>
</li>
<li>
<i class="icon iconfont">&#xe60d;</i>
<div class="name">验证码</div>
<div class="code">&amp;#xe60d;</div>
</li>
</ul>
<h2 id="unicode-">unicode引用</h2>
<hr>
<p>unicode是字体在网页端最原始的应用方式,特点是:</p>
<ul>
<li>兼容性最好,支持ie6+,及所有现代浏览器。</li>
<li>支持按字体的方式去动态调整图标大小,颜色等等。</li>
<li>但是因为是字体,所以不支持多色。只能使用平台里单色的图标,就算项目里有多色图标也会自动去色。</li>
</ul>
<blockquote>
<p>注意:新版iconfont支持多色图标,这些多色图标在unicode模式下将不能使用,如果有需求建议使用symbol的引用方式</p>
</blockquote>
<p>unicode使用步骤如下:</p>
<h3 id="-font-face">第一步:拷贝项目下面生成的font-face</h3>
<pre><code class="lang-js hljs javascript">@font-face {
font-family: <span class="hljs-string">'iconfont'</span>;
src: url(<span class="hljs-string">'iconfont.eot'</span>);
src: url(<span class="hljs-string">'iconfont.eot?#iefix'</span>) format(<span class="hljs-string">'embedded-opentype'</span>),
url(<span class="hljs-string">'iconfont.woff'</span>) format(<span class="hljs-string">'woff'</span>),
url(<span class="hljs-string">'iconfont.ttf'</span>) format(<span class="hljs-string">'truetype'</span>),
url(<span class="hljs-string">'iconfont.svg#iconfont'</span>) format(<span class="hljs-string">'svg'</span>);
}
</code></pre>
<h3 id="-iconfont-">第二步:定义使用iconfont的样式</h3>
<pre><code class="lang-js hljs javascript">.iconfont{
font-family:<span class="hljs-string">"iconfont"</span> !important;
font-size:<span class="hljs-number">16</span>px;font-style:normal;
-webkit-font-smoothing: antialiased;
-webkit-text-stroke-width: <span class="hljs-number">0.2</span>px;
-moz-osx-font-smoothing: grayscale;
}
</code></pre>
<h3 id="-">第三步:挑选相应图标并获取字体编码,应用于页面</h3>
<pre><code class="lang-js hljs javascript">&lt;i <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"iconfont"</span>&gt;&amp;#x33;<span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">i</span>&gt;</span></span></code></pre>
<blockquote>
<p>"iconfont"是你项目下的font-family。可以通过编辑项目查看,默认是"iconfont"。</p>
</blockquote>
</div>
</body>
</html>
@font-face {font-family: "iconfont";
src: url('iconfont.eot?t=1530625048960'); /* IE9*/
src: url('iconfont.eot?t=1530625048960#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('data:application/x-font-woff;charset=utf-8;base64,d09GRgABAAAAAAvIAAsAAAAAEOgAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABHU1VCAAABCAAAADMAAABCsP6z7U9TLzIAAAE8AAAARAAAAFZW7kk1Y21hcAAAAYAAAADFAAACdmPSBzlnbHlmAAACSAAABwMAAAkYg3QBN2hlYWQAAAlMAAAALwAAADYR4n4uaGhlYQAACXwAAAAeAAAAJAfeA5FobXR4AAAJnAAAABgAAAA8O+oAAGxvY2EAAAm0AAAAIAAAACAQ9BNAbWF4cAAACdQAAAAfAAAAIAEfAF1uYW1lAAAJ9AAAAUUAAAJtPlT+fXBvc3QAAAs8AAAAigAAALdWkMkSeJxjYGRgYOBikGPQYWB0cfMJYeBgYGGAAJAMY05meiJQDMoDyrGAaQ4gZoOIAgCKIwNPAHicY2Bk/s84gYGVgYOpk+kMAwNDP4RmfM1gxMjBwMDEwMrMgBUEpLmmMDgwVDx3Zm7438AQw9zI0AAUZgTJAQAquQy4eJzFkk0OgkAMhd/Ij4pCkJWRxB07114ADmXCFTwQK4/zOIa+UhYadattPpLpG9qmUwAJgEicRAyEGwLMBkXDFI+QTfEYV533KBVZ4UJww5wVazY8s2M/tve7bpiSSSnflE8WlNH8ID8+uSlrLJCiwEYVY9VMsEWubpYS0y/5fmDhf6VfbTt9h/lUiMuMWiQcTVHv4WieejVHkwVzx/5l6cD0nWObwcqx7WDt6C3AxrEN4tmxjtg5sNy9Yxs0tg6WDwqVPFwAAAB4nHVWW2wcVxk+/zk7M3uZmb3NbS/e8ezM7nR3471fjC+b0NrR2olTFKctcZ2kbR4aIQVMhOS2FOEK1cSiNOGlD1UvtDhppAqklFYqkELVJqII9aFCEEElUNU+pK9QCWTsCf+sGyigzp49Z/5/Znb+7zvf+c4SjpCbH7ArzCBJchtpkBnyJUKAr0BepiNgue0qrYBqcaquyMy1XUuw81U2DXqeV7Rmt13UeYGPggw5aFnNrlulLnTafToJTW0EIJVJLyYK2QQ7D2HDzT3uzdMXQTXtbLQ/5s3t2as0R5PBVTGRSCUSTwR5jgtSGojKcFrXQlwozHubXDStXjFL1AQx5aYPHpVGM4n7z7a/OlLQQwBra5DMjMov7Y2n49geTWvJREqISUEjLdmOAqsfRYykOFL8kODB+x37FX2biCRFiqRGxskXEa3l47AtH1GLs2RQNN3qQ7voqru53etQ/BQy+78TOEGnoooS3bkaU5QYnbo1fjY3PB/VJsrlibLyXwO9RzEVbD8FJafAsPvnboYGlNJkuTzpjarlyVJpEmJK2X/k31h+yQgRSIwYxCIl0vSx9MFFCK6Pwi8bMPDRFD4/cYgecKCw85oDL6dtu53PM/CDgp/efvNzU/TFwATHTRyFfNuPvc3ARCAwYf5v6N/atgkb1vs2/SvJkgpBBAWLL/bi7W5TU+O81rO0rhvvo2j0uMa7DHg77xa7PejmgBeGEVShDzrqTKB/8g4OOhDVZJpqwqsti4KsyQD9ud96R4NBMSiwEFwKqhIOP8Yw6B0NMUkNwqUQE2IwvQClSDQa8a73TErN3q1oYRroZe91PhJSBRjwLKEI3hsRHgaCkmC897qghoiP4+ZVtsimhpyXkXG7U/XpFlQbu3huSG4vXgXIF310Cp+0OpjBC9Sr0NWlpVVacWoANaRyOHp/dur1Qb1+wtuC+fHxeaDKkaWHKH1o6QjUHW/JqQOOcNGpe4/79w3q8OiR8XlK58cJoVjP79kNViFp0iKEs7CYjl2Fdg/Zamk6aCqWZWMHeeQRpd2K7+q7E2/1cbEWmbhzoz0LotNIw1r0Nm1sFB5LQ8MRYdZ7M5Xwvh1WYtNlkxpmeTqmQMRbUyow234fGoMU3BmNgeldTuedBrzfnmVOwrscNhXwPjFLACVctKjnCBxK+tPv1+qx/fQmqaPTkELbxWKraBe9vj/6JPKa3kCmFF7AABueY0P6Gv6X7R8tH5mKJZPdUUrvm5t7AGgyLzuQjLWWx2IJACcL6488/F3IluDhPamRsTSfSaSjjWeDc/f5D/DfqitmKpHh1UZOdNTcmMBsSm0mjOVu1fcEe5WtEZWM+i6IPPZcQeMFFyXK6T0HNQpuz69Hx+LYhixdvgiGARdemQ49DbIogvx0yKv/4QtnuJ+taqGri4yB8GXBMLCj3vixGw8GAg/eOAbv7Lz1i7HF4OY+g/3m2aGmdthJ1BQQm+whJNkAhUdDKqKTcq2miaJvdvdCt9XMcUyRYSisC/SNwbS3MD1gkVjabuW4WEG9/Y7b1UKMy7XsdCzCnl95fgUbm9yZmZqdnUq3Jpo1SwkbkqZJRlixas2JFvzozhX4+nMrK4gfsI5n2Edshbg4O7j6ECe2blEYzo9QpHqR13enJDecHlQbfTInxVUbCjoTy4FA1qheczbNcKAsMr0AthqXcoe2ZPaOvPVMshUz7uLidaVrUe7sgRPlxbj3d41aXaUe5+4yYq1k5u5z5+4m/p60xtZxHiIkSkZwX+phcYViDWyBFzjVYkkrCW20BpXJUEFj6LB2F31E4ZEyhh6SRAHZ+aKLabbubUcDyb8lONnbZvtfmNn5xgyckxVRBykEYel7ui4p0vfDEhhSGEIS6CL9R4VFDxyIskpz++dM3/6YboZFkMI77+FlOUSrEh4774UlKUz3i35axt+itbC8q6E1dg1rzw39mHfcYl7gAyhuFcWtfSpnn1u3XRSYX2cNEXR7mumznQN2KeJtrQcTwXVvKyLKNO7WDnc2FhY2OodrbpzKf/w4FGVS+KkIVWJi+JHfhTJ6gH7A9h7j+eV9jMbF0LvnL5wZnEynTw7OXDj/bkiMf3KTiDT4nXBGBwh+5UORxbO39P4Wu5/tG3rZZ50sz/tO5m98vpPZtwyMlbvs7KlTG6yDMCCn08PD8TnvCr13dvZeCn85fWqD0o1Tp03NO6SZpgavaObpmWVKl2f+w81jOKd1fB++reh/kB/BX/BR4FWN6F0HJecK+J+iRot9QF52dwF2lZnG8eWlg0pdnTt+z3HDpIA39da+CZmSwOAF75qYlYI/ESFjS+cgK+dTINGLRp6PZp1pWb4j54QCtvHAsa/92rsuoEX94IdwzbseZkHhteG9T4E4fBap+RfycJ0IAHicY2BkYGAA4rbp0vXx/DZfGbhZGEDgeuJcCQT9v4GFgbkRyOVgYAKJAgAOEQlTAHicY2BkYGBu+N/AEMMCZDEwsDAwgGkkwA8ARy4CeQAAeJxjYWBgYH7JwMACpFkYoTSRGAA5wgEmAAAAAAB2ANwBNAGYAeACNgKGAsIDBgNKA6gD/gQ2BIx4nGNgZGBg4GcIZGBjAAEmIOYCQgaG/2A+AwASUgF9AHicZY9NTsMwEIVf+gekEqqoYIfkBWIBKP0Rq25YVGr3XXTfpk6bKokjx63UA3AejsAJOALcgDvwSCebNpbH37x5Y08A3OAHHo7fLfeRPVwyO3INF7gXrlN/EG6QX4SbaONVuEX9TdjHM6bCbXRheYPXuGL2hHdhDx18CNdwjU/hOvUv4Qb5W7iJO/wKt9Dx6sI+5l5XuI1HL/bHVi+cXqnlQcWhySKTOb+CmV7vkoWt0uqca1vEJlODoF9JU51pW91T7NdD5yIVWZOqCas6SYzKrdnq0AUb5/JRrxeJHoQm5Vhj/rbGAo5xBYUlDowxQhhkiMro6DtVZvSvsUPCXntWPc3ndFsU1P9zhQEC9M9cU7qy0nk6T4E9XxtSdXQrbsuelDSRXs1JErJCXta2VELqATZlV44RelzRiT8oZ0j/AAlabsgAAAB4nG2MUQ6CMBiDVxhMUMDEc/iwM3gGDzDxl83AlrAtcZ7eGR58sQ9t8zUpK9imlv3XgAIlOCrUENihQYs9DujQY8CR4VU/yM5kxBay9trFRKWPTmxV8uhp7WgxSdm3Jjstqvoiya/Zm1k9TXB2kqffHoyyo86Q5x/ZexrjakK6uDudb4x9ABJyKqQAAA==') format('woff'),
url('iconfont.ttf?t=1530625048960') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/
url('iconfont.svg?t=1530625048960#iconfont') format('svg'); /* iOS 4.1- */
}
.iconfont {
font-family:"iconfont" !important;
font-size:16px;
font-style:normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.icon-fenlei:before { content: "\e60a"; }
.icon-fenlei1:before { content: "\e611"; }
.icon-shouye:before { content: "\e612"; }
.icon-suo:before { content: "\e625"; }
.icon-shouye1:before { content: "\e60b"; }
.icon-user:before { content: "\e743"; }
.icon-emiyanzhengma:before { content: "\e61b"; }
.icon-user1:before { content: "\e600"; }
.icon-User:before { content: "\e67b"; }
.icon-lajitong1:before { content: "\e610"; }
.icon-yanzhengmatianchong:before { content: "\e636"; }
.icon-suo1:before { content: "\e644"; }
.icon-securityCode-b:before { content: "\e60d"; }
(function(window){var svgSprite='<svg><symbol id="icon-fenlei" viewBox="0 0 1024 1024"><path d="M350.595448 297.31036l572.384275 0c19.787672 0 35.776831-16.027022 35.776831-35.776831 0-19.744693-15.989159-35.769668-35.776831-35.769668L350.595448 225.76386c-19.74981 0-35.775808 16.024975-35.775808 35.769668C314.818617 281.283338 330.845639 297.31036 350.595448 297.31036L350.595448 297.31036z" ></path><path d="M922.979724 476.182236 350.595448 476.182236c-19.74981 0-35.775808 16.027022-35.775808 35.770691 0 19.748786 16.027022 35.775808 35.775808 35.775808l572.384275 0c19.787672 0 35.776831-16.027022 35.776831-35.775808C958.756555 492.209258 942.767396 476.182236 922.979724 476.182236L922.979724 476.182236z" ></path><path d="M922.979724 726.601636 350.595448 726.601636c-19.74981 0-35.775808 15.989159-35.775808 35.775808 0 19.782555 16.027022 35.771715 35.775808 35.771715l572.384275 0c19.787672 0 35.776831-15.989159 35.776831-35.771715C958.756555 742.590795 942.767396 726.601636 922.979724 726.601636L922.979724 726.601636z" ></path><path d="M186.537975 210.942293c-13.241582-13.242606-31.856545-20.956288-50.590212-20.956288-18.72855 0-37.347606 7.713682-50.591235 20.956288-13.242606 13.243629-20.956288 31.862685-20.956288 50.590212s7.707542 37.347606 20.956288 50.590212c13.241582 13.241582 31.856545 20.956288 50.590212 20.956288 18.72855 0 37.347606-7.713682 50.591235-20.956288 13.242606-13.243629 20.956288-31.862685 20.956288-50.590212S199.786721 224.185922 186.537975 210.942293z" ></path><path d="M186.537975 711.877283c-13.241582-13.240559-31.856545-20.957311-50.590212-20.957311-18.72855 0-37.347606 7.716752-50.591235 20.957311-13.242606 13.244652-20.956288 31.862685-20.956288 50.590212 0 18.729573 7.707542 37.34863 20.956288 50.591235 13.241582 13.242606 31.856545 20.956288 50.590212 20.956288 18.72855 0 37.347606-7.712659 50.591235-20.956288 13.242606-13.242606 20.956288-31.862685 20.956288-50.591235C207.494263 743.739968 199.786721 725.122959 186.537975 711.877283z" ></path><path d="M186.537975 461.365786c-13.241582-13.241582-31.856545-20.956288-50.590212-20.956288-18.72855 0-37.347606 7.714705-50.591235 20.956288-13.242606 13.244652-20.956288 31.862685-20.956288 50.590212 0 18.72855 7.707542 37.34863 20.956288 50.591235 13.241582 13.242606 31.856545 20.956288 50.590212 20.956288 18.72855 0 37.347606-7.712659 50.591235-20.956288 13.242606-13.242606 20.956288-31.862685 20.956288-50.591235C207.494263 493.228471 199.786721 474.610438 186.537975 461.365786z" ></path></symbol><symbol id="icon-fenlei1" viewBox="0 0 1025 1024"><path d="M333.787794 221.683316l587.512363 0c47.837766 0 48.601189-66.276582 0-66.276582L333.787794 155.406734C286.716521 155.406734 285.186604 221.683316 333.787794 221.683316zM125.659842 128.878295c-33.777888 0-61.173109 27.420805-61.173109 61.248837 0 33.852593 27.396244 61.271351 61.173109 61.271351 33.780958 0 61.176179-27.418758 61.176179-61.271351C186.836021 156.2991 159.4408 128.878295 125.659842 128.878295zM921.300157 477.698154 333.787794 477.698154c-47.071273 0-48.601189 66.274535 0 66.274535l587.512363 0C969.13997 543.970642 969.901346 477.698154 921.300157 477.698154zM125.659842 451.170738c-33.777888 0-61.173109 27.420805-61.173109 61.247814 0 33.852593 27.396244 61.273398 61.173109 61.273398 33.780958 0 61.176179-27.420805 61.176179-61.273398C186.836021 478.591543 159.4408 451.170738 125.659842 451.170738zM921.300157 799.985481 333.787794 799.985481c-47.071273 0-48.601189 66.277605 0 66.277605l587.512363 0C969.13997 866.263086 969.901346 799.985481 921.300157 799.985481zM125.659842 773.460112c-33.777888 0-61.173109 27.420805-61.173109 61.248837 0 33.852593 27.396244 61.273398 61.173109 61.273398 33.780958 0 61.176179-27.420805 61.176179-61.273398C186.836021 800.880917 159.4408 773.460112 125.659842 773.460112z" ></path></symbol><symbol id="icon-shouye" viewBox="0 0 1024 1024"><path d="M730.402195 880.056634 293.632597 880.056634c-97.240695 0-123.57548-33.3035-123.57548-137.02377L170.057117 446.054055c0-14.601556 11.485589-26.437116 25.703405-26.437116 14.182001 0 25.666566 11.835559 25.666566 26.437116l0 296.979832c0 75.531254 3.048429 84.182284 72.205509 84.182284l436.769598 0c69.122287 0 81.939197-8.651031 81.939197-84.182284L812.341393 446.054055c0-14.601556 11.520381-26.437116 25.701358-26.437116 14.183024 0 25.703405 11.835559 25.703405 26.437116l0 296.979832C863.746156 846.753133 827.643913 880.056634 730.402195 880.056634L730.402195 880.056634zM527.442714 191.480033 103.526865 519.414877c-4.624321 3.605108-10.04989 5.322216-15.443737 5.322216-7.77508 0-15.47853-3.640923-20.520359-10.5421-8.544607-11.658528-6.26775-28.220738 5.078669-36.976146l423.916872-327.968613c11.344373-8.755408 27.452235-6.445806 35.96205 5.216815C541.063943 166.126598 538.78811 182.690856 527.442714 191.480033L527.442714 191.480033zM956.436208 514.194992c-5.04183 6.9022-12.744255 10.5421-20.519336 10.5421-5.392824 0-10.819416-1.716084-15.442714-5.28947l-423.914826-327.96759c-11.345396-8.7902-13.622252-25.317619-5.079692-36.978193 8.54563-11.660574 24.65247-13.9712 35.963073-5.251607l423.915849 327.968613C962.703959 486.005976 964.981838 502.536464 956.436208 514.194992L956.436208 514.194992z" ></path></symbol><symbol id="icon-suo" viewBox="0 0 1024 1024"><path d="M765.604952 364.063693l-42.267663 0 0-84.535325c0-116.65793-94.679359-211.337289-211.337289-211.337289s-211.337289 94.679359-211.337289 211.337289l0 84.535325-42.267663 0c-46.705742 0-84.535325 37.829584-84.535325 84.535325l0 422.674579c0 46.705742 37.829584 84.535325 84.535325 84.535325l507.209904 0c46.705742 0 84.535325-37.829584 84.535325-84.535325L850.140277 448.599018C850.140277 401.893276 812.310693 364.063693 765.604952 364.063693zM512 744.470609c-46.705742 0-84.535325-37.829584-84.535325-84.535325 0-46.705742 37.829584-84.535325 84.535325-84.535325s84.535325 37.829584 84.535325 84.535325C596.534302 706.642049 558.705742 744.470609 512 744.470609zM643.029242 364.063693 380.970758 364.063693l0-84.535325c0-72.27714 58.752102-131.029242 131.029242-131.029242S643.029242 207.251228 643.029242 279.528368L643.029242 364.063693z" ></path></symbol><symbol id="icon-shouye1" viewBox="0 0 1024 1024"><path d="M780.190476 938.934857 243.809524 938.934857c-67.218286 0-121.904762-54.686476-121.904762-121.904762l0-219.428571L109.714286 597.601524c-47.055238 0-85.333333-38.278095-85.333333-85.333333 0-23.478857 9.435429-45.397333 26.599619-61.732571L435.46819 115.98019c19.431619-19.529143 46.933333-30.915048 76.190476-30.915048 29.257143 0 56.758857 11.385905 77.433905 32.060952L973.994667 451.535238C991.036952 468.967619 999.619048 490.057143 999.619048 512.26819c0 47.030857-38.278095 85.333333-85.333333 85.333333L902.095238 597.601524l0 219.428571C902.095238 884.248381 847.408762 938.934857 780.190476 938.934857zM511.658667 133.827048c-16.237714 0-31.47581 6.314667-42.959238 17.773714L83.797333 486.595048C77.214476 492.885333 73.142857 502.272 73.142857 512.26819c0 20.163048 16.408381 36.571429 36.571429 36.571429L170.666667 548.839619l0 268.190476c0 40.326095 32.816762 73.142857 73.142857 73.142857l536.380952 0c40.326095 0 73.142857-32.816762 73.142857-73.142857l0-268.190476 60.952381 0c20.163048 0 36.571429-16.408381 36.571429-36.571429 0-9.48419-3.657143-18.480762-10.361905-25.380571L555.861333 152.771048C543.134476 140.141714 527.896381 133.827048 511.658667 133.827048z" ></path></symbol><symbol id="icon-user" viewBox="0 0 1024 1024"><path d="M837.914838 774.764566c0-27.980261-10.703783-52.738132-31.607882-68.308759-58.392922-39.787168-104.661711-64.805982-186.714496-100.475366-20.726044-7.637957-34.792411-27.450189-34.792411-50.726312 0-16.423041 7.087419-31.924083 19.368116-41.012066 73.433476-54.32221 83.992973-214.32125 83.992973-214.32125 0-94.293573-76.738755-170.732499-171.511235-170.732499-94.770434 0-172.122149 76.5607-172.122149 170.854273 0 0 4.312212 123.051547 51.780317 178.942485l0.004093 0c9.496282 13.553691 19.436678 25.414833 31.737842 35.378765 11.610432 9.925047 19.295462 24.52865 19.295462 40.951691 0 23.280216-14.644535 43.060725-35.370579 50.698682-68.563562 28.569686-126.814244 59.249429-188.084703 100.460016-20.904099 15.569604-34.46086 40.320311-34.46086 68.300572 0 39.774889 27.398 73.092715 64.401776 82.573647 0 0 95.646384 40.135092 256.966513 40.135092 160.177096 0 256.967536-40.078811 256.967536-40.11872l0-0.020466C804.176432 847.862397 837.914838 814.539454 837.914838 774.764566L837.914838 774.764566zM837.914838 774.764566" ></path></symbol><symbol id="icon-emiyanzhengma" viewBox="0 0 1024 1024"><path d="M905.450308 125.1037C896.061252 125.413837 886.857235 125.529313 877.875951 125.529313 640.975313 125.529313 536.595731 24.886788 535.697946 23.964627L512.065963 0 488.341461 23.964627C487.370003 25.002264 385.085824 125.529313 146.190869 125.529313 137.182172 125.529313 128.039835 125.413837 118.556545 125.1037L85.333333 124.052866 85.333333 580.377175C85.333333 699.862129 128.353375 874.191718 500.387895 1007.504132L511.999142 1011.694272 523.60525 1007.504132C895.638059 874.18512 938.666667 699.862129 938.666667 580.377175L938.666667 124.052866 905.450308 125.1037 905.450308 125.1037ZM475.450355 698.445071 261.083455 511.162345 317.998615 465.71418 431.988275 548.583255C431.988275 548.583255 589.347494 388.025039 741.338848 313.003401L763.015919 337.149491C763.015919 337.149491 573.091405 492.385901 475.450355 698.445071L475.450355 698.445071Z" ></path></symbol><symbol id="icon-user1" viewBox="0 0 1024 1024"><path d="M164.655 68.977l0 0 0 0zM866.321 769.149q0 59.804-36.377 94.437t-96.684 34.632l-435.544 0q-60.293 0-96.684-34.632t-36.377-94.437q0-26.414 1.744-51.573t6.977-54.321 13.2-54.069 21.432-48.586 30.892-40.367 42.614-26.665 55.563-9.963q4.479 0 20.931 10.717t37.131 23.916 53.819 23.916 66.531 10.717 66.531-10.717 53.819-23.916 37.131-23.916 20.931-10.717q30.405 0 55.563 9.963t42.614 26.665 30.893 40.367 21.432 48.586 13.2 54.069 6.977 54.321 1.744 51.573zM706.846 324.131q0 79.242-56.065 135.292t-135.293 56.065-135.293-56.065-56.065-135.292 56.065-135.293 135.293-56.065 135.293 56.065 56.065 135.293z" ></path></symbol><symbol id="icon-User" viewBox="0 0 1024 1024"><path d="M654.222222 739.555556c-42.666667-22.755556-19.911111-65.422222 0-85.333334 25.6-25.6 56.888889-113.777778 56.888889-113.777778 51.2-22.755556 56.888889-59.733333 62.577778-85.333333 22.755556-73.955556-34.133333-85.333333-34.133333-85.333333s45.511111-122.311111 8.533333-216.177778c-48.355556-122.311111-244.622222-167.822222-278.755556-54.044444C236.088889 48.355556 284.444444 369.777778 284.444444 369.777778s-56.888889 11.377778-34.133333 85.333333c5.688889 25.6 11.377778 62.577778 62.577778 85.333333 0 0 31.288889 88.177778 56.888889 113.777778 19.911111 19.911111 42.666667 62.577778 0 85.333334-85.333333 45.511111-341.333333 56.888889-341.333334 256h967.111112c0-199.111111-256-210.488889-341.333334-256z" fill="" ></path></symbol><symbol id="icon-lajitong1" viewBox="0 0 1024 1024"><path d="M901.76 136.064l-259.776-43.328a23.232 23.232 0 0 1-18.752-17.28L604.352 0H360.96l-18.432 75.328a23.296 23.296 0 0 1-18.752 17.408L64 136.064v50.112h837.76v-50.112M740.8 1024l67.84-791.296H157.12L225.024 1024h515.84zM623.552 348.16a23.68 23.68 0 0 1 24.256-22.336c12.8 0.576 22.784 11.392 22.272 24.192l-23.296 558.592a23.296 23.296 0 0 1-23.232 22.272h-0.96a23.232 23.232 0 0 1-22.272-24.192l23.232-558.592z m-162.944 0.96a23.296 23.296 0 1 1 46.592 0v558.528a23.296 23.296 0 0 1-46.592 0V349.12zM320 325.76a23.68 23.68 0 0 1 24.256 22.272l23.296 558.592c0.512 12.8-9.472 23.68-22.272 24.192h-1.024a23.232 23.232 0 0 1-23.232-22.272l-23.296-558.592A23.232 23.232 0 0 1 320 325.824z" fill="#000000" ></path></symbol><symbol id="icon-yanzhengmatianchong" viewBox="0 0 1024 1024"><path d="M936.316466 159.387852c-2.361432-0.205087-241.211754-26.286309-407.238568-153.575097a27.856691 27.856691 0 0 0-34.056182 0c-165.136151 126.568052-404.877137 153.370009-407.232709 153.575097-14.97136 1.459048-26.186696 14.65494-26.186695 30.446648 0 6.961243 0.597682 172.279042 53.937913 357.853589 31.589276 109.926697 75.179079 204.067546 129.802569 279.715396 69.184676 95.904598 164.813871 162.089142 266.671855 196.596515 101.957598-34.507373 197.457881-100.586444 266.636697-196.596515 54.523876-75.548236 98.219153-169.571892 129.808429-279.715396 53.240617-185.574547 53.932053-350.892346 53.932054-357.853589 0.105473-15.791708-11.115722-28.887986-26.075363-30.446648z m-205.567612 245.354513l-232.844199 256.640165a34.589408 34.589408 0 0 1-23.784246 13.348242 27.405499 27.405499 0 0 1-3.170061 0.123052c-8.432011 0-16.869881-3.052868-22.969758-8.197625l-149.649143-130.540883c-14.531887-12.311087-16.172584-34.220251-3.867357-48.640806a34.39604 34.39604 0 0 1 26.245292-12.059123c8.203485 0 16.184304 2.929816 22.395513 8.197626l121.874488 106.762496 210.694789-227.693583c11.490738-15.117851 33.159658-18.047667 48.511894-6.328402 7.265944 5.625247 12.076702 13.711539 13.242769 22.852565a33.944849 33.944849 0 0 1-6.679981 25.536276z" fill="" ></path></symbol><symbol id="icon-suo1" viewBox="0 0 1024 1024"><path d="M809.6 416.64h-53.76V308.48c0-135.68-108.096-243.84-243.2-243.84-135.04 0-243.2 108.16-243.2 243.84v108.16h-53.76c-29.44 0-53.76 24.32-53.76 53.76v433.28c0 29.44 24.32 53.76 53.76 53.76h593.92c30.08 0 54.4-24.32 54.4-53.76V470.4c0-29.44-24.32-53.76-54.4-53.76z m-135.04 0H350.72V308.48c0-89.6 72.96-162.56 161.92-162.56a162.56 162.56 0 0 1 161.92 162.56v108.16z" ></path></symbol><symbol id="icon-securityCode-b" viewBox="0 0 1024 1024"><path d="M963.801169 218.170758a72.850542 72.850542 0 0 0-57.513586-63.903984 1357.959666 1357.959666 0 0 1-185.960594-42.815669A690.80207 690.80207 0 0 1 554.17663 14.317049a76.045741 76.045741 0 0 0-88.826539 0 435.825173 435.825173 0 0 1-167.428438 96.495016 624.341926 624.341926 0 0 1-180.848276 44.732789 67.738223 67.738223 0 0 0-56.874546 63.903984S58.281712 379.847839 58.281712 521.075644c0 255.615937 301.626806 502.924356 452.440208 502.924356s406.42934-174.457877 447.32789-499.090117c10.224637-191.711953 3.195199-306.100085 3.195199-306.100085zM799.567929 415.63407l-315.046642 297.153527a42.815669 42.815669 0 0 1-52.401267 5.112318l-8.307518-7.029438L249.993665 530.022202a42.815669 42.815669 0 0 1 63.903984-58.791666L457.042574 621.404899l283.73369-268.396734a42.815669 42.815669 0 1 1 58.791665 63.903984" ></path></symbol></svg>';var script=function(){var scripts=document.getElementsByTagName("script");return scripts[scripts.length-1]}();var shouldInjectCss=script.getAttribute("data-injectcss");var ready=function(fn){if(document.addEventListener){if(~["complete","loaded","interactive"].indexOf(document.readyState)){setTimeout(fn,0)}else{var loadFn=function(){document.removeEventListener("DOMContentLoaded",loadFn,false);fn()};document.addEventListener("DOMContentLoaded",loadFn,false)}}else if(document.attachEvent){IEContentLoaded(window,fn)}function IEContentLoaded(w,fn){var d=w.document,done=false,init=function(){if(!done){done=true;fn()}};var polling=function(){try{d.documentElement.doScroll("left")}catch(e){setTimeout(polling,50);return}init()};polling();d.onreadystatechange=function(){if(d.readyState=="complete"){d.onreadystatechange=null;init()}}}};var before=function(el,target){target.parentNode.insertBefore(el,target)};var prepend=function(el,target){if(target.firstChild){before(el,target.firstChild)}else{target.appendChild(el)}};function appendSvg(){var div,svg;div=document.createElement("div");div.innerHTML=svgSprite;svgSprite=null;svg=div.getElementsByTagName("svg")[0];if(svg){svg.setAttribute("aria-hidden","true");svg.style.position="absolute";svg.style.width=0;svg.style.height=0;svg.style.overflow="hidden";prepend(svg,document.body)}}if(shouldInjectCss&&!window.__iconfont__svg__cssinject__){window.__iconfont__svg__cssinject__=true;try{document.write("<style>.svgfont {display: inline-block;width: 1em;height: 1em;fill: currentColor;vertical-align: -0.1em;font-size:16px;}</style>")}catch(e){console&&console.log(e)}}ready(appendSvg)})(window)
\ No newline at end of file
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
<!--
2013-9-30: Created.
-->
<svg>
<metadata>
Created by iconfont
</metadata>
<defs>
<font id="iconfont" horiz-adv-x="1024" >
<font-face
font-family="iconfont"
font-weight="500"
font-stretch="normal"
units-per-em="1024"
ascent="896"
descent="-128"
/>
<missing-glyph />
<glyph glyph-name="x" unicode="x" horiz-adv-x="1001"
d="M281 543q-27 -1 -53 -1h-83q-18 0 -36.5 -6t-32.5 -18.5t-23 -32t-9 -45.5v-76h912v41q0 16 -0.5 30t-0.5 18q0 13 -5 29t-17 29.5t-31.5 22.5t-49.5 9h-133v-97h-438v97zM955 310v-52q0 -23 0.5 -52t0.5 -58t-10.5 -47.5t-26 -30t-33 -16t-31.5 -4.5q-14 -1 -29.5 -0.5
t-29.5 0.5h-32l-45 128h-439l-44 -128h-29h-34q-20 0 -45 1q-25 0 -41 9.5t-25.5 23t-13.5 29.5t-4 30v167h911zM163 247q-12 0 -21 -8.5t-9 -21.5t9 -21.5t21 -8.5q13 0 22 8.5t9 21.5t-9 21.5t-22 8.5zM316 123q-8 -26 -14 -48q-5 -19 -10.5 -37t-7.5 -25t-3 -15t1 -14.5
t9.5 -10.5t21.5 -4h37h67h81h80h64h36q23 0 34 12t2 38q-5 13 -9.5 30.5t-9.5 34.5q-5 19 -11 39h-368zM336 498v228q0 11 2.5 23t10 21.5t20.5 15.5t34 6h188q31 0 51.5 -14.5t20.5 -52.5v-227h-327z" />
<glyph glyph-name="fenlei" unicode="&#58890;" d="M350.595448 598.68964l572.384275 0c19.787672 0 35.776831 16.027022 35.776831 35.776831 0 19.744693-15.989159 35.769668-35.776831 35.769668L350.595448 670.23614c-19.74981 0-35.775808-16.024975-35.775808-35.769668C314.818617 614.716662 330.845639 598.68964 350.595448 598.68964L350.595448 598.68964zM922.979724 419.817764 350.595448 419.817764c-19.74981 0-35.775808-16.027022-35.775808-35.770691 0-19.748786 16.027022-35.775808 35.775808-35.775808l572.384275 0c19.787672 0 35.776831 16.027022 35.776831 35.775808C958.756555 403.790742 942.767396 419.817764 922.979724 419.817764L922.979724 419.817764zM922.979724 169.398364 350.595448 169.398364c-19.74981 0-35.775808-15.989159-35.775808-35.775808 0-19.782555 16.027022-35.771715 35.775808-35.771715l572.384275 0c19.787672 0 35.776831 15.989159 35.776831 35.771715C958.756555 153.409205 942.767396 169.398364 922.979724 169.398364L922.979724 169.398364zM186.537975 685.057707c-13.241582 13.242606-31.856545 20.956288-50.590212 20.956288-18.72855 0-37.347606-7.713682-50.591235-20.956288-13.242606-13.243629-20.956288-31.862685-20.956288-50.590212s7.707542-37.347606 20.956288-50.590212c13.241582-13.241582 31.856545-20.956288 50.590212-20.956288 18.72855 0 37.347606 7.713682 50.591235 20.956288 13.242606 13.243629 20.956288 31.862685 20.956288 50.590212S199.786721 671.814078 186.537975 685.057707zM186.537975 184.122717c-13.241582 13.240559-31.856545 20.957311-50.590212 20.957311-18.72855 0-37.347606-7.716752-50.591235-20.957311-13.242606-13.244652-20.956288-31.862685-20.956288-50.590212 0-18.729573 7.707542-37.34863 20.956288-50.591235 13.241582-13.242606 31.856545-20.956288 50.590212-20.956288 18.72855 0 37.347606 7.712659 50.591235 20.956288 13.242606 13.242606 20.956288 31.862685 20.956288 50.591235C207.494263 152.260032 199.786721 170.877041 186.537975 184.122717zM186.537975 434.634214c-13.241582 13.241582-31.856545 20.956288-50.590212 20.956288-18.72855 0-37.347606-7.714705-50.591235-20.956288-13.242606-13.244652-20.956288-31.862685-20.956288-50.590212 0-18.72855 7.707542-37.34863 20.956288-50.591235 13.241582-13.242606 31.856545-20.956288 50.590212-20.956288 18.72855 0 37.347606 7.712659 50.591235 20.956288 13.242606 13.242606 20.956288 31.862685 20.956288 50.591235C207.494263 402.771529 199.786721 421.389562 186.537975 434.634214z" horiz-adv-x="1024" />
<glyph glyph-name="fenlei1" unicode="&#58897;" d="M333.787794 674.316684l587.512363 0c47.837766 0 48.601189 66.276582 0 66.276582L333.787794 740.593266C286.716521 740.593266 285.186604 674.316684 333.787794 674.316684zM125.659842 767.121705c-33.777888 0-61.173109-27.420805-61.173109-61.248837 0-33.852593 27.396244-61.271351 61.173109-61.271351 33.780958 0 61.176179 27.418758 61.176179 61.271351C186.836021 739.7009 159.4408 767.121705 125.659842 767.121705zM921.300157 418.301846 333.787794 418.301846c-47.071273 0-48.601189-66.274535 0-66.274535l587.512363 0C969.13997 352.029358 969.901346 418.301846 921.300157 418.301846zM125.659842 444.829262c-33.777888 0-61.173109-27.420805-61.173109-61.247814 0-33.852593 27.396244-61.273398 61.173109-61.273398 33.780958 0 61.176179 27.420805 61.176179 61.273398C186.836021 417.408457 159.4408 444.829262 125.659842 444.829262zM921.300157 96.014519 333.787794 96.014519c-47.071273 0-48.601189-66.277605 0-66.277605l587.512363 0C969.13997 29.736914 969.901346 96.014519 921.300157 96.014519zM125.659842 122.539888c-33.777888 0-61.173109-27.420805-61.173109-61.248837 0-33.852593 27.396244-61.273398 61.173109-61.273398 33.780958 0 61.176179 27.420805 61.176179 61.273398C186.836021 95.119083 159.4408 122.539888 125.659842 122.539888z" horiz-adv-x="1025" />
<glyph glyph-name="shouye" unicode="&#58898;" d="M730.402195 15.943366 293.632597 15.943366c-97.240695 0-123.57548 33.3035-123.57548 137.02377L170.057117 449.945945c0 14.601556 11.485589 26.437116 25.703405 26.437116 14.182001 0 25.666566-11.835559 25.666566-26.437116l0-296.979832c0-75.531254 3.048429-84.182284 72.205509-84.182284l436.769598 0c69.122287 0 81.939197 8.651031 81.939197 84.182284L812.341393 449.945945c0 14.601556 11.520381 26.437116 25.701358 26.437116 14.183024 0 25.703405-11.835559 25.703405-26.437116l0-296.979832C863.746156 49.246867 827.643913 15.943366 730.402195 15.943366L730.402195 15.943366zM527.442714 704.519967 103.526865 376.585123c-4.624321-3.605108-10.04989-5.322216-15.443737-5.322216-7.77508 0-15.47853 3.640923-20.520359 10.5421-8.544607 11.658528-6.26775 28.220738 5.078669 36.976146l423.916872 327.968613c11.344373 8.755408 27.452235 6.445806 35.96205-5.216815C541.063943 729.873402 538.78811 713.309144 527.442714 704.519967L527.442714 704.519967zM956.436208 381.805008c-5.04183-6.9022-12.744255-10.5421-20.519336-10.5421-5.392824 0-10.819416 1.716084-15.442714 5.28947l-423.914826 327.96759c-11.345396 8.7902-13.622252 25.317619-5.079692 36.978193 8.54563 11.660574 24.65247 13.9712 35.963073 5.251607l423.915849-327.968613C962.703959 409.994024 964.981838 393.463536 956.436208 381.805008L956.436208 381.805008z" horiz-adv-x="1024" />
<glyph glyph-name="suo" unicode="&#58917;" d="M765.604952 531.936307l-42.267663 0 0 84.535325c0 116.65793-94.679359 211.337289-211.337289 211.337289s-211.337289-94.679359-211.337289-211.337289l0-84.535325-42.267663 0c-46.705742 0-84.535325-37.829584-84.535325-84.535325l0-422.674579c0-46.705742 37.829584-84.535325 84.535325-84.535325l507.209904 0c46.705742 0 84.535325 37.829584 84.535325 84.535325L850.140277 447.400982C850.140277 494.106724 812.310693 531.936307 765.604952 531.936307zM512 151.529391c-46.705742 0-84.535325 37.829584-84.535325 84.535325 0 46.705742 37.829584 84.535325 84.535325 84.535325s84.535325-37.829584 84.535325-84.535325C596.534302 189.357951 558.705742 151.529391 512 151.529391zM643.029242 531.936307 380.970758 531.936307l0 84.535325c0 72.27714 58.752102 131.029242 131.029242 131.029242S643.029242 688.748772 643.029242 616.471632L643.029242 531.936307z" horiz-adv-x="1024" />
<glyph glyph-name="shouye1" unicode="&#58891;" d="M780.190476-42.934857 243.809524-42.934857c-67.218286 0-121.904762 54.686476-121.904762 121.904762l0 219.428571L109.714286 298.398476c-47.055238 0-85.333333 38.278095-85.333333 85.333333 0 23.478857 9.435429 45.397333 26.599619 61.732571L435.46819 780.01981c19.431619 19.529143 46.933333 30.915048 76.190476 30.915048 29.257143 0 56.758857-11.385905 77.433905-32.060952L973.994667 444.464762C991.036952 427.032381 999.619048 405.942857 999.619048 383.73181c0-47.030857-38.278095-85.333333-85.333333-85.333333L902.095238 298.398476l0-219.428571C902.095238 11.751619 847.408762-42.934857 780.190476-42.934857zM511.658667 762.172952c-16.237714 0-31.47581-6.314667-42.959238-17.773714L83.797333 409.404952C77.214476 403.114667 73.142857 393.728 73.142857 383.73181c0-20.163048 16.408381-36.571429 36.571429-36.571429L170.666667 347.160381l0-268.190476c0-40.326095 32.816762-73.142857 73.142857-73.142857l536.380952 0c40.326095 0 73.142857 32.816762 73.142857 73.142857l0 268.190476 60.952381 0c20.163048 0 36.571429 16.408381 36.571429 36.571429 0 9.48419-3.657143 18.480762-10.361905 25.380571L555.861333 743.228952C543.134476 755.858286 527.896381 762.172952 511.658667 762.172952z" horiz-adv-x="1024" />
<glyph glyph-name="user" unicode="&#59203;" d="M837.914838 121.235434c0 27.980261-10.703783 52.738132-31.607882 68.308759-58.392922 39.787168-104.661711 64.805982-186.714496 100.475366-20.726044 7.637957-34.792411 27.450189-34.792411 50.726312 0 16.423041 7.087419 31.924083 19.368116 41.012066 73.433476 54.32221 83.992973 214.32125 83.992973 214.32125 0 94.293573-76.738755 170.732499-171.511235 170.732499-94.770434 0-172.122149-76.5607-172.122149-170.854273 0 0 4.312212-123.051547 51.780317-178.942485l0.004093 0c9.496282-13.553691 19.436678-25.414833 31.737842-35.378765 11.610432-9.925047 19.295462-24.52865 19.295462-40.951691 0-23.280216-14.644535-43.060725-35.370579-50.698682-68.563562-28.569686-126.814244-59.249429-188.084703-100.460016-20.904099-15.569604-34.46086-40.320311-34.46086-68.300572 0-39.774889 27.398-73.092715 64.401776-82.573647 0 0 95.646384-40.135092 256.966513-40.135092 160.177096 0 256.967536 40.078811 256.967536 40.11872l0 0.020466C804.176432 48.137603 837.914838 81.460546 837.914838 121.235434L837.914838 121.235434zM837.914838 121.235434" horiz-adv-x="1024" />
<glyph glyph-name="emiyanzhengma" unicode="&#58907;" d="M905.450308 770.8963C896.061252 770.586163 886.857235 770.470687 877.875951 770.470687 640.975313 770.470687 536.595731 871.113212 535.697946 872.035373L512.065963 896 488.341461 872.035373C487.370003 870.997736 385.085824 770.470687 146.190869 770.470687 137.182172 770.470687 128.039835 770.586163 118.556545 770.8963L85.333333 771.947134 85.333333 315.622825C85.333333 196.137871 128.353375 21.808282 500.387895-111.504132L511.999142-115.694272 523.60525-111.504132C895.638059 21.81488 938.666667 196.137871 938.666667 315.622825L938.666667 771.947134 905.450308 770.8963 905.450308 770.8963ZM475.450355 197.554929 261.083455 384.837655 317.998615 430.28582 431.988275 347.416745C431.988275 347.416745 589.347494 507.974961 741.338848 582.996599L763.015919 558.850509C763.015919 558.850509 573.091405 403.614099 475.450355 197.554929L475.450355 197.554929Z" horiz-adv-x="1024" />
<glyph glyph-name="user1" unicode="&#58880;" d="M164.655 827.023l0 0 0 0zM866.321 126.851q0-59.804-36.377-94.437t-96.684-34.632l-435.544 0q-60.293 0-96.684 34.632t-36.377 94.437q0 26.414 1.744 51.573t6.977 54.321 13.2 54.069 21.432 48.586 30.892 40.367 42.614 26.665 55.563 9.963q4.479 0 20.931-10.717t37.131-23.916 53.819-23.916 66.531-10.717 66.531 10.717 53.819 23.916 37.131 23.916 20.931 10.717q30.405 0 55.563-9.963t42.614-26.665 30.893-40.367 21.432-48.586 13.2-54.069 6.977-54.321 1.744-51.573zM706.846 571.869q0-79.242-56.065-135.292t-135.293-56.065-135.293 56.065-56.065 135.292 56.065 135.293 135.293 56.065 135.293-56.065 56.065-135.293z" horiz-adv-x="1024" />
<glyph glyph-name="User" unicode="&#59003;" d="M654.222222 156.444444c-42.666667 22.755556-19.911111 65.422222 0 85.333334 25.6 25.6 56.888889 113.777778 56.888889 113.777778 51.2 22.755556 56.888889 59.733333 62.577778 85.333333 22.755556 73.955556-34.133333 85.333333-34.133333 85.333333s45.511111 122.311111 8.533333 216.177778c-48.355556 122.311111-244.622222 167.822222-278.755556 54.044444C236.088889 847.644444 284.444444 526.222222 284.444444 526.222222s-56.888889-11.377778-34.133333-85.333333c5.688889-25.6 11.377778-62.577778 62.577778-85.333333 0 0 31.288889-88.177778 56.888889-113.777778 19.911111-19.911111 42.666667-62.577778 0-85.333334-85.333333-45.511111-341.333333-56.888889-341.333334-256h967.111112c0 199.111111-256 210.488889-341.333334 256z" horiz-adv-x="1024" />
<glyph glyph-name="lajitong1" unicode="&#58896;" d="M901.76 759.936l-259.776 43.328a23.232 23.232 0 0 0-18.752 17.28L604.352 896H360.96l-18.432-75.328a23.296 23.296 0 0 0-18.752-17.408L64 759.936v-50.112h837.76v50.112M740.8-128l67.84 791.296H157.12L225.024-128h515.84zM623.552 547.84a23.68 23.68 0 0 0 24.256 22.336c12.8-0.576 22.784-11.392 22.272-24.192l-23.296-558.592a23.296 23.296 0 0 0-23.232-22.272h-0.96a23.232 23.232 0 0 0-22.272 24.192l23.232 558.592z m-162.944-0.96a23.296 23.296 0 1 0 46.592 0v-558.528a23.296 23.296 0 0 0-46.592 0V546.88zM320 570.24a23.68 23.68 0 0 0 24.256-22.272l23.296-558.592c0.512-12.8-9.472-23.68-22.272-24.192h-1.024a23.232 23.232 0 0 0-23.232 22.272l-23.296 558.592A23.232 23.232 0 0 0 320 570.176z" horiz-adv-x="1024" />
<glyph glyph-name="yanzhengmatianchong" unicode="&#58934;" d="M936.316466 736.612148c-2.361432 0.205087-241.211754 26.286309-407.238568 153.575097a27.856691 27.856691 0 0 1-34.056182 0c-165.136151-126.568052-404.877137-153.370009-407.232709-153.575097-14.97136-1.459048-26.186696-14.65494-26.186695-30.446648 0-6.961243 0.597682-172.279042 53.937913-357.853589 31.589276-109.926697 75.179079-204.067546 129.802569-279.715396 69.184676-95.904598 164.813871-162.089142 266.671855-196.596515 101.957598 34.507373 197.457881 100.586444 266.636697 196.596515 54.523876 75.548236 98.219153 169.571892 129.808429 279.715396 53.240617 185.574547 53.932053 350.892346 53.932054 357.853589 0.105473 15.791708-11.115722 28.887986-26.075363 30.446648z m-205.567612-245.354513l-232.844199-256.640165a34.589408 34.589408 0 0 0-23.784246-13.348242 27.405499 27.405499 0 0 0-3.170061-0.123052c-8.432011 0-16.869881 3.052868-22.969758 8.197625l-149.649143 130.540883c-14.531887 12.311087-16.172584 34.220251-3.867357 48.640806a34.39604 34.39604 0 0 0 26.245292 12.059123c8.203485 0 16.184304-2.929816 22.395513-8.197626l121.874488-106.762496 210.694789 227.693583c11.490738 15.117851 33.159658 18.047667 48.511894 6.328402 7.265944-5.625247 12.076702-13.711539 13.242769-22.852565a33.944849 33.944849 0 0 0-6.679981-25.536276z" horiz-adv-x="1024" />
<glyph glyph-name="suo1" unicode="&#58948;" d="M809.6 479.36h-53.76V587.52c0 135.68-108.096 243.84-243.2 243.84-135.04 0-243.2-108.16-243.2-243.84v-108.16h-53.76c-29.44 0-53.76-24.32-53.76-53.76v-433.28c0-29.44 24.32-53.76 53.76-53.76h593.92c30.08 0 54.4 24.32 54.4 53.76V425.6c0 29.44-24.32 53.76-54.4 53.76z m-135.04 0H350.72V587.52c0 89.6 72.96 162.56 161.92 162.56a162.56 162.56 0 0 0 161.92-162.56v-108.16z" horiz-adv-x="1024" />
<glyph glyph-name="securityCode-b" unicode="&#58893;" d="M963.801169 677.829242a72.850542 72.850542 0 0 1-57.513586 63.903984 1357.959666 1357.959666 0 0 0-185.960594 42.815669A690.80207 690.80207 0 0 0 554.17663 881.682951a76.045741 76.045741 0 0 1-88.826539 0 435.825173 435.825173 0 0 0-167.428438-96.495016 624.341926 624.341926 0 0 0-180.848276-44.732789 67.738223 67.738223 0 0 1-56.874546-63.903984S58.281712 516.152161 58.281712 374.924356c0-255.615937 301.626806-502.924356 452.440208-502.924356s406.42934 174.457877 447.32789 499.090117c10.224637 191.711953 3.195199 306.100085 3.195199 306.100085zM799.567929 480.36593l-315.046642-297.153527a42.815669 42.815669 0 0 0-52.401267-5.112318l-8.307518 7.029438L249.993665 365.977798a42.815669 42.815669 0 0 0 63.903984 58.791666L457.042574 274.595101l283.73369 268.396734a42.815669 42.815669 0 1 0 58.791665-63.903984" horiz-adv-x="1024" />
</font>
</defs></svg>
import React from 'react'
import { withRouter, Switch, Redirect } from 'react-router-dom'
import LoadableComponent from '../../utils/LoadableComponent'
import PrivateRoute from '../PrivateRoute'
const Home = LoadableComponent(()=>import('../../routes/Home/index')) //参数一定要是函数,否则不会懒加载,只会代码拆分
// 搜索结果
const StructureSearch = LoadableComponent(()=>import('../../routes/Home/StructureSearch/index'))
const SearchList = LoadableComponent(()=>import('../../routes/Home/SearchList/index'))
const SearchDetails = LoadableComponent(()=>import('../../routes/Home/SearchDetails/index'))
const TargetDetails = LoadableComponent(()=>import('../../routes/Home/TargetDetails/index'))
const AutoimmuneDiseases = LoadableComponent(()=>import('../../routes/Home/AutoimmuneDiseases/index'))
const AntigenDetails = LoadableComponent(()=>import('../../routes/Home/AntigenDetails/index'))
const MolstarView = LoadableComponent(()=>import('../../routes/Home/MolstarView/index'))
const SequenceDetails = LoadableComponent(()=>import('../../routes/Home/SequenceDetails/index'))
const Docking = LoadableComponent(()=>import('../../routes/Home/Docking/index'))
// 计算工具
const ProteinTools = LoadableComponent(()=>import('../../routes/computationalTools/ProteinTools/index'))
const MultipleSequenceAlignment = LoadableComponent(()=>import('../../routes/computationalTools/MultipleSequenceAlignment/index'))
@withRouter
class ContentMain extends React.Component {
render () {
return (
<div style={{padding: 16, position: 'relative'}}>
<Switch>
<PrivateRoute exact path='/home' component={Home}/>
<PrivateRoute exact path='/home/SearchList' component={SearchList}/>
<PrivateRoute exact path='/home/StructureSearch' component={StructureSearch}/>
<PrivateRoute exact path='/home/Docking' component={Docking}/>
<PrivateRoute exact path='/home/SearchDetails' component={SearchDetails}/>
<PrivateRoute exact path='/home/TargetDetails' component={TargetDetails}/>
<PrivateRoute exact path='/home/AutoimmuneDiseases' component={AutoimmuneDiseases}/>
<PrivateRoute exact path='/home/AntigenDetails' component={AntigenDetails}/>
<PrivateRoute exact path='/home/MolstarView' component={MolstarView}/>
<PrivateRoute exact path='/home/SequenceDetails' component={SequenceDetails}/>
<PrivateRoute exact path='/computationalTools/ProteinTools' component={ProteinTools}/>
<PrivateRoute exact path='/computationalTools/MultipleSequenceAlignment' component={MultipleSequenceAlignment}/>
<Redirect exact from='/' to='/home'/>
</Switch>
</div>
)
}
}
export default ContentMain
\ No newline at end of file
import React from 'react'
import {Breadcrumb} from 'antd'
import {Link} from 'react-router-dom'
const CustomBreadcrumb = (props)=>(
<Breadcrumb style={{marginBottom:16}}>
<Breadcrumb.Item><Link to='/home'>首页</Link></Breadcrumb.Item>
{props.arr && props.arr.map(item=>{
if ((typeof item) === 'object'){
return <Breadcrumb.Item key={item.title}><Link to={item.to}>{item.title}</Link></Breadcrumb.Item>
} else {
return <Breadcrumb.Item key={item}>{item}</Breadcrumb.Item>
}
})}
</Breadcrumb>
)
export default CustomBreadcrumb
\ No newline at end of file
import React from 'react'
import {Link,withRouter} from 'react-router-dom'
import {Menu, Icon} from 'antd'
//此组件的意义就是将数据抽离出来,通过传递数据去渲染
@withRouter
class CustomMenu extends React.Component {
state = {
openKeys: [],
selectedKeys: []
}
componentDidMount() {
// 防止页面刷新侧边栏又初始化了
const pathname = this.props.location.pathname
//获取当前所在的目录层级
const rank = pathname.split('/')
switch (rank.length) {
case 2 : //一级目录
this.setState({
selectedKeys: [pathname]
})
break;
case 5 : //三级目录,要展开两个subMenu
this.setState({
selectedKeys: [pathname],
openKeys: [rank.slice(0, 3).join('/'), rank.slice(0, 4).join('/')]
})
break;
default :
this.setState({
selectedKeys: [pathname],
openKeys: [pathname.substr(0, pathname.lastIndexOf('/'))]
})
}
}
componentWillReceiveProps(nextProps) {
//当点击面包屑导航时,侧边栏要同步响应
const pathname = nextProps.location.pathname
if (this.props.location.pathname !== pathname) {
this.setState({
selectedKeys: [pathname],
})
}
}
onOpenChange = (openKeys) => {
//此函数的作用只展开当前父级菜单(父级菜单下可能还有子菜单)
if (openKeys.length === 0 || openKeys.length === 1) {
this.setState({
openKeys
})
return
}
//最新展开的菜单
const latestOpenKey = openKeys[openKeys.length - 1]
//判断最新展开的菜单是不是父级菜单,若是父级菜单就只展开一个,不是父级菜单就展开父级菜单和当前子菜单
//因为我的子菜单的key包含了父级菜单,所以不用像官网的例子单独定义父级菜单数组,然后比较当前菜单在不在父级菜单数组里面。
//只适用于3级菜单
if (latestOpenKey.includes(openKeys[0])) {
this.setState({
openKeys
})
} else {
this.setState({
openKeys: [latestOpenKey]
})
}
}
renderMenuItem = ({key, icon, title,}) => {
return (
<Menu.Item key={key}>
<Link to={key}>
{icon && <Icon type={icon}/>}
<span>{title}</span>
</Link>
</Menu.Item>
)
}
renderSubMenu = ({key, icon, title, subs}) => {
return (
<Menu.SubMenu key={key} title={<span>{icon && <Icon type={icon}/>}<span>{title}</span></span>}>
{
subs && subs.map(item => {
return item.subs && item.subs.length > 0 ? this.renderSubMenu(item) : this.renderMenuItem(item)
})
}
</Menu.SubMenu>
)
}
render() {
const {openKeys, selectedKeys} = this.state
return (
<Menu
onOpenChange={this.onOpenChange}
onClick={({key}) => this.setState({selectedKeys: [key]})}
openKeys={openKeys}
selectedKeys={selectedKeys}
theme={this.props.theme ? this.props.theme : 'dark'}
mode='inline'>
{
this.props.menus && this.props.menus.map(item => {
return item.subs && item.subs.length > 0 ? this.renderSubMenu(item) : this.renderMenuItem(item)
})
}
</Menu>
)
}
}
export default CustomMenu
\ No newline at end of file
import React from 'react'
import { Icon, Badge, Dropdown, Menu, Modal } from 'antd'
import screenfull from 'screenfull'
import { inject, observer } from 'mobx-react'
import { Link, withRouter } from 'react-router-dom'
import { isAuthenticated } from '../../utils/Session'
//withRouter一定要写在前面,不然路由变化不会反映到props中去
@withRouter @inject('appStore') @observer
class HeaderBar extends React.Component {
state = {
icon: 'arrows-alt',
count: 100,
visible: false,
avatar: require('./img/defaultUser.jpg')
}
componentDidMount () {
screenfull.onchange(() => {
this.setState({
icon: screenfull.isFullscreen ? 'shrink' : 'arrows-alt'
})
})
}
componentWillUnmount () {
screenfull.off('change')
}
toggle = () => {
this.props.onToggle()
}
screenfullToggle = () => {
if (screenfull.enabled) {
screenfull.toggle()
}
}
logout = () => {
this.props.appStore.toggleLogin(false)
this.props.history.push(this.props.location.pathname)
}
render () {
const {icon, count, visible, avatar} = this.state
const {appStore, collapsed, location} = this.props
const notLogin = (
<div>
<Link to={{pathname: '/login', state: {from: location}}} style={{color: 'rgba(0, 0, 0, 0.65)'}}>登录</Link>&nbsp;
<img src={require('../../assets/img/defaultUser.jpg')} alt=""/>
</div>
)
const menu = (
<Menu className='menu'>
<Menu.ItemGroup title='用户中心' className='menu-group'>
{/* <Menu.Item>你好 - {isAuthenticated()}</Menu.Item>
<Menu.Item>个人信息</Menu.Item> */}
<Menu.Item><span onClick={this.logout}>退出登录</span></Menu.Item>
</Menu.ItemGroup>
{/* <Menu.ItemGroup title='设置中心' className='menu-group'>
<Menu.Item>个人设置</Menu.Item>
<Menu.Item>系统设置</Menu.Item>
</Menu.ItemGroup> */}
</Menu>
)
const login = (
<Dropdown overlay={menu}>
<img src={avatar} alt=""/>
</Dropdown>
)
return (
<div id='headerbar'>
<Icon
type={collapsed ? 'menu-unfold' : 'menu-fold'}
className='trigger'
onClick={this.toggle}/>
<div style={{lineHeight: '64px', float: 'right'}}>
<ul className='header-ul'>
<li><Icon type={icon} onClick={this.screenfullToggle}/></li>
{/* <li onClick={() => this.setState({count: 0})}>
<Badge count={appStore.isLogin ? count : 0} overflowCount={99} style={{marginRight: -17}}>
<Icon type="notification"/>
</Badge>
</li> */}
<li>
{appStore.isLogin ? login : notLogin}
</li>
</ul>
</div>
<Modal
footer={null} closable={false}
visible={visible}
wrapClassName="vertical-center-modal"
onCancel={() => this.setState({visible: false})}>
<img src={avatar} alt="" width='100%'/>
</Modal>
</div>
)
}
}
export default HeaderBar
\ No newline at end of file
import React from 'react'
import './style.css'
class Loading extends React.Component{
render(){
return (
<div id='loading'>
<div className="dot"/>
<div className="dot"/>
<div className="dot"/>
<div className="dot"/>
<div className="dot"/>
</div>
)
}
}
export default Loading
\ No newline at end of file
#loading .dot {
width: 24px;
height: 24px;
background: #3ac;
border-radius: 100%;
display: inline-block;
animation: slide 1s infinite;
}
#loading .dot:nth-child(1) {
animation-delay: 0.1s;
background: #32aacc;
}
#loading .dot:nth-child(2) {
animation-delay: 0.2s;
background: #64aacc;
}
#loading .dot:nth-child(3) {
animation-delay: 0.3s;
background: #96aacc;
}
#loading .dot:nth-child(4) {
animation-delay: 0.4s;
background: #c8aacc;
}
#loading .dot:nth-child(5) {
animation-delay: 0.5s;
background: #faaacc;
}
@-moz-keyframes slide {
0% {
transform: scale(1);
}
50% {
opacity: 0.3;
transform: scale(2);
}
100% {
transform: scale(1);
}
}
@-webkit-keyframes slide {
0% {
transform: scale(1);
}
50% {
opacity: 0.3;
transform: scale(2);
}
100% {
transform: scale(1);
}
}
@-o-keyframes slide {
0% {
transform: scale(1);
}
50% {
opacity: 0.3;
transform: scale(2);
}
100% {
transform: scale(1);
}
}
@keyframes slide {
0% {
transform: scale(1);
}
50% {
opacity: 0.3;
transform: scale(2);
}
100% {
transform: scale(1);
}
}
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
import React from 'react'
import bodymovin from 'bodymovin'
class Loading2 extends React.Component{
componentDidMount(){
const animData = {
wrapper: document.querySelector('#animationWindow'),
animType: 'svg',
loop: true,
prerender: true,
autoplay: true,
animationData:require('./data.json')
};
this.anim = bodymovin.loadAnimation(animData);
this.anim.setSpeed(1.42);
}
componentWillUnmount(){
this.anim = null
}
render(){
return (
<div style={{width:'100%',height:'100%'}}>
<div id="animationWindow" style={{width:'100%',height:'100%'}}/>
</div>
)
}
}
export default Loading2
\ No newline at end of file
.logo-div{
width: 100%;
display: flex;
justify-content: center;
position: fixed;
z-index: 100;
margin-top: 50px;
min-width: 1000px;
min-height: 100px;
}
.logo-div img{
height: 102px;
}
\ No newline at end of file
import React, { Component } from 'react'
import './index.css'
export default class LogoTitlte extends Component {
render() {
return (
<div className='logo-div'>
<img src={require('./img/logo.png')} alt=""/>
</div>
)
}
}
import React from 'react'
import { Route, Redirect, } from 'react-router-dom'
import { isAuthenticated } from '../../utils/Session'
const PrivateRoute = ({component: Component, ...rest}) => (
<Route {...rest} render={(props) => (
// <Component {...props} />
!!isAuthenticated()
? <Component {...props} />
: <Redirect to={{
pathname: '/login',
state: {from: props.location}
}}/>
)}/>
)
export default PrivateRoute
\ No newline at end of file
import React from 'react'
class Promptbox extends React.Component{
componentDidMount(){
this.addContent()
}
addContent = ()=>{
const ctx = this.canvas.getContext('2d')
const width =this.props.width
ctx.strokeStyle = '#fff'
ctx.shadowOffsetX = -2
ctx.shadowOffsetY = 2
ctx.shadowBlur = 2
ctx.shadowColor = 'rgba(0,0,0,.3)'
ctx.beginPath()
ctx.moveTo(0,20)
ctx.lineTo(8,16)
ctx.lineTo(8,1)
ctx.lineTo(width-1,1)
ctx.lineTo(width-1,39)
ctx.lineTo(8,39)
ctx.lineTo(8,23)
ctx.closePath()
ctx.stroke();
ctx.fillStyle = '#D3D7F7'
ctx.textBaseline = 'middle'
ctx.font = '14px sans-serif'
ctx.beginPath()
ctx.fillText(this.props.info, 20, 20);
}
render(){
return (
<div>
<canvas key={this.props.info} height='41' width={this.props.width} ref={el=>this.canvas=el}/>
</div>
)
}
}
export default Promptbox
\ No newline at end of file
import React from 'react'
import CustomMenu from "../CustomMenu/index";
const menus = [
{
title: '大分子平台',
icon: 'home',
key: '/home'
},
{
title: '小分子平台',
icon: 'home',
key: '/home/Docking'
},
// {
// title: '预测工具',
// icon: 'appstore',
// key: '/home/general',
// subs: [
// {key: '/home/general/button', title: '表位预测', icon: '',},
// ]
// },
// {
// title: '计算工具',
// icon: 'calculator',
// key: '/home/navigation',
// subs: [
// {key: '/computationalTools/MultipleSequenceAlignment', title: '多序列比对', icon: ''},
// {key: '/computationalTools/ProteinTools', title: '蛋白质性质计算', icon: ''},
// ]
// },
]
class SiderNav extends React.Component {
render() {
return (
<div style={{height: '100vh',overflowY:'scroll'}}>
<div style={styles.logo}>
{/* 深雅智慧 */}
</div>
<CustomMenu menus={menus}/>
</div>
)
}
}
const styles = {
logo: {
height: '32px',
// background: 'rgba(255, 255, 255, .2)',
margin: '16px'
}
}
export default SiderNav
\ No newline at end of file
import React from 'react'
import {Card} from 'antd'
import Typing from '../../utils/typing'
class TypingCard extends React.Component {
static defaultProps = {
title: '何时使用',
source:'',
height:136
}
componentDidMount(){
const typing = new Typing({
source:this.source,
output:this.output,
delay:30
})
typing.start()
}
render() {
return (
<Card hoverable bordered={false} className='card-item' title={this.props.title} style={{minHeight:this.props.height}} id={this.props.id}>
<div style={{display:'none'}} ref={el => this.source = el} dangerouslySetInnerHTML={{__html:this.props.source}}/>
<div ref={el => this.output = el}/>
</Card>
)
}
}
export default TypingCard
\ No newline at end of file
/* http://meyerweb.com/eric/tools/css/reset/
v2.0 | 20110126
License: none (public domain)
*/
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
display: block;
}
body {
line-height: 1;
}
ol, ul {
list-style: none;
}
blockquote, q {
quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
content: '';
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
\ No newline at end of file
import '@babel/polyfill'
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import registerServiceWorker from './registerServiceWorker';
import { HashRouter } from 'react-router-dom'
import { Provider } from 'mobx-react'
import { LocaleProvider } from 'antd'
import zh_CN from 'antd/lib/locale-provider/zh_CN'
import store from './store'
//打包时,用的HashRouter并加上了basename,因为放在服务器的二级目录下
ReactDOM.render(
<HashRouter>
<LocaleProvider locale={zh_CN}>
<Provider {...store}>
<App />
</Provider>
</LocaleProvider>
</HashRouter>,
document.getElementById('root'));
registerServiceWorker();
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 841.9 595.3">
<g fill="#61DAFB">
<path d="M666.3 296.5c0-32.5-40.7-63.3-103.1-82.4 14.4-63.6 8-114.2-20.2-130.4-6.5-3.8-14.1-5.6-22.4-5.6v22.3c4.6 0 8.3.9 11.4 2.6 13.6 7.8 19.5 37.5 14.9 75.7-1.1 9.4-2.9 19.3-5.1 29.4-19.6-4.8-41-8.5-63.5-10.9-13.5-18.5-27.5-35.3-41.6-50 32.6-30.3 63.2-46.9 84-46.9V78c-27.5 0-63.5 19.6-99.9 53.6-36.4-33.8-72.4-53.2-99.9-53.2v22.3c20.7 0 51.4 16.5 84 46.6-14 14.7-28 31.4-41.3 49.9-22.6 2.4-44 6.1-63.6 11-2.3-10-4-19.7-5.2-29-4.7-38.2 1.1-67.9 14.6-75.8 3-1.8 6.9-2.6 11.5-2.6V78.5c-8.4 0-16 1.8-22.6 5.6-28.1 16.2-34.4 66.7-19.9 130.1-62.2 19.2-102.7 49.9-102.7 82.3 0 32.5 40.7 63.3 103.1 82.4-14.4 63.6-8 114.2 20.2 130.4 6.5 3.8 14.1 5.6 22.5 5.6 27.5 0 63.5-19.6 99.9-53.6 36.4 33.8 72.4 53.2 99.9 53.2 8.4 0 16-1.8 22.6-5.6 28.1-16.2 34.4-66.7 19.9-130.1 62-19.1 102.5-49.9 102.5-82.3zm-130.2-66.7c-3.7 12.9-8.3 26.2-13.5 39.5-4.1-8-8.4-16-13.1-24-4.6-8-9.5-15.8-14.4-23.4 14.2 2.1 27.9 4.7 41 7.9zm-45.8 106.5c-7.8 13.5-15.8 26.3-24.1 38.2-14.9 1.3-30 2-45.2 2-15.1 0-30.2-.7-45-1.9-8.3-11.9-16.4-24.6-24.2-38-7.6-13.1-14.5-26.4-20.8-39.8 6.2-13.4 13.2-26.8 20.7-39.9 7.8-13.5 15.8-26.3 24.1-38.2 14.9-1.3 30-2 45.2-2 15.1 0 30.2.7 45 1.9 8.3 11.9 16.4 24.6 24.2 38 7.6 13.1 14.5 26.4 20.8 39.8-6.3 13.4-13.2 26.8-20.7 39.9zm32.3-13c5.4 13.4 10 26.8 13.8 39.8-13.1 3.2-26.9 5.9-41.2 8 4.9-7.7 9.8-15.6 14.4-23.7 4.6-8 8.9-16.1 13-24.1zM421.2 430c-9.3-9.6-18.6-20.3-27.8-32 9 .4 18.2.7 27.5.7 9.4 0 18.7-.2 27.8-.7-9 11.7-18.3 22.4-27.5 32zm-74.4-58.9c-14.2-2.1-27.9-4.7-41-7.9 3.7-12.9 8.3-26.2 13.5-39.5 4.1 8 8.4 16 13.1 24 4.7 8 9.5 15.8 14.4 23.4zM420.7 163c9.3 9.6 18.6 20.3 27.8 32-9-.4-18.2-.7-27.5-.7-9.4 0-18.7.2-27.8.7 9-11.7 18.3-22.4 27.5-32zm-74 58.9c-4.9 7.7-9.8 15.6-14.4 23.7-4.6 8-8.9 16-13 24-5.4-13.4-10-26.8-13.8-39.8 13.1-3.1 26.9-5.8 41.2-7.9zm-90.5 125.2c-35.4-15.1-58.3-34.9-58.3-50.6 0-15.7 22.9-35.6 58.3-50.6 8.6-3.7 18-7 27.7-10.1 5.7 19.6 13.2 40 22.5 60.9-9.2 20.8-16.6 41.1-22.2 60.6-9.9-3.1-19.3-6.5-28-10.2zM310 490c-13.6-7.8-19.5-37.5-14.9-75.7 1.1-9.4 2.9-19.3 5.1-29.4 19.6 4.8 41 8.5 63.5 10.9 13.5 18.5 27.5 35.3 41.6 50-32.6 30.3-63.2 46.9-84 46.9-4.5-.1-8.3-1-11.3-2.7zm237.2-76.2c4.7 38.2-1.1 67.9-14.6 75.8-3 1.8-6.9 2.6-11.5 2.6-20.7 0-51.4-16.5-84-46.6 14-14.7 28-31.4 41.3-49.9 22.6-2.4 44-6.1 63.6-11 2.3 10.1 4.1 19.8 5.2 29.1zm38.5-66.7c-8.6 3.7-18 7-27.7 10.1-5.7-19.6-13.2-40-22.5-60.9 9.2-20.8 16.6-41.1 22.2-60.6 9.9 3.1 19.3 6.5 28.1 10.2 35.4 15.1 58.3 34.9 58.3 50.6-.1 15.7-23 35.6-58.4 50.6zM320.8 78.4z"/>
<circle cx="420.9" cy="296.5" r="45.7"/>
<path d="M520.5 78.1z"/>
</g>
</svg>
// In production, we register a service worker to serve assets from local cache.
// This lets the app load faster on subsequent visits in production, and gives
// it offline capabilities. However, it also means that developers (and users)
// will only see deployed updates on the "N+1" visit to a page, since previously
// cached resources are updated in the background.
// To learn more about the benefits of this model, read https://goo.gl/KwvDNy.
// This link also includes instructions on opting out of this behavior.
const isLocalhost = Boolean(
window.location.hostname === 'localhost' ||
// [::1] is the IPv6 localhost address.
window.location.hostname === '[::1]' ||
// 127.0.0.1/8 is considered localhost for IPv4.
window.location.hostname.match(
/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
)
);
export default function register() {
if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
// The URL constructor is available in all browsers that support SW.
const publicUrl = new URL(process.env.PUBLIC_URL, window.location);
if (publicUrl.origin !== window.location.origin) {
// Our service worker won't work if PUBLIC_URL is on a different origin
// from what our page is served on. This might happen if a CDN is used to
// serve assets; see https://github.com/facebookincubator/create-react-app/issues/2374
return;
}
window.addEventListener('load', () => {
const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
if (isLocalhost) {
// This is running on localhost. Lets check if a service worker still exists or not.
checkValidServiceWorker(swUrl);
// Add some additional logging to localhost, pointing developers to the
// service worker/PWA documentation.
navigator.serviceWorker.ready.then(() => {
console.log(
'This web app is being served cache-first by a service ' +
'worker. To learn more, visit https://goo.gl/SC7cgQ'
);
});
} else {
// Is not local host. Just register service worker
registerValidSW(swUrl);
}
});
}
}
function registerValidSW(swUrl) {
navigator.serviceWorker
.register(swUrl)
.then(registration => {
registration.onupdatefound = () => {
const installingWorker = registration.installing;
installingWorker.onstatechange = () => {
if (installingWorker.state === 'installed') {
if (navigator.serviceWorker.controller) {
// At this point, the old content will have been purged and
// the fresh content will have been added to the cache.
// It's the perfect time to display a "New content is
// available; please refresh." message in your web app.
console.log('New content is available; please refresh.');
} else {
// At this point, everything has been precached.
// It's the perfect time to display a
// "Content is cached for offline use." message.
console.log('Content is cached for offline use.');
}
}
};
};
})
.catch(error => {
console.error('Error during service worker registration:', error);
});
}
function checkValidServiceWorker(swUrl) {
// Check if the service worker can be found. If it can't reload the page.
fetch(swUrl)
.then(response => {
// Ensure service worker exists, and that we really are getting a JS file.
if (
response.status === 404 ||
response.headers.get('content-type').indexOf('javascript') === -1
) {
// No service worker found. Probably a different app. Reload the page.
navigator.serviceWorker.ready.then(registration => {
registration.unregister().then(() => {
window.location.reload();
});
});
} else {
// Service worker found. Proceed as normal.
registerValidSW(swUrl);
}
})
.catch(() => {
console.log(
'No internet connection found. App is running in offline mode.'
);
});
}
export function unregister() {
if ('serviceWorker' in navigator) {
navigator.serviceWorker.ready.then(registration => {
registration.unregister();
});
}
}
import React from 'react'
import CustomBreadcrumb from '../../components/CustomBreadcrumb/index'
import TypingCard from '../../components/TypingCard'
export default class About extends React.Component{
render(){
return (
<div>
<CustomBreadcrumb arr={['关于']}/>
<TypingCard source={'这个人很懒,什么也没留下...'} title='关于' />
</div>
)
}
}
\ No newline at end of file
.AntigenDetails-div .title-div{
font-size: 30px;
font-weight: 600;
}
.AntigenDetails-div .div-list .list-one{
display: flex;
align-items: center;
}
.AntigenDetails-div .div-list .left-div {
color: black;
font-weight: 500;
font-size: 18px;
margin-right: 10px;
}
.AntigenDetails-div .div-list .right-div {
width: 80%;
word-wrap: break-word;
}
\ No newline at end of file
import React, { Component } from 'react'
import {Tabs,Table,message,Divider} from 'antd';
import request from '../../../utils/request'
import './index.css'
export default class AntigenDetails extends Component {
state={
id:515,
AntigenData:[]
}
componentDidMount(){
this.getAntigenList()
}
getAntigenList(){
const{id}=this.state
this.setState({loading:true})
request.get('/therapeutic/antigen/'+515)
.then(res => {
console.log(res)
if (res.data.code===0) {
console.log(res.data.data);
this.setState({AntigenData:res.data.data})
this.setState({loading:false}
)
}else{
message.error(res.data.msg);
}
})
.catch(err => {
console.error(err);
})
}
render() {
const {AntigenData}=this.state
const columns = [
{
title: 'Type',
dataIndex: 'epitopeType',
key: 'epitopeType',
// render: text => <a>{text}</a>,
},
{
title: 'Description',
dataIndex: 'epitopeDescription',
key: 'epitopeDescription',
},
{
title: 'Starting Position',
dataIndex: 'startingPosition',
key: 'startingPosition',
},
{
title: 'Ending Position',
key: 'endingPosition',
dataIndex: 'endingPosition',
// render: tags => (
// <span>
// {tags.map(tag => {
// let color = tag.length > 5 ? 'geekblue' : 'green';
// if (tag === 'loser') {
// color = 'volcano';
// }
// return (
// <Tag color={color} key={tag}>
// {tag.toUpperCase()}
// </Tag>
// );
// })}
// </span>
// ),
},
];
const AntigenView=AntigenData.map((item,index)=>{
return(
<div className='div-list' key={index} >
<div className='list-one'>
<div className='left-div itle-div'>
Antigen name:
</div>
<div className='right-div'>
{item.antibodyName}
</div>
</div>
<div className='list-one'>
<div className='left-div itle-div'>
Uniport ID:
</div>
<div className='right-div'>
{item.uniprotId}
</div>
</div>
<div className='list-one'>
<div className='left-div itle-div'>
Source:
</div>
<div className='right-div'>
{item.sequence}
</div>
</div>
<div className='list-one'>
<div className='left-div itle-div'>
Antigen Sequence:
</div>
<div className='right-div'>
{item.sequence}
</div>
</div>
<div className='list-one'>
<div className='left-div itle-div'>
Structures:
</div>
<div className='right-div'>
{item.sequence}
</div>
</div>
<div className='list-one'>
<div className='left-div itle-div'>
Epitopes :
</div>
<div className='right-div'>
{/* <Table columns={columns} dataSource={data} /> */}
</div>
</div>
<div className='list-one'>
<div className='left-div itle-div'>
{/* Epitopes : */}
</div>
<div className='right-div'>
<Table style={{backgroundColor: '#fff'}} columns={columns} pagination={false} dataSource={item.epitopes} />
</div>
</div>
<Divider />
</div>
)
})
return (
<div className='AntigenDetails-div'>{AntigenView}</div>
)
}
}
.AutoimmuneDiseases-div .title-div{
font-weight: 500;
font-size: 28px;
}
.AutoimmuneDiseases-div .bottom-div{
height: 80px;
display: flex;
align-items: center;
}
\ No newline at end of file
import React, { Component } from 'react'
import {Tabs,Table,message,Divider,Pagination} from 'antd';
import './index.css'
import request from '../../../utils/request'
import qs from 'qs'
export default class AutoimmuneDiseases extends Component {
state={
ClinicalIndicationData:[],
total_num:0,
searchData:{
clinicalIndication:qs.parse(this.props.location.search.slice(1)).clinicalIndication,
pageNum:1,
pageSize:10
}
}
componentDidMount(){
this.getClinicalIndicationList()
}
getPdid(e){
let data={
dataid:e,
defaultActiveKey:'Antibody'
}
this.props.history.push({ pathname: '/home/SearchDetails', search: qs.stringify(data)})
}
clinicalIndicationPdid(e){
let data={
dataid:e,
defaultActiveKey:'ClinicalIndication'
}
this.props.history.push({ pathname: '/home/SearchDetails', search: qs.stringify(data)})
}
TargetPdid(e){
let data={
dataid:e,
defaultActiveKey:'Antigen'
}
this.props.history.push({ pathname: '/home/SearchDetails', search: qs.stringify(data)})
}
getClinicalIndicationList(){
const{id}=this.state
this.setState({loading:true})
request.post('/therapeutic/clinical-indication/page-list',this.state.searchData)
.then(res => {
console.log(res)
if (res.data.code===0) {
console.log(res.data.data);
this.setState({total_num:Number(res.data.data.total)})
this.setState({ClinicalIndicationData:res.data.data.records})
this.setState({loading:false}
)
}else{
message.error(res.data.msg);
}
})
.catch(err => {
console.error(err);
})
}
onShowSizeChange=(current, pageSize)=>{
let searchData = this.state.searchData;
searchData.pageNum=current
searchData.pageSize=pageSize
this.setState({
searchData
})
this.getClinicalIndicationList()
}
onChange=(current, pageSize)=>{
let searchData = this.state.searchData;
searchData.pageNum=current
searchData.pageSize=pageSize
this.setState({
searchData
})
this.getClinicalIndicationList()
}
render() {
const{ClinicalIndicationData,total_num}=this.state
const columns = [
{
title: 'clinicalIndication',
dataIndex: 'clinicalIndication',
key: 'clinicalIndication',
render: text => <a>{text}</a>,
},
{
title: 'Antibody',
dataIndex: 'antibodyName',
key: 'antibodyName',
render: (text, record )=> <a onClick={()=>this.getPdid(record.therapeuticId)} >{text}</a>,
},
{
title: 'Antigen',
dataIndex: 'target',
key: 'target',
render: (text, record )=><a onClick={()=>this.TargetPdid(record.therapeuticId)}>{text}</a>,
},
{
title: 'Status',
dataIndex: 'developmentStatus',
key: 'developmentStatus',
},
{
title: 'Company',
key: 'company',
dataIndex: 'company',
},
];
return (
<div className='AutoimmuneDiseases-div'>
{/* <div className='title-div'>
Clinical indication: Autoimmune diseases
</div> */}
<div className='center-div'>
<Table rowKey='id' style={{backgroundColor: '#fff'}} columns={columns} pagination={false} dataSource={ClinicalIndicationData} />
</div>
<div className='bottom-div'>
<Pagination
showSizeChanger
onShowSizeChange={this.onShowSizeChange}
onChange={this.onChange}
total={total_num}
/>
</div>
</div>
)
}
}
import "./cutting.less"
import * as htmlToImage from 'html-to-image';
import { Component, useState, createRef } from "react"
import { Button } from "antd"
class Cutting extends Component {
constructor(props: any) {
super(props)
this.state = ({
canvasNode: createRef(),// canvas DOM节点
buttonGroupNode: createRef(),//裁剪框下的按钮组 DOM节点
originImg: null,//源图
startCoordinate: [0, 0], // 开始坐标
leftTopPoint: [0, 0],//左上角起始点坐标
dragging: false, //裁剪中
dragComplate: false,//裁剪框绘制完毕
trimPositionMap: [0, 0], // 裁剪框坐标信息
curPoisition: null,// 当前裁剪框坐标信息
borderPixelPoisition: null //判断鼠标是否停留在裁剪框上4个点
})
}
componentDidMount() {
let { canvasNode } = this.state
canvasNode.current.width = window.innerWidth
canvasNode.current.height = window.innerHeight
}
getCanvas() {
let { canvasNode } = this.state
var node = document.getElementsByTagName("html")[0]
htmlToImage.toPng(node).then(dataUrl => {
canvasNode.current.style.zIndex = 999
const image = new Image();
image.src = dataUrl
this.setState({
originImg: image
})
})
}
handleMouseDownEvent = (e: any) => {
let { buttonGroupNode, borderPixelPoisition, dragComplate, curPoisition, leftTopPoint } = this.state
if (!borderPixelPoisition && dragComplate) {
return
}
this.setState({
dragComplate: false
})
this.setDraging(true)
buttonGroupNode.current.style.display = "none"
const { offsetX, offsetY } = e.nativeEvent;
if (!borderPixelPoisition) {
this.setState({
startCoordinate: [offsetX, offsetY]
})
} else {
let ltX = leftTopPoint[0], ltY = leftTopPoint[1], w = Math.abs(curPoisition.w), h = Math.abs(curPoisition.h)
switch (borderPixelPoisition) {
case 'lefttop':
this.setState({
startCoordinate: [ltX + w, ltY + h]
})
break;
case "leftdown":
this.setState({
startCoordinate: [ltX + w, ltY]
})
break;
case "righttop":
this.setState({
startCoordinate: [ltX, ltY + h]
})
break;
case 'rightdown':
this.setState({
startCoordinate: leftTopPoint
})
break;
default:
break;
}
}
}
handleMouseMoveEvent = (e: any) => {
let { dragging, canvasNode, startCoordinate, dragComplate, curPoisition, borderPixelPoisition, leftTopPoint } = this.state
/** 是否绘制完成,判断鼠标有没有经过绘制的点上 */
if (dragComplate) {
const { offsetX, offsetY } = e.nativeEvent;
let w = Math.abs(curPoisition.w), h = Math.abs(curPoisition.h), startX = leftTopPoint[0], startY = leftTopPoint[1]
if (offsetX - startX < 2.5 && offsetX - startX > -2.5 && offsetY - startY < 2.5 && offsetY - startY > -2.5) {
//左上角
canvasNode.current.style.cursor = "nw-resize"
this.setState({
borderPixelPoisition: "lefttop"
})
} else if (offsetX - w - startX < 2.5 && offsetX - w - startX > -2.5 && offsetY - startY < 2.5 && offsetY - startY > -2.5) {
//右上角
canvasNode.current.style.cursor = "sw-resize"
this.setState({
borderPixelPoisition: "righttop"
})
} else if (offsetX - startX < 2.5 && offsetX - startX > -2.5 && offsetY - startY - h < 2.5 && offsetY - startY - h > -2.5) {
//左下角
canvasNode.current.style.cursor = "sw-resize"
this.setState({
borderPixelPoisition: "leftdown"
})
} else if (offsetX - w - startX < 2.5 && offsetX - w - startX > -2.5 && offsetY - startY - h < 2.5 && offsetY - startY - h > -2.5) {
//右下角
canvasNode.current.style.cursor = "nw-resize"
this.setState({
borderPixelPoisition: "rightdown"
})
} else {
canvasNode.current.style.cursor = "default"
this.setState({
borderPixelPoisition: null
})
}
}
/**不在裁剪中 */
if (!dragging) {
return
}
const ctx = canvasNode.current.getContext('2d');
// 每一帧都需要清除画布(取最后一帧绘图状态, 否则状态会累加)
ctx.clearRect(0, 0, canvasNode.current.clientWidth, canvasNode.current.clientHeight);
let tempWidth = 0, tempHeight = 0
const { offsetX, offsetY } = e.nativeEvent;
if (borderPixelPoisition && curPoisition) {
this.setState({
dragComplate: false
})
// 获取不同裁剪点下的高宽
let { w, h } = this.getPixelTempWH(offsetX, offsetY)
console.log(w, h)
tempWidth = w
tempHeight = h
} else {
// 计算临时裁剪框的宽高
tempWidth = offsetX - startCoordinate[0];
tempHeight = offsetY - startCoordinate[1];
}
// console.log(startCoordinate[0], startCoordinate[1])
// 调用绘制裁剪框的方法
this.drawTrim(startCoordinate[0], startCoordinate[1], tempWidth, tempHeight);
}
handleMouseRemoveEvent = (e: any) => {
let { curPoisition, buttonGroupNode, borderPixelPoisition, dragComplate } = this.state
//禁止已经绘画完截图之后,鼠标点击canvas又重新触发以下事件
if (dragComplate) {
return
}
// 结束裁剪
this.setDraging(false)
// 处理裁剪按钮样式
if (curPoisition == null) {
return;
}
if (buttonGroupNode == null) {
return;
}
const { x, y } = e.nativeEvent;
let ltX = x, ltY = y, w = curPoisition.w, h = curPoisition.h
switch (borderPixelPoisition) {
case "lefttop":
break;
case "righttop":
ltX = x - w
break;
case "leftdown":
ltY = y - h
break;
case "rightdown":
ltX = x - w
ltY = y - h
break;
default:
ltX = x - w
ltY = y - h
break;
}
this.setState({
leftTopPoint: [ltX, ltY],
dragComplate: true
})
buttonGroupNode.current.style.display = "block"
buttonGroupNode.current.style.left = `${ltX}px`
buttonGroupNode.current.style.top = `${ltY + curPoisition.h + 10}px`;
}
// 调用绘制裁剪框的方法
drawTrim(x: number, y: number, w: number, h: number, flag?: boolean) {
let { canvasNode, originImg } = this.state
const ctx = canvasNode.current.getContext('2d');
// 绘制蒙层
ctx.save();
ctx.fillStyle = 'rgba(0,0,0,0.4)'; // 蒙层颜色
ctx.fillRect(0, 0, canvasNode.current.clientWidth, canvasNode.current.clientHeight);
// 将蒙层凿开
ctx.globalCompositeOperation = 'source-atop';
// 裁剪选择框
ctx.clearRect(x, y, w, h);
// 绘制8个边框像素点
ctx.globalCompositeOperation = 'source-over';
this.drawBorderPixel(ctx, x, y, w, h);
// 保存当前区域坐标信息
this.setState({
curPoisition: {
w: w,
h: h,
startX: x,
startY: y,
position: [
[x, y],
[x + w, y],
[x, y + h],//左下角
[x + w, y + h]
]
}
});
ctx.restore();
// 再次调用drawImage将图片绘制到蒙层下方
ctx.save();
ctx.globalCompositeOperation = 'destination-over';
ctx.drawImage(originImg, 0, 0, canvasNode.current.clientWidth, canvasNode.current.clientHeight);
ctx.restore();
}
// 绘制边框像素点的方法
drawBorderPixel = (ctx: any, x: number, y: number, w: number, h: number) => {
ctx.fillStyle = '#f5222d';
const size = 5; // 自定义像素点大小
ctx.fillRect(x - size / 2, y - size / 2, size, size);
// ...同理通过ctx.fillRect再画出其余像素点
ctx.fillRect(x + w - size / 2, y - size / 2, size, size);
ctx.fillRect(x - size / 2, y + h - size / 2, size, size);
ctx.fillRect(x + w - size / 2, y + h - size / 2, size, size);
};
//获取不同裁剪点下的宽高
/**
* @param x 鼠标当前的x轴
* @param y 鼠标当前的y轴
*/
getPixelTempWH(x: number, y: number) {
let { borderPixelPoisition, leftTopPoint, startCoordinate } = this.state
let result = { w: 0, h: 0 }
let ltX = leftTopPoint[0], ltY = leftTopPoint[1], startX = startCoordinate[0], startY = startCoordinate[1]
switch (borderPixelPoisition) {
case "lefttop":
result.w = x - startX
result.h = y - startY
break;
case "leftdown":
result.w = x - startX
result.h = y - ltY
break;
case "righttop":
result.w = x - ltX
result.h = y - startY
break;
case "rightdown":
result.w = x - ltX
result.h = y - ltY
break;
default:
break;
}
return result
}
//清除画布
clearCanvas() {
let { canvasNode, buttonGroupNode } = this.state
const ctx = canvasNode.current.getContext('2d');
// 每一帧都需要清除画布(取最后一帧绘图状态, 否则状态会累加)
ctx.clearRect(0, 0, canvasNode.current.clientWidth, canvasNode.current.clientHeight);
canvasNode.current.style.zIndex = -1
buttonGroupNode.current.style.display = "none"
this.setState({
dragComplate: false
})
}
//获取裁剪图片输出
getImageData() {
let { canvasNode, curPoisition } = this.state
const trimCanvasNode = document.createElement('canvas')
trimCanvasNode.width = curPoisition.w;
trimCanvasNode.height = curPoisition.h;
const trimCtx = trimCanvasNode.getContext('2d');
trimCtx.clearRect(0, 0, trimCanvasNode.width, trimCanvasNode.height);
let ctx = canvasNode.current.getContext('2d')
let data = ctx.getImageData(curPoisition.startX, curPoisition.startY, curPoisition.w, curPoisition.h)
trimCtx.putImageData(data, 0, 0);
const trimData = trimCanvasNode.toDataURL();
console.log(trimData)
}
setDraging(flag: boolean) {
this.setState({
dragging: flag
})
}
render() {
let { canvasNode, buttonGroupNode } = this.state
return (
<div>
<Button onClick={() => this.getCanvas()}>裁剪</Button>
<canvas
width="100%" height="100%"
id="canvas"
ref={canvasNode}
onMouseDown={this.handleMouseDownEvent}
onMouseMove={this.handleMouseMoveEvent}
onMouseUp={this.handleMouseRemoveEvent}>
</canvas>
<div ref={buttonGroupNode} className="btns">
<Button onClick={() => this.clearCanvas()}>取消</Button>
<Button type="primary" onClick={() => this.getImageData()}>确定</Button>
</div>
</div>
)
}
}
export default Cutting
\ No newline at end of file
#canvas {
position: fixed;
top: 0;
left: 0;
z-index: -1;
}
.btns {
position: fixed;
z-index: 1000;
display: none;
}
\ No newline at end of file
.Docking-div{
/* display: flex; */
padding-top: 100px;
background-color: #fff;
min-height: 100vh;
/* height: 100vh; */
display: flex;
justify-content: center;
}
.Docking-div .left-div{
display: flex;
align-items: center;
justify-content: center;
border-left: 1px solid #f0f0f0;
border-right: 1px solid #f0f0f0;
border-bottom: 1px solid #f0f0f0;
box-sizing: border-box;
}
.Docking-div .left-div Button{
height: 50px;
border: 0px;
border-radius:0px;
width: 100%;
font-family: "Comic Sans MS"
}
.Docking-div .right-div{
padding: 20px;
/* display: flex; */
align-items: center;
justify-content: center;
padding-left: 100px;
padding-right: 100px;
box-sizing: border-box;
}
.Docking-div .right-div .right-div-one{
display: flex;
align-items: center;
width: 100%;
/* justify-content: space-between; */
}
.Docking-div .right-div .right-div-one .title-div{
width: 20%;
}
.sequencesearch-div .top-div {
margin-bottom: 100px;
}
.sequencesearch-div .sequence-center{
display: flex;
align-items: center;
}
.sequencesearch-div .TextArea-div{
width: 50%;
}
.bottom-butn button{
height: 50px;
width: 200px;
}
.bottom-butn{
display: flex;
align-items: center;
justify-content: center;
height: 50px;
}
.Jsme-div{
display: flex;
align-items: center;
justify-content: center
}
.Docking-div .top-div{
display: flex;
align-items: center;
justify-content: center;
height: 150px;
}
.Docking-div .Docking-center{
width: 1000px;
background-color: #f0f0f0;
padding-bottom: 100px;
}
.Docking-div .title-text{
font-size: 28px;
font-weight: 600;
}
.Docking-div .pharmacophore-div{
align-items: center;
justify-content: center;
}
.Docking-div .pharmacophore-div .pharmacophore-top{
display: flex;
align-items: center;
padding: 5px;
}
.Docking-div .displaydiv{
display: none;
}
.Docking-div .taskmanager-div{
width: 100%;
background-color: #fff;
padding: 10px;
}
.generalsearch-div{
}
.ant-advanced-search-form {
}
.ant-advanced-search-form .ant-form-item {
display: flex;
}
.ant-advanced-search-form .ant-form-item-control-wrapper {
flex: 1;
}
.Docking-center .logo-topdiv{
display: flex;
align-items: center;
justify-content: center;
height: 150px;
background-color: #fff;
}
.Docking-center .logo-topdiv img{
height: 150px;
}
.Docking-center .pharmacophore-title{
width: 50%;
}
.Docking-center .pharmacophore-title2{
width: 25%;
}
.Computational-div{
display: flex;
align-items: center;
justify-content: center;
}
.Computational-div div{
width: 587px;
padding-left: 100px;
font-family: "Comic Sans MS"
}
.DockingCenter{
height: 30px;
}
.Speed-div{
height: 30px;
}
import React, { Component } from "react";
import {
Tabs,
Button,
Radio,
Upload,
Input,
Select,
Form,
Icon,
Card,
Menu,
Table,
Tag,
message,
Pagination,
Divider,
Modal,
Col,
InputNumber,
} from "antd";
import qs from "qs";
import request from "../../../utils/request";
import { Jsme } from "jsme-react";
import "./index.css";
const { Option } = Select;
const { TextArea } = Input;
export default class StructureSearch extends Component {
state = {
list: [
{
name: "Welcome",
state: true,
},
{
name: "Docking",
state: false,
},
{
name: "Pharmacophore",
state: false,
},
{
name: "Automated Molecule Design",
state: false,
},
{
name: "Retrosynthesis",
state: false,
},
{
name: "Task Manager",
state: false,
},
],
stateName: "Welcome",
targetsDetail: {
name: "",
},
docking: {
pro: "",
lig: "",
ligand_file: "",
receptor_file: "",
ligand_smi: "",
receptor_pdb: "",
grid_center: "notinputcenter",
gridx: null,
gridy: null,
gridz: null,
handlespeed: "",
},
pharmacophoreData: {
lig: "",
ligand_file: "",
ligand_smi: "",
select_nums: null,
},
ListData: [],
taskManagerData: {
user_id: "1",
task_source: "",
task_status: "",
page: 1,
page_size: 10,
},
retrosynthesisData: {
lig: "",
ligand_file: "",
ligand_smi: "",
},
amd: {
pro: "",
lig: "",
ligand_file: "",
receptor_file: "",
ligand_smi: "",
receptor_pdb: "",
num_gen: null,
num_per_gen: null,
seed_per_gen: null,
growType: "",
docking_center: "notinputcenter",
x: null,
y: null,
z: null,
mode: null,
dl_per_gen:null,
dl_score_cutoff: "",
MW: null,
logP_lower: null,
logP_upper: "",
handlespeed: "",
},
fileList: [],
uploading: false,
visible: false,
total_num: 0,
ListData2: [],
Smiles: "",
};
getRetrosynthesis = () => {
request
.post("/yszhaizynth/finder", qs.stringify(this.state.retrosynthesisData))
.then((res) => {
console.log(res);
if (res.data.code === 200) {
message.success(res.data.message);
} else {
message.error(res.data.message);
}
})
.catch((err) => {
console.error(err);
});
};
getTaskManager = () => {
request
.post("/task/page", this.state.taskManagerData)
.then((res) => {
console.log(res);
if (res.data.code === 200) {
console.log(res.data.data);
this.setState({
ListData: res.data.data,
});
this.setState({
total_num: res.data.total_num,
});
} else {
message.error(res.data.message);
}
})
.catch((err) => {
console.error(err);
});
};
getPharmacophore = () => {
let formData = new FormData();
let pharmacophoreData = this.state.pharmacophoreData;
// formData.append("ligand_file", pharmacophoreData.ligand_file);
for (const key in pharmacophoreData) {
formData.append(key, pharmacophoreData[key]);
}
console.log(formData);
request
.post("/pharmacophore/pharmacophore_run", formData)
.then((res) => {
console.log(res);
if (res.data.code === 200) {
message.success(res.data.message);
} else {
message.error(res.data.message);
}
})
.catch((err) => {
console.error(err);
});
};
getDocking = () => {
let formData = new FormData();
let docking = this.state.docking;
for (const key in docking) {
formData.append(key, docking[key]);
}
console.log(formData);
request
.post("/docking/docking_run", formData)
.then((res) => {
console.log(res);
if (res.data.code === 200) {
message.success(res.data.message);
} else {
message.error(res.data.message);
}
})
.catch((err) => {
console.error(err);
});
};
getamd = () => {
let formData = new FormData();
let amd = this.state.amd;
for (const key in amd) {
formData.append(key, amd[key]);
}
console.log(formData);
request
.post("/amd/amd_run", formData)
.then((res) => {
console.log(res);
if (res.data.code === 200) {
message.success(res.data.message);
} else {
message.error(res.data.message);
}
})
.catch((err) => {
console.error(err);
});
};
onChangeSpeed = (e) => {
let { value } = e.target;
let docking = this.state.docking;
docking.handlespeed = value;
this.setState({
docking,
});
};
grid_x = (e) => {
// const { value } = e.target;
let docking = this.state.docking;
docking.gridx = e;
this.setState({
docking,
});
};
grid_y = (e) => {
// const { value } = e.target;
let docking = this.state.docking;
docking.gridy = e;
this.setState({
docking,
});
};
grid_z = (e) => {
// const { value } = e.target;
let docking = this.state.docking;
docking.gridz = e;
this.setState({
docking,
});
};
amdSpeed = (e) => {
const { value } = e.target;
let amd = this.state.amd;
amd.handlespeed = value;
this.setState({
amd,
});
};
amd_x = (e) => {
// const { value } = e.target;
let amd = this.state.amd;
amd.x = e;
this.setState({
amd,
});
};
amd_y = (e) => {
// const { value } = e.target;
let amd = this.state.amd;
amd.y = e;
this.setState({
amd,
});
};
amd_z = (e) => {
// const { value } = e.target;
let amd = this.state.amd;
amd.z = e;
this.setState({
amd,
});
};
num_gen = (e) => {
console.log(e);
let amd = this.state.amd;
amd.num_gen = e;
this.setState({
amd,
});
};
num_per_gen = (e) => {
let amd = this.state.amd;
amd.num_per_gen = e;
this.setState({
amd,
});
};
seed_per_gen = (e) => {
let amd = this.state.amd;
amd.seed_per_gen = e;
this.setState({
amd,
});
};
growType = (e) => {
let amd = this.state.amd;
amd.growType = e;
this.setState({
amd,
});
};
amdmode = (e) => {
let amd = this.state.amd;
amd.mode = e;
this.setState({
amd,
});
};
onChangeAmd = (e) => {
const { value } = e.target;
let amd = this.state.amd;
amd.pro = value;
this.setState({
amd,
});
};
amd_dl_per_gen = (e) => {
let amd = this.state.amd;
amd.dl_per_gen = e;
this.setState({
amd,
});
};
amdMW = (e) => {
let amd = this.state.amd;
amd.MW = e;
this.setState({
amd,
});
};
amd_logP_lower = (e) => {
let amd = this.state.amd;
amd.logP_lower = e;
this.setState({
amd,
});
};
onChangeAmdCenter = (e) => {
let { value } = e.target;
console.log(value);
let amd = this.state.amd;
amd.docking_center = value;
if (amd.docking_center == "notinputcenter") {
amd.x = "";
amd.y = "";
amd.z = "";
}
this.setState({
amd,
});
};
onChangeDockingCenter = (e) => {
let { value } = e.target;
console.log(value);
let docking = this.state.docking;
docking.grid_center = value;
if (docking.grid_center == "notinputcenter") {
docking.gridx = "";
docking.gridy = "";
docking.gridz = "";
}
this.setState({
docking,
});
};
SpecifyPDB = (e) => {
let { value } = e.target;
console.log(value);
let docking = this.state.docking;
docking.receptor_pdb = value;
this.setState({
docking,
});
};
SpecifyPDB2 = (e) => {
let { value } = e.target;
console.log(value);
let amd = this.state.amd;
amd.receptor_pdb = value;
this.setState({
amd,
});
};
// pharmacophore
select_nums = (e) => {
// const { value } = e.target;
let pharmacophoreData = this.state.pharmacophoreData;
pharmacophoreData.select_nums = e;
this.setState({
pharmacophoreData,
});
};
Receptorpreparation = (e) => {
let { value } = e.target;
console.log(value);
let docking = this.state.docking;
docking.pro = value;
this.setState({
docking,
});
};
goList = () => {
if (this.state.stateName == "Docking") {
this.selectionDocking();
return;
}
if (this.state.stateName == "Pharmacophore") {
this.selectionPharmacophore();
return;
}
if (this.state.stateName == "Retrosynthesis") {
this.selectionRetrosynthesis();
return;
}
if (this.state.stateName == "Automated Molecule Design") {
this.selectionAmd();
return;
}
};
callback = (e) => {
console.log(e);
};
getListOne = (e, name) => {
let newList = this.state.list;
this.setState({
stateName: name,
});
newList.forEach((item, index) => {
item.state = false;
if (e === index) {
item.state = true;
}
});
this.setState({
list: newList,
});
if (name == "Task Manager") {
this.getTaskManager();
return;
}
};
onChange = (e) => {
let { value } = e.target;
console.log(value);
// let docking = this.state.docking;
// docking.lig = value;
// this.setState({
// docking,
// });
let docking = this.state.docking;
docking.lig = value;
this.setState({
docking: docking,
});
let pharmacophoreData = this.state.pharmacophoreData;
pharmacophoreData.lig = value;
this.setState({
pharmacophoreData: pharmacophoreData,
});
let retrosynthesisData = this.state.retrosynthesisData;
retrosynthesisData.lig = value;
this.setState({
retrosynthesisData: retrosynthesisData,
});
let amd = this.state.amd;
amd.lig = value;
this.setState({
amd: amd,
});
console.log(this.state);
};
logSmiles = (e) => {
let Smiles = e;
this.setState({
Smiles,
});
let docking = this.state.docking;
docking.ligand_smi = Smiles;
this.setState({
docking: docking,
});
let pharmacophoreData = this.state.pharmacophoreData;
pharmacophoreData.ligand_smi = Smiles;
this.setState({
pharmacophoreData: pharmacophoreData,
});
let retrosynthesisData = this.state.retrosynthesisData;
retrosynthesisData.ligand_smi = Smiles;
this.setState({
retrosynthesisData: retrosynthesisData,
});
let amd = this.state.amd;
amd.ligand_smi = Smiles;
this.setState({
amd: amd,
});
};
handleChange = (value) => {
let taskManagerData = this.state.taskManagerData;
taskManagerData.task_source = value;
this.setState({
taskManagerData,
});
};
handleChange2 = (value) => {
let taskManagerData = this.state.taskManagerData;
taskManagerData.task_status = value;
this.setState({
taskManagerData,
});
};
onShowSizeChange = (current, pageSize) => {
let taskManagerData = this.state.taskManagerData;
taskManagerData.page = current;
taskManagerData.page_size = pageSize;
this.setState({
taskManagerData,
});
this.getTaskManager();
};
onChange2 = (current, pageSize) => {
let taskManagerData = this.state.taskManagerData;
taskManagerData.page = current;
taskManagerData.page_size = pageSize;
this.setState({
taskManagerData,
});
this.getTaskManager();
};
getResult = (e) => {
this.setState({ visible: true });
console.log(e);
let resultJson = eval("(" + e.resultJson + ")");
console.log(resultJson);
var jobId = resultJson.jobId;
let list = resultJson.list;
this.setState({
ListData2: list,
});
for (var key in list) {
console.log(jobId);
var imageHtml =
'<img style="width:700px;float: left;" src="http://52.83.230.236:8010/static/showreaction/' +
jobId +
"/" +
list[key]["imageFile"] +
'" id="' +
list[key]["imageFile"].replace(".png", "") +
'">';
// console.log(imageHtml);
}
};
ligandSmiles = (e) => {
const { value } = e.target;
this.setState({
Smiles: value,
});
let docking = this.state.docking;
docking.ligand_smi = value;
this.setState({
docking: docking,
});
let pharmacophoreData = this.state.pharmacophoreData;
pharmacophoreData.ligand_smi = value;
this.setState({
pharmacophoreData: pharmacophoreData,
});
let retrosynthesisData = this.state.retrosynthesisData;
retrosynthesisData.ligand_smi = value;
this.setState({
retrosynthesisData: retrosynthesisData,
});
let amd = this.state.amd;
amd.ligand_smi = value;
this.setState({
amd: amd,
});
};
selectionDocking = () => {
if (this.state.docking.pro == "") {
message.warning("please specify how to upload receptor");
return;
}
if (
this.state.docking.pro == "file" &&
this.state.docking.receptor_file == ""
) {
message.warning("please choose receptor file");
return;
}
if (
this.state.docking.pro == "pdbid" &&
this.state.docking.receptor_pdb == ""
) {
message.warning("please enter PDB ID of the receptor");
return;
}
if (this.state.docking.lig == "") {
message.warning("please specify how to upload receptor");
return;
}
if (
this.state.docking.lig == "file" &&
this.state.docking.ligand_file == ""
) {
message.warning("please choose ligand file");
return;
}
if (
this.state.docking.lig == "smi" &&
this.state.docking.ligand_smi == ""
) {
message.warning("please enter SMILES of the ligand");
return;
}
if (this.state.docking.handlespeed == "") {
message.warning("please choose docking speed");
return;
}
if (
this.state.docking.grid_center == "inputcenter" &&
(this.state.docking.gridx == null ||
this.state.docking.gridy == null ||
this.state.docking.gridz == null)
) {
console.log("inputcenter");
console.log(this.state.docking);
return message.warning("please input grid center");
// if (
// this.state.docking.gridx == "" ||
// this.state.docking.gridy == "" ||
// this.state.docking.gridz == ""
// ) {
// }
} else {
this.getDocking();
}
};
selectionAmd = () => {
if (this.state.amd.pro == "") {
message.warning("please specify how to upload receptor");
return;
}
if (this.state.amd.pro == "file" && this.state.amd.receptor_file == "") {
message.warning("please choose receptor file");
return;
}
if (this.state.amd.pro == "pdbid" && this.state.amd.receptor_pdb == "") {
message.warning("please enter PDB ID of the receptor");
return;
}
if (this.state.amd.lig == "") {
message.warning("please specify how to upload receptor");
return;
}
if (this.state.amd.lig == "file" && this.state.amd.ligand_file == "") {
message.warning("please choose ligand file");
return;
}
if (this.state.amd.lig == "smi" && this.state.amd.ligand_smi == "") {
message.warning("please enter SMILES of the ligand");
return;
}
if (this.state.amd.num_gen == null || !(this.state.amd.num_gen % 1 === 0)) {
message.warning(
"num_gen value cannot be a null character and must be an integer greater than 0"
);
return;
}
if (
this.state.amd.num_per_gen == null ||
!(this.state.amd.num_per_gen % 1 === 0)
) {
message.warning(
"num_per_gen value cannot be a null character and must be an integer greater than 0"
);
return;
}
if (
this.state.amd.seed_per_gen == null ||
!(this.state.amd.seed_per_gen % 1 === 0)
) {
message.warning(
"seed_per_gen value cannot be a null character and must be an integer greater than 0"
);
return;
}
if (this.state.amd.growType == "") {
message.warning("please choose growType");
return;
}
if (this.state.amd.handlespeed == "") {
message.warning("please choose docking speed");
return;
}
if (
this.state.amd.docking_center == "inputcenter" &&
(this.state.amd.x == null ||
this.state.amd.y == null ||
this.state.amd.z == null)
) {
message.warning("please input docking center");
return;
// if (
// this.state.amd.gridx == "" ||
// this.state.amd.gridy == "" ||
// this.state.amd.gridz == ""
// ) {
// message.warning("please input grid center");
// return;
// }
// document.getElementById("gridxyz").style.visibility="visible";
// document.getElementById("gridxyz").style.visibility="hidden";
}
if (
this.state.amd.mode== null
||!(this.state.amd.mode % 1 === 0)
) {
message.warning("mode cannot be null and is an integer");
return;
}
if (
this.state.amd.dl_per_gen== null||!(this.state.amd.dl_per_gen % 1 === 0)
) {
message.warning("dl_per_gen cannot be null and is an integer");
return;
}
if (
this.state.amd.MW== null||!(this.state.amd.MW % 1 === 0)
) {
message.warning("MW cannot be null and is an integer");
return;
}
if (
this.state.amd.logP_lower== null
) {
message.warning("please input logP_lower");
return;
}
else {
/* if (this.state.docking.gridx!= "" || this.state.docking.gridy!= "" || this.state.docking.gridz!= "") {
if (this.state.docking.gridx== "" || this.state.docking.gridy== "" || this.state.docking.gridz== ""){
message.warning("please input grid center");
return;
}
}*/
this.getamd();
}
};
selectionPharmacophore = () => {
if (this.state.pharmacophoreData.lig == "") {
message.warning("please specify how to upload receptor");
return;
}
if (
this.state.pharmacophoreData.lig == "file" &&
this.state.pharmacophoreData.ligand_file == ""
) {
message.warning("please choose ligand file");
return;
}
if (
this.state.pharmacophoreData.lig == "smi" &&
this.state.pharmacophoreData.ligand_smi == ""
) {
message.warning("please enter SMILES of the ligand");
return;
}
if (this.state.pharmacophoreData.select_nums == null||!(this.state.pharmacophoreData.select_nums % 1 === 0)) {
console.log(333333);
message.warning(
"The value cannot be a null character and must be an integer greater than 0"
);
return;
}
else {
/* if (this.state.docking.gridx!= "" || this.state.docking.gridy!= "" || this.state.docking.gridz!= "") {
if (this.state.docking.gridx== "" || this.state.docking.gridy== "" || this.state.docking.gridz== ""){
message.warning("please input grid center");
return;
}
}*/
this.getPharmacophore();
}
};
selectionRetrosynthesis = () => {
if (this.state.retrosynthesisData.lig == "") {
message.warning("please specify how to upload receptor");
return;
}
// if (
// this.state.retrosynthesisData.lig == "file" &&
// this.state.retrosynthesisData.ligand_file == ""
// ) {
// message.warning("please choose ligand file");
// return;
// }
if (
this.state.retrosynthesisData.lig == "smi" &&
this.state.retrosynthesisData.ligand_smi == ""
) {
message.warning("please enter SMILES of the ligand");
return;
} else {
/* if (this.state.docking.gridx!= "" || this.state.docking.gridy!= "" || this.state.docking.gridz!= "") {
if (this.state.docking.gridx== "" || this.state.docking.gridy== "" || this.state.docking.gridz== ""){
message.warning("please input grid center");
return;
}
}*/
this.getRetrosynthesis();
}
};
getDownload = (e) => {};
render() {
const props = {
beforeUpload: (file) => {
var fileName = file.name;
var suffixName = fileName.substring(fileName.lastIndexOf("."));
if (suffixName != ".smi") {
return message.error("You can only upload smi file!");
}
let docking = this.state.docking;
docking.ligand_file = file;
console.log(docking);
this.setState({
docking: docking,
});
let pharmacophoreData = this.state.pharmacophoreData;
pharmacophoreData.ligand_file = file;
console.log(pharmacophoreData);
this.setState({
pharmacophoreData: pharmacophoreData,
});
let retrosynthesisData = this.state.retrosynthesisData;
retrosynthesisData.ligand_file = file;
console.log(retrosynthesisData);
this.setState({
retrosynthesisData: retrosynthesisData,
});
let amd = this.state.amd;
amd.ligand_file = file;
console.log(amd);
this.setState({
amd: amd,
});
return false;
},
fileList,
};
const props2 = {
beforeUpload: (file) => {
var fileName = file.name;
var suffixName = fileName.substring(fileName.lastIndexOf("."));
if (suffixName != ".pdb") {
return message.error("You can only upload pdb file!");
}
let docking = this.state.docking;
docking.receptor_file = file;
console.log(docking);
this.setState({
docking: docking,
});
return false;
},
fileList,
};
const props3 = {
beforeUpload: (file) => {
var fileName = file.name;
var suffixName = fileName.substring(fileName.lastIndexOf("."));
if (suffixName != ".pdb") {
return message.error("You can only upload pdb file!");
}
let amd = this.state.amd;
amd.receptor_file = file;
console.log(amd);
this.setState({
amd: amd,
});
return false;
},
fileList,
};
const {
list,
total_num,
ListData,
uploading,
fileList,
visible,
ListData2,
} = this.state;
const formItemLayout2 = {
labelCol: {
xs: { span: 24 },
sm: { span: 4 },
},
wrapperCol: {
xs: { span: 24 },
sm: { span: 20 },
},
};
const formItemLayout = {
labelCol: { span: 4 },
wrapperCol: { span: 14 },
};
const formItemLayout3 = {
labelCol: { span: 8 },
wrapperCol: { span: 10 },
};
const radioStyle = {
display: "block",
height: "30px",
lineHeight: "30px",
marginBottom: "20px",
width: "700px",
};
const columns = [
{
title: "Type",
dataIndex: "taskSource",
key: "taskSource",
},
{
title: "Status",
dataIndex: "taskStatus",
key: "taskStatus",
},
{
title: "Start Time",
key: "startTime",
dataIndex: "startTime",
},
{
title: "End Time",
key: "endTime",
dataIndex: "endTime",
},
{
title: "Result",
key: "action",
render: (text, record) => (
<span>
{record.resultFilePath != null && (
<a
rel="noopener noreferrer"
target="_blank"
href={record.resultFilePath}
>
download
</a>
)}
{record.resultFilePath != null && record.resultJson != null && (
<Divider type="vertical" />
)}
{record.resultJson != null && (
<a onClick={() => this.getResult(record)}>result </a>
)}
</span>
),
},
];
const columns2 = [
{
title: "Predited Routes",
dataIndex: "imageFile",
key: "imageFile",
render: (imageFile) => (
<img
alt="example"
style={{ height: "100px", padding: "0px" }}
src={imageFile}
/>
),
},
{
title: "Score",
dataIndex: "score",
key: "score",
},
// {
// title: "smiles",
// dataIndex: "smiles",
// key: "smiles",
// },
];
const expandedRowRender = (e) => {
console.log(e);
const { pre_smiles } = e;
const columns = [
{
title: "Smiles",
dataIndex: "smiles",
key: "smiles",
render: (smiles) => (
<div>
<Jsme
height="100px"
width="100px"
options="depict,useopenchemlib"
smiles={smiles}
/>
</div>
),
},
{
title: "Brand Name",
dataIndex: "brand",
key: "brand",
},
{
title: "Price",
dataIndex: "origPrice",
key: "origPrice",
},
{
title: "Package",
dataIndex: "package",
key: "package",
},
];
return (
<Table columns={columns} dataSource={pre_smiles} pagination={false} />
);
};
return (
<div className="Docking-div">
<Modal
footer={null}
title="The results show"
visible={visible}
wrapClassName="vertical-center-modal"
width={"100%"}
height={"500px"}
onCancel={() => this.setState({ visible: false })}
>
{/* <Table
columns={columns2}
pagination={false}
dataSource={ListData2}
rowKey="id"
/> */}
<Table
bordered
style={{ top: 100 }}
rowKey="item"
dataSource={ListData2}
pagination={false}
columns={columns2}
expandedRowRender={expandedRowRender}
/>
</Modal>
<div className="Docking-center">
<div className="logo-topdiv">
<img
alt="example"
style={{ height: "100%", padding: "0px" }}
src={require("../../../assets/img/logo.png")}
/>
</div>
<div className="top-div">
<Card
hoverable
style={{
width: "100%",
// backgroundColor: "#00FF00",
textAlign: "center",
fontSize: "30px",
fontWeight: 600,
height: "150px",
lineHeight: "100px",
}}
>
<div className="Computational-div">
<div>Computational Platform11</div>
</div>
</Card>
</div>
<div>
<div className="left-div">
{list.map((item, index) => {
return (
<Button
type={item.state ? "primary" : ""}
size="large"
onClick={() => this.getListOne(index, item.name)}
key={index}
>
{item.name}
</Button>
);
})}
</div>
<div
className={
this.state.stateName === "Welcome" ||
this.state.stateName === "Task Manager"
? "displaydiv"
: "right-div"
}
>
{
<div className="generalsearch-div">
<div className="title-text">
{(this.state.stateName === "Automated Molecule Design" &&
"Input Fragment") ||
(this.state.stateName === "Pharmacophore" &&
"Query Molecule") ||
(this.state.stateName === "Retrosynthesis" &&
"New Compound for Synthesis")}
{this.state.stateName != "Automated Molecule Design" &&
"Ligand Preparation" &&
this.state.stateName != "Pharmacophore" &&
"Ligand Preparation" &&
this.state.stateName != "Retrosynthesis" &&
"Ligand Preparation"}
</div>
<Radio.Group onChange={this.onChange}>
<Radio style={radioStyle} value={"file"}>
Upload ligand file from your computer:
<Upload {...props}>
<Button
style={{
marginLeft: "5px",
}}
>
<Icon type="upload" /> 选择文件
</Button>
</Upload>
</Radio>
<Radio style={radioStyle} value={"smi"}>
Ligand SMILES:
<Input
value={this.state.Smiles}
onChange={this.ligandSmiles}
style={{ width: "200px", marginLeft: "5px" }}
/>
</Radio>
</Radio.Group>
{/* <div>enter SMILES or draw the ligand structure below:</div> */}
<div className="Jsme-div">
<Jsme
height="300px"
width="500px"
options="oldlook,star"
onChange={this.logSmiles}
/>
</div>
</div>
}
</div>
<div className="right-div">
{list[0].state && (
<div className="generalsearch-div">
<Card
hoverable
style={{ width: "100%", padding: "0px" }}
cover={
<img
alt="example"
style={{ height: "100%", padding: "0px" }}
src={require("../../../assets/img/u22.gif")}
/>
}
/>
</div>
)}
{list[1].state && (
<div className="generalsearch-div">
<div>
Availble Library for Docking
<Radio.Group
onChange={this.onChange}
value={this.state.value}
>
<Radio value={1}>Drugbank</Radio>
<Radio value={2}>Zinc</Radio>
<Radio value={3}>Enamine</Radio>
<Radio value={4}>Maybridge</Radio>
</Radio.Group>
</div>
<div className="title-text">Receptor preparation</div>
<Radio.Group
value={this.state.docking.pro}
onChange={this.Receptorpreparation}
>
<Radio style={radioStyle} value={"file"}>
Upload receptor file from your computer:
<Upload {...props2}>
<Button
style={{
marginLeft: "5px",
}}
>
<Icon type="upload" /> 选择文件
</Button>
</Upload>
</Radio>
<Radio style={radioStyle} value={"pdbid"}>
Specify PDB ID of receptor:
<Input
style={{ width: "200px", marginLeft: "5px" }}
value={this.state.docking.receptor_pdb}
onChange={this.SpecifyPDB}
/>
</Radio>
</Radio.Group>
<div className="DockingCenter">
Docking Center
<Radio.Group
onChange={this.onChangeDockingCenter}
value={this.state.docking.grid_center}
>
<Radio value={"inputcenter"}>yes</Radio>
<Radio value={"notinputcenter"}>no</Radio>
</Radio.Group>
</div>
{this.state.docking.grid_center == "inputcenter" && (
<Form layout="inline">
{/* <Form.Item label="Form Layout" {...formItemLayout} /> */}
<Form.Item label="grid_x" {...formItemLayout3}>
<InputNumber
style={{width:'150px'}}
value={this.state.docking.gridx}
onChange={this.grid_x}
placeholder="input placeholder"
/>
</Form.Item>
<Form.Item label="grid_y" {...formItemLayout3}>
<InputNumber
style={{width:'150px'}}
placeholder="input placeholder"
onChange={this.grid_y}
value={this.state.docking.gridy}
/>
</Form.Item>
<Form.Item label="grid_z" {...formItemLayout3}>
<InputNumber
style={{width:'150px'}}
placeholder="input placeholder"
onChange={this.grid_z}
value={this.state.docking.gridz}
/>
</Form.Item>
</Form>
)}
<div className="Speed-div">
Speed
<Radio.Group
onChange={this.onChangeSpeed}
value={this.state.docking.handlespeed}
>
<Radio value={"slow"}>accurate</Radio>
<Radio value={"quick"}>quick</Radio>
<Radio value={"highpass"}>high throught</Radio>
</Radio.Group>
</div>
</div>
)}
{list[2].state && (
<div className="pharmacophore-div">
<div className="pharmacophore-top">
<div className="pharmacophore-title">
Pharmacophore Database from PDB Rharmacophore:
</div>
<Radio.Group onChange={this.onChange} value={1}>
<Radio value={1}>PDB</Radio>
</Radio.Group>
</div>
<div className="pharmacophore-top">
<div className="pharmacophore-title2">
Number of Results Retained:
</div>
<div>
<InputNumber
min={0}
onChange={this.select_nums}
value={this.state.pharmacophoreData.select_nums}
style={{ width: "200px" }}
/>
</div>
</div>
</div>
)}
{list[3].state && (
<div className="generalsearch-div">
<Form className="ant-advanced-search-form">
<Col span={12}>
<Form.Item label="num_gen" {...formItemLayout3}>
<InputNumber
style={{width:'150px'}}
min={0}
placeholder="input placeholder"
onChange={this.num_gen}
value={this.state.amd.num_gen}
/>
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label="num_per_gen" {...formItemLayout3}>
<InputNumber
style={{width:'150px'}}
min={0}
onChange={this.num_per_gen}
value={this.state.amd.num_per_gen}
placeholder="input placeholder"
/>
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label="seed_per_gen" {...formItemLayout3}>
<InputNumber
style={{width:'150px'}}
min={0}
onChange={this.seed_per_gen}
value={this.state.amd.seed_per_gen}
placeholder="input placeholder"
/>
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label="grow type" {...formItemLayout3}>
{/* <Input
onChange={this.growType}
value={this.state.amd.growType}
placeholder="input placeholder"
/> */}
<Select onChange={this.growType} style={{width:'150px'}}>
<Option value="grow">grow</Option>
<Option value="mutation">mutation</Option>
<Option value="bioisoteric">bioisoteric</Option>
<Option value="reaction">reaction</Option>
</Select>
</Form.Item>
</Col>
</Form>
<div className="title-text">Docking</div>
<div className="Speed-div">
Speed
<Radio.Group
onChange={this.amdSpeed}
value={this.state.amd.handlespeed}
>
<Radio value={"XP"}>accurate</Radio>
<Radio value={"SP"}>quick</Radio>
<Radio value={"HTVS"}>high throught </Radio>
<Radio value={"vina"}>high throught </Radio>
</Radio.Group>
</div>
<Radio.Group
value={this.state.amd.pro}
onChange={this.onChangeAmd}
>
<Radio style={radioStyle} value={"file"}>
Upload receptor file from your computer:
<Upload {...props3}>
<Button style={{ marginLeft: "5px" }}>
<Icon type="upload" /> 选择文件
</Button>
</Upload>
</Radio>
<Radio style={radioStyle} value={"pdbid"}>
Specify PDB ID of receptor:
<Input
style={{ width: "200px", marginLeft: "5px" }}
value={this.state.amd.receptor_pdb}
onChange={this.SpecifyPDB2}
/>
</Radio>
</Radio.Group>
<div className="DockingCenter">
Docking Center
<Radio.Group
onChange={this.onChangeAmdCenter}
value={this.state.amd.docking_center}
>
<Radio value={"inputcenter"}>yes</Radio>
<Radio value={"notinputcenter"}>no</Radio>
</Radio.Group>
</div>
{this.state.amd.docking_center == "inputcenter" && (
<Form layout="inline">
<Form.Item label="X" {...formItemLayout}>
<InputNumber
style={{width:'150px'}}
placeholder="input placeholder"
value={this.state.amd.x}
onChange={this.amd_x}
/>
</Form.Item>
<Form.Item label="Y" {...formItemLayout}>
<InputNumber
style={{width:'150px'}}
placeholder="input placeholder"
onChange={this.amd_y}
value={this.state.amd.y}
/>
</Form.Item>
<Form.Item label="Z" {...formItemLayout}>
<InputNumber
style={{width:'150px'}}
placeholder="input placeholder"
onChange={this.amd_z}
value={this.state.amd.z}
/>
</Form.Item>
</Form>
)}
<div className="title-text">Deep Learning</div>
<Form
className="generalsearch-div"
style={{ height: "80px" }}
>
{/* <Form.Item label="Form Layout" {...formItemLayout} /> */}
<Col span={12}>
<Form.Item label="mode" {...formItemLayout3}>
<InputNumber
style={{width:'150px'}}
value={this.state.amd.mode}
onChange={this.amdmode}
placeholder="input placeholder"
/>
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label="dl_per_gen" {...formItemLayout3}>
<InputNumber
style={{width:'150px'}}
value={this.state.amd.dl_per_gen}
onChange={this.amd_dl_per_gen}
placeholder="input placeholder"
/>
</Form.Item>
</Col>
{/* <Col span={12}>
<Form.Item
label="dl_score_cutoffize"
{...formItemLayout3}
>
<Input placeholder="input placeholder" />
</Form.Item>
</Col> */}
</Form>
<div className="title-text">Properties</div>
<Form
className="generalsearch-div"
style={{ height: "100px" }}
>
{/* <Form.Item label="Form Layout" {...formItemLayout} /> */}
<Col span={12}>
<Form.Item label="MW" {...formItemLayout3}>
<InputNumber
style={{width:'150px'}}
value={this.state.amd.MW}
onChange={this.amdMW}
placeholder="input placeholder"
/>
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label="logP_lower" {...formItemLayout3}>
<InputNumber
style={{width:'150px'}}
value={this.state.amd.logP_lower}
onChange={this.amd_logP_lower}
placeholder="input placeholder"
/>
</Form.Item>
</Col>
{/* <Col span={12}>
<Form.Item
label="dl_score_cutoffize"
{...formItemLayout3}
>
<Input placeholder="input placeholder" />
</Form.Item>
</Col> */}
</Form>
</div>
)}
{list[5].state && (
<div className="taskmanager-div">
<div className="search-div">
<Form layout="inline">
<Form.Item label="type">
<Select
style={{ width: 120 }}
onChange={this.handleChange}
defaultValue=""
>
<Option value="1">retrosynthesis</Option>
<Option value="2">docking</Option>
<Option value="3">amd</Option>
<Option value="4">pharmacophore</Option>
<Option value="">all</Option>
</Select>
</Form.Item>
<Form.Item label="status">
<Select
style={{ width: 120 }}
onChange={this.handleChange2}
defaultValue=""
>
<Option value="1">running</Option>
<Option value="2">finshed</Option>
<Option value="3">others</Option>
<Option value="">all</Option>
</Select>
</Form.Item>
<Form.Item>
<Button type="primary" onClick={this.getTaskManager}>
search
</Button>
</Form.Item>
</Form>
</div>
<div className="list-div">
<Table
columns={columns}
pagination={false}
dataSource={ListData}
rowKey="id"
/>
<Pagination
showSizeChanger
onShowSizeChange={this.onShowSizeChange}
onChange={this.onChange2}
total={total_num}
/>
</div>
</div>
)}
</div>
</div>
<div
className={
this.state.stateName === "Welcome" ||
this.state.stateName === "Task Manager"
? "displaydiv"
: "bottom-butn"
}
>
<Button
onClick={this.goList}
type="primary"
size="large"
shape="round"
>
Run
</Button>
</div>
</div>
</div>
);
}
}
.Molstar-div{
height: 800px;
width: 800px;
}
\ No newline at end of file
import React, { Component } from 'react'
import Molstar from "molstar-react";
import {Tabs,} from 'antd';
import qs from 'qs'
import './index.css'
const { TabPane } = Tabs;
export default class MolstarView extends Component {
state={
PdbId:qs.parse(this.props.location.search.slice(1)).PdbId,
tabs:['Ligand','Water','Polymer','Ion','CDR']
}
render() {
const{tabs,PdbId}=this.state
console.log();
return (
<div>
<Tabs defaultActiveKey="0" type="card" tabPosition='left'>
{
tabs.map((item,index)=>{
return(
<TabPane tab={item} key={index}>
<div className='Molstar-div2'>
<Molstar pdbId={PdbId} />
</div>
</TabPane>
)
})
}
</Tabs>
</div>
)
}
}
.Molstar-div{
height: 800px;
width: 800px;
}
.Molstar-div2{
height: 500px;
width:100%;
}
.search-details-div{
background-color: #fff;
padding: 5px;
box-sizing: border-box;
}
.search-details-div .title-div{
font-size: 30px;
font-weight: 600;
padding-left: 10px;
box-sizing: border-box;
}
.search-details-div .div-list{
display: flex;
flex-wrap: wrap;
padding: 10px;
box-sizing: border-box;
background-color: #fff;
margin-bottom: 20px;
}
.search-details-div .div-list .list-one{
display: flex;
align-items: center;
width: 25%;
}
.search-details-div .div-list .left-div {
color: black;
font-weight: 500;
font-size: 18px;
margin-right: 10px;
}
.search-details-div .div-list .right-div {
/* width: 80%; */
word-wrap: break-word;
}
.search-details-div
.ant-collapse > .ant-collapse-item > .ant-collapse-header{
font-weight: 500;
font-size: 18px;
}
.search-details-div .isShowDiv{
display: none;
}
.search-details-div .title-div-top{
display: flex;
align-items: center;
justify-content: space-between;
}
.search-details-div .Jsme-div{
border: 1px solid black;
}
.search-details-div .link-div{
color: blue;
cursor: pointer;
}
.table-div{
background-color: #fff;
}
.search-details-div .title-div{
color: black;
font-weight: 600;
font-size: 23px;
margin-right: 10px;
}
.search-details-div .card-div{
background-color: #fff;
}
.search-details-div .card-div{
padding: 20px ;
box-sizing: border-box;
}
import React, { Component } from "react";
import { Tabs, Table,PageHeader, message, Card } from "antd";
import request from "../../../utils/request";
import "./index.css";
import qs from "qs";
const { TabPane } = Tabs;
export default class SearchDetails extends Component {
state = {
id: qs.parse(this.props.location.search.slice(1)).pdbCode,
// id:515,
AntibodyData: {
},
antibodyInfo:[],
AntigenData: [],
StructuresData: [],
ClinicalIndicationData: {},
defaultActiveKey: qs.parse(this.props.location.search.slice(1))
.defaultActiveKey,
};
componentDidMount() {
console.log(this.state);
this.getOne(this.state.defaultActiveKey);
this.getClinicalIndicationList;
}
getAntibodyList() {
const { id } = this.state;
console.log(id);
this.setState({ loading: true });
request
.get("/searchstruct/pdbdetail?pdbCode=" + id)
.then((res) => {
console.log(res);
if (res.data.code === 200) {
console.log(res.data.result.pdbCommonVO);
this.setState({ AntibodyData: res.data.result.pdbCommonVO });
this.setState({ antibodyInfo: res.data.result.antibodyInfo });
this.setState({ loading: false });
} else {
message.error(res.data.msg);
}
})
.catch((err) => {
console.error(err);
});
}
getPdb = (e) => {
let data = {
PdbId: e,
};
this.props.history.push({
pathname: "/home/MolstarView",
search: qs.stringify(data),
});
};
getOne(e) {
this.getAntibodyList();
}
callback = (e) => {
if (e === "Antibody") {
this.getAntibodyList();
return;
}
if (e === "Antigen") {
this.getAntigenList();
return;
}
if (e === "Structures") {
this.getStructuresList();
return;
}
if (e === "ClinicalIndication") {
this.getClinicalIndicationList();
return;
}
};
getSequenceDetails = (e) => {
let data = {
Sequence: e,
};
this.props.history.push({
pathname: "/home/SequenceDetails",
search: qs.stringify(data),
});
};
render() {
const {
AntibodyData,
antibodyInfo,
} = this.state;
const columns = [
{
title: "CDR",
dataIndex: "chainName",
key: "chainName",
// render: text => <a>{text}</a>,
width: 200,
},
{
title: "sequence",
dataIndex: "sequence",
key: "sequence",
width: 200,
render: (text, record) => (
<div style={{ wordWrap: "break-word", wordBreak: "break-word" }}>
{text}
</div>
),
},
{
title: "length",
dataIndex: "length",
key: "length",
width: 200,
},
{
title: "cluster",
key: "cluster",
dataIndex: "cluster",
width: 200,
},
];
const AntibodyView = (
<div className="div-list">
<div className="list-one">
<div className="left-div itle-div">In complex:</div>
<div className="right-div">{AntibodyData.inComplex}</div>
</div>
<div className="list-one">
<div className="left-div itle-div">Resolution:</div>
<div className="right-div">{AntibodyData.resolution}</div>
</div>
<div className="list-one">
<div className="left-div itle-div">R-free:</div>
<div className="right-div">{AntibodyData.rfree}</div>
</div>
<div className="list-one">
<div className="left-div itle-div">Released date:</div>
<div className="right-div">{AntibodyData.releasedDate}</div>
</div>
<div className="list-one">
<div className="left-div itle-div">Organism:</div>
<div className="right-div">{AntibodyData.organism}</div>
</div>
<div className="list-one">
<div className="left-div itle-div">R-factor:</div>
<div className="right-div">{AntibodyData.rfactor}</div>
</div>
<div className="list-one">
<div className="left-div itle-div">PMID:</div>
<div className="right-div">{AntibodyData.pmid}</div>
</div>
</div>
);
const AntibodyView2 = antibodyInfo.map((item,index)=>{
return(
<Card
hoverable
style={{ marginBottom: '10px'}}
>
<div className="card-div" key={index}>
<div className="title-div">antibody1</div>
<div className="div-list">
<div className="list-one">
<div className="left-div itle-div">Chains:</div>
<div className="right-div">{item.antibodyCommonInfoVO.chains}</div>
</div>
<div className="list-one">
<div className="left-div itle-div">Heavy chains::</div>
<div className="right-div">{item.antibodyCommonInfoVO.heavyChains}</div>
</div>
<div className="list-one">
<div className="left-div itle-div">Light chains:</div>
<div className="right-div">{item.antibodyCommonInfoVO.lightChains}</div>
</div>
<div className="list-one">
<div className="left-div itle-div">in complex:</div>
<div className="right-div">{item.antibodyCommonInfoVO.inComplex}</div>
</div>
<div className="list-one">
<div className="left-div itle-div">Antigen chains:</div>
<div className="right-div">{item.antibodyCommonInfoVO.antigenChains}</div>
</div>
<div className="list-one">
<div className="left-div itle-div">Format:</div>
<div className="right-div">{item.antibodyCommonInfoVO.format}</div>
</div>
</div>
<div className="title-div">heavy chain</div>
<div className="div-list">
<div className="list-one">
<div className="left-div itle-div">V gene usage:</div>
<div className="right-div">{item.antibodyCommonInfoVO.heavyChainVgeneusage}</div>
</div>
<div className="list-one">
<div className="left-div itle-div">Species:</div>
<div className="right-div">{item.antibodyCommonInfoVO.heavyChainSpecies}</div>
</div>
</div>
<div className="title-div">light chain</div>
<div className="div-list">
<div className="list-one">
<div className="left-div itle-div">V gene usage:</div>
<div className="right-div">{item.antibodyCommonInfoVO.lightChainVgeneusage}</div>
</div>
<div className="list-one">
<div className="left-div itle-div">Species:</div>
<div className="right-div">{item.antibodyCommonInfoVO.lightChainSpecies}</div>
</div>
</div>
<Table bordered columns={columns} pagination={false} dataSource={item.cdrList} rowKey='chainName' />
<div className="title-div">affinity information</div>
<div className="title-div">calculated property</div>
</div>
</Card>
)
})
return (
<div className="search-details-div">
<PageHeader
style={{
border: "1px solid rgb(235, 237, 240)",
}}
onBack={() => this.props.history.go(-1)}
title="返回"
/>
<div className="title-div">pdb</div>
{AntibodyView}
<div className="title-div">antibody information</div>
{AntibodyView2}
</div>
);
}
}
.search-div{
}
.search-div .list-div-one{
display: flex;
justify-content: space-between;
align-items: center;
}
.search-div .list-div-left{
width:20%;
font-size: 28px;
font-weight: 500;
color: blue;
}
.search-div .list-div-right{
width: 80%;
word-wrap: break-word; word-break: normal;
}
.Molstar-div{
height: 800px;
width: 800px;
}
.search-div .btn-list{
height: 100%;
display: flex;
width: 20%;
flex-wrap: wrap;
}
.search-div .search-content{
color: #000000d9;
font-weight: 500;
font-size: 30px;
}
.search-div .CheckboxList{
display: flex;
justify-content: end;
align-items: center;
padding: 10px;
}
.search-div .CheckboxList button{
margin-left: 10px;
}
.search-div .list-div-one .list-div-right span{
font-weight: 500;
color: black;
}
.search-div .ant-card-extra{
margin-left: initial !important;
font-weight: 500;
}
.search-div .list-div-one .btn-list span{
font-weight: 500;
color: black;
}
.search-div .list-div-one .btn-list .right-div {
width: 100%;
}
.search-div .isShowDiv{
display: none;
}
.search-div .pdb-idv{
padding-left: 20px;
}
.search-div .pdb-idv div{
margin-bottom: 2px;
}
.search-div .pdb-center{
display: flex;
}
.search-div .cdrs-div{
display: flex;
flex-flow: column;
}
.search-div .list-div-one .list-div-right .cdrs-div span{
font-weight: 400;
color: black;
}
.search-div .allEpitopeList .list-div-right{
width: 80%;
word-wrap: break-word; word-break: normal;
}
.search-div .allEpitopeList .list-div-left{
width: 20%;
font-size: 28px;
font-weight: 500;
color: blue;
}
import React, { Component } from "react";
import { Jsme } from "jsme-react";
import {
Card,
PageHeader,
Pagination,
Tabs,
Spin,
message,
Modal,
Tag,
} from "antd";
import Molstar from "molstar-react";
import request from "../../../utils/request";
import qs from "qs";
import "./index.css";
const { TabPane } = Tabs;
export default class SearchList extends Component {
state = {
smilesList: [{}, {}, {}],
CDRList: [],
EpitopeList: [],
visible: false,
pdbId: "6f6s",
total_num: 0,
searchData: qs.parse(this.props.location.search.slice(1)),
name: "Summary",
};
getPdid(e) {
let data = {
dataid: e,
defaultActiveKey: "Antibody",
};
this.props.history.push({
pathname: "/home/SearchDetails",
search: qs.stringify(data),
});
}
clinicalIndicationPdid(e) {
let data = {
dataid: e,
defaultActiveKey: "ClinicalIndication",
};
this.props.history.push({
pathname: "/home/SearchDetails",
search: qs.stringify(data),
});
}
TargetPdid(e) {
let data = {
pdbCode: e,
};
this.props.history.push({
pathname: "/home/SearchDetails",
search: qs.stringify(data),
});
}
onShowSizeChange = (current, pageSize) => {
let searchData = this.state.searchData;
if (searchData.searchType == 1) {
searchData.generalSearchDTO.pageNumber = current;
searchData.generalSearchDTO.pageSize = pageSize;
this.setState({
searchData,
});
this.getSummaryList();
return;
}
if (searchData.searchType == 2) {
searchData.cdrSearchDTO.pageNumber = current;
searchData.cdrSearchDTO.pageSize = pageSize;
this.setState({
searchData,
});
this.getSummaryList();
return;
}
if (searchData.searchType == 3) {
searchData.sequenceSearchDTO.pageNumber = current;
searchData.sequenceSearchDTO.pageSize = pageSize;
this.setState({
searchData,
});
this.getSummaryList();
return;
}
};
onChange = (current, pageSize) => {
let searchData = this.state.searchData;
if (searchData.searchType == 1) {
searchData.generalSearchDTO.pageNumber = current;
searchData.generalSearchDTO.pageSize = pageSize;
this.setState({
searchData,
});
this.getSummaryList();
return;
}
if (searchData.searchType == 2) {
searchData.cdrSearchDTO.pageNumber = current;
searchData.cdrSearchDTO.pageSize = pageSize;
this.setState({
searchData,
});
this.getSummaryList();
return;
}
if (searchData.searchType == 3) {
searchData.sequenceSearchDTO.pageNumber = current;
searchData.sequenceSearchDTO.pageSize = pageSize;
this.setState({
searchData,
});
this.getSummaryList();
return;
}
};
// getPdb(e){
// console.log(e);
// this.setState({visible: true})
// this.setState({pdbId: e})
// }
getPdb = (e) => {
let data = {
PdbId: e,
};
this.props.history.push({
pathname: "/home/MolstarView",
search: qs.stringify(data),
});
};
componentDidMount() {
console.log(qs.parse(this.props.location.search.slice(1)));
this.getSummaryList();
// if (this.state.smilesData.name==='Drugs') {
// this.getList()
// }
// if (this.state.smilesData.name==='Target') {
// this.getTargetList()
// }
}
getSummaryList() {
this.setState({ loading: true });
request
.post("/searchstruct/pdbpage", this.state.searchData)
.then((res) => {
console.log(res);
if (res.data.code == 200) {
this.setState({ smilesList: res.data.result.rows });
this.setState({ total_num: Number(res.data.result.totalCount) });
this.setState({ loading: false });
} else {
message.error(res.data.message);
this.props.history.go(-1);
}
})
.catch((err) => {
console.error(err);
});
}
callback = (e) => {
console.log(e);
this.setState({ name: e });
if (e === "Summary") {
this.getSummaryList();
return;
}
if (e === "CDR") {
this.getCDRList();
return;
}
if (e === "Epitope") {
this.getEpitopeList();
return;
}
};
getOne(e) {
console.log(e);
const { dataid, datatype } = e;
let data = {
dataid,
datatype,
};
if (this.state.smilesData.name === "Drugs") {
this.props.history.push({
pathname: "/home/SearchDetails",
search: qs.stringify(data),
});
}
if (this.state.smilesData.name === "Target") {
this.props.history.push({
pathname: "/home/TargetDetails",
search: qs.stringify(data),
});
}
}
render() {
const {
smilesList,
loading,
EpitopeList,
CDRList,
visible,
pdbId,
total_num,
smilesData,
} = this.state;
const SummaryList = smilesList.map((item, index) => {
console.log(item);
return (
<Card
loading={loading}
hoverable
extra={<a onClick={() => this.getOne(item)}>{item.name}</a>}
style={{ width: "100%", marginBottom: "20px" }}
key={index}
>
<div
className="list-div-one"
onClick={() => this.TargetPdid(item.pdbCode)}
>
<div
className="list-div-left"
onClick={() => this.getPdid(item.id)}
>
{item.antibodyName}
</div>
<div className="list-div-right">
<div>
<span style={{ color: "blue" }}>{item.pdbCode}</span>
</div>
<div>
<span>{item.compound}</span>
{/* {item.compound} */}
</div>
<div>
<span> Organism</span>
{item.organism}
</div>
<div>
<span> Resolution:</span>
{item.resolution}
</div>
<div>
<span>Method:</span>
{item.method}
</div>
<div>
<span> Released date </span>
{item.releasedDate}
</div>
</div>
{/* <div className='btn-list'>
</div> */}
<div />
</div>
</Card>
);
});
return (
<div className="search-div">
<Modal
footer={null}
closable={false}
width={850}
visible={visible}
wrapClassName="vertical-center-modal"
onCancel={() => this.setState({ visible: false })}
>
<div className="Molstar-div">
<Molstar pdbId={this.state.pdbId} />
</div>
</Modal>
<Spin tip="Loading..." size="large" spinning={this.state.loading}>
<PageHeader
style={{
border: "1px solid rgb(235, 237, 240)",
}}
onBack={() => this.props.history.go(-1)}
title="返回"
/>
{SummaryList}
<Pagination
showSizeChanger
onShowSizeChange={this.onShowSizeChange}
onChange={this.onChange}
total={total_num}
/>
</Spin>
</div>
);
}
}
.SequenceDetails-div {
word-wrap: break-word;
}
.SequenceDetails-div .title-div{
font-weight: 800;
font-size: 18px;
}
import React, { Component } from 'react'
import qs from 'qs'
import './index.css'
export default class SequenceDetails extends Component {
state={
SequenceDetails:qs.parse(this.props.location.search.slice(1)).Sequence
}
render() {
const{SequenceDetails}=this.state
return (
<div className='SequenceDetails-div'>
<span className='title-div'>
SequenceDetails:
</span>
{SequenceDetails}
</div>
)
}
}
.StructureSearch-div{
display: flex;
padding-top: 100px;
}
.StructureSearch-div .left-div{
width: 30%;
display: flex;
flex-direction: column;
align-items: center;
}
.StructureSearch-div .left-div Button{
margin-bottom: 100px;
height: 50px;
width: 200px;
}
.StructureSearch-div .right-div{
width: 70%;
padding: 20px;
}
.StructureSearch-div .right-div .right-div-one{
display: flex;
align-items: center;
width: 100%;
/* justify-content: space-between; */
}
.StructureSearch-div .right-div .right-div-one .title-div{
width: 20%;
}
.sequencesearch-div .top-div {
margin-bottom: 100px;
}
.sequencesearch-div .sequence-center{
display: flex;
align-items: center;
}
.sequencesearch-div .TextArea-div{
width: 50%;
}
.bottom-butn button{
height: 50px;
width: 200px;
}
.bottom-butn{
display: flex;
align-items: center;
justify-content: center;
height: 50px;
}
.sequencesearch-div .login-form .form-one{
display: flex ;
align-items: center ;
}
\ No newline at end of file
import React, { Component } from "react";
import qs from 'qs'
import {
PageHeader ,
Button,
Row,
Col,
Upload,
Input,
Select,
Form,
Icon,
message,
} from "antd";
import "./index.css";
import request from "../../../utils/request";
const { Option } = Select;
const { TextArea } = Input;
let id = 0;
@Form.create()
export default class StructureSearch extends Component {
state = {
list: [
{
name: "general search",
state: true,
searchType:1
},
{
name: "cdr search",
state: false,
searchType:2
},
{
name: "sequence search",
state: false,
searchType:3
},
],
targetsDetail: {
name: "",
},
sum:0,
LightChainSubclassList: [],
AntigenTypeList: [],
ExperimentalMethodList: [],
HaveyChainSubclassList: [],
LightChainTypeList:[],
addList:[],
generalSearchDTO: {
pdbCode: "",
lightChainType: "",
rfactorCutoff: "",
lightChainSubclass: "",
resolutionCutoff: "",
antigenType: "",
antigenName: "",
experimentalMethod: "",
antigenUniportId: "",
heavyChainSubclass: "",
limit: 0,
offset: 0,
pageNumber: 1,
pageSize: 10,
},
cdrSearchDTO: {
cdr1: "",
cdr2: "",
cdr3: "",
cdr4: "",
cdr5: "",
cdr6: "",
cdrType1: "",
cdrType2: "",
cdrType3: "",
cdrType4: "",
cdrType5: "",
cdrType6: "",
limit: 0,
offset: 0,
pageNumber: 1,
pageSize: 10,
},
sequenceSearchDTO: {
fileName: "",
identy: "",
limit: 0,
offset: 0,
pageNumber: 1,
pageSize: 10,
sequence: ""
},
fileList:[],
searchData:{
searchType:1
}
};
componentDidMount() {
this.getSelectList1();
this.getSelectList2();
this.getSelectList3();
this.getSelectList4();
this.getSelectList5()
this.getSelectList6()
this.add()
}
getForm=()=>{
}
goList = () => {
let data = this.state.searchData;
if (this.state.searchData.searchType===1) {
data.generalSearchDTO=this.state.generalSearchDTO
this.props.history.push({
pathname: "/home/SearchList",
search: qs.stringify(data),
});
return
}
if (this.state.searchData.searchType===2) {
this.handleSubmit()
data.cdrSearchDTO=this.state.cdrSearchDTO
this.props.history.push({
pathname: "/home/SearchList",
search: qs.stringify(data),
});
return
}
if (this.state.searchData.searchType===3) {
data.sequenceSearchDTO=this.state.sequenceSearchDTO
this.props.history.push({
pathname: "/home/SearchList",
search: qs.stringify(data),
});
return
}
};
getSelectList1 = () => {
request
.post("/common/comboBox", {
dictCode: "LIGHT-CHIAIN-SUBCLASS",
})
.then((res) => {
console.log(res.data.result);
if (res.data.code === 200) {
this.setState({
LightChainSubclassList: res.data.result,
});
} else {
message.error(res.data.msg);
}
})
.catch((err) => {
console.error(err);
});
};
getSelectList2 = () => {
request
.post("/common/comboBox", {
dictCode: "ANTIGEN-TYPE",
})
.then((res) => {
console.log(res.data.result);
if (res.data.code === 200) {
this.setState({
AntigenTypeList: res.data.result,
});
} else {
message.error(res.data.msg);
}
})
.catch((err) => {
console.error(err);
});
};
getSelectList3 = () => {
request
.post("/common/comboBox", {
dictCode: "EXPERIMENTAL-METHOD",
})
.then((res) => {
console.log(res.data.result);
if (res.data.code === 200) {
this.setState({
ExperimentalMethodList: res.data.result,
});
} else {
message.error(res.data.msg);
}
})
.catch((err) => {
console.error(err);
});
};
getSelectList4 = () => {
request
.post("/common/comboBox", {
dictCode: "HEAVY-CHAIN-SUBCLASS",
})
.then((res) => {
console.log(res.data.result);
if (res.data.code === 200) {
this.setState({
HaveyChainSubclassList: res.data.result,
});
} else {
message.error(res.data.msg);
}
})
.catch((err) => {
console.error(err);
});
};
getSelectList5 = () => {
request
.post("/common/comboBox", {
dictCode: "CDR_TYPE",
})
.then((res) => {
console.log(res.data.result);
if (res.data.code === 200) {
this.setState({
addList: res.data.result,
});
} else {
message.error(res.data.msg);
}
})
.catch((err) => {
console.error(err);
});
};
getSelectList6 = () => {
request
.post("/common/comboBox", {
dictCode: "LIGHT-CHAIN-TYPE",
})
.then((res) => {
console.log(res.data.result);
if (res.data.code === 200) {
this.setState({
LightChainTypeList: res.data.result,
});
} else {
message.error(res.data.msg);
}
})
.catch((err) => {
console.error(err);
});
};
callback = (e) => {
console.log(e);
// let searchData = this.state.searchData;
// searchData.name = e;
// this.setState(() => ({ searchData: searchData }));
// console.log(this.state.searchData);
};
getListOne = (e) => {
console.log(1111);
let newList = this.state.list;
console.log(e);
newList.forEach((item, index) => {
item.state = false;
if (e === index) {
item.state = true;
let searchData = this.state.searchData;
searchData.searchType = item.searchType;
this.setState(() => ({ searchData: searchData }));
}
});
this.setState({
list: newList,
});
};
remove = (k) => {
const { form } = this.props;
// can use data-binding to get
const keys = form.getFieldValue("keys");
// We need at least one passenger
if (keys.length === 1) {
return;
}
this.setState({
sum: keys.length-1
})
// can use data-binding to set
form.setFieldsValue({
keys: keys.filter((key) => key !== k),
});
};
add = () => {
const { form } = this.props;
// can use data-binding to get
const keys = form.getFieldValue("keys");
console.log(keys);
const nextKeys = keys.concat(id++);
// can use data-binding to set
// important! notify form to detect changes
form.setFieldsValue({
keys: nextKeys,
});
this.setState
({
sum:keys.length+1
})
};
handleSubmit = (e) => {
// console.log(e);
// e.preventDefault();
this.props.form.validateFields((err, values) => {
console.log(values);
const { keys, names,names2 } = values;
// console.log('Received values of form: ', values);
// console.log('Merged values:', keys.map(key => names[key]));
// let names=keys.map(key => names[key])
console.log(names);
console.log(names2);
for (let index = 0; index < names.length; index++) {
var element = names[index];
if (element == undefined) {
names[index] = "";
}
}
let newArr = names.filter((i) => i && i.trim());
for (let index = 0; index < names2.length; index++) {
var element = names2[index];
if (element == undefined) {
names2[index] = "";
}
}
let newArr2 = names2.filter((i) => i && i.trim());
console.log(newArr2);
let cdrSearchDTO=this.state.cdrSearchDTO
cdrSearchDTO.cdr1=newArr[0]===undefined?'':newArr[0]
cdrSearchDTO.cdr2=newArr[1]===undefined?'':newArr[1]
cdrSearchDTO.cdr3=newArr[2]===undefined?'':newArr[2]
cdrSearchDTO.cdr4=newArr[3]===undefined?'':newArr[3]
cdrSearchDTO.cdr5=newArr[4]===undefined?'':newArr[4]
cdrSearchDTO.cdr6=newArr[5]===undefined?'':newArr[5]
cdrSearchDTO.cdrType1=newArr2[0]===undefined?'':newArr2[0]
cdrSearchDTO.cdrType2=newArr2[1]===undefined?'':newArr2[1]
cdrSearchDTO.cdrType3=newArr2[2]===undefined?'':newArr2[2]
cdrSearchDTO.cdrType4=newArr2[3]===undefined?'':newArr2[3]
cdrSearchDTO.cdrType5=newArr2[4]===undefined?'':newArr2[4]
cdrSearchDTO.cdrType6=newArr2[5]===undefined?'':newArr2[5]
// cdrSearchDTO.cdr1=newArr[0]
// cdrSearchDTO.cdr2=newArr[1]
// cdrSearchDTO.cdr3=newArr[2]
// cdrSearchDTO.cdr4=newArr[3]
// cdrSearchDTO.cdr5=newArr[4]
// cdrSearchDTO.cdr6=newArr[5]
// cdrSearchDTO.cdrType1=newArr2[0]
// cdrSearchDTO.cdrType2=newArr2[1]
// cdrSearchDTO.cdrType3=newArr2[2]
// cdrSearchDTO.cdrType4=newArr2[3]
// cdrSearchDTO.cdrType5=newArr2[4]
// cdrSearchDTO.cdrType6=newArr2[5]
this.setState(() => ({ cdrSearchDTO: cdrSearchDTO }));
console.log(this.state.cdrSearchDTO);
});
};
getValue = (e) => {
const { value } = e.target;
let generalSearchDTO = this.state.generalSearchDTO;
generalSearchDTO.pdbCode = value;
this.setState(() => ({ generalSearchDTO: generalSearchDTO }));
};
getValue2 = (e) => {
const { value } = e.target;
let generalSearchDTO = this.state.generalSearchDTO;
generalSearchDTO.lightChainType = value;
this.setState(() => ({ generalSearchDTO: generalSearchDTO }));
};
getValue3 = (e) => {
const { value } = e.target;
let generalSearchDTO = this.state.generalSearchDTO;
generalSearchDTO.rfactorCutoff = value;
this.setState(() => ({ generalSearchDTO: generalSearchDTO }));
};
getValue4 = (e) => {
const { value } = e.target;
let generalSearchDTO = this.state.generalSearchDTO;
generalSearchDTO.resolutionCutoff = value;
this.setState(() => ({ generalSearchDTO: generalSearchDTO }));
};
getValue5 = (e) => {
const { value } = e.target;
let generalSearchDTO = this.state.generalSearchDTO;
generalSearchDTO.antigenName = value;
this.setState(() => ({ generalSearchDTO: generalSearchDTO }));
};
getValue6 = (e) => {
const { value } = e.target;
let generalSearchDTO = this.state.generalSearchDTO;
generalSearchDTO.antigenUniportId = value;
this.setState(() => ({ generalSearchDTO: generalSearchDTO }));
};
getValue7 = (e) => {
const { value } = e.target;
let sequenceSearchDTO = this.state.sequenceSearchDTO;
sequenceSearchDTO.sequence = value;
this.setState(() => ({ sequenceSearchDTO: sequenceSearchDTO }));
};
getValue8 = (e) => {
const { value } = e.target;
let sequenceSearchDTO = this.state.sequenceSearchDTO;
sequenceSearchDTO.identy = value;
this.setState(() => ({ sequenceSearchDTO: sequenceSearchDTO }));
};
SelectValue = (e) => {
console.log(e);
let generalSearchDTO = this.state.generalSearchDTO;
generalSearchDTO.lightChainSubclass = e;
this.setState(() => ({ generalSearchDTO: generalSearchDTO }));
};
SelectValue2 = (e) => {
console.log(e);
let generalSearchDTO = this.state.generalSearchDTO;
generalSearchDTO.antigenType = e;
this.setState(() => ({ generalSearchDTO: generalSearchDTO }));
};
SelectValue3 = (e) => {
console.log(e);
let generalSearchDTO = this.state.generalSearchDTO;
generalSearchDTO.experimentalMethod = e;
this.setState(() => ({ generalSearchDTO: generalSearchDTO }));
};
SelectValue4 = (e) => {
console.log(e);
let generalSearchDTO = this.state.generalSearchDTO;
generalSearchDTO.heavyChainSubclass = e;
this.setState(() => ({ generalSearchDTO: generalSearchDTO }));
};
SelectValue5 = (e) => {
console.log(e);
let generalSearchDTO = this.state.generalSearchDTO;
generalSearchDTO.lightChainType = e;
this.setState(() => ({ generalSearchDTO: generalSearchDTO }));
};
handleChange=(info)=> {
// console.log(info);
let fileList = [...info.fileList];
fileList = fileList.slice(-1);
fileList = fileList.map(file => {
if (file.response) {
// Component will show file.url as link
file.url = file.response.url;
}
return file;
});
if (fileList.length>0) {
if (fileList[0].response&&fileList[0].response.code===200) {
let sequenceSearchDTO=this.state.sequenceSearchDTO
sequenceSearchDTO.fileName=fileList[0].response.result
}
}else{
let sequenceSearchDTO=this.state.sequenceSearchDTO
sequenceSearchDTO.fileName=''
}
this.setState({ fileList });
// console.log(this.state.fileList);
// if (info.file.status === 'done') {
// console.log(info.file.response.result);
// message.success(`上传成功`);
// }if (info.file.status === 'error'){
// message.error(`上传失败`);
// }
}
render() {
const {
list,
LightChainSubclassList,
AntigenTypeList,
ExperimentalMethodList,
HaveyChainSubclassList,
addList,
sum,
LightChainTypeList
} = this.state;
const props = {
name: 'file',
action: 'http://52.83.230.236:8084/yszh-antibody/common/uploadFile',
onChange: this.handleChange,
headers: {
authorization: 'authorization-text',
accessToken:window.localStorage.getItem('token')
},}
const formItemLayout2 = {
labelCol: {
xs: { span: 24 },
sm: { span: 4 },
},
wrapperCol: {
xs: { span: 24 },
sm: { span: 20 },
},
};
const { getFieldDecorator, getFieldValue } = this.props.form;
const formItemLayoutWithOutLabel = {
wrapperCol: {
xs: { span: 24, offset: 0 },
sm: { span: 20, offset: 4 },
},
};
getFieldDecorator("keys", { initialValue: [] });
const keys = getFieldValue("keys");
const formItems = keys.map((k, index) => (
<Form.Item
{...(index === 0 ? formItemLayout2 : formItemLayoutWithOutLabel)}
label={index === 0 ? "AlignSequence: " : ""}
required={false}
key={k}
>
<div style={{ display: "flex ", alignItems: "center " }}>
{getFieldDecorator(`names[${k}]`)(
<Input
placeholder="请输入"
style={{ width: "200px", marginRight: 8 }}
/>
)}
<div>
<Form.Item style={{ margin:'0px'}}>
{getFieldDecorator(`names2[${k}]`)(
<Select style={{ width: "100px" }}>
{addList.map((item, index) => {
return (
<Option key={index} value={item.dictVal}>
{item.dictVal}
</Option>
);
})}
</Select>
)}
{keys.length > 1 ? (
<Icon
className="dynamic-delete-button"
type="minus-circle-o"
onClick={() => this.remove(k)}
style={{ marginLeft:'10px'}}
/>
) : null}
</Form.Item>
</div>
</div>
</Form.Item>
));
return (
<div>
<PageHeader
style={{
border: '1px solid rgb(235, 237, 240)',
}}
onBack={()=>this.props.history.go(-1)}
title="返回"
/>
<div className="StructureSearch-div">
<div className="left-div">
{list.map((item, index) => {
return (
<Button
type={item.state ? "primary" : ""}
size="large"
shape="round"
onClick={() => this.getListOne(index)}
key={index}
>
{item.name}
</Button>
);
})}
</div>
<div className="right-div">
{list[0].state && (
<div className="generalsearch-div">
<Row>
<Col span={12} style={{ marginBottom: 30 }}>
<div className="right-div-one">
<div className="title-div">PDBID:</div>
<div>
<Input
placeholder="请输入"
style={{ width: 200 }}
onChange={this.getValue}
value={this.state.generalSearchDTO.pdbCode}
/>
</div>
</div>
</Col>
<Col span={12}>
<div className="right-div-one">
<div className="title-div">Light chain type:</div>
<div>
<Select
showSearch
style={{ width: 200 }}
placeholder="请选择"
value={this.state.generalSearchDTO.lightChainType}
onChange={this.SelectValue5}
>
{LightChainTypeList.map((item, index) => {
return (
<Option key={index} value={item.dictVal}>
{item.dictVal}
</Option>
);
})}
</Select>
</div>
</div>
</Col>
</Row>
<Row>
<Col span={12} style={{ marginBottom: 30 }}>
<div className="right-div-one">
<div className="title-div">R-factor cutoff:</div>
<div>
<Input
placeholder="请输入"
value={this.state.generalSearchDTO.rfactorCutoff}
onChange={this.getValue3}
style={{ width: 200 }}
/>
</div>
</div>
</Col>
<Col span={12}>
<div className="right-div-one">
<div className="title-div">Light chain subclass:</div>
<div>
<Select
showSearch
style={{ width: 200 }}
placeholder="请选择"
value={this.state.generalSearchDTO.lightChainSubclass}
onChange={this.SelectValue}
>
{LightChainSubclassList.map((item, index) => {
return (
<Option key={index} value={item.dictVal}>
{item.dictVal}
</Option>
);
})}
</Select>
</div>
</div>
</Col>
</Row>
<Row>
<Col span={12} style={{ marginBottom: 30 }}>
<div className="right-div-one">
<div className="title-div">Resolution cutoff:</div>
<div>
<Input
placeholder="请输入"
value={this.state.generalSearchDTO.resolutionCutoff}
onChange={this.getValue4}
style={{ width: 200 }}
/>
</div>
</div>
</Col>
<Col span={12}>
<div className="right-div-one">
<div className="title-div">Antigen type:</div>
<div>
<Select
showSearch
style={{ width: 200 }}
placeholder="请选择"
value={this.state.generalSearchDTO.antigenType}
onChange={this.SelectValue2}
>
{AntigenTypeList.map((item, index) => {
return (
<Option key={index} value={item.dictVal}>
{item.dictVal}
</Option>
);
})}
</Select>
</div>
</div>
</Col>
</Row>
<Row>
<Col span={12} style={{ marginBottom: 30 }}>
<div className="right-div-one">
<div className="title-div">Antigen name :</div>
<div>
<Input
placeholder="请输入"
value={this.state.generalSearchDTO.antigenName}
onChange={this.getValue5}
style={{ width: 200 }}
/>
</div>
</div>
</Col>
<Col span={12}>
<div className="right-div-one">
<div className="title-div">Experimental method:</div>
<div>
<Select
showSearch
style={{ width: 200 }}
placeholder="请选择"
value={this.state.generalSearchDTO.experimentalMethod}
onChange={this.SelectValue3}
>
{ExperimentalMethodList.map((item, index) => {
return (
<Option key={index} value={item.dictVal}>
{item.dictVal}
</Option>
);
})}
</Select>
</div>
</div>
</Col>
</Row>
<Row>
<Col span={12}>
<div className="right-div-one">
<div className="title-div">antigent Uniport id:</div>
<div>
<Input
placeholder="请输入"
value={this.state.generalSearchDTO.antigenUniportId}
onChange={this.getValue6}
style={{ width: 200 }}
/>
</div>
</div>
</Col>
<Col span={12}>
<div className="right-div-one">
<div className="title-div">Havey chain subclass:</div>
<div>
<Select
showSearch
style={{ width: 200 }}
placeholder="请选择"
value={this.state.generalSearchDTO.heavyChainSubclass}
onChange={this.SelectValue4}
>
{HaveyChainSubclassList.map((item, index) => {
return (
<Option key={index} value={item.dictVal}>
{item.dictVal}
</Option>
);
})}
</Select>
</div>
</div>
</Col>
</Row>
</div>
)}
{list[1].state && (
<div className="form-div">
<Form onSubmit={evt => this.handleSubmit(evt)} className="login-form">
{formItems}
<Form.Item {...formItemLayoutWithOutLabel}>
{
sum<6&&(
<Button
type="dashed"
onClick={this.add}
style={{ width: "60%" }}
>
<Icon type="plus" /> Add field
</Button>
)
}
</Form.Item>
</Form>
</div>
)}
{list[2].state && (
<div className="sequencesearch-div">
<div className="bottom-div">
<div>sequence:</div>
<div className="sequence-center">
<div className="TextArea-div">
<TextArea rows={14} value={this.state.sequenceSearchDTO.sequence}
onChange={this.getValue7}/>
</div>
<div>
<Form layout="inline">
<Form.Item label="denty:">
<Input value={this.state.sequenceSearchDTO.identy}
onChange={this.getValue8} />
</Form.Item>
<Form.Item label="上传文件">
<Upload {...props} fileList={this.state.fileList}>
<Button>
<Icon type="upload" /> 选择文件
</Button>
</Upload>
</Form.Item>
</Form>
</div>
</div>
</div>
</div>
)}
</div>
</div>
<div className="bottom-butn">
<Button
onClick={this.goList}
type="primary"
size="large"
shape="round"
>
search
</Button>
</div>
</div>
);
}
}
.Molstar-div{
height: 800px;
width: 800px;
}
.Molstar-div2{
height: 500px;
width:100%;
}
.search-details-div .title-div{
font-size: 30px;
font-weight: 600;
}
.search-details-div .div-list .list-one{
display: flex;
align-items: center;
}
.search-details-div .div-list .list-one
div:first-child{
color: black;
font-weight: 500;
font-size: 18px;
margin-right: 10px;
}
.search-details-div
.ant-collapse > .ant-collapse-item > .ant-collapse-header{
font-weight: 500;
font-size: 18px;
}
.search-details-div .isShowDiv{
display: none;
}
.search-details-div .title-div-top{
display: flex;
align-items: center;
justify-content: space-between;
}
.search-details-div .Jsme-div{
border: 1px solid black;
}
.search-details-div .Radio-div{
display: flex;
justify-content: flex-end;
height: 50px;
align-items: center;
}
.search-details-div .Sequence-div{
overflow:scroll;
display: flex;
}
.search-details-div .zimu-div{
display: flex;
}
.search-details-div .Sequenceone-div{
margin-right: 5px;
}
.search-details-div .zimu-div div{
padding: 5px;
}
.res-color-A {
background-color: #e6e600;
color: #000;
}
.res-color-C {
background-color: #b2b548;
color: #000;
}
.res-color-D {
background-color: #e60a0a;
color: #fdff7b;
}
.res-color-E {
background-color: #e60a0a;
color: #fdff7b;
}
.res-color-F {
background-color: #18ff0b;
color: #000;
}
.res-color-G {
background-color: #ff00f2;
color: #000;
}
.res-color-H {
background-color: #0093dd;
color: #000;
}
.res-color-I {
background-color: #e6e600;
color: #000;
}
.res-color-K {
background-color: #145aff;
color: #fdff7b;
}
.res-color-L {
background-color: #e6e600;
color: #000;
}
.res-color-M {
background-color: #e6e600;
color: #000;
}
.res-color-N {
background-color: #a70cc6;
color: #fdff7b;
}
.res-color-P {
background-color: #c09;
color: #fdff7b;
}
.res-color-Q {
background-color: #a70cc6;
color: #fdff7b;
}
.res-color-R {
background-color: #145aff;
color: #fdff7b;
}
.res-color-S {
background-color: #a70cc6;
color: #fdff7b;
}
.res-color-T {
background-color: #a70cc6;
color: #fdff7b;
}
.res-color-V {
background-color: #e6e600;
color: #000;
}
.res-color-W {
background-color: #0bcf00;
color: #000;
}
.res-color-Y {
background-color: #18ff0b;
color: #000;
}
import React, { Component } from 'react'
import { Card,Tooltip,Popover,message,Radio,Button,Tabs,Spin,Table,Tag, Collapse,Modal,Divider} from 'antd';
import request from '../../../utils/request'
import Molstar from "molstar-react";
import { Jsme } from 'jsme-react'
import qs from 'qs'
import './index.css'
const { Panel } = Collapse;
const { TabPane } = Tabs;
export default class TargetDetails extends Component {
state = {
name:'',
Structure:[],
dataOne:qs.parse(this.props.location.search.slice(1)),
visible:false,
pdbId:'6f6s',
DetailsData:{
PubChemCID:5462310,
MolecularWeight:12.011,
smiles:'cccc'
},
panelList:{
Bioassay:[]
},
statusMutation:0,
OLDMutationList:[],
targetsDetail:{
Structure:[],
Sequence:[]
},
loading:true,
};
componentDidMount(){
this.getDetails()
}
getDetails(){
// this.setState({loading:true})
this.setState({loading:true})
request.post('/targets_detail', this.props.location.search.slice(1) )
.then(res => {
this.setState({loading:false})
if (res.data.code===200) {
console.log(res);
let data=res.data.data
this.setState({targetsDetail:data})
this.setState({OLDMutationList:data.Mutation})
this.setState({loading:false})
}else{
message.error(res.data.msg);
}
})
.catch(err => {
console.error(err);
})
}
getPdid(e){
console.log(e);
this.setState({visible: true})
this.setState({pdbId: e})
}
getTag=(e)=>{
console.log(e);
this.setState({visible: true})
this.setState({pdbId: e})
}
getReferences=(e)=>{
window.open(`https://pubmed.ncbi.nlm.nih.gov/${e}`)
}
onChangeRadio=(e)=>{
let OLDMutationList= this.state.targetsDetail.Mutation
this.setState({
OLDMutationList:OLDMutationList
})
let value=e.target.value
this.setState({
statusMutation:value
})
if (value===0) {
OLDMutationList=this.state.targetsDetail.Mutation
this.setState({
OLDMutationList:OLDMutationList
})
}
if (value===1) {
let MutationList1= OLDMutationList.filter((item)=>{
return item.status===1
})
this.setState({
OLDMutationList:MutationList1
})
}
if (value===2) {
let MutationList2= OLDMutationList.filter((item)=>{
return item.status===2
})
this.setState({
OLDMutationList:MutationList2
})
}
}
getDrug=(e)=>{
console.log(e);
let data={
dataid:e
}
this.props.history.push({ pathname: '/home/SearchDetails', search: qs.stringify(data)})
}
callback(){
}
render() {
const {visible,panelList,Structure,OLDMutationList, name,pdbId,targetsDetail}=this.state
const columnsDrug = [
{
title: 'Drug Structure',
dataIndex: 'Drug Structure',
key: 'Drug Structure',
render: DrugStructure => (
<Jsme height="100px" width="100px" options="depict,useopenchemlib" smiles={DrugStructure} />
),
},
{
title: 'Drug name',
dataIndex: 'Drug name',
key: 'Drug name',
render: (item,record) => (
<Button type="primary" onClick={()=>this.getDrug(record.Drug_dataid)}>{item}</Button>
),
},
{
title: 'Drug Type',
dataIndex: 'Drug type',
key: 'Drug type',
},
{
title: 'Indication',
dataIndex: 'Indication',
key: 'Indication',
},
{
title: 'Mechanism of Action',
dataIndex: 'Mechanism of Action',
key: 'Mechanism of Action',
},
{
title: 'Status',
dataIndex: 'Status',
key: 'Status',
},
{
title: 'Clinical Phase',
dataIndex: 'Clinical Phase',
key: 'Clinical Phase',
},
{
title: 'Clinical Status',
dataIndex: 'Clinical Status',
key: 'Clinical Status',
},
{
title: 'Year of Approval',
dataIndex: 'Year of Approval',
key: 'Year of Approval',
},
{
title: 'References',
dataIndex: 'References',
key: 'References',
render: References => (
<span>
{References.map(item => {
return (
<Tag color="blue" key={item} onClick={()=>{this.getReferences(item)}} >
{item.toUpperCase()}
</Tag>
);
})}
</span>
),
},
// render: Reference => (
// <span>
// {Reference.map(item => {
// return (
// <Tag color="blue" key={item} onClick={()=>{this.getReferences(item)}} >
// {item.toUpperCase()}
// </Tag>
// );
// })}
// </span>
// ),
// {
// title: 'PDB',
// dataIndex: 'PDB',
// render: PDB => (
// <span>
// {PDB.map(item => {
// return (
// <Tag color="blue" key={item} onClick={()=>{this.getTag(item)}} >
// {item.toUpperCase()}
// </Tag>
// );
// })}
// </span>
// ),
// },
// {
// title: 'sequence',
// dataIndex: 'sequence',
// key: 'sequence',
// render: sequence => (
// <span>
// {
// <Tooltip placement="topLeft" title={sequence}>
// <Button>Sequence</Button>
// </Tooltip>
// }
// </span>
// ),
// },
];
const columnsBioassay = [
{
title: 'Structure',
dataIndex: 'smile',
key: 'smile',
render: smile => (
<Jsme height="100px" width="100px" options="depict,useopenchemlib" smiles={smile} />
),
},
{
title: 'Compound name',
dataIndex: 'Compound name',
key: 'Compound name',
},
{
title: 'Type',
dataIndex: 'Type',
key: 'Type',
},
{
title: 'Action',
dataIndex: 'Action',
key: 'Action',
},
{
title: 'Parameter',
dataIndex: 'Parameter',
key: 'Parameter',
},
{
title: 'Value',
dataIndex: 'Value',
key: 'Value',
},
{
title: 'References',
dataIndex: 'References',
key: 'References',
render: References => (
<span>
{References.map(item => {
return (
<Tag color="blue" key={item} onClick={()=>{this.getReferences(item)}} >
{item.toUpperCase()}
</Tag>
);
})}
</span>
),
},
];
const columnsMutation = [
{
title: 'Generic number',
dataIndex: 'Generic',
key: 'Generic',
},
{
title: 'Position',
dataIndex: 'Position',
key: 'Position',
},
{
title: 'Segment',
dataIndex: 'Segment',
key: 'Segment',
},
{
title: 'Mutation',
dataIndex: 'Mutation',
key: 'Mutation',
},
{
title: 'Ligand',
dataIndex: 'Ligand',
key: 'Ligand',
render: Ligand => (
<Popover content={ <div>
<Jsme height="100px" width="100px" options="depict,useopenchemlib" smiles={Ligand.smile} />
</div>}>
{Ligand.name!=''&&(<Button type="primary">{Ligand.name}</Button>)}
</Popover>
),
},
{
title: 'Activity type',
dataIndex: 'Activity type',
key: 'Activity type',
},
{
title: 'Activity value',
dataIndex: 'Activity value',
key: 'Activity value',
},
{
title: 'Foldchange',
dataIndex: 'Foldchange',
key: 'Foldchange',
defaultSortOrder: 'descend',
sorter: (a, b) => a.Foldchange-b.Foldchange
},
// {
// title: 'Year of approval',
// dataIndex: 'Year of approval',
// key: 'Year of approval',
// },
{
title: 'Reference',
dataIndex: 'Reference',
render: Reference => (
<span>
{Reference.map(item => {
return (
<Tag color="blue" key={item} onClick={()=>{this.getReferences(item)}} >
{item.toUpperCase()}
</Tag>
);
})}
</span>
),
},
];
return (
<div className='search-details-div'>
<Modal
footer={null} closable={false}
width={850}
visible={visible}
wrapClassName="vertical-center-modal"
onCancel={() => this.setState({visible: false})}>
<div className='Molstar-div'>
<Molstar pdbId={pdbId} />
</div>
</Modal>
<Spin tip="Loading..." size='large' spinning={this.state.loading}>
<Card hoverable>
<div >
<div className='title-div'>
{targetsDetail.name}
</div>
<div className='title-div-top'>
<div className='DataList-left'>
<div >
<div className='div-list'>
<div className='list-one'>
<div>Gene name</div>
<div >
</div>
{targetsDetail['Gene name']}
</div>
<div className='list-one'>
<div>Species</div>
<div >
</div>
{targetsDetail.Species}
</div>
<div className='list-one'>
<div>Uniprot id</div>
<div >
</div>
{targetsDetail['Uniport id']}
</div>
<div className='list-one'>
<div>Class</div>
<div >
</div>
{targetsDetail.Class}
</div>
<div className='list-one'>
<div>Family</div>
<div >
</div>
{targetsDetail.Family}
</div>
</div>
</div>
</div>
</div>
</div>
</Card>
{/* {PanelList} */}
<Collapse defaultActiveKey={['1','2','3','4','5']} onChange={this.callback}>
<Panel header="Sequence" key="1">
<div className='Sequence-div'>
{targetsDetail.Sequence.map((item,index)=>{
// console.log(item);
// console.log(Object.entries(item));
return(
<div className='Sequenceone-div'>
{Object.entries(item)[0][0]}
<div className='zimu-div'>
{Object.entries(item)[0][1].map((item2,index)=>{
console.log(item2);
return(
<Tooltip placement="top" title={item2.title}>
<div className={'res-color-'+item2.thum}>
{item2.thum}
</div>
</Tooltip>
)
})}
</div>
</div>
)
})
}
</div>
</Panel>
<Panel header="Structure" key="2">
<Tabs defaultActiveKey="0" type="card" tabPosition='left'>
{
targetsDetail.Structure.map((item,index)=>{
return(
<TabPane tab={(item.pdb)} key={index}>
<div className='Molstar-div2'>
<Molstar pdbId={item.pdb} />
</div>
</TabPane>
)
})
}
</Tabs>
</Panel>
<Panel header="Mutation" key="3">
<div className='Radio-div'>
<Radio.Group onChange={this.onChangeRadio} value={this.state.statusMutation}>
<Radio value={0}>Full data</Radio>
<Radio value={1}>Increase only</Radio>
<Radio value={2}>Decrease only</Radio>
</Radio.Group>
</div>
<Table
bordered
rowKey='item'
dataSource={OLDMutationList}
pagination={false}
columns={columnsMutation}
/>
</Panel>
<Panel header="Drug & Clinical imformation" key="4">
<Table
bordered
rowKey='item'
dataSource={targetsDetail['Drugs information']}
pagination={false}
columns={columnsDrug}
/>
</Panel>
<Panel header="Bioassay" key="5">
<Table
bordered
rowKey='item'
dataSource={targetsDetail.Bioassay}
pagination={false}
columns={columnsBioassay}
/>
</Panel>
</Collapse>
</Spin>
</div>
)
}
}
import React from "react";
import {
Form,
Input,
Button,
Select,
Tabs,
message,
Radio,
Checkbox,
Row,
Col,
Card
} from "antd";
import LogoTitlte from "../../components/LogoTitlte/index";
import { Jsme } from "jsme-react";
import qs from "qs";
import request from "../../utils/request";
import "./style.css";
const { TabPane } = Tabs;
const { Option } = Select;
const { Meta } = Card;
class Home extends React.Component {
state = {
select_db: "Ligands",
data: "",
page: 1,
page_size: 10,
data_type: "smile",
target_class: "",
// target_families:'',
searchData: {
antibodyName: "",
species: "",
antibodyType: "",
antigenName: "",
clinicalIndication: "",
companies: "",
status: "",
pageNum: 1,
pageSize: 10,
},
disabled: true,
loading: false,
SelectList: [],
AntibodyTypeList: [],
StatusList: [],
draw: false,
classList: [],
classData: "All Class",
allClassList: {},
childClassList: [],
list: [
{
name: "general search",
state: true,
searchType: 1,
},
{
name: "cdr search",
state: false,
searchType: 2,
},
],
};
componentDidMount() {
// this.getList()
// this.getSelectList()
// this.getClassList();
}
getantibodyName = (e) => {
const { value } = e.target;
let searchData = this.state.searchData;
searchData.antibodyName = value;
this.setState(() => ({ searchData: searchData }));
};
getAntigenName = (e) => {
const { value } = e.target;
let searchData = this.state.searchData;
searchData.antigenName = value;
this.setState(() => ({ searchData: searchData }));
};
getClinicalIndication = (e) => {
const { value } = e.target;
let searchData = this.state.searchData;
searchData.clinicalIndication = value;
this.setState(() => ({ searchData: searchData }));
};
getCompanies = (e) => {
const { value } = e.target;
let searchData = this.state.searchData;
searchData.companies = value;
this.setState(() => ({ searchData: searchData }));
};
getSpecies = (e) => {
let searchData = this.state.searchData;
searchData.species = e;
this.setState(() => ({ searchData: searchData }));
};
getAntibodyType = (e) => {
let searchData = this.state.searchData;
searchData.antibodyType = e;
this.setState(() => ({ searchData: searchData }));
};
getStatus = (e) => {
let searchData = this.state.searchData;
searchData.status = e;
this.setState(() => ({ searchData: searchData }));
};
getValue = (e) => {
const { value } = e.target;
let searchData = this.state.searchData;
searchData.antibodyName = value;
this.setState(() => ({ searchData: searchData }));
};
getClassList() {
console.log(qs.parse(this.props.location.search.slice(1)));
this.setState({ loading: true });
request
.get("/common/codes")
.then((res) => {
console.log(res);
if (res.data.code === 0) {
console.log(res.data.data);
this.setState({ SelectList: res.data.data.species });
this.setState({ AntibodyTypeList: res.data.data.antibodyType });
this.setState({ StatusList: res.data.data.status });
this.setState({ loading: false });
} else {
message.error(res.data.msg);
}
})
.catch((err) => {
console.error(err);
});
}
getindication = (e) => {
const { value } = e.target;
let searchData = this.state.searchData;
searchData.indication = value;
this.setState(() => ({ searchData: searchData }));
};
getTargetData = (e) => {
const { value } = e.target;
let searchData = this.state.searchData;
searchData.target_data = value;
this.setState(() => ({ searchData: searchData }));
};
onChangeRadio = (e) => {
console.log(e.target.value);
let value = e.target.value;
let searchData = this.state.searchData;
searchData.pdb_status = value;
this.setState({
searchData: searchData,
});
};
SearchIndication = () => {
let data = {
clinicalIndication: this.state.searchData.clinicalIndication,
};
this.props.history.push({
pathname: "/home/AutoimmuneDiseases",
search: qs.stringify(data),
});
};
getList = () => {
let data = this.state.searchData;
this.props.history.push({
pathname: "/home/StructureSearch",
search: qs.stringify(data),
});
};
getDraw = () => {
this.setState(() => ({ draw: !this.state.draw }));
};
compoundChange = (e) => {
console.log(e);
let searchData = this.state.searchData;
searchData.drugs_type = e;
this.setState(() => ({ searchData: searchData }));
console.log(this.state.searchData);
};
callback = (e) => {
console.log(e);
let searchData = this.state.searchData;
searchData.name = e;
this.setState(() => ({ searchData: searchData }));
console.log(this.state.searchData);
};
getJsme = () => {
console.log(1);
};
getListOne = (e) => {
console.log(1111);
let newList = this.state.list;
console.log(e);
newList.forEach((item, index) => {
item.state = false;
if (e === index) {
item.state = true;
}
});
this.setState({
list: newList,
});
};
render() {
const { list } = this.state;
const formItemLayout = {
labelCol: { span: 8 },
wrapperCol: { span: 12 },
};
const formTailLayout = {
labelCol: { span: 8 },
wrapperCol: { span: 12, offset: 8 },
};
const formTailLayout2 = {
labelCol: { span: 8 },
wrapperCol: { span: 13, offset: 8 },
};
return (
<div className="home">
<LogoTitlte />
<div className="home-div">
<div className="top-div">
{/* <Tabs onChange={this.callback} type="card">
<TabPane tab="search" key="1">
<Button type="primary" onClick={this.getList} >结构搜索</Button>
</TabPane>
<TabPane tab="tools" key="2">
<Button type="primary">docking retrosynthesis</Button>
</TabPane>
</Tabs> */}
<div className="home-top-div">
<div className="left-div">
{list.map((item, index) => {
// return (
// <Button
// type={item.state ? "primary" : ""}
// size="large"
// shape="round"
// onClick={() => this.getListOne(index)}
// key={index}
// >
// {item.name}
// </Button>
// );
})}
</div>
<div className="right-div">
{list[0].state && (
<Button type="primary" onClick={this.getList}>
结构搜索
</Button>
)}
{list[1].state && (
<Button type="primary">docking retrosynthesis</Button>
)}
</div>
</div>
</div>
</div>
<div className="cardLIst">
<Card
hoverable
style={{ width: 240 }}
cover={
<img
alt="example"
src="http://52.83.169.190:3003/images/soluImg2.png"
/>
}
>
<Meta
title="模块"
description="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean"
/>
</Card>
<Card
hoverable
style={{ width: 240 }}
cover={
<img
alt="example"
src="http://52.83.169.190:3003/images/soluImg2.png"
/>
}
>
<Meta
title="模块"
description="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean"
/>
</Card>
<Card
hoverable
style={{ width: 240 }}
cover={
<img
alt="example"
src="http://52.83.169.190:3003/images/soluImg2.png"
/>
}
>
<Meta
title="模块"
description="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean"
/>
</Card>
</div>
</div>
);
}
}
export default Home;
.home .top-div{
/* display: flex; */
justify-content: center;
align-items: center;
padding: 10px 0px;
}
.home .bottom-div{
display: flex;
justify-content: center;
align-items: center;
}
.home .Radio-div{
display: flex;
justify-content: center;
align-items: center;
padding: 10px 0px;
}
.home .isShowDiv{
display: none;
}
.home .top-div label{
font-weight: 600;
font-size: 20px;
}
.home .Radio-div label{
font-size: 18px;
font-weight: 500;
}
.home .Tips-div{
line-height: 28px;
width: 500px;
}
.home .logo-div{
position: inherit;
}
.home .home-top-div{
display: flex;
padding-top: 100px;
}
.home .home-top-div .left-div{
width: 45%;
display: flex;
flex-direction: column;
align-items: center;
}
.home .home-top-div .left-div Button,.home-top-div .right-div Button{
margin-bottom: 100px;
height: 50px;
width: 200px;
}
.home.home-top-div .right-div{
width: 50%;
padding: 20px;
}
.home .home-top-div .right-div .right-div-one{
display: flex;
align-items: center;
width: 100%;
/* justify-content: space-between; */
}
.home .home-top-div .right-div {
display: flex;
align-items: center;
}
.home .cardLIst{
display: flex;
justify-content: space-evenly;
}
\ No newline at end of file
import React from 'react'
import {Layout} from 'antd'
import SiderNav from '../../components/SiderNav'
import ContentMain from '../../components/ContentMain'
import HeaderBar from '../../components/HeaderBar'
const {Sider, Header, Content, Footer} = Layout
class Index extends React.Component{
state = {
collapsed: false
}
toggle = () => {
// console.log(this) 状态提升后,到底是谁调用的它
this.setState({
collapsed: !this.state.collapsed
})
}
render() {
// 设置Sider的minHeight可以使左右自适应对齐
return (
<div id='page'>
<Layout>
<Sider collapsible
trigger={null}
collapsed={this.state.collapsed}
>
<SiderNav/>
</Sider>
<Layout>
<Header style={{background: '#fff', padding: '0 16px'}}>
<HeaderBar collapsed={this.state.collapsed} onToggle={this.toggle}/>
</Header>
<Content>
<ContentMain/>
</Content>
{/* <Footer></Footer> */}
</Layout>
</Layout>
</div>
);
}
}
export default Index
\ No newline at end of file
import React from 'react'
import { calculateWidth } from '../../utils/utils'
import { withRouter } from 'react-router-dom'
import { inject, observer } from 'mobx-react/index'
import { Form, Input,message } from 'antd'
import PromptBox from '../../components/PromptBox'
import request from '../../utils/request'
import qs from 'qs'
@withRouter @inject('appStore') @observer @Form.create()
class LoginForm extends React.Component {
state = {
focusItem: -1, //保存当前聚焦的input
code: '' //验证码
}
componentDidMount () {
// this.createCode()
}
/**
* 生成验证码
*/
// createCode = () => {
// const ctx = this.canvas.getContext('2d')
// const chars = [1, 2, 3, 4, 5, 6, 7, 8, 9, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'j', 'k', 'l', 'm', 'n', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']
// let code = ''
// ctx.clearRect(0, 0, 80, 39)
// for (let i = 0; i < 4; i++) {
// const char = chars[randomNum(0, 57)]
// code += char
// ctx.font = randomNum(20, 25) + 'px SimHei' //设置字体随机大小
// ctx.fillStyle = '#D3D7F7'
// ctx.textBaseline = 'middle'
// ctx.shadowOffsetX = randomNum(-3, 3)
// ctx.shadowOffsetY = randomNum(-3, 3)
// ctx.shadowBlur = randomNum(-3, 3)
// ctx.shadowColor = 'rgba(0, 0, 0, 0.3)'
// let x = 80 / 5 * (i + 1)
// let y = 39 / 2
// let deg = randomNum(-25, 25)
// /**设置旋转角度和坐标原点**/
// ctx.translate(x, y)
// ctx.rotate(deg * Math.PI / 180)
// ctx.fillText(char, 0, 0)
// /**恢复旋转角度和坐标原点**/
// ctx.rotate(-deg * Math.PI / 180)
// ctx.translate(-x, -y)
// }
// this.setState({
// code
// })
// }
loginSubmit = (e) => {
e.preventDefault()
this.setState({
focusItem: -1
})
this.props.form.validateFields((err, values) => {
// this.props.appStore.toggleLogin(true, {username: values.username})
// const {from} = this.props.location.state || {from: {pathname: '/'}}
// this.props.history.push(from)
if (!err) {
// 表单登录时,若验证码长度小于4则不会验证,所以我们这里要手动验证一次,线上的未修复
// if (this.state.code.toUpperCase() !== values.verification.toUpperCase()) {
// this.props.form.setFields({
// verification: {
// value: values.verification,
// errors: [new Error('验证码错误')]
// }
// })
// return
// }
// console.log();
// const users = this.props.appStore.users
// // 检测用户名是否存在
// const result = users.find(item => item.username === values.username)
// if (!result) {
// this.props.form.setFields({
// username: {
// value: values.username,
// errors: [new Error('用户名不存在')]
// }
// })
// return
// } else {
// //检测密码是否错误
// if (result.passwd !== values.passwd) {
// this.props.form.setFields({
// passwd: {
// value: values.passwd,
// errors: [new Error('密码错误')]
// }
// })
// return
// }
// }
// this.props.appStore.toggleLogin(true, {username: values.username})
// const {from} = this.props.location.state || {from: {pathname: '/'}}
// this.props.history.push(from)
request.post('/pub/login', values)
.then(res => {
console.log(res)
if (res.data.code===200) {
window.localStorage.setItem('token', res.data.result.token)
this.props.appStore.toggleLogin(true, {userAccount: values.userAccount})
const {from} = this.props.location.state || {from: {pathname: '/'}}
this.props.history.push(from)
}
else{
message.error(res.data.message);
}
})
.catch(err => {
console.error(err);
})
}
})
}
register = () => {
this.props.switchShowBox('register')
setTimeout(() => this.props.form.resetFields(), 500)
}
render () {
const {getFieldDecorator, getFieldError} = this.props.form
const {focusItem,} = this.state
return (
<div className={this.props.className}>
<h3 className='title'>管理员登录</h3>
<Form onSubmit={this.loginSubmit}>
<Form.Item help={getFieldError('userAccount') &&
<PromptBox info={getFieldError('userAccount')} width={calculateWidth(getFieldError('userAccount'))}/>}>
{getFieldDecorator('userAccount', {
rules: [{required: true, message: '请输入用户名'}]
})(
<Input
onFocus={() => this.setState({focusItem: 0})}
onBlur={() => this.setState({focusItem: -1})}
maxLength={16}
placeholder='用户名'
addonBefore={<span className='iconfont icon-User' style={focusItem === 0 ? styles.focus : {}}/>}/>
)}
</Form.Item>
<Form.Item help={getFieldError('userPwd') &&
<PromptBox info={getFieldError('userPwd')} width={calculateWidth(getFieldError('userPwd'))}/>}>
{getFieldDecorator('userPwd', {
rules: [{required: true, message: '请输入密码'}]
})(
<Input
onFocus={() => this.setState({focusItem: 1})}
onBlur={() => this.setState({focusItem: -1})}
type='userPwd'
maxLength={16}
placeholder='密码'
addonBefore={<span className='iconfont icon-suo1' style={focusItem === 1 ? styles.focus : {}}/>}/>
)}
</Form.Item>
{/* <Form.Item help={getFieldError('verification') &&
<PromptBox info={getFieldError('verification')} width={calculateWidth(getFieldError('verification'))}/>}>
{getFieldDecorator('verification', {
validateFirst: true,
rules: [
{required: true, message: '请输入验证码'},
{
validator: (rule, value, callback) => {
if (value.length >= 4 && code.toUpperCase() !== value.toUpperCase()) {
callback('验证码错误')
}
callback()
}
}
]
})(
<Row>
<Col span={15}>
<Input
onFocus={() => this.setState({focusItem: 2})}
onBlur={() => this.setState({focusItem: -1})}
maxLength={4}
placeholder='验证码'
addonBefore={<span className='iconfont icon-securityCode-b'
style={focusItem === 2 ? styles.focus : {}}/>}/>
</Col>
<Col span={9}>
<canvas onClick={this.createCode} width="80" height='39' ref={el => this.canvas = el}/>
</Col>
</Row>
)}
</Form.Item> */}
<div className='bottom'>
<input className='loginBtn' type="submit" value='登录'/>
{/* <span className='registerBtn' onClick={this.register}>注册</span> */}
</div>
</Form>
<div className='footer'>
<div>欢迎登陆雅深智慧平台</div>
</div>
</div>
)
}
}
const styles = {
focus: {
width: '20px',
opacity: 1
},
}
export default LoginForm
\ No newline at end of file
import React from 'react'
import { Form, Input, message } from 'antd'
import { inject, observer } from 'mobx-react/index'
import { calculateWidth } from '../../utils/utils'
import PromptBox from '../../components/PromptBox'
@inject('appStore') @observer @Form.create()
class RegisterForm extends React.Component {
state = {
focusItem: -1
}
registerSubmit = (e) => {
e.preventDefault()
this.setState({
focusItem: -1
})
this.props.form.validateFields((err, values) => {
if (!err) {
const users = this.props.appStore.users
// 检测用户名是否存在
const result = users.find(item => item.username === values.registerUsername)
if (result) {
this.props.form.setFields({
registerUsername: {
value: values.registerUsername,
errors: [new Error('用户名已存在')]
}
})
return
}
const obj = [...this.props.appStore.users, {
username: values.registerUsername,
password: values.registerPassword
}]
localStorage.setItem('users', JSON.stringify(obj))
this.props.appStore.initUsers()
message.success('注册成功')
}
})
}
gobackLogin = () => {
this.props.switchShowBox('login')
setTimeout(() => this.props.form.resetFields(), 500)
}
render () {
const {getFieldDecorator, getFieldError, getFieldValue} = this.props.form
const {focusItem} = this.state
return (
<div className={this.props.className}>
<h3 className='title'>管理员注册</h3>
<Form onSubmit={this.registerSubmit}>
<Form.Item help={getFieldError('registerUsername') && <PromptBox info={getFieldError('registerUsername')}
width={calculateWidth(getFieldError('registerUsername'))}/>}>
{getFieldDecorator('registerUsername', {
validateFirst: true,
rules: [
{required: true, message: '用户名不能为空'},
{pattern: '^[^ ]+$', message: '不能输入空格'},
]
})(
<Input
onFocus={() => this.setState({focusItem: 0})}
onBlur={() => this.setState({focusItem: -1})}
maxLength={16}
placeholder='用户名'
addonBefore={<span className='iconfont icon-User' style={focusItem === 0 ? styles.focus : {}}/>}/>
)}
</Form.Item>
<Form.Item help={getFieldError('registerPassword') && <PromptBox info={getFieldError('registerPassword')}
width={calculateWidth(getFieldError('registerPassword'))}/>}>
{getFieldDecorator('registerPassword', {
validateFirst: true,
rules: [
{required: true, message: '密码不能为空'},
{pattern: '^[^ ]+$', message: '密码不能有空格'}
]
})(
<Input
onFocus={() => this.setState({focusItem: 1})}
onBlur={() => this.setState({focusItem: -1})}
type='password'
maxLength={16}
placeholder='密码'
addonBefore={<span className='iconfont icon-suo1' style={focusItem === 1 ? styles.focus : {}}/>}/>
)}
</Form.Item>
<Form.Item help={getFieldError('confirmPassword') && <PromptBox info={getFieldError('confirmPassword')}
width={calculateWidth(getFieldError('confirmPassword'))}/>}>
{getFieldDecorator('confirmPassword', {
validateFirst: true,
rules: [
{required: true, message: '请确认密码'},
{
validator: (rule, value, callback) => {
if (value && value !== getFieldValue('registerPassword')) {
callback('两次输入不一致!')
}
callback()
}
},
]
})(
<Input
onFocus={() => this.setState({focusItem: 2})}
onBlur={() => this.setState({focusItem: -1})}
type='password'
maxLength={16}
placeholder='确认密码'
addonBefore={<span className='iconfont icon-suo1' style={focusItem === 2 ? styles.focus : {}}/>}/>
)}
</Form.Item>
<div className='bottom'>
<input className='loginBtn' type="submit" value='注册'/>
<span className='registerBtn' onClick={this.gobackLogin}>返回登录</span>
</div>
</Form>
<div className='footer'>
<div>欢迎登陆后台管理系统</div>
</div>
</div>
)
}
}
const styles = {
focus: {
width: '20px',
opacity: 1
},
}
export default RegisterForm
\ No newline at end of file
import React from 'react'
import BGParticle from '../../utils/BGParticle'
import { notification } from 'antd'
import './style.css'
import { withRouter } from 'react-router-dom'
import { inject, observer } from 'mobx-react/index'
import Loading2 from '../../components/Loading2'
import {preloadingImages} from '../../utils/utils'
import LogoTitlte from '../../components/LogoTitlte/index'
import 'animate.css'
import LoginForm from './LoginForm'
import RegisterForm from './RegisterForm'
const url = 'http://47.99.130.140/imgs/wallhaven-g83v2e.jpg'
const imgs = [
'http://47.99.130.140/imgs/wallhaven-p8r1e9.jpg',
'http://47.99.130.140/imgs/wallhaven-e7zyy8.jpg',
'http://47.99.130.140/imgs/wallhaven-6k9e7q.jpg',
'http://47.99.130.140/imgs/photo.jpg',
]
@withRouter @inject('appStore') @observer
class Login extends React.Component {
state = {
showBox: 'login', //展示当前表单
url: '', //背景图片
loading:false,
loading2:false,
}
componentDidMount () {
const isLogin = this.props.appStore
if(isLogin){
this.props.history.go(1) //当浏览器用后退按钮回到登录页时,判断登录页是否登录,是登录就重定向上个页面
// this.props.appStore.toggleLogin(false) //也可以设置退出登录
}
// this.initPage()
// preloadingImages(imgs) //预加载下一个页面的图片,预加载了第二次为什么还会去请求图片资源?
}
componentWillUnmount () {
this.particle && this.particle.destory()
notification.destroy()
}
//载入页面时的一些处理
initPage = () => {
this.setState({
loading:true
})
this.props.appStore.initUsers()
this.loadImageAsync(url).then(url=>{
this.setState({
loading:false,
url
})
}).then(()=>{
//为什么写在then里?id为backgroundBox的DOM元素是在loading为false时才有,而上面的setState可能是异步的,必须等到setState执行完成后才去获取dom
this.particle = new BGParticle('backgroundBox')
this.particle.init()
// notification.open({
// message:<ul><li>初始账号:admin</li><li>初始密码:admin</li></ul>,
// duration:0,
// className:'login-notification'
// })
})
}
//切换showbox
switchShowBox = (box) => {
this.setState({
showBox: box
})
}
//登录的背景图太大,等载入完后再显示,实际上是图片预加载,
loadImageAsync (url) {
return new Promise(function(resolve, reject) {
const image = new Image();
image.onload = function() {
resolve(url);
};
image.onerror = function() {
console.log('图片载入错误')
};
image.src = url;
});
}
render () {
const {showBox,loading} = this.state
return (
<div className='index-div'>
<LogoTitlte></LogoTitlte>
<div id='login-page'>
<div className='home-page-div'>
<div>Yashen API 是一个集成了化学、生物学、计算化学、计算生物学和机器学习的数据驱动的药物发现平台,帮助药物化学家在药物智能发现领域大展身手。</div>
<div> 我们的抗体平台专注于挖掘抗原表位序列和结构,抗体CDR序列,抗原和抗体相互作用的数据,并通过机器学习和计算机模拟理性设计发现高质量的抗体药物。</div>
<div> Yashen API is a data-driven drug discovery platform, which integrates chemistry, biology, computational chemistry, computational biology and machine learning to empower medicinal chemists to make intelligence drug discovery decisions. </div>
<div>Our antibody platform focuses on mining available antigen epitope sequences and structures, antibody sequences and structures, antigen-antibody interactions, and developing various computational tools to discover high quality antibody drugs.</div>
</div>
{
loading ?
<div>
<h3 style={styles.loadingTitle} className='animated bounceInLeft'>载入中...</h3>
<Loading2/>
</div>:
<div>
<div id='backgroundBox' style={styles.backgroundBox}/>
<div className='container'>
<LoginForm
className={showBox === 'login' ? 'box showBox' : 'box hiddenBox'}
switchShowBox={this.switchShowBox}/>
<RegisterForm
className={showBox === 'register' ? 'box showBox' : 'box hiddenBox'}
switchShowBox={this.switchShowBox}/>
</div>
</div>
}
</div>
</div>
)
}
}
const styles = {
backgroundBox: {
position: 'fixed',
top: '0',
left: '0',
width: '100vw',
height: '100vh',
// backgroundImage: `url(${url})`,
backgroundSize: 'cover',
transition:'all .5s',
// backgroundColor: '#4FA1D9'
},
focus: {
// transform: 'scale(0.7)',
width: '20px',
opacity: 1
},
loadingBox:{
position:'fixed',
top:'50%',
left:'50%',
transform:'translate(-50%,-50%)'
},
loadingTitle:{
position:'fixed',
top:'50%',
left:'50%',
marginLeft: -45,
marginTop: -18,
color:'#000',
fontWeight:500,
fontSize:24
},
}
export default Login
#login-page{
position: fixed;
display: flex;
justify-content: center;
align-items: center;
top: 0;
left: 0;
width: 100%;
height: 100%;
background:#fff;
z-index: 99;
min-width: 1000px;
min-height: 1000px;
}
#login-page .container{
position: relative;
width: 240px;
height: 300px;
padding: 100px 40px 40px 40px;
box-sizing: content-box;
}
#login-page .box{
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
padding: 90px 40px 40px 40px;
backface-visibility: hidden;
/* background: linear-gradient(230deg, rgba(53, 57, 74, 0) 0%, rgb(0, 0, 0) 100%); */
background-color:rgb(0, 0, 0) ;
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='rgba(53, 57, 74, 0)', endColorstr='rgb(0, 0, 0)',GradientType=1 );
box-shadow: -15px 15px 15px rgba(0,0,0,.4);
transition: all 1s;
}
#login-page .showBox{
transform:rotateY(0deg);
}
#login-page .hiddenBox{
transform:rotateY(180deg);
}
#login-page .loginBtn{
padding: 10px 50px;
border: 2px solid #4FA1D9;
border-radius: 50px;
background: transparent;
font-size: 11px;
color: #4FA1D9;
transition: all .2s;
}
#login-page .bottom{
display: flex;
height: 42px;
justify-content: space-between;
align-items: center;
}
#login-page .registerBtn{
color: #D3D7F7;
}
#login-page .registerBtn:hover{
color: #4FA1D9;
cursor: pointer;
}
#login-page .loginBtn:hover{
color: white;
background: #4FA1D9;
cursor: pointer;
}
#login-page .title{
height: 60px;
color:#D3D7F7;
font-size: 16px;
margin-bottom: 0;
}
#login-page .footer{
position: absolute;
bottom: 20px;
left: 35px;
width: 250px;
color: #D3D7F7;
font-size: 10px;
}
/*覆盖antd的默认样式*/
#login-page input{
color:#61BFFF;
border:none;
outline: none;
box-shadow: none;
background: transparent;
}
#login-page .ant-input-group-addon{
background: transparent;
padding:0;
border: none;
color: #fff;
opacity: 0.8;
}
#login-page .ant-input-group-addon .iconfont{
display: inline-block;
width: 30px;
transition: all .3s;
opacity: 0.6;
}
#login-page .ant-form-item{
margin-bottom: 10px;
}
#login-page .ant-form-explain{
position: absolute;
z-index: 99;
left:110%;
top:0;
height: 41px;
/*box-shadow: -2px 2px 2px rgba(0,0,0,.3);*/
}
.login-notification{
background: transparent;
border:1px solid #D3D7F7;
color:#D3D7F7;
width: 250px;
height: 80px;
float: right;
margin-right: 20px;
}
.login-notification .ant-notification-notice-message{
color:#D3D7F7;
}
.login-notification .ant-notification-notice-close{
color:#D3D7F7;
}
.home-page-div{
width: 50%;
padding: 50px;
box-sizing: border-box;
font-weight: 500;
font-size: 18px;
/* background-color: pink!important; */
}
.home-page-div div{
margin-bottom: 10px;
}
/*更改谷歌浏览器input背景*/
input:-webkit-autofill,
input:-webkit-autofill:hover,
input:-webkit-autofill:focus,
input:-webkit-autofill:active {
/*延迟背景颜色载入*/
-webkit-transition-delay: 99999s;
-webkit-transition: color 99999s ease-out, background-color 99999s ease-out;
}
\ No newline at end of file
import React from 'react'
import { Form, Input, Button, Col, Row, message, notification } from 'antd'
import { withRouter } from 'react-router-dom'
import GVerify from '../../utils/gVerify'
import { inject, observer } from 'mobx-react/index'
import BGParticle from '../../utils/BGParticle'
import './style.css'
@withRouter @inject('appStore') @observer @Form.create()
class LoginForm extends React.Component {
state = {
focusItem: -1,
}
componentDidMount () {
this.verifyCode = new GVerify('v_container')
}
componentWillUnmount () {
this.verifyCode = null
}
loginSubmit = (e) => {
e.preventDefault()
this.setState({
focusItem: -1
})
this.props.form.validateFields((err, values) => {
if (!err) {
const users = this.props.appStore.users
// 检测用户名是否存在
const result = users.find(item => item.username === values.username)
if (!result) {
this.props.form.setFields({
username: {
value: values.username,
errors: [new Error('用户名不存在')]
}
})
return
} else {
//检测密码是否错误
if (result.password !== values.password) {
this.props.form.setFields({
password: {
value: values.password,
errors: [new Error('密码错误')]
}
})
return
}
}
this.props.appStore.toggleLogin(true, {username: values.username})
const {from} = this.props.location.state || {from: {pathname: '/'}}
this.props.history.push(from)
}
})
}
register = () => {
this.props.setShowBox('register')
setTimeout(() => this.props.form.resetFields(), 500)
}
render () {
const {getFieldDecorator} = this.props.form
const {focusItem} = this.state
return (
<div className={this.props.className}>
<div className='owl'>
<div className='hand-left hand' style={focusItem === 1 ? styles.focusHandLeft : {}}/>
<div className='hand-right hand' style={focusItem === 1 ? styles.focusHandRight : {}}/>
<div className='arms-box'>
<div className='arms arms-left' style={focusItem === 1 ? styles.focusArmsLeft : {}}/>
<div className='arms arms-right' style={focusItem === 1 ? styles.focusArmsRight : {}}/>
</div>
</div>
<Form onSubmit={this.loginSubmit}>
<Form.Item>
{getFieldDecorator('username', {
rules: [{required: true, message: '请输入用户名'}]
})(
<Input
placeholder='用户名'
addonBefore={<span className='iconfont icon-User'
style={focusItem === 0 ? styles.focus : {}}/>}
onFocus={() => this.setState({focusItem: 0})}
onBlur={() => this.setState({focusItem: -1})}
size='large'/>
)}
</Form.Item>
<Form.Item>
{getFieldDecorator('password', {
rules: [{required: true, message: '请输入密码'}]
})(
<Input
placeholder='密码'
addonBefore={<span className='iconfont icon-suo1'
style={focusItem === 1 ? styles.focus : {}}/>}
type='password'
onFocus={() => this.setState({focusItem: 1})}
onBlur={() => this.setState({focusItem: -1})}
size='large'/>
)}
</Form.Item>
<Form.Item>
{getFieldDecorator('verification', {
validateFirst: true,
rules: [
{required: true, message: '请输入验证码'},
{
validator: (rule, value, callback) => {
if (value.length >= 4 && !this.verifyCode.validate(value)) {
callback('验证码错误')
}
callback()
}
}
]
})(
<Row gutter={8}>
<Col span={16}>
<Input
placeholder='验证码'
addonBefore={<span className='iconfont icon-securityCode-b'
style={focusItem === 2 ? styles.focus : {}}/>}
onFocus={() => this.setState({focusItem: 2})}
onBlur={() => this.setState({focusItem: -1})}
size='large'/>
</Col>
<Col span={8}>
<div id='v_container' style={{height: 40}}/>
</Col>
</Row>
)}
</Form.Item>
<div className='bottom'>
<span className='registerBtn' onClick={this.register}>注册</span>&emsp;
<Button type='primary' htmlType="submit">登录</Button>
</div>
</Form>
</div>
)
}
}
@inject('appStore') @observer @Form.create()
class RegisterForm extends React.Component {
state = {
focusItem: -1
}
registerSubmit = (e) => {
e.preventDefault()
this.setState({
focusItem: -1
})
this.props.form.validateFields((err, values) => {
if (!err) {
const users = this.props.appStore.users
// 检测用户名是否存在
const result = users.find(item => item.username === values.registerUsername)
if (result) {
this.props.form.setFields({
registerUsername: {
value: values.registerUsername,
errors: [new Error('用户名已存在')]
}
})
return
}
const obj = [...this.props.appStore.users, {
username: values.registerUsername,
password: values.registerPassword
}]
localStorage.setItem('users', JSON.stringify(obj))
this.props.appStore.initUsers()
message.success('注册成功')
}
})
}
gobackLogin = () => {
this.props.setShowBox('login')
setTimeout(() => this.props.form.resetFields(), 500)
}
render () {
const {getFieldDecorator} = this.props.form
const {focusItem} = this.state
return (
<div className={this.props.className}>
<div className='owl'>
<div className='hand-left hand' style={(focusItem === 1 || focusItem === 2) ? styles.focusHandLeft : {}}/>
<div className='hand-right hand' style={(focusItem === 1 || focusItem === 2) ? styles.focusHandRight : {}}/>
<div className='arms-box'>
<div className='arms arms-left' style={(focusItem === 1 || focusItem === 2) ? styles.focusArmsLeft : {}}/>
<div className='arms arms-right' style={(focusItem === 1 || focusItem === 2) ? styles.focusArmsRight : {}}/>
</div>
</div>
<Form onSubmit={this.registerSubmit} className='registerSubmit'>
<Form.Item>
{getFieldDecorator('registerUsername', {
validateFirst: true,
rules: [
{required: true, message: '用户名不能为空'},
{pattern: '^[^ ]+$', message: '不能输入空格'},
]
})(
<Input
placeholder='用户名'
addonBefore={<span className='iconfont icon-User'
style={focusItem === 0 ? styles.focus : {}}/>}
onFocus={() => this.setState({focusItem: 0})}
onBlur={() => this.setState({focusItem: -1})}
size='large'/>
)}
</Form.Item>
<Form.Item>
{getFieldDecorator('registerPassword', {
validateFirst: true,
rules: [
{required: true, message: '密码不能为空'},
{pattern: '^[^ ]+$', message: '密码不能有空格'}
]
})(
<Input
placeholder='密码'
addonBefore={<span className='iconfont icon-suo1'
style={focusItem === 1 ? styles.focus : {}}/>}
type='password'
onFocus={() => this.setState({focusItem: 1})}
onBlur={() => this.setState({focusItem: -1})}
size='large'/>
)}
</Form.Item>
<Form.Item>
{getFieldDecorator('confirmPassword', {
validateFirst: true,
rules: [
{required: true, message: '请确认密码'},
{
validator: (rule, value, callback) => {
const {getFieldValue} = this.props.form
if (!getFieldValue('registerPassword')) {
callback('请先输入上面的密码')
}
if (value && value !== getFieldValue('registerPassword')) {
callback('两次输入不一致!')
}
callback()
}
}
]
})(
<Input
placeholder='确认密码'
addonBefore={<span className='iconfont icon-suo1'
style={focusItem === 2 ? styles.focus : {}}/>}
type='password'
onFocus={() => this.setState({focusItem: 2})}
onBlur={() => this.setState({focusItem: -1})}
size='large'/>
)}
</Form.Item>
<div className='bottom'>
<span className='gobackBtn' onClick={this.gobackLogin}>返回登录</span>&emsp;
<Button type='primary' htmlType="submit">注册</Button>
</div>
</Form>
</div>
)
}
}
@withRouter @inject('appStore') @observer
class Login extends React.Component {
state = {
showBox: 'login'
}
componentDidMount () {
this.props.appStore.initUsers()
this.particle = new BGParticle('backgroundBox')
this.particle.init()
notification.open({
message: '初始登录',
duration: 10,
description: (<ul>
<li>账号:admin</li>
<li>密码:admin</li>
</ul>)
})
}
componentWillUnmount(){
this.particle.destory()
}
toggleShowBox = (box) => {
this.setState({
showBox: box
})
}
render () {
const {showBox} = this.state
return (
<div className='login-page' id='login-page'>
<div style={styles.backgroundBox} id='backgroundBox'/>
<div className='container'>
<LoginForm className={showBox === 'login' ? 'login-box-active login-box' : 'login-box-leave login-box'}
setShowBox={this.toggleShowBox}/>
<RegisterForm className={showBox === 'register' ? 'login-box-active login-box' : 'login-box-leave login-box'}
setShowBox={this.toggleShowBox}/>
</div>
</div>
)
}
}
const styles = {
backgroundBox:{
position:'fixed',
top:'0',
left:'0',
width:'100vw',
height:'100vh',
backgroundImage:`url(${require('./img/bg5.jpg')})`,
backgroundSize:'100% 100%'
},
focus: {
transform: 'scale(0.6)',
width: 40
},
focusHandLeft: {
transform: 'translateX(-42px) translateY(-15px) scale(0.7)',
},
focusHandRight: {
transform: 'translateX(42px) translateY(-15px) scale(0.7)',
},
focusArmsLeft: {
transform: 'translateY(-40px) translateX(-40px) scaleX(-1)'
},
focusArmsRight: {
transform: 'translateY(-40px) translateX(40px)'
}
}
export default Login
\ No newline at end of file
.login-page{
position: fixed;
display: flex;
justify-content: center;
align-items: center;
top: 0;
left: 0;
width: 100%;
height: 100%;
background:#666;
z-index: 99;
/*background-color: #f3f3f3;*/
}
.login-page .container{
position: relative;
width:400px;
height: 330px;
}
#login-page .container .login-box{
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
padding: 40px 40px 15px 40px;
background-color: #f0f8ff;
transition: all 1s;
backface-visibility: hidden;
}
#login-page .container .login-box-leave{
transform:rotateY(180deg);
}
#login-page .container .login-box-active{
transform:rotateY(0deg);
}
#login-page .container .login-box .owl{
position: absolute;
top: -100px;
left: 50%;
margin-left: -111px;
width: 211px;
height: 108px;
background-image: url("./img/owl-login.png");
}
#login-page .owl .hand{
position: absolute;
left: 14px;
bottom: -8px;
width: 34px;
height: 34px;
border-radius: 40px;
background-color: #472d20;
transition: .3s ease-out;
transform: scaleY(0.6);
}
#login-page .owl .hand.hand-left{
left: 170px;
}
#login-page .owl .arms-box{
position: absolute;
top: 58px;
height: 41px;
width: 100%;
overflow: hidden;
}
#login-page .owl .arms{
position: absolute;
top: 40px;
width: 40px;
height: 65px;
transition: 0.3s ease-out;
background-image: url("./img/owl-login-arm.png");
}
#login-page .owl .arms-left{
left: 158px;
transform: rotate(20deg) scaleX(-1);
}
#login-page .owl .arms-right{
left: 20px;
transform: rotate(-20deg);
}
#login-page .ant-input{
outline: none;
border:none;
box-shadow: none;
}
#login-page .ant-input-group-addon{
background-color: #6a7989;
padding:0;
border: none;
}
#login-page .iconfont{
display: inline-block;
color: #fff;
width: 50px;
transition: all .3s;
}
#login-page .ant-form-item-with-help{
margin-bottom: 24px;
}
#login-page .ant-form-explain{
position: absolute;
z-index: 99;
left:110%;
top:0;
height: 40px;
width: 120px;
background-color: #fff;
border: 1px solid #CFCFCF;
box-shadow: 0 0 2px 2px rgba(0, 0, 0, 0.1);
line-height: 40px;
padding:0 15px;
color:rgba(0, 0, 0, 0.65);
}
#login-page .registerSubmit .ant-form-explain{
width: 160px;
}
#login-page .ant-form-explain:before{
content:'';
position: absolute;
left: -14px;
top:12px;
width: 0;
height: 0;
border-right: 14px solid #CFCFCF;
border-top: 8px solid transparent;
border-bottom: 8px solid transparent;
}
#login-page .ant-form-explain:after{
content:'';
position: absolute;
left: -13px;
top:12px;
width: 0;
height: 0;
border-right: 14px solid #fff;
border-top: 8px solid transparent;
border-bottom: 8px solid transparent;
}
#login-page .container .login-box .bottom{
padding: 15px 0;
text-align: right;
}
#login-page .login-box .bottom .registerBtn{
color: #999;
}
#login-page .login-box .bottom .register:hover{
cursor: pointer;
}
#login-page .login-box .bottom .gobackBtn{
float: left;
color: #999;
margin-top: 5px;
}
.ProteinView-div .btn-div{
height: 80px;
display: flex;
align-items: center;
justify-content: flex-end;
}
.ProteinView-div .list-div-one .list-div-right span{
font-weight: 500;
color: black;
}
.ProteinView-div .ant-card-extra{
margin-left: initial !important;
font-weight: 500;
}
.ProteinView-div .list-div-one .btn-list span{
font-weight: 500;
color: black;
}
.ProteinView-div .list-div-one .btn-list .right-div {
width: 100%;
}
.ProteinView-div .right-center{
display: flex;
}
.Card-title{
white-space: pre-wrap;
}
import React, { Component } from 'react'
import {Input,Button,Card,message} from 'antd';
import './index.css'
import request from '../../../utils/request'
const { TextArea } = Input;
export default class ProteinView extends Component {
state={
sequence:'',
loading:false,
listData:[
]
}
onChange=(e)=>{
const { value } = e.target;
console.log(value);
this.setState({sequence:value})
}
getList(){
this.setState({loading:true})
request.post('/tool/sequence-alignment',{sequence:this.state.sequence})
.then(res => {
console.log(res)
this.setState({loading:false})
if (res.data.code===0) {
this.setState({listData:res.data.data })
}else{
message.error(res.data.msg);
}
})
.catch(err => {
this.setState({loading:false})
console.error(err);
})
}
render() {
const{listData,loading}=this.state
const ProteinViewList =
<Card loading={loading} className='Card-title' hoverable style={{ width: '100%', marginBottom: '20px',}} >
{
listData.map( (item,index)=> {
return(
<div className='list-div-one Card-title'>
<div className='list-div-right' >
<div className='right-center' >
{
<p key={index}>
<pre> {item}</pre>
</p>
}
</div>
</div>
<div>
</div>
</div>
)
} )
// listData
}
</Card>
return (
<div className='ProteinView-div'>
<div className='title-div' >
Please input your multiple sequence alignment
</div>
<div className='center-div'>
<TextArea
onChange={this.onChange}
placeholder=" Please input your multiple sequence alignment "
style={{height:'200px'}}
/>
</div>
<div className='btn-div'>
<Button type="primary" onClick={()=>this.getList()} disabled={this.state.loading}>Submit</Button>
</div>
{
listData.length>0&& (ProteinViewList)
}
</div>
)
}
}
.ProteinView-div .btn-div{
height: 80px;
display: flex;
align-items: center;
justify-content: flex-end;
}
.ProteinView-div .list-div-one .list-div-right span{
font-weight: 500;
color: black;
}
.ProteinView-div .ant-card-extra{
margin-left: initial !important;
font-weight: 500;
}
.ProteinView-div .list-div-one .btn-list span{
font-weight: 500;
color: black;
}
.ProteinView-div .list-div-one .btn-list .right-div {
width: 100%;
}
.ProteinView-div .right-center{
display: flex;
}
import React, { Component } from 'react'
import {Input,Button,Card,message} from 'antd';
import './index.css'
import request from '../../../utils/request'
const { TextArea } = Input;
export default class ProteinView extends Component {
state={
sequence:'',
loading:false,
listData:{}
}
onChange=(e)=>{
const { value } = e.target;
console.log(value);
this.setState({sequence:value})
}
getList(){
this.setState({loading:true})
request.post('/tool/calc-protein-property',{sequence:this.state.sequence})
.then(res => {
console.log(res)
this.setState({loading:false})
if (res.data.code===0) {
this.setState({listData:res.data.data })
}else{
message.error(res.data.msg);
}
})
.catch(err => {
this.setState({loading:false})
console.error(err);
})
}
render() {
const{listData,loading}=this.state
const ProteinViewList =
<Card loading={loading} hoverable style={{ width: '100%', marginBottom: '20px' }} >
{
Object.entries(listData).map( (item,index)=> {
return(
<div className='list-div-one'>
<div className='list-div-right' >
<div className='right-center' >
<span>{item[0]}</span>
{
<p key={index}>
{item[1]}
</p>
}
</div>
</div>
<div>
</div>
</div>
)
} )
}
</Card>
return (
<div className='ProteinView-div'>
<div className='title-div' >
Please input your sequence
</div>
<div className='center-div'>
<TextArea
onChange={this.onChange}
placeholder=" Please input your sequence"
style={{height:'200px'}}
/>
</div>
<div className='btn-div'>
<Button type="primary" onClick={()=>this.getList()} disabled={this.state.loading}>Submit</Button>
</div>
{
Object.entries(listData).length>0&& (ProteinViewList)
}
</div>
)
}
}
import {observable, action} from 'mobx'
import {isAuthenticated,authenticateSuccess,logout} from '../utils/Session'
class AppStore {
@observable isLogin = !!isAuthenticated() //利用cookie来判断用户是否登录,避免刷新页面后登录状态丢失
@observable users = [] //模拟用户数据库
@observable loginUser = {} //当前登录用户信息
@action toggleLogin(flag,info={}) {
this.loginUser = info //设置登录用户信息
if (flag) {
authenticateSuccess(info.username)
this.isLogin = true
} else {
logout()
this.isLogin = false
}
}
@action initUsers() {
const localUsers = localStorage['users']?JSON.parse(localStorage['users']):[]
this.users = [{username: 'admin', password: 'admin'},...localUsers]
}
}
export default new AppStore()
\ No newline at end of file
import appStore from './appStore'
// import stepFormStore from '../routes/Entry/FormDemo/store'
const store = {
appStore,
// stepFormStore
}
export default store
\ No newline at end of file
import React, {Component} from 'react'
export default function asyncComponent(importComponent) {
class AsyncComponent extends Component {
constructor(props) {
super(props)
this.state = {
component: null
}
}
async componentDidMount() {
const {default: component} = await importComponent()
this.setState({
component: component
})
}
render() {
const C = this.state.component
return C ? <C {...this.props} /> : null
}
}
return AsyncComponent
}
\ No newline at end of file
import {TweenLite,Circ} from "gsap/all";
class BGParticle {
constructor(id) {
this.id = id
this.width = window.innerWidth
this.height = window.innerHeight
this.points = []
this.target = {}
this.canvas = null
this.ctx = null
this.requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame ||
window.webkitRequestAnimationFrame || window.msRequestAnimationFrame
this.cancelAnimationFrame = window.cancelAnimationFrame || window.mozCancelAnimationFrame
}
createCanvas() {
this.canvas = document.createElement('canvas')
this.ctx = this.canvas.getContext('2d')
this.canvas.style.display = 'block' //防止全屏的canvas出现滚动条
this.canvas.width = this.width
this.canvas.height = this.height
this.canvas.style.position = 'fixed'
this.canvas.style.top = '0'
this.canvas.style.left = '0'
document.getElementById(this.id).appendChild(this.canvas)
}
createPoints() {
const {width, height} = this
//创建粒子和粒子的起始位置
for (let x = 0; x < width; x = x + width / 20) {
for (let y = 0; y < height; y = y + height / 20) {
let px = x + Math.random() * width / 20;
let py = y + Math.random() * height / 20;
let p = {x: px, originX: px, y: py, originY: py};
this.points.push(p);
}
}
//给每个粒子添加新属性closest、radius
for (let i = 0; i < this.points.length; i++) {
let closest = [];
let p1 = this.points[i];
for (let j = i + 1; j < this.points.length; j++) {
let p2 = this.points[j]
let placed = false;
for (let k = 0; k < 5; k++) {
if (!placed) {
if (closest[k] === undefined) {
closest[k] = p2;
placed = true;
}
}
}
for (let k = 0; k < 5; k++) {
if (!placed) {
if (this.getDistance(p1, p2) < this.getDistance(p1, closest[k])) {
closest[k] = p2;
placed = true;
}
}
}
}
p1.closest = closest;
p1.radius = 2 + Math.random() * 2
//给粒子添加抖动
this.shakePoint(p1);
}
}
shakePoint(point) {
TweenLite.to(point, 1 + 1 * Math.random(), {
x: point.originX - 50 + Math.random() * 100,
y: point.originY - 50 + Math.random() * 100, ease: Circ.easeInOut,
onComplete: () => {
this.shakePoint(point);
}
});
}
drawPoint(point, ctx) {
if (!point.pointActive) return;
ctx.beginPath();
ctx.arc(point.x, point.y, point.radius, 0, 2 * Math.PI, false);
ctx.fillStyle = 'rgba(156,217,249,' + point.pointActive + ')';
ctx.fill();
}
drawLines(point, ctx) {
if (!point.lineActive) return;
for (let item of point.closest) {
ctx.beginPath();
ctx.moveTo(point.x, point.y);
ctx.lineTo(item.x, item.y);
ctx.strokeStyle = 'rgba(156,217,249,' + point.lineActive + ')';
ctx.stroke();
}
}
getDistance(p1, p2) {
return Math.pow(p1.x - p2.x, 2) + Math.pow(p1.y - p2.y, 2);
}
handleResize() {
this.width = window.innerWidth
this.height = window.innerHeight
this.canvas.width = this.width
this.canvas.height = this.height
}
handleMouseMove(e) {
let posx = 0, posy = 0;
if (e.pageX || e.pageY) {
posx = e.pageX;
posy = e.pageY;
}
else if (e.clientX || e.clientY) {
posx = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
posy = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
}
this.target.x = posx;
this.target.y = posy;
}
init() {
this.createCanvas()
this.createPoints()
this.start()
window.onresize = (e) => this.handleResize(e)
window.onmousemove = (e) => this.handleMouseMove(e)
}
start() {
const {width, height, getDistance, points, ctx, target, requestAnimationFrame} = this
this.ctx.clearRect(0, 0, width, height);
for (let point of points) {
if (Math.abs(getDistance(target, point)) < 4000) {
point.lineActive = 0.3;
point.pointActive = 0.6;
} else if (Math.abs(getDistance(target, point)) < 20000) {
point.lineActive = 0.1;
point.pointActive = 0.3;
} else if (Math.abs(getDistance(target, point)) < 40000) {
point.lineActive = 0.02;
point.pointActive = 0.1;
} else {
point.lineActive = 0;
point.pointActive = 0;
}
this.drawLines(point, ctx)
this.drawPoint(point, ctx);
}
this.myReq = requestAnimationFrame(() => this.start());
}
destory() {
const cancelAnimationFrame = this.cancelAnimationFrame
cancelAnimationFrame(this.myReq)
window.onresize = null
window.onmousemove = null
}
}
export default BGParticle
\ No newline at end of file
import React from 'react'
import Loadable from 'react-loadable'
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'
class LoadingPage extends React.Component {
//类似github页面加载的那个加载条
componentWillMount(){
NProgress.start()
}
componentWillUnmount(){
NProgress.done()
}
render () {
return (
<div/>
)
}
}
const LoadableComponent = (component) => {
return Loadable({
loader: component,
loading: ()=><LoadingPage/>
})
}
export default LoadableComponent
\ No newline at end of file
const LOGIN_COOKIE_NAME = 'sessionId'
export function isAuthenticated () {
return _getCookie(LOGIN_COOKIE_NAME)
}
export function authenticateSuccess (token) {
_setCookie(LOGIN_COOKIE_NAME, token)
}
export function logout () {
_setCookie(LOGIN_COOKIE_NAME, '', 0)
}
function _getCookie (name) {
let start, end
if (document.cookie.length > 0) {
start = document.cookie.indexOf(name + '=')
if (start !== -1) {
start = start + name.length + 1
end = document.cookie.indexOf(';', start)
if (end === -1) {
end = document.cookie.length
}
return unescape(document.cookie.substring(start, end))
}
}
return ''
}
function _setCookie (name, value, expire) {
let date = new Date()
date.setDate(date.getDate() + expire)
document.cookie = name + '=' + escape(value) + '; path=/' +
(expire ? ';expires=' + date.toGMTString() : '')
}
\ No newline at end of file
function GVerify(options) { //创建一个图形验证码对象,接收options对象为参数
this.options = { //默认options参数值
id: "", //容器Id
canvasId: "verifyCanvas", //canvas的ID
width: "100", //默认canvas宽度
height: "30", //默认canvas高度
type: "blend", //图形验证码默认类型blend:数字字母混合类型、number:纯数字、letter:纯字母
code: ""
}
if(Object.prototype.toString.call(options) == "[object Object]"){//判断传入参数类型
for(var i in options) { //根据传入的参数,修改默认参数值
this.options[i] = options[i];
}
}else{
this.options.id = options;
}
this.options.numArr = "0,1,2,3,4,5,6,7,8,9".split(",");
this.options.letterArr = getAllLetter();
this._init();
this.refresh();
}
GVerify.prototype = {
/**版本号**/
version: '1.0.0',
/**初始化方法**/
_init: function() {
var con = document.getElementById(this.options.id);
var canvas = document.createElement("canvas");
this.options.width = con.offsetWidth > 0 ? con.offsetWidth : "100";
this.options.height = con.offsetHeight > 0 ? con.offsetHeight : "30";
canvas.id = this.options.canvasId;
canvas.width = this.options.width;
canvas.height = this.options.height;
canvas.style.cursor = "pointer";
canvas.innerHTML = "您的浏览器版本不支持canvas";
con.appendChild(canvas);
var parent = this;
canvas.onclick = function(){
parent.refresh();
}
},
/**生成验证码**/
refresh: function() {
this.options.code = "";
var canvas = document.getElementById(this.options.canvasId);
if(canvas.getContext) {
var ctx = canvas.getContext('2d');
}else{
return;
}
ctx.textBaseline = "middle";
ctx.fillStyle = randomColor(180, 240);
ctx.fillRect(0, 0, this.options.width, this.options.height);
if(this.options.type == "blend") { //判断验证码类型
var txtArr = this.options.numArr.concat(this.options.letterArr);
} else if(this.options.type == "number") {
var txtArr = this.options.numArr;
} else {
var txtArr = this.options.letterArr;
}
for(var i = 1; i <= 4; i++) {
var txt = txtArr[randomNum(0, txtArr.length)];
this.options.code += txt;
ctx.font = randomNum(this.options.height/2, this.options.height) + 'px SimHei'; //随机生成字体大小
ctx.fillStyle = randomColor(50, 160); //随机生成字体颜色
ctx.shadowOffsetX = randomNum(-3, 3);
ctx.shadowOffsetY = randomNum(-3, 3);
ctx.shadowBlur = randomNum(-3, 3);
ctx.shadowColor = "rgba(0, 0, 0, 0.3)";
var x = this.options.width / 5 * i;
var y = this.options.height / 2;
var deg = randomNum(-30, 30);
/**设置旋转角度和坐标原点**/
ctx.translate(x, y);
ctx.rotate(deg * Math.PI / 180);
ctx.fillText(txt, 0, 0);
/**恢复旋转角度和坐标原点**/
ctx.rotate(-deg * Math.PI / 180);
ctx.translate(-x, -y);
}
/**绘制干扰线**/
for(var i = 0; i < 4; i++) {
ctx.strokeStyle = randomColor(40, 180);
ctx.beginPath();
ctx.moveTo(randomNum(0, this.options.width), randomNum(0, this.options.height));
ctx.lineTo(randomNum(0, this.options.width), randomNum(0, this.options.height));
ctx.stroke();
}
/**绘制干扰点**/
for(var i = 0; i < this.options.width/4; i++) {
ctx.fillStyle = randomColor(0, 255);
ctx.beginPath();
ctx.arc(randomNum(0, this.options.width), randomNum(0, this.options.height), 1, 0, 2 * Math.PI);
ctx.fill();
}
},
/**验证验证码**/
validate: function(code){
var code = code.toLowerCase();
var v_code = this.options.code.toLowerCase();
if(code == v_code){
return true;
}else{
// this.refresh();
return false;
}
}
}
/**生成字母数组**/
function getAllLetter() {
var letterStr = "a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z";
return letterStr.split(",");
}
/**生成一个随机数**/
function randomNum(min, max) {
return Math.floor(Math.random() * (max - min) + min);
}
/**生成一个随机色**/
function randomColor(min, max) {
var r = randomNum(min, max);
var g = randomNum(min, max);
var b = randomNum(min, max);
return "rgb(" + r + "," + g + "," + b + ")";
}
export default GVerify
\ No newline at end of file
// import axios from 'axios';
// axios.defaults.timeout = 15000
// export const request = axios.create({
// baseURL: 'http://52.83.230.236:9001/yszh/1/api/',
// });
import axios from 'axios';
// import { bind } from "file-loader";
axios.defaults.timeout = 15000;
console.log(window.localStorage.getItem('token'));
//设置请求得基准地址
axios.defaults.baseURL = 'http://tcal.atelligence-ai.com/';
const request = axios.create();
//设置请求头
// document.onkeydown = function() {
// var e = window.event || arguments[0];
// if (e.keyCode == 123) {
// return false;
// } else if (e.ctrlKey && e.shiftKey && e.keyCode == 73) {
// return false;
// }
// };
// document.oncontextmenu = function() {
// return false;
// };
// axios.defaults.headers['content-type'] ='application/json';
// request.interceptors.request.use(config => {
// // 给请求头加token的字段,值为token
// config.headers.accessToken = window.localStorage.getItem('token')
// return config
// })
//导出
export default request;
export function yssb () {
}
\ No newline at end of file
class Typing {
constructor(opts) {
this.opts = opts || {};
this.source = opts.source;
this.output = opts.output;
this.delay = opts.delay || 120;
this.chain = {
parent: null,
dom: this.output,
val: []
};
if (!(typeof this.opts.done === 'function')) this.opts.done = function () {
};
}
init() {
//初始化函数
this.chain.val = this.convert(this.source, this.chain.val);
}
convert(dom, arr) {
//将dom节点的子节点转换成数组,
let children = Array.from(dom.childNodes)
for (let i = 0; i < children.length; i++) {
let node = children[i]
if (node.nodeType === 3) {
arr = arr.concat(node.nodeValue.split('')) //将字符串转换成字符串数组,后面打印时才会一个一个的打印
} else if (node.nodeType === 1) {
let val = []
val = this.convert(node, val)
arr.push({
'dom': node,
'val': val
})
}
}
return arr
}
print(dom, val, callback) {
setTimeout(function () {
dom.appendChild(document.createTextNode(val));
callback();
}, this.delay);
}
play(ele) {
//当打印最后一个字符时,动画完毕,执行done
if (!ele.val.length) {
if (ele.parent) this.play(ele.parent);
else this.opts.done();
return;
}
let current = ele.val.shift() //获取第一个元素,同时删除数组中的第一个元素
if (typeof current === 'string') {
this.print(ele.dom, current, () => {
this.play(ele); //继续打印下一个字符
})
} else {
let dom = current.dom.cloneNode() //克隆节点,不克隆节点的子节点,所以不用加参数true
ele.dom.appendChild(dom)
this.play({
parent: ele,
dom,
val: current.val
})
}
}
start() {
this.init();
this.play(this.chain);
}
}
export default Typing
\ No newline at end of file
function accMul(arg1, arg2) {
let m = 0;
const s1 = arg1.toString();
const s2 = arg2.toString();
m += s1.split(".").length > 1 ? s1.split(".")[1].length : 0;
m += s2.split(".").length > 1 ? s2.split(".")[1].length : 0;
return Number(s1.replace(".", "")) * Number(s2.replace(".", "")) / 10 ** m;
}
export function digitUppercase(n) {
const fraction = ['角', '分'];
const digit = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖'];
const unit = [['元', '万', '亿'], ['', '拾', '佰', '仟', '万']];
let num = Math.abs(n);
let s = '';
fraction.forEach((item, index) => {
s += (digit[Math.floor(accMul(num, 10 * 10 ** index)) % 10] + item).replace(/零./, '');
});
s = s || '整';
num = Math.floor(num);
for (let i = 0; i < unit[0].length && num > 0; i += 1) {
let p = '';
for (let j = 0; j < unit[1].length && num > 0; j += 1) {
p = digit[num % 10] + unit[1][j] + p;
num = Math.floor(num / 10);
}
s = p.replace(/(零.)*零$/, '').replace(/^$/, '零') + unit[0][i] + s;
}
return s
.replace(/(零.)*零元/, '元')
.replace(/(零.)+/g, '零')
.replace(/^整$/, '零元整');
}
/**
* 生成指定区间的随机整数
* @param min
* @param max
* @returns {number}
*/
export function randomNum(min, max) {
return Math.floor(Math.random() * (max - min) + min);
}
/**
* 计算提示框的宽度
* @param str
* @returns {number}
*/
export function calculateWidth(arr){
return 30 + arr[0].length*15
}
/**
* 图片预加载
* @param arr
* @constructor
*/
export function preloadingImages(arr) {
arr.forEach(item=>{
const img = new Image()
img.src = item
})
}
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
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