6 文件已重命名
239个文件已修改
6 文件已复制
98个文件已添加
30个文件已删除
| | |
| | | "dependencies": { |
| | | "immutable": { |
| | | "version": "3.7.6", |
| | | "resolved": "https://registry.npmjs.org/immutable/-/immutable-3.7.6.tgz", |
| | | "resolved": "http://registry.npm.taobao.org/immutable/download/immutable-3.7.6.tgz", |
| | | "integrity": "sha1-E7TTyxK++hVIKib+Gy665kAHHks=" |
| | | } |
| | | } |
| | |
| | | } |
| | | }, |
| | | "caniuse-lite": { |
| | | "version": "1.0.30001102", |
| | | "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001102.tgz", |
| | | "integrity": "sha512-fOjqRmHjRXv1H1YD6QVLb96iKqnu17TjcLSaX64TwhGYed0P1E1CCWZ9OujbbK4Z/7zax7zAzvQidzdtjx8RcA==" |
| | | "version": "1.0.30001191", |
| | | "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001191.tgz", |
| | | "integrity": "sha512-xJJqzyd+7GCJXkcoBiQ1GuxEiOBCLQ0aVW9HMekifZsAVGdj5eJ4mFB9fEhSHipq9IOk/QXFJUiIr9lZT+EsGw==" |
| | | }, |
| | | "capture-exit": { |
| | | "version": "2.0.0", |
| | |
| | | "verror": "1.10.0" |
| | | } |
| | | }, |
| | | "jssha": { |
| | | "version": "3.2.0", |
| | | "resolved": "https://registry.npmjs.org/jssha/-/jssha-3.2.0.tgz", |
| | | "integrity": "sha512-QuruyBENDWdN4tZwJbQq7/eAK85FqrI4oDbXjy5IBhYD+2pTJyBUWZe8ctWaCkrV0gy6AaelgOZZBMeswEa/6Q==" |
| | | }, |
| | | "jsx-ast-utils": { |
| | | "version": "2.2.1", |
| | | "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-2.2.1.tgz", |
| | |
| | | "braft-extensions": "^0.1.1", |
| | | "browserslist": "^4.13.0", |
| | | "camelcase": "^5.2.0", |
| | | "caniuse-lite": "^1.0.30001102", |
| | | "case-sensitive-paths-webpack-plugin": "2.2.0", |
| | | "codemirror": "^5.52.2", |
| | | "css-loader": "2.1.1", |
| | |
| | | "jest-resolve": "24.8.0", |
| | | "jest-watch-typeahead": "0.3.1", |
| | | "jsbarcode": "^3.11.3", |
| | | "jssha": "^3.2.0", |
| | | "md5": "^2.2.1", |
| | | "mini-css-extract-plugin": "0.5.0", |
| | | "moment": "^2.24.0", |
| | |
| | | systemType -- 判断业务系统为测试 (空) 或正式 (production) ,正式系统开发权限只含有系统升级等限定功能 |
| | | externalDatabase -- 外联库,不使用时默认为false |
| | | lineColor -- 登录页分割线颜色 |
| | | filter -- 页面滤镜,值为'true'时,页面显示为黑白色 |
| | | filter -- 页面滤镜,值为'true'时,页面显示为黑白色 |
| | | defaultApp -- 默认应用,系统需默认打开某个子应用时需填写应用编码,空值时跳转到管理后台 |
| | | defaultLang -- 默认打开的子应用语言类型,填入defaultApp时有效 |
New file |
| | |
| | | <!DOCTYPE html> |
| | | <html lang="en"> |
| | | <head> |
| | | <meta charset="utf-8" /> |
| | | <title></title> |
| | | </head> |
| | | <body> |
| | | <script> |
| | | if ('ActiveXObject' in window) { |
| | | window.onload = function() { |
| | | document.getElementById('root').innerHTML = '<div style="text-align: center; font-size: 30px; margin-top: 40vh;">您的浏览器<span style="color: #ff4d4f">不受支持</span></div>' |
| | | } |
| | | } else { |
| | | fetch(`./options.json`) |
| | | .then(function(response) {return response.json()}) |
| | | .catch(function() { |
| | | document.body.innerHTML = '<div style="text-align: center; font-size: 30px; margin-top: 40vh;">系统配置信息获取失败,请联系管理员!</div>' |
| | | }) |
| | | .then(function(config) { |
| | | if (!config) { |
| | | document.body.innerHTML = '<div style="text-align: center; font-size: 30px; margin-top: 40vh;">系统配置信息获取失败,请联系管理员!</div>' |
| | | } else { |
| | | var url = window.location.href.split(/(index.html)+/ig)[0] |
| | | var appPort = 'admin/index.html' |
| | | if ((navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i))) { |
| | | appPort = 'mob/index.html' |
| | | } else { |
| | | if (config.defaultApp) { |
| | | appPort = 'pc/' |
| | | } |
| | | } |
| | | window.location.replace(url + appPort) |
| | | } |
| | | }) |
| | | } |
| | | </script> |
| | | </body> |
| | | </html> |
| | |
| | | <head> |
| | | <meta charset="utf-8" /> |
| | | <meta name="renderer" content="webkit"> |
| | | <!-- <meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests" /> --> |
| | | <meta name="viewport" content="width=device-width, initial-scale=1" /> |
| | | <meta name="theme-color" content="#000000" /> |
| | | <link rel="shortcut icon" href="#"> |
| | |
| | | <body> |
| | | <noscript>You need to enable JavaScript to run this app.</noscript> |
| | | <div id="root"></div> |
| | | <script> |
| | | if ('ActiveXObject' in window) { |
| | | window.onload = function() { |
| | | document.getElementById('root').innerHTML = '<div style="text-align: center; font-size: 30px; margin-top: 40vh;">您的浏览器<span style="color: #ff4d4f">不受支持</span></div>' |
| | | } |
| | | } |
| | | </script> |
| | | </body> |
| | | </html> |
| | |
| | | { |
| | | "short_name": "MingKeOS", |
| | | "name": "MingKe Operating System 6.0", |
| | | "icons": [ |
| | | { |
| | | "src": "favicon.ico", |
| | | "sizes": "64x64 32x32 24x24 16x16", |
| | | "type": "image/x-icon" |
| | | }, |
| | | { |
| | | "src": "logo.png", |
| | | "type": "image/png", |
| | | "sizes": "64x64" |
| | | } |
| | | ], |
| | | "icons": [], |
| | | "start_url": ".", |
| | | "display": "standalone", |
| | | "theme_color": "#000000", |
| | |
| | | "systemType": "", |
| | | "externalDatabase": "false", |
| | | "lineColor": "", |
| | | "filter": "false" |
| | | "filter": "false", |
| | | "defaultApp": "", |
| | | "defaultLang": "zh-CN", |
| | | "host": "http://qingqiumarket.cn", |
| | | "service": "mkwms/" |
| | | } |
| | |
| | | 'use strict'; |
| | | // 'use strict'; |
| | | |
| | | // Do this as the first thing so that any code reading it knows the right env. |
| | | process.env.BABEL_ENV = 'production'; |
| | |
| | | 'use strict'; |
| | | // 'use strict'; |
| | | |
| | | // Do this as the first thing so that any code reading it knows the right env. |
| | | process.env.BABEL_ENV = 'development'; |
New file |
| | |
| | | /** |
| | | * @description 缓存工具类 |
| | | */ |
| | | export default class CacheUtils { |
| | | /** |
| | | * @description 打开websql |
| | | */ |
| | | static openWebSql () { |
| | | let service = window.GLOB.service ? '-' + window.GLOB.service.replace('/', '') : '' |
| | | try { |
| | | window.GLOB.WebSql = openDatabase(`mkdb${service}`, '1', 'mk-pc-database', 50 * 1024 * 1024) |
| | | window.GLOB.WebSql.transaction(tx => { |
| | | tx.executeSql('CREATE TABLE IF NOT EXISTS VERSIONS (version varchar(50), createDate varchar(50), CDefine1 varchar(50), CDefine2 varchar(50), CDefine3 varchar(50))', [], () => { |
| | | |
| | | }, () => { |
| | | // eslint-disable-next-line |
| | | throw 'CREATE TABLE ERROR' |
| | | }) |
| | | tx.executeSql('CREATE TABLE IF NOT EXISTS CONFIGS (menuid varchar(50), userid varchar(50), openEdition varchar(50), webEdition varchar(50), LongParam text, LongParamUser text, CDefine1 varchar(50), CDefine2 varchar(50), CDefine3 varchar(50), CDefine4 varchar(50), CDefine5 varchar(50))', [], () => { |
| | | |
| | | }, () => { |
| | | // eslint-disable-next-line |
| | | throw 'CREATE TABLE ERROR' |
| | | }) |
| | | }) |
| | | // window.GLOB.WebSql.transaction(tx => { |
| | | // tx.executeSql('DROP TABLE VERSIONS') |
| | | // tx.executeSql('DROP TABLE CONFIGS') |
| | | // }) |
| | | } catch (e) { |
| | | console.warn('WebSql 初始化失败!') |
| | | window.GLOB.WebSql = null |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * @description 获取websql中保存信息版本 |
| | | */ |
| | | static getWebSqlVersion () { |
| | | if (!window.GLOB.WebSql) { |
| | | return Promise.reject() |
| | | } |
| | | return new Promise((resolve, reject) => { |
| | | window.GLOB.WebSql.transaction(tx => { |
| | | tx.executeSql('SELECT * FROM VERSIONS', [], (tx, results) => { |
| | | if (results.rows.length === 0) { |
| | | tx.executeSql('DELETE FROM CONFIGS') |
| | | resolve({version: '', createDate: ''}) |
| | | } else if (results.rows.length === 1) { |
| | | resolve(results.rows[0]) |
| | | } else if (results.rows.length > 1) { |
| | | tx.executeSql('DELETE FROM VERSIONS') |
| | | tx.executeSql('DELETE FROM CONFIGS') |
| | | resolve({version: '', createDate: ''}) |
| | | } |
| | | }, (tx, results) => { |
| | | window.GLOB.WebSql = null |
| | | reject() |
| | | console.warn(results) |
| | | }) |
| | | }) |
| | | }) |
| | | } |
| | | |
| | | /** |
| | | * @description 清空websql中保存的配置信息 |
| | | */ |
| | | static clearWebSqlConfig () { |
| | | if (!window.GLOB.WebSql) return |
| | | window.GLOB.WebSql.transaction(tx => { |
| | | tx.executeSql(`DELETE FROM CONFIGS`, [], () => {}, () => { window.GLOB.WebSql = null }) |
| | | }) |
| | | } |
| | | |
| | | /** |
| | | * @description 删除websql中保存的配置信息 |
| | | */ |
| | | static delWebSqlConfig (keys) { |
| | | if (!window.GLOB.WebSql || !keys) return |
| | | window.GLOB.WebSql.transaction(tx => { |
| | | tx.executeSql(`DELETE FROM CONFIGS where menuid in (${keys})`, [], () => {}, () => { |
| | | window.GLOB.WebSql = null |
| | | }) |
| | | }) |
| | | } |
| | | |
| | | /** |
| | | * @description 删除websql中保存的配置信息 |
| | | */ |
| | | static delMenuWebSqlConfig (menuId) { |
| | | if (!window.GLOB.WebSql || !menuId) return Promise.resolve() |
| | | return new Promise(resolve => { |
| | | window.GLOB.WebSql.transaction(tx => { |
| | | tx.executeSql(`DELETE FROM CONFIGS where menuid='${menuId}'`, [], () => { |
| | | resolve() |
| | | }, () => { |
| | | window.GLOB.WebSql = null |
| | | resolve() |
| | | }) |
| | | }) |
| | | }) |
| | | } |
| | | |
| | | /** |
| | | * @description 更新websql中配置信息的保存时间 |
| | | */ |
| | | static updateWebSqlTime (curTime) { |
| | | if (!window.GLOB.WebSql || !curTime) return |
| | | window.GLOB.WebSql.transaction(tx => { |
| | | tx.executeSql(`UPDATE VERSIONS SET createDate='${curTime}'`, [], () => {}, () => { |
| | | window.GLOB.WebSql = null |
| | | }) |
| | | }) |
| | | } |
| | | |
| | | /** |
| | | * @description 更新websql中配置信息的版本 |
| | | */ |
| | | static updateWebSqlversion (version, curTime) { |
| | | if (!window.GLOB.WebSql || !curTime || !version) return |
| | | window.GLOB.WebSql.transaction(tx => { |
| | | tx.executeSql(`UPDATE VERSIONS SET version='${version}', createDate='${curTime}'`, [], () => {}, () => { |
| | | window.GLOB.WebSql = null |
| | | }) |
| | | }) |
| | | } |
| | | |
| | | /** |
| | | * @description 创建websql中配置信息的版本 |
| | | */ |
| | | static createWebSqlversion (version, curTime) { |
| | | if (!window.GLOB.WebSql || !curTime || !version) return |
| | | window.GLOB.WebSql.transaction(tx => { |
| | | tx.executeSql('INSERT INTO VERSIONS (version, createDate) VALUES (?, ?)', [version, curTime], () => {}, () => { |
| | | window.GLOB.WebSql = null |
| | | }) |
| | | }) |
| | | } |
| | | |
| | | /** |
| | | * @description 获取websql中的配置信息 |
| | | */ |
| | | static getWebSqlMenuConfig (MenuID, userid) { |
| | | if (!window.GLOB.WebSql || !MenuID || !userid) return Promise.reject() |
| | | return new Promise((resolve, reject) => { |
| | | window.GLOB.WebSql.transaction(tx => { |
| | | tx.executeSql(`SELECT * FROM CONFIGS WHERE menuid='${MenuID}' and userid='${userid}'`, [], (tx, results) => { |
| | | let paramItem = results.rows[0] |
| | | if (paramItem) { |
| | | resolve({ |
| | | ErrCode: 'S', |
| | | ErrMesg: '', |
| | | LongParam: paramItem.LongParam, |
| | | LongParamUser: paramItem.LongParamUser, |
| | | message: '', |
| | | open_edition: paramItem.openEdition, |
| | | status: true, |
| | | web_edition: paramItem.webEdition |
| | | }) |
| | | } else { |
| | | reject() |
| | | } |
| | | }, (tx, results) => { |
| | | window.GLOB.WebSql = null |
| | | console.warn(results) |
| | | reject() |
| | | }) |
| | | }) |
| | | }) |
| | | } |
| | | |
| | | /** |
| | | * @description 将数据写入websql |
| | | */ |
| | | static writeInWebSql (data) { |
| | | if (!window.GLOB.WebSql || !data) return |
| | | window.GLOB.WebSql.transaction(tx => { |
| | | tx.executeSql('INSERT INTO CONFIGS (menuid, userid, openEdition, webEdition, LongParam, LongParamUser) VALUES (?, ?, ?, ?, ?, ?)', data) |
| | | }) |
| | | } |
| | | |
| | | /** |
| | | * @description 打开IndexedDB |
| | | */ |
| | | static openIndexDB () { |
| | | let service = window.GLOB.service ? '-' + window.GLOB.service.replace('/', '') : '' |
| | | try { |
| | | let request = window.indexedDB.open(`mkdb${service}`, 1) |
| | | request.onerror = () => { |
| | | console.warn('IndexedDB 初始化失败!') |
| | | } |
| | | request.onsuccess = () => { |
| | | window.GLOB.IndexDB = request.result |
| | | } |
| | | request.onupgradeneeded = (event) => { |
| | | window.GLOB.IndexDB = event.target.result |
| | | if (!window.GLOB.IndexDB.objectStoreNames.contains('version')) { |
| | | window.GLOB.IndexDB.createObjectStore('version', { keyPath: 'id' }) |
| | | } |
| | | if (!window.GLOB.IndexDB.objectStoreNames.contains('configs')) { |
| | | let objectStore = window.GLOB.IndexDB.createObjectStore('configs', { keyPath: 'id' }) |
| | | objectStore.createIndex('menuid', 'menuid', { unique: false }) |
| | | objectStore.createIndex('userid', 'userid', { unique: false }) |
| | | } |
| | | } |
| | | } catch (e) { |
| | | console.warn('IndexedDB 初始化失败!') |
| | | window.GLOB.IndexDB = null |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * @description 获取IndexedDB中保存信息版本 |
| | | */ |
| | | static getIndexDBVersion () { |
| | | if (!window.GLOB.IndexDB) { |
| | | return Promise.reject() |
| | | } |
| | | return new Promise((resolve, reject) => { |
| | | let request = window.GLOB.IndexDB.transaction(['version']) |
| | | .objectStore('version') |
| | | .get('mksoft') |
| | | |
| | | request.onerror = (event) => { |
| | | window.GLOB.IndexDB = null |
| | | console.warn(event) |
| | | reject() |
| | | } |
| | | |
| | | request.onsuccess = () => { |
| | | if (request.result) { |
| | | resolve(request.result) |
| | | } else { |
| | | this.clearIndexDBConfig() |
| | | resolve({version: '', createDate: ''}) |
| | | } |
| | | } |
| | | }) |
| | | } |
| | | |
| | | /** |
| | | * @description 清空IndexedDB中保存的配置信息 |
| | | */ |
| | | static clearIndexDBConfig () { |
| | | if (!window.GLOB.IndexDB) return |
| | | let request = window.GLOB.IndexDB.transaction(['configs'], 'readwrite').objectStore('configs').clear() |
| | | |
| | | request.onerror = () => { |
| | | window.GLOB.IndexDB = null |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * @description 更新IndexedDB中配置信息的版本 |
| | | */ |
| | | static updateIndexDBversion (version) { |
| | | if (!window.GLOB.IndexDB || !version) return |
| | | |
| | | version.id = 'mksoft' |
| | | |
| | | let objectStore = window.GLOB.IndexDB.transaction(['version'], 'readwrite').objectStore('version') |
| | | let request = objectStore.get('mksoft') |
| | | |
| | | request.onerror = () => { |
| | | window.GLOB.IndexDB = null |
| | | } |
| | | |
| | | request.onsuccess = () => { |
| | | if (request.result) { |
| | | let put = objectStore.put(version) |
| | | |
| | | put.onerror = () => { |
| | | window.GLOB.IndexDB = null |
| | | } |
| | | } else { |
| | | this.clearIndexDBConfig() |
| | | |
| | | let add = objectStore.add(version) |
| | | |
| | | add.onerror = () => { |
| | | window.GLOB.IndexDB = null |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * @description 删除IndexedDB中保存的配置信息 |
| | | */ |
| | | static delMenuIndexDBConfig (key) { |
| | | if (!window.GLOB.IndexDB || !key) return Promise.resolve() |
| | | |
| | | return new Promise(resolve => { |
| | | let request = window.GLOB.IndexDB.transaction(['configs'], 'readwrite') |
| | | .objectStore('configs') |
| | | .delete(key) |
| | | |
| | | request.onsuccess = () => { |
| | | resolve() |
| | | } |
| | | request.onerror = () => { |
| | | window.GLOB.IndexDB = null |
| | | resolve() |
| | | } |
| | | }) |
| | | } |
| | | |
| | | /** |
| | | * @description 删除IndexedDB中保存的配置信息-批量 |
| | | */ |
| | | static delIndexDBConfig (keys) { |
| | | if (!window.GLOB.IndexDB || !keys) return |
| | | |
| | | let objectStore = window.GLOB.IndexDB.transaction(['configs'], 'readwrite').objectStore('configs') |
| | | |
| | | objectStore.openCursor().onsuccess = (event) => { |
| | | let cursor = event.target.result |
| | | |
| | | if (cursor) { |
| | | if (cursor.value && keys.includes(cursor.value.menuid)) { |
| | | let request = objectStore.delete(cursor.key) |
| | | |
| | | request.onerror = () => { |
| | | window.GLOB.IndexDB = null |
| | | } |
| | | } |
| | | |
| | | cursor.continue() |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * @description 获取IndexedDB中的配置信息 |
| | | */ |
| | | static getIndexDBMenuConfig (MenuID, userid) { |
| | | if (!window.GLOB.IndexDB || !MenuID || !userid) return Promise.reject() |
| | | let key = MenuID + userid |
| | | return new Promise((resolve, reject) => { |
| | | let request = window.GLOB.IndexDB.transaction(['configs']).objectStore('configs').get(key) |
| | | |
| | | request.onerror = () => { |
| | | window.GLOB.IndexDB = null |
| | | reject() |
| | | } |
| | | |
| | | request.onsuccess = () => { |
| | | if (request.result) { |
| | | resolve(request.result) |
| | | } else { |
| | | reject() |
| | | } |
| | | } |
| | | }) |
| | | } |
| | | |
| | | /** |
| | | * @description 将数据写入IndexedDB |
| | | */ |
| | | static writeInIndexDB (data) { |
| | | if (!window.GLOB.IndexDB || !data) return |
| | | |
| | | let request = window.GLOB.IndexDB.transaction(['configs'], 'readwrite') |
| | | .objectStore('configs') |
| | | .add(data) |
| | | |
| | | request.onerror = () => { |
| | | window.GLOB.IndexDB = null |
| | | } |
| | | } |
| | | } |
| | |
| | | import qs from 'qs' |
| | | import { notification } from 'antd' |
| | | import md5 from 'md5' |
| | | import jsSHA from 'jssha' |
| | | import moment from 'moment' |
| | | import Utils from '@/utils/utils.js' |
| | | import CacheUtils from './cacheutils' |
| | | import options from '@/store/options.js' |
| | | |
| | | let mkDataBase = null |
| | | window.GLOB.WebSql = null |
| | | window.GLOB.IndexDB = null |
| | | const systemMenuKeys = `1581067625930haged11ieaivpavv77k,1581734956310scks442ul2d955g9tu5,1583991994144ndddg0bhh0is6shi0v1,1583979633842550imkchl4qt4qppsiv,1578900109100np8aqd0a77q3na46oas,16044812935562g807p3p12huk8kokmb, |
| | | 1585192949946f3et2ts8tn82krmumdf,15855615451212m12ip23vpcm79kloro,1587005717541lov40vg61q7l1rbveon,1590458676585agbbr63t6ihighg2i1g,1602315375262ikd33ii0nii34pt861o,1582771068837vsv54a089lgp45migbg, |
| | | 1582777675954ifu05upurs465omoth7,158294809668898cklbv6c5bou8e1fpu,1584676379094iktph45fb8imhg96bql,1584695125339vo5g7iqgfn01qmrd6s2,1584699661372vhmpp9dn9foo0eob722,15848421131551gg04ie8sitsd3f7467, |
| | | 1589782279158ngr675kk3oksin35sul,1589788042787ffdt9hle4s45k9r1nvs,15900310928174dro07ihfckghpb5h13,1594095599055qicg2eb642v5qglhnuo,1599613340050c8nu6rbst9d4emnnbsq,1577972969199lei1g0qkvlh4tkc908m, |
| | | 1578479100252lfbp29v1kafk4s4q4ig,1577971621421tg4v0i1ur8873k7e0ob,1577929944419lgc5h3hepum765e2k7u,1588493493409k9guqp067d31lu7blsv` |
| | | |
| | | if (window.openDatabase) { |
| | | let service = window.GLOB.service ? '-' + window.GLOB.service.replace('/', '') : '' |
| | | try { |
| | | mkDataBase = openDatabase(`mkdb${service}`, '1', 'mk-pc-database', 50 * 1024 * 1024) |
| | | mkDataBase.transaction(tx => { |
| | | tx.executeSql('CREATE TABLE IF NOT EXISTS VERSIONS (version varchar(50), createDate varchar(50), CDefine1 varchar(50), CDefine2 varchar(50), CDefine3 varchar(50))', [], () => { |
| | | |
| | | }, () => { |
| | | // eslint-disable-next-line |
| | | throw 'CREATE TABLE ERROR' |
| | | }) |
| | | tx.executeSql('CREATE TABLE IF NOT EXISTS CONFIGS (menuid varchar(50), userid varchar(50), openEdition varchar(50), webEdition varchar(50), LongParam text, LongParamUser text, CDefine1 varchar(50), CDefine2 varchar(50), CDefine3 varchar(50), CDefine4 varchar(50), CDefine5 varchar(50))', [], () => { |
| | | |
| | | }, () => { |
| | | // eslint-disable-next-line |
| | | throw 'CREATE TABLE ERROR' |
| | | }) |
| | | }) |
| | | // mkDataBase.transaction(tx => { |
| | | // tx.executeSql('DROP TABLE VERSIONS') |
| | | // tx.executeSql('DROP TABLE CONFIGS') |
| | | // }) |
| | | } catch (e) { |
| | | console.warn(e) |
| | | mkDataBase = null |
| | | } |
| | | CacheUtils.openWebSql() |
| | | } else if (window.indexedDB) { |
| | | CacheUtils.openIndexDB() |
| | | } |
| | | |
| | | axios.defaults.crossDomain = true |
| | | axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8' |
| | | axios.defaults.withCredentials = true |
| | | axios.defaults.withCredentials = false |
| | | |
| | | axios.interceptors.request.use((config) => { |
| | | if (config.url.includes('LoginAndRedirect') || config.url.includes('getjsonresult') || config.url.includes('wxNativePay')) { |
| | | config.data = qs.stringify(config.data) |
| | | } else if (config.url.includes('Upload') || config.url.includes('doupload') || config.url.includes('dopreload')) { |
| | | config.headers = { 'Content-Type': 'multipart/form-data' } |
| | | } else if (config.method === 'post') { |
| | | } else if (config.method === 'post' && config.data) { |
| | | config.data = JSON.stringify(config.data) |
| | | } |
| | | |
| | |
| | | if (process.env.NODE_ENV === 'production') { |
| | | axios.defaults.baseURL = document.location.origin + '/' + window.GLOB.service |
| | | } else { |
| | | // axios.defaults.baseURL = 'http://127.0.0.1:8888' |
| | | axios.defaults.baseURL = window.GLOB.location + '/' + window.GLOB.service |
| | | } |
| | | } |
| | | |
| | |
| | | /* @description 直接请求 |
| | | * @param {Object} param 查询及提交参数 |
| | | */ |
| | | directRequest (url, method = 'post', param) { |
| | | directRequest (url, method = 'post', param, cross) { |
| | | if (cross === 'true' && param) { |
| | | return axios({ |
| | | url, |
| | | method, |
| | | data: param |
| | | }) |
| | | } else if (cross === 'true') { |
| | | return axios({ |
| | | url, |
| | | method |
| | | }) |
| | | } |
| | | |
| | | let params = { method: 'post' } |
| | | let _url = url |
| | | |
| | |
| | | } |
| | | |
| | | _url = _url.replace(/&/ig, '%26') |
| | | // _url = window.btoa(_url) |
| | | params.url = '/trans/redirect?rd=' + _url + '&method=' + method |
| | | |
| | | return axios(params) |
| | | } |
| | | |
| | | /** |
| | | * @description 使用dostar接口,跳转至dostars |
| | | * @param {Object} param 查询及提交参数 |
| | | */ |
| | | dostarToDostars (param) { |
| | | param.userid = param.userid || sessionStorage.getItem('UserID') || '' |
| | | param.LoginUID = param.LoginUID || sessionStorage.getItem('LoginUID') || '' |
| | | |
| | | param = this.encryptParam(param) |
| | | |
| | | return axios({ |
| | | url: '/webapi/dostar', |
| | | method: 'post', |
| | | data: param |
| | | }) |
| | | } |
| | | |
| | | /** |
| | |
| | | |
| | | param.appkey = window.GLOB.appkey || '' |
| | | |
| | | let url = '/webapi/dologon/s_visitor_login' |
| | | if (window.GLOB.mainSystemApi) { |
| | | param.rduri = window.GLOB.mainSystemApi.replace(/\/webapi(.*)/, '/webapi/dologon') |
| | | // url = window.GLOB.mainSystemApi.replace(/\/webapi(.*)/, '/webapi/dologon/s_visitor_login') |
| | | param.rduri = window.GLOB.mainSystemApi.replace(/\/webapi(.*)/, '/webapi/dologon/s_visitor_login') |
| | | } |
| | | |
| | | return axios({ |
| | | url: '/webapi/dologon', |
| | | url: url, |
| | | method: 'post', |
| | | data: param |
| | | }) |
| | |
| | | /** |
| | | * @description 手机号验证码登录 |
| | | */ |
| | | getphoneusermsg (phoneNo, checkcode, isCloud = false) { |
| | | getphoneusermsg (phoneNo, checkcode, isCloud = false, ipAddress, city) { |
| | | let param = { |
| | | // func: 'webapi_login', |
| | | mob: phoneNo, |
| | |
| | | Password: '', |
| | | check_code: checkcode, |
| | | way_no: 'sms_vcode', |
| | | systemType: options.sysType |
| | | systemType: options.sysType, |
| | | login_city: city, |
| | | login_id_address: ipAddress |
| | | } |
| | | |
| | | param.appkey = window.GLOB.appkey || '' |
| | | |
| | | let url = '/webapi/dologon' |
| | | if (isCloud) { |
| | | param.debug = 'Y' |
| | | if (options.cloudServiceApi) { |
| | | // url = options.cloudServiceApi.replace(/\/webapi(.*)/, '/webapi/dologon') |
| | | param.rduri = options.cloudServiceApi.replace(/\/webapi(.*)/, '/webapi/dologon') |
| | | } |
| | | } else if (!isCloud && window.GLOB.mainSystemApi) { |
| | | } else if (window.GLOB.mainSystemApi) { |
| | | if (options.sysType !== 'cloud' && window.GLOB.systemType !== 'production') { |
| | | param.linkurl = window.GLOB.linkurl |
| | | } |
| | | // url = window.GLOB.mainSystemApi.replace(/\/webapi(.*)/, '/webapi/dologon') |
| | | param.rduri = window.GLOB.mainSystemApi.replace(/\/webapi(.*)/, '/webapi/dologon') |
| | | } |
| | | |
| | | return axios({ |
| | | url: '/webapi/dologon', |
| | | url, |
| | | method: 'post', |
| | | data: param |
| | | }) |
| | |
| | | /** |
| | | * @description 登录系统, 获取用户信息 |
| | | */ |
| | | getusermsg (username, password, isCloud = false) { |
| | | getusermsg (username, password, isCloud = false, ipAddress, city) { |
| | | let param = { |
| | | // func: 'webapi_login', |
| | | UserName: username, |
| | | Password: password, |
| | | systemType: options.sysType, |
| | | Type: 'X' |
| | | Type: 'S', |
| | | login_city: city, |
| | | login_id_address: ipAddress |
| | | } |
| | | |
| | | param.Password = Utils.formatOptions(param.Password) |
| | | // Type: 'S' 时 |
| | | let shaObj = new jsSHA('SHA-1', 'TEXT') |
| | | param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') |
| | | shaObj.update(password) |
| | | param.Password = shaObj.getHash('HEX').toUpperCase() |
| | | param.Password = md5(username + param.Password + param.timestamp) |
| | | |
| | | // Type: 'X' 时 |
| | | // param.Password = Utils.formatOptions(password) |
| | | param.appkey = window.GLOB.appkey || '' |
| | | let url = '/webapi/dologon' |
| | | |
| | | if (isCloud) { |
| | | param.debug = 'Y' |
| | | if (options.cloudServiceApi) { |
| | | // url = options.cloudServiceApi.replace(/\/webapi(.*)/, '/webapi/dologon') |
| | | param.rduri = options.cloudServiceApi.replace(/\/webapi(.*)/, '/webapi/dologon') |
| | | } |
| | | } else if (!isCloud && window.GLOB.mainSystemApi) { |
| | | } else if (window.GLOB.mainSystemApi) { |
| | | if (options.sysType !== 'cloud' && window.GLOB.systemType !== 'production') { |
| | | param.linkurl = window.GLOB.linkurl |
| | | } |
| | | // url = window.GLOB.mainSystemApi.replace(/\/webapi(.*)/, '/webapi/dologon') |
| | | param.rduri = window.GLOB.mainSystemApi.replace(/\/webapi(.*)/, '/webapi/dologon') |
| | | } |
| | | |
| | | return axios({ |
| | | url: '/webapi/dologon', |
| | | url, |
| | | method: 'post', |
| | | data: param |
| | | }) |
| | |
| | | */ |
| | | getAppVersion (_resolve, _reject) { |
| | | let appVersion = {} |
| | | |
| | | new Promise((resolve, reject) => { |
| | | if (!mkDataBase) { |
| | | reject() |
| | | } else { |
| | | mkDataBase.transaction(tx => { |
| | | if (!mkDataBase) { |
| | | reject() |
| | | return |
| | | } |
| | | tx.executeSql('SELECT * FROM VERSIONS', [], (tx, results) => { |
| | | if (results.rows.length === 0) { |
| | | tx.executeSql('DELETE FROM CONFIGS') |
| | | resolve({version: '', createDate: ''}) |
| | | } else if (results.rows.length === 1) { |
| | | resolve(results.rows[0]) |
| | | } else if (results.rows.length > 1) { |
| | | tx.executeSql('DELETE FROM VERSIONS') |
| | | tx.executeSql('DELETE FROM CONFIGS') |
| | | resolve({version: '', createDate: ''}) |
| | | } |
| | | }, (tx, results) => { |
| | | reject() |
| | | console.warn(results) |
| | | }) |
| | | }) |
| | | } |
| | | }).then(msg => { |
| | | if (msg.version) { |
| | | appVersion.oldVersion = msg.version |
| | | } |
| | | let curTime = moment().format('YYYY-MM-DD HH:mm:ss') + '.000' |
| | | |
| | | let param = { |
| | | func: 's_get_app_version', |
| | | modifydate: msg.createDate || curTime, |
| | | } |
| | | |
| | | param.userid = sessionStorage.getItem('UserID') || '' |
| | | param.lang = localStorage.getItem('lang') || '' |
| | | param.SessionUid = localStorage.getItem('SessionUid') || '' |
| | | param.LoginUID = sessionStorage.getItem('LoginUID') || '' |
| | | param.appkey = window.GLOB.appkey || '' |
| | | |
| | | if (window.GLOB.mainSystemApi) { |
| | | param.rduri = window.GLOB.mainSystemApi |
| | | } |
| | | |
| | | param = this.encryptParam(param) |
| | | |
| | | return new Promise((resolve, reject) => { |
| | | axios({ |
| | | url: `/webapi/dostars${param.func ? '/' + param.func : ''}`, |
| | | method: 'post', |
| | | data: param |
| | | }).then(res => { |
| | | if (!res.status) { |
| | | reject() |
| | | return |
| | | } |
| | | let clear = false |
| | | let version = res.app_version || '1.00' |
| | | appVersion.newVersion = version |
| | | appVersion.oldVersion = appVersion.oldVersion || version |
| | | |
| | | if (res.menu_data && res.menu_data.length > 0) { |
| | | let keys = `1581067625930haged11ieaivpavv77k,1581734956310scks442ul2d955g9tu5,1583991994144ndddg0bhh0is6shi0v1,1583979633842550imkchl4qt4qppsiv,1578900109100np8aqd0a77q3na46oas,16044812935562g807p3p12huk8kokmb, |
| | | 1585192949946f3et2ts8tn82krmumdf,15855615451212m12ip23vpcm79kloro,1587005717541lov40vg61q7l1rbveon,1590458676585agbbr63t6ihighg2i1g,1602315375262ikd33ii0nii34pt861o,1582771068837vsv54a089lgp45migbg, |
| | | 1582777675954ifu05upurs465omoth7,158294809668898cklbv6c5bou8e1fpu,1584676379094iktph45fb8imhg96bql,1584695125339vo5g7iqgfn01qmrd6s2,1584699661372vhmpp9dn9foo0eob722,15848421131551gg04ie8sitsd3f7467, |
| | | 1589782279158ngr675kk3oksin35sul,1589788042787ffdt9hle4s45k9r1nvs,15900310928174dro07ihfckghpb5h13,1594095599055qicg2eb642v5qglhnuo,1599613340050c8nu6rbst9d4emnnbsq,1577972969199lei1g0qkvlh4tkc908m, |
| | | 1578479100252lfbp29v1kafk4s4q4ig,1577971621421tg4v0i1ur8873k7e0ob,1577929944419lgc5h3hepum765e2k7u,1588493493409k9guqp067d31lu7blsv` |
| | | |
| | | res.menu_data.forEach(mid => { |
| | | if (keys.indexOf(mid.menuid) > -1) { |
| | | clear = true |
| | | } |
| | | }) |
| | | } |
| | | |
| | | mkDataBase.transaction(tx => { |
| | | if (clear) { |
| | | tx.executeSql(`DELETE FROM CONFIGS`, [], () => {}, () => { reject() }) |
| | | } else if (res.menu_data && res.menu_data.length > 0) { |
| | | let keys = res.menu_data.map(mid => `'${mid.menuid}'`) |
| | | tx.executeSql(`DELETE FROM CONFIGS where menuid in (${keys.join(',')})`, [], () => {}, () => { |
| | | reject() |
| | | }) |
| | | } |
| | | if (msg.version) { |
| | | tx.executeSql(`UPDATE VERSIONS SET createDate='${curTime}'`, [], () => { |
| | | resolve() |
| | | }, () => { |
| | | reject() |
| | | }) |
| | | } else { |
| | | tx.executeSql('INSERT INTO VERSIONS (version, createDate) VALUES (?, ?)', [version, curTime], () => { |
| | | resolve() |
| | | }, () => { |
| | | reject() |
| | | }) |
| | | } |
| | | }) |
| | | }) |
| | | }) |
| | | }, () => { |
| | | mkDataBase = null |
| | | _reject() |
| | | if (!window.GLOB.WebSql && !window.GLOB.IndexDB) { |
| | | return Promise.reject() |
| | | }).then(() => { |
| | | _resolve(appVersion) |
| | | }, () => { |
| | | mkDataBase = null |
| | | _reject() |
| | | }) |
| | | } |
| | | |
| | | if (window.GLOB.WebSql) { |
| | | return new Promise((resolve, reject) => { |
| | | CacheUtils.getWebSqlVersion().then(msg => { |
| | | appVersion.oldVersion = msg.version || '' |
| | | let curTime = moment().format('YYYY-MM-DD HH:mm:ss') + '.000' |
| | | let param = { |
| | | func: 's_get_app_version', |
| | | modifydate: msg.createDate || curTime, |
| | | } |
| | | |
| | | this.getSystemConfig(param).then(res => { |
| | | if (!res.status) { |
| | | reject() |
| | | return |
| | | } |
| | | let clear = false |
| | | let version = res.app_version || '1.00' |
| | | appVersion.newVersion = version |
| | | appVersion.oldVersion = appVersion.oldVersion || version |
| | | |
| | | if (res.menu_data && res.menu_data.length > 0) { |
| | | res.menu_data.forEach(mid => { |
| | | if (systemMenuKeys.indexOf(mid.menuid) > -1) { |
| | | clear = true |
| | | } |
| | | }) |
| | | |
| | | if (clear) { |
| | | CacheUtils.clearWebSqlConfig() |
| | | } else { |
| | | let keys = res.menu_data.map(mid => `'${mid.menuid}'`).join(',') |
| | | CacheUtils.delWebSqlConfig(keys) |
| | | } |
| | | } |
| | | |
| | | if (msg.version) { |
| | | CacheUtils.updateWebSqlTime(curTime) |
| | | } else { |
| | | CacheUtils.createWebSqlversion(version, curTime) |
| | | } |
| | | |
| | | resolve(appVersion) |
| | | }) |
| | | }, () => { |
| | | reject() |
| | | }) |
| | | }) |
| | | } else { |
| | | return new Promise((resolve, reject) => { |
| | | CacheUtils.getIndexDBVersion().then(msg => { |
| | | appVersion.oldVersion = msg.version || '' |
| | | let curTime = moment().format('YYYY-MM-DD HH:mm:ss') + '.000' |
| | | let param = { |
| | | func: 's_get_app_version', |
| | | modifydate: msg.createDate || curTime, |
| | | } |
| | | |
| | | this.getSystemConfig(param).then(res => { |
| | | if (!res.status) { |
| | | reject() |
| | | return |
| | | } |
| | | let clear = false |
| | | let version = res.app_version || '1.00' |
| | | appVersion.newVersion = version |
| | | appVersion.oldVersion = appVersion.oldVersion || version |
| | | |
| | | if (res.menu_data && res.menu_data.length > 0) { |
| | | res.menu_data.forEach(mid => { |
| | | if (systemMenuKeys.indexOf(mid.menuid) > -1) { |
| | | clear = true |
| | | } |
| | | }) |
| | | |
| | | if (clear) { |
| | | CacheUtils.clearIndexDBConfig() |
| | | } else { |
| | | let keys = res.menu_data.map(mid => `'${mid.menuid}'`) |
| | | CacheUtils.delIndexDBConfig(keys) |
| | | } |
| | | } |
| | | |
| | | CacheUtils.updateIndexDBversion({version: appVersion.oldVersion, createDate: curTime}) |
| | | |
| | | resolve(appVersion) |
| | | }) |
| | | }, () => { |
| | | reject() |
| | | }) |
| | | }) |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * @description 更新系统版本信息,清空配置信息 |
| | | */ |
| | | updateAppVersion (newVersion) { |
| | | return new Promise(resolve => { |
| | | if (!mkDataBase) { |
| | | resolve({status: false}) |
| | | return |
| | | } |
| | | let curTime = moment().format('YYYY-MM-DD HH:mm:ss') + '.000' |
| | | |
| | | mkDataBase.transaction(tx => { |
| | | tx.executeSql(`DELETE FROM CONFIGS`, [], () => {}, () => { |
| | | resolve({status: false}) |
| | | }) |
| | | tx.executeSql(`UPDATE VERSIONS SET version='${newVersion}', createDate='${curTime}'`, [], () => { |
| | | resolve({status: true}) |
| | | }, () => { |
| | | resolve({status: false}) |
| | | }) |
| | | }) |
| | | }) |
| | | let curTime = moment().format('YYYY-MM-DD HH:mm:ss') + '.000' |
| | | CacheUtils.clearWebSqlConfig() |
| | | CacheUtils.updateWebSqlversion(newVersion, curTime) |
| | | CacheUtils.clearIndexDBConfig() |
| | | CacheUtils.updateIndexDBversion({version: newVersion, createDate: curTime}) |
| | | } |
| | | |
| | | /** |
| | | * @description 删除某个菜单配置信息 |
| | | */ |
| | | deleteMenuStorage (menuId) { |
| | | return new Promise(resolve => { |
| | | if (!mkDataBase) { |
| | | resolve() |
| | | return |
| | | if (window.GLOB.IndexDB) { |
| | | let key = menuId + (sessionStorage.getItem('UserID') || '') |
| | | |
| | | if (sessionStorage.getItem('isEditState') === 'true' && options.cloudServiceApi) { |
| | | key = menuId + (sessionStorage.getItem('CloudUserID') || '') |
| | | } |
| | | mkDataBase.transaction(tx => { |
| | | tx.executeSql(`DELETE FROM CONFIGS where menuid='${menuId}'`, [], () => { |
| | | resolve() |
| | | }, () => { |
| | | mkDataBase = null |
| | | }) |
| | | }) |
| | | }) |
| | | |
| | | return CacheUtils.delMenuIndexDBConfig(key) |
| | | } else { |
| | | return CacheUtils.delMenuWebSqlConfig(menuId) |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * @description 获取或修改云端配置 |
| | | */ |
| | | getCloudConfig (param) { |
| | | param.lang = localStorage.getItem('lang') || '' |
| | | param.lang = param.lang || sessionStorage.getItem('lang') || '' |
| | | param.appkey = window.GLOB.appkey || '' |
| | | param.SessionUid = localStorage.getItem('SessionUid') || '' |
| | | |
| | | if (sessionStorage.getItem('CloudUserID') && options.cloudServiceApi) { // 存在云端登录信息,且存在云端地址 |
| | | param.rduri = options.cloudServiceApi |
| | | param.userid = sessionStorage.getItem('CloudUserID') |
| | | param.LoginUID = sessionStorage.getItem('CloudLoginUID') || '' |
| | | } else if (window.GLOB.mainSystemApi) { |
| | | param.rduri = window.GLOB.mainSystemApi |
| | | param.userid = sessionStorage.getItem('UserID') |
| | | param.LoginUID = sessionStorage.getItem('LoginUID') || '' |
| | | } else { |
| | | param.userid = sessionStorage.getItem('UserID') |
| | | param.LoginUID = sessionStorage.getItem('LoginUID') || '' |
| | | } |
| | | param.userid = sessionStorage.getItem('CloudUserID') || '' |
| | | param.LoginUID = sessionStorage.getItem('CloudLoginUID') || '' |
| | | |
| | | param = this.encryptParam(param) |
| | | |
| | | let url = options.cloudServiceApi ? options.cloudServiceApi : '/webapi/dostars' |
| | | if (param.func) { |
| | | url = url + '/' + param.func |
| | | } |
| | | |
| | | return axios({ |
| | | url: `/webapi/dostars${param.func ? '/' + param.func : ''}`, |
| | | url, |
| | | method: 'post', |
| | | data: param |
| | | }) |
| | | } |
| | | |
| | | /** |
| | | * @description 获取云端配置,并缓存信息 |
| | | */ |
| | | getCloudCacheConfig (param) { |
| | | param.lang = localStorage.getItem('lang') || '' |
| | | param.appkey = window.GLOB.appkey || '' |
| | | param.SessionUid = localStorage.getItem('SessionUid') || '' |
| | | |
| | | if (sessionStorage.getItem('CloudUserID') && options.cloudServiceApi) { // 存在云端登录信息,且存在云端地址 |
| | | param.rduri = options.cloudServiceApi |
| | | param.userid = sessionStorage.getItem('CloudUserID') |
| | | param.LoginUID = sessionStorage.getItem('CloudLoginUID') || '' |
| | | } else if (window.GLOB.mainSystemApi) { |
| | | param.rduri = window.GLOB.mainSystemApi |
| | | param.userid = sessionStorage.getItem('UserID') |
| | | param.LoginUID = sessionStorage.getItem('LoginUID') || '' |
| | | } else { |
| | | param.userid = sessionStorage.getItem('UserID') |
| | | param.LoginUID = sessionStorage.getItem('LoginUID') || '' |
| | | } |
| | | |
| | | let _param = JSON.parse(JSON.stringify(param)) // 缓存校验,去除时间和加密字符 |
| | | delete _param.timestamp |
| | | delete _param.secretkey |
| | | delete _param.open_key |
| | | _param = JSON.stringify(_param) |
| | | _param = md5(_param) |
| | | |
| | | if (window.GLOB.CacheMap.has(_param)) { |
| | | return Promise.resolve(window.GLOB.CacheMap.get(_param)) |
| | | } else { |
| | | param = this.encryptParam(param) |
| | | |
| | | return new Promise(resolve => { |
| | | axios({ |
| | | url: `/webapi/dostars${param.func ? '/' + param.func : ''}`, |
| | | method: 'post', |
| | | data: param |
| | | }).then(res => { |
| | | if (res.status) { |
| | | window.GLOB.CacheMap.set(_param, res) |
| | | } |
| | | resolve(res) |
| | | }) |
| | | }) |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * @description 获取或修改系统配置,增加appkey |
| | | */ |
| | | getSystemConfig (param) { |
| | | param.userid = sessionStorage.getItem('UserID') || '' |
| | | param.lang = localStorage.getItem('lang') || '' |
| | | param.userid = param.userid || sessionStorage.getItem('UserID') || '' |
| | | param.lang = param.lang || sessionStorage.getItem('lang') || '' |
| | | param.SessionUid = localStorage.getItem('SessionUid') || '' |
| | | param.LoginUID = sessionStorage.getItem('LoginUID') || '' |
| | | param.LoginUID = param.LoginUID || sessionStorage.getItem('LoginUID') || '' |
| | | param.appkey = window.GLOB.appkey || '' |
| | | |
| | | let url = '/webapi/dostars' |
| | | if (sessionStorage.getItem('isEditState') === 'true' && options.cloudServiceApi) { // 编辑状态,且存在云端地址 |
| | | param.rduri = options.cloudServiceApi |
| | | url = options.cloudServiceApi |
| | | param.userid = sessionStorage.getItem('CloudUserID') || '' |
| | | param.LoginUID = sessionStorage.getItem('CloudLoginUID') || '' |
| | | } else if (window.GLOB.mainSystemApi) { |
| | | param.rduri = window.GLOB.mainSystemApi |
| | | url = window.GLOB.mainSystemApi |
| | | } |
| | | |
| | | param = this.encryptParam(param) |
| | | |
| | | return axios({ |
| | | url: `/webapi/dostars${param.func ? '/' + param.func : ''}`, |
| | | url: `${url}${param.func ? '/' + param.func : ''}`, |
| | | method: 'post', |
| | | data: param |
| | | }) |
| | |
| | | * @description 获取或修改本地配置,增加appkey |
| | | */ |
| | | getLocalConfig (param) { |
| | | param.userid = sessionStorage.getItem('UserID') || '' |
| | | param.lang = localStorage.getItem('lang') || '' |
| | | param.userid = param.userid || sessionStorage.getItem('UserID') || '' |
| | | param.lang = param.lang || sessionStorage.getItem('lang') || '' |
| | | param.SessionUid = localStorage.getItem('SessionUid') || '' |
| | | param.LoginUID = sessionStorage.getItem('LoginUID') || '' |
| | | param.LoginUID = param.LoginUID || sessionStorage.getItem('LoginUID') || '' |
| | | param.appkey = window.GLOB.appkey || '' |
| | | |
| | | let url = '/webapi/dostars' |
| | | if (param.rduri) { |
| | | url = param.rduri |
| | | delete param.rduri |
| | | } |
| | | |
| | | param = this.encryptParam(param) |
| | | |
| | | return axios({ |
| | | url: `/webapi/dostars${param.func ? '/' + param.func : ''}`, |
| | | url: `${url}${param.func ? '/' + param.func : ''}`, |
| | | method: 'post', |
| | | data: param |
| | | }) |
| | |
| | | */ |
| | | getCacheConfig (param) { |
| | | param.userid = sessionStorage.getItem('UserID') || '' |
| | | param.lang = localStorage.getItem('lang') || '' |
| | | param.lang = param.lang || sessionStorage.getItem('lang') || '' |
| | | param.SessionUid = localStorage.getItem('SessionUid') || '' |
| | | param.LoginUID = sessionStorage.getItem('LoginUID') || '' |
| | | param.appkey = window.GLOB.appkey || '' |
| | | |
| | | let url = '/webapi/dostars' |
| | | if (sessionStorage.getItem('isEditState') === 'true') { // 编辑状态,单点登录服务器为云端 |
| | | if (options.cloudServiceApi) { // 存在云端地址时,使用云端系统参数 |
| | | param.rduri = options.cloudServiceApi |
| | | url = options.cloudServiceApi |
| | | param.userid = sessionStorage.getItem('CloudUserID') || '' |
| | | param.LoginUID = sessionStorage.getItem('CloudLoginUID') || '' |
| | | } |
| | | } else if (window.GLOB.mainSystemApi) { |
| | | param.rduri = window.GLOB.mainSystemApi |
| | | url = window.GLOB.mainSystemApi |
| | | } |
| | | |
| | | let _param = JSON.parse(JSON.stringify(param)) // 缓存校验,去除时间和加密字符 |
| | |
| | | _param = JSON.stringify(_param) |
| | | _param = md5(_param) |
| | | |
| | | if (mkDataBase) { |
| | | param = this.encryptParam(param) |
| | | |
| | | if (window.GLOB.WebSql) { |
| | | return new Promise(resolve => { |
| | | mkDataBase.transaction(tx => { |
| | | tx.executeSql(`SELECT * FROM CONFIGS WHERE menuid='${param.MenuID}' and userid='${param.userid}'`, [], (tx, results) => { |
| | | let paramItem = results.rows[0] |
| | | if (paramItem) { |
| | | resolve({ |
| | | ErrCode: 'S', |
| | | ErrMesg: '', |
| | | LongParam: paramItem.LongParam, |
| | | LongParamUser: paramItem.LongParamUser, |
| | | message: '', |
| | | open_edition: paramItem.openEdition, |
| | | status: true, |
| | | web_edition: paramItem.webEdition |
| | | }) |
| | | } else { |
| | | axios({ |
| | | url: `/webapi/dostars${param.func ? '/' + param.func : ''}`, |
| | | method: 'post', |
| | | data: param |
| | | }).then(res => { |
| | | if (res.status) { |
| | | this.writeInWebSql([param.MenuID, param.userid, res.open_edition, res.web_edition, res.LongParam, res.LongParamUser]) |
| | | } |
| | | resolve(res) |
| | | }) |
| | | CacheUtils.getWebSqlMenuConfig(param.MenuID, param.userid).then(res => { |
| | | resolve(res) |
| | | }, () => { |
| | | param = this.encryptParam(param) |
| | | axios({ |
| | | url: `${url}${param.func ? '/' + param.func : ''}`, |
| | | method: 'post', |
| | | data: param |
| | | }).then(res => { |
| | | if (res.status && window.GLOB.WebSql) { |
| | | CacheUtils.writeInWebSql([param.MenuID, param.userid, res.open_edition, res.web_edition, res.LongParam, res.LongParamUser]) |
| | | } else if (res.status) { |
| | | window.GLOB.CacheMap.set(_param, res) |
| | | } |
| | | }, (tx, results) => { |
| | | mkDataBase = null |
| | | console.warn(results) |
| | | |
| | | axios({ |
| | | url: `/webapi/dostars${param.func ? '/' + param.func : ''}`, |
| | | method: 'post', |
| | | data: param |
| | | }).then(res => { |
| | | if (res.status) { |
| | | window.GLOB.CacheMap.set(_param, res) |
| | | resolve(res) |
| | | }) |
| | | }) |
| | | }) |
| | | } else if (window.GLOB.IndexDB) { |
| | | return new Promise(resolve => { |
| | | CacheUtils.getIndexDBMenuConfig(param.MenuID, param.userid).then(res => { |
| | | resolve(res) |
| | | }, () => { |
| | | param = this.encryptParam(param) |
| | | axios({ |
| | | url: `${url}${param.func ? '/' + param.func : ''}`, |
| | | method: 'post', |
| | | data: param |
| | | }).then(res => { |
| | | if (res.status && window.GLOB.IndexDB) { |
| | | let msg = { |
| | | ...res, |
| | | userid: param.userid, |
| | | menuid: param.MenuID, |
| | | id: param.MenuID + param.userid |
| | | } |
| | | resolve(res) |
| | | }) |
| | | CacheUtils.writeInIndexDB(msg) |
| | | } else if (res.status) { |
| | | window.GLOB.CacheMap.set(_param, res) |
| | | } |
| | | resolve(res) |
| | | }) |
| | | }) |
| | | }) |
| | |
| | | |
| | | return new Promise(resolve => { |
| | | axios({ |
| | | url: `/webapi/dostars${param.func ? '/' + param.func : ''}`, |
| | | url: `${url}${param.func ? '/' + param.func : ''}`, |
| | | method: 'post', |
| | | data: param |
| | | }).then(res => { |
| | |
| | | */ |
| | | getLocalCacheConfig (param) { |
| | | param.userid = sessionStorage.getItem('UserID') || '' |
| | | param.lang = localStorage.getItem('lang') || '' |
| | | param.lang = param.lang || sessionStorage.getItem('lang') || '' |
| | | param.SessionUid = localStorage.getItem('SessionUid') || '' |
| | | param.LoginUID = sessionStorage.getItem('LoginUID') || '' |
| | | param.appkey = window.GLOB.appkey || '' |
| | | |
| | | if (window.GLOB.mainSystemApi) { |
| | | param.rduri = window.GLOB.mainSystemApi |
| | | } |
| | | |
| | | let _param = md5(JSON.stringify(param)) |
| | | |
| | | if (mkDataBase) { |
| | | if (window.GLOB.WebSql) { |
| | | return new Promise(resolve => { |
| | | mkDataBase.transaction(tx => { |
| | | tx.executeSql(`SELECT * FROM CONFIGS WHERE menuid='${param.MenuID}' and userid='${param.userid}'`, [], (tx, results) => { |
| | | let paramItem = results.rows[0] |
| | | if (paramItem) { |
| | | resolve({ ErrCode: 'S', ErrMesg: '', LongParam: paramItem.LongParam, message: '', status: true }) |
| | | } else { |
| | | resolve({ ErrCode: 'S', ErrMesg: '', LongParam: '', message: '', status: false }) |
| | | } |
| | | }, (tx, results) => { |
| | | mkDataBase = null |
| | | resolve({ErrCode: 'S', ErrMesg: '', LongParam: '', message: '', status: false}) |
| | | }) |
| | | CacheUtils.getWebSqlMenuConfig(param.MenuID, param.userid).then(res => { |
| | | resolve(res) |
| | | }, () => { |
| | | resolve({ ErrCode: 'S', ErrMesg: '', LongParam: '', message: '', status: false }) |
| | | }) |
| | | }) |
| | | } else if (window.GLOB.CacheMap.has(_param)) { |
| | |
| | | } else { |
| | | return Promise.resolve({ErrCode: 'S', ErrMesg: '', LongParam: '', message: '', status: false}) |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * @description 将数据写入websql |
| | | */ |
| | | writeInWebSql (data) { |
| | | if (!mkDataBase) return |
| | | mkDataBase.transaction(tx => { |
| | | tx.executeSql('INSERT INTO CONFIGS (menuid, userid, openEdition, webEdition, LongParam, LongParamUser) VALUES (?, ?, ?, ?, ?, ?)', data) |
| | | }) |
| | | } |
| | | |
| | | /** |
| | |
| | | */ |
| | | getSystemCacheConfig (param) { |
| | | param.userid = param.userid || sessionStorage.getItem('UserID') || '' |
| | | param.lang = localStorage.getItem('lang') || '' |
| | | param.lang = param.lang || sessionStorage.getItem('lang') || '' |
| | | param.SessionUid = localStorage.getItem('SessionUid') || '' |
| | | param.LoginUID = param.LoginUID || sessionStorage.getItem('LoginUID') || '' |
| | | param.appkey = window.GLOB.appkey || '' |
| | | |
| | | let url = '/webapi/dostars' |
| | | if (param.rduri) { |
| | | url = param.rduri |
| | | delete param.rduri |
| | | } |
| | | |
| | | let _param = JSON.parse(JSON.stringify(param)) // 缓存校验,去除时间和加密字符 |
| | | delete _param.timestamp |
| | |
| | | |
| | | return new Promise(resolve => { |
| | | axios({ |
| | | url: `/webapi/dostars${param.func ? '/' + param.func : ''}`, |
| | | url: `${url}${param.func ? '/' + param.func : ''}`, |
| | | method: 'post', |
| | | data: param |
| | | }).then(res => { |
| | |
| | | * @description 获取业务通用接口 |
| | | */ |
| | | genericInterface (param) { |
| | | param.userid = sessionStorage.getItem('UserID') |
| | | param.lang = localStorage.getItem('lang') || '' |
| | | param.userid = sessionStorage.getItem('UserID') || '' |
| | | param.lang = sessionStorage.getItem('lang') || '' |
| | | param.SessionUid = localStorage.getItem('SessionUid') || '' |
| | | param.LoginUID = sessionStorage.getItem('LoginUID') || '' |
| | | param.appkey = window.GLOB.appkey || '' |
| | | |
| | | if (options.cloudServiceApi && param.rduri === options.cloudServiceApi) { // HS下菜单 |
| | | param.userid = sessionStorage.getItem('CloudUserID') || '' |
| | | param.LoginUID = sessionStorage.getItem('CloudLoginUID') || '' |
| | | param.userid = sessionStorage.getItem('CloudUserID') || param.userid || '' |
| | | param.LoginUID = sessionStorage.getItem('CloudLoginUID') || param.LoginUID || '' |
| | | } |
| | | |
| | | // 待优化,增加是否支持跨域请求 |
| | | // let url = '/webapi/dostars' |
| | | // if (param.rduri) { |
| | | // url = param.rduri |
| | | // delete param.rduri |
| | | // } |
| | | |
| | | param = this.encryptParam(param) |
| | | |
| | |
| | | */ |
| | | getExcelOut (param, name) { |
| | | param.userid = sessionStorage.getItem('UserID') |
| | | param.lang = localStorage.getItem('lang') || '' |
| | | param.lang = sessionStorage.getItem('lang') || '' |
| | | param.SessionUid = localStorage.getItem('SessionUid') || '' |
| | | param.LoginUID = sessionStorage.getItem('LoginUID') || '' |
| | | param.appkey = window.GLOB.appkey || '' |
| | |
| | | method: 'post', |
| | | data: param |
| | | }).then(res => { |
| | | |
| | | try { |
| | | const blob = new Blob([res]) |
| | | |
| | |
| | | fileuploadbase64 (param) { |
| | | param.func = '' |
| | | param.BasePath = 'Content/Upload' |
| | | param.lang = localStorage.getItem('lang') || '' |
| | | param.lang = sessionStorage.getItem('lang') || '' |
| | | param.appkey = window.GLOB.appkey || '' |
| | | param.SessionUid = localStorage.getItem('SessionUid') || '' |
| | | |
| | |
| | | param = this.encryptParam(param) |
| | | |
| | | if (param.rduri) { |
| | | param.rduri = param.rduri.replace(/webapi(.*)$/, 'webapi/SaveBase64Image') |
| | | let url = param.rduri.replace(/webapi(.*)$/, 'webapi/SaveBase64Image') |
| | | delete param.rduri |
| | | |
| | | return axios({ |
| | | url: '/webapi/dostars', |
| | | url, |
| | | method: 'post', |
| | | data: param |
| | | }) |
| | |
| | | } |
| | | } |
| | | } |
| | | .normal-data-table, .normal-custom-table { |
| | | table { |
| | | .ant-table-tbody { |
| | | > tr:hover:not(.ant-table-expanded-row):not(.ant-table-row-selected) > td { |
| | | background-color: $color1; |
| | | } |
| | | > tr.ant-table-row-selected:not(.background) td { |
| | | background-color: $color1; |
| | | } |
| | | > tr.ant-table-row-selected:not(.background):hover .ant-table-column-sort { |
| | | background-color: $color1; |
| | | } |
| | | > tr.mk-row-active:not(.background) td { |
| | | background-color: $color3; |
| | | } |
| | | > tr.ant-table-row-selected.mk-row-active:not(.background):hover .ant-table-column-sort { |
| | | background-color: $color3; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | .top-search { |
| | | >.ant-row { |
| | | .ant-col.search-button { |
| | | .ant-btn:not(.ant-btn-primary):active, .ant-btn:not(.ant-btn-primary).active, .ant-btn:not(.ant-btn-primary):hover, .ant-btn:not(.ant-btn-primary):focus { |
| | | color: $color7; |
| | | border-color: $color7; |
| | | } |
| | | .ant-btn-primary { |
| | | background-color: $color6; |
| | | border-color: $color6; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | .ant-tabs-nav .ant-tabs-tab-active { |
| | | color: $color6; |
| | | } |
| | |
| | | .ant-tabs-nav .ant-tabs-tab:hover { |
| | | color: $color5; |
| | | } |
| | | .ant-pagination { |
| | | .ant-pagination-item-active { |
| | | border-color: $color6; |
| | | a { |
| | | color: $color6; |
| | | } |
| | | } |
| | | .ant-pagination-item:hover a { |
| | | color: $color6; |
| | | } |
| | | .ant-pagination-prev:hover .ant-pagination-item-link { |
| | | color: $color6; |
| | | } |
| | | .ant-pagination-next:hover .ant-pagination-item-link { |
| | | color: $color6; |
| | | } |
| | | >.mk-breadview-wrap { |
| | | >.ant-breadcrumb { |
| | | .anticon-redo:hover, .anticon-home:hover { |
| | | color: $color5; |
| | | } |
| | | } |
| | | } |
| | |
| | | color: $color5; |
| | | } |
| | | } |
| | | // 搜索栏 |
| | | .top-search { |
| | | >.ant-row { |
| | | .ant-col.search-button { |
| | | .ant-btn:not(.ant-btn-primary):active, .ant-btn:not(.ant-btn-primary).active, .ant-btn:not(.ant-btn-primary):hover, .ant-btn:not(.ant-btn-primary):focus { |
| | | color: $color7; |
| | | border-color: $color7; |
| | | } |
| | | .ant-btn-primary { |
| | | background-color: $color6; |
| | | border-color: $color6; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | // 表格 |
| | | .normal-data-table, .normal-custom-table { |
| | | table { |
| | | .ant-table-tbody { |
| | | > tr:hover:not(.ant-table-expanded-row):not(.ant-table-row-selected) > td { |
| | | background-color: $color1; |
| | | } |
| | | > tr.ant-table-row-selected:not(.background) td { |
| | | background-color: $color1; |
| | | } |
| | | > tr.ant-table-row-selected:not(.background):hover .ant-table-column-sort { |
| | | background-color: $color1; |
| | | } |
| | | > tr.mk-row-active:not(.background) td { |
| | | background-color: $color3; |
| | | } |
| | | > tr.ant-table-row-selected.mk-row-active:not(.background):hover .ant-table-column-sort { |
| | | background-color: $color3; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | // 弹窗按钮 |
| | | .popview-modal { |
| | | .ant-modal-footer { |
| | | .ant-btn:not(.ant-btn-primary):active, .ant-btn:not(.ant-btn-primary).active, .ant-btn:not(.ant-btn-primary):hover, .ant-btn:not(.ant-btn-primary):focus { |
| | | color: $color7; |
| | | border-color: $color7; |
| | | } |
| | | } |
| | | } |
| | | // 表单弹窗 |
| | | .action-modal { |
| | | .ant-modal-footer { |
| | | .ant-btn:not(.ant-btn-primary):active, .ant-btn:not(.ant-btn-primary).active, .ant-btn:not(.ant-btn-primary):hover, .ant-btn:not(.ant-btn-primary):focus { |
| | | color: $color7; |
| | | border-color: $color7; |
| | | } |
| | | .ant-btn-primary { |
| | | background-color: $color6; |
| | | border-color: $color6; |
| | | } |
| | | } |
| | | } |
| | | // 是否框 |
| | | .ant-modal-confirm-confirm { |
| | | .ant-modal-confirm-btns { |
| | | .ant-btn:not(.ant-btn-primary):active, .ant-btn:not(.ant-btn-primary).active, .ant-btn:not(.ant-btn-primary):hover, .ant-btn:not(.ant-btn-primary):focus { |
| | | color: $color7; |
| | | border-color: $color7; |
| | | } |
| | | .ant-btn-primary { |
| | | background-color: $color6; |
| | | border-color: $color6; |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 系统样式修改 |
| | | // .ant-select-dropdown-menu-item:hover:not(.ant-select-dropdown-menu-item-disabled) { |
| | |
| | | let Img = new Image() |
| | | Img.src = this.props.url |
| | | |
| | | if (!this.ImageWrapDom) return |
| | | |
| | | if (Img.complete) { |
| | | this.setSize(Img.width, Img.height) |
| | | } else { |
| | |
| | | } |
| | | |
| | | setSize = (width, height) => { |
| | | if (!this.ImageWrapDom) return |
| | | const { clientWidth, clientHeight } = this.ImageWrapDom |
| | | |
| | | if (!clientWidth || !clientHeight || !width || !height) return |
New file |
| | |
| | | import React, {Component} from 'react' |
| | | import {connect} from 'react-redux' |
| | | import { is, fromJS } from 'immutable' |
| | | import { BackTop, Breadcrumb, Icon} from 'antd' |
| | | import moment from 'moment' |
| | | import 'moment/locale/zh-cn' |
| | | |
| | | import asyncComponent from '@/utils/asyncLoadComponent' |
| | | import NotFount from '@/components/404' |
| | | import mzhCN from '@/locales/zh-CN/main.js' |
| | | import menUS from '@/locales/en-US/main.js' |
| | | import MKEmitter from '@/utils/events.js' |
| | | |
| | | import './index.scss' |
| | | |
| | | const Home = asyncComponent(() => import('@/tabviews/home')) |
| | | const CustomPage = asyncComponent(() => import('@/tabviews/custom')) |
| | | const CommonTable = asyncComponent(() => import('@/tabviews/commontable')) |
| | | const CalendarPage = asyncComponent(() => import('@/tabviews/calendar')) |
| | | const TreePage = asyncComponent(() => import('@/tabviews/treepage')) |
| | | const Iframe = asyncComponent(() => import('@/tabviews/iframe')) |
| | | const RoleManage = asyncComponent(() => import('@/tabviews/rolemanage')) |
| | | const FormTab = asyncComponent(() => import('@/tabviews/formtab')) |
| | | |
| | | let service = '' |
| | | |
| | | if (process.env.NODE_ENV === 'production') { |
| | | service = document.location.origin + '/' + window.GLOB.service + 'zh-CN/' |
| | | } else { |
| | | service = window.GLOB.location + '/' + window.GLOB.service + 'zh-CN/' |
| | | } |
| | | |
| | | class BreadView extends Component { |
| | | state = { |
| | | tabview: null, // 标签 |
| | | dict: sessionStorage.getItem('lang') !== 'en-US' ? mzhCN : menUS, |
| | | hasNavBar: window.GLOB.navBar !== 'linkage' |
| | | } |
| | | |
| | | refreshTabview = () => { |
| | | const { tabview } = this.state |
| | | window.GLOB.CacheMap = new Map() |
| | | |
| | | MKEmitter.emit('reloadMenuView', tabview.MenuID) |
| | | } |
| | | |
| | | selectcomponent = (view) => { |
| | | // 根据tab页中菜单信息,选择所需的组件 |
| | | if (view.type === 'Home') { |
| | | return (<Home MenuNo={view.MenuNo} MenuID={view.MenuID} MenuName={view.MenuName} key={view.MenuID}/>) |
| | | } else if (view.type === 'CommonTable' || view.type === 'ManageTable') { |
| | | return (<CommonTable MenuNo={view.MenuNo} MenuID={view.MenuID} MenuName={view.MenuName} key={view.MenuID} param={view.param}/>) |
| | | } else if (view.type === 'CustomPage') { |
| | | return (<CustomPage MenuNo={view.MenuNo} MenuID={view.MenuID} MenuName={view.MenuName} key={view.MenuID} param={view.param}/>) |
| | | } else if (view.type === 'TreePage') { |
| | | return (<TreePage MenuNo={view.MenuNo} MenuID={view.MenuID} MenuName={view.MenuName} key={view.MenuID} param={view.param}/>) |
| | | } else if (view.type === 'CalendarPage') { |
| | | return (<CalendarPage MenuNo={view.MenuNo} MenuID={view.MenuID} MenuName={view.MenuName} key={view.MenuID} param={view.param}/>) |
| | | } else if (view.type === 'RolePermission') { |
| | | return (<RoleManage MenuNo={view.MenuNo} MenuID={view.MenuID} MenuName={view.MenuName} key={view.MenuID}/>) |
| | | } else if (view.type === 'FormTab') { |
| | | return (<FormTab MenuNo={view.MenuNo} MenuID={view.MenuID} MenuName={view.MenuName} key={view.MenuID} param={view.param}/>) |
| | | } else if (view.type === 'iframe') { |
| | | return (<Iframe key={view.MenuID} MenuID={view.MenuID} MenuNo={view.MenuNo} title={view.MenuName} MenuName={view.MenuName} url={service + view.LinkUrl}/>) |
| | | } else { |
| | | return (<NotFount key={view.MenuID} />) |
| | | } |
| | | } |
| | | |
| | | UNSAFE_componentWillMount () { |
| | | if (!sessionStorage.getItem('lang') || sessionStorage.getItem('lang') === 'zh-CN') { |
| | | moment.locale('zh-cn') |
| | | } else { |
| | | moment.locale('en') |
| | | } |
| | | |
| | | let home = { |
| | | MenuID: 'home_page_id', |
| | | MenuName: this.state.dict['main.homepage'], |
| | | selected: true, |
| | | type: 'Home' |
| | | } |
| | | this.setState({tabview: home}) |
| | | } |
| | | |
| | | gotoHome = () => { |
| | | let home = { |
| | | MenuID: 'home_page_id', |
| | | MenuName: this.state.dict['main.homepage'], |
| | | selected: true, |
| | | type: 'Home' |
| | | } |
| | | this.setState({tabview: home}) |
| | | } |
| | | |
| | | UNSAFE_componentWillReceiveProps (nextProps) { |
| | | if (nextProps.tabviews && !is(fromJS(this.state.tabviews), fromJS(nextProps.tabviews))) { |
| | | // 保存修改标签集 |
| | | this.setState({ |
| | | tabview: nextProps.tabviews[nextProps.tabviews.length - 1] |
| | | }) |
| | | |
| | | let node = document.getElementById('root').parentNode.parentNode |
| | | if (node) { |
| | | node.scrollTop = 0 |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * @description 组件销毁,清除state更新 |
| | | */ |
| | | componentWillUnmount () { |
| | | this.setState = () => { |
| | | return |
| | | } |
| | | } |
| | | |
| | | render () { |
| | | const { tabview, hasNavBar } = this.state |
| | | |
| | | return ( |
| | | <section id="mk-breadview-wrap" className="mk-breadview-wrap"> |
| | | {hasNavBar && tabview ? <Breadcrumb separator=""> |
| | | <Breadcrumb.Item> |
| | | <Icon type="home" onClick={this.gotoHome} /> |
| | | </Breadcrumb.Item> |
| | | {tabview.ParentNames && tabview.ParentNames[0] ? |
| | | <Breadcrumb.Item>{tabview.ParentNames[0]}</Breadcrumb.Item> : null} |
| | | {tabview.ParentNames && tabview.ParentNames[0] ? |
| | | <Breadcrumb.Separator children={<Icon type="right" />} /> : null} |
| | | {tabview.ParentNames && tabview.ParentNames[1] ? |
| | | <Breadcrumb.Item>{tabview.ParentNames[1]}</Breadcrumb.Item> : null} |
| | | {tabview.ParentNames && tabview.ParentNames[1] ? |
| | | <Breadcrumb.Separator children={<Icon type="right" />} /> : null} |
| | | <Breadcrumb.Item><Icon type="redo" onClick={this.refreshTabview}/>{tabview.MenuName}</Breadcrumb.Item> |
| | | </Breadcrumb> : null} |
| | | {tabview ? this.selectcomponent(tabview) : null} |
| | | <BackTop> |
| | | <div className="ant-back-top"> |
| | | <div className="ant-back-top-content"> |
| | | <div className="ant-back-top-icon"></div> |
| | | </div> |
| | | </div> |
| | | </BackTop> |
| | | </section> |
| | | ) |
| | | } |
| | | } |
| | | |
| | | const mapStateToProps = (state) => { |
| | | return { |
| | | tabviews: state.tabviews |
| | | } |
| | | } |
| | | |
| | | const mapDispatchToProps = () => { |
| | | return {} |
| | | } |
| | | |
| | | export default connect(mapStateToProps, mapDispatchToProps)(BreadView) |
New file |
| | |
| | | .mk-breadview-wrap { |
| | | min-height: 100%; |
| | | padding-top: 48px; |
| | | width: 100%; |
| | | box-sizing: content-box; |
| | | >.ant-breadcrumb { |
| | | padding: 10px; |
| | | .anticon-home { |
| | | cursor: pointer; |
| | | margin-right: 10px; |
| | | } |
| | | .anticon-redo { |
| | | cursor: pointer; |
| | | margin-right: 5px; |
| | | } |
| | | .ant-breadcrumb-link + .ant-breadcrumb-separator { |
| | | display: none; |
| | | } |
| | | } |
| | | >.commontable, >.calendar-page { |
| | | padding-left: 15px; |
| | | padding-right: 15px; |
| | | } |
| | | >.commontable, >.calendar-page { |
| | | > .top-search { |
| | | padding-left: 0; |
| | | padding-right: 0; |
| | | margin: 0 24px; |
| | | } |
| | | } |
| | | iframe { |
| | | width: 100%; |
| | | height: calc(100vh - 115px); |
| | | overflow-y: scroll; |
| | | border: 0; |
| | | margin-top: 16px; |
| | | } |
| | | .main-copy { |
| | | position: fixed; |
| | | z-index: 20; |
| | | bottom: 65px; |
| | | right: 30px; |
| | | width: 40px; |
| | | height: 40px; |
| | | i { |
| | | font-size: 18px; |
| | | } |
| | | } |
| | | .main-copy.ifr-copy { |
| | | bottom: 65px; |
| | | right: 40px; |
| | | width: 30px; |
| | | height: 32px; |
| | | border: 2px solid #687991; |
| | | opacity: 0.6; |
| | | i { |
| | | font-size: 14px; |
| | | color: #687991; |
| | | } |
| | | } |
| | | .main-copy.ifr-copy:hover { |
| | | opacity: 1; |
| | | } |
| | | .ant-back-top { |
| | | bottom: 20px; |
| | | right: 30px; |
| | | } |
| | | } |
| | | |
| | | .ant-message { |
| | | top: 50px; |
| | | z-index: 1080; |
| | | } |
| | |
| | | import {connect} from 'react-redux' |
| | | import { is, fromJS } from 'immutable' |
| | | import moment from 'moment' |
| | | import { Dropdown, Menu, Icon, Modal, Form, notification, Switch, Button, Input, Badge } from 'antd' |
| | | import { Dropdown, Menu, Icon, Modal, Form, notification, Switch, Input, Badge } from 'antd' |
| | | |
| | | import asyncComponent from '@/utils/asyncComponent' |
| | | import { |
| | | toggleCollapse, |
| | | modifyMenuTree, |
| | | modifyMainMenu, |
| | | modifyTabview, |
| | | resetState, |
| | | resetEditState, |
| | | resetEditLevel, |
| | | initActionPermission, |
| | | initMenuPermission, |
| | | logout |
| | | } from '@/store/action' |
| | | import Api from '@/api' |
| | | import MKEmitter from '@/utils/events.js' |
| | | import options from '@/store/options.js' |
| | | import zhCN from '@/locales/zh-CN/main.js' |
| | | import enUS from '@/locales/en-US/main.js' |
| | | import Utils from '@/utils/utils.js' |
| | | import avatar from '@/assets/img/avatar.jpg' |
| | | import MainLogo from '@/assets/img/main-logo.png' |
| | | import Resetpwd from './resetpwd' |
| | | import LoginForm from './loginform' |
| | | import './index.scss' |
| | | |
| | | const EditMenu = asyncComponent(() => import('@/templates/menuconfig/editfirstmenu')) |
| | | const { confirm } = Modal |
| | | const { Search } = Input |
| | | |
| | |
| | | state = { |
| | | menulist: null, // 一级菜单 |
| | | visible: false, // 修改密码模态框 |
| | | dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | confirmLoading: false, |
| | | userName: sessionStorage.getItem('User_Name'), |
| | | logourl: window.GLOB.mainlogo, |
| | |
| | | thdMenuList: [], |
| | | oriVersion: '', |
| | | newVersion: '', |
| | | debug: sessionStorage.getItem('debug') === 'true' |
| | | debug: sessionStorage.getItem('debug') === 'true', |
| | | navBar: ['linkage_navigation', 'linkage'].includes(window.GLOB.navBar) ? 'topmenu' : '' |
| | | } |
| | | |
| | | handleCollapse = () => { |
| | | // 展开、收起左侧菜单栏 |
| | | if (!this.props.editState) { |
| | | this.props.toggleCollapse(!this.props.collapse) |
| | | localStorage.setItem('collapse', !this.props.collapse) |
| | | } |
| | | this.props.toggleCollapse(!this.props.collapse) |
| | | localStorage.setItem('collapse', !this.props.collapse) |
| | | } |
| | | |
| | | changePassword = () => { |
| | |
| | | |
| | | changeMenu (value) { |
| | | // 主菜单切换 |
| | | if (this.props.editState && this.props.editLevel) { |
| | | // 编辑状态下,不可切换菜单 |
| | | return |
| | | } |
| | | |
| | | if (value.PageParam.OpenType === 'menu') { |
| | | if (value.OpenType === 'outpage' && value.linkUrl) { |
| | | window.open(value.linkUrl) |
| | | } else if (value.OpenType === 'menu') { |
| | | this.props.modifyMainMenu(value) |
| | | } else if (value.PageParam.OpenType === 'outpage') { |
| | | window.open(value.PageParam.linkUrl) |
| | | } |
| | | } |
| | | |
| | | async loadmenu () { |
| | | // 获取主菜单 |
| | | let _param = {func: 's_get_pc_menus', systemType: options.sysType} |
| | | if (sessionStorage.getItem('isEditState') === 'true') { // 编辑状态时,增加参数debug |
| | | _param.debug = 'Y' |
| | | } |
| | | if (options.sysType !== 'cloud' && window.GLOB.systemType !== 'production') { |
| | | _param.linkurl = window.GLOB.linkurl |
| | | } |
| | | _param.pro_sys = window.GLOB.systemType === 'production' ? 'Y' : '' |
| | | |
| | | let result = await Api.getSystemConfig(_param) |
| | | |
| | | // 登录超时 |
| | | if (!result) return |
| | | |
| | | if (result.status) { |
| | | const { menulist } = this.getMenulist(result) |
| | | |
| | | this.setState({ |
| | | menulist, |
| | | systems: [] |
| | | }) |
| | | |
| | | this.props.modifyMenuTree(menulist) |
| | | this.props.modifyMainMenu(menulist[0] || null) |
| | | } else { |
| | | notification.error({ |
| | | top: 92, |
| | | message: result.message, |
| | | duration: 10 |
| | | }) |
| | | } |
| | | } |
| | | |
| | |
| | | // 获取主菜单参数 |
| | | let menudefer = new Promise(resolve => { |
| | | let _param = {func: 's_get_pc_menus', systemType: options.sysType} |
| | | if (options.sysType !== 'cloud' && window.GLOB.systemType !== 'production') { |
| | | _param.linkurl = window.GLOB.linkurl |
| | | } |
| | | _param.pro_sys = window.GLOB.systemType === 'production' ? 'Y' : '' |
| | | |
| | | Api.getSystemConfig(_param).then(result => { |
| | |
| | | let tabs = fromJS(this.props.tabviews).toJS() |
| | | let menu = fromJS(response[1]).toJS() |
| | | |
| | | tabs = tabs.map(tab => { |
| | | tab.selected = false |
| | | return tab |
| | | }) |
| | | if (this.state.navBar === 'topmenu') { |
| | | menu.selected = true |
| | | this.props.modifyTabview([menu]) |
| | | } else { |
| | | tabs = tabs.map(tab => { |
| | | tab.selected = false |
| | | return tab |
| | | }) |
| | | |
| | | menu.selected = true |
| | | tabs.push(menu) |
| | | this.props.modifyTabview(tabs) |
| | | menu.selected = true |
| | | tabs.push(menu) |
| | | this.props.modifyTabview(tabs) |
| | | } |
| | | } |
| | | }) |
| | | } |
| | |
| | | let fstItem = { |
| | | MenuID: fst.MenuID, |
| | | MenuName: fst.MenuName, |
| | | PageParam: {OpenType: 'menu', linkUrl: ''}, |
| | | OpenType: 'menu', |
| | | children: [] |
| | | } |
| | | if (fst.PageParam) { |
| | | try { |
| | | fstItem.PageParam = JSON.parse(fst.PageParam) |
| | | } catch (e) { |
| | | fstItem.PageParam = {OpenType: 'menu', linkUrl: ''} |
| | | fstItem.PageParam = null |
| | | } |
| | | if (fstItem.PageParam && fstItem.PageParam.OpenType === 'outpage' && fstItem.PageParam.linkUrl) { |
| | | fstItem.OpenType = 'outpage' |
| | | fstItem.linkUrl = fstItem.PageParam.linkUrl |
| | | } |
| | | } |
| | | |
| | |
| | | debug: sessionStorage.getItem('debug'), |
| | | role_id: sessionStorage.getItem('role_id'), |
| | | mainlogo: window.GLOB.mainlogo, |
| | | navBar: window.GLOB.navBar || '', |
| | | mstyle: window.GLOB.style |
| | | } |
| | | |
| | |
| | | ParentId: snd.MenuID, |
| | | MenuID: trd.MenuID, |
| | | MenuName: trd.MenuName, |
| | | ParentNames: [fst.MenuName, snd.MenuName], |
| | | MenuNo: trd.MenuNo, |
| | | EasyCode: trd.EasyCode, |
| | | type: 'CommonTable', // 默认值为常用表 |
| | |
| | | |
| | | if (trd.LinkUrl && iframes.includes(trd.LinkUrl.split('?')[0])) { |
| | | trdItem.type = 'iframe' |
| | | trdItem.LinkUrl = trd.LinkUrl |
| | | trdItem.forbidden = true |
| | | trdItem.LinkUrl = trd.LinkUrl.replace('&', '&') |
| | | } else { |
| | | try { |
| | | trdItem.PageParam = trd.PageParam ? JSON.parse(trd.PageParam) : {OpenType: 'newtab'} |
| | |
| | | trdItem.type = trdItem.PageParam.Template || trdItem.type |
| | | trdItem.OpenType = trdItem.PageParam.OpenType || trdItem.OpenType |
| | | |
| | | if (trdItem.type === 'CustomPage' && this.props.memberLevel < 20) { // 会员等级大于等于20时,有编辑权限 |
| | | trdItem.forbidden = true |
| | | } |
| | | if (trdItem.type === 'NewPage') { |
| | | trdItem.src = trdItem.PageParam.url || '' |
| | | |
| | |
| | | return { menulist, thdMenuList } |
| | | } |
| | | |
| | | reload = () => { |
| | | this.loadmenu() |
| | | } |
| | | |
| | | changeEditState = (state) => { |
| | | if (!state) { // 退出编辑,页面刷新 |
| | | window.location.reload() |
| | | return |
| | | } |
| | | |
| | | changeEditState = () => { |
| | | // 修改编辑状态 |
| | | let UserID = sessionStorage.getItem('CloudUserID') |
| | | let LoginUID = sessionStorage.getItem('CloudLoginUID') |
| | |
| | | loginVisible: true |
| | | }) |
| | | } else { |
| | | sessionStorage.setItem('isEditState', 'true') |
| | | sessionStorage.setItem('role_id', sessionStorage.getItem('cloudRole_id')) |
| | | sessionStorage.setItem('dataM', sessionStorage.getItem('cloudDataM')) |
| | | sessionStorage.setItem('isEditState', 'true') |
| | | |
| | | if (window.GLOB.systemType === 'production') { |
| | | this.props.resetEditLevel('HS') |
| | | this.props.modifyMainMenu({ |
| | | MenuID: 'systemManageView' |
| | | }) |
| | | |
| | | this.setState({ |
| | | userName: sessionStorage.getItem('CloudUserName'), |
| | | avatar: Utils.getrealurl(sessionStorage.getItem('CloudAvatar')) |
| | | }) |
| | | this.props.resetEditState(state) |
| | | |
| | | return |
| | | } |
| | | |
| | | this.setState({ |
| | | menulist: null, |
| | | userName: sessionStorage.getItem('CloudUserName'), |
| | | avatar: Utils.getrealurl(sessionStorage.getItem('CloudAvatar')) |
| | | }) |
| | | this.loadmenu() |
| | | this.props.modifyMenuTree([]) |
| | | this.props.modifyMainMenu(null) |
| | | this.props.resetEditState(state) |
| | | } |
| | | this.props.modifyTabview([]) |
| | | |
| | | if (window.GLOB.systemType !== 'production') { |
| | | Api.getSystemConfig({func: 'sPC_Get_Roles_sModular'}).then(res => { |
| | | if (res.status) { |
| | | let _permFuncField = [] |
| | | let _sysRoles = [] |
| | | |
| | | if (res.Roles && res.Roles.length > 0) { |
| | | _sysRoles = res.Roles.map(role => { |
| | | return { |
| | | uuid: Utils.getuuid(), |
| | | value: role.RoleID, |
| | | text: role.RoleName |
| | | } |
| | | }) |
| | | } |
| | | |
| | | if (res.sModular && res.sModular.length > 0) { |
| | | res.sModular.forEach(field => { |
| | | if (field.ModularNo) { |
| | | _permFuncField.push(field.ModularNo) |
| | | } |
| | | }) |
| | | _permFuncField = _permFuncField.sort() |
| | | } |
| | | |
| | | sessionStorage.setItem('sysRoles', JSON.stringify(_sysRoles)) |
| | | sessionStorage.setItem('permFuncField', JSON.stringify(_permFuncField)) |
| | | } |
| | | }) |
| | | this.props.history.replace('/design') |
| | | } |
| | | } |
| | | |
| | |
| | | sessionStorage.setItem('dataM', res.dataM ? 'true' : '') |
| | | sessionStorage.setItem('isEditState', 'true') |
| | | |
| | | if (window.GLOB.systemType === 'production') { |
| | | this.props.resetEditLevel('HS') |
| | | this.props.modifyMainMenu({ |
| | | MenuID: 'systemManageView' |
| | | }) |
| | | |
| | | this.setState({ |
| | | loginVisible: false, |
| | | loginLoading: false, |
| | | userName: res.UserName, |
| | | avatar: res.icon |
| | | }) |
| | | this.props.resetEditState(true) |
| | | |
| | | return |
| | | } |
| | | |
| | | this.setState({ |
| | | menulist: null, |
| | | loginVisible: false, |
| | | loginLoading: false, |
| | | userName: res.UserName, |
| | | avatar: res.icon |
| | | }) |
| | | this.loadmenu() |
| | | this.props.modifyMenuTree([]) |
| | | this.props.modifyMainMenu(null) |
| | | this.props.resetEditState(true) |
| | | this.props.modifyTabview([]) |
| | | |
| | | this.props.history.replace('/design') |
| | | } else { |
| | | this.setState({ |
| | | loginLoading: false |
| | |
| | | } |
| | | }) |
| | | }) |
| | | } |
| | | |
| | | enterEdit = () => { |
| | | // 进入编辑状态 |
| | | this.props.resetEditLevel('level1') |
| | | } |
| | | |
| | | enterEditManage = () => { |
| | | const { editLevel } = this.props |
| | | |
| | | if (editLevel === 'HS') return |
| | | |
| | | this.props.resetEditLevel('HS') |
| | | this.props.modifyMainMenu({ |
| | | MenuID: 'systemManageView' |
| | | }) |
| | | } |
| | | |
| | | /** |
| | | * @description 退出管理界面菜单 |
| | | */ |
| | | exitManage = () => { |
| | | const { menulist } = this.state |
| | | |
| | | if (window.GLOB.systemType === 'production') { // 正式系统版本升级后,页面刷新 |
| | | window.location.reload() |
| | | return |
| | | } |
| | | |
| | | this.props.modifyMainMenu(menulist[0] || null) |
| | | this.props.resetEditLevel(false) |
| | | this.props.modifyTabview([]) |
| | | } |
| | | |
| | | exitEdit = () => { |
| | | // 退出编辑状态 |
| | | this.props.resetEditLevel(false) |
| | | } |
| | | |
| | | changeSystem = (system) => { |
| | |
| | | } |
| | | }) |
| | | } |
| | | |
| | | selectMenu = (item) => { |
| | | let tabs = fromJS(this.props.tabviews).toJS() |
| | | let menu = fromJS(item).toJS() |
| | | menu.selected = true |
| | | |
| | | tabs = tabs.filter(tab => { |
| | | tab.selected = false |
| | | return tab.MenuID !== menu.MenuID |
| | | }) |
| | | |
| | | if (this.props.tabviews.length !== tabs.length) { |
| | | this.props.modifyTabview(fromJS(tabs).toJS()) |
| | | } |
| | | |
| | | this.setState({}, () => { |
| | | tabs.push(menu) |
| | | this.props.modifyTabview(tabs) |
| | | }) |
| | | } |
| | | |
| | | UNSAFE_componentWillMount () { |
| | | // 组件加载时,获取菜单数据 |
| | |
| | | componentDidMount () { |
| | | // 获取系统的版本信息,延时查询 |
| | | setTimeout(() => { |
| | | new Promise((resolve, reject) => { |
| | | Api.getAppVersion(resolve, reject) |
| | | }).then(res => { |
| | | Api.getAppVersion().then(res => { |
| | | this.setState({ |
| | | oriVersion: res.oldVersion, |
| | | newVersion: res.newVersion |
| | | }) |
| | | }, () => { |
| | | console.warn('websql 初始化错误!') |
| | | }) |
| | | }, () => {}) |
| | | }, 1000) |
| | | } |
| | | |
| | | shouldComponentUpdate (nextProps, nextState) { |
| | | return !is(fromJS(this.props), fromJS(nextProps)) || !is(fromJS(this.state), fromJS(nextState)) |
| | | } |
| | | |
| | | /** |
| | | * @description 组件销毁,清除state更新 |
| | | */ |
| | | componentWillUnmount () { |
| | | this.setState = () => { |
| | | return |
| | | } |
| | | } |
| | | |
| | | verup = () => { |
| | |
| | | content: `最新版本${newVersion},当前版本${oriVersion}`, |
| | | onOk() { |
| | | return new Promise(resolve => { |
| | | Api.updateAppVersion(newVersion).then(res => { |
| | | if (res.status) { |
| | | notification.success({ |
| | | top: 92, |
| | | message: '升级成功!', |
| | | duration: 2 |
| | | }) |
| | | _this.setState({oriVersion: newVersion}) |
| | | } else { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '升级失败,请刷新页面重试!', |
| | | duration: 2 |
| | | }) |
| | | } |
| | | if (!window.GLOB.WebSql) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '升级失败,请刷新页面重试!', |
| | | duration: 2 |
| | | }) |
| | | resolve() |
| | | }) |
| | | } else { |
| | | Api.updateAppVersion(newVersion) |
| | | notification.success({ |
| | | top: 92, |
| | | message: '升级成功!', |
| | | duration: 2 |
| | | }) |
| | | _this.setState({oriVersion: newVersion}) |
| | | resolve() |
| | | } |
| | | }) |
| | | }, |
| | | onCancel() {} |
| | |
| | | } |
| | | } |
| | | |
| | | changeVerMenu(menu, type) { |
| | | if (type === 'first') { |
| | | if (menu.OpenType === 'outpage' && menu.linkUrl) { |
| | | window.open(menu.linkUrl) |
| | | } else if (menu.OpenType === 'menu') { |
| | | |
| | | } |
| | | } else { |
| | | if (menu.OpenType === 'newpage' || menu.OpenType === 'NewPage') { // NewPage为打开外部页面地址,newpage为打开系统菜单 |
| | | window.open(menu.src) |
| | | } else if (menu.OpenType === 'blank') { |
| | | menu.selected = true |
| | | this.props.modifyTabview([menu]) |
| | | } else if (this.state.navBar === 'topmenu') { |
| | | menu.selected = true |
| | | this.props.modifyTabview([menu]) |
| | | } else { |
| | | let tabs = fromJS(this.props.tabviews).toJS() |
| | | tabs = tabs.filter(tab => { |
| | | tab.selected = false |
| | | return tab.MenuID !== menu.MenuID |
| | | }) |
| | | |
| | | if (this.props.tabviews.length > tabs.length) { |
| | | this.props.modifyTabview(fromJS(tabs).toJS()) |
| | | } |
| | | |
| | | this.setState({}, () => { |
| | | menu.selected = true |
| | | tabs.push(menu) |
| | | this.props.modifyTabview(tabs) |
| | | }) |
| | | } |
| | | |
| | | if (window.GLOB.systemType === 'production') { |
| | | MKEmitter.emit('queryTrigger', {menuId: menu.MenuID, name: '菜单'}) |
| | | } |
| | | } |
| | | } |
| | | |
| | | render () { |
| | | const { mainMenu, collapse } = this.props |
| | | const { thdMenuList, searchkey, oriVersion, newVersion, debug, menulist } = this.state |
| | | const { thdMenuList, searchkey, oriVersion, newVersion, debug, menulist, navBar } = this.state |
| | | |
| | | const menu = ( |
| | | <Menu className="header-dropdown"> |
| | | {debug && <Menu.Item key="switch"> |
| | | {this.state.dict['main.edit']} |
| | | <Switch size="small" style={{marginLeft: '7px'}} disabled={!!this.props.editLevel} checked={this.props.editState} onChange={this.changeEditState} /> |
| | | <Switch size="small" style={{marginLeft: '7px'}} checked={false} onChange={this.changeEditState} /> |
| | | </Menu.Item>} |
| | | {!this.props.editState ? <Menu.Item key="password" onClick={this.changePassword}>{this.state.dict['main.password']}</Menu.Item> : null} |
| | | <Menu.Item key="password" onClick={this.changePassword}>{this.state.dict['main.password']}</Menu.Item> |
| | | {this.state.systems.length ? <Menu.SubMenu style={{minWidth: '110px'}} title="切换系统"> |
| | | {this.state.systems.map((system, index) => ( |
| | | <Menu.Item style={{minWidth: '100px', lineHeight: '30px'}} key={'sub' + index} onClick={() => {this.changeSystem(system)}}> {system.AppName} </Menu.Item> |
| | |
| | | |
| | | return ( |
| | | <header className="header-container ant-menu-dark" id="main-header-container"> |
| | | <div className={'header-logo ' + (collapse ? 'collapse' : '')}><img src={!this.props.editState ? this.state.logourl : MainLogo} alt=""/></div> |
| | | <div className={'header-collapse ' + (collapse ? 'collapse' : '')}> |
| | | {menulist && menulist.length ? <Icon type={collapse ? 'menu-unfold' : 'menu-fold'} onClick={this.handleCollapse}/> : null} |
| | | <div className={'header-logo ' + (collapse && navBar !== 'topmenu' ? 'collapse' : '')}><img src={this.state.logourl} alt=""/></div> |
| | | <div className={'header-collapse ' + (collapse && navBar !== 'topmenu' ? 'collapse' : '')}> |
| | | {navBar !== 'topmenu' ? <Icon type={collapse ? 'menu-unfold' : 'menu-fold'} onClick={this.handleCollapse}/> : null} |
| | | </div> |
| | | {/* 正常菜单 */} |
| | | {this.props.editLevel !== 'level1' && menulist ? |
| | | <ul className={'header-menu ' + this.props.editLevel}>{ |
| | | {navBar !== 'topmenu' && menulist ? |
| | | <ul className="header-menu">{ |
| | | menulist.map(item => { |
| | | return ( |
| | | <li key={item.MenuID} onClick={() => {this.changeMenu(item)}} className={mainMenu && mainMenu.MenuID === item.MenuID ? 'active' : ''}> |
| | |
| | | </li> |
| | | ) |
| | | })} |
| | | {this.props.editState && (!this.props.editLevel || this.props.editLevel === 'HS') ? |
| | | <li key="HS" onClick={this.enterEditManage} className={this.props.editLevel === 'HS' ? 'active' : ''}> |
| | | <span>HS</span> |
| | | </li> : null |
| | | } |
| | | </ul> : null |
| | | } |
| | | {this.props.editLevel === 'HS' ? <Button className="level4-close" type="primary" onClick={this.exitManage}>退出</Button> : null} |
| | | {/* 进入编辑按钮 */} |
| | | {this.props.editState && !this.props.editLevel ? <Icon onClick={this.enterEdit} className="edit-check" type="edit" /> : null} |
| | | {/* {this.props.editState && !this.props.editLevel && options.sysType === 'local' && window.GLOB.systemType !== 'production' ? |
| | | <a href="#/mobmanage" target="_blank" className="mobile" type="edit"> 应用管理 <Icon type="arrow-right" /></a> : null |
| | | } */} |
| | | {/* window.btoa(window.encodeURIComponent(JSON.stringify({ MenuType: 'home', MenuId: 'home_page_id', MenuName: '首页' }))) */} |
| | | {this.props.editState && !this.props.editLevel && window.GLOB.systemType !== 'production' && this.props.memberLevel >= 20 ? |
| | | <a className="home-edit" href={`#/menudesign/JTdCJTIyTWVudVR5cGUlMjIlM0ElMjJob21lJTIyJTJDJTIyTWVudUlkJTIyJTNBJTIyaG9tZV9wYWdlX2lkJTIyJTJDJTIyTWVudU5hbWUlMjIlM0ElMjIlRTklQTYlOTYlRTklQTElQjUlMjIlN0Q=`} target="_blank" rel="noopener noreferrer"> |
| | | 首页 <Icon type="arrow-right" /> |
| | | </a> : null |
| | | {/* 正常菜单 */} |
| | | {navBar === 'topmenu' && menulist ? |
| | | <ul className="header-menu vertical-menu">{ |
| | | menulist.map(item => { |
| | | if (item.children && item.children.length > 0) { |
| | | return ( |
| | | <Dropdown key={item.MenuID} overlayClassName="vertical-dropdown-menu" overlay={ |
| | | <Menu mode="vertical"> |
| | | {item.children.map(cell => { |
| | | if (!cell.children || cell.children.length === 0) { |
| | | return ( |
| | | <Menu.Item key={cell.MenuID}> |
| | | {cell.MenuName} |
| | | </Menu.Item> |
| | | ) |
| | | } else { |
| | | return ( |
| | | <Menu.SubMenu popupClassName="vertical-dropdown-submenu" key={cell.MenuID} title={cell.MenuName}> |
| | | {cell.children.map(m => ( |
| | | <Menu.Item key={m.MenuID} onClick={() => {this.changeVerMenu(m)}}> |
| | | {m.MenuName} |
| | | </Menu.Item> |
| | | ))} |
| | | </Menu.SubMenu> |
| | | ) |
| | | } |
| | | })} |
| | | </Menu> |
| | | }> |
| | | <li> |
| | | <span>{item.MenuName}</span> |
| | | </li> |
| | | </Dropdown> |
| | | ) |
| | | } else { |
| | | return ( |
| | | <li key={item.MenuID} onClick={() => {this.changeVerMenu(item, 'first')}}> |
| | | <span>{item.MenuName}</span> |
| | | </li> |
| | | ) |
| | | } |
| | | })} |
| | | </ul> : null |
| | | } |
| | | {/* 编辑菜单 */} |
| | | {this.props.editLevel === 'level1' ? <EditMenu menulist={this.state.menulist} reload={this.reload} exitEdit={this.exitEdit}/> : null} |
| | | {/* 头像、用户名 */} |
| | | <Dropdown className="header-setting" overlay={menu}> |
| | | <div> |
| | |
| | | </div> |
| | | </Dropdown> |
| | | {/* 菜单搜索 */} |
| | | {!this.props.editState && thdMenuList.length > 0 ? |
| | | {thdMenuList.length > 0 ? |
| | | <Dropdown overlayClassName="menu-select-dropdown" getPopupContainer={() => document.getElementById('main-header-container')} overlay={ |
| | | <div> |
| | | <Search |
| | |
| | | option.MenuNo.toLowerCase().indexOf(searchkey.toLowerCase()) >= 0 || |
| | | option.EasyCode.toLowerCase().indexOf(searchkey.toLowerCase()) >= 0 |
| | | ) { |
| | | return <Menu.Item key={option.MenuID} onClick={() => this.selectMenu(option)}>{option.MenuName}</Menu.Item> |
| | | return <Menu.Item key={option.MenuID} onClick={() => this.changeVerMenu(option)}>{option.MenuName}</Menu.Item> |
| | | } else { |
| | | return null |
| | | } |
| | | } |
| | | return <Menu.Item key={option.MenuID} onClick={() => this.selectMenu(option)}>{option.MenuName}</Menu.Item> |
| | | return <Menu.Item key={option.MenuID} onClick={() => this.changeVerMenu(option)}>{option.MenuName}</Menu.Item> |
| | | })} |
| | | </Menu> |
| | | </div> |
| | |
| | | collapse: state.collapse, |
| | | menuTree: state.menuTree, |
| | | mainMenu: state.mainMenu, |
| | | editState: state.editState, |
| | | editLevel: state.editLevel, |
| | | permAction: state.permAction, |
| | | memberLevel: state.memberLevel |
| | | } |
| | | } |
| | | |
| | |
| | | modifyTabview: (tabviews) => dispatch(modifyTabview(tabviews)), |
| | | modifyMenuTree: (menuTree) => dispatch(modifyMenuTree(menuTree)), |
| | | modifyMainMenu: (mainMenu) => dispatch(modifyMainMenu(mainMenu)), |
| | | resetEditState: (state) => dispatch(resetEditState(state)), |
| | | resetEditLevel: (level) => dispatch(resetEditLevel(level)), |
| | | initActionPermission: (permAction) => dispatch(initActionPermission(permAction)), |
| | | initMenuPermission: (permMenus) => dispatch(initMenuPermission(permMenus)), |
| | | resetState: () => dispatch(resetState()), |
| | | logout: () => dispatch(logout()) |
| | | } |
| | | } |
| | |
| | | @import '../../assets/css/global.scss'; |
| | | |
| | | .header-container { |
| | | position: fixed; |
| | | z-index: 1060; |
| | | z-index: 20; |
| | | left: 0; |
| | | top: 0; |
| | | font-weight: bold!important; |
| | |
| | | } |
| | | } |
| | | } |
| | | |
| | | .header-menu.level4 { |
| | | li { |
| | | cursor: default; |
| | | &:hover { |
| | | span { |
| | | cursor: default; |
| | | color: rgba(255, 255, 255, 0.65); |
| | | border-bottom: none; |
| | | } |
| | | } |
| | | &.active { |
| | | span { |
| | | color: #ffffff; |
| | | border-bottom: 4px solid #1890ff; |
| | | } |
| | | .header-menu.vertical-menu { |
| | | >li { |
| | | >span { |
| | | border-color: transparent!important; |
| | | } |
| | | } |
| | | } |
| | |
| | | } |
| | | } |
| | | } |
| | | .edit-check { |
| | | font-size: 18px; |
| | | margin-top: 14px; |
| | | margin-left: 10px; |
| | | cursor: pointer; |
| | | } |
| | | |
| | | .search-menu { |
| | | float: right; |
| | | font-size: 18px; |
| | | margin-top: 17px; |
| | | margin-right: 20px; |
| | | cursor: pointer; |
| | | } |
| | | .level4-close { |
| | | position: relative; |
| | | top: 13px; |
| | | left: 20px; |
| | | height: 26px; |
| | | padding: 0 10px; |
| | | } |
| | | .menu-select-dropdown { |
| | | top: 48px!important; |
| | |
| | | background: rgba(0, 0, 0, 0); |
| | | } |
| | | } |
| | | .mobile { |
| | | position: absolute; |
| | | top: 135px; |
| | | right: 50px; |
| | | color: #1890ff; |
| | | } |
| | | .home-edit { |
| | | position: absolute; |
| | | top: 100px; |
| | | right: 50px; |
| | | color: #1890ff; |
| | | } |
| | | } |
| | | .header-dropdown { |
| | | >li { |
| | |
| | | } |
| | | } |
| | | } |
| | | |
| | | .vertical-dropdown-menu, .vertical-dropdown-submenu { |
| | | ul.ant-dropdown-menu { |
| | | min-width: 125px; |
| | | } |
| | | .ant-dropdown-menu-submenu-title { |
| | | padding-right: 30px; |
| | | } |
| | | } |
| | |
| | | } |
| | | |
| | | state = { |
| | | dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS |
| | | dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS |
| | | } |
| | | |
| | | handleConfirm = () => { |
| | |
| | | import Utils from '@/utils/utils.js' |
| | | import MKEmitter from '@/utils/events.js' |
| | | |
| | | /** |
| | | * @description 操作记录,每隔六分钟更新一次 |
| | | */ |
| | | class QueryLog extends Component { |
| | | state = { |
| | | logs: [] |
| | |
| | | import React, {Component} from 'react' |
| | | import { withRouter } from 'react-router-dom' |
| | | import PropTypes from 'prop-types' |
| | | import { connect } from 'react-redux' |
| | | import { is, fromJS } from 'immutable' |
| | | import { Menu, Icon, notification } from 'antd' |
| | | import { Menu, Icon } from 'antd' |
| | | |
| | | import asyncComponent from '@/utils/asyncComponent' |
| | | import { modifyTabview, resetEditLevel, modifyMenuTree, modifyMainMenu } from '@/store/action' |
| | | import { SySMenuList } from './config' |
| | | import options from '@/store/options.js' |
| | | import { modifyTabview } from '@/store/action' |
| | | import MKEmitter from '@/utils/events.js' |
| | | import zhCN from '@/locales/zh-CN/main.js' |
| | | import enUS from '@/locales/en-US/main.js' |
| | | import Api from '@/api' |
| | | import './index.scss' |
| | | |
| | | const EditSecMenu = asyncComponent(() => import('@/templates/menuconfig/editsecmenu')) |
| | | const EditThdMenu = asyncComponent(() => import('@/templates/menuconfig/editthdmenu')) |
| | | const { SubMenu } = Menu |
| | | |
| | | class Sidemenu extends Component { |
| | |
| | | } |
| | | |
| | | state = { |
| | | dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | subMenulist: [], // 二级菜单 |
| | | editMenu: null, // 编辑三级菜单时设置 |
| | | rootSubmenuKeys: null, |
| | | createThirdMenu: false, |
| | | openKeys: null, |
| | | preview: null |
| | | } |
| | |
| | | subMenulist: [], |
| | | rootSubmenuKeys: [], |
| | | openKeys: [], |
| | | editMenu: null |
| | | }) |
| | | return |
| | | } |
| | |
| | | subMenulist: menu.children, |
| | | rootSubmenuKeys: menu.children.map(item => item.MenuID), |
| | | openKeys: this.props.collapse ? [] : [openKey], |
| | | editMenu: this.props.editLevel === 'level3' ? menu.children.filter(_menu => _menu.MenuID === this.state.editMenu.MenuID)[0] : null |
| | | }) |
| | | } |
| | | |
| | | enterManageView = () => { |
| | | let menulist = SySMenuList |
| | | |
| | | if (window.GLOB.systemType === 'production') { |
| | | menulist.forEach(menu => { |
| | | menu.children = menu.children.filter(item => item.systems && item.systems.includes(window.GLOB.systemType)) |
| | | }) |
| | | |
| | | menulist = menulist.filter(menu => menu.children.length > 0) |
| | | } else { |
| | | menulist.forEach(menu => { |
| | | menu.children = menu.children.filter(item => !item.systems || item.systems.includes(options.sysType)) |
| | | }) |
| | | |
| | | menulist = menulist.filter(menu => menu.children.length > 0) |
| | | } |
| | | |
| | | this.setState({ |
| | | subMenulist: menulist, |
| | | rootSubmenuKeys: menulist.map(item => item.MenuID), |
| | | openKeys: this.props.collapse ? [] : [menulist[0].MenuID] |
| | | }) |
| | | } |
| | | |
| | | changemenu(e, menu) { |
| | | e.preventDefault() |
| | | if (this.props.editState && this.props.editLevel !== 'HS') { |
| | | return |
| | | } |
| | | |
| | | if (menu.OpenType === 'newpage' || menu.OpenType === 'NewPage') { |
| | | window.open(menu.src) |
| | |
| | | return tab.MenuID !== menu.MenuID |
| | | }) |
| | | |
| | | if (this.props.tabviews.length !== tabs.length) { |
| | | if (this.props.tabviews.length > tabs.length) { |
| | | this.props.modifyTabview(fromJS(tabs).toJS()) |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | UNSAFE_componentWillReceiveProps (nextProps) { |
| | | if (!is(fromJS(this.props.mainMenu), fromJS(nextProps.mainMenu)) && nextProps.mainMenu && nextProps.mainMenu.MenuID === 'systemManageView') { |
| | | this.enterManageView() |
| | | } else if (!is(fromJS(this.props.mainMenu), fromJS(nextProps.mainMenu))) { |
| | | if (!is(fromJS(this.props.mainMenu), fromJS(nextProps.mainMenu))) { |
| | | // 主菜单切换,请求2、3级菜单数据 |
| | | this.loadsubmenu(nextProps.mainMenu) |
| | | } else if (nextProps.collapse && this.props.collapse !== nextProps.collapse) { |
| | |
| | | } |
| | | } |
| | | |
| | | enterSubEdit = (e) => { |
| | | // 编辑二级菜单 |
| | | e.stopPropagation() |
| | | this.props.resetEditLevel('level2') |
| | | } |
| | | |
| | | enterThrEdit = (e, menu) => { |
| | | // 编辑三级菜单 |
| | | e.stopPropagation() |
| | | this.props.resetEditLevel('level3') |
| | | this.setState({editMenu: menu}) |
| | | } |
| | | |
| | | reload = () => { |
| | | const { mainMenu } = this.props |
| | | let _param = {func: 's_get_pc_menus', systemType: options.sysType, debug: 'Y'} |
| | | if (options.sysType !== 'cloud' && window.GLOB.systemType !== 'production') { |
| | | _param.linkurl = window.GLOB.linkurl |
| | | } |
| | | _param.pro_sys = window.GLOB.systemType === 'production' ? 'Y' : '' |
| | | |
| | | Api.getSystemConfig(_param).then(result => { |
| | | // 登录超时 |
| | | if (!result) return |
| | | |
| | | if (result.status) { |
| | | let res = this.getMenulist(result) |
| | | let _mainMenu = res.menulist.filter(item => item.MenuID === mainMenu.MenuID)[0] |
| | | |
| | | this.props.modifyMenuTree(res.menulist) |
| | | this.props.modifyMainMenu(_mainMenu || null) |
| | | } else { |
| | | notification.error({ |
| | | top: 92, |
| | | message: result.message, |
| | | duration: 10 |
| | | }) |
| | | } |
| | | this.loadsubmenu(this.props.mainMenu) |
| | | }) |
| | | } |
| | | |
| | | getMenulist = (result) => { |
| | | let iframes = ['Main/Index', 'bda/rdt', 'Home/rdt'] |
| | | let menulist = result.fst_menu.map(fst => { |
| | | let fstItem = { |
| | | MenuID: fst.MenuID, |
| | | MenuName: fst.MenuName, |
| | | PageParam: {OpenType: 'menu', linkUrl: ''}, |
| | | children: [] |
| | | } |
| | | if (fst.PageParam) { |
| | | try { |
| | | fstItem.PageParam = JSON.parse(fst.PageParam) |
| | | } catch (e) { |
| | | fstItem.PageParam = {OpenType: 'menu', linkUrl: ''} |
| | | } |
| | | } |
| | | |
| | | if (fst.snd_menu) { |
| | | fstItem.children = fst.snd_menu.map(snd => { |
| | | let sndItem = { |
| | | ParentId: fst.MenuID, |
| | | MenuID: snd.MenuID, |
| | | MenuName: snd.MenuName, |
| | | PageParam: {Icon: 'folder'}, |
| | | children: [] |
| | | } |
| | | |
| | | if (snd.PageParam) { |
| | | try { |
| | | sndItem.PageParam = JSON.parse(snd.PageParam) |
| | | } catch (e) { |
| | | sndItem.PageParam = {Icon: 'folder'} |
| | | } |
| | | } |
| | | |
| | | if (snd.trd_menu) { |
| | | sndItem.children = snd.trd_menu.map(trd => { |
| | | let trdItem = { |
| | | FstId: fst.MenuID, |
| | | ParentId: snd.MenuID, |
| | | MenuID: trd.MenuID, |
| | | MenuName: trd.MenuName, |
| | | MenuNo: trd.MenuNo, |
| | | EasyCode: trd.EasyCode, |
| | | type: 'CommonTable', // 默认值为常用表 |
| | | OpenType: 'newtab' // 打开方式 |
| | | } |
| | | |
| | | if (trd.LinkUrl && iframes.includes(trd.LinkUrl.split('?')[0])) { |
| | | trdItem.type = 'iframe' |
| | | trdItem.LinkUrl = trd.LinkUrl |
| | | trdItem.forbidden = true |
| | | } else { |
| | | try { |
| | | trdItem.PageParam = trd.PageParam ? JSON.parse(trd.PageParam) : {OpenType: 'newtab'} |
| | | } catch (e) { |
| | | trdItem.PageParam = {OpenType: 'newtab'} |
| | | } |
| | | |
| | | trdItem.type = trdItem.PageParam.Template || trdItem.type |
| | | trdItem.OpenType = trdItem.PageParam.OpenType || trdItem.OpenType |
| | | |
| | | if (trdItem.type === 'CustomPage' && this.props.memberLevel < 20) { // 会员等级大于等于20时,有编辑权限 |
| | | trdItem.forbidden = true |
| | | } |
| | | } |
| | | |
| | | return trdItem |
| | | }) |
| | | } |
| | | |
| | | return sndItem |
| | | }) |
| | | } |
| | | |
| | | return fstItem |
| | | }) |
| | | |
| | | return { menulist } |
| | | } |
| | | |
| | | exitEdit = () => { |
| | | if (this.props.editLevel === 'level3') { |
| | | this.setState({editMenu: null}) |
| | | } |
| | | this.props.resetEditLevel(false) |
| | | } |
| | | |
| | | render () { |
| | | const { mainMenu } = this.props |
| | | const editShow = (this.props.editState && !this.props.editLevel) || false |
| | | |
| | | if (mainMenu === '') return (<span className="mk-side-menu-hidden"></span>) |
| | | |
| | | return ( |
| | | <aside id="mk-sidemenu-wrap" className={'mk-side-menu ant-menu-dark' + (this.props.collapse ? ' collapsed' : '') + (this.props.isiframe ? ' mk-iframe' : '') + (this.props.editState ? ' mk-edit' : '')}> |
| | | {!(this.props.editLevel === 'level2' || this.props.editLevel === 'level3') && |
| | | <Menu openKeys={this.state.openKeys} onOpenChange={this.onOpenChange} mode="inline" theme="dark" inlineCollapsed={this.props.collapse}> |
| | | {editShow && <li className="sup-menu"><Icon onClick={this.enterSubEdit} className="edit-check" type="edit" /></li>} |
| | | {this.state.subMenulist && this.state.subMenulist.map((item, index) => { |
| | | <aside id="mk-sidemenu-wrap" className={'mk-side-menu ant-menu-dark' + (this.props.collapse ? ' collapsed' : '') + (this.props.isiframe ? ' mk-iframe' : '')}> |
| | | <Menu openKeys={this.state.openKeys} onOpenChange={this.onOpenChange} mode="inline" theme="dark" inlineCollapsed={this.props.collapse}> |
| | | {this.state.subMenulist && this.state.subMenulist.map((item) => { |
| | | return ( |
| | | <SubMenu |
| | | key={item.MenuID} |
| | | title={ |
| | | <span className={editShow && index === 0 ? 'edit-control' : ''}> |
| | | <span> |
| | | <Icon type={item.PageParam.Icon} /> |
| | | <span>{item.MenuName}</span> |
| | | </span> |
| | | } |
| | | > |
| | | {editShow ? <li className={'ant-menu-item ' + (item.children.length > 0 ? 'sub-menu' : '')}> |
| | | <Icon onClick={(e) => {this.enterThrEdit(e, item)}} className="edit-check" type="edit" /> |
| | | </li> : null} |
| | | {item.children.map(cell => { |
| | | return ( |
| | | <Menu.Item key={cell.MenuID}> |
| | |
| | | </SubMenu> |
| | | ) |
| | | })} |
| | | </Menu>} |
| | | {this.props.editLevel === 'level2' ? |
| | | <EditSecMenu |
| | | menulist={this.state.subMenulist} |
| | | menuTree={this.props.menuTree} |
| | | supMenu={this.props.mainMenu} |
| | | reload={this.reload} |
| | | exitEdit={this.exitEdit} |
| | | /> : null |
| | | } |
| | | {this.props.editLevel === 'level3' && this.state.editMenu ? |
| | | <EditThdMenu |
| | | menulist={this.state.editMenu.children} |
| | | supMenuList={this.state.subMenulist} |
| | | supMenu={this.state.editMenu} |
| | | reload={this.reload} |
| | | exitEdit={this.exitEdit} |
| | | /> : null |
| | | } |
| | | </Menu> |
| | | </aside> |
| | | ) |
| | | } |
| | |
| | | isiframe: state.isiframe, |
| | | mainMenu: state.mainMenu, |
| | | menuTree: state.menuTree, |
| | | memberLevel: state.memberLevel, |
| | | editState: state.editState, |
| | | editLevel: state.editLevel |
| | | } |
| | | } |
| | | |
| | | const mapDispatchToProps = (dispatch) => { |
| | | return { |
| | | modifyMenuTree: (menuTree) => dispatch(modifyMenuTree(menuTree)), |
| | | modifyMainMenu: (mainMenu) => dispatch(modifyMainMenu(mainMenu)), |
| | | modifyTabview: (tabviews) => dispatch(modifyTabview(tabviews)), |
| | | resetEditLevel: (level) => dispatch(resetEditLevel(level)) |
| | | } |
| | | } |
| | | |
| | | export default withRouter(connect(mapStateToProps, mapDispatchToProps)(Sidemenu)) |
| | | export default connect(mapStateToProps, mapDispatchToProps)(Sidemenu) |
| | |
| | | @import '../../assets/css/iconfont.css'; |
| | | @import '../../assets/css/global.scss'; |
| | | |
| | | .mk-side-menu { |
| | | flex: 0 0 235px; |
| | |
| | | left: 187px; |
| | | } |
| | | } |
| | | .mk-side-menu.mk-edit { // 编辑时控制菜单底色 |
| | | .ant-menu-sub.ant-menu-inline { |
| | | > .ant-menu-item.ant-menu-item-selected { |
| | | background: unset; |
| | | } |
| | | > .ant-menu-item.ant-menu-item-active { |
| | | background: unset; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .mk-side-menu.mk-iframe { // tab页中为iframe时 |
| | | max-height: 100vh; |
| | | overflow-y: scroll; |
| | |
| | | import { modifyTabview, toggleIsiframe } from '@/store/action' |
| | | import asyncComponent from '@/utils/asyncLoadComponent' |
| | | import NotFount from '@/components/404' |
| | | // import options from '@/store/options.js' |
| | | import mzhCN from '@/locales/zh-CN/main.js' |
| | | import menUS from '@/locales/en-US/main.js' |
| | | import MKEmitter from '@/utils/events.js' |
| | |
| | | service = window.GLOB.location + '/' + window.GLOB.service + 'zh-CN/' |
| | | } |
| | | |
| | | class Header extends Component { |
| | | class TabViews extends Component { |
| | | static propTpyes = { |
| | | collapse: PropTypes.bool, |
| | | tabviews: PropTypes.array // 标签页数组 |
| | |
| | | activeId: '', |
| | | tabviews: null, // 标签集 |
| | | iFrameHeight: 0, |
| | | dict: localStorage.getItem('lang') !== 'en-US' ? mzhCN : menUS, |
| | | dict: sessionStorage.getItem('lang') !== 'en-US' ? mzhCN : menUS, |
| | | } |
| | | |
| | | handleTabview = (e, menu) => { |
| | |
| | | } |
| | | |
| | | componentDidMount () { |
| | | let home = { |
| | | MenuID: 'home_page_id', |
| | | MenuName: this.state.dict['main.homepage'], |
| | | selected: true, |
| | | type: 'Home' |
| | | if (sessionStorage.getItem('isEditState') !== 'true') { |
| | | let home = { |
| | | MenuID: 'home_page_id', |
| | | MenuName: this.state.dict['main.homepage'], |
| | | selected: true, |
| | | type: 'Home' |
| | | } |
| | | this.props.modifyTabview([home]) |
| | | } |
| | | this.props.modifyTabview([home]) |
| | | } |
| | | |
| | | UNSAFE_componentWillReceiveProps (nextProps) { |
| | |
| | | </div> |
| | | </div> |
| | | </BackTop> |
| | | {/* {options.sysType === 'local' && window.GLOB.systemType !== 'production' ? <div className="mk-water-mark">测试系统</div> : null} */} |
| | | </Tabs.TabPane> |
| | | ) |
| | | })} |
| | |
| | | } |
| | | } |
| | | |
| | | export default connect(mapStateToProps, mapDispatchToProps)(Header) |
| | | export default connect(mapStateToProps, mapDispatchToProps)(TabViews) |
| | |
| | | } |
| | | span.tab-control i.anticon-redo { |
| | | position: absolute; |
| | | left: -3px; |
| | | left: -2px; |
| | | top: 18px; |
| | | font-size: 14px; |
| | | margin: 0px; |
| | |
| | | bottom: 20px; |
| | | right: 30px; |
| | | } |
| | | .mk-water-mark { |
| | | position: absolute; |
| | | top: 47px; |
| | | left: 5px; |
| | | font-size: 13px; |
| | | font-style: italic; |
| | | } |
| | | } |
| | | .mk-tabview-wrap.collapsed { |
| | | max-width: calc(100% - 80px); |
| | |
| | | import { Provider } from 'react-redux' |
| | | import store from '@/store' |
| | | import * as serviceWorker from './serviceWorker' |
| | | import options from '@/store/options.js' |
| | | import options, { styles } from '@/store/options.js' |
| | | import '@/assets/css/main.scss' |
| | | import '@/assets/css/action.scss' |
| | | import '@/assets/css/minkeicon.css' |
| | |
| | | |
| | | if ((navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i))) { |
| | | window.location.replace(window.location.href.split(/(index.html)+/ig)[0] + 'mob/index.html') |
| | | } else if (window.location.href.indexOf('#/design') > -1) { // 编辑页面刷新时,跳转至主页 |
| | | window.location.replace(window.location.href.replace(/design/ig, 'main')) |
| | | } |
| | | |
| | | options.sysType = window.atob(options.sysType.replace('$mk', '')) |
| | |
| | | sessionStorage.setItem('role_id', sessionStorage.getItem('localRole_id') || '') |
| | | sessionStorage.setItem('dataM', sessionStorage.getItem('localDataM') || '') |
| | | |
| | | fetch(`./options.json`) |
| | | // 新系统文件置于admin中 ../options.json |
| | | |
| | | fetch('./options.json') |
| | | .then(response => response.json()) |
| | | .catch(() => { |
| | | console.warn('系统配置信息获取失败,请联系管理员!') |
| | | document.getElementById('root').innerHTML = '<div style="text-align: center; font-size: 30px; margin-top: 40vh;">系统配置信息获取失败,请联系管理员!</div>' |
| | | }) |
| | | .then(config => { |
| | | if (!config) return |
| | | |
| | | |
| | | let GLOB = {} |
| | | GLOB.appId = config.appId || '' |
| | | GLOB.lineColor = config.lineColor || '' |
| | | GLOB.filter = config.filter || '' |
| | | |
| | | if (config.externalDatabase !== false && config.externalDatabase !== 'false' && config.externalDatabase !== undefined) { |
| | | GLOB.externalDatabase = config.externalDatabase ? `[${config.externalDatabase}]..` : '' |
| | | } else { |
| | | GLOB.externalDatabase = null |
| | | |
| | | } |
| | | |
| | | // 只有业务系统才可以设置为正式系统 |
| | |
| | | } |
| | | if (config.mainSystemApi) { |
| | | let systemApi = config.mainSystemApi |
| | | |
| | | // if (/^(http|https):\/\//ig.test(systemApi)) { |
| | | // let _systemApi = /^(http|https):\/\/[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62}|(:[0-9]{1,4}))+\.?/ig.exec(systemApi) |
| | | |
| | | // systemApi = _systemApi ? _systemApi[0] : '' |
| | | // } else { |
| | | // systemApi = '' |
| | | // } |
| | | |
| | | // // 业务系统连接云端时,格式化处理 |
| | | // if (systemApi && systemApi === /^(http|https):\/\/[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62}|(:[0-9]{1,4}))+\.?/ig.exec(options.cloudServiceApi)[0]) { |
| | | // GLOB.dataFormat = true |
| | | // } |
| | | |
| | | // if (systemApi) { |
| | | // systemApi = systemApi + '/webapi/dostars' |
| | | // } |
| | | |
| | | // 业务系统不允许连接云端,业务系统连接sso.mk9h.cn时,数据虚化处理 |
| | | if (systemApi && systemApi.indexOf('cloud.mk9h.cn') > -1) { |
| | | systemApi = '' |
| | |
| | | } |
| | | |
| | | let _href = window.location.href.split('#')[0] |
| | | |
| | | if (localStorage.getItem(_href + 'lang')) { |
| | | sessionStorage.setItem('lang', localStorage.getItem(_href + 'lang')) |
| | | } |
| | | |
| | | let _systemMsg = localStorage.getItem(_href + 'system') |
| | | |
| | |
| | | GLOB.webSite = _systemMsg.webSite |
| | | GLOB.style = _systemMsg.style |
| | | GLOB.showline = _systemMsg.showline || '' |
| | | GLOB.navBar = _systemMsg.navBar || '' |
| | | |
| | | if (GLOB.favicon) { |
| | | let link = document.querySelector("link[rel*='icon']") || document.createElement('link') |
| | |
| | | link.href = GLOB.favicon |
| | | document.getElementsByTagName('head')[0].appendChild(link) |
| | | } |
| | | if (GLOB.style && options.styles[GLOB.style]) { |
| | | document.body.className = options.styles[GLOB.style] + ' ' + (GLOB.showline === 'false' ? 'hidden-split-line' : '') |
| | | if (GLOB.style && styles[GLOB.style]) { |
| | | document.body.className = styles[GLOB.style] + ' ' + (GLOB.showline === 'false' ? 'hidden-split-line' : '') |
| | | } |
| | | } catch { |
| | | console.warn('Parse Failure') |
| | |
| | | |
| | | document.title = GLOB.platTitle || '' |
| | | |
| | | if (GLOB.filter === 'true') { |
| | | if (config.filter === 'true') { |
| | | let html = document.getElementsByTagName('html')[0] |
| | | |
| | | if (html) { |
| | |
| | | } |
| | | |
| | | if (process.env.NODE_ENV === 'production') { // 用于校验是否存在开发权限 |
| | | let _service = window.location.href.replace(/\/index.html(.*)|\/#(.*)/ig, '').replace(new RegExp(document.location.origin + '/?', 'ig'), '') |
| | | let _service = window.location.href.replace(/(\/admin)?\/index.html(.*)|(\/admin)?\/#(.*)/ig, '').replace(new RegExp(document.location.origin + '/?', 'ig'), '') |
| | | GLOB.linkurl = _href |
| | | if (!/index.html/ig.test(GLOB.linkurl)) { |
| | | GLOB.linkurl = GLOB.linkurl + 'index.html' |
| | |
| | | GLOB.service = _service ? _service + '/' : '' |
| | | } else { |
| | | GLOB.linkurl = '' |
| | | GLOB.location = 'http://bms-test.kresstools.cn' |
| | | GLOB.service = 'oc/' |
| | | } |
| | | |
| | | if (GLOB.style && options.styles[GLOB.style]) { |
| | | document.getElementById('root').className = options.styles[GLOB.style] |
| | | GLOB.location = config.host |
| | | GLOB.service = config.service |
| | | } |
| | | |
| | | Object.defineProperty(GLOB, 'appId', { |
| | |
| | | 'model.form.excelOut': 'Export excel', |
| | | 'model.form.newpage': 'The new page', |
| | | 'model.form.newpage.type': 'Page type', |
| | | 'model.form.newpage.url': 'Page address', |
| | | 'header.form.blank': '当前页跳转', |
| | | 'model.pageUrl': 'Page address', |
| | | 'model.form.prompt': 'Prompt', |
| | | 'model.form.exec': 'Direct execution', |
| | | 'model.form.paramJoint': 'Joint param', |
| | |
| | | 'model.form.excelOut': '导出Excel', |
| | | 'model.form.newpage': '新页面', |
| | | 'model.form.newpage.type': '页面类型', |
| | | 'model.form.newpage.url': '页面地址', |
| | | 'header.form.blank': '当前页跳转', |
| | | 'model.pageUrl': '页面地址', |
| | | 'model.form.prompt': '提示框', |
| | | 'model.form.exec': '直接执行', |
| | | 'model.form.paramJoint': '拼接参数', |
| | |
| | | } |
| | | |
| | | state = { |
| | | dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | backgroundColor: '', |
| | | backgroundImage: '', |
| | | } |
| | |
| | | const Video = asyncComponent(() => import('@/components/video')) |
| | | const MarkColumn = asyncIconComponent(() => import('@/menu/components/share/markcomponent')) |
| | | |
| | | const Card = ({ id, parent, fields, card, moveCard, findCard, editCard, delCard, copyCard, changeStyle, updateMarks }) => { |
| | | const Card = ({ id, parent, fields, card, moveCard, findCard, editCard, delCard, copyCard, changeStyle, updateMarks, doubleClickCard }) => { |
| | | const originalIndex = findCard(id).index |
| | | const [{ isDragging }, drag] = useDrag({ |
| | | item: { type: 'action', id, originalIndex }, |
| | |
| | | } else if (card.eleType === 'text' || card.eleType === 'number') { |
| | | let val = `${card.prefix || ''}${card.datatype === 'static' ? (card.value || '') : (card.field || '')}${card.postfix || ''}` |
| | | return ( |
| | | <div className={'ant-mk-text line' + card.height} style={{height: card.innerHeight || 21}}>{val}</div> |
| | | <div className={'ant-mk-text line' + (card.height || '')} style={{height: card.innerHeight || 'auto'}}>{val}</div> |
| | | ) |
| | | } else if (card.eleType === 'icon') { |
| | | return (<Icon type={card.icon}/>) |
| | |
| | | </div> |
| | | } trigger="hover"> |
| | | <div ref={node => drag(drop(node))} className={'ant-col card-cell ant-col-' + card.width}> |
| | | <div style={_style} onClick={clickComponent} id={card.uuid}> |
| | | <div style={_style} onClick={clickComponent} onDoubleClick={() => doubleClickCard(id)} id={card.uuid}> |
| | | {getContent()} |
| | | </div> |
| | | </div> |
| | |
| | | |
| | | const doubleClickCard = id => { |
| | | const { card } = findCard(id) |
| | | |
| | | if (card.eleType !== 'button' && card.eleType !== 'text' && card.eleType !== 'picture') { |
| | | return |
| | | } |
| | | |
| | | handleSubConfig(card) |
| | | } |
| | | |
| | |
| | | editCard={editCard} |
| | | updateMarks={updateMarks} |
| | | changeStyle={changeStyle} |
| | | doubleClickCard={doubleClickCard} |
| | | delCard={delCard} |
| | | findCard={findCard} |
| | | /> |
| | |
| | | font-weight: inherit; |
| | | text-decoration: inherit; |
| | | } |
| | | .ant-mk-text:not(.line1) { |
| | | .ant-mk-text:not(.line1):not(.line) { |
| | | word-break: break-word; |
| | | display: -webkit-box; |
| | | -webkit-box-orient: vertical; |
| | |
| | | import asyncComponent from '@/utils/asyncComponent' |
| | | import './index.scss' |
| | | |
| | | const { TextArea } = Input |
| | | const ColorSketch = asyncComponent(() => import('@/mob/colorsketch')) |
| | | const SourceComponent = asyncComponent(() => import('@/menu/components/share/sourcecomponent')) |
| | | |
| | |
| | | item.required = card.eleType !== 'qrcode' |
| | | } |
| | | if (item.key === 'linkurl') { |
| | | item.type = card.link === 'dynamic' ? 'select' : 'text' |
| | | item.type = card.link === 'dynamic' ? 'select' : 'textarea' |
| | | } |
| | | |
| | | return item |
| | |
| | | } |
| | | |
| | | if (['text', 'picture'].includes(eleType) && link) { |
| | | _options.push('linkurl', 'joint') |
| | | if (link === 'dynamic' || link === 'static' || link === 'custom') { |
| | | _options.push('linkurl', 'joint') |
| | | } else if (link === 'page') { |
| | | _options.push('copyMenuId', 'joint', 'open') |
| | | } else if (link === 'linkpage') { |
| | | _options.push('linkmenu', 'joint', 'open') |
| | | } |
| | | } |
| | | } else if (eleType === 'icon') { |
| | | if (datatype === 'dynamic') { |
| | |
| | | */ |
| | | selectChange = (key, value, option) => { |
| | | const { config } = this.props |
| | | const { datatype } = this.state |
| | | const { datatype, eleType } = this.state |
| | | |
| | | if (key === 'eleType') { |
| | | let _options = this.getOptions(value, datatype, '') |
| | |
| | | if (this.props.form.getFieldValue('value') !== undefined) { |
| | | this.props.form.setFieldsValue({value: option.props.title}) |
| | | } |
| | | } else if (key === 'link') { |
| | | let _options = this.getOptions(eleType, this.state.datatype, value) |
| | | this.setState({ |
| | | link: value, |
| | | formlist: this.state.formlist.map(item => { |
| | | item.hidden = !_options.includes(item.key) |
| | | if (item.key === 'linkurl') { |
| | | item.type = value === 'dynamic' ? 'select' : 'textarea' |
| | | } |
| | | return item |
| | | }) |
| | | }) |
| | | } |
| | | } |
| | | |
| | |
| | | formlist: this.state.formlist.map(item => { |
| | | item.hidden = !_options.includes(item.key) |
| | | if (item.key === 'linkurl') { |
| | | item.type = value === 'dynamic' ? 'select' : 'text' |
| | | item.type = value === 'dynamic' ? 'select' : 'textarea' |
| | | } |
| | | return item |
| | | }) |
| | |
| | | const fields = [] |
| | | |
| | | this.state.formlist.forEach((item, index) => { |
| | | if (item.hidden) return |
| | | if (item.hidden || item.forbid) return |
| | | |
| | | if (item.type === 'text') { // 文本搜索 |
| | | let rules = [] |
| | | |
| | | fields.push( |
| | | <Col span={12} key={index}> |
| | | <Form.Item label={item.tooltip ? |
| | | <Tooltip placement="topLeft" overlayClassName={item.tooltipClass} title={item.tooltip}> |
| | | <Tooltip placement="topLeft" title={item.tooltip}> |
| | | <Icon type="question-circle" /> |
| | | {item.label} |
| | | </Tooltip> : item.label |
| | |
| | | { |
| | | max: formRule.input.max, |
| | | message: formRule.input.message |
| | | }, |
| | | ...rules |
| | | } |
| | | ] |
| | | })(<Input placeholder="" autoComplete="off" disabled={item.readonly} onPressEnter={this.handleSubmit} />)} |
| | | </Form.Item> |
| | | </Col> |
| | | ) |
| | | } else if (item.type === 'number') { |
| | | } else if (item.type === 'textarea') { // 文本搜索 |
| | | fields.push( |
| | | <Col span={12} key={index}> |
| | | <Col span={24} className="textarea" key={index}> |
| | | <Form.Item label={item.tooltip ? |
| | | <Tooltip placement="topLeft" overlayClassName={item.tooltipClass} title={item.tooltip}> |
| | | <Icon type="question-circle" /> |
| | | {item.label} |
| | | </Tooltip> : item.label |
| | | }> |
| | | {getFieldDecorator(item.key, { |
| | | initialValue: item.initVal, |
| | | rules: [ |
| | | { |
| | | required: item.readonly ? false : !!item.required, |
| | | message: this.props.dict['form.required.input'] + item.label + '!' |
| | | } |
| | | ] |
| | | })(<InputNumber min={item.min || 0} max={item.max || 10000} precision={item.precision || 0} onPressEnter={this.handleSubmit} />)} |
| | | </Form.Item> |
| | | </Col> |
| | | ) |
| | | } else if (item.type === 'select') { // 下拉搜索 |
| | | fields.push( |
| | | <Col span={12} key={index}> |
| | | <Form.Item label={item.tooltip ? |
| | | <Tooltip placement="topLeft" overlayClassName={item.tooltipClass} title={item.tooltip}> |
| | | <Tooltip placement="topLeft" title={item.tooltip}> |
| | | <Icon type="question-circle" /> |
| | | {item.label} |
| | | </Tooltip> : item.label |
| | |
| | | initialValue: item.initVal || '', |
| | | rules: [ |
| | | { |
| | | required: !!item.required, |
| | | message: this.props.dict['form.required.select'] + item.label + '!' |
| | | required: item.readonly ? false : !!item.required, |
| | | message: this.props.dict['form.required.input'] + item.label + '!' |
| | | }, |
| | | { |
| | | max: formRule.input.max, |
| | | message: formRule.input.message |
| | | } |
| | | ] |
| | | })(<TextArea rows={2} disabled={item.readonly} />)} |
| | | </Form.Item> |
| | | </Col> |
| | | ) |
| | | } else if (item.type === 'number') { |
| | | fields.push( |
| | | <Col span={12} key={index}> |
| | | <Form.Item label={item.tooltip ? |
| | | <Tooltip placement="topLeft" title={item.tooltip}> |
| | | <Icon type="question-circle" /> |
| | | {item.label} |
| | | </Tooltip> : item.label |
| | | }> |
| | | {getFieldDecorator(item.key, { |
| | | initialValue: item.initVal, |
| | | rules: [{ |
| | | required: item.readonly ? false : !!item.required, |
| | | message: this.props.dict['form.required.input'] + item.label + '!' |
| | | }] |
| | | })(<InputNumber min={item.min || 0} max={item.max || 10000} precision={item.precision || 0} onPressEnter={this.handleSubmit} />)} |
| | | </Form.Item> |
| | | </Col> |
| | | ) |
| | | } else if (item.type === 'select') { // 下拉搜索 |
| | | fields.push( |
| | | <Col span={12} key={index}> |
| | | <Form.Item label={item.tooltip ? |
| | | <Tooltip placement="topLeft" title={item.tooltip}> |
| | | <Icon type="question-circle" /> |
| | | {item.label} |
| | | </Tooltip> : item.label |
| | | }> |
| | | {getFieldDecorator(item.key, { |
| | | initialValue: item.initVal || '', |
| | | rules: [{ |
| | | required: !!item.required, |
| | | message: this.props.dict['form.required.select'] + item.label + '!' |
| | | }] |
| | | })( |
| | | <Select |
| | | showSearch |
| | |
| | | } else if (item.type === 'radio') { |
| | | fields.push( |
| | | <Col span={12} key={index}> |
| | | <Form.Item label={item.label}> |
| | | <Form.Item label={item.tooltip ? |
| | | <Tooltip placement="topLeft" title={item.tooltip}> |
| | | <Icon type="question-circle" /> |
| | | {item.label} |
| | | </Tooltip> : item.label |
| | | }> |
| | | {getFieldDecorator(item.key, { |
| | | initialValue: item.initVal, |
| | | rules: [ |
| | | { |
| | | required: !!item.required, |
| | | message: this.props.dict['form.required.select'] + item.label + '!' |
| | | } |
| | | ] |
| | | rules: [{ |
| | | required: !!item.required, |
| | | message: this.props.dict['form.required.select'] + item.label + '!' |
| | | }] |
| | | })( |
| | | <Radio.Group onChange={(e) => {this.onChange(e, item.key)}} disabled={item.readonly}> |
| | | { |
| | | item.options.map(option => { |
| | | return ( |
| | | <Radio key={option.value} value={option.value}>{option.text}</Radio> |
| | | ) |
| | | }) |
| | | } |
| | | {item.options.map(option => { |
| | | return ( |
| | | <Radio key={option.value} value={option.value}>{option.text}</Radio> |
| | | ) |
| | | })} |
| | | </Radio.Group> |
| | | )} |
| | | </Form.Item> |
| | |
| | | if (!err) { |
| | | values.uuid = this.props.card.uuid |
| | | values.marks = this.props.card.marks || null |
| | | |
| | | // if (values.eleType === 'picture' && values.datatype === 'static' && !values.url) { |
| | | // notification.warning({ |
| | | // top: 92, |
| | | // message: '尚未添加图片或图片上传失败,请重新添加!', |
| | | // duration: 5 |
| | | // }) |
| | | // return |
| | | // } |
| | | |
| | | resolve(values) |
| | | } else { |
| | |
| | | margin-right: 5px; |
| | | } |
| | | } |
| | | .ant-col { |
| | | height: 65px; |
| | | >.ant-row { |
| | | >.ant-col { |
| | | height: 65px; |
| | | } |
| | | .ant-col.textarea { |
| | | height: 80px; |
| | | .ant-form-item-label { |
| | | width: 14.2%; |
| | | } |
| | | .ant-form-item-control-wrapper { |
| | | width: 85.8%; |
| | | } |
| | | } |
| | | } |
| | | .color-form { |
| | | .ant-form-item-control { |
| | |
| | | import zhCN from '@/locales/zh-CN/model.js' |
| | | import enUS from '@/locales/en-US/model.js' |
| | | |
| | | const Formdict = localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS |
| | | const Formdict = sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS |
| | | |
| | | /** |
| | | * @description 获取按钮表单配置信息 |
| | |
| | | |
| | | if (type === 'table') { |
| | | _options.push({value: 'sequence', text: '序号'}) |
| | | } |
| | | let appMenus = [] |
| | | const isApp = sessionStorage.getItem('appType') === 'pc' |
| | | |
| | | if (isApp) { |
| | | appMenus = sessionStorage.getItem('appMenus') |
| | | if (appMenus) { |
| | | try { |
| | | appMenus = JSON.parse(appMenus) |
| | | appMenus = appMenus.map(item => ({value: item.MenuID, text: item.MenuName})) |
| | | } catch { |
| | | appMenus = [] |
| | | } |
| | | } else { |
| | | appMenus = [] |
| | | } |
| | | } |
| | | |
| | | let forms = [ |
| | |
| | | min: 0, |
| | | label: '内容', |
| | | initVal: card.value || '', |
| | | tooltip: '文本类型,会替换内容中的@username@、@fullName@、@login_city@。', |
| | | required: true |
| | | }, |
| | | { |
| | |
| | | { value: 'true', text: '是' }, |
| | | { value: 'false', text: '否' } |
| | | ] |
| | | }, |
| | | { |
| | | type: 'radio', |
| | | key: 'link', |
| | | label: '链接', |
| | | initVal: card.link || '', |
| | | required: false, |
| | | options: [ |
| | | { value: '', text: '无' }, |
| | | { value: 'dynamic', text: '动态' }, |
| | | { value: 'static', text: '静态' } |
| | | ] |
| | | }, |
| | | { |
| | | type: 'select', |
| | | key: 'linkurl', |
| | | label: '链接地址', |
| | | initVal: card.linkurl || '', |
| | | required: true, |
| | | options: [] |
| | | }, |
| | | { |
| | | type: 'select', |
| | |
| | | }, |
| | | { |
| | | type: 'radio', |
| | | key: 'link', |
| | | label: '链接', |
| | | initVal: card.link || '', |
| | | tooltip: '动态地址为绑定字段值。', |
| | | required: false, |
| | | forbid: isApp, |
| | | options: [ |
| | | { value: '', text: '无' }, |
| | | { value: 'dynamic', text: '动态' }, |
| | | { value: 'static', text: '静态' } |
| | | ] |
| | | }, |
| | | { |
| | | type: 'select', |
| | | key: 'link', |
| | | label: '链接', |
| | | initVal: card.link || '', |
| | | required: false, |
| | | forbid: !isApp, |
| | | options: [ |
| | | { value: '', text: '无' }, |
| | | { value: 'page', text: '菜单' }, |
| | | { value: 'linkpage', text: '关联菜单' }, |
| | | { value: 'custom', text: '链接' } |
| | | ] |
| | | }, |
| | | { |
| | | type: 'select', |
| | | key: 'linkmenu', |
| | | label: '关联菜单', |
| | | initVal: card.linkmenu || '', |
| | | required: true, |
| | | forbid: !isApp, |
| | | options: appMenus |
| | | }, |
| | | { |
| | | type: 'radio', |
| | | key: 'open', |
| | | label: '打开方式', |
| | | initVal: card.open || 'blank', |
| | | required: false, |
| | | forbid: !isApp, |
| | | options: [ |
| | | { value: 'blank', text: '新页面' }, |
| | | { value: 'self', text: '当前页面' } |
| | | ] |
| | | }, |
| | | { |
| | | type: 'select', |
| | | key: 'copyMenuId', |
| | | label: '复制菜单', |
| | | initVal: card.copyMenuId || '', |
| | | required: false, |
| | | forbid: !isApp, |
| | | options: appMenus |
| | | }, |
| | | { |
| | | type: 'radio', |
| | | key: 'joint', |
| | | label: Formdict['model.form.paramJoint'], |
| | | initVal: card.joint || 'true', |
| | |
| | | text: Formdict['model.false'] |
| | | }] |
| | | }, |
| | | { |
| | | type: 'select', |
| | | key: 'linkurl', |
| | | label: '链接地址', |
| | | initVal: card.linkurl || '', |
| | | required: true, |
| | | options: [] |
| | | }, |
| | | ] |
| | | |
| | | return forms |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { is, fromJS } from 'immutable' |
| | | import {connect} from 'react-redux' |
| | | import { Modal, Button } from 'antd' |
| | | |
| | | import zhCN from '@/locales/zh-CN/model.js' |
| | |
| | | import { getActionForm } from '@/menu/components/share/actioncomponent/formconfig' |
| | | |
| | | import MKEmitter from '@/utils/events.js' |
| | | import MenuUtils from '@/menu/utils/menuUtils.js' |
| | | import MenuUtils from '@/utils/utils-custom.js' |
| | | import ElementForm from './elementform' |
| | | import DragElement from './dragaction' |
| | | import './index.scss' |
| | |
| | | const { confirm } = Modal |
| | | |
| | | const ActionForm = asyncComponent(() => import('@/menu/components/share/actioncomponent/actionform')) |
| | | const CreateFunc = asyncComponent(() => import('@/templates/zshare/createfunc')) |
| | | const VerifyCard = asyncComponent(() => import('@/templates/zshare/verifycard')) |
| | | const VerifyPrint = asyncComponent(() => import('@/templates/sharecomponent/actioncomponent/verifyprint')) |
| | | const VerifyExcelIn = asyncComponent(() => import('@/templates/sharecomponent/actioncomponent/verifyexcelin')) |
| | |
| | | } |
| | | |
| | | state = { |
| | | dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | card: null, // 编辑中元素 |
| | | formlist: null, // 表单信息 |
| | | elements: null, // 按钮组 |
| | |
| | | const { cards, cardCell } = this.props |
| | | const { card, elements } = this.state |
| | | |
| | | if (comIds.length !== 3 || comIds[0] !== cards.uuid || comIds[1] !== cardCell.uuid) return |
| | | if (comIds.length !== 3 || comIds[0] !== cards.uuid || comIds[1] !== cardCell.uuid || !card) return |
| | | |
| | | let _card = this.resetCardStyle(card, style) |
| | | |
| | |
| | | |
| | | let fontSize = 14 |
| | | let lineHeight = 1.5 |
| | | let line = _card.height || 1 |
| | | let line = _card.height || null |
| | | |
| | | if (_card.style.fontSize) { |
| | | fontSize = parseInt(_card.style.fontSize) |
| | |
| | | lineHeight = parseFloat(_card.style.lineHeight) |
| | | } |
| | | |
| | | _card.innerHeight = fontSize * lineHeight * line |
| | | if (line) { |
| | | _card.innerHeight = fontSize * lineHeight * line |
| | | } |
| | | } else if (_card.eleType === 'barcode') { |
| | | _card.style = style |
| | | |
| | |
| | | * @description 按钮编辑,获取按钮表单信息 |
| | | */ |
| | | handleAction = (card) => { |
| | | const { menu, cards } = this.props |
| | | const { cards } = this.props |
| | | |
| | | let usefulFields = sessionStorage.getItem('permFuncField') |
| | | if (usefulFields) { |
| | |
| | | menulist = [] |
| | | } |
| | | |
| | | let modules = MenuUtils.getSubModules(menu.components, cards.uuid) |
| | | let modules = MenuUtils.getSubModules(window.GLOB.customMenu.components, cards.uuid) |
| | | |
| | | this.setState({ |
| | | actvisible: true, |
| | |
| | | } else if (res.eleType === 'text' || res.eleType === 'number') { |
| | | let fontSize = 14 |
| | | let lineHeight = 1.5 |
| | | let line = res.height || 1 |
| | | let line = res.height || null |
| | | |
| | | if (res.style && res.style.fontSize) { |
| | | fontSize = parseInt(res.style.fontSize) |
| | |
| | | if (res.style && res.style.lineHeight) { |
| | | lineHeight = parseFloat(res.style.lineHeight) |
| | | } |
| | | res.innerHeight = fontSize * lineHeight * line |
| | | |
| | | if (line) { |
| | | res.innerHeight = fontSize * lineHeight * line |
| | | } |
| | | |
| | | if (res.eleType === 'text' && res.link && !res.style.color) { |
| | | res.style.color = '#2440B3' |
| | |
| | | const { cards } = this.props |
| | | let btn = fromJS(item).toJS() |
| | | |
| | | if (btn.eleType !== 'button' || (sessionStorage.getItem('style-control') && sessionStorage.getItem('style-control') !== 'false')) return |
| | | if ((sessionStorage.getItem('style-control') && sessionStorage.getItem('style-control') !== 'false')) return |
| | | |
| | | if (btn.OpenType === 'pop') { |
| | | if (!btn.modal) { |
| | | btn.modal = { |
| | | setting: { title: btn.label, width: 60, cols: '2', container: 'view', focus: '', finish: 'close', clickouter: 'unclose', display: 'modal' }, |
| | | tables: [], |
| | | groups: [], |
| | | fields: [] |
| | | if (btn.eleType === 'button') { |
| | | if (btn.OpenType === 'pop') { |
| | | if (!btn.modal) { |
| | | btn.modal = { |
| | | setting: { title: btn.label, width: 60, cols: '2', container: 'view', focus: '', finish: 'close', clickouter: 'unclose', display: 'modal' }, |
| | | tables: [], |
| | | groups: [], |
| | | fields: [] |
| | | } |
| | | } |
| | | |
| | | MKEmitter.emit('changeModal', cards, btn) |
| | | } else if (btn.OpenType === 'popview') { |
| | | MKEmitter.emit('changePopview', cards, btn) |
| | | } else if (btn.OpenType === 'innerpage' && btn.pageTemplate === 'page') { |
| | | MKEmitter.emit('changeEditMenu', {MenuID: btn.uuid, copyMenuId: btn.copyMenuId}) |
| | | } else if (btn.OpenType === 'innerpage' && btn.pageTemplate === 'linkpage') { |
| | | MKEmitter.emit('changeEditMenu', {MenuID: btn.linkmenu}) |
| | | } |
| | | |
| | | MKEmitter.emit('changeModal', cards, btn) |
| | | } else if (btn.OpenType === 'popview') { |
| | | MKEmitter.emit('changePopview', cards, btn) |
| | | } else { |
| | | if (btn.link === 'page') { |
| | | MKEmitter.emit('changeEditMenu', {MenuID: btn.uuid, copyMenuId: btn.copyMenuId}) |
| | | } else if (btn.link === 'linkpage') { |
| | | MKEmitter.emit('changeEditMenu', {MenuID: btn.linkmenu}) |
| | | } |
| | | } |
| | | } |
| | | |
| | |
| | | |
| | | dropButton = (id) => { |
| | | const { cards } = this.props |
| | | |
| | | if (!cards.action) return |
| | | |
| | | let index = cards.action.findIndex(item => item.uuid === id) |
| | | |
| | | if (index === -1) return |
| | |
| | | maskClosable={false} |
| | | onCancel={this.editModalCancel} |
| | | footer={[ |
| | | <CreateFunc key="create" dict={dict} ref="btnCreatFunc" trigger={this.creatFunc}/>, |
| | | <Button key="cancel" onClick={this.editModalCancel}>{dict['model.cancel']}</Button>, |
| | | <Button key="confirm" type="primary" onClick={this.handleActionSubmit}>{dict['model.confirm']}</Button> |
| | | ]} |
| | |
| | | visible={profVisible} |
| | | width={'75vw'} |
| | | maskClosable={false} |
| | | style={{minWidth: '900px', maxWidth: '1200px'}} |
| | | okText={dict['model.submit']} |
| | | onOk={this.verifySubmit} |
| | | onCancel={() => { this.setState({ profVisible: false }) }} |
| | |
| | | } |
| | | } |
| | | |
| | | const mapStateToProps = (state) => { |
| | | return { |
| | | menu: state.customMenu |
| | | } |
| | | } |
| | | |
| | | const mapDispatchToProps = () => { |
| | | return {} |
| | | } |
| | | |
| | | export default connect(mapStateToProps, mapDispatchToProps)(CardCellComponent) |
| | | export default CardCellComponent |
| | |
| | | } |
| | | |
| | | state = { |
| | | dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | card: null, // 卡片信息,包括正反面 |
| | | formlist: null, // 设置表单信息 |
| | | elements: null, // 编辑组 |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { Form, Row, Col, Radio, Tooltip, Icon, Input, InputNumber, Select } from 'antd' |
| | | import { Form, Row, Col, Radio, Tooltip, Icon, Input, InputNumber, Select, Cascader } from 'antd' |
| | | |
| | | import './index.scss' |
| | | |
| | | const { TextArea } = Input |
| | | |
| | | class SettingForm extends Component { |
| | | static propTpyes = { |
| | |
| | | } |
| | | |
| | | state = { |
| | | type: this.props.setting.type || 'simple' |
| | | type: this.props.setting.type || 'simple', |
| | | click: this.props.setting.click || '', |
| | | isApp: sessionStorage.getItem('appType') === 'pc', |
| | | menulist: [] |
| | | } |
| | | |
| | | UNSAFE_componentWillMount() { |
| | | const { isApp } = this.state |
| | | let menulist = null |
| | | |
| | | if (isApp) { |
| | | menulist = sessionStorage.getItem('appMenus') |
| | | } else { |
| | | menulist = sessionStorage.getItem('fstMenuList') |
| | | } |
| | | |
| | | if (menulist) { |
| | | try { |
| | | menulist = JSON.parse(menulist) |
| | | } catch { |
| | | menulist = [] |
| | | } |
| | | } else { |
| | | menulist = [] |
| | | } |
| | | this.setState({menulist}) |
| | | } |
| | | |
| | | handleConfirm = () => { |
| | |
| | | render() { |
| | | const { setting, cards } = this.props |
| | | const { getFieldDecorator } = this.props.form |
| | | const { menulist, click, isApp } = this.state |
| | | |
| | | const formItemLayout = { |
| | | labelCol: { |
| | |
| | | })(<Input placeholder="" autoComplete="off" onPressEnter={this.handleSubmit}/>)} |
| | | </Form.Item> |
| | | </Col> : null} |
| | | <Col span={12}> |
| | | <Form.Item label="点击事件"> |
| | | {getFieldDecorator('click', { |
| | | initialValue: click |
| | | })( |
| | | <Radio.Group onChange={(e) => this.setState({click: e.target.value})}> |
| | | <Radio value="">无</Radio> |
| | | <Radio value="menu">菜单</Radio> |
| | | <Radio value="link">链接</Radio> |
| | | </Radio.Group> |
| | | )} |
| | | </Form.Item> |
| | | </Col> |
| | | {!isApp && click === 'menu' ? <Col span={12}> |
| | | <Form.Item label="菜单"> |
| | | {getFieldDecorator('menu', { |
| | | initialValue: setting.menu || [], |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: this.props.dict['form.required.select'] + '菜单!' |
| | | } |
| | | ] |
| | | })( |
| | | <Cascader options={menulist} placeholder=""/> |
| | | )} |
| | | </Form.Item> |
| | | </Col> : null} |
| | | {isApp && click === 'menu' ? <Col span={12}> |
| | | <Form.Item label="关联菜单"> |
| | | {getFieldDecorator('menu', { |
| | | initialValue: setting.menu || '', |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: this.props.dict['form.required.select'] + '关联菜单!' |
| | | } |
| | | ] |
| | | })( |
| | | <Select |
| | | showSearch |
| | | filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0} |
| | | > |
| | | {menulist.map(option => |
| | | <Select.Option key={option.MenuID} value={option.MenuID}>{option.MenuName}</Select.Option> |
| | | )} |
| | | </Select> |
| | | )} |
| | | </Form.Item> |
| | | </Col> : null} |
| | | {click === 'link' ? <Col span={24} className="textarea"> |
| | | <Form.Item label="链接"> |
| | | {getFieldDecorator('linkurl', { |
| | | initialValue: setting.linkurl || '', |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: this.props.dict['form.required.input'] + '链接!' |
| | | } |
| | | ] |
| | | })( <TextArea rows={2}/> )} |
| | | </Form.Item> |
| | | </Col> : null} |
| | | {isApp ? <Col span={12}> |
| | | <Form.Item label="打开方式"> |
| | | {getFieldDecorator('open', { |
| | | initialValue: setting.open || 'blank' |
| | | })( |
| | | <Radio.Group> |
| | | <Radio value="blank">新窗口</Radio> |
| | | <Radio value="self">当前窗口</Radio> |
| | | </Radio.Group> |
| | | )} |
| | | </Form.Item> |
| | | </Col> : null} |
| | | {click !== '' ? <Col span={12}> |
| | | <Form.Item label="参数拼接"> |
| | | {getFieldDecorator('joint', { |
| | | initialValue: setting.joint || 'true' |
| | | })( |
| | | <Radio.Group> |
| | | <Radio value="true">是</Radio> |
| | | <Radio value="false">否</Radio> |
| | | </Radio.Group> |
| | | )} |
| | | </Form.Item> |
| | | </Col> : null} |
| | | </Row> |
| | | </Form> |
| | | </div> |
| | |
| | | .ant-input-number { |
| | | width: 100%; |
| | | } |
| | | .textarea { |
| | | .ant-form-item-label { |
| | | width: 16%; |
| | | } |
| | | .ant-form-item-control-wrapper { |
| | | width: 84%; |
| | | } |
| | | } |
| | | } |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { connect } from 'react-redux' |
| | | import { is, fromJS } from 'immutable' |
| | | import { Icon, Popover, Modal, Pagination, notification } from 'antd' |
| | | |
| | |
| | | } |
| | | |
| | | state = { |
| | | dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | card: null, |
| | | back: false |
| | | } |
| | |
| | | const { card } = this.props |
| | | |
| | | if (card.isNew) { |
| | | let ismob = sessionStorage.getItem('appType') === 'mob' |
| | | let _card = { |
| | | uuid: card.uuid, |
| | | type: card.type, |
| | |
| | | btnlog: [], |
| | | subcards: [{ |
| | | uuid: Utils.getuuid(), |
| | | setting: { width: 6, type: 'simple'}, |
| | | setting: { width: ismob ? 24 : 6, type: 'simple'}, |
| | | style: { |
| | | borderWidth: '1px', borderColor: '#e8e8e8', |
| | | paddingTop: '15px', paddingBottom: '15px', paddingLeft: '15px', paddingRight: '15px', |
| | |
| | | } |
| | | |
| | | shouldComponentUpdate (nextProps, nextState) { |
| | | return !is(fromJS(this.state), fromJS(nextState)) || (!this.props.menu && nextProps.menu) |
| | | return !is(fromJS(this.state), fromJS(nextState)) |
| | | } |
| | | |
| | | /** |
| | |
| | | const { card } = this.state |
| | | let btn = fromJS(item).toJS() |
| | | |
| | | if (btn.OpenType === 'pop') { |
| | | if (btn.OpenType === 'pop' || btn.execMode === 'pop') { |
| | | if (!btn.modal) { |
| | | btn.modal = { |
| | | setting: { title: btn.label, width: 60, cols: '2', container: 'view', focus: '', finish: 'close', clickouter: 'unclose', display: 'modal' }, |
| | |
| | | } |
| | | } |
| | | |
| | | const mapStateToProps = (state) => { |
| | | return { |
| | | menu: state.customMenu |
| | | } |
| | | } |
| | | |
| | | const mapDispatchToProps = () => { |
| | | return {} |
| | | } |
| | | |
| | | export default connect(mapStateToProps, mapDispatchToProps)(DataCardEditComponent) |
| | | export default DataCardEditComponent |
| | |
| | | } |
| | | |
| | | state = { |
| | | dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | visible: false, |
| | | wrap: null |
| | | } |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import {connect} from 'react-redux' |
| | | import { is, fromJS } from 'immutable' |
| | | import { Icon, Popover, Modal, notification } from 'antd' |
| | | |
| | |
| | | const PasteComponent = asyncIconComponent(() => import('@/menu/components/share/pastecomponent')) |
| | | const LogComponent = asyncIconComponent(() => import('@/menu/components/share/logcomponent')) |
| | | const UserComponent = asyncIconComponent(() => import('@/menu/components/share/usercomponent')) |
| | | const ClockComponent = asyncIconComponent(() => import('@/menu/components/share/clockcomponent')) |
| | | const NormalHeader = asyncComponent(() => import('@/menu/components/share/normalheader')) |
| | | |
| | | const { confirm } = Modal |
| | |
| | | } |
| | | |
| | | state = { |
| | | dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | card: null, |
| | | back: false |
| | | } |
| | |
| | | const { card } = this.props |
| | | |
| | | if (card.isNew) { |
| | | let ismob = sessionStorage.getItem('appType') === 'mob' |
| | | let _card = { |
| | | uuid: card.uuid, |
| | | type: card.type, |
| | |
| | | name: card.name, |
| | | subtype: card.subtype, |
| | | setting: { interType: 'system' }, |
| | | wrap: { name: card.name, width: card.width || 24, title: '', addable: 'false', switch: 'false', datatype: 'static' }, |
| | | wrap: { name: card.name, width: card.width || 24, title: '', switch: 'false', datatype: 'static' }, |
| | | style: { marginLeft: '0px', marginRight: '0px', marginTop: '8px', marginBottom: '8px' }, |
| | | headerStyle: { fontSize: '16px', borderBottomWidth: '1px', borderBottomColor: '#e8e8e8' }, |
| | | columns: [], |
| | | scripts: [], |
| | | subcards: [{ |
| | | uuid: Utils.getuuid(), |
| | | setting: { width: 6, type: 'simple'}, |
| | | setting: { width: ismob ? 24 : 6, type: 'simple'}, |
| | | style: { |
| | | borderWidth: '1px', borderColor: '#e8e8e8', |
| | | paddingTop: '15px', paddingBottom: '15px', paddingLeft: '15px', paddingRight: '15px', |
| | |
| | | } |
| | | |
| | | shouldComponentUpdate (nextProps, nextState) { |
| | | return !is(fromJS(this.state), fromJS(nextState)) || (!this.props.menu && nextProps.menu) |
| | | return !is(fromJS(this.state), fromJS(nextState)) |
| | | } |
| | | |
| | | /** |
| | |
| | | <PasteComponent config={card} options={['cardcell']} updateConfig={this.updateComponent} /> |
| | | <Icon className="style" title="调整样式" onClick={this.changeStyle} type="font-colors" /> |
| | | <LogComponent btnlog={card.btnlog || []} handlelog={this.handleLog} /> |
| | | <ClockComponent config={card} updateConfig={this.updateComponent}/> |
| | | <UserComponent config={card}/> |
| | | <Icon className="close" title="删除组件" type="delete" onClick={() => this.props.deletecomponent(card.uuid)} /> |
| | | {card.wrap.datatype !== 'static' ? <SettingComponent config={card} updateConfig={this.updateComponent} /> : null} |
| | |
| | | } |
| | | } |
| | | |
| | | const mapStateToProps = (state) => { |
| | | return { |
| | | menu: state.customMenu |
| | | } |
| | | } |
| | | |
| | | const mapDispatchToProps = () => { |
| | | return {} |
| | | } |
| | | |
| | | export default connect(mapStateToProps, mapDispatchToProps)(PropCardEditComponent) |
| | | export default PropCardEditComponent |
| | |
| | | } |
| | | |
| | | state = { |
| | | dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | card: null, // 卡片信息,包括正反面 |
| | | formlist: null, // 设置表单信息 |
| | | elements: null, // 编辑组 |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import {connect} from 'react-redux' |
| | | import { is, fromJS } from 'immutable' |
| | | import { Icon, Popover, Modal, Pagination, notification } from 'antd' |
| | | |
| | |
| | | } |
| | | |
| | | state = { |
| | | dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | card: null, |
| | | back: false |
| | | } |
| | |
| | | } |
| | | } |
| | | |
| | | const mapStateToProps = (state) => { |
| | | return { |
| | | menu: state.customMenu |
| | | } |
| | | } |
| | | |
| | | const mapDispatchToProps = () => { |
| | | return {} |
| | | } |
| | | |
| | | export default connect(mapStateToProps, mapDispatchToProps)(TableCardEditComponent) |
| | | export default TableCardEditComponent |
New file |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { is, fromJS } from 'immutable' |
| | | import { Modal, Popover, Icon } from 'antd' |
| | | |
| | | import asyncComponent from '@/utils/asyncComponent' |
| | | import asyncIconComponent from '@/utils/asyncIconComponent' |
| | | import zhCN from '@/locales/zh-CN/model.js' |
| | | import enUS from '@/locales/en-US/model.js' |
| | | import SettingForm from './settingform' |
| | | |
| | | import Utils from '@/utils/utils.js' |
| | | import MKEmitter from '@/utils/events.js' |
| | | import './index.scss' |
| | | |
| | | const CardCellComponent = asyncComponent(() => import('@/menu/components/card/cardcellcomponent')) |
| | | const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent')) |
| | | |
| | | class CardBoxComponent extends Component { |
| | | static propTpyes = { |
| | | cards: PropTypes.object, // 卡片行配置信息 |
| | | card: PropTypes.object, // 卡片配置信息 |
| | | move: PropTypes.func, // 卡片移动 |
| | | deleteElement: PropTypes.func, // 卡片删除 |
| | | updateElement: PropTypes.func // 菜单配置更新 |
| | | } |
| | | |
| | | state = { |
| | | dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | card: null, // 卡片信息,包括正反面 |
| | | formlist: null, // 设置表单信息 |
| | | elements: null, // 编辑组 |
| | | visible: false, // 模态框控制 |
| | | settingVisible: false, |
| | | } |
| | | |
| | | /** |
| | | * @description 搜索条件初始化 |
| | | */ |
| | | UNSAFE_componentWillMount () { |
| | | const { card } = this.props |
| | | |
| | | this.setState({ |
| | | card: fromJS(card).toJS(), |
| | | elements: fromJS(card.elements).toJS(), |
| | | }) |
| | | } |
| | | |
| | | componentDidMount () { |
| | | MKEmitter.addListener('submitStyle', this.getStyle) |
| | | } |
| | | |
| | | shouldComponentUpdate (nextProps, nextState) { |
| | | const { cards } = this.props |
| | | |
| | | return !is(fromJS(cards), fromJS(nextProps.cards)) || !is(fromJS(this.state), fromJS(nextState)) |
| | | } |
| | | |
| | | /** |
| | | * @description 组件销毁,清除state更新,清除快捷键设置 |
| | | */ |
| | | componentWillUnmount () { |
| | | this.setState = () => { |
| | | return |
| | | } |
| | | MKEmitter.removeListener('submitStyle', this.getStyle) |
| | | } |
| | | |
| | | getStyle = (comIds, style) => { |
| | | const { cards } = this.props |
| | | const { card } = this.state |
| | | |
| | | if (comIds.length !== 2 || comIds[0] !== cards.uuid || comIds[1] !== card.uuid) return |
| | | |
| | | let _card = fromJS(card).toJS() |
| | | _card.style = style |
| | | |
| | | this.setState({ |
| | | card: _card |
| | | }) |
| | | |
| | | this.props.updateElement(_card) |
| | | } |
| | | |
| | | updateCard = (elements) => { |
| | | const { card } = this.state |
| | | |
| | | let _card = {...card, elements: elements} |
| | | |
| | | this.setState({ |
| | | card: _card |
| | | }) |
| | | |
| | | this.props.updateElement(_card) |
| | | } |
| | | |
| | | addElement = () => { |
| | | const { cards } = this.props |
| | | const { card } = this.state |
| | | |
| | | let newcard = {} |
| | | newcard.uuid = Utils.getuuid() |
| | | newcard.focus = true |
| | | |
| | | newcard.eleType = 'text' |
| | | newcard.datatype = 'dynamic' |
| | | newcard.height = 1 |
| | | |
| | | // 注册事件-添加元素 |
| | | MKEmitter.emit('cardAddElement', [cards.uuid, card.uuid], newcard) |
| | | } |
| | | |
| | | addButton = () => { |
| | | const { cards } = this.props |
| | | const { card } = this.state |
| | | |
| | | let newcard = {} |
| | | newcard.uuid = Utils.getuuid() |
| | | newcard.focus = true |
| | | |
| | | newcard.eleType = 'button' |
| | | newcard.label = 'button' |
| | | newcard.sqlType = '' |
| | | newcard.Ot = 'requiredSgl' |
| | | newcard.OpenType = 'prompt' |
| | | newcard.icon = '' |
| | | newcard.class = 'primary' |
| | | newcard.intertype = 'system' |
| | | newcard.execSuccess = 'grid' |
| | | newcard.execError = 'never' |
| | | newcard.popClose = 'never' |
| | | newcard.errorTime = 10 |
| | | newcard.verify = null |
| | | newcard.show = 'link' |
| | | |
| | | // 注册事件-添加元素 |
| | | MKEmitter.emit('cardAddElement', [cards.uuid, card.uuid], newcard) |
| | | } |
| | | |
| | | changeStyle = () => { |
| | | const { cards } = this.props |
| | | const { card } = this.state |
| | | |
| | | let options = ['background', 'border', 'padding', 'margin', 'shadow'] |
| | | |
| | | MKEmitter.emit('changeStyle', [cards.uuid, card.uuid], options, fromJS(card.style).toJS()) |
| | | } |
| | | |
| | | settingSubmit = () => { |
| | | const { card } = this.state |
| | | |
| | | this.settingRef.handleConfirm().then(res => { |
| | | this.setState({ |
| | | settingVisible: false, |
| | | card: {...card, setting: res} |
| | | }) |
| | | |
| | | this.props.updateElement({...card, setting: res}) |
| | | }) |
| | | } |
| | | |
| | | clickComponent = (e) => { |
| | | if ((sessionStorage.getItem('style-control') === 'true' || sessionStorage.getItem('style-control') === 'propcard') && this.props.cards.subtype === 'propcard') { |
| | | e.stopPropagation() |
| | | MKEmitter.emit('clickComponent', this.state.card, this.props.cards, 'propcard') |
| | | } |
| | | } |
| | | |
| | | render() { |
| | | const { cards } = this.props |
| | | const { card, elements, settingVisible, dict } = this.state |
| | | |
| | | let _style = {...card.style} |
| | | |
| | | if (_style.shadow) { |
| | | _style.boxShadow = '0 0 4px ' + _style.shadow |
| | | } |
| | | _style.height = cards.style.height |
| | | |
| | | return ( |
| | | <div className="card-item" style={_style} onClick={this.clickComponent} id={card.uuid}> |
| | | <CardCellComponent cards={cards} cardCell={card} side="front" elements={elements} updateElement={this.updateCard}/> |
| | | <div className="card-control"> |
| | | <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={ |
| | | <div className="mk-popover-control"> |
| | | <Icon className="plus" title="添加元素" onClick={this.addElement} type="plus" /> |
| | | <Icon className="plus" title="添加按钮" onClick={this.addButton} type="plus-square" /> |
| | | <Icon className="edit" title="编辑" type="edit" onClick={() => this.setState({settingVisible: true})} /> |
| | | <CopyComponent type="cardcell" card={card}/> |
| | | <Icon className="style" title="调整样式" onClick={this.changeStyle} type="font-colors" /> |
| | | {cards.subtype === 'propcard' ? <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={ |
| | | <div className="mk-popover-control"> |
| | | <Icon className="plus" title="左移" type="arrow-left" onClick={() => this.props.move(card, 'left')} /> |
| | | <Icon className="close" title="右移" type="arrow-right" onClick={() => this.props.move(card, 'right')} /> |
| | | </div> |
| | | } trigger="hover" getPopupContainer={() => document.getElementById(card.uuid + 'swap')}> |
| | | <Icon type="swap" id={card.uuid + 'swap'}/> |
| | | </Popover> : null} |
| | | {cards.subtype === 'propcard' ? <Icon className="close" title="删除卡片" type="delete" onClick={() => this.props.deleteElement(card)} /> : null} |
| | | </div> |
| | | } trigger="hover"> |
| | | <Icon type="tool" /> |
| | | </Popover> |
| | | </div> |
| | | <Modal |
| | | wrapClassName="popview-modal" |
| | | title={'卡片设置'} |
| | | visible={settingVisible} |
| | | width={700} |
| | | maskClosable={false} |
| | | okText={dict['model.submit']} |
| | | onOk={this.settingSubmit} |
| | | onCancel={() => { this.setState({ settingVisible: false }) }} |
| | | destroyOnClose |
| | | > |
| | | <SettingForm |
| | | dict={dict} |
| | | cards={cards} |
| | | setting={card.setting} |
| | | inputSubmit={this.settingSubmit} |
| | | wrappedComponentRef={(inst) => this.settingRef = inst} |
| | | /> |
| | | </Modal> |
| | | </div> |
| | | ) |
| | | } |
| | | } |
| | | |
| | | export default CardBoxComponent |
copy from src/mob/datasource/verifycard/columnform/index.scss
copy to src/menu/components/carousel/cardcomponent/index.scss
New file |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { Form, Row, Col, Radio, Tooltip, Icon, Input, Cascader, Select } from 'antd' |
| | | |
| | | import './index.scss' |
| | | |
| | | const { TextArea } = Input |
| | | |
| | | class SettingForm extends Component { |
| | | static propTpyes = { |
| | | dict: PropTypes.object, // 字典项 |
| | | cards: PropTypes.object, // 卡片集 |
| | | setting: PropTypes.object, // 数据源配置 |
| | | inputSubmit: PropTypes.func // 回车事件 |
| | | } |
| | | |
| | | state = { |
| | | type: this.props.setting.type || 'simple', |
| | | click: this.props.setting.click || '', |
| | | isApp: sessionStorage.getItem('appType') === 'pc', |
| | | menulist: [] |
| | | } |
| | | |
| | | UNSAFE_componentWillMount() { |
| | | const { isApp } = this.state |
| | | let menulist = null |
| | | |
| | | if (isApp) { |
| | | menulist = sessionStorage.getItem('appMenus') |
| | | } else { |
| | | menulist = sessionStorage.getItem('fstMenuList') |
| | | } |
| | | |
| | | if (menulist) { |
| | | try { |
| | | menulist = JSON.parse(menulist) |
| | | } catch { |
| | | menulist = [] |
| | | } |
| | | } else { |
| | | menulist = [] |
| | | } |
| | | |
| | | this.setState({menulist}) |
| | | } |
| | | |
| | | handleConfirm = () => { |
| | | // 表单提交时检查输入值是否正确 |
| | | return new Promise((resolve, reject) => { |
| | | this.props.form.validateFieldsAndScroll((err, values) => { |
| | | if (!err) { |
| | | resolve(values) |
| | | } else { |
| | | reject(err) |
| | | } |
| | | }) |
| | | }) |
| | | } |
| | | |
| | | handleSubmit = (e) => { |
| | | e.preventDefault() |
| | | |
| | | if (this.props.inputSubmit) { |
| | | this.props.inputSubmit() |
| | | } |
| | | } |
| | | |
| | | render() { |
| | | const { setting, cards } = this.props |
| | | const { getFieldDecorator } = this.props.form |
| | | const { click, menulist, isApp } = this.state |
| | | |
| | | const formItemLayout = { |
| | | labelCol: { |
| | | xs: { span: 24 }, |
| | | sm: { span: 8 } |
| | | }, |
| | | wrapperCol: { |
| | | xs: { span: 24 }, |
| | | sm: { span: 16 } |
| | | } |
| | | } |
| | | |
| | | return ( |
| | | <div className="model-menu-setting-form"> |
| | | <Form {...formItemLayout}> |
| | | <Row gutter={24}> |
| | | {cards.subtype === 'propcard' ? <Col span={12}> |
| | | <Form.Item label={ |
| | | <Tooltip placement="topLeft" title="卡片点击时,向其他组件传递的BID值。"> |
| | | <Icon type="question-circle" /> |
| | | 主键值 |
| | | </Tooltip> |
| | | }> |
| | | {getFieldDecorator('primaryId', { |
| | | initialValue: setting.primaryId || '' |
| | | })(<Input placeholder="" autoComplete="off" onPressEnter={this.handleSubmit}/>)} |
| | | </Form.Item> |
| | | </Col> : null} |
| | | <Col span={12}> |
| | | <Form.Item label="点击事件"> |
| | | {getFieldDecorator('click', { |
| | | initialValue: click |
| | | })( |
| | | <Radio.Group onChange={(e) => this.setState({click: e.target.value})}> |
| | | <Radio value="">无</Radio> |
| | | <Radio value="menu">菜单</Radio> |
| | | <Radio value="link">链接</Radio> |
| | | </Radio.Group> |
| | | )} |
| | | </Form.Item> |
| | | </Col> |
| | | {!isApp && click === 'menu' ? <Col span={12}> |
| | | <Form.Item label="菜单"> |
| | | {getFieldDecorator('menu', { |
| | | initialValue: setting.menu || [], |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: this.props.dict['form.required.select'] + '菜单!' |
| | | } |
| | | ] |
| | | })( |
| | | <Cascader options={menulist} placeholder=""/> |
| | | )} |
| | | </Form.Item> |
| | | </Col> : null} |
| | | {isApp && click === 'menu' ? <Col span={12}> |
| | | <Form.Item label="关联菜单"> |
| | | {getFieldDecorator('menu', { |
| | | initialValue: setting.menu || '', |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: this.props.dict['form.required.select'] + '关联菜单!' |
| | | } |
| | | ] |
| | | })( |
| | | <Select |
| | | showSearch |
| | | filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0} |
| | | > |
| | | {menulist.map(option => |
| | | <Select.Option key={option.MenuID} value={option.MenuID}>{option.MenuName}</Select.Option> |
| | | )} |
| | | </Select> |
| | | )} |
| | | </Form.Item> |
| | | </Col> : null} |
| | | {click === 'link' ? <Col span={24} className="textarea"> |
| | | <Form.Item label="链接"> |
| | | {getFieldDecorator('linkurl', { |
| | | initialValue: setting.linkurl || '', |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: this.props.dict['form.required.input'] + '链接!' |
| | | } |
| | | ] |
| | | })( <TextArea rows={2}/> )} |
| | | </Form.Item> |
| | | </Col> : null} |
| | | {isApp ? <Col span={12}> |
| | | <Form.Item label="打开方式"> |
| | | {getFieldDecorator('open', { |
| | | initialValue: setting.open || 'blank' |
| | | })( |
| | | <Radio.Group> |
| | | <Radio value="blank">新窗口</Radio> |
| | | <Radio value="self">当前窗口</Radio> |
| | | </Radio.Group> |
| | | )} |
| | | </Form.Item> |
| | | </Col> : null} |
| | | {click !== '' ? <Col span={12}> |
| | | <Form.Item label="参数拼接"> |
| | | {getFieldDecorator('joint', { |
| | | initialValue: setting.joint || 'true' |
| | | })( |
| | | <Radio.Group> |
| | | <Radio value="true">是</Radio> |
| | | <Radio value="false">否</Radio> |
| | | </Radio.Group> |
| | | )} |
| | | </Form.Item> |
| | | </Col> : null} |
| | | </Row> |
| | | </Form> |
| | | </div> |
| | | ) |
| | | } |
| | | } |
| | | |
| | | export default Form.create()(SettingForm) |
New file |
| | |
| | | .model-menu-setting-form { |
| | | position: relative; |
| | | |
| | | .anticon-question-circle { |
| | | color: #c49f47; |
| | | margin-right: 3px; |
| | | } |
| | | .ant-input-number { |
| | | width: 100%; |
| | | } |
| | | } |
New file |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { is, fromJS } from 'immutable' |
| | | import { Icon, Popover, Modal, notification } from 'antd' |
| | | |
| | | import asyncComponent from '@/utils/asyncComponent' |
| | | import asyncIconComponent from '@/utils/asyncIconComponent' |
| | | |
| | | import MKEmitter from '@/utils/events.js' |
| | | import Utils from '@/utils/utils.js' |
| | | import zhCN from '@/locales/zh-CN/model.js' |
| | | import enUS from '@/locales/en-US/model.js' |
| | | import './index.scss' |
| | | |
| | | const SettingComponent = asyncIconComponent(() => import('@/menu/datasource')) |
| | | const WrapComponent = asyncIconComponent(() => import('./wrapsetting')) |
| | | const CardComponent = asyncComponent(() => import('../cardcomponent')) |
| | | const LogComponent = asyncIconComponent(() => import('@/menu/components/share/logcomponent')) |
| | | const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent')) |
| | | const UserComponent = asyncIconComponent(() => import('@/menu/components/share/usercomponent')) |
| | | |
| | | const { confirm } = Modal |
| | | |
| | | class DataCardEditComponent extends Component { |
| | | static propTpyes = { |
| | | card: PropTypes.object, |
| | | deletecomponent: PropTypes.func, |
| | | updateConfig: PropTypes.func, |
| | | } |
| | | |
| | | state = { |
| | | dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | card: null, |
| | | back: false |
| | | } |
| | | |
| | | UNSAFE_componentWillMount () { |
| | | const { card } = this.props |
| | | |
| | | if (card.isNew) { |
| | | let _card = { |
| | | uuid: card.uuid, |
| | | type: card.type, |
| | | floor: card.floor, |
| | | tabId: card.tabId || '', |
| | | parentId: card.parentId || '', |
| | | format: 'array', // 组件属性 - 数据格式 |
| | | pageable: false, // 组件属性 - 是否可分页 |
| | | switchable: false, // 组件属性 - 数据是否可切换 |
| | | dataName: card.dataName || '', |
| | | width: card.width || 24, |
| | | name: card.name, |
| | | subtype: card.subtype, |
| | | setting: { interType: 'system' }, |
| | | wrap: { name: card.name, width: card.width || 24, autoplay: 'false', dots: 'true' }, |
| | | style: { borderWidth: '1px', borderColor: '#e8e8e8', marginTop: '8px', marginBottom: '8px', height: '300px' }, |
| | | columns: [], |
| | | scripts: [], |
| | | btnlog: [], |
| | | subcards: [{ |
| | | uuid: Utils.getuuid(), |
| | | setting: {}, |
| | | style: { |
| | | paddingTop: '15px', paddingBottom: '15px', paddingLeft: '15px', paddingRight: '15px', |
| | | }, |
| | | elements: [] |
| | | }] |
| | | } |
| | | |
| | | if (card.config) { |
| | | let config = fromJS(card.config).toJS() |
| | | |
| | | _card.wrap = config.wrap |
| | | _card.wrap.name = card.name |
| | | _card.style = config.style |
| | | |
| | | _card.subcards = config.subcards.map(scard => { |
| | | scard.uuid = Utils.getuuid() |
| | | scard.elements = scard.elements.map(elem => { |
| | | elem.uuid = Utils.getuuid() |
| | | return elem |
| | | }) |
| | | return scard |
| | | }) |
| | | } |
| | | |
| | | this.setState({ |
| | | card: _card |
| | | }) |
| | | this.props.updateConfig(_card) |
| | | } else { |
| | | this.setState({ |
| | | card: fromJS(card).toJS() |
| | | }) |
| | | } |
| | | } |
| | | |
| | | componentDidMount () { |
| | | MKEmitter.addListener('submitStyle', this.getStyle) |
| | | MKEmitter.addListener('logButton', this.logButton) |
| | | } |
| | | |
| | | shouldComponentUpdate (nextProps, nextState) { |
| | | return !is(fromJS(this.state), fromJS(nextState)) |
| | | } |
| | | |
| | | /** |
| | | * @description 组件销毁,清除state更新,清除快捷键设置 |
| | | */ |
| | | componentWillUnmount () { |
| | | this.setState = () => { |
| | | return |
| | | } |
| | | MKEmitter.removeListener('submitStyle', this.getStyle) |
| | | MKEmitter.removeListener('logButton', this.logButton) |
| | | } |
| | | |
| | | logButton = (id, item) => { |
| | | const { card } = this.state |
| | | |
| | | if (id !== card.uuid) return |
| | | |
| | | let btnlog = card.btnlog || [] |
| | | btnlog.push(item) |
| | | |
| | | this.setState({ |
| | | card: {...card, btnlog} |
| | | }) |
| | | this.props.updateConfig({...card, btnlog}) |
| | | } |
| | | |
| | | /** |
| | | * @description 卡片行外层信息更新(数据源,样式等) |
| | | */ |
| | | updateComponent = (component) => { |
| | | this.setState({ |
| | | card: component |
| | | }) |
| | | |
| | | component.width = component.wrap.width |
| | | component.name = component.wrap.name |
| | | |
| | | this.props.updateConfig(component) |
| | | } |
| | | |
| | | /** |
| | | * @description 单个卡片信息更新 |
| | | */ |
| | | updateCard = (cell) => { |
| | | let card = fromJS(this.state.card).toJS() |
| | | |
| | | card.subcards = card.subcards.map(item => { |
| | | if (item.uuid === cell.uuid) return cell |
| | | return item |
| | | }) |
| | | |
| | | this.setState({card}) |
| | | |
| | | this.props.updateConfig(card) |
| | | } |
| | | |
| | | /** |
| | | * @description 单个卡片信息更新 |
| | | */ |
| | | deleteCard = (cell) => { |
| | | let card = fromJS(this.state.card).toJS() |
| | | let _this = this |
| | | |
| | | confirm({ |
| | | content: '确定删除卡片吗?', |
| | | onOk() { |
| | | card.subcards = card.subcards.filter(item => item.uuid !== cell.uuid) |
| | | |
| | | let uuids = [] |
| | | cell.elements && cell.elements.forEach(c => { |
| | | if (c.eleType === 'button') { |
| | | uuids.push(c.uuid) |
| | | } |
| | | }) |
| | | MKEmitter.emit('delButtons', uuids) |
| | | |
| | | if (card.btnlog) { |
| | | card.btnlog = card.btnlog.filter(c => c.$parentId !== cell.uuid) |
| | | } |
| | | |
| | | _this.setState({card}) |
| | | _this.props.updateConfig(card) |
| | | }, |
| | | onCancel() {} |
| | | }) |
| | | } |
| | | |
| | | changeStyle = () => { |
| | | const { card } = this.state |
| | | |
| | | MKEmitter.emit('changeStyle', [card.uuid], ['height', 'background', 'border', 'padding', 'margin'], card.style) |
| | | } |
| | | |
| | | getStyle = (comIds, style) => { |
| | | const { card } = this.state |
| | | |
| | | if (comIds.length !== 1 || comIds[0] !== card.uuid) return |
| | | |
| | | let _card = {...card, style} |
| | | |
| | | this.setState({ |
| | | card: _card |
| | | }) |
| | | |
| | | this.props.updateConfig(_card) |
| | | } |
| | | |
| | | handleLog = (type, logs, item) => { |
| | | let card = fromJS(this.state.card).toJS() |
| | | |
| | | if (type === 'revert') { |
| | | card.subcards.forEach(col => { |
| | | col.elements = [...col.elements, item] |
| | | if (item.$parentId === col.uuid) { |
| | | col.elements = [...col.elements, item] |
| | | } |
| | | }) |
| | | |
| | | card.btnlog = logs |
| | | |
| | | this.setState({ card }) |
| | | this.props.updateConfig(card) |
| | | notification.success({ |
| | | top: 92, |
| | | message: '恢复成功!', |
| | | duration: 2 |
| | | }) |
| | | } else { |
| | | card.btnlog = logs |
| | | this.setState({ card }) |
| | | this.props.updateConfig(card) |
| | | notification.success({ |
| | | top: 92, |
| | | message: '清除成功!', |
| | | duration: 2 |
| | | }) |
| | | } |
| | | } |
| | | |
| | | clickComponent = (e) => { |
| | | if (sessionStorage.getItem('style-control') === 'true' || sessionStorage.getItem('style-control') === 'component') { |
| | | e.stopPropagation() |
| | | MKEmitter.emit('clickComponent', this.state.card) |
| | | } |
| | | } |
| | | |
| | | render() { |
| | | const { card } = this.state |
| | | |
| | | return ( |
| | | <div className="menu-data-carousel-edit-box" style={{...card.style}} onClick={this.clickComponent} id={card.uuid}> |
| | | <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={ |
| | | <div className="mk-popover-control"> |
| | | <WrapComponent config={card} updateConfig={this.updateComponent}/> |
| | | <CopyComponent type="datacard" card={card}/> |
| | | <Icon className="style" title="调整样式" onClick={this.changeStyle} type="font-colors"/> |
| | | <LogComponent btnlog={card.btnlog || []} handlelog={this.handleLog}/> |
| | | <UserComponent config={card}/> |
| | | <Icon className="close" title="删除组件" type="delete" onClick={() => this.props.deletecomponent(card.uuid)}/> |
| | | <SettingComponent config={card} updateConfig={this.updateComponent}/> |
| | | </div> |
| | | } trigger="hover"> |
| | | <Icon type="tool"/> |
| | | </Popover> |
| | | <CardComponent cards={card} card={card.subcards[0]} updateElement={this.updateCard} deleteElement={this.deleteCard}/> |
| | | </div> |
| | | ) |
| | | } |
| | | } |
| | | |
| | | export default DataCardEditComponent |
New file |
| | |
| | | .menu-data-carousel-edit-box { |
| | | position: relative; |
| | | box-sizing: border-box; |
| | | background: #ffffff; |
| | | background-position: center center; |
| | | background-repeat: no-repeat; |
| | | background-size: cover; |
| | | min-height: 30px; |
| | | |
| | | .card-control { |
| | | position: absolute; |
| | | top: 0px; |
| | | left: 0px; |
| | | .anticon-tool { |
| | | right: auto; |
| | | left: 1px; |
| | | padding: 1px; |
| | | } |
| | | } |
| | | .anticon-tool { |
| | | position: absolute; |
| | | z-index: 2; |
| | | font-size: 16px; |
| | | right: 1px; |
| | | top: 1px; |
| | | cursor: pointer; |
| | | padding: 5px; |
| | | background: rgba(255, 255, 255, 0.55); |
| | | } |
| | | |
| | | .card-item { |
| | | overflow: hidden; |
| | | position: relative; |
| | | background-position: center center; |
| | | background-repeat: no-repeat; |
| | | background-size: cover; |
| | | min-height: 20px; |
| | | height: 100%; |
| | | } |
| | | |
| | | .card-item:hover { |
| | | box-shadow: 0px 0px 2px #1890ff; |
| | | } |
| | | |
| | | .model-menu-card-cell-list .card-detail-row > .anticon-plus { |
| | | position: absolute; |
| | | right: -30px; |
| | | font-size: 16px; |
| | | } |
| | | .model-menu-action-list { |
| | | line-height: 40px; |
| | | .ant-row > .anticon-plus { |
| | | position: absolute; |
| | | right: -30px; |
| | | font-size: 16px; |
| | | } |
| | | } |
| | | .card-add-button { |
| | | text-align: right; |
| | | clear: left; |
| | | .anticon-plus { |
| | | font-size: 20px; |
| | | color: #26C281; |
| | | padding: 5px; |
| | | margin-right: 10px; |
| | | } |
| | | } |
| | | .ant-pagination { |
| | | float: right; |
| | | margin: 10px; |
| | | } |
| | | |
| | | .model-menu-action-list { |
| | | .page-card { |
| | | line-height: 55px; |
| | | } |
| | | } |
| | | } |
| | | .menu-carousel-edit-box::after { |
| | | display: block; |
| | | content: ' '; |
| | | clear: both; |
| | | } |
| | | .menu-carousel-edit-box:hover { |
| | | z-index: 1; |
| | | box-shadow: 0px 0px 4px #1890ff; |
| | | } |
New file |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { is, fromJS } from 'immutable' |
| | | import { Icon, Modal } from 'antd' |
| | | |
| | | import zhCN from '@/locales/zh-CN/model.js' |
| | | import enUS from '@/locales/en-US/model.js' |
| | | import SettingForm from './settingform' |
| | | import './index.scss' |
| | | |
| | | class DataSource extends Component { |
| | | static propTpyes = { |
| | | config: PropTypes.any, |
| | | updateConfig: PropTypes.func |
| | | } |
| | | |
| | | state = { |
| | | dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | visible: false, |
| | | wrap: null |
| | | } |
| | | |
| | | UNSAFE_componentWillMount () { |
| | | const { config } = this.props |
| | | |
| | | this.setState({wrap: fromJS(config.wrap).toJS()}) |
| | | } |
| | | |
| | | shouldComponentUpdate (nextProps, nextState) { |
| | | return !is(fromJS(this.props), fromJS(nextProps)) || !is(fromJS(this.state), fromJS(nextState)) |
| | | } |
| | | |
| | | editDataSource = () => { |
| | | this.setState({ |
| | | visible: true |
| | | }) |
| | | } |
| | | |
| | | verifySubmit = () => { |
| | | const { config } = this.props |
| | | |
| | | this.verifyRef.handleConfirm().then(res => { |
| | | |
| | | this.setState({ |
| | | wrap: res, |
| | | visible: false |
| | | }) |
| | | this.props.updateConfig({...config, wrap: res}) |
| | | }) |
| | | } |
| | | |
| | | render () { |
| | | const { config } = this.props |
| | | const { visible, dict, wrap } = this.state |
| | | |
| | | return ( |
| | | <div className="model-menu-setting-wrap"> |
| | | <Icon type="edit" title="编辑" onClick={() => this.editDataSource()} /> |
| | | <Modal |
| | | wrapClassName="popview-modal" |
| | | title="卡片设置" |
| | | visible={visible} |
| | | width={800} |
| | | maskClosable={false} |
| | | okText={dict['model.submit']} |
| | | onOk={this.verifySubmit} |
| | | onCancel={() => { this.setState({ visible: false }) }} |
| | | destroyOnClose |
| | | > |
| | | <SettingForm |
| | | dict={dict} |
| | | wrap={wrap} |
| | | config={config} |
| | | inputSubmit={this.verifySubmit} |
| | | wrappedComponentRef={(inst) => this.verifyRef = inst} |
| | | /> |
| | | </Modal> |
| | | </div> |
| | | ) |
| | | } |
| | | } |
| | | |
| | | export default DataSource |
New file |
| | |
| | | .model-menu-setting-wrap { |
| | | display: inline-block; |
| | | |
| | | >.anticon-edit { |
| | | color: #1890ff; |
| | | } |
| | | } |
New file |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { Form, Row, Col, Input, Radio, Tooltip, Icon, InputNumber, Select } from 'antd' |
| | | |
| | | import './index.scss' |
| | | |
| | | class SettingForm extends Component { |
| | | static propTpyes = { |
| | | dict: PropTypes.object, // 字典项 |
| | | config: PropTypes.object, // 卡片行信息 |
| | | wrap: PropTypes.object, // 数据源配置 |
| | | inputSubmit: PropTypes.func // 回车事件 |
| | | } |
| | | |
| | | state = { |
| | | roleList: [] |
| | | } |
| | | |
| | | UNSAFE_componentWillMount () { |
| | | let roleList = sessionStorage.getItem('sysRoles') |
| | | if (roleList) { |
| | | try { |
| | | roleList = JSON.parse(roleList) |
| | | } catch { |
| | | roleList = [] |
| | | } |
| | | } else { |
| | | roleList = [] |
| | | } |
| | | |
| | | this.setState({roleList}) |
| | | } |
| | | |
| | | handleConfirm = () => { |
| | | // 表单提交时检查输入值是否正确 |
| | | return new Promise((resolve, reject) => { |
| | | this.props.form.validateFieldsAndScroll((err, values) => { |
| | | if (!err) { |
| | | resolve(values) |
| | | } else { |
| | | reject(err) |
| | | } |
| | | }) |
| | | }) |
| | | } |
| | | |
| | | handleSubmit = (e) => { |
| | | e.preventDefault() |
| | | |
| | | if (this.props.inputSubmit) { |
| | | this.props.inputSubmit() |
| | | } |
| | | } |
| | | |
| | | render() { |
| | | const { wrap, config } = this.props |
| | | const { getFieldDecorator } = this.props.form |
| | | const { roleList } = this.state |
| | | |
| | | const formItemLayout = { |
| | | labelCol: { |
| | | xs: { span: 24 }, |
| | | sm: { span: 8 } |
| | | }, |
| | | wrapperCol: { |
| | | xs: { span: 24 }, |
| | | sm: { span: 16 } |
| | | } |
| | | } |
| | | |
| | | return ( |
| | | <div className="model-menu-setting-form"> |
| | | <Form {...formItemLayout}> |
| | | <Row gutter={24}> |
| | | <Col span={12}> |
| | | <Form.Item label={ |
| | | <Tooltip placement="topLeft" title="用于组件间的区分。"> |
| | | <Icon type="question-circle" /> |
| | | 组件名称 |
| | | </Tooltip> |
| | | }> |
| | | {getFieldDecorator('name', { |
| | | initialValue: wrap.name, |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: this.props.dict['form.required.input'] + '组件名称!' |
| | | } |
| | | ] |
| | | })(<Input placeholder={''} autoComplete="off" onPressEnter={this.handleSubmit} />)} |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={12}> |
| | | <Form.Item label={ |
| | | <Tooltip placement="topLeft" title="栅格布局,每行等分为24列。"> |
| | | <Icon type="question-circle" /> |
| | | 宽度 |
| | | </Tooltip> |
| | | }> |
| | | {getFieldDecorator('width', { |
| | | initialValue: wrap.width || 24, |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: this.props.dict['form.required.input'] + '宽度!' |
| | | } |
| | | ] |
| | | })(<InputNumber min={1} max={24} precision={0} onPressEnter={this.handleSubmit} />)} |
| | | </Form.Item> |
| | | </Col> |
| | | {config.subtype === 'propcard' ? <Col span={12}> |
| | | <Form.Item label={ |
| | | <Tooltip placement="topLeft" title="选择静态值,无需配置数据源。"> |
| | | <Icon type="question-circle" /> |
| | | 数据来源 |
| | | </Tooltip> |
| | | }> |
| | | {getFieldDecorator('datatype', { |
| | | initialValue: wrap.datatype || 'dynamic' |
| | | })( |
| | | <Radio.Group> |
| | | <Radio value="dynamic">动态</Radio> |
| | | <Radio value="static">静态</Radio> |
| | | </Radio.Group> |
| | | )} |
| | | </Form.Item> |
| | | </Col> : null} |
| | | <Col span={12}> |
| | | <Form.Item label="自动切换"> |
| | | {getFieldDecorator('autoplay', { |
| | | initialValue: wrap.autoplay || 'false' |
| | | })( |
| | | <Radio.Group> |
| | | <Radio value="false">否</Radio> |
| | | <Radio value="true">是</Radio> |
| | | </Radio.Group> |
| | | )} |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={12}> |
| | | <Form.Item label={ |
| | | <Tooltip placement="topLeft" title="使用自动切换时有效,默认为3秒。"> |
| | | <Icon type="question-circle" /> |
| | | 时间间隔 |
| | | </Tooltip> |
| | | }> |
| | | {getFieldDecorator('speed', { |
| | | initialValue: wrap.speed || 3 |
| | | })(<InputNumber min={1} max={100} precision={0} onPressEnter={this.handleSubmit} />)} |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={12}> |
| | | <Form.Item label="指示点"> |
| | | {getFieldDecorator('dots', { |
| | | initialValue: wrap.dots || 'true' |
| | | })( |
| | | <Radio.Group> |
| | | <Radio value="true">显示</Radio> |
| | | <Radio value="false">隐藏</Radio> |
| | | </Radio.Group> |
| | | )} |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={12}> |
| | | <Form.Item label="指示点位置"> |
| | | {getFieldDecorator('dotPosition', { |
| | | initialValue: wrap.dotPosition || 'bottom' |
| | | })( |
| | | <Radio.Group> |
| | | <Radio value="top">上</Radio> |
| | | <Radio value="bottom">下</Radio> |
| | | <Radio value="left">左</Radio> |
| | | <Radio value="right">右</Radio> |
| | | </Radio.Group> |
| | | )} |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={12}> |
| | | <Form.Item label="动画效果"> |
| | | {getFieldDecorator('effect', { |
| | | initialValue: wrap.effect || 'scrollx' |
| | | })( |
| | | <Radio.Group> |
| | | <Radio value="scrollx">切换</Radio> |
| | | <Radio value="fade">渐显</Radio> |
| | | </Radio.Group> |
| | | )} |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={12}> |
| | | <Form.Item label="黑名单"> |
| | | {getFieldDecorator('blacklist', { |
| | | initialValue: wrap.blacklist || [] |
| | | })( |
| | | <Select |
| | | showSearch |
| | | mode="multiple" |
| | | filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0} |
| | | > |
| | | {roleList.map(option => |
| | | <Select.Option key={option.uuid} value={option.value}>{option.text}</Select.Option> |
| | | )} |
| | | </Select> |
| | | )} |
| | | </Form.Item> |
| | | </Col> |
| | | </Row> |
| | | </Form> |
| | | </div> |
| | | ) |
| | | } |
| | | } |
| | | |
| | | export default Form.create()(SettingForm) |
New file |
| | |
| | | .model-menu-setting-form { |
| | | position: relative; |
| | | |
| | | .anticon-question-circle { |
| | | color: #c49f47; |
| | | margin-right: 3px; |
| | | } |
| | | .ant-input-number { |
| | | width: 100%; |
| | | } |
| | | } |
New file |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { is, fromJS } from 'immutable' |
| | | import { Icon, Popover, Modal, notification, Carousel } from 'antd' |
| | | |
| | | import asyncComponent from '@/utils/asyncComponent' |
| | | import asyncIconComponent from '@/utils/asyncIconComponent' |
| | | |
| | | import MKEmitter from '@/utils/events.js' |
| | | import Utils from '@/utils/utils.js' |
| | | import zhCN from '@/locales/zh-CN/model.js' |
| | | import enUS from '@/locales/en-US/model.js' |
| | | import './index.scss' |
| | | |
| | | const SettingComponent = asyncIconComponent(() => import('@/menu/datasource')) |
| | | const WrapComponent = asyncIconComponent(() => import('../data-card/wrapsetting')) |
| | | const CardComponent = asyncComponent(() => import('../cardcomponent')) |
| | | const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent')) |
| | | const PasteComponent = asyncIconComponent(() => import('@/menu/components/share/pastecomponent')) |
| | | const LogComponent = asyncIconComponent(() => import('@/menu/components/share/logcomponent')) |
| | | const UserComponent = asyncIconComponent(() => import('@/menu/components/share/usercomponent')) |
| | | |
| | | const { confirm } = Modal |
| | | |
| | | class PropCardEditComponent extends Component { |
| | | static propTpyes = { |
| | | card: PropTypes.object, |
| | | deletecomponent: PropTypes.func, |
| | | updateConfig: PropTypes.func, |
| | | } |
| | | |
| | | state = { |
| | | dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | card: null, |
| | | back: false |
| | | } |
| | | |
| | | UNSAFE_componentWillMount () { |
| | | const { card } = this.props |
| | | |
| | | if (card.isNew) { |
| | | let _card = { |
| | | uuid: card.uuid, |
| | | type: card.type, |
| | | floor: card.floor, |
| | | tabId: card.tabId || '', |
| | | parentId: card.parentId || '', |
| | | format: 'object', // 组件属性 - 数据格式 |
| | | pageable: false, // 组件属性 - 是否可分页 |
| | | switchable: false, // 组件属性 - 数据是否可切换 |
| | | dataName: card.dataName || '', |
| | | width: card.width || 24, |
| | | name: card.name, |
| | | subtype: card.subtype, |
| | | setting: { }, |
| | | wrap: { name: card.name, width: card.width || 24, datatype: 'static', autoplay: 'false', dots: 'true' }, |
| | | style: { borderWidth: '1px', borderColor: '#e8e8e8', marginLeft: '0px', marginRight: '0px', marginTop: '8px', marginBottom: '8px', height: '300px' }, |
| | | columns: [], |
| | | scripts: [], |
| | | subcards: [{ |
| | | uuid: Utils.getuuid(), |
| | | setting: {}, |
| | | style: {}, |
| | | elements: [], |
| | | }], |
| | | btnlog: [], |
| | | } |
| | | |
| | | if (card.config) { |
| | | let config = fromJS(card.config).toJS() |
| | | |
| | | _card.wrap = config.wrap |
| | | _card.wrap.name = card.name |
| | | _card.style = config.style |
| | | |
| | | _card.subcards = config.subcards.map(scard => { |
| | | scard.uuid = Utils.getuuid() |
| | | scard.elements = scard.elements.map(elem => { |
| | | elem.uuid = Utils.getuuid() |
| | | return elem |
| | | }) |
| | | return scard |
| | | }) |
| | | } |
| | | this.setState({ |
| | | card: _card |
| | | }) |
| | | this.props.updateConfig(_card) |
| | | } else { |
| | | this.setState({ |
| | | card: fromJS(card).toJS() |
| | | }) |
| | | } |
| | | } |
| | | |
| | | componentDidMount () { |
| | | MKEmitter.addListener('submitStyle', this.getStyle) |
| | | MKEmitter.addListener('logButton', this.logButton) |
| | | MKEmitter.addListener('submitComponentStyle', this.updateComponentStyle) |
| | | } |
| | | |
| | | shouldComponentUpdate (nextProps, nextState) { |
| | | return !is(fromJS(this.state), fromJS(nextState)) |
| | | } |
| | | |
| | | /** |
| | | * @description 组件销毁,清除state更新,清除快捷键设置 |
| | | */ |
| | | componentWillUnmount () { |
| | | this.setState = () => { |
| | | return |
| | | } |
| | | MKEmitter.removeListener('submitStyle', this.getStyle) |
| | | MKEmitter.removeListener('logButton', this.logButton) |
| | | MKEmitter.removeListener('submitComponentStyle', this.updateComponentStyle) |
| | | } |
| | | |
| | | updateComponentStyle = (parentId, keys, style) => { |
| | | const { card } = this.state |
| | | |
| | | if (card.uuid !== parentId) return |
| | | |
| | | let subcards = card.subcards.map(item => { |
| | | if (keys.includes(item.uuid)) { |
| | | item.style = {...item.style, ...style} |
| | | } |
| | | return item |
| | | }) |
| | | |
| | | this.setState({card: {...card, subcards: []}}, () => { |
| | | this.updateComponent({...card, subcards: subcards}) |
| | | }) |
| | | } |
| | | |
| | | logButton = (id, item) => { |
| | | const { card } = this.state |
| | | |
| | | if (id !== card.uuid) return |
| | | |
| | | let btnlog = card.btnlog || [] |
| | | btnlog.push(item) |
| | | |
| | | this.setState({ |
| | | card: {...card, btnlog} |
| | | }) |
| | | this.props.updateConfig({...card, btnlog}) |
| | | } |
| | | |
| | | /** |
| | | * @description 卡片行外层信息更新(数据源,样式等) |
| | | */ |
| | | updateComponent = (component) => { |
| | | this.setState({ |
| | | card: component |
| | | }) |
| | | |
| | | component.width = component.wrap.width |
| | | component.name = component.wrap.name |
| | | |
| | | this.props.updateConfig(component) |
| | | } |
| | | |
| | | /** |
| | | * @description 单个卡片信息更新 |
| | | */ |
| | | updateCard = (cell) => { |
| | | let card = fromJS(this.state.card).toJS() |
| | | |
| | | card.subcards = card.subcards.map(item => { |
| | | if (item.uuid === cell.uuid) return cell |
| | | return item |
| | | }) |
| | | |
| | | this.setState({card}) |
| | | |
| | | this.props.updateConfig(card) |
| | | } |
| | | |
| | | /** |
| | | * @description 单个卡片信息更新 |
| | | */ |
| | | deleteCard = (cell) => { |
| | | let card = fromJS(this.state.card).toJS() |
| | | let _this = this |
| | | |
| | | confirm({ |
| | | content: '确定删除卡片吗?', |
| | | onOk() { |
| | | card.subcards = card.subcards.filter(item => item.uuid !== cell.uuid) |
| | | |
| | | let uuids = [] |
| | | cell.elements && cell.elements.forEach(c => { |
| | | if (c.eleType === 'button') { |
| | | uuids.push(c.uuid) |
| | | } |
| | | }) |
| | | MKEmitter.emit('delButtons', uuids) |
| | | |
| | | if (card.btnlog) { |
| | | card.btnlog = card.btnlog.filter(c => c.$parentId !== cell.uuid) |
| | | } |
| | | |
| | | _this.setState({card}) |
| | | _this.props.updateConfig(card) |
| | | }, |
| | | onCancel() {} |
| | | }) |
| | | } |
| | | |
| | | changeStyle = () => { |
| | | const { card } = this.state |
| | | |
| | | MKEmitter.emit('changeStyle', [card.uuid], ['height', 'background', 'border', 'padding', 'margin'], card.style) |
| | | } |
| | | |
| | | getStyle = (comIds, style) => { |
| | | const { card } = this.state |
| | | |
| | | if (comIds.length !== 1 || comIds[0] !== card.uuid) return |
| | | |
| | | let _card = {...card, style} |
| | | |
| | | this.setState({ |
| | | card: _card |
| | | }) |
| | | |
| | | this.props.updateConfig(_card) |
| | | } |
| | | |
| | | addCard = () => { |
| | | let card = fromJS(this.state.card).toJS() |
| | | |
| | | let newcard = { |
| | | uuid: Utils.getuuid(), |
| | | setting: {}, |
| | | style: {}, |
| | | elements: [], |
| | | } |
| | | |
| | | if (card.subcards.length > 0) { |
| | | newcard = fromJS(card.subcards.slice(-1)[0]).toJS() |
| | | newcard.uuid = Utils.getuuid() |
| | | newcard.elements = newcard.elements.map(elem => { |
| | | elem.uuid = Utils.getuuid() |
| | | return elem |
| | | }) |
| | | } |
| | | |
| | | card.subcards.push(newcard) |
| | | |
| | | this.setState({card}) |
| | | this.props.updateConfig(card) |
| | | } |
| | | |
| | | handleLog = (type, logs, item) => { |
| | | let card = fromJS(this.state.card).toJS() |
| | | |
| | | if (type === 'revert') { |
| | | let done = false |
| | | if (item.$parentId) { |
| | | card.subcards.forEach(col => { |
| | | if (item.$parentId === col.uuid) { |
| | | col.elements = [...col.elements, item] |
| | | done = true |
| | | } |
| | | }) |
| | | } |
| | | |
| | | card.btnlog = logs |
| | | |
| | | this.setState({ card: {...card, subcards: []} }, () => { |
| | | this.setState({ card }) |
| | | this.props.updateConfig(card) |
| | | }) |
| | | if (!done) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '附属卡片已删除!', |
| | | duration: 2 |
| | | }) |
| | | } else { |
| | | notification.success({ |
| | | top: 92, |
| | | message: '恢复成功!', |
| | | duration: 2 |
| | | }) |
| | | } |
| | | } else { |
| | | card.btnlog = logs |
| | | this.setState({ card }) |
| | | this.props.updateConfig(card) |
| | | notification.success({ |
| | | top: 92, |
| | | message: '清除成功!', |
| | | duration: 2 |
| | | }) |
| | | } |
| | | } |
| | | |
| | | move = (item, direction) => { |
| | | let card = fromJS(this.state.card).toJS() |
| | | |
| | | let dragIndex = card.subcards.findIndex(c => c.uuid === item.uuid) |
| | | let hoverIndex = null |
| | | |
| | | if (direction === 'left') { |
| | | hoverIndex = dragIndex - 1 |
| | | } else { |
| | | hoverIndex = dragIndex + 1 |
| | | } |
| | | |
| | | if (hoverIndex === -1 || hoverIndex === card.subcards.length) return |
| | | |
| | | card.subcards.splice(hoverIndex, 0, ...card.subcards.splice(dragIndex, 1)) |
| | | |
| | | this.setState({card: {...card, subcards: []}}, () => { |
| | | this.setState({card}) |
| | | }) |
| | | this.props.updateConfig(card) |
| | | } |
| | | |
| | | clickComponent = (e) => { |
| | | if (sessionStorage.getItem('style-control') === 'true' || sessionStorage.getItem('style-control') === 'component') { |
| | | e.stopPropagation() |
| | | MKEmitter.emit('clickComponent', this.state.card) |
| | | } |
| | | } |
| | | |
| | | render() { |
| | | const { card } = this.state |
| | | |
| | | return ( |
| | | <div className="menu-prop-carousel-edit-box" style={{...card.style}} onClick={this.clickComponent} id={card.uuid}> |
| | | <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={ |
| | | <div className="mk-popover-control"> |
| | | <Icon className="plus" title="添加卡片" onClick={this.addCard} type="plus" /> |
| | | <WrapComponent config={card} updateConfig={this.updateComponent} /> |
| | | <CopyComponent type="propcard" card={card}/> |
| | | <PasteComponent config={card} options={['cardcell']} updateConfig={this.updateComponent} /> |
| | | <Icon className="style" title="调整样式" onClick={this.changeStyle} type="font-colors" /> |
| | | <LogComponent btnlog={card.btnlog || []} handlelog={this.handleLog} /> |
| | | <UserComponent config={card}/> |
| | | <Icon className="close" title="删除组件" type="delete" onClick={() => this.props.deletecomponent(card.uuid)} /> |
| | | {card.wrap.datatype !== 'static' ? <SettingComponent config={card} updateConfig={this.updateComponent} /> : null} |
| | | {card.wrap.datatype === 'static' ? <Icon style={{color: '#eeeeee', cursor: 'not-allowed'}} type="setting"/> : null} |
| | | </div> |
| | | } trigger="hover"> |
| | | <Icon type="tool" /> |
| | | </Popover> |
| | | {card.subcards.length > 0 ? <Carousel dotPosition={card.wrap.dotPosition || 'bottom'} effect={card.wrap.effect || 'scrollx'}> |
| | | {card.subcards.map((subcard) => (<CardComponent key={subcard.uuid} cards={card} card={subcard} move={this.move} updateElement={this.updateCard} deleteElement={this.deleteCard}/>))} |
| | | </Carousel> : null} |
| | | </div> |
| | | ) |
| | | } |
| | | } |
| | | |
| | | export default PropCardEditComponent |
New file |
| | |
| | | .menu-prop-carousel-edit-box { |
| | | position: relative; |
| | | box-sizing: border-box; |
| | | background: #ffffff; |
| | | background-position: center center; |
| | | background-repeat: no-repeat; |
| | | background-size: cover; |
| | | min-height: 30px; |
| | | |
| | | .card-control { |
| | | position: absolute; |
| | | top: 0px; |
| | | left: 0px; |
| | | .anticon-tool { |
| | | right: auto; |
| | | left: 1px; |
| | | padding: 1px; |
| | | } |
| | | } |
| | | .anticon-tool { |
| | | position: absolute; |
| | | z-index: 2; |
| | | font-size: 16px; |
| | | right: 1px; |
| | | top: 1px; |
| | | cursor: pointer; |
| | | padding: 5px; |
| | | background: rgba(255, 255, 255, 0.55); |
| | | } |
| | | |
| | | .card-item { |
| | | overflow: hidden; |
| | | position: relative; |
| | | background-position: center center; |
| | | background-repeat: no-repeat; |
| | | background-size: cover; |
| | | min-height: 20px; |
| | | height: 100%; |
| | | } |
| | | .ant-carousel:not(.ant-carousel-vertical) { |
| | | .slick-dots li button { |
| | | height: 8px; |
| | | } |
| | | } |
| | | .ant-carousel.ant-carousel-vertical { |
| | | .slick-dots li button { |
| | | width: 8px; |
| | | } |
| | | } |
| | | .ant-carousel { |
| | | .slick-dots li button { |
| | | background: #1890ff; |
| | | } |
| | | } |
| | | |
| | | .card-item:hover { |
| | | box-shadow: 0px 0px 2px #1890ff; |
| | | } |
| | | |
| | | .model-menu-card-cell-list .card-detail-row > .anticon-plus { |
| | | position: absolute; |
| | | right: -30px; |
| | | font-size: 16px; |
| | | } |
| | | .model-menu-action-list { |
| | | line-height: 40px; |
| | | .ant-row > .anticon-plus { |
| | | position: absolute; |
| | | right: -30px; |
| | | font-size: 16px; |
| | | } |
| | | } |
| | | .card-add-button { |
| | | text-align: right; |
| | | clear: left; |
| | | .anticon-plus { |
| | | font-size: 20px; |
| | | color: #26C281; |
| | | padding: 5px; |
| | | margin-right: 10px; |
| | | } |
| | | } |
| | | } |
| | | .menu-prop-card-edit-box::after { |
| | | display: block; |
| | | content: ' '; |
| | | clear: both; |
| | | } |
| | | .menu-prop-card-edit-box:hover { |
| | | z-index: 1; |
| | | box-shadow: 0px 0px 4px #1890ff; |
| | | } |
| | |
| | | import zhCN from '@/locales/zh-CN/model.js' |
| | | import enUS from '@/locales/en-US/model.js' |
| | | |
| | | const Formdict = localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS |
| | | const Formdict = sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS |
| | | |
| | | /** |
| | | * @description 获取图表视图配置表单 |
| | | * @param {object} card // 图表对象 |
| | | */ |
| | | export function getBaseForm (card) { |
| | | let menulist = sessionStorage.getItem('fstMenuList') |
| | | let isApp = sessionStorage.getItem('appType') === 'pc' |
| | | let menulist = null |
| | | |
| | | if (isApp) { |
| | | menulist = sessionStorage.getItem('appMenus') |
| | | } else { |
| | | menulist = sessionStorage.getItem('fstMenuList') |
| | | } |
| | | |
| | | if (menulist) { |
| | | try { |
| | | menulist = JSON.parse(menulist) |
| | | if (isApp) { |
| | | menulist = menulist.map(item => { |
| | | item.value = item.MenuID |
| | | item.text = item.MenuName |
| | | return item |
| | | }) |
| | | } |
| | | } catch { |
| | | menulist = [] |
| | | } |
| | |
| | | initVal: card.linkmenu || [], |
| | | tooltip: '在使用柱形图且未启用自定义设置时有效。', |
| | | required: false, |
| | | forbid: isApp, |
| | | options: menulist |
| | | }, |
| | | { |
| | | type: 'select', |
| | | key: 'linkmenu', |
| | | label: '关联菜单', |
| | | initVal: card.linkmenu || '', |
| | | tooltip: '双击饼图,会打开关联的菜单。', |
| | | required: false, |
| | | forbid: !isApp, |
| | | options: menulist |
| | | }, |
| | | { |
| | | type: 'radio', |
| | | key: 'open', |
| | | label: '打开方式', |
| | | initVal: card.open || 'blank', |
| | | required: false, |
| | | forbid: !isApp, |
| | | options: [ |
| | | { value: 'blank', text: '新窗口' }, |
| | | { value: 'self', text: '当前窗口' } |
| | | ] |
| | | } |
| | | ] |
| | | } |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import {connect} from 'react-redux' |
| | | import { is, fromJS } from 'immutable' |
| | | import { Icon, Popover, notification } from 'antd' |
| | | import { Chart } from '@antv/g2' |
| | |
| | | const NormalHeader = asyncComponent(() => import('@/menu/components/share/normalheader')) |
| | | const ActionComponent = asyncComponent(() => import('@/menu/components/share/actioncomponent')) |
| | | const UserComponent = asyncIconComponent(() => import('@/menu/components/share/usercomponent')) |
| | | const ClockComponent = asyncIconComponent(() => import('@/menu/components/share/clockcomponent')) |
| | | |
| | | class antvBarLineChart extends Component { |
| | | static propTpyes = { |
| | |
| | | } |
| | | |
| | | state = { |
| | | dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | card: null, |
| | | eventListener: null |
| | | } |
| | |
| | | } |
| | | |
| | | shouldComponentUpdate (nextProps, nextState) { |
| | | return !is(fromJS(this.state), fromJS(nextState)) || (!this.props.menu && nextProps.menu) |
| | | return !is(fromJS(this.state), fromJS(nextState)) |
| | | } |
| | | |
| | | /** |
| | |
| | | |
| | | let _card = {...card, style} |
| | | |
| | | // this.setState({ |
| | | // card: _card |
| | | // }) |
| | | |
| | | this.updateComponent(_card) |
| | | // this.props.updateConfig(_card) |
| | | } |
| | | |
| | | handleLog = (type, logs, item) => { |
| | |
| | | <PasteComponent config={card} options={['action', 'search', 'form']} updateConfig={this.updateComponent} /> |
| | | <Icon className="style" title="调整样式" onClick={this.changeStyle} type="font-colors" /> |
| | | <LogComponent btnlog={card.btnlog || []} handlelog={this.handleLog} /> |
| | | <ClockComponent config={card} updateConfig={this.updateComponent}/> |
| | | <UserComponent config={card}/> |
| | | <Icon className="close" title="delete" type="delete" onClick={() => this.props.deletecomponent(card.uuid)} /> |
| | | <SettingComponent config={card} updateConfig={this.updateComponent}/> |
| | |
| | | } |
| | | } |
| | | |
| | | const mapStateToProps = (state) => { |
| | | return { |
| | | menu: state.customMenu |
| | | } |
| | | } |
| | | |
| | | const mapDispatchToProps = () => { |
| | | return {} |
| | | } |
| | | |
| | | export default connect(mapStateToProps, mapDispatchToProps)(antvBarLineChart) |
| | | export default antvBarLineChart |
| | |
| | | // import zhCN from '@/locales/zh-CN/model.js' |
| | | // import enUS from '@/locales/en-US/model.js' |
| | | |
| | | // const Formdict = localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS |
| | | // const Formdict = sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS |
| | | |
| | | /** |
| | | * @description 获取图表视图配置表单 |
| | | * @param {object} card // 图表对象 |
| | | */ |
| | | export function getBaseForm (card) { |
| | | let menulist = sessionStorage.getItem('fstMenuList') |
| | | let isApp = sessionStorage.getItem('appType') === 'pc' |
| | | let menulist = null |
| | | |
| | | if (isApp) { |
| | | menulist = sessionStorage.getItem('appMenus') |
| | | } else { |
| | | menulist = sessionStorage.getItem('fstMenuList') |
| | | } |
| | | |
| | | if (menulist) { |
| | | try { |
| | | menulist = JSON.parse(menulist) |
| | | if (isApp) { |
| | | menulist = menulist.map(item => { |
| | | item.value = item.MenuID |
| | | item.text = item.MenuName |
| | | return item |
| | | }) |
| | | } |
| | | } catch { |
| | | menulist = [] |
| | | } |
| | |
| | | initVal: card.linkmenu || [], |
| | | tooltip: '双击饼图,会打开关联的菜单。', |
| | | required: false, |
| | | forbid: isApp, |
| | | options: menulist |
| | | }, |
| | | { |
| | | type: 'select', |
| | | key: 'linkmenu', |
| | | label: '关联菜单', |
| | | initVal: card.linkmenu || '', |
| | | tooltip: '双击饼图,会打开关联的菜单。', |
| | | required: false, |
| | | forbid: !isApp, |
| | | options: menulist |
| | | }, |
| | | { |
| | | type: 'radio', |
| | | key: 'open', |
| | | label: '打开方式', |
| | | initVal: card.open || 'blank', |
| | | required: false, |
| | | forbid: !isApp, |
| | | options: [ |
| | | { value: 'blank', text: '新窗口' }, |
| | | { value: 'self', text: '当前窗口' } |
| | | ] |
| | | } |
| | | ] |
| | | } |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import {connect} from 'react-redux' |
| | | import { is, fromJS } from 'immutable' |
| | | import { Icon, Popover, notification } from 'antd' |
| | | import { Chart } from '@antv/g2' |
| | |
| | | const LogComponent = asyncIconComponent(() => import('@/menu/components/share/logcomponent')) |
| | | const NormalHeader = asyncComponent(() => import('@/menu/components/share/normalheader')) |
| | | const UserComponent = asyncIconComponent(() => import('@/menu/components/share/usercomponent')) |
| | | const ClockComponent = asyncIconComponent(() => import('@/menu/components/share/clockcomponent')) |
| | | |
| | | class antvBarLineChart extends Component { |
| | | static propTpyes = { |
| | |
| | | } |
| | | |
| | | state = { |
| | | dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | card: null, |
| | | eventListener: null |
| | | } |
| | |
| | | } |
| | | |
| | | shouldComponentUpdate (nextProps, nextState) { |
| | | return !is(fromJS(this.state), fromJS(nextState)) || (!this.props.menu && nextProps.menu) |
| | | return !is(fromJS(this.state), fromJS(nextState)) |
| | | } |
| | | |
| | | /** |
| | |
| | | <PasteComponent config={card} options={['search', 'form']} updateConfig={this.updateComponent} /> |
| | | <Icon className="style" title="调整样式" onClick={this.changeStyle} type="font-colors" /> |
| | | <LogComponent btnlog={card.btnlog || []} handlelog={this.handleLog} /> |
| | | <ClockComponent config={card} updateConfig={this.updateComponent}/> |
| | | <UserComponent config={card}/> |
| | | <Icon className="close" title="delete" type="delete" onClick={() => this.props.deletecomponent(card.uuid)} /> |
| | | <SettingComponent config={card} updateConfig={this.updateComponent}/> |
| | |
| | | } |
| | | } |
| | | |
| | | const mapStateToProps = (state) => { |
| | | return { |
| | | menu: state.customMenu |
| | | } |
| | | } |
| | | |
| | | const mapDispatchToProps = () => { |
| | | return {} |
| | | } |
| | | |
| | | export default connect(mapStateToProps, mapDispatchToProps)(antvBarLineChart) |
| | | export default antvBarLineChart |
| | |
| | | } |
| | | |
| | | state = { |
| | | dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | visible: false, |
| | | html: '', |
| | | css: '', |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import {connect} from 'react-redux' |
| | | import { is, fromJS } from 'immutable' |
| | | import { Icon, Popover } from 'antd' |
| | | |
| | |
| | | } |
| | | |
| | | state = { |
| | | dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | card: null, |
| | | back: false |
| | | } |
| | |
| | | } |
| | | |
| | | shouldComponentUpdate (nextProps, nextState) { |
| | | return !is(fromJS(this.state), fromJS(nextState)) || (!this.props.menu && nextProps.menu) |
| | | return !is(fromJS(this.state), fromJS(nextState)) |
| | | } |
| | | |
| | | /** |
| | |
| | | } |
| | | } |
| | | |
| | | const mapStateToProps = (state) => { |
| | | return { |
| | | menu: state.customMenu |
| | | } |
| | | } |
| | | |
| | | const mapDispatchToProps = () => { |
| | | return {} |
| | | } |
| | | |
| | | export default connect(mapStateToProps, mapDispatchToProps)(CodeSandBox) |
| | | export default CodeSandBox |
| | |
| | | } |
| | | |
| | | state = { |
| | | dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | visible: false, |
| | | wrap: null |
| | | } |
| | |
| | | } |
| | | |
| | | state = { |
| | | dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | visible: false, |
| | | html: null |
| | | } |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import {connect} from 'react-redux' |
| | | import { is, fromJS } from 'immutable' |
| | | import { Icon, Popover } from 'antd' |
| | | |
| | |
| | | } |
| | | |
| | | state = { |
| | | dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | card: null, |
| | | back: false |
| | | } |
| | |
| | | } |
| | | |
| | | shouldComponentUpdate (nextProps, nextState) { |
| | | return !is(fromJS(this.state), fromJS(nextState)) || (!this.props.menu && nextProps.menu) |
| | | return !is(fromJS(this.state), fromJS(nextState)) |
| | | } |
| | | |
| | | /** |
| | |
| | | } |
| | | } |
| | | |
| | | const mapStateToProps = (state) => { |
| | | return { |
| | | menu: state.customMenu |
| | | } |
| | | } |
| | | |
| | | const mapDispatchToProps = () => { |
| | | return {} |
| | | } |
| | | |
| | | export default connect(mapStateToProps, mapDispatchToProps)(BraftEditorComponent) |
| | | export default BraftEditorComponent |
| | |
| | | } |
| | | |
| | | state = { |
| | | dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | visible: false, |
| | | wrap: null |
| | | } |
New file |
| | |
| | | import React from 'react' |
| | | import { useDrag, useDrop } from 'react-dnd' |
| | | import { Icon, Popover } from 'antd' |
| | | |
| | | import './index.scss' |
| | | |
| | | const Card = ({ id, card, active, moveCard, findCard, editCard, closeCard, selectCard }) => { |
| | | const originalIndex = findCard(id).index |
| | | const [{ isDragging }, drag] = useDrag({ |
| | | item: { type: 'form', id, originalIndex }, |
| | | collect: monitor => ({ |
| | | isDragging: monitor.isDragging(), |
| | | }), |
| | | }) |
| | | const [, drop] = useDrop({ |
| | | accept: 'form', |
| | | canDrop: () => true, |
| | | drop: (item) => { |
| | | const { id: draggedId, originalIndex } = item |
| | | |
| | | if (originalIndex === undefined) { |
| | | item.dropTargetId = id |
| | | } else if (draggedId && draggedId !== id) { |
| | | const { index: overIndex } = findCard(id) |
| | | moveCard(draggedId, overIndex) |
| | | } |
| | | } |
| | | }) |
| | | const opacity = isDragging ? 0 : 1 |
| | | |
| | | const edit = () => { |
| | | editCard(id) |
| | | } |
| | | |
| | | const close = () => { |
| | | closeCard(id) |
| | | } |
| | | |
| | | const select = () => { |
| | | selectCard(id) |
| | | } |
| | | |
| | | return ( |
| | | <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={ |
| | | <div className="mk-popover-control"> |
| | | <Icon className="edit" type="edit" onClick={edit} /> |
| | | <Icon className="close" type="close" onClick={close} /> |
| | | </div> |
| | | } trigger="hover"> |
| | | <div className={'page-card ' + (active ? 'active' : '')} onClick={select} style={{ opacity: opacity}}> |
| | | <div ref={node => drag(drop(node))}> |
| | | <span className="form-sort">{card.sort}</span> |
| | | {card.setting.title} |
| | | </div> |
| | | </div> |
| | | </Popover> |
| | | ) |
| | | } |
| | | export default Card |
New file |
| | |
| | | import React, { useState } from 'react' |
| | | import { is, fromJS } from 'immutable' |
| | | import update from 'immutability-helper' |
| | | import Card from './card' |
| | | import './index.scss' |
| | | |
| | | const Container = ({list, selectId, handleList, handleGroup, closeGroup, selectGroup}) => { |
| | | const [cards, setCards] = useState(list) |
| | | const moveCard = (id, atIndex) => { |
| | | const { card, index } = findCard(id) |
| | | |
| | | if (!card) return |
| | | |
| | | const _cards = update(cards, { $splice: [[index, 1], [atIndex, 0, card]] }) |
| | | |
| | | handleList(_cards) |
| | | } |
| | | |
| | | if (!is(fromJS(cards), fromJS(list))) { |
| | | setCards(list) |
| | | } |
| | | |
| | | const findCard = id => { |
| | | const card = cards.filter(c => `${c.uuid}` === id)[0] |
| | | return { |
| | | card, |
| | | index: cards.indexOf(card), |
| | | } |
| | | } |
| | | |
| | | const editCard = id => { |
| | | const { card } = findCard(id) |
| | | handleGroup(card) |
| | | } |
| | | |
| | | const closeCard = id => { |
| | | const { card } = findCard(id) |
| | | closeGroup(card) |
| | | } |
| | | |
| | | const selectCard = id => { |
| | | const { card } = findCard(id) |
| | | selectGroup(card) |
| | | } |
| | | |
| | | return ( |
| | | <div className="normal-form-titles" > |
| | | {cards.map(card => ( |
| | | <Card |
| | | id={card.uuid} |
| | | key={card.uuid} |
| | | active={card.uuid === selectId} |
| | | card={card} |
| | | moveCard={moveCard} |
| | | editCard={editCard} |
| | | closeCard={closeCard} |
| | | findCard={findCard} |
| | | selectCard={selectCard} |
| | | /> |
| | | ))} |
| | | </div> |
| | | ) |
| | | } |
| | | export default Container |
New file |
| | |
| | | .normal-form-titles { |
| | | display: flex; |
| | | line-height: 30px; |
| | | min-height: 50px; |
| | | .page-card { |
| | | position: relative; |
| | | flex: 1; |
| | | text-align: center; |
| | | cursor: move; |
| | | .form-sort { |
| | | background: #d8d8d8; |
| | | display: block; |
| | | width: 20px; |
| | | height: 20px; |
| | | line-height: 20px; |
| | | border-radius: 20px; |
| | | text-align: center; |
| | | color: #ffffff; |
| | | margin: 10px auto 0px; |
| | | position: relative; |
| | | z-index: 1; |
| | | } |
| | | } |
| | | .page-card:not(:first-child)::before { |
| | | position: absolute; |
| | | content: ' '; |
| | | display: inline-block; |
| | | width: 100%; |
| | | height: 2px; |
| | | background: #d8d8d8; |
| | | left: -50%; |
| | | top: 18px; |
| | | } |
| | | .page-card.active { |
| | | .form-sort { |
| | | background: #1890ff; |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | // import { fromJS } from 'immutable' |
| | | import { Form, Row, Col, Input, Select, Icon, Radio, Tooltip, InputNumber, Cascader } from 'antd' |
| | | import { formRule } from '@/utils/option.js' |
| | | |
| | | import './index.scss' |
| | | |
| | | const { TextArea } = Input |
| | | |
| | | class ActionForm extends Component { |
| | | static propTpyes = { |
| | | dict: PropTypes.object, // 字典项 |
| | | formlist: PropTypes.any, // 表单信息 |
| | | card: PropTypes.any, // 按钮信息 |
| | | inputSubmit: PropTypes.any // 回车提交事件 |
| | | } |
| | | |
| | | state = { |
| | | formlist: null, // 表单信息 |
| | | interType: null, // 接口类型:内部、外部 |
| | | procMode: null, // 参数方式 |
| | | } |
| | | |
| | | |
| | | UNSAFE_componentWillMount () { |
| | | const { card } = this.props |
| | | |
| | | let _intertype = card.intertype || 'system' // 接口类型 |
| | | let _procMode = card.procMode || 'system' // 参数请求方式 |
| | | |
| | | let _options = this.getOptions(_intertype, _procMode) |
| | | |
| | | this.setState({ |
| | | interType: _intertype, |
| | | procMode: _procMode, |
| | | formlist: this.props.formlist.map(item => { |
| | | if (item.key === 'innerFunc' && _procMode === 'inner') { |
| | | item.required = true |
| | | } |
| | | |
| | | item.hidden = !_options.includes(item.key) |
| | | return item |
| | | }) |
| | | }) |
| | | } |
| | | |
| | | getOptions = (_intertype, _procMode) => { |
| | | const { card } = this.props |
| | | |
| | | if (card.type === 'prev') { |
| | | return ['type', 'label'] |
| | | } else if (card.type === 'next') { |
| | | return ['type', 'label', 'enable'] |
| | | } |
| | | let _options = ['type', 'label', 'intertype', 'syncComponent', 'linkmenu', 'open'] // 选项列表 |
| | | |
| | | if (_intertype === 'custom') { |
| | | _options.push('procMode', 'interface', 'callbackType', 'cbTable', 'proInterface', 'method', 'cross') |
| | | if (_procMode === 'system') { |
| | | _options.push('sql', 'sqlType') |
| | | } else { |
| | | _options.push('innerFunc') |
| | | } |
| | | } else if (_intertype === 'outer') { |
| | | _options.push('innerFunc', 'sysInterface', 'interface', 'proInterface', 'outerFunc', 'callbackFunc') |
| | | } else if (_intertype === 'inner') { |
| | | _options.push('innerFunc') |
| | | } else { |
| | | _options.push('sql', 'sqlType') |
| | | } |
| | | |
| | | return _options |
| | | } |
| | | |
| | | /** |
| | | * @description 下拉切换 |
| | | * 1、打开方式切换,重置可见表单和表单值 |
| | | * 2、显示位置切换,重置选择行 |
| | | * 3、切换标签类型,重置可选标签 |
| | | */ |
| | | optionChange = (key, value) => { |
| | | const { procMode } = this.state |
| | | |
| | | if (key === 'intertype') { |
| | | let _options = this.getOptions(value, procMode) |
| | | |
| | | this.setState({ |
| | | interType: value, |
| | | formlist: this.state.formlist.map(item => { |
| | | item.hidden = !_options.includes(item.key) |
| | | |
| | | if (item.key === 'interface') { |
| | | item.readonly = false |
| | | } else if (item.key === 'sysInterface') { |
| | | item.initVal = 'false' |
| | | } |
| | | return item |
| | | }) |
| | | }) |
| | | } else if (key === 'procMode') { |
| | | let _options = this.getOptions(this.state.interType, value) |
| | | |
| | | this.setState({ |
| | | procMode: value, |
| | | formlist: this.state.formlist.map(item => { |
| | | item.hidden = !_options.includes(item.key) |
| | | |
| | | if (item.key === 'innerFunc') { |
| | | item.required = true |
| | | } |
| | | return item |
| | | }) |
| | | }) |
| | | } else if (key === 'sysInterface') { |
| | | if (value === 'true') { |
| | | this.props.form.setFieldsValue({ |
| | | interface: window.GLOB.mainSystemApi || '' |
| | | }) |
| | | } |
| | | this.setState({ |
| | | formlist: this.state.formlist.map(item => { |
| | | if (item.key === 'interface' && value === 'true') { |
| | | item.readonly = true |
| | | } else if (item.key === 'interface') { |
| | | item.readonly = false |
| | | } |
| | | |
| | | return item |
| | | }) |
| | | }) |
| | | } |
| | | } |
| | | |
| | | handleSubmit = (e) => { |
| | | e.preventDefault() |
| | | |
| | | if (this.props.inputSubmit) { |
| | | this.props.inputSubmit() |
| | | } |
| | | } |
| | | |
| | | getFields() { |
| | | const { getFieldDecorator } = this.props.form |
| | | const fields = [] |
| | | |
| | | this.state.formlist.forEach((item, index) => { |
| | | if (item.hidden || item.forbid) return |
| | | |
| | | if (item.type === 'text') { // 文本搜索 |
| | | let _rules = [] |
| | | if (item.key === 'innerFunc') { |
| | | let str = '^(' + item.fields.join('|') + ')' |
| | | let _patten = new RegExp(str + formRule.func.innerPattern + '$', 'g') |
| | | _rules = [{ |
| | | pattern: _patten, |
| | | message: formRule.func.innerMessage |
| | | }, { |
| | | max: formRule.func.max, |
| | | message: formRule.func.maxMessage |
| | | }] |
| | | } else if (item.key === 'outerFunc' || item.key === 'callbackFunc') { |
| | | _rules = [{ |
| | | pattern: formRule.func.pattern, |
| | | message: formRule.func.message |
| | | }, { |
| | | max: formRule.func.max, |
| | | message: formRule.func.maxMessage |
| | | }] |
| | | } else { |
| | | _rules = [{ |
| | | max: formRule.input.max, |
| | | message: formRule.input.message |
| | | }] |
| | | } |
| | | fields.push( |
| | | <Col span={12} key={index}> |
| | | <Form.Item label={item.tooltip ? |
| | | <Tooltip placement="topLeft" overlayClassName={item.tooltipClass} title={item.tooltip}> |
| | | <Icon type="question-circle" /> |
| | | {item.label} |
| | | </Tooltip> : item.label |
| | | }> |
| | | {getFieldDecorator(item.key, { |
| | | initialValue: item.initVal || '', |
| | | rules: [ |
| | | { |
| | | required: item.readonly ? false : !!item.required, |
| | | message: this.props.dict['form.required.input'] + item.label + '!' |
| | | }, |
| | | ..._rules |
| | | ] |
| | | })(<Input placeholder="" autoComplete="off" disabled={item.readonly} onPressEnter={this.handleSubmit} />)} |
| | | </Form.Item> |
| | | </Col> |
| | | ) |
| | | } else if (item.type === 'tip') { |
| | | fields.push( |
| | | <Col span={12} key={index}> |
| | | <Form.Item label={item.label}> |
| | | {item.initVal} |
| | | </Form.Item> |
| | | </Col> |
| | | ) |
| | | } else if (item.type === 'number') { |
| | | fields.push( |
| | | <Col span={12} key={index}> |
| | | <Form.Item label={item.tooltip ? |
| | | <Tooltip placement="topLeft" overlayClassName={item.tooltipClass} title={item.tooltip}> |
| | | <Icon type="question-circle" /> |
| | | {item.label} |
| | | </Tooltip> : item.label |
| | | }> |
| | | {getFieldDecorator(item.key, { |
| | | initialValue: item.initVal, |
| | | rules: [ |
| | | { |
| | | required: item.readonly ? false : !!item.required, |
| | | message: this.props.dict['form.required.input'] + item.label + '!' |
| | | } |
| | | ] |
| | | })(<InputNumber min={0} max={10000} precision={0} />)} |
| | | </Form.Item> |
| | | </Col> |
| | | ) |
| | | } else if (item.type === 'select') { // 下拉搜索 |
| | | fields.push( |
| | | <Col span={12} key={index}> |
| | | <Form.Item label={item.tooltip ? |
| | | <Tooltip placement="topLeft" overlayClassName={item.tooltipClass} title={item.tooltip}> |
| | | <Icon type="question-circle" /> |
| | | {item.label} |
| | | </Tooltip> : item.label |
| | | }> |
| | | {getFieldDecorator(item.key, { |
| | | initialValue: item.initVal || '', |
| | | rules: [ |
| | | { |
| | | required: !!item.required, |
| | | message: this.props.dict['form.required.select'] + item.label + '!' |
| | | } |
| | | ] |
| | | })( |
| | | <Select |
| | | showSearch |
| | | filterOption={(input, option) => option.props.children[2].toLowerCase().indexOf(input.toLowerCase()) >= 0} |
| | | onChange={(value) => {this.optionChange(item.key, value)}} |
| | | getPopupContainer={() => document.getElementById('winter')} |
| | | > |
| | | {item.options.map((option, index) => |
| | | <Select.Option id={`${index}`} title={option.text} key={`${index}`} value={option.value}> |
| | | {option.text} |
| | | </Select.Option> |
| | | )} |
| | | </Select> |
| | | )} |
| | | </Form.Item> |
| | | </Col> |
| | | ) |
| | | } else if (item.type === 'radio') { |
| | | fields.push( |
| | | <Col span={12} key={index}> |
| | | <Form.Item label={item.tooltip ? |
| | | <Tooltip placement="topLeft" overlayClassName={item.tooltipClass} title={item.tooltip}> |
| | | <Icon type="question-circle" /> |
| | | {item.label} |
| | | </Tooltip> : item.label |
| | | }> |
| | | {getFieldDecorator(item.key, { |
| | | initialValue: item.initVal, |
| | | rules: [ |
| | | { |
| | | required: !!item.required, |
| | | message: this.props.dict['form.required.select'] + item.label + '!' |
| | | } |
| | | ] |
| | | })( |
| | | <Radio.Group onChange={(e) => {this.optionChange(item.key, e.target.value)}} disabled={item.readonly}> |
| | | { |
| | | item.options.map(option => { |
| | | return ( |
| | | <Radio key={option.value} value={option.value}>{option.text}</Radio> |
| | | ) |
| | | }) |
| | | } |
| | | </Radio.Group> |
| | | )} |
| | | </Form.Item> |
| | | </Col> |
| | | ) |
| | | } else if (item.type === 'textarea') { |
| | | fields.push( |
| | | <Col span={24} key={index}> |
| | | <Form.Item label={item.label} className="textarea"> |
| | | {getFieldDecorator(item.key, { |
| | | initialValue: item.initVal, |
| | | rules: [ |
| | | { |
| | | required: item.readonly ? false : !!item.required, |
| | | message: this.props.dict['form.required.input'] + item.label + '!' |
| | | } |
| | | ] |
| | | })(<TextArea rows={2} readOnly={item.readonly}/>)} |
| | | </Form.Item> |
| | | </Col> |
| | | ) |
| | | } else if (item.type === 'cascader') { |
| | | fields.push( |
| | | <Col span={12} key={index}> |
| | | <Form.Item label={item.tooltip ? |
| | | <Tooltip placement="topLeft" overlayClassName={item.tooltipClass} title={item.tooltip}> |
| | | <Icon type="question-circle" /> |
| | | {item.label} |
| | | </Tooltip> : item.label |
| | | }> |
| | | {getFieldDecorator(item.key, { |
| | | initialValue: item.initVal || [], |
| | | rules: [ |
| | | { |
| | | required: !!item.required, |
| | | message: this.props.dict['form.required.select'] + item.label + '!' |
| | | } |
| | | ] |
| | | })( |
| | | <Cascader options={item.options || []} expandTrigger="hover" placeholder=""/> |
| | | )} |
| | | </Form.Item> |
| | | </Col> |
| | | ) |
| | | } |
| | | }) |
| | | return fields |
| | | } |
| | | |
| | | handleConfirm = () => { |
| | | // 表单提交时检查输入值是否正确 |
| | | return new Promise((resolve, reject) => { |
| | | this.props.form.validateFieldsAndScroll((err, values) => { |
| | | if (!err) { |
| | | resolve(values) |
| | | } else { |
| | | reject(err) |
| | | } |
| | | }) |
| | | }) |
| | | } |
| | | |
| | | render() { |
| | | const formItemLayout = { |
| | | labelCol: { |
| | | xs: { span: 24 }, |
| | | sm: { span: 7 } |
| | | }, |
| | | wrapperCol: { |
| | | xs: { span: 24 }, |
| | | sm: { span: 17 } |
| | | } |
| | | } |
| | | return ( |
| | | <Form {...formItemLayout} className="menu-action-list-form" id="winter"> |
| | | <Row gutter={24}>{this.getFields()}</Row> |
| | | </Form> |
| | | ) |
| | | } |
| | | } |
| | | |
| | | export default Form.create()(ActionForm) |
New file |
| | |
| | | .menu-action-list-form { |
| | | min-height: 190px; |
| | | .superconfig { |
| | | color: #1890ff; |
| | | cursor: pointer; |
| | | } |
| | | .textarea { |
| | | .ant-col-sm-7 { |
| | | width: 14%; |
| | | } |
| | | .ant-col-sm-17 { |
| | | width: 86%; |
| | | } |
| | | } |
| | | .ant-radio-group { |
| | | white-space: nowrap; |
| | | .ant-radio-wrapper { |
| | | margin-right: 4px; |
| | | } |
| | | } |
| | | .ant-input-number { |
| | | width: 100%; |
| | | } |
| | | .anticon-question-circle { |
| | | color: #c49f47; |
| | | position: relative; |
| | | left: -3px; |
| | | } |
| | | .with-button { |
| | | .ant-form-item-control-wrapper { |
| | | padding-right: 63px; |
| | | } |
| | | .ant-btn { |
| | | position: absolute; |
| | | right: 12px; |
| | | top: 4.5px; |
| | | } |
| | | } |
| | | .ant-input:read-only { |
| | | background: #fafafa; |
| | | resize: none; |
| | | } |
| | | .ant-input:read-only:hover, .ant-input:read-only:focus { |
| | | border-color: #d9d9d9; |
| | | box-shadow: none; |
| | | } |
| | | } |
New file |
| | |
| | | import zhCN from '@/locales/zh-CN/model.js' |
| | | import enUS from '@/locales/en-US/model.js' |
| | | |
| | | const Formdict = sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS |
| | | |
| | | /** |
| | | * @description 获取表单按钮配置信息 |
| | | * @param {*} card 编辑按钮 |
| | | * @param {*} type 按钮类型,用于区分可选的打开方式 |
| | | */ |
| | | |
| | | export function getActionForm (card, functip, tableName, usefulFields, modules) { |
| | | const isApp = sessionStorage.getItem('appType') === 'pc' |
| | | let _type = '提交' |
| | | if (card.type === 'prev') { |
| | | _type = '上一步' |
| | | } else if (card.type === 'next') { |
| | | _type = '下一步' |
| | | } |
| | | |
| | | let menulist = [] |
| | | if (isApp) { |
| | | menulist = sessionStorage.getItem('appMenus') |
| | | if (menulist) { |
| | | try { |
| | | menulist = JSON.parse(menulist) |
| | | menulist = menulist.map(item => ({value: item.MenuID, text: item.MenuName})) |
| | | } catch { |
| | | menulist = [] |
| | | } |
| | | } else { |
| | | menulist = [] |
| | | } |
| | | menulist.unshift({value: '', text: '无'}) |
| | | } else { |
| | | menulist = sessionStorage.getItem('fstMenuList') |
| | | if (menulist) { |
| | | try { |
| | | menulist = JSON.parse(menulist) |
| | | } catch { |
| | | menulist = [] |
| | | } |
| | | } else { |
| | | menulist = [] |
| | | } |
| | | } |
| | | |
| | | return [ |
| | | { |
| | | type: 'tip', |
| | | key: 'type', |
| | | label: '按钮类型', |
| | | initVal: _type |
| | | }, |
| | | { |
| | | type: 'text', |
| | | key: 'label', |
| | | label: '按钮名称', |
| | | initVal: card.label, |
| | | required: true, |
| | | readonly: false |
| | | }, |
| | | { |
| | | type: 'radio', |
| | | key: 'intertype', |
| | | label: Formdict['header.form.intertype'], |
| | | initVal: card.intertype || 'system', |
| | | required: true, |
| | | options: [{ |
| | | value: 'system', |
| | | text: Formdict['model.interface.system'] |
| | | }, { |
| | | value: 'inner', |
| | | text: Formdict['model.interface.inner'] |
| | | }, { |
| | | value: 'outer', |
| | | text: Formdict['model.interface.outer'] |
| | | }, { |
| | | value: 'custom', |
| | | text: '自定义' |
| | | }] |
| | | }, |
| | | { |
| | | type: 'radio', |
| | | key: 'procMode', |
| | | label: '参数处理', |
| | | initVal: card.procMode || 'system', |
| | | required: true, |
| | | options: [{ |
| | | value: 'system', |
| | | text: '系统函数' |
| | | }, { |
| | | value: 'inner', |
| | | text: '内部函数' |
| | | }] |
| | | }, |
| | | { |
| | | type: 'radio', |
| | | key: 'sqlType', |
| | | label: Formdict['header.form.action.type'], |
| | | initVal: card.sqlType || 'update', |
| | | required: true, |
| | | options: [{ |
| | | value: 'insert', |
| | | text: Formdict['header.form.action.insert'] |
| | | }, { |
| | | value: 'update', |
| | | text: Formdict['header.form.action.update'] |
| | | }, { |
| | | value: 'audit', |
| | | text: Formdict['header.form.action.audit'] |
| | | }] |
| | | }, |
| | | { |
| | | type: 'text', |
| | | key: 'sql', |
| | | label: Formdict['model.form.tablename'], |
| | | initVal: card.sql || tableName || '', |
| | | required: true |
| | | }, |
| | | { |
| | | type: 'text', |
| | | key: 'innerFunc', |
| | | label: Formdict['header.form.innerFunc'], |
| | | initVal: card.innerFunc || '', |
| | | tooltip: functip, |
| | | fields: usefulFields, |
| | | tooltipClass: 'middle', |
| | | required: card.intertype === 'inner', |
| | | readonly: false |
| | | }, |
| | | { |
| | | type: 'select', |
| | | key: 'linkTab', |
| | | label: '关联标签', |
| | | initVal: card.linkTab || '', |
| | | required: false, |
| | | options: [] |
| | | }, |
| | | { |
| | | type: 'text', |
| | | key: 'url', |
| | | label: Formdict['model.pageUrl'], |
| | | initVal: card.url || '', |
| | | required: true |
| | | }, |
| | | { |
| | | type: 'radio', |
| | | key: 'sysInterface', |
| | | label: Formdict['header.form.sysInterface'], |
| | | initVal: card.sysInterface || 'false', |
| | | required: true, |
| | | options: [{ |
| | | value: 'true', |
| | | text: Formdict['model.true'] |
| | | }, { |
| | | value: 'false', |
| | | text: Formdict['model.false'] |
| | | }] |
| | | }, |
| | | { |
| | | type: 'text', |
| | | key: 'outerFunc', |
| | | label: Formdict['header.form.outerFunc'], |
| | | initVal: card.outerFunc || '', |
| | | required: false, |
| | | readonly: false |
| | | }, |
| | | { |
| | | type: 'textarea', |
| | | key: 'interface', |
| | | label: '测试地址', |
| | | initVal: card.sysInterface === 'true' ? (window.GLOB.mainSystemApi || '') : (card.interface || ''), |
| | | required: true, |
| | | readonly: card.sysInterface === 'true' |
| | | }, |
| | | { |
| | | type: 'textarea', |
| | | key: 'proInterface', |
| | | label: '正式地址', |
| | | initVal: card.proInterface || '', |
| | | tooltip: '正式系统所使用的接口地址。', |
| | | required: false |
| | | }, |
| | | { |
| | | type: 'radio', |
| | | key: 'method', |
| | | label: '请求方式', |
| | | initVal: card.method || 'post', |
| | | required: true, |
| | | options: [{ |
| | | value: 'get', |
| | | text: 'GET' |
| | | }, { |
| | | value: 'post', |
| | | text: 'POST' |
| | | }] |
| | | }, |
| | | { |
| | | type: 'radio', |
| | | key: 'cross', |
| | | label: '跨域请求', |
| | | initVal: card.cross || 'true', |
| | | tooltip: '如果自定义接口不支持跨域请求,会通过当前系统转发。', |
| | | required: false, |
| | | options: [{ |
| | | value: 'true', |
| | | text: '支持' |
| | | }, { |
| | | value: 'false', |
| | | text: '不支持' |
| | | }] |
| | | }, |
| | | { |
| | | type: 'radio', |
| | | key: 'callbackType', |
| | | label: '回调方式', |
| | | initVal: card.callbackType || 'script', |
| | | tooltip: '使用后台脚本执行时,需要配合计划任务。', |
| | | required: true, |
| | | options: [{ |
| | | value: 'script', |
| | | text: '自定义脚本' |
| | | }, { |
| | | value: 'default', |
| | | text: '后台脚本' |
| | | }] |
| | | }, |
| | | { |
| | | type: 'text', |
| | | key: 'cbTable', |
| | | label: '回调表名', |
| | | initVal: card.cbTable || '', |
| | | required: true |
| | | }, |
| | | { |
| | | type: 'text', |
| | | key: 'callbackFunc', |
| | | label: Formdict['header.form.callbackFunc'], |
| | | initVal: card.callbackFunc || '', |
| | | required: false, |
| | | readonly: false |
| | | }, |
| | | { |
| | | type: isApp ? 'select' : 'cascader', |
| | | key: 'linkmenu', |
| | | label: '打开菜单', |
| | | tooltip: '执行成功后需要打开的菜单。', |
| | | initVal: card.linkmenu, |
| | | required: false, |
| | | options: menulist |
| | | }, |
| | | { |
| | | type: 'radio', |
| | | key: 'open', |
| | | label: '打开方式', |
| | | initVal: card.open || 'blank', |
| | | required: false, |
| | | forbid: !isApp, |
| | | options: [{ |
| | | value: 'blank', |
| | | text: '新窗口' |
| | | }, { |
| | | value: 'self', |
| | | text: '当前窗口' |
| | | }] |
| | | }, |
| | | { |
| | | type: 'cascader', |
| | | key: 'syncComponent', |
| | | label: '同步刷新', |
| | | initVal: card.syncComponent, |
| | | tooltip: '执行成功后需要刷新的组件。', |
| | | required: false, |
| | | options: modules |
| | | }, |
| | | { |
| | | type: 'radio', |
| | | key: 'enable', |
| | | label: '是否显示', |
| | | initVal: card.enable || 'false', |
| | | required: false, |
| | | options: [{ |
| | | value: 'true', |
| | | text: '显示' |
| | | }, { |
| | | value: 'false', |
| | | text: '隐藏' |
| | | }] |
| | | }, |
| | | ] |
| | | } |
New file |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { is, fromJS } from 'immutable' |
| | | import { Modal, Button, Popover, Icon } from 'antd' |
| | | |
| | | import zhCN from '@/locales/zh-CN/model.js' |
| | | import enUS from '@/locales/en-US/model.js' |
| | | import asyncComponent from '@/utils/asyncComponent' |
| | | import { getActionForm } from './formconfig' |
| | | |
| | | import MKEmitter from '@/utils/events.js' |
| | | import MenuUtils from '@/utils/utils-custom.js' |
| | | import './index.scss' |
| | | |
| | | const ActionForm = asyncComponent(() => import('./actionform')) |
| | | const VerifyCard = asyncComponent(() => import('@/templates/zshare/verifycard')) |
| | | |
| | | class CardCellComponent extends Component { |
| | | static propTpyes = { |
| | | group: PropTypes.object, // 分组信息 |
| | | updateconfig: PropTypes.func // 菜单配置更新 |
| | | } |
| | | |
| | | state = { |
| | | dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | card: null, // 编辑中元素 |
| | | formlist: null, // 表单信息 |
| | | visible: false, // 模态框控制 |
| | | profVisible: false, // 验证信息编辑 |
| | | } |
| | | |
| | | componentDidMount () { |
| | | MKEmitter.addListener('submitStyle', this.getStyle) |
| | | } |
| | | |
| | | shouldComponentUpdate (nextProps, nextState) { |
| | | return !is(fromJS(this.props.group), fromJS(nextProps.group)) || !is(fromJS(this.state), fromJS(nextState)) |
| | | } |
| | | |
| | | /** |
| | | * @description 组件销毁,清除state更新,清除快捷键设置 |
| | | */ |
| | | componentWillUnmount () { |
| | | this.setState = () => { |
| | | return |
| | | } |
| | | MKEmitter.removeListener('submitStyle', this.getStyle) |
| | | } |
| | | |
| | | handleStyle = (element) => { |
| | | const { group } = this.props |
| | | |
| | | let _style = element.style ? fromJS(element.style).toJS() : {} |
| | | let options = ['font', 'border', 'padding', 'margin', 'backgroundColor'] |
| | | |
| | | this.setState({ |
| | | card: element |
| | | }) |
| | | |
| | | MKEmitter.emit('changeStyle', [group.uuid, element.type], options, _style) |
| | | } |
| | | |
| | | getStyle = (comIds, style) => { |
| | | let group = fromJS(this.props.group).toJS() |
| | | |
| | | if (comIds.length !== 2 || comIds[0] !== group.uuid) return |
| | | |
| | | if (comIds[1] === 'prev') { |
| | | group.prevButton.style = style |
| | | } else if (comIds[1] === 'submit') { |
| | | group.subButton.style = style |
| | | } else if (comIds[1] === 'next') { |
| | | group.nextButton.style = style |
| | | } |
| | | |
| | | this.props.updateconfig(group) |
| | | } |
| | | |
| | | /** |
| | | * @description 按钮编辑,获取按钮表单信息 |
| | | */ |
| | | handleAction = (card) => { |
| | | const { config } = this.props |
| | | |
| | | let usefulFields = sessionStorage.getItem('permFuncField') |
| | | if (usefulFields) { |
| | | try { |
| | | usefulFields = JSON.parse(usefulFields) |
| | | } catch { |
| | | usefulFields = [] |
| | | } |
| | | } else { |
| | | usefulFields = [] |
| | | } |
| | | |
| | | let ableField = usefulFields.join(', ') |
| | | let functip = <div> |
| | | <p style={{marginBottom: '5px'}}>{this.state.dict['model.tooltip.func.innerface'].replace('@ableField', ableField)}</p> |
| | | </div> |
| | | |
| | | let modules = MenuUtils.getSubModules(window.GLOB.customMenu.components, config.uuid) |
| | | |
| | | this.setState({ |
| | | visible: true, |
| | | card: card, |
| | | formlist: getActionForm(card, functip, config.setting.tableName, usefulFields, modules) |
| | | }) |
| | | } |
| | | |
| | | /** |
| | | * @description 取消保存,如果元素为新添元素,则从序列中删除 |
| | | */ |
| | | editModalCancel = () => { |
| | | this.setState({ |
| | | card: null, |
| | | visible: false |
| | | }) |
| | | } |
| | | |
| | | /** |
| | | * @description 元素修改后提交保存 |
| | | */ |
| | | handleActionSubmit = () => { |
| | | const { card } = this.state |
| | | |
| | | this.actionFormRef.handleConfirm().then(res => { |
| | | res.type = card.type |
| | | res.style = card.style || null |
| | | if (card.verify) { |
| | | res.verify = card.verify |
| | | } |
| | | |
| | | let group = fromJS(this.props.group).toJS() |
| | | |
| | | if (res.type === 'prev') { |
| | | group.prevButton = res |
| | | } else if (res.type === 'submit') { |
| | | group.subButton = res |
| | | } else if (res.type === 'next') { |
| | | group.nextButton = res |
| | | } |
| | | |
| | | this.setState({ |
| | | visible: false |
| | | }) |
| | | this.props.updateconfig(group) |
| | | }) |
| | | } |
| | | |
| | | /** |
| | | * @description 验证信息配置 |
| | | */ |
| | | profileAction = () => { |
| | | this.setState({ |
| | | profVisible: true |
| | | }) |
| | | } |
| | | |
| | | /** |
| | | * @description 验证信息保存 |
| | | */ |
| | | verifySubmit = () => { |
| | | this.verifyRef.handleConfirm().then(res => { |
| | | let group = fromJS(this.props.group).toJS() |
| | | |
| | | group.subButton.verify = res |
| | | |
| | | this.setState({ |
| | | profVisible: false |
| | | }) |
| | | this.props.updateconfig(group) |
| | | }) |
| | | } |
| | | |
| | | render() { |
| | | const { group, config } = this.props |
| | | const { visible, profVisible, card, dict } = this.state |
| | | |
| | | return ( |
| | | <div className="mk-form-action"> |
| | | {group.sort !== 1 ? <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={ |
| | | <div className="mk-popover-control"> |
| | | <Icon className="edit" title="编辑" type="edit" onClick={() => this.handleAction(group.prevButton)} /> |
| | | <Icon className="style" title="调整样式" onClick={() => this.handleStyle(group.prevButton)} type="font-colors" /> |
| | | </div> |
| | | } trigger="hover"> |
| | | <Button type="link" className="prev" style={group.prevButton.style}>{group.prevButton.label}</Button> |
| | | </Popover> : null} |
| | | <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={ |
| | | <div className="mk-popover-control"> |
| | | <Icon className="edit" title="编辑" type="edit" onClick={() => this.handleAction(group.subButton)} /> |
| | | <Icon className="style" title="调整样式" onClick={() => this.handleStyle(group.subButton)} type="font-colors" /> |
| | | <Icon className="profile" title="setting" type="profile" onClick={() => this.profileAction()} /> |
| | | </div> |
| | | } trigger="hover"> |
| | | <Button type="link" className="submit mk-primary" style={group.subButton.style}>{group.subButton.label}</Button> |
| | | </Popover> |
| | | {group.sort !== config.subcards.length ? <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={ |
| | | <div className="mk-popover-control"> |
| | | <Icon className="edit" title="编辑" type="edit" onClick={() => this.handleAction(group.nextButton)} /> |
| | | <Icon className="style" title="调整样式" onClick={() => this.handleStyle(group.nextButton)} type="font-colors" /> |
| | | </div> |
| | | } trigger="hover"> |
| | | <Button type="link" className={'skip ' + group.nextButton.enable} style={group.nextButton.style}>{group.nextButton.label}</Button> |
| | | </Popover> : null} |
| | | {/* 编辑按钮:复制、编辑 */} |
| | | <Modal |
| | | title={dict['model.edit']} |
| | | visible={visible} |
| | | width={800} |
| | | maskClosable={false} |
| | | onCancel={this.editModalCancel} |
| | | footer={[ |
| | | <Button key="cancel" onClick={this.editModalCancel}>{dict['model.cancel']}</Button>, |
| | | <Button key="confirm" type="primary" onClick={this.handleActionSubmit}>{dict['model.confirm']}</Button> |
| | | ]} |
| | | destroyOnClose |
| | | > |
| | | <ActionForm |
| | | dict={dict} |
| | | card={card} |
| | | setting={config.setting} |
| | | formlist={this.state.formlist} |
| | | inputSubmit={this.handleActionSubmit} |
| | | wrappedComponentRef={(inst) => this.actionFormRef = inst} |
| | | /> |
| | | </Modal> |
| | | {/* 按钮使用系统存储过程时,验证信息模态框 */} |
| | | <Modal |
| | | wrapClassName="model-table-action-verify-modal" |
| | | title={'验证信息'} |
| | | visible={profVisible} |
| | | width={'75vw'} |
| | | maskClosable={false} |
| | | okText={dict['model.submit']} |
| | | onOk={this.verifySubmit} |
| | | onCancel={() => { this.setState({ profVisible: false }) }} |
| | | destroyOnClose |
| | | > |
| | | <VerifyCard |
| | | card={{...group.subButton, modal: {fields: group.fields}}} |
| | | dict={dict} |
| | | config={config} |
| | | columns={config.columns} |
| | | wrappedComponentRef={(inst) => this.verifyRef = inst} |
| | | /> |
| | | </Modal> |
| | | </div> |
| | | ) |
| | | } |
| | | } |
| | | |
| | | export default CardCellComponent |
New file |
| | |
| | | .mk-form-action { |
| | | position: relative; |
| | | text-align: center; |
| | | padding-bottom: 10px; |
| | | |
| | | .prev { |
| | | margin-right: 15px; |
| | | } |
| | | .submit { |
| | | border: none; |
| | | } |
| | | .skip { |
| | | position: absolute; |
| | | right: 5px; |
| | | } |
| | | .skip:not(.true) { |
| | | span { |
| | | text-decoration: line-through; |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { Form, Row, Col, Input, Radio, Select, Tooltip, Icon } from 'antd' |
| | | import { formRule } from '@/utils/option.js' |
| | | import './index.scss' |
| | | |
| | | class SettingForm extends Component { |
| | | static propTpyes = { |
| | | dict: PropTypes.object, // 字典项 |
| | | group: PropTypes.object, // 表单配置信息 |
| | | inputSubmit: PropTypes.any // 回车提交事件 |
| | | } |
| | | |
| | | state = { |
| | | fields: null, |
| | | appType: sessionStorage.getItem('appType') |
| | | } |
| | | |
| | | UNSAFE_componentWillMount () { |
| | | const { group } = this.props |
| | | let fields = [] |
| | | |
| | | group.fields.forEach(f => { |
| | | if (f.field && ['select', 'link', 'text', 'number'].includes(f.type) && f.hidden !== 'true' && f.readonly !== 'true') { |
| | | fields.push(f) |
| | | } |
| | | }) |
| | | |
| | | this.setState({ |
| | | fields: fields |
| | | }) |
| | | } |
| | | |
| | | handleConfirm = () => { |
| | | // 表单提交时检查输入值是否正确 |
| | | return new Promise((resolve, reject) => { |
| | | this.props.form.validateFieldsAndScroll((err, values) => { |
| | | if (!err) { |
| | | resolve(values) |
| | | } else { |
| | | reject(err) |
| | | } |
| | | }) |
| | | }) |
| | | } |
| | | |
| | | handleSubmit = (e) => { |
| | | e.preventDefault() |
| | | |
| | | if (this.props.inputSubmit) { |
| | | this.props.inputSubmit() |
| | | } |
| | | } |
| | | |
| | | render() { |
| | | const { group, dict } = this.props |
| | | const { getFieldDecorator } = this.props.form |
| | | const { fields } = this.state |
| | | |
| | | const formItemLayout = { |
| | | labelCol: { |
| | | xs: { span: 24 }, |
| | | sm: { span: 8 } |
| | | }, |
| | | wrapperCol: { |
| | | xs: { span: 24 }, |
| | | sm: { span: 16 } |
| | | } |
| | | } |
| | | |
| | | return ( |
| | | <Form {...formItemLayout} className="ant-advanced-search-form modal-setting-form"> |
| | | <Row gutter={24}> |
| | | <Col span={12}> |
| | | <Form.Item label="标题"> |
| | | {getFieldDecorator('title', { |
| | | initialValue: group.setting.title, |
| | | rules: [ |
| | | { |
| | | max: formRule.input.max, |
| | | message: formRule.input.message |
| | | } |
| | | ] |
| | | })(<Input placeholder="" autoComplete="off" onPressEnter={this.handleSubmit} />)} |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={12}> |
| | | <Form.Item label={ |
| | | <Tooltip placement="topLeft" title="用于表单加载时的状态控制。"> |
| | | <Icon type="question-circle" /> |
| | | 状态值 |
| | | </Tooltip> |
| | | }> |
| | | {getFieldDecorator('status', { |
| | | initialValue: group.setting.status || '', |
| | | rules: [ |
| | | { |
| | | max: formRule.input.max, |
| | | message: formRule.input.message |
| | | } |
| | | ] |
| | | })(<Input placeholder="" autoComplete="off" onPressEnter={this.handleSubmit} />)} |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={12}> |
| | | <Form.Item label="焦点"> |
| | | {getFieldDecorator('focus', { |
| | | initialValue: group.setting.focus || '' |
| | | })( |
| | | <Select |
| | | showSearch |
| | | filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0} |
| | | > |
| | | <Select.Option value=""> |
| | | {dict['model.empty']} |
| | | </Select.Option> |
| | | {fields.map(option => |
| | | <Select.Option id={option.uuid} title={option.label} key={option.uuid} value={option.field}> |
| | | {option.label} |
| | | </Select.Option> |
| | | )} |
| | | </Select> |
| | | )} |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={12}> |
| | | <Form.Item label="表单排列"> |
| | | {getFieldDecorator('align', { |
| | | initialValue: group.setting.align || 'left_right' |
| | | })( |
| | | <Radio.Group> |
| | | <Radio value="left_right">左右</Radio> |
| | | <Radio value="up_down">上下</Radio> |
| | | </Radio.Group> |
| | | )} |
| | | </Form.Item> |
| | | </Col> |
| | | </Row> |
| | | </Form> |
| | | ) |
| | | } |
| | | } |
| | | |
| | | export default Form.create()(SettingForm) |
File was renamed from src/templates/modalconfig/groupform/index.scss |
| | |
| | | .ant-input-number { |
| | | width: 100%; |
| | | } |
| | | .anticon-question-circle { |
| | | color: #c49f47; |
| | | position: relative; |
| | | left: -3px; |
| | | } |
| | | } |
New file |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { is, fromJS } from 'immutable' |
| | | import { Icon, Popover, Modal, Button, Switch, notification } from 'antd' |
| | | import moment from 'moment' |
| | | |
| | | import Api from '@/api' |
| | | import asyncComponent from '@/utils/asyncComponent' |
| | | import asyncIconComponent from '@/utils/asyncIconComponent' |
| | | import { getModalForm } from '@/templates/zshare/formconfig' |
| | | import ModalForm from '@/templates/zshare/modalform' |
| | | import MKEmitter from '@/utils/events.js' |
| | | import Utils from '@/utils/utils.js' |
| | | import zhCN from '@/locales/zh-CN/model.js' |
| | | import enUS from '@/locales/en-US/model.js' |
| | | import './index.scss' |
| | | |
| | | const SettingComponent = asyncIconComponent(() => import('@/menu/datasource')) |
| | | const WrapComponent = asyncIconComponent(() => import('@/menu/components/form/wrapsetting')) |
| | | const CardComponent = asyncComponent(() => import('@/templates/modalconfig/dragelement')) |
| | | const FormTitle = asyncComponent(() => import('../dragtitle')) |
| | | const GroupForm = asyncComponent(() => import('./groupform')) |
| | | const FormAction = asyncComponent(() => import('../formaction')) |
| | | const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent')) |
| | | const PasteComponent = asyncIconComponent(() => import('@/menu/components/share/pastecomponent')) |
| | | const UserComponent = asyncIconComponent(() => import('@/menu/components/share/usercomponent')) |
| | | const FieldsComponent = asyncComponent(() => import('@/templates/sharecomponent/fieldscomponent')) |
| | | |
| | | const { confirm } = Modal |
| | | |
| | | class PropCardEditComponent extends Component { |
| | | static propTpyes = { |
| | | card: PropTypes.object, |
| | | deletecomponent: PropTypes.func, |
| | | updateConfig: PropTypes.func, |
| | | } |
| | | |
| | | state = { |
| | | dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | card: null, |
| | | back: false, |
| | | group: null, |
| | | showField: false, |
| | | visible: false, |
| | | editform: null, |
| | | formlist: null, |
| | | sqlVerifing: false, |
| | | standardform: null |
| | | } |
| | | |
| | | UNSAFE_componentWillMount () { |
| | | const { card } = this.props |
| | | |
| | | if (card.isNew) { |
| | | let _card = { |
| | | uuid: card.uuid, |
| | | type: card.type, |
| | | floor: card.floor, |
| | | tabId: card.tabId || '', |
| | | parentId: card.parentId || '', |
| | | format: 'object', // 组件属性 - 数据格式 |
| | | pageable: false, // 组件属性 - 是否可分页 |
| | | switchable: false, // 组件属性 - 数据是否可切换 |
| | | dataName: card.dataName || '', |
| | | width: card.width || 24, |
| | | name: card.name, |
| | | subtype: card.subtype, |
| | | setting: { }, |
| | | wrap: { name: card.name, width: card.width || 24, datatype: 'static', color: '#1890ff' }, |
| | | style: { marginLeft: '0px', marginRight: '0px', marginTop: '8px', marginBottom: '8px' }, |
| | | columns: [], |
| | | scripts: [], |
| | | subcards: [{ |
| | | uuid: Utils.getuuid(), |
| | | setting: {title: '第一步', align: 'left_right'}, |
| | | sort: 1, |
| | | style: {}, |
| | | fields: [], |
| | | prevButton: {label: '上一步', type: 'prev'}, |
| | | subButton: {label: '提交', type: 'submit', style: {backgroundColor: '#1890ff', color: '#ffffff', paddingLeft: '25px', paddingRight: '25px'}}, |
| | | nextButton: {label: '跳过', type: 'next', enable: 'false'} |
| | | }] |
| | | } |
| | | |
| | | if (card.config) { |
| | | let config = fromJS(card.config).toJS() |
| | | |
| | | _card.wrap = config.wrap |
| | | _card.wrap.name = card.name |
| | | _card.style = config.style |
| | | |
| | | _card.subcards = config.subcards.map(scard => { |
| | | scard.uuid = Utils.getuuid() |
| | | scard.fields = scard.fields.map(elem => { |
| | | elem.uuid = Utils.getuuid() |
| | | return elem |
| | | }) |
| | | return scard |
| | | }) |
| | | } |
| | | this.setState({ |
| | | card: _card, |
| | | group: _card.subcards[0] || null |
| | | }) |
| | | this.props.updateConfig(_card) |
| | | } else { |
| | | let _card = fromJS(card).toJS() |
| | | this.setState({ |
| | | card: _card, |
| | | group: _card.subcards[0] || null |
| | | }) |
| | | } |
| | | } |
| | | |
| | | componentDidMount () { |
| | | MKEmitter.addListener('submitStyle', this.getStyle) |
| | | MKEmitter.addListener('submitComponentStyle', this.updateComponentStyle) |
| | | } |
| | | |
| | | shouldComponentUpdate (nextProps, nextState) { |
| | | return !is(fromJS(this.state), fromJS(nextState)) |
| | | } |
| | | |
| | | /** |
| | | * @description 组件销毁,清除state更新,清除快捷键设置 |
| | | */ |
| | | componentWillUnmount () { |
| | | this.setState = () => { |
| | | return |
| | | } |
| | | MKEmitter.removeListener('submitStyle', this.getStyle) |
| | | MKEmitter.removeListener('submitComponentStyle', this.updateComponentStyle) |
| | | } |
| | | |
| | | updateComponentStyle = (parentId, keys, style) => { |
| | | const { card } = this.state |
| | | |
| | | if (card.uuid !== parentId) return |
| | | |
| | | let subcards = card.subcards.map(item => { |
| | | if (keys.includes(item.uuid)) { |
| | | item.style = {...item.style, ...style} |
| | | } |
| | | return item |
| | | }) |
| | | |
| | | this.setState({card: {...card, subcards: []}}, () => { |
| | | this.updateComponent({...card, subcards: subcards}) |
| | | }) |
| | | } |
| | | |
| | | /** |
| | | * @description 卡片行外层信息更新(数据源,样式等) |
| | | */ |
| | | updateComponent = (component) => { |
| | | this.setState({ |
| | | card: component |
| | | }) |
| | | |
| | | component.width = component.wrap.width |
| | | component.name = component.wrap.name |
| | | |
| | | this.props.updateConfig(component) |
| | | } |
| | | |
| | | /** |
| | | * @description 单个卡片信息更新 |
| | | */ |
| | | updateCard = (cell) => { |
| | | let card = fromJS(this.state.card).toJS() |
| | | |
| | | card.subcards = card.subcards.map(item => { |
| | | if (item.uuid === cell.uuid) return cell |
| | | return item |
| | | }) |
| | | |
| | | this.setState({card}) |
| | | |
| | | this.props.updateConfig(card) |
| | | } |
| | | |
| | | /** |
| | | * @description 单个卡片信息更新 |
| | | */ |
| | | deleteCard = (cell) => { |
| | | let card = fromJS(this.state.card).toJS() |
| | | let _this = this |
| | | |
| | | confirm({ |
| | | content: '确定删除表单吗?', |
| | | onOk() { |
| | | card.subcards = card.subcards.filter(item => item.uuid !== cell.uuid) |
| | | |
| | | let uuids = [] |
| | | cell.elements && cell.elements.forEach(c => { |
| | | if (c.eleType === 'button') { |
| | | uuids.push(c.uuid) |
| | | } |
| | | }) |
| | | MKEmitter.emit('delButtons', uuids) |
| | | |
| | | _this.setState({card}) |
| | | _this.props.updateConfig(card) |
| | | }, |
| | | onCancel() {} |
| | | }) |
| | | } |
| | | |
| | | changeStyle = () => { |
| | | const { card } = this.state |
| | | |
| | | MKEmitter.emit('changeStyle', [card.uuid], ['height', 'background', 'border', 'padding', 'margin'], card.style) |
| | | } |
| | | |
| | | getStyle = (comIds, style) => { |
| | | const { card } = this.state |
| | | |
| | | if (comIds.length !== 1 || comIds[0] !== card.uuid) return |
| | | |
| | | let _card = {...card, style} |
| | | |
| | | this.setState({ |
| | | card: _card |
| | | }) |
| | | |
| | | this.props.updateConfig(_card) |
| | | } |
| | | |
| | | addCard = () => { |
| | | let card = fromJS(this.state.card).toJS() |
| | | |
| | | let newcard = { |
| | | uuid: Utils.getuuid(), |
| | | setting: { title: `第${card.subcards.length + 1}步`, align: 'left_right' }, |
| | | sort: card.subcards.length + 1, |
| | | style: {}, |
| | | fields: [], |
| | | prevButton: {label: '上一步', type: 'prev'}, |
| | | subButton: {label: '提交', type: 'submit', style: {backgroundColor: '#1890ff', color: '#ffffff', paddingLeft: '25px', paddingRight: '25px'}}, |
| | | nextButton: {label: '跳过', type: 'next', enable: 'false'} |
| | | } |
| | | |
| | | card.subcards.push(newcard) |
| | | |
| | | this.setState({ |
| | | card, |
| | | group: newcard, |
| | | groupvisible: true |
| | | }) |
| | | this.props.updateConfig(card) |
| | | } |
| | | |
| | | changecards = (list) => { |
| | | let card = fromJS(this.state.card).toJS() |
| | | card.subcards = list.map((item, index) => { |
| | | item.sort = index + 1 |
| | | return item |
| | | }) |
| | | |
| | | this.setState({card}) |
| | | this.props.updateConfig(card) |
| | | } |
| | | |
| | | selectGroup = (item) => { |
| | | this.setState({ |
| | | group: item |
| | | }) |
| | | } |
| | | |
| | | changeGroup = (item) => { |
| | | this.setState({ |
| | | group: item, |
| | | groupvisible: true |
| | | }) |
| | | } |
| | | |
| | | closeGroup = (cell) => { |
| | | const { group } = this.state |
| | | let card = fromJS(this.state.card).toJS() |
| | | const _this = this |
| | | |
| | | confirm({ |
| | | content: '确定删除分组吗?', |
| | | onOk() { |
| | | card.subcards = card.subcards.filter(item => item.uuid !== cell.uuid) |
| | | let _group = group |
| | | |
| | | if (group.uuid === cell.uuid) { |
| | | _group = card.subcards[0] || null |
| | | } |
| | | |
| | | _this.setState({card, group: _group}) |
| | | _this.props.updateConfig(card) |
| | | }, |
| | | onCancel() {} |
| | | }) |
| | | } |
| | | |
| | | updateGroup = (group) => { |
| | | let card = fromJS(this.state.card).toJS() |
| | | |
| | | card.subcards = card.subcards.map(item => { |
| | | if (item.uuid === group.uuid) { |
| | | return group |
| | | } |
| | | return item |
| | | }) |
| | | |
| | | this.setState({card, group}) |
| | | this.props.updateConfig(card) |
| | | } |
| | | |
| | | handleGroupSubmit = () => { |
| | | const { group } = this.state |
| | | |
| | | this.groupRef.handleConfirm().then(res => { |
| | | group.setting = res |
| | | this.setState({groupvisible: false}) |
| | | this.updateGroup(group) |
| | | }) |
| | | } |
| | | |
| | | changecols = (type) => { |
| | | let card = fromJS(this.state.card).toJS() |
| | | let config = fromJS(this.state.group).toJS() |
| | | let _this = this |
| | | |
| | | config.fields = config.fields.map(item => { |
| | | item.labelwidth = 33.3 |
| | | item.span = 24 |
| | | if (['textarea','split','hint','checkcard','brafteditor'].includes(item.type)) { |
| | | if (type === 2) { |
| | | item.labelwidth = 16.3 |
| | | } else if (type === 3) { |
| | | item.labelwidth = 10.5 |
| | | } else if (type === 4) { |
| | | item.labelwidth = 8.3 |
| | | } |
| | | } else if (type === 2) { |
| | | item.span = 12 |
| | | } else if (type === 3) { |
| | | item.span = 8 |
| | | } else if (type === 4) { |
| | | item.span = 6 |
| | | } |
| | | return item |
| | | }) |
| | | |
| | | confirm({ |
| | | content: `确定切换为${type}列吗?`, |
| | | onOk() { |
| | | card.subcards = card.subcards.map(item => { |
| | | if (item.uuid === config.uuid) { |
| | | return config |
| | | } |
| | | return item |
| | | }) |
| | | _this.setState({group: config, card}) |
| | | _this.props.updateConfig(card) |
| | | }, |
| | | onCancel() {} |
| | | }) |
| | | } |
| | | |
| | | handleList = (list) => { |
| | | let group = fromJS(this.state.group).toJS() |
| | | let card = fromJS(this.state.card).toJS() |
| | | |
| | | group.fields = list |
| | | |
| | | card.subcards = card.subcards.map(item => { |
| | | if (item.uuid === group.uuid) { |
| | | return group |
| | | } |
| | | return item |
| | | }) |
| | | |
| | | this.setState({card, group}) |
| | | this.props.updateConfig(card) |
| | | } |
| | | |
| | | closeForm = (cell) => { |
| | | let group = fromJS(this.state.group).toJS() |
| | | let card = fromJS(this.state.card).toJS() |
| | | let _this = this |
| | | |
| | | group.fields = group.fields.filter(item => item.uuid !== cell.uuid) |
| | | |
| | | card.subcards = card.subcards.map(item => { |
| | | if (item.uuid === group.uuid) { |
| | | return group |
| | | } |
| | | return item |
| | | }) |
| | | |
| | | confirm({ |
| | | content: `确定删除<<${cell.label}>>吗?`, |
| | | onOk() { |
| | | _this.setState({card, group}) |
| | | _this.props.updateConfig(card) |
| | | }, |
| | | onCancel() {} |
| | | }) |
| | | } |
| | | |
| | | addForm = () => { |
| | | let group = fromJS(this.state.group).toJS() |
| | | let lastItem = group.fields[group.fields.length - 1] |
| | | let span = lastItem ? lastItem.span : 12 |
| | | |
| | | let newcard = { |
| | | uuid: Utils.getuuid(), |
| | | label: '', |
| | | field: '', |
| | | initval: '', |
| | | type: 'text', |
| | | resourceType: '0', |
| | | setAll: 'false', |
| | | span: span, |
| | | labelwidth: 33.3, |
| | | options: [], |
| | | dataSource: '', |
| | | decimal: 0, |
| | | orderType: 'asc', |
| | | readonly: 'false', |
| | | required: 'true', |
| | | focus: true |
| | | } |
| | | |
| | | group.fields.push(newcard) |
| | | |
| | | this.setState({group}, () => { |
| | | this.handleForm(newcard) |
| | | }) |
| | | } |
| | | |
| | | editModalCancel = () => { |
| | | let group = fromJS(this.state.group).toJS() |
| | | group.fields = group.fields.filter(item => !item.focus) |
| | | |
| | | this.setState({group, visible: false, editform: null}) |
| | | } |
| | | |
| | | /** |
| | | * @description 表单编辑 |
| | | */ |
| | | handleForm = (_item) => { |
| | | const { card, group } = this.state |
| | | let _form = fromJS(_item).toJS() |
| | | let _inputfields = [] |
| | | let _tabfields = [] |
| | | let _linkableFields = [] |
| | | let _linksupFields = [{ |
| | | value: '', |
| | | text: '空' |
| | | }] |
| | | let standardform = null |
| | | |
| | | _inputfields = group.fields.filter(item => item.type === 'text' || item.type === 'number' || item.type === 'textarea' || item.type === 'color') |
| | | _tabfields = group.fields.filter(item => _form.field !== item.field && item.hidden !== 'true' && ['text', 'number', 'select', 'link'].includes(item.type)) |
| | | _tabfields.unshift({field: '', text: '原表单'}) |
| | | |
| | | let uniq = new Map() |
| | | uniq.set(_form.field, true) |
| | | let index = null |
| | | group.fields.forEach((item, i) => { |
| | | if (_form.uuid === item.uuid) { |
| | | index = i |
| | | } |
| | | if (item.type !== 'select' && item.type !== 'link' && item.type !== 'radio') return |
| | | if (item.field && !uniq.has(item.field)) { |
| | | uniq.set(item.field, true) |
| | | |
| | | _linkableFields.push({ |
| | | value: item.field, |
| | | text: item.label + ' (表单)' |
| | | }) |
| | | _linksupFields.push({ |
| | | value: item.field, |
| | | text: item.label |
| | | }) |
| | | } |
| | | }) |
| | | if (index !== null) { |
| | | if (index === 0) { |
| | | standardform = group.fields[index + 1] || null |
| | | } else { |
| | | standardform = group.fields[index - 1] || null |
| | | } |
| | | } |
| | | |
| | | card.columns.forEach(col => { |
| | | if (col.field && !uniq.has(col.field)) { |
| | | uniq.set(col.field, true) |
| | | |
| | | _linkableFields.push({ |
| | | value: col.field, |
| | | text: col.label + ' (显示列)' |
| | | }) |
| | | } |
| | | }) |
| | | |
| | | if (_form.linkSubField && _form.linkSubField.length > 0) { |
| | | let fields = _inputfields.map(item => item.field) |
| | | _form.linkSubField = _form.linkSubField.filter(item => fields.includes(item)) |
| | | } |
| | | |
| | | if (!_form.span && standardform && standardform.span) { |
| | | _form.span = standardform.span |
| | | _form.labelwidth = standardform.labelwidth |
| | | } |
| | | |
| | | this.setState({ |
| | | standardform, |
| | | visible: true, |
| | | editform: _form, |
| | | formlist: getModalForm(_form, _inputfields, _tabfields, _linkableFields, _linksupFields, false) |
| | | }) |
| | | } |
| | | |
| | | /** |
| | | * @description 编辑后提交 |
| | | * 1、获取编辑后的表单信息 |
| | | * 2、去除可能存在的示例表单 |
| | | * 3、通过loading刷新 |
| | | */ |
| | | handleSubmit = () => { |
| | | this.formRef.handleConfirm().then(res => { |
| | | let _config = fromJS(this.state.group).toJS() |
| | | let fieldrepet = false // 字段重复 |
| | | let labelrepet = false // 提示文字重复 |
| | | |
| | | _config.fields = _config.fields.map(item => { |
| | | if (item.uuid !== res.uuid && res.field && item.field && item.field.toLowerCase() === res.field.toLowerCase()) { |
| | | fieldrepet = true |
| | | } else if (res.label && item.uuid !== res.uuid && item.label === res.label) { |
| | | labelrepet = true |
| | | } |
| | | |
| | | if (item.uuid === res.uuid) { |
| | | return res |
| | | } else { |
| | | return item |
| | | } |
| | | }) |
| | | |
| | | if (fieldrepet) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '字段已存在!', |
| | | duration: 10 |
| | | }) |
| | | return |
| | | } else if (labelrepet) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '名称已存在!', |
| | | duration: 10 |
| | | }) |
| | | return |
| | | } |
| | | |
| | | if ((res.type === 'select' || res.type === 'multiselect' || res.type === 'link') && res.resourceType === '1' && /\s/.test(res.dataSource)) { |
| | | this.setState({ |
| | | sqlVerifing: true |
| | | }) |
| | | |
| | | let param = { |
| | | func: 's_debug_sql', |
| | | exec_type: 'y', |
| | | LText: res.dataSource |
| | | } |
| | | |
| | | param.LText = param.LText.replace(/@\$|\$@/ig, '') |
| | | |
| | | param.LText = Utils.formatOptions(param.LText) |
| | | param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') |
| | | param.secretkey = Utils.encrypt('', param.timestamp) |
| | | |
| | | if (window.GLOB.mainSystemApi && res.database === 'sso') { |
| | | param.rduri = window.GLOB.mainSystemApi |
| | | } |
| | | |
| | | Api.getLocalConfig(param).then(result => { |
| | | if (result.status) { |
| | | this.setState({ |
| | | sqlVerifing: false, |
| | | editform: null, |
| | | visible: false |
| | | }) |
| | | this.updateGroup(_config) |
| | | } else { |
| | | this.setState({sqlVerifing: false}) |
| | | |
| | | Modal.error({ |
| | | title: result.message |
| | | }) |
| | | } |
| | | }) |
| | | } else { |
| | | this.setState({ |
| | | editform: null, |
| | | visible: false |
| | | }) |
| | | this.updateGroup(_config) |
| | | } |
| | | }) |
| | | } |
| | | |
| | | clickComponent = (e) => { |
| | | if (sessionStorage.getItem('style-control') === 'true' || sessionStorage.getItem('style-control') === 'component') { |
| | | e.stopPropagation() |
| | | MKEmitter.emit('clickComponent', this.state.card) |
| | | } |
| | | } |
| | | |
| | | render() { |
| | | const { card, dict, group } = this.state |
| | | |
| | | return ( |
| | | <div className="menu-normal-form-edit-box" style={{...card.style}} onClick={this.clickComponent} id={card.uuid}> |
| | | <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={ |
| | | <div className="mk-popover-control"> |
| | | <Icon className="plus" title="添加分组" onClick={this.addCard} type="plus" /> |
| | | <WrapComponent config={card} updateConfig={this.updateComponent} /> |
| | | <CopyComponent type="propcard" card={card}/> |
| | | <PasteComponent config={card} options={['cardcell']} updateConfig={this.updateComponent} /> |
| | | <Icon className="style" title="调整样式" onClick={this.changeStyle} type="font-colors" /> |
| | | <UserComponent config={card}/> |
| | | <Icon className="close" title="删除组件" type="delete" onClick={() => this.props.deletecomponent(card.uuid)} /> |
| | | {card.wrap.datatype !== 'static' ? <SettingComponent config={card} updateConfig={this.updateComponent} /> : null} |
| | | {card.wrap.datatype === 'static' ? <Icon style={{color: '#eeeeee', cursor: 'not-allowed'}} type="setting"/> : null} |
| | | </div> |
| | | } trigger="hover"> |
| | | <Icon type="tool" /> |
| | | </Popover> |
| | | <FormTitle |
| | | list={card.subcards} |
| | | selectId={group ? group.uuid : ''} |
| | | handleList={this.changecards} |
| | | handleGroup={this.changeGroup} |
| | | closeGroup={this.closeGroup} |
| | | selectGroup={this.selectGroup} |
| | | /> |
| | | {group ? <div className="form-area"> |
| | | <Icon className="plus" title="添加表单" onClick={this.addForm} type="plus" /> |
| | | <FieldsComponent config={group} type="form" updatefield={this.updateGroup} /> |
| | | <Switch checkedChildren={dict['model.switch.open']} unCheckedChildren={dict['model.switch.close']} defaultChecked={this.state.showField} onChange={(val) => this.setState({showField: val})} /> |
| | | <Button className="mk-cols-change" onClick={() => this.changecols(1)}>1列</Button> |
| | | <Button className="mk-cols-change" onClick={() => this.changecols(2)}>2列</Button> |
| | | <Button className="mk-cols-change" onClick={() => this.changecols(3)}>3列</Button> |
| | | <Button className="mk-cols-change" onClick={() => this.changecols(4)}>4列</Button> |
| | | <div style={{clear: 'both'}}></div> |
| | | <CardComponent |
| | | list={group.fields} |
| | | setting={group.setting} |
| | | showField={this.state.showField} |
| | | placeholder={dict['header.form.modal.placeholder']} |
| | | handleList={this.handleList} |
| | | handleForm={this.handleForm} |
| | | closeForm={this.closeForm} |
| | | /> |
| | | <FormAction config={card} group={group} updateconfig={this.updateGroup}/> |
| | | </div> : null} |
| | | <Modal |
| | | title="分组编辑" |
| | | visible={this.state.groupvisible} |
| | | width={850} |
| | | maskClosable={false} |
| | | onCancel={() => this.setState({groupvisible: false})} |
| | | onOk={this.handleGroupSubmit} |
| | | destroyOnClose |
| | | > |
| | | <GroupForm |
| | | dict={dict} |
| | | group={group} |
| | | inputSubmit={this.handleGroupSubmit} |
| | | wrappedComponentRef={(inst) => this.groupRef = inst} |
| | | /> |
| | | </Modal> |
| | | <Modal |
| | | title={this.state.dict['model.edit']} |
| | | visible={this.state.visible} |
| | | width={850} |
| | | onCancel={this.editModalCancel} |
| | | onOk={this.handleSubmit} |
| | | confirmLoading={this.state.sqlVerifing} |
| | | destroyOnClose |
| | | > |
| | | <ModalForm |
| | | dict={this.state.dict} |
| | | card={this.state.editform} |
| | | formlist={this.state.formlist} |
| | | inputSubmit={this.handleSubmit} |
| | | standardform={this.state.standardform} |
| | | wrappedComponentRef={(inst) => this.formRef = inst} |
| | | /> |
| | | </Modal> |
| | | </div> |
| | | ) |
| | | } |
| | | } |
| | | |
| | | export default PropCardEditComponent |
New file |
| | |
| | | .menu-normal-form-edit-box { |
| | | position: relative; |
| | | box-sizing: border-box; |
| | | background: #ffffff; |
| | | background-position: center center; |
| | | background-repeat: no-repeat; |
| | | background-size: cover; |
| | | min-height: 30px; |
| | | |
| | | .card-control { |
| | | position: absolute; |
| | | top: 0px; |
| | | left: 0px; |
| | | .anticon-tool { |
| | | right: auto; |
| | | left: 1px; |
| | | padding: 1px; |
| | | } |
| | | } |
| | | .anticon-tool { |
| | | position: absolute; |
| | | z-index: 2; |
| | | font-size: 16px; |
| | | right: 1px; |
| | | top: 1px; |
| | | cursor: pointer; |
| | | padding: 5px; |
| | | background: rgba(255, 255, 255, 0.55); |
| | | } |
| | | |
| | | .page-card { |
| | | position: relative; |
| | | background: #ffffff; |
| | | border-radius: 2px; |
| | | margin-bottom: 15px; |
| | | } |
| | | .form-area { |
| | | position: relative; |
| | | >.plus { |
| | | color: #26C281; |
| | | cursor: pointer; |
| | | padding: 4px 10px; |
| | | } |
| | | >button { |
| | | float: right; |
| | | margin-right: 10px; |
| | | } |
| | | >.mk-cols-change { |
| | | height: 24px; |
| | | padding: 0 10px; |
| | | } |
| | | >.quickly-add { |
| | | display: inline-block; |
| | | margin-left: 10px; |
| | | button { |
| | | color: #1890ff; |
| | | background: transparent; |
| | | border: none; |
| | | box-shadow: none; |
| | | padding: 0; |
| | | height: 24px; |
| | | } |
| | | } |
| | | .modal-fields-row { |
| | | padding-top: 10px; |
| | | padding-bottom: 30px; |
| | | } |
| | | } |
| | | } |
| | | .menu-normal-form-edit-box::after { |
| | | display: block; |
| | | content: ' '; |
| | | clear: both; |
| | | } |
| | | .menu-normal-form-edit-box:hover { |
| | | z-index: 1; |
| | | box-shadow: 0px 0px 4px #1890ff; |
| | | } |
New file |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { is, fromJS } from 'immutable' |
| | | import { Icon, Modal } from 'antd' |
| | | |
| | | import zhCN from '@/locales/zh-CN/model.js' |
| | | import enUS from '@/locales/en-US/model.js' |
| | | import SettingForm from './settingform' |
| | | import './index.scss' |
| | | |
| | | class DataSource extends Component { |
| | | static propTpyes = { |
| | | config: PropTypes.any, |
| | | updateConfig: PropTypes.func |
| | | } |
| | | |
| | | state = { |
| | | dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | visible: false, |
| | | wrap: null |
| | | } |
| | | |
| | | UNSAFE_componentWillMount () { |
| | | const { config } = this.props |
| | | |
| | | this.setState({wrap: fromJS(config.wrap).toJS()}) |
| | | } |
| | | |
| | | shouldComponentUpdate (nextProps, nextState) { |
| | | return !is(fromJS(this.props), fromJS(nextProps)) || !is(fromJS(this.state), fromJS(nextState)) |
| | | } |
| | | |
| | | editDataSource = () => { |
| | | this.setState({ |
| | | visible: true |
| | | }) |
| | | } |
| | | |
| | | verifySubmit = () => { |
| | | const { config } = this.props |
| | | |
| | | this.verifyRef.handleConfirm().then(res => { |
| | | |
| | | this.setState({ |
| | | wrap: res, |
| | | visible: false |
| | | }) |
| | | this.props.updateConfig({...config, wrap: res}) |
| | | }) |
| | | } |
| | | |
| | | render () { |
| | | const { config } = this.props |
| | | const { visible, dict, wrap } = this.state |
| | | |
| | | return ( |
| | | <div className="model-menu-setting-wrap"> |
| | | <Icon type="edit" title="编辑" onClick={() => this.editDataSource()} /> |
| | | <Modal |
| | | wrapClassName="popview-modal" |
| | | title="表单设置" |
| | | visible={visible} |
| | | width={800} |
| | | maskClosable={false} |
| | | okText={dict['model.submit']} |
| | | onOk={this.verifySubmit} |
| | | onCancel={() => { this.setState({ visible: false }) }} |
| | | destroyOnClose |
| | | > |
| | | <SettingForm |
| | | dict={dict} |
| | | wrap={wrap} |
| | | config={config} |
| | | inputSubmit={this.verifySubmit} |
| | | wrappedComponentRef={(inst) => this.verifyRef = inst} |
| | | /> |
| | | </Modal> |
| | | </div> |
| | | ) |
| | | } |
| | | } |
| | | |
| | | export default DataSource |
New file |
| | |
| | | .model-menu-setting-wrap { |
| | | display: inline-block; |
| | | |
| | | >.anticon-edit { |
| | | color: #1890ff; |
| | | } |
| | | } |
New file |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { Form, Row, Col, Input, Radio, Tooltip, Icon, InputNumber, Select } from 'antd' |
| | | |
| | | import asyncComponent from '@/utils/asyncComponent' |
| | | import './index.scss' |
| | | |
| | | const ColorSketch = asyncComponent(() => import('@/mob/colorsketch')) |
| | | |
| | | class SettingForm extends Component { |
| | | static propTpyes = { |
| | | dict: PropTypes.object, // 字典项 |
| | | config: PropTypes.object, // 卡片行信息 |
| | | wrap: PropTypes.object, // 数据源配置 |
| | | inputSubmit: PropTypes.func // 回车事件 |
| | | } |
| | | |
| | | state = { |
| | | roleList: [] |
| | | } |
| | | |
| | | UNSAFE_componentWillMount () { |
| | | let roleList = sessionStorage.getItem('sysRoles') |
| | | if (roleList) { |
| | | try { |
| | | roleList = JSON.parse(roleList) |
| | | } catch { |
| | | roleList = [] |
| | | } |
| | | } else { |
| | | roleList = [] |
| | | } |
| | | |
| | | this.setState({roleList}) |
| | | } |
| | | |
| | | handleConfirm = () => { |
| | | // 表单提交时检查输入值是否正确 |
| | | return new Promise((resolve, reject) => { |
| | | this.props.form.validateFieldsAndScroll((err, values) => { |
| | | if (!err) { |
| | | resolve(values) |
| | | } else { |
| | | reject(err) |
| | | } |
| | | }) |
| | | }) |
| | | } |
| | | |
| | | handleSubmit = (e) => { |
| | | e.preventDefault() |
| | | |
| | | if (this.props.inputSubmit) { |
| | | this.props.inputSubmit() |
| | | } |
| | | } |
| | | |
| | | render() { |
| | | const { wrap, config } = this.props |
| | | const { getFieldDecorator } = this.props.form |
| | | const { roleList } = this.state |
| | | |
| | | const formItemLayout = { |
| | | labelCol: { |
| | | xs: { span: 24 }, |
| | | sm: { span: 8 } |
| | | }, |
| | | wrapperCol: { |
| | | xs: { span: 24 }, |
| | | sm: { span: 16 } |
| | | } |
| | | } |
| | | |
| | | return ( |
| | | <div className="model-menu-setting-form"> |
| | | <Form {...formItemLayout}> |
| | | <Row gutter={24}> |
| | | <Col span={12}> |
| | | <Form.Item label={ |
| | | <Tooltip placement="topLeft" title="用于组件间的区分。"> |
| | | <Icon type="question-circle" /> |
| | | 组件名称 |
| | | </Tooltip> |
| | | }> |
| | | {getFieldDecorator('name', { |
| | | initialValue: wrap.name, |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: this.props.dict['form.required.input'] + '组件名称!' |
| | | } |
| | | ] |
| | | })(<Input placeholder={''} autoComplete="off" onPressEnter={this.handleSubmit} />)} |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={12}> |
| | | <Form.Item label={ |
| | | <Tooltip placement="topLeft" title="栅格布局,每行等分为24列。"> |
| | | <Icon type="question-circle" /> |
| | | 宽度 |
| | | </Tooltip> |
| | | }> |
| | | {getFieldDecorator('width', { |
| | | initialValue: wrap.width || 24, |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: this.props.dict['form.required.input'] + '宽度!' |
| | | } |
| | | ] |
| | | })(<InputNumber min={1} max={24} precision={0} onPressEnter={this.handleSubmit} />)} |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={12}> |
| | | <Form.Item label={ |
| | | <Tooltip placement="topLeft" title="初始值来源于数据源或表单默认值。"> |
| | | <Icon type="question-circle" /> |
| | | 初始值 |
| | | </Tooltip> |
| | | }> |
| | | {getFieldDecorator('datatype', { |
| | | initialValue: wrap.datatype || 'dynamic' |
| | | })( |
| | | <Radio.Group> |
| | | <Radio value="dynamic">动态</Radio> |
| | | <Radio value="static">静态</Radio> |
| | | </Radio.Group> |
| | | )} |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={12}> |
| | | <Form.Item label={ |
| | | <Tooltip placement="topLeft" title="表单加载时的状态,当字段值与表单组的状态值一致时,启用对应的表单组。"> |
| | | <Icon type="question-circle" /> |
| | | 状态控制 |
| | | </Tooltip> |
| | | }> |
| | | {getFieldDecorator('statusControl', { |
| | | initialValue: wrap.statusControl || '' |
| | | })( |
| | | <Select> |
| | | <Select.Option key='' value={''}>无</Select.Option> |
| | | {config.columns.map(option => |
| | | <Select.Option key={option.uuid} value={option.field}>{option.label}</Select.Option> |
| | | )} |
| | | </Select> |
| | | )} |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={12}> |
| | | <Form.Item label={ |
| | | <Tooltip placement="topLeft" title="完成后的颜色"> |
| | | <Icon type="question-circle" /> |
| | | 颜色控制 |
| | | </Tooltip> |
| | | }> |
| | | {getFieldDecorator('color', { |
| | | initialValue: wrap.color || '#1890ff' |
| | | })( |
| | | <ColorSketch /> |
| | | )} |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={12}> |
| | | <Form.Item label="黑名单"> |
| | | {getFieldDecorator('blacklist', { |
| | | initialValue: wrap.blacklist || [] |
| | | })( |
| | | <Select |
| | | showSearch |
| | | mode="multiple" |
| | | filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0} |
| | | > |
| | | {roleList.map(option => |
| | | <Select.Option key={option.uuid} value={option.value}>{option.text}</Select.Option> |
| | | )} |
| | | </Select> |
| | | )} |
| | | </Form.Item> |
| | | </Col> |
| | | </Row> |
| | | </Form> |
| | | </div> |
| | | ) |
| | | } |
| | | } |
| | | |
| | | export default Form.create()(SettingForm) |
New file |
| | |
| | | .model-menu-setting-form { |
| | | position: relative; |
| | | |
| | | .anticon-question-circle { |
| | | color: #c49f47; |
| | | margin-right: 3px; |
| | | } |
| | | .ant-input-number { |
| | | width: 100%; |
| | | } |
| | | .color-sketch-block { |
| | | margin-top: 6px; |
| | | } |
| | | } |
| | |
| | | } |
| | | |
| | | state = { |
| | | dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | visible: false, |
| | | setting: null |
| | | } |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { connect } from 'react-redux' |
| | | import { is, fromJS } from 'immutable' |
| | | import { Icon, Popover, Button } from 'antd' |
| | | |
| | |
| | | } |
| | | |
| | | state = { |
| | | dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | group: null, |
| | | editab: null, |
| | | } |
| | |
| | | } |
| | | } |
| | | |
| | | const mapStateToProps = (state) => { |
| | | return { |
| | | menu: state.customMenu |
| | | } |
| | | } |
| | | |
| | | const mapDispatchToProps = () => { |
| | | return {} |
| | | } |
| | | |
| | | export default connect(mapStateToProps, mapDispatchToProps)(NormalGroup) |
| | | export default NormalGroup |
| | |
| | | import React, { Component } from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { connect } from 'react-redux' |
| | | import { is, fromJS } from 'immutable' |
| | | import { Modal, notification, Popover, Icon } from 'antd' |
| | | import moment from 'moment' |
| | |
| | | } |
| | | |
| | | state = { |
| | | dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | searchlist: null, // 搜索条件集 |
| | | sqlVerifing: false, // sql验证中 |
| | | visible: false, // 模态框控制 |
| | |
| | | ) |
| | | } |
| | | } |
| | | const mapStateToProps = (state) => { |
| | | return { |
| | | menu: state.customMenu |
| | | } |
| | | } |
| | | |
| | | const mapDispatchToProps = () => { |
| | | return {} |
| | | } |
| | | |
| | | export default connect(mapStateToProps, mapDispatchToProps)(MainSearchComponent) |
| | | export default MainSearchComponent |
| | |
| | | } |
| | | |
| | | state = { |
| | | dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | visible: false, |
| | | wrap: null |
| | | } |
| | |
| | | excelOut: ['label', 'OpenType', 'intertype', 'show', 'icon', 'class', 'execSuccess', 'execError', 'syncComponent', 'resetPageIndex', 'pagination', 'search', 'width'], |
| | | popview: ['label', 'Ot', 'OpenType', 'show', 'icon', 'class', 'popClose', 'resetPageIndex', 'width'], |
| | | tab: ['label', 'Ot', 'OpenType', 'show', 'icon', 'class', 'linkmenu', 'width'], |
| | | innerpage: ['label', 'Ot', 'OpenType', 'pageTemplate', 'show', 'icon', 'class', 'width'], |
| | | innerpage: ['label', 'Ot', 'OpenType', 'pageTemplate', 'show', 'icon', 'class', 'width', 'open'], |
| | | funcbutton: ['label', 'OpenType', 'funcType', 'show', 'icon', 'class', 'width'] |
| | | } |
| | | |
| | | class MainSearch extends Component { |
| | | class ActionForm extends Component { |
| | | static propTpyes = { |
| | | dict: PropTypes.object, // 字典项 |
| | | type: PropTypes.any, // type为"card"时,只可选单行或不选行 |
| | |
| | | |
| | | let _opentype = card.OpenType // 打开方式 |
| | | let _intertype = card.intertype || 'system' // 接口类型 |
| | | let _funcType = card.funcType || 'print' // 功能按钮默认类型 |
| | | let _procMode = card.procMode || 'system' // 参数请求方式 |
| | | let _funcType = card.funcType || '' // 功能按钮默认类型 |
| | | let _procMode = card.procMode || 'system' // 参数请求方式 |
| | | |
| | | let _options = this.getOptions(_opentype, _intertype, _funcType, card.pageTemplate, _procMode) |
| | | |
| | |
| | | item.options = this.state.requireOptions.filter(op => ['notRequired', 'requiredSgl'].includes(op.value)) |
| | | } else if (card.pageTemplate === 'pay') { // 行级按钮、支付按钮,只能选单行 |
| | | item.options = this.state.requireOptions.filter(op => ['requiredSgl'].includes(op.value)) |
| | | } else if (['innerpage', 'blank', 'tab', 'popview', 'excelIn'].includes(_opentype)) { |
| | | } else if (['innerpage', 'tab', 'popview', 'excelIn'].includes(_opentype)) { |
| | | item.options = this.state.requireOptions.filter(op => ['notRequired', 'requiredSgl'].includes(op.value)) |
| | | } else if (card.sqlType === 'insert') { |
| | | item.options = this.state.requireOptions.filter(op => ['notRequired', 'requiredSgl', 'required'].includes(op.value)) |
| | |
| | | if (_opentype === 'innerpage') { // 新页面,可选模板(自定义时,可填入外部链接) |
| | | if (_pageTemplate === 'custom') { |
| | | _options.push('url', 'joint') |
| | | } else if (_pageTemplate === 'page') { |
| | | _options.push('copyMenuId', 'joint') |
| | | } else if (_pageTemplate === 'linkpage') { |
| | | _options.push('linkmenu', 'joint') |
| | | } |
| | | } else if (_opentype === 'excelOut') { // 导入导出 |
| | | if (_intertype === 'outer') { |
| | |
| | | } |
| | | } else if (_opentype !== 'popview' && _opentype !== 'tab') { |
| | | if (_intertype === 'custom') { |
| | | _options.push('procMode', 'interface', 'callbackType', 'cbTable', 'proInterface', 'method') |
| | | _options.push('procMode', 'interface', 'callbackType', 'cbTable', 'proInterface', 'method', 'cross') |
| | | if (_procMode === 'system') { |
| | | _options.push('sql', 'sqlType') |
| | | } else { |
| | |
| | | } else if (item.key === 'Ot') { |
| | | if (type === 'card') { |
| | | item.options = this.state.requireOptions.filter(op => ['notRequired', 'requiredSgl'].includes(op.value)) |
| | | } else if (['innerpage', 'blank', 'tab', 'popview'].includes(value)) { |
| | | } else if (['innerpage', 'tab', 'popview'].includes(value)) { |
| | | item.options = this.state.requireOptions.filter(op => ['notRequired', 'requiredSgl'].includes(op.value)) |
| | | _fieldval.Ot = 'requiredSgl' |
| | | } else if (value === 'excelIn') { |
| | |
| | | this.props.form.setFieldsValue(_fieldval) |
| | | }) |
| | | } else if (key === 'funcType') { |
| | | let _options = this.getOptions(this.state.openType, this.state.interType, value, card.pageTemplate, procMode) |
| | | let _options = this.getOptions(openType, this.state.interType, value, card.pageTemplate, procMode) |
| | | let _fieldval = {} |
| | | |
| | | this.setState({ |
| | |
| | | }) |
| | | } else if (key === 'pageTemplate') { |
| | | let _fieldval = {} |
| | | let _options = this.getOptions(this.state.openType, this.state.interType, this.state.funcType, value, procMode) |
| | | let _options = this.getOptions(openType, this.state.interType, this.state.funcType, value, procMode) |
| | | |
| | | this.setState({ |
| | | openType: value, |
| | | formlist: this.state.formlist.map(item => { |
| | | item.hidden = !_options.includes(item.key) |
| | | |
| | |
| | | </Form.Item> |
| | | </Col> |
| | | ) |
| | | } else if (item.type === 'tip') { |
| | | fields.push( |
| | | <Col span={12} key={index}> |
| | | <Form.Item label={item.label}> |
| | | {item} |
| | | </Form.Item> |
| | | </Col> |
| | | ) |
| | | } else if (item.type === 'number') { |
| | | fields.push( |
| | | <Col span={12} key={index}> |
| | |
| | | } else if (item.type === 'radio') { |
| | | fields.push( |
| | | <Col span={12} key={index}> |
| | | <Form.Item label={item.label}> |
| | | <Form.Item label={item.tooltip ? |
| | | <Tooltip placement="topLeft" overlayClassName={item.tooltipClass} title={item.tooltip}> |
| | | <Icon type="question-circle" /> |
| | | {item.label} |
| | | </Tooltip> : item.label |
| | | }> |
| | | {getFieldDecorator(item.key, { |
| | | initialValue: item.initVal, |
| | | rules: [ |
| | |
| | | } |
| | | |
| | | handleConfirm = () => { |
| | | const { setting } = this.props |
| | | const { setting, card } = this.props |
| | | // 表单提交时检查输入值是否正确 |
| | | return new Promise((resolve, reject) => { |
| | | this.props.form.validateFieldsAndScroll((err, values) => { |
| | | if (!err) { |
| | | values.uuid = this.props.card.uuid |
| | | values.verify = this.props.card.verify || null |
| | | values.uuid = card.uuid |
| | | values.verify = card.verify || null |
| | | |
| | | if (values.show === 'icon' && !values.icon) { |
| | | notification.warning({ |
| | |
| | | |
| | | values.Ot = 'notRequired' |
| | | } else if (['pop', 'prompt', 'exec'].includes(values.OpenType) && values.verify) { |
| | | if ((values.Ot === 'requiredOnce' || this.props.card.Ot === 'requiredOnce') && this.props.card.Ot !== values.Ot) { |
| | | if ((values.Ot === 'requiredOnce' || card.Ot === 'requiredOnce') && card.Ot !== values.Ot) { |
| | | values.verify.uniques = [] |
| | | } |
| | | if (card.Ot !== values.Ot) { |
| | | if (values.Ot === 'notRequired') { |
| | | values.verify.invalid = 'false' |
| | | } else if (card.Ot === 'notRequired' && values.Ot !== 'notRequired') { |
| | | values.verify.invalid = 'true' |
| | | } |
| | | } |
| | | } |
| | | |
| | |
| | | } |
| | | } |
| | | |
| | | export default Form.create()(MainSearch) |
| | | export default Form.create()(ActionForm) |
| | |
| | | import zhCN from '@/locales/zh-CN/model.js' |
| | | import enUS from '@/locales/en-US/model.js' |
| | | |
| | | const Formdict = localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS |
| | | const Formdict = sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS |
| | | |
| | | /** |
| | | * @description 获取按钮表单配置信息 |
| | |
| | | * @param {*} type 按钮类型,用于区分可选的打开方式 |
| | | */ |
| | | export function getActionForm (card, functip, setting, usefulFields, type, menulist = [], modules = []) { |
| | | let appMenus = [] |
| | | let opentypes = [ |
| | | { |
| | | value: 'pop', |
| | |
| | | } |
| | | ] |
| | | |
| | | let pageTemps = [ |
| | | { value: 'billprint', text: '单据打印' }, |
| | | { value: 'pay', text: Formdict['model.pay'] }, |
| | | { value: 'custom', text: Formdict['header.form.custom'] } |
| | | ] |
| | | const isApp = sessionStorage.getItem('appType') === 'pc' |
| | | |
| | | let funTypes = [ |
| | | { value: 'changeuser', text: Formdict['header.form.func.changeuser'] }, |
| | | { value: 'print', text: '标签打印' } |
| | | ] |
| | | |
| | | if (isApp) { |
| | | opentypes = opentypes.filter(item => item.value !== 'tab') |
| | | pageTemps = [ |
| | | { value: 'page', text: '菜单' }, |
| | | { value: 'linkpage', text: '关联菜单' }, |
| | | { value: 'billprint', text: '单据打印' }, |
| | | { value: 'pay', text: Formdict['model.pay'] }, |
| | | { value: 'custom', text: '链接' } |
| | | ] |
| | | funTypes = [ |
| | | { value: 'changeuser', text: Formdict['header.form.func.changeuser'] }, |
| | | ] |
| | | appMenus = sessionStorage.getItem('appMenus') |
| | | if (appMenus) { |
| | | try { |
| | | appMenus = JSON.parse(appMenus) |
| | | appMenus = appMenus.map(item => ({value: item.MenuID, text: item.MenuName})) |
| | | } catch { |
| | | appMenus = [] |
| | | } |
| | | } else { |
| | | appMenus = [] |
| | | } |
| | | } |
| | | |
| | | if (type === 'chart') { |
| | | opentypes = opentypes.filter(item => item.value === 'excelIn' || item.value === 'excelOut') |
| | | } |
| | |
| | | type: 'radio', |
| | | key: 'funcType', |
| | | label: Formdict['header.form.funcType'], |
| | | initVal: card.funcType || 'print', |
| | | initVal: card.funcType || (isApp ? 'changeuser' : ''), |
| | | required: true, |
| | | options: [{ |
| | | value: 'changeuser', |
| | | text: Formdict['header.form.func.changeuser'] |
| | | }, { |
| | | value: 'print', |
| | | text: '标签打印' |
| | | }] |
| | | options: funTypes |
| | | }, |
| | | { |
| | | type: 'select', |
| | |
| | | label: Formdict['model.form.newpage.type'], |
| | | initVal: card.pageTemplate || '', |
| | | required: true, |
| | | options: pageTemps |
| | | }, |
| | | { |
| | | type: 'radio', |
| | | key: 'open', |
| | | label: '链接方式', |
| | | initVal: card.open || 'blank', |
| | | required: true, |
| | | forbid: !isApp, |
| | | options: [{ |
| | | value: 'billprint', |
| | | text: '单据打印' |
| | | value: 'blank', |
| | | text: '新窗口' |
| | | }, { |
| | | value: 'pay', |
| | | text: Formdict['model.pay'] |
| | | }, { |
| | | value: 'custom', |
| | | text: Formdict['header.form.custom'] |
| | | value: 'self', |
| | | text: '当前窗口' |
| | | }] |
| | | }, |
| | | { |
| | | type: 'text', |
| | | type: 'select', |
| | | key: 'linkmenu', |
| | | label: '关联菜单', |
| | | initVal: card.linkmenu || '', |
| | | required: true, |
| | | options: appMenus |
| | | }, |
| | | { |
| | | type: 'select', |
| | | key: 'copyMenuId', |
| | | label: '复制菜单', |
| | | initVal: card.copyMenuId || '', |
| | | required: false, |
| | | options: appMenus |
| | | }, |
| | | { |
| | | type: 'textarea', |
| | | key: 'url', |
| | | label: Formdict['model.form.newpage.url'], |
| | | label: Formdict['model.pageUrl'], |
| | | initVal: card.url || '', |
| | | required: true |
| | | }, |
| | |
| | | }, |
| | | { |
| | | type: 'radio', |
| | | key: 'cross', |
| | | label: '跨域请求', |
| | | initVal: card.cross || 'true', |
| | | tooltip: '如果自定义接口不支持跨域请求,会通过当前系统转发。', |
| | | required: false, |
| | | options: [{ |
| | | value: 'true', |
| | | text: '支持' |
| | | }, { |
| | | value: 'false', |
| | | text: '不支持' |
| | | }] |
| | | }, |
| | | { |
| | | type: 'radio', |
| | | key: 'callbackType', |
| | | label: '回调方式', |
| | | initVal: card.callbackType || 'script', |
| | | tooltip: '使用默认方式执行时,需要配合计划任务。', |
| | | tooltip: '使用后台脚本执行时,需要配合计划任务。', |
| | | required: true, |
| | | options: [{ |
| | | value: 'default', |
| | | text: '默认脚本' |
| | | }, { |
| | | value: 'script', |
| | | text: '自定义脚本' |
| | | }, { |
| | | value: 'default', |
| | | text: '后台脚本' |
| | | }] |
| | | }, |
| | | { |
| | |
| | | label: Formdict['model.form.linkmenu'], |
| | | initVal: card.linkmenu || [], |
| | | required: true, |
| | | forbid: isApp, |
| | | options: menulist |
| | | }, |
| | | { |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import {connect} from 'react-redux' |
| | | import { is, fromJS } from 'immutable' |
| | | import { Modal, notification, Button } from 'antd' |
| | | |
| | | import Utils from '@/utils/utils.js' |
| | | import DevUtils from '@/utils/devutils.js' |
| | | import Utils, { FuncUtils } from '@/utils/utils.js' |
| | | import zhCN from '@/locales/zh-CN/model.js' |
| | | import enUS from '@/locales/en-US/model.js' |
| | | import { getActionForm } from './formconfig' |
| | |
| | | |
| | | import MKEmitter from '@/utils/events.js' |
| | | import ActionForm from './actionform' |
| | | import MenuUtils from '@/menu/utils/menuUtils.js' |
| | | import MenuUtils from '@/utils/utils-custom.js' |
| | | import CreateFunc from '@/templates/zshare/createfunc' |
| | | import DragElement from './dragaction' |
| | | import './index.scss' |
| | |
| | | } |
| | | |
| | | state = { |
| | | dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | card: null, // 编辑中元素 |
| | | formlist: null, // 表单信息 |
| | | actionlist: null, // 按钮组 |
| | |
| | | * @description 按钮编辑,获取按钮表单信息 |
| | | */ |
| | | handleAction = (card) => { |
| | | const { menu, config } = this.props |
| | | const { config } = this.props |
| | | |
| | | let usefulFields = sessionStorage.getItem('permFuncField') |
| | | if (usefulFields) { |
| | |
| | | menulist = [] |
| | | } |
| | | |
| | | let modules = MenuUtils.getSubModules(menu.components, config.uuid) |
| | | let modules = MenuUtils.getSubModules(window.GLOB.customMenu.components, config.uuid) |
| | | |
| | | this.setState({ |
| | | visible: true, |
| | |
| | | * @description 创建按钮存储过程 |
| | | */ |
| | | creatFunc = () => { |
| | | const { menu } = this.props |
| | | const menu = window.GLOB.customMenu |
| | | let _config = fromJS(this.props.config).toJS() |
| | | |
| | | this.actionFormRef.handleConfirm().then(res => { |
| | |
| | | } |
| | | |
| | | if (btn.OpenType === 'pop') { |
| | | let fields = [] |
| | | if (btn.groups.length > 0) { |
| | | btn.groups.forEach(group => { |
| | | fields = [...fields, ...group.sublist] |
| | | }) |
| | | } else { |
| | | fields = btn.fields |
| | | } |
| | | |
| | | let _param = { |
| | | funcName: btn.innerFunc, |
| | | name: _config.setting.tableName || '', |
| | | fields: fields, |
| | | fields: btn.fields, |
| | | menuNo: menu.MenuNo |
| | | } |
| | | newLText = Utils.formatOptions(DevUtils.getfunc(_param, btn, menu, _config)) |
| | | DelText = Utils.formatOptions(DevUtils.dropfunc(btn.innerFunc)) |
| | | newLText = Utils.formatOptions(FuncUtils.getfunc(_param, btn, menu, _config)) |
| | | DelText = Utils.formatOptions(FuncUtils.dropfunc(btn.innerFunc)) |
| | | } else if (btn.OpenType === 'excelIn') { |
| | | let _param = { |
| | | funcName: btn.innerFunc, |
| | | menuNo: menu.MenuNo |
| | | } |
| | | newLText = Utils.formatOptions(DevUtils.getexcelInfunc(_param, btn, menu)) |
| | | DelText = Utils.formatOptions(DevUtils.dropfunc(btn.innerFunc)) |
| | | newLText = Utils.formatOptions(FuncUtils.getexcelInfunc(_param, btn, menu)) |
| | | DelText = Utils.formatOptions(FuncUtils.dropfunc(btn.innerFunc)) |
| | | } else if (btn.OpenType === 'excelOut') { |
| | | let _param = { |
| | | innerFunc: btn.innerFunc |
| | | } |
| | | |
| | | newLText = Utils.formatOptions(DevUtils.getTableFunc(_param, menu, _config)) // 创建存储过程sql |
| | | DelText = Utils.formatOptions(DevUtils.dropfunc(btn.innerFunc)) |
| | | newLText = Utils.formatOptions(FuncUtils.getTableFunc(_param, menu, _config)) // 创建存储过程sql |
| | | DelText = Utils.formatOptions(FuncUtils.dropfunc(btn.innerFunc)) |
| | | } else { |
| | | let _param = { |
| | | funcName: btn.innerFunc, |
| | |
| | | fields: '', |
| | | menuNo: menu.MenuNo |
| | | } |
| | | newLText = Utils.formatOptions(DevUtils.getfunc(_param, btn, menu, _config)) |
| | | DelText = Utils.formatOptions(DevUtils.dropfunc(btn.innerFunc)) |
| | | newLText = Utils.formatOptions(FuncUtils.getfunc(_param, btn, menu, _config)) |
| | | DelText = Utils.formatOptions(FuncUtils.dropfunc(btn.innerFunc)) |
| | | } |
| | | |
| | | this.refs.btnCreatFunc.exec(btn.innerFunc, newLText, DelText) |
| | |
| | | btnDoubleClick = (element) => { |
| | | if (sessionStorage.getItem('style-control') && sessionStorage.getItem('style-control') !== 'false') return |
| | | |
| | | if (element.OpenType === 'pop' || element.OpenType === 'popview') { |
| | | if (element.OpenType === 'pop' || element.OpenType === 'popview' || element.execMode === 'pop') { |
| | | this.props.setSubConfig(element) |
| | | } else if (element.OpenType === 'innerpage' && element.pageTemplate === 'page') { |
| | | MKEmitter.emit('changeEditMenu', {MenuID: element.uuid, copyMenuId: element.copyMenuId}) |
| | | } else if (element.OpenType === 'innerpage' && element.pageTemplate === 'linkpage') { |
| | | MKEmitter.emit('changeEditMenu', {MenuID: element.linkmenu}) |
| | | } else { |
| | | notification.warning({ |
| | | top: 92, |
| | |
| | | visible={profVisible} |
| | | width={'75vw'} |
| | | maskClosable={false} |
| | | style={{minWidth: '900px', maxWidth: '1200px'}} |
| | | okText={dict['model.submit']} |
| | | onOk={this.verifySubmit} |
| | | onCancel={() => { this.setState({ profVisible: false }) }} |
| | |
| | | } |
| | | } |
| | | |
| | | const mapStateToProps = (state) => { |
| | | return { |
| | | menu: state.customMenu |
| | | } |
| | | } |
| | | |
| | | const mapDispatchToProps = () => { |
| | | return {} |
| | | } |
| | | |
| | | export default connect(mapStateToProps, mapDispatchToProps)(ActionComponent) |
| | | export default ActionComponent |
| | |
| | | min-height: calc(100vh - 300px); |
| | | overflow-y: auto; |
| | | .ant-empty { |
| | | margin: 15vh 8px; |
| | | margin: 5vh 8px; |
| | | } |
| | | } |
| | | .ant-modal-body::-webkit-scrollbar { |
New file |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { is, fromJS } from 'immutable' |
| | | import { Icon, Modal } from 'antd' |
| | | |
| | | import zhCN from '@/locales/zh-CN/model.js' |
| | | import enUS from '@/locales/en-US/model.js' |
| | | import ClockForm from './settingform' |
| | | import './index.scss' |
| | | |
| | | class ClockComponent extends Component { |
| | | static propTpyes = { |
| | | btnlog: PropTypes.array, |
| | | updateConfig: PropTypes.func |
| | | } |
| | | |
| | | state = { |
| | | dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | visible: false, |
| | | timer: '', |
| | | } |
| | | |
| | | shouldComponentUpdate (nextProps, nextState) { |
| | | return !is(fromJS(this.state), fromJS(nextState)) |
| | | } |
| | | |
| | | trigger = () => { |
| | | const { config } = this.props |
| | | |
| | | this.setState({ |
| | | visible: true, |
| | | timer: config.timer || '' |
| | | }) |
| | | } |
| | | |
| | | submit = () => { |
| | | const { config } = this.props |
| | | |
| | | this.verifyRef.handleConfirm().then(res => { |
| | | this.setState({ |
| | | visible: false |
| | | }) |
| | | this.props.updateConfig({...config, timer: res.timer}) |
| | | }) |
| | | } |
| | | |
| | | render () { |
| | | const { visible, loading, timer } = this.state |
| | | |
| | | return ( |
| | | <div className="clock-component-wrap"> |
| | | <Icon type="clock-circle" title="定时器" onClick={this.trigger} /> |
| | | <Modal |
| | | title="定时器设置" |
| | | visible={visible} |
| | | width={500} |
| | | maskClosable={false} |
| | | confirmLoading={loading} |
| | | onOk={this.submit} |
| | | onCancel={() => this.setState({ visible: false })} |
| | | destroyOnClose |
| | | > |
| | | <ClockForm timer={timer} inputSubmit={this.submit} wrappedComponentRef={(inst) => this.verifyRef = inst}/> |
| | | </Modal> |
| | | </div> |
| | | ) |
| | | } |
| | | } |
| | | |
| | | export default ClockComponent |
New file |
| | |
| | | .clock-component-wrap { |
| | | display: inline-block; |
| | | |
| | | >.anticon-clock-circle { |
| | | color: rgb(38, 194, 129); |
| | | } |
| | | } |
New file |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { Form, Row, Col, Select } from 'antd' |
| | | |
| | | import './index.scss' |
| | | |
| | | class SettingForm extends Component { |
| | | static propTpyes = { |
| | | timer: PropTypes.string, // 组件名称 |
| | | inputSubmit: PropTypes.func // 回车事件 |
| | | } |
| | | |
| | | state = {} |
| | | |
| | | handleConfirm = () => { |
| | | // 表单提交时检查输入值是否正确 |
| | | return new Promise((resolve, reject) => { |
| | | this.props.form.validateFieldsAndScroll((err, values) => { |
| | | if (!err) { |
| | | resolve(values) |
| | | } else { |
| | | reject(err) |
| | | } |
| | | }) |
| | | }) |
| | | } |
| | | |
| | | render() { |
| | | const { getFieldDecorator } = this.props.form |
| | | |
| | | const formItemLayout = { |
| | | labelCol: { |
| | | xs: { span: 24 }, |
| | | sm: { span: 8 } |
| | | }, |
| | | wrapperCol: { |
| | | xs: { span: 24 }, |
| | | sm: { span: 16 } |
| | | } |
| | | } |
| | | |
| | | return ( |
| | | <div> |
| | | <Form {...formItemLayout}> |
| | | <Row gutter={24}> |
| | | <Col span={22}> |
| | | <Form.Item label="定时器"> |
| | | {getFieldDecorator('timer', { |
| | | initialValue: this.props.timer || '' |
| | | })( |
| | | <Select> |
| | | <Select.Option value=""> 无 </Select.Option> |
| | | <Select.Option value="15s"> 15秒 </Select.Option> |
| | | <Select.Option value="30s"> 30秒 </Select.Option> |
| | | <Select.Option value="1min"> 1分钟 </Select.Option> |
| | | <Select.Option value="5min"> 5分钟 </Select.Option> |
| | | <Select.Option value="10min"> 10分钟 </Select.Option> |
| | | <Select.Option value="15min"> 15分钟 </Select.Option> |
| | | <Select.Option value="30min"> 30分钟 </Select.Option> |
| | | <Select.Option value="1hour"> 1小时 </Select.Option> |
| | | </Select> |
| | | )} |
| | | </Form.Item> |
| | | </Col> |
| | | </Row> |
| | | </Form> |
| | | </div> |
| | | ) |
| | | } |
| | | } |
| | | |
| | | export default Form.create()(SettingForm) |
copy from src/mob/datasource/verifycard/columnform/index.scss
copy to src/menu/components/share/clockcomponent/settingform/index.scss
| | |
| | | } |
| | | |
| | | state = { |
| | | dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | visible: false, |
| | | data: [], |
| | | columns: [ |
| | |
| | | } |
| | | |
| | | state = { |
| | | dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | marks: null, |
| | | columns: null, |
| | | visible: false, |
| | |
| | | visible={visible} |
| | | width={'75vw'} |
| | | maskClosable={false} |
| | | style={{minWidth: '900px', maxWidth: '1200px'}} |
| | | okText={dict['model.submit']} |
| | | onOk={this.markSubmit} |
| | | onCancel={() => { this.setState({ visible: false }) }} |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { is, fromJS } from 'immutable' |
| | | import {connect} from 'react-redux' |
| | | import { Modal, notification } from 'antd' |
| | | import moment from 'moment' |
| | | |
| | |
| | | } |
| | | |
| | | state = { |
| | | dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | searchlist: null, // 搜索条件集 |
| | | sqlVerifing: false, // sql验证中 |
| | | visible: false, // 模态框控制 |
| | |
| | | } |
| | | } |
| | | |
| | | const mapStateToProps = (state) => { |
| | | return { |
| | | menu: state.customMenu |
| | | } |
| | | } |
| | | |
| | | const mapDispatchToProps = () => { |
| | | return {} |
| | | } |
| | | |
| | | export default connect(mapStateToProps, mapDispatchToProps)(SearchComponent) |
| | | export default SearchComponent |
| | |
| | | import MKEmitter from '@/utils/events.js' |
| | | import './index.scss' |
| | | |
| | | class DataSource extends Component { |
| | | class UserComponent extends Component { |
| | | static propTpyes = { |
| | | btnlog: PropTypes.array, |
| | | handlelog: PropTypes.func |
| | | btnlog: PropTypes.array |
| | | } |
| | | |
| | | state = { |
| | | dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | visible: false, |
| | | loading: false, |
| | | name: '', |
| | |
| | | } |
| | | } |
| | | |
| | | export default DataSource |
| | | export default UserComponent |
| | |
| | | import zhCN from '@/locales/zh-CN/model.js' |
| | | import enUS from '@/locales/en-US/model.js' |
| | | |
| | | const Formdict = localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS |
| | | const Formdict = sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS |
| | | |
| | | /** |
| | | * @description 获取显示列表单配置信息 |
| | |
| | | value: 'action', |
| | | text: '操作' |
| | | }) |
| | | } |
| | | |
| | | if (!card.linkurl && (!card.linkmenu || card.linkmenu.length === 0)) { |
| | | card.perspective = '' |
| | | } |
| | | |
| | | return [ |
| | |
| | | type: 'radio', |
| | | key: 'perspective', |
| | | label: '字段透视', |
| | | initVal: card.perspective || 'linkmenu', |
| | | initVal: card.perspective || '', |
| | | options: [{ |
| | | value: '', |
| | | text: '无' |
| | | }, { |
| | | value: 'linkmenu', |
| | | text: '菜单' |
| | | }, { |
| | |
| | | key: 'linkmenu', |
| | | label: Formdict['model.menu'], |
| | | initVal: card.linkmenu || [], |
| | | required: false, |
| | | required: true, |
| | | options: menulist |
| | | }, |
| | | { |
| | | type: 'text', |
| | | type: 'textarea', |
| | | key: 'linkurl', |
| | | label: '链接地址', |
| | | initVal: card.linkurl || '', |
| | | required: false |
| | | required: true |
| | | }, |
| | | { |
| | | type: 'multiselect', |
| | | key: 'linkfields', |
| | | label: '关联字段', |
| | | initVal: card.linkfields || [], |
| | | required: false, |
| | | options: fields |
| | | }, |
| | | { |
| | | type: 'multiselect', |
| | |
| | | import { formRule } from '@/utils/option.js' |
| | | import './index.scss' |
| | | |
| | | const { TextArea } = Input |
| | | const columnTypeOptions = { |
| | | text: ['label', 'field', 'type', 'Align', 'Hide', 'IsSort', 'Width', 'prefix', 'postfix', 'textFormat', 'blacklist', 'perspective', 'rowspan'], |
| | | number: ['label', 'field', 'type', 'Align', 'Hide', 'IsSort', 'Width', 'decimal', 'format', 'prefix', 'postfix', 'blacklist', 'perspective', 'sum', 'rowspan'], |
| | |
| | | let formlist = getColumnForm(column, menulist, this.props.fields) |
| | | let _options = fromJS(columnTypeOptions[column.type]).toJS() |
| | | if (column.type === 'text' || column.type === 'number') { |
| | | if (column.perspective !== 'linkurl') { |
| | | _options.push('linkmenu') |
| | | } else { |
| | | _options.push('linkurl') |
| | | if (column.perspective === 'linkmenu') { |
| | | _options.push('linkmenu', 'linkfields') |
| | | } else if (column.perspective === 'linkurl') { |
| | | _options.push('linkurl', 'linkfields') |
| | | } |
| | | } |
| | | |
| | |
| | | if (key === 'type') { |
| | | let _options = fromJS(columnTypeOptions[value]).toJS() |
| | | |
| | | if (value === 'text' || value === 'number') { |
| | | _options.push('linkmenu') |
| | | } |
| | | |
| | | this.setState({ |
| | | type: value, |
| | | formlist: this.state.formlist.map(item => { |
| | |
| | | if (value === 'link' || value === 'textarea' || value === 'picture') { |
| | | this.props.form.setFieldsValue({IsSort: 'false'}) |
| | | } else if (value === 'text' || value === 'number') { |
| | | this.props.form.setFieldsValue({perspective: 'linkmenu'}) |
| | | this.props.form.setFieldsValue({perspective: ''}) |
| | | } else if (value === 'action' || value === 'colspan') { |
| | | this.props.form.setFieldsValue({Align: 'center'}) |
| | | } |
| | |
| | | if (key === 'perspective') { |
| | | let _options = fromJS(columnTypeOptions[this.state.type]).toJS() |
| | | |
| | | if (value !== 'linkurl') { |
| | | _options.push('linkmenu') |
| | | } else { |
| | | _options.push('linkurl') |
| | | if (value === 'linkmenu') { |
| | | _options.push('linkmenu', 'linkfields') |
| | | } else if (value === 'linkurl') { |
| | | _options.push('linkurl', 'linkfields') |
| | | } |
| | | |
| | | this.setState({ |
| | |
| | | filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0} |
| | | > |
| | | {item.options.map((option, i) => |
| | | <Select.Option id={i} key={i} value={option.value}>{option.text}</Select.Option> |
| | | <Select.Option id={i} key={i} value={option.value || option.field}>{option.text || option.label}</Select.Option> |
| | | )} |
| | | </Select> |
| | | )} |
| | |
| | | <Col span={12} key={index}> |
| | | <Form.Item label={item.label}> |
| | | {getFieldDecorator(item.key, { |
| | | initialValue: item.initVal || [] |
| | | initialValue: item.initVal || [], |
| | | rules: [ |
| | | { |
| | | required: !!item.required, |
| | | message: this.props.dict['form.required.select'] + item.label + '!' |
| | | } |
| | | ] |
| | | })( |
| | | <Cascader |
| | | options={item.options} |
| | |
| | | </Form.Item> |
| | | </Col> |
| | | ) |
| | | } else if (item.type === 'textarea') { // 文本搜索 |
| | | fields.push( |
| | | <Col span={24} key={index} className="textarea"> |
| | | <Form.Item label={item.tooltip ? |
| | | <Tooltip placement="topLeft" title={item.tooltip}> |
| | | <Icon type="question-circle" /> |
| | | {item.label} |
| | | </Tooltip> : item.label |
| | | }> |
| | | {getFieldDecorator(item.key, { |
| | | initialValue: item.initVal || '', |
| | | rules: [ |
| | | { |
| | | required: !!item.required, |
| | | message: this.props.dict['form.required.input'] + item.label + '!' |
| | | } |
| | | ] |
| | | })(<TextArea rows={2} disabled={item.readonly} onPressEnter={this.handleSubmit} />)} |
| | | </Form.Item> |
| | | </Col> |
| | | ) |
| | | } |
| | | }) |
| | | return fields |
| | |
| | | padding-right: 3px; |
| | | } |
| | | } |
| | | .textarea { |
| | | .ant-form-item-label { |
| | | width: 12%; |
| | | } |
| | | .ant-form-item-control-wrapper { |
| | | width: 88%; |
| | | } |
| | | } |
| | | } |
| | |
| | | } |
| | | |
| | | state = { |
| | | dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | tableId: '', |
| | | data: [{uuid: Utils.getuuid()}], |
| | | refresh: false, // 强制刷新 |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import {connect} from 'react-redux' |
| | | import { is, fromJS } from 'immutable' |
| | | import { Icon, Popover, Modal, notification } from 'antd' |
| | | |
| | |
| | | } |
| | | |
| | | state = { |
| | | dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | card: null, |
| | | back: false |
| | | } |
| | |
| | | } |
| | | |
| | | shouldComponentUpdate (nextProps, nextState) { |
| | | return !is(fromJS(this.state), fromJS(nextState)) || (!this.props.menu && nextProps.menu) |
| | | return !is(fromJS(this.state), fromJS(nextState)) |
| | | } |
| | | |
| | | /** |
| | |
| | | const { card } = this.state |
| | | let btn = fromJS(item).toJS() |
| | | |
| | | if (btn.OpenType === 'pop') { |
| | | if (btn.OpenType === 'pop' || btn.execMode === 'pop') { |
| | | if (!btn.modal) { |
| | | btn.modal = { |
| | | setting: { title: btn.label, width: 60, cols: '2', container: 'view', focus: '', finish: 'close', clickouter: 'unclose', display: 'modal' }, |
| | |
| | | } |
| | | } |
| | | |
| | | const mapStateToProps = (state) => { |
| | | return { |
| | | menu: state.customMenu |
| | | } |
| | | } |
| | | |
| | | const mapDispatchToProps = () => { |
| | | return {} |
| | | } |
| | | |
| | | export default connect(mapStateToProps, mapDispatchToProps)(TableCardEditComponent) |
| | | export default TableCardEditComponent |
| | |
| | | } |
| | | |
| | | state = { |
| | | dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | visible: false, |
| | | wrap: null |
| | | } |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { connect } from 'react-redux' |
| | | import { is, fromJS } from 'immutable' |
| | | import { Tabs, Icon, Popover, Modal } from 'antd' |
| | | |
| | |
| | | } |
| | | |
| | | state = { |
| | | dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | tabs: null, |
| | | editab: null, |
| | | labelvisible: false |
| | |
| | | this.tabLabelRef.handleConfirm().then(res => { |
| | | editab.label = res.label |
| | | editab.icon = res.icon |
| | | editab.blacklist = res.blacklist |
| | | |
| | | if (editab.uuid) { |
| | | tabs.subtabs = tabs.subtabs.map(t => { |
| | |
| | | } |
| | | } |
| | | |
| | | const mapStateToProps = (state) => { |
| | | return { |
| | | menu: state.customMenu |
| | | } |
| | | } |
| | | |
| | | const mapDispatchToProps = () => { |
| | | return {} |
| | | } |
| | | |
| | | export default connect(mapStateToProps, mapDispatchToProps)(antvTabs) |
| | | export default antvTabs |
| | |
| | | const AntvTabs = asyncComponent(() => import('@/menu/components/tabs/antv-tabs')) |
| | | const DataCard = asyncComponent(() => import('@/menu/components/card/data-card')) |
| | | const PropCard = asyncComponent(() => import('@/menu/components/card/prop-card')) |
| | | const CarouselDataCard = asyncComponent(() => import('@/menu/components/carousel/data-card')) |
| | | const CarouselPropCard = asyncComponent(() => import('@/menu/components/carousel/prop-card')) |
| | | const TableCard = asyncComponent(() => import('@/menu/components/card/table-card')) |
| | | const NormalTable = asyncComponent(() => import('@/menu/components/table/normal-table')) |
| | | const NormalGroup = asyncComponent(() => import('@/menu/components/group/normal-group')) |
| | |
| | | return (<DataCard card={card} updateConfig={updateConfig} deletecomponent={delCard} />) |
| | | } else if (card.type === 'card' && card.subtype === 'propcard') { |
| | | return (<PropCard card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) |
| | | } else if (card.type === 'carousel' && card.subtype === 'datacard') { |
| | | return (<CarouselDataCard card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) |
| | | } else if (card.type === 'carousel' && card.subtype === 'propcard') { |
| | | return (<CarouselPropCard card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) |
| | | } else if (card.type === 'table' && card.subtype === 'tablecard') { |
| | | return (<TableCard card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) |
| | | } else if (card.type === 'table' && card.subtype === 'normaltable') { |
| | |
| | | |
| | | import Utils from '@/utils/utils.js' |
| | | import MKEmitter from '@/utils/events.js' |
| | | import MenuUtils from '@/menu/utils/menuUtils.js' |
| | | import MenuUtils from '@/utils/utils-custom.js' |
| | | import Card from './card' |
| | | import './index.scss' |
| | | |
| | |
| | | table: '表格', |
| | | group: '分组', |
| | | editor: '富文本', |
| | | carousel: '轮播', |
| | | card: '卡片' |
| | | } |
| | | let i = 1 |
| | |
| | | inputSubmit: PropTypes.func // 回车事件 |
| | | } |
| | | |
| | | state = {} |
| | | state = {roleList: []} |
| | | |
| | | UNSAFE_componentWillMount () { |
| | | let roleList = sessionStorage.getItem('sysRoles') |
| | | if (roleList) { |
| | | try { |
| | | roleList = JSON.parse(roleList) |
| | | } catch { |
| | | roleList = [] |
| | | } |
| | | } else { |
| | | roleList = [] |
| | | } |
| | | |
| | | this.setState({roleList}) |
| | | } |
| | | |
| | | handleConfirm = () => { |
| | |
| | | render() { |
| | | const { tab } = this.props |
| | | const { getFieldDecorator } = this.props.form |
| | | const { roleList } = this.state |
| | | |
| | | const formItemLayout = { |
| | | labelCol: { |
| | |
| | | )} |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={24}> |
| | | <Form.Item label="黑名单"> |
| | | {getFieldDecorator('blacklist', { |
| | | initialValue: tab.blacklist || [] |
| | | })( |
| | | <Select |
| | | showSearch |
| | | mode="multiple" |
| | | filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0} |
| | | > |
| | | {roleList.map(option => |
| | | <Select.Option key={option.uuid} value={option.value}>{option.text}</Select.Option> |
| | | )} |
| | | </Select> |
| | | )} |
| | | </Form.Item> |
| | | </Col> |
| | | </Row> |
| | | </Form> |
| | | ) |
| | |
| | | } |
| | | |
| | | state = { |
| | | dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | visible: false, |
| | | setting: null |
| | | } |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import {connect} from 'react-redux' |
| | | import { is, fromJS } from 'immutable' |
| | | import { Icon, Modal } from 'antd' |
| | | |
| | |
| | | } |
| | | |
| | | state = { |
| | | dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | sourcelist: [], |
| | | mainSearch: [], |
| | | visible: false, |
| | |
| | | } |
| | | |
| | | editDataSource = () => { |
| | | const { config, menu } = this.props |
| | | const { config } = this.props |
| | | |
| | | let search = [] |
| | | let parents = [] |
| | |
| | | _conf = item |
| | | |
| | | if (_conf.parentId && _conf.tabId) { |
| | | getParents(menu) |
| | | getParents(tab) |
| | | } |
| | | } else { |
| | | getParents(tab) |
| | |
| | | } |
| | | |
| | | if (config.parentId && config.tabId) { |
| | | getParents(menu) |
| | | getParents(window.GLOB.customMenu) |
| | | } |
| | | |
| | | parents.unshift(menu) |
| | | parents.unshift(window.GLOB.customMenu) |
| | | |
| | | parents.forEach(parent => { |
| | | parent.components.forEach(item => { |
| | |
| | | } |
| | | |
| | | render () { |
| | | const { config, menu } = this.props |
| | | const { config } = this.props |
| | | const { visible, dict, loading, mainSearch } = this.state |
| | | |
| | | return ( |
| | |
| | | visible={visible} |
| | | width={'75vw'} |
| | | maskClosable={false} |
| | | style={{minWidth: '900px', maxWidth: '1200px'}} |
| | | okText={dict['model.submit']} |
| | | onOk={this.verifySubmit} |
| | | confirmLoading={loading} |
| | |
| | | > |
| | | <VerifyCard |
| | | dict={dict} |
| | | menu={menu} |
| | | menu={window.GLOB.customMenu} |
| | | mainSearch={mainSearch} |
| | | config={config} |
| | | wrappedComponentRef={(inst) => this.verifyRef = inst} |
| | |
| | | } |
| | | } |
| | | |
| | | const mapStateToProps = (state) => { |
| | | return { |
| | | menu: state.customMenu |
| | | } |
| | | } |
| | | |
| | | const mapDispatchToProps = () => { |
| | | return {} |
| | | } |
| | | |
| | | export default connect(mapStateToProps, mapDispatchToProps)(DataSource) |
| | | export default DataSource |
| | |
| | | </Col> |
| | | <Col span={24} className="sqlfield"> |
| | | <Form.Item label={'可用字段'}> |
| | | id, bid, loginuid, sessionuid, userid, username, fullname, appkey, time_id, orderBy, pageSize, pageIndex{usefulFields ? ', ' + usefulFields : ''} |
| | | id, bid, loginuid, sessionuid, userid, username, fullname, login_city, appkey, time_id, orderBy, pageSize, pageIndex{usefulFields ? ', ' + usefulFields : ''} |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={10} style={{width: '43%'}}> |
| | |
| | | let _loading = false |
| | | if (this.scriptsForm && this.scriptsForm.state.editItem) { |
| | | _loading = true |
| | | } else if (this.scriptsForm && this.scriptsForm.props.form.getFieldValue('sql') && this.scriptsForm.props.form.getFieldValue('sql') !== ' ') { |
| | | } else if (this.scriptsForm && this.scriptsForm.props.form.getFieldValue('sql') && !/^\s+$/.test(this.scriptsForm.props.form.getFieldValue('sql'))) { |
| | | _loading = true |
| | | } |
| | | |
| | |
| | | let _loading = false |
| | | if (this.scriptsForm && this.scriptsForm.state.editItem) { |
| | | _loading = true |
| | | } else if (this.scriptsForm && this.scriptsForm.props.form.getFieldValue('sql') && this.scriptsForm.props.form.getFieldValue('sql') !== ' ') { |
| | | } else if (this.scriptsForm && this.scriptsForm.props.form.getFieldValue('sql') && !/^\s+$/.test(this.scriptsForm.props.form.getFieldValue('sql'))) { |
| | | _loading = true |
| | | } |
| | | |
| | |
| | | <FieldsComponent |
| | | config={{...config, columns}} |
| | | type="fields" |
| | | tableFields={menu.tableFields} |
| | | updatefield={this.updatefields} |
| | | /> |
| | | <EditTable actions={['edit', 'move', 'copy', 'del']} type="datasourcefield" data={columns} columns={colColumns} onChange={(columns) => this.setState({columns})}/> |
| | |
| | | |
| | | import { formRule } from '@/utils/option.js' |
| | | import Utils from '@/utils/utils.js' |
| | | import MenuUtils from '@/menu/utils/menuUtils.js' |
| | | import MenuUtils from '@/utils/utils-custom.js' |
| | | import CodeMirror from '@/templates/zshare/codemirror' |
| | | import './index.scss' |
| | | |
| | |
| | | {config.format === 'array' ? <Col span={8}> |
| | | <Form.Item label="默认排序"> |
| | | {getFieldDecorator('order', { |
| | | initialValue: setting.order || '', |
| | | initialValue: setting.order || 'ID desc', |
| | | rules: [ |
| | | { |
| | | required: true, |
| | |
| | | <Form.Item label={ |
| | | <Tooltip placement="topLeft" title={'优先使用同级的搜索条件组件,同级搜索不存在时,依次向上选取,与当前组件的搜索条件一同用作数据过滤(当前组件的搜索条件优先)。'}> |
| | | <Icon type="question-circle" /> |
| | | 外层搜索 |
| | | 外部搜索 |
| | | </Tooltip> |
| | | }> |
| | | {getFieldDecorator('useMSearch', { |
| | | initialValue: setting.useMSearch || 'false' |
| | | initialValue: setting.useMSearch || 'true' |
| | | })( |
| | | <Radio.Group onChange={(e) => this.setState({useMSearch: e.target.value})}> |
| | | <Radio value="true">使用</Radio> |
| | |
| | | .ant-input-number { |
| | | width: 100%; |
| | | } |
| | | .ant-radio-group { |
| | | white-space: nowrap; |
| | | } |
| | | } |
| | |
| | | _customScript = _customScript.replace(/@\$|\$@/ig, '') |
| | | |
| | | if (_customScript) { |
| | | _customScript = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@UserName nvarchar(50),@FullName nvarchar(50) select @ErrorCode='',@retmsg ='' |
| | | _customScript = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@UserName nvarchar(50),@FullName nvarchar(50),@login_city nvarchar(50) select @ErrorCode='',@retmsg ='' |
| | | ${_customScript} |
| | | ` |
| | | } |
| | |
| | | _dataresource = _dataresource.replace(/@db@/ig, window.GLOB.externalDatabase) |
| | | _customScript = _customScript.replace(/@db@/ig, window.GLOB.externalDatabase) |
| | | } |
| | | |
| | | if (window.GLOB.urlFields) { |
| | | window.GLOB.urlFields.forEach(field => { |
| | | let reg = new RegExp('@' + field + '@', 'ig') |
| | | _dataresource = _dataresource.replace(reg, '0') |
| | | _customScript = _customScript.replace(reg, '0') |
| | | }) |
| | | } |
| | | |
| | | |
| | | // 正则替换 |
| | | let _regoptions = [] |
| | |
| | | |
| | | if (_customScript) { |
| | | _regoptions.push({ |
| | | var: new RegExp('@orderBy', 'ig'), |
| | | reg: new RegExp('@login_city@', 'ig'), |
| | | }, { |
| | | reg: new RegExp('@orderBy@', 'ig'), |
| | | }) |
| | | _regoptions.push({ |
| | | var: new RegExp('@UserName', 'ig'), |
| | | }, { |
| | | reg: new RegExp('@UserName@', 'ig'), |
| | | }) |
| | | _regoptions.push({ |
| | | var: new RegExp('@FullName', 'ig'), |
| | | }, { |
| | | reg: new RegExp('@FullName@', 'ig'), |
| | | }) |
| | | if (setting.laypage !== 'false') { |
| | | _regoptions.push({ |
| | | var: new RegExp('@pageSize', 'ig'), |
| | | reg: new RegExp('@pageSize@', 'ig'), |
| | | }, { |
| | | var: new RegExp('@pageIndex', 'ig'), |
| | | reg: new RegExp('@pageIndex@', 'ig'), |
| | | }) |
| | | } |
| | | _regoptions.forEach(item => { |
| | | _customScript = _customScript.replace(item.reg, '0') |
| | | originscript = originscript.replace(item.reg, '0') |
| | | originscript = originscript.replace(item.var, '0') |
| | | }) |
| | | |
| | | if (setting.varMark) { |
| | |
| | | const AntvTabs = asyncComponent(() => import('@/menu/components/tabs/antv-tabs')) |
| | | const DataCard = asyncComponent(() => import('@/menu/components/card/data-card')) |
| | | const PropCard = asyncComponent(() => import('@/menu/components/card/prop-card')) |
| | | const CarouselDataCard = asyncComponent(() => import('@/menu/components/carousel/data-card')) |
| | | const CarouselPropCard = asyncComponent(() => import('@/menu/components/carousel/prop-card')) |
| | | const TableCard = asyncComponent(() => import('@/menu/components/card/table-card')) |
| | | const NormalTable = asyncComponent(() => import('@/menu/components/table/normal-table')) |
| | | const NormalForm = asyncComponent(() => import('@/menu/components/form/normal-form')) |
| | | const NormalGroup = asyncComponent(() => import('@/menu/components/group/normal-group')) |
| | | const BraftEditor = asyncComponent(() => import('@/menu/components/editor/braft-editor')) |
| | | const CodeSandbox = asyncComponent(() => import('@/menu/components/code/sandbox')) |
| | |
| | | return (<MainSearch card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) |
| | | } else if (card.type === 'pie') { |
| | | return (<AntvPie card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) |
| | | } else if (card.type === 'form') { |
| | | return (<NormalForm card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) |
| | | } else if (card.type === 'tabs') { |
| | | return (<AntvTabs tabs={card} updateConfig={updateConfig} deletecomponent={delCard}/>) |
| | | } else if (card.type === 'card' && card.subtype === 'datacard') { |
| | | return (<DataCard card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) |
| | | } else if (card.type === 'card' && card.subtype === 'propcard') { |
| | | return (<PropCard card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) |
| | | } else if (card.type === 'carousel' && card.subtype === 'datacard') { |
| | | return (<CarouselDataCard card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) |
| | | } else if (card.type === 'carousel' && card.subtype === 'propcard') { |
| | | return (<CarouselPropCard card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) |
| | | } else if (card.type === 'table' && card.subtype === 'tablecard') { |
| | | return (<TableCard card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) |
| | | } else if (card.type === 'table' && card.subtype === 'normaltable') { |
| | |
| | | import React, { useState } from 'react' |
| | | import { useDrop } from 'react-dnd' |
| | | import { is, fromJS } from 'immutable' |
| | | import update from 'immutability-helper' |
| | | import { Empty, notification, Modal } from 'antd' |
| | | |
| | | import Utils from '@/utils/utils.js' |
| | | import MKEmitter from '@/utils/events.js' |
| | | import MenuUtils from '@/menu/utils/menuUtils.js' |
| | | import MenuUtils from '@/utils/utils-custom.js' |
| | | import Card from './card' |
| | | import './index.scss' |
| | | |
| | |
| | | const { card, index } = findCard(id) |
| | | const _cards = update(cards, { $splice: [[index, 1], [atIndex, 0, card]] }) |
| | | handleList({...menu, components: _cards}) |
| | | } |
| | | |
| | | if (!is(fromJS(cards), fromJS(menu.components))) { |
| | | setCards(menu.components) |
| | | setCards(_cards) |
| | | } |
| | | |
| | | const findCard = id => { |
| | |
| | | } |
| | | |
| | | const updateConfig = (element) => { |
| | | handleList({...menu, components: cards.map(item => item.uuid === element.uuid ? element : item)}) |
| | | const _cards = cards.map(item => item.uuid === element.uuid ? element : item) |
| | | handleList({...menu, components: _cards}) |
| | | setCards(_cards) |
| | | } |
| | | |
| | | const deleteCard = (id) => { |
| | |
| | | title: `确定删除《${card.name}》吗?`, |
| | | content: hasComponent ? '当前组件中含有子组件!' : '', |
| | | onOk() { |
| | | const _cards = cards.filter(item => item.uuid !== card.uuid) |
| | | MKEmitter.emit('delButtons', uuids) |
| | | handleList({...menu, components: cards.filter(item => item.uuid !== card.uuid)}) |
| | | handleList({...menu, components: _cards}) |
| | | setCards(_cards) |
| | | }, |
| | | onCancel() {} |
| | | }) |
| | |
| | | group: '分组', |
| | | editor: '富文本', |
| | | code: '自定义', |
| | | carousel: '轮播', |
| | | form: '表单', |
| | | card: '卡片' |
| | | } |
| | | let i = 1 |
| | |
| | | const _cards = update(cards, { $splice: [[overIndex + 1, 0, newcard]] }) |
| | | |
| | | handleList({...menu, components: _cards}) |
| | | setCards(_cards) |
| | | } |
| | | }) |
| | | |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import {connect} from 'react-redux' |
| | | import { is, fromJS } from 'immutable' |
| | | import { DndProvider } from 'react-dnd' |
| | | import HTML5Backend from 'react-dnd-html5-backend' |
| | | import moment from 'moment' |
| | | import { Button, Card, Modal, Collapse, notification, Icon, Empty, Popover } from 'antd' |
| | | import { Button, Card, Modal, Collapse, notification, Icon, Switch } from 'antd' |
| | | |
| | | import Api from '@/api' |
| | | import Utils from '@/utils/utils.js' |
| | |
| | | import { getModalForm } from '@/templates/zshare/formconfig' |
| | | |
| | | import ModalForm from '@/templates/zshare/modalform' |
| | | import DragElement from '@/templates/modalconfig/dragelement' |
| | | import SourceElement from '@/templates/modalconfig/dragelement/source' |
| | | import SettingForm from '@/templates/modalconfig/settingform' |
| | | import GroupForm from '@/templates/modalconfig/groupform' |
| | | import EditCard from '@/templates/modalconfig/editcard' |
| | | import asyncComponent from '@/utils/asyncComponent' |
| | | import { SearchItems } from '@/templates/modalconfig/source' |
| | | import './index.scss' |
| | | |
| | | const { Panel } = Collapse |
| | | const { confirm } = Modal |
| | | const CommonDict = localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS |
| | | const CommonDict = sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS |
| | | const EditComponent = asyncComponent(() => import('@/templates/zshare/editcomponent')) |
| | | const DragElement = asyncComponent(() => import('@/templates/modalconfig/dragelement')) |
| | | const FieldsComponent = asyncComponent(() => import('@/templates/sharecomponent/fieldscomponent')) |
| | | |
| | | class ComModalConfig extends Component { |
| | | static propTpyes = { |
| | |
| | | } |
| | | |
| | | state = { |
| | | menu: null, // 上级菜单,三级菜单或标签 |
| | | dict: CommonDict, // 字典 |
| | | config: null, // 页面配置,包括模板类型、模态框设置、添加表名、表单列表 |
| | | visible: false, // 表单编辑模态框,显示控制 |
| | |
| | | tables: [], // 可用表名 |
| | | selectedTables: [], // 已选表名 |
| | | originConfig: null, // 原始菜单 |
| | | groupVisible: false, // 全局配置模态框 |
| | | curgroup: null, // 当前组,新建或编辑 |
| | | sources: null, // 表单类型 |
| | | sqlVerifing: false, // sql验证 |
| | | openEdition: '' // 编辑版本标记,防止多人操作 |
| | | openEdition: '', // 编辑版本标记,防止多人操作 |
| | | showField: false, // 显示表单字段值 |
| | | standardform: null |
| | | } |
| | | |
| | | /** |
| | |
| | | const { btn } = this.props |
| | | |
| | | let _config = btn.modal |
| | | _config.version = '1.0' |
| | | |
| | | this.setState({ |
| | | config: _config, |
| | | originConfig: fromJS(_config).toJS() |
| | | }) |
| | | } |
| | | |
| | | /** |
| | | * @description 获取数据表信息 |
| | | * 1、获取系统中全部表名 |
| | | * 2、根据已选表名,获取表格字段列表 |
| | | */ |
| | | componentDidMount () { |
| | | |
| | | } |
| | | |
| | | /** |
| | |
| | | * 2、表单移动后,保存移动后的顺序 |
| | | * 3、新增表单时,直接打开编辑框 |
| | | */ |
| | | handleList = (list, group, elementId, newcard) => { |
| | | handleList = (list, newcard) => { |
| | | let _config = fromJS(this.state.config).toJS() |
| | | |
| | | if (!group && !elementId) { |
| | | // 没有分组时(拖拽添加) |
| | | if (list.length > _config.fields.length) { |
| | | _config.fields = list.filter(item => !item.origin) |
| | | |
| | | this.setState({ |
| | | config: _config |
| | | }, () => { |
| | | this.handleForm(newcard) |
| | | }) |
| | | } else { |
| | | _config.fields = list |
| | | this.setState({config: _config}) |
| | | } |
| | | } else if (group && !elementId) { |
| | | // 存在分组时,拖拽添加 |
| | | if (list.length > group.sublist.length) { |
| | | group.sublist = list |
| | | _config.groups = _config.groups.map(item => { |
| | | if (item.uuid === group.uuid) { |
| | | return group |
| | | } else { |
| | | return item |
| | | } |
| | | }) |
| | | |
| | | this.setState({ |
| | | config: _config |
| | | }, () => { |
| | | this.handleForm(newcard) |
| | | }) |
| | | } else { |
| | | group.sublist = list |
| | | _config.groups = _config.groups.map(item => { |
| | | if (item.uuid === group.uuid) { |
| | | return group |
| | | } else { |
| | | return item |
| | | } |
| | | }) |
| | | this.setState({config: _config}) |
| | | } |
| | | } else if (group && elementId) { |
| | | // 修改已有元素的分组 |
| | | let element = null |
| | | _config.groups.forEach(item => { |
| | | item.sublist = item.sublist.filter(cell => { |
| | | if (cell.uuid !== elementId) { |
| | | return true |
| | | } else { |
| | | element = cell |
| | | return false |
| | | } |
| | | }) |
| | | }) |
| | | |
| | | group.sublist.push(element) |
| | | |
| | | _config.groups = _config.groups.map(item => { |
| | | if (item.uuid === group.uuid) { |
| | | return group |
| | | } else { |
| | | return item |
| | | } |
| | | }) |
| | | if (list.length > _config.fields.length) { |
| | | _config.fields = list.filter(item => !item.origin) |
| | | |
| | | this.setState({ |
| | | config: _config |
| | | }, () => { |
| | | this.handleForm(newcard) |
| | | }) |
| | | } else { |
| | | _config.fields = list |
| | | this.setState({config: _config}) |
| | | } |
| | | } |
| | | |
| | |
| | | value: '', |
| | | text: '空' |
| | | }] |
| | | let _formfields = [] |
| | | let standardform = null |
| | | |
| | | // 设置下拉菜单可关联字段(上级与下级) |
| | | if (config.groups.length > 0) { |
| | | config.groups.forEach(group => { |
| | | _formfields = [..._formfields, ...group.sublist] |
| | | }) |
| | | } else { |
| | | _formfields = config.fields |
| | | } |
| | | |
| | | _inputfields = _formfields.filter(item => item.type === 'text' || item.type === 'number' || item.type === 'textarea' || item.type === 'color') |
| | | _tabfields = _formfields.filter(item => card.field !== item.field && item.hidden !== 'true' && ['text', 'number', 'select', 'link'].includes(item.type)) |
| | | _inputfields = config.fields.filter(item => item.type === 'text' || item.type === 'number' || item.type === 'textarea' || item.type === 'color') |
| | | _tabfields = config.fields.filter(item => card.field !== item.field && item.hidden !== 'true' && ['text', 'number', 'select', 'link'].includes(item.type)) |
| | | _tabfields.unshift({field: '', text: '原表单'}) |
| | | |
| | | let uniq = new Map() |
| | | uniq.set(card.field, true) |
| | | _formfields.forEach(item => { |
| | | let index = null |
| | | config.fields.forEach((item, i) => { |
| | | if (card.uuid === item.uuid) { |
| | | index = i |
| | | } |
| | | if (item.type !== 'select' && item.type !== 'link' && item.type !== 'radio') return |
| | | if (item.field && !uniq.has(item.field)) { |
| | | uniq.set(item.field, true) |
| | |
| | | }) |
| | | } |
| | | }) |
| | | if (index !== null) { |
| | | if (index === 0) { |
| | | standardform = config.fields[index + 1] || null |
| | | } else { |
| | | standardform = config.fields[index - 1] || null |
| | | } |
| | | } |
| | | |
| | | componentConfig.columns.forEach(col => { |
| | | if (col.field && !uniq.has(col.field)) { |
| | |
| | | card.linkSubField = card.linkSubField.filter(item => fields.includes(item)) |
| | | } |
| | | |
| | | if (!card.span && standardform && standardform.span) { |
| | | card.span = standardform.span |
| | | card.labelwidth = standardform.labelwidth |
| | | } |
| | | |
| | | this.setState({ |
| | | standardform, |
| | | visible: true, |
| | | card: card, |
| | | formlist: getModalForm(card, _inputfields, _tabfields, _linkableFields, _linksupFields, !!this.props.editTab) |
| | |
| | | let fieldrepet = false // 字段重复 |
| | | let labelrepet = false // 提示文字重复 |
| | | |
| | | if (_config.groups.length > 0) { |
| | | _config.groups.forEach(group => { |
| | | group.sublist = group.sublist.map(item => { |
| | | if (item.uuid !== res.uuid && item.field.toLowerCase() === res.field.toLowerCase()) { |
| | | fieldrepet = true |
| | | } else if (item.uuid !== res.uuid && item.label === res.label) { |
| | | labelrepet = true |
| | | } |
| | | _config.fields = _config.fields.map(item => { |
| | | if (item.uuid !== res.uuid && res.field && item.field && item.field.toLowerCase() === res.field.toLowerCase()) { |
| | | fieldrepet = true |
| | | } else if (res.label && item.uuid !== res.uuid && item.label === res.label) { |
| | | labelrepet = true |
| | | } |
| | | |
| | | if (item.uuid === res.uuid) { |
| | | return res |
| | | } else { |
| | | return item |
| | | } |
| | | }) |
| | | }) |
| | | } else { |
| | | _config.fields = _config.fields.map(item => { |
| | | if (item.uuid !== res.uuid && item.field.toLowerCase() === res.field.toLowerCase()) { |
| | | fieldrepet = true |
| | | } else if (item.uuid !== res.uuid && item.label === res.label) { |
| | | labelrepet = true |
| | | } |
| | | |
| | | if (item.uuid === res.uuid) { |
| | | return res |
| | | } else { |
| | | return item |
| | | } |
| | | }) |
| | | } |
| | | if (item.uuid === res.uuid) { |
| | | return res |
| | | } else { |
| | | return item |
| | | } |
| | | }) |
| | | |
| | | if (fieldrepet) { |
| | | notification.warning({ |
| | |
| | | let _this = this |
| | | |
| | | confirm({ |
| | | content: `确定删除<<${card.label}>>吗?`, |
| | | content: `确定删除${card.label ? `<<${card.label}>>` : ''}吗?`, |
| | | onOk() { |
| | | let _config = fromJS(_this.state.config).toJS() |
| | | |
| | | if (_config.groups.length > 0) { |
| | | _config.groups.forEach(group => { |
| | | group.sublist = group.sublist.filter(item => !(item.uuid === card.uuid)) |
| | | }) |
| | | } else { |
| | | _config.fields = _config.fields.filter(item => !(item.uuid === card.uuid)) |
| | | } |
| | | _config.fields = _config.fields.filter(item => !(item.uuid === card.uuid)) |
| | | |
| | | _this.setState({ |
| | | config: _config, |
| | |
| | | } |
| | | |
| | | /** |
| | | * @description 通过表字段添加表单 |
| | | * 1、检查是否已选表名,为选时警告提示 |
| | | * 2、表字段名通过map去重 |
| | | * 3、检查表单中的已选字段,并标记已选 |
| | | */ |
| | | queryField = () => { |
| | | const { menu } = this.props |
| | | const { config } = this.state |
| | | |
| | | if (menu.tables.length === 0) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '请选择表名!', |
| | | duration: 10 |
| | | }) |
| | | return |
| | | } |
| | | |
| | | let columns = new Map() |
| | | menu.tableFields.forEach(table => { |
| | | table.columns.forEach(column => { |
| | | columns.set(column.field, column) |
| | | }) |
| | | }) |
| | | |
| | | if (config.groups.length > 1) { |
| | | config.groups.forEach(group => { |
| | | group.sublist.forEach(item => { |
| | | if (columns.has(item.field)) { |
| | | columns.set(item.field, {...item, selected: true}) |
| | | } |
| | | }) |
| | | }) |
| | | } else { |
| | | config.fields.forEach(item => { |
| | | if (columns.has(item.field)) { |
| | | columns.set(item.field, {...item, selected: true}) |
| | | } |
| | | }) |
| | | } |
| | | |
| | | this.setState({ |
| | | tableVisible: true, |
| | | fields: [...columns.values()] |
| | | }) |
| | | } |
| | | |
| | | /** |
| | | * @description 选择字段后提交 |
| | | * 1、没有可选字段时,直接关闭 |
| | | * 2、获取已选字段 |
| | | * 3、与已有字段对比 |
| | | * 4、添加新增字段 |
| | | */ |
| | | addFieldSubmit = () => { |
| | | if (!this.state.fields || this.state.fields.length === 0) { |
| | | this.setState({ |
| | | tableVisible: false |
| | | }) |
| | | } |
| | | |
| | | let _config = fromJS(this.state.config).toJS() |
| | | |
| | | let cards = this.refs.searchcard.state.selectCards |
| | | let columns = new Map() |
| | | cards.forEach(card => { |
| | | columns.set(card.field, card) |
| | | }) |
| | | |
| | | if (_config.groups.length > 1) { |
| | | _config.groups.forEach(group => { |
| | | let items = [] |
| | | group.sublist.forEach(item => { |
| | | if (columns.has(item.field)) { |
| | | let cell = columns.get(item.field) |
| | | |
| | | if (cell.selected && cell.type === item.type) { // 数据选择状态及类型未修改时,直接添加 |
| | | items.push(item) |
| | | } else if (cell.selected) { // 数据类型修改时,重置类型及初始值 |
| | | item.type = cell.type |
| | | item.initval = '' |
| | | items.push(item) |
| | | } |
| | | columns.delete(item.field) |
| | | } else if (!item.origin) { // 过滤示例项 |
| | | items.push(item) |
| | | } |
| | | }) |
| | | group.sublist = items |
| | | }) |
| | | |
| | | let _columns = [...columns.values()] |
| | | |
| | | let _additems = _columns.map(item => { // 循环添加新增字段 |
| | | return { |
| | | uuid: Utils.getuuid(), |
| | | label: item.label, |
| | | field: item.field, |
| | | initval: '', |
| | | type: item.type, |
| | | resourceType: '0', |
| | | setAll: 'false', |
| | | options: [], |
| | | orderType: 'asc', |
| | | decimal: 0, |
| | | min: '', |
| | | max: '', |
| | | readonly: 'false', |
| | | required: 'true' |
| | | } |
| | | }) |
| | | _config.groups[_config.groups.length - 1].sublist = [..._config.groups.slice(-1)[0].sublist, ..._additems] |
| | | |
| | | } else { |
| | | let items = [] |
| | | _config.fields.forEach(item => { |
| | | if (columns.has(item.field)) { |
| | | let cell = columns.get(item.field) |
| | | |
| | | if (cell.selected && cell.type === item.type) { // 数据选择状态及类型未修改时,直接添加 |
| | | items.push(item) |
| | | } else if (cell.selected) { // 数据类型修改时,重置类型及初始值 |
| | | item.type = cell.type |
| | | item.initval = '' |
| | | items.push(item) |
| | | } |
| | | columns.delete(item.field) |
| | | } else if (!item.origin) { // 过滤示例项 |
| | | items.push(item) |
| | | } |
| | | }) |
| | | |
| | | let _columns = [...columns.values()] |
| | | |
| | | _columns.forEach(item => { // 循环添加新增字段 |
| | | if (item.selected) { |
| | | let newcard = { |
| | | uuid: Utils.getuuid(), |
| | | label: item.label, |
| | | field: item.field, |
| | | initval: '', |
| | | type: item.type, |
| | | resourceType: '0', |
| | | setAll: 'false', |
| | | options: [], |
| | | orderType: 'asc', |
| | | readonly: 'false', |
| | | required: 'true' |
| | | } |
| | | |
| | | items.push(newcard) |
| | | } |
| | | }) |
| | | |
| | | _config.fields = items |
| | | } |
| | | |
| | | this.setState({ |
| | | config: _config |
| | | }) |
| | | notification.success({ |
| | | top: 92, |
| | | message: '添加成功', |
| | | duration: 2 |
| | | }) |
| | | } |
| | | |
| | | /** |
| | | * @description 全局设置模态框 |
| | | */ |
| | | changeSetting = () => { |
| | |
| | | }) |
| | | } |
| | | |
| | | handleGroup = (group) => { |
| | | let curgroup = '' |
| | | |
| | | if (group) { |
| | | curgroup = group |
| | | } else { |
| | | curgroup = { |
| | | isnew: true, |
| | | label: '', |
| | | default: false, |
| | | uuid: Utils.getuuid(), |
| | | sublist: [] |
| | | } |
| | | } |
| | | |
| | | this.setState({ |
| | | groupVisible: true, |
| | | curgroup: curgroup |
| | | }) |
| | | } |
| | | |
| | | closeGroup = (group) => { |
| | | let _this = this |
| | | |
| | | confirm({ |
| | | content: `确定删除分组<<${group.label}>>吗?`, |
| | | onOk() { |
| | | let _config = fromJS(_this.state.config).toJS() |
| | | _config.groups = _config.groups.filter(item => !(item.uuid === group.uuid)) |
| | | let _length = _config.groups.length |
| | | |
| | | if (_length === 1) { |
| | | _config.fields = [...group.sublist, ..._config.groups[0].sublist] |
| | | _config.groups = [] |
| | | } else { |
| | | _config.groups[_length - 1].sublist = [...group.sublist, ..._config.groups[_length - 1].sublist] |
| | | } |
| | | |
| | | _this.setState({ |
| | | config: _config |
| | | }) |
| | | }, |
| | | onCancel() {} |
| | | }) |
| | | } |
| | | |
| | | handleGroupSave = () => { |
| | | let _group = fromJS(this.state.curgroup).toJS() |
| | | let config = fromJS(this.state.config).toJS() |
| | | |
| | | this.groupRef.handleConfirm().then(res => { |
| | | _group = {..._group, ...res.target} |
| | | |
| | | if (_group.isnew) { |
| | | delete _group.isnew |
| | | config.groups.unshift(_group) |
| | | |
| | | if (config.groups.length > 1) { |
| | | config.groups = config.groups.map(item => { |
| | | if (item.default) { |
| | | return res.default |
| | | } else { |
| | | return item |
| | | } |
| | | }) |
| | | } else { |
| | | config.groups.push(res.default) |
| | | } |
| | | } else { |
| | | config.groups = config.groups.map(item => { |
| | | if (item.uuid === _group.uuid) { |
| | | return _group |
| | | } else if (item.default) { |
| | | return res.default |
| | | } else { |
| | | return item |
| | | } |
| | | }) |
| | | } |
| | | |
| | | config.fields = [] |
| | | |
| | | config.groups = config.groups.sort((a, b) => { |
| | | return a.sort - b.sort |
| | | }) |
| | | |
| | | this.setState({ |
| | | groupVisible: false, |
| | | curgroup: '', |
| | | config: config |
| | | }) |
| | | }) |
| | | } |
| | | |
| | | editModalCancel = () => { |
| | | const { config, card } = this.state |
| | | |
| | | if (card.focus) { |
| | | let _config = null |
| | | if (config.groups.length > 0) { |
| | | let _groups = config.groups.map(group => { |
| | | group.sublist = group.sublist.filter(item => item.uuid !== card.uuid) |
| | | return group |
| | | }) |
| | | _config = {...config, groups: _groups} |
| | | } else { |
| | | let _fields = config.fields.filter(item => item.uuid !== card.uuid) |
| | | _config = {...config, fields: _fields} |
| | | } |
| | | let _fields = config.fields.filter(item => item.uuid !== card.uuid) |
| | | let _config = {...config, fields: _fields} |
| | | |
| | | this.setState({ |
| | | card: null, |
| | |
| | | } |
| | | |
| | | /** |
| | | * @description 编辑功能完成更新,包括解冻按钮、粘贴、替换等 |
| | | * @description 更新 |
| | | */ |
| | | updateConfig = (res) => { |
| | | if (res.type === 'paste') { |
| | | this.setState({ |
| | | config: res.config |
| | | }) |
| | | } |
| | | updateConfig = (config) => { |
| | | this.setState({ |
| | | config |
| | | }) |
| | | } |
| | | |
| | | changecols = (type) => { |
| | | let config = fromJS(this.state.config).toJS() |
| | | let _this = this |
| | | |
| | | config.fields = config.fields.map(item => { |
| | | item.labelwidth = 33.3 |
| | | item.span = 24 |
| | | if (['textarea','split','hint','checkcard','brafteditor'].includes(item.type)) { |
| | | if (type === 2) { |
| | | item.labelwidth = 16.3 |
| | | } else if (type === 3) { |
| | | item.labelwidth = 10.5 |
| | | } else if (type === 4) { |
| | | item.labelwidth = 8.3 |
| | | } |
| | | } else if (type === 2) { |
| | | item.span = 12 |
| | | } else if (type === 3) { |
| | | item.span = 8 |
| | | } else if (type === 4) { |
| | | item.span = 6 |
| | | } |
| | | return item |
| | | }) |
| | | |
| | | confirm({ |
| | | content: `确定切换为${type}列吗?`, |
| | | onOk() { |
| | | _this.setState({config}) |
| | | }, |
| | | onCancel() {} |
| | | }) |
| | | } |
| | | |
| | | render () { |
| | | const { config } = this.state |
| | | const { config, dict } = this.state |
| | | |
| | | return ( |
| | | <div className="modal-form-board"> |
| | | <DndProvider backend={HTML5Backend}> |
| | | <div className="tools"> |
| | | <Collapse accordion defaultActiveKey="1" bordered={false}> |
| | | <Panel header={this.state.dict['header.menu.form']} key="1"> |
| | | <Panel header={dict['header.menu.form']} key="1"> |
| | | <div className="search-element"> |
| | | {SearchItems.map((item, index) => { |
| | | return (<SourceElement key={index} content={item}/>) |
| | | })} |
| | | </div> |
| | | <Button type="primary" block onClick={() => this.queryField()}>{this.state.dict['model.batchAdd']}</Button> |
| | | <Button type="primary" block onClick={() => this.handleGroup()}>{this.state.dict['header.menu.group.add']}</Button> |
| | | <FieldsComponent |
| | | config={config} |
| | | type="form" |
| | | updatefield={this.updateConfig} |
| | | /> |
| | | </Panel> |
| | | </Collapse> |
| | | </div> |
| | | <div className="setting"> |
| | | <Card title={this.state.dict['header.menu.form.configurable']} bordered={false} extra={ |
| | | <Card title={dict['header.menu.form.configurable']} bordered={false} extra={ |
| | | <div> |
| | | <EditComponent dict={this.state.dict} options={['form']} config={this.state.config} refresh={this.updateConfig}/> |
| | | <Button type="primary" onClick={this.submitConfig}>{this.state.dict['model.confirm']}</Button> |
| | | <Button onClick={this.cancelConfig}>{this.state.dict['model.cancel']}</Button> |
| | | <EditComponent dict={dict} options={['form']} config={this.state.config} refresh={(res) => this.updateConfig(res.config)}/> |
| | | <Button type="primary" onClick={this.submitConfig}>{dict['model.confirm']}</Button> |
| | | <Button onClick={this.cancelConfig}>{dict['model.cancel']}</Button> |
| | | </div> |
| | | } style={{ width: '100%' }}> |
| | | <Icon type="setting" onClick={this.changeSetting} /> |
| | | <div className="ant-modal-content" style={{width: config.setting.width + '%'}}> |
| | | <button type="button" className="ant-modal-close"> |
| | | <span className="ant-modal-close-x"><Icon type="close"/></span> |
| | | </button> |
| | | <div className="ant-modal-header"> |
| | | <div className="ant-modal-title">{config.setting.title}</div> |
| | | <Button className="mk-cols-change" onClick={() => this.changecols(1)}>1列</Button> |
| | | <Button className="mk-cols-change" onClick={() => this.changecols(2)}>2列</Button> |
| | | <Button className="mk-cols-change" onClick={() => this.changecols(3)}>3列</Button> |
| | | <Button className="mk-cols-change" onClick={() => this.changecols(4)}>4列</Button> |
| | | <Switch checkedChildren={dict['model.switch.open']} unCheckedChildren={dict['model.switch.close']} defaultChecked={this.state.showField} onChange={(val) => this.setState({showField: val})} /> |
| | | </div> |
| | | <div className="ant-modal-body"> |
| | | <div className="modal-form"> |
| | | {config.groups.length > 0 && |
| | | config.groups.map(group => { |
| | | return ( |
| | | <div key={group.uuid}> |
| | | <div className="group-title"> |
| | | {!group.default ? <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={ |
| | | <div className="mk-popover-control"> |
| | | <Icon className="edit" type="edit" onClick={() => {this.handleGroup(group)}} /> |
| | | <Icon className="edit close" type="close" onClick={() => {this.closeGroup(group)}} /> |
| | | </div> |
| | | } trigger="hover"> |
| | | <span>{group.label}</span> |
| | | </Popover> : null} |
| | | {group.default ? <span style={{color: '#bcbcbc'}}>{group.label}</span> : null} |
| | | </div> |
| | | <DragElement |
| | | group={group} |
| | | list={group.sublist} |
| | | setting={config.setting} |
| | | placeholder={this.state.dict['header.form.modal.placeholder']} |
| | | handleList={this.handleList} |
| | | handleForm={this.handleForm} |
| | | closeForm={this.closeForm} |
| | | /> |
| | | </div> |
| | | ) |
| | | }) |
| | | } |
| | | {config.groups.length === 0 ? |
| | | <DragElement |
| | | list={config.fields} |
| | | setting={config.setting} |
| | | placeholder={this.state.dict['header.form.modal.placeholder']} |
| | | handleList={this.handleList} |
| | | handleForm={this.handleForm} |
| | | closeForm={this.closeForm} |
| | | /> : null |
| | | } |
| | | <DragElement |
| | | list={config.fields} |
| | | setting={config.setting} |
| | | showField={this.state.showField} |
| | | placeholder={this.state.dict['header.form.modal.placeholder']} |
| | | handleList={this.handleList} |
| | | handleForm={this.handleForm} |
| | | closeForm={this.closeForm} |
| | | /> |
| | | </div> |
| | | </div> |
| | | <div className="ant-modal-footer"> |
| | |
| | | card={this.state.card} |
| | | formlist={this.state.formlist} |
| | | inputSubmit={this.handleSubmit} |
| | | standardform={this.state.standardform} |
| | | wrappedComponentRef={(inst) => this.formRef = inst} |
| | | /> |
| | | </Modal> |
| | | <Modal |
| | | wrapClassName="modal-fields" |
| | | title={this.state.dict['model.edit']} |
| | | visible={this.state.tableVisible} |
| | | width={'65vw'} |
| | | maskClosable={false} |
| | | style={{minWidth: '900px', maxWidth: '1200px'}} |
| | | onOk={this.addFieldSubmit} |
| | | cancelText={this.state.dict['model.close']} |
| | | onCancel={() => { this.setState({ tableVisible: false }) }} |
| | | destroyOnClose |
| | | > |
| | | {this.state.fields && this.state.fields.length > 0 ? |
| | | <EditCard data={this.state.fields} ref="searchcard" type="search" /> : null |
| | | } |
| | | {(!this.state.fields || this.state.fields.length === 0) && |
| | | <Empty /> |
| | | } |
| | | </Modal> |
| | | <Modal |
| | | title={this.state.dict['model.edit']} |
| | |
| | | > |
| | | {this.state.dict['header.menu.config.placeholder']} |
| | | </Modal> |
| | | <Modal |
| | | title={this.state.dict['header.menu.group.manage']} |
| | | visible={this.state.groupVisible} |
| | | width={700} |
| | | maskClosable={false} |
| | | onOk={this.handleGroupSave} |
| | | onCancel={() => { this.setState({ groupVisible: false }) }} |
| | | destroyOnClose |
| | | > |
| | | <GroupForm |
| | | config={config} |
| | | dict={this.state.dict} |
| | | group={this.state.curgroup} |
| | | inputSubmit={this.handleGroupSave} |
| | | wrappedComponentRef={(inst) => this.groupRef = inst} |
| | | /> |
| | | </Modal> |
| | | </div> |
| | | ) |
| | | } |
| | | } |
| | | |
| | | const mapStateToProps = (state) => { |
| | | return { |
| | | menu: state.customMenu |
| | | } |
| | | } |
| | | |
| | | const mapDispatchToProps = () => { |
| | | return {} |
| | | } |
| | | |
| | | export default connect(mapStateToProps, mapDispatchToProps)(ComModalConfig) |
| | | export default ComModalConfig |
| | |
| | | z-index: 10; |
| | | background: transparent; |
| | | min-height: 50px; |
| | | padding-right: 75px; |
| | | .ant-modal-title { |
| | | display: inline-block; |
| | | } |
| | | .ant-switch { |
| | | position: absolute; |
| | | top: 15px; |
| | | right: 10px; |
| | | } |
| | | .mk-cols-change { |
| | | float: right; |
| | | height: 25px; |
| | | margin-right: 10px; |
| | | } |
| | | } |
| | | .ant-modal-close { |
| | | opacity: 0.3; |
| | |
| | | width: 100%; |
| | | margin-top: 4px; |
| | | } |
| | | .normal-braft-editor { |
| | | border: 1px solid #d9d9d9; |
| | | border-radius: 4px; |
| | | } |
| | | } |
| | | .ant-form-item-control-wrapper::after { |
| | | content: ''; |
| | |
| | | import Pie1 from '@/assets/mobimg/ring.png' |
| | | import Pie2 from '@/assets/mobimg/nightingale.png' |
| | | import Mainsearch from '@/assets/mobimg/mainsearch.png' |
| | | import Carousel from '@/assets/mobimg/carousel.png' |
| | | import Carousel1 from '@/assets/mobimg/carousel1.png' |
| | | import form from '@/assets/mobimg/form.png' |
| | | |
| | | // 组件配置信息 |
| | | export const menuOptions = [ |
| | |
| | | { type: 'menu', url: Mainsearch, component: 'search', subtype: 'mainsearch', title: '搜索条件', width: 24, forbid: ['billPrint'] }, |
| | | { type: 'menu', url: card1, component: 'card', subtype: 'datacard', title: '数据卡', width: 24 }, |
| | | { type: 'menu', url: card2, component: 'card', subtype: 'propcard', title: '属性卡', width: 24 }, |
| | | { type: 'menu', url: form, component: 'form', subtype: 'stepform', title: '表单', width: 24 }, |
| | | { type: 'menu', url: Carousel, component: 'carousel', subtype: 'datacard', title: '轮播-动态数据', width: 24, forbid: ['billPrint'] }, |
| | | { type: 'menu', url: Carousel1, component: 'carousel', subtype: 'propcard', title: '轮播-静态数据', width: 24, forbid: ['billPrint'] }, |
| | | { type: 'menu', url: NormalTable, component: 'table', subtype: 'normaltable', title: '常用表', width: 24 }, |
| | | { type: 'menu', url: TableCard, component: 'table', subtype: 'tablecard', title: '表格', width: 12 }, |
| | | { type: 'menu', url: line, component: 'line', subtype: 'line', title: '折线图', width: 24 }, |
| | |
| | | } |
| | | |
| | | state = { |
| | | dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | paddingTop: '', |
| | | paddingBottom: '', |
| | | paddingLeft: '', |
| | |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } else if (values.urls && values.urls[0]) { |
| | | } else if (values.urls && values.urls[0] && values.urls[0].status !== 'done') { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '文件上传中,请稍后!', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } else if (values.urls && values.urls[0] && values.urls[0].response) { |
| | | values.linkurl = values.urls[0].response |
| | | } else { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '未获取到文件路径!', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } |
| | | resolve(values) |
| | | } else { |
| | |
| | | <Col span={24}> |
| | | <Form.Item label="备注"> |
| | | {getFieldDecorator('remark', { |
| | | initialValue: card.remark, |
| | | initialValue: card.remark || '', |
| | | rules: [ |
| | | { |
| | | max: 50, |
| | |
| | | </Col> |
| | | </Row> |
| | | <Row gutter={16} style={{height: '340px'}}> |
| | | {piclist.length && piclist.map(item => ( |
| | | {piclist.length > 0 && piclist.map(item => ( |
| | | <Col span={4} key={item.id}> |
| | | <div className="image-video-box"> |
| | | <div className="image-video-box-body"> |
| | |
| | | </Col> |
| | | </Row> |
| | | <Row gutter={16} style={{height: '340px'}}> |
| | | {vidlist.length && vidlist.map(item => ( |
| | | {vidlist.length > 0 && vidlist.map(item => ( |
| | | <Col span={4} key={item.id}> |
| | | <div className="image-video-box"> |
| | | <div className="image-video-box-body"> |
| | |
| | | import React, { Component } from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { connect } from 'react-redux' |
| | | import { DndProvider } from 'react-dnd' |
| | | import { is, fromJS } from 'immutable' |
| | | import moment from 'moment' |
| | |
| | | import enUS from '@/locales/en-US/mob.js' |
| | | import MKEmitter from '@/utils/events.js' |
| | | import asyncComponent from '@/utils/asyncComponent' |
| | | import { modifyCustomMenu } from '@/store/action' |
| | | |
| | | import './index.scss' |
| | | |
| | |
| | | } |
| | | |
| | | state = { |
| | | dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | MenuType: '', |
| | | MenuId: '', |
| | | MenuNo: '', |
| | | tableFields: [], |
| | | delButtons: [], |
| | | activeKey: 'basedata', |
| | | menuloading: false, |
| | | oriConfig: null, |
| | | openEdition: '', |
| | | config: null, |
| | | customComponents: [] |
| | | } |
| | |
| | | return |
| | | } |
| | | |
| | | let _config = fromJS(config).toJS() |
| | | delete _config.tableFields |
| | | const _this = this |
| | | |
| | | if (!is(fromJS(oriConfig), fromJS(_config))) { |
| | | if (!is(fromJS(oriConfig), fromJS(config))) { |
| | | confirm({ |
| | | title: '配置已修改,放弃保存吗?', |
| | | content: '', |
| | |
| | | config.Template = 'CustomPage' |
| | | } |
| | | |
| | | config.open_edition = result.open_edition || '' |
| | | |
| | | this.setState({ |
| | | oriConfig: config, |
| | | config: fromJS(config).toJS(), |
| | | openEdition: result.open_edition || '', |
| | | config: fromJS(config).toJS() |
| | | }) |
| | | |
| | | this.props.modifyCustomMenu(config) |
| | | window.GLOB.customMenu = config |
| | | } else { |
| | | notification.warning({ |
| | | top: 92, |
| | |
| | | |
| | | submitConfig = () => { |
| | | const { btn } = this.props |
| | | const { openEdition, delButtons } = this.state |
| | | const { delButtons } = this.state |
| | | let config = fromJS(this.state.config).toJS() |
| | | |
| | | if ((config.cacheUseful === 'true' && !config.cacheTime) || !config.MenuNo || !config.MenuName) { |
| | |
| | | config.enabled = false |
| | | } |
| | | |
| | | let _config = fromJS(config).toJS() |
| | | delete _config.tableFields |
| | | |
| | | let _name = (btn.component.name ? btn.component.name + '-' : '') + btn.label |
| | | |
| | | let param = { |
| | | func: 'sPC_ButtonParam_AddUpt', |
| | | ParentID: btn.config.uuid, |
| | | MenuID: _config.uuid, |
| | | MenuNo: _config.MenuNo || '', |
| | | MenuID: config.uuid, |
| | | MenuNo: config.MenuNo || '', |
| | | Template: 'CustomPage', |
| | | MenuName: _name, |
| | | PageParam: JSON.stringify({Template: 'CustomPage'}), |
| | | LongParam: window.btoa(window.encodeURIComponent(JSON.stringify(_config))) |
| | | } |
| | | |
| | | if (openEdition) { // 版本管理 |
| | | param.open_edition = openEdition |
| | | LongParam: window.btoa(window.encodeURIComponent(JSON.stringify(config))), |
| | | open_edition: config.open_edition |
| | | } |
| | | |
| | | let btnParam = { // 添加菜单按钮 |
| | | func: 'sPC_Button_AddUpt', |
| | | Type: 60, // 添加菜单下的按钮type为40,按钮下的按钮type为60 |
| | | ParentID: _config.uuid, |
| | | MenuNo: _config.MenuNo, |
| | | ParentID: config.uuid, |
| | | MenuNo: config.MenuNo, |
| | | Template: 'CustomPage', |
| | | PageParam: '', |
| | | LongParam: '', |
| | |
| | | if (!res) return |
| | | |
| | | if (res.status) { |
| | | config.open_edition = res.open_edition || '' |
| | | |
| | | this.setState({ |
| | | oriConfig: fromJS(_config).toJS(), |
| | | openEdition: res.open_edition || '' |
| | | oriConfig: fromJS(config).toJS() |
| | | }) |
| | | |
| | | if (btnParam.LText) { |
| | |
| | | config: config |
| | | }) |
| | | |
| | | this.props.modifyCustomMenu(config) |
| | | window.GLOB.customMenu = config |
| | | } |
| | | |
| | | /** |
| | | * @description 更新常用表信息,快捷添加后更新配置信息 |
| | | */ |
| | | updatetable = (config, fields) => { |
| | | const { tableFields } = this.state |
| | | updatetable = (config) => { |
| | | this.setState({ config }) |
| | | |
| | | config.tableFields = fields ? fields : tableFields |
| | | |
| | | this.setState({ |
| | | tableFields: fields ? fields : tableFields, |
| | | config |
| | | }) |
| | | |
| | | this.props.modifyCustomMenu(config) |
| | | window.GLOB.customMenu = config |
| | | } |
| | | |
| | | insert = (item) => { |
| | |
| | | config.components.push(item) |
| | | |
| | | this.setState({config}) |
| | | this.props.modifyCustomMenu(config) |
| | | window.GLOB.customMenu = config |
| | | } |
| | | |
| | | render () { |
| | |
| | | } |
| | | } |
| | | |
| | | const mapStateToProps = () => { |
| | | return {} |
| | | } |
| | | |
| | | const mapDispatchToProps = (dispatch) => { |
| | | return { |
| | | modifyCustomMenu: (customMenu) => dispatch(modifyCustomMenu(customMenu)) |
| | | } |
| | | } |
| | | |
| | | export default connect(mapStateToProps, mapDispatchToProps)(MenuDesign) |
| | | export default MenuDesign |
| | |
| | | } |
| | | |
| | | state = { |
| | | dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | options: [], |
| | | style: {}, |
| | | borposition: 'outer' |
| | |
| | | label={<Icon title="高度" type="column-height" />} |
| | | labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} } |
| | | > |
| | | <StyleInput defaultValue={''} options={['px']} onChange={this.changeHeight}/> |
| | | <StyleInput defaultValue={''} options={['px', 'vh', 'vw']} onChange={this.changeHeight}/> |
| | | </Form.Item> |
| | | </Col> |
| | | </Panel> : null} |
| | |
| | | } |
| | | |
| | | state = { |
| | | dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | card: null, |
| | | comIds: [], |
| | | backgroundImage: '', |
| | |
| | | this.updateStyle(_style) |
| | | } |
| | | |
| | | changeWidth = (val) => { |
| | | let _val = val |
| | | if (_val === '0px') { |
| | | _val = 'auto' |
| | | } |
| | | |
| | | this.updateStyle({width: _val}) |
| | | } |
| | | |
| | | changeHeight = (val) => { |
| | | let _val = val |
| | | if (_val === '0px') { |
| | |
| | | <div className="menu-style-controller"> |
| | | <Form {...formItemLayout}> |
| | | {card ? <Collapse expandIconPosition="right" destroyInactivePanel={true} defaultActiveKey={options[0]}> |
| | | {options.includes('width') ? <Panel header="宽度" key="width"> |
| | | <Col span={24}> |
| | | <Form.Item |
| | | colon={false} |
| | | label={<Icon title="宽度" type="column-width" />} |
| | | labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} } |
| | | > |
| | | <StyleInput defaultValue={card.width || ''} options={['px', 'vh', 'vw']} onChange={this.changeWidth}/> |
| | | </Form.Item> |
| | | </Col> |
| | | </Panel> : null} |
| | | {options.includes('height') ? <Panel header="高度" key="height"> |
| | | <Col span={24}> |
| | | <Form.Item |
| | |
| | | label={<Icon title="高度" type="column-height" />} |
| | | labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} } |
| | | > |
| | | <StyleInput defaultValue={card.height || ''} options={['px']} onChange={this.changeHeight}/> |
| | | <StyleInput defaultValue={card.height || ''} options={['px', 'vh', 'vw']} onChange={this.changeHeight}/> |
| | | </Form.Item> |
| | | </Col> |
| | | </Panel> : null} |
| | |
| | | } |
| | | } |
| | | |
| | | let _val = parseInt(val) |
| | | let _val = parseFloat(val) |
| | | |
| | | if (isNaN(_val)) { |
| | | _val = '' |
| | |
| | | } |
| | | } |
| | | |
| | | let _val = parseInt(val) |
| | | let _val = parseFloat(val) |
| | | |
| | | if (isNaN(_val)) { |
| | | _val = '' |
| | |
| | | changeValue = (e) => { |
| | | const { unit } = this.state |
| | | let val = e.target.value |
| | | let _val = parseInt(val) |
| | | |
| | | if (/\d+\.$/.test(val)) { |
| | | this.setState({ |
| | | value: val |
| | | }) |
| | | return |
| | | } |
| | | let _val = parseFloat(val) |
| | | |
| | | if (isNaN(_val)) { |
| | | _val = '' |
| | |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={12}> |
| | | <Form.Item label={ |
| | | <Tooltip placement="topLeft" title={'如果自定义接口不支持跨域请求,会通过当前系统转发。'}> |
| | | <Icon type="question-circle" /> |
| | | 跨域请求 |
| | | </Tooltip> |
| | | }> |
| | | {getFieldDecorator('cross', { |
| | | initialValue: setting.cross || 'true' |
| | | })( |
| | | <Radio.Group> |
| | | <Radio value="true">支持</Radio> |
| | | <Radio value="false">不支持</Radio> |
| | | </Radio.Group>)} |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={12}> |
| | | <Form.Item label="回调方式"> |
| | | {getFieldDecorator('callbackType', { |
| | | initialValue: setting.callbackType || 'script' |
| | |
| | | } |
| | | |
| | | state = { |
| | | dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | formlist: [], |
| | | btnloading: false, |
| | | activeKey: 'setting', |
| | |
| | | const { activeKey, setting, preScripts, cbScripts } = this.state |
| | | |
| | | let _loading = false |
| | | if (this.preScriptsForm && this.preScriptsForm.props.form.getFieldValue('sql')) { |
| | | if (this.preScriptsForm && this.preScriptsForm.props.form.getFieldValue('sql') && !/^\s+$/.test(this.preScriptsForm.props.form.getFieldValue('sql'))) { |
| | | _loading = true |
| | | } else if (this.cbScriptsForm && this.cbScriptsForm.props.form.getFieldValue('sql')) { |
| | | } else if (this.cbScriptsForm && this.cbScriptsForm.props.form.getFieldValue('sql') && !/^\s+$/.test(this.cbScriptsForm.props.form.getFieldValue('sql'))) { |
| | | _loading = true |
| | | } |
| | | |
| | |
| | | const { activeKey } = this.state |
| | | |
| | | let _loading = false |
| | | if (this.preScriptsForm && this.preScriptsForm.props.form.getFieldValue('sql')) { |
| | | if (this.preScriptsForm && this.preScriptsForm.props.form.getFieldValue('sql') && !/^\s+$/.test(this.preScriptsForm.props.form.getFieldValue('sql'))) { |
| | | _loading = true |
| | | } else if (this.cbScriptsForm && this.cbScriptsForm.props.form.getFieldValue('sql')) { |
| | | } else if (this.cbScriptsForm && this.cbScriptsForm.props.form.getFieldValue('sql') && !/^\s+$/.test(this.cbScriptsForm.props.form.getFieldValue('sql'))) { |
| | | _loading = true |
| | | } |
| | | |
| | |
| | | </Col> |
| | | <Col span={24} className="sqlfield"> |
| | | <Form.Item label={'可用字段'}> |
| | | bid, loginuid, sessionuid, userid, username, fullname, appkey, time_id |
| | | bid, loginuid, sessionuid, userid, username, fullname, login_city, appkey, time_id |
| | | </Form.Item> |
| | | </Col> |
| | | {type === 'back' ? <Col span={8} style={{whiteSpace: 'nowrap'}}> |
| | |
| | | }) |
| | | |
| | | if (_customScript) { |
| | | _customScript = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@UserName nvarchar(50),@FullName nvarchar(50) select @ErrorCode='',@retmsg ='' |
| | | _customScript = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@UserName nvarchar(50),@FullName nvarchar(50),@login_city nvarchar(50) select @ErrorCode='',@retmsg ='' |
| | | ${_customScript} |
| | | ` |
| | | } |
| | | |
| | | _customScript = _customScript.replace(/@\$|\$@/ig, '') |
| | | _customScript = _customScript.replace(/@userName@|@fullName@/ig, `''`) |
| | | _customScript = _customScript.replace(/@userName@|@fullName@|@login_city@/ig, `''`) |
| | | // 外联数据库替换 |
| | | if (window.GLOB.externalDatabase !== null) { |
| | | _customScript = _customScript.replace(/@db@/ig, window.GLOB.externalDatabase) |
New file |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { is, fromJS } from 'immutable' |
| | | import { Icon, Modal, Tooltip, notification } from 'antd' |
| | | |
| | | import SettingForm from './settingform' |
| | | import './index.scss' |
| | | |
| | | const { confirm } = Modal |
| | | |
| | | class UrlFieldComponent extends Component { |
| | | static propTpyes = { |
| | | config: PropTypes.any, |
| | | updateConfig: PropTypes.func |
| | | } |
| | | |
| | | state = { |
| | | visible: false, |
| | | urlFields: this.props.config.urlFields || [] |
| | | } |
| | | |
| | | shouldComponentUpdate (nextProps, nextState) { |
| | | return !is(fromJS(this.state), fromJS(nextState)) |
| | | } |
| | | |
| | | editDataSource = () => { |
| | | this.setState({ |
| | | visible: true |
| | | }) |
| | | } |
| | | |
| | | verifySubmit = () => { |
| | | const { urlFields } = this.state |
| | | const { config } = this.props |
| | | |
| | | this.verifyRef.handleConfirm().then(res => { |
| | | if (urlFields.filter(field => field === res.field).length > 0) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '字段已存在!', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } |
| | | |
| | | let _urlFields = [...urlFields, res.field] |
| | | |
| | | this.setState({ |
| | | visible: false, |
| | | urlFields: _urlFields |
| | | }) |
| | | |
| | | if (window.GLOB.urlFields) { |
| | | window.GLOB.urlFields = _urlFields |
| | | } |
| | | |
| | | this.props.updateConfig({...config, urlFields: _urlFields}) |
| | | }) |
| | | } |
| | | |
| | | deleteField = (field) => { |
| | | let config = JSON.stringify(this.props.config) |
| | | const _this = this |
| | | |
| | | if (new RegExp(field, 'ig').test(config)) { |
| | | confirm({ |
| | | title: `配置中存在@${field}@,确定删除吗?`, |
| | | content: '', |
| | | onOk() { |
| | | _this.execDelete(field) |
| | | }, |
| | | onCancel() {} |
| | | }) |
| | | } else { |
| | | this.execDelete(field) |
| | | } |
| | | } |
| | | |
| | | execDelete = (_field) => { |
| | | const { config } = this.props |
| | | let _urlFields = this.state.urlFields.filter(field => field !== _field) |
| | | |
| | | this.setState({ |
| | | urlFields: _urlFields |
| | | }) |
| | | |
| | | if (window.GLOB.urlFields) { |
| | | window.GLOB.urlFields = _urlFields |
| | | } |
| | | |
| | | this.props.updateConfig({...config, urlFields: _urlFields}) |
| | | } |
| | | |
| | | render () { |
| | | const { visible, urlFields } = this.state |
| | | |
| | | return ( |
| | | <div className="url-field-component"> |
| | | <div className="field-plus"> |
| | | <Tooltip placement="topLeft" title="页面可接收的参数字段,在查询数据源或自定义脚本中使用 @字段@ 接收。"> |
| | | <Icon type="question-circle" /> |
| | | url变量 |
| | | </Tooltip> |
| | | <Icon type="plus" title="添加" onClick={() => this.editDataSource()} /> |
| | | </div> |
| | | <div> |
| | | {urlFields.map((field, index) => { |
| | | return ( |
| | | <div className="field-item" key={index}> |
| | | <Icon type="close" title="删除" onClick={() => this.deleteField(field)} /> |
| | | {field} |
| | | </div> |
| | | ) |
| | | })} |
| | | </div> |
| | | <Modal |
| | | title="字段添加" |
| | | visible={visible} |
| | | width={500} |
| | | maskClosable={false} |
| | | onOk={this.verifySubmit} |
| | | onCancel={() => { this.setState({ visible: false }) }} |
| | | destroyOnClose |
| | | > |
| | | <SettingForm |
| | | inputSubmit={this.verifySubmit} |
| | | wrappedComponentRef={(inst) => this.verifyRef = inst} |
| | | /> |
| | | </Modal> |
| | | </div> |
| | | ) |
| | | } |
| | | } |
| | | |
| | | export default UrlFieldComponent |
New file |
| | |
| | | .url-field-component { |
| | | margin-bottom: 15px; |
| | | .field-plus { |
| | | line-height: 35px; |
| | | >.anticon-plus { |
| | | color: #26C281; |
| | | padding: 2px 5px; |
| | | margin-left: 5px; |
| | | } |
| | | .anticon-question-circle { |
| | | color: #c49f47; |
| | | margin-right: 3px; |
| | | } |
| | | } |
| | | .field-item { |
| | | position: relative; |
| | | border: 1px solid #e8e8e8; |
| | | padding: 5px 10px; |
| | | border-radius: 4px; |
| | | |
| | | >.anticon-close { |
| | | position: absolute; |
| | | right: 5px; |
| | | top: 3px; |
| | | font-size: 13px; |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { Form, Input } from 'antd' |
| | | |
| | | import './index.scss' |
| | | |
| | | class SettingForm extends Component { |
| | | static propTpyes = { |
| | | inputSubmit: PropTypes.func // 回车事件 |
| | | } |
| | | |
| | | handleConfirm = () => { |
| | | // 表单提交时检查输入值是否正确 |
| | | return new Promise((resolve, reject) => { |
| | | this.props.form.validateFieldsAndScroll((err, values) => { |
| | | if (!err) { |
| | | resolve(values) |
| | | } else { |
| | | reject(err) |
| | | } |
| | | }) |
| | | }) |
| | | } |
| | | |
| | | handleSubmit = (e) => { |
| | | e.preventDefault() |
| | | |
| | | if (this.props.inputSubmit) { |
| | | this.props.inputSubmit() |
| | | } |
| | | } |
| | | |
| | | componentDidMount() { |
| | | try { |
| | | let _input = document.getElementById('field') |
| | | if (_input.focus) { |
| | | _input.focus() |
| | | } |
| | | } catch { |
| | | console.warn('focus error!') |
| | | } |
| | | } |
| | | |
| | | render() { |
| | | const { getFieldDecorator } = this.props.form |
| | | |
| | | const formItemLayout = { |
| | | labelCol: { |
| | | xs: { span: 24 }, |
| | | sm: { span: 8 } |
| | | }, |
| | | wrapperCol: { |
| | | xs: { span: 24 }, |
| | | sm: { span: 14 } |
| | | } |
| | | } |
| | | |
| | | return ( |
| | | <div className="url-field-form"> |
| | | <Form {...formItemLayout}> |
| | | <Form.Item label="字段名"> |
| | | {getFieldDecorator('field', { |
| | | initialValue: '', |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: '请输入字段名!' |
| | | }, |
| | | { |
| | | pattern: /^[a-zA-Z0-9_]*$/ig, |
| | | message: '字段可使用英文、数字或_' |
| | | } |
| | | ] |
| | | })(<Input placeholder={''} autoComplete="off" onPressEnter={this.handleSubmit} />)} |
| | | </Form.Item> |
| | | </Form> |
| | | </div> |
| | | ) |
| | | } |
| | | } |
| | | |
| | | export default Form.create()(SettingForm) |
| | |
| | | } |
| | | |
| | | state = { |
| | | dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | rember: true, |
| | | param: { |
| | | type: 'login', |
| | |
| | | } |
| | | |
| | | state = { |
| | | dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | view: 'account', |
| | | param: { |
| | | type: 'login', |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { is, fromJS } from 'immutable' |
| | | import { connect } from 'react-redux' |
| | | import { withRouter } from 'react-router-dom' |
| | | import {Dropdown, Menu, Icon, Modal, Tooltip, Button } from 'antd' |
| | | |
| | | import { logout } from '@/store/action' |
| | | import zhCN from '@/locales/zh-CN/mob.js' |
| | | import enUS from '@/locales/en-US/mob.js' |
| | | import avatar from '@/assets/img/avatar.jpg' |
| | | import MainLogo from '@/assets/img/main-logo.png' |
| | | import './index.scss' |
| | | |
| | | const { confirm } = Modal |
| | | |
| | | class MobHeader extends Component { |
| | | static propTpyes = { |
| | | view: PropTypes.string, |
| | | saveIng: PropTypes.any, |
| | | triggerSave: PropTypes.func, |
| | | jumpToManage: PropTypes.func |
| | | } |
| | | |
| | | state = { |
| | | dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | avatar: sessionStorage.getItem('CloudAvatar') || avatar, |
| | | userName: sessionStorage.getItem('CloudUserName') |
| | | } |
| | | |
| | | logout = () => { |
| | | // 退出登录 |
| | | let _this = this |
| | | confirm({ |
| | | title: this.state.dict['mob.logout.hint'], |
| | | content: '', |
| | | onOk() { |
| | | sessionStorage.clear() |
| | | _this.props.logout() |
| | | _this.props.history.replace('/login') |
| | | }, |
| | | onCancel() {} |
| | | }) |
| | | } |
| | | |
| | | shouldComponentUpdate (nextProps, nextState) { |
| | | return !is(fromJS(this.props), fromJS(nextProps)) || !is(fromJS(this.state), fromJS(nextState)) |
| | | } |
| | | |
| | | render () { |
| | | const { view } = this.props |
| | | |
| | | return ( |
| | | <header className="mob-header-container"> |
| | | <div className="header-logo"><img src={MainLogo} alt=""/></div> |
| | | {view === 'manage' ? |
| | | <div className="mob-manage-title"> |
| | | 应用管理 |
| | | </div> :null |
| | | } |
| | | {view === 'design' ? |
| | | <Menu |
| | | mode="inline" |
| | | theme="dark" |
| | | inlineCollapsed={this.state.collapsed} |
| | | > |
| | | <Menu.Item key="1"> |
| | | <Tooltip placement="bottom" title="返回应用管理"> |
| | | <Icon type="arrow-left" onClick={this.props.jumpToManage} /> |
| | | </Tooltip> |
| | | </Menu.Item> |
| | | <Menu.Item key="2"> |
| | | <Tooltip placement="bottom" title="保存"> |
| | | <Button icon="save" loading={this.props.saveIng} onClick={this.props.triggerSave}></Button> |
| | | </Tooltip> |
| | | </Menu.Item> |
| | | </Menu> : null |
| | | } |
| | | <Dropdown className="header-setting" overlay={ |
| | | <Menu> |
| | | <Menu.Item key="2" onClick={this.logout}>{this.state.dict['mob.logout']}</Menu.Item> |
| | | </Menu> |
| | | }> |
| | | <div> |
| | | <img src={this.state.avatar} alt=""/> |
| | | <span> |
| | | <span className="username">{this.state.userName}</span> <Icon type="down" /> |
| | | </span> |
| | | </div> |
| | | </Dropdown> |
| | | <div className="header-user"> |
| | | <img src={this.state.avatar} alt=""/> |
| | | <span> |
| | | <span className="username">{this.state.userName}</span> |
| | | </span> |
| | | </div> |
| | | </header> |
| | | ) |
| | | } |
| | | } |
| | | |
| | | const mapStateToProps = () => { |
| | | return {} |
| | | } |
| | | |
| | | const mapDispatchToProps = (dispatch) => { |
| | | return { |
| | | logout: () => dispatch(logout()) |
| | | } |
| | | } |
| | | |
| | | export default withRouter(connect(mapStateToProps, mapDispatchToProps)(MobHeader)) |
| | | export default MobHeader |
| | |
| | | .mob-header-container { |
| | | width: 100%; |
| | | height: 48px; |
| | | padding-right: 320px; |
| | | color: rgba(255, 255, 255, 0.65); |
| | | position: fixed; |
| | | top: 0px; |
| | |
| | | max-height: 40px; |
| | | } |
| | | } |
| | | .header-setting { |
| | | .header-user { |
| | | float: right; |
| | | line-height: 48px; |
| | | margin-right: 10px; |
| | |
| | | text-overflow: ellipsis; |
| | | white-space: nowrap; |
| | | } |
| | | } |
| | | } |
| | | .mob-manage-title { |
| | | position: absolute; |
| | | left: calc(50vw - 45px); |
| | | color: #ffffff; |
| | | font-size: 16px; |
| | | line-height: 48px; |
| | | letter-spacing: 2px; |
| | | } |
| | | >.ant-menu { |
| | | float: left; |
| | | width: unset!important; |
| | | .ant-menu-item { |
| | | margin-bottom: 0!important; |
| | | float: left; |
| | | width: unset!important; |
| | | cursor: default; |
| | | .anticon-arrow-left { |
| | | height: 24px; |
| | | cursor: pointer; |
| | | } |
| | | .ant-btn { |
| | | color: #fff; |
| | | width: unset; |
| | | cursor: pointer; |
| | | height: 37px; |
| | | background: transparent; |
| | | border: 0; |
| | | .anticon-save { |
| | | margin-right: 0; |
| | | } |
| | | } |
| | | .ant-btn[ant-click-animating-without-extra-node="true"]::after { |
| | | display: none!important; |
| | | } |
| | | .ant-btn::before { |
| | | display: none!important; |
| | | } |
| | | } |
| | | .ant-menu-item.ant-menu-item-selected { |
| | | background-color: transparent; |
| | | } |
| | | .ant-menu-item:not(:last-child) { |
| | | border-right: 1px solid #353535; |
| | | } |
| | | } |
| | | } |
| | |
| | | // collapse: PropTypes.bool, |
| | | // } |
| | | state = { |
| | | dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | } |
| | | |
| | | shouldComponentUpdate (nextProps, nextState) { |
| | |
| | | import { useDrag, useDrop } from 'react-dnd' |
| | | |
| | | import asyncComponent from '@/utils/asyncComponent' |
| | | |
| | | import './index.scss' |
| | | |
| | | // const Home = asyncComponent(() => import('@/mob/home')) |
| | | const MobLogin1 = asyncComponent(() => import('@/mob/components/login/mob-login-1')) |
| | | const MobLogin2 = asyncComponent(() => import('@/mob/components/login/mob-login-2')) |
| | | const AntvBar = asyncComponent(() => import('@/menu/components/chart/antv-bar')) |
| | | const MainSearch = asyncComponent(() => import('@/menu/components/search/main-search')) |
| | | const AntvPie = asyncComponent(() => import('@/menu/components/chart/antv-pie')) |
| | | const AntvTabs = asyncComponent(() => import('@/menu/components/tabs/antv-tabs')) |
| | | const DataCard = asyncComponent(() => import('@/menu/components/card/data-card')) |
| | | const PropCard = asyncComponent(() => import('@/menu/components/card/prop-card')) |
| | | const CarouselDataCard = asyncComponent(() => import('@/menu/components/carousel/data-card')) |
| | | const CarouselPropCard = asyncComponent(() => import('@/menu/components/carousel/prop-card')) |
| | | const TableCard = asyncComponent(() => import('@/menu/components/card/table-card')) |
| | | const NormalTable = asyncComponent(() => import('@/menu/components/table/normal-table')) |
| | | const NormalForm = asyncComponent(() => import('@/menu/components/form/normal-form')) |
| | | const NormalGroup = asyncComponent(() => import('@/menu/components/group/normal-group')) |
| | | const CodeSandbox = asyncComponent(() => import('@/menu/components/code/sandbox')) |
| | | |
| | | const Card = ({ id, card, moveCard, findCard, editId, editCard, delCard, doubleClickCard, updateConfig }) => { |
| | | const Card = ({ id, card, moveCard, findCard, delCard, updateConfig }) => { |
| | | const originalIndex = findCard(id).index |
| | | const [{ isDragging }, drag] = useDrag({ |
| | | item: { type: 'mob', id, originalIndex }, |
| | | item: { type: 'menu', id, originalIndex, floor: card.floor }, |
| | | collect: monitor => ({ |
| | | isDragging: monitor.isDragging(), |
| | | }), |
| | | }) |
| | | const [, drop] = useDrop({ |
| | | accept: 'mob', |
| | | accept: 'menu', |
| | | canDrop: () => true, |
| | | drop: (item) => { |
| | | const { id: draggedId, originalIndex } = item |
| | | |
| | | const { id: draggedId, originalIndex, floor } = item |
| | | if (originalIndex === undefined) { |
| | | item.dropTargetId = id |
| | | } else if (draggedId && draggedId !== id) { |
| | | } else if (draggedId && floor === card.floor) { |
| | | if (draggedId === id) return |
| | | const { index: originIndex } = findCard(draggedId) |
| | | |
| | | if (originIndex === -1) return |
| | | |
| | | const { index: overIndex } = findCard(id) |
| | | |
| | | moveCard(draggedId, overIndex) |
| | | } |
| | | } |
| | | }) |
| | | |
| | | let style = { opacity: 1} |
| | | if (isDragging && card.type !== 'login') { |
| | | if (isDragging) { |
| | | style = { opacity: 0.3} |
| | | } |
| | | if (card.type === 'login') { |
| | | style.height = '100%' |
| | | } |
| | | |
| | | const getCardComponent = () => { |
| | | if (card.type === 'login') { |
| | | if (card.subtype === 'mob-login-1') { |
| | | return (<MobLogin1 card={card} triggerEdit={editCard} editId={editId} onDoubleClick={doubleClickCard} updateConfig={updateConfig} />) |
| | | } else if (card.subtype === 'mob-login-2') { |
| | | return (<MobLogin2 card={card} triggerEdit={editCard} editId={editId} onDoubleClick={doubleClickCard} updateConfig={updateConfig} />) |
| | | } |
| | | if (card.type === 'bar' || card.type === 'line') { |
| | | return (<AntvBar card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) |
| | | } else if (card.type === 'search') { |
| | | return (<MainSearch card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) |
| | | } else if (card.type === 'pie') { |
| | | return (<AntvPie card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) |
| | | } else if (card.type === 'form') { |
| | | return (<NormalForm card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) |
| | | } else if (card.type === 'tabs') { |
| | | return (<AntvTabs tabs={card} updateConfig={updateConfig} deletecomponent={delCard}/>) |
| | | } else if (card.type === 'card' && card.subtype === 'datacard') { |
| | | return (<DataCard card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) |
| | | } else if (card.type === 'card' && card.subtype === 'propcard') { |
| | | return (<PropCard card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) |
| | | } else if (card.type === 'carousel' && card.subtype === 'datacard') { |
| | | return (<CarouselDataCard card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) |
| | | } else if (card.type === 'carousel' && card.subtype === 'propcard') { |
| | | return (<CarouselPropCard card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) |
| | | } else if (card.type === 'table' && card.subtype === 'tablecard') { |
| | | return (<TableCard card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) |
| | | } else if (card.type === 'table' && card.subtype === 'normaltable') { |
| | | return (<NormalTable card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) |
| | | } else if (card.type === 'group' && card.subtype === 'normalgroup') { |
| | | return (<NormalGroup group={card} updateConfig={updateConfig} deletecomponent={delCard}/>) |
| | | } else if (card.type === 'code') { |
| | | return (<CodeSandbox card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) |
| | | } |
| | | } |
| | | |
| | | return ( |
| | | <div className="mk-component-card" ref={node => drag(drop(node))} style={style}> |
| | | <div className={'ant-col mk-component-card ant-col-' + (card.width || 24)} ref={node => drag(drop(node))} style={style}> |
| | | {getCardComponent()} |
| | | </div> |
| | | ) |
| | |
| | | import React, { useState } from 'react' |
| | | import { useDrop } from 'react-dnd' |
| | | import { is, fromJS } from 'immutable' |
| | | import update from 'immutability-helper' |
| | | import { message, Empty } from 'antd' |
| | | import { Empty, notification, Modal } from 'antd' |
| | | |
| | | import Utils from '@/utils/utils.js' |
| | | import MKEmitter from '@/utils/events.js' |
| | | import MenuUtils from '@/utils/utils-custom.js' |
| | | import Card from './card' |
| | | import './index.scss' |
| | | |
| | | const Container = ({config, editId, handleList, editCard, deleteCard, doubleClickCard }) => { |
| | | const [cards, setCards] = useState(config.components) |
| | | const { confirm } = Modal |
| | | |
| | | const Container = ({menu, handleList }) => { |
| | | const [cards, setCards] = useState(menu.components) |
| | | const moveCard = (id, atIndex) => { |
| | | const { card, index } = findCard(id) |
| | | const _cards = update(cards, { $splice: [[index, 1], [atIndex, 0, card]] }) |
| | | handleList({...config, components: _cards}) |
| | | } |
| | | |
| | | if (!is(fromJS(cards), fromJS(config.components))) { |
| | | setCards(config.components) |
| | | handleList({...menu, components: _cards}) |
| | | setCards(_cards) |
| | | } |
| | | |
| | | const findCard = id => { |
| | |
| | | } |
| | | |
| | | const updateConfig = (element) => { |
| | | handleList({...config, components: cards.map(item => item.uuid === element.uuid ? element : item)}) |
| | | const _cards = cards.map(item => item.uuid === element.uuid ? element : item) |
| | | handleList({...menu, components: _cards}) |
| | | setCards(_cards) |
| | | } |
| | | |
| | | const deleteCard = (id) => { |
| | | const { card } = findCard(id) |
| | | |
| | | let hasComponent = false |
| | | if (card.type === 'tabs') { |
| | | card.subtabs.forEach(tab => { |
| | | if (tab.components.length > 0) { |
| | | hasComponent = true |
| | | } |
| | | }) |
| | | } |
| | | |
| | | let uuids = MenuUtils.getDelButtonIds(card) |
| | | |
| | | confirm({ |
| | | title: `确定删除《${card.name}》吗?`, |
| | | content: hasComponent ? '当前组件中含有子组件!' : '', |
| | | onOk() { |
| | | MKEmitter.emit('delButtons', uuids) |
| | | const _cards = cards.filter(item => item.uuid !== card.uuid) |
| | | handleList({...menu, components: _cards}) |
| | | setCards(_cards) |
| | | }, |
| | | onCancel() {} |
| | | }) |
| | | } |
| | | |
| | | const [, drop] = useDrop({ |
| | | accept: 'mob', |
| | | accept: 'menu', |
| | | drop(item) { |
| | | if (item.hasOwnProperty('originalIndex')) { |
| | | if (item.hasOwnProperty('originalIndex') || item.added) { |
| | | delete item.added // 删除组件添加标记 |
| | | return |
| | | } |
| | | |
| | | if (cards.length > 0 && cards[0].type === 'login') { |
| | | message.warning('登录页不可添加其他元素!') |
| | | return |
| | | if (item.component === 'search') { // 搜索组件不可重复添加 |
| | | if (cards.filter(card => card.type === 'search').length > 0) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '搜索条件不可重复添加!', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } |
| | | } |
| | | |
| | | let name = '' |
| | | let names = { |
| | | bar: '柱状图', |
| | | line: '折线图', |
| | | tabs: '标签组', |
| | | pie: '饼图', |
| | | search: '搜索', |
| | | table: '表格', |
| | | group: '分组', |
| | | editor: '富文本', |
| | | code: '自定义', |
| | | carousel: '轮播', |
| | | form: '表单', |
| | | card: '卡片' |
| | | } |
| | | let i = 1 |
| | | |
| | | while (!name && names[item.component]) { |
| | | let _name = names[item.component] + i |
| | | if (menu.components.filter(com => com.name === _name).length === 0) { |
| | | name = _name |
| | | } |
| | | i++ |
| | | } |
| | | |
| | | let newcard = { |
| | | uuid: Utils.getuuid(), |
| | | type: item.componentType, |
| | | type: item.component, |
| | | subtype: item.subtype, |
| | | config: item.config, |
| | | width: item.width || 24, |
| | | dataName: Utils.getdataName(), |
| | | name: name, |
| | | floor: 1, // 组件的层级 |
| | | isNew: true // 新添加标志,用于初始化 |
| | | } |
| | | |
| | | |
| | | let targetId = '' |
| | | |
| | | if (item.dropTargetId) { |
| | |
| | | targetId = cards.slice(-1)[0].uuid |
| | | } |
| | | |
| | | const { index: overIndex } = findCard(`${targetId}`) // cards为空时 overIndex 为 -1 |
| | | const { index: overIndex } = findCard(`${targetId}`) |
| | | const _cards = update(cards, { $splice: [[overIndex + 1, 0, newcard]] }) |
| | | |
| | | handleList({...config, components: _cards}) |
| | | handleList({...menu, components: _cards}) |
| | | setCards(_cards) |
| | | } |
| | | }) |
| | | |
| | | return ( |
| | | <div ref={drop} className="mob-shell-inner"> |
| | | {cards.map(card => ( |
| | | <Card |
| | | id={card.uuid} |
| | | key={card.uuid} |
| | | card={card} |
| | | editId={editId} |
| | | moveCard={moveCard} |
| | | editCard={editCard} |
| | | delCard={deleteCard} |
| | | findCard={findCard} |
| | | updateConfig={updateConfig} |
| | | doubleClickCard={doubleClickCard} |
| | | /> |
| | | ))} |
| | | <div ref={drop} className="mob-shell-inner" id="menu-shell-inner" style={menu.style}> |
| | | <div className="ant-row"> |
| | | {cards.map(card => ( |
| | | <Card |
| | | id={card.uuid} |
| | | key={card.uuid} |
| | | card={card} |
| | | moveCard={moveCard} |
| | | delCard={deleteCard} |
| | | findCard={findCard} |
| | | updateConfig={updateConfig} |
| | | /> |
| | | ))} |
| | | </div> |
| | | {cards.length === 0 ? |
| | | <Empty description="请添加组件" /> : null |
| | | } |
| | |
| | | ) |
| | | } |
| | | export default Container |
| | | |
New file |
| | |
| | | import React from 'react' |
| | | import { useDrag } from 'react-dnd' |
| | | import { Icon } from 'antd' |
| | | import './index.scss' |
| | | |
| | | const MobSourceElement = ({item, triggerDel}) => { |
| | | const [, drag] = useDrag({ item }) |
| | | return ( |
| | | <div className="menu-source-item"> |
| | | <div className="property"><span>{item.title}</span>{item.config ? <Icon onClick={() => triggerDel(item)} type="close-circle" /> : null}</div> |
| | | <img ref={drag} src={item.url} alt=""/> |
| | | </div> |
| | | ) |
| | | } |
| | | export default MobSourceElement |
New file |
| | |
| | | .menu-source-item { |
| | | display: inline-block; |
| | | width: 100%; |
| | | margin-bottom: 15px; |
| | | height: auto; |
| | | min-height: 70px; |
| | | |
| | | .property { |
| | | font-size: 14px; |
| | | color: rgba(0, 0, 0, 0.65); |
| | | margin-bottom: 2px; |
| | | |
| | | .anticon-close-circle { |
| | | opacity: 0; |
| | | cursor: pointer; |
| | | padding: 0 3px; |
| | | color: #ff4d4f; |
| | | transition: all 0.3s; |
| | | } |
| | | } |
| | | |
| | | img { |
| | | width: 100%; |
| | | cursor: move; |
| | | box-shadow: 0px 0px 1px #1890ff; |
| | | } |
| | | |
| | | .tooltip-block { |
| | | width: 100%; |
| | | height: 100%; |
| | | background: transparent; |
| | | } |
| | | } |
| | | |
| | | .menu-source-item:hover .property { |
| | | .anticon-close-circle { |
| | | opacity: 1; |
| | | } |
| | | } |
| | | |
| | | .menu-source-tooltip-box { |
| | | margin-left: 20px; |
| | | .ant-tooltip-content { |
| | | width: 250px; |
| | | } |
| | | } |
New file |
| | |
| | | import React, {Component} from 'react' |
| | | import { is, fromJS } from 'immutable' |
| | | import { Modal, notification } from 'antd' |
| | | |
| | | import Api from '@/api' |
| | | import { menuOptions } from './option' |
| | | import SourceWrap from './dragsource' |
| | | import MKEmitter from '@/utils/events.js' |
| | | import './index.scss' |
| | | |
| | | const { confirm } = Modal |
| | | |
| | | class ModelSource extends Component { |
| | | state = { |
| | | menuOptions: null, |
| | | } |
| | | |
| | | UNSAFE_componentWillMount () { |
| | | const { components } = this.props |
| | | let options = [] |
| | | |
| | | if (components) { |
| | | options = fromJS(components).toJS() |
| | | } else { |
| | | options = fromJS(menuOptions).toJS() |
| | | } |
| | | |
| | | this.setState({ |
| | | menuOptions: options |
| | | }) |
| | | } |
| | | |
| | | UNSAFE_componentWillReceiveProps (nextProps) { |
| | | if (nextProps.components && !is(fromJS(this.props.components), fromJS(nextProps.components))) { |
| | | this.setState({ |
| | | menuOptions: fromJS(nextProps.components).toJS() |
| | | }) |
| | | } |
| | | } |
| | | |
| | | shouldComponentUpdate (nextProps, nextState) { |
| | | return !is(fromJS(this.state), fromJS(nextState)) |
| | | } |
| | | |
| | | triggerDel = (item) => { |
| | | confirm({ |
| | | title: `确定删除<${item.title}>吗?`, |
| | | content: '', |
| | | onOk() { |
| | | return new Promise(resolve => { |
| | | Api.getSystemConfig({ |
| | | func: 's_custom_components_adduptdel', |
| | | c_id: item.uuid, |
| | | images: '', |
| | | c_name: item.title, |
| | | long_param: '', |
| | | del_type: 'Y' |
| | | }).then(result => { |
| | | if (result.status) { |
| | | notification.success({ |
| | | top: 92, |
| | | message: '删除成功!', |
| | | duration: 5 |
| | | }) |
| | | |
| | | MKEmitter.emit('updateCustomComponent') |
| | | } else { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: result.message, |
| | | duration: 5 |
| | | }) |
| | | } |
| | | resolve() |
| | | }) |
| | | }) |
| | | }, |
| | | onCancel() {} |
| | | }) |
| | | } |
| | | |
| | | render() { |
| | | const { menuOptions } = this.state |
| | | |
| | | return ( |
| | | <div className="mob-card-source-box"> |
| | | {menuOptions.map((item, index) => (<SourceWrap key={index} item={item} triggerDel={this.triggerDel} />))} |
| | | </div> |
| | | ) |
| | | } |
| | | } |
| | | |
| | | export default ModelSource |
File was renamed from src/mob/modelsource/index.scss |
| | |
| | | .mob-card-source-box { |
| | | padding: 20px 0px 20px 15px; |
| | | padding: 20px 0px; |
| | | position: relative; |
| | | |
| | | p { |
New file |
| | |
| | | import bar from '@/assets/mobimg/bar.png' |
| | | import bar1 from '@/assets/mobimg/bar1.png' |
| | | import line from '@/assets/mobimg/line.png' |
| | | import line1 from '@/assets/mobimg/line1.png' |
| | | import tabs from '@/assets/mobimg/tabs.png' |
| | | import group from '@/assets/mobimg/group.png' |
| | | import card1 from '@/assets/mobimg/card1.png' |
| | | import card2 from '@/assets/mobimg/card2.png' |
| | | import TableCard from '@/assets/mobimg/table-card.png' |
| | | import NormalTable from '@/assets/mobimg/normal-table.png' |
| | | import Pie from '@/assets/mobimg/pie.png' |
| | | import SandBox from '@/assets/mobimg/sandbox.png' |
| | | import Pie1 from '@/assets/mobimg/ring.png' |
| | | import Pie2 from '@/assets/mobimg/nightingale.png' |
| | | import Mainsearch from '@/assets/mobimg/mainsearch.png' |
| | | import Navbar from '@/assets/mobimg/navbar-mob.png' |
| | | import Carousel from '@/assets/mobimg/carousel.png' |
| | | import Carousel1 from '@/assets/mobimg/carousel1.png' |
| | | import form from '@/assets/mobimg/form.png' |
| | | |
| | | // 组件配置信息 |
| | | export const menuOptions = [ |
| | | { type: 'menu', url: Navbar, component: 'navbar', subtype: 'mobnavbar', title: '导航栏', width: 1200 }, |
| | | { type: 'menu', url: tabs, component: 'tabs', subtype: 'tabs', title: '标签页', width: 24 }, |
| | | { type: 'menu', url: Mainsearch, component: 'search', subtype: 'mainsearch', title: '搜索条件', width: 24 }, |
| | | { type: 'menu', url: card1, component: 'card', subtype: 'datacard', title: '数据卡', width: 24 }, |
| | | { type: 'menu', url: card2, component: 'card', subtype: 'propcard', title: '属性卡', width: 24 }, |
| | | { type: 'menu', url: form, component: 'form', subtype: 'stepform', title: '表单', width: 24 }, |
| | | { type: 'menu', url: Carousel, component: 'carousel', subtype: 'datacard', title: '轮播-动态数据', width: 24 }, |
| | | { type: 'menu', url: Carousel1, component: 'carousel', subtype: 'propcard', title: '轮播-静态数据', width: 24 }, |
| | | { type: 'menu', url: NormalTable, component: 'table', subtype: 'normaltable', title: '常用表', width: 24 }, |
| | | { type: 'menu', url: TableCard, component: 'table', subtype: 'tablecard', title: '表格', width: 24 }, |
| | | { type: 'menu', url: line, component: 'line', subtype: 'line', title: '折线图', width: 24 }, |
| | | { type: 'menu', url: line1, component: 'line', subtype: 'line1', title: '阶梯折线图', width: 24 }, |
| | | { type: 'menu', url: bar, component: 'bar', subtype: 'bar', title: '柱状图', width: 24 }, |
| | | { type: 'menu', url: bar1, component: 'bar', subtype: 'bar1', title: '条形图', width: 24 }, |
| | | { type: 'menu', url: Pie, component: 'pie', subtype: 'pie', title: '饼图', width: 24 }, |
| | | { type: 'menu', url: Pie1, component: 'pie', subtype: 'ring', title: '环图', width: 24 }, |
| | | { type: 'menu', url: SandBox, component: 'code', subtype: 'sandbox', title: '自定义', width: 24 }, |
| | | { type: 'menu', url: Pie2, component: 'pie', subtype: 'nightingale', title: '南丁格尔图', width: 24 }, |
| | | { type: 'menu', url: group, component: 'group', subtype: 'normalgroup', title: '分组', width: 24 }, |
| | | ] |
New file |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { is, fromJS } from 'immutable' |
| | | import { Form, Icon } from 'antd' |
| | | |
| | | import zhCN from '@/locales/zh-CN/mob.js' |
| | | import enUS from '@/locales/en-US/mob.js' |
| | | import asyncComponent from '@/utils/asyncComponent' |
| | | import './index.scss' |
| | | |
| | | const ColorSketch = asyncComponent(() => import('@/mob/colorsketch')) |
| | | const StyleInput = asyncComponent(() => import('@/menu/stylecontroller/styleInput')) |
| | | const SourceComponent = asyncComponent(() => import('@/menu/components/share/sourcecomponent')) |
| | | |
| | | class MobController extends Component { |
| | | static propTpyes = { |
| | | config: PropTypes.any, |
| | | updateConfig: PropTypes.func, |
| | | } |
| | | |
| | | state = { |
| | | dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | backgroundColor: '', |
| | | backgroundImage: '', |
| | | } |
| | | |
| | | UNSAFE_componentWillMount () { |
| | | const { config } = this.props |
| | | |
| | | let bgImg = config.style.backgroundImage || '' |
| | | |
| | | if (bgImg && /^url/.test(bgImg)) { |
| | | bgImg = bgImg.replace('url(', '') |
| | | bgImg = bgImg.replace(')', '') |
| | | } |
| | | |
| | | this.setState({ |
| | | backgroundColor: config.style.backgroundColor, |
| | | backgroundImage: bgImg |
| | | }) |
| | | } |
| | | |
| | | shouldComponentUpdate (nextProps, nextState) { |
| | | return !is(fromJS(this.state), fromJS(nextState)) |
| | | } |
| | | |
| | | /** |
| | | * @description 修改背景颜色 ,颜色控件 |
| | | */ |
| | | changeBackgroundColor = (val) => { |
| | | let config = fromJS(this.props.config).toJS() |
| | | |
| | | this.setState({ |
| | | backgroundColor: val |
| | | }) |
| | | |
| | | config.style.backgroundColor = val |
| | | this.props.updateConfig(config) |
| | | } |
| | | |
| | | /** |
| | | * @description 修改背景颜色 ,颜色控件 |
| | | */ |
| | | changePadding = (val, type) => { |
| | | let config = fromJS(this.props.config).toJS() |
| | | |
| | | config.style[type] = val |
| | | this.props.updateConfig(config) |
| | | } |
| | | |
| | | |
| | | imgChange = (val) => { |
| | | this.setState({ |
| | | backgroundImage: val |
| | | }) |
| | | |
| | | let config = fromJS(this.props.config).toJS() |
| | | |
| | | if (val) { |
| | | config.style.backgroundImage = `url(${val})` |
| | | } else { |
| | | delete config.style.backgroundImage |
| | | } |
| | | this.props.updateConfig(config) |
| | | } |
| | | |
| | | render () { |
| | | const { config } = this.props |
| | | const { backgroundColor, backgroundImage } = this.state |
| | | const formItemLayout = { |
| | | labelCol: { |
| | | xs: { span: 24 }, |
| | | sm: { span: 5 } |
| | | }, |
| | | wrapperCol: { |
| | | xs: { span: 24 }, |
| | | sm: { span: 19 } |
| | | } |
| | | } |
| | | |
| | | return ( |
| | | <div className="pc-style-controller"> |
| | | <Form {...formItemLayout}> |
| | | <Form.Item |
| | | colon={false} |
| | | label="宽度" |
| | | > |
| | | <StyleInput defaultValue={config.style.width || '100%'} options={['px', '%', 'vw']} onChange={(val) => this.changePadding(val, 'width')}/> |
| | | </Form.Item> |
| | | <Form.Item className="color-control" colon={false} label="背景色"> |
| | | <ColorSketch value={backgroundColor} onChange={this.changeBackgroundColor} /> |
| | | </Form.Item> |
| | | <Form.Item colon={false} label="背景图"> |
| | | <SourceComponent value={backgroundImage} type="" placement="right" onChange={this.imgChange}/> |
| | | </Form.Item> |
| | | <p style={{borderBottom: '1px solid #eaeaea', color: '#40a9ff'}}>内边距</p> |
| | | <Form.Item |
| | | colon={false} |
| | | label={<Icon title="上边距" type="arrow-up"/>} |
| | | > |
| | | <StyleInput defaultValue={config.style.paddingTop || '0px'} options={['px', 'vh', 'vw']} onChange={(val) => this.changePadding(val, 'paddingTop')}/> |
| | | </Form.Item> |
| | | <Form.Item |
| | | colon={false} |
| | | label={<Icon title="下边距" type="arrow-down"/>} |
| | | > |
| | | <StyleInput defaultValue={config.style.paddingBottom || '0px'} options={['px', 'vh', 'vw']} onChange={(val) => this.changePadding(val, 'paddingBottom')}/> |
| | | </Form.Item> |
| | | <Form.Item |
| | | colon={false} |
| | | label={<Icon title="左边距" type="arrow-left"/>} |
| | | > |
| | | <StyleInput defaultValue={config.style.paddingLeft || '0px'} options={['px', 'vh', 'vw']} onChange={(val) => this.changePadding(val, 'paddingLeft')}/> |
| | | </Form.Item> |
| | | <Form.Item |
| | | colon={false} |
| | | label={<Icon title="右边距" type="arrow-right"/>} |
| | | > |
| | | <StyleInput defaultValue={config.style.paddingRight || '0px'} options={['px', 'vh', 'vw']} onChange={(val) => this.changePadding(val, 'paddingRight')}/> |
| | | </Form.Item> |
| | | <p style={{borderBottom: '1px solid #eaeaea', color: '#40a9ff'}}>外边距</p> |
| | | <Form.Item |
| | | colon={false} |
| | | label={<Icon title="上边距" type="arrow-up"/>} |
| | | > |
| | | <StyleInput defaultValue={config.style.marginTop || '0px'} options={['px', 'vh', 'vw']} onChange={(val) => this.changePadding(val, 'marginTop')}/> |
| | | </Form.Item> |
| | | <Form.Item |
| | | colon={false} |
| | | label={<Icon title="下边距" type="arrow-down"/>} |
| | | > |
| | | <StyleInput defaultValue={config.style.marginBottom || '0px'} options={['px', 'vh', 'vw']} onChange={(val) => this.changePadding(val, 'marginBottom')}/> |
| | | </Form.Item> |
| | | <Form.Item |
| | | colon={false} |
| | | label={<Icon title="左边距" type="arrow-left"/>} |
| | | > |
| | | <StyleInput defaultValue={config.style.marginLeft || '0px'} options={['px', 'vh', 'vw']} onChange={(val) => this.changePadding(val, 'marginLeft')}/> |
| | | </Form.Item> |
| | | <Form.Item |
| | | colon={false} |
| | | label={<Icon title="右边距" type="arrow-right"/>} |
| | | > |
| | | <StyleInput defaultValue={config.style.marginRight || '0px'} options={['px', 'vh', 'vw']} onChange={(val) => this.changePadding(val, 'marginRight')}/> |
| | | </Form.Item> |
| | | </Form> |
| | | </div> |
| | | ) |
| | | } |
| | | } |
| | | |
| | | export default MobController |
New file |
| | |
| | | .pc-style-controller { |
| | | width: 100%; |
| | | height: 100%; |
| | | overflow: hidden; |
| | | .color-control .ant-form-item-control { |
| | | padding-top: 10px; |
| | | line-height: 35px; |
| | | } |
| | | .mk-source-wrap { |
| | | height: 32px; |
| | | .mk-source-item-info { |
| | | top: 5px; |
| | | } |
| | | } |
| | | .ant-form-item label > .anticon { |
| | | font-size: 16px; |
| | | vertical-align: middle; |
| | | } |
| | | } |
New file |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { is, fromJS } from 'immutable' |
| | | import { Icon, Popover, Menu, Button } from 'antd' |
| | | |
| | | import asyncIconComponent from '@/utils/asyncIconComponent' |
| | | |
| | | import MKEmitter from '@/utils/events.js' |
| | | import zhCN from '@/locales/zh-CN/model.js' |
| | | import enUS from '@/locales/en-US/model.js' |
| | | import './index.scss' |
| | | |
| | | const WrapComponent = asyncIconComponent(() => import('./wrapsetting')) |
| | | const MenuComponent = asyncIconComponent(() => import('./menusetting')) |
| | | const LinkComponent = asyncIconComponent(() => import('./linksetting')) |
| | | |
| | | const { SubMenu } = Menu |
| | | |
| | | class NormalNavbar extends Component { |
| | | static propTpyes = { |
| | | card: PropTypes.object, |
| | | deletecomponent: PropTypes.func, |
| | | updateConfig: PropTypes.func, |
| | | } |
| | | |
| | | state = { |
| | | dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | card: null, |
| | | back: false |
| | | } |
| | | |
| | | UNSAFE_componentWillMount () { |
| | | const { card } = this.props |
| | | |
| | | if (card.isNew) { |
| | | let _card = { |
| | | uuid: card.uuid, |
| | | type: card.type, |
| | | floor: card.floor, |
| | | dataName: card.dataName || '', |
| | | width: card.width || 24, |
| | | name: card.name, |
| | | subtype: card.subtype, |
| | | wrap: { name: card.name, width: card.width || 1200 }, |
| | | logoStyle: { width: '100px' }, |
| | | style: { }, |
| | | links: [], |
| | | menus: [], |
| | | } |
| | | |
| | | if (card.config) { |
| | | let config = fromJS(card.config).toJS() |
| | | |
| | | _card.wrap = config.wrap |
| | | _card.wrap.name = card.name |
| | | _card.style = config.style |
| | | } |
| | | |
| | | this.setState({ |
| | | card: _card |
| | | }) |
| | | this.props.updateConfig(_card) |
| | | } else { |
| | | this.setState({ |
| | | card: fromJS(card).toJS() |
| | | }) |
| | | } |
| | | } |
| | | |
| | | componentDidMount () { |
| | | MKEmitter.addListener('submitStyle', this.getStyle) |
| | | } |
| | | |
| | | shouldComponentUpdate (nextProps, nextState) { |
| | | return !is(fromJS(this.state), fromJS(nextState)) |
| | | } |
| | | |
| | | /** |
| | | * @description 组件销毁,清除state更新,清除快捷键设置 |
| | | */ |
| | | componentWillUnmount () { |
| | | this.setState = () => { |
| | | return |
| | | } |
| | | MKEmitter.removeListener('submitStyle', this.getStyle) |
| | | } |
| | | |
| | | /** |
| | | * @description 卡片行外层信息更新(数据源,样式等) |
| | | */ |
| | | updateComponent = (component) => { |
| | | this.setState({ |
| | | card: component |
| | | }) |
| | | |
| | | component.width = component.wrap.width |
| | | component.name = component.wrap.name |
| | | |
| | | this.props.updateConfig(component) |
| | | } |
| | | |
| | | getStyle = (comIds, style) => { |
| | | const { card } = this.state |
| | | |
| | | if (comIds[0] !== card.uuid) return |
| | | |
| | | let _card = {...card} |
| | | if (comIds.length === 1) { |
| | | _card = {...card, style} |
| | | } else if (comIds[1] === 'logo') { |
| | | _card = {...card, logoStyle: style} |
| | | } |
| | | |
| | | this.setState({ |
| | | card: _card |
| | | }) |
| | | |
| | | this.props.updateConfig(_card) |
| | | } |
| | | |
| | | changeStyle = () => { |
| | | const { card } = this.state |
| | | |
| | | MKEmitter.emit('changeStyle', [card.uuid], ['font', 'background', 'shadow'], card.style) |
| | | } |
| | | |
| | | changeLogoStyle = () => { |
| | | const { card } = this.state |
| | | |
| | | MKEmitter.emit('changeStyle', [card.uuid, 'logo'], ['width', 'margin'], card.logoStyle) |
| | | } |
| | | |
| | | clickComponent = (e) => { |
| | | if (sessionStorage.getItem('style-control') === 'true' || sessionStorage.getItem('style-control') === 'component') { |
| | | e.stopPropagation() |
| | | MKEmitter.emit('clickComponent', this.state.card) |
| | | } |
| | | } |
| | | |
| | | changeMenu = (menu) => { |
| | | MKEmitter.emit('changeEditMenu', { |
| | | fixed: menu.property === 'menu', |
| | | MenuID: menu.property === 'linkmenu' ? menu.linkMenuId : menu.MenuID, |
| | | copyMenuId: menu.property === 'menu' ? menu.copyMenuId : '', |
| | | MenuNo: menu.MenuNo, |
| | | MenuName: menu.name, |
| | | }) |
| | | } |
| | | |
| | | changeLogoMenu = () => { |
| | | const { card } = this.state |
| | | |
| | | if (!card.wrap.logolink) return |
| | | |
| | | MKEmitter.emit('changeEditMenu', {MenuID: card.wrap.logolink}) |
| | | } |
| | | |
| | | render() { |
| | | const { card } = this.state |
| | | |
| | | let _style = {...card.style} |
| | | if (_style.shadow) { |
| | | _style.boxShadow = '0 0 4px ' + _style.shadow |
| | | } |
| | | |
| | | return ( |
| | | <div className="normal-navbar-edit-box" style={_style} onClick={this.clickComponent} id={card.uuid}> |
| | | <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={ |
| | | <div className="mk-popover-control"> |
| | | <MenuComponent config={card} updateConfig={this.updateComponent} /> |
| | | <LinkComponent config={card} updateConfig={this.updateComponent} /> |
| | | <WrapComponent config={card} updateConfig={this.updateComponent} /> |
| | | <Icon className="style" title="调整样式" onClick={this.changeStyle} type="font-colors" /> |
| | | <Icon className="close" title="删除组件" type="delete" onClick={() => this.props.deletecomponent(card.uuid)} /> |
| | | </div> |
| | | } trigger="hover"> |
| | | <Icon type="tool" /> |
| | | </Popover> |
| | | <div className="navbar-wrap" style={{width: card.wrap.width + 'px', height: card.wrap.height + 'px', lineHeight: card.wrap.height + 'px'}}> |
| | | {card.wrap.logo ? <Popover overlayClassName="mk-popover-control-wrap top-menu-popover" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={ |
| | | <div className="mk-popover-control"> |
| | | <Icon className="style" title="调整样式" onClick={this.changeLogoStyle} type="font-colors" /> |
| | | </div> |
| | | } trigger="hover"> |
| | | <div className={'logo' + (card.wrap.logolink ? ' pointer' : '')} style={card.logoStyle} onDoubleClick={this.changeLogoMenu}><img src={card.wrap.logo} alt=""/></div> |
| | | </Popover> : null} |
| | | <div className="menu"> |
| | | <Menu mode="horizontal"> |
| | | {card.menus.map(fst => { |
| | | if (fst.property === 'classify' && fst.sublist.length > 0) { |
| | | return ( |
| | | <SubMenu title={fst.name} key={fst.MenuID} popupClassName="normal-navbar-submenu"> |
| | | {fst.sublist.map(scd => { |
| | | if (scd.property === 'classify' && scd.sublist.length > 0) { |
| | | return ( |
| | | <Menu.ItemGroup key={scd.MenuID} title={scd.name}> |
| | | {scd.sublist.map(thd => { |
| | | return ( |
| | | <Menu.Item key={thd.MenuID} > |
| | | <span onClick={(e) => e.stopPropagation()} onDoubleClick={() => this.changeMenu(thd)}>{thd.name}</span> |
| | | </Menu.Item> |
| | | ) |
| | | })} |
| | | </Menu.ItemGroup> |
| | | ) |
| | | } else { |
| | | return ( |
| | | <Menu.Item key={scd.MenuID} onClick={(e) => e.stopPropagation()}> |
| | | <span onClick={(e) => e.stopPropagation()} onDoubleClick={() => this.changeMenu(scd)}>{scd.name}</span> |
| | | </Menu.Item> |
| | | ) |
| | | } |
| | | })} |
| | | </SubMenu> |
| | | ) |
| | | } else { |
| | | return ( |
| | | <Menu.Item key={fst.MenuID}> |
| | | <span onClick={(e) => e.stopPropagation()} onDoubleClick={() => this.changeMenu(fst)}>{fst.name}</span> |
| | | </Menu.Item> |
| | | ) |
| | | } |
| | | })} |
| | | </Menu> |
| | | </div> |
| | | <div className="link"> |
| | | {card.links.map(link => { |
| | | return <Button type="link" key={link.MenuID} onDoubleClick={() => this.changeMenu(link)}>{link.name}</Button> |
| | | })} |
| | | </div> |
| | | </div> |
| | | </div> |
| | | ) |
| | | } |
| | | } |
| | | |
| | | export default NormalNavbar |
New file |
| | |
| | | .normal-navbar-edit-box { |
| | | position: fixed; |
| | | top: 0px; |
| | | left: 0px; |
| | | width: 100%; |
| | | box-sizing: border-box; |
| | | background: #ffffff; |
| | | background-position: center center; |
| | | background-repeat: no-repeat; |
| | | background-size: cover; |
| | | min-height: 50px; |
| | | z-index: 3; |
| | | |
| | | .navbar-wrap { |
| | | margin: 0 auto; |
| | | display: flex; |
| | | max-width: 100%; |
| | | |
| | | .logo { |
| | | display: inline-block; |
| | | img { |
| | | max-width: 100%; |
| | | max-height: 100%; |
| | | } |
| | | } |
| | | .logo.pointer { |
| | | cursor: pointer; |
| | | } |
| | | .menu { |
| | | flex: 1; |
| | | display: inline-block; |
| | | font-size: inherit; |
| | | color: inherit; |
| | | .ant-menu { |
| | | background: transparent; |
| | | line-height: inherit; |
| | | font-size: inherit; |
| | | color: inherit; |
| | | border: 0; |
| | | .ant-menu-item:hover, .ant-menu-item-active, .ant-menu:not(.ant-menu-inline) .ant-menu-submenu-open, .ant-menu-submenu-active, .ant-menu-submenu-title:hover { |
| | | color: unset; |
| | | } |
| | | .ant-menu-item span { |
| | | display: inline-block; |
| | | } |
| | | } |
| | | .ant-menu-horizontal > .ant-menu-item:hover, .ant-menu-horizontal > .ant-menu-submenu:hover, .ant-menu-horizontal > .ant-menu-item-active, .ant-menu-horizontal > .ant-menu-submenu-active, .ant-menu-horizontal > .ant-menu-item-open, .ant-menu-horizontal > .ant-menu-submenu-open, .ant-menu-horizontal > .ant-menu-item-selected, .ant-menu-horizontal > .ant-menu-submenu-selected { |
| | | color: unset; |
| | | } |
| | | } |
| | | .link { |
| | | flex: 1; |
| | | display: inline-block; |
| | | text-align: right; |
| | | color: inherit; |
| | | button { |
| | | color: inherit; |
| | | } |
| | | } |
| | | } |
| | | .card-control { |
| | | position: absolute; |
| | | top: 0px; |
| | | left: 0px; |
| | | .anticon-tool { |
| | | right: auto; |
| | | left: 1px; |
| | | padding: 1px; |
| | | } |
| | | } |
| | | .anticon-tool { |
| | | position: absolute; |
| | | z-index: 2; |
| | | font-size: 16px; |
| | | right: 25px; |
| | | top: 1px; |
| | | cursor: pointer; |
| | | padding: 5px; |
| | | background: rgba(255, 255, 255, 0.55); |
| | | } |
| | | |
| | | .card-item { |
| | | overflow: hidden; |
| | | position: relative; |
| | | background-color: #ffffff; |
| | | background-position: center center; |
| | | background-repeat: no-repeat; |
| | | background-size: cover; |
| | | min-height: 20px; |
| | | } |
| | | |
| | | .card-item:hover { |
| | | box-shadow: 0px 0px 2px #1890ff; |
| | | } |
| | | |
| | | .model-menu-card-cell-list .card-detail-row > .anticon-plus { |
| | | position: absolute; |
| | | right: -30px; |
| | | font-size: 16px; |
| | | } |
| | | .model-menu-action-list { |
| | | line-height: 40px; |
| | | .ant-row > .anticon-plus { |
| | | position: absolute; |
| | | right: -30px; |
| | | font-size: 16px; |
| | | } |
| | | } |
| | | .card-add-button { |
| | | text-align: right; |
| | | clear: left; |
| | | .anticon-plus { |
| | | font-size: 20px; |
| | | color: #26C281; |
| | | padding: 5px; |
| | | margin-right: 10px; |
| | | } |
| | | } |
| | | .ant-pagination { |
| | | float: right; |
| | | margin: 10px; |
| | | } |
| | | |
| | | .model-menu-action-list { |
| | | .page-card { |
| | | line-height: 55px; |
| | | } |
| | | } |
| | | } |
| | | .normal-navbar-edit-box::after { |
| | | display: block; |
| | | content: ' '; |
| | | clear: both; |
| | | } |
| | | .normal-navbar-edit-box:hover { |
| | | box-shadow: 0px 0px 4px #1890ff; |
| | | } |
| | | .top-menu-popover { |
| | | padding-top: 0!important; |
| | | } |
| | | .normal-navbar-submenu { |
| | | .ant-menu-item-group { |
| | | float: left; |
| | | } |
| | | .ant-menu-item { |
| | | height: 32px; |
| | | line-height: 32px; |
| | | span { |
| | | display: inline-block; |
| | | width: 100%; |
| | | height: 100%; |
| | | padding: 0 16px 0 28px; |
| | | } |
| | | padding: 0; |
| | | } |
| | | .ant-menu .ant-menu-item-selected { |
| | | background-color: #ffffff; |
| | | } |
| | | } |
New file |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { is, fromJS } from 'immutable' |
| | | import { Icon, Modal } from 'antd' |
| | | |
| | | import zhCN from '@/locales/zh-CN/model.js' |
| | | import enUS from '@/locales/en-US/model.js' |
| | | import LinkTable from './linktable' |
| | | import './index.scss' |
| | | |
| | | class DataSource extends Component { |
| | | static propTpyes = { |
| | | config: PropTypes.any, |
| | | updateConfig: PropTypes.func |
| | | } |
| | | |
| | | state = { |
| | | dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | visible: false |
| | | } |
| | | |
| | | shouldComponentUpdate (nextProps, nextState) { |
| | | return !is(fromJS(this.props), fromJS(nextProps)) || !is(fromJS(this.state), fromJS(nextState)) |
| | | } |
| | | |
| | | verifySubmit = () => { |
| | | const { config } = this.props |
| | | |
| | | this.props.updateConfig({...config, links: this.mTable.state.data || []}) |
| | | this.setState({visible: false}) |
| | | } |
| | | |
| | | render () { |
| | | const { config } = this.props |
| | | const { visible, dict } = this.state |
| | | |
| | | return ( |
| | | <div className="model-link-setting-wrap"> |
| | | <Icon type="link" title="链接" onClick={() => this.setState({ visible: true })}/> |
| | | <Modal |
| | | wrapClassName="popview-modal" |
| | | title="链接编辑" |
| | | visible={visible} |
| | | width={950} |
| | | maskClosable={false} |
| | | okText={dict['model.submit']} |
| | | onOk={this.verifySubmit} |
| | | onCancel={() => { this.setState({ visible: false }) }} |
| | | destroyOnClose |
| | | > |
| | | <LinkTable |
| | | links={config.links || []} |
| | | ref={(ref) => { this.mTable = ref }} |
| | | /> |
| | | </Modal> |
| | | </div> |
| | | ) |
| | | } |
| | | } |
| | | |
| | | export default DataSource |
New file |
| | |
| | | .model-link-setting-wrap { |
| | | display: inline-block; |
| | | |
| | | >.anticon-link { |
| | | color: rgb(38, 194, 129); |
| | | } |
| | | |
| | | >.anticon-edit { |
| | | color: #1890ff; |
| | | } |
| | | } |
New file |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { Form, Row, Col, Input, Radio, Tooltip, Icon, Select } from 'antd' |
| | | |
| | | import './index.scss' |
| | | |
| | | const { TextArea } = Input |
| | | |
| | | class SettingForm extends Component { |
| | | static propTpyes = { |
| | | menu: PropTypes.object, // 卡片行信息 |
| | | inputSubmit: PropTypes.func // 回车事件 |
| | | } |
| | | |
| | | state = { |
| | | property: this.props.menu.property || 'link', |
| | | appMenus: [], |
| | | } |
| | | |
| | | UNSAFE_componentWillMount () { |
| | | let appMenus = sessionStorage.getItem('appMenus') |
| | | if (appMenus) { |
| | | try { |
| | | appMenus = JSON.parse(appMenus) |
| | | } catch { |
| | | appMenus = [] |
| | | } |
| | | } else { |
| | | appMenus = [] |
| | | } |
| | | |
| | | this.setState({appMenus}) |
| | | } |
| | | |
| | | componentDidMount() { |
| | | const { menu } = this.props |
| | | |
| | | if (!menu.MenuID) { |
| | | let _form = document.getElementById('name') |
| | | _form && _form.select() |
| | | } |
| | | } |
| | | |
| | | handleConfirm = () => { |
| | | // 表单提交时检查输入值是否正确 |
| | | return new Promise((resolve, reject) => { |
| | | this.props.form.validateFieldsAndScroll((err, values) => { |
| | | if (!err) { |
| | | resolve(values) |
| | | } else { |
| | | reject(err) |
| | | } |
| | | }) |
| | | }) |
| | | } |
| | | |
| | | handleSubmit = (e) => { |
| | | e.preventDefault() |
| | | |
| | | if (this.props.inputSubmit) { |
| | | this.props.inputSubmit() |
| | | } |
| | | } |
| | | |
| | | changeProperty = (e) => { |
| | | let val = e.target.value |
| | | |
| | | this.setState({property: val}) |
| | | } |
| | | |
| | | render() { |
| | | const { menu } = this.props |
| | | const { getFieldDecorator } = this.props.form |
| | | const { property, appMenus } = this.state |
| | | |
| | | const formItemLayout = { |
| | | labelCol: { |
| | | xs: { span: 24 }, |
| | | sm: { span: 8 } |
| | | }, |
| | | wrapperCol: { |
| | | xs: { span: 24 }, |
| | | sm: { span: 16 } |
| | | } |
| | | } |
| | | |
| | | return ( |
| | | <Form {...formItemLayout}> |
| | | <Row gutter={24}> |
| | | <Col span={22}> |
| | | <Form.Item label="链接名称"> |
| | | {getFieldDecorator('name', { |
| | | initialValue: menu.name, |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: '请输入链接名称!' |
| | | } |
| | | ] |
| | | })(<Input placeholder={''} autoComplete="off" onPressEnter={this.handleSubmit} />)} |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={22}> |
| | | <Form.Item label="链接属性"> |
| | | {getFieldDecorator('property', { |
| | | initialValue: menu.property || 'link' |
| | | })( |
| | | <Radio.Group onChange={this.changeProperty}> |
| | | <Radio value="link">链接</Radio> |
| | | <Radio value="linkmenu">关联菜单</Radio> |
| | | </Radio.Group> |
| | | )} |
| | | </Form.Item> |
| | | </Col> |
| | | {property === 'link' ? <Col span={22}> |
| | | <Form.Item label="链接地址"> |
| | | {getFieldDecorator('link', { |
| | | initialValue: menu.link || '', |
| | | rules: [{ |
| | | required: true, |
| | | message: '请输入链接地址!' |
| | | }] |
| | | })(<TextArea rows={2} />)} |
| | | </Form.Item> |
| | | </Col> : null} |
| | | <Col span={22}> |
| | | <Form.Item label="打开方式"> |
| | | {getFieldDecorator('open', { |
| | | initialValue: menu.open || 'blank' |
| | | })( |
| | | <Radio.Group> |
| | | <Radio value="blank">新窗口</Radio> |
| | | <Radio value="self">当前窗口</Radio> |
| | | </Radio.Group> |
| | | )} |
| | | </Form.Item> |
| | | </Col> |
| | | {property === 'linkmenu' ? <Col span={22}> |
| | | <Form.Item label={ |
| | | <Tooltip placement="topLeft" title="关联当前app中已有的菜单。"> |
| | | <Icon type="question-circle" style={{color: '#c49f47', marginRight: '3px'}}/> |
| | | 关联菜单 |
| | | </Tooltip> |
| | | }> |
| | | {getFieldDecorator('linkMenuId', { |
| | | initialValue: menu.linkMenuId || '', |
| | | rules: [{ |
| | | required: true, |
| | | message: '请选择关联菜单!' |
| | | }] |
| | | })( |
| | | <Select> |
| | | {appMenus.map(item => (<Select.Option key={item.MenuID} value={item.MenuID}>{item.MenuName}</Select.Option>))} |
| | | </Select> |
| | | )} |
| | | </Form.Item> |
| | | </Col> : null} |
| | | </Row> |
| | | </Form> |
| | | ) |
| | | } |
| | | } |
| | | |
| | | export default Form.create()(SettingForm) |
copy from src/mob/datasource/verifycard/columnform/index.scss
copy to src/pc/components/navbar/normal-navbar/linksetting/linkform/index.scss
New file |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { is, fromJS } from 'immutable' |
| | | import { Table, Button, Modal, Icon } from 'antd' |
| | | |
| | | import LinkForm from '../linkform' |
| | | import Utils from '@/utils/utils.js' |
| | | import './index.scss' |
| | | |
| | | const { confirm } = Modal |
| | | |
| | | class LinkTable extends Component { |
| | | static propTpyes = { |
| | | links: PropTypes.object, // 卡片行信息 |
| | | } |
| | | |
| | | state = { |
| | | data: [], |
| | | editMenu: null, |
| | | columns: [ |
| | | { title: '链接名称', dataIndex: 'name', key: 'name' }, |
| | | { title: '链接属性', dataIndex: 'property', key: 'property', render: text => { |
| | | const trans = {link: '链接', linkmenu: '关联菜单'} |
| | | |
| | | return trans[text] |
| | | }}, |
| | | { title: '链接地址', dataIndex: 'link', key: 'link'}, |
| | | { title: '打开方式', dataIndex: 'open', key: 'open', render: (text, record) => { |
| | | const trans = {blank: '新窗口', self: '当前窗口'} |
| | | |
| | | return trans[text] |
| | | }}, |
| | | { title: '操作', key: 'operation', align: 'center', width: '190px', render: (text, record) => |
| | | (<div> |
| | | <Button type="link" style={{padding: '0 5px', marginRight: '5px'}} onClick={() => this.editMenu(record)}>编辑</Button> |
| | | <Button type="link" style={{color: '#ff4d4f', padding: '0 5px', marginRight: '5px'}} onClick={() => this.delMenu(record)}>删除</Button> |
| | | <Icon type="arrow-up" style={{color: '#26C281', cursor: 'pointer', padding: '0 5px', marginRight: '5px'}} onClick={() => this.moveUp(record)}/> |
| | | <Icon type="arrow-down" style={{color: '#ff4d4f', cursor: 'pointer', padding: '0 5px'}} onClick={() => this.moveDown(record)}/> |
| | | </div>) |
| | | } |
| | | ] |
| | | } |
| | | |
| | | UNSAFE_componentWillMount () { |
| | | const { links } = this.props |
| | | |
| | | this.setState({data: fromJS(links).toJS()}) |
| | | } |
| | | |
| | | shouldComponentUpdate (nextProps, nextState) { |
| | | return !is(fromJS(this.state), fromJS(nextState)) |
| | | } |
| | | |
| | | moveUp = (record) => { |
| | | let data = fromJS(this.state.data).toJS() |
| | | |
| | | let dragIndex = data.findIndex(c => c.MenuID === record.MenuID) |
| | | let hoverIndex = dragIndex - 1 |
| | | |
| | | if (hoverIndex === -1) return |
| | | |
| | | data.splice(hoverIndex, 0, ...data.splice(dragIndex, 1)) |
| | | this.setState({data}) |
| | | } |
| | | |
| | | moveDown = (record) => { |
| | | let data = fromJS(this.state.data).toJS() |
| | | |
| | | let dragIndex = data.findIndex(c => c.MenuID === record.MenuID) |
| | | let hoverIndex = dragIndex + 1 |
| | | |
| | | if (hoverIndex === data.length) return |
| | | |
| | | data.splice(hoverIndex, 0, ...data.splice(dragIndex, 1)) |
| | | this.setState({data}) |
| | | } |
| | | |
| | | delMenu = (record) => { |
| | | const { data } = this.state |
| | | const _this = this |
| | | |
| | | confirm({ |
| | | title: '确定删除吗?', |
| | | content: '', |
| | | onOk() { |
| | | _this.setState({data: data.filter(item => item.MenuID !== record.MenuID)}) |
| | | }, |
| | | onCancel() {} |
| | | }) |
| | | } |
| | | |
| | | editMenu = (record) => { |
| | | this.setState({editMenu: record, visible: true}) |
| | | } |
| | | |
| | | plusMenu = () => { |
| | | let _menu = { |
| | | name: '链接' |
| | | } |
| | | |
| | | this.setState({editMenu: _menu, visible: true}) |
| | | } |
| | | |
| | | menuSubmit = () => { |
| | | const { editMenu, data } = this.state |
| | | |
| | | this.menuRef.handleConfirm().then(res => { |
| | | let _menu = {...editMenu, ...res} |
| | | if (!_menu.MenuID) { |
| | | _menu.MenuID = Utils.getuuid() |
| | | this.setState({data: [...data, _menu], editMenu: null, visible: false}) |
| | | } else { |
| | | this.setState({ |
| | | editMenu: null, |
| | | visible: false, |
| | | data: data.map(item => { |
| | | if (item.MenuID === _menu.MenuID) { |
| | | return _menu |
| | | } else { |
| | | return item |
| | | } |
| | | }) |
| | | }) |
| | | } |
| | | }) |
| | | } |
| | | |
| | | render() { |
| | | const { columns, data, visible, editMenu } = this.state |
| | | |
| | | return ( |
| | | <div className="link-control-wrap"> |
| | | <Button className="link-plus mk-green" onClick={this.plusMenu}>添加</Button> |
| | | <Table |
| | | rowKey="MenuID" |
| | | columns={columns} |
| | | dataSource={data} |
| | | pagination={false} |
| | | /> |
| | | <Modal |
| | | title="编辑" |
| | | visible={visible} |
| | | width={600} |
| | | maskClosable={false} |
| | | onOk={this.menuSubmit} |
| | | onCancel={() => { this.setState({ visible: false }) }} |
| | | destroyOnClose |
| | | > |
| | | <LinkForm |
| | | menu={editMenu} |
| | | inputSubmit={this.menuSubmit} |
| | | wrappedComponentRef={(inst) => this.menuRef = inst} |
| | | /> |
| | | </Modal> |
| | | </div> |
| | | ) |
| | | } |
| | | } |
| | | |
| | | export default LinkTable |
New file |
| | |
| | | .link-control-wrap { |
| | | position: relative; |
| | | |
| | | .link-plus { |
| | | float: right; |
| | | position: relative; |
| | | z-index: 1; |
| | | margin-bottom: 5px; |
| | | } |
| | | .ant-empty { |
| | | margin: 5px 0; |
| | | } |
| | | thead tr { |
| | | background: #fbfbfb; |
| | | } |
| | | |
| | | .ant-table-body { |
| | | margin: 0!important; |
| | | } |
| | | } |
New file |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { is, fromJS } from 'immutable' |
| | | import { Icon, Modal } from 'antd' |
| | | |
| | | import zhCN from '@/locales/zh-CN/model.js' |
| | | import enUS from '@/locales/en-US/model.js' |
| | | import MenuTable from './menutable' |
| | | import './index.scss' |
| | | |
| | | class DataSource extends Component { |
| | | static propTpyes = { |
| | | config: PropTypes.any, |
| | | updateConfig: PropTypes.func |
| | | } |
| | | |
| | | state = { |
| | | dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | visible: false |
| | | } |
| | | |
| | | shouldComponentUpdate (nextProps, nextState) { |
| | | return !is(fromJS(this.props), fromJS(nextProps)) || !is(fromJS(this.state), fromJS(nextState)) |
| | | } |
| | | |
| | | verifySubmit = () => { |
| | | const { config } = this.props |
| | | let menus = this.mTable.state.data || [] |
| | | |
| | | this.props.updateConfig({...config, menus}) |
| | | this.setState({visible: false}) |
| | | } |
| | | |
| | | render () { |
| | | const { config } = this.props |
| | | const { visible, dict } = this.state |
| | | |
| | | return ( |
| | | <div className="model-menu-setting-wrap"> |
| | | <Icon type="menu" title="菜单" onClick={() => this.setState({ visible: true })}/> |
| | | <Modal |
| | | wrapClassName="popview-modal" |
| | | title="菜单编辑" |
| | | visible={visible} |
| | | width={950} |
| | | maskClosable={false} |
| | | okText={dict['model.submit']} |
| | | onOk={this.verifySubmit} |
| | | onCancel={() => { this.setState({ visible: false }) }} |
| | | destroyOnClose |
| | | > |
| | | <MenuTable |
| | | menus={config.menus} |
| | | ref={(ref) => { this.mTable = ref }} |
| | | /> |
| | | </Modal> |
| | | </div> |
| | | ) |
| | | } |
| | | } |
| | | |
| | | export default DataSource |
New file |
| | |
| | | .model-menu-setting-wrap { |
| | | display: inline-block; |
| | | |
| | | >.anticon-menu { |
| | | color: purple; |
| | | } |
| | | |
| | | >.anticon-edit { |
| | | color: #1890ff; |
| | | } |
| | | } |
New file |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { Form, Row, Col, Input, Radio, Tooltip, Icon, Select } from 'antd' |
| | | |
| | | import './index.scss' |
| | | |
| | | const { TextArea } = Input |
| | | |
| | | class SettingForm extends Component { |
| | | static propTpyes = { |
| | | menu: PropTypes.object, // 卡片行信息 |
| | | inputSubmit: PropTypes.func // 回车事件 |
| | | } |
| | | |
| | | state = { |
| | | property: this.props.menu.property || 'menu', |
| | | appMenus: [], |
| | | } |
| | | |
| | | UNSAFE_componentWillMount () { |
| | | let appMenus = sessionStorage.getItem('appMenus') |
| | | if (appMenus) { |
| | | try { |
| | | appMenus = JSON.parse(appMenus) |
| | | } catch { |
| | | appMenus = [] |
| | | } |
| | | } else { |
| | | appMenus = [] |
| | | } |
| | | |
| | | this.setState({appMenus}) |
| | | } |
| | | |
| | | componentDidMount() { |
| | | const { menu } = this.props |
| | | |
| | | if (!menu.MenuID) { |
| | | let _form = document.getElementById('name') |
| | | _form && _form.select() |
| | | } |
| | | } |
| | | |
| | | handleConfirm = () => { |
| | | // 表单提交时检查输入值是否正确 |
| | | return new Promise((resolve, reject) => { |
| | | this.props.form.validateFieldsAndScroll((err, values) => { |
| | | if (!err) { |
| | | resolve(values) |
| | | } else { |
| | | reject(err) |
| | | } |
| | | }) |
| | | }) |
| | | } |
| | | |
| | | handleSubmit = (e) => { |
| | | e.preventDefault() |
| | | |
| | | if (this.props.inputSubmit) { |
| | | this.props.inputSubmit() |
| | | } |
| | | } |
| | | |
| | | changeProperty = (e) => { |
| | | let val = e.target.value |
| | | |
| | | this.setState({property: val}) |
| | | } |
| | | |
| | | render() { |
| | | const { menu } = this.props |
| | | const { getFieldDecorator } = this.props.form |
| | | const { property, appMenus } = this.state |
| | | |
| | | const formItemLayout = { |
| | | labelCol: { |
| | | xs: { span: 24 }, |
| | | sm: { span: 8 } |
| | | }, |
| | | wrapperCol: { |
| | | xs: { span: 24 }, |
| | | sm: { span: 16 } |
| | | } |
| | | } |
| | | |
| | | return ( |
| | | <Form {...formItemLayout}> |
| | | <Row gutter={24}> |
| | | <Col span={22}> |
| | | <Form.Item label="菜单名称"> |
| | | {getFieldDecorator('name', { |
| | | initialValue: menu.name, |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: '请输入菜单名称!' |
| | | } |
| | | ] |
| | | })(<Input placeholder={''} autoComplete="off" onPressEnter={this.handleSubmit} />)} |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={22}> |
| | | <Form.Item label="菜单参数"> |
| | | {getFieldDecorator('MenuNo', { |
| | | initialValue: menu.MenuNo || '', |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: '请输入菜单参数!' |
| | | } |
| | | ] |
| | | })(<Input placeholder={''} autoComplete="off" onPressEnter={this.handleSubmit} />)} |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={22}> |
| | | <Form.Item label="菜单属性"> |
| | | {getFieldDecorator('property', { |
| | | initialValue: menu.property || 'menu' |
| | | })( |
| | | <Radio.Group onChange={this.changeProperty}> |
| | | <Radio value="menu">菜单</Radio> |
| | | <Radio value="link">链接</Radio> |
| | | <Radio value="linkmenu">关联菜单</Radio> |
| | | {menu.level === 1 || menu.level === 2 ? <Radio value="classify">分类</Radio> : null} |
| | | </Radio.Group> |
| | | )} |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={22}> |
| | | <Form.Item label="隐藏"> |
| | | {getFieldDecorator('hidden', { |
| | | initialValue: menu.hidden || 'false' |
| | | })( |
| | | <Radio.Group> |
| | | <Radio value="false">否</Radio> |
| | | <Radio value="true">是</Radio> |
| | | </Radio.Group> |
| | | )} |
| | | </Form.Item> |
| | | </Col> |
| | | {property === 'link' ? <Col span={22}> |
| | | <Form.Item label="链接地址"> |
| | | {getFieldDecorator('link', { |
| | | initialValue: menu.link || '', |
| | | rules: [{ |
| | | required: true, |
| | | message: '请输入链接地址!' |
| | | }] |
| | | })(<TextArea rows={2} />)} |
| | | </Form.Item> |
| | | </Col> : null} |
| | | {property !== 'classify' ? <Col span={22}> |
| | | <Form.Item label="打开方式"> |
| | | {getFieldDecorator('open', { |
| | | initialValue: menu.open || 'blank' |
| | | })( |
| | | <Radio.Group> |
| | | <Radio value="blank">新窗口</Radio> |
| | | <Radio value="self">当前窗口</Radio> |
| | | </Radio.Group> |
| | | )} |
| | | </Form.Item> |
| | | </Col> : null} |
| | | {property === 'linkmenu' ? <Col span={22}> |
| | | <Form.Item label={ |
| | | <Tooltip placement="topLeft" title="关联当前app中已有的菜单。"> |
| | | <Icon type="question-circle" style={{color: '#c49f47', marginRight: '3px'}}/> |
| | | 关联菜单 |
| | | </Tooltip> |
| | | }> |
| | | {getFieldDecorator('linkMenuId', { |
| | | initialValue: menu.linkMenuId || '', |
| | | rules: [{ |
| | | required: true, |
| | | message: '请选择关联菜单!' |
| | | }] |
| | | })( |
| | | <Select> |
| | | {appMenus.map(item => (<Select.Option key={item.MenuID} value={item.MenuID}>{item.MenuName}</Select.Option>))} |
| | | </Select> |
| | | )} |
| | | </Form.Item> |
| | | </Col> : null} |
| | | {property === 'menu' ? <Col span={22}> |
| | | <Form.Item label={ |
| | | <Tooltip placement="topLeft" title="复制菜单仅在当前菜单不存在时有效。"> |
| | | <Icon type="question-circle" style={{color: '#c49f47', marginRight: '3px'}}/> |
| | | 复制菜单 |
| | | </Tooltip> |
| | | }> |
| | | {getFieldDecorator('copyMenuId', { |
| | | initialValue: menu.copyMenuId || '' |
| | | })( |
| | | <Select> |
| | | {appMenus.map(item => (<Select.Option key={item.MenuID} value={item.MenuID}>{item.MenuName}</Select.Option>))} |
| | | </Select> |
| | | )} |
| | | </Form.Item> |
| | | </Col> : null} |
| | | </Row> |
| | | </Form> |
| | | ) |
| | | } |
| | | } |
| | | |
| | | export default Form.create()(SettingForm) |
copy from src/mob/datasource/verifycard/columnform/index.scss
copy to src/pc/components/navbar/normal-navbar/menusetting/menuform/index.scss
New file |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { is, fromJS } from 'immutable' |
| | | import { Table, Button, Modal, Icon } from 'antd' |
| | | |
| | | import MenuForm from '../menuform' |
| | | import Utils from '@/utils/utils.js' |
| | | import MKEmitter from '@/utils/events.js' |
| | | import './index.scss' |
| | | |
| | | const { confirm } = Modal |
| | | |
| | | class ThdTable extends Component { |
| | | static propTpyes = { |
| | | menus: PropTypes.object, // 卡片行信息 |
| | | menuUpdate: PropTypes.func // 卡片行信息 |
| | | } |
| | | |
| | | state = { |
| | | data: [], |
| | | editMenu: null, |
| | | columns: [ |
| | | { title: '菜单名称', dataIndex: 'name', key: 'name' }, |
| | | { title: '菜单参数', dataIndex: 'MenuNo', key: 'MenuNo' }, |
| | | { title: '菜单属性', dataIndex: 'property', key: 'property', render: text => { |
| | | const trans = {menu: '菜单', link: '链接', linkmenu: '关联菜单', classify: '分类'} |
| | | |
| | | return trans[text] |
| | | }}, |
| | | { title: '打开方式', dataIndex: 'open', key: 'open', render: (text, record) => { |
| | | if (record.property === 'classify') return '' |
| | | |
| | | const trans = {blank: '新窗口', self: '当前窗口'} |
| | | |
| | | return trans[text] |
| | | }}, |
| | | { title: '是否隐藏', dataIndex: 'hidden', key: 'hidden', render: (text, record) => { |
| | | const trans = {'true': '是', 'false': '否'} |
| | | return trans[text] || '否' |
| | | }}, |
| | | { title: '操作', key: 'operation', align: 'center', width: '190px', render: (text, record) => |
| | | (<div> |
| | | <Button type="link" style={{padding: '0 5px', marginRight: '5px'}} onClick={() => this.editMenu(record)}>编辑</Button> |
| | | <Button type="link" style={{color: '#ff4d4f', padding: '0 5px', marginRight: '5px'}} onClick={() => this.delMenu(record)}>删除</Button> |
| | | <Icon type="arrow-up" style={{color: '#26C281', cursor: 'pointer', padding: '0 5px', marginRight: '5px'}} onClick={() => this.moveUp(record)}/> |
| | | <Icon type="arrow-down" style={{color: '#ff4d4f', cursor: 'pointer', padding: '0 5px'}} onClick={() => this.moveDown(record)}/> |
| | | </div>) |
| | | } |
| | | ] |
| | | } |
| | | |
| | | UNSAFE_componentWillMount () { |
| | | const { menu } = this.props |
| | | this.setState({data: menu.sublist ? fromJS(menu.sublist).toJS() : []}) |
| | | } |
| | | |
| | | shouldComponentUpdate (nextProps, nextState) { |
| | | return !is(fromJS(this.state), fromJS(nextState)) |
| | | } |
| | | |
| | | moveUp = (record) => { |
| | | const { menu } = this.props |
| | | let data = fromJS(this.state.data).toJS() |
| | | |
| | | let dragIndex = data.findIndex(c => c.MenuID === record.MenuID) |
| | | let hoverIndex = dragIndex - 1 |
| | | |
| | | if (hoverIndex === -1) return |
| | | |
| | | data.splice(hoverIndex, 0, ...data.splice(dragIndex, 1)) |
| | | this.setState({data}) |
| | | this.props.menuUpdate({...menu, sublist: data}) |
| | | } |
| | | |
| | | moveDown = (record) => { |
| | | const { menu } = this.props |
| | | let data = fromJS(this.state.data).toJS() |
| | | |
| | | let dragIndex = data.findIndex(c => c.MenuID === record.MenuID) |
| | | let hoverIndex = dragIndex + 1 |
| | | |
| | | if (hoverIndex === data.length) return |
| | | |
| | | data.splice(hoverIndex, 0, ...data.splice(dragIndex, 1)) |
| | | this.setState({data}) |
| | | this.props.menuUpdate({...menu, sublist: data}) |
| | | } |
| | | |
| | | delMenu = (record) => { |
| | | const { menu } = this.props |
| | | const _this = this |
| | | |
| | | confirm({ |
| | | title: '确定删除吗?', |
| | | content: '', |
| | | onOk() { |
| | | let _data = _this.state.data.filter(item => item.MenuID !== record.MenuID) |
| | | _this.setState({data: _data}) |
| | | _this.props.menuUpdate({...menu, sublist: _data}) |
| | | MKEmitter.emit('delButtons', [record.MenuID]) |
| | | }, |
| | | onCancel() {} |
| | | }) |
| | | } |
| | | |
| | | editMenu = (record) => { |
| | | this.setState({editMenu: record, visible: true}) |
| | | } |
| | | |
| | | plusMenu = () => { |
| | | let _menu = { |
| | | name: '菜单', |
| | | property: 'menu', |
| | | level: 3, |
| | | sublist: [] |
| | | } |
| | | |
| | | this.setState({editMenu: _menu, visible: true}) |
| | | } |
| | | |
| | | menuSubmit = () => { |
| | | const { menu } = this.props |
| | | const { editMenu } = this.state |
| | | |
| | | this.menuRef.handleConfirm().then(res => { |
| | | let _menu = {...editMenu, ...res} |
| | | let _data = this.state.data |
| | | if (!_menu.MenuID) { |
| | | _menu.MenuID = Utils.getuuid() |
| | | _data.push(_menu) |
| | | } else { |
| | | _data = _data.map(item => { |
| | | if (item.MenuID === _menu.MenuID) { |
| | | return _menu |
| | | } else { |
| | | return item |
| | | } |
| | | }) |
| | | } |
| | | this.setState({data: _data, editMenu: null, visible: false}) |
| | | this.props.menuUpdate({...menu, sublist: _data}) |
| | | }) |
| | | } |
| | | |
| | | render() { |
| | | const { columns, data, visible, editMenu } = this.state |
| | | |
| | | return ( |
| | | <div className="thdmenu-control-wrap"> |
| | | <Icon type="plus" style={{color: '#26C281', padding: '5px', fontSize: '16px'}} onClick={this.plusMenu}/> |
| | | <Table |
| | | rowKey="MenuID" |
| | | size="small" |
| | | columns={columns} |
| | | dataSource={data} |
| | | pagination={false} |
| | | /> |
| | | <Modal |
| | | title="编辑" |
| | | visible={visible} |
| | | width={600} |
| | | maskClosable={false} |
| | | onOk={this.menuSubmit} |
| | | onCancel={() => { this.setState({ visible: false }) }} |
| | | destroyOnClose |
| | | > |
| | | <MenuForm |
| | | menu={editMenu} |
| | | inputSubmit={this.menuSubmit} |
| | | wrappedComponentRef={(inst) => this.menuRef = inst} |
| | | /> |
| | | </Modal> |
| | | </div> |
| | | ) |
| | | } |
| | | } |
| | | |
| | | class SubTable extends Component { |
| | | static propTpyes = { |
| | | menu: PropTypes.object, // 卡片行信息 |
| | | menuUpdate: PropTypes.func // 卡片行信息 |
| | | } |
| | | |
| | | state = { |
| | | data: [], |
| | | editMenu: null, |
| | | columns: [ |
| | | { title: '菜单名称', dataIndex: 'name', key: 'name' }, |
| | | { title: '菜单参数', dataIndex: 'MenuNo', key: 'MenuNo' }, |
| | | { title: '菜单属性', dataIndex: 'property', key: 'property', render: text => { |
| | | const trans = {menu: '菜单', link: '链接', linkmenu: '关联菜单', classify: '分类'} |
| | | |
| | | return trans[text] |
| | | }}, |
| | | { title: '打开方式', dataIndex: 'open', key: 'open', render: (text, record) => { |
| | | if (record.property === 'classify') return '' |
| | | |
| | | const trans = {blank: '新窗口', self: '当前窗口'} |
| | | |
| | | return trans[text] |
| | | }}, |
| | | { title: '是否隐藏', dataIndex: 'hidden', key: 'hidden', render: (text, record) => { |
| | | const trans = {'true': '是', 'false': '否'} |
| | | return trans[text] || '否' |
| | | }}, |
| | | { title: '操作', key: 'operation', align: 'center', width: '190px', render: (text, record) => |
| | | (<div> |
| | | <Button type="link" style={{padding: '0 5px', marginRight: '5px'}} onClick={() => this.editMenu(record)}>编辑</Button> |
| | | <Button type="link" style={{color: '#ff4d4f', padding: '0 5px', marginRight: '5px'}} onClick={() => this.delMenu(record)}>删除</Button> |
| | | <Icon type="arrow-up" style={{color: '#26C281', cursor: 'pointer', padding: '0 5px', marginRight: '5px'}} onClick={() => this.moveUp(record)}/> |
| | | <Icon type="arrow-down" style={{color: '#ff4d4f', cursor: 'pointer', padding: '0 5px'}} onClick={() => this.moveDown(record)}/> |
| | | </div>) |
| | | } |
| | | ] |
| | | } |
| | | |
| | | UNSAFE_componentWillMount () { |
| | | const { menu } = this.props |
| | | |
| | | this.setState({data: menu.sublist ? fromJS(menu.sublist).toJS() : []}) |
| | | } |
| | | |
| | | shouldComponentUpdate (nextProps, nextState) { |
| | | return !is(fromJS(this.state), fromJS(nextState)) |
| | | } |
| | | |
| | | moveUp = (record) => { |
| | | const { menu } = this.props |
| | | let data = fromJS(this.state.data).toJS() |
| | | |
| | | let dragIndex = data.findIndex(c => c.MenuID === record.MenuID) |
| | | let hoverIndex = dragIndex - 1 |
| | | |
| | | if (hoverIndex === -1) return |
| | | |
| | | data.splice(hoverIndex, 0, ...data.splice(dragIndex, 1)) |
| | | this.setState({data}) |
| | | this.props.menuUpdate({...menu, sublist: data}) |
| | | } |
| | | |
| | | moveDown = (record) => { |
| | | const { menu } = this.props |
| | | let data = fromJS(this.state.data).toJS() |
| | | |
| | | let dragIndex = data.findIndex(c => c.MenuID === record.MenuID) |
| | | let hoverIndex = dragIndex + 1 |
| | | |
| | | if (hoverIndex === data.length) return |
| | | |
| | | data.splice(hoverIndex, 0, ...data.splice(dragIndex, 1)) |
| | | this.setState({data}) |
| | | this.props.menuUpdate({...menu, sublist: data}) |
| | | } |
| | | |
| | | delMenu = (record) => { |
| | | const { menu } = this.props |
| | | const _this = this |
| | | |
| | | confirm({ |
| | | title: (record.property === 'classify' && record.sublist.length > 0 ? '菜单下含有子菜单,' : '') + '确定删除吗?', |
| | | content: '', |
| | | onOk() { |
| | | let _data = _this.state.data.filter(item => item.MenuID !== record.MenuID) |
| | | _this.setState({data: _data}) |
| | | _this.props.menuUpdate({...menu, sublist: _data}) |
| | | |
| | | let uuids = [record.MenuID] |
| | | record.sublist && record.sublist.forEach(item => { |
| | | uuids.push(item.MenuID) |
| | | }) |
| | | MKEmitter.emit('delButtons', uuids) |
| | | }, |
| | | onCancel() {} |
| | | }) |
| | | } |
| | | |
| | | editMenu = (record) => { |
| | | this.setState({editMenu: record, visible: true}) |
| | | } |
| | | |
| | | plusMenu = () => { |
| | | let _menu = { |
| | | name: '菜单', |
| | | property: 'classify', |
| | | level: 2, |
| | | sublist: [] |
| | | } |
| | | |
| | | this.setState({editMenu: _menu, visible: true}) |
| | | } |
| | | |
| | | menuSubmit = () => { |
| | | const { menu } = this.props |
| | | const { editMenu } = this.state |
| | | |
| | | this.menuRef.handleConfirm().then(res => { |
| | | let _menu = {...editMenu, ...res} |
| | | let _data = this.state.data |
| | | if (!_menu.MenuID) { |
| | | _menu.MenuID = Utils.getuuid() |
| | | _data.push(_menu) |
| | | } else { |
| | | _data = _data.map(item => { |
| | | if (item.MenuID === _menu.MenuID) { |
| | | return _menu |
| | | } else { |
| | | return item |
| | | } |
| | | }) |
| | | } |
| | | this.setState({data: _data, editMenu: null, visible: false}) |
| | | this.props.menuUpdate({...menu, sublist: _data}) |
| | | }) |
| | | } |
| | | |
| | | menuUpdate = (res) => { |
| | | const { menu } = this.props |
| | | |
| | | let _data = this.state.data.map(item => { |
| | | if (item.MenuID === res.MenuID) { |
| | | return res |
| | | } else { |
| | | return item |
| | | } |
| | | }) |
| | | |
| | | this.setState({data: _data}) |
| | | this.props.menuUpdate({...menu, sublist: _data}) |
| | | } |
| | | |
| | | render() { |
| | | const { columns, data, visible, editMenu } = this.state |
| | | |
| | | return ( |
| | | <div className="submenu-control-wrap"> |
| | | <Icon type="plus" style={{color: '#26C281', padding: '5px', fontSize: '16px'}} onClick={this.plusMenu}/> |
| | | <Table |
| | | size="middle" |
| | | rowKey="MenuID" |
| | | columns={columns} |
| | | rowClassName={record => record.property} |
| | | expandedRowRender={record => <ThdTable menu={record} menuUpdate={this.menuUpdate} />} |
| | | dataSource={data} |
| | | pagination={false} |
| | | /> |
| | | <Modal |
| | | title="编辑" |
| | | visible={visible} |
| | | width={600} |
| | | maskClosable={false} |
| | | onOk={this.menuSubmit} |
| | | onCancel={() => { this.setState({ visible: false }) }} |
| | | destroyOnClose |
| | | > |
| | | <MenuForm |
| | | menu={editMenu} |
| | | inputSubmit={this.menuSubmit} |
| | | wrappedComponentRef={(inst) => this.menuRef = inst} |
| | | /> |
| | | </Modal> |
| | | </div> |
| | | ) |
| | | } |
| | | } |
| | | |
| | | class MenuTable extends Component { |
| | | static propTpyes = { |
| | | menus: PropTypes.object, // 卡片行信息 |
| | | } |
| | | |
| | | state = { |
| | | data: [], |
| | | editMenu: null, |
| | | columns: [ |
| | | { title: '菜单名称', dataIndex: 'name', key: 'name' }, |
| | | { title: '菜单参数', dataIndex: 'MenuNo', key: 'MenuNo' }, |
| | | { title: '菜单属性', dataIndex: 'property', key: 'property', render: text => { |
| | | const trans = {menu: '菜单', link: '链接', linkmenu: '关联菜单', classify: '分类'} |
| | | |
| | | return trans[text] |
| | | }}, |
| | | { title: '打开方式', dataIndex: 'open', key: 'open', render: (text, record) => { |
| | | if (record.property === 'classify') return '' |
| | | |
| | | const trans = {blank: '新窗口', self: '当前窗口'} |
| | | |
| | | return trans[text] |
| | | }}, |
| | | { title: '是否隐藏', dataIndex: 'hidden', key: 'hidden', render: (text, record) => { |
| | | const trans = {'true': '是', 'false': '否'} |
| | | return trans[text] || '否' |
| | | }}, |
| | | { title: '操作', key: 'operation', align: 'center', width: '190px', render: (text, record) => |
| | | (<div> |
| | | <Button type="link" style={{padding: '0 5px', marginRight: '5px'}} onClick={() => this.editMenu(record)}>编辑</Button> |
| | | <Button type="link" style={{color: '#ff4d4f', padding: '0 5px', marginRight: '5px'}} onClick={() => this.delMenu(record)}>删除</Button> |
| | | <Icon type="arrow-up" style={{color: '#26C281', cursor: 'pointer', padding: '0 5px', marginRight: '5px'}} onClick={() => this.moveUp(record)}/> |
| | | <Icon type="arrow-down" style={{color: '#ff4d4f', cursor: 'pointer', padding: '0 5px'}} onClick={() => this.moveDown(record)}/> |
| | | </div>) |
| | | } |
| | | ] |
| | | } |
| | | |
| | | UNSAFE_componentWillMount () { |
| | | const { menus } = this.props |
| | | |
| | | this.setState({data: fromJS(menus).toJS()}) |
| | | } |
| | | |
| | | shouldComponentUpdate (nextProps, nextState) { |
| | | return !is(fromJS(this.state), fromJS(nextState)) |
| | | } |
| | | |
| | | moveUp = (record) => { |
| | | let data = fromJS(this.state.data).toJS() |
| | | |
| | | let dragIndex = data.findIndex(c => c.MenuID === record.MenuID) |
| | | let hoverIndex = dragIndex - 1 |
| | | |
| | | if (hoverIndex === -1) return |
| | | |
| | | data.splice(hoverIndex, 0, ...data.splice(dragIndex, 1)) |
| | | this.setState({data}) |
| | | } |
| | | |
| | | moveDown = (record) => { |
| | | let data = fromJS(this.state.data).toJS() |
| | | |
| | | let dragIndex = data.findIndex(c => c.MenuID === record.MenuID) |
| | | let hoverIndex = dragIndex + 1 |
| | | |
| | | if (hoverIndex === data.length) return |
| | | |
| | | data.splice(hoverIndex, 0, ...data.splice(dragIndex, 1)) |
| | | this.setState({data}) |
| | | } |
| | | |
| | | delMenu = (record) => { |
| | | const { data } = this.state |
| | | const _this = this |
| | | |
| | | confirm({ |
| | | title: (record.property === 'classify' && record.sublist.length > 0 ? '菜单下含有子菜单,' : '') + '确定删除吗?', |
| | | content: '', |
| | | onOk() { |
| | | _this.setState({data: data.filter(item => item.MenuID !== record.MenuID)}) |
| | | |
| | | let uuids = [record.MenuID] |
| | | record.sublist && record.sublist.forEach(item => { |
| | | uuids.push(item.MenuID) |
| | | |
| | | item.sublist && item.sublist.forEach(cell => { |
| | | uuids.push(cell.MenuID) |
| | | }) |
| | | }) |
| | | MKEmitter.emit('delButtons', uuids) |
| | | }, |
| | | onCancel() {} |
| | | }) |
| | | } |
| | | |
| | | editMenu = (record) => { |
| | | this.setState({editMenu: record, visible: true}) |
| | | } |
| | | |
| | | plusMenu = () => { |
| | | let _menu = { |
| | | name: '菜单', |
| | | property: 'classify', |
| | | level: 1, |
| | | sublist: [] |
| | | } |
| | | |
| | | this.setState({editMenu: _menu, visible: true}) |
| | | } |
| | | |
| | | menuSubmit = () => { |
| | | const { editMenu, data } = this.state |
| | | |
| | | this.menuRef.handleConfirm().then(res => { |
| | | let _menu = {...editMenu, ...res} |
| | | if (!_menu.MenuID) { |
| | | _menu.MenuID = Utils.getuuid() |
| | | this.setState({data: [...data, _menu], editMenu: null, visible: false}) |
| | | } else { |
| | | this.setState({ |
| | | editMenu: null, |
| | | visible: false, |
| | | data: data.map(item => { |
| | | if (item.MenuID === _menu.MenuID) { |
| | | return _menu |
| | | } else { |
| | | return item |
| | | } |
| | | }) |
| | | }) |
| | | } |
| | | }) |
| | | } |
| | | |
| | | menuUpdate = (res) => { |
| | | const { data } = this.state |
| | | |
| | | this.setState({ |
| | | data: data.map(item => { |
| | | if (item.MenuID === res.MenuID) { |
| | | return res |
| | | } else { |
| | | return item |
| | | } |
| | | }) |
| | | }) |
| | | } |
| | | |
| | | render() { |
| | | const { columns, data, visible, editMenu } = this.state |
| | | |
| | | return ( |
| | | <div className="menu-control-wrap"> |
| | | <Button className="menu-plus mk-green" onClick={this.plusMenu}>添加</Button> |
| | | <Table |
| | | rowKey="MenuID" |
| | | columns={columns} |
| | | rowClassName={record => record.property} |
| | | expandedRowRender={record => <SubTable menu={record} menuUpdate={this.menuUpdate} />} |
| | | dataSource={data} |
| | | pagination={false} |
| | | /> |
| | | <Modal |
| | | title="编辑" |
| | | visible={visible} |
| | | width={600} |
| | | maskClosable={false} |
| | | onOk={this.menuSubmit} |
| | | onCancel={() => { this.setState({ visible: false }) }} |
| | | destroyOnClose |
| | | > |
| | | <MenuForm |
| | | menu={editMenu} |
| | | inputSubmit={this.menuSubmit} |
| | | wrappedComponentRef={(inst) => this.menuRef = inst} |
| | | /> |
| | | </Modal> |
| | | </div> |
| | | ) |
| | | } |
| | | } |
| | | |
| | | export default MenuTable |
New file |
| | |
| | | .menu-control-wrap { |
| | | position: relative; |
| | | |
| | | .menu-plus { |
| | | float: right; |
| | | position: relative; |
| | | z-index: 1; |
| | | margin-bottom: 5px; |
| | | } |
| | | .ant-empty { |
| | | margin: 5px 0; |
| | | } |
| | | thead tr { |
| | | background: #fbfbfb; |
| | | } |
| | | tbody > tr:not(.ant-table-expanded-row) { |
| | | background: #ffffff; |
| | | } |
| | | tr:not(.classify) { |
| | | > td { |
| | | >.ant-table-row-expand-icon-cell { |
| | | div { |
| | | display: none; |
| | | } |
| | | } |
| | | >.ant-table-row-expand-icon { |
| | | display: none; |
| | | } |
| | | } |
| | | } |
| | | tr:not(.classify) + .ant-table-expanded-row { |
| | | display: none; |
| | | } |
| | | td[colspan="6"] { |
| | | padding: 5px 0px 5px 5px!important; |
| | | } |
| | | .ant-table-body { |
| | | margin: 0!important; |
| | | } |
| | | |
| | | .submenu-control-wrap { |
| | | position: relative; |
| | | |
| | | .anticon-plus { |
| | | position: absolute; |
| | | top: 8px; |
| | | right: 10px; |
| | | z-index: 1; |
| | | } |
| | | |
| | | .thdmenu-control-wrap { |
| | | position: relative; |
| | | .ant-table-row-indent { |
| | | display: none; |
| | | } |
| | | .ant-table-row-expand-icon { |
| | | display: none; |
| | | } |
| | | .ant-table-small { |
| | | border: 0; |
| | | } |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { is, fromJS } from 'immutable' |
| | | import { Icon, Modal } from 'antd' |
| | | |
| | | import zhCN from '@/locales/zh-CN/model.js' |
| | | import enUS from '@/locales/en-US/model.js' |
| | | import SettingForm from './settingform' |
| | | import './index.scss' |
| | | |
| | | class DataSource extends Component { |
| | | static propTpyes = { |
| | | config: PropTypes.any, |
| | | updateConfig: PropTypes.func |
| | | } |
| | | |
| | | state = { |
| | | dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | visible: false, |
| | | wrap: null |
| | | } |
| | | |
| | | UNSAFE_componentWillMount () { |
| | | const { config } = this.props |
| | | |
| | | this.setState({wrap: fromJS(config.wrap).toJS()}) |
| | | } |
| | | |
| | | shouldComponentUpdate (nextProps, nextState) { |
| | | return !is(fromJS(this.props), fromJS(nextProps)) || !is(fromJS(this.state), fromJS(nextState)) |
| | | } |
| | | |
| | | editDataSource = () => { |
| | | this.setState({ |
| | | visible: true |
| | | }) |
| | | } |
| | | |
| | | verifySubmit = () => { |
| | | const { config } = this.props |
| | | |
| | | this.verifyRef.handleConfirm().then(res => { |
| | | |
| | | this.setState({ |
| | | wrap: res, |
| | | visible: false |
| | | }) |
| | | this.props.updateConfig({...config, wrap: res}) |
| | | }) |
| | | } |
| | | |
| | | render () { |
| | | const { config } = this.props |
| | | const { visible, dict, wrap } = this.state |
| | | |
| | | return ( |
| | | <div className="model-menu-setting-wrap"> |
| | | <Icon type="edit" title="编辑" onClick={() => this.editDataSource()} /> |
| | | <Modal |
| | | wrapClassName="popview-modal" |
| | | title={config.type === 'table' ? '表格设置' : '卡片设置'} |
| | | visible={visible} |
| | | width={800} |
| | | maskClosable={false} |
| | | okText={dict['model.submit']} |
| | | onOk={this.verifySubmit} |
| | | onCancel={() => { this.setState({ visible: false }) }} |
| | | destroyOnClose |
| | | > |
| | | <SettingForm |
| | | dict={dict} |
| | | wrap={wrap} |
| | | config={config} |
| | | inputSubmit={this.verifySubmit} |
| | | wrappedComponentRef={(inst) => this.verifyRef = inst} |
| | | /> |
| | | </Modal> |
| | | </div> |
| | | ) |
| | | } |
| | | } |
| | | |
| | | export default DataSource |
New file |
| | |
| | | .model-menu-setting-wrap { |
| | | display: inline-block; |
| | | |
| | | >.anticon-edit { |
| | | color: #1890ff; |
| | | } |
| | | } |
New file |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { Form, Row, Col, Input, Tooltip, Icon, InputNumber, Select, Radio } from 'antd' |
| | | |
| | | import asyncComponent from '@/utils/asyncComponent' |
| | | import './index.scss' |
| | | |
| | | const SourceComponent = asyncComponent(() => import('@/menu/components/share/sourcecomponent')) |
| | | |
| | | class SettingForm extends Component { |
| | | static propTpyes = { |
| | | dict: PropTypes.object, // 字典项 |
| | | config: PropTypes.object, // 卡片行信息 |
| | | wrap: PropTypes.object, // 数据源配置 |
| | | inputSubmit: PropTypes.func // 回车事件 |
| | | } |
| | | |
| | | state = { |
| | | appMenus: [] |
| | | } |
| | | |
| | | UNSAFE_componentWillMount () { |
| | | let appMenus = sessionStorage.getItem('appMenus') |
| | | if (appMenus) { |
| | | try { |
| | | appMenus = JSON.parse(appMenus) |
| | | } catch { |
| | | appMenus = [] |
| | | } |
| | | } else { |
| | | appMenus = [] |
| | | } |
| | | |
| | | this.setState({appMenus}) |
| | | } |
| | | |
| | | handleConfirm = () => { |
| | | // 表单提交时检查输入值是否正确 |
| | | return new Promise((resolve, reject) => { |
| | | this.props.form.validateFieldsAndScroll((err, values) => { |
| | | if (!err) { |
| | | resolve(values) |
| | | } else { |
| | | reject(err) |
| | | } |
| | | }) |
| | | }) |
| | | } |
| | | |
| | | handleSubmit = (e) => { |
| | | e.preventDefault() |
| | | |
| | | if (this.props.inputSubmit) { |
| | | this.props.inputSubmit() |
| | | } |
| | | } |
| | | |
| | | render() { |
| | | const { wrap } = this.props |
| | | const { getFieldDecorator } = this.props.form |
| | | const { appMenus } = this.state |
| | | const formItemLayout = { |
| | | labelCol: { |
| | | xs: { span: 24 }, |
| | | sm: { span: 8 } |
| | | }, |
| | | wrapperCol: { |
| | | xs: { span: 24 }, |
| | | sm: { span: 16 } |
| | | } |
| | | } |
| | | |
| | | return ( |
| | | <div className="model-menu-setting-form"> |
| | | <Form {...formItemLayout}> |
| | | <Row gutter={24}> |
| | | <Col span={12}> |
| | | <Form.Item label="导航栏名称"> |
| | | {getFieldDecorator('name', { |
| | | initialValue: wrap.name, |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: this.props.dict['form.required.input'] + '导航栏名称!' |
| | | } |
| | | ] |
| | | })(<Input placeholder={''} autoComplete="off" onPressEnter={this.handleSubmit} />)} |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={12}> |
| | | <Form.Item label="菜单参数"> |
| | | {getFieldDecorator('MenuNo', { |
| | | initialValue: wrap.MenuNo, |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: this.props.dict['form.required.input'] + '菜单参数!' |
| | | } |
| | | ] |
| | | })(<Input placeholder={''} autoComplete="off" onPressEnter={this.handleSubmit} />)} |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={12}> |
| | | <Form.Item label={ |
| | | <Tooltip placement="topLeft" title="导航栏主体内容宽度(包括logo、菜单、链接等)。"> |
| | | <Icon type="question-circle" /> |
| | | 宽度 |
| | | </Tooltip> |
| | | }> |
| | | {getFieldDecorator('width', { |
| | | initialValue: wrap.width || 1200, |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: this.props.dict['form.required.input'] + '宽度!' |
| | | } |
| | | ] |
| | | })(<InputNumber min={400} precision={0} onPressEnter={this.handleSubmit} />)} |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={12}> |
| | | <Form.Item label="高度"> |
| | | {getFieldDecorator('height', { |
| | | initialValue: wrap.height || 50, |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: this.props.dict['form.required.input'] + '高度!' |
| | | } |
| | | ] |
| | | })(<InputNumber min={50} max={200} precision={0} onPressEnter={this.handleSubmit} />)} |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={12}> |
| | | <Form.Item label="logo"> |
| | | {getFieldDecorator('logo', { |
| | | initialValue: wrap.logo |
| | | })( |
| | | <SourceComponent type="image" /> |
| | | )} |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={12}> |
| | | <Form.Item label="logo链接"> |
| | | {getFieldDecorator('logolink', { |
| | | initialValue: wrap.logolink || '' |
| | | })( |
| | | <Select |
| | | showSearch |
| | | filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0} |
| | | > |
| | | <Select.Option key="empty" intid={''} value={''}>无</Select.Option> |
| | | {appMenus.map(option => |
| | | <Select.Option key={option.MenuID} value={option.MenuID}>{option.MenuName}</Select.Option> |
| | | )} |
| | | </Select> |
| | | )} |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={12}> |
| | | <Form.Item label={ |
| | | <Tooltip placement="topLeft" title="存在登录且取到登录信息时,显示用户头像、用户名及退出。"> |
| | | <Icon type="question-circle" /> |
| | | 用户信息 |
| | | </Tooltip> |
| | | }> |
| | | {getFieldDecorator('user', { |
| | | initialValue: wrap.user || 'hidden' |
| | | })( |
| | | <Radio.Group> |
| | | <Radio value="hidden">隐藏</Radio> |
| | | <Radio value="show">显示</Radio> |
| | | </Radio.Group> |
| | | )} |
| | | </Form.Item> |
| | | </Col> |
| | | </Row> |
| | | </Form> |
| | | </div> |
| | | ) |
| | | } |
| | | } |
| | | |
| | | export default Form.create()(SettingForm) |
New file |
| | |
| | | .model-menu-setting-form { |
| | | position: relative; |
| | | |
| | | .anticon-question-circle { |
| | | color: #c49f47; |
| | | margin-right: 3px; |
| | | } |
| | | .ant-input-number { |
| | | width: 100%; |
| | | } |
| | | } |
New file |
| | |
| | | import React from 'react' |
| | | import { useDrag, useDrop } from 'react-dnd' |
| | | |
| | | import asyncComponent from '@/utils/asyncComponent' |
| | | import './index.scss' |
| | | |
| | | const AntvBar = asyncComponent(() => import('@/menu/components/chart/antv-bar')) |
| | | const MainSearch = asyncComponent(() => import('@/menu/components/search/main-search')) |
| | | const AntvPie = asyncComponent(() => import('@/menu/components/chart/antv-pie')) |
| | | const AntvTabs = asyncComponent(() => import('@/menu/components/tabs/antv-tabs')) |
| | | const DataCard = asyncComponent(() => import('@/menu/components/card/data-card')) |
| | | const PropCard = asyncComponent(() => import('@/menu/components/card/prop-card')) |
| | | const TableCard = asyncComponent(() => import('@/menu/components/card/table-card')) |
| | | const NormalTable = asyncComponent(() => import('@/menu/components/table/normal-table')) |
| | | const NormalGroup = asyncComponent(() => import('@/menu/components/group/normal-group')) |
| | | const NormalForm = asyncComponent(() => import('@/menu/components/form/normal-form')) |
| | | const BraftEditor = asyncComponent(() => import('@/menu/components/editor/braft-editor')) |
| | | const CodeSandbox = asyncComponent(() => import('@/menu/components/code/sandbox')) |
| | | const NormalNavbar = asyncComponent(() => import('@/pc/components/navbar/normal-navbar')) |
| | | const CarouselDataCard = asyncComponent(() => import('@/menu/components/carousel/data-card')) |
| | | const CarouselPropCard = asyncComponent(() => import('@/menu/components/carousel/prop-card')) |
| | | |
| | | const Card = ({ id, card, moveCard, findCard, delCard, updateConfig }) => { |
| | | const originalIndex = findCard(id).index |
| | | const [{ isDragging }, drag] = useDrag({ |
| | | item: { type: 'menu', id, originalIndex, floor: card.floor }, |
| | | collect: monitor => ({ |
| | | isDragging: monitor.isDragging(), |
| | | }), |
| | | }) |
| | | const [, drop] = useDrop({ |
| | | accept: 'menu', |
| | | canDrop: () => true, |
| | | drop: (item) => { |
| | | const { id: draggedId, originalIndex, floor } = item |
| | | if (originalIndex === undefined) { |
| | | item.dropTargetId = id |
| | | } else if (draggedId && floor === card.floor) { |
| | | if (draggedId === id) return |
| | | const { index: originIndex } = findCard(draggedId) |
| | | |
| | | if (originIndex === -1) return |
| | | |
| | | const { index: overIndex } = findCard(id) |
| | | |
| | | moveCard(draggedId, overIndex) |
| | | } |
| | | } |
| | | }) |
| | | |
| | | let style = { opacity: 1} |
| | | if (isDragging) { |
| | | style = { opacity: 0.3} |
| | | } |
| | | let col = ' ant-col ant-col-' + (card.width || 24) |
| | | if (card.type === 'navbar') { |
| | | col = '' |
| | | } |
| | | |
| | | const getCardComponent = () => { |
| | | if (card.type === 'bar' || card.type === 'line') { |
| | | return (<AntvBar card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) |
| | | } else if (card.type === 'navbar') { |
| | | return (<NormalNavbar card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) |
| | | } else if (card.type === 'form') { |
| | | return (<NormalForm card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) |
| | | } else if (card.type === 'search') { |
| | | return (<MainSearch card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) |
| | | } else if (card.type === 'pie') { |
| | | return (<AntvPie card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) |
| | | } else if (card.type === 'tabs') { |
| | | return (<AntvTabs tabs={card} updateConfig={updateConfig} deletecomponent={delCard}/>) |
| | | } else if (card.type === 'card' && card.subtype === 'datacard') { |
| | | return (<DataCard card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) |
| | | } else if (card.type === 'card' && card.subtype === 'propcard') { |
| | | return (<PropCard card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) |
| | | } else if (card.type === 'carousel' && card.subtype === 'datacard') { |
| | | return (<CarouselDataCard card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) |
| | | } else if (card.type === 'carousel' && card.subtype === 'propcard') { |
| | | return (<CarouselPropCard card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) |
| | | } else if (card.type === 'table' && card.subtype === 'tablecard') { |
| | | return (<TableCard card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) |
| | | } else if (card.type === 'table' && card.subtype === 'normaltable') { |
| | | return (<NormalTable card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) |
| | | } else if (card.type === 'group' && card.subtype === 'normalgroup') { |
| | | return (<NormalGroup group={card} updateConfig={updateConfig} deletecomponent={delCard}/>) |
| | | } else if (card.type === 'editor') { |
| | | return (<BraftEditor card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) |
| | | } else if (card.type === 'code') { |
| | | return (<CodeSandbox card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) |
| | | } |
| | | } |
| | | return ( |
| | | <div className={`mk-component-card ${col}`} ref={node => drag(drop(node))} style={style}> |
| | | {getCardComponent()} |
| | | </div> |
| | | ) |
| | | } |
| | | export default Card |
New file |
| | |
| | | import React, { useState } from 'react' |
| | | import { useDrop } from 'react-dnd' |
| | | import update from 'immutability-helper' |
| | | import { Empty, notification, Modal } from 'antd' |
| | | |
| | | import Utils from '@/utils/utils.js' |
| | | import MKEmitter from '@/utils/events.js' |
| | | import MenuUtils from '@/utils/utils-custom.js' |
| | | import Card from './card' |
| | | import './index.scss' |
| | | |
| | | const { confirm } = Modal |
| | | |
| | | const Container = ({menu, handleList }) => { |
| | | const [cards, setCards] = useState(menu.components) |
| | | const moveCard = (id, atIndex) => { |
| | | const { card, index } = findCard(id) |
| | | const _cards = update(cards, { $splice: [[index, 1], [atIndex, 0, card]] }) |
| | | handleList({...menu, components: _cards}) |
| | | setCards(_cards) |
| | | } |
| | | |
| | | const findCard = id => { |
| | | const card = cards.filter(c => `${c.uuid}` === id)[0] |
| | | return { |
| | | card, |
| | | index: cards.indexOf(card), |
| | | } |
| | | } |
| | | |
| | | const updateConfig = (element) => { |
| | | const _cards = cards.map(item => item.uuid === element.uuid ? element : item) |
| | | handleList({...menu, components: _cards}) |
| | | setCards(_cards) |
| | | } |
| | | |
| | | const deleteCard = (id) => { |
| | | const { card } = findCard(id) |
| | | |
| | | let hasComponent = false |
| | | if (card.type === 'tabs') { |
| | | card.subtabs.forEach(tab => { |
| | | if (tab.components.length > 0) { |
| | | hasComponent = true |
| | | } |
| | | }) |
| | | } |
| | | |
| | | let uuids = MenuUtils.getDelButtonIds(card) |
| | | |
| | | confirm({ |
| | | title: `确定删除《${card.name}》吗?`, |
| | | content: hasComponent ? '当前组件中含有子组件!' : '', |
| | | onOk() { |
| | | MKEmitter.emit('delButtons', uuids) |
| | | const _cards = cards.filter(item => item.uuid !== card.uuid) |
| | | handleList({...menu, components: _cards}) |
| | | setCards(_cards) |
| | | }, |
| | | onCancel() {} |
| | | }) |
| | | } |
| | | |
| | | const [, drop] = useDrop({ |
| | | accept: 'menu', |
| | | drop(item) { |
| | | if (item.hasOwnProperty('originalIndex') || item.added) { |
| | | delete item.added // 删除组件添加标记 |
| | | return |
| | | } |
| | | |
| | | if (item.component === 'search') { // 搜索组件不可重复添加 |
| | | if (cards.filter(card => card.type === 'search').length > 0) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '搜索条件不可重复添加!', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } |
| | | } else if (item.component === 'navbar') { |
| | | if (cards.filter(card => card.type === 'navbar').length > 0) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '导航栏不可重复添加!', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } |
| | | } |
| | | |
| | | let name = '' |
| | | let names = { |
| | | bar: '柱状图', |
| | | line: '折线图', |
| | | tabs: '标签组', |
| | | pie: '饼图', |
| | | search: '搜索', |
| | | table: '表格', |
| | | group: '分组', |
| | | editor: '富文本', |
| | | code: '自定义', |
| | | navbar: '导航栏', |
| | | carousel: '轮播', |
| | | card: '卡片' |
| | | } |
| | | let i = 1 |
| | | |
| | | while (!name && names[item.component]) { |
| | | let _name = names[item.component] + i |
| | | if (menu.components.filter(com => com.name === _name).length === 0) { |
| | | name = _name |
| | | } |
| | | i++ |
| | | } |
| | | |
| | | let newcard = { |
| | | uuid: Utils.getuuid(), |
| | | type: item.component, |
| | | subtype: item.subtype, |
| | | config: item.config, |
| | | width: item.width || 24, |
| | | dataName: Utils.getdataName(), |
| | | name: name, |
| | | floor: 1, // 组件的层级 |
| | | isNew: true // 新添加标志,用于初始化 |
| | | } |
| | | |
| | | let targetId = '' |
| | | |
| | | if (item.dropTargetId) { |
| | | targetId = item.dropTargetId |
| | | delete item.dropTargetId |
| | | } else if (cards.length > 0) { |
| | | targetId = cards.slice(-1)[0].uuid |
| | | } |
| | | |
| | | const { index: overIndex } = findCard(`${targetId}`) |
| | | const _cards = update(cards, { $splice: [[overIndex + 1, 0, newcard]] }) |
| | | |
| | | handleList({...menu, components: _cards}) |
| | | setCards(_cards) |
| | | } |
| | | }) |
| | | |
| | | return ( |
| | | <div ref={drop} className="menu-shell-inner" id="menu-shell-inner" style={menu.style}> |
| | | <div className="ant-row"> |
| | | {cards.map(card => ( |
| | | <Card |
| | | id={card.uuid} |
| | | key={card.uuid} |
| | | card={card} |
| | | moveCard={moveCard} |
| | | delCard={deleteCard} |
| | | findCard={findCard} |
| | | updateConfig={updateConfig} |
| | | /> |
| | | ))} |
| | | </div> |
| | | {cards.length === 0 ? |
| | | <Empty description="请添加组件" /> : null |
| | | } |
| | | </div> |
| | | ) |
| | | } |
| | | export default Container |
New file |
| | |
| | | .menu-shell-inner { |
| | | min-height: calc(100vh - 100px); |
| | | width: 100%; |
| | | background-size: 100%; |
| | | |
| | | .anticon { |
| | | cursor: unset; |
| | | } |
| | | |
| | | .mk-component-card { |
| | | position: relative; |
| | | } |
| | | |
| | | >.ant-empty { |
| | | padding-top: 150px; |
| | | } |
| | | .anticon-tool { |
| | | color: rgba(0, 0, 0, 0.55); |
| | | } |
| | | .anticon-tool:hover { |
| | | color: #1890ff; |
| | | } |
| | | } |
New file |
| | |
| | | import React from 'react' |
| | | import { useDrag } from 'react-dnd' |
| | | import { Icon } from 'antd' |
| | | import './index.scss' |
| | | |
| | | const MobSourceElement = ({item, triggerDel}) => { |
| | | const [, drag] = useDrag({ item }) |
| | | return ( |
| | | <div className="menu-source-item"> |
| | | <div className="property"><span>{item.title}</span>{item.config ? <Icon onClick={() => triggerDel(item)} type="close-circle" /> : null}</div> |
| | | <img ref={drag} src={item.url} alt=""/> |
| | | </div> |
| | | ) |
| | | } |
| | | export default MobSourceElement |
New file |
| | |
| | | .menu-source-item { |
| | | display: inline-block; |
| | | width: 100%; |
| | | margin-bottom: 15px; |
| | | height: auto; |
| | | min-height: 70px; |
| | | |
| | | .property { |
| | | font-size: 14px; |
| | | color: rgba(0, 0, 0, 0.65); |
| | | margin-bottom: 2px; |
| | | |
| | | .anticon-close-circle { |
| | | opacity: 0; |
| | | cursor: pointer; |
| | | padding: 0 3px; |
| | | color: #ff4d4f; |
| | | transition: all 0.3s; |
| | | } |
| | | } |
| | | |
| | | img { |
| | | width: 100%; |
| | | cursor: move; |
| | | box-shadow: 0px 0px 1px #1890ff; |
| | | } |
| | | |
| | | .tooltip-block { |
| | | width: 100%; |
| | | height: 100%; |
| | | background: transparent; |
| | | } |
| | | } |
| | | |
| | | .menu-source-item:hover .property { |
| | | .anticon-close-circle { |
| | | opacity: 1; |
| | | } |
| | | } |
| | | |
| | | .menu-source-tooltip-box { |
| | | margin-left: 20px; |
| | | .ant-tooltip-content { |
| | | width: 250px; |
| | | } |
| | | } |
New file |
| | |
| | | import React, {Component} from 'react' |
| | | import { is, fromJS } from 'immutable' |
| | | import { Modal, notification } from 'antd' |
| | | |
| | | import Api from '@/api' |
| | | import { menuOptions } from './option' |
| | | import SourceWrap from './dragsource' |
| | | import MKEmitter from '@/utils/events.js' |
| | | import './index.scss' |
| | | |
| | | const { confirm } = Modal |
| | | |
| | | class ModelSource extends Component { |
| | | state = { |
| | | menuOptions: null, |
| | | } |
| | | |
| | | UNSAFE_componentWillMount () { |
| | | const { components } = this.props |
| | | let options = [] |
| | | |
| | | if (components) { |
| | | options = fromJS(components).toJS() |
| | | } else { |
| | | options = fromJS(menuOptions).toJS() |
| | | } |
| | | |
| | | this.setState({ |
| | | menuOptions: options |
| | | }) |
| | | } |
| | | |
| | | UNSAFE_componentWillReceiveProps (nextProps) { |
| | | if (nextProps.components && !is(fromJS(this.props.components), fromJS(nextProps.components))) { |
| | | this.setState({ |
| | | menuOptions: fromJS(nextProps.components).toJS() |
| | | }) |
| | | } |
| | | } |
| | | |
| | | shouldComponentUpdate (nextProps, nextState) { |
| | | return !is(fromJS(this.state), fromJS(nextState)) |
| | | } |
| | | |
| | | triggerDel = (item) => { |
| | | confirm({ |
| | | title: `确定删除<${item.title}>吗?`, |
| | | content: '', |
| | | onOk() { |
| | | return new Promise(resolve => { |
| | | Api.getSystemConfig({ |
| | | func: 's_custom_components_adduptdel', |
| | | c_id: item.uuid, |
| | | images: '', |
| | | c_name: item.title, |
| | | long_param: '', |
| | | del_type: 'Y' |
| | | }).then(result => { |
| | | if (result.status) { |
| | | notification.success({ |
| | | top: 92, |
| | | message: '删除成功!', |
| | | duration: 5 |
| | | }) |
| | | |
| | | MKEmitter.emit('updateCustomComponent') |
| | | } else { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: result.message, |
| | | duration: 5 |
| | | }) |
| | | } |
| | | resolve() |
| | | }) |
| | | }) |
| | | }, |
| | | onCancel() {} |
| | | }) |
| | | } |
| | | |
| | | render() { |
| | | const { menuOptions } = this.state |
| | | |
| | | return ( |
| | | <div className="mob-card-source-box"> |
| | | {menuOptions.map((item, index) => (<SourceWrap key={index} item={item} triggerDel={this.triggerDel} />))} |
| | | </div> |
| | | ) |
| | | } |
| | | } |
| | | |
| | | export default ModelSource |
copy from src/mob/modelsource/index.scss
copy to src/pc/modulesource/index.scss
File was copied from src/mob/modelsource/index.scss |
| | |
| | | .mob-card-source-box { |
| | | padding: 20px 0px 20px 15px; |
| | | padding: 20px 0px; |
| | | position: relative; |
| | | |
| | | p { |
New file |
| | |
| | | import bar from '@/assets/mobimg/bar.png' |
| | | import bar1 from '@/assets/mobimg/bar1.png' |
| | | import line from '@/assets/mobimg/line.png' |
| | | import line1 from '@/assets/mobimg/line1.png' |
| | | import tabs from '@/assets/mobimg/tabs.png' |
| | | import group from '@/assets/mobimg/group.png' |
| | | import card1 from '@/assets/mobimg/card1.png' |
| | | import card2 from '@/assets/mobimg/card2.png' |
| | | import TableCard from '@/assets/mobimg/table-card.png' |
| | | import NormalTable from '@/assets/mobimg/normal-table.png' |
| | | import Pie from '@/assets/mobimg/pie.png' |
| | | import Editor from '@/assets/mobimg/editor.png' |
| | | import SandBox from '@/assets/mobimg/sandbox.png' |
| | | import Pie1 from '@/assets/mobimg/ring.png' |
| | | import Pie2 from '@/assets/mobimg/nightingale.png' |
| | | import Mainsearch from '@/assets/mobimg/mainsearch.png' |
| | | import Navbar from '@/assets/mobimg/navbar.png' |
| | | import Carousel from '@/assets/mobimg/carousel.png' |
| | | import Carousel1 from '@/assets/mobimg/carousel1.png' |
| | | import form from '@/assets/mobimg/form.png' |
| | | |
| | | // 组件配置信息 |
| | | export const menuOptions = [ |
| | | { type: 'menu', url: Navbar, component: 'navbar', subtype: 'navbar', title: '导航栏', width: 1200 }, |
| | | { type: 'menu', url: tabs, component: 'tabs', subtype: 'tabs', title: '标签页', width: 24 }, |
| | | { type: 'menu', url: Mainsearch, component: 'search', subtype: 'mainsearch', title: '搜索条件', width: 24 }, |
| | | { type: 'menu', url: card1, component: 'card', subtype: 'datacard', title: '数据卡', width: 24 }, |
| | | { type: 'menu', url: card2, component: 'card', subtype: 'propcard', title: '属性卡', width: 24 }, |
| | | { type: 'menu', url: form, component: 'form', subtype: 'stepform', title: '表单', width: 24 }, |
| | | { type: 'menu', url: Carousel, component: 'carousel', subtype: 'datacard', title: '轮播-动态数据', width: 24 }, |
| | | { type: 'menu', url: Carousel1, component: 'carousel', subtype: 'propcard', title: '轮播-静态数据', width: 24 }, |
| | | { type: 'menu', url: NormalTable, component: 'table', subtype: 'normaltable', title: '常用表', width: 24 }, |
| | | { type: 'menu', url: TableCard, component: 'table', subtype: 'tablecard', title: '表格', width: 12 }, |
| | | { type: 'menu', url: line, component: 'line', subtype: 'line', title: '折线图', width: 24 }, |
| | | { type: 'menu', url: line1, component: 'line', subtype: 'line1', title: '阶梯折线图', width: 24 }, |
| | | { type: 'menu', url: bar, component: 'bar', subtype: 'bar', title: '柱状图', width: 24 }, |
| | | { type: 'menu', url: bar1, component: 'bar', subtype: 'bar1', title: '条形图', width: 24 }, |
| | | { type: 'menu', url: Pie, component: 'pie', subtype: 'pie', title: '饼图', width: 12 }, |
| | | { type: 'menu', url: Pie1, component: 'pie', subtype: 'ring', title: '环图', width: 12 }, |
| | | { type: 'menu', url: Editor, component: 'editor', subtype: 'brafteditor', title: '富文本', width: 24 }, |
| | | { type: 'menu', url: SandBox, component: 'code', subtype: 'sandbox', title: '自定义', width: 24 }, |
| | | { type: 'menu', url: Pie2, component: 'pie', subtype: 'nightingale', title: '南丁格尔图', width: 12 }, |
| | | { type: 'menu', url: group, component: 'group', subtype: 'normalgroup', title: '分组', width: 24 }, |
| | | ] |
New file |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { is, fromJS } from 'immutable' |
| | | import { Button, Modal, notification } from 'antd' |
| | | |
| | | import zhCN from '@/locales/zh-CN/model.js' |
| | | import enUS from '@/locales/en-US/model.js' |
| | | import SettingForm from './settingform' |
| | | import Api from '@/api' |
| | | import './index.scss' |
| | | |
| | | class Quotecomponent extends Component { |
| | | static propTpyes = { |
| | | config: PropTypes.any, |
| | | updateConfig: PropTypes.func |
| | | } |
| | | |
| | | state = { |
| | | dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | visible: false, |
| | | } |
| | | |
| | | shouldComponentUpdate (nextProps, nextState) { |
| | | return !is(fromJS(this.props), fromJS(nextProps)) || !is(fromJS(this.state), fromJS(nextState)) |
| | | } |
| | | |
| | | verifySubmit = () => { |
| | | let config = fromJS(this.props.config).toJS() |
| | | |
| | | this.verifyRef.handleConfirm().then(res => { |
| | | let exit = false |
| | | config.components.forEach(item => { |
| | | if (item.type === res.keys_type) { |
| | | exit = true |
| | | } |
| | | }) |
| | | |
| | | if (exit) { |
| | | let msg = '' |
| | | if (res.keys_type === 'navbar') { |
| | | msg = '导航栏已存在!' |
| | | } |
| | | notification.warning({ |
| | | top: 92, |
| | | message: msg, |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } |
| | | |
| | | Api.getSystemConfig({ |
| | | func: 'sPC_Get_LongParam', |
| | | TypeCharOne: sessionStorage.getItem('kei_no'), |
| | | typename: 'pc', |
| | | MenuID: res.keys_id |
| | | }).then(result => { |
| | | if (!result.status) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: result.message, |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } |
| | | let _config = null |
| | | try { |
| | | _config = JSON.parse(window.decodeURIComponent(window.atob(result.LongParam))) |
| | | } catch (e) { |
| | | console.warn('Parse Failure') |
| | | _config = null |
| | | } |
| | | |
| | | if (!_config) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '未获取到配置信息!', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } |
| | | |
| | | _config.open_edition = result.open_edition || '' |
| | | window.GLOB.CacheIndependent.set(_config.uuid, fromJS(_config).toJS()) |
| | | |
| | | config.components.unshift(_config) |
| | | |
| | | this.setState({ |
| | | visible: false |
| | | }) |
| | | this.props.updateConfig(config) |
| | | }) |
| | | }) |
| | | } |
| | | |
| | | render () { |
| | | const { config } = this.props |
| | | const { visible, dict } = this.state |
| | | |
| | | return ( |
| | | <div className="quote-wrap"> |
| | | <Button icon="appstore" onClick={() => {this.setState({visible: true})}}>组件引用</Button> |
| | | <Modal |
| | | title="组件引用" |
| | | visible={visible} |
| | | width={500} |
| | | maskClosable={false} |
| | | okText={dict['model.submit']} |
| | | onOk={this.verifySubmit} |
| | | onCancel={() => { this.setState({ visible: false }) }} |
| | | destroyOnClose |
| | | > |
| | | <SettingForm |
| | | dict={dict} |
| | | config={config} |
| | | wrappedComponentRef={(inst) => this.verifyRef = inst} |
| | | /> |
| | | </Modal> |
| | | </div> |
| | | ) |
| | | } |
| | | } |
| | | |
| | | export default Quotecomponent |
New file |
| | |
| | | .quote-wrap { |
| | | button { |
| | | border-color: #40a9ff; |
| | | color: #40a9ff; |
| | | } |
| | | } |
New file |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { Form, Row, Col, Select } from 'antd' |
| | | |
| | | import './index.scss' |
| | | |
| | | class SettingForm extends Component { |
| | | static propTpyes = { |
| | | dict: PropTypes.object, // 字典项 |
| | | } |
| | | |
| | | state = { |
| | | appMenus: [] |
| | | } |
| | | |
| | | UNSAFE_componentWillMount () { |
| | | let appMenus = sessionStorage.getItem('appViewList') |
| | | if (appMenus) { |
| | | try { |
| | | appMenus = JSON.parse(appMenus) |
| | | appMenus = appMenus.filter(item => item.keys_type !== 'index') |
| | | } catch { |
| | | appMenus = [] |
| | | } |
| | | } else { |
| | | appMenus = [] |
| | | } |
| | | |
| | | this.setState({appMenus}) |
| | | } |
| | | |
| | | handleConfirm = () => { |
| | | const { appMenus } = this.state |
| | | // 表单提交时检查输入值是否正确 |
| | | return new Promise((resolve, reject) => { |
| | | this.props.form.validateFieldsAndScroll((err, values) => { |
| | | if (!err) { |
| | | let item = appMenus.filter(_menu => _menu.keys_id === values.menu)[0] |
| | | resolve(item) |
| | | } else { |
| | | reject(err) |
| | | } |
| | | }) |
| | | }) |
| | | } |
| | | |
| | | render() { |
| | | const { getFieldDecorator } = this.props.form |
| | | const { appMenus } = this.state |
| | | |
| | | const formItemLayout = { |
| | | labelCol: { |
| | | xs: { span: 24 }, |
| | | sm: { span: 8 } |
| | | }, |
| | | wrapperCol: { |
| | | xs: { span: 24 }, |
| | | sm: { span: 16 } |
| | | } |
| | | } |
| | | |
| | | return ( |
| | | <Form {...formItemLayout}> |
| | | <Row gutter={24}> |
| | | <Col span={20}> |
| | | <Form.Item label="菜单"> |
| | | {getFieldDecorator('menu', { |
| | | initialValue: '', |
| | | rules: [{ |
| | | required: true, |
| | | message: '请选择菜单!' |
| | | }] |
| | | })( |
| | | <Select> |
| | | {appMenus.map(option => |
| | | <Select.Option key={option.keys_id} value={option.keys_id}>{option.remark}</Select.Option> |
| | | )} |
| | | </Select> |
| | | )} |
| | | </Form.Item> |
| | | </Col> |
| | | </Row> |
| | | </Form> |
| | | ) |
| | | } |
| | | } |
| | | |
| | | export default Form.create()(SettingForm) |
New file |
| | |
| | | .model-menu-setting-form { |
| | | position: relative; |
| | | |
| | | .anticon-question-circle { |
| | | color: #c49f47; |
| | | margin-right: 3px; |
| | | } |
| | | .ant-input-number { |
| | | width: 100%; |
| | | } |
| | | } |
| | |
| | | import {HashRouter, Switch, Route, Redirect} from 'react-router-dom' |
| | | import md5 from 'md5' |
| | | import moment from 'moment' |
| | | import options from '@/store/options.js' |
| | | import { styles } from '@/store/options.js' |
| | | import asyncComponent from '@/utils/asyncComponent' |
| | | import asyncLoadComponent from '@/utils/asyncLoadComponent' |
| | | |
| | | const Pay = asyncLoadComponent(() => import('@/views/pay')) |
| | | const Sso = asyncLoadComponent(() => import('@/views/sso')) |
| | | const Main = asyncLoadComponent(() => import('@/views/main')) |
| | | const Design = asyncLoadComponent(() => import('@/views/design')) |
| | | const Login = asyncLoadComponent(() => import('@/views/login')) |
| | | const NotFound = asyncComponent(() => import('@/views/404')) |
| | | const MobManage = asyncLoadComponent(() => import('@/views/mobmanage')) |
| | | const AppManage = asyncLoadComponent(() => import('@/views/appmanage')) |
| | | const PCDesign = asyncLoadComponent(() => import('@/views/pcdesign')) |
| | | const MobDesign = asyncLoadComponent(() => import('@/views/mobdesign')) |
| | | const MenuDesign = asyncLoadComponent(() => import('@/views/menudesign')) |
| | | const BillPrint = asyncLoadComponent(() => import('@/views/billprint')) |
| | |
| | | {path: '/print/:param', name: 'print', component: PrintT, auth: false}, |
| | | {path: '/ssologin/:param', name: 'ssologin', component: Sso, auth: false}, |
| | | {path: '/main', name: 'main', component: Main, auth: true}, |
| | | {path: '/mobmanage', name: 'mobmanage', component: MobManage, auth: true}, |
| | | {path: '/mobdesign/:appId/:appType/:appCode/:appName', name: 'mobdesign', component: MobDesign, auth: true}, |
| | | {path: '/design', name: 'design', component: Design, auth: true}, |
| | | {path: '/appmanage', name: 'appmanage', component: AppManage, auth: true}, |
| | | {path: '/pcdesign/:param', name: 'pcdesign', component: PCDesign, auth: true}, |
| | | {path: '/mobdesign/:param', name: 'mobdesign', component: MobDesign, auth: true}, |
| | | {path: '/menudesign/:param', name: 'menudesign', component: MenuDesign, auth: true}, |
| | | {path: '/billprint/:param', name: 'billprint', component: BillPrint, auth: true}, |
| | | {path: '/paramsmain/:param', name: 'pmain', component: Main, auth: true} |
| | |
| | | if (_param.mainlogo) { |
| | | window.GLOB.mainlogo = _param.mainlogo |
| | | } |
| | | if (_param.mstyle && options.styles[_param.mstyle]) { |
| | | document.getElementById('root').className = options.styles[_param.mstyle] |
| | | if (_param.navBar) { |
| | | window.GLOB.navBar = _param.navBar |
| | | } |
| | | if (_param.mstyle && styles[_param.mstyle]) { |
| | | document.body.className = styles[_param.mstyle] |
| | | } |
| | | if (_param.MainMenu) { |
| | | sessionStorage.setItem('MainMenu', _param.MainMenu) |
| | |
| | | const proxy = require('http-proxy-middleware') |
| | | const host = 'http://bms-test.kresstools.cn' |
| | | const service = 'oc/' |
| | | // const proxy = require('http-proxy-middleware') |
| | | // const host = 'http://qingqiumarket.cn' |
| | | // const service = 'mkwms/' |
| | | |
| | | module.exports = function(app) { |
| | | app.use(proxy('/webapi', { |
| | | target: `${host}/${service}webapi`, |
| | | secure: false, |
| | | changeOrigin: true, |
| | | pathRewrite: { |
| | | '^/webapi': '/' |
| | | } |
| | | // cookieDomainRewrite: "http://localhost:3000" |
| | | })) |
| | | module.exports = function() {} |
| | | // module.exports = function(app) { |
| | | // app.use(proxy('/webapi', { |
| | | // target: `${host}/${service}webapi`, |
| | | // secure: false, |
| | | // changeOrigin: true, |
| | | // pathRewrite: { |
| | | // '^/webapi': '/' |
| | | // } |
| | | // // cookieDomainRewrite: "http://localhost:3000" |
| | | // })) |
| | | |
| | | app.use(proxy('/zh-CN', { // 登录接口 |
| | | target: `${host}/${service}zh-CN`, |
| | | secure: false, |
| | | changeOrigin: true, |
| | | pathRewrite: { |
| | | '^/zh-CN': '/' |
| | | } |
| | | })) |
| | | // app.use(proxy('/zh-CN', { // 登录接口 |
| | | // target: `${host}/${service}zh-CN`, |
| | | // secure: false, |
| | | // changeOrigin: true, |
| | | // pathRewrite: { |
| | | // '^/zh-CN': '/' |
| | | // } |
| | | // })) |
| | | |
| | | app.use(proxy('/Upload', { |
| | | target: `${host}/${service}zh-CN/Home/Upload`, |
| | | secure: false, |
| | | changeOrigin: true, |
| | | pathRewrite: { |
| | | '^/Upload': '/' |
| | | } |
| | | })) |
| | | // app.use(proxy('/Upload', { |
| | | // target: `${host}/${service}zh-CN/Home/Upload`, |
| | | // secure: false, |
| | | // changeOrigin: true, |
| | | // pathRewrite: { |
| | | // '^/Upload': '/' |
| | | // } |
| | | // })) |
| | | |
| | | app.use(proxy('/wxpay', { |
| | | target: `${host}/${service}wxpay`, |
| | | secure: false, |
| | | changeOrigin: true, |
| | | pathRewrite: { |
| | | '^/wxpay': '/' |
| | | } |
| | | })) |
| | | // app.use(proxy('/wxpay', { |
| | | // target: `${host}/${service}wxpay`, |
| | | // secure: false, |
| | | // changeOrigin: true, |
| | | // pathRewrite: { |
| | | // '^/wxpay': '/' |
| | | // } |
| | | // })) |
| | | |
| | | app.use(proxy('/Home', { |
| | | target: `${host}/Home`, |
| | | secure: false, |
| | | changeOrigin: true, |
| | | pathRewrite: { |
| | | '^/Home': '/' |
| | | } |
| | | // cookieDomainRewrite: "http://localhost:3000" |
| | | })) |
| | | |
| | | app.use(proxy('/trans', { |
| | | target: `${host}/${service}trans`, |
| | | secure: false, |
| | | changeOrigin: true, |
| | | pathRewrite: { |
| | | '^/trans': '/' |
| | | } |
| | | })) |
| | | } |
| | | // app.use(proxy('/trans', { |
| | | // target: `${host}/${service}trans`, |
| | | // secure: false, |
| | | // changeOrigin: true, |
| | | // pathRewrite: { |
| | | // '^/trans': '/' |
| | | // } |
| | | // })) |
| | | // } |
| | |
| | | // 修改窗口样式,区分iframe与正常页面 |
| | | export const TOGGLE_ISIFRAME = 'TOGGLE_ISIFRAME' |
| | | |
| | | // 退出系统时参数重置 |
| | | export const RESET_STATE = 'RESET_STATE' |
| | | |
| | | // 刷新tab页面 |
| | | export const REFRESH_TABVIEW = 'REFRESH_TABVIEW' |
| | | |
| | | // 重置编辑状态 |
| | | export const RESET_EDITSTATE = 'RESET_EDITSTATE' |
| | | |
| | | // 重置编辑级别 |
| | | export const RESET_EDITLEVEL = 'RESET_EDITLEVEL' |
| | |
| | | |
| | | // 修改会员等级 |
| | | export const MODIFY_MEMBERLEVEL = 'MODIFY_MEMBERLEVEL' |
| | | |
| | | // 修改自定义菜单 |
| | | export const MODIFY_CUSTOMMENU = 'MODIFY_CUSTOMMENU' |
| | | |
| | | // 退出 |
| | | export const LOGOUT = 'LOGOUT' |
| | |
| | | } |
| | | } |
| | | |
| | | // 退出系统时参数重置 |
| | | export const resetState = () => { |
| | | return { |
| | | type: user.RESET_STATE |
| | | } |
| | | } |
| | | |
| | | // 重置编辑状态 |
| | | export const resetEditState = (editState) => { |
| | | return { |
| | | type: user.RESET_EDITSTATE, |
| | | editState |
| | | } |
| | | } |
| | | |
| | | // 重置编辑级别 |
| | | export const resetEditLevel = (editLevel) => { |
| | | return { |
| | |
| | | return { |
| | | type: user.MODIFY_MEMBERLEVEL, |
| | | memberLevel: memberLevel |
| | | } |
| | | } |
| | | |
| | | // 修改自定义菜单 |
| | | export const modifyCustomMenu = (customMenu) => { |
| | | return { |
| | | type: user.MODIFY_CUSTOMMENU, |
| | | customMenu: customMenu |
| | | } |
| | | } |
| | | |
| | |
| | | // 系统配置 |
| | | /** |
| | | * @description 系统信息 |
| | | * 1、yun ( Y2xv$mkdWQ= ) 、 dandian ( U1$mkNP ) 、 yewu ( bG9j$mkYWw= ) |
| | | * 2、window.btoa('') 域名 不带 / |
| | | * 3、baoshide old ( aHR0cDovL2Nsb3VkLnBv$mkc2l0ZWNncm91cC5jb206ODA4MA== ) |
| | | * 4、baoshide ( aHR0cHM6Ly9jbG91ZC5$mkwb3NpdGVjZ3JvdXAuY29t ) |
| | | */ |
| | | export default { |
| | | sysType: 'bG9j$mkYWw=', // yun ( Y2xv$mkdWQ= ) 、 dandian ( U1$mkNP ) 、 yewu ( bG9j$mkYWw= ) |
| | | sysType: 'bG9j$mkYWw=', |
| | | caId: 'MjAyMDAxMTYxMjMzMzU1MDd$mkGQzkyMzI1Rjk4MDY0QUNGQjQ2Mg==', |
| | | cakey: 'MjAyMDAxMTYxMjQwMDQ2NDM$mk2N0QzODE2MjExNUI0MTc4OTVDMQ==', |
| | | cdomain: 'aHR0cDovL2Nsb3VkLnBv$mkc2l0ZWNncm91cC5jb206ODA4MA==', // window.btoa('') 域名 不带 /; baoshide ( aHR0cDovL2Nsb3VkLnBv$mkc2l0ZWNncm91cC5jb206ODA4MA== ) |
| | | styles: { |
| | | bg_black_style_blue: 'mk-blue-black', |
| | | bg_white_style_blue: 'mk-blue-white', |
| | | bg_black_style_red: 'mk-red-black', |
| | | bg_white_style_red: 'mk-red-white', |
| | | bg_black_style_orange_red: 'mk-orange-red-black', |
| | | bg_white_style_orange_red: 'mk-orange-red-white', |
| | | bg_black_style_orange: 'mk-orange-black', |
| | | bg_white_style_orange: 'mk-orange-white', |
| | | bg_black_style_orange_yellow: 'mk-orange-yellow-black', |
| | | bg_white_style_orange_yellow: 'mk-orange-yellow-white', |
| | | bg_black_style_yellow: 'mk-yellow-black', |
| | | bg_white_style_yellow: 'mk-yellow-white', |
| | | bg_black_style_yellow_green: 'mk-yellow-green-black', |
| | | bg_white_style_yellow_green: 'mk-yellow-green-white', |
| | | bg_black_style_green: 'mk-green-black', |
| | | bg_white_style_green: 'mk-green-white', |
| | | bg_black_style_cyan: 'mk-cyan-black', |
| | | bg_white_style_cyan: 'mk-cyan-white', |
| | | bg_black_style_blue_purple: 'mk-blue-purple-black', |
| | | bg_white_style_blue_purple: 'mk-blue-purple-white', |
| | | bg_black_style_purple: 'mk-purple-black', |
| | | bg_white_style_purple: 'mk-purple-white', |
| | | bg_black_style_magenta: 'mk-magenta-black', |
| | | bg_white_style_magenta: 'mk-magenta-white', |
| | | bg_black_style_grass_green: 'mk-grass-green-black', |
| | | bg_white_style_grass_green: 'mk-grass-green-white', |
| | | bg_black_style_deep_red: 'mk-deep-red-black', |
| | | bg_white_style_deep_red: 'mk-deep-red-white', |
| | | } |
| | | cdomain: 'aHR0cHM6Ly9jbG91ZC5$mkwb3NpdGVjZ3JvdXAuY29t' |
| | | } |
| | | |
| | | /** |
| | | * @description 系统样式库 |
| | | */ |
| | | export const styles = { |
| | | bg_black_style_blue: 'mk-blue-black', |
| | | bg_white_style_blue: 'mk-blue-white', |
| | | bg_black_style_red: 'mk-red-black', |
| | | bg_white_style_red: 'mk-red-white', |
| | | bg_black_style_orange_red: 'mk-orange-red-black', |
| | | bg_white_style_orange_red: 'mk-orange-red-white', |
| | | bg_black_style_orange: 'mk-orange-black', |
| | | bg_white_style_orange: 'mk-orange-white', |
| | | bg_black_style_orange_yellow: 'mk-orange-yellow-black', |
| | | bg_white_style_orange_yellow: 'mk-orange-yellow-white', |
| | | bg_black_style_yellow: 'mk-yellow-black', |
| | | bg_white_style_yellow: 'mk-yellow-white', |
| | | bg_black_style_yellow_green: 'mk-yellow-green-black', |
| | | bg_white_style_yellow_green: 'mk-yellow-green-white', |
| | | bg_black_style_green: 'mk-green-black', |
| | | bg_white_style_green: 'mk-green-white', |
| | | bg_black_style_cyan: 'mk-cyan-black', |
| | | bg_white_style_cyan: 'mk-cyan-white', |
| | | bg_black_style_blue_purple: 'mk-blue-purple-black', |
| | | bg_white_style_blue_purple: 'mk-blue-purple-white', |
| | | bg_black_style_purple: 'mk-purple-black', |
| | | bg_white_style_purple: 'mk-purple-white', |
| | | bg_black_style_magenta: 'mk-magenta-black', |
| | | bg_white_style_magenta: 'mk-magenta-white', |
| | | bg_black_style_grass_green: 'mk-grass-green-black', |
| | | bg_white_style_grass_green: 'mk-grass-green-white', |
| | | bg_black_style_deep_red: 'mk-deep-red-black', |
| | | bg_white_style_deep_red: 'mk-deep-red-white', |
| | | } |
| | |
| | | tabviews: [], // 导航栏 |
| | | collapse: _collapse, // 是否收起侧边栏导航 |
| | | isiframe: false, // 是否为iframe窗口 |
| | | editState: false, // 是否为编辑状态,值为false、true |
| | | editLevel: null, // 编辑菜单级别,值为level1、level2、level3、HS |
| | | permAction: {}, // 用户按钮权限 |
| | | permMenus: [], // 用户三级菜单列表 |
| | | memberLevel: _level, // 会员等级 |
| | | customMenu: null // 编辑中的菜单(自定义页面) |
| | | } |
| | | |
| | | // 用户消息 |
| | |
| | | ...state, |
| | | isiframe: action.isiframe |
| | | } |
| | | case Type.RESET_STATE: |
| | | // 重置默认参数(退出时) |
| | | return { |
| | | ...state, |
| | | ...{ |
| | | mainMenu: null, |
| | | tabviews: [], |
| | | collapse: false, |
| | | isiframe: false |
| | | } |
| | | } |
| | | case Type.RESET_EDITSTATE: |
| | | // 重置编辑状态 |
| | | document.body.className = '' |
| | | return { |
| | | ...state, |
| | | tabviews: [], |
| | | editState: action.editState, |
| | | collapse: false |
| | | } |
| | | case Type.RESET_EDITLEVEL: |
| | | // 重置编辑级别 |
| | | return { |
| | | ...state, |
| | | editState: true, |
| | | editLevel: action.editLevel |
| | | } |
| | | case Type.INIT_ACTIONPERMISSION: |
| | |
| | | ...state, |
| | | memberLevel: action.memberLevel |
| | | } |
| | | case Type.MODIFY_CUSTOMMENU: |
| | | // 修改自定义菜单信息 |
| | | return { |
| | | ...state, |
| | | customMenu: action.customMenu |
| | | } |
| | | case Type.LOGOUT: |
| | | return { |
| | | menuTree: null, |
| | |
| | | tabviews: [], |
| | | collapse: localStorage.getItem('collapse') === 'true', |
| | | isiframe: false, |
| | | editState: false, |
| | | editLevel: null, |
| | | permAction: {}, |
| | | permMenus: [], |
| | | customMenu: null |
| | | } |
| | | default: |
| | | return state |
| | |
| | | let roleId = sessionStorage.getItem('role_id') || '' |
| | | config.search = config.search.map(item => { |
| | | item.oriInitval = item.initval |
| | | if (['text', 'select', 'link'].includes(item.type) && param) { |
| | | if (param.searchkey === item.field) { |
| | | item.initval = param.searchval |
| | | } else if (param.BID && item.field.toLowerCase() === 'bid') { |
| | | item.initval = param.BID |
| | | } else if (param.data && param.data[item.field]) { |
| | | item.initval = param.data[item.field] |
| | | } |
| | | if (['text', 'select', 'link'].includes(item.type) && param && param.$searchkey === item.field) { |
| | | item.initval = param.$searchval |
| | | } |
| | | |
| | | if (item.required === 'true' && !item.initval) { |
| | |
| | | config.setting.dataresource = config.setting.dataresource.replace(/@\$|\$@/ig, '') |
| | | _customScript = _customScript.replace(/@\$|\$@/ig, '') |
| | | } |
| | | if (config.urlFields) { |
| | | let _param = param || {} |
| | | config.urlFields.forEach(field => { |
| | | let reg = new RegExp('@' + field + '@', 'ig') |
| | | let val = `'${_param[field] || ''}'` |
| | | config.setting.dataresource = config.setting.dataresource.replace(reg, val) |
| | | _customScript = _customScript.replace(reg, val) |
| | | }) |
| | | } |
| | | |
| | | config.setting.customScript = _customScript |
| | | } |
| | | |
| | | this.setState({ |
| | | BID: param && param.BID ? param.BID : '', |
| | | BID: param && param.$BID ? param.$BID : '', |
| | | loadingview: false, |
| | | config: config, |
| | | userConfig: userConfig, |
| | |
| | | let regoptions = [] |
| | | let userName = sessionStorage.getItem('User_Name') || '' |
| | | let fullName = sessionStorage.getItem('Full_Name') || '' |
| | | let city = sessionStorage.getItem('city') || '' |
| | | |
| | | if (sessionStorage.getItem('isEditState') === 'true') { |
| | | userName = sessionStorage.getItem('CloudUserName') || '' |
| | |
| | | } |
| | | }) |
| | | regoptions.push({ |
| | | reg: new RegExp('@login_city@', 'ig'), |
| | | value: city |
| | | }, { |
| | | reg: new RegExp('@userName@', 'ig'), |
| | | value: userName |
| | | }, { |
| | |
| | | param.custom_script = param.custom_script.replace(item.reg, item.value) |
| | | }) |
| | | |
| | | param.custom_script = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@UserName nvarchar(50),@FullName nvarchar(50) |
| | | Select @ErrorCode='',@retmsg ='',@UserName='${userName}', @FullName='${fullName}' |
| | | param.custom_script = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@UserName nvarchar(50),@FullName nvarchar(50),@login_city nvarchar(50) |
| | | Select @ErrorCode='',@retmsg ='',@UserName='${userName}', @FullName='${fullName}', @login_city='${city}' |
| | | ${param.custom_script} |
| | | ` |
| | | |
| | |
| | | UNSAFE_componentWillMount () { |
| | | // 组件加载时,获取菜单数据 |
| | | this.loadconfig() |
| | | } |
| | | |
| | | UNSAFE_componentWillReceiveProps(nextProps) { |
| | | if (nextProps.param && !is(fromJS(this.props.param), fromJS(nextProps.param))) { |
| | | let search = this.state.search.map(item => { |
| | | if (item.type === 'text' && item.key === nextProps.param.searchkey) { |
| | | item.value = nextProps.param.searchval |
| | | } |
| | | return item |
| | | }) |
| | | this.refreshbysearch(search) |
| | | } |
| | | } |
| | | |
| | | shouldComponentUpdate (nextProps, nextState) { |
| | |
| | | // 字段权限黑名单 |
| | | config.search = config.search.map(item => { |
| | | item.oriInitval = item.initval |
| | | if (['text', 'select', 'link'].includes(item.type) && param) { |
| | | if (param.searchkey === item.field) { |
| | | item.initval = param.searchval |
| | | } else if (param.BID && item.field.toLowerCase() === 'bid') { |
| | | item.initval = param.BID |
| | | } else if (param.data && param.data[item.field]) { |
| | | item.initval = param.data[item.field] |
| | | } |
| | | if (['text', 'select', 'link'].includes(item.type) && param && param.$searchkey === item.field) { |
| | | item.initval = param.$searchval |
| | | } |
| | | |
| | | if (!item.blacklist || item.blacklist.length === 0) return item |
| | |
| | | config.setting.laypage = config.setting.laypage !== 'false' // 是否分页,转为boolean 统一格式 |
| | | config.setting.execute = config.setting.default !== 'false' // 默认sql是否执行,转为boolean 统一格式 |
| | | config.setting.customScript = '' // 自定义脚本 |
| | | config.setting.dataresource = config.setting.dataresource || '' |
| | | |
| | | if (config.setting.interType === 'system' || (config.setting.interType === 'custom' && config.setting.requestMode === 'system')) { |
| | | if (config.setting.scripts && config.setting.scripts.length > 0) { |
| | |
| | | |
| | | if (!config.setting.execute) { // 默认sql 不执行时 置空 |
| | | config.setting.dataresource = '' |
| | | } else { |
| | | config.setting.dataresource = config.setting.dataresource || '' |
| | | } |
| | | if (/\s/.test(config.setting.dataresource)) { |
| | | config.setting.dataresource = '(' + config.setting.dataresource + ') tb' |
| | |
| | | } else { |
| | | config.setting.dataresource = config.setting.dataresource.replace(/@\$|\$@/ig, '') |
| | | config.setting.customScript = config.setting.customScript.replace(/@\$|\$@/ig, '') |
| | | } |
| | | if (config.urlFields) { |
| | | let _param = param || {} |
| | | config.urlFields.forEach(field => { |
| | | let reg = new RegExp('@' + field + '@', 'ig') |
| | | let val = `'${_param[field] || ''}'` |
| | | config.setting.dataresource = config.setting.dataresource.replace(reg, val) |
| | | config.setting.customScript = config.setting.customScript.replace(reg, val) |
| | | }) |
| | | } |
| | | } |
| | | |
| | |
| | | if (col.field) { |
| | | _arrField.push(col.field) |
| | | |
| | | if (col.linkmenu && col.linkmenu.length > 0) { |
| | | let menu_id = col.linkmenu.slice(-1)[0] |
| | | col.linkThdMenu = permMenus.filter(m => m.MenuID === menu_id)[0] || '' |
| | | } else { |
| | | col.linkThdMenu = '' |
| | | } |
| | | |
| | | col.nameField && _arrField.push(col.nameField) // 链接名字段 |
| | | if (col.Hide !== 'true' && col.type === 'number' && col.sum === 'true') { |
| | | statFields.push(col) |
| | |
| | | // 生成显示列,处理合并列中的字段 |
| | | config.columns.forEach((col, index) => { |
| | | if (_hideCol.includes(col.uuid)) return |
| | | |
| | | if (col.linkmenu && col.linkmenu.length > 0) { |
| | | let menu_id = col.linkmenu.slice(-1)[0] |
| | | col.linkThdMenu = permMenus.filter(m => m.MenuID === menu_id)[0] || '' |
| | | } else { |
| | | col.linkThdMenu = '' |
| | | } |
| | | |
| | | col.sort = index |
| | | |
| | |
| | | actions: _actions, |
| | | columns: _columns, |
| | | arr_field: _arrField.join(','), |
| | | BID: param && param.BID ? param.BID : '', |
| | | BID: param && param.$BID ? param.$BID : '', |
| | | search: Utils.initMainSearch(config.search), // 搜索条件初始化(含有时间格式,需要转化) |
| | | hasReqFields |
| | | }, () => { |
| | |
| | | |
| | | Api.genericInterface(param).then(res => { |
| | | if (res.status) { |
| | | if (res.mk_ex_invoke === 'false') { |
| | | if (res.mk_ex_invoke === 'false' || res.mk_ex_invoke === false) { |
| | | this.loadmaindata() |
| | | } else { |
| | | this.customOuterRequest(res) |
| | |
| | | param[key] = result[key] |
| | | }) |
| | | |
| | | Api.directRequest(url, setting.method, param).then(res => { |
| | | Api.directRequest(url, setting.method, param, setting.cross).then(res => { |
| | | if (typeof(res) !== 'object' || Array.isArray(res)) { |
| | | let error = '未知的返回结果!' |
| | | |
| | |
| | | let result = await Api.genericInterface(param) |
| | | if (result.status) { |
| | | let data = fromJS(this.state.data).toJS() |
| | | let selectedData = fromJS(this.state.selectedData).toJS() |
| | | if (result.data && result.data[0]) { |
| | | let _data = result.data[0] |
| | | let _data = result.data[0] || {} |
| | | |
| | | if (absFields.length) { |
| | | absFields.forEach(field => { |
| | |
| | | _data[field] = Math.abs(_data[field]) |
| | | }) |
| | | } |
| | | _data.$$uuid = _data[setting.primaryKey] || '' |
| | | _data.$$BID = BID || '' |
| | | |
| | | try { |
| | | data = data.map(item => { |
| | | if (item[setting.primaryKey] === _data[setting.primaryKey]) { |
| | | if (item.$$uuid === _data.$$uuid) { |
| | | _data.key = item.key |
| | | _data.$$uuid = _data[setting.primaryKey] || '' |
| | | _data.$$BID = BID || '' |
| | | |
| | | return _data |
| | | } else { |
| | | return item |
| | | } |
| | | }) |
| | | selectedData = selectedData.map(item => { |
| | | if (_data.$$uuid === item.$$uuid) { |
| | | return _data |
| | | } |
| | | return item |
| | | }) |
| | | } catch { |
| | | console.warn('数据查询错误') |
| | |
| | | } |
| | | |
| | | this.setState({ |
| | | data: data, |
| | | data, |
| | | selectedData, |
| | | loading: false |
| | | }) |
| | | } else { |
| | |
| | | } |
| | | |
| | | UNSAFE_componentWillReceiveProps(nextProps) { |
| | | if (!is(fromJS(this.props.tabviews), fromJS(nextProps.tabviews))) { |
| | | if (!is(fromJS(this.props.tabviews), fromJS(nextProps.tabviews))) { |
| | | let selectTab = nextProps.tabviews.filter(tab => tab.selected)[0] |
| | | if (selectTab && selectTab.MenuID === this.props.MenuID) { |
| | | this.setShortcut() |
| | | } |
| | | } else if (nextProps.param && !is(fromJS(this.props.param), fromJS(nextProps.param))) { |
| | | let search = this.state.search.map(item => { |
| | | if (item.type === 'text' && item.key === nextProps.param.searchkey) { |
| | | item.value = nextProps.param.searchval |
| | | } |
| | | return item |
| | | }) |
| | | this.refreshbysearch(search) |
| | | } |
| | | } |
| | | |
| | |
| | | .commontable-main-action { |
| | | min-height: 25px; |
| | | .button-list { |
| | | padding-right: 110px; |
| | | padding-right: 60px; |
| | | } |
| | | } |
| | | .ant-modal-mask { |
| | |
| | | import { is, fromJS } from 'immutable' |
| | | |
| | | import asyncComponent from '@/utils/asyncComponent' |
| | | import zhCN from '@/locales/zh-CN/model.js' |
| | | import enUS from '@/locales/en-US/model.js' |
| | | |
| | | import './index.scss' |
| | | |
| | | const CardCellComponent = asyncComponent(() => import('../cardcellList')) |
| | |
| | | } |
| | | |
| | | state = { |
| | | dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | card: null, // 卡片信息,包括正反面 |
| | | } |
| | | |
| | |
| | | import { Icon, Col, Tooltip, notification } from 'antd' |
| | | import moment from 'moment' |
| | | |
| | | import zhCN from '@/locales/zh-CN/model.js' |
| | | import enUS from '@/locales/en-US/model.js' |
| | | import asyncComponent from './asyncButtonComponent' |
| | | import asyncElementComponent from '@/utils/asyncComponent' |
| | | |
| | |
| | | } |
| | | |
| | | state = { |
| | | dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | card: null, // 编辑中元素 |
| | | elements: null, // 按钮组 |
| | | } |
| | |
| | | let _style = card.style ? {...card.style} : {} |
| | | |
| | | if (card.datatype === 'static') { |
| | | val = card.value |
| | | val = card.value || '' |
| | | if (/@username@|@fullName@|@login_city@/ig.test(val)) { |
| | | let userName = sessionStorage.getItem('User_Name') || '' |
| | | let fullName = sessionStorage.getItem('Full_Name') || '' |
| | | let city = sessionStorage.getItem('city') || '' |
| | | val = val.replace(/@username@/ig, userName).replace(/@fullName@/ig, fullName).replace(/@login_city@/ig, city) |
| | | } |
| | | } else if (data.hasOwnProperty(card.field)) { |
| | | val = data[card.field] |
| | | } |
| | |
| | | return ( |
| | | <Col key={card.uuid} span={card.width}> |
| | | <div style={_style} onClick={(e) => {this.openNewView(e, card)}}> |
| | | <div className={'ant-mk-text line' + card.height} style={{height: card.innerHeight || 21}}>{val}</div> |
| | | <div className={'ant-mk-text line' + card.height} style={{height: card.innerHeight || 'auto'}}>{val}</div> |
| | | </div> |
| | | </Col> |
| | | ) |
| | |
| | | return ( |
| | | <Col key={card.uuid} span={card.width}> |
| | | <div style={_style}> |
| | | <div className={'ant-mk-text line' + card.height} style={{height: card.innerHeight || 21}}>{val}</div> |
| | | <div className={'ant-mk-text line' + card.height} style={{height: card.innerHeight || 'auto'}}>{val}</div> |
| | | </div> |
| | | </Col> |
| | | ) |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { is, fromJS } from 'immutable' |
| | | import { connect } from 'react-redux' |
| | | import { Spin, Empty, notification, Col, Pagination } from 'antd' |
| | | |
| | | import Api from '@/api' |
| | |
| | | import nextImg from '@/assets/img/next.png' |
| | | import MKEmitter from '@/utils/events.js' |
| | | import asyncComponent from '@/utils/asyncComponent' |
| | | import { modifyTabview } from '@/store/action' |
| | | import './index.scss' |
| | | |
| | | const CardItem = asyncComponent(() => import('../cardItem')) |
| | |
| | | changeCard = (index, item) => { |
| | | const { config, selectKeys, selectedData, activeKey } = this.state |
| | | |
| | | if (!config.wrap.cardType) return |
| | | this.openView(item) |
| | | |
| | | if (!config.wrap.cardType) return |
| | | |
| | | let _selectKeys = [] |
| | | let _selectedData = [] |
| | | let _activeKey = '' |
| | |
| | | }) |
| | | |
| | | MKEmitter.emit('resetSelectLine', config.uuid, (_item ? _item.$$uuid : ''), _item) |
| | | } |
| | | |
| | | openView = (item) => { |
| | | const { card } = this.state |
| | | |
| | | if (card.setting.click === 'menu') { |
| | | let menu = null |
| | | |
| | | if (card.setting.menu && card.setting.menu.length > 0) { |
| | | let menu_id = card.setting.menu.slice(-1)[0] |
| | | menu = this.props.permMenus.filter(m => m.MenuID === menu_id)[0] || '' |
| | | } |
| | | |
| | | if (!menu) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '菜单已删除或没有访问权限!', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } |
| | | |
| | | let newtab = { |
| | | ...menu, |
| | | selected: true, |
| | | param: {} |
| | | } |
| | | |
| | | if (card.setting.joint === 'true') { |
| | | newtab.param.$BID = item.$$uuid |
| | | } |
| | | |
| | | if (['linkage_navigation', 'linkage'].includes(window.GLOB.navBar)) { |
| | | this.props.modifyTabview([newtab]) |
| | | } else { |
| | | let tabs = this.props.tabviews.filter((tab, i) => { |
| | | tab.selected = false |
| | | return tab.MenuID !== newtab.MenuID |
| | | }) |
| | | |
| | | if (this.props.tabviews.length > tabs.length) { |
| | | this.props.modifyTabview(fromJS(tabs).toJS()) |
| | | } |
| | | |
| | | this.setState({}, () => { |
| | | tabs.push(newtab) |
| | | this.props.modifyTabview(tabs) |
| | | }) |
| | | } |
| | | } else if (card.setting.click === 'link') { |
| | | let src = card.setting.linkurl |
| | | |
| | | if (src.indexOf('paramsmain/') > -1) { |
| | | try { |
| | | let _url = src.split('paramsmain/')[0] + 'paramsmain/' |
| | | let _param = JSON.parse(window.decodeURIComponent(window.atob(src.split('paramsmain/')[1]))) |
| | | |
| | | _param.UserID = sessionStorage.getItem('UserID') |
| | | _param.LoginUID = sessionStorage.getItem('LoginUID') |
| | | _param.User_Name = sessionStorage.getItem('User_Name') |
| | | _param.param = { BID: item.$$uuid } |
| | | src = _url + window.btoa(window.encodeURIComponent(JSON.stringify(_param))) |
| | | } catch { |
| | | console.warn('菜单参数解析错误!') |
| | | } |
| | | } else if (card.setting.joint === 'true') { |
| | | let con = '?' |
| | | |
| | | if (/\?/ig.test(src)) { |
| | | con = '&' |
| | | } |
| | | |
| | | src = src + `${con}id=${item.$$uuid}&appkey=${window.GLOB.appkey}&userid=${sessionStorage.getItem('UserID')}&LoginUID=${sessionStorage.getItem('LoginUID') || ''}` |
| | | } |
| | | |
| | | window.open(src) |
| | | } |
| | | } |
| | | |
| | | render() { |
| | |
| | | {switchable ? <div className={'prev-page ' + (pageIndex === 1 ? 'disabled' : '')} onClick={this.prevPage}><div><div><img src={preImg} alt=""/></div></div></div> : null} |
| | | {data && data.length > 0 ? <div className="card-row-list"> |
| | | {data.map((item, index) => ( |
| | | <Col className={activeKey === index ? 'active' : (selectKeys.indexOf(index) > -1 ? 'selected' : '')} key={index} span={card.setting.width} offset={!index ? offset : 0} onClick={() => {this.changeCard(index, item)}}> |
| | | <Col className={(activeKey === index ? 'active' : (selectKeys.indexOf(index) > -1 ? 'selected' : '')) + (card.setting.click ? ' pointer' : '')} key={index} span={card.setting.width} offset={!index ? offset : 0} onClick={() => {this.changeCard(index, item)}}> |
| | | <CardItem card={card} cards={config} data={item}/> |
| | | </Col> |
| | | ))} |
| | |
| | | } |
| | | } |
| | | |
| | | export default DataCard |
| | | const mapStateToProps = (state) => { |
| | | return { |
| | | permMenus: state.permMenus, |
| | | tabviews: state.tabviews, |
| | | } |
| | | } |
| | | |
| | | const mapDispatchToProps = (dispatch) => { |
| | | return { |
| | | modifyTabview: (tabviews) => dispatch(modifyTabview(tabviews)) |
| | | } |
| | | } |
| | | |
| | | export default connect(mapStateToProps, mapDispatchToProps)(DataCard) |
| | |
| | | background-color: #ffffff; |
| | | transition: all 0.3s; |
| | | } |
| | | >.pointer { |
| | | cursor: pointer; |
| | | } |
| | | >.active >.card-item-box { |
| | | border-color: #1890ff!important; |
| | | box-shadow: 0 0 4px #1890ff; |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { is, fromJS } from 'immutable' |
| | | import { connect } from 'react-redux' |
| | | import { Spin, notification, Col } from 'antd' |
| | | import moment from 'moment' |
| | | |
| | | import asyncComponent from '@/utils/asyncComponent' |
| | | import Api from '@/api' |
| | | import Utils from '@/utils/utils.js' |
| | | import UtilsDM from '@/utils/utils-datamanage.js' |
| | | import asyncComponent from '@/utils/asyncComponent' |
| | | import MKEmitter from '@/utils/events.js' |
| | | import { modifyTabview } from '@/store/action' |
| | | import './index.scss' |
| | | |
| | | const CardItem = asyncComponent(() => import('../cardItem')) |
| | | const NormalHeader = asyncComponent(() => import('@/tabviews/custom/components/share/normalheader')) |
| | | |
| | | class DataCard extends Component { |
| | | class PropCard extends Component { |
| | | static propTpyes = { |
| | | BID: PropTypes.any, // 父级Id |
| | | data: PropTypes.array, // 统一查询数据 |
| | |
| | | loading: false, // 数据加载状态 |
| | | activeKey: '', // 选中数据 |
| | | sync: false, // 是否统一请求数据 |
| | | data: {} // 数据 |
| | | data: {}, // 数据 |
| | | timer: null // 定时器时间间隔 |
| | | } |
| | | |
| | | UNSAFE_componentWillMount () { |
| | |
| | | MKEmitter.addListener('reloadData', this.reloadData) |
| | | MKEmitter.addListener('resetSelectLine', this.resetParentParam) |
| | | MKEmitter.removeListener('refreshByButtonResult', this.refreshByButtonResult) |
| | | this.handleTimer() |
| | | } |
| | | |
| | | shouldComponentUpdate (nextProps, nextState) { |
| | |
| | | } |
| | | |
| | | componentWillUnmount () { |
| | | clearTimeout(this.timer) |
| | | this.setState = () => { |
| | | return |
| | | } |
| | |
| | | }) |
| | | } |
| | | } |
| | | } |
| | | |
| | | handleTimer = () => { |
| | | const { config } = this.state |
| | | |
| | | if (!config.timer) return |
| | | |
| | | const _change = { |
| | | '15s': 15000, |
| | | '30s': 30000, |
| | | '1min': 60000, |
| | | '5min': 300000, |
| | | '10min': 600000, |
| | | '15min': 900000, |
| | | '30min': 1800000, |
| | | '1hour': 3600000 |
| | | } |
| | | |
| | | let timer = _change[config.timer] |
| | | |
| | | if (!timer) return |
| | | |
| | | let _param = { |
| | | func: 's_get_timers_role', |
| | | LText: `select '${window.GLOB.appkey || ''}','${config.uuid}'`, |
| | | timer_type: config.timer, |
| | | component_id: config.uuid |
| | | } |
| | | |
| | | _param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') // 时间戳 |
| | | _param.LText = Utils.formatOptions(_param.LText) // 关键字符替换,base64加密 |
| | | _param.secretkey = Utils.encrypt(_param.LText, _param.timestamp) // md5密钥 |
| | | |
| | | Api.getSystemConfig(_param).then(result => { |
| | | if (!result.status) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: result.message, |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } else if (result.run_type) { |
| | | this.setState({timer}) |
| | | this.timer = setTimeout(() => { |
| | | this.timerTask() |
| | | }, timer) |
| | | } |
| | | }) |
| | | } |
| | | |
| | | timerTask = () => { |
| | | const { timer } = this.state |
| | | if (!timer) return |
| | | |
| | | this.loadData(true) |
| | | |
| | | this.timer = setTimeout(() => { |
| | | this.timerTask() |
| | | }, timer) |
| | | } |
| | | |
| | | /** |
| | |
| | | this.loadData() |
| | | } |
| | | |
| | | async loadData () { |
| | | async loadData (hastimer) { |
| | | const { mainSearch, menuType } = this.props |
| | | const { config, arr_field, BID } = this.state |
| | | |
| | |
| | | }) |
| | | } |
| | | |
| | | this.setState({ |
| | | loading: true |
| | | }) |
| | | if (!hastimer) { |
| | | this.setState({ |
| | | loading: true |
| | | }) |
| | | } |
| | | |
| | | let _orderBy = config.setting.order || '' |
| | | let param = UtilsDM.getQueryDataParams(config.setting, arr_field, searches, _orderBy, 1, 1, BID, menuType) |
| | |
| | | }) |
| | | } else { |
| | | this.setState({ |
| | | loading: false |
| | | loading: false, |
| | | timer: null |
| | | }) |
| | | notification.error({ |
| | | top: 92, |
| | |
| | | changeCard = (index, item) => { |
| | | const { config, data, activeKey } = this.state |
| | | |
| | | this.openView(item) |
| | | |
| | | if (!config.wrap.cardType || activeKey === index) return |
| | | |
| | | this.setState({ |
| | |
| | | |
| | | MKEmitter.emit('resetSelectLine', config.uuid, (item.setting.primaryId || ''), data) |
| | | } |
| | | |
| | | openView = (item) => { |
| | | if (item.setting.click === 'menu') { |
| | | let menu = null |
| | | |
| | | if (item.setting.menu && item.setting.menu.length > 0) { |
| | | let menu_id = item.setting.menu.slice(-1)[0] |
| | | menu = this.props.permMenus.filter(m => m.MenuID === menu_id)[0] || '' |
| | | } |
| | | |
| | | if (!menu) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '菜单已删除或没有访问权限!', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } |
| | | |
| | | let newtab = { |
| | | ...menu, |
| | | selected: true, |
| | | param: {} |
| | | } |
| | | |
| | | if (item.setting.joint === 'true') { |
| | | newtab.param.$BID = item.setting.primaryId || '' |
| | | } |
| | | |
| | | if (['linkage_navigation', 'linkage'].includes(window.GLOB.navBar)) { |
| | | this.props.modifyTabview([newtab]) |
| | | } else { |
| | | let tabs = this.props.tabviews.filter((tab, i) => { |
| | | tab.selected = false |
| | | return tab.MenuID !== newtab.MenuID |
| | | }) |
| | | |
| | | if (this.props.tabviews.length > tabs.length) { |
| | | this.props.modifyTabview(fromJS(tabs).toJS()) |
| | | } |
| | | |
| | | this.setState({}, () => { |
| | | tabs.push(newtab) |
| | | this.props.modifyTabview(tabs) |
| | | }) |
| | | } |
| | | } else if (item.setting.click === 'link') { |
| | | let src = item.setting.linkurl |
| | | |
| | | if (src.indexOf('paramsmain/') > -1) { |
| | | try { |
| | | let _url = src.split('paramsmain/')[0] + 'paramsmain/' |
| | | let _param = JSON.parse(window.decodeURIComponent(window.atob(src.split('paramsmain/')[1]))) |
| | | |
| | | _param.UserID = sessionStorage.getItem('UserID') |
| | | _param.LoginUID = sessionStorage.getItem('LoginUID') |
| | | _param.User_Name = sessionStorage.getItem('User_Name') |
| | | _param.param = { BID: item.setting.primaryId } |
| | | src = _url + window.btoa(window.encodeURIComponent(JSON.stringify(_param))) |
| | | } catch { |
| | | console.warn('菜单参数解析错误!') |
| | | } |
| | | } else if (item.setting.joint === 'true') { |
| | | let con = '?' |
| | | |
| | | if (/\?/ig.test(src)) { |
| | | con = '&' |
| | | } |
| | | |
| | | src = src + `${con}id=${item.setting.primaryId}&appkey=${window.GLOB.appkey}&userid=${sessionStorage.getItem('UserID')}&LoginUID=${sessionStorage.getItem('LoginUID') || ''}` |
| | | } |
| | | |
| | | window.open(src) |
| | | } |
| | | } |
| | | |
| | | |
| | | render() { |
| | | const { config, loading, data, activeKey } = this.state |
| | |
| | | <NormalHeader config={config}/> |
| | | <div className={`card-row-list ${config.wrap.cardType || ''} ${config.wrap.scale || ''}`}> |
| | | {config.subcards.map((item, index) => ( |
| | | <Col className={activeKey === index ? 'active' : ''} key={index} span={item.setting.width || 6} offset={item.offset || 0} onClick={() => {this.changeCard(index, item)}}> |
| | | <Col className={(activeKey === index ? 'active' : '') + (item.setting.click ? ' pointer' : '')} key={index} span={item.setting.width || 6} offset={item.offset || 0} onClick={() => {this.changeCard(index, item)}}> |
| | | <CardItem card={item} cards={config} data={data}/> |
| | | </Col> |
| | | ))} |
| | |
| | | } |
| | | } |
| | | |
| | | export default DataCard |
| | | const mapStateToProps = (state) => { |
| | | return { |
| | | permMenus: state.permMenus, |
| | | tabviews: state.tabviews, |
| | | } |
| | | } |
| | | |
| | | const mapDispatchToProps = (dispatch) => { |
| | | return { |
| | | modifyTabview: (tabviews) => dispatch(modifyTabview(tabviews)) |
| | | } |
| | | } |
| | | |
| | | export default connect(mapStateToProps, mapDispatchToProps)(PropCard) |
| | |
| | | background-color: #ffffff; |
| | | transition: all 0.3s; |
| | | } |
| | | >.pointer { |
| | | cursor: pointer; |
| | | } |
| | | >.active >.card-item-box { |
| | | border-color: #1890ff!important; |
| | | box-shadow: 0 0 4px #1890ff; |
New file |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { is, fromJS } from 'immutable' |
| | | |
| | | import asyncComponent from '@/utils/asyncComponent' |
| | | |
| | | import './index.scss' |
| | | |
| | | const CardCellComponent = asyncComponent(() => import('@/tabviews/custom/components/card/cardcellList')) |
| | | |
| | | class CardBoxComponent extends Component { |
| | | static propTpyes = { |
| | | cards: PropTypes.object, // 卡片行配置信息 |
| | | card: PropTypes.object, // 卡片配置信息 |
| | | data: PropTypes.object, |
| | | } |
| | | |
| | | state = { |
| | | card: null, // 卡片信息,包括正反面 |
| | | } |
| | | |
| | | /** |
| | | * @description 搜索条件初始化 |
| | | */ |
| | | UNSAFE_componentWillMount () { |
| | | |
| | | } |
| | | |
| | | shouldComponentUpdate (nextProps, nextState) { |
| | | return !is(fromJS(this.state), fromJS(nextState)) || !is(fromJS(this.props), fromJS(nextProps)) |
| | | } |
| | | |
| | | /** |
| | | * @description 组件销毁,清除state更新,清除快捷键设置 |
| | | */ |
| | | componentWillUnmount () { |
| | | this.setState = () => { |
| | | return |
| | | } |
| | | } |
| | | |
| | | render() { |
| | | const { card, data, cards } = this.props |
| | | |
| | | return ( |
| | | <div className="card-item-box" style={card.style}> |
| | | <CardCellComponent data={data} cards={cards} cardCell={card} elements={card.elements}/> |
| | | </div> |
| | | ) |
| | | } |
| | | } |
| | | |
| | | export default CardBoxComponent |
New file |
| | |
| | | .card-item-box { |
| | | position: relative; |
| | | overflow: hidden; |
| | | |
| | | .back-side { |
| | | position: absolute; |
| | | top: 0px; |
| | | left: 0px; |
| | | right: 0px; |
| | | bottom: 0px; |
| | | background-color: #ffffff; |
| | | transition: all 0.3s; |
| | | background-position: center center; |
| | | background-repeat: no-repeat; |
| | | background-size: cover; |
| | | } |
| | | .back-side.up { |
| | | transform: translate(0, 100%); |
| | | } |
| | | .back-side.down { |
| | | transform: translate(0, -100%); |
| | | } |
| | | .back-side.left { |
| | | transform: translate(100%, 0); |
| | | } |
| | | .back-side.right { |
| | | transform: translate(-100%, 0); |
| | | } |
| | | .back-side.opacity { |
| | | opacity: 0; |
| | | } |
| | | .back-side.rotateX { |
| | | transform: rotateX(90deg); |
| | | } |
| | | .back-side.rotateY { |
| | | transform: rotateY(90deg); |
| | | } |
| | | .back-side.scale { |
| | | transform: scale(0, 0); |
| | | } |
| | | } |
| | | .card-item-box:hover { |
| | | .back-side.up, .back-side.down, .back-side.left, .back-side.right { |
| | | transform: translate(0, 0); |
| | | } |
| | | .back-side.opacity { |
| | | opacity: 1; |
| | | } |
| | | .back-side.rotateX { |
| | | transform: rotateX(0deg); |
| | | } |
| | | .back-side.rotateY { |
| | | transform: rotateY(0deg); |
| | | } |
| | | .back-side.scale { |
| | | transform: scale(1, 1); |
| | | } |
| | | } |
New file |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { is, fromJS } from 'immutable' |
| | | import { connect } from 'react-redux' |
| | | import { Spin, Empty, notification, Carousel } from 'antd' |
| | | |
| | | import Api from '@/api' |
| | | import UtilsDM from '@/utils/utils-datamanage.js' |
| | | import MKEmitter from '@/utils/events.js' |
| | | import asyncComponent from '@/utils/asyncComponent' |
| | | import { modifyTabview } from '@/store/action' |
| | | import './index.scss' |
| | | |
| | | const CardItem = asyncComponent(() => import('../cardItem')) |
| | | |
| | | class DataCard extends Component { |
| | | static propTpyes = { |
| | | BID: PropTypes.any, // 父级Id |
| | | data: PropTypes.array, // 统一查询数据 |
| | | config: PropTypes.object, // 组件配置信息 |
| | | mainSearch: PropTypes.any, // 外层搜索条件 |
| | | menuType: PropTypes.any, // 菜单类型 |
| | | } |
| | | |
| | | state = { |
| | | BID: '', // 上级ID |
| | | config: null, // 图表配置信息 |
| | | loading: false, // 数据加载状态 |
| | | sync: false, // 是否统一请求数据 |
| | | card: null, // 卡片设置 |
| | | data: null, // 数据 |
| | | } |
| | | |
| | | UNSAFE_componentWillMount () { |
| | | const { data, initdata, BID } = this.props |
| | | let _config = fromJS(this.props.config).toJS() |
| | | let _card = _config.subcards[0] |
| | | let _cols = new Map() |
| | | |
| | | let _data = null |
| | | let _sync = _config.setting.sync === 'true' |
| | | |
| | | if (_config.setting.sync === 'true' && data) { |
| | | _data = data[_config.dataName] || [] |
| | | _sync = false |
| | | } else if (_config.setting.sync === 'true' && initdata) { |
| | | _data = initdata || [] |
| | | _sync = false |
| | | } |
| | | |
| | | if (_data) { |
| | | _data = _data.map((item, index) => { |
| | | item.key = index |
| | | item.$$uuid = item[_config.setting.primaryKey] || '' |
| | | item.$$BID = BID || '' |
| | | return item |
| | | }) |
| | | } |
| | | |
| | | _config.columns.forEach(item => { |
| | | _cols.set(item.field, item) |
| | | }) |
| | | |
| | | _card.style.height = _config.style.height |
| | | |
| | | if (_card.setting.click) { |
| | | _card.style.cursor = 'pointer' |
| | | } |
| | | |
| | | _card.elements = _card.elements.map(item => { |
| | | if (item.field && _cols.has(item.field)) { |
| | | item.col = _cols.get(item.field) |
| | | } |
| | | return item |
| | | }) |
| | | |
| | | _config.wrap.speed = (_config.wrap.speed || 3) * 1000 |
| | | |
| | | this.setState({ |
| | | sync: _sync, |
| | | data: _data, |
| | | BID: BID || '', |
| | | config: _config, |
| | | card: _card, |
| | | arr_field: _config.columns.map(col => col.field).join(','), |
| | | }, () => { |
| | | if (_config.setting.sync !== 'true' && _config.setting.onload === 'true') { |
| | | this.loadData() |
| | | } |
| | | }) |
| | | } |
| | | |
| | | componentDidMount () { |
| | | MKEmitter.addListener('resetSelectLine', this.resetParentParam) |
| | | MKEmitter.addListener('getexceloutparam', this.getexceloutparam) |
| | | MKEmitter.addListener('refreshByButtonResult', this.refreshByButtonResult) |
| | | } |
| | | |
| | | shouldComponentUpdate (nextProps, nextState) { |
| | | return !is(fromJS(this.state), fromJS(nextState)) |
| | | } |
| | | |
| | | UNSAFE_componentWillReceiveProps (nextProps) { |
| | | const { sync, config, BID } = this.state |
| | | |
| | | if (sync && !is(fromJS(this.props.data), fromJS(nextProps.data))) { |
| | | let _data = [] |
| | | if (nextProps.data && nextProps.data[config.dataName]) { |
| | | _data = nextProps.data[config.dataName] || [] |
| | | } |
| | | |
| | | _data = _data.map((item, index) => { |
| | | item.key = index |
| | | item.$$uuid = item[config.setting.primaryKey] || '' |
| | | item.$$BID = BID || '' |
| | | return item |
| | | }) |
| | | |
| | | this.setState({sync: false, data: _data}) |
| | | } else if (nextProps.mainSearch && !is(fromJS(this.props.mainSearch), fromJS(nextProps.mainSearch))) { |
| | | if (config.setting.syncRefresh === 'true') { |
| | | this.setState({}, () => { |
| | | this.loadData() |
| | | }) |
| | | } |
| | | } |
| | | } |
| | | |
| | | componentWillUnmount () { |
| | | this.setState = () => { |
| | | return |
| | | } |
| | | MKEmitter.removeListener('resetSelectLine', this.resetParentParam) |
| | | MKEmitter.removeListener('getexceloutparam', this.getexceloutparam) |
| | | MKEmitter.removeListener('refreshByButtonResult', this.refreshByButtonResult) |
| | | } |
| | | |
| | | /** |
| | | * @description 按钮执行完成后页面刷新 |
| | | * @param {*} menuId // 菜单Id |
| | | * @param {*} position // 刷新位置 |
| | | * @param {*} btn // 执行的按钮 |
| | | */ |
| | | refreshByButtonResult = (menuId, position, btn) => { |
| | | const { config, BID } = this.state |
| | | |
| | | if (config.uuid !== menuId) return |
| | | |
| | | this.loadData(btn) // 数据刷新 |
| | | |
| | | if (btn.syncComponentId && btn.syncComponentId !== config.uuid && btn.syncComponentId !== config.setting.supModule) { |
| | | MKEmitter.emit('reloadData', btn.syncComponentId) // 同级标签刷新 |
| | | } |
| | | |
| | | if (position === 'mainline' && config.setting.supModule) { // 主表行刷新 |
| | | MKEmitter.emit('reloadData', config.setting.supModule, (BID || 'empty')) |
| | | } else if (position === 'popclose') { // 标签关闭刷新 |
| | | config.setting.supModule && MKEmitter.emit('reloadData', config.setting.supModule, (BID || 'empty')) |
| | | btn.$tabId && MKEmitter.emit('refreshPopButton', btn.$tabId) |
| | | } |
| | | } |
| | | |
| | | resetParentParam = (MenuID, id, data) => { |
| | | const { config } = this.state |
| | | |
| | | if (!config.setting.supModule || config.setting.supModule !== MenuID) return |
| | | if (id !== this.state.BID) { |
| | | this.setState({ BID: id }, () => { |
| | | this.loadData() |
| | | }) |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * @description 导出Excel时,获取页面搜索排序等参数 |
| | | */ |
| | | getexceloutparam = (menuId, btnId) => { |
| | | const { mainSearch } = this.props |
| | | const { arr_field, config } = this.state |
| | | |
| | | if (config.uuid !== menuId) return |
| | | |
| | | let searches = mainSearch ? fromJS(mainSearch).toJS() : [] |
| | | |
| | | MKEmitter.emit('execExcelout', config.uuid, btnId, { |
| | | arr_field: arr_field, |
| | | orderBy: config.setting.order || '', |
| | | search: searches, |
| | | menuName: config.name |
| | | }) |
| | | } |
| | | |
| | | async loadData () { |
| | | const { mainSearch, menuType } = this.props |
| | | const { config, arr_field, BID } = this.state |
| | | |
| | | if (config.setting.supModule && !BID) { // BID 不存在时,不做查询 |
| | | this.setState({ |
| | | data: [], |
| | | loading: false |
| | | }) |
| | | return |
| | | } |
| | | |
| | | let searches = mainSearch ? fromJS(mainSearch).toJS() : [] |
| | | |
| | | this.setState({ |
| | | loading: true |
| | | }) |
| | | |
| | | let _orderBy = config.setting.order || '' |
| | | let param = UtilsDM.getQueryDataParams(config.setting, arr_field, searches, _orderBy, '', '', BID, menuType) |
| | | |
| | | let result = await Api.genericInterface(param) |
| | | if (result.status) { |
| | | this.setState({ |
| | | data: result.data.map((item, index) => { |
| | | item.key = index |
| | | item.$$uuid = item[config.setting.primaryKey] || '' |
| | | item.$$BID = BID || '' |
| | | return item |
| | | }), |
| | | loading: false |
| | | }) |
| | | } else { |
| | | this.setState({ |
| | | loading: false |
| | | }) |
| | | notification.error({ |
| | | top: 92, |
| | | message: result.message, |
| | | duration: 10 |
| | | }) |
| | | } |
| | | } |
| | | |
| | | openView = (item) => { |
| | | const { card } = this.state |
| | | |
| | | if (card.setting.click === 'menu') { |
| | | let menu = null |
| | | |
| | | if (card.setting.menu && card.setting.menu.length > 0) { |
| | | let menu_id = card.setting.menu.slice(-1)[0] |
| | | menu = this.props.permMenus.filter(m => m.MenuID === menu_id)[0] || '' |
| | | } |
| | | |
| | | if (!menu) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '菜单已删除或没有访问权限!', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } |
| | | |
| | | let newtab = { |
| | | ...menu, |
| | | selected: true, |
| | | param: {} |
| | | } |
| | | |
| | | if (card.setting.joint === 'true') { |
| | | newtab.param.$BID = item.$$uuid |
| | | } |
| | | |
| | | if (['linkage_navigation', 'linkage'].includes(window.GLOB.navBar)) { |
| | | this.props.modifyTabview([newtab]) |
| | | } else { |
| | | let tabs = this.props.tabviews.filter((tab, i) => { |
| | | tab.selected = false |
| | | return tab.MenuID !== newtab.MenuID |
| | | }) |
| | | |
| | | if (this.props.tabviews.length > tabs.length) { |
| | | this.props.modifyTabview(fromJS(tabs).toJS()) |
| | | } |
| | | |
| | | this.setState({}, () => { |
| | | tabs.push(newtab) |
| | | this.props.modifyTabview(tabs) |
| | | }) |
| | | } |
| | | } else if (card.setting.click === 'link') { |
| | | let src = card.setting.linkurl |
| | | |
| | | if (src.indexOf('paramsmain/') > -1) { |
| | | try { |
| | | let _url = src.split('paramsmain/')[0] + 'paramsmain/' |
| | | let _param = JSON.parse(window.decodeURIComponent(window.atob(src.split('paramsmain/')[1]))) |
| | | |
| | | _param.UserID = sessionStorage.getItem('UserID') |
| | | _param.LoginUID = sessionStorage.getItem('LoginUID') |
| | | _param.User_Name = sessionStorage.getItem('User_Name') |
| | | _param.param = { BID: item.$$uuid } |
| | | src = _url + window.btoa(window.encodeURIComponent(JSON.stringify(_param))) |
| | | } catch { |
| | | console.warn('菜单参数解析错误!') |
| | | } |
| | | } else if (card.setting.joint === 'true') { |
| | | let con = '?' |
| | | |
| | | if (/\?/ig.test(src)) { |
| | | con = '&' |
| | | } |
| | | |
| | | src = src + `${con}id=${item.$$uuid}&appkey=${window.GLOB.appkey}&userid=${sessionStorage.getItem('UserID')}&LoginUID=${sessionStorage.getItem('LoginUID') || ''}` |
| | | } |
| | | |
| | | window.open(src) |
| | | } |
| | | } |
| | | |
| | | render() { |
| | | const { config, loading, data, card } = this.state |
| | | |
| | | return ( |
| | | <div className="custom-data-carousel-box" style={{...config.style, minHeight: config.wrap.minHeight}}> |
| | | {loading ? |
| | | <div className="loading-mask"> |
| | | {data ? <div className="ant-spin-blur"></div> : null} |
| | | <Spin /> |
| | | </div> : null |
| | | } |
| | | {data && data.length > 0 ? <Carousel |
| | | autoplay={config.wrap.autoplay !== 'false'} |
| | | dots={config.wrap.dots !== 'false'} |
| | | dotPosition={config.wrap.dotPosition || 'bottom'} |
| | | effect={config.wrap.effect || 'scrollx'} |
| | | autoplaySpeed={config.wrap.speed} |
| | | > |
| | | {data.map((item, index) => ( |
| | | <div key={index} onClick={() => {this.openView(item)}}> |
| | | <CardItem card={card} cards={config} data={item}/> |
| | | </div> |
| | | ))} |
| | | </Carousel> : null} |
| | | {!data || data.length === 0 ? <Empty description={false}/> : null} |
| | | </div> |
| | | ) |
| | | } |
| | | } |
| | | |
| | | const mapStateToProps = (state) => { |
| | | return { |
| | | permMenus: state.permMenus, |
| | | tabviews: state.tabviews, |
| | | } |
| | | } |
| | | |
| | | const mapDispatchToProps = (dispatch) => { |
| | | return { |
| | | modifyTabview: (tabviews) => dispatch(modifyTabview(tabviews)) |
| | | } |
| | | } |
| | | |
| | | export default connect(mapStateToProps, mapDispatchToProps)(DataCard) |
New file |
| | |
| | | .custom-data-carousel-box { |
| | | background: #ffffff; |
| | | background-position: center center; |
| | | background-repeat: no-repeat; |
| | | background-size: cover; |
| | | min-height: 30px; |
| | | |
| | | .card-item-box { |
| | | background-position: center center; |
| | | background-repeat: no-repeat; |
| | | background-size: cover; |
| | | } |
| | | |
| | | .ant-empty { |
| | | width: 100%; |
| | | min-height: 100px; |
| | | padding-top: 15px; |
| | | |
| | | .ant-empty-image { |
| | | height: 60px; |
| | | } |
| | | } |
| | | .loading-mask { |
| | | position: absolute; |
| | | left: 0px; |
| | | top: 0; |
| | | right: 0px; |
| | | bottom: 0px; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | text-align: justify; |
| | | z-index: 1; |
| | | |
| | | .ant-spin-blur { |
| | | position: absolute; |
| | | width: 100%; |
| | | height: 100%; |
| | | opacity: 0.5; |
| | | background: #ffffff; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .custom-data-carousel-box::after { |
| | | content: ' '; |
| | | display: block; |
| | | clear: both; |
| | | } |
New file |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { is, fromJS } from 'immutable' |
| | | import { connect } from 'react-redux' |
| | | import { Spin, notification, Carousel } from 'antd' |
| | | |
| | | import asyncComponent from '@/utils/asyncComponent' |
| | | import Api from '@/api' |
| | | import UtilsDM from '@/utils/utils-datamanage.js' |
| | | import MKEmitter from '@/utils/events.js' |
| | | import { modifyTabview } from '@/store/action' |
| | | import './index.scss' |
| | | |
| | | const CardItem = asyncComponent(() => import('../cardItem')) |
| | | |
| | | class PropCard extends Component { |
| | | static propTpyes = { |
| | | BID: PropTypes.any, // 父级Id |
| | | data: PropTypes.array, // 统一查询数据 |
| | | config: PropTypes.object, // 组件配置信息 |
| | | mainSearch: PropTypes.any, // 外层搜索条件 |
| | | menuType: PropTypes.any, // 菜单类型 |
| | | } |
| | | |
| | | state = { |
| | | BID: '', // 上级ID |
| | | config: null, // 图表配置信息 |
| | | loading: false, // 数据加载状态 |
| | | sync: false, // 是否统一请求数据 |
| | | data: {} // 数据 |
| | | } |
| | | |
| | | UNSAFE_componentWillMount () { |
| | | const { data, initdata, BID } = this.props |
| | | let _config = fromJS(this.props.config).toJS() |
| | | let _cols = new Map() |
| | | |
| | | let _data = {} |
| | | let _sync = false |
| | | |
| | | if (_config.setting && _config.wrap.datatype !== 'static') { |
| | | _sync = _config.setting.sync === 'true' |
| | | |
| | | if (_sync && data) { |
| | | _data = data[_config.dataName] || {} |
| | | if (_data && Array.isArray(_data)) { |
| | | _data = _data[0] || {} |
| | | } |
| | | _sync = false |
| | | } else if (_sync && initdata) { |
| | | _data = initdata || {} |
| | | if (_data && Array.isArray(_data)) { |
| | | _data = _data[0] || {} |
| | | } |
| | | _sync = false |
| | | } |
| | | } else { |
| | | _data = {} |
| | | } |
| | | |
| | | if (_data) { |
| | | _data.$$BID = BID || '' |
| | | } |
| | | |
| | | _config.columns.forEach(item => { |
| | | _cols.set(item.field, item) |
| | | }) |
| | | |
| | | _config.subcards.forEach(card => { |
| | | card.style.height = _config.style.height |
| | | if (card.setting.click) { |
| | | card.style.cursor = 'pointer' |
| | | } |
| | | card.elements = card.elements.map(item => { |
| | | if (item.field && _cols.has(item.field)) { |
| | | item.col = _cols.get(item.field) |
| | | } |
| | | return item |
| | | }) |
| | | }) |
| | | |
| | | _config.wrap.speed = (_config.wrap.speed || 3) * 1000 |
| | | |
| | | this.setState({ |
| | | sync: _sync, |
| | | data: _data, |
| | | BID: BID || '', |
| | | config: _config, |
| | | arr_field: _config.columns.map(col => col.field).join(','), |
| | | }, () => { |
| | | if (_config.wrap.datatype !== 'static' && _config.setting && _config.setting.sync !== 'true' && _config.setting.onload === 'true') { |
| | | this.loadData() |
| | | } |
| | | }) |
| | | } |
| | | |
| | | componentDidMount () { |
| | | MKEmitter.addListener('reloadData', this.reloadData) |
| | | MKEmitter.addListener('resetSelectLine', this.resetParentParam) |
| | | MKEmitter.removeListener('refreshByButtonResult', this.refreshByButtonResult) |
| | | } |
| | | |
| | | shouldComponentUpdate (nextProps, nextState) { |
| | | return !is(fromJS(this.state), fromJS(nextState)) |
| | | } |
| | | |
| | | componentWillUnmount () { |
| | | this.setState = () => { |
| | | return |
| | | } |
| | | MKEmitter.removeListener('reloadData', this.reloadData) |
| | | MKEmitter.removeListener('resetSelectLine', this.resetParentParam) |
| | | MKEmitter.removeListener('refreshByButtonResult', this.refreshByButtonResult) |
| | | } |
| | | |
| | | /** |
| | | * @description 图表数据更新,刷新内容 |
| | | */ |
| | | UNSAFE_componentWillReceiveProps (nextProps) { |
| | | const { sync, config, BID } = this.state |
| | | |
| | | if (sync && !is(fromJS(this.props.data), fromJS(nextProps.data))) { |
| | | let _data = {} |
| | | if (nextProps.data && nextProps.data[config.dataName]) { |
| | | _data = nextProps.data[config.dataName] |
| | | if (_data && Array.isArray(_data)) { |
| | | _data = _data[0] |
| | | } |
| | | } |
| | | |
| | | if (_data) { |
| | | _data.$$BID = BID || '' |
| | | } |
| | | |
| | | this.setState({sync: false, data: _data}) |
| | | } else if (nextProps.mainSearch && !is(fromJS(this.props.mainSearch), fromJS(nextProps.mainSearch))) { |
| | | if (config.wrap.datatype !== 'static' && config.setting.syncRefresh === 'true') { |
| | | this.setState({}, () => { |
| | | this.loadData() |
| | | }) |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * @description 按钮执行完成后页面刷新 |
| | | * @param {*} menuId // 菜单Id |
| | | * @param {*} position // 刷新位置 |
| | | * @param {*} btn // 执行的按钮 |
| | | */ |
| | | refreshByButtonResult = (menuId, position, btn) => { |
| | | const { config, BID } = this.state |
| | | |
| | | if (config.uuid !== menuId) return |
| | | |
| | | this.loadData() // 数据刷新 |
| | | |
| | | if (btn.syncComponentId && btn.syncComponentId !== config.uuid && btn.syncComponentId !== config.setting.supModule) { |
| | | MKEmitter.emit('reloadData', btn.syncComponentId) // 同级标签刷新 |
| | | } |
| | | |
| | | if (position === 'mainline' && config.setting.supModule) { // 主表行刷新 |
| | | MKEmitter.emit('reloadData', config.setting.supModule, (BID || 'empty')) |
| | | } else if (position === 'popclose') { // 标签关闭刷新 |
| | | config.setting.supModule && MKEmitter.emit('reloadData', config.setting.supModule, (BID || 'empty')) |
| | | btn.$tabId && MKEmitter.emit('refreshPopButton', btn.$tabId) |
| | | } |
| | | } |
| | | |
| | | resetParentParam = (MenuID, id) => { |
| | | const { config } = this.state |
| | | |
| | | if (config.wrap.datatype === 'static' || !config.setting.supModule || config.setting.supModule !== MenuID) return |
| | | if (id !== this.state.BID) { |
| | | this.setState({ BID: id }, () => { |
| | | this.loadData() |
| | | }) |
| | | } |
| | | } |
| | | |
| | | reloadData = (menuId) => { |
| | | const { config } = this.state |
| | | |
| | | if (menuId !== config.uuid) return |
| | | |
| | | this.loadData() |
| | | } |
| | | |
| | | async loadData () { |
| | | const { mainSearch, menuType } = this.props |
| | | const { config, arr_field, BID } = this.state |
| | | |
| | | if (config.wrap.datatype === 'static') { |
| | | this.setState({ |
| | | data: {$$BID: BID || ''}, |
| | | loading: false |
| | | }) |
| | | return |
| | | } else if (config.setting.supModule && !BID) { // BID 不存在时,不做查询 |
| | | this.setState({ |
| | | data: {$$BID: BID || ''}, |
| | | loading: false |
| | | }) |
| | | return |
| | | } |
| | | |
| | | let searches = [] |
| | | if (mainSearch && mainSearch.length > 0) { // 主表搜索条件 |
| | | let keys = searches.map(item => item.key) |
| | | mainSearch.forEach(item => { |
| | | if (!keys.includes(item.key)) { |
| | | searches.push(item) |
| | | } |
| | | }) |
| | | } |
| | | |
| | | this.setState({ |
| | | loading: true |
| | | }) |
| | | |
| | | let _orderBy = config.setting.order || '' |
| | | let param = UtilsDM.getQueryDataParams(config.setting, arr_field, searches, _orderBy, 1, 1, BID, menuType) |
| | | |
| | | let result = await Api.genericInterface(param) |
| | | if (result.status) { |
| | | let _data = result.data && result.data[0] ? result.data[0] : {} |
| | | _data.$$BID = BID || '' |
| | | |
| | | this.setState({ |
| | | data: _data, |
| | | loading: false |
| | | }) |
| | | } else { |
| | | this.setState({ |
| | | loading: false |
| | | }) |
| | | notification.error({ |
| | | top: 92, |
| | | message: result.message, |
| | | duration: 10 |
| | | }) |
| | | } |
| | | } |
| | | |
| | | openView = (item) => { |
| | | if (item.setting.click === 'menu') { |
| | | let menu = null |
| | | |
| | | if (item.setting.menu && item.setting.menu.length > 0) { |
| | | let menu_id = item.setting.menu.slice(-1)[0] |
| | | menu = this.props.permMenus.filter(m => m.MenuID === menu_id)[0] || '' |
| | | } |
| | | |
| | | if (!menu) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '菜单已删除或没有访问权限!', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } |
| | | |
| | | let newtab = { |
| | | ...menu, |
| | | selected: true, |
| | | param: {} |
| | | } |
| | | |
| | | if (item.setting.joint === 'true') { |
| | | newtab.param.$BID = item.setting.primaryId |
| | | } |
| | | |
| | | if (['linkage_navigation', 'linkage'].includes(window.GLOB.navBar)) { |
| | | this.props.modifyTabview([newtab]) |
| | | } else { |
| | | let tabs = this.props.tabviews.filter((tab, i) => { |
| | | tab.selected = false |
| | | return tab.MenuID !== newtab.MenuID |
| | | }) |
| | | |
| | | if (this.props.tabviews.length > tabs.length) { |
| | | this.props.modifyTabview(fromJS(tabs).toJS()) |
| | | } |
| | | |
| | | this.setState({}, () => { |
| | | tabs.push(newtab) |
| | | this.props.modifyTabview(tabs) |
| | | }) |
| | | } |
| | | } else if (item.setting.click === 'link') { |
| | | let src = item.setting.linkurl |
| | | |
| | | if (src.indexOf('paramsmain/') > -1) { |
| | | try { |
| | | let _url = src.split('paramsmain/')[0] + 'paramsmain/' |
| | | let _param = JSON.parse(window.decodeURIComponent(window.atob(src.split('paramsmain/')[1]))) |
| | | |
| | | _param.UserID = sessionStorage.getItem('UserID') |
| | | _param.LoginUID = sessionStorage.getItem('LoginUID') |
| | | _param.User_Name = sessionStorage.getItem('User_Name') |
| | | _param.param = { BID: item.setting.primaryId } |
| | | src = _url + window.btoa(window.encodeURIComponent(JSON.stringify(_param))) |
| | | } catch { |
| | | console.warn('菜单参数解析错误!') |
| | | } |
| | | } else if (item.setting.joint === 'true') { |
| | | let con = '?' |
| | | |
| | | if (/\?/ig.test(src)) { |
| | | con = '&' |
| | | } |
| | | |
| | | src = src + `${con}id=${item.setting.primaryId}&appkey=${window.GLOB.appkey}&userid=${sessionStorage.getItem('UserID')}&LoginUID=${sessionStorage.getItem('LoginUID') || ''}` |
| | | } |
| | | |
| | | window.open(src) |
| | | } |
| | | } |
| | | |
| | | |
| | | render() { |
| | | const { config, loading, data } = this.state |
| | | |
| | | return ( |
| | | <div className="custom-prop-carousel-box" style={config.style}> |
| | | {loading ? |
| | | <div className="loading-mask"> |
| | | <div className="ant-spin-blur"></div> |
| | | <Spin /> |
| | | </div> : null |
| | | } |
| | | <Carousel |
| | | autoplay={config.wrap.autoplay !== 'false'} |
| | | dots={config.wrap.dots !== 'false'} |
| | | dotPosition={config.wrap.dotPosition || 'bottom'} |
| | | effect={config.wrap.effect || 'scrollx'} |
| | | autoplaySpeed={config.wrap.speed} |
| | | > |
| | | {config.subcards.map((item, index) => ( |
| | | <div key={index} onClick={() => {this.openView(item)}}> |
| | | <CardItem card={item} cards={config} data={data}/> |
| | | </div> |
| | | ))} |
| | | </Carousel> |
| | | </div> |
| | | ) |
| | | } |
| | | } |
| | | |
| | | const mapStateToProps = (state) => { |
| | | return { |
| | | permMenus: state.permMenus, |
| | | tabviews: state.tabviews, |
| | | } |
| | | } |
| | | |
| | | const mapDispatchToProps = (dispatch) => { |
| | | return { |
| | | modifyTabview: (tabviews) => dispatch(modifyTabview(tabviews)) |
| | | } |
| | | } |
| | | |
| | | export default connect(mapStateToProps, mapDispatchToProps)(PropCard) |
New file |
| | |
| | | .custom-prop-carousel-box { |
| | | background: #ffffff; |
| | | background-position: center center; |
| | | background-repeat: no-repeat; |
| | | background-size: cover; |
| | | min-height: 30px; |
| | | position: relative; |
| | | |
| | | .card-item-box { |
| | | position: relative; |
| | | background-position: center center; |
| | | background-repeat: no-repeat; |
| | | background-size: cover; |
| | | } |
| | | |
| | | .loading-mask { |
| | | position: absolute; |
| | | left: 40px; |
| | | top: 0; |
| | | right: 40px; |
| | | bottom: 0px; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | text-align: justify; |
| | | z-index: 1; |
| | | |
| | | .ant-spin-blur { |
| | | position: absolute; |
| | | width: 100%; |
| | | height: 100%; |
| | | opacity: 0.5; |
| | | background: #ffffff; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .custom-prop-carousel-box::after { |
| | | content: ' '; |
| | | display: block; |
| | | clear: both; |
| | | } |
| | |
| | | import { connect } from 'react-redux' |
| | | import DataSet from '@antv/data-set' |
| | | import { Spin, Empty, Select, notification } from 'antd' |
| | | import moment from 'moment' |
| | | |
| | | import asyncComponent from './asyncButtonComponent' |
| | | import { chartColors } from '@/utils/option.js' |
| | |
| | | MKEmitter.addListener('resetSelectLine', this.resetParentParam) |
| | | MKEmitter.addListener('getexceloutparam', this.getexceloutparam) |
| | | MKEmitter.addListener('refreshByButtonResult', this.refreshByButtonResult) |
| | | this.handleTimer() |
| | | } |
| | | |
| | | /** |
| | | * @description 组件销毁,清除state更新,清除快捷键设置 |
| | | */ |
| | | componentWillUnmount () { |
| | | clearTimeout(this.timer) |
| | | this.setState = () => { |
| | | return |
| | | } |
| | |
| | | MKEmitter.removeListener('resetSelectLine', this.resetParentParam) |
| | | MKEmitter.removeListener('getexceloutparam', this.getexceloutparam) |
| | | MKEmitter.removeListener('refreshByButtonResult', this.refreshByButtonResult) |
| | | } |
| | | |
| | | handleTimer = () => { |
| | | const { config } = this.state |
| | | |
| | | if (!config.timer) return |
| | | |
| | | const _change = { |
| | | '15s': 15000, |
| | | '30s': 30000, |
| | | '1min': 60000, |
| | | '5min': 300000, |
| | | '10min': 600000, |
| | | '15min': 900000, |
| | | '30min': 1800000, |
| | | '1hour': 3600000 |
| | | } |
| | | |
| | | let timer = _change[config.timer] |
| | | |
| | | if (!timer) return |
| | | |
| | | let _param = { |
| | | func: 's_get_timers_role', |
| | | LText: `select '${window.GLOB.appkey || ''}','${config.uuid}'`, |
| | | timer_type: config.timer, |
| | | component_id: config.uuid |
| | | } |
| | | |
| | | _param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') // 时间戳 |
| | | _param.LText = Utils.formatOptions(_param.LText) // 关键字符替换,base64加密 |
| | | _param.secretkey = Utils.encrypt(_param.LText, _param.timestamp) // md5密钥 |
| | | |
| | | Api.getSystemConfig(_param).then(result => { |
| | | if (!result.status) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: result.message, |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } else if (result.run_type) { |
| | | this.setState({timer}) |
| | | this.timer = setTimeout(() => { |
| | | this.timerTask() |
| | | }, timer) |
| | | } |
| | | }) |
| | | } |
| | | |
| | | timerTask = () => { |
| | | const { timer } = this.state |
| | | if (!timer) return |
| | | |
| | | this.loadData(true) |
| | | |
| | | this.timer = setTimeout(() => { |
| | | this.timerTask() |
| | | }, timer) |
| | | } |
| | | |
| | | /** |
| | |
| | | /** |
| | | * @description 数据加载 |
| | | */ |
| | | async loadData () { |
| | | async loadData (hastimer) { |
| | | const { mainSearch, menuType } = this.props |
| | | const { config, arr_field, BID, search } = this.state |
| | | |
| | |
| | | }) |
| | | } |
| | | |
| | | this.setState({ |
| | | loading: true |
| | | }) |
| | | if (!hastimer) { |
| | | this.setState({ |
| | | loading: true |
| | | }) |
| | | } |
| | | |
| | | let _orderBy = config.setting.order || '' |
| | | let param = UtilsDM.getQueryDataParams(config.setting, arr_field, searches, _orderBy, '', '', BID, menuType) |
| | |
| | | }) |
| | | } else { |
| | | this.setState({ |
| | | loading: false |
| | | loading: false, |
| | | timer: null |
| | | }) |
| | | notification.error({ |
| | | top: 92, |
| | |
| | | ...menu, |
| | | selected: true, |
| | | param: { |
| | | BID: primaryId, |
| | | data: data |
| | | $BID: primaryId |
| | | } |
| | | } |
| | | |
| | |
| | | return tab.MenuID !== newtab.MenuID |
| | | }) |
| | | |
| | | if (this.props.tabviews.length !== tabs.length) { |
| | | if (this.props.tabviews.length > tabs.length) { |
| | | this.props.modifyTabview(fromJS(tabs).toJS()) |
| | | } |
| | | |
| | |
| | | import { connect } from 'react-redux' |
| | | import DataSet from '@antv/data-set' |
| | | import { Spin, Empty, notification } from 'antd' |
| | | import moment from 'moment' |
| | | |
| | | import Api from '@/api' |
| | | import Utils from '@/utils/utils.js' |
| | |
| | | componentDidMount () { |
| | | MKEmitter.addListener('reloadData', this.reloadData) |
| | | MKEmitter.addListener('resetSelectLine', this.resetParentParam) |
| | | this.handleTimer() |
| | | } |
| | | |
| | | /** |
| | | * @description 组件销毁,清除state更新,清除快捷键设置 |
| | | */ |
| | | componentWillUnmount () { |
| | | clearTimeout(this.timer) |
| | | this.setState = () => { |
| | | return |
| | | } |
| | | MKEmitter.removeListener('reloadData', this.reloadData) |
| | | MKEmitter.removeListener('resetSelectLine', this.resetParentParam) |
| | | } |
| | | |
| | | handleTimer = () => { |
| | | const { config } = this.state |
| | | |
| | | if (!config.timer) return |
| | | |
| | | const _change = { |
| | | '15s': 15000, |
| | | '30s': 30000, |
| | | '1min': 60000, |
| | | '5min': 300000, |
| | | '10min': 600000, |
| | | '15min': 900000, |
| | | '30min': 1800000, |
| | | '1hour': 3600000 |
| | | } |
| | | |
| | | let timer = _change[config.timer] |
| | | |
| | | if (!timer) return |
| | | |
| | | let _param = { |
| | | func: 's_get_timers_role', |
| | | LText: `select '${window.GLOB.appkey || ''}','${config.uuid}'`, |
| | | timer_type: config.timer, |
| | | component_id: config.uuid |
| | | } |
| | | |
| | | _param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') // 时间戳 |
| | | _param.LText = Utils.formatOptions(_param.LText) // 关键字符替换,base64加密 |
| | | _param.secretkey = Utils.encrypt(_param.LText, _param.timestamp) // md5密钥 |
| | | |
| | | Api.getSystemConfig(_param).then(result => { |
| | | if (!result.status) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: result.message, |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } else if (result.run_type) { |
| | | this.setState({timer}) |
| | | this.timer = setTimeout(() => { |
| | | this.timerTask() |
| | | }, timer) |
| | | } |
| | | }) |
| | | } |
| | | |
| | | timerTask = () => { |
| | | const { timer } = this.state |
| | | if (!timer) return |
| | | |
| | | this.loadData(true) |
| | | |
| | | this.timer = setTimeout(() => { |
| | | this.timerTask() |
| | | }, timer) |
| | | } |
| | | |
| | | reloadData = (menuId) => { |
| | |
| | | this.pierender() |
| | | } |
| | | |
| | | async loadData () { |
| | | async loadData (hastimer) { |
| | | const { mainSearch, menuType } = this.props |
| | | const { config, arr_field, search, BID } = this.state |
| | | |
| | |
| | | }) |
| | | } |
| | | |
| | | this.setState({ |
| | | loading: true |
| | | }) |
| | | if (!hastimer) { |
| | | this.setState({ |
| | | loading: true |
| | | }) |
| | | } |
| | | |
| | | let _orderBy = config.setting.order || '' |
| | | let param = UtilsDM.getQueryDataParams(config.setting, arr_field, searches, _orderBy, '', '', BID, menuType) |
| | |
| | | }) |
| | | } else { |
| | | this.setState({ |
| | | loading: false |
| | | loading: false, |
| | | timer: null |
| | | }) |
| | | notification.error({ |
| | | top: 92, |
| | |
| | | ...menu, |
| | | selected: true, |
| | | param: { |
| | | BID: primaryId, |
| | | data: data |
| | | $BID: primaryId |
| | | } |
| | | } |
| | | |
| | |
| | | return tab.MenuID !== newtab.MenuID |
| | | }) |
| | | |
| | | if (this.props.tabviews.length !== tabs.length) { |
| | | if (this.props.tabviews.length > tabs.length) { |
| | | this.props.modifyTabview(fromJS(tabs).toJS()) |
| | | } |
| | | |
New file |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { is, fromJS } from 'immutable' |
| | | import { connect } from 'react-redux' |
| | | import { Spin, notification, Button } from 'antd' |
| | | // import moment from 'moment' |
| | | |
| | | import Api from '@/api' |
| | | import Utils from '@/utils/utils.js' |
| | | import UtilsDM from '@/utils/utils-datamanage.js' |
| | | import asyncComponent from '@/utils/asyncComponent' |
| | | import asyncSpinComponent from '@/utils/asyncSpinComponent' |
| | | import MKEmitter from '@/utils/events.js' |
| | | import zhCN from '@/locales/zh-CN/main.js' |
| | | import enUS from '@/locales/en-US/main.js' |
| | | import { modifyTabview } from '@/store/action' |
| | | import './index.scss' |
| | | |
| | | const MutilForm = asyncSpinComponent(() => import('@/tabviews/zshare/mutilform')) |
| | | const NormalButton = asyncComponent(() => import('@/tabviews/zshare/actionList/normalbutton')) |
| | | |
| | | class NormalForm extends Component { |
| | | static propTpyes = { |
| | | BID: PropTypes.any, // 父级Id |
| | | data: PropTypes.array, // 统一查询数据 |
| | | config: PropTypes.object, // 组件配置信息 |
| | | mainSearch: PropTypes.any, // 外层搜索条件 |
| | | menuType: PropTypes.any, // 菜单类型 |
| | | } |
| | | |
| | | state = { |
| | | dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | BID: '', // 上级ID |
| | | config: null, // 图表配置信息 |
| | | loading: false, // 数据加载状态 |
| | | activeKey: '', // 选中数据 |
| | | sync: false, // 是否统一请求数据 |
| | | data: null, // 数据 |
| | | group: null, |
| | | step: 0 |
| | | } |
| | | |
| | | UNSAFE_componentWillMount () { |
| | | const { data, BID, config } = this.props |
| | | |
| | | let _data = null |
| | | let _sync = false |
| | | |
| | | if (config.wrap.datatype !== 'static') { |
| | | _sync = config.setting.sync === 'true' |
| | | |
| | | if (_sync && data && data[config.dataName]) { |
| | | _data = data[config.dataName] |
| | | if (Array.isArray(_data)) { |
| | | _data = _data[0] || {} |
| | | } |
| | | _sync = false |
| | | } |
| | | } else { |
| | | _data = {} |
| | | } |
| | | |
| | | let roleId = sessionStorage.getItem('role_id') || '' |
| | | |
| | | config.subcards = config.subcards.map(group => { |
| | | group.subButton.uuid = group.uuid |
| | | group.subButton.$menuId = group.uuid |
| | | group.subButton.Ot = 'requiredSgl' |
| | | group.subButton.btnstyle = group.subButton.style |
| | | group.subButton.OpenType = 'formSubmit' |
| | | group.subButton.execError = 'never' |
| | | |
| | | group.fields = group.fields.map(cell => { |
| | | // 数据源sql语句,预处理,权限黑名单字段设置为隐藏表单 |
| | | if (['select', 'link', 'multiselect', 'radio', 'checkbox', 'checkcard'].includes(cell.type) && cell.resourceType === '1') { |
| | | let _option = Utils.getSelectQueryOptions(cell) |
| | | |
| | | cell.data_sql = Utils.formatOptions(_option.sql) |
| | | cell.base_sql = window.btoa(window.encodeURIComponent(_option.sql)) |
| | | cell.arr_field = _option.field |
| | | } |
| | | |
| | | // 字段权限黑名单 |
| | | if (!cell.blacklist || !roleId || cell.blacklist.length === 0) return cell |
| | | if (cell.blacklist.filter(v => roleId.indexOf(v) > -1).length > 0) { |
| | | cell.hidden = 'true' |
| | | } |
| | | |
| | | return cell |
| | | }) |
| | | |
| | | return group |
| | | }) |
| | | |
| | | let _group = config.subcards[0] |
| | | |
| | | if (_data && config.wrap.statusControl && _data[config.wrap.statusControl]) { |
| | | let _status = _data[config.wrap.statusControl] |
| | | |
| | | let _groups = config.subcards.filter(item => item.setting.status === _status)[0] |
| | | _group = _groups || _group |
| | | } |
| | | |
| | | this.setState({ |
| | | sync: _sync, |
| | | data: _data, |
| | | group: _group, |
| | | step: _group.sort - 1, |
| | | BID: BID || '', |
| | | config: config, |
| | | arr_field: config.columns.map(col => col.field).join(','), |
| | | }, () => { |
| | | if (config.wrap.datatype !== 'static' && config.setting && config.setting.sync !== 'true' && config.setting.onload === 'true') { |
| | | this.loadData() |
| | | } |
| | | }) |
| | | } |
| | | |
| | | componentDidMount () { |
| | | MKEmitter.addListener('mkFormSubmit', this.mkFormSubmit) |
| | | MKEmitter.addListener('resetSelectLine', this.resetParentParam) |
| | | MKEmitter.addListener('refreshByButtonResult', this.refreshByButtonResult) |
| | | } |
| | | |
| | | shouldComponentUpdate (nextProps, nextState) { |
| | | return !is(fromJS(this.state), fromJS(nextState)) |
| | | } |
| | | |
| | | componentWillUnmount () { |
| | | this.setState = () => { |
| | | return |
| | | } |
| | | MKEmitter.removeListener('mkFormSubmit', this.mkFormSubmit) |
| | | MKEmitter.removeListener('resetSelectLine', this.resetParentParam) |
| | | MKEmitter.removeListener('refreshByButtonResult', this.refreshByButtonResult) |
| | | } |
| | | |
| | | /** |
| | | * @description 图表数据更新,刷新内容 |
| | | */ |
| | | UNSAFE_componentWillReceiveProps (nextProps) { |
| | | const { sync, config, group } = this.state |
| | | |
| | | if (sync && !is(fromJS(this.props.data), fromJS(nextProps.data))) { |
| | | let _data = {} |
| | | let _group = group |
| | | if (nextProps.data && nextProps.data[config.dataName]) { |
| | | _data = nextProps.data[config.dataName] |
| | | if (Array.isArray(_data)) { |
| | | _data = _data[0] || {} |
| | | } |
| | | } |
| | | if (config.wrap.statusControl && _data[config.wrap.statusControl]) { |
| | | let _status = _data[config.wrap.statusControl] |
| | | let _groups = config.subcards.filter(item => item.setting.status === _status)[0] |
| | | _group = _groups || _group |
| | | } |
| | | |
| | | this.setState({sync: false, data: _data, group: _group, step: _group.sort - 1,}) |
| | | } else if (nextProps.mainSearch && !is(fromJS(this.props.mainSearch), fromJS(nextProps.mainSearch))) { |
| | | if (config.wrap.datatype !== 'static' && config.setting.syncRefresh === 'true') { |
| | | this.setState({}, () => { |
| | | this.loadData() |
| | | }) |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * @description 按钮执行完成后页面刷新 |
| | | * @param {*} menuId // 菜单Id |
| | | * @param {*} position // 刷新位置 |
| | | * @param {*} btn // 执行的按钮 |
| | | */ |
| | | refreshByButtonResult = (menuId, position, btn) => { |
| | | const { config, group } = this.state |
| | | |
| | | if (group.uuid !== menuId) return |
| | | |
| | | if (btn.syncComponentId && btn.syncComponentId !== config.uuid && btn.syncComponentId !== config.setting.supModule) { |
| | | MKEmitter.emit('reloadData', btn.syncComponentId) // 同级标签刷新 |
| | | } |
| | | |
| | | if (config.subcards.length > group.sort) { |
| | | let _group = config.subcards.filter(item => item.sort === (group.sort + 1))[0] |
| | | |
| | | this.setState({group: null, step: group.sort}, () => { |
| | | this.setState({group: _group}) |
| | | }) |
| | | } else { |
| | | this.setState({step: group.sort}) |
| | | } |
| | | |
| | | if (btn.linkmenu && btn.linkmenu.length > 0) { |
| | | let menu_id = btn.linkmenu[btn.linkmenu.length - 1] |
| | | let menu = this.props.permMenus.filter(m => m.MenuID === menu_id)[0] || '' |
| | | |
| | | if (!menu) return |
| | | |
| | | let newtab = { |
| | | ...menu, |
| | | selected: true, |
| | | param: {} |
| | | } |
| | | let tabs = this.props.tabviews.filter((tab, i) => { |
| | | tab.selected = false |
| | | return tab.MenuID !== newtab.MenuID |
| | | }) |
| | | |
| | | if (this.props.tabviews.length > tabs.length) { |
| | | this.props.modifyTabview(fromJS(tabs).toJS()) |
| | | } |
| | | |
| | | this.setState({}, () => { |
| | | tabs.push(newtab) |
| | | this.props.modifyTabview(tabs) |
| | | }) |
| | | } |
| | | } |
| | | |
| | | resetParentParam = (MenuID, id) => { |
| | | const { config } = this.state |
| | | if (config.wrap.datatype === 'static' || !config.setting.supModule || config.setting.supModule !== MenuID) return |
| | | if (id !== this.state.BID) { |
| | | this.setState({ BID: id }, () => { |
| | | this.loadData() |
| | | }) |
| | | } |
| | | } |
| | | |
| | | async loadData () { |
| | | const { mainSearch, menuType } = this.props |
| | | const { config, arr_field, BID, group } = this.state |
| | | |
| | | if (config.wrap.datatype === 'static' || (config.setting.supModule && !BID)) { |
| | | this.setState({ |
| | | data: {}, |
| | | loading: false |
| | | }) |
| | | return |
| | | } |
| | | |
| | | let searches = [] |
| | | if (mainSearch && mainSearch.length > 0) { // 主表搜索条件 |
| | | let keys = searches.map(item => item.key) |
| | | mainSearch.forEach(item => { |
| | | if (!keys.includes(item.key)) { |
| | | searches.push(item) |
| | | } |
| | | }) |
| | | } |
| | | |
| | | this.setState({ |
| | | loading: true |
| | | }) |
| | | |
| | | let _orderBy = config.setting.order || '' |
| | | let param = UtilsDM.getQueryDataParams(config.setting, arr_field, searches, _orderBy, 1, 1, BID, menuType) |
| | | |
| | | let result = await Api.genericInterface(param) |
| | | if (result.status) { |
| | | let _data = result.data && result.data[0] ? result.data[0] : {} |
| | | let _group = group |
| | | if (config.wrap.statusControl && _data[config.wrap.statusControl]) { |
| | | let _status = _data[config.wrap.statusControl] |
| | | let _groups = config.subcards.filter(item => item.setting.status === _status)[0] |
| | | _group = _groups || _group |
| | | } |
| | | |
| | | this.setState({ |
| | | group: _group, |
| | | step: _group.sort - 1, |
| | | activeKey: '', |
| | | data: _data || {}, |
| | | loading: false |
| | | }) |
| | | } else { |
| | | this.setState({ |
| | | loading: false, |
| | | }) |
| | | notification.error({ |
| | | top: 92, |
| | | message: result.message, |
| | | duration: 10 |
| | | }) |
| | | } |
| | | } |
| | | |
| | | mkFormSubmit = (btnId) => { |
| | | const { group } = this.state |
| | | |
| | | if (group.uuid !== btnId) return |
| | | |
| | | this.formRef.handleConfirm().then(res => { |
| | | MKEmitter.emit('triggerFormSubmit', {menuId: btnId, form: res}) |
| | | }) |
| | | } |
| | | |
| | | prevStep = () => { |
| | | const { config, group } = this.state |
| | | |
| | | let _group = config.subcards.filter(item => item.sort === (group.sort - 1))[0] |
| | | |
| | | this.setState({group: null, step: group.sort - 2}, () => { |
| | | this.setState({group: _group}) |
| | | }) |
| | | } |
| | | |
| | | nextStep = () => { |
| | | const { config, group } = this.state |
| | | |
| | | let _group = config.subcards.filter(item => item.sort === (group.sort + 1))[0] |
| | | |
| | | this.setState({group: null, step: group.sort}, () => { |
| | | this.setState({group: _group}) |
| | | }) |
| | | } |
| | | |
| | | render() { |
| | | const { config, loading, BID, data, group, dict, step } = this.state |
| | | |
| | | return ( |
| | | <div className="custom-normal-form-box" style={{...config.style}}> |
| | | {loading ? |
| | | <div className="loading-mask"> |
| | | <div className="ant-spin-blur"></div> |
| | | <Spin /> |
| | | </div> : null |
| | | } |
| | | {config.subcards.length > 1 ? <div className="mk-normal-form-title"> |
| | | {config.subcards.map(card => ( |
| | | <div key={card.uuid} className={'form-title' + (card.sort <= step ? ' active' : '')}> |
| | | <span className="form-sort" style={{background: config.wrap.color}}>{card.sort}</span> |
| | | <span className="before-line" style={{background: config.wrap.color}}></span> |
| | | <span className="after-line" style={{background: config.wrap.color}}></span> |
| | | {card.setting.title} |
| | | </div>)) |
| | | } |
| | | </div> : null} |
| | | {group && data ? <MutilForm |
| | | BID={BID} |
| | | dict={dict} |
| | | data={data} |
| | | action={group} |
| | | inputSubmit={this.handleOk} |
| | | wrappedComponentRef={(inst) => this.formRef = inst} |
| | | /> : null} |
| | | {group && data ? <div className="mk-form-action"> |
| | | {group.sort !== 1 ? <Button type="link" className="prev" onClick={this.prevStep} style={group.prevButton.style}>{group.prevButton.label}</Button> : null} |
| | | <NormalButton |
| | | BID={BID} |
| | | position="form" |
| | | btn={group.subButton} |
| | | setting={config.setting} |
| | | columns={config.columns} |
| | | selectedData={[data]} |
| | | /> |
| | | {group.nextButton.enable === 'true' && group.sort !== config.subcards.length ? <Button type="link" className="skip" onClick={this.nextStep} style={group.nextButton.style}>{group.nextButton.label}</Button> : null} |
| | | </div> : null} |
| | | </div> |
| | | ) |
| | | } |
| | | } |
| | | |
| | | const mapStateToProps = (state) => { |
| | | return { |
| | | permMenus: state.permMenus, |
| | | tabviews: state.tabviews, |
| | | } |
| | | } |
| | | |
| | | const mapDispatchToProps = (dispatch) => { |
| | | return { |
| | | modifyTabview: (tabviews) => dispatch(modifyTabview(tabviews)) |
| | | } |
| | | } |
| | | |
| | | export default connect(mapStateToProps, mapDispatchToProps)(NormalForm) |
New file |
| | |
| | | .custom-normal-form-box { |
| | | background: #ffffff; |
| | | background-position: center center; |
| | | background-repeat: no-repeat; |
| | | background-size: cover; |
| | | position: relative; |
| | | min-height: 200px; |
| | | |
| | | .mk-normal-form-title { |
| | | display: flex; |
| | | line-height: 30px; |
| | | min-height: 50px; |
| | | margin-bottom: 20px; |
| | | .form-title { |
| | | position: relative; |
| | | flex: 1; |
| | | text-align: center; |
| | | .form-sort { |
| | | background: #d8d8d8; |
| | | display: block; |
| | | width: 20px; |
| | | height: 20px; |
| | | line-height: 20px; |
| | | border-radius: 20px; |
| | | text-align: center; |
| | | color: #ffffff; |
| | | margin: 10px auto 0px; |
| | | position: relative; |
| | | z-index: 1; |
| | | } |
| | | } |
| | | .before-line, .after-line { |
| | | display: none; |
| | | } |
| | | .form-title:not(:first-child) .before-line { |
| | | position: absolute; |
| | | display: inline-block; |
| | | width: 50%; |
| | | height: 2px; |
| | | background: #d8d8d8; |
| | | left: 0%; |
| | | top: 18px; |
| | | } |
| | | .form-title:not(:last-child) .after-line { |
| | | position: absolute; |
| | | content: ' '; |
| | | display: inline-block; |
| | | width: 50%; |
| | | height: 2px; |
| | | background: #d8d8d8; |
| | | left: 50%; |
| | | top: 18px; |
| | | } |
| | | .form-title:not(.active) { |
| | | .form-sort { |
| | | background: #d8d8d8!important; |
| | | } |
| | | .before-line, .after-line { |
| | | background: #d8d8d8!important; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .mk-form-action { |
| | | position: relative; |
| | | text-align: center; |
| | | padding-bottom: 10px; |
| | | |
| | | .prev { |
| | | margin-right: 15px; |
| | | } |
| | | .submit { |
| | | min-width: 70px; |
| | | border: none; |
| | | } |
| | | .skip { |
| | | position: absolute; |
| | | right: 5px; |
| | | } |
| | | } |
| | | |
| | | .loading-mask { |
| | | position: absolute; |
| | | left: 40px; |
| | | top: 0; |
| | | right: 40px; |
| | | bottom: 0px; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | text-align: justify; |
| | | z-index: 1; |
| | | |
| | | .ant-spin-blur { |
| | | position: absolute; |
| | | width: 100%; |
| | | height: 100%; |
| | | opacity: 0.5; |
| | | background: #ffffff; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .custom-card-box::after { |
| | | content: ' '; |
| | | display: block; |
| | | clear: both; |
| | | } |
| | |
| | | let diffUser = false |
| | | let userName = sessionStorage.getItem('User_Name') || '' |
| | | let fullName = sessionStorage.getItem('Full_Name') || '' |
| | | let city = sessionStorage.getItem('city') || '' |
| | | |
| | | if (sessionStorage.getItem('isEditState') === 'true') { |
| | | userName = sessionStorage.getItem('CloudUserName') || '' |
| | |
| | | let _script = item.script |
| | | |
| | | if (index === 0) { |
| | | _script = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@UserName nvarchar(50),@FullName nvarchar(50) |
| | | select @ErrorCode='',@retmsg ='',@UserName='${userName}', @FullName='${fullName}' |
| | | _script = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@UserName nvarchar(50),@FullName nvarchar(50),@login_city nvarchar(50) |
| | | select @ErrorCode='',@retmsg ='',@UserName='${userName}', @FullName='${fullName}', @login_city='${city}' |
| | | ${_script} |
| | | ` |
| | | } |
| | |
| | | if (col.rowspan === 'true') { |
| | | resProps.rowSpan = record['$$' + col.field] |
| | | } |
| | | |
| | | |
| | | if (col.linkThdMenu || col.linkurl) { |
| | | content = ( |
| | | <div> |
| | | <div className="link-menu" onDoubleClick={(e) => this.triggerLink(e, col, record)}></div> |
| | | <div className="link-menu" onDoubleClick={(e) => triggerLink(e, col, record)}></div> |
| | | {content} |
| | | </div> |
| | | ) |
| | |
| | | if (col.linkThdMenu || col.linkurl) { |
| | | content = ( |
| | | <div> |
| | | <div className="link-menu" onDoubleClick={(e) => this.triggerLink(e, col, record)}></div> |
| | | <div className="link-menu" onDoubleClick={(e) => triggerLink(e, col, record)}></div> |
| | | {content} |
| | | </div> |
| | | ) |
| | |
| | | |
| | | // 字段透视 |
| | | triggerLink = (e, item, record) => { |
| | | const { tabviews, MenuID } = this.props |
| | | const { tabviews } = this.props |
| | | e.stopPropagation() |
| | | |
| | | let __param = { |
| | | $searchkey: item.field, |
| | | $searchval: record[item.field] || '', |
| | | $BID: record.$$uuid |
| | | } |
| | | |
| | | if (item.linkfields && item.linkfields.length > 0) { |
| | | item.linkfields.forEach(field => { |
| | | __param[field] = record[field] || '' |
| | | }) |
| | | } |
| | | |
| | | if (item.linkThdMenu) { |
| | | let tabmenu = item.linkThdMenu |
| | | |
| | | tabmenu.param = { |
| | | searchkey: item.field, |
| | | searchval: record[item.field] || '', |
| | | BID: record.$$uuid |
| | | } |
| | | |
| | | tabmenu.param = __param |
| | | tabmenu.selected = true |
| | | |
| | | let index = 0 |
| | | let isexit = false |
| | | let tabs = tabviews.map((tab, i) => { |
| | | let tabs = tabviews.filter((tab, i) => { |
| | | tab.selected = false |
| | | |
| | | if (tab.MenuID === MenuID) { |
| | | index = i |
| | | } else if (tab.MenuID === tabmenu.MenuID) { |
| | | tab.param = tabmenu.param |
| | | tab.selected = true |
| | | isexit = true |
| | | } |
| | | |
| | | return tab |
| | | return tab.MenuID !== tabmenu.MenuID |
| | | }) |
| | | |
| | | if (!isexit) { |
| | | tabs.splice(index + 1, 0, tabmenu) |
| | | if (tabviews.length > tabs.length) { |
| | | this.props.modifyTabview(fromJS(tabs).toJS()) |
| | | } |
| | | |
| | | this.props.modifyTabview(tabs) |
| | | } else { |
| | | this.setState({}, () => { |
| | | tabs.push(tabmenu) |
| | | this.props.modifyTabview(tabs) |
| | | }) |
| | | } else if (item.linkurl) { |
| | | let src = item.linkurl |
| | | |
| | | if (item.linkurl.indexOf('paramsmain/') > -1) { |
| | | if (src.indexOf('paramsmain/') > -1) { |
| | | try { |
| | | let _url = item.linkurl.split('paramsmain/')[0] + 'paramsmain/' |
| | | let _param = JSON.parse(window.decodeURIComponent(window.atob(item.linkurl.split('paramsmain/')[1]))) |
| | | let dataparam = { |
| | | searchkey: item.field, |
| | | searchval: record[item.field] || '', |
| | | BID: record.$$uuid |
| | | } |
| | | _param.UserID = sessionStorage.getItem('UserID') |
| | | _param.LoginUID = sessionStorage.getItem('LoginUID') |
| | | _param.User_Name = sessionStorage.getItem('User_Name') |
| | | _param.param = dataparam |
| | | _param.param = __param |
| | | src = _url + window.btoa(window.encodeURIComponent(JSON.stringify(_param))) |
| | | } catch { |
| | | console.warn('菜单参数解析错误!') |
| | | } |
| | | } else { |
| | | let con = '?' |
| | | |
| | | if (/\?/ig.test(src)) { |
| | | con = '&' |
| | | } |
| | | |
| | | if (item.linkfields && item.linkfields.length > 0) { |
| | | item.linkfields.forEach(field => { |
| | | if (field.toLowerCase() === 'id') return |
| | | con += `${field}=${record[field] || ''}&` |
| | | }) |
| | | } |
| | | |
| | | src = src + `${con}id=${record.$$uuid}&appkey=${window.GLOB.appkey}&userid=${sessionStorage.getItem('UserID')}&LoginUID=${sessionStorage.getItem('LoginUID') || ''}` |
| | | } |
| | | |
| | | window.open(src) |
| | |
| | | index = selectedRowKeys.slice(-1)[0] |
| | | } |
| | | |
| | | if (setting.tableType === 'checkbox') { |
| | | if (setting.tableType === 'checkbox' || setting.tableType === 'radio') { |
| | | _activeIndex = index === '' ? null : index |
| | | } |
| | | |
| | |
| | | if (setting.tableType === 'radio') { |
| | | newkeys = [index] |
| | | this.changedata(index) |
| | | this.setState({ selectedRowKeys: newkeys }) |
| | | this.setState({ selectedRowKeys: newkeys, activeIndex: index }) |
| | | } else { |
| | | let _index = '' |
| | | if (newkeys.includes(index)) { |
| | |
| | | vertical-align: middle; |
| | | } |
| | | .ant-table-tbody > tr > td.ant-table-column-has-actions { |
| | | .content { |
| | | position: relative; |
| | | z-index: 1; |
| | | word-wrap: break-word; |
| | | word-break: break-word; |
| | | } |
| | | } |
| | | .ant-table-tbody > tr > td { |
| | | position: relative; |
| | | .link-menu { |
| | | position: absolute; |
| | |
| | | bottom: 0px; |
| | | opacity: 0; |
| | | cursor: pointer; |
| | | } |
| | | |
| | | .content { |
| | | position: relative; |
| | | z-index: 1; |
| | | word-wrap: break-word; |
| | | word-break: break-word; |
| | | } |
| | | } |
| | | .ant-table-tbody > tr > td .content { |
| | |
| | | let diffUser = false |
| | | let userName = sessionStorage.getItem('User_Name') || '' |
| | | let fullName = sessionStorage.getItem('Full_Name') || '' |
| | | let city = sessionStorage.getItem('city') || '' |
| | | |
| | | if (sessionStorage.getItem('isEditState') === 'true') { |
| | | userName = sessionStorage.getItem('CloudUserName') || '' |
| | |
| | | let _script = item.script |
| | | |
| | | if (index === 0) { |
| | | _script = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@UserName nvarchar(50),@FullName nvarchar(50) |
| | | select @ErrorCode='',@retmsg ='',@UserName='${userName}', @FullName='${fullName}' |
| | | _script = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@UserName nvarchar(50),@FullName nvarchar(50),@login_city nvarchar(50) |
| | | select @ErrorCode='',@retmsg ='',@UserName='${userName}', @FullName='${fullName}', @login_city='${city}' |
| | | ${_script} |
| | | ` |
| | | } |
| | |
| | | let result = await Api.genericInterface(param) |
| | | if (result.status) { |
| | | let data = fromJS(this.state.data).toJS() |
| | | let selectedData = fromJS(this.state.selectedData).toJS() |
| | | if (result.data && result.data[0]) { |
| | | let _data = result.data[0] |
| | | |
| | | let _data = result.data[0] || {} |
| | | _data.$$uuid = _data[setting.primaryKey] || '' |
| | | _data.$$BID = BID || '' |
| | | try { |
| | | data = data.map(item => { |
| | | if (item[setting.primaryKey] === _data[setting.primaryKey]) { |
| | | if (item.$$uuid === _data.$$uuid) { |
| | | _data.key = item.key |
| | | _data.$$uuid = _data[setting.primaryKey] || '' |
| | | _data.$$BID = BID || '' |
| | | return _data |
| | | } else { |
| | | return item |
| | | } |
| | | }) |
| | | selectedData = selectedData.map(item => { |
| | | if (_data.$$uuid === item.$$uuid) { |
| | | return _data |
| | | } |
| | | return item |
| | | }) |
| | | } catch { |
| | | console.warn('数据查询错误') |
| | |
| | | } |
| | | |
| | | this.setState({ |
| | | data: data, |
| | | data, |
| | | selectedData, |
| | | loading: false |
| | | }) |
| | | } else { |
| | |
| | | >.button-list.toolbar-button { |
| | | padding: 0; |
| | | line-height: 55px; |
| | | padding-right: 110px; |
| | | padding-right: 60px; |
| | | button { |
| | | margin-right: 0px; |
| | | margin-bottom: 0px; |
| | |
| | | const AntvTabs = asyncComponent(() => import('./components/tabs/antv-tabs')) |
| | | const DataCard = asyncComponent(() => import('./components/card/data-card')) |
| | | const PropCard = asyncComponent(() => import('./components/card/prop-card')) |
| | | const NormalForm = asyncComponent(() => import('./components/form/normal-form')) |
| | | const CarouselDataCard = asyncComponent(() => import('./components/carousel/data-card')) |
| | | const CarouselPropCard = asyncComponent(() => import('./components/carousel/prop-card')) |
| | | const TableCard = asyncComponent(() => import('./components/card/table-card')) |
| | | const MainSearch = asyncComponent(() => import('@/tabviews/zshare/topSearch')) |
| | | const NormalTable = asyncComponent(() => import('./components/table/normal-table')) |
| | |
| | | |
| | | component.search = component.search.map(item => { |
| | | item.oriInitval = item.initval |
| | | if (['text', 'select', 'link'].includes(item.type) && param) { |
| | | if (param.searchkey === item.field) { |
| | | item.initval = param.searchval |
| | | } else if (param.BID && item.field.toLowerCase() === 'bid') { |
| | | item.initval = param.BID |
| | | } else if (param.data && param.data[item.field]) { |
| | | item.initval = param.data[item.field] |
| | | } |
| | | if (['text', 'select', 'link'].includes(item.type) && param && param.$searchkey === item.field) { |
| | | item.initval = param.$searchval |
| | | } |
| | | |
| | | return item |
| | |
| | | }) |
| | | |
| | | let params = [] |
| | | let BID = param && param.BID ? param.BID : '' |
| | | let BID = param && param.$BID ? param.$BID : '' |
| | | let inherit = {} |
| | | |
| | | if (config.cacheUseful === 'true') { // 缓存继承 |
| | |
| | | inherit.cacheTime = config.cacheTime |
| | | } |
| | | |
| | | config.components = this.formatSetting(config.components, params, mainSearch, inherit) |
| | | let userName = sessionStorage.getItem('User_Name') || '' |
| | | let fullName = sessionStorage.getItem('Full_Name') || '' |
| | | let city = sessionStorage.getItem('city') || '' |
| | | |
| | | if (sessionStorage.getItem('isEditState') === 'true') { |
| | | userName = sessionStorage.getItem('CloudUserName') || '' |
| | | fullName = sessionStorage.getItem('CloudFullName') || '' |
| | | } |
| | | |
| | | let regs = [ |
| | | { reg: /@userName@/ig, value: userName }, |
| | | { reg: /@fullName@/ig, value: fullName }, |
| | | { reg: /@login_city@/ig, value: city } |
| | | ] |
| | | |
| | | if (window.GLOB.externalDatabase !== null) { |
| | | regs.push({ |
| | | reg: /@db@/ig, |
| | | value: window.GLOB.externalDatabase |
| | | }) |
| | | } |
| | | if (config.urlFields) { |
| | | config.urlFields.forEach(field => { |
| | | let val = `'${param ? (param[field] || '') : ''}'` |
| | | regs.push({ |
| | | reg: new RegExp(field, 'ig'), |
| | | value: val |
| | | }) |
| | | }) |
| | | } |
| | | |
| | | config.components = this.formatSetting(config.components, params, mainSearch, inherit, regs) |
| | | |
| | | this.setState({ |
| | | BID: BID, |
| | |
| | | |
| | | Api.genericInterface(param).then(res => { |
| | | if (res.status) { |
| | | if (res.mk_ex_invoke === 'false') { |
| | | if (res.mk_ex_invoke === 'false' || res.mk_ex_invoke === false) { |
| | | if (inters.length > 0) { |
| | | this.loadOutResource(inters) |
| | | } |
| | |
| | | param[key] = result[key] |
| | | }) |
| | | |
| | | Api.directRequest(url, setting.method, param).then(res => { |
| | | Api.directRequest(url, setting.method, param, setting.cross).then(res => { |
| | | if (typeof(res) !== 'object' || Array.isArray(res)) { |
| | | let error = '未知的返回结果!' |
| | | |
| | |
| | | ) { |
| | | return false |
| | | } |
| | | |
| | | item.subtabs = item.subtabs.filter(tab => { |
| | | if ( |
| | | tab.blacklist && tab.blacklist.length > 0 && |
| | | tab.blacklist.filter(v => roleId.indexOf(v) > -1).length > 0 |
| | | ) { |
| | | return false |
| | | } |
| | | return true |
| | | }) |
| | | |
| | | item.subtabs = item.subtabs.map(tab => { |
| | | tab.components = this.filterComponent(tab.components, roleId, permAction, permMenus) |
| | |
| | | return cell.eleType !== 'button' || isHS || permAction[cell.uuid] |
| | | }) |
| | | }) |
| | | } else if (item.type === 'table' && item.subtype === 'tablecard') { |
| | | } else if ((item.type === 'table' && item.subtype === 'tablecard') || item.type === 'carousel') { |
| | | item.subcards.forEach(card => { |
| | | let _hasheight = card.style.height && card.style.height !== 'auto' |
| | | card.elements = card.elements.filter(cell => { |
| | |
| | | } |
| | | |
| | | // 格式化默认设置 |
| | | formatSetting = (components, params, mainSearch, inherit) => { |
| | | formatSetting = (components, params, mainSearch, inherit, regs) => { |
| | | return components.map(component => { |
| | | if (component.type === 'tabs') { |
| | | component.subtabs = component.subtabs.map(tab => { |
| | | tab.components = this.formatSetting(tab.components, [], [], inherit) |
| | | tab.components = this.formatSetting(tab.components, [], [], inherit, regs) |
| | | tab = {...tab, ...inherit} |
| | | return tab |
| | | }) |
| | | return component |
| | | } else if (component.type === 'group') { |
| | | component.components = this.formatSetting(component.components, [], [], inherit) |
| | | component.components = this.formatSetting(component.components, [], [], inherit, regs) |
| | | component = {...component, ...inherit} |
| | | return component |
| | | } |
| | | |
| | | if (['propcard', 'brafteditor', 'sandbox'].includes(component.subtype) && component.wrap.datatype === 'static') { |
| | | if (['propcard', 'brafteditor', 'sandbox', 'stepform'].includes(component.subtype) && component.wrap.datatype === 'static') { |
| | | component.format = '' |
| | | } |
| | | |
| | |
| | | component.setting.dataresource = component.setting.dataresource.replace(/@\$|\$@/ig, '') |
| | | _customScript = _customScript.replace(/@\$|\$@/ig, '') |
| | | } |
| | | |
| | | regs.forEach(cell => { |
| | | component.setting.dataresource = component.setting.dataresource.replace(cell.reg, cell.value) |
| | | _customScript = _customScript.replace(cell.reg, cell.value) |
| | | }) |
| | | |
| | | component.setting.customScript = _customScript // 整理后自定义脚本 |
| | | |
| | |
| | | let diffUser = false |
| | | let userName = sessionStorage.getItem('User_Name') || '' |
| | | let fullName = sessionStorage.getItem('Full_Name') || '' |
| | | let city = sessionStorage.getItem('city') || '' |
| | | |
| | | if (sessionStorage.getItem('isEditState') === 'true') { |
| | | userName = sessionStorage.getItem('CloudUserName') || '' |
| | |
| | | let _script = item.script |
| | | |
| | | if (index === 0) { |
| | | _script = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@UserName nvarchar(50),@FullName nvarchar(50) |
| | | select @ErrorCode='',@retmsg ='',@UserName='${userName}', @FullName='${fullName}' |
| | | _script = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@UserName nvarchar(50),@FullName nvarchar(50),@login_city nvarchar(50) |
| | | select @ErrorCode='',@retmsg ='',@UserName='${userName}', @FullName='${fullName}', @login_city='${city}' |
| | | ${_script} |
| | | ` |
| | | } |
| | |
| | | <AntvPie config={item} data={data} BID={_bid} mainSearch={mainSearch} menuType={menuType} /> |
| | | </Col> |
| | | ) |
| | | } else if (item.type === 'form') { |
| | | return ( |
| | | <Col span={item.width} key={item.uuid}> |
| | | <NormalForm config={item} data={data} BID={_bid} mainSearch={mainSearch} menuType={menuType} /> |
| | | </Col> |
| | | ) |
| | | } else if (item.type === 'search') { |
| | | return ( |
| | | <Col span={item.width} key={item.uuid}> |
| | |
| | | <PropCard config={item} data={data} BID={_bid} mainSearch={mainSearch} menuType={menuType} /> |
| | | </Col> |
| | | ) |
| | | } else if (item.type === 'carousel' && item.subtype === 'datacard') { |
| | | return ( |
| | | <Col span={item.width} key={item.uuid}> |
| | | <CarouselDataCard config={item} data={data} BID={_bid} mainSearch={mainSearch} menuType={menuType} /> |
| | | </Col> |
| | | ) |
| | | } else if (item.type === 'carousel' && item.subtype === 'propcard') { |
| | | return ( |
| | | <Col span={item.width} key={item.uuid}> |
| | | <CarouselPropCard config={item} data={data} BID={_bid} mainSearch={mainSearch} menuType={menuType} /> |
| | | </Col> |
| | | ) |
| | | } else if (item.type === 'table' && item.subtype === 'tablecard') { |
| | | return ( |
| | | <Col span={item.width} key={item.uuid}> |
| | |
| | | obj_name: 'data', |
| | | arr_field: _option.field |
| | | } |
| | | |
| | | if (sessionStorage.getItem('dataM') === 'true') { // 数据权限 |
| | | param.LText = param.LText.replace(/\$@/ig, '/*') |
| | | param.LText = param.LText.replace(/@\$/ig, '*/') |
| | | } else { |
| | | param.LText = param.LText.replace(/@\$|\$@/ig, '') |
| | | } |
| | | |
| | | param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') |
| | | param.secretkey = Utils.encrypt(param.LText, param.timestamp) |
| | |
| | | |
| | | state = { |
| | | visible: true, |
| | | dict: localStorage.getItem('lang') !== 'en-US' ? mzhCN : menUS, |
| | | dict: sessionStorage.getItem('lang') !== 'en-US' ? mzhCN : menUS, |
| | | debug: sessionStorage.getItem('debug') === 'true' |
| | | } |
| | | |
| | |
| | | let _openKeys = [] |
| | | // MenuID(菜单Id)、MenuName(菜单名称)、OnlySelf(值为true,表示三级菜单,增加-仅页面)、Type(菜单级别) |
| | | // ParentID(父级Id)、Selected(是否选中-已失效)、Tabs( 标签类型)、TypeCharOne 菜单类型PC或其他 |
| | | // result.data.forEach(item => { // 测试 |
| | | // if (item.ParentID === '0') { |
| | | // item.ParentID = item.TypeCharOne |
| | | // } |
| | | // }) |
| | | let _tree = this.getTree(fromJS(mainMenus).toJS(), result.data) |
| | | if (_tree[0]) { |
| | | if (_tree[0].key === 'PC' && _tree[0].children) { |
| | |
| | | import PropTypes from 'prop-types' |
| | | import moment from 'moment' |
| | | import { Button, Modal, notification, message } from 'antd' |
| | | import MutilForm from '@/tabviews/zshare/mutilform' |
| | | |
| | | import asyncSpinComponent from '@/utils/asyncSpinComponent' |
| | | import options from '@/store/options.js' |
| | | import Utils from '@/utils/utils.js' |
| | | import Api from '@/api' |
| | | import './index.scss' |
| | | |
| | | const { confirm } = Modal |
| | | const MutilForm = asyncSpinComponent(() => import('@/tabviews/zshare/mutilform')) |
| | | |
| | | class MainAction extends Component { |
| | | static propTpyes = { |
| | |
| | | tables:[ |
| | | {"TbName":"s_custom_script","Remark":"自定义脚本"} |
| | | ], |
| | | groups:[], |
| | | fields:[ |
| | | {"label":"函数","field":"func","type":"text","initval":"","readonly":"false","required":"true","hidden":"false","readin":"true","fieldlength":50,"regular":"funcname","supField":"","blacklist":[],"uuid":"1587006164634l397q15t49u2pfq02f5"}, |
| | | {"label":"排序","field":"Sort","type":"number","initval":0,"decimal":0,"min":"","max":"","readonly":"false","hidden":"false","readin":"true","supField":"","blacklist":[],"uuid":"15870101796149403f2pqfpviuo415m2"}, |
| | | {"label":"描述","field":"Remark","type":"textarea","initval":"","readonly":"false","required":"false","hidden":"false","readin":"true","fieldlength":512,"maxRows":6,"supField":"","blacklist":[],"uuid":"1587006199263k8hm45cmtomgu6hd881"}, |
| | | {"label":"脚本","field":"LongParam","type":"textarea","initval":"","readonly":"false","required":"true","encryption":"true","hidden":"false","readin":"true","fieldlength":12000,"maxRows":20,"supField":"","blacklist":[],"uuid":"1587006209935qbkle15h4d9i9lg9tcu"} |
| | | {"label":"函数",span:12,labelwidth: 33.3,"field":"func","type":"text","initval":"","readonly":"false","required":"true","hidden":"false","readin":"true","fieldlength":50,"regular":"funcname","supField":"","blacklist":[],"uuid":"1587006164634l397q15t49u2pfq02f5"}, |
| | | {"label":"排序",span:12,labelwidth: 33.3,"field":"Sort","type":"number","initval":0,"decimal":0,"min":"","max":"","readonly":"false","hidden":"false","readin":"true","supField":"","blacklist":[],"uuid":"15870101796149403f2pqfpviuo415m2"}, |
| | | {"label":"描述",span:24,labelwidth: 16.3,"field":"Remark","type":"textarea","initval":"","readonly":"false","required":"false","hidden":"false","readin":"true","fieldlength":512,"maxRows":6,"supField":"","blacklist":[],"uuid":"1587006199263k8hm45cmtomgu6hd881"}, |
| | | {"label":"脚本",span:24,labelwidth: 16.3,"field":"LongParam","type":"textarea","initval":"","readonly":"false","required":"true","encryption":"true","hidden":"false","readin":"true","fieldlength":12000,"maxRows":20,"supField":"","blacklist":[],"uuid":"1587006209935qbkle15h4d9i9lg9tcu"} |
| | | ] |
| | | }, |
| | | '1587007258155ut4nbggg4r66t9uhut2': { |
| | |
| | | "display":"modal" |
| | | }, |
| | | tables: [{"TbName":"s_custom_script","Remark":"自定义脚本"}], |
| | | groups: [], |
| | | fields: [ |
| | | {"label":"函数","field":"func","type":"text","initval":"","readonly":"false","required":"true","hidden":"false","readin":"true","fieldlength":50,"regular":"funcname","supField":"","blacklist":[],"uuid":"1587006164634l397q15t49u2pfq02f5"}, |
| | | {"label":"排序","field":"Sort","type":"number","initval":0,"decimal":0,"min":"","max":"","readonly":"false","hidden":"false","readin":"true","supField":"","blacklist":[],"uuid":"1587010196675i9m6ie3tv9kg2rhgfi0"}, |
| | | {"label":"描述","field":"Remark","type":"textarea","initval":"","readonly":"false","required":"false","hidden":"false","readin":"true","fieldlength":512,"maxRows":6,"supField":"","blacklist":[],"uuid":"1587006199263k8hm45cmtomgu6hd881"}, |
| | | {"label":"脚本","field":"LongParam","type":"textarea","initval":"","readonly":"false","required":"true","encryption":"true","hidden":"false","readin":"true","fieldlength":12000,"maxRows":20,"supField":"","blacklist":[],"uuid":"1587006209935qbkle15h4d9i9lg9tcu"} |
| | | {"label":"函数",span:12,labelwidth: 33.3,"field":"func","type":"text","initval":"","readonly":"false","required":"true","hidden":"false","readin":"true","fieldlength":50,"regular":"funcname","supField":"","blacklist":[],"uuid":"1587006164634l397q15t49u2pfq02f5"}, |
| | | {"label":"排序",span:12,labelwidth: 33.3,"field":"Sort","type":"number","initval":0,"decimal":0,"min":"","max":"","readonly":"false","hidden":"false","readin":"true","supField":"","blacklist":[],"uuid":"1587010196675i9m6ie3tv9kg2rhgfi0"}, |
| | | {"label":"描述",span:24,labelwidth: 16.3,"field":"Remark","type":"textarea","initval":"","readonly":"false","required":"false","hidden":"false","readin":"true","fieldlength":512,"maxRows":6,"supField":"","blacklist":[],"uuid":"1587006199263k8hm45cmtomgu6hd881"}, |
| | | {"label":"脚本",span:24,labelwidth: 16.3,"field":"LongParam","type":"textarea","initval":"","readonly":"false","required":"true","encryption":"true","hidden":"false","readin":"true","fieldlength":12000,"maxRows":20,"supField":"","blacklist":[],"uuid":"1587006209935qbkle15h4d9i9lg9tcu"} |
| | | ] |
| | | } |
| | | } |
| | |
| | | * @description 主表数据加载 |
| | | */ |
| | | async loadmaindata () { |
| | | const { setting } = this.state |
| | | let param = this.getDefaultParam() |
| | | |
| | | this.setState({ |
| | |
| | | data: result.data.map((item, index) => { |
| | | // item.LongParam = this.UnformatOptions(item.LongParam) |
| | | item.key = index |
| | | item.$$uuid = item[setting.primaryKey] || '' |
| | | return item |
| | | }), |
| | | total: result.total, |
| | |
| | | import options from '@/store/options.js' |
| | | import UtilsDM from '@/utils/utils-datamanage.js' |
| | | import { updateSubTable } from '@/utils/utils-update.js' |
| | | import { modifyTabview } from '@/store/action' |
| | | import asyncComponent from '@/utils/asyncComponent' |
| | | import asyncSpinComponent from '@/utils/asyncSpinComponent' |
| | | import NotFount from '@/components/404' |
| | |
| | | if (col.field) { |
| | | _arrField.push(col.field) |
| | | |
| | | if (col.linkmenu && col.linkmenu.length > 0) { |
| | | let menu_id = col.linkmenu.slice(-1)[0] |
| | | col.linkThdMenu = permMenus.filter(m => m.MenuID === menu_id)[0] || '' |
| | | } else { |
| | | col.linkThdMenu = '' |
| | | } |
| | | |
| | | col.nameField && _arrField.push(col.nameField) // 链接名字段 |
| | | if (col.Hide !== 'true' && col.type === 'number' && col.sum === 'true') { |
| | | statFields.push(col) |
| | |
| | | // 生成显示列,处理合并列中的字段 |
| | | config.columns.forEach((col, index) => { |
| | | if (_hideCol.includes(col.uuid)) return |
| | | |
| | | if (col.linkmenu && col.linkmenu.length > 0) { |
| | | let menu_id = col.linkmenu.slice(-1)[0] |
| | | col.linkThdMenu = permMenus.filter(m => m.MenuID === menu_id)[0] || '' |
| | | } else { |
| | | col.linkThdMenu = '' |
| | | } |
| | | |
| | | col.sort = index |
| | | |
| | |
| | | |
| | | Api.genericInterface(param).then(res => { |
| | | if (res.status) { |
| | | if (res.mk_ex_invoke === 'false') { |
| | | if (res.mk_ex_invoke === 'false' || res.mk_ex_invoke === false) { |
| | | this.loadmaindata() |
| | | } else { |
| | | this.customOuterRequest(res) |
| | |
| | | param[key] = result[key] |
| | | }) |
| | | |
| | | Api.directRequest(url, setting.method, param).then(res => { |
| | | Api.directRequest(url, setting.method, param, setting.cross).then(res => { |
| | | if (typeof(res) !== 'object' || Array.isArray(res)) { |
| | | let error = '未知的返回结果!' |
| | | |
| | |
| | | let result = await Api.genericInterface(param) |
| | | if (result.status) { |
| | | let data = fromJS(this.state.data).toJS() |
| | | let selectedData = fromJS(this.state.selectedData).toJS() |
| | | if (result.data && result.data[0]) { |
| | | let _data = result.data[0] |
| | | let _data = result.data[0] || {} |
| | | |
| | | if (absFields.length) { |
| | | absFields.forEach(field => { |
| | |
| | | }) |
| | | } |
| | | |
| | | _data.$$uuid = _data[setting.primaryKey] || '' |
| | | _data.$$BID = BID || '' |
| | | |
| | | try { |
| | | data = data.map(item => { |
| | | if (item[setting.primaryKey] === _data[setting.primaryKey]) { |
| | | if (item.$$uuid === _data.$$uuid) { |
| | | _data.key = item.key |
| | | _data.$$uuid = _data[setting.primaryKey] || '' |
| | | _data.$$BID = BID || '' |
| | | |
| | | return _data |
| | | } else { |
| | | return item |
| | | } |
| | | }) |
| | | selectedData = selectedData.map(item => { |
| | | if (_data.$$uuid === item.$$uuid) { |
| | | return _data |
| | | } |
| | | return item |
| | | }) |
| | | } catch { |
| | | console.warn('数据查询错误') |
| | |
| | | } |
| | | |
| | | this.setState({ |
| | | data: data, |
| | | data, |
| | | selectedData, |
| | | loading: false |
| | | }) |
| | | } else { |
| | |
| | | |
| | | const mapStateToProps = (state) => { |
| | | return { |
| | | tabviews: state.tabviews, |
| | | menuType: state.editLevel, |
| | | permAction: state.permAction, |
| | | permMenus: state.permMenus, |
| | | } |
| | | } |
| | | |
| | | const mapDispatchToProps = (dispatch) => { |
| | | return { |
| | | modifyTabview: (tabviews) => dispatch(modifyTabview(tabviews)) |
| | | } |
| | | const mapDispatchToProps = () => { |
| | | return {} |
| | | } |
| | | |
| | | export default connect(mapStateToProps, mapDispatchToProps)(SubTabViewTable) |
| | |
| | | |
| | | Api.genericInterface(param).then(res => { |
| | | if (res.status) { |
| | | if (res.mk_ex_invoke === 'false') { |
| | | if (res.mk_ex_invoke === 'false' || res.mk_ex_invoke === false) { |
| | | this.loadmaindata() |
| | | } else { |
| | | this.customOuterRequest(res) |
| | |
| | | param[key] = result[key] |
| | | }) |
| | | |
| | | Api.directRequest(url, setting.method, param).then(res => { |
| | | Api.directRequest(url, setting.method, param, setting.cross).then(res => { |
| | | if (typeof(res) !== 'object' || Array.isArray(res)) { |
| | | let error = '未知的返回结果!' |
| | | |
| | |
| | | } |
| | | |
| | | this.setState({ |
| | | BID: param && param.BID ? param.BID : '', |
| | | BID: param && param.$BID ? param.$BID : '', |
| | | loadingview: false, |
| | | config: config, |
| | | setting: config.setting, |
| | |
| | | import PropTypes from 'prop-types' |
| | | import moment from 'moment' |
| | | import { Button, Modal, notification, message } from 'antd' |
| | | import MutilForm from '@/tabviews/zshare/mutilform' |
| | | |
| | | import asyncSpinComponent from '@/utils/asyncSpinComponent' |
| | | import Utils, { getSysDefaultSql } from '@/utils/utils.js' |
| | | import options from '@/store/options.js' |
| | | import { updateForm } from '@/utils/utils-update.js' |
| | | import Api from '@/api' |
| | | import './index.scss' |
| | | |
| | | const { confirm } = Modal |
| | | const MutilForm = asyncSpinComponent(() => import('@/tabviews/zshare/mutilform')) |
| | | |
| | | class MainAction extends Component { |
| | | static propTpyes = { |
| | |
| | | this.setState({loadingUuid: ''}) |
| | | }) |
| | | } else if (item.OpenType === 'pop') { |
| | | item = updateForm(item) |
| | | if (item.setting.display === 'prompt') { // 如果表单以是否框展示,不请求下拉菜单信息 |
| | | this.setState({ |
| | | execAction: item, |
| | |
| | | const { BData } = this.props |
| | | const { execAction, tabledata } = this.state |
| | | let _this = this |
| | | let _fields = [] |
| | | |
| | | if (execAction.groups.length > 0) { |
| | | execAction.groups.forEach(group => { |
| | | _fields = [..._fields, ...group.sublist] |
| | | }) |
| | | } else { |
| | | _fields = execAction.fields |
| | | } |
| | | |
| | | let result = _fields.map(item => { |
| | | let result = [] |
| | | execAction.fields.forEach(item => { |
| | | if (!item.field) return |
| | | let _readin = item.readin !== 'false' |
| | | let _initval = item.initval |
| | | |
| | |
| | | _fieldlen = item.decimal ? item.decimal : 0 |
| | | } |
| | | |
| | | return { |
| | | result.push({ |
| | | key: item.field, |
| | | readonly: item.readonly === 'true', |
| | | readin: _readin, |
| | | fieldlen: _fieldlen, |
| | | type: item.type, |
| | | value: _initval |
| | | } |
| | | }) |
| | | }) |
| | | |
| | | confirm({ |
| | |
| | | export const buttonConfig = { |
| | | '1583979660949vpssdb2p2lsqff9abkr': { |
| | | type: 'Modal', |
| | | setting:{title: '添加',width:45,focus:'VersionName',cols:'1',finish:'close',clickouter:'unclose',container:'tab',display:'modal'}, |
| | | version: '1.0', |
| | | setting:{title: '添加',width:45,focus:'VersionName',finish:'close',clickouter:'unclose',container:'tab',display:'modal'}, |
| | | tables:[], |
| | | groups:[], |
| | | fields:[ |
| | | {label:'传输号',field:'VersionName',type:'text',initval:'',regular:'letter&number',readonly:'false',required:'true',hidden:'false',fieldlength:20,readin:'true',uuid:'1581738428097qgoe876i5u0866373uu'} |
| | | {label:'传输号',field:'VersionName',span:24,labelwidth: 33.3,type:'text',initval:'',regular:'letter&number',readonly:'false',required:'true',hidden:'false',fieldlength:20,readin:'true',uuid:'1581738428097qgoe876i5u0866373uu'} |
| | | ] |
| | | }, |
| | | '1583983849299g1qfd28g3c9n9e0e57a': { |
| | |
| | | this.setState({ |
| | | data: result.data.map((item, index) => { |
| | | item.key = index |
| | | item.$$uuid = item[setting.primaryKey] || '' |
| | | return item |
| | | }), |
| | | total: result.total, |
| | |
| | | this.setState({ |
| | | data: result.data.map((item, index) => { |
| | | item.key = index |
| | | item.$$uuid = item[setting.primaryKey] || '' |
| | | item.$$BID = _BID || '' |
| | | return item |
| | | }), |
| | |
| | | |
| | | let errors = null |
| | | let sheetName = btn.verify.sheet |
| | | let errDetail = '' |
| | | |
| | | if (Object.keys(workbook.Sheets).length === 1) { |
| | | sheetName = Object.keys(workbook.Sheets)[0] |
| | |
| | | } else { |
| | | let iserror = false |
| | | btn.verify.columns.forEach(op => { |
| | | if (header[op.Column] !== op.Text) { |
| | | let _name = typeof(header[op.Column]) === 'string' ? header[op.Column].replace(/(^\s*|\s*$)/g, '') : header[op.Column] |
| | | let _text = op.Text ? op.Text.replace(/(^\s*|\s*$)/g, '') : op.Text |
| | | |
| | | if (_name !== _text && !iserror) { |
| | | iserror = true |
| | | errors = 'headerError' |
| | | errDetail = `Excel中(${_name})与按钮列信息(${_text})不一致!` |
| | | } |
| | | }) |
| | | |
| | | if (iserror) { |
| | | errors = 'headerError' |
| | | } |
| | | } |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | // 最终获取到并且格式化后的 json 数据 |
| | | this.props.returndata(data, errors, sheetName) |
| | | this.props.returndata(data, errors, sheetName, errDetail) |
| | | this.setState({ |
| | | excelId: '', |
| | | }, () => { |
| | |
| | | /** |
| | | * @description Excel 导入 |
| | | */ |
| | | getexceldata = (data, errors, sheetName) => { |
| | | getexceldata = (data, errors, sheetName, errDetail) => { |
| | | const { btn } = this.props |
| | | |
| | | if (errors) { |
| | |
| | | } else if (errors === 'headerError') { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '工作表《' + sheetName + '》表头设置错误,请检查表头中的名称及顺序,与按钮Excel列信息是否一致!', |
| | | message: `工作表《${sheetName}》表头错误,${errDetail}`, |
| | | duration: 5 |
| | | }) |
| | | } |
| | |
| | | let _header = [] |
| | | let _topRow = {} |
| | | let colwidth = [] |
| | | let abses = [] |
| | | |
| | | btn.verify.columns.forEach(col => { |
| | | if (_topRow[col.Column]) return |
| | | |
| | | _header.push(col.Column) |
| | | _topRow[col.Column] = col.Text |
| | | |
| | | if (col.abs === 'true') { |
| | | abses.push(col.Column) |
| | | } |
| | | |
| | | colwidth.push({width: col.Width || 20}) |
| | | }) |
| | |
| | | |
| | | table.push(_topRow) |
| | | |
| | | data && data.forEach(item => { |
| | | let _row = {} |
| | | _header.forEach(field => { |
| | | _row[field] = item[field] |
| | | if (data && abses.length > 0) { |
| | | data.forEach(item => { |
| | | let _row = {} |
| | | _header.forEach(field => { |
| | | if (item[field] && abses.includes(field)) { |
| | | _row[field] = Math.abs(item[field]) |
| | | } else { |
| | | _row[field] = item[field] |
| | | } |
| | | }) |
| | | |
| | | table.push(_row) |
| | | }) |
| | | |
| | | table.push(_row) |
| | | }) |
| | | } else if (data) { |
| | | data.forEach(item => { |
| | | let _row = {} |
| | | _header.forEach(field => { |
| | | _row[field] = item[field] |
| | | }) |
| | | |
| | | table.push(_row) |
| | | }) |
| | | } |
| | | |
| | | const ws = XLSX.utils.json_to_sheet(table, {header: _header, skipHeader: true}) |
| | | |
| | |
| | | let allSearch = Utils.getAllSearchOptions(search) |
| | | let userName = sessionStorage.getItem('User_Name') || '' |
| | | let fullName = sessionStorage.getItem('Full_Name') || '' |
| | | let city = sessionStorage.getItem('city') || '' |
| | | |
| | | if (sessionStorage.getItem('isEditState') === 'true') { |
| | | userName = sessionStorage.getItem('CloudUserName') || '' |
| | |
| | | }) |
| | | |
| | | regoptions.push({ |
| | | reg: new RegExp('@login_city@', 'ig'), |
| | | value: city |
| | | }, { |
| | | reg: new RegExp('@userName@', 'ig'), |
| | | value: userName |
| | | }, { |
| | |
| | | selectedData={selectedData} |
| | | /> |
| | | ) |
| | | } else if (item.OpenType === 'tab' || item.OpenType === 'blank') { |
| | | } else if (item.OpenType === 'tab') { |
| | | return ( |
| | | <TabButton |
| | | key={item.uuid} |
| | |
| | | import zhCN from '@/locales/zh-CN/main.js' |
| | | import enUS from '@/locales/en-US/main.js' |
| | | import asyncSpinComponent from '@/utils/asyncSpinComponent' |
| | | import { updateForm } from '@/utils/utils-update.js' |
| | | import MKEmitter from '@/utils/events.js' |
| | | import './index.scss' |
| | | |
| | |
| | | |
| | | if (position === 'toolbar') { |
| | | MKEmitter.addListener('triggerBtnId', this.actionTrigger) |
| | | } else if (position === 'form') { |
| | | MKEmitter.addListener('triggerFormSubmit', this.actionSubmit) |
| | | } |
| | | } |
| | | |
| | |
| | | return |
| | | } |
| | | MKEmitter.removeListener('triggerBtnId', this.actionTrigger) |
| | | MKEmitter.removeListener('triggerFormSubmit', this.actionSubmit) |
| | | } |
| | | |
| | | actionSubmit = (res) => { |
| | | const { btn } = this.props |
| | | |
| | | if (btn.uuid !== res.menuId) return |
| | | |
| | | this.setState({ |
| | | loading: true |
| | | }) |
| | | |
| | | this.execSubmit(this.state.tabledata, () => {}, res.form) |
| | | } |
| | | |
| | | /** |
| | |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } else if (!setting.primaryKey) { |
| | | } else if (btn.OpenType !== 'formSubmit' && !setting.primaryKey) { |
| | | // 需要选择行时,校验是否设置主键 |
| | | notification.warning({ |
| | | top: 92, |
| | |
| | | return |
| | | } |
| | | |
| | | if (btn.OpenType === 'prompt') { |
| | | if (btn.OpenType === 'formSubmit') { |
| | | this.setState({ |
| | | tabledata: data |
| | | }) |
| | | MKEmitter.emit('mkFormSubmit', btn.uuid) |
| | | return |
| | | } else if (btn.OpenType === 'prompt') { |
| | | this.updateStatus('start') |
| | | confirm({ |
| | | title: this.state.dict['main.action.confirm.tip'], |
| | |
| | | } else if (btn.OpenType === 'pop') { |
| | | this.updateStatus('start') |
| | | |
| | | let modal = this.state.btnconfig |
| | | if (!modal && btn.modal) { |
| | | modal = this.handleModelConfig(btn.modal) |
| | | } |
| | | |
| | | this.setState({ |
| | | tabledata: data, |
| | | btnconfig: btn.modal ? btn.modal : this.state.btnconfig |
| | | btnconfig: modal |
| | | }, () => { |
| | | this.improveAction() |
| | | }) |
| | |
| | | } |
| | | |
| | | param.LText = Utils.formatOptions(param.LText) |
| | | } else if (btn.OpenType === 'pop') { // 表单 |
| | | } else if (btn.OpenType === 'pop' || btn.OpenType === 'formSubmit') { // 表单 |
| | | if (btn.sqlType === 'insert') { // 系统函数添加时,生成uuid |
| | | primaryId = '' |
| | | |
| | |
| | | |
| | | param[setting.primaryKey] = primaryId // 设置主键参数 |
| | | |
| | | if (btn.OpenType === 'pop') { // 表单 |
| | | if (btn.OpenType === 'pop' || btn.OpenType === 'formSubmit') { // 表单 |
| | | formdata.forEach(_data => { |
| | | param[_data.key] = _data.value |
| | | }) |
| | |
| | | param.BID = this.props.BID |
| | | } |
| | | |
| | | if (btn.OpenType === 'pop' && formdata) { // 表单 |
| | | if ((btn.OpenType === 'pop' || btn.OpenType === 'formSubmit') && formdata) { // 表单 |
| | | formdata.forEach(_data => { |
| | | param[_data.key] = _data.value |
| | | }) |
| | |
| | | |
| | | Api.genericInterface(param).then(res => { |
| | | if (res.status) { |
| | | if (res.mk_ex_invoke === 'false' && params.length === 0) { |
| | | if ((res.mk_ex_invoke === 'false' || res.mk_ex_invoke === false) && params.length === 0) { |
| | | this.execSuccess(res) |
| | | _resolve() |
| | | } else if (res.mk_ex_invoke === 'false' && params.length > 0) { |
| | | } else if ((res.mk_ex_invoke === 'false' || res.mk_ex_invoke === false) && params.length > 0) { |
| | | this.customLoopRequest(params, _resolve) |
| | | } else { |
| | | this.customOuterRequest(params, res, record, _resolve) |
| | |
| | | return new Promise(resolve => { |
| | | Api.genericInterface(_this.state.checkParam).then((result) => { |
| | | if (result.status) { |
| | | if (result.mk_ex_invoke === 'false' && params.length === 0) { |
| | | if ((result.mk_ex_invoke === 'false' || result.mk_ex_invoke === false) && params.length === 0) { |
| | | _this.execSuccess(result) |
| | | _resolve() |
| | | } else if (result.mk_ex_invoke === 'false' && params.length > 0) { |
| | | } else if ((result.mk_ex_invoke === 'false' || result.mk_ex_invoke === false) && params.length > 0) { |
| | | _this.customLoopRequest(params, _resolve) |
| | | } else { |
| | | _this.customOuterRequest(params, result, record, _resolve) |
| | |
| | | param[key] = result[key] |
| | | }) |
| | | |
| | | Api.directRequest(url, btn.method, param).then(res => { |
| | | Api.directRequest(url, btn.method, param, btn.cross).then(res => { |
| | | if (typeof(res) !== 'object' || Array.isArray(res)) { |
| | | let error = '未知的返回结果!' |
| | | |
| | |
| | | } |
| | | |
| | | if (btn.execSuccess !== 'never') { |
| | | MKEmitter.emit('refreshByButtonResult', btn.$menuId, btn.execSuccess, btn) |
| | | MKEmitter.emit('refreshByButtonResult', btn.$menuId, btn.execSuccess || '', btn) |
| | | } |
| | | } |
| | | |
| | |
| | | }) |
| | | } |
| | | |
| | | handleModelConfig = (config) => { |
| | | let roleId = sessionStorage.getItem('role_id') || '' // 角色ID |
| | | config.fields = config.fields.map(cell => { |
| | | // 数据源sql语句,预处理,权限黑名单字段设置为隐藏表单 |
| | | if (['select', 'link', 'multiselect', 'radio', 'checkbox', 'checkcard'].includes(cell.type) && cell.resourceType === '1') { |
| | | let _option = Utils.getSelectQueryOptions(cell) |
| | | |
| | | cell.data_sql = Utils.formatOptions(_option.sql) |
| | | cell.base_sql = window.btoa(window.encodeURIComponent(_option.sql)) |
| | | cell.arr_field = _option.field |
| | | } |
| | | |
| | | // 字段权限黑名单 |
| | | if (!cell.blacklist || cell.blacklist.length === 0) return cell |
| | | if (cell.blacklist.filter(v => roleId.indexOf(v) > -1).length > 0) { |
| | | cell.hidden = 'true' |
| | | } |
| | | |
| | | return cell |
| | | }) |
| | | return config |
| | | } |
| | | |
| | | /** |
| | | * @description 获取按钮配置信息 |
| | | */ |
| | |
| | | }) |
| | | this.updateStatus('over') |
| | | } else { |
| | | let roleId = sessionStorage.getItem('role_id') || '' // 角色ID |
| | | if (_LongParam.groups.length > 0) { |
| | | _LongParam.groups.forEach(group => { |
| | | group.sublist = group.sublist.map(cell => { |
| | | // 数据源sql语句,预处理, 权限黑名单字段设置为隐藏表单 |
| | | if (['select', 'link', 'multiselect', 'radio', 'checkbox', 'checkcard'].includes(cell.type) && cell.resourceType === '1') { |
| | | let _option = Utils.getSelectQueryOptions(cell) |
| | | |
| | | if (sessionStorage.getItem('dataM') === 'true') { // 数据权限 |
| | | _option.sql = _option.sql.replace(/\$@/ig, '/*') |
| | | _option.sql = _option.sql.replace(/@\$/ig, '*/') |
| | | } else { |
| | | _option.sql = _option.sql.replace(/@\$|\$@/ig, '') |
| | | } |
| | | // 外联数据库替换 |
| | | if (window.GLOB.externalDatabase !== null) { |
| | | _option.sql = _option.sql.replace(/@db@/ig, window.GLOB.externalDatabase) |
| | | } |
| | | |
| | | cell.data_sql = Utils.formatOptions(_option.sql) |
| | | cell.base_sql = window.btoa(window.encodeURIComponent(_option.sql)) |
| | | cell.arr_field = _option.field |
| | | } |
| | | |
| | | // 字段权限黑名单 |
| | | if (!cell.blacklist || cell.blacklist.length === 0) return cell |
| | | if (cell.blacklist.filter(v => roleId.indexOf(v) > -1).length > 0) { |
| | | cell.hidden = 'true' |
| | | } |
| | | |
| | | return cell |
| | | }) |
| | | }) |
| | | } else { |
| | | _LongParam.fields = _LongParam.fields.map(cell => { |
| | | // 数据源sql语句,预处理,权限黑名单字段设置为隐藏表单 |
| | | if (['select', 'link', 'multiselect', 'radio', 'checkbox', 'checkcard'].includes(cell.type) && cell.resourceType === '1') { |
| | | let _option = Utils.getSelectQueryOptions(cell) |
| | | |
| | | if (sessionStorage.getItem('dataM') === 'true') { // 数据权限 |
| | | _option.sql = _option.sql.replace(/\$@/ig, '/*') |
| | | _option.sql = _option.sql.replace(/@\$/ig, '*/') |
| | | } else { |
| | | _option.sql = _option.sql.replace(/@\$|\$@/ig, '') |
| | | } |
| | | |
| | | cell.data_sql = Utils.formatOptions(_option.sql) |
| | | cell.base_sql = window.btoa(window.encodeURIComponent(_option.sql)) |
| | | cell.arr_field = _option.field |
| | | } |
| | | |
| | | // 字段权限黑名单 |
| | | if (!cell.blacklist || cell.blacklist.length === 0) return cell |
| | | if (cell.blacklist.filter(v => roleId.indexOf(v) > -1).length > 0) { |
| | | cell.hidden = 'true' |
| | | } |
| | | |
| | | return cell |
| | | }) |
| | | } |
| | | |
| | | _LongParam = updateForm(_LongParam) |
| | | _LongParam = this.handleModelConfig(_LongParam) |
| | | |
| | | this.setState({ |
| | | btnconfig: _LongParam |
| | | }, () => { |
| | |
| | | const { BData } = this.props |
| | | const { btnconfig, tabledata } = this.state |
| | | let _this = this |
| | | let _fields = [] |
| | | |
| | | if (btnconfig.groups.length > 0) { |
| | | btnconfig.groups.forEach(group => { |
| | | _fields = [..._fields, ...group.sublist] |
| | | }) |
| | | } else { |
| | | _fields = btnconfig.fields |
| | | } |
| | | |
| | | let result = _fields.map(item => { |
| | | let result = [] |
| | | btnconfig.fields.forEach(item => { |
| | | if (!item.field) return |
| | | let _readin = item.readin !== 'false' |
| | | let _initval = item.initval |
| | | |
| | |
| | | _fieldlen = item.decimal ? item.decimal : 0 |
| | | } |
| | | |
| | | return { |
| | | if (_initval === undefined) { |
| | | _initval = '' |
| | | } |
| | | |
| | | result.push({ |
| | | key: item.field, |
| | | readonly: item.readonly === 'true', |
| | | readin: _readin, |
| | | fieldlen: _fieldlen, |
| | | writein: item.writein !== 'false', |
| | | type: item.type, |
| | | value: _initval |
| | | } |
| | | }) |
| | | }) |
| | | |
| | | confirm({ |
| | |
| | | import zhCN from '@/locales/zh-CN/main.js' |
| | | import enUS from '@/locales/en-US/main.js' |
| | | import asyncSpinComponent from '@/utils/asyncSpinComponent' |
| | | import { updateForm } from '@/utils/utils-update.js' |
| | | import MKEmitter from '@/utils/events.js' |
| | | import './index.scss' |
| | | |
| | |
| | | |
| | | if (btn.execMode === 'pop') { |
| | | this.updateStatus('start') |
| | | let modal = this.state.btnconfig |
| | | if (!modal && btn.modal) { |
| | | modal = this.handleModelConfig(btn.modal) |
| | | } |
| | | |
| | | this.setState({ |
| | | tabledata: data, |
| | | btnconfig: btn.modal ? btn.modal : this.state.btnconfig |
| | | btnconfig: modal |
| | | }, () => { |
| | | this.improveAction() |
| | | }) |
| | |
| | | }) |
| | | } |
| | | |
| | | handleModelConfig = (config) => { |
| | | let roleId = sessionStorage.getItem('role_id') || '' // 角色ID |
| | | config.fields = config.fields.map(cell => { |
| | | // 数据源sql语句,预处理,权限黑名单字段设置为隐藏表单 |
| | | if (['select', 'link', 'multiselect', 'radio', 'checkbox', 'checkcard'].includes(cell.type) && cell.resourceType === '1') { |
| | | let _option = Utils.getSelectQueryOptions(cell) |
| | | |
| | | cell.data_sql = Utils.formatOptions(_option.sql) |
| | | cell.base_sql = window.btoa(window.encodeURIComponent(_option.sql)) |
| | | cell.arr_field = _option.field |
| | | } |
| | | |
| | | // 字段权限黑名单 |
| | | if (!cell.blacklist || cell.blacklist.length === 0) return cell |
| | | if (cell.blacklist.filter(v => roleId.indexOf(v) > -1).length > 0) { |
| | | cell.hidden = 'true' |
| | | } |
| | | |
| | | return cell |
| | | }) |
| | | return config |
| | | } |
| | | |
| | | /** |
| | | * @description 获取按钮配置信息 |
| | | */ |
| | |
| | | }) |
| | | this.updateStatus('over') |
| | | } else { |
| | | let roleId = sessionStorage.getItem('role_id') || '' // 角色ID |
| | | if (_LongParam.groups.length > 0) { |
| | | _LongParam.groups.forEach(group => { |
| | | group.sublist = group.sublist.map(cell => { |
| | | // 数据源sql语句,预处理 |
| | | if (['select', 'link', 'multiselect', 'radio', 'checkbox', 'checkcard'].includes(cell.type) && cell.resourceType === '1') { |
| | | let _option = Utils.getSelectQueryOptions(cell) |
| | | |
| | | if (sessionStorage.getItem('dataM') === 'true') { // 数据权限 |
| | | _option.sql = _option.sql.replace(/\$@/ig, '/*') |
| | | _option.sql = _option.sql.replace(/@\$/ig, '*/') |
| | | } else { |
| | | _option.sql = _option.sql.replace(/@\$|\$@/ig, '') |
| | | } |
| | | // 外联数据库替换 |
| | | if (window.GLOB.externalDatabase !== null) { |
| | | _option.sql = _option.sql.replace(/@db@/ig, window.GLOB.externalDatabase) |
| | | } |
| | | |
| | | cell.data_sql = Utils.formatOptions(_option.sql) |
| | | cell.base_sql = window.btoa(window.encodeURIComponent(_option.sql)) |
| | | cell.arr_field = _option.field |
| | | } |
| | | |
| | | // 字段权限黑名单 |
| | | if (!cell.blacklist || cell.blacklist.length === 0) return cell |
| | | if (cell.blacklist.filter(v => roleId.indexOf(v) > -1).length > 0) { |
| | | cell.hidden = 'true' |
| | | } |
| | | |
| | | return cell |
| | | }) |
| | | }) |
| | | } else { |
| | | _LongParam.fields = _LongParam.fields.map(cell => { |
| | | // 数据源sql语句,预处理 |
| | | if (['select', 'link', 'multiselect', 'radio', 'checkbox', 'checkcard'].includes(cell.type) && cell.resourceType === '1') { |
| | | let _option = Utils.getSelectQueryOptions(cell) |
| | | |
| | | if (sessionStorage.getItem('dataM') === 'true') { // 数据权限 |
| | | _option.sql = _option.sql.replace(/\$@/ig, '/*') |
| | | _option.sql = _option.sql.replace(/@\$/ig, '*/') |
| | | } else { |
| | | _option.sql = _option.sql.replace(/@\$|\$@/ig, '') |
| | | } |
| | | |
| | | cell.data_sql = Utils.formatOptions(_option.sql) |
| | | cell.base_sql = window.btoa(window.encodeURIComponent(_option.sql)) |
| | | cell.arr_field = _option.field |
| | | } |
| | | |
| | | // 字段权限黑名单 |
| | | if (!cell.blacklist || cell.blacklist.length === 0) return cell |
| | | if (cell.blacklist.filter(v => roleId.indexOf(v) > -1).length > 0) { |
| | | cell.hidden = 'true' |
| | | } |
| | | |
| | | return cell |
| | | }) |
| | | } |
| | | _LongParam = updateForm(_LongParam) |
| | | _LongParam = this.handleModelConfig(_LongParam) |
| | | |
| | | this.setState({ |
| | | btnconfig: _LongParam |
| | |
| | | const { BData } = this.props |
| | | const { btnconfig, tabledata } = this.state |
| | | let _this = this |
| | | let _fields = [] |
| | | let result = [] |
| | | |
| | | if (btnconfig.groups.length > 0) { |
| | | btnconfig.groups.forEach(group => { |
| | | _fields = [..._fields, ...group.sublist] |
| | | }) |
| | | } else { |
| | | _fields = btnconfig.fields |
| | | } |
| | | |
| | | let result = _fields.map(item => { |
| | | btnconfig.fields.forEach(item => { |
| | | if (!item.field) return |
| | | let _readin = item.readin !== 'false' |
| | | let _initval = item.initval |
| | | |
| | |
| | | _fieldlen = item.decimal ? item.decimal : 0 |
| | | } |
| | | |
| | | return { |
| | | if (_initval === undefined) { |
| | | _initval = '' |
| | | } |
| | | |
| | | result.push({ |
| | | key: item.field, |
| | | readonly: item.readonly === 'true', |
| | | readin: _readin, |
| | | fieldlen: _fieldlen, |
| | | type: item.type, |
| | | value: _initval |
| | | } |
| | | }) |
| | | }) |
| | | |
| | | confirm({ |
| | |
| | | } |
| | | |
| | | let primaryId = '' |
| | | let _data = null |
| | | |
| | | if (btn.Ot === 'requiredSgl') { |
| | | primaryId = data[0][setting.primaryKey] || '' |
| | | _data = data[0] |
| | | } |
| | | |
| | | let newtab = {} |
| | |
| | | ...menu, |
| | | selected: true, |
| | | param: { |
| | | BID: primaryId, |
| | | data: _data |
| | | $BID: primaryId |
| | | } |
| | | } |
| | | } |
| | |
| | | return tab.MenuID !== newtab.MenuID |
| | | }) |
| | | |
| | | if (tabviews.length !== tabs.length) { |
| | | this.props.modifyTabview(fromJS(tabs).toJS()) |
| | | } |
| | | |
| | | this.setState({}, () => { |
| | | if (MenuID) { |
| | | tabs.splice(index + 1, 0, newtab) |
| | | } else { |
| | | tabs.push(newtab) |
| | | if (['linkage_navigation', 'linkage'].includes(window.GLOB.navBar)) { |
| | | this.props.modifyTabview([newtab]) |
| | | } else { |
| | | if (tabviews.length !== tabs.length) { |
| | | this.props.modifyTabview(fromJS(tabs).toJS()) |
| | | } |
| | | this.props.modifyTabview(tabs) |
| | | }) |
| | | |
| | | this.setState({}, () => { |
| | | if (MenuID) { |
| | | tabs.splice(index + 1, 0, newtab) |
| | | } else { |
| | | tabs.push(newtab) |
| | | } |
| | | this.props.modifyTabview(tabs) |
| | | }) |
| | | } |
| | | |
| | | MKEmitter.emit('openNewTab') |
| | | if (window.GLOB.systemType === 'production') { |
| | |
| | | selectedData={[data]} |
| | | /> |
| | | ) |
| | | } else if (item.OpenType === 'tab' || item.OpenType === 'blank') { |
| | | } else if (item.OpenType === 'tab') { |
| | | return ( |
| | | <TabButton |
| | | key={item.uuid} |
| | |
| | | } |
| | | |
| | | state = { |
| | | dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, // 字典 |
| | | dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, // 字典 |
| | | empty: true, // 图表数据为空 |
| | | actions: [], // 图表绑定的按钮组 |
| | | chartId: Utils.getuuid(), // 图表Id |
| | |
| | | } else if (quarter === 3) { |
| | | _stime = year + '-07-01' |
| | | _etime = year + '-09-30' |
| | | } else if (quarter === 2) { |
| | | } else if (quarter === 4) { |
| | | _stime = year + '-10-01' |
| | | _etime = year + '-12-31' |
| | | } |
| | |
| | | } |
| | | } |
| | | } |
| | | tr:hover { |
| | | tr:not(.ant-quarter-selected):hover { |
| | | font-weight: bold; |
| | | background: #e6f7ff; |
| | | } |
| | | tr.ant-quarter-selected { |
| | | font-weight: bold; |
| | | background: #bae7ff!important; |
| | | background: #bae7ff; |
| | | } |
| | | } |
| | | .quarter-picker-tooltip.bottomRight { |
| | |
| | | } |
| | | |
| | | onDelete = (msg) => { |
| | | let filelist = this.state.filelist.filter(v => !v.url && !v.response) |
| | | |
| | | let filelist = this.state.filelist.map(item => { |
| | | if (!item.url && !item.response && !item.status) { |
| | | item.status = 'error' |
| | | } |
| | | return item |
| | | }) |
| | | this.setState({filelist, showprogress: false}) |
| | | this.props.onChange(filelist) |
| | | |
| | |
| | | } |
| | | .fileupload-form-container.limit-fileupload { |
| | | > .ant-upload { |
| | | display: none; |
| | | display: inline; |
| | | >.ant-upload { |
| | | >input { |
| | | display: none; |
| | | } |
| | | >button { |
| | | display: none; |
| | | } |
| | | } |
| | | } |
| | | } |
| | |
| | | paddingTop = '56.25%' |
| | | } |
| | | |
| | | if (display !== 'picture') { |
| | | if (!options || options.length === 0) { |
| | | return null |
| | | } else if (display !== 'picture') { |
| | | if (!fields || fields.length === 0) { |
| | | return null |
| | | } |
| | | return options.map(item => { |
| | | let _active = false |
| | | if (multiple === 'true' && selectKeys.includes(item.$value)) { |
| | |
| | | |
| | | state = { |
| | | value: '', |
| | | encryption: 'false' |
| | | encryption: false |
| | | } |
| | | |
| | | UNSAFE_componentWillMount () { |
| | | let value = '' |
| | | let encryption = 'false' |
| | | let encryption = false |
| | | |
| | | if (this.props['data-__meta']) { |
| | | value = this.props['data-__meta'].initialValue || '' |
| | | } |
| | | |
| | | if (this.props.Item && this.props.Item.encryption === 'true') { |
| | | encryption = 'true' |
| | | encryption = true |
| | | if (value) { |
| | | try { |
| | | value = window.decodeURIComponent(window.atob(value)) |
| | |
| | | }) |
| | | } |
| | | |
| | | UNSAFE_componentWillReceiveProps(nextProps) { |
| | | const { value, encryption } = this.state |
| | | |
| | | if (!encryption && value !== nextProps.value) { |
| | | this.setState({ value: nextProps.value || '' }) |
| | | } else if (encryption && window.btoa(window.encodeURIComponent(value)) !== nextProps.value) { |
| | | let _value = nextProps.value || '' |
| | | try { |
| | | _value = window.decodeURIComponent(window.atob(_value)) |
| | | } catch { |
| | | _value = nextProps.value || '' |
| | | } |
| | | this.setState({ value: _value }) |
| | | } |
| | | } |
| | | |
| | | onChange = (e) => { |
| | | const { encryption } = this.state |
| | | let val = e.target.value |
| | |
| | | this.setState({ value: val }) |
| | | |
| | | let _val = val |
| | | if (encryption === 'true') { |
| | | if (encryption) { |
| | | try { |
| | | _val = window.btoa(window.encodeURIComponent(_val)) |
| | | } catch { |
| | |
| | | } |
| | | |
| | | state = { |
| | | cols: 2, // 显示为多少列 |
| | | datatype: null, // 数据类型 |
| | | readtype: null, // 是否只读 |
| | | readin: null, // 行数据是否写入 |
| | |
| | | record: {} // 记录下拉表单关联字段,用于数据写入 |
| | | } |
| | | |
| | | UNSAFE_componentWillMount () { |
| | | let cols = 2 |
| | | if (this.props.action.setting && this.props.action.setting.cols) { |
| | | cols = parseInt(this.props.action.setting.cols) |
| | | if (cols > 4 || cols < 1) { |
| | | cols = 2 |
| | | } |
| | | } |
| | | |
| | | this.setState({ |
| | | cols: cols |
| | | }) |
| | | } |
| | | |
| | | componentDidMount () { |
| | | const { data, BData } = this.props |
| | | let action = fromJS(this.props.action).toJS() |
| | | |
| | | const { data, BData, action } = this.props |
| | | |
| | | let datatype = {} |
| | | let readtype = {} |
| | | let readin = {} |
| | | let writein = {} |
| | | let fieldlen = {} |
| | | let formlist = [] |
| | | let intercepts = [] |
| | | let _inputfields = [] |
| | | |
| | | if (action.groups.length > 0) { |
| | | action.groups.forEach(group => { |
| | | if (group.sublist.length === 0) return |
| | | |
| | | if (!group.default) { |
| | | formlist.push({ |
| | | type: 'title', |
| | | label: group.label, |
| | | uuid: group.uuid |
| | | }) |
| | | } |
| | | |
| | | formlist.push(...group.sublist) |
| | | }) |
| | | } else { |
| | | formlist = action.fields |
| | | } |
| | | |
| | | let linkFields = {} // 关联菜单 |
| | | let supItemVal = {} // 上级菜单初始值 |
| | | let deForms = [] // 需要动态获取下拉菜单的表单 |
| | | |
| | | let formlist = fromJS(action.fields).toJS() |
| | | |
| | | formlist.forEach(item => { |
| | | if (item.type === 'text' || item.type === 'number') { // 用于过滤下拉菜单关联表单 |
| | |
| | | }) |
| | | |
| | | formlist = formlist.map(item => { |
| | | if (item.type === 'title') return item |
| | | if (item.labelwidth) { |
| | | item.labelCol = {style: {width: item.labelwidth + '%'}} |
| | | item.wrapperCol = {style: {width: (100 - item.labelwidth) + '%'}} |
| | | } |
| | | if (item.type === 'split' || item.type === 'hint') return item |
| | | |
| | | // 数据自动填充 |
| | | let _readin = item.readin !== 'false' |
| | |
| | | |
| | | if (item.type === 'linkMain') { |
| | | newval = BData && BData[item.field] ? BData[item.field] : '' |
| | | } else if (_readin && !/^date/.test(item.type) && this.props.data && this.props.data.hasOwnProperty(item.field)) { |
| | | newval = this.props.data[item.field] |
| | | } else if (_readin && !/^date/.test(item.type) && data && data.hasOwnProperty(item.field)) { |
| | | newval = data[item.field] |
| | | } else if (item.type === 'date') { // 时间搜索 |
| | | if (_readin && this.props.data && this.props.data.hasOwnProperty(item.field)) { |
| | | newval = this.props.data[item.field] |
| | | if (_readin && data && data.hasOwnProperty(item.field)) { |
| | | newval = data[item.field] |
| | | } |
| | | if (newval) { |
| | | newval = moment(newval, 'YYYY-MM-DD') |
| | |
| | | newval = null |
| | | } |
| | | } else if (item.type === 'datemonth') { |
| | | if (_readin && this.props.data && this.props.data.hasOwnProperty(item.field)) { |
| | | newval = this.props.data[item.field] |
| | | if (_readin && data && data.hasOwnProperty(item.field)) { |
| | | newval = data[item.field] |
| | | } |
| | | if (newval) { |
| | | newval = moment(newval, 'YYYY-MM') |
| | |
| | | newval = null |
| | | } |
| | | } else if (item.type === 'datetime') { |
| | | if (_readin && this.props.data && this.props.data.hasOwnProperty(item.field)) { |
| | | newval = this.props.data[item.field] |
| | | if (_readin && data && data.hasOwnProperty(item.field)) { |
| | | newval = data[item.field] |
| | | } |
| | | if (newval) { |
| | | newval = moment(newval, 'YYYY-MM-DD HH:mm:ss') |
| | |
| | | if (['select', 'link', 'multiselect', 'radio', 'checkbox', 'checkcard'].includes(item.type) && item.resourceType === '1') { |
| | | deForms.push(item) |
| | | } else if (['select', 'link', 'radio'].includes(item.type) && item.resourceType !== '1') { // 选中第一项 |
| | | if (item.initval && item.initval.indexOf('$first') > -1) { |
| | | if (typeof(item.initval) === 'string' && item.initval.indexOf('$first') > -1) { |
| | | item.initval = item.options[0] ? item.options[0].Value : '' |
| | | } |
| | | } |
| | |
| | | formlist |
| | | }, () => { |
| | | if (action.setting && action.setting.focus) { |
| | | this.selectInput(action.setting.focus, 'init') |
| | | setTimeout(() => { |
| | | this.selectInput(action.setting.focus) |
| | | }, 500) |
| | | } |
| | | // 用来更新state,防止受控表单初始时不显示 |
| | | this.setState({ |
| | |
| | | }) |
| | | } |
| | | |
| | | selectInput = (selectId, type) => { |
| | | selectInput = (selectId) => { |
| | | try { |
| | | let _form = document.getElementById('main-form-box') |
| | | let _inputs = _form.getElementsByTagName('input') |
| | |
| | | _inputs.forEach(input => { |
| | | if (!input || input.id !== selectId) return |
| | | |
| | | if (input.className === 'ant-select-search__field' && type !== 'init') { |
| | | if (input.className === 'ant-select-search__field') { |
| | | let div = input.parentNode |
| | | while (div && div.parentNode) { |
| | | div = div.parentNode |
| | |
| | | } else if (['select', 'multiselect', 'radio', 'checkbox', 'checkcard'].includes(item.type)) { |
| | | item.options = item.oriOptions |
| | | } |
| | | if (['select', 'link', 'radio'].includes(item.type) && item.initval && item.initval.indexOf('$first') > -1) { // 选中第一项 |
| | | if (['select', 'link', 'radio'].includes(item.type) && typeof(item.initval) === 'string' && item.initval.indexOf('$first') > -1) { // 选中第一项 |
| | | item.initval = item.options[0] ? item.options[0].Value : '' |
| | | values.push({field: item.field, value: item.initval}) |
| | | } |
| | |
| | | } else if (['select', 'multiselect', 'radio', 'checkbox', 'checkcard'].includes(item.type)) { |
| | | item.options = item.oriOptions |
| | | } |
| | | if (['select', 'link', 'radio'].includes(item.type) && item.initval && item.initval.indexOf('$first') > -1) { // 选中第一项 |
| | | if (['select', 'link', 'radio'].includes(item.type) && typeof(item.initval) === 'string' && item.initval.indexOf('$first') > -1) { // 选中第一项 |
| | | item.initval = item.options[0] ? item.options[0].Value : '' |
| | | values.push({field: item.field, value: item.initval}) |
| | | } |
| | |
| | | // 表单切换时,更新关联字段 |
| | | if (_field.linkSubField) { |
| | | let _data = _field.options.filter(op => op.Value === value)[0] |
| | | |
| | | |
| | | if (_data) { |
| | | _field.linkSubField.forEach(subfield => { |
| | | if (this.props.form.getFieldValue(subfield) !== undefined) { |
| | |
| | | |
| | | getFields() { |
| | | const { getFieldDecorator } = this.props.form |
| | | const { cols, formlist } = this.state |
| | | const { formlist } = this.state |
| | | |
| | | const fields = [] |
| | | let filtration = {} |
| | | |
| | | formlist.forEach((item, index) => { |
| | | if ((!item.field && item.type !== 'title' && item.type !== 'hint') || item.hidden === 'true' || item.type === 'funcvar') return |
| | | if ((!item.field && item.type !== 'split' && item.type !== 'hint') || item.hidden === 'true' || item.type === 'funcvar') return |
| | | if (item.supField) { // 多层表单控制 |
| | | let _supVal = this.props.form.getFieldValue(item.supField) |
| | | |
| | |
| | | } |
| | | } |
| | | |
| | | let _colspan = 24 / cols |
| | | if (item.entireLine === 'true') { |
| | | _colspan = 24 |
| | | } |
| | | |
| | | if (item.type === 'title') { |
| | | if (item.type === 'split') { |
| | | fields.push( |
| | | <Col span={24} key={index}> |
| | | <p>{item.label}</p> |
| | | <p className="mk-form-split-line">{item.label}</p> |
| | | </Col> |
| | | ) |
| | | } else if (item.type === 'hint') { |
| | | fields.push( |
| | | <Col span={24} key={index}> |
| | | <Form.Item colon={!!item.label} label={item.label || ' '} className="hint"> |
| | | <Col span={item.span || 24} key={index}> |
| | | <Form.Item |
| | | colon={!!item.label} |
| | | label={item.label} |
| | | labelCol={item.labelCol} |
| | | wrapperCol={item.wrapperCol} |
| | | className="hint" |
| | | > |
| | | <div className="message">{item.message}</div> |
| | | </Form.Item> |
| | | </Col> |
| | |
| | | } |
| | | |
| | | fields.push( |
| | | <Col span={_colspan} key={index}> |
| | | <Form.Item label={item.tooltip ? |
| | | <Tooltip placement="topLeft" title={item.tooltip}> |
| | | <Icon type="question-circle" /> |
| | | {item.label} |
| | | </Tooltip> : item.label |
| | | }> |
| | | <Col span={item.span || 24} key={index}> |
| | | <Form.Item |
| | | extra={item.extra || null} |
| | | labelCol={item.labelCol} |
| | | wrapperCol={item.wrapperCol} |
| | | label={item.tooltip ? |
| | | <Tooltip placement="topLeft" title={item.tooltip}> |
| | | <Icon type="question-circle" /> |
| | | {item.label} |
| | | </Tooltip> : item.label |
| | | } |
| | | > |
| | | {getFieldDecorator(item.field, { |
| | | initialValue: item.initval + '', |
| | | rules: [ |
| | |
| | | let precision = (item.decimal || item.decimal === 0) ? item.decimal : null |
| | | |
| | | fields.push( |
| | | <Col span={_colspan} key={index}> |
| | | <Form.Item label={item.tooltip ? |
| | | <Tooltip placement="topLeft" title={item.tooltip}> |
| | | <Icon type="question-circle" /> |
| | | {item.label} |
| | | </Tooltip> : item.label |
| | | }> |
| | | <Col span={item.span || 24} key={index}> |
| | | <Form.Item |
| | | extra={item.extra || null} |
| | | labelCol={item.labelCol} |
| | | wrapperCol={item.wrapperCol} |
| | | label={item.tooltip ? |
| | | <Tooltip placement="topLeft" title={item.tooltip}> |
| | | <Icon type="question-circle" /> |
| | | {item.label} |
| | | </Tooltip> : item.label |
| | | } |
| | | > |
| | | {getFieldDecorator(item.field, { |
| | | initialValue: item.initval, |
| | | rules: [ |
| | |
| | | ) |
| | | } else if (item.type === 'color') { // 颜色选择 |
| | | fields.push( |
| | | <Col span={_colspan} key={index}> |
| | | <Form.Item label={item.tooltip ? |
| | | <Tooltip placement="topLeft" title={item.tooltip}> |
| | | <Icon type="question-circle" /> |
| | | {item.label} |
| | | </Tooltip> : item.label |
| | | }> |
| | | <Col span={item.span || 24} key={index}> |
| | | <Form.Item |
| | | extra={item.extra || null} |
| | | labelCol={item.labelCol} |
| | | wrapperCol={item.wrapperCol} |
| | | label={item.tooltip ? |
| | | <Tooltip placement="topLeft" title={item.tooltip}> |
| | | <Icon type="question-circle" /> |
| | | {item.label} |
| | | </Tooltip> : item.label |
| | | } |
| | | > |
| | | {getFieldDecorator(item.field, { |
| | | initialValue: item.initval || 'transparent', |
| | | rules: [ |
| | |
| | | ) |
| | | } else if (item.type === 'checkcard') { // 多选框 |
| | | fields.push( |
| | | <Col span={24} key={index}> |
| | | <Form.Item label={item.tooltip ? |
| | | <Tooltip placement="topLeft" title={item.tooltip}> |
| | | <Icon type="question-circle" /> |
| | | {item.label} |
| | | </Tooltip> : item.label |
| | | } className="checkcard"> |
| | | <Col span={item.span || 24} key={index}> |
| | | <Form.Item |
| | | className="checkcard" |
| | | extra={item.extra || null} |
| | | labelCol={item.labelCol} |
| | | wrapperCol={item.wrapperCol} |
| | | label={item.tooltip ? |
| | | <Tooltip placement="topLeft" title={item.tooltip}> |
| | | <Icon type="question-circle" /> |
| | | {item.label} |
| | | </Tooltip> : item.label |
| | | } |
| | | > |
| | | {getFieldDecorator(item.field, { |
| | | initialValue: item.initval, |
| | | rules: [ |
| | |
| | | ) |
| | | } else if (item.type === 'switch') { // 多选框 |
| | | fields.push( |
| | | <Col span={_colspan} key={index}> |
| | | <Form.Item label={item.tooltip ? |
| | | <Tooltip placement="topLeft" title={item.tooltip}> |
| | | <Icon type="question-circle" /> |
| | | {item.label} |
| | | </Tooltip> : item.label |
| | | }> |
| | | <Col span={item.span || 24} key={index}> |
| | | <Form.Item |
| | | extra={item.extra || null} |
| | | labelCol={item.labelCol} |
| | | wrapperCol={item.wrapperCol} |
| | | label={item.tooltip ? |
| | | <Tooltip placement="topLeft" title={item.tooltip}> |
| | | <Icon type="question-circle" /> |
| | | {item.label} |
| | | </Tooltip> : item.label |
| | | } |
| | | > |
| | | {getFieldDecorator(item.field, { |
| | | initialValue: item.initval, |
| | | rules: [ |
| | |
| | | let _initval = item.initval ? item.initval.split(',').filter(Boolean) : [] |
| | | |
| | | fields.push( |
| | | <Col span={_colspan} key={index}> |
| | | <Form.Item label={item.tooltip ? |
| | | <Tooltip placement="topLeft" title={item.tooltip}> |
| | | <Icon type="question-circle" /> |
| | | {item.label} |
| | | </Tooltip> : item.label |
| | | }> |
| | | <Col span={item.span || 24} key={index}> |
| | | <Form.Item |
| | | extra={item.extra || null} |
| | | labelCol={item.labelCol} |
| | | wrapperCol={item.wrapperCol} |
| | | label={item.tooltip ? |
| | | <Tooltip placement="topLeft" title={item.tooltip}> |
| | | <Icon type="question-circle" /> |
| | | {item.label} |
| | | </Tooltip> : item.label |
| | | } |
| | | > |
| | | {getFieldDecorator(item.field, { |
| | | initialValue: _initval, |
| | | rules: [ |
| | |
| | | ) |
| | | } else if (item.type === 'radio') { // 单选框 |
| | | fields.push( |
| | | <Col span={_colspan} key={index}> |
| | | <Form.Item label={item.tooltip ? |
| | | <Tooltip placement="topLeft" title={item.tooltip}> |
| | | <Icon type="question-circle" /> |
| | | {item.label} |
| | | </Tooltip> : item.label |
| | | }> |
| | | <Col span={item.span || 24} key={index}> |
| | | <Form.Item |
| | | extra={item.extra || null} |
| | | labelCol={item.labelCol} |
| | | wrapperCol={item.wrapperCol} |
| | | label={item.tooltip ? |
| | | <Tooltip placement="topLeft" title={item.tooltip}> |
| | | <Icon type="question-circle" /> |
| | | {item.label} |
| | | </Tooltip> : item.label |
| | | } |
| | | > |
| | | {getFieldDecorator(item.field, { |
| | | initialValue: item.initval, |
| | | rules: [ |
| | |
| | | ) |
| | | } else if (item.type === 'select' || item.type === 'link') { // 下拉搜索 |
| | | fields.push( |
| | | <Col span={_colspan} key={index}> |
| | | <Form.Item label={item.tooltip ? |
| | | <Tooltip placement="topLeft" title={item.tooltip}> |
| | | <Icon type="question-circle" /> |
| | | {item.label} |
| | | </Tooltip> : item.label |
| | | }> |
| | | <Col span={item.span || 24} key={index}> |
| | | <Form.Item |
| | | extra={item.extra || null} |
| | | labelCol={item.labelCol} |
| | | wrapperCol={item.wrapperCol} |
| | | label={item.tooltip ? |
| | | <Tooltip placement="topLeft" title={item.tooltip}> |
| | | <Icon type="question-circle" /> |
| | | {item.label} |
| | | </Tooltip> : item.label |
| | | } |
| | | > |
| | | {getFieldDecorator(item.field, { |
| | | initialValue: item.initval, |
| | | rules: [ |
| | |
| | | } else if (item.type === 'multiselect') { // 多选 |
| | | let _initval = item.initval ? item.initval.split(',').filter(Boolean) : [] |
| | | fields.push( |
| | | <Col span={_colspan} key={index}> |
| | | <Form.Item label={item.tooltip ? |
| | | <Tooltip placement="topLeft" title={item.tooltip}> |
| | | <Icon type="question-circle" /> |
| | | {item.label} |
| | | </Tooltip> : item.label |
| | | }> |
| | | <Col span={item.span || 24} key={index}> |
| | | <Form.Item |
| | | extra={item.extra || null} |
| | | labelCol={item.labelCol} |
| | | wrapperCol={item.wrapperCol} |
| | | label={item.tooltip ? |
| | | <Tooltip placement="topLeft" title={item.tooltip}> |
| | | <Icon type="question-circle" /> |
| | | {item.label} |
| | | </Tooltip> : item.label |
| | | } |
| | | > |
| | | {getFieldDecorator(item.field, { |
| | | initialValue: _initval, |
| | | rules: [ |
| | |
| | | ) |
| | | } else if (item.type === 'date') { // 时间搜索 |
| | | fields.push( |
| | | <Col span={_colspan} key={index}> |
| | | <Form.Item label={item.tooltip ? |
| | | <Tooltip placement="topLeft" title={item.tooltip}> |
| | | <Icon type="question-circle" /> |
| | | {item.label} |
| | | </Tooltip> : item.label |
| | | }> |
| | | <Col span={item.span || 24} key={index}> |
| | | <Form.Item |
| | | extra={item.extra || null} |
| | | labelCol={item.labelCol} |
| | | wrapperCol={item.wrapperCol} |
| | | label={item.tooltip ? |
| | | <Tooltip placement="topLeft" title={item.tooltip}> |
| | | <Icon type="question-circle" /> |
| | | {item.label} |
| | | </Tooltip> : item.label |
| | | } |
| | | > |
| | | {getFieldDecorator(item.field, { |
| | | initialValue: item.initval, |
| | | rules: [ |
| | |
| | | ) |
| | | } else if (item.type === 'datemonth') { |
| | | fields.push( |
| | | <Col span={_colspan} key={index}> |
| | | <Form.Item label={item.tooltip ? |
| | | <Tooltip placement="topLeft" title={item.tooltip}> |
| | | <Icon type="question-circle" /> |
| | | {item.label} |
| | | </Tooltip> : item.label |
| | | }> |
| | | <Col span={item.span || 24} key={index}> |
| | | <Form.Item |
| | | extra={item.extra || null} |
| | | labelCol={item.labelCol} |
| | | wrapperCol={item.wrapperCol} |
| | | label={item.tooltip ? |
| | | <Tooltip placement="topLeft" title={item.tooltip}> |
| | | <Icon type="question-circle" /> |
| | | {item.label} |
| | | </Tooltip> : item.label |
| | | } |
| | | > |
| | | {getFieldDecorator(item.field, { |
| | | initialValue: item.initval, |
| | | rules: [ |
| | |
| | | ) |
| | | } else if (item.type === 'datetime') { |
| | | fields.push( |
| | | <Col span={_colspan} key={index}> |
| | | <Form.Item label={item.tooltip ? |
| | | <Tooltip placement="topLeft" title={item.tooltip}> |
| | | <Icon type="question-circle" /> |
| | | {item.label} |
| | | </Tooltip> : item.label |
| | | }> |
| | | <Col span={item.span || 24} key={index}> |
| | | <Form.Item |
| | | extra={item.extra || null} |
| | | labelCol={item.labelCol} |
| | | wrapperCol={item.wrapperCol} |
| | | label={item.tooltip ? |
| | | <Tooltip placement="topLeft" title={item.tooltip}> |
| | | <Icon type="question-circle" /> |
| | | {item.label} |
| | | </Tooltip> : item.label |
| | | } |
| | | > |
| | | {getFieldDecorator(item.field, { |
| | | initialValue: item.initval, |
| | | rules: [ |
| | |
| | | } |
| | | |
| | | fields.push( |
| | | <Col span={_colspan} key={index}> |
| | | <Form.Item label={item.tooltip ? |
| | | <Tooltip placement="topLeft" title={item.tooltip}> |
| | | <Icon type="question-circle" /> |
| | | {item.label} |
| | | </Tooltip> : item.label |
| | | }> |
| | | <Col span={item.span || 24} key={index}> |
| | | <Form.Item |
| | | extra={item.extra || null} |
| | | labelCol={item.labelCol} |
| | | wrapperCol={item.wrapperCol} |
| | | label={item.tooltip ? |
| | | <Tooltip placement="topLeft" title={item.tooltip}> |
| | | <Icon type="question-circle" /> |
| | | {item.label} |
| | | </Tooltip> : item.label |
| | | } |
| | | > |
| | | {getFieldDecorator(item.field, { |
| | | initialValue: filelist, |
| | | rules: [ |
| | |
| | | ) |
| | | } else if (item.type === 'linkMain') { |
| | | fields.push( |
| | | <Col span={_colspan} key={index}> |
| | | <Form.Item label={item.tooltip ? |
| | | <Tooltip placement="topLeft" title={item.tooltip}> |
| | | <Icon type="question-circle" /> |
| | | {item.label} |
| | | </Tooltip> : item.label |
| | | }> |
| | | <Col span={item.span || 24} key={index}> |
| | | <Form.Item |
| | | extra={item.extra || null} |
| | | labelCol={item.labelCol} |
| | | wrapperCol={item.wrapperCol} |
| | | label={item.tooltip ? |
| | | <Tooltip placement="topLeft" title={item.tooltip}> |
| | | <Icon type="question-circle" /> |
| | | {item.label} |
| | | </Tooltip> : item.label |
| | | } |
| | | > |
| | | {getFieldDecorator(item.field, { |
| | | initialValue: item.initval, |
| | | rules: [ |
| | |
| | | }] |
| | | } |
| | | fields.push( |
| | | <Col span={24} key={index}> |
| | | <Form.Item label={item.tooltip ? |
| | | <Tooltip placement="topLeft" title={item.tooltip}> |
| | | <Icon type="question-circle" /> |
| | | {item.label} |
| | | </Tooltip> : item.label |
| | | }> |
| | | <Col span={item.span || 24} key={index}> |
| | | <Form.Item |
| | | extra={item.extra || null} |
| | | labelCol={item.labelCol} |
| | | wrapperCol={item.wrapperCol} |
| | | label={item.tooltip ? |
| | | <Tooltip placement="topLeft" title={item.tooltip}> |
| | | <Icon type="question-circle" /> |
| | | {item.label} |
| | | </Tooltip> : item.label |
| | | } |
| | | > |
| | | {getFieldDecorator(item.field, { |
| | | initialValue: item.initval, |
| | | rules: [ |
| | |
| | | let _max = item.fieldlength || 512 |
| | | |
| | | fields.push( |
| | | <Col span={24} key={index}> |
| | | <Form.Item label={item.hidelabel !== 'true' && item.tooltip ? |
| | | <Tooltip placement="topLeft" title={item.tooltip}> |
| | | <Icon type="question-circle" /> |
| | | {item.label} |
| | | </Tooltip> : (item.hidelabel !== 'true' ? item.label : '') |
| | | }> |
| | | <Col span={item.span || 24} key={index}> |
| | | <Form.Item |
| | | extra={item.extra || null} |
| | | labelCol={item.labelCol} |
| | | wrapperCol={item.wrapperCol} |
| | | label={item.hidelabel !== 'true' && item.tooltip ? |
| | | <Tooltip placement="topLeft" title={item.tooltip}> |
| | | <Icon type="question-circle" /> |
| | | {item.label} |
| | | </Tooltip> : (item.hidelabel !== 'true' ? item.label : '') |
| | | } |
| | | > |
| | | {getFieldDecorator(item.field, { |
| | | initialValue: item.initval || '', |
| | | rules: [ |
| | |
| | | } |
| | | |
| | | render() { |
| | | const { cols } = this.state |
| | | const formItemLayout = { |
| | | labelCol: { |
| | | xs: { span: 24 }, |
| | | sm: { span: 8 } |
| | | }, |
| | | wrapperCol: { |
| | | xs: { span: 24 }, |
| | | sm: { span: 16 } |
| | | } |
| | | const { action } = this.props |
| | | |
| | | let _align = 'left_right' |
| | | if (action.setting && action.setting.align) { |
| | | _align = action.setting.align |
| | | } |
| | | |
| | | return ( |
| | | <Form {...formItemLayout} className="ant-advanced-search-form main-form-field" id="main-form-box"> |
| | | <Row className={'cols' + cols} gutter={24}>{this.getFields()}</Row> |
| | | <Form className={'main-form-field ' + _align} id="main-form-box"> |
| | | <Row gutter={24}>{this.getFields()}</Row> |
| | | </Form> |
| | | ) |
| | | } |
src/tabviews/zshare/mutilform/index.scss
src/tabviews/zshare/normalTable/index.jsx
src/tabviews/zshare/normalTable/index.scss
src/tabviews/zshare/settingcomponent/editTable/index.jsx
src/tabviews/zshare/topSearch/index.jsx
src/templates/calendarconfig/calcomponent/index.jsx
src/templates/calendarconfig/index.jsx
src/templates/calendarconfig/source.jsx
src/templates/calendarconfig/tabcomponent/index.jsx
src/templates/comtableconfig/index.jsx
src/templates/comtableconfig/source.jsx
src/templates/formtabconfig/index.jsx
src/templates/formtabconfig/source.jsx
src/templates/menuconfig/editfirstmenu/index.jsx
src/templates/menuconfig/editfirstmenu/index.scss
src/templates/menuconfig/editsecmenu/index.jsx
src/templates/menuconfig/editsecmenu/index.scss
src/templates/menuconfig/editthdmenu/index.jsx
src/templates/menuconfig/editthdmenu/index.scss
src/templates/menuconfig/editthdmenu/menuform/index.jsx
src/templates/menuconfig/menuelement/card.jsx
src/templates/modalconfig/checkCard/index.jsx
src/templates/modalconfig/dragelement/card.jsx
src/templates/modalconfig/dragelement/index.jsx
src/templates/modalconfig/dragelement/index.scss
src/templates/modalconfig/groupform/index.jsx (deleted)
src/templates/modalconfig/index.jsx
src/templates/modalconfig/index.scss
src/templates/modalconfig/settingform/index.jsx
src/templates/modalconfig/source.jsx
src/templates/sharecomponent/actioncomponent/actionform/index.jsx
src/templates/sharecomponent/actioncomponent/index.jsx
src/templates/sharecomponent/actioncomponent/index.scss
src/templates/sharecomponent/actioncomponent/verifyexcelin/customscript/index.jsx
src/templates/sharecomponent/actioncomponent/verifyexcelin/index.jsx
src/templates/sharecomponent/actioncomponent/verifyexcelout/index.jsx
src/templates/sharecomponent/cardcomponent/index.jsx
src/templates/sharecomponent/chartcomponent/index.jsx
src/templates/sharecomponent/chartgroupcomponent/index.jsx
src/templates/sharecomponent/columncomponent/columnform/index.jsx
src/templates/sharecomponent/columncomponent/columnform/index.scss
src/templates/sharecomponent/columncomponent/index.jsx
src/templates/sharecomponent/columncomponent/markcolumn/markform/index.jsx
src/templates/sharecomponent/fieldscomponent/index.jsx
src/templates/sharecomponent/searchcomponent/index.jsx
src/templates/sharecomponent/settingcalcomponent/index.jsx
src/templates/sharecomponent/settingcalcomponent/verifycard/index.jsx
src/templates/sharecomponent/settingcalcomponent/verifycard/settingform/index.scss
src/templates/sharecomponent/settingcalcomponent/verifycard/utils.jsx
src/templates/sharecomponent/settingcomponent/index.jsx
src/templates/sharecomponent/settingcomponent/settingform/datasource/index.jsx
src/templates/sharecomponent/settingcomponent/settingform/index.jsx
src/templates/sharecomponent/settingcomponent/settingform/simplescript/index.jsx
src/templates/sharecomponent/settingcomponent/settingform/utils.jsx
src/templates/sharecomponent/tablecomponent/index.jsx
src/templates/sharecomponent/tabscomponent/index.jsx
src/templates/sharecomponent/treesettingcomponent/index.jsx
src/templates/sharecomponent/treesettingcomponent/settingform/datasource/index.jsx
src/templates/sharecomponent/treesettingcomponent/settingform/index.jsx
src/templates/sharecomponent/treesettingcomponent/settingform/utils.jsx
src/templates/subtableconfig/index.jsx
src/templates/subtableconfig/source.jsx
src/templates/treepageconfig/index.jsx
src/templates/treepageconfig/source.jsx
src/templates/zshare/createinterface/index.jsx
src/templates/zshare/customscript/index.jsx
src/templates/zshare/editTable/index.jsx
src/templates/zshare/editcomponent/index.jsx
src/templates/zshare/formconfig.jsx
src/templates/zshare/modalform/index.jsx
src/templates/zshare/verifycard/callbackcustomscript/index.jsx
src/templates/zshare/verifycard/customscript/index.jsx
src/templates/zshare/verifycard/index.jsx
src/utils/devutils.js (deleted)
src/utils/utils-custom.js
src/utils/utils-datamanage.js
src/utils/utils-update.js
src/utils/utils.js
src/views/appmanage/index.jsx
src/views/appmanage/index.scss
src/views/appmanage/mutilform/index.jsx
src/views/appmanage/mutilform/index.scss
src/views/appmanage/submutilform/index.jsx
src/views/appmanage/submutilform/index.scss
src/views/billprint/index.jsx
src/views/design/header/index.jsx
src/views/design/header/index.scss
src/views/design/index.jsx
src/views/design/index.scss
src/views/design/sidemenu/config.jsx
src/views/design/sidemenu/index.jsx
src/views/design/sidemenu/index.scss
src/views/login/index.jsx
src/views/login/logincloudform.jsx
src/views/login/loginform.jsx
src/views/main/index.jsx
src/views/menudesign/index.jsx
src/views/menudesign/menuform/index.jsx
src/views/menudesign/menuform/index.scss
src/views/mobdesign/index.jsx
src/views/mobdesign/index.scss
src/views/mobdesign/menuform/index.jsx
src/views/mobdesign/menuform/index.scss
src/views/mobmanage/index.jsx (deleted)
src/views/mobmanage/index.scss (deleted)
src/views/pcdesign/index.jsx
src/views/pcdesign/index.scss
src/views/pcdesign/menuform/index.jsx
src/views/pcdesign/menuform/index.scss
src/views/sso/index.jsx |