优化版

This commit is contained in:
caishi 2020-04-28 17:23:34 +08:00
parent 6d14b0280a
commit 4bfd4234b5
736 changed files with 118584 additions and 69950 deletions

21
LICENSE
View File

@ -1,21 +0,0 @@
MIT License
Copyright (c) [year] [fullname]
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -26,11 +26,9 @@ MainContentContainer
TODO
待同步
TODO
待同步
1、timer图标样式更换
index.html
WebSSHTimer.css
WebSSHTimer.js
WebSSHTimer.js

View File

@ -76,7 +76,7 @@ function getClientEnvironment(publicUrl) {
// 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: '/react/build/.',
PUBLIC_URL: publicUrl,
}
);
// Stringify all values so we can feed into Webpack DefinePlugin

View File

@ -7,32 +7,41 @@ 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 MonacoWebpackPlugin = require('monaco-editor-webpack-plugin');
const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin');
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);
const env = getClientEnvironment('/');
// 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.s
//devtool: "cheap-module-eval-source-map",
optimization: {
splitChunks: {
chunks: 'async',
// 大于30KB才单独分离成chunk
minSize: 30000,
maxAsyncRequests: 5,
maxInitialRequests: 3,
name: true,
cacheGroups: {
default: {
priority: -20,
reuseExistingChunk: true,
},
vendors: {
name: 'vendors',
test: /[\\/]node_modules[\\/]/,
priority: -10,
chunks: "all"
}
}
},
runtimeChunk: true
},
mode: 'development',
// 开启调试
devtool: "source-map", // 开启调试
devtool: "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.
@ -59,6 +68,7 @@ module.exports = {
output: {
// Add /* filename */ comments to generated require()s in the output.
pathinfo: true,
globalObject: 'this',
// 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.
@ -66,7 +76,7 @@ module.exports = {
// 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,
publicPath,
// Point sourcemap entries to original disk location (format as URL on Windows)
devtoolModuleFilenameTemplate: info =>
path.resolve(info.absoluteResourcePath).replace(/\\/g, '/'),
@ -101,36 +111,11 @@ module.exports = {
// 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]),
// MonacoEditor
// https://github.com/Microsoft/monaco-editor/blob/master/docs/integrate-esm.md
// https://github.com/Microsoft/monaco-editor-webpack-plugin/issues/56
// new MonacoWebpackPlugin(),
],
},
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
@ -151,13 +136,20 @@ module.exports = {
{
test: /\.(js|jsx|mjs)$/,
include: paths.appSrc,
exclude: /node_modules/,
loader: require.resolve('babel-loader'),
options: {
// This is a feature of `babel-loader` for webpack (not Babel itself).
// 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,
"plugins": [
["import", {
"libraryName": "antd",
"libraryDirectory": "es",
"style": "css"
}]
]
},
},
// "postcss" loader applies autoprefixer to our CSS.
@ -200,7 +192,7 @@ module.exports = {
{
test: /\.scss$/,
use: [
require.resolve("style-loader"),
require.resolve('style-loader'),
{
loader: require.resolve("css-loader"),
options: {
@ -239,12 +231,13 @@ module.exports = {
// 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,
inject: false,
template: paths.appHtml,
}),
new InterpolateHtmlPlugin(HtmlWebpackPlugin, env.raw),
// 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:
@ -267,8 +260,10 @@ module.exports = {
// 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$/),
// new MonacoWebpackPlugin(),
],
new MonacoWebpackPlugin({
features: ['!gotoSymbol'],
})
],
// 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: {

View File

@ -1,89 +1,76 @@
'use strict';
// extract-css-assets-webpack-plugin
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 MiniCssExtractPlugin = require('mini-css-extract-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 ParallelUglifyPlugin = require('webpack-parallel-uglify-plugin');
// const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin');
// const TerserPlugin = require('terser-webpack-plugin');
const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin');
const TerserJSPlugin = require('terser-webpack-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
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.');
let publicPath = '/react/build/';
let nodeEnv = process.env.NODE_ENV
if (nodeEnv === 'testBuild') {
publicPath = 'https://testali-cdn.educoder.net/react/build/';
}
// 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('../') }
: {};
if (nodeEnv === 'production') {
publicPath = 'https://ali-cdn.educoder.net/react/build/';
}
const publicUrl = publicPath.slice(0, -1);
const shouldUseSourceMap = process.env.GENERATE_SOURCEMAP !== 'false';
const env = getClientEnvironment(publicPath);
// 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.
// 上线用的
// console.log('publicPath ', publicPath)
module.exports = {
// optimization: {
// minimize: true,
// minimizer: [new TerserPlugin()],
// },
// externals: {
// 'react': 'window.React'
// },
// Don't attempt to continue if there are any errors.
optimization: {
minimizer: [new TerserJSPlugin({}), new OptimizeCSSAssetsPlugin({})],
splitChunks: {
chunks: 'async',
// 大于30KB才单独分离成chunk
minSize: 30000,
maxAsyncRequests: 5,
maxInitialRequests: 3,
name: true,
cacheGroups: {
default: {
minChunks: 2,
priority: -20,
reuseExistingChunk: true,
},
vendors: {
name: 'vendors',
test: /[\\/]node_modules[\\/]/,
priority: -10,
chunks: "all"
}
}
},
runtimeChunk: true
},
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 ? 'nosources-source-map' : false, //正式版
devtool:false,//测试版
// In production, we only want to load the polyfills and the app code.
mode: 'production',
devtool: false,//测试版
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.
// cdn
// publicPath: 'https://shixun.educoder.net/react/build/', //publicPath, https://cdn.educoder.net
// publicPath: 'https://cdn-testeduplus2.educoder.net/react/build/', //publicPath, https://cdn.educoder.net
publicPath: '/react/build/', //publicPath, https://cdn.educoder.net
globalObject: 'this',
filename: './static/js/[name].[contenthash:8].js',
chunkFilename: './static/js/[name].[contenthash:8].chunk.js',
publicPath,
// Point sourcemap entries to original disk location (format as URL on Windows)
devtoolModuleFilenameTemplate: info =>
@ -125,12 +112,6 @@ module.exports = {
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',
@ -165,86 +146,74 @@ module.exports = {
{
test: /\.(js|jsx|mjs)$/,
include: paths.appSrc,
exclude: /node_modules/,
loader: require.resolve('babel-loader'),
options: {
compact: true,
"plugins": [
["import", {
"libraryName": "antd",
"libraryDirectory": "es",
"style": "css"
}]
]
},
},
// 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`.
use: [{
loader: MiniCssExtractPlugin.loader,
options: {
publicPath
},
},
{
loader: require.resolve("css-loader"),
options: {
importLoaders: 1,
sourceMap: shouldUseSourceMap,
},
},
{
loader: require.resolve('postcss-loader'),
options: {
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',
}),
],
},
}
]
},
{
test: /\.scss$/,
use: [
require.resolve("style-loader"),
{
loader: require.resolve("css-loader"),
options: {
importLoaders: 1,
minimize: true,
sourceMap: shouldUseSourceMap,
},
use: [{
loader: MiniCssExtractPlugin.loader,
options: {
publicPath
},
{
loader: require.resolve("sass-loader")
}
},
{
loader: require.resolve("css-loader"),
options: {
importLoaders: 1,
sourceMap: shouldUseSourceMap,
},
},
{
loader: require.resolve("sass-loader")
}
],
},
// "file" loader makes sure assets end up in the `build` folder.
@ -259,7 +228,7 @@ module.exports = {
// by webpacks internal loaders.
exclude: [/\.(js|jsx|mjs)$/, /\.html$/, /\.json$/],
options: {
name: 'static/media/[name].[hash:8].[ext]',
name: 'static/media/[name].[contenthash:8].[ext]',
},
},
// ** STOP ** Are you adding a new loader?
@ -274,10 +243,9 @@ module.exports = {
// <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,
inject: false,
template: paths.appHtml,
minify: {
removeComments: true,
@ -292,48 +260,16 @@ module.exports = {
minifyURLs: true,
},
}),
new InterpolateHtmlPlugin(HtmlWebpackPlugin, env.raw),
// 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,
// }),
//正式版上线后打开去掉debuger和console
// new ParallelUglifyPlugin({
// cacheDir: '.cache/',
// uglifyJS:{
// output: {
// comments: false
// },
// compress: {
// drop_debugger: true,
// drop_console: true
// }
// }
// }),
// Note: this won't work without ExtractTextPlugin.extract(..) in `loaders`.
new ExtractTextPlugin({
filename: cssFilename,
new MiniCssExtractPlugin({
filename: 'static/css/[name].[contenthash:8].css',
chunkFilename: 'static/css/[name].[contenthash:8].chunk.css',
}),
// 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
@ -377,7 +313,11 @@ module.exports = {
// 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$/),
// new MonacoWebpackPlugin(),
new MonacoWebpackPlugin({
features: ['!gotoSymbol'],
}),
new webpack.NamedChunksPlugin(),
new webpack.HashedModuleIdsPlugin()
],
// 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.

View File

@ -1,46 +0,0 @@
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import './indexPlus.css';
import App from './App';
// 加之前main.js 18.1MB
// import { message } from 'antd';
import message from 'antd/lib/message';
import 'antd/lib/message/style/css';
import { AppContainer } from 'react-hot-loader';
import registerServiceWorker from './registerServiceWorker';
import { configureUrlQuery } from 'react-url-query';
import history from './history';
// link the history used in our app to url-query so it can update the URL with it.
configureUrlQuery({ history });
// ----------------------------------------------------------------------------------- 请求配置
window.__useKindEditor = false;
const render = (Component) => {
ReactDOM.render(
<AppContainer {...this.props} {...this.state}>
<Component {...this.props} {...this.state}/>
</AppContainer>,
document.getElementById('root')
);
}
// ReactDOM.render(
// ,
// document.getElementById('root'));
// registerServiceWorker();
render(App);
if (module.hot) {
module.hot.accept('./App', () => { render(App) });
}

15882
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -3,10 +3,9 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@icedesign/base": "^0.2.5",
"@monaco-editor/react": "^2.3.0",
"@novnc/novnc": "^1.1.0",
"antd": "^3.23.2",
"antd": "^3.26.15",
"array-flatten": "^2.1.2",
"autoprefixer": "7.1.6",
"axios": "^0.18.1",
@ -17,102 +16,104 @@
"babel-plugin-syntax-dynamic-import": "^6.18.0",
"babel-preset-react-app": "^3.1.1",
"babel-runtime": "6.26.0",
"bizcharts": "^3.5.5",
"bizcharts": "^3.5.8",
"bundle-loader": "^0.5.6",
"case-sensitive-paths-webpack-plugin": "2.1.1",
"chalk": "1.1.3",
"classnames": "^2.2.5",
"clipboard": "^2.0.4",
"codemirror": "^5.46.0",
"clipboard": "^2.0.6",
"codemirror": "^5.53.0",
"connected-react-router": "4.4.1",
"css-loader": "0.28.7",
"css-loader": "^3.5.2",
"dotenv": "4.0.0",
"dotenv-expand": "4.2.0",
"echarts": "^4.2.0-rc.2",
"echarts": "^4.7.0",
"editor.md": "^1.5.0",
"eslint": "4.10.0",
"eslint-config-react-app": "^2.1.0",
"eslint-loader": "1.9.0",
"eslint-loader": "^4.0.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",
"file-loader": "^6.0.0",
"flv.js": "^1.5.0",
"fs-extra": "3.0.1",
"html-webpack-plugin": "2.29.0",
"html-webpack-plugin": "^4.0.4",
"immutability-helper": "^2.6.6",
"install": "^0.12.2",
"jest": "20.0.4",
"js-base64": "^2.5.1",
"js-base64": "^2.5.2",
"katex": "^0.11.1",
"lodash": "^4.17.15",
"loglevel": "^1.6.1",
"loglevel": "^1.6.8",
"material-ui": "^1.0.0-beta.40",
"md5": "^2.2.1",
"mini-css-extract-plugin": "^0.9.0",
"moment": "^2.23.0",
"monaco-editor": "0.13",
"monaco-editor-webpack-plugin": "^1.8.1",
"npm": "^6.10.1",
"monaco-editor": "^0.20.0",
"monaco-editor-webpack-plugin": "^1.9.0",
"numeral": "^2.0.6",
"object-assign": "4.1.1",
"postcss-flexbugs-fixes": "3.2.0",
"postcss-loader": "2.0.8",
"promise": "8.0.1",
"prop-types": "^15.6.1",
"qs": "^6.6.0",
"qrcode.react": "^1.0.0",
"qs": "^6.9.3",
"quill": "^1.3.7",
"quill-delta-to-html": "^0.11.0",
"raf": "3.4.0",
"rc-form": "^2.1.7",
"rc-pagination": "^1.16.2",
"rc-rate": "^2.4.0",
"rc-form": "^2.4.11",
"rc-pagination": "^1.21.0",
"rc-rate": "^2.6.0",
"rc-select": "^8.0.12",
"rc-tree": "^1.7.11",
"rc-upload": "^2.5.1",
"react": "^16.9.0",
"rc-tree": "^1.15.3",
"rc-upload": "^2.9.4",
"react": "^16.13.1",
"react-color": "^2.18.0",
"react-beautiful-dnd": "^10.0.4",
"react-codemirror": "^1.0.0",
"react-codemirror2": "^6.0.0",
"react-color": "^2.18.0",
"react-codemirror2": "^6.0.1",
"react-content-loader": "^3.1.1",
"react-cookies": "^0.1.1",
"react-dev-utils": "^5.0.0",
"react-dom": "^16.9.0",
"react-hot-loader": "^4.0.0",
"react-datepicker": "^2.14.1",
"react-dev-utils": "^9.2.0-next.80",
"react-dom": "^16.13.1",
"react-hot-loader": "^4.12.20",
"react-infinite-scroller": "^1.2.4",
"react-loadable": "^5.3.1",
"react-monaco-editor": "^0.25.1",
"react-player": "^1.11.1",
"react-player": "^1.15.3",
"react-redux": "5.0.7",
"react-router": "^4.2.0",
"react-router-dom": "^4.2.2",
"react-split-pane": "^0.1.89",
"react-url-query": "^1.4.0",
"redux": "^4.0.0",
"react-split-pane": "^0.1.91",
"react-url-query": "^1.5.0",
"react-zmage": "^0.8.5-beta.31",
"redux": "^4.0.5",
"redux-thunk": "2.3.0",
"rsuite": "^4.0.1",
"sass-loader": "^7.3.1",
"scroll-into-view": "^1.12.3",
"rsuite": "^4.3.4",
"sass-loader": "7.3.1",
"scroll-into-view": "^1.14.2",
"showdown": "^1.9.1",
"showdown-katex": "^0.6.0",
"source-map-support": "^0.5.16",
"showdown-katex": "^0.8.0",
"store": "^2.0.12",
"style-loader": "0.19.0",
"styled-components": "^4.1.3",
"styled-components": "^4.4.1",
"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",
"webpack-parallel-uglify-plugin": "^1.1.0",
"webpack-cli": "^3.3.11",
"webpack-dev-server": "^3.10.3",
"webpack-manifest-plugin": "^2.2.0",
"whatwg-fetch": "2.0.3",
"wrap-md-editor": "^0.2.20"
},
"scripts": {
"start": "node --max_old_space_size=20000 scripts/start.js",
"build": "node --max_old_space_size=15360 scripts/build.js",
"concat": "node scripts/concat.js",
"start": "node --max_old_space_size=15360 scripts/start.js",
"build": "NODE_ENV=production node --max_old_space_size=15360 scripts/build.js",
"test-build": "NODE_ENV=testBuild node --max_old_space_size=15360 scripts/build.js",
"pre-build": "NODE_ENV=preBuild node --max_old_space_size=15360 scripts/build.js",
"gen_stats": "NODE_ENV=production webpack --profile --config=./config/webpack.config.prod.js --json > stats.json",
"ana": "webpack-bundle-analyzer ./stats.json",
"analyze": "npm run build -- --stats && webpack-bundle-analyzer build/bundle-stats.json",
@ -177,14 +178,19 @@
"port": "3007",
"devDependencies": {
"@babel/runtime": "7.0.0-beta.51",
"babel-plugin-import": "^1.11.0",
"babel-plugin-import": "^1.13.0",
"compression-webpack-plugin": "^1.1.12",
"concat": "^1.0.3",
"happypack": "^5.0.1",
"mockjs": "^1.1.0",
"node-sass": "^4.12.0",
"optimize-css-assets-webpack-plugin": "^5.0.3",
"purgecss": "^2.1.2",
"reqwest": "^2.0.5",
"webpack-bundle-analyzer": "^3.0.3",
"webpack-parallel-uglify-plugin": "^1.1.0"
"resize-observer-polyfill": "^1.5.1",
"terser-webpack-plugin": "^2.3.5",
"uglifyjs-webpack-plugin": "^2.2.0",
"webpack": "^4.42.1",
"webpack-bundle-analyzer": "^3.7.0"
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,239 @@
/*******************************************************************************
* KindEditor - WYSIWYG HTML Editor for Internet
* Copyright (C) 2006-2011 kindsoft.net
*
* @author Roddy <luolonghao@gmail.com>
* @site http://www.kindsoft.net/
* @licence http://www.kindsoft.net/license.php
*******************************************************************************/
KindEditor.lang({
imagedirectupload:'本地图片',
more: '切换到更多功能',
less: '切换到简单功能',
source : 'HTML代码',
preview : '预览',
undo : '后退(Ctrl+Z)',
redo : '前进(Ctrl+Y)',
cut : '剪切(Ctrl+X)',
copy : '复制(Ctrl+C)',
paste : '粘贴(Ctrl+V)',
plainpaste : '粘贴为无格式文本',
wordpaste : '从Word粘贴',
selectall : '全选(Ctrl+A)',
justifyleft : '左对齐',
justifycenter : '居中',
justifyright : '右对齐',
justifyfull : '两端对齐',
insertorderedlist : '编号',
insertunorderedlist : '项目符号',
indent : '增加缩进',
outdent : '减少缩进',
subscript : '下标',
superscript : '上标',
formatblock : '段落',
fontname : '字体',
fontsize : '文字大小',
forecolor : '文字颜色',
hilitecolor : '文字背景',
bold : '粗体(Ctrl+B)',
italic : '斜体(Ctrl+I)',
underline : '下划线(Ctrl+U)',
strikethrough : '删除线',
removeformat : '删除格式',
image : '图片',
multiimage : '批量图片上传',
flash : 'Flash',
media : '视音频',
table : '表格',
tablecell : '单元格',
hr : '插入横线',
emoticons : '插入表情',
link : '超级链接',
unlink : '取消超级链接',
fullscreen : '全屏显示',
about : '关于',
print : '打印(Ctrl+P)',
filemanager : '文件空间',
code : '插入程序代码',
map : 'Google地图',
baidumap : '百度地图',
lineheight : '行距',
clearhtml : '清理HTML代码',
pagebreak : '插入分页符',
quickformat : '一键排版',
insertfile : '插入文件',
template : '插入模板',
anchor : '锚点',
yes : '确定',
no : '取消',
close : '关闭',
editImage : '图片属性',
deleteImage : '删除图片',
editFlash : 'Flash属性',
deleteFlash : '删除Flash',
editMedia : '视音频属性',
deleteMedia : '删除视音频',
editLink : '超级链接属性',
deleteLink : '取消超级链接',
editAnchor : '锚点属性',
deleteAnchor : '删除锚点',
tableprop : '表格属性',
tablecellprop : '单元格属性',
tableinsert : '插入表格',
tabledelete : '删除表格',
tablecolinsertleft : '左侧插入列',
tablecolinsertright : '右侧插入列',
tablerowinsertabove : '上方插入行',
tablerowinsertbelow : '下方插入行',
tablerowmerge : '向下合并单元格',
tablecolmerge : '向右合并单元格',
tablerowsplit : '拆分行',
tablecolsplit : '拆分列',
tablecoldelete : '删除列',
tablerowdelete : '删除行',
noColor : '无颜色',
pleaseSelectFile : '请选择文件。',
invalidImg : "请输入有效的URL地址。\n只允许jpg,gif,bmp,png格式。",
invalidMedia : "请输入有效的URL地址。\n只允许swf,flv,mp3,wav,wma,wmv,mid,avi,mpg,asf,rm,rmvb格式。",
invalidWidth : "宽度必须为数字。",
invalidHeight : "高度必须为数字。",
invalidBorder : "边框必须为数字。",
invalidUrl : "请输入有效的URL地址。",
invalidRows : '行数为必选项只允许输入大于0的数字。',
invalidCols : '列数为必选项只允许输入大于0的数字。',
invalidPadding : '边距必须为数字。',
invalidSpacing : '间距必须为数字。',
invalidJson : '服务器发生故障。',
uploadSuccess : '上传成功。',
cutError : '您的浏览器安全设置不允许使用剪切操作,请使用快捷键(Ctrl+X)来完成。',
copyError : '您的浏览器安全设置不允许使用复制操作,请使用快捷键(Ctrl+C)来完成。',
pasteError : '您的浏览器安全设置不允许使用粘贴操作,请使用快捷键(Ctrl+V)来完成。',
ajaxLoading : '加载中,请稍候 ...',
uploadLoading : '上传中,请稍候 ...',
uploadError : '上传错误',
'plainpaste.comment' : '请使用快捷键(Ctrl+V)把内容粘贴到下面的方框里。',
'wordpaste.comment' : '请使用快捷键(Ctrl+V)把内容粘贴到下面的方框里。',
'code.pleaseInput' : '请输入程序代码。',
'link.url' : 'URL',
'link.linkType' : '打开类型',
'link.newWindow' : '新窗口',
'link.selfWindow' : '当前窗口',
'flash.url' : 'URL',
'flash.width' : '宽度',
'flash.height' : '高度',
'flash.upload' : '上传',
'flash.viewServer' : '文件空间',
'media.url' : 'URL',
'media.width' : '宽度',
'media.height' : '高度',
'media.autostart' : '自动播放',
'media.upload' : '上传',
'media.viewServer' : '文件空间',
'image.remoteImage' : '网络图片',
'image.localImage' : '本地上传',
'image.remoteUrl' : '图片地址',
'image.localUrl' : '上传文件',
'image.size' : '图片大小',
'image.width' : '宽',
'image.height' : '高',
'image.resetSize' : '重置大小',
'image.align' : '对齐方式',
'image.defaultAlign' : '默认方式',
'image.leftAlign' : '左对齐',
'image.rightAlign' : '右对齐',
'image.imgTitle' : '图片说明',
'image.upload' : '浏览...',
'image.viewServer' : '图片空间',
'multiimage.uploadDesc' : '允许用户同时上传<%=uploadLimit%>张图片,单张图片容量不超过<%=sizeLimit%>',
'multiimage.startUpload' : '开始上传',
'multiimage.clearAll' : '全部清空',
'multiimage.insertAll' : '全部插入',
'multiimage.queueLimitExceeded' : '文件数量超过限制。',
'multiimage.fileExceedsSizeLimit' : '文件大小超过限制。',
'multiimage.zeroByteFile' : '无法上传空文件。',
'multiimage.invalidFiletype' : '文件类型不正确。',
'multiimage.unknownError' : '发生异常,无法上传。',
'multiimage.pending' : '等待上传',
'multiimage.uploadError' : '上传失败',
'filemanager.emptyFolder' : '空文件夹',
'filemanager.moveup' : '移到上一级文件夹',
'filemanager.viewType' : '显示方式:',
'filemanager.viewImage' : '缩略图',
'filemanager.listImage' : '详细信息',
'filemanager.orderType' : '排序方式:',
'filemanager.fileName' : '名称',
'filemanager.fileSize' : '大小',
'filemanager.fileType' : '类型',
'insertfile.url' : 'URL',
'insertfile.title' : '文件说明',
'insertfile.upload' : '上传',
'insertfile.viewServer' : '文件空间',
'table.cells' : '单元格数',
'table.rows' : '行数',
'table.cols' : '列数',
'table.size' : '大小',
'table.width' : '宽度',
'table.height' : '高度',
'table.percent' : '%',
'table.px' : 'px',
'table.space' : '边距间距',
'table.padding' : '边距',
'table.spacing' : '间距',
'table.align' : '对齐方式',
'table.textAlign' : '水平对齐',
'table.verticalAlign' : '垂直对齐',
'table.alignDefault' : '默认',
'table.alignLeft' : '左对齐',
'table.alignCenter' : '居中',
'table.alignRight' : '右对齐',
'table.alignTop' : '顶部',
'table.alignMiddle' : '中部',
'table.alignBottom' : '底部',
'table.alignBaseline' : '基线',
'table.border' : '边框',
'table.borderWidth' : '边框',
'table.borderColor' : '颜色',
'table.backgroundColor' : '背景颜色',
'map.address' : '地址: ',
'map.search' : '搜索',
'baidumap.address' : '地址: ',
'baidumap.search' : '搜索',
'baidumap.insertDynamicMap' : '插入动态地图',
'anchor.name' : '锚点名称',
'formatblock.formatBlock' : {
h1 : '标题 1',
h2 : '标题 2',
h3 : '标题 3',
h4 : '标题 4',
p : '正 文'
},
'fontname.fontName' : {
'SimSun' : '宋体',
'NSimSun' : '新宋体',
'FangSong_GB2312' : '仿宋_GB2312',
'KaiTi_GB2312' : '楷体_GB2312',
'SimHei' : '黑体',
'Microsoft YaHei' : '微软雅黑',
'Arial' : 'Arial',
'Arial Black' : 'Arial Black',
'Times New Roman' : 'Times New Roman',
'Courier New' : 'Courier New',
'Tahoma' : 'Tahoma',
'Verdana' : 'Verdana'
},
'lineheight.lineHeight' : [
{'1' : '单倍行距'},
{'1.5' : '1.5倍行距'},
{'2' : '2倍行距'},
{'2.5' : '2.5倍行距'},
{'3' : '3倍行距'}
],
'template.selectTemplate' : '可选模板',
'template.replaceContent' : '替换当前内容',
'template.fileList' : {
'1.html' : '图片和文字',
'2.html' : '表格',
'3.html' : '项目编号'
}
}, 'zh_CN');

View File

@ -0,0 +1,71 @@
/*******************************************************************************
* KindEditor - WYSIWYG HTML Editor for Internet
* Copyright (C) 2006-2011 kindsoft.net
*
* @author Roddy <luolonghao@gmail.com>
* @site http://www.kindsoft.net/
* @licence http://www.kindsoft.net/license.php
*******************************************************************************/
KindEditor.plugin('autoheight', function(K) {
var self = this;
//self.autoHeightMode = true;
if (!self.autoHeightMode) {
return;
}
var minHeight;
function hideScroll() {
var edit = self.edit;
var body = edit.doc.body;
edit.iframe[0].scroll = 'no';
body.style.overflowY = 'hidden';
}
function resetHeight() {
var edit = self.edit;
var body = edit.doc.body;
edit.iframe.height(minHeight);
//最高418 超过用滚动条
self.resize(null, Math.max(
(K.IE ? body.scrollHeight : body.offsetHeight) > 385 ? 385+33 : (K.IE ? body.scrollHeight : body.offsetHeight)
+ 33, minHeight));
if( self.height == "418px" ){
edit.iframe[0].scroll = 'yes';
body.style.overflowY = 'auto';
}
else{
hideScroll();
}
}
function init() {
minHeight = K.removeUnit(self.height);
self.edit.afterChange(resetHeight);
hideScroll();
var edit = self.edit;
var body = edit.doc.body;
edit.iframe.height(minHeight);
self.resize(null, Math.max(
((K.IE ? body.scrollHeight : body.offsetHeight) > 250 ? 250 : (K.IE ? body.scrollHeight : body.offsetHeight)) //限制初始化太高的情况
+ 33, minHeight));
}
if (self.isCreated) {
init();
} else {
self.afterCreate(init);
}
});
/*
* 如何实现真正的自动高度
* 修改编辑器高度之后再次获取body内容高度时最小值只会是当前iframe的设置高度这样就导致高度只增不减
* 所以每次获取body内容高度之前先将iframe的高度重置为最小高度这样就能获取body的实际高度
* 由此就实现了真正的自动高度
* 测试chromefirefoxIE9IE8
* */

View File

@ -0,0 +1,56 @@
.ke-content {
font-family: "微软雅黑","宋体";
}
.ke-content pre {
font-size:9pt;
font-family:Courier New,Arial;
border:1px solid #ddd;
border-left:5px solid #6CE26C;
background:#f6f6f6;
padding:5px;
}
.ke-content code {
margin: 0 2px;
padding: 0 5px;
white-space: nowrap;
border: 1px solid #DDD;
background-color: #F6F6F6;
border-radius: 3px;
}
.ke-content pre>code {
margin: 0;
padding: 0;
white-space: pre;
border: none;
background: transparent;
}
.ke-content pre code {
background-color: transparent;
border: none;
}
.ke-content p {
/*margin: 0 0 15px 0;*/
/*margin-bottom:15pt;*/
line-height:1.5;
/*letter-spacing: 1px;*/
}
.ke-content div.ref {border:1px solid #ddd;margin:0 0 10px 0;padding:2px;font-size:9pt;background:#ffe;}
.ke-content div.ref h4 {margin:0;padding:1px 3px;background:#CC9966;color:#fff;font-size:9pt;font-weight:normal;}
.ke-content div.ref .ref_body {margin:0;padding:2px;line-height:20px;color:#666;font-size:9pt;}
.ke-content blockquote{background: none;border: none;padding: 0px;margin: 0 0 0 40px;}
span.at {color:#269ac9;}
span.at a{color:#269ac9;text-decoration: none;}
/*yk*/
.ke-content ol li{list-style-type: decimal;}
.ke-content ul li{list-style-type: disc;}
.ke-content ol,.ke-content ul,.ke-content h1,.ke-content h2,.ke-content h3,.ke-content h4{margin-top:0;margin-bottom: 0;}
.ke-content a{color: #136ec2;}
.ke-content a:link,.ke-content a:visited{text-decoration:none;}

View File

@ -0,0 +1,361 @@
// Generated by CoffeeScript 1.9.0
/*
paste.js is an interface to read data ( text / image ) from clipboard in different browsers. It also contains several hacks.
https://github.com/layerssss/paste.js
*/
(function() {
var $, Paste, createHiddenEditable, dataURLtoBlob;
$ = window.jQuery;
$.paste = function(pasteContainer) {
var pm;
if (typeof console !== "undefined" && console !== null) {
console.log("DEPRECATED: This method is deprecated. Please use $.fn.pastableNonInputable() instead.");
}
pm = Paste.mountNonInputable(pasteContainer);
return pm._container;
};
$.fn.pastableNonInputable = function() {
var el, _i, _len;
for (_i = 0, _len = this.length; _i < _len; _i++) {
el = this[_i];
Paste.mountNonInputable(el);
}
return this;
};
$.fn.pastableTextarea = function() {
var el, _i, _len;
for (_i = 0, _len = this.length; _i < _len; _i++) {
el = this[_i];
Paste.mountTextarea(el);
}
return this;
};
$.fn.pastableContenteditable = function() {
var el, _i, _len;
for (_i = 0, _len = this.length; _i < _len; _i++) {
el = this[_i];
Paste.mountContenteditable(el);
}
return this;
};
dataURLtoBlob = function(dataURL, sliceSize) {
var b64Data, byteArray, byteArrays, byteCharacters, byteNumbers, contentType, i, m, offset, slice, _ref;
if (sliceSize == null) {
sliceSize = 512;
}
if (!(m = dataURL.match(/^data\:([^\;]+)\;base64\,(.+)$/))) {
return null;
}
_ref = m, m = _ref[0], contentType = _ref[1], b64Data = _ref[2];
byteCharacters = atob(b64Data);
byteArrays = [];
offset = 0;
while (offset < byteCharacters.length) {
slice = byteCharacters.slice(offset, offset + sliceSize);
byteNumbers = new Array(slice.length);
i = 0;
while (i < slice.length) {
byteNumbers[i] = slice.charCodeAt(i);
i++;
}
byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
offset += sliceSize;
}
return new Blob(byteArrays, {
type: contentType
});
};
createHiddenEditable = function() {
return $(document.createElement('div')).attr('contenteditable', true).css({
width: 1,
height: 1,
position: 'fixed',
left: -100,
overflow: 'hidden'
});
};
Paste = (function() {
Paste.prototype._target = null;
Paste.prototype._container = null;
Paste.mountNonInputable = function(nonInputable) {
var paste;
paste = new Paste(createHiddenEditable().appendTo(nonInputable), nonInputable);
$(nonInputable).on('click', (function(_this) {
return function() {
return paste._container.focus();
};
})(this));
paste._container.on('focus', (function(_this) {
return function() {
return $(nonInputable).addClass('pastable-focus');
};
})(this));
return paste._container.on('blur', (function(_this) {
return function() {
return $(nonInputable).removeClass('pastable-focus');
};
})(this));
};
Paste.mountTextarea = function(textarea) {
var ctlDown, paste;
if (-1 !== navigator.userAgent.toLowerCase().indexOf('chrome')) {
return this.mountContenteditable(textarea);
}
paste = new Paste(createHiddenEditable().insertBefore(textarea), textarea);
ctlDown = false;
$(textarea).on('keyup', function(ev) {
var _ref;
if ((_ref = ev.keyCode) === 17 || _ref === 224) {
return ctlDown = false;
}
});
$(textarea).on('keydown', function(ev) {
var _ref;
if ((_ref = ev.keyCode) === 17 || _ref === 224) {
ctlDown = true;
}
if (ctlDown && ev.keyCode === 86) {
return paste._container.focus();
}
});
$(paste._target).on('pasteImage', (function(_this) {
return function() {
return $(textarea).focus();
};
})(this));
$(paste._target).on('pasteText', (function(_this) {
return function() {
return $(textarea).focus();
};
})(this));
$(textarea).on('focus', (function(_this) {
return function() {
return $(textarea).addClass('pastable-focus');
};
})(this));
return $(textarea).on('blur', (function(_this) {
return function() {
return $(textarea).removeClass('pastable-focus');
};
})(this));
};
Paste.mountContenteditable = function(contenteditable) {
var paste;
paste = new Paste(contenteditable, contenteditable);
$(contenteditable).on('focus', (function(_this) {
return function() {
return $(contenteditable).addClass('pastable-focus');
};
})(this));
return $(contenteditable).on('blur', (function(_this) {
return function() {
return $(contenteditable).removeClass('pastable-focus');
};
})(this));
};
function Paste(_at__container, _at__target) {
this._container = _at__container;
this._target = _at__target;
this._container = $(this._container);
this._target = $(this._target).addClass('pastable');
this._container.on('paste', (function(_this) {
return function(ev) {
var clipboardData, file, item, reader, text, _i, _j, _len, _len1, _ref, _ref1, _ref2, _ref3, _results;
if (((_ref = ev.originalEvent) != null ? _ref.clipboardData : void 0) != null) {
clipboardData = ev.originalEvent.clipboardData;
if (clipboardData.items) {
_ref1 = clipboardData.items;
for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
item = _ref1[_i];
if (item.type.match(/^image\//)) {
reader = new FileReader();
reader.onload = function(event) {
return _this._handleImage(event.target.result);
};
reader.readAsDataURL(item.getAsFile());
}
if (item.type === 'text/plain') {
item.getAsString(function(string) {
return _this._target.trigger('pasteText', {
text: string
});
});
}
}
} else {
if (-1 !== Array.prototype.indexOf.call(clipboardData.types, 'text/plain')) {
text = clipboardData.getData('Text');
_this._target.trigger('pasteText', {
text: text
});
}
_this._checkImagesInContainer(function(src) {
return _this._handleImage(src);
});
}
}
if (clipboardData = window.clipboardData) {
if ((_ref2 = (text = clipboardData.getData('Text'))) != null ? _ref2.length : void 0) {
return _this._target.trigger('pasteText', {
text: text
});
} else {
_ref3 = clipboardData.files;
_results = [];
for (_j = 0, _len1 = _ref3.length; _j < _len1; _j++) {
file = _ref3[_j];
_this._handleImage(URL.createObjectURL(file));
_results.push(_this._checkImagesInContainer(function() {}));
}
return _results;
}
}
};
})(this));
}
Paste.prototype._handleImage = function(src) {
var loader;
loader = new Image();
loader.onload = (function(_this) {
return function() {
var blob, canvas, ctx, dataURL;
canvas = document.createElement('canvas');
canvas.width = loader.width;
canvas.height = loader.height;
ctx = canvas.getContext('2d');
ctx.drawImage(loader, 0, 0, canvas.width, canvas.height);
dataURL = null;
try {
dataURL = canvas.toDataURL('image/png');
blob = dataURLtoBlob(dataURL);
} catch (_error) {}
if (dataURL) {
return _this._target.trigger('pasteImage', {
blob: blob,
dataURL: dataURL,
width: loader.width,
height: loader.height
});
}
};
})(this);
return loader.src = src;
};
Paste.prototype._checkImagesInContainer = function(cb) {
var img, timespan, _i, _len, _ref;
timespan = Math.floor(1000 * Math.random());
_ref = this._container.find('img');
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
img = _ref[_i];
img["_paste_marked_" + timespan] = true;
}
return setTimeout((function(_this) {
return function() {
var _j, _len1, _ref1, _results;
_ref1 = _this._container.find('img');
_results = [];
for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
img = _ref1[_j];
if (!img["_paste_marked_" + timespan]) {
cb(img.src);
}
//firefox问题处理因为采用了 pastableContenteditable 模式,故只需要删除默认的粘贴
if ($(img).attr('src').startsWith('data:image/')) {
_results.push($(img).remove());
};
}
return _results;
};
})(this), 1);
};
return Paste;
})();
}).call(this);
KindEditor.plugin('paste', function(K) {
var editor = this,
name = 'paste';
if(editor.edit == undefined || editor.edit.iframe == undefined){
return;
}
var contentWindow = editor.edit.iframe[0].contentWindow;
//var contentWindow = editor.iframeDoc;
//var contentWindow = document.getElementsByTagName('iframe')[0].contentWindow;
var nodeBody = contentWindow.document.getElementsByTagName('body')[0];
console.log(nodeBody);
$(nodeBody).pastableContenteditable();
dataURItoBlob = function(dataURI) {
// convert base64/URLEncoded data component to raw binary data held in a string
var byteString;
if (dataURI.split(',')[0].indexOf('base64') >= 0)
byteString = atob(dataURI.split(',')[1]);
else
byteString = unescape(dataURI.split(',')[1]);
// separate out the mime component
var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
// write the bytes of the string to a typed array
var ia = new Uint8Array(byteString.length);
for (var i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
return new Blob([ia], {type:mimeString});
};
$(nodeBody).on('pasteImage', function(ev, data) {
console.log('pasteImage');
console.log("dataURL: " + data.dataURL);
console.log("width: " + data.width);
console.log("height: " + data.height);
var blob = dataURItoBlob(data.dataURL);
if (data.blob !== null) {
var data = new FormData();
// data.append("imgFile",blob, "imageFilename.png");
data.append("file",blob, "imageFilename.png");
console.log(data);
$.ajax({
url: '/kindeditor/upload?dir=image',
url: '/api/attachments.json',
contentType: false,
type: 'POST',
data: data,
processData: false,
success: function(data) {
console.log(data);
// editor.exec('insertimage', JSON.parse(data).url);
// /api/attachments/227362
editor.exec('insertimage', '/api/attachments/' + data.id);
}
});
}
});
return;
});

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -30,6 +30,174 @@
<div class="content unicode" style="display: block;">
<ul class="icon_lists dib-box">
<li class="dib">
<span class="icon iconfont">&#xe748;</span>
<div class="name">多行公式</div>
<div class="code-name">&amp;#xe748;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe747;</span>
<div class="name">行内公式</div>
<div class="code-name">&amp;#xe747;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe746;</span>
<div class="name">取消置顶</div>
<div class="code-name">&amp;#xe746;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe745;</span>
<div class="name">置顶</div>
<div class="code-name">&amp;#xe745;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe744;</span>
<div class="name">新建简历、我的简历</div>
<div class="code-name">&amp;#xe744;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe743;</span>
<div class="name">回复</div>
<div class="code-name">&amp;#xe743;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe742;</span>
<div class="name">图片</div>
<div class="code-name">&amp;#xe742;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe741;</span>
<div class="name">问题列表</div>
<div class="code-name">&amp;#xe741;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe73f;</span>
<div class="name">职称</div>
<div class="code-name">&amp;#xe73f;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe76b;</span>
<div class="name">upload</div>
<div class="code-name">&amp;#xe76b;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe73e;</span>
<div class="name">发布职位</div>
<div class="code-name">&amp;#xe73e;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe73d;</span>
<div class="name">职位要求</div>
<div class="code-name">&amp;#xe73d;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe73c;</span>
<div class="name">公司介绍</div>
<div class="code-name">&amp;#xe73c;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe73b;</span>
<div class="name">公司地址</div>
<div class="code-name">&amp;#xe73b;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe73a;</span>
<div class="name">局部刷新键头</div>
<div class="code-name">&amp;#xe73a;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe739;</span>
<div class="name">返回</div>
<div class="code-name">&amp;#xe739;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe738;</span>
<div class="name">统计</div>
<div class="code-name">&amp;#xe738;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe736;</span>
<div class="name">签到-02</div>
<div class="code-name">&amp;#xe736;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe737;</span>
<div class="name">下箭头</div>
<div class="code-name">&amp;#xe737;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe735;</span>
<div class="name">签到-01</div>
<div class="code-name">&amp;#xe735;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe734;</span>
<div class="name">移动</div>
<div class="code-name">&amp;#xe734;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe732;</span>
<div class="name">下移2</div>
<div class="code-name">&amp;#xe732;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe731;</span>
<div class="name">上移2</div>
<div class="code-name">&amp;#xe731;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe730;</span>
<div class="name">下移</div>
<div class="code-name">&amp;#xe730;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe72f;</span>
<div class="name">上移</div>
<div class="code-name">&amp;#xe72f;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe72e;</span>
<div class="name">编辑</div>
<div class="code-name">&amp;#xe72e;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe72d;</span>
<div class="name">删除</div>
<div class="code-name">&amp;#xe72d;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe72c;</span>
<div class="name">选择</div>
<div class="code-name">&amp;#xe72c;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe72a;</span>
<div class="name">编辑</div>
@ -2012,6 +2180,258 @@
<div class="content font-class">
<ul class="icon_lists dib-box">
<li class="dib">
<span class="icon iconfont icon-duohanggongshi"></span>
<div class="name">
多行公式
</div>
<div class="code-name">.icon-duohanggongshi
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-hangneigongshi"></span>
<div class="name">
行内公式
</div>
<div class="code-name">.icon-hangneigongshi
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-quxiaozhiding"></span>
<div class="name">
取消置顶
</div>
<div class="code-name">.icon-quxiaozhiding
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-zhiding1"></span>
<div class="name">
置顶
</div>
<div class="code-name">.icon-zhiding1
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-xinjianjianliwodejianli"></span>
<div class="name">
新建简历、我的简历
</div>
<div class="code-name">.icon-xinjianjianliwodejianli
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-huifu"></span>
<div class="name">
回复
</div>
<div class="code-name">.icon-huifu
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-tupian"></span>
<div class="name">
图片
</div>
<div class="code-name">.icon-tupian
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-wentiliebiao"></span>
<div class="name">
问题列表
</div>
<div class="code-name">.icon-wentiliebiao
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-zhicheng"></span>
<div class="name">
职称
</div>
<div class="code-name">.icon-zhicheng
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-upload"></span>
<div class="name">
upload
</div>
<div class="code-name">.icon-upload
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-fabuzhiwei"></span>
<div class="name">
发布职位
</div>
<div class="code-name">.icon-fabuzhiwei
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-zhiweiyaoqiu"></span>
<div class="name">
职位要求
</div>
<div class="code-name">.icon-zhiweiyaoqiu
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-gongsijieshao"></span>
<div class="name">
公司介绍
</div>
<div class="code-name">.icon-gongsijieshao
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-gongsidizhi"></span>
<div class="name">
公司地址
</div>
<div class="code-name">.icon-gongsidizhi
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-jubushuaxinjiantou"></span>
<div class="name">
局部刷新键头
</div>
<div class="code-name">.icon-jubushuaxinjiantou
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-fanhui"></span>
<div class="name">
返回
</div>
<div class="code-name">.icon-fanhui
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-tongji1"></span>
<div class="name">
统计
</div>
<div class="code-name">.icon-tongji1
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-qiandao-1"></span>
<div class="name">
签到-02
</div>
<div class="code-name">.icon-qiandao-1
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-xiajiantou2"></span>
<div class="name">
下箭头
</div>
<div class="code-name">.icon-xiajiantou2
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-qiandao-"></span>
<div class="name">
签到-01
</div>
<div class="code-name">.icon-qiandao-
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-yidong"></span>
<div class="name">
移动
</div>
<div class="code-name">.icon-yidong
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-xiayi1"></span>
<div class="name">
下移2
</div>
<div class="code-name">.icon-xiayi1
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-shangyi1"></span>
<div class="name">
上移2
</div>
<div class="code-name">.icon-shangyi1
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-xiayi"></span>
<div class="name">
下移
</div>
<div class="code-name">.icon-xiayi
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-shangyi"></span>
<div class="name">
上移
</div>
<div class="code-name">.icon-shangyi
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-bianji5"></span>
<div class="name">
编辑
</div>
<div class="code-name">.icon-bianji5
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-shanchu3"></span>
<div class="name">
删除
</div>
<div class="code-name">.icon-shanchu3
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-xuanze"></span>
<div class="name">
选择
</div>
<div class="code-name">.icon-xuanze
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-bianji4"></span>
<div class="name">
@ -4939,6 +5359,230 @@
<div class="content symbol">
<ul class="icon_lists dib-box">
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-duohanggongshi"></use>
</svg>
<div class="name">多行公式</div>
<div class="code-name">#icon-duohanggongshi</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-hangneigongshi"></use>
</svg>
<div class="name">行内公式</div>
<div class="code-name">#icon-hangneigongshi</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-quxiaozhiding"></use>
</svg>
<div class="name">取消置顶</div>
<div class="code-name">#icon-quxiaozhiding</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-zhiding1"></use>
</svg>
<div class="name">置顶</div>
<div class="code-name">#icon-zhiding1</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-xinjianjianliwodejianli"></use>
</svg>
<div class="name">新建简历、我的简历</div>
<div class="code-name">#icon-xinjianjianliwodejianli</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-huifu"></use>
</svg>
<div class="name">回复</div>
<div class="code-name">#icon-huifu</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-tupian"></use>
</svg>
<div class="name">图片</div>
<div class="code-name">#icon-tupian</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-wentiliebiao"></use>
</svg>
<div class="name">问题列表</div>
<div class="code-name">#icon-wentiliebiao</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-zhicheng"></use>
</svg>
<div class="name">职称</div>
<div class="code-name">#icon-zhicheng</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-upload"></use>
</svg>
<div class="name">upload</div>
<div class="code-name">#icon-upload</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-fabuzhiwei"></use>
</svg>
<div class="name">发布职位</div>
<div class="code-name">#icon-fabuzhiwei</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-zhiweiyaoqiu"></use>
</svg>
<div class="name">职位要求</div>
<div class="code-name">#icon-zhiweiyaoqiu</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-gongsijieshao"></use>
</svg>
<div class="name">公司介绍</div>
<div class="code-name">#icon-gongsijieshao</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-gongsidizhi"></use>
</svg>
<div class="name">公司地址</div>
<div class="code-name">#icon-gongsidizhi</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-jubushuaxinjiantou"></use>
</svg>
<div class="name">局部刷新键头</div>
<div class="code-name">#icon-jubushuaxinjiantou</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-fanhui"></use>
</svg>
<div class="name">返回</div>
<div class="code-name">#icon-fanhui</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-tongji1"></use>
</svg>
<div class="name">统计</div>
<div class="code-name">#icon-tongji1</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-qiandao-1"></use>
</svg>
<div class="name">签到-02</div>
<div class="code-name">#icon-qiandao-1</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-xiajiantou2"></use>
</svg>
<div class="name">下箭头</div>
<div class="code-name">#icon-xiajiantou2</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-qiandao-"></use>
</svg>
<div class="name">签到-01</div>
<div class="code-name">#icon-qiandao-</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-yidong"></use>
</svg>
<div class="name">移动</div>
<div class="code-name">#icon-yidong</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-xiayi1"></use>
</svg>
<div class="name">下移2</div>
<div class="code-name">#icon-xiayi1</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-shangyi1"></use>
</svg>
<div class="name">上移2</div>
<div class="code-name">#icon-shangyi1</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-xiayi"></use>
</svg>
<div class="name">下移</div>
<div class="code-name">#icon-xiayi</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-shangyi"></use>
</svg>
<div class="name">上移</div>
<div class="code-name">#icon-shangyi</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-bianji5"></use>
</svg>
<div class="name">编辑</div>
<div class="code-name">#icon-bianji5</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-shanchu3"></use>
</svg>
<div class="name">删除</div>
<div class="code-name">#icon-shanchu3</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-xuanze"></use>
</svg>
<div class="name">选择</div>
<div class="code-name">#icon-xuanze</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-bianji4"></use>

File diff suppressed because it is too large Load Diff

3519
public/css/edu-common.css Executable file

File diff suppressed because it is too large Load Diff

4255
public/css/edu-main.css Normal file

File diff suppressed because it is too large Load Diff

2411
public/css/edu-public.css Executable file

File diff suppressed because it is too large Load Diff

6742
public/css/edu-purge.css Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,481 +0,0 @@
/* 头部 */
.header{ width:100%; height:51px;min-width:1200px;background:rgb(23, 22, 22); }
.header_con{ width:1200px; min-width:1200px; height:50px; margin:0 auto;}
.new-logo img{ width:36px; height:36px;margin-top:7px; border-radius:3px; }
.new-logo p{ font-size: 18px; color:#fff; line-height: 50px; }
a.new-nav-a{ display: block; font-size: 14px; line-height: 50px; color:#fff;}
a:hover.new-nav-a{ color:#ff7500; text-decoration: none;}
.header-search{border-radius:3px; background:#fff;}
.header-search a{text-decoration: none; color:#666!important;}
.header-search a:hover{color:#ff7500!important;}
input.header-search-input{ width:150px; height:30px; padding:0 5px; border-style: none; border: none;outline:none;}
.innner-nav{ margin-left:40px;}
.innner-nav li{float:left; margin-right:40px;}
.innner-nav li a{ display: block; color:#fff; padding:0 10px; }
.inner-btnbox02{ width:270px; margin: 30px auto 0;}
.new-container-inner02{width:1200px; margin:0px auto; padding:50px 0;}
.inner-nav-mes{ font-size:16px; color:#fff; margin-right:35px; margin-top:18px; }
.inner-nav-cir{ background:#ff6530; color:#fff; border-radius:15px;padding:0 5px; display: inline-block; font-size:10px; height:17px; line-height:17px;}
.inner-nav-user{ width: 75px; height: 45px; margin-top:5px; position: relative; padding-left: 0px;}
.inner-nav-user-img{ width: 40px; height: 40px; border-radius:50px;}
select.header-search-select{ border:none; font-size:14px; padding:5px; background: none;}
.edu-unlogin-nav a{ color:#fff!important; font-size:14px; line-height:50px;}
.edu-unlogin-nav a:hover{ color:#3b94d6;}
.edu-unlogin-nav{ font-size:12px; color:#fff; line-height:50px;}
.task-user-dropdown{font-size:12px; line-height: 1.9; width:120px; background-color:#fff; border-radius:3px; box-shadow: 0px 2px 8px rgba(146, 153, 169, 0.5); position:relative; top:5px; right:44px; display: none; z-index:999;}
.task-user-dropdown font{ border: 1px solid #dddddd; display: block; border-width: 8px; position: absolute; top: -13px;left:100px; border-style:solid; border-color: transparent transparent #fff transparent;font-size: 0;line-height: 0; box-shadow:2px rgba(146, 153, 169, 0.5); }
.task-user-dropdown-nav { padding-top:5px; }
.task-user-dropdown-nav li { display: inline-block; text-align: center; width:100%; height: 30px; line-height: 30px;}
.task-user-dropdown-nav li:hover{ background:#eee;}
.task-user-dropdown-nav li:hover a{color: #FF7500!important;}
.task-line{ display: block; height: 1px!important; line-height: 1px!important; border-bottom:1px solid #eee; margin:0;}
.inner-nav-user:hover .task-user-dropdown{ display:block;}
dropdown { display: inline-block; height:30px; line-height:1.9; font-size:12px; }
dropdown label, dropdown ul li{ display: block; width:42px; padding:4px 10px; text-align: center;border-radius:3px; color:#666;}
dropdown ul li:hover{background: #eee; color:#666;cursor: pointer;}
dropdown label{color: #666;border-radius: 3px 0 0 3px; position: relative; z-index: 2; width:50px; text-align: center; height:22px;}
dropdown input{display: none;}
dropdown input:checked + label{ background: #fff;color:#666;}
dropdown ul{ position: absolute; visibility: visible; opacity: 1; top: 38px; background: #fff; z-index: 99; border-radius:3px;}
$colors: #fff, #0072B5, #2C3E50;
@for $i from 1 through length($colors) {
dropdown ul li:nth-child(#{$i}) {
border-left: 4px solid nth($colors, $i);
.fa{
color: nth($colors, $i);
}
&:hover {
background: nth($colors, $i);
color: white;
.fa{
color: white;
}
}
}
}
.edu-dropdown{ position: relative; padding:0 15px; }
.edu-dropdown-menu{ background-color:#fff; text-align: center; border-radius:3px; box-shadow: 0px 2px 8px rgba(146, 153, 169, 0.5); position:absolute; top:25px; left:0px; z-index: 999; display:none;}
.edu-dropdown-menu li{ height:30px; line-height:30px; display: block; padding:0 15px; text-align: left;}
.edu-dropdown-menu li label{ cursor: pointer;}
.edu-dropdown-menu li:hover{ color: #FF7500!important;}
/*.edu-dropdown:hover .edu-dropdown-menu{ display: block;}*/
.animate{ -webkit-transition: all .3s; -moz-transition: all .3s; -ms-transition: all .3s; -ms-transition: all .3s;
transition: all .3s; backface-visibility:hidden; -webkit-backface-visibility:hidden; /* Chrome and Safari */ -moz-backface-visibility:hidden; /* Firefox */ -ms-backface-visibility:hidden; /* Internet Explorer */}
/* 底部 */
.footer{width:100%; height:100px; background-color:#fff; }
.footer_con{ width:1200px; height:100px; margin:0 auto; text-align: center; padding:20px 0; }
.footer_con-inner{ width: 300px; margin:0px auto;}
.footer_con-inner li a{ font-size: 16px; color: #888;display: block;padding:0 15px; border-right: solid 1px #888;}
.footer_con-inner li a:hover{text-decoration: underline;}
.footer_con-p{ color: #888; margin-top:10px;}
.inner-footer{ width: 100%; min-width:1200px; background:#323232; padding-bottom:30px;}
.inner-footer_con{ width: 1200px; margin: 0 auto;}
.inner-footer-nav{ height: 50px; border-bottom:1px solid #47494d;}
.inner-footer-nav li a{ float: left; margin-right:15px; font-size: 14px; color: #888; line-height: 50px;}
.saoma-box{ position: relative;}
.saoma-img-box{ position: absolute; top:-300px; left: -86px; border-radius:3px; background:#fff; padding:15px;box-shadow: 0px 2px 8px rgba(146, 153, 169, 0.5); display: none;}
.saoma-box li:hover ul{display:block; }
.img-show{ width:50px; height:50px; border-radius:50px; }
.saoma-img-box font{ border: 1px solid #dddddd; display: block; border-width: 8px; position: absolute; top:289px;left: 103px; border-style:solid; border-color:#fff transparent transparent transparent;font-size: 0;line-height: 0; box-shadow:2px rgba(146, 153, 169, 0.5); }
.inner-footer-p-big{ display: block; height: 50px; line-height: 50px; color:#888; font-size: 16px; border-left:2px solid #888; padding-left:15px;}
.inner-btnbox02{ width:270px; margin: 30px auto 0;}
.new-container-inner02{width:1200px; margin:0px auto; padding:50px 0;}
img.edu-footer-logo{ height: 50px;}
/************布局 byLB****************/
.panel-content{ width: 1200px; margin:20px auto; background:#eaebec;}
.panel-contentss{ width: 1200px; margin:10px auto; margin-bottom:20px; background:#fff;}
/************讨论区20170321 byLB****************/
.panel-inner-fourm{ padding:20px; border-bottom:1px solid #eee;}
.panel-inner-fourm:hover{ background:#EFF9FD;}
.nobg:hover{ background:#fff;}
a.panel-list-title,.panel-list-title { display:inline-block; font-size: 16px; color: #333; font-weight:normal; max-width:82%;}
a:hover.panel-list-title{color:#FF7500;}
.panel-list-img{ width: 60px; height: 60px; border-radius:100px;}
a.panel-name-small{ display: inline-block; max-width:100px; color:#29bd8b; font-size:12px; }
.panel-list-infobox{ width: 92%; margin-left:8%; margin-top:-70px;}
.panel-lightgrey,.panel-lightgrey span{ font-size:12px; color:#888;}
.panel-inner-info{ width: 93%; margin-left:7%;}
.panel-bg-grey{ padding:5px 0;background:#f6f6f6; width: 100%; color:#666;}
.panel-list-nodata{ width: 420px; margin:100px auto; text-align: center;}
/*班级讨论区panel 2017/07/20 cs*/
.panel-content-box{background: #FFFFFF;}
.panel-content-line{width: 90%;margin: 30px 5%;}
.panel-content-line .panel-line-left{width: 8%;text-align: right;}
.panel-content-line .panel-content-label{height: 40px;line-height: 40px}
.panel-content-line .panel-content-input{width: 90%;height: 28px;padding: 5px;}
.panel-content-line .panel-content-ta{width: 90%;min-height: 148px;padding: 5px;}
/* 回复评论 */
.panel-comment_item{ width: 100%; }
.panel-comment_item .t_area{ color:#888;}
.comment_item_cont{ padding:15px; border-bottom:1px solid #e3e3e3;}
.comment_item_cont .J_Comment_Face{height: 50px}
.comment_item_cont .J_Comment_Face img{ width:50px; height:50px; border-radius:100px; }
.panel-comment_item .t_content{ width:93%; margin-left:15px;}
.panel-comment_item a.content-username {font-size:14px; margin-right:15px; display:inline-block; max-width:100px;color: #888888}
.J_Comment_Info{height: 20px;line-height: 22px;}
/*.panel-comment_item a:hover.content-username{color:#FF7500;}*/
.panel-comment_item .orig_user img{width:40px; height:40px;border-radius:100px; }
.panel-comment_item .reply-right{ float:right; position:relative;}
.panel-comment_item .reply_iconup02{ position:absolute; top:22px; left:14px; color:#d4d4d4; font-size:16px; background:#f1f1f1; line-height:13px;}
.panel-comment_item .comment_orig_content{margin:10px 0; color:#999;}
.panel-comment_item .comment_orig_content .comment_orig_content{margin-top:0; color:#666;}
.panel-comment_item .orig_cont{ border:solid 1px #F3DDB3; background:#FFFEF4; padding:4px;color:#999;margin-top:-1px; }
.panel-comment_item .orig_cont_sub{ border-top:0}
.panel-comment_item .comment_orig_content .orig_index{ float:right; color:#666; font-family:Arial; padding-right:5px;line-height:30px;}
.panel-comment_item .comment_orig_content .orig_user{ margin:10px 15px 10px 5px;}
.panel-comment_item .comment_orig_content .orig_user span{ color:#999; padding-right:5px;}
.panel-comment_item .comment_orig_content .orig_content{padding:5px 0px 5px 0px;line-height:24px; color:#333; }
.panel-comment_item .orig_right{ width:80%; margin-top:5px;}
.panel-comment_item .orig_right img{max-width:100%;}
.panel-comment_item a.comment_ding_link{ height:24px;line-height:24px;display:inline-block;padding-left:2px;vertical-align:middle; color:#333; }
.panel-comment_item a:hover.comment_ding_link{ color:#269ac9;}
.panel-comment_item .comment_ding_link span{display: inline-block;padding: 0 0px 0 8px;}
.panel-comment_item .comment_ding_link em{font-style: normal;font-family:arial;}
.panel-comment_item .comment_reply_link{ display:inline-block; width:50px; height:24px;line-height: 24px; vertical-align:middle;text-align: center;}
.panel-comment_item .comment_reply_link:link,.comment_reply_link:visited{color:#333;text-decoration: none;}
.panel-comment_item .comment_content{ color:#666;}
.comment_content img,.orig_content img{max-width: 100%}
.panel-comment_item .t_txt{ margin-top:10px;}
.panel-comment_item .orig_reply_box{border-top:1px solid #e3e3e3; width:100%;padding: 15px 0px 0px 0;margin-top: 5px;}
.panel-comment_item .orig_textarea{width:90%; margin-bottom:10px;}
.panel-comment_item .orig_textarea02{ border:1px solid #ccc; background-color:#fff; width:92%; margin-bottom:10px;}
.panel-comment_item .orig_sub{ float:right; background-color:#269ac9; color:#fff; height:25px; line-height:25px; text-align:center; width:80px; border:none;}
.panel-comment_item .orig_sub:hover{ background:#297fb8;}
.panel-comment_item .orig_cont_hide{ text-align:center; width:100%; display:block; font-size:14px; color:#666; border-bottom:1px solid #F3DDB3; padding:8px 0;}
.panel-comment_item .orig_icon{ color:#888; margin-right:10px; font-size:14px; font-weight:bold;}
.orig_reply{ font-size: 12px; }
.panel-mes-head{ padding:10px; border-bottom:1px solid #eee;}
.homepagePostReplyPortrait a img{border-radius: 100px;}
/* 表格 */
.panel-new-table { width:100%; text-align: center; }
.panel-new-table tr th{ color:#333; height: 50px;line-height:50px; }
.panel-new-table tr th,.panel-new-table tr td{ border-bottom:1px solid #eee; }
.panel-new-table tr td{color:#666; height: 40px; line-height:40px;}
.panel-table-pd15 tr td{ padding:15px 0;}
.panel-new-table tbody tr:hover{ background:#f9f9f9;}
a.panel-table-name{display:block; max-width:100px;text-align:center;}
a.panel-table-title{display:block; max-width:240px;text-align:center;}
.table-num{ width:5%; text-align: center;}
/* 滑动条 */
.panel-slider-bg{ width:240px; height: 15px; border-radius:15px; background:#f1f2f7; }
.panel-slider-inner00{ display:block; width:0%; height: 15px; border-radius:15px; background:#29bd8b;}
.panel-slider-inner01{ display:block; width:10%; height: 15px; border-radius:15px; background:#29bd8b;}
.panel-slider-inner02{ display:block; width:20%; height: 15px; border-radius:15px; background:#29bd8b;}
.panel-slider-inner03{ display:block; width:30%; height: 15px; border-radius:15px; background:#29bd8b;}
.panel-slider-inner04{ display:block; width:40%; height: 15px; border-radius:15px; background:#29bd8b;}
.panel-slider-inner05{ display:block; width:50%; height: 15px; border-radius:15px; background:#29bd8b;}
.panel-slider-inner06{ display:block; width:60%; height: 15px; border-radius:15px; background:#29bd8b;}
.panel-slider-inner07{ display:block; width:70%; height: 15px; border-radius:15px; background:#29bd8b;}
.panel-slider-inner08{ display:block; width:80%; height: 15px; border-radius:15px; background:#29bd8b;}
.panel-slider-inner09{ display:block; width:90%; height: 15px; border-radius:15px; background:#29bd8b;}
.panel-slider-inner10{ display:block; width:100%; height: 15px; border-radius:15px; background:#29bd8b;}
/* 翻页 */
.panel-pages a{ display: inline-block; border:1px solid #d1d1d1; color:#888; float:left;text-align:center; padding:0 10px; margin-right:5px; height: 30px; line-height: 30px; }
.panel-pages a:hover,.panel-pages .active{ background-color:#29bd8b; border:1px solid #29bd8b;color:#fff; }
.panel-pages{ width: 350px; margin:20px auto;}
/* 翻页*/
.pages_right_min a{ display: inline-block;border:1px solid #d1d1d1; color:#888!important; float:left;text-align:center; padding:3px 10px; line-height:1.9; margin: 0 5px;}
.pages_right_min a.pages-border-right{border-right:1px solid #d1d1d1; }
.pages_right_min a:hover,.pages_right_min a.active{ background-color:#FC7033; color:#fff!important;border:1px solid #FC7033}
.pages_right_min li{float: left;}
/* 个人主页翻页 */
.pages_user_show a:hover,.pages_user_show a.active{ background-color:#FC7033;; color:#fff;border: 1px solid #FC7033;}
.pages_user_show a{ display: inline-block;border:1px solid #d1d1d1; color:#888; float:left;text-align:center; padding:3px 10px; line-height:1.9; margin: 0 5px;}
.pages_user_show li{float: left; list-style-type: none;}
.pages_user_show ul li{list-style-type: none !important;}
.pages_user_show ul li a{color:#888}
/* 小翻页 */
.pages_little_show a:hover,.pages_little_show a.active{ background-color:#FC7033;; color:#fff!important;border:1px solid #FC7033}
.pages_little_show a{ display: inline-block;border:1px solid #d1d1d1; color:#888!important; float:left;text-align:center; padding:3px 3px; line-height:1.9; margin: 0 2px; font-size: 12px;}
.pages_little_show li{float: left;}
/* 搜索*/
.panel-search{ position: relative;}
input.panel-search-input{ height: 30px; width:300px; color: #666;}
.panel-search-btn{ position: absolute; top:2px; right:10px;}
/* 表单*/
.label-w20{ width:20%!important;}
.panel-form-label{ display:inline-block; width:10%; min-width:90px; text-align:right; line-height:40px; font-weight: normal; }
.panel-form input,.panel-form textarea,.panel-form select{ border:1px solid #e2e2e2;color:#666;line-height: 1.9; background:#fff;}
.panel-box-sizing{-moz-box-sizing: border-box; /*Firefox3.5+*/-webkit-box-sizing: border-box; /*Safari3.2+*/-o-box-sizing: border-box; /*Opera9.6*/-ms-box-sizing: border-box; /*IE8*/box-sizing: border-box; border-radius:3px;}
input.panel-form-width-690{ padding:5px;width:90%; height:40px; }
input.panel-form-width-100{ padding:5px;width:100%; height:40px;}
input.panel-form-width-45{ padding:5px;width:44.5%; height:40px; }
input.panel-form-width-50{ padding:5px;width:44.5%; height:25px; }
input.panel-form-width-60{ padding:5px;width:60%; height:40px; }
textarea.panel-form-width-100{ padding:5px;width:100%; height:150px; }
textarea.panel-form-width-690{ padding:5px;width:90%; height:150px; }
.panel-form-width-670{ width: 670px; padding:5px;}
.panel-form-height-150{ height: 150px;}
.panel-form-height-30{height: 30px;}
.task-bg-grey{ background:#f3f3f3; width:90%; min-width:700px; padding:10px; border:1px solid #f3f3f3; color:#888;}
.task-bg-grey02{ background:#f3f3f3; width:80%; min-width:700px; padding:7px 10px; border:1px solid #f3f3f3; color:#888;}
input.task-form-10,textarea.task-form-10,select.task-form-10,.task-form-10{padding:5px;width:10%;box-sizing: border-box}
input.task-form-15,textarea.task-form-15,select.task-form-15,.task-form-15{padding:5px;width:15%;box-sizing: border-box}
input.task-form-20,textarea.task-form-20,select.task-form-20,.task-form-20{padding:5px;width:20%;box-sizing: border-box}
input.task-form-30,textarea.task-form-30,select.task-form-30,.task-form-30{padding:5px;width:30%;box-sizing: border-box}
input.task-form-35,textarea.task-form-35,select.task-form-35,.task-form-35{padding:5px;width:35%;box-sizing: border-box}
input.task-form-40,textarea.task-form-40,select.task-form-40,.task-form-40{padding:5px;width:40%;box-sizing: border-box}
input.task-form-45,textarea.task-form-45,select.task-form-45,.task-form-45{padding:5px;width:45%;box-sizing: border-box}
input.task-form-50,textarea.task-form-50,select.task-form-50,.task-form-50{padding:5px;width:50%;box-sizing: border-box}
input.task-form-60,textarea.task-form-60,select.task-form-60,.task-form-60{padding:5px;width:60%;box-sizing: border-box}
input.task-form-70,textarea.task-form-70,select.task-form-70,.task-form-70{padding:5px;width:70%;box-sizing: border-box}
input.task-form-80,textarea.task-form-80,select.task-form-80,.task-form-80{padding:5px;width:80%;box-sizing: border-box}
input.task-form-90,textarea.task-form-90,select.task-form-90,.task-form-90{padding:5px;width:90%;box-sizing: border-box}
input.task-form-100,textarea.task-form-100,select.task-form-100,.task-form-100{padding:5px;width:100%;}
input.task-height-40,textarea.task-height-40,.task-height-40,select.task-height-40{height:40px;}
input.task-height-30,textarea.task-height-30,.task-height-30,select.task-height-30{height:32px;}
input.task-height-220,textarea.task-height-220,.task-height-220{height:220px;}
input.task-height-150,textarea.task-height-150,.task-height-150{height:150px;}
input.task-height-100,textarea.task-height-100,.task-height-100{height:100px;}
input.task-height-80,textarea.task-height-80,.task-height-80{height:80px;}
/*头像下拉弹框*/
.my_account_info{ width:160px; background-color:#fff; border-radius: 3px; box-shadow: 0px 2px 8px rgba(146, 153, 169, 0.5); position:absolute; font-size: 14px; top:46px; left:-97px;display: none; z-index:999;}
.my_account_info li a{ color: #888;}
.my_account_info font{ border: 1px solid #dddddd; display: block; border-width: 8px; position: absolute; top: -15px;left: 140px; border-style:solid; border-color: transparent transparent #fff transparent;font-size: 0;line-height: 0; box-shadow:2px rgba(146, 153, 169, 0.5); }
.my_account_info li{ padding-left: 5px; line-height: 1.5;}
.li_bottom_border{ border-bottom:1px solid #eee;}
a.task-index-name{ display: inline-block; max-width:80px;}
.task-index-name{ display: inline-block; max-width:80px;}
/*滑块验证*/
.drag_slider{ position: relative; background-color: #e8e8e8; width:100%; height: 45px; line-height: 45px; text-align: center;border-radius: 4px;}
.drag_slider .handler{ border-radius: 4px 0px 0px 4px;position: absolute; top: 0px; left: 0px; width: 50px; height: 43px; border: 1px solid #eee; cursor: move;}
.handler_bg{ background: #fff url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA3hpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDIxIDc5LjE1NTc3MiwgMjAxNC8wMS8xMy0xOTo0NDowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDo0ZDhlNWY5My05NmI0LTRlNWQtOGFjYi03ZTY4OGYyMTU2ZTYiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NTEyNTVEMURGMkVFMTFFNEI5NDBCMjQ2M0ExMDQ1OUYiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NTEyNTVEMUNGMkVFMTFFNEI5NDBCMjQ2M0ExMDQ1OUYiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTQgKE1hY2ludG9zaCkiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo2MTc5NzNmZS02OTQxLTQyOTYtYTIwNi02NDI2YTNkOWU5YmUiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6NGQ4ZTVmOTMtOTZiNC00ZTVkLThhY2ItN2U2ODhmMjE1NmU2Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+YiRG4AAAALFJREFUeNpi/P//PwMlgImBQkA9A+bOnfsIiBOxKcInh+yCaCDuByoswaIOpxwjciACFegBqZ1AvBSIS5OTk/8TkmNEjwWgQiUgtQuIjwAxUF3yX3xyGIEIFLwHpKyAWB+I1xGSwxULIGf9A7mQkBwTlhBXAFLHgPgqEAcTkmNCU6AL9d8WII4HOvk3ITkWJAXWUMlOoGQHmsE45ViQ2KuBuASoYC4Wf+OUYxz6mQkgwAAN9mIrUReCXgAAAABJRU5ErkJggg==") no-repeat center;}
.handler_ok_bg{ background: #fff url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA3hpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDIxIDc5LjE1NTc3MiwgMjAxNC8wMS8xMy0xOTo0NDowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDo0ZDhlNWY5My05NmI0LTRlNWQtOGFjYi03ZTY4OGYyMTU2ZTYiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NDlBRDI3NjVGMkQ2MTFFNEI5NDBCMjQ2M0ExMDQ1OUYiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NDlBRDI3NjRGMkQ2MTFFNEI5NDBCMjQ2M0ExMDQ1OUYiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTQgKE1hY2ludG9zaCkiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDphNWEzMWNhMC1hYmViLTQxNWEtYTEwZS04Y2U5NzRlN2Q4YTEiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6NGQ4ZTVmOTMtOTZiNC00ZTVkLThhY2ItN2U2ODhmMjE1NmU2Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+k+sHwwAAASZJREFUeNpi/P//PwMyKD8uZw+kUoDYEYgloMIvgHg/EM/ptHx0EFk9I8wAoEZ+IDUPiIMY8IN1QJwENOgj3ACo5gNAbMBAHLgAxA4gQ5igAnNJ0MwAVTsX7IKyY7L2UNuJAf+AmAmJ78AEDTBiwGYg5gbifCSxFCZoaBMCy4A4GOjnH0D6DpK4IxNSVIHAfSDOAeLraJrjgJp/AwPbHMhejiQnwYRmUzNQ4VQgDQqXK0ia/0I17wJiPmQNTNBEAgMlQIWiQA2vgWw7QppBekGxsAjIiEUSBNnsBDWEAY9mEFgMMgBk00E0iZtA7AHEctDQ58MRuA6wlLgGFMoMpIG1QFeGwAIxGZo8GUhIysmwQGSAZgwHaEZhICIzOaBkJkqyM0CAAQDGx279Jf50AAAAAABJRU5ErkJggg==") no-repeat center;}
.drag_slider .drag_bg{ background-color: #29bd8b; height: 45px; width: 0px;}
.drag_slider .drag_text{border-radius: 4px 0px 0px 4px;position: absolute; top: 0px; width: 100%; -moz-user-select: none; -webkit-user-select: none; user-select: none; -o-user-select:none; -ms-user-select:none;}
/*新建新增*/
/*.edu-con-top{ padding:10px 0; background:#fff; border-bottom:1px solid #eee;font-size:16px; }*/
/*.edu-con-top h2{ font-size:16px;}*/
/*.edu-con-bg01{ width: 100%; background:#fff;}*/
/*.edu-con-top .color-grey{ color:#666!important;}*/
/*附件上传的样式*/
.atta_input{ width: 980px; white-space: nowrap; text-overflow:ellipsis;}
/*作业描述、帖子内容*/
.upload_img img{max-width: 100%;}
.table_maxWidth table {max-width: 642px;}
.list_style ol li{list-style-type: decimal;margin-left: 40px;}
.list_style ul li{list-style-type: disc;margin-left: 40px;}
/*数据为空公共页面*/
img.edu-nodata-img{ width:200px; margin:50px auto 20px; display: block;}
.edu-nodata-p{ font-size: 16px; text-align: center; color:#888;border-bottom:none!important;}
/* new tab */
.edu-tab{ width: 100%; background:#fff;}
#edu-tab-nav{height:47px;background: #fff;}
#edu-tab-nav li.new-tab-nav {float:left; width: 150px; text-align:center;height:48px;line-height:48px;border-top-right-radius:5px;border-top-left-radius:5px; }
#edu-tab-nav li a{font-size:14px; }
#edu-user-tab-nav{height:40px;background: #fff; border-bottom:2px solid #FC7033;}
#edu-user-tab-nav li.new-tab-nav {float:left; width: 120px; text-align:center;height:42px;line-height:42px;border-top-left-radius: 5px;border-top-right-radius:5px}
#edu-user-tab-nav li a{font-size:14px; }
.edu-new-tab-hover { background:#5faee3; }
.edu-user-tab-hover{background:#FC7033;}
.edu-user-tab-hover a{color:#fff!important;}
.edu-new-tab-hover a{color:#fff!important;}
.edu-class-con-list:hover{ background:#EFF9FD;}
.edu-bg-shadow{box-shadow: 0px 0px 5px rgba(146, 153, 169, 0.2);}
a.task-btn-line{display: inline-block;font-weight: bold;padding: 0 12px;color: #666;background: #fff;letter-spacing: 1px;text-align: center;font-size: 14px;height: 30px;line-height: 30px;border-radius: 3px; border:1px solid #ccc;}
a:hover.task-btn-line{ border:1px solid #3498db;background:#3498db;color: #fff;}
/*阴影*/
.user_bg_shadow{-webkit-box-shadow: 0 0 8px 0 rgba(142,142,142,.1);-moz-box-shadow: 0 0 8px 0 rgba(142,142,142,.1);box-shadow: 0 0 8px 0 rgba(142,142,142,.1);}/*四边阴影*/
.user_bg_shadow_notop{-webkit-box-shadow: 0 3px 8px 0 rgba(142,142,142,.1);-moz-box-shadow: 0 3px 8px 0 rgba(142,142,142,.1);box-shadow: 0 3px 8px 0 rgba(142,142,142,.1);}/*没有上边阴影*/
/*阴影+边框*/
.shadow_border{border:1px solid #eee;-webkit-box-shadow: 0 0 8px 0 rgba(142,142,142,.1);-moz-box-shadow: 0 0 8px 0 rgba(142,142,142,.1);box-shadow: 0 0 8px 0 rgba(142,142,142,.1);}
.shadow_border_notop{border:1px solid #eee;-webkit-box-shadow: 0 3px 8px 0 rgba(142,142,142,.1);-moz-box-shadow: 0 3px 8px 0 rgba(142,142,142,.1);box-shadow: 0 3px 8px 0 rgba(142,142,142,.1);}
.user_bg_shadow01{-webkit-box-shadow: 0 1px 2px 2px rgba(123, 123, 123, 0.15);-moz-box-shadow: 0 1px 2px 2px rgba(123, 123, 123, 0.15);box-shadow: 0 1px 2px 2px rgba(123, 123, 123, 0.15);}
.user_bg_shadow02{-webkit-box-shadow: 0 2px 8px 0 rgba(123, 123, 123, 0.15);-moz-box-shadow: 0 2px 8px 0 rgba(123, 123, 123, 0.15);box-shadow: 0 2px 8px 0 rgba(123, 123, 123, 0.15);}
.box_bg_shandow {box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.15);}
/*新增的公用样式*/
.box-boxshadow{box-shadow: 3px 3px 10px rgba(146, 153, 169, 0.2);}
.prop-notice-info{padding: 10px;border:1px solid #F3DDB3;background-color: #FFFEF4;}
.prop-notice-info ol{list-style-type: disc;list-style-position:inside}
.prop-notice-info ol li{list-style-type: disc;color: #ff6532;margin-bottom:0!important;}
/*input框移出后没有内容将边框阴影变为红色*/
.notinput_bg_shadow{border: none;box-shadow: 0px 0px 4px rgba(227,53,37,1);}
/*设置input框的placehoder的字体颜色*/
input::-webkit-input-placeholder,textarea::-webkit-input-placeholder{color: #cccccc}
input::-moz-placeholder,textarea::-moz-placeholder { color:#cccccc;}
input::-moz-placeholder,textarea::-moz-placeholder { color:#cccccc;}
input::-ms-input-placeholder,textarea::-ms-input-placeholder {color:#cccccc;}
/*班级讨论区置顶的样式*/
.btn-cir {display: inline-block;padding: 0px 5px;border-radius: 25px;line-height: 20px;font-size: 12px;}
.btn-cir:hover{background:#fff;color:#333333}.all_work_border{border: 1px solid #4c515d;}/*TPI全部任务的数量需要加一个边框*/
.btn-cir-grey{background: #e1e1e1;color: #8c8c8c;font-weight: normal;border: 1px solid #e1e1e1}
.btn-cir-red{background:red;color: #fff; font-weight: normal;}
.btn-cir-red:hover{background:red;}
.btn-cir-orange {background: #ff7500; color: #fff; font-weight: normal;border: 1px solid #ff7500}
.btn-top{display: inline-block;padding: 0px 5px;line-height: 20px;font-size: 12px;border-radius: 3px;}
.btn-cir-big{ background: #999;color: #fff;display: inline-block; padding:0px 10px; border-radius:25px; line-height:25px; height: 25px; font-size:12px;}
/*圆形绿色背景---------22*/
.panel-inner-icon{width: 22px;height: 22px;line-height: 22px;border-radius: 50%;background: #29bd8b;display: block;text-align: center}
.panel-inner-icon{width: 22px;height: 22px;line-height: 22px;border-radius: 50%;background: #29bd8b;display: block;text-align: center}
/*圆形绿色背景------------------18*/
.panel-inner-icon18{width: 18px;height: 18px;line-height: 18px;border-radius: 50%;background: #29bd8b;display: block;text-align: center}
/*---------------块右上角的三角形,颜色为浅橙色*/
.triangle-topright {position: absolute;right: -1px;top:0px;width: 0;height: 0;border-top: 35px solid #FF9E6A;border-left: 60px solid transparent;z-index: 1}
.triangle-font{position: absolute;right: 1px;top: 2px;z-index: 2;font-size: 12px;color: white;transform: rotate(31deg);}
.triangle-font2{position: absolute;right: 1px;top: -5px;z-index: 2;font-size: 12px;color: white;transform: rotate(31deg);}
/* colorbox
*******************************************************************************/
/*
Colorbox Core Style:
The following CSS is consistent between example themes and should not be altered.
*/
#colorbox, #cboxOverlay, #cboxWrapper{position:absolute; top:0; left:0; z-index:99999; overflow:hidden;}
#cboxWrapper {max-width:none;}
#cboxOverlay{position:fixed; width:100%; height:100%;}
#cboxMiddleLeft, #cboxBottomLeft{clear:left;}
#cboxContent{position:relative;}
#cboxLoadedContent{overflow:auto; -webkit-overflow-scrolling: touch;}
#cboxTitle{margin:0;}
#cboxLoadingOverlay, #cboxLoadingGraphic{position:absolute; top:0; left:0; width:100%; height:100%;}
#cboxPrevious, #cboxNext, #cboxClose, #cboxSlideshow{cursor:pointer;}
.cboxPhoto{float:left; margin:auto; border:0; display:block; max-width:none; -ms-interpolation-mode:bicubic;}
.cboxIframe{width:100%; height:100%; display:block; border:0; padding:0; margin:0;}
#colorbox, #cboxContent, #cboxLoadedContent{box-sizing:content-box; -moz-box-sizing:content-box; -webkit-box-sizing:content-box;}
/*
User Style:
Change the following styles to modify the appearance of Colorbox. They are
ordered & tabbed in a way that represents the nesting of the generated HTML.
*/
#cboxOverlay{background:#fff;}
#colorbox{outline:0;}
#cboxTopLeft{width:25px; height:25px; background:url(/images/colorbox/border1.png) no-repeat 0 0;}
#cboxTopCenter{height:25px; background:url(/images/colorbox/border1.png) repeat-x 0 -50px;}
#cboxTopRight{width:25px; height:25px; background:url(/images/colorbox/border1.png) no-repeat -25px 0;}
#cboxBottomLeft{width:25px; height:25px; background:url(/images/colorbox/border1.png) no-repeat 0 -25px;}
#cboxBottomCenter{height:25px; background:url(/images/colorbox/border1.png) repeat-x 0 -75px;}
#cboxBottomRight{width:25px; height:25px; background:url(/images/colorbox/border1.png) no-repeat -25px -25px;}
#cboxMiddleLeft{width:25px; background:url(/images/colorbox/border2.png) repeat-y 0 0;}
#cboxMiddleRight{width:25px; background:url(/images/colorbox/border2.png) repeat-y -25px 0;}
#cboxContent{background:#fff; overflow:hidden;}
.cboxIframe{background:#fff;}
#cboxError{padding:50px; border:1px solid #ccc;}
#cboxLoadedContent{margin-bottom:20px;}
#cboxTitle{position:absolute; bottom:0px; left:0; text-align:center; width:100%; color:#999;}
#cboxCurrent{position:absolute; bottom:0px; left:100px; color:#999;}
#cboxLoadingOverlay{background:#fff url(/images/colorbox/loading.gif) no-repeat 5px 5px;}
/* these elements are buttons, and may need to have additional styles reset to avoid unwanted base styles */
#cboxPrevious, #cboxNext, #cboxSlideshow, #cboxClose {border:0; padding:0; margin:0; overflow:visible; width:auto; background:none; }
/* avoid outlines on :active (mouseclick), but preserve outlines on :focus (tabbed navigating) */
#cboxPrevious:active, #cboxNext:active, #cboxSlideshow:active, #cboxClose:active {outline:0;}
#cboxSlideshow{position:absolute; bottom:0px; right:42px; color:#444;}
#cboxPrevious{position:absolute; bottom:0px; left:0; color:#444;}
#cboxNext{position:absolute; bottom:0px; left:63px; color:#444;}
#cboxClose{position:absolute; bottom:0; right:0; display:block; color:#444;}
/*-----下拉框--------*/
.down-select{display:none;position: absolute;z-index: 10;left: 0px;width: 100%;overflow-y: auto;background: #fff;max-height: 200px;}
.down-select p{height: 35px;line-height: 35px;padding-left: 5px;}
.down-select p:hover{background: #f3f4f6}
/*课程、实训的条状样式*/
.homepage-list-show p{height:70px;line-height:70px;}
.homepage-list-show p:nth-child(odd){background:#fafbfb;}
.homepage-list-show p .first{width:58%;display:inline-block;overflow:hidden; white-space: nowrap; text-overflow:ellipsis;}
.homepage-list-show p .hasmargin{width:23%;display:inline-block;text-align: center;color:#888;overflow:hidden; white-space: nowrap; text-overflow:ellipsis;}
.homepage-list-show p .haspadding{width:16.7%;display:inline-block;margin-right:12%;color:#888;overflow:hidden; white-space: nowrap; text-overflow:ellipsis;}
.homepage-list-show p .last{width:8.33%;display:inline-block;color:#888;cursor: pointer; display: none;}
.homepage-list-show p .last:hover{color:#5faee3;}
.homepage-list-show p .last:hover .blue{color:#5faee3;}
/*-----课程名称下拉框--------*/
.course_list_ul,.down-list{ overflow-y: scroll;display: none;position: absolute;top:40px;left: -1px;width: 100% !important;border:1px solid #eeeeee;background: #FFFFFF;max-height: 150px;z-index: 10}
.course_list_ul li{height:20px;padding:5px 10px;clear:both;line-height:28px;margin-bottom: 0 !important;cursor: pointer;}
.down-list li{text-align: left;outline: none;padding: 5px 10px;clear: both;line-height: 22px!important;margin-bottom: 0 !important;cursor: pointer;width: 100%;box-sizing: border-box;height: 30px;border: none!important;}
.down-list li:hover{background: #eee}
.down-list{top:32px}
.unit-part{border:1px solid #ccc;padding: 0px 8px;border-radius: 5px;margin-right: 10px}
.unit-part input{border: none!important;text-align: left;width:auto;outline: none}
/*-----试卷提交状态--------*/
.post_status_btn{display: block;float: left;padding: 0px 5px;font-size: 12px;color: #FFFFFF;border-radius: 4px;height: 20px;line-height: 20px;;}
.post_btn_green{background: #29bd8b;border: 1px solid #29bd8b!important;color: #fff;}
.post_btn_green_q{background: #5ECFBA;border: 1px solid #5ECFBA!important;color: #fff;}
.post_btn_orange{background: #FF7500;border: 1px solid #FF7500!important;color: #fff;}
.post_btn_red{background: #ee4a1f;border: 1px solid #ee4a1f!important;color: #fff;}
.post_btn_grey{background: #e4e4e3;border: 1px solid #e4e4e3!important;}
.post_btn_white{background: #ffffff;}
/*评阅状态*/
.checkstatus_box_small{width: 10px;height: 10px;display: block;float: left;margin-right: 3px;}
.checkstatus_box_big{cursor: default;width: 30px;height: 30px;line-height: 30px;text-align: center;margin-right: 10px;border:1px solid #CCCCCC;display: block;float: left;margin-bottom: 10px}
.checkstatus_box_big i{position: absolute;top:18px;left: 10px;}
/*个人主页头部认证圆形背景*/
.user-info-span{border-radius: 50%;float:left;background: #F3F5F7;text-align: center;width: 23px;height: 23px;line-height: 23px;margin-top: 3px;margin-right: 5px}
/*试卷答题倒计时*/
.time_panel span.factorial{float: left;display: block;line-height: 35px;padding: 0px 3px;}
.time_panel span.time{float: left;display: block;color: #ffffff;background-color: #333333;font-size: 16px;border-radius: 5px;letter-spacing: 1px;width: 33px;text-align: center;line-height: 35px;height: 35px;}
.hidemsg{overflow: hidden;cursor: pointer}
.hidemsg div{
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;
opacity:0.4;
background-color: #ffffff;
-webkit-border-radius: 100%;
-moz-border-radius: 100%;
-o-border-radius: 100%;
-ms-border-radius: 100%;
-webkit-animation-fill-mode: both;
-moz-animation-fill-mode: both;
-ms-animation-fill-mode: both;
-o-animation-fill-mode: both;
width: 80px;
height: 80px;
-webkit-animation: ball-scale 1s 0s ease-in-out infinite;
-moz-animation: ball-scale 1s 0s ease-in-out infinite;
-ms-animation: ball-scale 1s 0s ease-in-out infinite;
-o-animation: ball-scale 1s 0s ease-in-out infinite;
animation: ball-scale 1s 0s ease-in-out infinite;
}
@keyframes ball-scale{
0%{width: 0px;height: 0px}
100%{width: 80px;height: 80px}
}
/*-------------------个人主页关注和粉丝列表改版 以及TPM合作者部分改版 2018/01/15-------------------------*/
.-task-con-int .favour .fens-table-list{display: flex;width:21.29%;margin:0px 1.5% 1.5% 0px;min-height: 125px;border: 1px solid #EEEEEE;padding: 10px;background: #f9fbfd}
.-task-con-int .favour .fens-table-list:nth-child(4n+1){margin:0px 1.5% 1.5% 1.5%;}
.-task-con-int .favour .fens-table-list .touxiang{border-radius: 50%;overflow: hidden;}
.white-icon-ring{width: 25px;height: 25px;background: #ffffff;border-radius: 50%;text-align: center;line-height: 25px;}
a.btn-focus{display: block;width:80px;height: 35px;line-height: 35px;border-radius: 4px;border:1px solid #EEEEEE;text-align: center;cursor: pointer;background: #ffffff}
a.btn-focus:hover{color: #FFFFFF!important;background:#FC7033;border: 1px solid #FC7033 }
.fans-name{max-width: 100px;word-break: break-all;overflow: hidden;height: 26px;text-overflow: ellipsis;white-space: nowrap;}
.school-name{max-width: 196px;word-break: break-all;overflow: hidden;height: 26px;text-overflow: ellipsis;white-space: nowrap;}
.fans_del{position: absolute;right: 12px;top: 12px;cursor: pointer;
text-align: center;}
.fans_del i{color: #b5b5b5}
.fans_del:hover i{color: #ff7500!important;}
.-task-con-int .favour .p2{line-height:90px;text-align:center;}
.-task-con-int .favour .p2:hover .changecolor{color:#5faee3;}
.-task-con-int .favour .fens{position:relative;}
.-task-con-int .favour .fens .many{position:absolute;right:22px;top:-35px;}
.-task-con-int .favour .fens .list{width:100px;text-align:center;padding-top:5px;}
.-task-con-int .favour .fens .list dt{margin:20px;margin-bottom:5px;}
.-task-con-int .favour .fens .touxiang{border-radius:28px;overflow:hidden;}
/*选择实训的弹框*/
.shixun_work_div{overflow-y: auto;max-height: 90px;}

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because one or more lines are too long

View File

@ -5,6 +5,202 @@
"css_prefix_text": "icon-",
"description": "",
"glyphs": [
{
"icon_id": "14364807",
"name": "多行公式",
"font_class": "duohanggongshi",
"unicode": "e748",
"unicode_decimal": 59208
},
{
"icon_id": "14364804",
"name": "行内公式",
"font_class": "hangneigongshi",
"unicode": "e747",
"unicode_decimal": 59207
},
{
"icon_id": "14269491",
"name": "取消置顶",
"font_class": "quxiaozhiding",
"unicode": "e746",
"unicode_decimal": 59206
},
{
"icon_id": "14269490",
"name": "置顶",
"font_class": "zhiding1",
"unicode": "e745",
"unicode_decimal": 59205
},
{
"icon_id": "14240818",
"name": "新建简历、我的简历",
"font_class": "xinjianjianliwodejianli",
"unicode": "e744",
"unicode_decimal": 59204
},
{
"icon_id": "14108259",
"name": "回复",
"font_class": "huifu",
"unicode": "e743",
"unicode_decimal": 59203
},
{
"icon_id": "14102491",
"name": "图片",
"font_class": "tupian",
"unicode": "e742",
"unicode_decimal": 59202
},
{
"icon_id": "14102400",
"name": "问题列表",
"font_class": "wentiliebiao",
"unicode": "e741",
"unicode_decimal": 59201
},
{
"icon_id": "14101755",
"name": "职称",
"font_class": "zhicheng",
"unicode": "e73f",
"unicode_decimal": 59199
},
{
"icon_id": "11488156",
"name": "upload",
"font_class": "upload",
"unicode": "e76b",
"unicode_decimal": 59243
},
{
"icon_id": "13839898",
"name": "发布职位",
"font_class": "fabuzhiwei",
"unicode": "e73e",
"unicode_decimal": 59198
},
{
"icon_id": "13839895",
"name": "职位要求",
"font_class": "zhiweiyaoqiu",
"unicode": "e73d",
"unicode_decimal": 59197
},
{
"icon_id": "13839892",
"name": "公司介绍",
"font_class": "gongsijieshao",
"unicode": "e73c",
"unicode_decimal": 59196
},
{
"icon_id": "13839888",
"name": "公司地址",
"font_class": "gongsidizhi",
"unicode": "e73b",
"unicode_decimal": 59195
},
{
"icon_id": "13515025",
"name": "局部刷新键头",
"font_class": "jubushuaxinjiantou",
"unicode": "e73a",
"unicode_decimal": 59194
},
{
"icon_id": "13458315",
"name": "返回",
"font_class": "fanhui",
"unicode": "e739",
"unicode_decimal": 59193
},
{
"icon_id": "13458287",
"name": "统计",
"font_class": "tongji1",
"unicode": "e738",
"unicode_decimal": 59192
},
{
"icon_id": "13428689",
"name": "签到-02",
"font_class": "qiandao-1",
"unicode": "e736",
"unicode_decimal": 59190
},
{
"icon_id": "13428658",
"name": "下箭头",
"font_class": "xiajiantou2",
"unicode": "e737",
"unicode_decimal": 59191
},
{
"icon_id": "13427273",
"name": "签到-01",
"font_class": "qiandao-",
"unicode": "e735",
"unicode_decimal": 59189
},
{
"icon_id": "13353315",
"name": "移动",
"font_class": "yidong",
"unicode": "e734",
"unicode_decimal": 59188
},
{
"icon_id": "13247262",
"name": "下移2",
"font_class": "xiayi1",
"unicode": "e732",
"unicode_decimal": 59186
},
{
"icon_id": "13247261",
"name": "上移2",
"font_class": "shangyi1",
"unicode": "e731",
"unicode_decimal": 59185
},
{
"icon_id": "13247178",
"name": "下移",
"font_class": "xiayi",
"unicode": "e730",
"unicode_decimal": 59184
},
{
"icon_id": "13247175",
"name": "上移",
"font_class": "shangyi",
"unicode": "e72f",
"unicode_decimal": 59183
},
{
"icon_id": "13247173",
"name": "编辑",
"font_class": "bianji5",
"unicode": "e72e",
"unicode_decimal": 59182
},
{
"icon_id": "13247168",
"name": "删除",
"font_class": "shanchu3",
"unicode": "e72d",
"unicode_decimal": 59181
},
{
"icon_id": "13183780",
"name": "选择",
"font_class": "xuanze",
"unicode": "e72c",
"unicode_decimal": 59180
},
{
"icon_id": "2077714",
"name": "编辑",

View File

@ -20,6 +20,90 @@ Created by iconfont
/>
<missing-glyph />
<glyph glyph-name="duohanggongshi" unicode="&#59208;" d="M665.6 418.133333h17.066667v113.777778H295.822222l193.422222-227.555555-216.177777-216.177778h409.6l34.133333 130.844444h-22.755556c0-11.377778-5.688889-17.066667-11.377777-28.444444s-17.066667-17.066667-28.444445-22.755556H426.666667l164.977777 164.977778-136.533333 159.288889H597.333333c22.755556-5.688889 45.511111-11.377778 56.888889-22.755556 5.688889-17.066667 11.377778-34.133333 11.377778-51.2zM807.822222-116.622222H233.244444c-62.577778 0-119.466667 51.2-119.466666 119.466666V748.088889C113.777778 810.666667 164.977778 867.555556 233.244444 867.555556h443.733334l244.622222-233.244445v-637.155555c0-62.577778-51.2-113.777778-113.777778-113.777778zM233.244444 810.666667c-34.133333 0-62.577778-28.444444-62.577777-62.577778v-750.933333c0-34.133333 28.444444-62.577778 62.577777-62.577778h574.577778c34.133333 0 62.577778 28.444444 62.577778 62.577778V611.555556L654.222222 810.666667H233.244444zM898.844444 594.488889h-176.355555c-45.511111 0-85.333333 39.822222-85.333333 85.333333V839.111111h56.888888v-159.288889c0-17.066667 11.377778-28.444444 28.444445-28.444444h176.355555v-56.888889z" horiz-adv-x="1024" />
<glyph glyph-name="hangneigongshi" unicode="&#59207;" d="M907.946667 636.586667h34.133333V896H54.613333l443.733334-525.653333L0-128h942.08l81.92 307.2h-54.613333c0-20.48-13.653333-40.96-27.306667-68.266667s-34.133333-40.96-68.266667-47.786666H348.16l382.293333 375.466666-327.68 375.466667h327.68c61.44-6.826667 102.4-27.306667 129.706667-54.613333 34.133333-34.133333 47.786667-75.093333 47.786667-122.88z" horiz-adv-x="1024" />
<glyph glyph-name="quxiaozhiding" unicode="&#59206;" d="M480.492308 29.538462c-31.507692 0-63.015385 15.753846-86.646154 31.507692v7.876923L86.646154 407.630769C70.892308 431.261538 55.138462 462.769231 55.138462 494.276923c0 31.507692 15.753846 63.015385 39.384615 78.769231 23.630769 15.753846 47.261538 31.507692 78.769231 31.507692h102.4V738.461538c0 63.015385 55.138462 118.153846 118.153846 118.153847h228.430769c63.015385 0 118.153846-55.138462 118.153846-118.153847v-133.907692h78.769231c63.015385 0 118.153846-55.138462 118.153846-118.153846 0-31.507692-15.753846-63.015385-31.507692-86.646154l-338.707692-338.707692c-23.630769-23.630769-55.138462-39.384615-86.646154-31.507692zM173.292308 525.784615c-7.876923 0-15.753846 0-23.63077-7.876923-15.753846-15.753846-15.753846-39.384615 0-55.138461l307.2-338.707693c7.876923-15.753846 15.753846-15.753846 23.63077-15.753846 15.753846 0 23.630769 0 31.507692 7.876923l338.707692 338.707693c7.876923 7.876923 7.876923 15.753846 7.876923 31.507692 0 23.630769-15.753846 39.384615-39.384615 39.384615h-157.538462V738.461538c0 23.630769-15.753846 39.384615-39.384615 39.384616H401.723077c-23.630769 0-39.384615-15.753846-39.384615-39.384616v-212.676923H173.292308zM913.723077-96.492308H102.4c-23.630769 0-39.384615 15.753846-39.384615 39.384616s15.753846 39.384615 39.384615 39.384615h811.323077c23.630769 0 39.384615-15.753846 39.384615-39.384615s-23.630769-39.384615-39.384615-39.384616z" horiz-adv-x="1024" />
<glyph glyph-name="zhiding1" unicode="&#59205;" d="M622.276923-88.615385H401.723077c-70.892308 0-118.153846 55.138462-118.153846 118.153847V163.446154H173.292308c-31.507692 0-55.138462 7.876923-78.769231 31.507692-47.261538 39.384615-47.261538 118.153846-7.876923 165.415385L393.846154 699.076923c23.630769 23.630769 55.138462 39.384615 86.646154 39.384615 31.507692 0 63.015385-15.753846 86.646154-31.507692l338.707692-338.707692c23.630769-23.630769 31.507692-55.138462 31.507692-86.646154 0-63.015385-55.138462-118.153846-118.153846-118.153846h-78.769231V29.538462c0-63.015385-47.261538-118.153846-118.153846-118.153847zM480.492308 659.692308c-7.876923 0-15.753846 0-23.63077-7.876923L149.661538 305.230769c-7.876923-7.876923-15.753846-15.753846-15.753846-23.630769 0-7.876923 7.876923-23.630769 15.753846-23.630769 7.876923-15.753846 15.753846-15.753846 23.63077-15.753846h181.16923V29.538462c0-23.630769 15.753846-39.384615 39.384616-39.384616h228.430769c23.630769 0 39.384615 15.753846 39.384615 39.384616V242.215385h157.538462c23.630769 0 39.384615 15.753846 39.384615 39.384615 0 7.876923-7.876923 23.630769-7.876923 31.507692L512 651.815385c-7.876923 7.876923-15.753846 15.753846-31.507692 7.876923zM913.723077 785.723077H102.4C78.769231 785.723077 63.015385 801.476923 63.015385 825.107692s15.753846 39.384615 39.384615 39.384616h811.323077c23.630769 0 39.384615-15.753846 39.384615-39.384616s-23.630769-39.384615-39.384615-39.384615z" horiz-adv-x="1024" />
<glyph glyph-name="xinjianjianliwodejianli" unicode="&#59204;" d="M698.181818-104.727273H139.636364c-79.127273 0-139.636364 60.509091-139.636364 139.636364V756.363636c0 79.127273 60.509091 139.636364 139.636364 139.636364h712.145454c79.127273 0 139.636364-60.509091 139.636364-139.636364v-595.781818L698.181818-104.727273zM139.636364 802.909091c-27.927273 0-46.545455-18.618182-46.545455-46.545455v-721.454545c0-27.927273 18.618182-46.545455 46.545455-46.545455h521.309091l237.381818 214.109091V756.363636c0 27.927273-18.618182 46.545455-46.545455 46.545455H139.636364zM735.418182-11.636364h-69.818182v181.527273c0 46.545455 37.236364 83.781818 83.781818 83.781818h153.6v-69.818182H744.727273c-4.654545 0-9.309091-4.654545-9.309091-9.30909v-186.181819zM451.490909 160.581818H279.272727c-18.618182 0-37.236364 13.963636-37.236363 37.236364s13.963636 37.236364 37.236363 37.236363h172.218182c18.618182 0 37.236364-13.963636 37.236364-37.236363s-13.963636-37.236364-37.236364-37.236364zM730.763636 356.072727H279.272727c-18.618182 0-37.236364 13.963636-37.236363 37.236364s18.618182 32.581818 37.236363 32.581818h451.490909c18.618182 0 37.236364-13.963636 37.236364-37.236364s-13.963636-32.581818-37.236364-32.581818zM730.763636 551.563636H279.272727c-18.618182 0-37.236364 13.963636-37.236363 37.236364s18.618182 32.581818 37.236363 32.581818h451.490909c18.618182 0 37.236364-13.963636 37.236364-37.236363s-13.963636-32.581818-37.236364-32.581819z" horiz-adv-x="1024" />
<glyph glyph-name="huifu" unicode="&#59203;" d="M512-96H166.4c-44.8 6.4-70.4 51.2-64 96 19.2 96 12.8 121.6 12.8 121.6-12.8 25.6-32 51.2-44.8 83.2C44.8 256 32 320 32 384 32 646.4 249.6 864 512 864s480-217.6 480-480-217.6-480-480-480z m0 896C281.6 800 96 614.4 96 384c0-57.6 12.8-108.8 32-160 12.8-25.6 25.6-51.2 38.4-70.4 12.8-19.2 19.2-51.2-6.4-166.4 0-6.4 6.4-19.2 12.8-19.2H512c230.4 0 416 185.6 416 416S742.4 800 512 800zM288 384m-76.8 0a76.8 76.8 0 1 1 153.6 0 76.8 76.8 0 1 1-153.6 0ZM512 384m-76.8 0a76.8 76.8 0 1 1 153.6 0 76.8 76.8 0 1 1-153.6 0ZM736 384m-76.8 0a76.8 76.8 0 1 1 153.6 0 76.8 76.8 0 1 1-153.6 0Z" horiz-adv-x="1024" />
<glyph glyph-name="tupian" unicode="&#59202;" d="M1185.684211-128H215.578947c-118.568421 0-215.578947 97.010526-215.578947 215.578947V680.421053c0 118.568421 97.010526 215.578947 215.578947 215.578947h970.105264c118.568421 0 215.578947-97.010526 215.578947-215.578947v-592.842106c0-118.568421-97.010526-215.578947-215.578947-215.578947zM215.578947 788.210526c-59.284211 0-107.789474-48.505263-107.789473-107.789473v-592.842106c0-59.284211 48.505263-107.789474 107.789473-107.789473h970.105264c59.284211 0 107.789474 48.505263 107.789473 107.789473V680.421053c0 59.284211-48.505263 107.789474-107.789473 107.789473H215.578947zM0 179.2l247.915789 145.515789c64.673684 37.726316 145.515789 37.726316 210.189474 5.389474l274.863158-145.515789 258.694737 274.863158c43.115789 43.115789 102.4 59.284211 161.68421 43.115789L1401.263158 427.115789V33.684211c0-91.621053-70.063158-161.684211-161.684211-161.684211H161.684211c-91.621053 0-161.684211 70.063158-161.684211 161.684211M210.189474 578.021053a107.789474 107.789474 0 1 1 215.578947 0 107.789474 107.789474 0 1 1-215.578947 0Z" horiz-adv-x="1401" />
<glyph glyph-name="wentiliebiao" unicode="&#59201;" d="M512 384m-512 0a512 512 0 1 1 1024 0 512 512 0 1 1-1024 0ZM512 175.261538c-55.138462 0-98.461538 19.692308-129.969231 55.138462-31.507692 35.446154-51.2 82.707692-51.2 141.784615 0 63.015385 15.753846 110.276923 51.2 149.661539 35.446154 35.446154 78.769231 55.138462 137.846154 55.138461 51.2 0 94.523077-19.692308 129.969231-55.138461s47.261538-82.707692 47.261538-141.784616c0-63.015385-15.753846-114.215385-51.2-149.661538l-23.630769-23.630769 110.276923-78.769231h-82.707692l-70.892308 55.138462c-23.630769-3.938462-43.323077-7.876923-66.953846-7.876924z m3.938462 358.4c-39.384615 0-74.830769-15.753846-98.461539-43.323076s-39.384615-66.953846-39.384615-114.215385 11.815385-86.646154 35.446154-114.215385c23.630769-27.569231 55.138462-43.323077 98.461538-43.323077s74.830769 15.753846 98.461538 43.323077c23.630769 27.569231 35.446154 66.953846 35.446154 114.215385 0 51.2-11.815385 90.584615-35.446154 118.153846-19.692308 23.630769-51.2 39.384615-94.523076 39.384615z" horiz-adv-x="1024" />
<glyph glyph-name="zhicheng" unicode="&#59199;" d="M1331.2-128h-1160.533333C75.093333-128 0-52.906667 0 42.666667v682.666666C0 820.906667 75.093333 896 170.666667 896h1160.533333C1426.773333 896 1501.866667 820.906667 1501.866667 725.333333v-682.666666c0-95.573333-75.093333-170.666667-170.666667-170.666667zM170.666667 827.733333C116.053333 827.733333 68.266667 779.946667 68.266667 725.333333v-682.666666c0-54.613333 47.786667-102.4 102.4-102.4h1160.533333c54.613333 0 102.4 47.786667 102.4 102.4v682.666666c0 54.613333-47.786667 102.4-102.4 102.4h-1160.533333zM750.933333 56.32c-20.48 0-34.133333 13.653333-34.133333 34.133333 0 129.706667-109.226667 238.933333-238.933333 238.933334s-238.933333-109.226667-238.933334-238.933334c0-20.48-13.653333-34.133333-34.133333-34.133333s-34.133333 13.653333-34.133333 34.133333c0 170.666667 136.533333 307.2 307.2 307.2s307.2-136.533333 307.2-307.2c0-20.48-13.653333-34.133333-34.133334-34.133333zM477.866667 363.52c-88.746667 0-163.84 75.093333-163.84 163.84S389.12 691.2 477.866667 691.2s163.84-75.093333 163.84-163.84S566.613333 363.52 477.866667 363.52zM477.866667 622.933333c-54.613333 0-95.573333-40.96-95.573334-95.573333S423.253333 431.786667 477.866667 431.786667s95.573333 40.96 95.573333 95.573333S532.48 622.933333 477.866667 622.933333zM1262.933333 76.8h-341.333333c-20.48 0-34.133333 13.653333-34.133333 34.133333s13.653333 34.133333 34.133333 34.133334h341.333333c20.48 0 34.133333-13.653333 34.133334-34.133334s-13.653333-34.133333-34.133334-34.133333zM1194.666667 315.733333h-273.066667c-20.48 0-34.133333 13.653333-34.133333 34.133334s13.653333 34.133333 34.133333 34.133333h273.066667c20.48 0 34.133333-13.653333 34.133333-34.133333s-13.653333-34.133333-34.133333-34.133334zM1058.133333 520.533333h-136.533333c-20.48 0-34.133333 13.653333-34.133333 34.133334s13.653333 34.133333 34.133333 34.133333h136.533333c20.48 0 34.133333-13.653333 34.133334-34.133333s-13.653333-34.133333-34.133334-34.133334z" horiz-adv-x="1501" />
<glyph glyph-name="upload" unicode="&#59243;" d="M704 554.666667h64a64 64 0 0 0 64-64v-362.666667a64 64 0 0 0-64-64H256a64 64 0 0 0-64 64V490.666667a64 64 0 0 0 64 64h64v-64h-64v-362.666667h512V490.666667h-64v64zM517.653333 771.370667l150.826667-150.826667-45.226667-45.269333-74.026666 74.005333v-304.768h-64V648.384l-73.173334-73.130667-45.248 45.248 150.826667 150.848z" horiz-adv-x="1024" />
<glyph glyph-name="fabuzhiwei" unicode="&#59198;" d="M851.781818-118.690909H139.636364c-79.127273 0-139.636364 60.509091-139.636364 139.636364V751.709091c0 79.127273 60.509091 139.636364 139.636364 139.636364h470.109091c27.927273 0 46.545455-18.618182 46.545454-46.545455s-18.618182-46.545455-46.545454-46.545455H139.636364c-27.927273 0-46.545455-18.618182-46.545455-46.545454v-730.763636c0-27.927273 18.618182-46.545455 46.545455-46.545455h712.145454c27.927273 0 46.545455 18.618182 46.545455 46.545455V528.290909c0 27.927273 18.618182 46.545455 46.545454 46.545455s46.545455-18.618182 46.545455-46.545455v-507.345454c0-74.472727-60.509091-139.636364-139.636364-139.636364zM721.454545 109.381818H269.963636c-18.618182 0-37.236364 13.963636-37.236363 37.236364s13.963636 37.236364 37.236363 37.236363h451.490909c18.618182 0 37.236364-13.963636 37.236364-37.236363s-13.963636-37.236364-37.236364-37.236364zM721.454545 342.109091H269.963636c-18.618182 0-37.236364 13.963636-37.236363 37.236364s13.963636 37.236364 37.236363 37.236363h451.490909c18.618182 0 37.236364-13.963636 37.236364-37.236363s-13.963636-37.236364-37.236364-37.236364zM442.181818 560.872727H269.963636c-18.618182 0-37.236364 13.963636-37.236363 32.581818s13.963636 37.236364 37.236363 37.236364h172.218182c18.618182 0 37.236364-13.963636 37.236364-37.236364s-13.963636-32.581818-37.236364-32.581818zM656.290909 528.290909c-13.963636 0-23.272727 4.654545-32.581818 13.963636-18.618182 18.618182-18.618182 46.545455 0 65.163637L893.672727 863.418182c18.618182 18.618182 46.545455 18.618182 65.163637 0 18.618182-18.618182 18.618182-46.545455 0-65.163637l-269.963637-256c-9.309091-9.309091-18.618182-13.963636-32.581818-13.963636z" horiz-adv-x="1024" />
<glyph glyph-name="zhiweiyaoqiu" unicode="&#59197;" d="M823.652174-128H200.347826c-75.686957 0-133.565217 57.878261-133.565217 133.565217V628.869565c0 75.686957 57.878261 133.565217 133.565217 133.565218h623.304348c75.686957 0 133.565217-57.878261 133.565217-133.565218v-623.304348c0-75.686957-57.878261-133.565217-133.565217-133.565217zM200.347826 673.391304c-26.713043 0-44.521739-17.808696-44.521739-44.521739v-623.304348c0-26.713043 17.808696-44.521739 44.521739-44.521739h623.304348c26.713043 0 44.521739 17.808696 44.521739 44.521739V628.869565c0 26.713043-17.808696 44.521739-44.521739 44.521739H200.347826zM311.652174 642.226087c-26.713043 0-44.521739 17.808696-44.521739 44.521739V838.121739c0 26.713043 17.808696 44.521739 44.521739 44.521739s44.521739-17.808696 44.521739-44.521739v-146.921739c0-26.713043-17.808696-48.973913-44.521739-48.973913zM756.869565 642.226087c-26.713043 0-44.521739 17.808696-44.521739 44.521739V838.121739c0 26.713043 17.808696 44.521739 44.521739 44.521739s44.521739-17.808696 44.521739-44.521739v-146.921739c0-26.713043-17.808696-48.973913-44.521739-48.973913zM721.252174 486.4H302.747826c-17.808696 0-35.617391 13.356522-35.617391 35.617391s13.356522 35.617391 35.617391 35.617392h414.052174c17.808696 0 35.617391-13.356522 35.617391-35.617392s-13.356522-35.617391-31.165217-35.617391zM721.252174 263.791304H302.747826c-17.808696 0-35.617391 13.356522-35.617391 35.617392s13.356522 35.617391 35.617391 35.617391h414.052174c17.808696 0 35.617391-13.356522 35.617391-35.617391s-13.356522-35.617391-31.165217-35.617392zM645.565217 58.991304H302.747826c-17.808696 0-35.617391 13.356522-35.617391 35.617392s13.356522 35.617391 35.617391 35.617391H645.565217c17.808696 0 35.617391-13.356522 35.617392-35.617391s-17.808696-35.617391-35.617392-35.617392z" horiz-adv-x="1024" />
<glyph glyph-name="gongsijieshao" unicode="&#59196;" d="M487.619048 569.295238H414.47619c-39.009524 0-68.266667 34.133333-68.266666 73.142857s29.257143 68.266667 68.266666 68.266667H487.619048c39.009524 0 68.266667-29.257143 68.266666-68.266667s-29.257143-73.142857-68.266666-73.142857zM414.47619 661.942857c-9.752381 0-19.504762-9.752381-19.504761-19.504762s9.752381-19.504762 19.504761-19.504762H487.619048c9.752381 0 19.504762 9.752381 19.504762 19.504762s-9.752381 19.504762-19.504762 19.504762H414.47619zM487.619048 340.114286H414.47619c-39.009524 0-68.266667 29.257143-68.266666 68.266666s29.257143 68.266667 68.266666 68.266667H487.619048c39.009524 0 68.266667-29.257143 68.266666-68.266667s-29.257143-68.266667-68.266666-68.266666zM414.47619 427.885714c-9.752381 0-19.504762-9.752381-19.504761-19.504762s9.752381-19.504762 19.504761-19.504762H487.619048c9.752381 0 19.504762 9.752381 19.504762 19.504762s-9.752381 19.504762-19.504762 19.504762H414.47619zM487.619048 106.057143H414.47619c-39.009524 0-68.266667 29.257143-68.266666 68.266667s29.257143 68.266667 68.266666 68.266666H487.619048c39.009524 0 68.266667-29.257143 68.266666-68.266666s-29.257143-68.266667-68.266666-68.266667z m-73.142858 92.647619c-9.752381 0-19.504762-9.752381-19.504761-19.504762s9.752381-19.504762 19.504761-19.504762H487.619048c9.752381 0 19.504762 9.752381 19.504762 19.504762s-9.752381 19.504762-19.504762 19.504762H414.47619zM809.447619-79.238095h-633.904762V798.47619c0 53.638095 43.885714 97.52381 97.52381 97.52381h438.857143c53.638095 0 97.52381-43.885714 97.523809-97.52381v-877.714285z m-536.380952 97.523809h438.857143V798.47619h-438.857143v-780.190476zM1189.790476-79.238095h-463.238095V427.885714c0 53.638095 43.885714 97.52381 97.523809 97.52381h268.190477c53.638095 0 97.52381-43.885714 97.523809-97.52381V-79.238095z m-365.714286 97.523809h268.190477V427.885714h-268.190477V18.285714zM1297.066667-103.619048H68.266667c-29.257143 0-48.761905 19.504762-48.761905 48.761905s19.504762 48.761905 48.761905 48.761905h1223.923809c29.257143 0 48.761905-19.504762 48.761905-48.761905s-19.504762-48.761905-43.885714-48.761905z" horiz-adv-x="1365" />
<glyph glyph-name="gongsidizhi" unicode="&#59195;" d="M1015.466667-128H93.866667c-46.933333 0-85.333333 38.4-85.333334 85.333333v17.066667l59.733334 307.2c8.533333 38.4 42.666667 68.266667 85.333333 68.266667h85.333333v-85.333334h-85.333333L93.866667-42.666667h921.6l-59.733334 307.2h-89.6v85.333334h89.6c42.666667 0 76.8-29.866667 85.333334-68.266667l59.733333-307.2c4.266667-21.333333 0-46.933333-12.8-64-12.8-17.066667-34.133333-29.866667-55.466667-34.133333-8.533333-4.266667-12.8-4.266667-17.066666-4.266667zM554.666667 76.8l-29.866667 34.133333c-149.333333 153.6-243.2 264.533333-281.6 324.266667-34.133333 42.666667-46.933333 98.133333-46.933333 149.333333C196.266667 755.2 354.133333 896 554.666667 896s358.4-140.8 358.4-311.466667c0-55.466667-17.066667-110.933333-46.933334-157.866666-38.4-55.466667-132.266667-166.4-281.6-320l-29.866666-29.866667zM554.666667 810.666667C401.066667 810.666667 281.6 708.266667 281.6 584.533333c0-38.4 12.8-72.533333 34.133333-106.666666s85.333333-110.933333 243.2-277.333334c157.866667 166.4 217.6 238.933333 238.933334 273.066667 21.333333 34.133333 34.133333 68.266667 34.133333 106.666667-4.266667 128-123.733333 230.4-277.333333 230.4zM550.4 409.6c-72.533333 0-128 55.466667-128 128s55.466667 128 128 128 128-55.466667 128-128-59.733333-128-128-128z m0 213.333333c-46.933333 0-85.333333-38.4-85.333333-85.333333s38.4-85.333333 85.333333-85.333333 85.333333 38.4 85.333333 85.333333-38.4 85.333333-85.333333 85.333333z" horiz-adv-x="1109" />
<glyph glyph-name="jubushuaxinjiantou" unicode="&#59194;" d="M783.090347-128a35.498667 35.498667 0 0 0-22.528 8.192l-546.133334 477.866667a32.768 32.768 0 0 0-8.874666 22.528 34.133333 34.133333 0 0 0 11.605333 25.941333l546.133333 477.866667a32.768 32.768 0 0 0 47.786667 0 34.133333 34.133333 0 0 0 0-48.469334L288.83968 384l516.778667-449.194667a34.816 34.816 0 0 0 3.413333-48.469333 35.498667 35.498667 0 0 0-25.941333-14.336z" horiz-adv-x="1024" />
<glyph glyph-name="fanhui" unicode="&#59193;" d="M590.769231-107.362462H315.076923c-31.507692 0-63.015385 23.630769-63.015385 63.015385s23.630769 63.015385 63.015385 63.015385h275.692308c259.938462 0 378.092308 7.876923 378.092307 252.061538s-118.153846 252.061538-378.092307 252.061539H315.076923c-31.507692 0-63.015385 23.630769-63.015385 63.015384s31.507692 55.138462 63.015385 55.138462h275.692308c228.430769 0 496.246154 0 496.246154-378.092308s-267.815385-370.215385-496.246154-370.215385zM47.261538 514.914462l259.938462-196.923077c39.384615-23.630769 86.646154-15.753846 110.276923 15.753846 7.876923 15.753846 15.753846 31.507692 15.753846 47.261538v393.846154c0 47.261538-31.507692 78.769231-78.769231 78.769231-15.753846 0-31.507692-7.876923-47.261538-15.753846l-259.938462-196.923077c-39.384615-31.507692-47.261538-78.769231-15.753846-110.276923 0-7.876923 7.876923-15.753846 15.753846-15.753846z" horiz-adv-x="1102" />
<glyph glyph-name="tongji1" unicode="&#59192;" d="M702.171429 52.419048c-78.019048 0-141.409524 63.390476-141.409524 141.409523V754.590476c0 78.019048 63.390476 141.409524 141.409524 141.409524 78.019048 0 141.409524-63.390476 141.409523-141.409524v-565.638095c-4.87619-73.142857-68.266667-136.533333-141.409523-136.533333z m0 746.057142c-24.380952 0-43.885714-19.504762-43.885715-43.885714v-565.638095c0-24.380952 19.504762-43.885714 43.885715-43.885714s43.885714 19.504762 43.885714 43.885714V754.590476c-4.87619 24.380952-24.380952 43.885714-43.885714 43.885714zM1067.885714 52.419048c-78.019048 0-141.409524 63.390476-141.409524 141.409523V447.390476c0 78.019048 63.390476 141.409524 141.409524 141.409524s141.409524-63.390476 141.409524-141.409524v-253.561905c0-78.019048-63.390476-141.409524-141.409524-141.409523z m0 433.980952c-24.380952 0-43.885714-19.504762-43.885714-43.885714v-253.561905c0-24.380952 19.504762-43.885714 43.885714-43.885714s43.885714 19.504762 43.885715 43.885714V447.390476c0 19.504762-19.504762 39.009524-43.885715 39.009524zM331.580952 52.419048C253.561905 52.419048 195.047619 115.809524 195.047619 193.828571V447.390476c0 78.019048 63.390476 141.409524 141.409524 141.409524 78.019048 0 141.409524-63.390476 141.409524-141.409524v-253.561905c-4.87619-78.019048-68.266667-141.409524-146.285715-141.409523z m0 433.980952c-19.504762 0-39.009524-19.504762-39.009523-39.009524v-253.561905c0-24.380952 19.504762-43.885714 43.885714-43.885714s43.885714 19.504762 43.885714 43.885714V447.390476c-4.87619 19.504762-24.380952 39.009524-48.761905 39.009524zM1297.066667-108.495238H48.761905c-29.257143 0-48.761905 19.504762-48.761905 48.761905v536.380952c0 29.257143 19.504762 48.761905 48.761905 48.761905s48.761905-19.504762 48.761905-48.761905v-487.619048h1199.542857c29.257143 0 48.761905-19.504762 48.761904-48.761904s-24.380952-48.761905-48.761904-48.761905z" horiz-adv-x="1365" />
<glyph glyph-name="qiandao-1" unicode="&#59190;" d="M881.509434-128h-724.528302a157.584906 157.584906 0 0 0-156.981132 156.981132v603.773585a157.584906 157.584906 0 0 0 156.981132 156.981132h724.528302a157.584906 157.584906 0 0 0 156.981132-156.981132v-603.773585a157.584906 157.584906 0 0 0-156.981132-156.981132z m-724.528302 845.283019a84.528302 84.528302 0 0 1-84.528302-84.528302v-603.773585a84.528302 84.528302 0 0 1 84.528302-84.528302h724.528302a84.528302 84.528302 0 0 1 84.528302 84.528302v603.773585a84.528302 84.528302 0 0 1-84.528302 84.528302zM277.735849 859.773585v-241.509434M277.735849 582.037736a36.226415 36.226415 0 0 0-36.226415 36.226415v241.509434a36.226415 36.226415 0 1 0 72.45283 0v-241.509434a36.226415 36.226415 0 0 0-36.226415-36.226415zM760.754717 859.773585v-241.509434M760.754717 582.037736a36.226415 36.226415 0 0 0-36.226415 36.226415v241.509434a36.226415 36.226415 0 0 0 72.45283 0v-241.509434a36.226415 36.226415 0 0 0-36.226415-36.226415zM486.641509 149.735849a37.433962 37.433962 0 0 0-27.773584 10.867925l-175.09434 181.132075a36.226415 36.226415 0 0 0 0 51.320755 36.830189 36.830189 0 0 0 51.320755 0l152.754717-158.792453 281.962264 221.584906a36.226415 36.226415 0 0 0 50.716981-6.037736 36.830189 36.830189 0 0 0-6.037736-51.320755l-307.320755-241.509434a38.037736 38.037736 0 0 0-20.528302-7.245283z" horiz-adv-x="1038" />
<glyph glyph-name="xiajiantou2" unicode="&#59191;" d="M796.390468-127.928326a113.768929 113.768929 0 0 0-86.464386 39.819126l-682.613575 796.382503A113.768929 113.768929 0 1 0 200.24128 856.172911L796.390468 156.493997 1392.539656 851.622154a113.768929 113.768929 0 0 0 172.928773-147.899608l-682.613575-796.382504A113.768929 113.768929 0 0 0 796.390468-127.928326z" horiz-adv-x="1592" />
<glyph glyph-name="qiandao-" unicode="&#59189;" d="M881.509434-128h-724.528302a157.584906 157.584906 0 0 0-156.981132 156.981132v603.773585a157.584906 157.584906 0 0 0 156.981132 156.981132h724.528302a157.584906 157.584906 0 0 0 156.981132-156.981132v-603.773585a157.584906 157.584906 0 0 0-156.981132-156.981132z m-724.528302 845.283019a84.528302 84.528302 0 0 1-84.528302-84.528302v-603.773585a84.528302 84.528302 0 0 1 84.528302-84.528302h724.528302a84.528302 84.528302 0 0 1 84.528302 84.528302v603.773585a84.528302 84.528302 0 0 1-84.528302 84.528302zM277.735849 859.773585v-241.509434M277.735849 582.037736a36.226415 36.226415 0 0 0-36.226415 36.226415v241.509434a36.226415 36.226415 0 1 0 72.45283 0v-241.509434a36.226415 36.226415 0 0 0-36.226415-36.226415zM760.754717 859.773585v-241.509434M760.754717 582.037736a36.226415 36.226415 0 0 0-36.226415 36.226415v241.509434a36.226415 36.226415 0 0 0 72.45283 0v-241.509434a36.226415 36.226415 0 0 0-36.226415-36.226415zM486.641509 149.73584900000003a37.433962 37.433962 0 0 0-27.773584 10.867925l-175.09434 181.132075a36.226415 36.226415 0 0 0 0 51.320755 36.830189 36.830189 0 0 0 51.320755 0l152.754717-158.792453 281.962264 221.584906a36.226415 36.226415 0 0 0 50.716981-6.037736 36.830189 36.830189 0 0 0-6.037736-51.320755l-307.320755-241.509434a38.037736 38.037736 0 0 0-20.528302-7.245283z" horiz-adv-x="1038" />
<glyph glyph-name="yidong" unicode="&#59188;" d="M855.341176-121.976471H174.682353c-90.352941 0-156.611765 72.282353-156.611765 156.611765V721.317647C18.070588 811.670588 90.352941 877.929412 174.682353 877.929412h680.658823c90.352941 0 156.611765-72.282353 156.611765-156.611765v-78.305882h-90.352941V721.317647c0 36.141176-30.117647 66.258824-66.258824 66.258824H174.682353c-36.141176 0-66.258824-30.117647-66.258824-66.258824v-680.658823c0-36.141176 30.117647-66.258824 66.258824-66.258824h680.658823c36.141176 0 66.258824 30.117647 66.258824 66.258824v78.305882h90.352941v-78.305882c6.023529-90.352941-66.258824-162.635294-156.611765-162.635295zM951.717647 299.670588H271.058824c-24.094118 0-48.188235 18.070588-48.188236 48.188236s18.070588 48.188235 48.188236 48.188235h680.658823c24.094118 0 48.188235-18.070588 48.188235-48.188235s-24.094118-48.188235-48.188235-48.188236zM1084.235294 347.858824L921.6 173.176471V534.588235L1084.235294 359.905882v-12.047058z" horiz-adv-x="1084" />
<glyph glyph-name="xiayi1" unicode="&#59186;" d="M512 384m-481.882353 0a481.882353 481.882353 0 1 1 963.764706 0 481.882353 481.882353 0 1 1-963.764706 0ZM512-128C228.894118-128 0 100.894118 0 384S228.894118 896 512 896 1024 667.105882 1024 384 795.105882-128 512-128z m0 963.764706C265.035294 835.764706 60.235294 630.964706 60.235294 384S265.035294-67.764706 512-67.764706 963.764706 137.035294 963.764706 384 758.964706 835.764706 512 835.764706zM502.964706 143.058824c-18.070588 0-30.117647 12.047059-30.117647 30.117647V588.8c0 18.070588 12.047059 30.117647 30.117647 30.117647s30.117647-12.047059 30.117647-30.117647V173.176471c0-18.070588-12.047059-30.117647-30.117647-30.117647zM502.964706 88.847059c-6.023529 0-12.047059 0-18.070588 6.023529l-144.564706 132.517647c-12.047059 12.047059-12.047059 30.117647 0 42.164706 12.047059 12.047059 30.117647 12.047059 42.164706 0l126.494117-108.423529 132.517647 108.423529c12.047059 12.047059 30.117647 12.047059 42.164706-6.023529 6.023529-6.023529 6.023529-30.117647-12.047059-36.141177l-150.588235-132.517647c-6.023529 0-12.047059-6.023529-18.070588-6.023529z" horiz-adv-x="1024" />
<glyph glyph-name="shangyi1" unicode="&#59185;" d="M512 384m-481.882353 0a481.882353 481.882353 0 1 1 963.764706 0 481.882353 481.882353 0 1 1-963.764706 0ZM512-128C228.894118-128 0 100.894118 0 384S228.894118 896 512 896 1024 667.105882 1024 384 795.105882-128 512-128z m0 963.764706C265.035294 835.764706 60.235294 630.964706 60.235294 384S265.035294-67.764706 512-67.764706 963.764706 137.035294 963.764706 384 758.964706 835.764706 512 835.764706zM502.964706 106.917647c-18.070588 0-30.117647 12.047059-30.117647 30.117647V552.658824c0 18.070588 12.047059 30.117647 30.117647 30.117647s30.117647-12.047059 30.117647-30.117647v-415.62353c0-18.070588-12.047059-30.117647-30.117647-30.117647zM653.552941 444.235294c-6.023529 0-12.047059 0-18.070588 6.02353l-132.517647 114.447058-126.494118-108.423529c-12.047059-12.047059-30.117647-12.047059-42.164706 0-12.047059 12.047059-12.047059 30.117647 0 42.164706l144.564706 126.494117c12.047059 12.047059 30.117647 12.047059 42.164706 0l150.588235-126.494117c12.047059-12.047059 12.047059-30.117647 6.02353-42.164706-6.023529-6.023529-12.047059-12.047059-24.094118-12.047059z" horiz-adv-x="1024" />
<glyph glyph-name="xiayi" unicode="&#59184;" d="M512 384m-481.882353 0a481.882353 481.882353 0 1 1 963.764706 0 481.882353 481.882353 0 1 1-963.764706 0ZM512-128C228.894118-128 0 100.894118 0 384S228.894118 896 512 896 1024 667.105882 1024 384 795.105882-128 512-128z m0 963.764706C265.035294 835.764706 60.235294 630.964706 60.235294 384S265.035294-67.764706 512-67.764706 963.764706 137.035294 963.764706 384 758.964706 835.764706 512 835.764706zM502.964706 143.058824c-18.070588 0-30.117647 12.047059-30.117647 30.117647V588.8c0 18.070588 12.047059 30.117647 30.117647 30.117647s30.117647-12.047059 30.117647-30.117647V173.176471c0-18.070588-12.047059-30.117647-30.117647-30.117647zM502.964706 88.847059c-6.023529 0-12.047059 0-18.070588 6.023529l-144.564706 132.517647c-12.047059 12.047059-12.047059 30.117647 0 42.164706 12.047059 12.047059 30.117647 12.047059 42.164706 0l126.494117-108.423529 132.517647 108.423529c12.047059 12.047059 30.117647 12.047059 42.164706-6.023529 6.023529-6.023529 6.023529-30.117647-12.047059-36.141177l-150.588235-132.517647c-6.023529 0-12.047059-6.023529-18.070588-6.023529z" horiz-adv-x="1024" />
<glyph glyph-name="shangyi" unicode="&#59183;" d="M512 384m-481.882353 0a481.882353 481.882353 0 1 1 963.764706 0 481.882353 481.882353 0 1 1-963.764706 0ZM512-128C228.894118-128 0 100.894118 0 384S228.894118 896 512 896 1024 667.105882 1024 384 795.105882-128 512-128z m0 963.764706C265.035294 835.764706 60.235294 630.964706 60.235294 384S265.035294-67.764706 512-67.764706 963.764706 137.035294 963.764706 384 758.964706 835.764706 512 835.764706zM502.964706 106.917647c-18.070588 0-30.117647 12.047059-30.117647 30.117647V552.658824c0 18.070588 12.047059 30.117647 30.117647 30.117647s30.117647-12.047059 30.117647-30.117647v-415.62353c0-18.070588-12.047059-30.117647-30.117647-30.117647zM653.552941 444.235294c-6.023529 0-12.047059 0-18.070588 6.02353l-132.517647 114.447058-126.494118-108.423529c-12.047059-12.047059-30.117647-12.047059-42.164706 0-12.047059 12.047059-12.047059 30.117647 0 42.164706l144.564706 126.494117c12.047059 12.047059 30.117647 12.047059 42.164706 0l150.588235-126.494117c12.047059-12.047059 12.047059-30.117647 6.02353-42.164706-6.023529-6.023529-12.047059-12.047059-24.094118-12.047059z" horiz-adv-x="1024" />
<glyph glyph-name="bianji5" unicode="&#59182;" d="M704.752941-97.882353H198.776471c-78.305882 0-138.541176 60.235294-138.541177 132.517647V667.105882c0 72.282353 66.258824 132.517647 138.541177 132.517647h319.247058c18.070588 0 30.117647-12.047059 30.117647-30.117647s-12.047059-24.094118-30.117647-24.094117H198.776471c-42.164706 0-78.305882-36.141176-78.305883-72.282353v-632.470588c0-42.164706 36.141176-72.282353 78.305883-72.282353h499.952941c42.164706 0 78.305882 36.141176 78.305882 72.282353V293.647059c0 18.070588 12.047059 30.117647 30.117647 30.117647s30.117647-12.047059 30.117647-30.117647v-259.011765c6.023529-72.282353-60.235294-132.517647-132.517647-132.517647zM313.223529 161.129412c-24.094118 0-54.211765 18.070588-60.235294 48.188235v30.117647l36.141177 126.494118 445.741176 445.741176c48.188235 48.188235 120.470588 48.188235 168.658824 0 48.188235-48.188235 48.188235-120.470588 0-168.658823l-445.741177-445.741177-126.494117-30.117647c-6.023529-6.023529-12.047059-6.023529-18.070589-6.023529z m36.141177 174.682353l-36.141177-114.447059 120.470589 30.117647 433.694117 433.694118c12.047059 12.047059 18.070588 24.094118 18.070589 42.164705 0 18.070588-6.023529 30.117647-18.070589 42.164706-24.094118 24.094118-60.235294 24.094118-84.329411 0L349.364706 335.811765z" horiz-adv-x="1024" />
<glyph glyph-name="shanchu3" unicode="&#59181;" d="M654.222222-99.555556H375.466667c-68.266667 0-125.155556 56.888889-136.533334 142.222223L142.222222 571.733333c0 17.066667 5.688889 28.444444 22.755556 34.133334 17.066667 0 28.444444-5.688889 34.133333-22.755556l91.022222-534.755555c11.377778-51.2 45.511111-91.022222 85.333334-91.022223h278.755555c39.822222 0 73.955556 39.822222 85.333334 91.022223l91.022222 534.755555c0 17.066667 17.066667 28.444444 34.133333 22.755556 17.066667 0 28.444444-17.066667 22.755556-34.133334L796.444444 42.666667c-17.066667-85.333333-73.955556-142.222222-142.222222-142.222223zM597.333333 708.266667v5.688889c0 51.2-39.822222 96.711111-85.333333 96.711111s-85.333333-45.511111-85.333333-102.4h-56.888889C369.777778 793.6 432.355556 867.555556 512 867.555556c73.955556 0 136.533333-68.266667 142.222222-147.911112v-5.688888l-56.888889-5.688889zM398.222222 36.977778c-11.377778 0-28.444444 11.377778-28.444444 22.755555L284.444444 577.422222c0 17.066667 11.377778 34.133333 22.755556 34.133334 17.066667 5.688889 34.133333-5.688889 34.133333-22.755556l85.333334-517.688889c0-17.066667-5.688889-34.133333-28.444445-34.133333 5.688889 0 0 0 0 0zM625.777778 36.977778s-5.688889 0 0 0c-22.755556 5.688889-28.444444 17.066667-28.444445 34.133333L682.666667 588.8c0 17.066667 17.066667 28.444444 34.133333 22.755556 11.377778 0 22.755556-17.066667 22.755556-34.133334l-85.333334-517.688889c0-11.377778-17.066667-22.755556-28.444444-22.755555zM512 36.977778c-17.066667 0-28.444444 11.377778-28.444444 28.444444V583.111111c0 17.066667 11.377778 28.444444 28.444444 28.444445s28.444444-11.377778 28.444444-28.444445v-517.688889c0-17.066667-11.377778-28.444444-28.444444-28.444444zM938.666667 645.688889H85.333333c-17.066667 0-28.444444 17.066667-28.444444 28.444444s11.377778 28.444444 28.444444 28.444445h853.333334c17.066667 0 28.444444-11.377778 28.444444-28.444445s-11.377778-28.444444-28.444444-28.444444z" horiz-adv-x="1024" />
<glyph glyph-name="xuanze" unicode="&#59180;" d="M870.4 896H153.6C66.56 896 0 829.44 0 742.4v-716.8c0-87.04 66.56-153.6 153.6-153.6h716.8c87.04 0 153.6 66.56 153.6 153.6V742.4c0 87.04-66.56 153.6-153.6 153.6z m-40.96-394.24l-337.92-358.4c-10.24-10.24-25.6-15.36-40.96-15.36-10.24 0-20.48 5.12-30.72 10.24L174.08 332.8c-20.48 15.36-25.6 51.2-10.24 71.68 15.36 20.48 51.2 25.6 71.68 10.24l209.92-163.84 307.2 327.68c20.48 20.48 51.2 20.48 71.68 0 20.48-20.48 25.6-56.32 5.12-76.8z" horiz-adv-x="1024" />
<glyph glyph-name="bianji4" unicode="&#59178;" d="M934.724189 617.173271L834.414864 516.863946 653.380212 697.898598l100.394659 100.351991A42.257063 42.257063 0 0 0 783.769535 810.666588c6.527999 0 19.157332-1.621333 29.951997-12.415999l121.002657-121.002656a42.538663 42.538663 0 0 0 0-60.074662zM299.374908-18.176009l-200.661316-19.626665 19.669331 200.661316L593.049551 637.52527 774.084202 456.533285l-474.709294-474.709294z m695.679942 755.79727L874.09486 858.581251A127.317323 127.317323 0 0 1 783.769535 895.999915c-32.725331 0-65.407995-12.458666-90.367993-37.418664l-646.229279-646.229279c-7.082666-7.082666-11.434666-16.469332-12.287999-26.495998l-26.197331-267.818645c-2.133333-25.002665 17.706665-46.037329 42.239996-46.037329 1.194667 0 2.432 0.042667 3.626666 0.128l267.818645 26.239998a42.12053 42.12053 0 0 1 26.495998 12.287999l646.186612 646.186613c49.919996 49.919996 49.919996 130.858656 0 180.778651z" horiz-adv-x="1032" />

Before

Width:  |  Height:  |  Size: 394 KiB

After

Width:  |  Height:  |  Size: 428 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,23 +1,35 @@
.CodeMirror-merge {
position: relative;
white-space: pre;
}
.CodeMirror-merge, .CodeMirror-merge .CodeMirror {
min-height:50px;
.CodeMirror-merge,
.CodeMirror-merge .CodeMirror {
min-height: 50px;
}
.CodeMirror-merge-2pane .CodeMirror-merge-pane { width: 48%; }
.CodeMirror-merge-2pane .CodeMirror-merge-gap { width: 4%; }
.CodeMirror-merge-3pane .CodeMirror-merge-pane { width: 31%; }
.CodeMirror-merge-3pane .CodeMirror-merge-gap { width: 3.5%; }
.CodeMirror-merge-2pane .CodeMirror-merge-pane {
width: 48%;
}
.CodeMirror-merge-2pane .CodeMirror-merge-gap {
width: 4%;
}
.CodeMirror-merge-3pane .CodeMirror-merge-pane {
width: 31%;
}
.CodeMirror-merge-3pane .CodeMirror-merge-gap {
width: 3.5%;
}
.CodeMirror-merge-pane {
display: inline-block;
white-space: normal;
vertical-align: top;
}
.CodeMirror-merge-pane-rightmost {
position: absolute;
right: 0px;
@ -25,20 +37,22 @@
}
.CodeMirror-merge-gap {
z-index: 2;
display: inline-block;
height: 100%;
-moz-box-sizing: border-box;
box-sizing: border-box;
overflow: hidden;
position: relative;
background: #515151;
z-index: 2;
display: inline-block;
height: 100%;
-moz-box-sizing: border-box;
box-sizing: border-box;
overflow: hidden;
position: relative;
background: #515151;
}
.CodeMirror-merge-scrolllock-wrap {
position: absolute;
bottom: 0; left: 50%;
bottom: 0;
left: 50%;
}
.CodeMirror-merge-scrolllock {
position: relative;
left: -50%;
@ -47,10 +61,13 @@
line-height: 1;
}
.CodeMirror-merge-copybuttons-left, .CodeMirror-merge-copybuttons-right {
.CodeMirror-merge-copybuttons-left,
.CodeMirror-merge-copybuttons-right {
position: absolute;
left: 0; top: 0;
right: 0; bottom: 0;
left: 0;
top: 0;
right: 0;
bottom: 0;
line-height: 1;
}
@ -67,38 +84,70 @@
color: #44c;
}
.CodeMirror-merge-copybuttons-left .CodeMirror-merge-copy { left: 2px; }
.CodeMirror-merge-copybuttons-right .CodeMirror-merge-copy { right: 2px; }
.CodeMirror-merge-copybuttons-left .CodeMirror-merge-copy {
left: 2px;
}
.CodeMirror-merge-r-inserted, .CodeMirror-merge-l-inserted {
.CodeMirror-merge-copybuttons-right .CodeMirror-merge-copy {
right: 2px;
}
.CodeMirror-merge-r-inserted,
.CodeMirror-merge-l-inserted {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAACCAYAAACddGYaAAAAGUlEQVQI12MwuCXy3+CWyH8GBgYGJgYkAABZbAQ9ELXurwAAAABJRU5ErkJggg==);
background-position: bottom left;
background-repeat: repeat-x;
}
.CodeMirror-merge-r-deleted, .CodeMirror-merge-l-deleted {
.CodeMirror-merge-r-deleted,
.CodeMirror-merge-l-deleted {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAACCAYAAACddGYaAAAAGUlEQVQI12M4Kyb2/6yY2H8GBgYGJgYkAABURgPz6Ks7wQAAAABJRU5ErkJggg==);
background-position: bottom left;
background-repeat: repeat-x;
}
.CodeMirror-merge-r-chunk { background: #9a6868; }
.CodeMirror-merge-r-chunk-start { /*border-top: 1px solid #ee8; */}
.CodeMirror-merge-r-chunk-end {/* border-bottom: 1px solid #ee8; */}
.CodeMirror-merge-r-connect { fill:#9a6868;}
.CodeMirror-merge-r-chunk {
background: #9a6868;
}
.CodeMirror-merge-l-chunk { background: #eef; }
.CodeMirror-merge-l-chunk-start { border-top: 1px solid #88e; }
.CodeMirror-merge-l-chunk-end { border-bottom: 1px solid #88e; }
.CodeMirror-merge-l-connect { fill: #eef; stroke: #88e; stroke-width: 1px; }
.CodeMirror-merge-r-connect {
fill: #9a6868;
}
.CodeMirror-merge-l-chunk.CodeMirror-merge-r-chunk { background: #dfd; }
.CodeMirror-merge-l-chunk-start.CodeMirror-merge-r-chunk-start { border-top: 1px solid #4e4; }
.CodeMirror-merge-l-chunk-end.CodeMirror-merge-r-chunk-end { border-bottom: 1px solid #4e4; }
.CodeMirror-merge-l-chunk {
background: #eef;
}
.CodeMirror-merge-l-chunk-start {
border-top: 1px solid #88e;
}
.CodeMirror-merge-l-chunk-end {
border-bottom: 1px solid #88e;
}
.CodeMirror-merge-l-connect {
fill: #eef;
stroke: #88e;
stroke-width: 1px;
}
.CodeMirror-merge-l-chunk.CodeMirror-merge-r-chunk {
background: #dfd;
}
.CodeMirror-merge-l-chunk-start.CodeMirror-merge-r-chunk-start {
border-top: 1px solid #4e4;
}
.CodeMirror-merge-l-chunk-end.CodeMirror-merge-r-chunk-end {
border-bottom: 1px solid #4e4;
}
.CodeMirror-merge-collapsed-widget:before {
content: "(...)";
}
.CodeMirror-merge-collapsed-widget {
cursor: pointer;
color: #88b;
@ -108,4 +157,7 @@
padding: 0 3px;
border-radius: 4px;
}
.CodeMirror-merge-collapsed-line .CodeMirror-gutter-elt { display: none; }
.CodeMirror-merge-collapsed-line .CodeMirror-gutter-elt {
display: none;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,103 +1,53 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<head>
<meta name=”Keywords” Content=”EduCoder,信息技术实践教学,精品课程网,慕课MOOC″>
<meta name=”Keywords” Content=”实践课程,项目实战,java实训,python实战,人工智能技术,后端开发学习,移动开发入门″>
<meta name=”Keywords” Content=”翻转课堂,高效课堂创建,教学模式″>
<meta name=”Keywords” Content=”实训项目,python教程,C语言入门,java书,php后端开发,app前端开发,数据库技术″>
<meta name=”Keywords” Content=”在线竞赛,计算机应用大赛,编程大赛,大学生计算机设计大赛,全国高校绿色计算机大赛″>
<meta name=”Description” Content=”EduCoder是信息技术类实践教学平台。EduCoder涵盖了计算机、大数据、云计算、人工智能、软件工程、物联网等专业课程。超10000个实训案例及22000个技能评测点建立学、练、评、测一体化实验环境。”>
<meta name=”Description” Content=”EduCoder实践课程旨在于通过企业级实战实训案例帮助众多程序员提升各项业务能力。解决学生、学员、企业员工等程序设计能力、算法设计能力、问题求解能力、应用开发能力、系统运维能力等。”>
<meta name=”Description” Content=”EduCoder翻转课堂教学模式颠覆了传统教学模式让教师与学生的关系由“权威”变成了“伙伴”。将学习的主动权转交给学生使学生可个性化化学学生的学习主体得到了彰显。”>
<meta name=”Description” Content=”EduCoder实训项目为单个知识点关卡实践训练帮助学生巩固单一弱点强化学习。 >
<meta name=”Description” Content=”EduCoder实践教学平台各类大赛为进一步提高各类学生综合运用高级语言程序设计能力培养创新意识和实践探索精神发掘优秀软件人才。 >
<meta name="viewport" id="viewport" content="width=device-width, initial-scale=0.3, maximum-scale=0.3">
<meta charset="utf-8">
<meta name=”Keywords” Content=”EduCoder,信息技术实践教学,精品课程网,慕课MOOC″>
<meta name=”Keywords” Content=”实践课程,项目实战,java实训,python实战,人工智能技术,后端开发学习,移动开发入门″>
<meta name=”Keywords” Content=”翻转课堂,高效课堂创建,教学模式″>
<meta name=”Keywords” Content=”实训项目,python教程,C语言入门,java书,php后端开发,app前端开发,数据库技术″>
<meta name=”Keywords” Content=”在线竞赛,计算机应用大赛,编程大赛,大学生计算机设计大赛,全国高校绿色计算机大赛″>
<meta name=”Description”
Content=”EduCoder是信息技术类实践教学平台。EduCoder涵盖了计算机、大数据、云计算、人工智能、软件工程、物联网等专业课程。超10000个实训案例及22000个技能评测点建立学、练、评、测一体化实验环境。”>
<meta name=”Description”
Content=”EduCoder实践课程旨在于通过企业级实战实训案例帮助众多程序员提升各项业务能力。解决学生、学员、企业员工等程序设计能力、算法设计能力、问题求解能力、应用开发能力、系统运维能力等。”>
<meta name=”Description”
Content=”EduCoder翻转课堂教学模式颠覆了传统教学模式让教师与学生的关系由“权威”变成了“伙伴”。将学习的主动权转交给学生使学生可个性化化学学生的学习主体得到了彰显。”>
<meta name=”Description” Content=”EduCoder实训项目为单个知识点关卡实践训练帮助学生巩固单一弱点强化学习。 >
<meta name=”Description” Content=”EduCoder实践教学平台各类大赛为进一步提高各类学生综合运用高级语言程序设计能力培养创新意识和实践探索精神发掘优秀软件人才。 >
<meta name="theme-color" content="#000000">
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
<meta name="theme-color" content="#000000">
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
<script type="text/javascript">
window.__isR = true;
if (
(navigator.userAgent.indexOf('MSIE 9') != -1
|| navigator.userAgent.indexOf('MSIE 10') != -1)
&&
location.pathname.indexOf("/compatibility") == -1) {
location.href = '/compatibility.html'
}
</script>
<script type="text/javascript">
<link rel=" stylesheet" type="text/css" href="%PUBLIC_URL%css/iconfont.css">
<link rel=" stylesheet" type="text/css" href="%PUBLIC_URL%css/edu-purge.css">
<link rel="stylesheet" type="text/css" href="%PUBLIC_URL%css/editormd.min.css">
<link rel="stylesheet" type="text/css" href="%PUBLIC_URL%css/merge.css">
<%= htmlWebpackPlugin.tags.headTags %>
</head>
window.__isR = true;
// 不支持ie9 ie10
if (
( navigator.userAgent.indexOf('MSIE 9') != -1
|| navigator.userAgent.indexOf('MSIE 10') != -1 )
&&
location.pathname.indexOf("/compatibility") == -1) {
debugger;
// location.href = './compatibility'
location.href = '/compatibility.html'
}
// const isMobile = (/android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini/i.test(navigator.userAgent.toLowerCase()));
const isWeiXin = (/MicroMessenger/i.test(navigator.userAgent.toLowerCase()));
if (isWeiXin) {
document.write('<script type="text/javascript" src="/javascripts/wx/jweixin-1.3.0.js"><\/script>');
}
</script>
<link rel="stylesheet" type="text/css" href="/css/css_min_all.css">
<!--需要去build js配置-->
<link rel="stylesheet" type="text/css" href="/css/iconfont.css">
<body>
<!--用于markdown转html -->
<div id="md_div" style="display: none;"></div>
<div id="root" class="page -layout-v -fit widthunit"></div>
<div id="picture_display" style="display: none;"></div>
<script src="%PUBLIC_URL%js/js_min_all.js"></script>
<script src="%PUBLIC_URL%js/codemirror/codemirror.js"></script>
<script src="%PUBLIC_URL%js/editormd/editormd.min.js"></script>
<script src="%PUBLIC_URL%js/codemirror/merge/merge.js"></script>
<%= htmlWebpackPlugin.tags.bodyTags %>
</body>
<link rel="stylesheet" type="text/css" href="https://cdn.bootcss.com/quill/1.3.7/quill.core.min.css">
<style>
/*<!--去除浏览器点击操作后有蓝色的底块-->*/
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
user-select: none;
</style>
</head>
<body>
<noscript>
You need to enable JavaScript to run this app.
</noscript>
<!--用于markdown转html -->
<div id="md_div" style="display: none;"></div>
<div id="root" class="page -layout-v -fit widthunit">
</div>
<div id="picture_display" style="display: none;"></div>
<!-- js css合并 文件优先级的问题 -->
<script type="text/javascript" src="/js/js_min_all.js"></script>
<!-- 在tpi js里加载这3个脚本 -->
<script>
(function() { // Scoping function to avoid globals
var href = location.href;
if(window.location.port === "3007"){
if (href.indexOf('/tasks/') != -1) {
document.write('<script type="text/javascript" src="https://newweb.educoder.net/assets/kindeditor/kindeditor.js"><\/script>');
// build.js中会将这个url附加一个前缀 react/build
document.write('<script type="text/javascript" src="/js/create_kindeditor.js"><\/script>');
document.write('<script type="text/javascript" src="https://newweb.educoder.net/javascripts/educoder/edu_application.js"><\/script>');
} else if (href.indexOf('/paths/') != -1) {
document.write('<script type="text/javascript" src="https://newweb.educoder.net/javascripts/educoder/edu_application.js"><\/script>');
}
}else{
if (href.indexOf('/tasks/') != -1) {
document.write('<script type="text/javascript" src="/assets/kindeditor/kindeditor.js"><\/script>');
// build.js中会将这个url附加一个前缀 react/build
document.write('<script type="text/javascript" src="/js/create_kindeditor.js"><\/script>');
document.write('<script type="text/javascript" src="/javascripts/educoder/edu_application.js"><\/script>');
} else if (href.indexOf('/paths/') != -1) {
document.write('<script type="text/javascript" src="/javascripts/educoder/edu_application.js"><\/script>');
}
}
})();
</script>
<script type="text/javascript" src="https://cdn.bootcss.com/quill/1.3.7/quill.core.min.js"></script>
</body>
</html>
</html>

View File

@ -11267,7 +11267,7 @@ Copyright © 2018 Basecamp, LLC
type: "GET",
dataType: "script",
cache: true,
async: false,
async: true,
global: false,
// Only evaluate the response if it is successful (gh-4126)

378
public/js/create_kindeditor.js Executable file → Normal file
View File

@ -1,5 +1,5 @@
//需求:表情栏可以隐藏显示,高度只要一点高
function sd_create_editor(params){
function sd_create_editor(params) {
// var minHeight; //最小高度
var paramsHeight = params.height; //设定的高度
var id = arguments[1] ? arguments[1] : undefined;
@ -7,40 +7,40 @@ function sd_create_editor(params){
var paramsWidth = params.width == undefined ? "100%" : params.width;
var editor = params.kindutil.create(params.textarea, {
resizeType : 1,minWidth:"1px",width:"94%",
height:"33px",// == undefined ? "30px":paramsHeight+"px",
minHeight:"33px",// == undefined ? "30px":paramsHeight+"px",
width:params.width,
resizeType: 1, minWidth: "1px", width: "94%",
height: "33px",// == undefined ? "30px":paramsHeight+"px",
minHeight: "33px",// == undefined ? "30px":paramsHeight+"px",
width: params.width,
/*
items:['emoticons','fontname',
'forecolor', 'hilitecolor', 'bold', '|', 'justifyleft', 'justifycenter', 'insertorderedlist','insertunorderedlist', '|',
'formatblock', 'fontsize', '|','indent', 'outdent',
'|','imagedirectupload','more'],*/
items : ['code','emoticons','fontname',
'forecolor', 'hilitecolor', 'bold', '|', 'justifyleft', 'justifycenter', 'insertorderedlist','insertunorderedlist', '|',
'formatblock', 'fontsize', '|','indent', 'outdent',
'|','imagedirectupload','table', 'media', 'preview',"more"
items: ['code', 'emoticons', 'fontname',
'forecolor', 'hilitecolor', 'bold', '|', 'justifyleft', 'justifycenter', 'insertorderedlist', 'insertunorderedlist', '|',
'formatblock', 'fontsize', '|', 'indent', 'outdent',
'|', 'imagedirectupload', 'table', 'media', 'preview', "more"
],
afterChange:function(){//按键事件
afterChange: function () {//按键事件
var edit = this.edit;
var body = edit.doc.body;
edit.iframe.height(paramsHeight);
this.resize(null, Math.max((params.kindutil.IE ? body.scrollHeight : (params.kindutil.GECKO ? body.offsetHeight+26:body.offsetHeight+7)) , paramsHeight));
this.resize(null, Math.max((params.kindutil.IE ? body.scrollHeight : (params.kindutil.GECKO ? body.offsetHeight + 26 : body.offsetHeight + 7)), paramsHeight));
},
afterBlur:function(){
afterBlur: function () {
//params.toolbar_container.hide();
params.textarea.blur();
sd_check_editor_form_field({content:this,contentmsg:params.contentmsg,textarea:params.textarea});
if(this.isEmpty()) {
sd_check_editor_form_field({ content: this, contentmsg: params.contentmsg, textarea: params.textarea });
if (this.isEmpty()) {
this.edit.html("<span id='hint' style='color:#999999;font-size:12px;'>我要回复</span>");
}
//params.toolbar_container.hide();
$('#reply_image_' + id).addClass('imageFuzzy');
if(/^\s*<\w*\s*\w*\=\"\w*\"\s*\w*\=\"\w*\:\s*\#\d*\;\s*\w*\-\w*\:\s*\w*\;\"\>[\u4e00-\u9fa5]*<\/\w*\>\s*$/.test(this.edit.html())){
if (/^\s*<\w*\s*\w*\=\"\w*\"\s*\w*\=\"\w*\:\s*\#\d*\;\s*\w*\-\w*\:\s*\w*\;\"\>[\u4e00-\u9fa5]*<\/\w*\>\s*$/.test(this.edit.html())) {
params.submit_btn.hide();
params.toolbar_container.hide();
this.resize("100%", null);
}else if(this.edit.html().trim() != ""){
} else if (this.edit.html().trim() != "") {
params.submit_btn.show();
params.toolbar_container.show();
}
@ -48,10 +48,10 @@ function sd_create_editor(params){
//params.submit_btn.css("display","none");
},
afterFocus: function(){
afterFocus: function () {
var edit = this.edit;
var body = edit.doc.body;
if(/^\s*<\w*\s*\w*\=\"\w*\"\s*\w*\=\"\w*\:\s*\#\d*\;\s*\w*\-\w*\:\s*\w*\;\"\>[\u4e00-\u9fa5]*<\/\w*\>\s*$/.test(edit.html())){
if (/^\s*<\w*\s*\w*\=\"\w*\"\s*\w*\=\"\w*\:\s*\#\d*\;\s*\w*\-\w*\:\s*\w*\;\"\>[\u4e00-\u9fa5]*<\/\w*\>\s*$/.test(edit.html())) {
edit.html('');
}
params.submit_btn.show();
@ -67,12 +67,12 @@ function sd_create_editor(params){
},
afterCreate:function(){
afterCreate: function () {
//params.submit_btn.hide();
var toolbar = $("div[class='ke-toolbar']",params.div_form);
toolbar.css('display','inline');
toolbar.css('padding',0);
$(".ke-outline>.ke-toolbar-icon",toolbar).append('表情');
var toolbar = $("div[class='ke-toolbar']", params.div_form);
toolbar.css('display', 'inline');
toolbar.css('padding', 0);
$(".ke-outline>.ke-toolbar-icon", toolbar).append('表情');
params.toolbar_container.append(toolbar);
params.toolbar_container.hide();
params.submit_btn.hide();
@ -85,9 +85,9 @@ function sd_create_editor(params){
paramsHeight = paramsHeight == undefined ? params.kindutil.removeUnit(this.height) : paramsHeight;
edit.iframe.height(paramsHeight);
edit.html("<span id='hint' style='color:#999999;font-size:12px;'>我要回复</span>");
this.resize(null,paramsHeight);// Math.max((params.kindutil.IE ? body.scrollHeight : body.offsetHeight)+ paramsHeight , paramsHeight)
this.resize(null, paramsHeight);// Math.max((params.kindutil.IE ? body.scrollHeight : body.offsetHeight)+ paramsHeight , paramsHeight)
// params.toolbar_container.hide();
if(typeof enableAt === 'function'){
if (typeof enableAt === 'function') {
enableAt(this, id, type);
}
}
@ -95,7 +95,7 @@ function sd_create_editor(params){
return editor;
}
function sd_create_shixun_editor(params){
function sd_create_shixun_editor(params) {
// var minHeight; //最小高度
var paramsHeight = params.height; //设定的高度
var id = arguments[1] ? arguments[1] : undefined;
@ -103,20 +103,20 @@ function sd_create_shixun_editor(params){
var paramsWidth = params.width == undefined ? "100%" : params.width;
var editor = params.kindutil.create(params.textarea, {
resizeType : 1,minWidth:"1px",width:"94%",
height:"33px",// == undefined ? "30px":paramsHeight+"px",
minHeight:"33px",// == undefined ? "30px":paramsHeight+"px",
width:params.width,
resizeType: 1, minWidth: "1px", width: "94%",
height: "33px",// == undefined ? "30px":paramsHeight+"px",
minHeight: "33px",// == undefined ? "30px":paramsHeight+"px",
width: params.width,
/*
items:['emoticons','fontname',
'forecolor', 'hilitecolor', 'bold', '|', 'justifyleft', 'justifycenter', 'insertorderedlist','insertunorderedlist', '|',
'formatblock', 'fontsize', '|','indent', 'outdent',
'|','imagedirectupload','more'],*/
items : ['imagedirectupload'],
afterChange:function(){//按键事件
if(this.isEmpty() || this.edit.doc.body.innerText == '说点什么') {
$('#mini_comment_section').height('auto')
} else {
items: ['imagedirectupload'],
afterChange: function () {//按键事件
if (this.isEmpty() || this.edit.doc.body.innerText == '说点什么') {
$('#mini_comment_section').height('auto')
} else {
var edit = this.edit;
var body = edit.doc.body;
var newHeight = 0;
@ -125,14 +125,14 @@ function sd_create_shixun_editor(params){
if (FF) { // 火狐下处理方式不一样
newHeight = $(body).height()
} else {
$(body).children().each(function(){newHeight+=$(this).height()});
$(body).children().each(function () { newHeight += $(this).height() });
}
// var newHeight = $(body).height()
var maxHeight = 357 // $(window).height() - 150 - 57; // 150 上部距离 57 下部距离
newHeight = newHeight <= maxHeight ? newHeight : maxHeight
if (newHeight > 150) {
if (FF) { // 火狐下处理方式不一样
@ -140,9 +140,9 @@ function sd_create_shixun_editor(params){
} else {
this.resize("100%", newHeight + 'px');
}
$('#mini_comment_section').height(newHeight+57)
$('#mini_comment_section').height(newHeight + 57)
} else {
this.resize("100%", '150px');
this.resize("100%", '150px');
$('#mini_comment_section').height('auto')
}
}
@ -150,19 +150,19 @@ function sd_create_shixun_editor(params){
//edit.iframe.height(paramsHeight);
//this.resize(null, Math.max((params.kindutil.IE ? body.scrollHeight : (params.kindutil.GECKO ? body.offsetHeight+26:body.offsetHeight+7)) , 15));
},
afterBlur:function(){
afterBlur: function () {
//params.toolbar_container.hide();
params.textarea.blur();
sd_check_editor_form_field({content:this,contentmsg:params.contentmsg,textarea:params.textarea});
if(this.isEmpty()) {
sd_check_editor_form_field({ content: this, contentmsg: params.contentmsg, textarea: params.textarea });
if (this.isEmpty()) {
$('#mini_comment_section').height('auto')
this.edit.html("<span id='hint' style='color:#999999;font-size:14px;'>说点什么</span>");
params.submit_btn.hide();
params.toolbar_container.hide();
this.resize("100%", "30px");
$("#dis_reply_id").val("");
if($("#editor_panel").length>0){
$("#editor_panel").attr("style","margin-top:9px;flex: 1;");
if ($("#editor_panel").length > 0) {
$("#editor_panel").attr("style", "margin-top:9px;flex: 1;");
$("#editor_panel").parents("form").addClass("df")
}
}
@ -180,10 +180,10 @@ function sd_create_shixun_editor(params){
// $('#mini_comment_section').height('auto')
},
afterFocus: function(){
afterFocus: function () {
var edit = this.edit;
var body = edit.doc.body;
if(/^\s*<\w*\s*\w*\=\"\w*\"\s*\w*\=\"\w*\:\s*\#\d*\;\s*\w*\-\w*\:\s*\w*\;\"\>[\u4e00-\u9fa5]*<\/\w*\>\s*$/.test(edit.html())){
if (/^\s*<\w*\s*\w*\=\"\w*\"\s*\w*\=\"\w*\:\s*\#\d*\;\s*\w*\-\w*\:\s*\w*\;\"\>[\u4e00-\u9fa5]*<\/\w*\>\s*$/.test(edit.html())) {
edit.html("");
}
params.submit_btn.show();
@ -192,14 +192,14 @@ function sd_create_shixun_editor(params){
// params.toolbar_container.show();
$('#reply_image_' + id).removeClass('imageFuzzy');
//edit.iframe.width(paramsWidth);
var newHeight = $(body).height()
if (newHeight < 150) {
this.resize("100%", "150px");
this.resize(paramsWidth, "150px");
}
if($("#editor_panel").length>0){
$("#editor_panel").attr("style","width:100%;margin-top:9px;");
if ($("#editor_panel").length > 0) {
$("#editor_panel").attr("style", "width:100%;margin-top:9px;");
$("#editor_panel").parents("form").removeClass("df")
}
//params.submit_btn.show();
@ -207,12 +207,12 @@ function sd_create_shixun_editor(params){
// $('#mini_comment_section').height('244px')
},
afterCreate:function(){
afterCreate: function () {
//params.submit_btn.hide();
var toolbar = $("div[class='ke-toolbar']",params.div_form);
toolbar.css('display','inline');
toolbar.css('padding',0);
$(".ke-outline>.ke-toolbar-icon",toolbar).append('表情');
var toolbar = $("div[class='ke-toolbar']", params.div_form);
toolbar.css('display', 'inline');
toolbar.css('padding', 0);
$(".ke-outline>.ke-toolbar-icon", toolbar).append('表情');
params.toolbar_container.append(toolbar);
params.toolbar_container.hide();
params.submit_btn.hide();
@ -221,16 +221,16 @@ function sd_create_shixun_editor(params){
var body = edit.doc.body;
edit.iframe[0].scroll = 'no';
// body.style.overflowY = 'hidden';
body.style['padding-top']= '2px';
body.style['padding-left']= '5px';
body.style['padding-top'] = '2px';
body.style['padding-left'] = '5px';
// <style type='text/css'>body{padding-top: 2px;padding-left: 5px;}</style>
//reset height
paramsHeight = paramsHeight == undefined ? params.kindutil.removeUnit(this.height) : paramsHeight;
edit.iframe.height(paramsHeight);
edit.html("<span id='hint' style='color:#999999;font-size:14px;'>说点什么</span>");
this.resize(null,paramsHeight);// Math.max((params.kindutil.IE ? body.scrollHeight : body.offsetHeight)+ paramsHeight , paramsHeight)
this.resize(null, paramsHeight);// Math.max((params.kindutil.IE ? body.scrollHeight : body.offsetHeight)+ paramsHeight , paramsHeight)
// params.toolbar_container.hide();
if(typeof enableAt === 'function'){
if (typeof enableAt === 'function') {
enableAt(this, id, type);
}
@ -242,43 +242,43 @@ function sd_create_shixun_editor(params){
return editor;
}
function sd_check_editor_form_field(params){
var result=true;
if(params.content!=undefined){
if(params.content.isEmpty()){
result=false;
function sd_check_editor_form_field(params) {
var result = true;
if (params.content != undefined) {
if (params.content.isEmpty()) {
result = false;
}
if(params.content.html()!=params.textarea.html() || params.issubmit==true){
if (params.content.html() != params.textarea.html() || params.issubmit == true) {
params.textarea.html(params.content.html());
params.content.sync();
if(params.content.isEmpty() || /^\s*<\w*\s*\w*\=\"\w*\"\s*\w*\=\"\w*\:\s*\#\d*\;\s*\w*\-\w*\:\s*\w*\;\"\>[\u4e00-\u9fa5]*<\/\w*\>\s*$/.test(params.textarea.html())){
if (params.content.isEmpty() || /^\s*<\w*\s*\w*\=\"\w*\"\s*\w*\=\"\w*\:\s*\#\d*\;\s*\w*\-\w*\:\s*\w*\;\"\>[\u4e00-\u9fa5]*<\/\w*\>\s*$/.test(params.textarea.html())) {
params.contentmsg.html('内容不能为空');
params.contentmsg.css({color:'#ff0000'});
}else{
params.contentmsg.css({ color: '#ff0000' });
} else {
params.contentmsg.html('填写正确');
params.contentmsg.css({color:'#008000'});
params.contentmsg.css({ color: '#008000' });
}
params.contentmsg.show();
}
}
return result;
}
function sd_create_form(params){
params.form.submit(function(){
function sd_create_form(params) {
params.form.submit(function () {
var flag = false;
if(params.form.attr('data-remote') != undefined ){
if (params.form.attr('data-remote') != undefined) {
flag = true
}
var is_checked = sd_check_editor_form_field({
issubmit:true,
content:params.editor,
contentmsg:params.contentmsg,
textarea:params.textarea
issubmit: true,
content: params.editor,
contentmsg: params.contentmsg,
textarea: params.textarea
});
if(is_checked){
if(flag){
if (is_checked) {
if (flag) {
return true;
}else{
} else {
$(this)[0].submit();
return false;
}
@ -286,144 +286,142 @@ function sd_create_form(params){
return false;
});
}
function sd_reset_editor_form(params){
function sd_reset_editor_form(params) {
params.form[0].reset();
params.textarea.empty();
if(params.editor != undefined){
if (params.editor != undefined) {
params.editor.html(params.textarea.html());
}
params.contentmsg.hide();
}
//第二个参数是高度,可以传,可以不传
function sd_create_editor_from_data(id){
function sd_create_editor_from_data(id) {
var height = arguments[1] ? arguments[1] : undefined;
var width = arguments[2] ? arguments[2] : undefined;
var type = arguments[3] ? arguments[3] : undefined;
// KindEditor.ready(function (K) {
// react 环境不需要ready方法页面已经加载完了才执行sd_create_editor_from_data
var K = KindEditor;
$("div[nhname='new_message_" + id + "']").each(function () {
var params = {};
params.kindutil = K;
params.div_form = $(this);
params.form = $("form", params.div_form);
if (params.form == undefined || params.form.length == 0) {
return;
}
params.textarea = $("textarea[nhname='new_message_textarea_" + id + "']", params.div_form);
params.contentmsg = $("span[nhname='contentmsg_" + id + "']", params.div_form);
params.toolbar_container = $("div[nhname='toolbar_container_" + id + "']", params.div_form);
params.cancel_btn = $("#new_message_cancel_btn_" + id);
params.submit_btn = $("#new_message_submit_btn_" + id);
params.height = height;
params.width = width;
if (params.textarea.data('init') == undefined) {
params.editor = sd_create_editor(params,id, type);
sd_create_form(params);
params.cancel_btn.click(function () {
sd_reset_editor_form(params);
});
params.submit_btn.click(function () {
var tContents = $("#comment_news_" + id).val();
if(tContents != undefined){
var beforeImage = tContents.split("<img");
var afterImage = tContents.split("/>");
if(beforeImage[0] == "" && afterImage[1] == ""){
notice_box('不支持纯图片评论<br/>请在评论中增加文字信息');
return;
}
if (tContents.startsWith('<') && tContents.endsWith('>')
&& (tContents.indexOf('<link') != -1 || tContents.indexOf('<script') != -1 )) {
notice_box('不支持包含link或script标签的html内容');
return;
}
var K = KindEditor;
$("div[nhname='new_message_" + id + "']").each(function () {
var params = {};
params.kindutil = K;
params.div_form = $(this);
params.form = $("form", params.div_form);
if (params.form == undefined || params.form.length == 0) {
return;
}
params.textarea = $("textarea[nhname='new_message_textarea_" + id + "']", params.div_form);
params.contentmsg = $("span[nhname='contentmsg_" + id + "']", params.div_form);
params.toolbar_container = $("div[nhname='toolbar_container_" + id + "']", params.div_form);
params.cancel_btn = $("#new_message_cancel_btn_" + id);
params.submit_btn = $("#new_message_submit_btn_" + id);
params.height = height;
params.width = width;
if (params.textarea.data('init') == undefined) {
params.editor = sd_create_editor(params, id, type);
sd_create_form(params);
params.cancel_btn.click(function () {
sd_reset_editor_form(params);
});
params.submit_btn.click(function () {
var tContents = $("#comment_news_" + id).val();
if (tContents != undefined) {
var beforeImage = tContents.split("<img");
var afterImage = tContents.split("/>");
if (beforeImage[0] == "" && afterImage[1] == "") {
notice_box('不支持纯图片评论<br/>请在评论中增加文字信息');
return;
}
// react环境下发消息给react组件
if (window['__isR'] === true) {
$(document).trigger("onReply", { commentContent:tContents, id:id, editor:params.editor } );
} else {
params.form.submit();
}
});
params.textarea.focus(function (){
params.editor.focus();
});
params.textarea.data('init', 1);
$(this).show();
__editor = params.editor
}
});
if (tContents.startsWith('<') && tContents.endsWith('>')
&& (tContents.indexOf('<link') != -1 || tContents.indexOf('<script') != -1)) {
notice_box('不支持包含link或script标签的html内容');
return;
}
}
// react环境下发消息给react组件
if (window['__isR'] === true) {
$(document).trigger("onReply", { commentContent: tContents, id: id, editor: params.editor });
} else {
params.form.submit();
}
});
params.textarea.focus(function () {
params.editor.focus();
});
params.textarea.data('init', 1);
$(this).show();
__editor = params.editor
}
});
// });
div_form = $("div[nhname='new_message_" + id + "']");
$(".ke-edit", div_form).css("height","33px");
$(".ke-edit-iframe",div_form).css("height","33px");
$(".ke-edit", div_form).css("height", "33px");
$(".ke-edit-iframe", div_form).css("height", "33px");
return __editor;
}
//第二个参数是高度,可以传,可以不传
function sd_create_editor_from_shixun_data(id){
function sd_create_editor_from_shixun_data(id) {
var height = arguments[1] ? arguments[1] : undefined;
var width = arguments[2] ? arguments[2] : undefined;
var type = arguments[3] ? arguments[3] : undefined;
// KindEditor.ready(function (K) {
// react 环境不需要ready方法页面已经加载完了才执行sd_create_editor_from_data
var K = KindEditor;
$("div[nhname='new_message_" + id + "']").each(function () {
var params = {};
params.kindutil = K;
params.div_form = $(this);
params.form = $("form", params.div_form);
if (params.form == undefined || params.form.length == 0) {
return;
}
params.textarea = $("textarea[nhname='new_message_textarea_" + id + "']", params.div_form);
params.contentmsg = $("span[nhname='contentmsg_" + id + "']", params.div_form);
params.toolbar_container = $("div[nhname='toolbar_container_" + id + "']", params.div_form);
params.cancel_btn = $("#new_message_cancel_btn_" + id);
params.submit_btn = $("#new_message_submit_btn_" + id);
params.height = height;
params.width = width;
if (params.textarea.data('init') == undefined) {
params.editor = sd_create_shixun_editor(params,id, type);
window._commentInput = params.editor;
sd_create_form(params);
params.cancel_btn.click(function () {
sd_reset_editor_form(params);
});
// 在react组件中hide
// params.submit_btn.click(function () {
// $(this).hide()
// });
// 非react环境才监听这个click
!window['__isR'] && params.submit_btn.click(function () {
var tContents = $("#comment_news_" + id).val();
if(tContents != undefined){
var beforeImage = tContents.split("<img");
var afterImage = tContents.split("/>");
if(beforeImage[0] == "" && afterImage[1] == ""){
notice_box('不支持纯图片评论<br/>请在评论中增加文字信息');
return;
}
// react 环境不需要ready方法页面已经加载完了才执行sd_create_editor_from_data
var K = KindEditor;
$("div[nhname='new_message_" + id + "']").each(function () {
var params = {};
params.kindutil = K;
params.div_form = $(this);
params.form = $("form", params.div_form);
if (params.form == undefined || params.form.length == 0) {
return;
}
params.textarea = $("textarea[nhname='new_message_textarea_" + id + "']", params.div_form);
params.contentmsg = $("span[nhname='contentmsg_" + id + "']", params.div_form);
params.toolbar_container = $("div[nhname='toolbar_container_" + id + "']", params.div_form);
params.cancel_btn = $("#new_message_cancel_btn_" + id);
params.submit_btn = $("#new_message_submit_btn_" + id);
params.height = height;
params.width = width;
if (params.textarea.data('init') == undefined) {
params.editor = sd_create_shixun_editor(params, id, type);
window._commentInput = params.editor;
sd_create_form(params);
params.cancel_btn.click(function () {
sd_reset_editor_form(params);
});
// 在react组件中hide
// params.submit_btn.click(function () {
// $(this).hide()
// });
// 非react环境才监听这个click
!window['__isR'] && params.submit_btn.click(function () {
var tContents = $("#comment_news_" + id).val();
if (tContents != undefined) {
var beforeImage = tContents.split("<img");
var afterImage = tContents.split("/>");
if (beforeImage[0] == "" && afterImage[1] == "") {
notice_box('不支持纯图片评论<br/>请在评论中增加文字信息');
return;
}
params.form.submit();
});
params.textarea.focus(function (){
params.editor.focus();
});
params.textarea.data('init', 1);
$(this).show();
}
});
}
params.form.submit();
});
params.textarea.focus(function () {
params.editor.focus();
});
params.textarea.data('init', 1);
$(this).show();
}
});
// });
div_form = $("div[nhname='new_message_" + id + "']");
$(".ke-edit", div_form).css("height","33px");
$(".ke-edit-iframe",div_form).css("height","33px");
$(".ke-edit", div_form).css("height", "33px");
$(".ke-edit-iframe", div_form).css("height", "33px");
}

File diff suppressed because it is too large Load Diff

View File

7
public/js/flv.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -13,7 +13,7 @@
*/
function openTerminal(options) {
// 为了多个实例能同时存在
(function () {
(function () {
var heartBeatInterval;
var force_close_socket = false;
//var CONNECT_TIME = 0; // 请求连接次数
@ -21,20 +21,21 @@ function openTerminal(options) {
var parentDomId = options.parentDomId || ''
var client = new WSSHClient();
var base64 = new Base64();
var term = new Terminal({cols: options.columns, rows: Rows, screenKeys: true, useStyle: true
// TODO 默认是canvas可能被其他样式影响了 canvas用不了
var term = new Terminal({
cols: options.columns, rows: Rows, screenKeys: true, useStyle: true
// TODO 默认是canvas可能被其他样式影响了 canvas用不了
, rendererType: 'dom'
, fontSize: 16
});
});
term.on('data', function (data) {
console.log("xterm data: ");
console.log(data);
client.sendClientData(data);
window.parent.postMessage({tp: 'sshWorking'}, "*");
window.parent.postMessage({ tp: 'sshWorking' }, "*");
});
term.open();
$('body>.terminal').detach().appendTo( parentDomId + ' #term' );
$('body>.terminal').detach().appendTo(parentDomId + ' #term');
$(parentDomId + " #term").show();
term.write("Connecting...");
console.log(options)
@ -43,7 +44,7 @@ function openTerminal(options) {
//var interTime = setInterval(client_connect, 1000)
setTimeout(client_connect, 3000);
heartBeatInterval = setInterval(function(){
heartBeatInterval = setInterval(function () {
client.sendHeartBeat()
}, 30 * 1000)
/**
@ -67,13 +68,13 @@ function openTerminal(options) {
window.addEventListener("message", function (event) {
console.log("post message: ");
console.log(event.data);
if(event.data.tp === 'resize'){
if (event.data.tp === 'resize') {
resizeTerminal(event.data);
} else if (event.data.tp === 'reload') {
window.location.reload()
} else if (event.data.tp === 'close_ssh_cocket') {
force_close_socket = true; // 强制关闭socket用于不开启自动重连
client && client.close();
client && client.close();
}
}, false);
@ -94,10 +95,9 @@ function openTerminal(options) {
term.focus();
},
onClose: function () {
debugger;
clearInterval(heartBeatInterval);
console.log("连接关闭");
term.write("\r\nconnection closed");
if (CONNECTED) {
@ -106,7 +106,7 @@ function openTerminal(options) {
}
if (force_close_socket === false) {
// $(window).trigger('setSSHConnectStatus');
window.parent.postMessage({tp: 'setSSHConnectStatus', tab: options.tab}, "*");
window.parent.postMessage({ tp: 'setSSHConnectStatus', tab: options.tab }, "*");
} else {
// 主动关闭连接时,不自动重连
force_close_socket = false;
@ -116,10 +116,10 @@ function openTerminal(options) {
if (!CONNECTED) {
console.log("first connected.");
// 问题重现的实训 带代码tab的 命令行实训 https://www.educoder.net/tasks/83hflni9es7tl
setTimeout(function() {
setTimeout(function () {
// TODO canvas模式下没有body
if ( term && term.body && term.body.innerText
&& term.body.innerText.indexOf('Connecting') != -1 ) {
if (term && term.body && term.body.innerText
&& term.body.innerText.indexOf('Connecting') != -1) {
term.clear(); // 有的连上后还出现了“Connecting。。。”
}
}, 1000)
@ -179,10 +179,10 @@ function connect() {
username: $("#username").val(),
secret: $("#password").val(),
gameid: $("#gameid").val(),
rows: parseInt( $("#terminalRow").val() ),
columns: parseInt( $("#terminalColumn").val() ),
width: parseInt( $("#terminalWidth").val() ),
height: parseInt( $("#terminalHeight").val() ),
rows: parseInt($("#terminalRow").val()),
columns: parseInt($("#terminalColumn").val()),
width: parseInt($("#terminalWidth").val()),
height: parseInt($("#terminalHeight").val()),
tab: $("#terminalTab").val(),
}
if (remember) {

File diff suppressed because one or more lines are too long

View File

@ -2,7 +2,6 @@
// 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
@ -46,10 +45,10 @@ if (!checkRequiredFiles([paths.appHtml, paths.appIndexJs])) {
function removeExceptGitDir(dir) {
// readdirSync
const list = fs2.readdirSync(dir)
// if (err) return done(err);
// if (err) return done(err);
var pending = list.length;
// if (!pending) return done(null, results);
list.forEach(function(file) {
list.forEach(function (file) {
if (file.indexOf('.git') == -1) {
file = path.resolve(dir, file);
fs.removeSync(file)
@ -80,13 +79,13 @@ measureFileSizesBeforeBuild(paths.appBuild)
console.log(warnings.join('\n\n'));
console.log(
'\nSearch for the ' +
chalk.underline(chalk.yellow('keywords')) +
' to learn more about each warning.'
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'
chalk.cyan('// eslint-disable-next-line') +
' to the line before.\n'
);
} else {
console.log(chalk.green('Compiled successfully.\n'));
@ -149,14 +148,12 @@ function build(previousFileSizes) {
console.log(
chalk.yellow(
'\nTreating warnings as errors because process.env.CI = true.\n' +
'Most CI servers set it automatically.\n'
'Most CI servers set it automatically.\n'
)
);
return reject(new Error(messages.warnings.join('\n\n')));
}
generateNewIndexJsp();
return resolve({
stats,
previousFileSizes,
@ -170,82 +167,5 @@ function copyPublicFolder() {
fs.copySync(paths.appPublic, paths.appBuild, {
dereference: true,
filter: file => file !== paths.appHtml,
});
}
// 给build脚本增加的方法对其生成的index.html做一些文本替换以及cdn处理
function generateNewIndexJsp() {
// var combinedStream = CombinedStream.create();
var filePath = paths.appBuild + '/index.html';
// var htmlContent = fs2.createReadStream( filePath )
// stream没有replace方法
// htmlContent = htmlContent.replace('/js/js_min_all.js', '/react/build/js/js_min_all.js')
// htmlContent = htmlContent.replace('/css/css_min_all.css', '/react/build/css/css_min_all.css')
// combinedStream.append(htmlContent);
// combinedStream.pipe(fs2.createWriteStream( filePath ));
var outputPath = paths.appBuild + '/index.html'
fs2.readFile(filePath, 'utf8', function (err,data) {
if (err) {
return console.log(err);
}
const newVersion = '1.1.1'
let cdnHost = 'https://shixun.educoder.net'
cdnHost = 'https://ali-cdn.educoder.net'
cdnHost = ''
var mainRegex = /<script type="text\/javascript" src="\/react\/build\/.\/static\/js\/main.([a-zA-Z0-9]{8,}).js"><\/script>/
var matchResult = data.match(mainRegex)
var code = `
<script>
(function() {
var _host = '/react/build/'
/**/
if (window.location.host == 'pre-newweb.educoder.net') {
_host = 'https://testali-cdn.educoder.net/react/build/'
} else if (window.location.host == 'www.educoder.net') {
_host = 'https://ali-cdn.educoder.net/react/build/'
}
document.write('<script type="text/javascript" src="' + _host + 'js/js_min_all.js"><\\/script>');
document.write('<script type="text/javascript" src="' + _host + 'static/js/main.${matchResult[1]}.js"><\\/script>');
})()
</script>
`
var jsMinAllRegex = /<script type="text\/javascript" src="\/js\/js_min_all.js"><\/script>/
// <script type="text/javascript" src="/js/js_min_all.js"></script>
var result = data
.replace(jsMinAllRegex, code)
// .replace('/js/js_min_all.js', `${cdnHost}/react/build/js/js_min_all.js?v=${newVersion}`)
// .replace('/js/js_min_all_2.js', `${cdnHost}/react/build/js/js_min_all_2.js?v=${newVersion}`)
// ${cdnHost} 加了cdn后这个文件里的字体文件加载会有跨域的报错 ../fonts/fontawesome-webfont.eot
// TODO tpi 评测结果关闭也使用了fontawesome
.replace('/css/css_min_all.css', `${cdnHost}/react/build/css/css_min_all.css?v=${newVersion}`)
.replace('/css/iconfont.css', `${cdnHost}/react/build/css/iconfont.css?v=${newVersion}`)
.replace(/\/js\/create_kindeditor.js/g, `${cdnHost}/react/build/js/create_kindeditor.js?v=${newVersion}`)
.replace(mainRegex, '')
// .replace('/react/build/./static/css/main', `${cdnHost}/react/build/./static/css/main`)
// .replace('/react/build/./static/js/main', `${cdnHost}/react/build/./static/js/main`)
// .replace(/https:\/\/testeduplus2.educoder.net/g, '');
// .replace(/http:\/\/testbdweb.educoder.net/g, '');
// .replace('/css/css_min_all.css', '/react/build/css/css_min_all.css');
fs2.writeFile(outputPath, result, 'utf8', function (err) {
if (err) return console.log(err);
// commitAndPush();
});
});
}
function commitAndPush() {
var exec = require('child_process').exec;
function puts(error, stdout, stderr) { console.log(stdout) }
var options = {cwd:"./build"};
exec("git status && git commit -am 'b' && git push", options, puts);
})
}

View File

@ -1,31 +1,31 @@
var fs = require('fs');
var uglify = require("uglify-js");
var path = require('path');
var concat = require('concat')
var concat = require('concat')
var results = [];
var walk = function(dir, done) {
fs.readdir(dir, function(err, list) {
console.log(list)
if (err) return done(err);
var pending = list.length;
if (!pending) return done(null, results);
list.forEach(function(file) {
file = path.resolve(dir, file);
fs.stat(file, function(err, stat) {
if (stat && stat.isDirectory()) {
walk(file, function(err, res) {
// results = results.concat(res);
if (!--pending) done(null, results);
});
} else {
results.push(file);
if (!--pending) done(null, results);
}
});
});
});
var walk = function (dir, done) {
fs.readdir(dir, function (err, list) {
console.log(list)
if (err) return done(err);
var pending = list.length;
if (!pending) return done(null, results);
list.forEach(function (file) {
file = path.resolve(dir, file);
fs.stat(file, function (err, stat) {
if (stat && stat.isDirectory()) {
walk(file, function (err, res) {
// results = results.concat(res);
if (!--pending) done(null, results);
});
} else {
results.push(file);
if (!--pending) done(null, results);
}
});
});
});
};
// 需要输出文件名数组时改为true
@ -34,65 +34,51 @@ var cssDir = './public/css'
// true &&
false &&
walk(cssDir, function() {
console.log('results', results.length, results)
})
walk(cssDir, function () {
console.log('results', results.length, results)
})
// return;
// ----------------------------------------------------------------------------- CSS
var cssResults = [
'D:\\Code\\trustieplus\\public\\react\\public\\css\\edu-common.css',
'D:\\Code\\trustieplus\\public\\react\\public\\css\\edu-public.css',
'D:\\Code\\trustieplus\\public\\react\\public\\css\\taskstyle.css' ,
var cssResults = [
'D:\\Code\\trustieplus\\public\\react\\public\\css\\font-awesome.css',
'D:\\Code\\trustieplus\\public\\react\\public\\css\\editormd.min.css',
'D:\\Code\\trustieplus\\public\\react\\public\\css\\merge.css',
]
concat(cssResults, './public/css/css_min_all.css')
'D:\\Code\\trustieplus\\public\\react\\public\\css\\edu-common.css',
'D:\\Code\\trustieplus\\public\\react\\public\\css\\edu-public.css',
'D:\\Code\\trustieplus\\public\\react\\public\\css\\taskstyle.css',
'D:\\Code\\trustieplus\\public\\react\\public\\css\\font-awesome.css',
'D:\\Code\\trustieplus\\public\\react\\public\\css\\editormd.min.css',
'D:\\Code\\trustieplus\\public\\react\\public\\css\\merge.css',
]
concat(cssResults, './public/css/css_min_all.css')
return;
// ----------------------------------------------------------------------------- JS
var _results = [
var _results = [
'D:\\Code\\trustieplus\\public\\react\\public\\js\\jquery-1.8.3.min.js',
'D:\\Code\\trustieplus\\public\\react\\public\\js\\editormd\\underscore.min.js',
'D:\\Code\\trustieplus\\public\\react\\public\\js\\editormd\\marked.min.js',
'D:\\Code\\trustieplus\\public\\react\\public\\js\\editormd\\prettify.min.js',
'D:\\Code\\trustieplus\\public\\react\\public\\js\\editormd\\raphael.min.js',
'D:\\Code\\trustieplus\\public\\react\\public\\js\\editormd\\sequence-diagram.min.js',
'D:\\Code\\trustieplus\\public\\react\\public\\js\\editormd\\raphael.min.js',
'D:\\Code\\trustieplus\\public\\react\\public\\js\\editormd\\sequence-diagram.min.js',
'D:\\Code\\trustieplus\\public\\react\\public\\js\\editormd\\flowchart.min.js',
'D:\\Code\\trustieplus\\public\\react\\public\\js\\editormd\\jquery.flowchart.min.js',
'D:\\Code\\trustieplus\\public\\react\\public\\js\\editormd\\editormd.min.js',
'D:\\Code\\trustieplus\\public\\react\\public\\js\\editormd\\jquery.flowchart.min.js',
'D:\\Code\\trustieplus\\public\\react\\public\\js\\editormd\\editormd.min.js',
'D:\\Code\\trustieplus\\public\\react\\public\\js\\codemirror\\codemirror.js',
'D:\\Code\\trustieplus\\public\\react\\public\\js\\codemirror\\mode\\javascript.js',
'D:\\Code\\trustieplus\\public\\react\\public\\js\\diff_match_patch.js',
'D:\\Code\\trustieplus\\public\\react\\public\\js\\merge.js',
'D:\\Code\\trustieplus\\public\\react\\public\\js\\edu_tpi.js',
]
concat(_results, './public/js/js_min_all.js')
// var uglified = uglify.minify(['./public/js/merge.js']);
// console.log('uglified', uglified)
// fs.writeFile('concat.min.js', uglified.code, function (err){
// if(err) {
// console.log(err);
// } else {
// console.log("Script generated and saved:", 'concat.min.js');
// }
// });
// var uglified = uglify.minify(['file1.js', 'file2.js', 'file3.js']);
'D:\\Code\\trustieplus\\public\\react\\public\\js\\merge.js',
'D:\\Code\\trustieplus\\public\\react\\public\\js\\edu_tpi.js',
]
concat(_results, './public/js/js_min_all.js')

21
scripts/purge-css.js Normal file
View File

@ -0,0 +1,21 @@
const { PurgeCSS } = require('purgecss')
var fs = require('fs');
async function purgeBuild() {
const purgeCSSResult = await new PurgeCSS().purge({
content: ['../src/**/*.js', '../src/**/*.jsx',],
css: ['../public/css/edu-public.css', '../public/css/taskstyle.css', '../public/css/edu-main.css', '../public/css/edu-all.css']
})
let result = []
for (let i = 0; i < purgeCSSResult.length; i++) {
let item = purgeCSSResult[i]
result.push(item.css)
}
fs.writeFile('../public/css/edu-purge.css', result.join(''), 'utf8', function (err) {
if (err) return console.log(err)
})
}
purgeBuild()

View File

@ -36,7 +36,7 @@ const useYarn = fs.existsSync(paths.yarnLockFile);
const isInteractive = process.stdout.isTTY;
const portSetting = require(paths.appPackageJson).port
if ( portSetting ) {
if (portSetting) {
process.env.port = portSetting
}
@ -76,10 +76,9 @@ choosePort(HOST, DEFAULT_PORT)
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);
const compiler = createCompiler({ webpack, config, appName, urls, useYarn });
// Load proxy config
const proxySetting = require(paths.appPackageJson).proxy;
console.log('-------------------------proxySetting:', proxySetting)
const proxyConfig = prepareProxy(proxySetting, paths.appPublic);
// Serve webpack assets generated by the compiler over a web sever.
const serverConfig = createDevServerConfig(
@ -99,8 +98,8 @@ choosePort(HOST, DEFAULT_PORT)
openBrowser(urls.localUrlForBrowser);
});
['SIGINT', 'SIGTERM'].forEach(function(sig) {
process.on(sig, function() {
['SIGINT', 'SIGTERM'].forEach(function (sig) {
process.on(sig, function () {
devServer.close();
process.exit();
});

View File

@ -23,8 +23,13 @@
}
@keyframes App-logo-spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
@ -35,63 +40,78 @@
.editormd .CodeMirror-linenumbers {
padding: 0;
}
.editormd-html-preview hr, .editormd-preview-container hr {
.editormd-html-preview hr,
.editormd-preview-container hr {
/* 颜色加深 */
border-top: 1px solid #ccc;
}
/* 重置掉antd的一些样式 */
html, body {
html,
body {
-webkit-font-smoothing: auto !important;
}
.ant-progress-textyes {
color: #52c41a;
}
.ant-progress-textno{
.ant-progress-textno {
color: #f5222d;
}
/* md多空格 */
.markdown-body p {
white-space: pre-wrap;
font-size: 16px!important
font-size: 16px !important
}
.markdown-body > p {
.markdown-body>p {
line-height: 25px;
}
/* https://www.educoder.net/courses/2346/group_homeworks/34405/question */
.renderAsHtml.markdown-body p {
white-space: inherit;
}
/* resize */
.editormd .CodeMirror {
border-right: none !important;
}
.editormd-preview {
border-left: 1px solid rgb(221, 221, 221);
/* 某些情况下被cm盖住了 */
z-index: 99;
}
/* 图片点击放大的场景,隐藏图片链接 */
.editormd-image-click-expand .editormd-image-dialog {
height: 234px !important;
}
.editormd-image-click-expand .editormd-image-dialog .image-link {
display: none;
}
.editormd-image-click-expand .editormd-image-dialog .image-link {
display: none;
}
/* 解决鼠标框选时,左边第一列没高亮的问题 */
.CodeMirror .CodeMirror-lines pre.CodeMirror-line, .CodeMirror .CodeMirror-lines pre.CodeMirror-line-like {
padding: 0 12px ;
.CodeMirror .CodeMirror-lines pre.CodeMirror-line,
.CodeMirror .CodeMirror-lines pre.CodeMirror-line-like {
padding: 0 12px;
}
/* antd扩展 */
.formItemInline.ant-form-item {
.formItemInline.ant-form-item {
display: flex;
}
.formItemInline .ant-form-item-control-wrapper {
flex: 1;
}
/* AutoComplete placeholder 不显示的问题 */
.ant-select-auto-complete.ant-select .ant-select-selection__placeholder {
z-index: 2;

View File

@ -1,8 +1,6 @@
import React, {Component} from 'react';
import './public-path';
// import logo from './logo.svg';
import React, { Component } from 'react';
import './App.css';
import {ConfigProvider} from 'antd'
import { ConfigProvider } from 'antd'
import zhCN from 'antd/lib/locale-provider/zh_CN';
import {
BrowserRouter as Router,
@ -10,9 +8,6 @@ import {
Switch
} from 'react-router-dom';
import axios from 'axios';
import '@icedesign/base/dist/ICEDesignBase.css';
import '@icedesign/base/index.scss';
import LoginDialog from './modules/login/LoginDialog';
import Notcompletedysl from './modules/user/Notcompletedysl';
@ -21,9 +16,7 @@ import Trialapplicationreview from './modules/user/Trialapplicationreview';
import Addcourses from "./modules/courses/coursesPublic/Addcourses";
import AccountProfile from "./modules/user/AccountProfile";
import Accountnewprofile from './modules/user/Accountnewprofile';
// import Trialapplication from './modules/login/Trialapplication';
import Certifiedprofessional from './modules/modals/Certifiedprofessional';
// import NotFoundPage from './NotFoundPage'
import Loading from './Loading'
@ -32,18 +25,14 @@ import Loadable from 'react-loadable';
import moment from 'moment'
import {MuiThemeProvider, createMuiTheme} from 'material-ui/styles';
// import './AppConfig'
import { MuiThemeProvider, createMuiTheme } from 'material-ui/styles';
import history from './history';
import {SnackbarHOC} from 'educoder'
import {initAxiosInterceptors} from './AppConfig'
import { SnackbarHOC } from 'educoder'
import { initAxiosInterceptors } from './AppConfig'
import { Provider } from 'react-redux';
import configureStore from './redux/stores/configureStore';
// tpi需要这个来加载css
import {TPMIndexHOC} from './modules/tpm/TPMIndexHOC';
const store = configureStore();
const theme = createMuiTheme({
@ -52,14 +41,9 @@ const theme = createMuiTheme({
main: '#4CACFF',
contrastText: 'rgba(255, 255, 255, 0.87)'
},
secondary: {main: '#4CACFF'}, // #11cb5f This is just green.A700 as hex.
secondary: { main: '#4CACFF' }, // #11cb5f This is just green.A700 as hex.
},
});
//
// const Trialapplication= Loadable({
// loader: () =>import('./modules/login/Trialapplication'),
// loading:Loading,
// })
//登入
const EducoderLogin = Loadable({
loader: () => import('./modules/login/EducoderLogin'),
@ -68,30 +52,26 @@ const EducoderLogin = Loadable({
//微信登录
const Otherlogin=Loadable({
const Otherlogin = Loadable({
loader: () => import('./modules/login/Otherlogin'),
loading: Loading,
})
//微信登录
const Loginqq=Loadable({
const Loginqq = Loadable({
loader: () => import('./modules/login/Loginqq'),
loading: Loading,
})
const Otherloginstart=Loadable({
const Otherloginstart = Loadable({
loader: () => import('./modules/login/Otherloginstart'),
loading: Loading,
})
const Otherloginsqq=Loadable({
const Otherloginsqq = Loadable({
loader: () => import('./modules/login/Otherloginqq'),
loading: Loading,
})
// const TestIndex = Loadable({
// loader: () => import('./modules/test'),
// loading: Loading,
// })
const IndexWrapperComponent = Loadable({
loader: () => import('./modules/page/IndexWrapper'),
@ -103,24 +83,6 @@ const CommentComponent = Loadable({
loading: Loading,
})
// const TestMaterialDesignComponent = Loadable({
// loader: () => import('./modules/test/md/TestMaterialDesign'),
// loading: Loading,
// })
// const TestCodeMirrorComponent = Loadable({
// loader: () => import('./modules/test/codemirror/TestCodeMirror'),
// loading: Loading,
// })
// const TestComponent = Loadable({
// loader: () => import('./modules/test/TestRC'),
// loading: Loading,
// })
// const TestUrlQueryComponent = Loadable({
// loader: () => import('./modules/test/urlquery/TestUrlQuery'),
// loading: Loading,
// })
const TPMIndexComponent = Loadable({
loader: () => import('./modules/tpm/TPMIndex'),
loading: Loading,
@ -135,6 +97,11 @@ const ShixunPaths = Loadable({
loader: () => import('./modules/paths/Index'),
loading: Loading,
})
//forge项目
const Projects = Loadable({
loader: () => import('./forge/Index'),
loading: Loading,
})
//在线课堂
const CoursesIndex = Loadable({
@ -146,53 +113,12 @@ const SearchPage = Loadable({
loading: Loading,
})
// 课堂讨论
// const BoardIndex = Loadable({
// loader: () => import('./modules/courses/boards/BoardIndex'),
// loading:Loading,
// })
// //课堂普通作业&分组作业
// const CoursesWorkIndex = Loadable({
// loader: () => import('./modules/courses/busyWork/Index'),
// loading:Loading,
// })
//
// const TPMShixunchildIndexComponent = Loadable({
// loader: () => import('./modules/tpm/shixunchild/ShixunChildIndex'),
// loading: Loading,
// })
// const TPMshixunfork_listIndexComponent = Loadable({
// loader: () => import('./modules/tpm/shixunchild/Shixunfork_list'),
// loading: Loading,
// })
const ForumsIndexComponent = Loadable({
loader: () => import('./modules/forums/ForumsIndex'),
loading: Loading,
})
const ProjectIndex = Loadable({
loader: () => import('./forge/Index'),
loading: Loading,
})
// trustie plus forum
// const TPForumsIndexComponent = Loadable({
// loader: () => import('./modules/tp-forums/TPForumsIndex'),
// loading: Loading,
// })
// const TestPageComponent = Loadable({
// loader: () => import('./modules/page/Index'),
// loading: Loading,
// })
//新建实训
const Newshixuns = Loadable({
@ -200,14 +126,11 @@ const Newshixuns = Loadable({
loading: Loading,
})
//实训首页
const ShixunsHome = Loadable({
loader: () => import('./modules/home/shixunsHome'),
loader: () => import('./modules/home'),
loading: Loading,
})
const CompatibilityPageLoadable = Loadable({
loader: () => import('./modules/common/CompatibilityPage'),
loading: Loading,
@ -259,7 +182,7 @@ const BanksIndex = Loadable({
// 教学案例
const MoopCases = Loadable({
const MoopCases = Loadable({
loader: () => import('./modules/moop_cases/index'),
loading: Loading,
})
@ -277,23 +200,23 @@ const Interestpage = Loadable({
// })
//竞赛
const NewCompetitions=Loadable({
const NewCompetitions = Loadable({
loader: () => import('./modules/competitions/Competitions'),
loading: Loading,
})
//黑客松定制竞赛
const Osshackathon=Loadable({
const Osshackathon = Loadable({
loader: () => import('./modules/osshackathon/Osshackathon'),
loading: Loading,
})
const Messagerouting= Loadable({
const Messagerouting = Loadable({
loader: () => import('./modules/message/js/Messagerouting'),
loading: Loading,
})
const Topicbank= Loadable({
const Topicbank = Loadable({
loader: () => import('./modules/topic_bank/Topic_bank'),
loading: Loading,
})
@ -326,28 +249,28 @@ const Questionitem_banks = Loadable({
})
//试卷库
const Testpaperlibrary= Loadable({
const Testpaperlibrary = Loadable({
loader: () => import('./modules/testpaper/Testpaperlibrary'),
loading: Loading
})
//试卷编辑
const Paperlibraryeditid= Loadable({
const Paperlibraryeditid = Loadable({
loader: () => import('./modules/testpaper/Paperlibraryeditid'),
loading: Loading
})
//试卷查看
const Paperlibraryseeid= Loadable({
const Paperlibraryseeid = Loadable({
loader: () => import('./modules/testpaper/Paperlibraryseeid'),
loading: Loading
})
//人工组卷
const Paperreview= Loadable({
const Paperreview = Loadable({
loader: () => import('./modules/question/Paperreview'),
loading: Loading
})
//智能组卷
const Integeneration= Loadable({
const Integeneration = Loadable({
loader: () => import('./modules/testpaper/Intecomponents'),
loading: Loading
})
@ -378,6 +301,17 @@ const JupyterTPI = Loadable({
loader: () => import('./modules/tpm/jupyter'),
loading: Loading
});
//我的简历
const Tecruitment= Loadable({
loader: () => import('./modules/recruitment/Tecruitment'),
loading: Loading
});
//编辑简历
const EditResume= Loadable({
loader: () => import('./modules/recruitment/EditResume'),
loading: Loading
});
// 微信代码编辑器
// const WXCode = Loadable({
// loader: () => import('./modules/wxcode'),
@ -392,44 +326,44 @@ class App extends Component {
constructor(props) {
super(props)
this.state = {
Addcoursestype:false,
Addcoursestypes:false,
mydisplay:false,
occupation:0,
Addcoursestype: false,
Addcoursestypes: false,
mydisplay: false,
occupation: 0,
mygetHelmetapi: null,
}
}
HideAddcoursestypess=(i)=>{
HideAddcoursestypess = (i) => {
console.log("调用了");
this.setState({
Addcoursestype:false,
Addcoursestypes:false,
mydisplay:true,
occupation:i,
Addcoursestype: false,
Addcoursestypes: false,
mydisplay: true,
occupation: i,
})
};
hideAddcoursestypes=()=>{
hideAddcoursestypes = () => {
this.setState({
Addcoursestypes:false
Addcoursestypes: false
})
};
ModalCancelsy=()=>{
ModalCancelsy = () => {
this.setState({
mydisplay:false,
mydisplay: false,
})
window.location.href = "/";
};
ModalshowCancelsy=()=>{
ModalshowCancelsy = () => {
this.setState({
mydisplay:true,
mydisplay: true,
})
};
disableVideoContextMenu = () => {
window.$( "body" ).on( "mousedown", "video", function(event) {
if(event.which === 3) {
window.$('video').bind('contextmenu',function () { return false; });
window.$("body").on("mousedown", "video", function (event) {
if (event.which === 3) {
window.$('video').bind('contextmenu', function () { return false; });
} else {
window.$('video').unbind('contextmenu');
}
@ -447,8 +381,7 @@ class App extends Component {
});
initAxiosInterceptors(this.props);
// 顶部和底部的动态设置
// this.getAppdata();
this.getAppdata();
//
// axios.interceptors.response.use((response) => {
// // console.log("response"+response);
@ -466,13 +399,13 @@ class App extends Component {
window.addEventListener('error', (event) => {
const msg = `${event.type}: ${event.message}`;
console.log(msg)
// console.log(msg)
});
}
//修改登录方法
Modifyloginvalue=()=>{
Modifyloginvalue = () => {
this.setState({
isRender:false,
isRender: false,
})
};
@ -481,7 +414,7 @@ class App extends Component {
this.setState({
mygetHelmetapi: undefined
});
// document.title = "Forge";
document.title = "EduCoder";
var link = document.createElement('link'),
oldLink = document.getElementById('dynamic-favicon');
link.id = 'dynamic-favicon';
@ -506,20 +439,20 @@ class App extends Component {
}
document.head.appendChild(link);
}
//获取当前定制信息
getAppdata=()=>{
//获取当前定制信息
getAppdata = () => {
let url = "/setting.json";
axios.get(url).then((response) => {
// console.log("app.js开始请求/setting.json");
// console.log("获取当前定制信息");
if(response){
if(response.data){
if (response) {
if (response.data) {
this.setState({
mygetHelmetapi:response.data.setting
mygetHelmetapi: response.data.setting
});
//存储配置到游览器
localStorage.setItem('chromesetting',JSON.stringify(response.data.setting));
localStorage.setItem('chromesettingresponse',JSON.stringify(response));
localStorage.setItem('chromesetting', JSON.stringify(response.data.setting));
localStorage.setItem('chromesettingresponse', JSON.stringify(response));
try {
if (response.data.setting.tab_logo_url) {
this.gettablogourldata(response);
@ -549,81 +482,112 @@ class App extends Component {
};
render() {
let { mygetHelmetapi } = this.state;
// console.log("appappapp");
// console.log(mygetHelmetapi);
return (
<Provider store={store}>
<ConfigProvider locale={zhCN}>
<MuiThemeProvider theme={theme}>
<Accountnewprofile {...this.props}{...this.state}/>
<LoginDialog {...this.props} {...this.state} Modifyloginvalue={()=>this.Modifyloginvalue()}></LoginDialog>
<Accountnewprofile {...this.props}{...this.state} />
<LoginDialog {...this.props} {...this.state} Modifyloginvalue={() => this.Modifyloginvalue()}></LoginDialog>
<Notcompletedysl {...this.props} {...this.state}></Notcompletedysl>
<Trialapplicationysl {...this.props} {...this.state}></Trialapplicationysl>
<Trialapplicationreview {...this.props} {...this.state}></Trialapplicationreview>
<Addcourses {...this.props} {...this.state} HideAddcoursestypess={(i)=>this.HideAddcoursestypess(i)}/>
<AccountProfile {...this.props} {...this.state} />
<Certifiedprofessional {...this.props} {...this.state} ModalCancelsy={this.ModalCancelsy} ModalshowCancelsy={this.ModalshowCancelsy}/>
<Addcourses {...this.props} {...this.state} HideAddcoursestypess={(i) => this.HideAddcoursestypess(i)} />
<AccountProfile {...this.props} {...this.state} />
<Certifiedprofessional {...this.props} {...this.state} ModalCancelsy={this.ModalCancelsy} ModalshowCancelsy={this.ModalshowCancelsy} />
<Router>
<Switch>
{/* 项目 */}
<Route path="/projects"
render={
(props) => {
return (<ProjectIndex {...this.props} {...props} {...this.state} />)
}
}></Route>
{/*项目*/}
<Route
path={"/projects"}
render={
(props) => {
return (<Projects {...this.props} {...props} {...this.state} />)
}
}>
</Route>
{/*求职招聘*/}
<Route
path={"/recruitment"}
render={
(props) => {
return (<Tecruitment {...this.props} {...props} {...this.state} />)
}
}
></Route>
{/*编辑简历*/}
<Route
path={"/editresume"}
render={
(props) => {
return (<EditResume {...this.props} {...props} {...this.state} />)
}
}
></Route>
{/*题库*/}
<Route path="/topicbank/:username/:topicstype"
render={
(props) => {
render={
(props) => {
return (<Topicbank {...this.props} {...props} {...this.state} />)
}
}></Route>
return (<Topicbank {...this.props} {...props} {...this.state} />)
}
}></Route>
{/*题库*/}
<Route path="/topicbank/:topicstype"
render={
(props) => {
render={
(props) => {
return (<Topicbank {...this.props} {...props} {...this.state} />)
}
}></Route>
return (<Topicbank {...this.props} {...props} {...this.state} />)
}
}></Route>
{/*/!*众包创新*!/*/}
{/*<Route path={"/crowdsourcing"} component={ProjectPackages}/>*/}
{/*竞赛*/}
<Route path={"/competitions"}
render={
(props) => {
render={
(props) => {
return (<NewCompetitions {...this.props} {...props} {...this.state} />)
}
}></Route>
return (<NewCompetitions {...this.props} {...props} {...this.state} />)
}
}></Route>
{/*黑客松定制竞赛*/}
<Route
path={"/osshackathon"}
render={
(props)=>{
return(
(props) => {
return (
<Osshackathon {...this.props} {...props} {...this.state} />
)
}
}
/>
{/*求职招聘*/}
<Route
path={"/recruitment"}
render={
(props) => {
return (<Tecruitment {...this.props} {...props} {...this.state} />)
}
}
></Route>
{/*认证*/}
<Route path="/account" component={AccountPage}/>
<Route path="/account" component={AccountPage} />
{/*403*/}
<Route path="/403" component={Shixunauthority}/>
<Route path="/403" component={Shixunauthority} />
<Route path="/500" component={http500}/>
<Route path="/500" component={http500} />
{/*404*/}
<Route path="/nopage" component={Shixunnopage}/>
<Route path="/nopage" component={Shixunnopage} />
<Route path="/compatibility" component={CompatibilityPageLoadable}/>
<Route path="/compatibility" component={CompatibilityPageLoadable} />
<Route
path="/login"
render={
@ -661,20 +625,14 @@ class App extends Component {
return (<InfosIndex {...this.props} {...props} {...this.state} />)
}
}></Route>
}></Route>
<Route path="/banks"
render={
(props) => {
return (<BanksIndex {...this.props} {...props} {...this.state} />)
}
}></Route>
{/*<Route*/}
{/*path="/personalcompetit"*/}
{/*render={*/}
{/*(props) => (<PersonalCompetit {...this.props} {...props} {...this.state}></PersonalCompetit>)*/}
{/*}*/}
{/*/>*/}
}></Route>
<Route
path="/changepassword"
render={
@ -684,29 +642,84 @@ class App extends Component {
}
}
/>
{/*<Route*/}
{/* path="/interesse" component={Interestpage}*/}
{/*/>*/}
<Route path="/shixuns/new" component={Newshixuns}>
</Route>
<Route path="/colleges/:id/statistics"
render={
(props) => (<College {...this.props} {...props} {...this.state} />)
}/>
render={
(props) => (<College {...this.props} {...props} {...this.state} />)
} />
{/* jupyter */}
<Route path="/tasks/:identifier/jupyter/"
render={
(props) => {
return (<JupyterTPI {...this.props} {...props} {...this.state}/>)
return (<JupyterTPI {...this.props} {...props} {...this.state} />)
}
}
/>
<Route path="/tasks/:stageId" component={IndexWrapperComponent} />
<Route path="/shixuns/:shixunId"
render={
(props) => (<TPMIndexComponent {...this.props} {...props} {...this.state}></TPMIndexComponent>)
}
></Route>
<Route path="/shixuns"
render={
(props) => (<TPMShixunsIndexComponent {...this.props} {...props} {...this.state}></TPMShixunsIndexComponent>)
}
></Route>
{/*实训课程(原实训路径)*/}
<Route path="/paths" component={ShixunPaths}></Route>
<Route path="/search"
render={
(props) => (<SearchPage {...this.props} {...props} {...this.state}></SearchPage>)
}
></Route>
{/*课堂*/}
<Route path="/classrooms" component={CoursesIndex} {...this.props} {...this.state}></Route>
{/* <Route path="/forums" component={ForumsIndexComponent}>
</Route> */}
{/* 教学案例 */}
<Route path="/moop_cases" render={
(props) => (<MoopCases {...this.props} {...props} {...this.state} />)
} />
<Route path="/forums"
render={
(props) => (<ForumsIndexComponent {...this.props} {...props} {...this.state}></ForumsIndexComponent>)
}
>
</Route>
<Route path="/comment" component={CommentComponent} />
<Route path="/messages"
render={
(props) => (<Messagerouting {...this.props} {...props} {...this.state}></Messagerouting>)
}
></Route>
<Route path="/help/:type"
render={
(props) => (<Help {...this.props} {...props} {...this.state}></Help>)
} />
<Route path="/ecs"
render={
(props) => (<Ecs {...this.props} {...props} {...this.state}></Ecs>)
} />
<Route path="/problems/new/:id?"
render={
(props) => {
return (<NewOrEditTask {...this.props} {...props} {...this.state} />)
}
}
}
/>
<Route path="/myproblems/record_detail/:id"
render={
(props) => (<RecordDetail {...this.props} {...props} {...this.state} />)
}
render={
(props) => (<RecordDetail {...this.props} {...props} {...this.state} />)
}
/>
<Route
path="/problems/:id/edit"
@ -714,78 +727,65 @@ class App extends Component {
(props) => (<NewOrEditTask {...this.props} {...props} {...this.state} />)
} />
<Route path="/Integeneration/:type/:id"
render={
(props) => (<Paperreview {...this.props} {...props} {...this.state} />)
}/>
render={
(props) => (<Paperreview {...this.props} {...props} {...this.state} />)
} />
<Route path="/paperreview/:type"
render={
(props) => (<Paperreview {...this.props} {...props} {...this.state} />)
}/>
render={
(props) => (<Paperreview {...this.props} {...props} {...this.state} />)
} />
<Route path="/paperlibrary/edit/:id"
render={
(props) => (<Paperlibraryeditid {...this.props} {...props} {...this.state} />)
}/>
render={
(props) => (<Paperlibraryeditid {...this.props} {...props} {...this.state} />)
} />
<Route path="/paperlibrary/see/:id"
render={
(props) => (<Paperlibraryseeid {...this.props} {...props} {...this.state} />)
}/>
render={
(props) => (<Paperlibraryseeid {...this.props} {...props} {...this.state} />)
} />
<Route path="/myproblems/:id/:tab?"
render={
(props) => (<StudentStudy {...this.props} {...props} {...this.state} />)
} />
<Route path="/question/edit/:id"
render={
(props) => (<Questionitem_banks {...this.props} {...props} {...this.state} />)
} />
render={
(props) => (<StudentStudy {...this.props} {...props} {...this.state} />)
} />
<Route path="/problemset/:type/:id"
render={
(props) => (<Questionitem_banks {...this.props} {...props} {...this.state} />)
} />
<Route path="/question/newitem"
render={
(props) => (<Questionitem_banks {...this.props} {...props} {...this.state} />)
} />
<Route path="/question/:type"
render={
(props) => (<Headplugselection {...this.props} {...props} {...this.state} />)
} />
<Route path="/problemset/newitem"
render={
(props) => (<Questionitem_banks {...this.props} {...props} {...this.state} />)
} />
<Route path="/problemset/:type"
render={
(props) => (<Headplugselection {...this.props} {...props} {...this.state} />)
} />
<Route path="/paperlibrary"
render={
(props) => (<Testpaperlibrary {...this.props} {...props} {...this.state} />)
}/>
render={
(props) => (<Testpaperlibrary {...this.props} {...props} {...this.state} />)
} />
<Route path="/Integeneration"
render={
(props) => (<Integeneration {...this.props} {...props} {...this.state} />)
}/>
render={
(props) => (<Integeneration {...this.props} {...props} {...this.state} />)
} />
<Route path="/problems"
render={
(props) => (<Developer {...this.props} {...props} {...this.state} />)
}/>
<Route path="/question"
render={
(props) => (<Headplugselection {...this.props} {...props} {...this.state} />)
}/>
{/*<Route path="/wxcode/:identifier?" component={WXCode}*/}
{/* render={*/}
{/* (props)=>(<WXCode {...this.props} {...props} {...this.state}></WXCode>)*/}
{/* }*/}
{/*/>*/}
{/*<Route exact path="/"*/}
{/*// component={ShixunsHome}*/}
{/*render={*/}
{/*(props)=>(<ShixunsHome {...this.props} {...props} {...this.state}></ShixunsHome>)*/}
{/*}*/}
{/*/>*/}
render={
(props) => (<Developer {...this.props} {...props} {...this.state} />)
} />
<Route path="/problemset"
render={
(props) => (<Headplugselection {...this.props} {...props} {...this.state} />)
} />
<Route exact path="/"
// component={ShixunsHome}
render={
(props)=>(<ProjectIndex {...this.props} {...props} {...this.state}></ProjectIndex>)
}
render={
(props) => (<ShixunsHome {...this.props} {...props} {...this.state}></ShixunsHome>)
}
/>
<Route component={Shixunnopage}/>
<Route component={Shixunnopage} />
</Switch>
</Router>
@ -907,4 +907,4 @@ moment.defineLocale('zh-cn', {
doy: 4 // The week that contains Jan 4th is the first week of the year.
}
});
export default SnackbarHOC()(App) ;
export default SnackbarHOC()(App);

View File

@ -1,36 +1,29 @@
import React from "react";
import axios from 'axios';
import md5 from 'md5';
import { requestProxy } from "./indexEduplus2RequestProxy";
import { broadcastChannelOnmessage , isDev, queryString } from 'educoder';
import { notification } from 'antd';
import { broadcastChannelOnmessage, SetAppModel, isDev, queryString } from 'educoder';
import { notification } from 'antd';
import cookie from 'react-cookies';
import './index.css';
const $ = window.$;
const opens ="79e33abd4b6588941ab7622aed1e67e8";
const opens = "79e33abd4b6588941ab7622aed1e67e8";
let timestamp;
let checkSubmitFlg = false;
let message501=false;
let message501 = false;
broadcastChannelOnmessage('refreshPage', () => {
window.location.reload()
window.location.reload()
})
function locationurl(list){
function locationurl(list) {
if (window.location.port === "3007") {
} else {
window.location.href=list
window.location.href = list
}
}
// TODO 开发期多个身份切换
let debugType =""
let debugType = ""
if (isDev) {
const _search = window.location.search;
let parsed = {};
@ -42,38 +35,33 @@ if (isDev) {
window.location.search.indexOf('debug=a') != -1 ? 'admin' : parsed.debug || 'admin'
}
// 超管
// debugType="admin";
//debugType = "admin";
// 老师
//debugType="teacher";
// debugType="teacher";
// 学生
//debugType="student";
// debugType = "student";
function clearAllCookie() {
cookie.remove('_educoder_session', {path: '/'});
cookie.remove('autologin_trustie', {path: '/'});
cookie.remove('_educoder_session', { path: '/' });
cookie.remove('autologin_trustie', { path: '/' });
setpostcookie()
}
clearAllCookie();
function setpostcookie() {
const str =window.location.pathname;
// console.log(str.indexOf("/wxcode"))
let newdomain=".educoder.net"
if(str.indexOf("/wxcode") !== -1){
const str = window.location.pathname;
let newdomain = ".educoder.net"
if (str.indexOf("/wxcode") !== -1) {
console.log("123")
cookie.remove('_educoder_session', {path: '/'});
cookie.remove('autologin_trustie', {path: '/'});
// console.log("开始重写cookis");
cookie.remove('_educoder_session', { path: '/' });
cookie.remove('autologin_trustie', { path: '/' });
const _params = window.location.search;
// console.log("1111");
if (_params) {
// console.log("22222");
let _search = _params.split('?')[1];
let _educoder_sessions= _search.split('&')[0].split('=');
cookie.save('_educoder_session',_educoder_sessions[1], { domain:'.educoder.net', path: '/'});
let autologin_trusties=_search.split('&')[1].split('=');
cookie.save('autologin_trustie',autologin_trusties[1], { domain:'.educoder.net', path: '/'});
let _educoder_sessions = _search.split('&')[0].split('=');
cookie.save('_educoder_session', _educoder_sessions[1], { domain: '.educoder.net', path: '/' });
let autologin_trusties = _search.split('&')[1].split('=');
cookie.save('autologin_trustie', autologin_trusties[1], { domain: '.educoder.net', path: '/' });
}
}
@ -81,180 +69,283 @@ function setpostcookie() {
setpostcookie();
function railsgettimes(proxy) {
function railsgettimes(proxy) {
clearAllCookie()
clearAllCookie()
if(timestamp&&checkSubmitFlg===false){
$.ajax({url:proxy,async:false,success:function(data){
if(data.status===0){
timestamp=data.message;
setpostcookie();
}
}})
checkSubmitFlg=true
window.setTimeout(()=>{
checkSubmitFlg=false;
}, 2000);
}else if(checkSubmitFlg===false){
$.ajax({url:proxy,async:false,success:function(data){
if(data.status===0){
timestamp=data.message;
setpostcookie();
}
}})
checkSubmitFlg=true
window.setTimeout( ()=>{
checkSubmitFlg=false;
}, 2000);
}
if (timestamp && checkSubmitFlg === false) {
$.ajax({
url: proxy, async: true, success: function (data) {
if (data.status === 0) {
timestamp = data.message;
setpostcookie();
}
}
})
checkSubmitFlg = true
window.setTimeout(() => {
checkSubmitFlg = false;
}, 2000);
} else if (checkSubmitFlg === false) {
$.ajax({
url: proxy, async: true, success: function (data) {
if (data.status === 0) {
timestamp = data.message;
setpostcookie();
}
}
})
checkSubmitFlg = true
window.setTimeout(() => {
checkSubmitFlg = false;
}, 2000);
}
}
window._debugType = debugType;
export function initAxiosInterceptors(props) {
initOnlineOfflineListener()
initOnlineOfflineListener()
var //proxy = "http://localhost:3000"
proxy="https://testforgeplus.trustie.net/"
const requestMap = {};
// TODO 避免重复的请求 https://github.com/axios/axios#cancellation
// https://github.com/axios/axios/issues/1497
window.setfalseInRequestMap = function(keyName) {
requestMap[keyName] = false;
}
// TODO 读取到package.json中的配置
var proxy = "http://localhost:3000"
// proxy = "http://testbdweb.trustie.net"
// proxy = "http://testbdweb.educoder.net"
// proxy = "https://testeduplus2.educoder.net"
//proxy="http://47.96.87.25:48080"
proxy = "https://pre-newweb.educoder.net"
proxy = "https://testforgeplus.trustie.net/"
// proxy="https://test-jupyterweb.educoder.net"
// proxy="https://test-newweb.educoder.net"
// proxy="https://test-jupyterweb.educoder.net"
//响应前的设置
axios.interceptors.request.use(
config => {
setpostcookie()
clearAllCookie()
if (config.url.indexOf(proxy) !== -1 || config.url.indexOf(':') !== -1) {
return config
}
requestProxy(config)
let url = `/api${config.url}`;
//qq登录去掉api
if(config.params&&config.params.redirect_uri!=undefined){
if(config.params.redirect_uri.indexOf('otherloginqq')!=-1){
url = `${config.url}`;
}
}
if(`${config[0]}`!=`true`){
let timestamp = Date.parse(new Date())/1000;
if (window.location.port === "3007") {
config.url = `${proxy}${url}`;
if (config.url.indexOf('?') == -1) {
config.url = `${config.url}?debug=${debugType}`;
} else {
config.url = `${config.url}&debug=${debugType}`;
}
} else {
// 加api前缀
config.url = url;
}
setpostcookie();
}
if (config.method === "post") {
if (requestMap[config.url] === true) { // 避免重复的请求 导致页面f5刷新 也会被阻止 显示这个方法会影响到定制信息
return false;
}
}
// 非file_update请求
if (config.url.indexOf('update_file') === -1) {
requestMap[config.url] = true;
// 在这里使用requestMap控制避免用户通过双击等操作发出重复的请求
// 如果需要支持重复的请求考虑config里面自定义一个allowRepeat参考来控制
const requestMap = {};
window.setTimeout("setfalseInRequestMap('"+config.url+"')", 900)
}
// setTimeout("setfalseInRequestMap(" + config.url + ")", 1200)
return config;
},
err => {
return Promise.reject(err);
});
window.setfalseInRequestMap = function (keyName) {
requestMap[keyName] = false;
}
axios.interceptors.response.use(function (response) {
if(response===undefined){
return
}
const config = response.config
if (response.data.status === -1) {
if (window.location.pathname.startsWith('/tasks/')) {
props.showSnackbar( response.data.message || '服务器异常,请联系管理员。' )
} else {
notification.open({
message:"提示",
description: response.data.message || '服务器异常,请联系管理员。',
style: {
zIndex: 99999999
},
});
// notification['error']({
// message:"提示",
// description: response.data.message || '服务器异常,请联系管理员。',
// });
//响应前的设置
axios.interceptors.request.use(
config => {
setpostcookie()
clearAllCookie()
// config.headers['Content-Type']= 'no-cache'
// if (token) { // 每次发送请求之前判断是否存在token如果存在则统一在http请求的header都加上token不用每次请求都手动添加了
// config.headers.Authorization = token;
// }
// --------------------------------------------- 測試3007连测试服的代码
// if (url.indexOf('file_update') != -1 || url.indexOf('game_build') != -1 || url.indexOf('game_status') != -1) {
// proxy = 'https://testbdweb.trustie.net'
// } else {
// proxy = 'http://localhost:3000'
// }
// ---------------------------------------------
// console.log("开始请求了");
// console.log(config.url);
// console.log(window.location.pathname);
//
// try {
// const str =window.location.pathname;
// if(str.indexOf("/wxcode") !== -1){
// // console.log("开始重写cookis");
// const _params = window.location.search;
// // console.log("1111");
// if (_params) {
// // console.log("22222");
// let _search = _params.split('?')[1];
// var _educoder_sessionmys="";
// var autologin_trusties="";
// _search.split('&').forEach(item => {
// const _arr = item.split('=');
// if(_arr[0]==='_educoder_session'){
// cookie.save('_educoder_session',_arr[1], { domain: '.educoder.net', path: '/'});
// _educoder_sessionmys=_arr[1];
// }else{
// cookie.save('autologin_trustie',_arr[1], { domain: '.educoder.net', path: '/'});
// autologin_trusties=_arr[1];
// }
// });
// try {
// const autlogins= `_educoder_session=${_educoder_sessionmys}; autologin_trustie=${autologin_trusties} `;
// config.params = {'Cookie': autlogins}
// config.headers['Cookie'] =autlogins;
// // console.log("设置了cookis");
// } catch (e) {
//
// }
// try {
// const autloginysls= `_educoder_session=${_educoder_sessionmys}; autologin_trustie=${autologin_trusties} `;
// config.params = {'autloginysls': autloginysls}
// config.headers['Cookie'] =autloginysls;
// // console.log("设置了cookis");
// }catch (e) {
//
// }
// }
// }
// }catch (e) {
//
// }
if (config.url.indexOf(proxy) != -1 || config.url.indexOf(':') != -1) {
return config
}
requestProxy(config)
let url = `/api${config.url}`;
//qq登录去掉api
if (config.params && config.params.redirect_uri != undefined) {
if (config.params.redirect_uri.indexOf('otherloginqq') != -1) {
url = `${config.url}`;
}
}
if (`${config[0]}` != `true`) {
if (window.location.port === "3007") {
config.url = `${proxy}${url}`;
if (config.url.indexOf('?') == -1) {
config.url = `${config.url}?debug=${debugType}`;
} else {
config.url = `${config.url}&debug=${debugType}`;
}
}
setpostcookie();
}
if (config.url.indexOf('update_file') === -1) {
requestMap[config.url] = true;
throw new axios.Cancel('Operation canceled by the user.');
window.setTimeout("setfalseInRequestMap('" + config.url + "')", 900)
}
return config;
},
err => {
return Promise.reject(err);
});
axios.interceptors.response.use(function (response) {
// console.log(".............")
if (response === undefined) {
return
}
if (response.data.status === 403||response.data.status === "403") {
const config = response.config
if (response.data.status === -1) {
// console.error('error:', response.data.message)
// throw new Error()
// https://github.com/axios/axios/issues?utf8=%E2%9C%93&q=cancel+request+in+response+interceptors+
// https://github.com/axios/axios/issues/583
// message.info(response.data.message || '服务端返回status -1请联系管理员。');
// props.showSnackbar( response.data.message || '服务器异常,请联系管理员。' )
if (window.location.pathname.startsWith('/tasks/')) {
props.showSnackbar(response.data.message || '服务器异常,请联系管理员。')
} else {
notification.open({
message: "提示",
description: response.data.message || '服务器异常,请联系管理员。',
style: {
zIndex: 99999999
},
});
// notification['error']({
// message:"提示",
// description: response.data.message || '服务器异常,请联系管理员。',
// });
}
throw new axios.Cancel('Operation canceled by the user.');
} else {
// hash跳转
// var hash = window.location.hash;
// if (hash) {
// hashTimeout && window.clearTimeout(hashTimeout)
// hashTimeout = setTimeout(() => {
// var element = document.querySelector(hash);
// if (element) {
// element.scrollIntoView();
// }
// }, 400)
// }
}
// if(response.data.status === 401){
// console.log("401401401")
// }
if (response.data.status === 403 || response.data.status === "403") {
locationurl('/403');
}
if (response.data.status === 404) {
locationurl('/nopage');
locationurl('/nopage');
}
if (response.data.status === 500) {
locationurl('/500');
locationurl('/500');
}
if (response.data.status === 501) {
if(message501===false){
message501=true
if (message501 === false) {
message501 = true
notification.open({
message:"提示",
description:response.data.message || '访问异常,请求不合理',
message: "提示",
description: response.data.message || '访问异常,请求不合理',
style: {
zIndex: 99999999
}
})
}
window.setTimeout(function () {
message501=false
message501 = false
}, 2000);
}
requestMap[response.config.url] = false;
setpostcookie();
return response;
}, function (error) {
return Promise.reject(error);
});
// -----------------------------------------------------------------------------------
}, function (error) {
return Promise.reject(error);
});
// -----------------------------------------------------------------------------------
}
function initOnlineOfflineListener() {
const $ = window.$
$(window).bind("online", () => {
notification.destroy()
notification.success({
duration: 2,
message: '网络恢复正常',
description:
'网络恢复正常,感谢使用。',
})
});
$(window).bind("offline", () => {
notification.destroy()
const $ = window.$
$(window).bind("online", () => {
notification.destroy()
notification.success({
duration: 2,
message: '网络恢复正常',
description:
'网络恢复正常,感谢使用。',
})
});
$(window).bind("offline", () => {
notification.destroy()
notification.warning({
duration: null,
message: '网络异常',
description:
'网络异常,请检测网络后重试。',
})
});
notification.warning({
duration: null,
message: '网络异常',
description:
'网络异常,请检测网络后重试。',
})
});
}

View File

@ -5,17 +5,16 @@ import { BrowserRouter as Router, Route, Link } from "react-router-dom";
import { Spin } from 'antd';
class Loading extends Component {
componentDidUpdate(prevProps, prevState) {
if (!prevProps.error && this.props.error) {
console.log(this.props.error)
window.location.reload()
componentDidUpdate(prevProps, prevState) {
if (!prevProps.error && this.props.error) {
console.log(this.props.error)
}
}
}
render() {
// Loading
return (
<div className="App" style={{minHeight: '800px',width:"100%"}}>
render() {
// Loading
return (
<div className="App" style={{ minHeight: '800px', width: "100%" }}>
<style>
{
`
@ -25,10 +24,10 @@ class Loading extends Component {
`
}
</style>
<Spin size="large" className={"margintop"}/>
</div>
);
}
<Spin size="large" className={"margintop"} />
</div>
);
}
}
export default Loading;

9
src/app-test.jsx Normal file
View File

@ -0,0 +1,9 @@
import React from 'react'
import MiniPagination from './components/mini-pagination'
export default () => {
function onPageChange(page) {
console.log(page, '-----------')
}
return <MiniPagination onChange={onPageChange} current={1} total={100} pageSize={16} />
}

View File

@ -29,7 +29,7 @@ class College extends Component {
align: 'center',
className: "edu-txt-center font-14 maxnamewidth247",
render: (text, record) => (
<a href={`/courses/${record.id}/students`} title={record.name} target="_blank" className="d-inline-block text-truncate maxnamewidth247"
<a href={`/classrooms/${record.id}/students`} title={record.name} target="_blank" className="d-inline-block text-truncate maxnamewidth247"
style={{
maxWidth:'220px',
color:'#007bff',
@ -895,7 +895,7 @@ class College extends Component {
共建实训
</p>
<p className="yslstatistic-base-item-label">
报告
报告
</p>
<p className="yslstatistic-base-item-label">
学员实战时间
@ -907,7 +907,7 @@ class College extends Component {
<div className="jibenshiyong100 sortinxdirection yinyin">
<div className="yslstatistic-base-item-labels">
{
teachers_count?
teachers_count || teachers_count===0?
<div className="yslstatistic-base-item-labelsp"> {teachers_count}<span className="yslstatistic-base-item-labelsspan"></span></div>
:
<Spin/>
@ -915,7 +915,7 @@ class College extends Component {
</div>
<div className="yslstatistic-base-item-labels">
{
students_count?
students_count || students_count===0?
<div className="yslstatistic-base-item-labelsp">{students_count}<span className="yslstatistic-base-item-labelsspan"></span></div>
:
<Spin/>
@ -923,7 +923,7 @@ class College extends Component {
</div>
<div className="yslstatistic-base-item-labels">
{
courses_count?
courses_count || courses_count === 0?
<div className="yslstatistic-base-item-labelsp">{courses_count}<span className="yslstatistic-base-item-labelsspan"></span></div>
:
<Spin/>
@ -931,7 +931,7 @@ class College extends Component {
</div>
<div className="yslstatistic-base-item-labels">
{
shixuns_count?
shixuns_count || shixuns_count === 0?
<div className="yslstatistic-base-item-labelsp">{shixuns_count}<span className="yslstatistic-base-item-labelsspan"></span></div>
:
<Spin/>
@ -939,7 +939,7 @@ class College extends Component {
</div>
<div className="yslstatistic-base-item-labels">
{
shixun_report_count?
shixun_report_count || shixun_report_count===0?
<div className="yslstatistic-base-item-labelsp">{shixun_report_count}<span className="yslstatistic-base-item-labelsspan"></span></div>
:
<Spin/>
@ -947,8 +947,8 @@ class College extends Component {
</div>
<div className="yslstatistic-base-item-labels">
{
shixun_time?
<div className="yslstatistic-base-item-labelsp">{shixun_time}<span className="yslstatistic-base-item-labelsspan"></span></div>
shixun_time || shixun_time === 0 ?
<div className="yslstatistic-base-item-labelsp">{shixun_time}<span className="yslstatistic-base-item-labelsspan">分钟</span></div>
:
<Spin/>
}

View File

@ -1,112 +1,129 @@
.yslstatistic-header {
width: 100%;
height: 240px;
background-image: url('/images/educoder/statistics.jpg');
background-size: 100% 100%;
}
.yslborder{
border: 1px solid;
}
.yslstatistic-header-title{
flex: 1;
display: flex;
align-items: center;
color: #4CACFF;
font-size: 32px;
}
.yslstatistic-header-content{
width: 100%;
display: flex;
justify-content: space-around;
}
.yslstatistic-header-item{
margin-bottom: 22px;
display: flex;
flex-direction: column;
align-items: center;
color: #fff;
}
.yslstatistic-header-item-label{
color: #989898;
width: 100%;
height: 240px;
background-image: url('/images/educoder/statistics.jpg');
background-size: 100% 100%;
}
.yslstatistic-base-item-label{
width: 217px;
text-align: center;
font-size: 16px;
height: 48px;
line-height: 48px;
color: #686868;
background: #F5F5F5;
border-top: 1px solid #EBEBEB;
}
.yslstatistic-base-item-labels{
width: 217px;
text-align: center;
height: 100px;
line-height: 100px;
background: #ffffff;
border-top: 1px solid #EBEBEB;
border-bottom: 1px solid #EBEBEB;
}
.yslstatistic-base-item-labelsp{
color: #000000;
font-size: 24px;
}
.yslstatistic-base-item-labelsspan{
color: #000000;
margin-left: 5px;
font-size: 16px;
}
.jibenshiyong100{
width: 100%;
.yslborder {
border: 1px solid;
}
.yslstatistic-header-item-content{
font-size: 24px;
.yslstatistic-header-title {
flex: 1;
display: flex;
align-items: center;
color: #4CACFF;
font-size: 32px;
}
.yslstatistic-header-content {
width: 100%;
display: flex;
justify-content: space-around;
}
.yslstatistic-header-item {
margin-bottom: 22px;
display: flex;
flex-direction: column;
align-items: center;
color: #fff;
}
.yslstatistic-header-item-label {
color: #989898;
}
.yslstatistic-base-item-label {
width: 217px;
text-align: center;
font-size: 16px;
height: 48px;
line-height: 48px;
color: #686868;
background: #F5F5F5;
border-top: 1px solid #EBEBEB;
}
.yslstatistic-base-item-labels {
width: 217px;
text-align: center;
height: 100px;
line-height: 100px;
background: #ffffff;
border-top: 1px solid #EBEBEB;
border-bottom: 1px solid #EBEBEB;
}
.yslstatistic-base-item-labelsp {
color: #000000;
font-size: 24px;
}
.yslstatistic-base-item-labelsspan {
color: #000000;
margin-left: 5px;
font-size: 16px;
}
.jibenshiyong100 {
width: 100%;
}
.yslstatistic-header-item-content {
font-size: 24px;
}
/* 中间居中 */
.intermediatecenter{
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
.intermediatecenter {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
/* 简单居中 */
.intermediatecenterysls{
display: flex;
align-items: center;
.intermediatecenterysls {
display: flex;
align-items: center;
}
.spacearound{
display: flex;
justify-content: space-around;
.spacearound {
display: flex;
justify-content: space-around;
}
.spacebetween{
display: flex;
justify-content: space-between;
.spacebetween {
display: flex;
justify-content: space-between;
}
/* 头顶部居中 */
.topcenter{
display: -webkit-flex;
flex-direction: column;
align-items: center;
.topcenter {
display: -webkit-flex;
flex-direction: column;
align-items: center;
}
/* x轴正方向排序 */
/* 一 二 三 四 五 六 七 八 */
.sortinxdirection{
display: flex;
flex-direction:row;
.sortinxdirection {
display: flex;
flex-direction: row;
align-items: center;
}
/* x轴反方向排序 */
/* 八 七 六 五 四 三 二 一 */
.xaxisreverseorder{
display: flex;
flex-direction:row-reverse;
.xaxisreverseorder {
display: flex;
flex-direction: row-reverse;
}
/* 垂直布局 正方向*/
/*
@ -116,98 +133,118 @@
*/
.verticallayout{
display: flex;
flex-direction:column;
.verticallayout {
display: flex;
flex-direction: column;
}
/* 垂直布局 反方向*/
.reversedirection{
display: flex;
flex-direction:column-reverse;
.reversedirection {
display: flex;
flex-direction: column-reverse;
}
.h4{
font-size: 1.5rem;
font-weight: 500 !important;
}
.ysllinjibenshiyong{
font-weight: 500;
line-height: 1.2;
padding: 2rem 1.25rem;
border-bottom: unset;
background:#fff;
}
.linjibenshiyong{
font-weight: 500;
line-height: 1.2;
padding: 2rem 1.25rem;
border-bottom: unset;
background:#fff;
box-shadow:0px 6px 12px 0px rgba(0,0,0,0.1);
border-radius:2px;
}
.yslslinjibenshiyong{
font-weight: 500;
line-height: 1.2;
border-bottom: unset;
box-shadow:0px 6px 12px 0px rgba(0,0,0,0.1);
border-radius:2px;
}
.yinyin{
background: #fff;
box-shadow:0px 6px 12px 0px rgba(0,0,0,0.1);
border-radius:2px;
}
.edu-back-eeee{
background:#EEEEEE !important;
}
.mt-4{
margin-top: 1.5rem !important;
.h4 {
font-size: 1.5rem;
font-weight: 500 !important;
}
.statistic-label{
padding: 2rem 1.25rem;
font-size: 1.5rem;
font-weight: 400 !important;
}
.mb50{
padding-bottom: 50px !important;
}
.mt40{
margin-top: 40px;
}
.mb80{
margin-bottom: 80px;
}
.task-hide{overflow:hidden; white-space: nowrap; text-overflow:ellipsis;}
a:hover{
color:#0056b3;
}
.color-blue{
color: #4CACFF;
.ysllinjibenshiyong {
font-weight: 500;
line-height: 1.2;
padding: 2rem 1.25rem;
border-bottom: unset;
background: #fff;
}
.color-huang{
color:#ffc107 !important
.linjibenshiyong {
font-weight: 500;
line-height: 1.2;
padding: 2rem 1.25rem;
border-bottom: unset;
background: #fff;
box-shadow: 0px 6px 12px 0px rgba(0, 0, 0, 0.1);
border-radius: 2px;
}
.maxnamewidth105{
max-width: 105px;
overflow:hidden;
text-overflow:ellipsis;
white-space:nowrap;
cursor: default;
.yslslinjibenshiyong {
font-weight: 500;
line-height: 1.2;
border-bottom: unset;
box-shadow: 0px 6px 12px 0px rgba(0, 0, 0, 0.1);
border-radius: 2px;
}
.maxnamewidth247{
max-width: 247px;
overflow:hidden;
text-overflow:ellipsis;
white-space:nowrap;
cursor: default;
.yinyin {
background: #fff;
box-shadow: 0px 6px 12px 0px rgba(0, 0, 0, 0.1);
border-radius: 2px;
}
.maxnamewidth340{
max-width: 340px;
overflow:hidden;
text-overflow:ellipsis;
white-space:nowrap;
cursor: default;
.edu-back-eeee {
background: #EEEEEE !important;
}
.mt-4 {
margin-top: 1.5rem !important;
}
.statistic-label {
padding: 2rem 1.25rem;
font-size: 1.5rem;
font-weight: 400 !important;
}
.mb50 {
padding-bottom: 50px !important;
}
.mt40 {
margin-top: 40px;
}
.mb80 {
margin-bottom: 80px;
}
.task-hide {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
a:hover {
color: #0056b3;
}
.color-blue {
color: #4CACFF;
}
.color-huang {
color: #ffc107 !important
}
.maxnamewidth105 {
max-width: 105px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
cursor: default;
}
.maxnamewidth247 {
max-width: 247px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
cursor: default;
}
.maxnamewidth340 {
max-width: 340px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
cursor: default;
}

View File

@ -38,6 +38,36 @@ export function getNextHalfHourOfMoment(moment) {
return moment
}
 export function formatSeconds(value) {
        var theTime = parseInt(value);// 秒
        var middle= 0;// 分
        var hour= 0;// 小时
    
        if(theTime > 60) {
            middle= parseInt(theTime/60);
            theTime = parseInt(theTime%60);
            if(middle> 60) {
                hour= parseInt(middle/60);
                middle= parseInt(middle%60);
            }
        }
        var result = ""+parseInt(theTime)+"秒";
        if(middle > 0) {
if(hour>0){
result = ""+parseInt(middle)+"分";
}else{
result = ""+parseInt(middle)+"分"+result;
}
            
        }
        if(hour> 0) {
            result = ""+parseInt(hour)+"小时"+result;
        }
        return result;
    }
export function formatDuring(mss){
var days = parseInt(mss / (1000 * 60 * 60 * 24));
var hours = parseInt((mss % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
@ -66,4 +96,4 @@ export function formatDuring(mss){
}
return days + "天" + hours + "小时" + minutes + "分";
}
}

View File

@ -21,9 +21,9 @@ class LoadingSpin extends Component{
}
`}
</style>
<Spin tip="正在获取相关数据..."/>
<Spin/>
</div>
)
}
}
export default LoadingSpin;
export default LoadingSpin;

View File

@ -17,14 +17,14 @@ const timeStamp = () => {
/*
带trace的默认折叠起来的控制台输出
第一个参数最好传入string类型的标识接着可以跟任意类型任意个数的参数各个参数都会打印到控制台
*/
*/
export function trace_collapse(content) {
if (console.groupCollapsed) {
console.groupCollapsed(typeof content == 'string' ? content : 'trace_collapse');
log.trace(arguments);
console.groupEnd();
// console.groupCollapsed(typeof content == 'string' ? content : 'trace_collapse');
// log.trace(arguments);
// console.groupEnd();
} else {
trace(content)
// trace(content)
}
}

View File

@ -2,19 +2,23 @@ import React, { Component } from 'react';
import Snackbar from 'material-ui/Snackbar';
import Fade from 'material-ui/transitions/Fade';
import { notification } from 'antd'
const snackbarProp = { 'aria-describedby': 'message-id' }
export function SnackbarHOC(options = {}) {
return function wrap(WrappedComponent) {
return class Wrapper extends Component {
constructor(props) {
super(props);
this.showSnackbar = this.showSnackbar.bind(this)
this.state = {
snackbarText: '',
snackbarOpen: false,
}
}
return class Wrapper extends Component {
constructor(props) {
super(props);
this.showSnackbar = this.showSnackbar.bind(this)
this.handleSnackbarClose = this.handleSnackbarClose.bind(this)
this.state = {
snackbarText: '',
snackbarOpen: false,
}
}
handleSnackbarClose() {
handleSnackbarClose() {
this.setState({
snackbarOpen: false,
snackbarVertical: '',
@ -22,70 +26,50 @@ export function SnackbarHOC(options = {}) {
})
}
// 全局的snackbar this.props.showSnackbar调用即可
// showSnackbar(description, message = "提示",icon) {
// // this.setState({
// // snackbarOpen: true,
// // snackbarText: text,
// // snackbarVertical: vertical,
// // snackbarHorizontal: horizontal,
// // })
// const data = {
// message,
// description
// }
// if (icon) {
// data.icon = icon;
// }
// notification.open(data);
// }
showSnackbar(text, vertical, horizontal) {
this.setState({
snackbarOpen: true,
snackbarText: text,
snackbarVertical: vertical,
snackbarHorizontal: horizontal,
})
showSnackbar(text, vertical, horizontal) {
this.setState({
snackbarOpen: true,
snackbarText: text,
snackbarVertical: vertical,
snackbarHorizontal: horizontal,
})
}
//个别情况需要走
showNotification = (description, message = "提示", icon) => {
const data = {
message,
description
}
//个别情况需要走
showNotification = (description, message = "提示", icon) => {
const data = {
message,
description
}
if (icon) {
data.icon = icon;
}
notification.open(data);
if (icon) {
data.icon = icon;
}
render() {
const { snackbarOpen, snackbarText, snackbarHorizontal, snackbarVertical } = this.state;
notification.open(data);
}
render() {
return (
<React.Fragment>
<Snackbar
className={"rootSnackbar"}
style={{zIndex:30000}}
open={this.state.snackbarOpen}
autoHideDuration={3000}
anchorOrigin={{ vertical: this.state.snackbarVertical || 'top'
, horizontal: this.state.snackbarHorizontal || 'center' }}
onClose={() => {this.handleSnackbarClose()}}
transition={Fade}
SnackbarContentProps={{
'aria-describedby': 'message-id',
}}
resumeHideDuration={2000}
message={<span id="message-id">{this.state.snackbarText}</span>}
/>
<WrappedComponent {...this.props} showSnackbar={ this.showSnackbar } showNotification= { this.showNotification } >
</WrappedComponent>
</React.Fragment>
)
}
}
return (
<React.Fragment>
<Snackbar
className={"rootSnackbar"}
style={{ zIndex: 30000 }}
open={this.state.snackbarOpen}
autoHideDuration={3000}
anchorOrigin={{
vertical: this.state.snackbarVertical || 'top'
, horizontal: this.state.snackbarHorizontal || 'center'
}}
onClose={this.handleSnackbarClose}
transition={Fade}
SnackbarContentProps={snackbarProp}
resumeHideDuration={2000}
message={<span id="message-id">{this.state.snackbarText}</span>}
/>
<WrappedComponent {...this.props} showSnackbar={this.showSnackbar} showNotification={this.showNotification} >
</WrappedComponent>
</React.Fragment>
)
}
}
}
}

View File

@ -1,79 +1,167 @@
import { bytesToSize, getUrl, getUrl2 } from 'educoder';
const $ = window.$
export function isImageExtension(fileName) {
return fileName ? !!(fileName.match(/.(jpg|jpeg|png|gif)$/i)) : false
}
export function markdownToHTML(oldContent, selector) {
window.$('#md_div').html('')
// markdown to html
if (selector && oldContent && oldContent.startsWith('<p')) { // 普通html处理
window.$('#' + selector).addClass('renderAsHtml')
window.$('#' + selector).html(oldContent)
} else {
try {
$("#"+selector).html('')
// selector ||
var markdwonParser = window.editormd.markdownToHTML(selector || "md_div", {
markdown: oldContent, // .replace(/▁/g,"▁▁▁"),
emoji: true,
htmlDecode: "style,script,iframe", // you can filter tags decode
taskList: true,
tex: true, // 默认不解析
flowChart: true, // 默认不解析
sequenceDiagram: true // 默认不解析
});
} catch(e) {
console.error(e)
}
// selector = '.' + selector
if (selector) {
return;
}
const content = window.$('#md_div').html()
if (selector) {
window.$(selector).html(content)
}
return content
}
}
function _doDownload(options) {
$.fileDownload(getUrl() + "/api" + options.url, {
successCallback: options.successCallback,
failCallback: options.failCallback
});
}
export function downloadFile(options) {
if ($.fileDownload) {
_doDownload(options)
} else {
const _url_origin = getUrl2()
$.getScript(
`${_url_origin}/javascripts/download/jquery.fileDownload.min.js`,
(data, textStatus, jqxhr) => {
_doDownload(options)
});
}
}
export function appendFileSizeToUploadFile(item) {
return `${item.title}${uploadNameSizeSeperator}${item.filesize}`
}
export function appendFileSizeToUploadFileAll(fileList) {
return fileList.map(item => {
if (item.name.indexOf(uploadNameSizeSeperator) == -1) {
return Object.assign({}, item, {name: `${item.name}${uploadNameSizeSeperator}${bytesToSize(item.size)}`})
}
return item
})
}
export const uploadNameSizeSeperator = '  '
export const sortDirections = ["ascend", "descend", "ascend", "descend", "ascend", "descend", "ascend", "descend", "ascend", "descend", "ascend", "descend", "ascend", "descend",
"ascend", "descend", "ascend", "descend", "ascend", "descend", "ascend", "descend", "ascend", "descend", "ascend", "descend", "ascend", "descend",
"ascend", "descend", "ascend", "descend", "ascend", "descend", "ascend", "descend", "ascend", "descend", "ascend", "descend", "ascend", "descend",
"ascend", "descend", "ascend", "descend", "ascend", "descend", "ascend", "descend", "ascend", "descend", "ascend", "descend", "ascend", "descend", ]
import { bytesToSize, getUrl, getUrl2 } from 'educoder'
import showdown from 'showdown'
const $ = window.$
export function isImageExtension(fileName) {
return fileName ? !!(fileName.match(/.(jpg|jpeg|png|gif)$/i)) : false
}
export function markdownToHTML(oldContent, selector) {
try {
window.$('#md_div').html('')
if (selector && oldContent && oldContent.startsWith('<p')) { // 普通html处理
window.$('#' + selector).addClass('renderAsHtml')
window.$('#' + selector).html(oldContent)
} else {
try {
$("#" + selector).html('')
// selector ||
var markdwonParser = window.editormd.markdownToHTML(selector || "md_div", {
markdown: oldContent, // .replace(/▁/g,"▁▁▁"),
emoji: true,
htmlDecode: "style,script,iframe", // you can filter tags decode
taskList: true,
tex: true, // 默认不解析
flowChart: true, // 默认不解析
sequenceDiagram: true // 默认不解析
});
} catch (e) {
console.error(e)
}
// selector = '.' + selector
if (selector) {
return;
}
const content = window.$('#md_div').html()
if (selector) {
window.$(selector).html(content)
}
return content
}
} catch (e) {
}
}
function _doDownload(options) {
$.fileDownload(getUrl() + "/api" + options.url, {
successCallback: options.successCallback,
failCallback: options.failCallback
});
}
export function downloadFile(options) {
if ($.fileDownload) {
_doDownload(options)
} else {
const _url_origin = getUrl2()
$.getScript(
`${_url_origin}/javascripts/download/jquery.fileDownload.min.js`,
(data, textStatus, jqxhr) => {
_doDownload(options)
});
}
}
export function appendFileSizeToUploadFile(item) {
return `${item.title}${uploadNameSizeSeperator}${item.filesize}`
}
export function appendFileSizeToUploadFileAll(fileList) {
return fileList.map(item => {
if (item.name.indexOf(uploadNameSizeSeperator) == -1) {
return Object.assign({}, item, { name: `${item.name}${uploadNameSizeSeperator}${bytesToSize(item.size)}` })
}
return item
})
}
export const uploadNameSizeSeperator = '  '
export const sortDirections = ["ascend", "descend", "ascend", "descend", "ascend", "descend", "ascend", "descend", "ascend", "descend", "ascend", "descend", "ascend", "descend",
"ascend", "descend", "ascend", "descend", "ascend", "descend", "ascend", "descend", "ascend", "descend", "ascend", "descend", "ascend", "descend",
"ascend", "descend", "ascend", "descend", "ascend", "descend", "ascend", "descend", "ascend", "descend", "ascend", "descend", "ascend", "descend",
"ascend", "descend", "ascend", "descend", "ascend", "descend", "ascend", "descend", "ascend", "descend", "ascend", "descend", "ascend", "descend",]
export function validateLength(str = '', length = 100) {
let len = 0
if (str) {
len = str.length
for (let i = 0; i < len; i++) {
let charCode = str.charCodeAt(i)
if (charCode >= 0xD800 && charCode <= 0xDBFF) {
len--
i++
}
}
}
return len <= length
}
export function mdJSONParse(str) {
let val = "";
try {
return val = JSON.parse(str)
} catch (error) {
if (str) {
return val = str;
} else {
return "";
}
}
}
showdown.extension('prettify', function () {
return [{
type: 'output',
filter: function (source) {
return source.replace(/(<pre[^>]*>)?[\n\s]?<code([^>]*)>/gi, function (match, pre, codeClass) {
if (pre) {
return '<pre class="prettyprint linenums"><code' + codeClass + '>'
} else {
return ' <code class="prettyprint">'
}
})
}
}]
})
const showdownKatex = require('showdown-katex')
const CONVERTER = new showdown.Converter({
tables: true,
simpleLineBreaks: false,
underline: true,
extensions: [
'prettify',
showdownKatex({
throwOnError: false,
displayMode: false,
errorColor: '#1500ff',
}),
]
})
const oldKatexMode = /(?:`?\$\$)([^`\$]+)(?:\$\$`?)/g
export function exportMdtoHtml(md = '') {
if (typeof md === 'string') {
let rs = md.replace(oldKatexMode, (_, p1) => {
return "$$" + p1 + "$$"
})
return CONVERTER.makeHtml(rs)
}
return md + ''
}
function escapeText(text) {
return text.replace(/[&<>"']/g, s => {
const entityMap = {
'&': '&amp;',
'<': '&lt;',
'>': '&gt;',
'"': '',
"'": '',
};
return entityMap[s]
})
}

View File

@ -5,26 +5,75 @@ const { Search } = Input;
const $ = window.$;
const isDev = window.location.port == 3007;
export const TEST_HOST = "https://testforgeplus.trustie.net"
const isdev2= window.location.hostname ==='www.educoder.net'
export const TEST_HOST = "https://testforgeplus.trustie.net/"
export function getImageUrl(path) {
// https://www.educoder.net
// https://testbdweb.trustie.net
// const local = 'http://localhost:3000'
const local = 'https://testforgeplus.trustie.net'
const local = 'https://testforgeplus.trustie.net/'
if (isDev) {
return `${local}/${path}`
}
return `/${path}`;
}
export function setImagesUrl(path){
const local = 'https://testforgeplus.trustie.net'
export function getcdnImageUrl(path) {
// https://www.educoder.net
// https://testbdweb.trustie.net
// const local = 'http://localhost:3000'
const testlocal = 'https://testali-cdn.educoder.net'
const local='https://ali-cdn.educoder.net'
let firstStr=path.substr(0,1);
// console.log(firstStr);
if(firstStr=="/"){
return isDev?`${local}${path}`:`${path}`;
if (isdev2) {
return `${local}/${path}`;
}else{
return isDev?`${local}/${path}`:`/${path}`;
if(firstStr=="/"){
return `${path}`
}else{
return `/${path}`
}
}
// return `${local}/${path}`;
}
export function setcndImagesUrl(path){
const testlocal = 'https://testali-cdn.educoder.net'
const local='https://ali-cdn.educoder.net'
let firstStr=path.substr(0,1);
if(firstStr=="/"){
if (!isdev2) {
return `${path}`
}
return `${local}${path}`;
//return isDev?`${testlocal}${path}`:`${local}${path}`;
}else{
if (!isdev2) {
return `/${path}`
}
return `${local}/${path}`;
// return isDev?`${testlocal}/${path}`:`${local}/${path}`;
}
}
export function setImagesUrl(path){
const testlocal = 'https://testali-cdn.educoder.net'
const local='https://ali-cdn.educoder.net'
let firstStr=path.substr(0,1);
if(firstStr=="/"){
if (!isdev2) {
return `${path}`
}
return `${local}${path}`;
// return isDev?`${testlocal}${path}`:`${path}`;
}else{
if (!isdev2) {
return `/${path}`
}
return `${local}/${path}`;
//return isDev?`${testlocal}/${path}`:`/${path}`;
}
}
@ -37,7 +86,7 @@ export function getUrl(path, goTest) {
// testbdweb.educoder.net testbdweb.trustie.net
// const local = goTest ? 'https://testeduplus2.educoder.net' : 'http://localhost:3000'
// const local = 'https://testeduplus2.educoder.net'
const local = 'http://localhost:3007'
const local = 'https://testforgeplus.trustie.net/'
if (isDev) {
return `${local}${path?path:''}`
}
@ -97,7 +146,7 @@ function railsgettimess(proxy) {
export function Railsgettimes() {
railsgettimess(`${getUrl()}/api/main/first_stamp.json`);
// railsgettimess(`${getUrl()}/api/main/first_stamp.json`);
// railsgettimess(`https://api.m.taobao.com/rest/api3.do?api=mtop.common.getTimestamp`);
}
export function getmyUrl(geturl) {
@ -111,26 +160,33 @@ export function getUploadActionUrl(path, goTest) {
return `${getUrl()}/api/attachments.json${isDev ? `?debug=${window._debugType || 'admin'}&randomcode=${newtimestamp}&client_key=${anewopens}` : `?randomcode=${newtimestamp}&client_key=${anewopens}`}`;
}
export function getUploadLogoActionUrl() {
let anewopens=md5(newopens+newtimestamp);
return `${getUrl()}/api/resumes/logo.json${isDev ? `?debug=${window._debugType || 'admin'}&randomcode=${newtimestamp}&client_key=${anewopens}` : `?randomcode=${newtimestamp}&client_key=${anewopens}`}`;
}
export function getUploadActionUrltwo(id) {
// Railsgettimes()
let anewopens=md5(newopens+newtimestamp);
return `${getUrlmys()}/api/shixuns/${id}/upload_data_sets.json${isDev ? `?debug=${window._debugType || 'admin'}&randomcode=${newtimestamp}&client_key=${anewopens}` : `?randomcode=${newtimestamp}&client_key=${anewopens}`}`
}
export function getUploadActionUrlthree() {
// Railsgettimes()
let anewopens=md5(newopens+newtimestamp);
return `${getUrlmys()}/api/jupyters/import_with_tpm.json${isDev ? `?debug=${window._debugType || 'admin'}&randomcode=${newtimestamp}&client_key=${anewopens}` : `?randomcode=${newtimestamp}&client_key=${anewopens}`}`
}
export function getupload_git_file(id) {
let anewopens=md5(newopens+newtimestamp);
return `${getUrlmys()}/api/shixuns/${id}/upload_git_file.json${isDev ? `?debug=${window._debugType || 'admin'}&randomcode=${newtimestamp}&client_key=${anewopens}` : `?randomcode=${newtimestamp}&client_key=${anewopens}`}`
}
export function getUploadActionUrlOfAuth(id) {
// Railsgettimes()
let anewopens=md5(newopens+newtimestamp);
return `${getUrl()}/api/users/accounts/${id}/auth_attachment.json${isDev ? `?debug=${window._debugType || 'admin'}&randomcode=${newtimestamp}&client_key=${anewopens}` : `?randomcode=${newtimestamp}&client_key=${anewopens}`}`
}
export function getRandomNumber(type) {
// Railsgettimes()
let anewopens=md5(newopens+newtimestamp);
return type===true?`randomcode=${newtimestamp}&client_key=${anewopens}`:`?randomcode=${newtimestamp}&client_key=${anewopens}`
}
@ -149,7 +205,7 @@ export function getTaskUrlById(id) {
}
export function getRandomcode(url) {
// Railsgettimes()
Railsgettimes()
let anewopens=md5(newopens+newtimestamp);
if (url.indexOf('?') == -1) {

View File

@ -1,52 +1,11 @@
import React, { Component } from 'react';
import { getUrl2, isDev } from 'educoder'
const $ = window.$
let _url_origin = getUrl2()
// let _url_origin = `http://47.96.87.25:48080`;
function save_avatar(){
// if($(img_lg).html().trim() == ""){
// $("#avatar-name").html("请先选择图片上传").css("color", 'red');
// } else {
// $("#avatar-name").html("").css("color", '#333');
const previewId = this.props.previewId
var img_lg = document.getElementById(previewId || 'img-preview');
// 截图小的显示框内的内容
window.html2canvas(img_lg).then(function(canvas) {
// for test
// document.getElementById('canvasWrap').appendChild(canvas);
var dataUrl = canvas.toDataURL("image/jpeg");
console.log(dataUrl)
// TODO upload base64 image data to server
});
return
// 老版接口:
// html2canvas(img_lg, {
// allowTaint: true,
// taintTest: false,
// onrendered: function(canvas) {
// canvas.id = "mycanvas";
// //生成base64图片数据
// var dataUrl = canvas.toDataURL("image/jpeg");
// console.log(dataUrl)
// var newImg = document.getElementById("showImg");
// newImg.src = dataUrl;
// return;
// imagesAjax(dataUrl);
// $(".avatar-save").attr("disabled","true");
// }
// });
// }
}
/**
props 说明
imageId 源图片标签的id
@ -54,64 +13,50 @@ function save_avatar(){
imageSrc 源图片src
width 数字格式
height 数字格式
*/
*/
class Cropper extends Component {
state = {
};
handleChange = (info) => {
}
componentDidMount() {
this.options = {
aspectRatio: 1,
crop(event) {
// console.log(event.detail.x);
// console.log(event.detail.y);
// console.log(event.detail.width);
// console.log(event.detail.height);
// console.log(event.detail.rotate);
// console.log(event.detail.scaleX);
// console.log(event.detail.scaleY);
},
preview: this.props.previewId ? `#${this.props.previewId}` : '.img-preview',
}
this.options = {
aspectRatio: 1,
preview: this.props.previewId ? `#${this.props.previewId}` : '.img-preview',
}
if (!window.Cropper) {
$.ajaxSetup({
cache: true
});
const _isDev = isDev()
let _path = _isDev ? 'public' : 'build'
$('head').append($('<link rel="stylesheet" type="text/css" />')
.attr('href', `${_url_origin}/react/${_path}/js/cropper/cropper.min.css`));
$.getScript(
`${_url_origin}/react/${_path}/js/cropper/cropper.js`,
(data, textStatus, jqxhr) => {
if (!window.Cropper) {
$.ajaxSetup({
cache: true
});
const _isDev = isDev()
let _path = _isDev ? 'public' : 'build'
$.getScript(
`${_url_origin}/react/${_path}/js/cropper/html2canvas.min.js`,
(data, textStatus, jqxhr) => {
$('head').append($('<link rel="stylesheet" type="text/css" />')
.attr('href', `${_url_origin}/react/${_path}/js/cropper/cropper.min.css`));
$.getScript(
`${_url_origin}/react/${_path}/js/cropper/cropper.js`,
(data, textStatus, jqxhr) => {
});
$.getScript(
`${_url_origin}/react/${_path}/js/cropper/html2canvas.min.js`,
(data, textStatus, jqxhr) => {
});
}
}
setTimeout(() => {
const image = document.getElementById(this.props.imageId || '__image');
this.cropper = new window.Cropper(image, this.options);
}, 1200)
setTimeout(() => {
const image = document.getElementById(this.props.imageId || '__image');
this.cropper = new window.Cropper(image, this.options);
}, 1200)
}
renew = (image) => {
this.cropper && this.cropper.destroy();
this.cropper = new window.Cropper(image, this.options);
}
render() {
const { width, height, previewId, imageSrc } = this.props;
return (
@ -119,8 +64,8 @@ class Cropper extends Component {
{/* This rule is very important, please do not ignore this! */}
<style>{`
.wrapper {
width: ${ width ? (width+'px') : '500px'};
height: ${ height ? (height+'px') : '500px'};
width: ${ width ? (width + 'px') : '500px'};
height: ${ height ? (height + 'px') : '500px'};
border: 1px solid #eee;
}
img {
@ -134,155 +79,13 @@ class Cropper extends Component {
}
`}</style>
<div className="wrapper">
{/* http://localhost:3007/images/footNavLogo.png 图片转了后不对
|| "/images/testPicture.jpg"
|| "/images/shixun0.jpg"
*/}
<img id={this.props.imageId || "__image"} src={`${imageSrc }`}></img>
<img id={this.props.imageId || "__image"} src={`${imageSrc}`}></img>
</div>
{/* background: 'aquamarine',
'border-radius': '128px'
*/}
{!previewId && <div id="img-preview" className="img-preview preview-lg" style={{width: '128px', height: '128px', }}>
{!previewId && <div id="img-preview" className="img-preview preview-lg" style={{ width: '128px', height: '128px', }}>
</div>}
{/* <img id="showImg" src="http://localhost:3007/images/testPicture.jpg"></img> */}
{/* <div id="canvasWrap"></div> */}
{/* <button onClick={save_avatar.bind(this)}>save </button> */}
</div>
);
}
}
export default Cropper;
// function aaa () {
// function showedit_headphoto() {
// var html = `
// <script src=\"../head/jquery.min.js\"><\/script>\n
// <link href=\"../head/cropper.min.css\" rel=\"stylesheet\">\n
// <link href=\"../head/sitelogo.css\" rel=\"stylesheet\">\n
// <script src=\"../head/bootstrap.min.js\"><\/script>\n
// <script src=\"../head/cropper.js\"><\/script>\n
// <script src=\"../head/sitelogo.js\"><\/script>\n
// <script src=\"../head/html2canvas.min.js\" type=\"text/javascript\" charset=\"utf-8\"><\/script>\n\n
// <div class=\"task-popup\" style=\"width: 550px;\">\n <div class=\"task-popup-title clearfix task-popup-bggrey\">上传头像<\/div>\n <div class=\"clearfix\">\n
// <div class=\"modal fade\" style=\"outline: none;\" id=\"avatar-modal\" aria-hidden=\"true\" aria-labelledby=\"avatar-modal-label\" role=\"dialog\" tabindex=\"-1\">\n
// <div class=\"modal-dialog modal-lg\">\n <div class=\"modal-content\">\n <form class=\"avatar-form\">\n <div class=\"modal-body\">\n
// <div class=\"padding20\">\n <div class=\"avatar-upload\">\n <input class=\"avatar-src\" name=\"avatar_src\" type=\"hidden\">\n
// <input class=\"avatar-data\" name=\"avatar_data\" type=\"hidden\">\n\n <span id=\"avatar-name\"><\/span>\n
// <input class=\"avatar-input\" style=\"display:none;\" id=\"avatarInput\" value=\"avatars/User/116\" name=\"avatar_file\" type=\"file\">\n
// <input type=\"hidden\" id=\"source_id\" value=\"116\"/>\n <input type=\"hidden\" id=\"source_type\" value=\"User\"/>\n <\/div>\n
// <div class=\"row clearfix mt20 pl20\">\n <div class=\"task-form-45 fl panel-box-sizing uplaodImg\">\n
// <div class=\"avatar-wrapper\" id=\"wrapper_image_show\">\n <!--<span style=\"display: block;\">\n 选择你要上传的图片<br/>
// \n 仅支持JPG、GIF、PNG且文件小于2M\n <\/span>-->\n <\/div>\n
// <div class=\"row avatar-btns clearfix\">\n <a href=\"javascript:void(0);\" class=\"fl\" type=\"button\" onClick=\"$(\'input[id=avatarInput]\').click();\">重新上传<\/a>\n
// <!--<div class=\"btn-group\">\n <a href=\"javascript:void(0);\" class=\"fa fa-repeat fr mt5 color-grey-9\" data-method=\"rotate\" data-option=\"90\"
// type=\"button\" title=\"Rotate 90 degrees\">\n <\/a>\n <\/div>-->\n <\/div>\n <\/div>\n
// <div class=\"task-form-50 panel-box-sizing fr color-grey pr20\" style=\"width: 128px;\">\n <div class=\"edu-txt-center\">\n
// <div class=\"avatar-preview preview-lg radius\" id=\"imageHead\">\n
// <img alt=\"头像\" height=\"128\" nhname=\"avatar_image\" src=\"/images/avatars/User/116?1556802838\" width=\"128\" />\n <\/div>\n
// <span>头像预览<\/span>\n <\/div>\n
// <p class=\"color-grey-9 font-12 mt110 justify\">仅支持JPG、GIF、PNG且文件小于2M<\/p>\n <\/div>\n <\/div>\n
// <\/div>\n <div class=\"clearfix edu-txt-center mb20 mt10\">\n
// <a href=\"javascript:void(0);\" class=\"task-btn mr20\" onclick=\"hideModal()\">取消<\/a>\n
// <a href=\"javascript:void(0);\" class=\"avatar-save task-btn task-btn-orange\" data-dismiss=\"modal\">确定<\/a>\n
// <\/div>\n <\/div>\n <\/form>\n <\/div>\n <\/div>\n <\/div>\n <\/div>\n<\/div>\n\n<script>\n
// $(function () {\n new CropAvatar($(\'#crop-avatar\'), 1/1);\n\n //---------------------------头像上传-----------------------------//\n //做个下简易的验证 大小 格式\n $(\'#avatarInput\').on(\'change\', function(e) {\n var filemaxsize = 1024 * 5;//5M\n var target = $(e.target);\n var Size = target[0].files[0].size / 1024;\n if(Size > filemaxsize) {\n alert(\'图片过大,请重新选择!\');\n $(\".avatar-wrapper\").children().remove;\n return false;\n }\n if(!this.files[0].type.match(/image.*/)) {\n alert(\'请选择正确的图片!\')\n } else {\n /*var filename = document.querySelector(\"#avatar-name\");*/\n var texts = document.querySelector(\"#avatarInput\").value;\n var teststr = texts; //你这里的路径写错了\n testend = teststr.match(/[^\\\\]+\\.[^\\(]+/i); //直接完整文件名的\n /*filename.innerHTML = testend;\n $(filename).css(\"color\", \'#333\');*/\n $(\".avatar-save\").removeClass(\"task-btn-grey\").addClass(\"task-btn-orange\");\n $(\".avatar-save\").on(\"click\", save_avatar);\n }\n\n });\n });\n\n function save_avatar(){\n var img_lg = document.getElementById(\'imageHead\');\n if($(img_lg).html().trim() == \"\"){\n $(\"#avatar-name\").html(\"请先选择图片上传\").css(\"color\", \'red\');\n } else {\n $(\"#avatar-name\").html(\"\").css(\"color\", \'#333\');\n // 截图小的显示框内的内容\n html2canvas(img_lg, {\n allowTaint: true,\n taintTest: false,\n onrendered: function(canvas) {\n canvas.id = \"mycanvas\";\n //生成base64图片数据\n var dataUrl = canvas.toDataURL(\"image/jpeg\");\n var newImg = document.createElement(\"img\");\n newImg.src = dataUrl;\n imagesAjax(dataUrl);\n $(\".avatar-save\").attr(\"disabled\",\"true\");\n }\n });\n }\n }\n\n function imagesAjax(src) {\n var data = {};\n data.img = src;\n data.source_id = $(\'#source_id\').val();\n data.source_type = $(\'#source_type\').val();\n data.is_direct = 0;\n $.ajax({\n url: \"/upload_avatar\",\n beforeSend: function(xhr) {xhr.setRequestHeader(\'X-CSRF-Token\', $(\'meta[name=\"csrf-token\"]\').attr(\'content\'))},\n data: data,\n type: \"POST\",\n success: function (re) {\n console.log(re);\n console.log(1562050370);\n if(re){\n var o = JSON.parse(re);\n if (o.status !=0 ){\n console.log(o.message);\n } else {\n var imgSpan = $(\"img[nhname=\'avatar_image\']\");\n imgSpan.attr({\"src\": o.url + \'?1562050370\'});\n $(\"#user_code\").html(o.grade);\n notice_box_redirect(\"/users/shitou\", \"上传成功\");\n }\n } else {\n notice_box(\"上传出错\");\n }\n\n },\n error: function (e) {\n alert(e);\n }\n });\n }\n
// <\/script>`;
// pop_box_new(html, 550, 510);
// $("#imageHead img").attr({"src": $("#user_avatar_show").attr("src")});
// $("#wrapper_image_show img").attr({"src": $("#user_avatar_show").attr("src")});
// }
// $(function () {
// new CropAvatar($('#crop-avatar'), 1/1);
// //---------------------------头像上传-----------------------------//
// //做个下简易的验证 大小 格式
// $('#avatarInput').on('change', function(e) {
// var filemaxsize = 1024 * 5;//5M
// var target = $(e.target);
// var Size = target[0].files[0].size / 1024;
// if(Size > filemaxsize) {
// alert('图片过大,请重新选择!');
// $(".avatar-wrapper").children().remove;
// return false;
// }
// if(!this.files[0].type.match(/image.*/)) {
// alert('请选择正确的图片!')
// } else {
// /*var filename = document.querySelector("#avatar-name");*/
// var texts = document.querySelector("#avatarInput").value;
// var teststr = texts; //你这里的路径写错了
// testend = teststr.match(/[^\\\\]+\\.[^\\(]+/i); //直接完整文件名的
// /*filename.innerHTML = testend; $(filename).css("color", '#333');*/
// $(".avatar-save").removeClass("task-btn-grey").addClass("task-btn-orange");
// $(".avatar-save").on("click", save_avatar);
// }
// });
// });
// function save_avatar(){
// var img_lg = document.getElementById('imageHead');
// if($(img_lg).html().trim() == ""){
// $("#avatar-name").html("请先选择图片上传").css("color", 'red');
// } else {
// $("#avatar-name").html("").css("color", '#333');
// // 截图小的显示框内的内容
// html2canvas(img_lg, {
// allowTaint: true,
// taintTest: false,
// onrendered: function(canvas) {
// canvas.id = "mycanvas";
// //生成base64图片数据
// var dataUrl = canvas.toDataURL("image/jpeg");
// var newImg = document.createElement("img");
// newImg.src = dataUrl;
// imagesAjax(dataUrl);
// $(".avatar-save").attr("disabled","true");
// }
// });
// }
// }
// function imagesAjax(src) {
// var data = {};
// data.img = src;
// data.source_id = $('#source_id').val();
// data.source_type = $('#source_type').val();
// data.is_direct = 0;
// $.ajax({
// url: "/upload_avatar",
// beforeSend: function(xhr) {
// xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'))
// },
// data: data,
// type: "POST",
// success: function (re) {
// console.log(re);
// // console.log(1562050370);
// if(re){
// var o = JSON.parse(re);
// if (o.status !=0 ){
// console.log(o.message);
// } else {
// var imgSpan = $("img[nhname='avatar_image']");
// imgSpan.attr({"src": o.url + '?1562050370'});
// $("#user_code").html(o.grade);
// notice_box_redirect("/users/shitou", "上传成功");
// }
// } else {
// notice_box("上传出错");
// }
// },
// error: function (e) {
// alert(e);
// }
// });
// }
// }
export default Cropper;

View File

@ -1,116 +0,0 @@
import React, { Component } from 'react';
const $ = window.jQuery
const jQuery = $;
// if () {
// !$.drag
// (function($){
// $.fn.dragValidator = function(options){
// var x, drag = this, isMove = false, defaults = {
// };
// var options = $.extend(defaults, options);
// //添加背景,文字,滑块
// var html = '<div class="drag_bg"></div>'+
// '<div class="drag_text" onselectstart="return false;" unselectable="on">拖动滑块验证</div>'+
// '<div class="handler handler_bg"></div>';
// this.append(html);
//
// var handler = drag.find('.handler');
// var drag_bg = drag.find('.drag_bg');
// var text = drag.find('.drag_text');
// var maxWidth = text.width() - handler.width(); //能滑动的最大间距
// //鼠标按下时候的x轴的位置
// handler.mousedown(function(e){
// isMove = true;
// x = e.pageX - parseInt(handler.css('left'), 10);
// });
//
// //鼠标指针在上下文移动时移动距离大于0小于最大间距滑块x轴位置等于鼠标移动距离
// $(document).mousemove(function(e){
// var _x = e.pageX - x;
// var handler_offset = handler.offset();
// var lastX = e.clientX -x;
// lastX = Math.max(0,Math.min(maxWidth,lastX));
// if(isMove){
// if(_x > 0 && _x <= maxWidth){
// handler.css({'left': lastX});
// drag_bg.css({'width': lastX});
// }
// else if(lastX > maxWidth - 5 && lastX < maxWidth + 5 ){ //鼠标指针移动距离达到最大时清空事件
// dragOk();
//
// }
// }
// });
// handler.mouseup(function(e){
// isMove = false;
// var _x = e.pageX - x;
// if(text.text() != '验证通过' && _x < maxWidth){ //鼠标松开时,如果没有达到最大距离位置,滑块就返回初始位置
// handler.animate({'left': 0});
// drag_bg.animate({'width': 0});
// }
// });
//
// //清空事件
// function dragOk(){
// options.dragOkCallback && options.dragOkCallback()
// var kuaiwidth=drag.width() - handler.width() - 2;
// handler.removeClass('handler_bg').addClass('handler_ok_bg');
// handler.css({'left':kuaiwidth+'px'})
// text.css({'width':kuaiwidth+'px'});
// text.text('验证通过');
// drag.css({'color': '#fff'});
// drag_bg.css({'width':kuaiwidth+'px'})
// handler.unbind('mousedown');
// $(document).unbind('mousemove');
// $(document).unbind('mouseup');
// $("#user_verification_notice").html("");
// $('#user_verification_notice').parent().hide();
// }
// };
// })(jQuery);
// }
class DragValidator extends Component {
componentDidMount () {
// if($("#reg-drag").length>0 && IsPC()){
// $("#reg-drag").dragValidator({
// height: this.props.height,
// dragOkCallback: () => {
// this.props.dragOkCallback && this.props.dragOkCallback()
// }
// });
// }else{
// $("#reg-drag").empty();
// }
}
empty() {
// $("#reg-drag").empty();
}
render() {
const height = this.props.height || 45;
const className = this.props.className
const successGreenColor = this.props.successGreenColor || '#29bd8b'
// newMain clearfix
return (
<div id="reg-drag" style={{ width:"287px",}} className={`drag_slider ${className}`}>
<style>{`
.drag_slider .handler {
height: 100%;
}
.drag_slider {
height: ${height}px;
line-height: ${height}px;
}
.drag_slider .drag_bg {
height: ${height}px;
background-color: ${successGreenColor};
}
`}</style>
</div>
);
}
}
export default ( DragValidator );

View File

@ -6,23 +6,23 @@ class LinkAfterLogin extends Component {
constructor(props) {
super(props);
}
checkAuth = () => {
if (this.props.checkIfLogin()) {
if(this.props.checkProfileComplete){
if(this.props.checkIfProfileCompleted()){
this.props.history.push(this.props.to)
}else{
this.props.showProfileCompleteDialog();
}
}else{
this.props.history.push(this.props.to)
}
} else {
this.props.showLoginDialog()
}
}
checkAuth = () => {
if (this.props.checkIfLogin()) {
if (this.props.checkProfileComplete) {
if (this.props.checkIfProfileCompleted()) {
this.props.history.push(this.props.to)
} else {
this.props.showProfileCompleteDialog();
}
} else {
this.props.history.push(this.props.to)
}
} else {
this.props.showLoginDialog()
}
}
render() {
return(
return (
<a {...this.props} onClick={this.checkAuth}>{this.props.children}</a>
)
}

View File

@ -1,7 +1,7 @@
/*
* @Description: 评论表单
* @Author: tangjiang
* @Github:
* @Github:
* @Date: 2019-12-17 17:32:55
* @LastEditors : tangjiang
* @LastEditTime : 2020-01-06 18:42:09
@ -10,15 +10,13 @@ import './index.scss';
import React, { useState } from 'react';
import { Form, Button, Input } from 'antd';
import QuillForEditor from '../../quillForEditor';
// import { QuillDeltaToHtmlConverter } from 'quill-delta-to-html'
// import {formatDelta} from './util';
const FormItem = Form.Item;
function CommentForm (props) {
function CommentForm(props) {
const {
onCancel,
onSubmit,
onSubmit,
form,
type
} = props;
@ -28,9 +26,6 @@ function CommentForm (props) {
const [focus, setFocus] = useState(false);
const options = [
// ['bold', 'italic', 'underline'],
// [{header: [1,2,3,false]}],
'code-block',
'link',
'image',
'formula'
@ -47,20 +42,30 @@ function CommentForm (props) {
setShowQuill(false);
setCtx('');
props.form.resetFields();
onCancel && onCancel();
onCancel && onCancel();
}
// 编辑器内容变化时
const handleContentChange = (content) => {
console.log('编辑器内容', content);
setCtx(content);
try {
// const _html = new QuillDeltaToHtmlConverter(content.ops, {}).convert();
// props.form.setFieldsValue({'comment': _html.replace(/<\/?[^>]*>/g, '')});
props.form.setFieldsValue({'comment': content});
} catch (error) {
console.log(error);
const handleContentChange=(quill,html,mydata)=>{
const reg = /^[\s\S]*.*[^\s][\s\S]*$/;
if (!reg.test(html)) {
setCtx(html);
try {
// const _html = new QuillDeltaToHtmlConverter(content.ops, {}).convert();
props.form.setFieldsValue({ 'comment': html });
} catch (error) {
console.log(error);
}
}else{
setCtx(html);
try {
// const _html = new QuillDeltaToHtmlConverter(content.ops, {}).convert();
props.form.setFieldsValue({ 'comment': html });
} catch (error) {
console.log(error);
}
}
}
// 发送
const handleSubmit = (e) => {
@ -69,7 +74,7 @@ function CommentForm (props) {
if (!err) {
setShowQuill(false);
const content = ctx;
props.form.setFieldsValue({'comment': ''});
props.form.setFieldsValue({ 'comment': '' });
setCtx('');
// const _html = formatDelta(content.ops);
// console.log('保存的内容=====》》》》', content);
@ -95,10 +100,10 @@ function CommentForm (props) {
{
getFieldDecorator('comment', {
rules: [
{ required: true, message: '评论内容不能为空'}
{ required: true, message: '评论内容不能为空' }
],
})(
<Input
<Input
onClick={() => handleInputClick(type)}
placeholder="说点儿什么~"
className={showQuill ? '' : 'show_input'}
@ -110,13 +115,13 @@ function CommentForm (props) {
/>
)
}
<QuillForEditor
imgAttrs={{width: '60px', height: '30px'}}
imgAttrs={{ width: '60px', height: '30px' }}
wrapStyle={{
height: showQuill ? 'auto' : '0px',
opacity: showQuill ? 1 : 0,
overflow: showQuill ? 'none' : 'hidden',
overflow: showQuill ? 'none' : 'none',
transition: 'all 0.3s'
}}
autoFocus={focus}
@ -130,7 +135,7 @@ function CommentForm (props) {
</FormItem>
<FormItem style={{ textAlign: 'right', display: showQuill ? 'block' : 'none' }}>
<Button onClick={handleCancle}>取消</Button>
<Button onClick={handleSubmit} type="primary" style={{ marginLeft: '10px'}}>发送</Button>
<Button onClick={handleSubmit} type="primary" style={{ marginLeft: '10px' }}>发送</Button>
</FormItem>
</Form>
);

View File

@ -1,24 +1,21 @@
/*
* @Description: 评论单列
* @Author: tangjiang
* @Github:
* @Github:
* @Date: 2019-12-17 17:35:17
* @LastEditors : tangjiang
* @LastEditTime : 2019-12-27 11:05:17
*/
import './index.scss';
import 'quill/dist/quill.core.css'; // 核心样式
import 'quill/dist/quill.snow.css'; // 有工具栏
import 'quill/dist/quill.bubble.css'; // 无工具栏
import 'katex/dist/katex.min.css'; // katex 表达式样式
import React, { useState } from 'react';
import CommentIcon from './CommentIcon';
import { getImageUrl, CNotificationHOC } from 'educoder'
import { Icon } from 'antd';
import CommentForm from './CommentForm';
import QuillForEditor from '../../quillForEditor';
import {markdownToHTML} from 'educoder'
// import QuillForEditor from '../../quillForEditor';
function CommentItem ({
function CommentItem({
isAdmin,
options,
confirm,
@ -39,7 +36,7 @@ function CommentItem ({
// 上传图片的ulr
const [url, setUrl] = useState('');
const {
const {
author = {}, // 作者
id, // 评论id
content, // 回复内容
@ -57,22 +54,21 @@ function CommentItem ({
confirm({
title: '提示',
content: ('确定要删除该条回复吗?'),
onOk () {
console.log('点击了删除', id);
onOk() {
submitDeleteComment && submitDeleteComment(id);
}
});
}
// 评论头像
const commentAvatar = (author) => (
<img
className="item-flex flex-image"
const commentAvatar = (author) => (
<img
className="item-flex flex-image"
src={author.image_url ? getImageUrl(`images/${author.image_url}`) : 'https://b-ssl.duitang.com/uploads/item/201511/13/20151113110434_kyReJ.jpeg'}
alt=""
/>
);
// 评论信息
const commentInfo = (id, author, time, can_delete) => {
const _classNames = can_delete ? 'item-close' : 'item-close hide';
@ -84,11 +80,10 @@ function CommentItem ({
<span className="iconfont icon-shanchu icon_font_size_14" onClick={() => deleteComment(id)}></span>
</span>
</div>
);
);
};
const handleShowUploadImage = (url) => {
// console.log('==============>>>>>>>>>>>>',url);
setUrl(url);
}
// 评论内容
@ -99,13 +94,15 @@ function CommentItem ({
} catch (e) {
_ctx = ctx;
}
// <QuillForEditor
// readOnly={true}
// value={_ctx}
// showUploadImage={handleShowUploadImage}
// />
return (
<QuillForEditor
readOnly={true}
value={_ctx}
showUploadImage={handleShowUploadImage}
/>
)};
<div className={"mt15 ml15"} style={{wordBreak: "break-word",fontWeight:"bold"}} dangerouslySetInnerHTML={{__html: markdownToHTML(_ctx).replace(/▁/g, "▁▁▁")}}></div>
)
};
// 加载更多
const handleOnLoadMore = (len) => {
@ -154,7 +151,7 @@ function CommentItem ({
<li className={_moreClass} onClick={() => handleOnLoadMore(len)}>
<p className="loadmore-txt">展开其余{lastTxt}条评论</p>
<p className="loadmore-icon">
<Icon type={!arrow ? 'down' : 'up'}/>
<Icon type={!arrow ? 'down' : 'up'} />
</p>
</li>
</ul>
@ -169,7 +166,7 @@ function CommentItem ({
const handleClickLick = (id) => {
likeComment && likeComment(id);
}
// 点击评论icon
const handleClickMessage = () => {
setShowQuill(true);
@ -198,33 +195,33 @@ function CommentItem ({
<div className="item-flex item-desc">
{commentInfo(id, author, time, can_delete)}
{commentCtx(content)}
{commentAppend(children)}
<div className="comment_icon_area">
<CommentIcon
style={{ display: isAdmin ? 'inline-block' : 'none'}}
className='comment-icon-margin'
type={!hidden ? "xianshi" : 'yincang1'}
style={{ display: isAdmin ? 'inline-block' : 'none' }}
className='comment-icon-margin'
type={!hidden ? "xianshi" : 'yincang1'}
iconClick={() => handleShowOrHide(id, !hidden ? 1 : 0)}
/>
<CommentIcon
style={{ display: can_delete ? 'inline-block' : 'none'}}
className='comment-icon-margin'
type={'shanchu'}
style={{ display: can_delete ? 'inline-block' : 'none' }}
className='comment-icon-margin'
type={'shanchu'}
iconClick={() => deleteComment(id)}
/>
{/* 回复 */}
<CommentIcon
className='comment-icon-margin'
<CommentIcon
className='comment-icon-margin'
type="huifu1"
count={children.length}
count={children.length}
iconClick={handleClickMessage}
/>
{/* 点赞 */}
<CommentIcon
iconColor={ user_praise ? '#5091FF' : '' }
<CommentIcon
iconColor={user_praise ? '#5091FF' : ''}
className='comment-icon-margin'
theme={user_praise ? 'filled' : ''}
type="dianzan"
@ -234,7 +231,7 @@ function CommentItem ({
</div>
<div
style={{ display: showQuill ? 'block' : 'none'}}
style={{ display: showQuill ? 'block' : 'none' }}
className="comment_item_quill">
<CommentForm
onCancel={handleClickCancel}
@ -242,11 +239,10 @@ function CommentItem ({
/>
</div>
{/* 显示上传的图片信息 */}
<div className="show_upload_image" style={{ display: url ? 'block' : 'none'}}>
<Icon type="close" className="image_close" onClick={handleClose}/>
<div className="show_upload_image" style={{ display: url ? 'block' : 'none' }}>
<Icon type="close" className="image_close" onClick={handleClose} />
<div className="image_info">
<img className="image" src={url} alt=""/>
<img className="image" src={url} alt="" />
</div>
</div>
</div>
@ -254,4 +250,4 @@ function CommentItem ({
);
}
export default CNotificationHOC() (CommentItem);
export default CNotificationHOC()(CommentItem);

View File

@ -7,39 +7,28 @@
* @LastEditTime : 2019-12-24 18:03:21
*/
import React from 'react';
// import CommentForm from './CommentForm';
import CommentList from './CommentList';
function Comment (props) {
function Comment(props) {
const {
const {
commentLists,
// addComment,
// cancelComment,
isAdmin,
addChildComment,
likeComment,
showOrHideComment,
submitDeleteComment
} = props;
// const handleCancelComment = () => {
// cancelComment && cancelComment();
// };
return (
<React.Fragment>
{/* <CommentForm
onCancel={handleCancelComment}
onSubmit={addComment}
/> */}
<CommentList
isAdmin={isAdmin}
likeComment={likeComment}
showOrHideComment={showOrHideComment}
commentLists={commentLists}
submitChildComment={addChildComment}
submitDeleteComment={submitDeleteComment}
/>
</React.Fragment>
<CommentList
isAdmin={isAdmin}
likeComment={likeComment}
showOrHideComment={showOrHideComment}
commentLists={commentLists}
submitChildComment={addChildComment}
submitDeleteComment={submitDeleteComment}
/>
);
}

View File

@ -1,7 +1,7 @@
/*
* @Description: quill delta -> html
* @Author: tangjiang
* @Github:
* @Github:
* @Date: 2019-12-24 08:51:25
* @LastEditors : tangjiang
* @LastEditTime : 2019-12-26 09:30:11
@ -55,7 +55,7 @@ export const formatDelta = (deltas) => {
*/
export const operate = (text, key, value) => {
let operatedText = null;
debugger;
switch (key) {
case 'bold':
operatedText = `<strong>${text}</strong>`;
@ -72,7 +72,7 @@ export const operate = (text, key, value) => {
case 'link':
operatedText = `<a href="${value}" style="color: #5091ff; text-decoration: underline;" target="bland">${text}</a>`;
break;
default:
default:
operatedText = text;
}

View File

@ -0,0 +1,64 @@
import React, { useMemo, useState, useEffect } from 'react'
import TPMMDEditor from '../../../modules/tpm/challengesnew/tpm-md-editor'
import { markdownToHTML } from 'educoder'
import './index.scss'
function noop() { }
export const defaultQuillOpt = [
'bold', 'italic', 'underline',
{ list: 'ordered' }, { list: 'bullet' },
{ script: 'sub' }, { script: 'super' },
{ 'color': [] },
{ 'background': [] },
'image', 'code-block', 'formula', 'clean'
]
export default ({ is_md, value, onChange, placeholder, autoFocus = true, isError, isShowEditor, height = 160, options = defaultQuillOpt, index, onActiveOption = noop, md_id, showResizeBar = false }) => {
let html = useMemo(() => {
if (value) {
return is_md ? markdownToHTML(value) : value
}
return placeholder
}, [is_md, placeholder, value])
const [isFocus, setIsFocus] = useState(false)
useEffect(() => {
if (isShowEditor) {
setIsFocus(autoFocus)
} else {
setIsFocus(false)
}
}, [autoFocus, isShowEditor])
function onMdContentChangeHandler(v) {
onChange(v, index)
}
function onActiveHandler(e) {
e.preventDefault()
e.stopPropagation()
onActiveOption(index)
}
return (
<div className='editor-content-panel-wrapper'>
<div className={`editor-content-panel markdown-body ${isShowEditor ? 'hide' : null} ${isError ? 'error' : null} ${value ? 'hasValue' : null} `}
dangerouslySetInnerHTML={{ __html: html }} onClick={onActiveHandler} />
{is_md ?
<TPMMDEditor
initValue={value}
height={height}
mdID={md_id}
noStorage={true}
className={`${isShowEditor ? null : 'hideMd'} ${isError ? 'md-error' : null} `}
onChange={onMdContentChangeHandler}
showResizeBar={showResizeBar}
placeholder={placeholder}
/> : null
}
</div>
)
}

View File

@ -0,0 +1,46 @@
.editor-content-panel-wrapper {
margin-bottom: 12px;
.editor-content-panel {
display: flex;
align-items: center;
word-break: break-all;
border-radius: 2px;
max-width: 1056px;
text-align: justify;
height: auto;
min-height: 38px;
border: 1px solid rgba(234, 234, 234, 1);
padding: 4px;
width: 100%;
p {
width: 100%;
}
}
.hide {
display: none;
}
.hasValue {
color: rgb(153, 153, 153);
}
}
.md-error {
.edu-back-greyf5 {
border: 1px solid red;
}
}
.hideMd {
display: none;
}
.error {
border: 1px solid red;
}

View File

@ -524,8 +524,8 @@ const options = [{
value: '天水',
label: '天水'
},{
value: '武都',
label: '武都'
value: '陇南',
label: '陇南'
},{
value: '武威',
label: '武威'
@ -1746,7 +1746,6 @@ class City extends Component{
}
}
onChange = (r1, r2) => {
// debugger
this.props.onChange(r1, r2)
this.setState({ value: r1 })
}

View File

@ -1,12 +0,0 @@
.hideMd {
display: none !important;
}
.content_editorMd_show {
height: auto;
min-height: 38px;
width: 800px;
border: 1px solid rgba(234,234,234,1);
margin-top: 2px;
padding: 4px;
width: 100%;
}

View File

@ -1,83 +0,0 @@
import React,{ Component } from "react";
import TPMMDEditor from '../../../modules/tpm/challengesnew/TPMMDEditor'
import {markdownToHTML} from 'educoder'
import './DMDEditor.css'
// 需要父组件通过toShowMode、toMDMode 来控制一次只能打开一个DMDEditor
class DMDEditor extends Component{
constructor(props){
super(props);
this.mdRef = React.createRef()
this.state={
mdMode: false,
// value: this.props.initValue
}
}
componentDidUpdate(prevProps, prevState) {
}
componentDidMount() {
// if(this.props.initValue != this.mdRef.current.getValue()) {
// this.mdRef.current.setValue(this.props.initValue)
// }
}
toMDMode = () => {
this.setState({mdMode: true}, () => {
this.mdRef.current.resize()
this.mdRef.current.setValue(this.props.initValue)
})
this.props.toMDMode(this)
}
toShowMode = () => {
this.setState({mdMode: false})
this.props.toShowMode && this.props.toShowMode(this)
}
onCMBlur = () => {
this.toShowMode()
}
onChange = (val) => {
// this.setState({ value: val })
this.props.onChange(val)
if (this.state.showError == true) {
this.setState({showError: false})
}
}
showError = () => {
this.mdRef.current.showError()
this.setState({showError: true})
}
render(){
const { mdMode, showError } = this.state;
const { initValue } = this.props;
let _style = {}
if (showError) {
_style.border = '1px solid red'
}
_style = Object.assign(_style, {display: mdMode == true ? 'none' : '', color: initValue? '': '#999', alignItems: 'center', wordBreak: 'break-all'})
return(
<React.Fragment>
<style>{`
`}</style>
<div id="content_editorMd_show" className="new_li content_editorMd_show markdown-body"
style={_style}
dangerouslySetInnerHTML={{__html: initValue ? markdownToHTML(initValue):this.props.placeholder}}
onClick={this.toMDMode}
>
</div>
{/*
onCMBlur={this.onCMBlur} */}
<TPMMDEditor
ref={this.mdRef}
{...this.props}
initValue={initValue}
className={`${this.props.className} ${mdMode == true ? '' : 'hideMd'}`}
onChange={this.onChange}
></TPMMDEditor>
</React.Fragment>
)
}
}
export default DMDEditor;

View File

@ -8,12 +8,12 @@ let _path = isDev() ? 'public' : 'build'
let uploader
let _testHost = '' ; '192.168.2.63:3001/api'
let _testHost = ''; '192.168.2.63:3001/api'
const login = 'innov'
function createUploader () {
function createUploader() {
uploader = new window.AliyunUpload.Vod({
timeout: $('#timeout').val() || 60000,
partSize: $('#partSize').val() || 1048576,
@ -35,12 +35,12 @@ function createUploader () {
},
// 开始上传
onUploadstarted: function (uploadInfo) {
// 如果是 UploadAuth 上传方式, 需要调用 uploader.setUploadAuthAndAddress 方法
// 如果是 UploadAuth 上传方式, 需要根据 uploadInfo.videoId是否有值调用点播的不同接口获取uploadauth和uploadAddress
// 如果 uploadInfo.videoId 有值,调用刷新视频上传凭证接口,否则调用创建视频上传凭证接口
// 注意: 这里是测试 demo 所以直接调用了获取 UploadAuth 的测试接口, 用户在使用时需要判断 uploadInfo.videoId 存在与否从而调用 openApi
// 如果 uploadInfo.videoId 存在, 调用 刷新视频上传凭证接口(https://help.aliyun.com/document_detail/55408.html)
// 如果 uploadInfo.videoId 不存在,调用 获取视频上传地址和凭证接口(https://help.aliyun.com/document_detail/55407.html)
// 如果是 UploadAuth 上传方式, 需要调用 uploader.setUploadAuthAndAddress 方法
// 如果是 UploadAuth 上传方式, 需要根据 uploadInfo.videoId是否有值调用点播的不同接口获取uploadauth和uploadAddress
// 如果 uploadInfo.videoId 有值,调用刷新视频上传凭证接口,否则调用创建视频上传凭证接口
// 注意: 这里是测试 demo 所以直接调用了获取 UploadAuth 的测试接口, 用户在使用时需要判断 uploadInfo.videoId 存在与否从而调用 openApi
// 如果 uploadInfo.videoId 存在, 调用 刷新视频上传凭证接口(https://help.aliyun.com/document_detail/55408.html)
// 如果 uploadInfo.videoId 不存在,调用 获取视频上传地址和凭证接口(https://help.aliyun.com/document_detail/55407.html)
if (!uploadInfo.videoId) {
// var createUrl = 'https://demo-vod.cn-shanghai.aliyuncs.com/voddemo/CreateUploadVideo?Title=testvod1&FileName=aa.mp4&BusinessType=vodai&TerminalType=pc&DeviceModel=iPhone9,2&UUID=59ECA-4193-4695-94DD-7E1247288&AppVersion=1.0.0&VideoId=5bfcc7864fc14b96972842172207c9e6'
// $.get(createUrl, function (data) {
@ -49,9 +49,9 @@ function createUploader () {
// var videoId = data.VideoId
// uploader.setUploadAuthAndAddress(uploadInfo, uploadAuth, uploadAddress,videoId)
// }, 'json')
var createUrl = `${_testHost}/users/${login}/video_auths.json?debug=true`
axios.post(createUrl, {
title: 'testvod1',
file_name: 'aa.mp4'
@ -65,7 +65,7 @@ function createUploader () {
}).catch((error) => {
console.log(error)
})
$('#status').text('文件开始上传...')
console.log("onUploadStarted:" + uploadInfo.file.name + ", endpoint:" + uploadInfo.endpoint + ", bucket:" + uploadInfo.bucket + ", object:" + uploadInfo.object)
@ -81,7 +81,7 @@ function createUploader () {
// }, 'json')
var refreshUrl = `${_testHost}/users/${login}/video_auths.json?debug=true`
axios.put(refreshUrl, {
video_id: uploadInfo.videoId,
}).then((response) => {
@ -132,7 +132,7 @@ function createUploader () {
// }, 'json')
var refreshUrl = `${_testHost}/users/${login}/video_auths.json?debug=true`
axios.put(refreshUrl, {
video_id: uploadInfo.videoId,
}).then((response) => {
@ -152,24 +152,24 @@ function createUploader () {
return uploader
}
function AliyunUploader(props) {
useEffect(() => {
if (window.AliyunUpload && window.AliyunUpload.Vod) {
} else {
$.getScript(
`${_url_origin}/react/${_path}/js/aliyun-upload/lib/es6-promise.min.js`,
(data, textStatus, jqxhr) => {
$.getScript(
`${_url_origin}/react/${_path}/js/aliyun-upload/lib/aliyun-oss-sdk-5.3.1.min.js`,
`${_url_origin}/react/${_path}/js/aliyun-upload/lib/es6-promise.min.js`,
(data, textStatus, jqxhr) => {
$.getScript(
`${_url_origin}/react/${_path}/js/aliyun-upload/aliyun-upload-sdk-1.5.0.min.js`,
(data, textStatus, jqxhr) => {
});
`${_url_origin}/react/${_path}/js/aliyun-upload/lib/aliyun-oss-sdk-5.3.1.min.js`,
(data, textStatus, jqxhr) => {
$.getScript(
`${_url_origin}/react/${_path}/js/aliyun-upload/aliyun-upload-sdk-1.5.0.min.js`,
(data, textStatus, jqxhr) => {
});
});
});
});
}
$('#fileUpload').on('change', function (e) {
@ -201,7 +201,7 @@ function AliyunUploader(props) {
}, [])
let { source, id, className, type } = props;
function onStop() {
$('#resumeUpload').attr('disabled', false)
// $('#pauseUpload').attr('disabled', true)
@ -212,26 +212,26 @@ function AliyunUploader(props) {
// $('#pauseUpload').attr('disabled', false)
uploader.startUpload()
}
return(
return (
<React.Fragment>
<div>
<input type="file" id="fileUpload"></input>
<label class="status">上传状态: <span id="status"></span></label>
<label className="status">上传状态: <span id="status"></span></label>
</div>
<div class="upload-type">
<div className="upload-type">
上传方式一, 使用 UploadAuth 上传:
{/* <button id="authUpload" disabled="true"></button>
<button id="pauseUpload" disabled="true" onClick={onStop}>暂停</button>
<button id="resumeUpload" disabled="true" onClick={onResume}>恢复上传</button> */}
<button id="authUpload" >开始上传</button>
<button id="pauseUpload" onClick={onStop}>暂停</button>
<button id="resumeUpload" onClick={onResume}>恢复上传</button>
<span class="progress">上传进度: <i id="auth-progress">0</i> %</span>
<button id="pauseUpload" onClick={onStop}>暂停</button>
<button id="resumeUpload" onClick={onResume}>恢复上传</button>
<span className="progress">上传进度: <i id="auth-progress">0</i> %</span>
<span></span>
</div>
</React.Fragment>
)
}
export default AliyunUploader

View File

@ -8,7 +8,7 @@ let _path = _isDev ? 'public' : 'build'
let uploader
function createUploader () {
function createUploader() {
uploader = new AliyunUpload.Vod({
timeout: $('#timeout').val() || 60000,
partSize: $('#partSize').val() || 1048576,
@ -30,19 +30,19 @@ function createUploader () {
},
// 开始上传
onUploadstarted: function (uploadInfo) {
// 如果是 UploadAuth 上传方式, 需要调用 uploader.setUploadAuthAndAddress 方法
// 如果是 UploadAuth 上传方式, 需要根据 uploadInfo.videoId是否有值调用点播的不同接口获取uploadauth和uploadAddress
// 如果 uploadInfo.videoId 有值,调用刷新视频上传凭证接口,否则调用创建视频上传凭证接口
// 注意: 这里是测试 demo 所以直接调用了获取 UploadAuth 的测试接口, 用户在使用时需要判断 uploadInfo.videoId 存在与否从而调用 openApi
// 如果 uploadInfo.videoId 存在, 调用 刷新视频上传凭证接口(https://help.aliyun.com/document_detail/55408.html)
// 如果 uploadInfo.videoId 不存在,调用 获取视频上传地址和凭证接口(https://help.aliyun.com/document_detail/55407.html)
// 如果是 UploadAuth 上传方式, 需要调用 uploader.setUploadAuthAndAddress 方法
// 如果是 UploadAuth 上传方式, 需要根据 uploadInfo.videoId是否有值调用点播的不同接口获取uploadauth和uploadAddress
// 如果 uploadInfo.videoId 有值,调用刷新视频上传凭证接口,否则调用创建视频上传凭证接口
// 注意: 这里是测试 demo 所以直接调用了获取 UploadAuth 的测试接口, 用户在使用时需要判断 uploadInfo.videoId 存在与否从而调用 openApi
// 如果 uploadInfo.videoId 存在, 调用 刷新视频上传凭证接口(https://help.aliyun.com/document_detail/55408.html)
// 如果 uploadInfo.videoId 不存在,调用 获取视频上传地址和凭证接口(https://help.aliyun.com/document_detail/55407.html)
if (!uploadInfo.videoId) {
var createUrl = 'https://demo-vod.cn-shanghai.aliyuncs.com/voddemo/CreateUploadVideo?Title=testvod1&FileName=aa.mp4&BusinessType=vodai&TerminalType=pc&DeviceModel=iPhone9,2&UUID=59ECA-4193-4695-94DD-7E1247288&AppVersion=1.0.0&VideoId=5bfcc7864fc14b96972842172207c9e6'
$.get(createUrl, function (data) {
var uploadAuth = data.UploadAuth
var uploadAddress = data.UploadAddress
var videoId = data.VideoId
uploader.setUploadAuthAndAddress(uploadInfo, uploadAuth, uploadAddress,videoId)
var uploadAuth = data.UploadAuth
var uploadAddress = data.UploadAddress
var videoId = data.VideoId
uploader.setUploadAuthAndAddress(uploadInfo, uploadAuth, uploadAddress, videoId)
}, 'json')
$('#status').text('文件开始上传...')
console.log("onUploadStarted:" + uploadInfo.file.name + ", endpoint:" + uploadInfo.endpoint + ", bucket:" + uploadInfo.bucket + ", object:" + uploadInfo.object)
@ -51,10 +51,10 @@ function createUploader () {
// https://help.aliyun.com/document_detail/55408.html?spm=a2c4g.11186623.6.630.BoYYcY
var refreshUrl = 'https://demo-vod.cn-shanghai.aliyuncs.com/voddemo/RefreshUploadVideo?BusinessType=vodai&TerminalType=pc&DeviceModel=iPhone9,2&UUID=59ECA-4193-4695-94DD-7E1247288&AppVersion=1.0.0&Title=haha1&FileName=xxx.mp4&VideoId=' + uploadInfo.videoId
$.get(refreshUrl, function (data) {
var uploadAuth = data.UploadAuth
var uploadAddress = data.UploadAddress
var videoId = data.VideoId
uploader.setUploadAuthAndAddress(uploadInfo, uploadAuth, uploadAddress,videoId)
var uploadAuth = data.UploadAuth
var uploadAddress = data.UploadAddress
var videoId = data.VideoId
uploader.setUploadAuthAndAddress(uploadInfo, uploadAuth, uploadAddress, videoId)
}, 'json')
}
},
@ -103,24 +103,24 @@ function createUploader () {
return uploader
}
function AliyunUploaderDemo(props) {
useEffect(() => {
if (window.AliyunUpload && window.AliyunUpload.Vod) {
} else {
$.getScript(
`${_url_origin}/react/${_path}/js/aliyun-upload/lib/es6-promise.min.js`,
(data, textStatus, jqxhr) => {
$.getScript(
`${_url_origin}/react/${_path}/js/aliyun-upload/lib/aliyun-oss-sdk-5.3.1.min.js`,
`${_url_origin}/react/${_path}/js/aliyun-upload/lib/es6-promise.min.js`,
(data, textStatus, jqxhr) => {
$.getScript(
`${_url_origin}/react/${_path}/js/aliyun-upload/aliyun-upload-sdk-1.5.0.min.js`,
(data, textStatus, jqxhr) => {
});
`${_url_origin}/react/${_path}/js/aliyun-upload/lib/aliyun-oss-sdk-5.3.1.min.js`,
(data, textStatus, jqxhr) => {
$.getScript(
`${_url_origin}/react/${_path}/js/aliyun-upload/aliyun-upload-sdk-1.5.0.min.js`,
(data, textStatus, jqxhr) => {
});
});
});
});
}
$('#fileUpload').on('change', function (e) {
@ -152,7 +152,7 @@ function AliyunUploaderDemo(props) {
}, [])
let { source, id, className, type } = props;
function onStop() {
$('#resumeUpload').attr('disabled', false)
// $('#pauseUpload').attr('disabled', true)
@ -163,26 +163,26 @@ function AliyunUploaderDemo(props) {
// $('#pauseUpload').attr('disabled', false)
uploader.startUpload()
}
return(
return (
<React.Fragment>
<div>
<input type="file" id="fileUpload"></input>
<label class="status">上传状态: <span id="status"></span></label>
<label className="status">上传状态: <span id="status"></span></label>
</div>
<div class="upload-type">
<div className="upload-type">
上传方式一, 使用 UploadAuth 上传:
{/* <button id="authUpload" disabled="true"></button>
<button id="pauseUpload" disabled="true" onClick={onStop}>暂停</button>
<button id="resumeUpload" disabled="true" onClick={onResume}>恢复上传</button> */}
<button id="authUpload" >开始上传</button>
<button id="pauseUpload" onClick={onStop}>暂停</button>
<button id="resumeUpload" onClick={onResume}>恢复上传</button>
<span class="progress">上传进度: <i id="auth-progress">0</i> %</span>
<button id="pauseUpload" onClick={onStop}>暂停</button>
<button id="resumeUpload" onClick={onResume}>恢复上传</button>
<span className="progress">上传进度: <i id="auth-progress">0</i> %</span>
<span></span>
</div>
</React.Fragment>
)
}
export default AliyunUploaderDemo

View File

@ -1,7 +1,8 @@
import React, { Component } from 'react';
import {Link} from 'react-router-dom'
import { Link } from 'react-router-dom'
const map={"blue":"blueFull","greyBack":"greyBack","grey":"greyWidthFixed","green":"greenBack",'greyLine':"greyLine",'orangeLine':"orangeLine",
const map = {
"blue": "blueFull", "greyBack": "greyBack", "grey": "greyWidthFixed", "green": "greenBack", 'greyLine': "greyLine", 'orangeLine': "orangeLine",
'colorBlue': 'colorBlue', // 蓝字白底
}
class ActionBtn extends Component {
@ -10,17 +11,17 @@ class ActionBtn extends Component {
}
render() {
let{to, children, style, className, ...others}=this.props
return(
let { to, children, style, className, ...others } = this.props
return (
<React.Fragment>
{
to==undefined ?
<a href="javascript:void(0)" onClick={this.props.onClick}
{...others}
className={"Actionbtn "+`${map[style || 'blue']} ${this.props.className}`}
>{children}</a>
:
<Link to={to} className={"btn "+`${map[this.props.style]} ${this.props.className}`} {...others}>{this.props.children}</Link>
to == undefined ?
<a onClick={this.props.onClick}
{...others}
className={"Actionbtn " + `${map[style || 'blue']} ${this.props.className}`}
>{children}</a>
:
<Link to={to} className={"btn " + `${map[this.props.style]} ${this.props.className}`} {...others}>{this.props.children}</Link>
}
</React.Fragment>
)

View File

@ -1,28 +1,28 @@
import React, { Component } from 'react';
import {Link} from 'react-router-dom'
import { Link } from 'react-router-dom'
const map={"blue":"colorblue","white":"colorwhite","grey":"colorgrey", 'orange': "color-orange",'colorgrey9':'color-grey-9'}
const map = { "blue": "colorblue", "white": "colorwhite", "grey": "colorgrey", 'orange': "color-orange", 'colorgrey9': 'color-grey-9' }
class WordsBtn extends Component {
constructor(props) {
super(props);
}
render() {
let{to, href,targets, style2, style, className, ...others }=this.props
return(
let { to, href, targets, style2, style, className, ...others } = this.props
return (
<React.Fragment>
{
to==undefined&&targets==undefined ?
<a href={href || "javascript:void(0)"} onClick={this.props.onClick} className={"btn "+`${map[this.props.style]} ${this.props.className}`}
to == undefined && targets == undefined ?
<a onClick={this.props.onClick} className={"btn " + `${map[this.props.style]} ${this.props.className || ""}`}
style={style2} {...others}
>{this.props.children}</a>:
targets!=undefined? <a href={to} target="_blank" className={"btn "+`${map[this.props.style]} ${this.props.className}`}
>{this.props.children}</a> :
targets != undefined ? <a href={to} target="_blank" className={"btn " + `${map[this.props.style]} ${this.props.className}`}
style={style2} {...others}
>{this.props.children}</a>
:
<Link to={to} className={"btn "+`${map[this.props.style]} ${this.props.className}`}
style={style2} {...others}
>{this.props.children}</Link>
:
<Link to={to} className={"btn " + `${map[this.props.style]} ${this.props.className || ""}`}
style={style2} {...others}
>{this.props.children}</Link>
}
</React.Fragment>
)

View File

@ -2,64 +2,72 @@
// export { default as OrderStateUtil } from '../routes/Order/components/OrderStateUtil';
export { getImageUrl as getImageUrl,getmyUrl as getmyUrl, getRandomNumber as getRandomNumber,getUrl as getUrl, publicSearchs as publicSearchs,getRandomcode as getRandomcode,getUrlmys as getUrlmys, getUrl2 as getUrl2, setImagesUrl as setImagesUrl
, getUploadActionUrl as getUploadActionUrl,getUploadActionUrltwo as getUploadActionUrltwo ,getUploadActionUrlthree as getUploadActionUrlthree, getUploadActionUrlOfAuth as getUploadActionUrlOfAuth
, getTaskUrlById as getTaskUrlById, TEST_HOST ,htmlEncode as htmlEncode ,getupload_git_file as getupload_git_file} from './UrlTool';
export {
getUploadLogoActionUrl as getUploadLogoActionUrl,
getImageUrl as getImageUrl, getmyUrl as getmyUrl, getRandomNumber as getRandomNumber, getUrl as getUrl, publicSearchs as publicSearchs, getRandomcode as getRandomcode, getUrlmys as getUrlmys, getUrl2 as getUrl2, setImagesUrl as setImagesUrl
, getUploadActionUrl as getUploadActionUrl, getUploadActionUrltwo as getUploadActionUrltwo, getUploadActionUrlthree as getUploadActionUrlthree, getUploadActionUrlOfAuth as getUploadActionUrlOfAuth
, getTaskUrlById as getTaskUrlById, TEST_HOST, htmlEncode as htmlEncode, getupload_git_file as getupload_git_file, getcdnImageUrl as getcdnImageUrl
} from './UrlTool';
export {setmiyah as setmiyah} from './Component';
export { default as queryString } from './UrlTool2';
export { setmiyah as setmiyah } from './Component';
export { default as queryString } from './UrlTool2';
export { SnackbarHOC as SnackbarHOC } from './SnackbarHOC';
export { SnackbarHOC as SnackbarHOC } from './SnackbarHOC';
export { trigger as trigger, on as on, off as off
, broadcastChannelPostMessage, broadcastChannelOnmessage } from './EventUtil';
export {
trigger as trigger, on as on, off as off
, broadcastChannelPostMessage, broadcastChannelOnmessage
} from './EventUtil';
export { updatePageParams as updatePageParams } from './RouterUtil';
export { updatePageParams as updatePageParams } from './RouterUtil';
export { bytesToSize as bytesToSize } from './UnitUtil';
export { bytesToSize as bytesToSize } from './UnitUtil';
export { markdownToHTML, uploadNameSizeSeperator, appendFileSizeToUploadFile, appendFileSizeToUploadFileAll, isImageExtension,
downloadFile, sortDirections } from './TextUtil'
export { handleDateString, getNextHalfHourOfMoment,formatDuring } from './DateUtil'
export {
markdownToHTML, uploadNameSizeSeperator, appendFileSizeToUploadFile, appendFileSizeToUploadFileAll, isImageExtension,
downloadFile, sortDirections, validateLength, mdJSONParse, exportMdtoHtml
} from './TextUtil'
export { handleDateString, getNextHalfHourOfMoment, formatDuring, formatSeconds } from './DateUtil'
export { configShareForIndex, configShareForPaths, configShareForShixuns, configShareForCourses, configShareForCustom } from './util/ShareUtil'
export { configShareForIndex, configShareForPaths, configShareForShixuns, configShareForCourses, configShareForCustom } from './util/ShareUtil'
export { isDev as isDev, isMobile } from './Env'
export { isDev as isDev, isMobile } from './Env'
export { toStore as toStore, fromStore as fromStore } from './Store'
export { toStore as toStore, fromStore as fromStore } from './Store'
export { trace_collapse, trace, debug, info, warn, error, trace_c, debug_c, info_c, warn_c, error_c } from './LogUtil'
export { trace_collapse, trace, debug, info, warn, error, trace_c, debug_c, info_c, warn_c, error_c } from './LogUtil'
export { EDU_ADMIN, EDU_BUSINESS, EDU_SHIXUN_MANAGER, EDU_SHIXUN_MEMBER, EDU_CERTIFICATION_TEACHER
, EDU_GAME_MANAGER, EDU_TEACHER, EDU_NORMAL} from './Const'
export {
EDU_ADMIN, EDU_BUSINESS, EDU_SHIXUN_MANAGER, EDU_SHIXUN_MEMBER, EDU_CERTIFICATION_TEACHER
, EDU_GAME_MANAGER, EDU_TEACHER, EDU_NORMAL
} from './Const'
export { default as AttachmentList } from './components/attachment/AttachmentList'
export { themes, ThemeContext } from './context/ThemeContext'
export { themes, ThemeContext } from './context/ThemeContext'
export { ModalHOC } from './components/ModalHOC'
export { ModalHOC } from './components/ModalHOC'
export { SetAppModel } from './components/SetAppModel'
export { SetAppModel } from './components/SetAppModel'
export { default as LinkAfterLogin } from './components/LinkAfterLogin'
export { default as Cropper } from './components/Cropper'
export { default as ConditionToolTip } from './components/ConditionToolTip'
// export { default as DragValidator } from './components/DragValidator'
export { default as LinkAfterLogin } from './components/LinkAfterLogin'
export { default as Cropper } from './components/Cropper'
export { default as ConditionToolTip } from './components/ConditionToolTip'
export { default as PopInstruction } from './components/instruction/PopInstruction'
export { default as PopInstruction } from './components/instruction/PopInstruction'
export { default as City } from './components/form/City'
export { default as City } from './components/form/City'
// course
export { default as WordsBtn } from './course/WordsBtn'
export { default as WordsBtn } from './course/WordsBtn'
export { default as ActionBtn } from './course/ActionBtn'
export { default as MarkdownToHtml } from './components/markdown/MarkdownToHtml'
export { default as DMDEditor } from './components/markdown/DMDEditor'
export { default as QuillForEditor } from './quillForEditor'
export { default as Clappr } from './components/media/Clappr'
export { default as AliyunUploader } from './components/media/AliyunUploader'
@ -73,5 +81,5 @@ export { CNotificationHOC as CNotificationHOC } from '../modules/courses/common/
export { default as ModalWrapper } from '../modules/courses/common/ModalWrapper'
export { default as NoneData } from '../modules/courses/coursesPublic/NoneData'
export {default as WordNumberTextarea} from '../modules/modals/WordNumberTextarea'
export { default as WordNumberTextarea } from '../modules/modals/WordNumberTextarea'

View File

@ -16,10 +16,10 @@ function ImageLayer2(props) {
const imageSrc = event.target.src || event.target.getAttribute('src') || event.target.getAttribute('href')
// 判断imageSrc是否是图片
const fileName = event.target.innerHTML.trim()
if (isImageExtension(imageSrc.trim()) || isImageExtension(fileName) || event.target.tagName == 'IMG' || imageSrc.indexOf('base64,') != -1) {
if (isImageExtension((imageSrc && imageSrc.trim())) || isImageExtension(fileName) || event.target.tagName == 'IMG' || (imageSrc && imageSrc.indexOf('base64,')) != -1) {
// 非回复里的头像图片; 非emoticons
if (imageSrc.indexOf('/images/avatars/User') === -1 &&
imageSrc.indexOf('kindeditor/plugins/emoticons') === -1 ) {
if (imageSrc.indexOf('/images/avatars/User') === -1 &&
imageSrc.indexOf('kindeditor/plugins/emoticons') === -1 ) {
setShowImage(true)
setImageSrc(imageSrc)
}
@ -41,7 +41,7 @@ function ImageLayer2(props) {
})
return (
<ImageLayer showImage={showImage} imageSrc={imageSrc} onImageLayerClose={onImageLayerClose}></ImageLayer>
showImage?<ImageLayer showImage={showImage} imageSrc={imageSrc} onImageLayerClose={onImageLayerClose}></ImageLayer>:""
)
}

46
src/common/mediator.js Normal file
View File

@ -0,0 +1,46 @@
function Mediator(obj) {
const channels = {}
const mediator = {
subscribe: function (channel, cb) {
if (!channels[channel]) {
channels[channel] = []
}
channels[channel].push(cb)
return this.unsubscribe.bind(null, channel, cb)
},
unsubscribe: function (channel, cb) {
let rs = channels[channel]
let index = -1
if (rs) {
for (let i = 0; i < rs.length; i++) {
if (rs[i].name === cb.name) {
index = i
break
}
}
if (index >= 0) {
channels[channel].splice(index, 1)
return true
}
}
return false
},
publish: function (channel) {
if (!channels[channel]) {
return false
}
const args = Array.prototype.slice.call(arguments, 1)
channels[channel].forEach(subscription => {
subscription.apply(null, args)
})
return this
},
}
return obj ? Object.assign(obj, mediator) : mediator
}
const mediator = new Mediator()
export default mediator

View File

@ -6,28 +6,27 @@
* @LastEditors : tangjiang
* @LastEditTime : 2020-02-05 10:44:01
*/
import Quill from 'quill';
let Inline = Quill.import('blots/inline');
// const BlockEmbed = Quill.import('blots/embed');
class FillBlot extends Inline {
static create (value) {
const node = super.cerate(value);
// node.classList.add('icon icon-bianji2');
// node.setAttribute('data-fill', 'fill');
console.log('编辑器值===》》》》》', value);
node.setAttribute('data_index', value.data_index);
node.nodeValue = value.text;
import Quill from "quill"
const InlineBlot = Quill.import('blots/inline')
const Prop = 'data-index'
class FillBlot extends InlineBlot {
static create(value) {
const node = super.create()
node.setAttribute(Prop, value.data_index);
node.innerText = value.text;
return node;
}
static value (node) {
static value(node) {
return {
// dataSet: node.getAttribute('data-fill'),
data_index: node.getAttribute('data_index')
fill_index: node.getAttribute(Prop)
}
}
}
}
FillBlot.blotName = "fill";
FillBlot.tagName = "span";

View File

@ -1,70 +1,54 @@
/*
* @Description: 重写图片
* @Author: tangjiang
* @Github:
* @Github:
* @Date: 2019-12-16 15:50:45
* @LastEditors : tangjiang
* @LastEditTime : 2019-12-31 13:59:02
*/
import Quill from "quill";
import mediator from "../mediator";
const BlockEmbed = Quill.import('blots/block/embed');
//stringify 序列化其中的onclick函数会丢失。
export default class ImageBlot extends BlockEmbed {
static create(value) {
const node = super.create();
node.setAttribute('alt', value.alt);
node.setAttribute('src', value.url);
// console.log('~~~~~~~~~~~', node, value);
node.addEventListener('click', function () {
value.onclick(value.url);
}, false);
if (value.width) {
node.setAttribute('width', value.width);
}
if (value.height) {
node.setAttribute('height', value.height);
}
const node = super.create()
const { alt, url, width, height, id } = value
node.setAttribute('alt', alt)
node.setAttribute('src', url)
if (value.id) {
node.setAttribute('id', value.id);
}
// 宽度和高度都不存在时,
if (!value.width && !value.height) {
// node.setAttribute('display', 'block');
node.setAttribute('width', '100%');
node.setAttribute('style', 'max-width: 100%, cursor:pointer');
node.onload = function () {
node.setAttribute('width', width ? width : this.width)
node.setAttribute('height', height ? height : this.height)
}
// node.setAttribute('style', { cursor: 'pointer' });
// if (node.onclick) {
// console.log('image 有图片点击事件======》》》》》》');
// // node.setAttribute('onclick', node.onCLick);
// }
// 给图片添加点击事件
// node.onclick = () => {
// value.onClick && value.onClick(value.url);
// }
node.addEventListener('click', () => {
mediator.publish('on-preview-image', value.url)
})
return node;
}
// 获取节点值
static value (node) {
static value(node) {
return {
alt: node.getAttribute('alt'),
url: node.getAttribute('src'),
onclick: node.onclick,
width: node.width,
height: node.height,
display: node.getAttribute('display'),
id: node.id,
// style: node.style
};
}
}
ImageBlot.blotName = 'image';
ImageBlot.tagName = 'img';
ImageBlot.tagName = 'img';

View File

@ -0,0 +1,66 @@
@charset "utf-8";
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=SimSun]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=SimSun]::before {
content: "宋体";
font-family:SimSun !important;
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=SimHei]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=SimHei]::before {
content: "黑体";
font-family:SimHei !important;
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=Microsoft-YaHei]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=Microsoft-YaHei]::before {
content: "微软雅黑";
font-family:Microsoft YaHei !important;
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=KaiTi]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=KaiTi]::before {
content: "楷体";
font-family:KaiTi !important;
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=FangSong]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=FangSong]::before {
content: "仿宋";
font-family:FangSong !important;
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=Arial]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=Arial]::before {
content: "Arial";
font-family:Arial !important;
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=Times-New-Roman]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=Times-New-Roman]::before {
content: "Times New Roman";
font-family:Times New Roman !important;
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=sans-serif]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=sans-serif]::before {
content: "sans-serif";
font-family:sans-serif !important;
}
.ql-font-SimSun {
font-family:SimSun !important;
}
.ql-font-SimHei {
font-family:SimHei !important;
}
.ql-font-Microsoft-YaHei {
font-family:Microsoft YaHei !important;
}
.ql-font-KaiTi {
font-family:KaiTi !important;
}
.ql-font-FangSong {
font-family:FangSong !important;
}
.ql-font-Arial {
font-family:Arial !important;
}
.ql-font-Times-New-Roman {
font-family:Times New Roman !important;
}
.ql-font-sans-serif {
font-family:sans-serif !important;
}

View File

@ -1,43 +1,100 @@
/*
* @Description: quill 编辑器
* @Author: tangjiang
* @Github:
* @Date: 2019-12-18 08:49:30
* @LastEditors : tangjiang
* @LastEditTime : 2020-02-05 11:23:03
*/
import './index.scss';
import 'quill/dist/quill.core.css'; // 核心样式
import 'quill/dist/quill.snow.css'; // 有工具栏
import 'quill/dist/quill.bubble.css'; // 无工具栏
import 'katex/dist/katex.min.css'; // katex 表达式样式
import React, { useState, useRef, useEffect } from 'react';
import Quill from 'quill';
import katex from 'katex';
import deepEqual from './deepEqual.js'
import { fetchUploadImage } from '../../services/ojService.js';
import { getImageUrl } from 'educoder'
import ImageBlot from './ImageBlot';
import FillBlot from './FillBlot';
const Size = Quill.import('attributors/style/size');
const Font = Quill.import('formats/font');
// const Color = Quill.import('attributes/style/color');
Size.whitelist = ['12px', '14px', '16px', '18px', '20px', false];
Font.whitelist = ['SimSun', 'SimHei','Microsoft-YaHei','KaiTi','FangSong','Arial','Times-New-Roman','sans-serif'];
import './index.scss'
import 'quill/dist/quill.core.css' // 核心样式
import 'quill/dist/quill.snow.css' // 有工具栏
import 'quill/dist/quill.bubble.css' // 无工具栏
import './font.css'
import React, { useState, useRef, useEffect } from 'react'
import Quill from 'quill'
import katex from 'katex'
import { fetchUploadImage } from '../../services/ojService.js'
import { getImageUrl } from 'educoder'
import ImageBlot from './ImageBlot'
import FillBlot from './FillBlot'
import LinkBlot from './link-blot'
import mediator from '../mediator'
import { defaultQuillOpt } from '../components/custom-editor'
let Size = Quill.import('attributors/style/size')
Size.whitelist = ['14px', '16px', '18px', '20px', false]
let fonts = ['Microsoft-YaHei', 'SimSun', 'SimHei', 'KaiTi', 'FangSong']
let Font = Quill.import('formats/font')
Font.whitelist = fonts; //将字体加入到白名单
window.Quill = Quill;
window.katex = katex;
Quill.register(ImageBlot);
Quill.register(Size);
Quill.register(LinkBlot);
Quill.register(Font, true);
// Quill.register({'modules/toolbar': Toolbar});
Quill.register({
'formats/fill': FillBlot
});
// Quill.register(Color);
Quill.register(FillBlot)
function QuillForEditor ({
const FillStr = '▁'
const FillReg = new RegExp(FillStr, 'g')
const BRSTR = '<p><br></p>'
//hack
function quillSetValue(el, value) {
if (value && value.hasOwnProperty('ops')) {
el.setContents(value)
} else {
if (value) {
let rs = value
if (rs.endsWith(BRSTR)) {
rs += BRSTR
}
el.clipboard.dangerouslyPasteHTML(rs);
}
}
}
const BUTTONTIP = {
'bold': '加粗',
'strike': '删除线',
'italic': '斜体',
'underline': '下划线',
'ordered': '有序列表',
'bullet': '无序列表',
'color': '字体颜色',
'background': '背景色',
'sub': '下标',
'super': '上标',
'image': '上传图片',
'code-block': '代码块',
'formula': '公式',
'clean': '清除格式',
'fill': '插入填空项',
'align': '对齐',
'header1': '标题一',
'header2': '标题二',
'header3': '标题三',
'header4': '标题四',
'header5': '标题五',
'header6': '标题六'
}
function insertAfter(newNode, referenceNode) {
referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
}
function initButtonTip(el) {
const container = el.getModule('toolbar').container
const btns = container.querySelectorAll('.ql-formats > button,.ql-formats>span')
Array.from(btns).forEach(btn => {
let value = btn.getAttribute('value')
let cls = btn.classList[0].replace('ql-', '')
btn.setAttribute('title', BUTTONTIP[value || cls] || BUTTONTIP[`${cls}${value}`])
if (cls === 'fill') {
let span = document.createElement('span')
span.setAttribute('class', 'fill-tip')
span.innerText = '点击插入填空项'
span.addEventListener('click', () => { btn.click() })
insertAfter(span, btn)
}
})
}
export default ({
defaultValue,
placeholder,
readOnly,
autoFocus = false,
@ -48,46 +105,16 @@ function QuillForEditor ({
wrapStyle = {},
showUploadImage,
onContentChange,
addFill, // 点击填空成功的回调
deleteFill // 删除填空,返回删除的下标
// getQuillContent
}) {
// toolbar 默认值
const defaultConfig = [
'bold', 'italic', 'underline',
{size: ['12px', '14px', '16px', '18px', '20px']},
{align: []}, {list: 'ordered'}, {list: 'bullet'}, // 列表
{script: 'sub'}, {script: 'super'},
{ 'color': [] }, { 'background': [] },
{header: [1,2,3,4,5,false]},
'blockquote', 'code-block',
'link', 'image', 'video',
'formula',
'clean'
];
className,
onAddFill,
onDeleteFill
}) => {
const editorRef = useRef(null);
const editorRef = useRef(null)
// quill 实例
const [quill, setQuill] = useState(null);
const [selection, setSelection] = useState(null);
const [fillCount, setFillCount] = useState(0);
const [quillCtx, setQuillCtx] = useState({});
// 文本内容变化时
const handleOnChange = content => {
// getQuillContent && getQuillContent(quill);
onContentChange && onContentChange(content, quill);
};
const renderOptions = options || defaultConfig;
const [quill, setQuill] = useState(null)
const bindings = {
tab: {
key: 9,
handler: function () {
console.log('调用了tab=====>>>>');
}
},
backspace: {
key: 'Backspace',
/**
@ -98,183 +125,150 @@ function QuillForEditor ({
* @param {*} context 上下文
*/
handler: function (range, context) {
/**
* index: 删除元素的位置
* length: 删除元素的个数
*/
const {index, length} = range;
const _start = length === 0 ? index - 1 : index;
const _length = length || 1;
let delCtx = this.quill.getText(_start, _length); // 删除的元素
// aa
const reg = /▁/g;
const delArrs = delCtx.match(reg);
const [index, delArrs] = getFillInfo(range, this.quill)
if (delArrs) {
const r = window.confirm('确定要删除吗?');
if (r) {
let leaveCtx; // 获取删除元素之前的内容
if (length === 0) {
leaveCtx = this.quill.getText(0, index - 1);
} else {
leaveCtx = this.quill.getText(0, index);
}
const leaveArrs = leaveCtx.match(reg);
const leaveLen = (leaveArrs || []).length;
let delIndexs = [];
// 获取删除元素的下标
delArrs.forEach((item, i) => {
leaveLen === 0 ? delIndexs.push(i) : delIndexs.push(leaveLen + i);
});
deleteFill && deleteFill(delIndexs); // 调用删除回调, 返回删除的元素下标[]
if (window.confirm('确定要删除这个填空吗?')) {
onDeleteFill && onDeleteFill(index, delArrs.length) // 调用删除回调, 返回删除的元素下标[]
return true
} else {
return false;
return false
}
}
return true;
return true
}
}
};
// quill 配置信息
}
const quillOption = {
modules: {
toolbar: renderOptions,
toolbar: options || defaultQuillOpt,
'syntax': false,
keyboard: {
bindings: bindings
}
// toolbar: {
// container: renderOptions
// }
},
readOnly,
placeholder,
theme: readOnly ? 'bubble' : 'snow',
};
}
//返回当前选中文件之前填空的索引,和选中的文本内有多少个填空
function getFillInfo(range, quill) {
const { index, length } = range
const start = length === 0 ? index - 1 : index
const selectionText = quill.getText(start, Math.max(1, length))
const beforeSelectionText = quill.getText(0, start)
return [(beforeSelectionText.match(FillReg) || []).length, selectionText.match(FillReg)]
}
useEffect(() => {
const quillNode = document.createElement('div');
editorRef.current.appendChild(quillNode);
const _quill = new Quill(editorRef.current, quillOption);
setQuill(_quill);
const quillInstance = new Quill(editorRef.current, quillOption)
setQuill(quillInstance)
// 处理图片上传功能
_quill.getModule('toolbar').addHandler('image', (e) => {
const input = document.createElement('input');
input.setAttribute('type', 'file');
input.setAttribute('accept', 'image/*');
input.click();
quillInstance.getModule('toolbar').addHandler('image', (e) => {
const input = document.createElement('input')
input.setAttribute('type', 'file')
input.setAttribute('accept', 'image/*')
input.click()
input.onchange = async (e) => {
const file = input.files[0]; // 获取文件信息
const formData = new FormData();
formData.append('file', file);
const file = input.files[0] // 获取文件信息
const formData = new FormData()
formData.append('file', file)
const range = _quill.getSelection(true);
let fileUrl = ''; // 保存上传成功后图片的url
// 上传文件
const result = await fetchUploadImage(formData);
const range = quillInstance.getSelection(true)
let fileUrl = '' // 保存上传成功后图片的url
const result = await fetchUploadImage(formData)
// 获取上传图片的url
if (result.data && result.data.id) {
fileUrl = getImageUrl(`api/attachments/${result.data.id}`);
fileUrl = getImageUrl(`api/attachments/${result.data.id}`)
}
// 根据id获取文件路径
const { width, height } = imgAttrs;
// console.log('上传图片的url:', fileUrl);
const { width, height } = imgAttrs
if (fileUrl) {
_quill.insertEmbed(range.index, 'image', {
let imgOption = {
url: fileUrl,
alt: '图片信息',
onClick: showUploadImage,
width,
height
});
}
quillInstance.insertEmbed(range.index, 'image', imgOption)
}
}
});
// 处理填空
_quill.getModule('toolbar').addHandler('fill', (e) => {
// alert(1111);
setFillCount(fillCount + 1);
const range = _quill.getSelection(true);
_quill.insertText(range.index, '▁');
addFill && addFill(); // 调用添加回调
});
}, []);
})
quillInstance.getModule('toolbar').addHandler('fill', (e) => {
const range = quillInstance.getSelection(true)
const [fillIndex, _] = getFillInfo(range, quillInstance)
quillInstance.insertEmbed(range.index, 'fill', { "data-index": fillIndex, text: FillStr })
quillInstance.setSelection(quillInstance.getLength(), 0, 'api')
onAddFill && onAddFill(fillIndex) // 调用添加回调
})
// 设置值
useEffect(() => {
if (!quill) return
initButtonTip(quillInstance)
const previous = quill.getContents()
quillSetValue(quillInstance, value)
if (value && value.hasOwnProperty('ops')) {
// console.log(value.ops);
const ops = value.ops || [];
ops.forEach((item, i) => {
if (item.insert['image']) {
item.insert['image'] = Object.assign({}, item.insert['image'], {style: { cursor: 'pointer' }, onclick: (url) => showUploadImage(url)});
}
});
if (autoFocus) {
quillInstance.focus()
}
const current = value
if (!deepEqual(previous, current)) {
setSelection(quill.getSelection())
if (typeof value === 'string' && value) {
// debugger
quill.clipboard.dangerouslyPasteHTML(value, 'api');
if (autoFocus) {
quill.focus();
} else {
quill.blur();
}
} else {
quill.setContents(value)
if (autoFocus) quill.focus();
function onPreview(url) {
if (showUploadImage) {
showUploadImage(url)
}
}
}, [quill, value, setQuill, autoFocus]);
// 清除选择区域
useEffect(() => {
if (quill && selection) {
quill.setSelection(selection)
setSelection(null)
}
}, [quill, selection, setSelection]);
// 设置placeholder值
useEffect(() => {
if (!quill || !quill.root) return;
quill.root.dataset.placeholder = placeholder;
}, [quill, placeholder]);
// 处理内容变化
useEffect(() => {
if (!quill) return;
if (typeof handleOnChange !== 'function') return;
let handler;
quill.on(
'text-change',
(handler = (delta, oldDelta, source) => {
const _ctx = quill.getContents();
setQuillCtx(_ctx);
handleOnChange(quill.getContents()); // getContents: 检索编辑器内容
})
);
let unsub = mediator.subscribe('on-preview-image', onPreview)
return () => {
quill.off('text-change', handler);
unsub()
}
}, [quill, handleOnChange]);
}, [])
useEffect(() => {
if (quill) {
if (readOnly === true) {
quill.enable(false)
} else {
quill.enable(true)
}
}
}, [quill, readOnly])
useEffect(() => {
quillSetValue(quill, defaultValue)
}, [quill, defaultValue])
useEffect(() => {
if (quill) {
quill.root.dataset.placeholder = placeholder;
}
}, [quill, placeholder])
useEffect(() => {
if (quill) {
autoFocus ? quill.focus() : quill.blur()
}
}, [quill, autoFocus])
useEffect(() => {
if (quill && onContentChange) {
function onChangeHandler(delta, oldDelta, source) {
let html = editorRef.current.children[0].innerHTML
let text = quill.getText()
if (html === '<p><br></p>') html = ''
if (onContentChange) {
onContentChange(quill.getContents(), html, { quill, text, delta, oldDelta, source })
}
}
quill.on('text-change', onChangeHandler)
return () => {
quill.off('text-change', onChangeHandler)
}
}
}, [quill, onContentChange])
// 返回结果
return (
<div className='quill_editor_for_react_area' style={wrapStyle}>
<div ref={editorRef} style={style}></div>
</div>
);
}
export default QuillForEditor;
<div className={`quill_editor_for_react_area ${className} `} style={wrapStyle}>
<div ref={editorRef} style={style}></div>
</div>
)
}

View File

@ -1,132 +1,200 @@
.quill_editor_for_react_area{
.quill_editor_for_react_area {
// background: #fff;
// margin: 0 15px;
.ql-editing{
.ql-editing {
left: 0 !important;
}
.ql-editor{
img{
.ql-editor {
img {
cursor: pointer;
}
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="12px"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="12px"]::before {
content: '12px';
font-size: 12px;
content: '12px';
font-size: 12px;
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="14px"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="14px"]::before {
content: '14px';
font-size: 14px;
content: '14px';
font-size: 14px;
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="16px"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="16px"]::before {
content: '16px';
font-size: 16px;
content: '16px';
font-size: 16px;
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="18px"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="18px"]::before {
content: '18px';
font-size: 18px;
content: '18px';
font-size: 18px;
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="20px"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="20px"]::before {
content: '20px';
font-size: 20px;
content: '20px';
font-size: 20px;
}
//默认的样式
.ql-snow .ql-picker.ql-size .ql-picker-label::before,
.ql-snow .ql-picker.ql-size .ql-picker-item::before {
content: '14px';
font-size: 14px;
}
content: '14px';
font-size: 14px;
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=SimSun]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=SimSun]::before {
content: "宋体";
font-family: "SimSun";
content: "宋体";
font-family: "SimSun";
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=SimHei]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=SimHei]::before {
content: "黑体";
font-family: "SimHei";
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=Microsoft-YaHei]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=Microsoft-YaHei]::before {
content: "微软雅黑";
font-family: "Microsoft YaHei";
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=KaiTi]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=KaiTi]::before {
content: "楷体";
font-family: "KaiTi";
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=FangSong]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=FangSong]::before {
content: "仿宋";
font-family: "FangSong";
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=Arial]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=Arial]::before {
content: "Arial";
font-family: "Arial";
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=Times-New-Roman]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=Times-New-Roman]::before {
content: "Times New Roman";
font-family: "Times New Roman";
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=sans-serif]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=sans-serif]::before {
content: "sans-serif";
font-family: "sans-serif";
}
.ql-font-SimSun {
font-family: "SimSun";
font-family: "SimSun";
}
.ql-font-SimHei {
font-family: "SimHei";
font-family: "SimHei";
}
.ql-font-Microsoft-YaHei {
font-family: "Microsoft YaHei";
font-family: "Microsoft YaHei";
}
.ql-font-KaiTi {
font-family: "KaiTi";
font-family: "KaiTi";
}
.ql-font-FangSong {
font-family: "FangSong";
font-family: "FangSong";
}
.ql-font-Arial {
font-family: "Arial";
font-family: "Arial";
}
.ql-font-Times-New-Roman {
font-family: "Times New Roman";
font-family: "Times New Roman";
}
.ql-font-sans-serif {
font-family: "sans-serif";
font-family: "sans-serif";
}
.ql-snow .ql-picker.ql-font .ql-picker-label::before,
.ql-snow .ql-picker.ql-font .ql-picker-item::before {
content: "微软雅黑";
font-family: "Microsoft YaHei";
}
}
// 填空图标
.ql-snow .ql-fill{
.ql-snow .ql-fill {
display: inline-block;
position: relative;
color: #05101A;
// font-size: 18px;
vertical-align: top;
&::before{
&::before {
position: absolute;
left: 50%;
top: -1px;
content: '\e709';
content: '\e691';
font-family: 'iconfont';
margin-left: -7px;
}
}
//块点不动
.ql-toolbar .ql-formats .ql-code-block svg {
pointer-events: none;
}
}
.fill-tip {
cursor: pointer;
font-size: 12px;
display: inline-block;
padding: 5px;
border: 1px solid #eaeaea;
border-radius: 5px;
box-sizing: border-box;
line-height: 16px;
color: #666;
position: relative;
justify-content: center;
margin-left: 10px;
&::before {
content: ' ';
width: 0;
height: 0;
border-top: 6px solid transparent;
border-bottom: 6px solid transparent;
border-right: 6px solid #fff;
position: absolute;
left: -6px;
top: 6px;
z-index: 10;
}
&::after {
content: ' ';
width: 0;
height: 0;
border-top: 6px solid transparent;
border-bottom: 6px solid transparent;
border-right: 6px solid #cccbcb;
position: absolute;
left: -7px;
top: 6px;
}
}

View File

@ -0,0 +1,21 @@
import Quill from "quill";
const Inline = Quill.import('blots/inline');
export default class LinkBlot extends Inline {
static create(value) {
let node = super.create()
let rs = value
if (rs.indexOf('http://') < 0) {
rs = 'http://' + rs
}
node.setAttribute('href', rs)
node.setAttribute('target', '_blank')
return node;
}
static formats(node) {
return node.getAttribute('href');
}
}
LinkBlot.blotName = 'link'
LinkBlot.tagName = 'a'

View File

@ -0,0 +1,18 @@
.ql-editor .ql-font-Microsoft-YaHei {
font-family: "Microsoft YaHei";
}
.ql-editor .ql-font-SimSun {
font-family: "SimSun";
}
.ql-editor .ql-font-SimHei {
font-family: "SimHei";
}
.ql-editor .ql-font-KaiTi {
font-family: "KaiTi";
}
.ql-editor .ql-font-Arial {
font-family: "Arial";
}
.ql-editor .Times-New-Roman {
font-family: "Times New Roman";
}

View File

@ -0,0 +1,28 @@
.ql-snow .ql-picker.ql-font .ql-picker-label::before,
.ql-snow .ql-picker.ql-font .ql-picker-item::before {
content: '微软雅黑';
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=Microsoft-YaHei]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=Microsoft-YaHei]::before {
content: "微软雅黑";
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=SimSun]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=SimSun]::before {
content: "宋体";
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=SimHei]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=SimHei]::before {
content: "黑体";
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=KaiTi]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=KaiTi]::before {
content: "楷体";
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=Arial]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=Arial]::before {
content: "Arial";
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=Times-New-Roman]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=Times-New-Roman]::before {
content: "Times New Roman";
}

View File

@ -1,54 +0,0 @@
/*
* @Description: 重写图片
* @Author: tangjiang
* @Github:
* @Date: 2019-12-16 15:50:45
* @LastEditors: tangjiang
* @LastEditTime: 2019-12-17 16:44:48
*/
import Quill from "quill";
const BlockEmbed = Quill.import('blots/block/embed');
export default class ImageBlot extends BlockEmbed {
static create(value) {
const node = super.create();
node.setAttribute('alt', value.alt);
node.setAttribute('src', value.url);
if (value.width) {
node.setAttribute('width', value.width);
}
if (value.height) {
node.setAttribute('height', value.height);
}
// 宽度和高度都不存在时,
if (!value.width && !value.height) {
node.setAttribute('display', 'block');
node.setAttribute('width', '100%');
}
// 给图片添加点击事件
node.onclick = () => {
value.onClick && value.onClick(value.url);
}
return node;
}
static value (node) {
return {
alt: node.getAttribute('alt'),
url: node.getAttribute('src'),
onclick: node.onclick,
// width: node.width,
// height: node.height,
display: node.getAttribute('display')
};
}
}
ImageBlot.blotName = 'image';
ImageBlot.tagName = 'img';

View File

@ -1,45 +0,0 @@
/*
* @Description:
* @Author: tangjiang
* @Github:
* @Date: 2019-12-09 09:09:42
* @LastEditors: tangjiang
* @LastEditTime: 2019-12-18 08:46:20
*/
import 'quill/dist/quill.core.css'; // 核心样式
import 'quill/dist/quill.snow.css'; // 有工具栏
import 'quill/dist/quill.bubble.css'; // 无工具栏
import 'katex/dist/katex.min.css'; // katex 表达式样式
import React, { useState, useReducer, useEffect } from 'react';
import useQuill from './useQuill';
function ReactQuill ({
disallowColors, // 不可见时颜色
placeholder, // 提示信息
uploadImage, // 图片上传
onChange, // 内容变化时
options, // 配置信息
value, // 显示的内容
style,
showUploadImage // 显示上传图片
}) {
const [element, setElement] = useState(); // quill 渲染节点
useQuill({
disallowColors,
placeholder,
uploadImage,
onChange,
options,
value,
showUploadImage,
element
});
return (
<div className='react_quill_area' ref={setElement} style={style}/>
);
}
export default ReactQuill;

View File

@ -1,47 +0,0 @@
function deepEqual (prev, current) {
if (prev === current) { // 基本类型比较,值,类型都相同 或者同为 null or undefined
return true;
}
if ((!prev && current)
|| (prev && !current)
|| (!prev && !current)
) {
return false;
}
if (Array.isArray(prev)) {
if (!Array.isArray(current)) return false;
if (prev.length !== current.length) return false;
for (let i = 0; i < prev.length; i++) {
if (!deepEqual(current[i], prev[i])) {
return false;
}
}
return true;
}
if (typeof current === 'object') {
if (typeof prev !== 'object') return false;
const prevKeys = Object.keys(prev);
const curKeys = Object.keys(current);
if (prevKeys.length !== curKeys.length) return false;
prevKeys.sort();
curKeys.sort();
for (let i = 0; i < prevKeys.length; i++) {
if (prevKeys[i] !== curKeys[i]) return false;
const key = prevKeys[i];
if (!deepEqual(prev[key], current[key])) return false;
}
return true;
}
return false;
}
export default deepEqual;

View File

@ -1,26 +0,0 @@
/*
* @Description: 将多维数组转变成一维数组
* @Author: tangjiang
* @Github:
* @Date: 2019-12-09 09:35:01
* @LastEditors: tangjiang
* @LastEditTime: 2019-12-16 11:36:22
*/
function flatten (array) {
return flatten.rec(array, []);
}
flatten.rec = function flatten (array, result) {
for (let item of array) {
if (Array.isArray(item)) {
flatten(item, result);
} else {
result.push(item);
}
}
return result;
}
export default flatten;

View File

@ -1,108 +0,0 @@
/*
* @Description: 入口文件
* @Author: tangjiang
* @Github:
* @Date: 2019-12-17 10:41:48
* @LastEditors: tangjiang
* @LastEditTime: 2019-12-17 20:34:40
*/
import React, { useState, useCallback, useEffect } from 'react';
import ReactQuill from './lib';
function Wrapper (props) {
// 默认工具栏配置项
const toolbarConfig = [
['bold', 'italic', 'underline'],
[{align: []}, {list: 'ordered'}, {list: 'bullet'}], // 列表
[{script: 'sub'}, {script: 'super'}],
[{header: [1,2,3,4,5,false]}],
['blockquote', 'code-block'],
['link', 'image', 'video'],
['formula'],
['clean']
];
const [placeholder] = useState(props.placeholder || 'placeholder');
const [disableBold] = useState(false);
const [value, setValue] = useState(props.value || '');
const [toolbar, setToolbar] = useState(toolbarConfig);
const [theme, setTheme] = useState(props.theme || 'snow');
const [readOnly] = useState(props.readOnly || false);
const {
onContentChagne, // 当编辑器内容变化时调用该函数
showUploadImage, // 显示上传图片, 返回url主要用于点击图片放大
} = props;
// 配置信息
const options = {
modules: {
toolbar: toolbar,
clipboard: {
matchVisual: false
}
},
readOnly: readOnly,
theme: theme
}
// 配置信息
useEffect (() => {
if (props.options) {
setToolbar(props.options);
}
setTheme(props.theme || 'snow');
setValue(props.value);
}, [props]);
// 当内容变化时
const handleOnChange = useCallback(
contents => {
if (disableBold) {
setValue({
ops: contents.ops.map(x => {
x = {...x};
if (x && x.attributes && x.attributes.bold) {
x.attributes = { ...x.attributes };
delete x.attributes.bold;
if (!Object.keys(x.attributes).length) {
delete x.attributes;
}
}
return x;
})
});
} else {
setValue(contents);
}
onContentChagne && onContentChagne(contents);
}, [disableBold]
);
// 图片上传
const handleUploadImage = (files) => {
console.log('选择的图片信息', files);
}
// 显示图片
const handleShowUploadImage = (url) => {
// console.log('上传的图片url:', url);
showUploadImage && showUploadImage(url);
}
return (
<React.Fragment>
<ReactQuill
value={value}
style={props.style}
onChange={handleOnChange}
placeholder={`${placeholder}`}
options={options}
uploadImage={handleUploadImage}
showUploadImage={(url) => handleShowUploadImage(url)}
/>
</React.Fragment>
);
}
export default Wrapper;
// ReactDOM.render(<Wrapper />, document.querySelector('#root'));

View File

@ -1,32 +0,0 @@
#quill-toolbar{
.quill-btn{
vertical-align: middle;
}
.quill_image{
display: inline-block;
position: relative;
vertical-align: middle;
width: 28px;
height: 24px;
overflow: hidden;
.image_input{
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
opacity: 0;
}
.ql-image{
position: relative;
left: 0;
top: 0;
}
}
}
.react_quill_area{
.ql-toolbar:not(:last-child) {
display: none;
}
}

View File

@ -1,13 +0,0 @@
/*
* @Description: 导出 ReactQuill
* @Author: tangjiang
* @Github:
* @Date: 2019-12-09 09:08:24
* @LastEditors: tangjiang
* @LastEditTime: 2019-12-16 11:37:13
*/
import ReactQuill from './ReactQuill';
import useQuill from './useQuill';
export default ReactQuill;
export { useQuill };

View File

@ -1,27 +0,0 @@
/*
* @Description:
* @Author: tangjiang
* @Github:
* @Date: 2019-12-12 19:48:55
* @LastEditors: tangjiang
* @LastEditTime: 2019-12-16 11:38:16
*/
import { useState, useEffect } from 'react';
import deepEqual from './deepEqual';
function useDeepEqual (input) {
const [value, setValue] = useState(input);
useEffect(() => {
if (!deepEqual(input, value)) {
setValue(input)
}
}, [input, value]);
return value;
}
export default useDeepEqual;

View File

@ -1,148 +0,0 @@
/*
* @Description: 创建 reactQuill实例
* @Author: tangjiang
* @Github:
* @Date: 2019-12-09 09:31:42
* @LastEditors: tangjiang
* @LastEditTime: 2019-12-17 20:42:05
*/
import Quill from 'quill'; // 导入quill
import { useState, useEffect, useMemo } from 'react';
import flatten from './flatten.js';
import useDeepEqualMemo from './useDeepEqualMemo';
import Katex from 'katex';
import ImageBlot from './ImageBlot';
import { fetchUploadImage } from '../../services/ojService.js';
import { getImageUrl } from 'educoder'
window.katex = Katex;
Quill.register(ImageBlot);
function useMountQuill ({
element,
options: passedOptions,
uploadImage,
showUploadImage,
imgAttrs = {} // 指定图片的宽高属性
}) {
// 是否引入 katex
const [katexLoaded, setKatexLoaded] = useState(Boolean(window.katex))
const [quill, setQuill] = useState(null);
const options = useDeepEqualMemo(passedOptions);
console.log('use mount quill: ', passedOptions);
// 判断options中是否包含公式
const requireKatex = useMemo(() => {
return flatten(options.modules.toolbar).includes('formula');
}, [options]);
// 加载katex
useEffect(() => {
if (!requireKatex) return;
if (katexLoaded) return;
const interval = setInterval(() => {
if (window.katex) {
setKatexLoaded(true);
clearInterval(interval);
}
});
return () => { // 定义回调清除定时器
clearInterval(interval);
}
}, [
setKatexLoaded,
katexLoaded,
requireKatex
]);
// 加载 quill
useEffect(() => {
if (!element) return;
if (requireKatex && !katexLoaded) {
element.innerHTML = `
<div style="color: #ddd">
Loading Katex...
</div>
`
}
// 清空内容
element.innerHTML = '';
console.log(element);
// 创建 quill 节点
const quillNode = document.createElement('div');
element.appendChild(quillNode); // 将quill节点追回到 element 元素中
const quill = new Quill(element, options);
setQuill(quill);
// 加载上传图片功能
if (typeof uploadImage === 'function') {
quill.getModule('toolbar').addHandler('image', (e) => {
// 创建type类型输入框加载本地图片
const input = document.createElement('input');
input.setAttribute('type', 'file');
input.setAttribute('accept', 'image/*');
input.click();
input.onchange = async (e) => {
const file = input.files[0]; // 获取文件信息
const formData = new FormData();
formData.append('file', file);
// const reader = new FileReader();
// reader.readAsDataURL(file);
// console.log('文件信息===>>', reader);
// reader.onload = function (e) {
// debugger;
// console.log('文件信息===>>', e.target.result);
// const image = new Image();
// image.src = e.target.result;
// image.onload = function () {
// // file.width =
// console.log(image.width, image.height);
// }
// }
const range = quill.getSelection(true);
let fileUrl = ''; // 保存上传成功后图片的url
// 上传文件
const result = await fetchUploadImage(formData);
// 获取上传图片的url
if (result.data && result.data.id) {
fileUrl = getImageUrl(`api/attachments/${result.data.id}`);
}
// 根据id获取文件路径
const { width, height } = imgAttrs;
// console.log('上传图片的url:', fileUrl);
if (fileUrl) {
quill.insertEmbed(range.index, 'image', {
url: fileUrl,
alt: '',
onClick: showUploadImage,
width,
height
});
}
}
});
}
return () => {
element.innerHTML = '';
}
}, [
element,
options,
requireKatex,
katexLoaded,
]);
return quill;
}
export default useMountQuill;

View File

@ -1,60 +0,0 @@
/*
* @Description:
* @Author: tangjiang
* @Github:
* @Date: 2019-12-09 09:09:50
* @LastEditors: tangjiang
* @LastEditTime: 2019-12-17 15:46:50
*/
import useQuillPlaceholder from './useQuillPlaceholder';
import useQuillValueSync from './useQuillValueSync';
import useQuillOnChange from './useQuillOnChange';
import useMountQuill from './useMountQuill';
import { useEffect } from 'react';
function useQuill ({
disallowColors,
placeholder,
uploadImage,
onChange,
options,
value,
element,
showUploadImage
}) {
// 获取 quill 实例
const quill = useMountQuill({
element,
options,
uploadImage,
showUploadImage
});
useEffect(() => {
if (disallowColors && quill) {
quill.clipboard.addMatcher(Node.ELEMENT_NODE, (node, delta) => {
delta.ops = delta.ops.map(op => {
if (op.attributes && op.attributes.color) {
const { color, ...attributes } = op.attributes;
return {
...op,
attributes
}
}
return op;
});
return delta;
});
}
}, [
disallowColors,
quill
]);
useQuillPlaceholder(quill, placeholder);
useQuillValueSync(quill, value);
useQuillOnChange(quill, onChange);
}
export default useQuill;

View File

@ -1,33 +0,0 @@
/*
* @Description:
* @Author: tangjiang
* @Github:
* @Date: 2019-12-12 19:49:11
* @LastEditors: tangjiang
* @LastEditTime: 2019-12-16 11:39:27
*/
import { useEffect } from 'react';
function useQuillOnChange (quill, onChange) {
useEffect(() => {
if (!quill) return;
if (typeof onChange !== 'function') return;
let handler;
quill.on(
'text-change',
(handler = () => {
onChange(quill.getContents()); // getContents: 检索编辑器内容
})
);
return () => {
quill.off('text-change', handler);
}
}, [quill, onChange]);
}
export default useQuillOnChange;

View File

@ -1,22 +0,0 @@
/*
* @Description:
* @Author: tangjiang
* @Github:
* @Date: 2019-12-09 09:28:34
* @LastEditors: tangjiang
* @LastEditTime: 2019-12-16 11:39:48
*/
import { useEffect } from 'react'
function useQuillPlaceholder (
quill,
placeholder
) {
useEffect(() => {
if (!quill || !quill.root) return;
quill.root.dataset.placeholder = placeholder;
}, [quill, placeholder]);
}
export default useQuillPlaceholder;

View File

@ -1,31 +0,0 @@
import { useEffect, useState } from 'react'
import deepEqual from './deepEqual.js'
function useQuillValueSync(quill, value) {
const [selection, setSelection] = useState(null)
useEffect(() => {
if (!quill) return
const previous = quill.getContents()
const current = value
if (!deepEqual(previous, current)) {
setSelection(quill.getSelection())
if (typeof value === 'string') {
quill.clipboard.dangerouslyPasteHTML(value, 'api')
} else {
quill.setContents(value)
}
}
}, [quill, value, setSelection])
useEffect(() => {
if (quill && selection) {
quill.setSelection(selection)
setSelection(null)
}
}, [quill, selection, setSelection])
}
export default useQuillValueSync

View File

@ -60,17 +60,17 @@ function requestForSignatrue (callback) {
/**
实践课程 平台提供涵盖基础入门案例实践和创新应用的完整实训项目体系通过由浅入深的实训路径帮助学生快速提升实战能力
实训项目 覆盖不同专业的IT实验和实训每周更新无需配置本机实验环境随时随地开启企业级真实实训
翻转课堂 自动评测实训任务支持技能统计提供教学活动分析报告减轻教师和助教的辅导压力免去作业发布和批改的困扰实时了解学生学习情况全面提升教师施教效率和水平
教学课堂 自动评测实训任务支持技能统计提供教学活动分析报告减轻教师和助教的辅导压力免去作业发布和批改的困扰实时了解学生学习情况全面提升教师施教效率和水平
单个课程和实训 获取课程/实训的简介 该课程或者实训展示的缩略图
*/
export function configShareForIndex (path) {
export function configShareForIndex (path) {
requestForSignatrue(() => {
var shareData = {
title: 'EduCoder - 首页',
desc: 'Educoder是一个面向计算机类的互联网IT教育和实战平台提供企业级工程实训以实现工程化专业教学的自动化和智能化。高校和企业人员可以在此开展计算机实践性教学活动将传统的知识传授和时兴的工程实战一体化。',
link: host + (path || ''),
imgUrl: window.__testImageUrl
imgUrl: window.__testImageUrl
|| host + '/react/build/images/share_logo_icon.jpg'
};
share(shareData)
@ -83,7 +83,7 @@ export function configShareForPaths () {
title: 'EduCoder - 实践课程',
desc: '平台提供涵盖基础入门、案例实践和创新应用的完整实训项目体系,通过由浅入深的实训路径,帮助学生快速提升实战能力。',
link: `${host}/paths`,
imgUrl: window.__testImageUrl
imgUrl: window.__testImageUrl
|| host + '/react/build/images/share_logo_icon.jpg'
};
share(shareData)
@ -97,7 +97,7 @@ export function configShareForShixuns () {
title: 'EduCoder - 实训项目',
desc: '覆盖不同专业的IT实验和实训每周更新无需配置本机实验环境随时随地开启企业级真实实训。',
link: `${host}/shixuns`,
imgUrl: window.__testImageUrl
imgUrl: window.__testImageUrl
|| host + '/react/build/images/share_logo_icon.jpg'
};
share(shareData)
@ -108,10 +108,10 @@ export function configShareForCourses () {
console.log('configShareForCourses', host)
var shareData = {
title: 'EduCoder - 翻转课堂',
title: 'EduCoder - 教学课堂',
desc: '自动评测实训任务,支持技能统计,提供教学活动分析报告,减轻教师和助教的辅导压力,免去作业发布和批改的困扰,实时了解学生学习情况,全面提升教师施教效率和水平。',
link: `${host}/courses`,
imgUrl: window.__testImageUrl
link: `${host}/classrooms`,
imgUrl: window.__testImageUrl
|| host + '/react/build/images/share_logo_icon.jpg'
};
share(shareData)
@ -127,7 +127,7 @@ export function configShareForCustom (title, desc, imgUrl, path) {
title: title,
desc: desc,
link: path ? `${host}/${path}` : _url,
imgUrl: imgUrl || window.__testImageUrl
imgUrl: imgUrl || window.__testImageUrl
|| host + '/react/build/images/share_logo_icon.jpg'
};
share(shareData)

View File

@ -0,0 +1,32 @@
import React, { useState } from 'react'
import './index.scss'
function noop() { }
export default ({ current, defaultCurrent, total, pageSize, onChange = noop }) => {
const maxPage = Math.ceil(total / pageSize)
const [page, setPage] = useState(current || defaultCurrent)
function next() {
if (page < maxPage) {
let value = page + 1
setPage(value)
onChange(value)
}
}
function prev() {
if (page > 1) {
let value = page - 1
setPage(value)
onChange(value)
}
}
return (
<div className="mini-pagination">
<a className={page === 1 ? 'disabled' : 'normal'} onClick={prev}>上一页</a>
<a className={page === maxPage ? 'disabled' : 'normal'} onClick={next} >下一页</a>
</div>
)
}

View File

@ -0,0 +1,65 @@
.mini-pagination {
display: flex;
flex-flow: row nowrap;
justify-content: center;
align-items: center;
a {
display: block;
padding: 0 10px 0 22px;
border-width: 1px;
border-radius: 3px;
margin-right: 4px;
font-size: 12px;
line-height: 30px;
cursor: pointer;
border-style: solid;
outline: none;
border-color: #c4c6cf;
background: #fff;
color: #333;
position: relative;
&:hover {
background-color: #f2f3f7;
border-color: #a0a2ad;
text-decoration: none;
}
&:before {
position: absolute;
content: ' ';
width: 8px;
top: 10px;
left: 10px;
height: 8px;
transform: rotate(-45deg);
border-top: 1px solid #333;
border-left: 1px solid #333;
}
&:last-child {
padding: 0 22px 0 10px;
margin: 0 0 0 4px;
&:before {
left: auto;
right: 10px;
transform: rotate(135deg);
}
}
&.disabled {
cursor: not-allowed;
background-color: #f7f8fa;
border-color: #e6e7eb;
color: #e0e0e0;
&:before {
border-top: 1px solid #e0e0e0;
border-left: 1px solid #e0e0e0;
}
}
}
}

Some files were not shown because too many files have changed in this diff Show More