Merge branch 'master' into positec
| | |
| | | "tslib": "^1.10.0" |
| | | } |
| | | }, |
| | | "@antv/algorithm": { |
| | | "version": "0.1.23", |
| | | "resolved": "https://registry.npmjs.org/@antv/algorithm/-/algorithm-0.1.23.tgz", |
| | | "integrity": "sha512-ncAfXwpO9angkGlZ/4LYsFk+T2hvQI6A+mEEGMslj8wF7ddPdtZ+DK3KFbhfJvQ4iz9Z44sJfdJ/fybwt0g0kA==", |
| | | "requires": { |
| | | "@antv/util": "^2.0.13", |
| | | "tslib": "^2.0.0" |
| | | }, |
| | | "dependencies": { |
| | | "tslib": { |
| | | "version": "2.4.0", |
| | | "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", |
| | | "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" |
| | | } |
| | | } |
| | | }, |
| | | "@antv/attr": { |
| | | "version": "0.3.2", |
| | | "resolved": "https://registry.npmjs.org/@antv/attr/-/attr-0.3.2.tgz", |
| | |
| | | } |
| | | } |
| | | }, |
| | | "@antv/g-webgpu": { |
| | | "version": "0.5.5", |
| | | "resolved": "https://registry.npmjs.org/@antv/g-webgpu/-/g-webgpu-0.5.5.tgz", |
| | | "integrity": "sha512-TxtBniINFq1jFGEPo46xjJfrbJbUqkFd5wmsRs3tcg/7J7xoldOP1kEadpI3AJG9knMYdE92VpILw1VPd6DgzQ==", |
| | | "requires": { |
| | | "@antv/g-webgpu-core": "^0.5.5", |
| | | "@antv/g-webgpu-engine": "^0.5.5", |
| | | "@webgpu/types": "^0.0.31", |
| | | "gl-matrix": "^3.1.0", |
| | | "gl-vec2": "^1.3.0", |
| | | "hammerjs": "^2.0.8", |
| | | "inversify": "^5.0.1", |
| | | "inversify-inject-decorators": "^3.1.0", |
| | | "polyline-miter-util": "^1.0.1", |
| | | "polyline-normals": "^2.0.2", |
| | | "probe.gl": "^3.1.1", |
| | | "reflect-metadata": "^0.1.13" |
| | | } |
| | | }, |
| | | "@antv/g-webgpu-core": { |
| | | "version": "0.5.6", |
| | | "resolved": "https://registry.npmjs.org/@antv/g-webgpu-core/-/g-webgpu-core-0.5.6.tgz", |
| | | "integrity": "sha512-DPiH3GkAUiT0Q+LAKeImpI+IOQ/gP2w6HstYKivpFIpBPIvZ/9equM3icVrn1iDfDkZANVXQ1PppcO3xBv1ZTw==", |
| | | "requires": { |
| | | "eventemitter3": "^4.0.0", |
| | | "gl-matrix": "^3.1.0", |
| | | "inversify": "^5.0.1", |
| | | "inversify-inject-decorators": "^3.1.0", |
| | | "probe.gl": "^3.1.1", |
| | | "reflect-metadata": "^0.1.13" |
| | | } |
| | | }, |
| | | "@antv/g-webgpu-engine": { |
| | | "version": "0.5.6", |
| | | "resolved": "https://registry.npmjs.org/@antv/g-webgpu-engine/-/g-webgpu-engine-0.5.6.tgz", |
| | | "integrity": "sha512-D311qYUefdEFwLayutIHqucrAY3cAGH3BdnXS37nq+0nsglrHcNP0Ab1YTinn9RihLoY3yXFTLzrYkJHJbZXDg==", |
| | | "requires": { |
| | | "@antv/g-webgpu-core": "^0.5.6", |
| | | "@webgpu/glslang": "^0.0.15", |
| | | "@webgpu/types": "^0.0.31", |
| | | "gl-matrix": "^3.1.0", |
| | | "hammerjs": "^2.0.8", |
| | | "inversify": "^5.0.1", |
| | | "inversify-inject-decorators": "^3.1.0", |
| | | "probe.gl": "^3.1.1", |
| | | "reflect-metadata": "^0.1.13", |
| | | "regl": "^1.3.11" |
| | | } |
| | | }, |
| | | "@antv/g2": { |
| | | "version": "4.1.34", |
| | | "resolved": "https://registry.npmjs.org/@antv/g2/-/g2-4.1.34.tgz", |
| | |
| | | } |
| | | } |
| | | }, |
| | | "@antv/g6": { |
| | | "version": "4.6.4", |
| | | "resolved": "https://registry.npmjs.org/@antv/g6/-/g6-4.6.4.tgz", |
| | | "integrity": "sha512-8xU96NISJ7G3Gwo6m1BTtqzfBeRd23BWcLDIpwX4v1KoE3NMHZlJkUaNvnKsoeoEoLNCDYBvTfBfEwV4C5gWfw==", |
| | | "requires": { |
| | | "@antv/g6-pc": "0.6.4" |
| | | } |
| | | }, |
| | | "@antv/g6-core": { |
| | | "version": "0.6.4", |
| | | "resolved": "https://registry.npmjs.org/@antv/g6-core/-/g6-core-0.6.4.tgz", |
| | | "integrity": "sha512-8JYIZME7zaQJImlPOatmlTe/tKPxRaq8/wV2f61/7mfKON3LF9kEVvTrpJexMnXoCBuM+puxx3DbiPb64gL4LQ==", |
| | | "requires": { |
| | | "@antv/algorithm": "^0.1.8", |
| | | "@antv/dom-util": "^2.0.1", |
| | | "@antv/event-emitter": "~0.1.0", |
| | | "@antv/g-base": "^0.5.1", |
| | | "@antv/g-math": "^0.1.1", |
| | | "@antv/matrix-util": "^3.1.0-beta.3", |
| | | "@antv/path-util": "^2.0.3", |
| | | "@antv/util": "~2.0.5", |
| | | "ml-matrix": "^6.5.0", |
| | | "tslib": "^2.1.0" |
| | | }, |
| | | "dependencies": { |
| | | "tslib": { |
| | | "version": "2.4.0", |
| | | "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", |
| | | "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" |
| | | } |
| | | } |
| | | }, |
| | | "@antv/g6-element": { |
| | | "version": "0.6.4", |
| | | "resolved": "https://registry.npmjs.org/@antv/g6-element/-/g6-element-0.6.4.tgz", |
| | | "integrity": "sha512-9wKogi6LnA4IoiVEWv8HmvHgHOXzbT73jDi4QrdSWjrttu7cyR2wQeKRYDp2lL2OPkHzzuNcI+ULQxbLKl3Oqg==", |
| | | "requires": { |
| | | "@antv/g-base": "^0.5.1", |
| | | "@antv/g6-core": "0.6.4", |
| | | "@antv/util": "~2.0.5" |
| | | } |
| | | }, |
| | | "@antv/g6-pc": { |
| | | "version": "0.6.4", |
| | | "resolved": "https://registry.npmjs.org/@antv/g6-pc/-/g6-pc-0.6.4.tgz", |
| | | "integrity": "sha512-bEQ3pqHzkqDvk2aWRghj9cB73qXx0n4NRJFmL4cSJnB1SQyk7akfBHgLBzw5aqsYviL9WK7VR6uCCZRPK3PoXA==", |
| | | "requires": { |
| | | "@ant-design/colors": "^4.0.5", |
| | | "@antv/algorithm": "^0.1.8", |
| | | "@antv/dom-util": "^2.0.1", |
| | | "@antv/event-emitter": "~0.1.0", |
| | | "@antv/g-base": "^0.5.1", |
| | | "@antv/g-canvas": "^0.5.2", |
| | | "@antv/g-math": "^0.1.1", |
| | | "@antv/g-svg": "^0.5.1", |
| | | "@antv/g6-core": "0.6.4", |
| | | "@antv/g6-element": "0.6.4", |
| | | "@antv/g6-plugin": "0.6.4", |
| | | "@antv/hierarchy": "^0.6.7", |
| | | "@antv/layout": "^0.2.1", |
| | | "@antv/matrix-util": "^3.1.0-beta.3", |
| | | "@antv/path-util": "^2.0.3", |
| | | "@antv/util": "~2.0.5", |
| | | "color": "^3.1.3", |
| | | "d3-force": "^2.0.1", |
| | | "dagre": "^0.8.5", |
| | | "insert-css": "^2.0.0", |
| | | "ml-matrix": "^6.5.0" |
| | | }, |
| | | "dependencies": { |
| | | "@ant-design/colors": { |
| | | "version": "4.0.5", |
| | | "resolved": "https://registry.npmjs.org/@ant-design/colors/-/colors-4.0.5.tgz", |
| | | "integrity": "sha512-3mnuX2prnWOWvpFTS2WH2LoouWlOgtnIpc6IarWN6GOzzLF8dW/U8UctuvIPhoboETehZfJ61XP+CGakBEPJ3Q==", |
| | | "requires": { |
| | | "tinycolor2": "^1.4.1" |
| | | } |
| | | }, |
| | | "@antv/hierarchy": { |
| | | "version": "0.6.8", |
| | | "resolved": "https://registry.npmjs.org/@antv/hierarchy/-/hierarchy-0.6.8.tgz", |
| | | "integrity": "sha512-wVzUl+pxny5gyGJ2mkWx8IiEypX6bnMHgr/NILgbxY6shoy0Vf4FhZpI3CY8Ez7bQT6js8fMkB2NymPW7d7i8A==", |
| | | "requires": { |
| | | "@antv/util": "^2.0.7" |
| | | } |
| | | }, |
| | | "color": { |
| | | "version": "3.2.1", |
| | | "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", |
| | | "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", |
| | | "requires": { |
| | | "color-convert": "^1.9.3", |
| | | "color-string": "^1.6.0" |
| | | } |
| | | }, |
| | | "color-string": { |
| | | "version": "1.9.1", |
| | | "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", |
| | | "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", |
| | | "requires": { |
| | | "color-name": "^1.0.0", |
| | | "simple-swizzle": "^0.2.2" |
| | | } |
| | | } |
| | | } |
| | | }, |
| | | "@antv/g6-plugin": { |
| | | "version": "0.6.4", |
| | | "resolved": "https://registry.npmjs.org/@antv/g6-plugin/-/g6-plugin-0.6.4.tgz", |
| | | "integrity": "sha512-eStD6j3nB54owXdYcA6/vxVCxJfBiMUfc33p4cKnRJnomSvEHYG/7i21SbyzMQQq7dRc0RDIPubYVwSilKzLCA==", |
| | | "requires": { |
| | | "@antv/dom-util": "^2.0.2", |
| | | "@antv/g-base": "^0.5.1", |
| | | "@antv/g-canvas": "^0.5.2", |
| | | "@antv/g-svg": "^0.5.2", |
| | | "@antv/g6-core": "0.6.4", |
| | | "@antv/matrix-util": "^3.1.0-beta.3", |
| | | "@antv/scale": "^0.3.4", |
| | | "@antv/util": "^2.0.9", |
| | | "insert-css": "^2.0.0" |
| | | } |
| | | }, |
| | | "@antv/graphlib": { |
| | | "version": "1.2.0", |
| | | "resolved": "https://registry.npmjs.org/@antv/graphlib/-/graphlib-1.2.0.tgz", |
| | | "integrity": "sha512-hhJOMThec51nU4Fe5p/viLlNIL71uDEgYFzKPajWjr2715SFG1HAgiP6AVylIeqBcAZ04u3Lw7usjl/TuI5RuQ==" |
| | | }, |
| | | "@antv/hierarchy": { |
| | | "version": "0.6.3", |
| | | "resolved": "https://registry.npmjs.org/@antv/hierarchy/-/hierarchy-0.6.3.tgz", |
| | | "integrity": "sha512-91YZUiZFXK8zp2nC2C+4FEc1LDIPZ5Q4YQbzMnKhH+7nei4QCfIdXPrPh0EKRws78CVt2hxR5gHD7zq6UlokAQ==", |
| | | "requires": { |
| | | "@antv/util": "^2.0.7" |
| | | } |
| | | }, |
| | | "@antv/layout": { |
| | | "version": "0.2.2", |
| | | "resolved": "https://registry.npmjs.org/@antv/layout/-/layout-0.2.2.tgz", |
| | | "integrity": "sha512-J2qRZwhA6NbR3gPrbw8Vw+6TpXtMmpW86q8LnwtCnNvdRNQQ7wSfvWAiphtFRfHqwL9ky44J51v4ysCENgTGDQ==", |
| | | "requires": { |
| | | "@antv/g-webgpu": "0.5.5", |
| | | "@antv/graphlib": "^1.0.0", |
| | | "d3-force": "^2.0.1", |
| | | "dagre-compound": "^0.0.11", |
| | | "ml-matrix": "^6.5.0" |
| | | } |
| | | }, |
| | | "@antv/matrix-util": { |
| | |
| | | "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz", |
| | | "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==" |
| | | }, |
| | | "@probe.gl/env": { |
| | | "version": "3.5.0", |
| | | "resolved": "https://registry.npmjs.org/@probe.gl/env/-/env-3.5.0.tgz", |
| | | "integrity": "sha512-YdlpZZshhyYxvWDBmZ5RIW2pTR14Pw4p9czMlt/v7F6HbFzWfAdmH7q6xVwFRYxUpQLwhWensWyv4aFysiWl4g==", |
| | | "requires": { |
| | | "@babel/runtime": "^7.0.0" |
| | | } |
| | | }, |
| | | "@probe.gl/log": { |
| | | "version": "3.5.0", |
| | | "resolved": "https://registry.npmjs.org/@probe.gl/log/-/log-3.5.0.tgz", |
| | | "integrity": "sha512-nW/qz2X1xY08WU/TsmJP6/6IPNcaY5fS/vLjpC4ahJuE2Mezga4hGM/R2X5JWE/nkPc+BsC5GnAnD13rwAxS7g==", |
| | | "requires": { |
| | | "@babel/runtime": "^7.0.0", |
| | | "@probe.gl/env": "3.5.0" |
| | | } |
| | | }, |
| | | "@probe.gl/stats": { |
| | | "version": "3.5.0", |
| | | "resolved": "https://registry.npmjs.org/@probe.gl/stats/-/stats-3.5.0.tgz", |
| | | "integrity": "sha512-IH2M+F3c8HR1DTroBARePUFG7wIewumtKA0UFqx51Z7S4hKrD60wFbpMmg0AcF4FvHAXMBoC+kYi1UKW9XbAOw==", |
| | | "requires": { |
| | | "@babel/runtime": "^7.0.0" |
| | | } |
| | | }, |
| | | "@react-native-community/cli-debugger-ui": { |
| | | "version": "4.9.0", |
| | | "resolved": "https://registry.npmjs.org/@react-native-community/cli-debugger-ui/-/cli-debugger-ui-4.9.0.tgz", |
| | |
| | | "@webassemblyjs/wast-parser": "1.8.5", |
| | | "@xtuc/long": "4.2.2" |
| | | } |
| | | }, |
| | | "@webgpu/glslang": { |
| | | "version": "0.0.15", |
| | | "resolved": "https://registry.npmjs.org/@webgpu/glslang/-/glslang-0.0.15.tgz", |
| | | "integrity": "sha512-niT+Prh3Aff8Uf1MVBVUsaNjFj9rJAKDXuoHIKiQbB+6IUP/3J3JIhBNyZ7lDhytvXxw6ppgnwKZdDJ08UMj4Q==" |
| | | }, |
| | | "@webgpu/types": { |
| | | "version": "0.0.31", |
| | | "resolved": "https://registry.npmjs.org/@webgpu/types/-/types-0.0.31.tgz", |
| | | "integrity": "sha512-cvvCMSZBT4VsRNtt0lI6XQqvOIIWw6+NRUtnPUMDVDgsI4pCZColz3qzF5QcP9wIYOHEc3jssIBse8UWONKhlQ==" |
| | | }, |
| | | "@xmldom/xmldom": { |
| | | "version": "0.7.5", |
| | |
| | | "randomfill": "^1.0.3" |
| | | } |
| | | }, |
| | | "crypto-js": { |
| | | "version": "4.1.1", |
| | | "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.1.1.tgz", |
| | | "integrity": "sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw==" |
| | | }, |
| | | "css": { |
| | | "version": "2.2.4", |
| | | "resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz", |
| | |
| | | } |
| | | } |
| | | }, |
| | | "d3-dispatch": { |
| | | "version": "2.0.0", |
| | | "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-2.0.0.tgz", |
| | | "integrity": "sha512-S/m2VsXI7gAti2pBoLClFFTMOO1HTtT0j99AuXLoGFKO6deHDdnv6ZGTxSTTUTgO1zVcv82fCOtDjYK4EECmWA==" |
| | | }, |
| | | "d3-dsv": { |
| | | "version": "1.2.0", |
| | | "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-1.2.0.tgz", |
| | |
| | | "version": "1.0.7", |
| | | "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-1.0.7.tgz", |
| | | "integrity": "sha512-lx14ZPYkhNx0s/2HX5sLFUI3mbasHjSSpwO/KaaNACweVwxUruKyWVcb293wMv1RqTPZyZ8kSZ2NogUZNcLOFQ==" |
| | | }, |
| | | "d3-force": { |
| | | "version": "2.1.1", |
| | | "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-2.1.1.tgz", |
| | | "integrity": "sha512-nAuHEzBqMvpFVMf9OX75d00OxvOXdxY+xECIXjW6Gv8BRrXu6gAWbv/9XKrvfJ5i5DCokDW7RYE50LRoK092ew==", |
| | | "requires": { |
| | | "d3-dispatch": "1 - 2", |
| | | "d3-quadtree": "1 - 2", |
| | | "d3-timer": "1 - 2" |
| | | } |
| | | }, |
| | | "d3-geo": { |
| | | "version": "1.6.4", |
| | |
| | | "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-1.0.9.tgz", |
| | | "integrity": "sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==" |
| | | }, |
| | | "d3-quadtree": { |
| | | "version": "2.0.0", |
| | | "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-2.0.0.tgz", |
| | | "integrity": "sha512-b0Ed2t1UUalJpc3qXzKi+cPGxeXRr4KU9YSlocN74aTzp6R/Ud43t79yLLqxHRWZfsvWXmbDWPpoENK1K539xw==" |
| | | }, |
| | | "d3-sankey": { |
| | | "version": "0.9.1", |
| | | "resolved": "https://registry.npmjs.org/d3-sankey/-/d3-sankey-0.9.1.tgz", |
| | |
| | | "graphlib": "^2.1.8", |
| | | "lodash": "^4.17.15" |
| | | } |
| | | }, |
| | | "dagre-compound": { |
| | | "version": "0.0.11", |
| | | "resolved": "https://registry.npmjs.org/dagre-compound/-/dagre-compound-0.0.11.tgz", |
| | | "integrity": "sha512-UrSgRP9LtOZCYb9e5doolZXpc7xayyszgyOs7uakTK4n4KsLegLVTRRtq01GpQd/iZjYw5fWMapx9ed+c80MAQ==" |
| | | }, |
| | | "damerau-levenshtein": { |
| | | "version": "1.0.5", |
| | |
| | | "resolved": "https://registry.npmjs.org/gl-matrix/-/gl-matrix-3.4.3.tgz", |
| | | "integrity": "sha512-wcCp8vu8FT22BnvKVPjXa/ICBWRq/zjFfdofZy1WSpQZpphblv12/bOQLBC1rMM7SGOFS9ltVmKOHil5+Ml7gA==" |
| | | }, |
| | | "gl-vec2": { |
| | | "version": "1.3.0", |
| | | "resolved": "https://registry.npmjs.org/gl-vec2/-/gl-vec2-1.3.0.tgz", |
| | | "integrity": "sha512-YiqaAuNsheWmUV0Sa8k94kBB0D6RWjwZztyO+trEYS8KzJ6OQB/4686gdrf59wld4hHFIvaxynO3nRxpk1Ij/A==" |
| | | }, |
| | | "glob": { |
| | | "version": "7.1.4", |
| | | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", |
| | |
| | | } |
| | | } |
| | | }, |
| | | "insert-css": { |
| | | "version": "2.0.0", |
| | | "resolved": "https://registry.npmjs.org/insert-css/-/insert-css-2.0.0.tgz", |
| | | "integrity": "sha1-610Ql7dUL0x56jBg067gfQU4gPQ=" |
| | | }, |
| | | "internal-ip": { |
| | | "version": "4.3.0", |
| | | "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-4.3.0.tgz", |
| | |
| | | "requires": { |
| | | "loose-envify": "^1.0.0" |
| | | } |
| | | }, |
| | | "inversify": { |
| | | "version": "5.1.1", |
| | | "resolved": "https://registry.npmjs.org/inversify/-/inversify-5.1.1.tgz", |
| | | "integrity": "sha512-j8grHGDzv1v+8T1sAQ+3boTCntFPfvxLCkNcxB1J8qA0lUN+fAlSyYd+RXKvaPRL4AGyPxViutBEJHNXOyUdFQ==" |
| | | }, |
| | | "inversify-inject-decorators": { |
| | | "version": "3.1.0", |
| | | "resolved": "https://registry.npmjs.org/inversify-inject-decorators/-/inversify-inject-decorators-3.1.0.tgz", |
| | | "integrity": "sha512-/seBlVp5bXrLQS3DpKEmlgeZL6C7Tf/QITd+IMQrbBBGuCbxb7k3hRAWu9XSreNpFzLgSboz3sClLSEmGwHphw==" |
| | | }, |
| | | "invert-kv": { |
| | | "version": "1.0.0", |
| | |
| | | "requires": { |
| | | "kind-of": "^3.0.2" |
| | | } |
| | | }, |
| | | "is-any-array": { |
| | | "version": "2.0.0", |
| | | "resolved": "https://registry.npmjs.org/is-any-array/-/is-any-array-2.0.0.tgz", |
| | | "integrity": "sha512-WdPV58rT3aOWXvvyuBydnCq4S2BM1Yz8shKxlEpk/6x+GX202XRvXOycEFtNgnHVLoc46hpexPFx8Pz1/sMS0w==" |
| | | }, |
| | | "is-arguments": { |
| | | "version": "1.0.4", |
| | |
| | | } |
| | | } |
| | | }, |
| | | "ml-array-max": { |
| | | "version": "1.2.4", |
| | | "resolved": "https://registry.npmjs.org/ml-array-max/-/ml-array-max-1.2.4.tgz", |
| | | "integrity": "sha512-BlEeg80jI0tW6WaPyGxf5Sa4sqvcyY6lbSn5Vcv44lp1I2GR6AWojfUvLnGTNsIXrZ8uqWmo8VcG1WpkI2ONMQ==", |
| | | "requires": { |
| | | "is-any-array": "^2.0.0" |
| | | } |
| | | }, |
| | | "ml-array-min": { |
| | | "version": "1.2.3", |
| | | "resolved": "https://registry.npmjs.org/ml-array-min/-/ml-array-min-1.2.3.tgz", |
| | | "integrity": "sha512-VcZ5f3VZ1iihtrGvgfh/q0XlMobG6GQ8FsNyQXD3T+IlstDv85g8kfV0xUG1QPRO/t21aukaJowDzMTc7j5V6Q==", |
| | | "requires": { |
| | | "is-any-array": "^2.0.0" |
| | | } |
| | | }, |
| | | "ml-array-rescale": { |
| | | "version": "1.3.7", |
| | | "resolved": "https://registry.npmjs.org/ml-array-rescale/-/ml-array-rescale-1.3.7.tgz", |
| | | "integrity": "sha512-48NGChTouvEo9KBctDfHC3udWnQKNKEWN0ziELvY3KG25GR5cA8K8wNVzracsqSW1QEkAXjTNx+ycgAv06/1mQ==", |
| | | "requires": { |
| | | "is-any-array": "^2.0.0", |
| | | "ml-array-max": "^1.2.4", |
| | | "ml-array-min": "^1.2.3" |
| | | } |
| | | }, |
| | | "ml-matrix": { |
| | | "version": "6.10.0", |
| | | "resolved": "https://registry.npmjs.org/ml-matrix/-/ml-matrix-6.10.0.tgz", |
| | | "integrity": "sha512-wU+jacx1dcP1QArV1/Kv49Ah6y2fq+BiQl2BnNVBC+hoCW7KgBZ4YZrowPopeoY164TB6Kes5wMeDjY8ODHYDg==", |
| | | "requires": { |
| | | "is-any-array": "^2.0.0", |
| | | "ml-array-rescale": "^1.3.7" |
| | | } |
| | | }, |
| | | "moment": { |
| | | "version": "2.24.0", |
| | | "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", |
| | |
| | | "parse-svg-path": "~0.1.1" |
| | | } |
| | | }, |
| | | "polyline-miter-util": { |
| | | "version": "1.0.1", |
| | | "resolved": "https://registry.npmjs.org/polyline-miter-util/-/polyline-miter-util-1.0.1.tgz", |
| | | "integrity": "sha1-tpPyOJ6g3tNqa89ezS7OS2kX2Vc=", |
| | | "requires": { |
| | | "gl-vec2": "^1.0.0" |
| | | } |
| | | }, |
| | | "polyline-normals": { |
| | | "version": "2.0.2", |
| | | "resolved": "https://registry.npmjs.org/polyline-normals/-/polyline-normals-2.0.2.tgz", |
| | | "integrity": "sha1-oXN+ddjA3MsaWR+csn8J7vS30TU=", |
| | | "requires": { |
| | | "polyline-miter-util": "^1.0.1" |
| | | } |
| | | }, |
| | | "portfinder": { |
| | | "version": "1.0.24", |
| | | "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.24.tgz", |
| | |
| | | "version": "0.1.8", |
| | | "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", |
| | | "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==" |
| | | }, |
| | | "probe.gl": { |
| | | "version": "3.5.0", |
| | | "resolved": "https://registry.npmjs.org/probe.gl/-/probe.gl-3.5.0.tgz", |
| | | "integrity": "sha512-KWj8u0PNytr/rVwcQFcN7O8SK7n/ITOsUZ91l4fSX95oHhKvVCI7eadrzFUzFRlXkFfBWpMWZXFHITsHHHUctw==", |
| | | "requires": { |
| | | "@babel/runtime": "^7.0.0", |
| | | "@probe.gl/env": "3.5.0", |
| | | "@probe.gl/log": "3.5.0", |
| | | "@probe.gl/stats": "3.5.0" |
| | | } |
| | | }, |
| | | "process": { |
| | | "version": "0.11.10", |
| | |
| | | "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.3.0.tgz", |
| | | "integrity": "sha512-km6dclyFnmcvxhAcrQV2AkZmPQjzPDjgVlQtR0EQjxZPyJ0BnMf3in1ryuR8A2qU0HldVRfxYXbFSKlI3N7Slw==" |
| | | }, |
| | | "reflect-metadata": { |
| | | "version": "0.1.13", |
| | | "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz", |
| | | "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==" |
| | | }, |
| | | "regenerate": { |
| | | "version": "1.4.0", |
| | | "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz", |
| | |
| | | } |
| | | } |
| | | }, |
| | | "regl": { |
| | | "version": "1.7.0", |
| | | "resolved": "https://registry.npmjs.org/regl/-/regl-1.7.0.tgz", |
| | | "integrity": "sha512-bEAtp/qrtKucxXSJkD4ebopFZYP0q1+3Vb2WECWv/T8yQEgKxDxJ7ztO285tAMaYZVR6mM1GgI6CCn8FROtL1w==" |
| | | }, |
| | | "regression": { |
| | | "version": "2.0.1", |
| | | "resolved": "https://registry.npmjs.org/regression/-/regression-2.0.1.tgz", |
| | |
| | | "@ant-design/icons": "^4.6.2", |
| | | "@antv/data-set": "^0.11.4", |
| | | "@antv/g2": "^4.1.34", |
| | | "@antv/g6": "^4.6.4", |
| | | "@antv/util": "^2.0.17", |
| | | "@babel/core": "7.5.5", |
| | | "@svgr/webpack": "4.3.2", |
| | |
| | | "camelcase": "^5.2.0", |
| | | "case-sensitive-paths-webpack-plugin": "2.2.0", |
| | | "codemirror": "^5.52.2", |
| | | "crypto-js": "^4.1.1", |
| | | "css-loader": "2.1.1", |
| | | "dotenv": "6.2.0", |
| | | "dotenv-expand": "4.2.0", |
| | |
| | | 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' |
| | | var url = window.location.href.split(/index\.html|#/ig)[0].replace(/\/$/ig, '') |
| | | var appPort = '/admin/index.html' |
| | | |
| | | if (config.defaultApp) { |
| | | 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#/index' |
| | | appPort = '/mob/index.html#/index' |
| | | } else { |
| | | appPort = 'pc/index.html#/index' |
| | | appPort = '/pc/index.html#/index' |
| | | } |
| | | } |
| | | window.location.replace(url + appPort) |
| | |
| | | return Promise.resolve(response.data) |
| | | } |
| | | }, (error) => { |
| | | if (error && error.response) { |
| | | notification.error({ |
| | | className: 'notification-custom-error', |
| | | bottom: 0, |
| | | message: '状态码-' + error.response.status + ',请联系管理员', |
| | | placement: 'bottomRight', |
| | | duration: 15 |
| | | }) |
| | | let response = error.response |
| | | |
| | | if (response) { |
| | | if (!response.data || !response.data.errors) { // 过滤旷视报错信息 |
| | | notification.error({ |
| | | className: 'notification-custom-error', |
| | | bottom: 0, |
| | | message: '状态码-' + response.status + ',请联系管理员', |
| | | placement: 'bottomRight', |
| | | duration: 15 |
| | | }) |
| | | } |
| | | return Promise.reject(response) |
| | | } else { |
| | | return Promise.reject() |
| | | } |
| | | return Promise.reject(error.response) |
| | | }) |
| | | |
| | | class Api { |
New file |
| | |
| | | import axios from 'axios' |
| | | import jsSHA from 'jssha' |
| | | |
| | | class W4kApi { |
| | | /** |
| | | * @description 鉴权挑战 |
| | | * @param {Object} param 查询及提交参数 |
| | | */ |
| | | login (ip, username = 'admin', password) { |
| | | return new Promise((resolve, reject) => { |
| | | let challurl = ip + '/api/auth/login/challenge?username=' + username |
| | | challurl = '/trans/redirect?rd=' + challurl + '&method=get' |
| | | |
| | | let loginurl = ip + '/api/auth/login' |
| | | loginurl = '/trans/redirect?rd=' + loginurl + '&method=post' |
| | | |
| | | axios({ |
| | | url: challurl, |
| | | method: 'post' // get |
| | | }).then(res => { |
| | | if (res.errors) { |
| | | reject(res) |
| | | } else { |
| | | const shaObj = new jsSHA('SHA-256', 'TEXT', { encoding: 'UTF8' }) |
| | | shaObj.update(password + res.salt + res.challenge) |
| | | const hash = shaObj.getHash('HEX') |
| | | |
| | | axios({ |
| | | url: loginurl, |
| | | method: 'post', |
| | | data: { |
| | | session_id: res.session_id, |
| | | username: username, |
| | | password: hash |
| | | } |
| | | }).then(result => { |
| | | resolve(result) |
| | | }, (err) => { |
| | | reject(err) |
| | | }) |
| | | } |
| | | }, (err) => { |
| | | reject(err) |
| | | }) |
| | | }) |
| | | } |
| | | |
| | | queryUsers (ip) { |
| | | let url = ip + '/api/persons/query' |
| | | url = '/trans/redirect?rd=' + url + '&method=post' |
| | | |
| | | return axios({ |
| | | url: url, |
| | | method: 'POST', |
| | | withCredentials: true, |
| | | headers: { 'Content-Type': 'application/json' }, |
| | | data: { |
| | | limit: 100, |
| | | offset: 0, |
| | | sort: 'desc', |
| | | query_id: '', |
| | | query_string: '' |
| | | } |
| | | }) |
| | | } |
| | | |
| | | addUsers (ip, data) { |
| | | return new Promise((resolve, reject) => { |
| | | let delurl = ip + '/api/persons/item/' + data.id |
| | | delurl = '/trans/redirect?rd=' + delurl + '&method=DELETE' |
| | | |
| | | let addurl = ip + '/api/persons/item' |
| | | addurl = '/trans/redirect?rd=' + addurl + '&method=post' |
| | | |
| | | if (data.deleted) { |
| | | delete data.deleted |
| | | axios({ |
| | | url: delurl, |
| | | method: 'post' // DELETE |
| | | }).then(res => { |
| | | if (res.errors) { |
| | | reject(res) |
| | | } else { |
| | | axios({ |
| | | url: addurl, |
| | | method: 'post', |
| | | data: data |
| | | }).then(result => { |
| | | resolve(result) |
| | | }, (err) => { |
| | | reject(err) |
| | | }) |
| | | } |
| | | }, (err) => { |
| | | reject(err) |
| | | }) |
| | | } else { |
| | | delete data.deleted |
| | | axios({ |
| | | url: addurl, |
| | | method: 'post', |
| | | data: data |
| | | }).then(result => { |
| | | resolve(result) |
| | | }, (err) => { |
| | | reject(err) |
| | | }) |
| | | } |
| | | }) |
| | | } |
| | | } |
| | | |
| | | export default new W4kApi() |
| | |
| | | color: inherit!important; |
| | | } |
| | | } |
| | | // .ant-table.ant-table-mini .ant-table-thead > tr > th { |
| | | // padding: 8px 4px; |
| | | // } |
| | | // .ant-table.ant-table-mini .ant-table-tbody > tr > td { |
| | | // padding: 4px 4px; |
| | | // } |
| | | .ant-table.ant-table-mini .ant-table-thead > tr > th { |
| | | padding: 8px 8px!important; |
| | | } |
| | | .ant-table.ant-table-mini .ant-table-tbody > tr > td { |
| | | padding: 2px 8px!important; |
| | | line-height: 1.5; |
| | | } |
| | | .mk-date-picker.minute { |
| | | .ant-calendar-time-picker-combobox { |
| | | .ant-calendar-time-picker-select { |
| | |
| | | let url = `${ssodomain}/doc/index.html#?appkey=${window.GLOB.appkey}&LoginUID=${sessionStorage.getItem('LoginUID')}` |
| | | window.open(url) |
| | | } else if (options.sysType === 'SSO' || options.sysType === 'cloud') { |
| | | window.open(`${window.location.href.replace(/\/index.html(.*)|\/#(.*)/ig, '')}/doc/index.html#?appkey=${window.GLOB.appkey}&LoginUID=${sessionStorage.getItem('LoginUID')}`) |
| | | window.open(`${window.location.href.replace(/\/admin(.*)|\/index.html(.*)|\/#(.*)/ig, '')}/doc/index.html#?appkey=${window.GLOB.appkey}&LoginUID=${sessionStorage.getItem('LoginUID')}`) |
| | | } |
| | | } |
| | | |
| | |
| | | </Popover> |
| | | {card.wrap.checkAll === 'show' ? <div className="check-all"><Checkbox>全选</Checkbox></div> : null} |
| | | <CardCellComponent cards={card} cardCell={card} elements={card.elements} updateElement={this.updateCard}/> |
| | | <div className="component-name"><div className="center">{card.name}</div></div> |
| | | </div> |
| | | ) |
| | | } |
| | |
| | | {hasProfile ? <ProfileOutlined className="profile" title="setting" onClick={() => profileCard(id)} /> : null} |
| | | </div> |
| | | } trigger="hover"> |
| | | <div ref={node => drag(drop(node))} className={'ant-col card-button-cell ant-col-' + card.width} onDoubleClick={(e) => {e.stopPropagation(); doubleClickCard(id)}}> |
| | | <div ref={node => drag(drop(node))} className={'ant-col card-button-cell ant-col-' + card.width + (card.hidden === 'true' ? ' mk-hidden' : '')} onDoubleClick={(e) => {e.stopPropagation(); doubleClickCard(id)}}> |
| | | <div style={{opacity: isDragging ? 0 : 1, ...card.wrapStyle}}> |
| | | {btnElement} |
| | | </div> |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { fromJS } from 'immutable' |
| | | import { Form, Row, Col, Input, Select, Radio, Tooltip, InputNumber } from 'antd' |
| | | import { Form, Row, Col, Input, Select, Radio, Tooltip, InputNumber, Cascader } from 'antd' |
| | | import { QuestionCircleOutlined } from '@ant-design/icons' |
| | | |
| | | import { formRule } from '@/utils/option.js' |
| | |
| | | |
| | | const cardTypeOptions = { |
| | | sequence: ['eleType', 'width'], |
| | | text: ['eleType', 'datatype', 'format', 'width', 'height', 'prefix', 'postfix', 'link', 'noValue', 'bgImage', 'fixStyle'], |
| | | text: ['eleType', 'datatype', 'format', 'width', 'height', 'prefix', 'postfix', 'link', 'anchors', 'noValue', 'bgImage', 'fixStyle'], |
| | | number: ['eleType', 'datatype', 'format', 'width', 'height', 'prefix', 'postfix', 'noValue', 'fixStyle'], |
| | | picture: ['eleType', 'datatype', 'width', 'lenWidRadio', 'maxWidth', 'link', 'noValue'], |
| | | video: ['eleType', 'datatype', 'width', 'aspectRatio', 'autoPlay', 'loop', 'noValue'], |
| | |
| | | } else if (item.type === 'number') { |
| | | fields.push( |
| | | <Col span={12} key={index}> |
| | | <Form.Item label={item.tooltip ? |
| | | <Form.Item help={item.help || null} label={item.tooltip ? |
| | | <Tooltip placement="topLeft" title={item.tooltip}> |
| | | <QuestionCircleOutlined className="mk-form-tip" /> |
| | | {item.label} |
| | |
| | | </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}> |
| | | <QuestionCircleOutlined className="mk-form-tip" /> |
| | | {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 |
| | |
| | | * @param {*} card |
| | | * @param {*} type |
| | | */ |
| | | export function getCardCellForm (card, type, subtype, cardCell) { |
| | | export function getCardCellForm (card, type, subtype, cardCell, anchors) { |
| | | let _options = [ |
| | | { value: 'text', text: '文本'}, |
| | | { value: 'number', text: '数值'}, |
| | |
| | | options: [] |
| | | }, |
| | | { |
| | | type: 'cascader', |
| | | key: 'anchors', |
| | | label: '跳转锚点', |
| | | initVal: card.anchors || [], |
| | | required: false, |
| | | options: anchors |
| | | }, |
| | | { |
| | | type: 'number', |
| | | key: 'barHeight', |
| | | min: 5, |
| | |
| | | label: '最大宽度', |
| | | initVal: card.maxWidth || '', |
| | | tooltip: '图片宽度的最大值。', |
| | | help: '注:此值存在时,左右外边距为0居中显示。', |
| | | required: false, |
| | | }, |
| | | { |
| | |
| | | initVal: card.link || '', |
| | | tooltip: '动态地址为绑定字段值。', |
| | | required: false, |
| | | // forbid: isApp, |
| | | options: [ |
| | | { value: '', text: '无' }, |
| | | { value: 'dynamic', text: '动态' }, |
| | |
| | | label: '链接类型', |
| | | initVal: card.linkType || 'other', |
| | | required: false, |
| | | // forbid: isApp, |
| | | options: [ |
| | | { value: 'tel', text: '电话' }, |
| | | { value: 'email', text: '邮箱' }, |
| | |
| | | type: 'number', |
| | | key: 'fixSize', |
| | | min: 10, |
| | | max: 100, |
| | | max: 300, |
| | | label: '字体大小', |
| | | initVal: card.fixSize || 14, |
| | | tooltip: '前缀、后缀的字体大小。', |
| | |
| | | import MKEmitter from '@/utils/events.js' |
| | | import MenuUtils from '@/utils/utils-custom.js' |
| | | import ElementForm from './elementform' |
| | | import CreateFunc from '@/templates/zshare/createfunc' |
| | | import DragElement from './dragaction' |
| | | import './index.scss' |
| | | |
| | |
| | | visible: false, // 模态框控制 |
| | | actvisible: false, // 按钮编辑模态框 |
| | | profVisible: false, // 验证信息编辑 |
| | | record: null |
| | | } |
| | | |
| | | /** |
| | |
| | | if (card.eleType === 'button') { |
| | | this.handleAction(card) |
| | | } else { |
| | | let anchors = MenuUtils.getAnchors(window.GLOB.customMenu.components, cards.uuid) || [] |
| | | |
| | | this.setState({ |
| | | visible: true, |
| | | card: card, |
| | | formlist: getCardCellForm(card, cards.type, cards.subtype, cardCell) |
| | | formlist: getCardCellForm(card, cards.type, cards.subtype, cardCell, anchors) |
| | | }) |
| | | } |
| | | } |
| | |
| | | } |
| | | |
| | | let modules = MenuUtils.getSubModules(window.GLOB.customMenu.components, cards.uuid) || [] |
| | | let anchors = MenuUtils.getAnchors(window.GLOB.customMenu.components, cards.uuid) || [] |
| | | |
| | | this.setState({ |
| | | actvisible: true, |
| | | card: card, |
| | | formlist: getActionForm(card, functip, cards, usefulFields, 'card', menulist, modules) |
| | | formlist: getActionForm(card, functip, cards, usefulFields, 'card', menulist, modules, anchors) |
| | | }) |
| | | } |
| | | |
| | |
| | | |
| | | render() { |
| | | const { cards, cardCell } = this.props |
| | | const { elements, visible, actvisible, profVisible, card, dict } = this.state |
| | | const { elements, visible, actvisible, profVisible, card, dict, record } = this.state |
| | | |
| | | return ( |
| | | <div className="model-menu-card-cell-list"> |
| | |
| | | maskClosable={false} |
| | | onCancel={this.editModalCancel} |
| | | footer={[ |
| | | record && record.intertype === 'inner' ? <CreateFunc key="create" dict={dict} ref="btnCreatFunc" trigger={this.creatFunc}/> : null, |
| | | <Button key="cancel" onClick={this.editModalCancel}>{dict['model.cancel']}</Button>, |
| | | <Button key="confirm" type="primary" onClick={this.handleActionSubmit}>{dict['model.confirm']}</Button> |
| | | ]} |
| | |
| | | formlist={this.state.formlist} |
| | | inputSubmit={this.handleActionSubmit} |
| | | setting={cards.setting} |
| | | updRecord={(record) => this.setState({record: fromJS(record).toJS()})} |
| | | wrappedComponentRef={(inst) => this.actionFormRef = inst} |
| | | /> |
| | | </Modal> |
| | |
| | | <div style={{clear: 'both'}}></div> |
| | | {card.wrap.pagestyle === 'page' && card.setting.laypage === 'true' && appType !== 'mob' ? <Pagination total={85} size="small" showTotal={total => `共 ${total} 条`} pageSize={20} defaultCurrent={1}/> : null} |
| | | {card.wrap.pagestyle === 'page' && card.setting.laypage === 'true' && appType === 'mob' ? <MobPagination /> : null} |
| | | <div className="component-name"><div className="center">{card.name}</div></div> |
| | | </div> |
| | | ) |
| | | } |
| | |
| | | <div className={(card.wrap.layout || 'grid') + '-layout float-' + (card.wrap.cardFloat || 'left')}> |
| | | {card.subcards.map(subcard => (<CardComponent key={subcard.uuid} cards={card} card={subcard} move={this.move} updateElement={this.updateCard} deleteElement={this.deleteCard}/>))} |
| | | </div> |
| | | <div className="component-name"><div className="center">{card.name}</div></div> |
| | | </div> |
| | | ) |
| | | } |
| | |
| | | </div> |
| | | {card.setting.laypage === 'true' && card.wrap.pagestyle !== 'slide' && appType !== 'mob' ? <Pagination size="small" total={50} /> : null} |
| | | {card.setting.laypage === 'true' && card.wrap.pagestyle !== 'slide' && appType === 'mob' ? <MobPagination /> : null} |
| | | <div className="component-name"><div className="center">{card.name}</div></div> |
| | | </div> |
| | | ) |
| | | } |
| | |
| | | <ToolOutlined/> |
| | | </Popover> |
| | | <CardSimpleComponent cards={card} card={card.subcards[0]} updateElement={this.updateCard} deleteElement={this.deleteCard}/> |
| | | <div className="component-name"><div className="center">{card.name}</div></div> |
| | | </div> |
| | | ) |
| | | } |
| | |
| | | {card.subcards.length > 0 ? <Carousel dotPosition={card.wrap.dotPosition || 'bottom'} effect={card.wrap.effect || 'scrollx'}> |
| | | {card.subcards.map((subcard) => (<CardSimpleComponent key={subcard.uuid} cards={card} card={subcard} move={this.move} updateElement={this.updateCard} deleteElement={this.deleteCard}/>))} |
| | | </Carousel> : null} |
| | | <div className="component-name"><div className="center">{card.name}</div></div> |
| | | </div> |
| | | ) |
| | | } |
| | |
| | | * @description 获取图表视图配置表单 |
| | | * @param {object} card // 图表对象 |
| | | */ |
| | | export function getBaseForm (card) { |
| | | export function getBaseForm (card, columns = []) { |
| | | let appType = sessionStorage.getItem('appType') |
| | | let roleList = sessionStorage.getItem('sysRoles') |
| | | if (roleList) { |
| | |
| | | } |
| | | } else { |
| | | roleList = [] |
| | | } |
| | | |
| | | let menulist = [] |
| | | |
| | | if (appType === 'pc') { |
| | | menulist = sessionStorage.getItem('appMenus') |
| | | if (menulist) { |
| | | try { |
| | | menulist = JSON.parse(menulist) |
| | | } catch (e) { |
| | | menulist = [] |
| | | } |
| | | } else { |
| | | menulist = [] |
| | | } |
| | | } else if (appType === '') { |
| | | menulist = sessionStorage.getItem('fstMenuList') |
| | | if (menulist) { |
| | | try { |
| | | menulist = JSON.parse(menulist) |
| | | } catch (e) { |
| | | menulist = [] |
| | | } |
| | | } else { |
| | | menulist = [] |
| | | } |
| | | } |
| | | |
| | | return [ |
| | |
| | | options: roleList, |
| | | forbid: !!appType |
| | | }, |
| | | // { |
| | | // type: 'cascader', |
| | | // key: 'linkmenu', |
| | | // label: '关联菜单', |
| | | // initVal: card.linkmenu || [], |
| | | // tooltip: '在使用柱形图且未启用自定义设置时有效。', |
| | | // required: false, |
| | | // forbid: appType === 'pc' || appType === 'mob', |
| | | // options: menulist |
| | | // }, |
| | | // { |
| | | // type: 'select', |
| | | // key: 'linkmenu', |
| | | // label: '关联菜单', |
| | | // initVal: card.linkmenu || '', |
| | | // tooltip: '双击柱状图,会打开关联的菜单。', |
| | | // required: false, |
| | | // forbid: appType !== 'pc', |
| | | // options: menulist |
| | | // }, |
| | | // { |
| | | // type: 'radio', |
| | | // key: 'open', |
| | | // label: '打开方式', |
| | | // initVal: card.open || 'blank', |
| | | // required: false, |
| | | // forbid: appType !== 'pc', |
| | | // options: [ |
| | | // { value: 'blank', text: '新窗口' }, |
| | | // { value: 'self', text: '当前窗口' } |
| | | // ] |
| | | // } |
| | | { |
| | | type: 'radio', |
| | | key: 'click', |
| | | label: '点击事件', |
| | | initVal: card.click || '', |
| | | tooltip: '当绑定点击事件时,柱形图的切换功能将失效。', |
| | | required: false, |
| | | forbid: appType === 'mob' || card.chartType !== 'bar', |
| | | options: [ |
| | | {value: '', label: '无'}, |
| | | {value: 'menu', label: '菜单'}, |
| | | {value: 'menus', label: '菜单组'} |
| | | ] |
| | | }, |
| | | { |
| | | type: appType === '' ? 'cascader' : 'select', |
| | | key: 'menu', |
| | | label: '关联菜单', |
| | | initVal: card.menu || (appType === '' ? [] : ''), |
| | | tooltip: '在使用柱形图且未启用自定义设置时有效。', |
| | | required: true, |
| | | forbid: appType === 'mob' || card.chartType !== 'bar', |
| | | hidden: card.click !== 'menu', |
| | | options: menulist |
| | | }, |
| | | { |
| | | type: 'select', |
| | | key: 'menuType', |
| | | label: '菜单类型', |
| | | initVal: card.menuType || '', |
| | | required: true, |
| | | forbid: appType === 'mob' || card.chartType !== 'bar', |
| | | hidden: card.click !== 'menus', |
| | | options: columns, |
| | | }, |
| | | { |
| | | type: 'radio', |
| | | key: 'open', |
| | | label: '打开方式', |
| | | initVal: card.open || 'blank', |
| | | required: false, |
| | | options: [ |
| | | {value: 'blank', label: '新窗口'}, |
| | | {value: 'self', label: '当前窗口'}, |
| | | ], |
| | | forbid: appType !== 'pc' || card.chartType !== 'bar', |
| | | hidden: card.click !== 'menu' && card.click !== 'menus' |
| | | }, |
| | | { |
| | | type: 'radio', |
| | | key: 'joint', |
| | | label: '参数拼接', |
| | | initVal: card.joint || 'true', |
| | | required: false, |
| | | options: [ |
| | | {value: 'true', label: '是'}, |
| | | {value: 'false', label: '否'}, |
| | | ], |
| | | forbid: appType === 'mob' || card.chartType !== 'bar', |
| | | hidden: card.click !== 'menu' && card.click !== 'menus' |
| | | }, |
| | | { |
| | | type: 'table', |
| | | key: 'menus', |
| | | label: '菜单组', |
| | | initVal: card.menus || [], |
| | | required: true, |
| | | span: 24, |
| | | actions: ['view'], |
| | | forbid: appType === 'mob' || card.chartType !== 'bar', |
| | | hidden: card.click !== 'menus', |
| | | columns: [ |
| | | { |
| | | title: '标识', |
| | | dataIndex: 'sign', |
| | | inputType: 'input', |
| | | editable: true, |
| | | unique: true, |
| | | required: false, |
| | | width: '35%' |
| | | }, |
| | | { |
| | | title: '菜单', |
| | | dataIndex: 'menu', |
| | | inputType: !appType ? 'cascader' : 'select', |
| | | editable: true, |
| | | required: true, |
| | | extends: !appType ? 'Menu' : [{key: 'label', value: 'label'}], |
| | | width: '35%', |
| | | render: (text, record) => record.label, |
| | | options: menulist |
| | | } |
| | | ] |
| | | } |
| | | ] |
| | | } |
| | | |
| | |
| | | |
| | | if (card.chartType === 'line') { |
| | | shapes = [ |
| | | { field: 'smooth', label: 'smooth' }, |
| | | { field: 'line', label: 'line' }, |
| | | { field: 'dot', label: 'dot' }, |
| | | { field: 'dash', label: 'dash' }, |
| | | { field: 'hv', label: 'hv' }, |
| | | { field: 'vh', label: 'vh' }, |
| | | { field: 'hvh', label: 'hvh' }, |
| | | { field: 'vhv', label: 'vhv' } |
| | | { field: 'smooth', label: 'smooth(平滑线)' }, |
| | | { field: 'line', label: 'line(直线)' }, |
| | | { field: 'dot', label: 'dot(点状线)' }, |
| | | { field: 'dash', label: 'dash(虚线)' }, |
| | | { field: 'hv', label: 'hv(水平-垂直线)' }, |
| | | { field: 'vh', label: 'vh(垂直-水平线)' }, |
| | | { field: 'hvh', label: 'hvh(水平-垂直-水平线)' }, |
| | | { field: 'vhv', label: 'vhv(垂直-水平-垂直线)' } |
| | | ] |
| | | } else if (card.chartType === 'bar') { |
| | | shapes = [ |
| | | { field: 'rect', label: 'rect' }, |
| | | { field: 'hollow-rect', label: 'hollow-rect' }, |
| | | { field: 'line', label: 'line' }, |
| | | { field: 'tick', label: 'tick' }, |
| | | { field: 'funnel', label: 'funnel' }, |
| | | { field: 'pyramid', label: 'pyramid' } |
| | | { field: 'rect', label: 'rect(矩形)' }, |
| | | { field: 'hollow-rect', label: 'hollow-rect(空心矩形)' }, |
| | | { field: 'line', label: 'line(线条)' }, |
| | | { field: 'tick', label: 'tick(波动)' }, |
| | | // { field: 'funnel', label: 'funnel' }, |
| | | { field: 'pyramid', label: 'pyramid(角锥)' } |
| | | ] |
| | | } |
| | | |
| | |
| | | key: 'show', |
| | | label: '显示', |
| | | initVal: card.show || 'value', |
| | | tooltip: '当使用自定义设置时,可在显示(值/%)处单独设置显示类型。注:自定义为空时使用此处设置。', |
| | | required: false, |
| | | options: [{ |
| | | value: 'value', |
| | |
| | | }, { |
| | | type: labelOptions.length > 20 ? 'select' : 'radio', |
| | | key: 'label', |
| | | label: '标签', |
| | | label: '标注', |
| | | initVal: card.label || 'false', |
| | | tooltip: '图形节点处的数值。', |
| | | required: false, |
| | | options: labelOptions |
| | | }, { |
| | | type: 'radio', |
| | | key: 'labelColor', |
| | | label: '标签颜色', |
| | | label: '标注颜色', |
| | | initVal: card.labelColor || 'system', |
| | | tooltip: '使用系统色时,使用色系选项设置的系统颜色,使用自定义为颜色设置中定义的图形颜色。', |
| | | required: false, |
| | |
| | | } |
| | | }, |
| | | { |
| | | title: '显示', |
| | | title: '显示(值/%)', |
| | | dataIndex: 'show', |
| | | inputType: 'select', |
| | | editable: true, |
| | |
| | | datatype: config.plot.datatype || 'query', |
| | | fieldName: fieldName, |
| | | plot: fromJS(config.plot).toJS(), |
| | | baseFormlist: getBaseForm(config.plot), |
| | | baseFormlist: getBaseForm(config.plot, config.columns), |
| | | formlist: getOptionForm(config.plot, config.columns) |
| | | }) |
| | | } |
| | |
| | | this.baseRef.handleConfirm().then(res => { |
| | | let _plot = {...plot, ...res} |
| | | |
| | | if (res.click === 'menu') { |
| | | delete _plot.menus |
| | | } else if (res.click === 'menus') { |
| | | delete _plot.menu |
| | | } else { |
| | | delete _plot.menus |
| | | delete _plot.menu |
| | | } |
| | | |
| | | delete _plot.MenuID |
| | | delete _plot.MenuName |
| | | delete _plot.MenuNo |
| | | delete _plot.tabType |
| | | |
| | | if (_plot.click === 'menu' && sessionStorage.getItem('appType') === '' && _plot.menu) { |
| | | let list = null |
| | | try { |
| | | list = JSON.parse(sessionStorage.getItem('thdMenuList')) || [] |
| | | } catch (e) { |
| | | list = [] |
| | | } |
| | | |
| | | let id = _plot.menu[_plot.menu.length - 1] |
| | | |
| | | list.forEach(item => { |
| | | if (item.MenuID === id) { |
| | | _plot.MenuID = id |
| | | _plot.MenuName = item.MenuName |
| | | _plot.MenuNo = item.MenuNo |
| | | _plot.tabType = item.type |
| | | } |
| | | }) |
| | | } |
| | | |
| | | this.setState({ |
| | | plot: _plot, |
| | | visible: false |
| | |
| | | }) |
| | | } else if (view === 'base') { |
| | | this.baseRef.handleConfirm().then(res => { |
| | | let _plot = {...plot, ...res} |
| | | |
| | | if (res.click === 'menu') { |
| | | delete _plot.menus |
| | | } else if (res.click === 'menus') { |
| | | delete _plot.menu |
| | | } else { |
| | | delete _plot.menus |
| | | delete _plot.menu |
| | | } |
| | | |
| | | delete _plot.MenuID |
| | | delete _plot.MenuName |
| | | delete _plot.MenuNo |
| | | delete _plot.tabType |
| | | |
| | | if (_plot.click === 'menu' && sessionStorage.getItem('appType') === '' && _plot.menu) { |
| | | let list = null |
| | | try { |
| | | list = JSON.parse(sessionStorage.getItem('thdMenuList')) || [] |
| | | } catch (e) { |
| | | list = [] |
| | | } |
| | | |
| | | let id = _plot.menu[_plot.menu.length - 1] |
| | | |
| | | list.forEach(item => { |
| | | if (item.MenuID === id) { |
| | | _plot.MenuID = id |
| | | _plot.MenuName = item.MenuName |
| | | _plot.MenuNo = item.MenuNo |
| | | _plot.tabType = item.type |
| | | } |
| | | }) |
| | | } |
| | | |
| | | this.setState({ |
| | | plot: {...plot, ...res}, |
| | | plot: _plot, |
| | | view: tab |
| | | }) |
| | | }) |
| | |
| | | wrapClassName="popview-modal menu-chart-edit-modal" |
| | | title={config.type === 'bar' ? '柱状图编辑' : '折线图编辑'} |
| | | visible={visible} |
| | | width={950} |
| | | width={1000} |
| | | maskClosable={false} |
| | | onOk={this.onSubmit} |
| | | onCancel={() => { this.setState({ visible: false }) }} |
| | |
| | | position: relative; |
| | | z-index: 1; |
| | | } |
| | | .ant-table-column-title { |
| | | white-space: nowrap; |
| | | } |
| | | } |
| | | } |
| | | } |
| | |
| | | handleTabsChange = (parentId) => { |
| | | const { card } = this.state |
| | | |
| | | if (parentId === card.parentId) { |
| | | if (parentId === card.parentId || parentId === 'all') { |
| | | let _element = document.getElementById(card.uuid + 'canvas') |
| | | if (_element) { |
| | | _element.innerHTML = '' |
| | |
| | | config={card} |
| | | updateaction={this.updateComponent} |
| | | /> : null} |
| | | <div className="component-name"><div className="center">{card.name}</div></div> |
| | | </div> |
| | | ) |
| | | } |
| | |
| | | label: '字体大小', |
| | | initVal: card.fontSize || 28, |
| | | min: 12, |
| | | max: 200, |
| | | max: 300, |
| | | decimal: 0, |
| | | required: true |
| | | }, |
| | |
| | | handleTabsChange = (parentId) => { |
| | | const { card } = this.state |
| | | |
| | | if (parentId === card.parentId) { |
| | | let _element = document.getElementById(card.uuid + 'canvas') |
| | | if (parentId === card.parentId || parentId === 'all') { |
| | | let _element = document.getElementById(card.uuid + 'dashboard') |
| | | if (_element) { |
| | | _element.innerHTML = '' |
| | | } |
| | |
| | | </Popover> |
| | | <NormalHeader hideSearch="true" config={card} updateComponent={this.updateComponent}/> |
| | | <div className="canvas" id={card.uuid + 'dashboard'} ref={ref => this.wrap = ref}></div> |
| | | <div className="component-name"><div className="center">{card.name}</div></div> |
| | | </div> |
| | | ) |
| | | } |
| | |
| | | handleTabsChange = (parentId) => { |
| | | const { card } = this.state |
| | | |
| | | if (parentId === card.parentId) { |
| | | if (parentId === card.parentId || parentId === 'all') { |
| | | let _element = document.getElementById(card.uuid + 'canvas') |
| | | if (_element) { |
| | | _element.innerHTML = '' |
| | |
| | | </Popover> |
| | | <NormalHeader config={card} updateComponent={this.updateComponent}/> |
| | | <div className="canvas" id={card.uuid + 'canvas'} ref={ref => this.wrap = ref}></div> |
| | | <div className="component-name"><div className="center">{card.name}</div></div> |
| | | </div> |
| | | ) |
| | | } |
| | |
| | | handleTabsChange = (parentId) => { |
| | | const { card } = this.state |
| | | |
| | | if (parentId === card.parentId) { |
| | | if (parentId === card.parentId || parentId === 'all') { |
| | | let _element = document.getElementById(card.uuid + 'canvas') |
| | | if (_element) { |
| | | _element.innerHTML = '' |
| | |
| | | <NormalHeader config={card} updateComponent={this.updateComponent}/> |
| | | <div className="canvas" id={card.uuid + 'canvas'} ref={ref => this.wrap = ref}></div> |
| | | {appType !== 'mob' ? <ActionComponent type="chart" config={card} updateaction={this.updateComponent}/> : null} |
| | | <div className="component-name"><div className="center">{card.name}</div></div> |
| | | </div> |
| | | ) |
| | | } |
| | |
| | | handleTabsChange = (parentId) => { |
| | | const { card } = this.state |
| | | |
| | | if (parentId === card.parentId) { |
| | | if (parentId === card.parentId || parentId === 'all') { |
| | | let _element = document.getElementById(card.uuid + 'canvas') |
| | | if (_element) { |
| | | _element.innerHTML = '' |
| | |
| | | </Popover> |
| | | <NormalHeader config={card} updateComponent={this.updateComponent}/> |
| | | <div className="canvas" id={card.uuid + 'canvas'} ref={ref => this.wrap = ref}></div> |
| | | <div className="component-name"><div className="center">{card.name}</div></div> |
| | | </div> |
| | | ) |
| | | } |
| | |
| | | <ToolOutlined /> |
| | | </Popover> |
| | | <CodeContent name={card.name} html={card.html} css={card.css} js={card.js}/> |
| | | <div className="component-name"><div className="center">{card.name}</div></div> |
| | | </div> |
| | | ) |
| | | } |
| | |
| | | value={card.wrap.datatype !== 'static' ? '<p class="empty-content">富文本</p>' : card.html} |
| | | encryption="false" |
| | | /> |
| | | <div className="component-name"><div className="center">{card.name}</div></div> |
| | | </div> |
| | | ) |
| | | } |
| | |
| | | } else if (card.type === 'next') { |
| | | return ['type', 'label', 'enable'] |
| | | } |
| | | let _options = ['type', 'label', 'intertype', 'syncComponent', 'linkmenu', 'open', 'enable', 'output', 'reload'] // 选项列表 |
| | | let _options = ['type', 'label', 'intertype', 'syncComponent', 'anchors', 'linkmenu', 'open', 'enable', 'output', 'reload'] // 选项列表 |
| | | |
| | | if (_intertype === 'custom') { |
| | | _options.pop() |
| | |
| | | * @param {*} type 按钮类型,用于区分可选的打开方式 |
| | | */ |
| | | |
| | | export function getActionForm (card, functip, tableName, usefulFields, modules) { |
| | | export function getActionForm (card, functip, tableName, usefulFields, modules, anchors) { |
| | | const appType = sessionStorage.getItem('appType') |
| | | let _type = '提交' |
| | | if (card.type === 'prev') { |
| | |
| | | options: modules |
| | | }, |
| | | { |
| | | type: 'cascader', |
| | | key: 'anchors', |
| | | label: '跳转锚点', |
| | | initVal: card.anchors || [], |
| | | tooltip: '执行成功后,需要跳转的锚点', |
| | | required: false, |
| | | options: anchors |
| | | }, |
| | | { |
| | | type: 'radio', |
| | | key: 'reload', |
| | | label: '上一页', |
| | |
| | | </div> |
| | | |
| | | let modules = MenuUtils.getSubModules(window.GLOB.customMenu.components, config.uuid) || [] |
| | | let anchors = MenuUtils.getAnchors(window.GLOB.customMenu.components, config.uuid) || [] |
| | | |
| | | this.setState({ |
| | | visible: true, |
| | | card: card, |
| | | formlist: getActionForm(card, functip, config.setting.tableName, usefulFields, modules) |
| | | formlist: getActionForm(card, functip, config.setting.tableName, usefulFields, modules, anchors) |
| | | }) |
| | | } |
| | | |
| | |
| | | index = i |
| | | } |
| | | |
| | | let label = item.label || '' |
| | | if (item.field && item.field.toLowerCase() !== label.toLowerCase()) { |
| | | label = label + ' (' + item.field + ')' |
| | | } |
| | | |
| | | if (['text', 'number', 'textarea', 'color'].includes(item.type) && _item.field !== item.field) { |
| | | _inputfields.push({ |
| | | field: item.field, |
| | | label: _inputIndex + '、' + item.label |
| | | label: _inputIndex + '、' + label |
| | | }) |
| | | _inputIndex++ |
| | | } |
| | | if (appType === 'mob') { |
| | | if (_form.field !== item.field && item.hidden !== 'true' && ['text', 'number'].includes(item.type)) { |
| | | _tabfields.push({ |
| | | field: item.field, |
| | | label: _tabIndex + '、' + item.label |
| | | }) |
| | | _tabIndex++ |
| | | } |
| | | } else { |
| | | if (_form.field !== item.field && item.hidden !== 'true' && ['text', 'number', 'select', 'link'].includes(item.type)) { |
| | | _tabfields.push({ |
| | | field: item.field, |
| | | label: _tabIndex + '、' + item.label |
| | | }) |
| | | _tabIndex++ |
| | | } |
| | | |
| | | if (_item.field !== item.field && item.hidden !== 'true' && ['text', 'number', 'select', 'link'].includes(item.type)) { |
| | | _tabfields.push({ |
| | | field: item.field, |
| | | label: _tabIndex + '、' + label |
| | | }) |
| | | _tabIndex++ |
| | | } |
| | | |
| | | if (item.type === 'switch') { |
| | | _linksupFields.push({ |
| | | field: item.field, |
| | | label: _linkIndex + '、' + item.label |
| | | label: _linkIndex + '、' + label |
| | | }) |
| | | } |
| | | |
| | |
| | | }) |
| | | _linksupFields.push({ |
| | | field: item.field, |
| | | label: _linkIndex + '、' + item.label |
| | | label: _linkIndex + '、' + label |
| | | }) |
| | | _linkIndex++ |
| | | } |
| | |
| | | />} |
| | | <FormAction config={card} group={group} updateconfig={this.updateGroup}/> |
| | | </div> : null} |
| | | <div className="component-name"><div className="center">{card.name}</div></div> |
| | | <Modal |
| | | title={this.state.dict['model.edit']} |
| | | visible={this.state.visible} |
| | |
| | | index = i |
| | | } |
| | | |
| | | let label = item.label || '' |
| | | if (item.field && item.field.toLowerCase() !== label.toLowerCase()) { |
| | | label = label + ' (' + item.field + ')' |
| | | } |
| | | |
| | | if (['text', 'number', 'textarea', 'color'].includes(item.type) && _item.field !== item.field) { |
| | | _inputfields.push({ |
| | | field: item.field, |
| | | label: _inputIndex + '、' + item.label |
| | | label: _inputIndex + '、' + label |
| | | }) |
| | | _inputIndex++ |
| | | } |
| | | if (appType === 'mob') { |
| | | if (_form.field !== item.field && item.hidden !== 'true' && ['text', 'number'].includes(item.type)) { |
| | | _tabfields.push({ |
| | | field: item.field, |
| | | label: _tabIndex + '、' + item.label |
| | | }) |
| | | _tabIndex++ |
| | | } |
| | | } else { |
| | | if (_form.field !== item.field && item.hidden !== 'true' && ['text', 'number', 'select', 'link'].includes(item.type)) { |
| | | _tabfields.push({ |
| | | field: item.field, |
| | | label: _tabIndex + '、' + item.label |
| | | }) |
| | | _tabIndex++ |
| | | } |
| | | if (_form.field !== item.field && item.hidden !== 'true' && ['text', 'number', 'select', 'link'].includes(item.type)) { |
| | | _tabfields.push({ |
| | | field: item.field, |
| | | label: _tabIndex + '、' + label |
| | | }) |
| | | _tabIndex++ |
| | | } |
| | | |
| | | if (item.type === 'switch') { |
| | | _linksupFields.push({ |
| | | field: item.field, |
| | | label: _linkIndex + '、' + item.label |
| | | label: _linkIndex + '、' + label |
| | | }) |
| | | } |
| | | |
| | |
| | | }) |
| | | _linksupFields.push({ |
| | | value: item.field, |
| | | text: _linkIndex + '、' + item.label |
| | | text: _linkIndex + '、' + label |
| | | }) |
| | | |
| | | _linkIndex++ |
| | |
| | | />} |
| | | <FormAction config={card} group={group} updateconfig={this.updateGroup}/> |
| | | </div> : null} |
| | | <div className="component-name"><div className="center">{card.name}</div></div> |
| | | <Modal |
| | | title={this.state.dict['model.edit']} |
| | | visible={this.state.visible} |
| | |
| | | <div className="ant-row ant-form-item" style={{lineHeight: '40px', height: '55px', marginBottom: 0}}> |
| | | <div className="ant-col ant-form-item-label ant-col-xs-24 ant-col-sm-8"> |
| | | </div> |
| | | <div className="ant-col ant-form-item-control-wrapper ant-col-xs-24 ant-col-sm-16"> |
| | | <div className="ant-col ant-form-item-control-wrapper ant-col-xs-24 ant-col-sm-16" style={{whiteSpace: 'nowrap'}}> |
| | | <Button type="primary">搜索</Button> |
| | | {appType !== 'mob' ? <Button style={{ marginLeft: 8 }}>重置</Button> : null} |
| | | <div style={{position: 'absolute', top: 0, bottom: 0, left: 0, right: 0}}></div> |
| | |
| | | <div className="ant-row ant-form-item" style={{lineHeight: '40px', height: '55px', marginBottom: 0}}> |
| | | <div className="ant-col ant-form-item-label ant-col-xs-24 ant-col-sm-8"> |
| | | </div> |
| | | <div className="ant-col ant-form-item-control-wrapper ant-col-xs-24 ant-col-sm-16"> |
| | | <div className="ant-col ant-form-item-control-wrapper ant-col-xs-24 ant-col-sm-16" style={{whiteSpace: 'nowrap'}}> |
| | | <Button type="primary">搜索</Button> |
| | | {appType !== 'mob' ? <Button style={{ marginLeft: 8 }}>重置</Button> : null} |
| | | <div style={{position: 'absolute', top: 0, bottom: 0, left: 0, right: 0}}></div> |
| | |
| | | } trigger="hover"> |
| | | <ToolOutlined /> |
| | | </Popover> |
| | | <div className="component-name"><div className="center">{card.name}</div></div> |
| | | {/* 编辑搜索条件 */} |
| | | <Modal |
| | | title="搜索条件-编辑" |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { fromJS } from 'immutable' |
| | | import { Form, Row, Col, Input, Select, Radio, notification, Tooltip, InputNumber, Cascader } from 'antd' |
| | | import { Form, Row, Col, Input, Select, Radio, Tooltip, InputNumber, Cascader } from 'antd' |
| | | import { QuestionCircleOutlined } from '@ant-design/icons' |
| | | import { formRule } from '@/utils/option.js' |
| | | |
| | |
| | | const { TextArea } = Input |
| | | const MkEditIcon = asyncComponent(() => import('@/components/mkIcon')) |
| | | const acTyOptions = { |
| | | pop: ['label', 'OpenType', 'intertype', 'Ot', 'show', 'swipe', 'icon', 'class', 'color', 'execSuccess', 'execError', 'resetPageIndex', 'syncComponent', 'switchTab', 'width', 'openmenu', 'open', 'refreshTab', 'position', 'tipTitle'], |
| | | prompt: ['label', 'OpenType', 'intertype', 'Ot', 'show', 'swipe', 'icon', 'class', 'color', 'execSuccess', 'execError', 'resetPageIndex', 'syncComponent', 'switchTab', 'width', 'openmenu', 'open', 'refreshTab', 'position', 'tipTitle'], |
| | | exec: ['label', 'OpenType', 'intertype', 'Ot', 'show', 'swipe', 'icon', 'class', 'color', 'execSuccess', 'execError', 'resetPageIndex', 'syncComponent', 'switchTab', 'width', 'openmenu', 'open', 'refreshTab'], |
| | | excelIn: ['label', 'Ot', 'OpenType', 'intertype', 'show', 'icon', 'class', 'color', 'sheet', 'execSuccess', 'execError', 'resetPageIndex', 'syncComponent', 'switchTab', 'width'], |
| | | excelOut: ['label', 'OpenType', 'intertype', 'show', 'icon', 'class', 'color', 'execSuccess', 'execError', 'syncComponent', 'switchTab', 'resetPageIndex', 'pagination', 'search', 'width'], |
| | | popview: ['label', 'Ot', 'OpenType', 'show', 'icon', 'class', 'color', 'popClose', 'resetPageIndex', 'width', 'display', 'ratio', 'syncComponent', 'clickouter'], |
| | | tab: ['label', 'Ot', 'OpenType', 'show', 'icon', 'class', 'color', 'linkmenu', 'width'], |
| | | innerpage: ['label', 'Ot', 'OpenType', 'pageTemplate', 'show', 'swipe', 'icon', 'class', 'color', 'width', 'open'], |
| | | funcbutton: ['label', 'OpenType', 'funcType', 'show', 'swipe', 'icon', 'class', 'color', 'width'], |
| | | form: ['label', 'OpenType', 'formType', 'intertype', 'Ot', 'execSuccess', 'execError', 'resetPageIndex', 'syncComponent', 'width', 'open', 'refreshTab', 'title'] |
| | | pop: ['label', 'OpenType', 'intertype', 'Ot', 'show', 'swipe', 'icon', 'class', 'color', 'execSuccess', 'execError', 'resetPageIndex', 'syncComponent', 'switchTab', 'anchors', 'width', 'openmenu', 'open', 'refreshTab', 'position', 'tipTitle', 'hidden'], |
| | | prompt: ['label', 'OpenType', 'intertype', 'Ot', 'show', 'swipe', 'icon', 'class', 'color', 'execSuccess', 'execError', 'resetPageIndex', 'syncComponent', 'switchTab', 'anchors', 'width', 'openmenu', 'open', 'refreshTab', 'position', 'tipTitle', 'hidden'], |
| | | exec: ['label', 'OpenType', 'intertype', 'Ot', 'show', 'swipe', 'icon', 'class', 'color', 'execSuccess', 'execError', 'resetPageIndex', 'syncComponent', 'switchTab', 'anchors', 'width', 'openmenu', 'open', 'refreshTab', 'hidden'], |
| | | excelIn: ['label', 'Ot', 'OpenType', 'intertype', 'show', 'icon', 'class', 'color', 'sheet', 'execSuccess', 'execError', 'resetPageIndex', 'syncComponent', 'switchTab', 'width', 'hidden'], |
| | | excelOut: ['label', 'OpenType', 'intertype', 'show', 'icon', 'class', 'color', 'execSuccess', 'execError', 'syncComponent', 'switchTab', 'resetPageIndex', 'pagination', 'search', 'width', 'hidden'], |
| | | popview: ['label', 'Ot', 'OpenType', 'show', 'icon', 'class', 'color', 'popClose', 'resetPageIndex', 'width', 'display', 'ratio', 'syncComponent', 'clickouter', 'hidden'], |
| | | tab: ['label', 'Ot', 'OpenType', 'show', 'icon', 'class', 'color', 'linkmenu', 'width', 'hidden'], |
| | | innerpage: ['label', 'Ot', 'OpenType', 'pageTemplate', 'show', 'swipe', 'icon', 'class', 'color', 'width', 'open', 'hidden'], |
| | | funcbutton: ['label', 'OpenType', 'funcType', 'show', 'swipe', 'icon', 'class', 'color', 'width', 'hidden'], |
| | | form: ['label', 'OpenType', 'formType', 'intertype', 'Ot', 'execSuccess', 'execError', 'resetPageIndex', 'syncComponent', 'width', 'open', 'refreshTab', 'title', 'hidden'] |
| | | } |
| | | |
| | | class ActionForm extends Component { |
| | |
| | | setting: PropTypes.object, // 页面设置 |
| | | formlist: PropTypes.any, // 表单信息 |
| | | card: PropTypes.any, // 按钮信息 |
| | | inputSubmit: PropTypes.any // 回车提交事件 |
| | | inputSubmit: PropTypes.func, // 回车提交事件 |
| | | updRecord: PropTypes.func // 更新信息 |
| | | } |
| | | |
| | | state = { |
| | |
| | | } |
| | | }, 100) |
| | | } |
| | | this.props.updRecord && this.props.updRecord(this.record) |
| | | } |
| | | |
| | | getMutilOptions = (requireOptions) => { |
| | |
| | | reTooltip.linkmenu = '使用扫码登录功能或菜单跳转功能时,需选择跳转的菜单。' |
| | | } else if (_funcType === 'goBack') { |
| | | shows.push('reload') |
| | | // } else if (_funcType === 'megvii') { |
| | | // shows.push('subFunc') |
| | | } else if (_funcType === 'megvii') { |
| | | shows.push('subFunc') |
| | | } |
| | | } |
| | | |
| | |
| | | this.record.control = '' |
| | | _fieldval.control = '' |
| | | } |
| | | |
| | | this.props.updRecord && this.props.updRecord(this.record) |
| | | } else if (key === 'funcType') { |
| | | if (value === 'print') { |
| | | _fieldval.label = '打印' |
| | |
| | | } |
| | | } else if (key === 'intertype') { |
| | | this.record.sysInterface = 'false' |
| | | |
| | | this.props.updRecord && this.props.updRecord(this.record) |
| | | } else if (key === 'sysInterface') { |
| | | if (value === 'true') { |
| | | _fieldval.interface = window.GLOB.mainSystemApi || '' |
| | |
| | | } |
| | | |
| | | handleConfirm = () => { |
| | | const { setting, card } = this.props |
| | | const { card } = this.props |
| | | // 表单提交时检查输入值是否正确 |
| | | return new Promise((resolve, reject) => { |
| | | this.props.form.validateFieldsAndScroll((err, values) => { |
| | |
| | | values.closeVal = +values.closeVal |
| | | } |
| | | } else if (values.OpenType === 'excelOut') { |
| | | if (values.intertype === 'system' && setting.interType !== 'system') { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '表格数据查询未使用系统函数,导出Excel不可使用系统函数!', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } |
| | | |
| | | values.Ot = 'notRequired' |
| | | } else if (['pop', 'prompt', 'exec'].includes(values.OpenType) && values.verify) { |
| | | if ((values.Ot === 'requiredOnce' || card.Ot === 'requiredOnce') && card.Ot !== values.Ot) { |
| | |
| | | hasProfile = true |
| | | } else if (card.funcType === 'print') { |
| | | hasProfile = true |
| | | } else if (card.funcType === 'megvii') { |
| | | hasProfile = true |
| | | } |
| | | |
| | | let btnElement = null |
| | |
| | | _class = 'swiper swiper-' + card.color |
| | | show = 'button' |
| | | } |
| | | if (card.hidden === 'true') { |
| | | _class += ' mk-hidden' |
| | | } |
| | | let warning = null |
| | | if (card.OpenType === 'innerpage' && !card.pageTemplate) { |
| | | warning = <WarningOutlined style={{color: 'orange', marginLeft: '5px'}}/> |
| | |
| | | * @param {*} usefulFields 存储过程可用的开始字段 |
| | | * @param {*} type 按钮类型,用于区分可选的打开方式 |
| | | */ |
| | | export function getActionForm (card, functip, config, usefulFields, type, menulist = [], modules = []) { |
| | | export function getActionForm (card, functip, config, usefulFields, type, menulist = [], modules = [], anchors = []) { |
| | | let appType = sessionStorage.getItem('appType') |
| | | let viewType = sessionStorage.getItem('editMenuType') // 弹窗 popview |
| | | let printTemps = sessionStorage.getItem('printTemps') |
| | |
| | | { value: 'changeuser', text: '切换用户' }, |
| | | { value: 'print', text: '标签打印' }, |
| | | { value: 'closetab', text: '标签关闭' }, |
| | | { value: 'megvii', text: '旷视面板机' }, |
| | | ] |
| | | |
| | | if (isApp) { |
| | |
| | | { value: 'mkUnsubscribe', text: '注销账户' }, |
| | | { value: 'reAuth', text: '切换系统(清空缓存-小程序)' }, |
| | | { value: 'goBack', text: '返回' }, |
| | | // { value: 'megvii', text: '旷视面板机' }, |
| | | ] |
| | | pageTemps = [ |
| | | { value: 'linkpage', text: '关联菜单' }, |
| | |
| | | required: true, |
| | | options: funTypes |
| | | }, |
| | | // { |
| | | // type: 'select', |
| | | // key: 'subFunc', |
| | | // label: '接口名称', |
| | | // initVal: card.subFunc || '', |
| | | // required: true, |
| | | // options: [ |
| | | // { value: 'login', text: '登录' } |
| | | // ] |
| | | // }, |
| | | { |
| | | type: 'radio', |
| | | key: 'subFunc', |
| | | label: '接口名称', |
| | | initVal: card.subFunc || 'addUser', |
| | | required: true, |
| | | options: [ |
| | | { value: 'addUser', text: '添加用户' }, |
| | | ] |
| | | }, |
| | | { |
| | | type: 'radio', |
| | | key: 'formType', |
| | |
| | | }, |
| | | { |
| | | type: 'cascader', |
| | | key: 'anchors', |
| | | label: '跳转锚点', |
| | | initVal: card.anchors || [], |
| | | tooltip: '执行成功后,需要跳转的锚点', |
| | | required: false, |
| | | options: anchors |
| | | }, |
| | | { |
| | | type: 'cascader', |
| | | key: 'refreshTab', |
| | | label: '刷新菜单', |
| | | initVal: card.refreshTab || [], |
| | |
| | | precision: 0, |
| | | label: '比例', |
| | | initVal: card.ratio || 85, |
| | | tooltip: '小于100为宽度(或高度)百分比,大于100为像素值。', |
| | | tooltip: '模态框或抽屉的宽度,小于100为窗口宽度(或高度)百分比,大于100为像素值。', |
| | | required: true |
| | | }, |
| | | { |
| | |
| | | initVal: card.closeText || '', |
| | | required: false, |
| | | }, |
| | | { |
| | | type: 'radio', |
| | | key: 'hidden', |
| | | label: '隐藏', |
| | | initVal: card.hidden || 'false', |
| | | tooltip: '隐藏后按钮在页面中不显示,且不参与权限分配。', |
| | | required: false, |
| | | options: [{ |
| | | value: 'false', |
| | | text: '否' |
| | | }, { |
| | | value: 'true', |
| | | text: '是' |
| | | }] |
| | | } |
| | | ] |
| | | |
| | | return forms |
| | |
| | | const VerifyPrint = asyncSpinComponent(() => import('@/templates/sharecomponent/actioncomponent/verifyprint')) |
| | | const VerifyExcelIn = asyncSpinComponent(() => import('@/templates/sharecomponent/actioncomponent/verifyexcelin')) |
| | | const VerifyExcelOut = asyncSpinComponent(() => import('@/templates/sharecomponent/actioncomponent/verifyexcelout')) |
| | | const VerifyMegvii = asyncSpinComponent(() => import('@/templates/sharecomponent/actioncomponent/verifymegvii')) |
| | | |
| | | class ActionComponent extends Component { |
| | | static propTpyes = { |
| | |
| | | formlist: null, // 表单信息 |
| | | actionlist: null, // 按钮组 |
| | | visible: false, // 模态框控制 |
| | | profVisible: false // 验证信息模态框 |
| | | profVisible: false, // 验证信息模态框 |
| | | record: null |
| | | } |
| | | |
| | | /** |
| | |
| | | } |
| | | |
| | | let modules = MenuUtils.getSubModules(window.GLOB.customMenu.components, config.uuid) || [] |
| | | let anchors = MenuUtils.getAnchors(window.GLOB.customMenu.components, config.uuid) || [] |
| | | |
| | | this.setState({ |
| | | visible: true, |
| | | card: card, |
| | | formlist: getActionForm(card, functip, config, usefulFields, this.props.type, menulist, modules) |
| | | formlist: getActionForm(card, functip, config, usefulFields, this.props.type, menulist, modules, anchors) |
| | | }) |
| | | } |
| | | |
| | |
| | | }) |
| | | } |
| | | |
| | | getVerify = (card) => { |
| | | const { config } = this.props |
| | | const { dict } = this.state |
| | | |
| | | if (!card) return null |
| | | |
| | | if (['pop', 'prompt', 'exec'].includes(card.OpenType)) { |
| | | return <VerifyCard |
| | | card={card} |
| | | dict={dict} |
| | | config={config} |
| | | columns={config.columns} |
| | | wrappedComponentRef={(inst) => this.verifyRef = inst} |
| | | /> |
| | | } else if (card.OpenType === 'excelIn') { |
| | | return <VerifyExcelIn |
| | | card={card} |
| | | dict={dict} |
| | | columns={config.columns} |
| | | wrappedComponentRef={(inst) => this.verifyRef = inst} |
| | | /> |
| | | } else if (card.OpenType === 'excelOut') { |
| | | return <VerifyExcelOut |
| | | card={card} |
| | | dict={dict} |
| | | config={config} |
| | | wrappedComponentRef={(inst) => this.verifyRef = inst} |
| | | /> |
| | | } else if (card.OpenType === 'funcbutton' && card.funcType === 'print') { |
| | | return <VerifyPrint |
| | | card={card} |
| | | dict={dict} |
| | | columns={config.columns} |
| | | wrappedComponentRef={(inst) => this.verifyRef = inst} |
| | | /> |
| | | } else if (card.OpenType === 'funcbutton' && card.funcType === 'megvii') { |
| | | return <VerifyMegvii |
| | | card={card} |
| | | dict={dict} |
| | | columns={config.columns} |
| | | wrappedComponentRef={(inst) => this.verifyRef = inst} |
| | | /> |
| | | } |
| | | } |
| | | |
| | | render() { |
| | | const { config, type } = this.props |
| | | const { actionlist, visible, appType, card, dict, profVisible } = this.state |
| | | const { actionlist, visible, appType, card, dict, profVisible, record } = this.state |
| | | |
| | | return ( |
| | | <div className={'model-menu-action-list'}> |
| | |
| | | /> |
| | | {/* 编辑按钮:复制、编辑 */} |
| | | <Modal |
| | | // title={dict['model.action'] + '-' + (card && card.copyType === 'action' ? dict['model.copy'] : dict['model.edit'])} |
| | | title="按钮·编辑" |
| | | visible={visible} |
| | | width={850} |
| | | maskClosable={false} |
| | | onCancel={this.editModalCancel} |
| | | footer={[ |
| | | <CreateFunc key="create" dict={dict} ref="btnCreatFunc" trigger={this.creatFunc}/>, |
| | | record && record.intertype === 'inner' ? <CreateFunc key="create" dict={dict} ref="btnCreatFunc" trigger={this.creatFunc}/> : null, |
| | | <Button key="cancel" onClick={this.editModalCancel}>{dict['model.cancel']}</Button>, |
| | | <Button key="confirm" type="primary" onClick={this.handleSubmit}>{dict['model.confirm']}</Button> |
| | | ]} |
| | |
| | | formlist={this.state.formlist} |
| | | inputSubmit={this.handleSubmit} |
| | | setting={config.setting} |
| | | updRecord={(record) => this.setState({record: fromJS(record).toJS()})} |
| | | wrappedComponentRef={(inst) => this.actionFormRef = inst} |
| | | /> |
| | | </Modal> |
| | |
| | | }} |
| | | destroyOnClose |
| | | > |
| | | {card && !card.execMode && card.OpenType !== 'excelIn' && card.OpenType !== 'excelOut' ? |
| | | <VerifyCard |
| | | card={card} |
| | | dict={dict} |
| | | config={config} |
| | | columns={config.columns} |
| | | wrappedComponentRef={(inst) => this.verifyRef = inst} |
| | | /> : null |
| | | } |
| | | {card && card.execMode ? |
| | | <VerifyPrint |
| | | card={card} |
| | | dict={dict} |
| | | columns={config.columns} |
| | | wrappedComponentRef={(inst) => this.verifyRef = inst} |
| | | /> : null |
| | | } |
| | | {card && card.OpenType === 'excelIn' ? |
| | | <VerifyExcelIn |
| | | card={card} |
| | | dict={dict} |
| | | columns={config.columns} |
| | | wrappedComponentRef={(inst) => this.verifyRef = inst} |
| | | /> : null |
| | | } |
| | | {card && card.OpenType === 'excelOut' ? |
| | | <VerifyExcelOut |
| | | card={card} |
| | | dict={dict} |
| | | config={config} |
| | | wrappedComponentRef={(inst) => this.verifyRef = inst} |
| | | /> : null |
| | | } |
| | | {this.getVerify(card)} |
| | | </Modal> |
| | | </div> |
| | | ) |
| | |
| | | const { visible, loading } = this.state |
| | | |
| | | return ( |
| | | <div className="clock-component-wrap"> |
| | | <div className={'clock-component-wrap' + (config.timer ? ' tip-sign' : '')}> |
| | | <ClockCircleOutlined title="定时器" onClick={this.trigger} /> |
| | | <Modal |
| | | title="定时器设置" |
| | |
| | | .clock-component-wrap { |
| | | position: relative; |
| | | display: inline-block; |
| | | |
| | | >.anticon-clock-circle { |
| | | color: rgb(38, 194, 129); |
| | | } |
| | | } |
| | | |
| | | .clock-component-wrap.tip-sign::after { |
| | | content: ' '; |
| | | position: absolute; |
| | | top: -2px; |
| | | right: 2px; |
| | | height: 8px; |
| | | width: 8px; |
| | | border-radius: 100%; |
| | | background: #ff5b05; |
| | | z-index: 1; |
| | | } |
| | |
| | | } |
| | | |
| | | render () { |
| | | const { btnlog } = this.props |
| | | const { visible, dict, data, columns } = this.state |
| | | |
| | | return ( |
| | | <div className="btn-log-wrap"> |
| | | <div className={'btn-log-wrap' + (btnlog && btnlog.length > 0 ? ' tip-sign' : '')}> |
| | | <RollbackOutlined title="解除冻结" onClick={this.trigger} /> |
| | | <Modal |
| | | wrapClassName="popview-modal" |
| | |
| | | .btn-log-wrap { |
| | | position: relative; |
| | | display: inline-block; |
| | | |
| | | >.anticon-rollback { |
| | |
| | | padding: 5px; |
| | | } |
| | | } |
| | | } |
| | | .btn-log-wrap.tip-sign::after { |
| | | content: ' '; |
| | | position: absolute; |
| | | top: -2px; |
| | | right: 2px; |
| | | height: 8px; |
| | | width: 8px; |
| | | border-radius: 100%; |
| | | background: #ff5b05; |
| | | z-index: 1; |
| | | } |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { fromJS } from 'immutable' |
| | | import { Form, Row, Col, Input, Tooltip, InputNumber, Select, Radio, Cascader } from 'antd' |
| | | import { QuestionCircleOutlined } from '@ant-design/icons' |
| | | |
| | | // import './index.scss' |
| | | import asyncComponent from '@/utils/asyncComponent' |
| | | import './index.scss' |
| | | |
| | | const MKTable = asyncComponent(() => import('@/components/normalform/modalform/mkTable')) |
| | | |
| | | class SettingForm extends Component { |
| | | static propTpyes = { |
| | | dict: PropTypes.object, // 字典项 |
| | | formlist: PropTypes.array, // 表单 |
| | | inputSubmit: PropTypes.func // 回车事件 |
| | | } |
| | | |
| | | state = { |
| | | formlist: [], |
| | | } |
| | | |
| | | UNSAFE_componentWillMount() { |
| | | const { formlist } = this.props |
| | | |
| | | this.setState({formlist: fromJS(formlist).toJS()}) |
| | | } |
| | | |
| | | handleConfirm = () => { |
| | |
| | | } |
| | | } |
| | | |
| | | getFields() { |
| | | const { formlist } = this.props |
| | | const { getFieldDecorator } = this.props.form |
| | | const fields = [] |
| | | optionChange = (item, val) => { |
| | | if (item.key === 'click') { |
| | | this.setState({formlist: fromJS(this.state.formlist).toJS().map(cell => { |
| | | if (!['menu', 'menuType', 'open', 'joint', 'menus'].includes(cell.key)) return cell |
| | | |
| | | if (val === 'menu') { |
| | | cell.hidden = !['menu', 'open', 'joint'].includes(cell.key) |
| | | } else if (val === 'menus') { |
| | | cell.hidden = !['menuType', 'open', 'joint', 'menus'].includes(cell.key) |
| | | } else { |
| | | cell.hidden = true |
| | | } |
| | | |
| | | if (!formlist) return [] |
| | | return cell |
| | | })}) |
| | | } |
| | | } |
| | | |
| | | getFields() { |
| | | const { formlist } = this.state |
| | | const { getFieldDecorator } = this.props.form |
| | | |
| | | const fields = [] |
| | | |
| | | formlist.forEach((item, index) => { |
| | | if (item.hidden || item.forbid) return |
| | | |
| | | |
| | | let content = null |
| | | let label = item.tooltip ? <Tooltip placement="topLeft" title={item.tooltip}><QuestionCircleOutlined className="mk-form-tip" />{item.label}</Tooltip> : item.label |
| | | |
| | | if (item.type === 'text') { |
| | | fields.push( |
| | | <Col span={12} key={index}> |
| | | <Form.Item label={item.tooltip ? |
| | | <Tooltip placement="topLeft" title={item.tooltip}> |
| | | <QuestionCircleOutlined className="mk-form-tip" /> |
| | | {item.label} |
| | | </Tooltip> : item.label |
| | | }> |
| | | {getFieldDecorator(item.key, { |
| | | initialValue: item.initVal, |
| | | rules: [ |
| | | { |
| | | required: item.required, |
| | | message: this.props.dict['form.required.input'] + item.label + '!' |
| | | } |
| | | ] |
| | | })(<Input placeholder="" autoComplete="off" disabled={item.readonly} onPressEnter={this.handleSubmit}/>)} |
| | | </Form.Item> |
| | | </Col> |
| | | ) |
| | | content = (<Input placeholder="" autoComplete="off" onPressEnter={this.handleSubmit}/>) |
| | | } else if (item.type === 'number') { |
| | | fields.push( |
| | | <Col span={12} key={index}> |
| | | <Form.Item label={item.tooltip ? |
| | | <Tooltip placement="topLeft" title={item.tooltip}> |
| | | <QuestionCircleOutlined className="mk-form-tip" /> |
| | | {item.label} |
| | | </Tooltip> : item.label |
| | | }> |
| | | {getFieldDecorator(item.key, { |
| | | initialValue: item.initVal, |
| | | rules: [ |
| | | { |
| | | required: item.required, |
| | | message: this.props.dict['form.required.input'] + item.label + '!' |
| | | } |
| | | ] |
| | | })(<InputNumber min={item.min} max={item.max} precision={item.decimal} 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}> |
| | | <QuestionCircleOutlined className="mk-form-tip" /> |
| | | {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 mode={item.multi ? 'multiple' : ''}> |
| | | {item.options.map((option, index) => |
| | | <Select.Option key={index} value={option.field || option.value}> |
| | | {option.label || option.text} |
| | | </Select.Option> |
| | | )} |
| | | </Select> |
| | | )} |
| | | </Form.Item> |
| | | </Col> |
| | | ) |
| | | content = (<InputNumber min={item.min} max={item.max} precision={item.decimal} onPressEnter={this.handleSubmit}/>) |
| | | } else if (item.type === 'select') { |
| | | content = (<Select mode={item.multi ? 'multiple' : ''}> |
| | | {item.options.map((option, index) => |
| | | <Select.Option key={index} value={option.field || option.value}> |
| | | {option.label || option.text} |
| | | </Select.Option> |
| | | )} |
| | | </Select>) |
| | | } else if (item.type === 'radio') { |
| | | fields.push( |
| | | <Col span={12} key={index}> |
| | | <Form.Item label={item.tooltip ? |
| | | <Tooltip placement="topLeft" title={item.tooltip}> |
| | | <QuestionCircleOutlined className="mk-form-tip" /> |
| | | {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 disabled={item.readonly}> |
| | | {item.options.map(option => { |
| | | return ( |
| | | <Radio key={option.value} value={option.value}>{option.text}</Radio> |
| | | ) |
| | | })} |
| | | </Radio.Group> |
| | | )} |
| | | </Form.Item> |
| | | </Col> |
| | | ) |
| | | content = (<Radio.Group onChange={(e) => this.optionChange(item, e.target.value)}> |
| | | {item.options.map(option => { |
| | | return ( |
| | | <Radio key={option.value} value={option.field || option.value}>{option.label || option.text}</Radio> |
| | | ) |
| | | })} |
| | | </Radio.Group>) |
| | | } else if (item.type === 'cascader') { |
| | | fields.push( |
| | | <Col span={12} key={index}> |
| | | <Form.Item label={item.tooltip ? |
| | | <Tooltip placement="topLeft" title={item.tooltip}> |
| | | <QuestionCircleOutlined className="mk-form-tip" /> |
| | | {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} placeholder=""/> |
| | | )} |
| | | </Form.Item> |
| | | </Col> |
| | | ) |
| | | content = (<Cascader options={item.options} placeholder=""/>) |
| | | } else if (item.type === 'table') { |
| | | content = (<MKTable columns={item.columns || []} actions={item.actions || []}/>) |
| | | } |
| | | |
| | | if (!content) return |
| | | |
| | | fields.push( |
| | | <Col span={item.span || 12} key={index}> |
| | | <Form.Item label={label}> |
| | | {getFieldDecorator(item.key, { |
| | | initialValue: item.initVal, |
| | | rules: [ |
| | | { |
| | | required: item.required, |
| | | message: (item.type === 'select' || item.type === 'cascader' ? '请选择' : '请输入') + item.label + '!' |
| | | } |
| | | ] |
| | | })(content)} |
| | | </Form.Item> |
| | | </Col> |
| | | ) |
| | | }) |
| | | |
| | | return fields |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | return ( |
| | | <div> |
| | | <div className="plot-base-wrap"> |
| | | <Form {...formItemLayout}><Row gutter={16}>{this.getFields()}</Row></Form> |
| | | </div> |
| | | ) |
| | |
| | | .plot-base-wrap { |
| | | .ant-col-24 { |
| | | .ant-form-item-label { |
| | | width: 16.5%; |
| | | } |
| | | .ant-form-item-control-wrapper { |
| | | width: 83.5%; |
| | | } |
| | | } |
| | | } |
| | |
| | | val = column.formula |
| | | if (column.eval === 'false') { |
| | | val = val.replace(/\n/ig, '<br/>').replace(/\s/ig, ' ') |
| | | val = <span dangerouslySetInnerHTML={{__html: val}}></span> |
| | | val = <span style={{fontWeight: 'inherit'}} dangerouslySetInnerHTML={{__html: val}}></span> |
| | | } |
| | | } |
| | | return ( |
| | |
| | | return uuid.join('') |
| | | }) () |
| | | |
| | | if (config.wrap && config.wrap.borderColor) { // 边框颜色 |
| | | let style = `#${tableId} table, #${tableId} tr, #${tableId} th, #${tableId} td {border-color: ${config.wrap.borderColor}}` |
| | | let ele = document.createElement('style') |
| | | ele.innerHTML = style |
| | | document.getElementsByTagName('head')[0].appendChild(ele) |
| | | } |
| | | |
| | | this.setState({ |
| | | tableId, |
| | | columns: fromJS(config.cols).toJS(), |
| | | fields: fromJS(config.columns).toJS(), |
| | | lineMarks: config.lineMarks ? fromJS(config.lineMarks).toJS() : [] |
| | | }, () => { |
| | | const element = document.getElementById(tableId) |
| | | element && element.style.setProperty('--mk-table-border-color', config.wrap.borderColor || '#e8e8e8') |
| | | element && element.style.setProperty('--mk-table-color', config.wrap.color || 'rgba(0, 0, 0, 0.65)') |
| | | element && element.style.setProperty('--mk-table-font-size', config.wrap.fontSize || '14px') |
| | | element && element.style.setProperty('--mk-table-font-weight', config.wrap.fontWeight || 'normal') |
| | | }) |
| | | } |
| | | |
| | |
| | | } |
| | | } else if (!is(fromJS(this.state.fields), fromJS(nextProps.config.columns))) { |
| | | this.setState({fields: fromJS(nextProps.config.columns).toJS()}) |
| | | } else if (this.props.config.wrap.borderColor !== nextProps.config.wrap.borderColor) { |
| | | let style = `#${this.state.tableId} table, #${this.state.tableId} tr, #${this.state.tableId} th, #${this.state.tableId} td {border-color: ${nextProps.config.wrap.borderColor}}` |
| | | let ele = document.createElement('style') |
| | | ele.innerHTML = style |
| | | document.getElementsByTagName('head')[0].appendChild(ele) |
| | | } else if (!is(fromJS(this.props.config.wrap), fromJS(nextProps.config.wrap))) { |
| | | const element = document.getElementById(this.state.tableId) |
| | | element && element.style.setProperty('--mk-table-border-color', nextProps.config.wrap.borderColor || '#e8e8e8') |
| | | element && element.style.setProperty('--mk-table-color', nextProps.config.wrap.color || 'rgba(0, 0, 0, 0.65)') |
| | | element && element.style.setProperty('--mk-table-font-size', nextProps.config.wrap.fontSize || '14px') |
| | | element && element.style.setProperty('--mk-table-font-weight', nextProps.config.wrap.fontWeight || 'normal') |
| | | } |
| | | } |
| | | |
| | |
| | | } |
| | | }) |
| | | |
| | | let style = {} |
| | | if (config.wrap.color) { |
| | | style.color = config.wrap.color |
| | | } |
| | | if (config.wrap.fontSize) { |
| | | style.fontSize = config.wrap.fontSize |
| | | } |
| | | |
| | | return ( |
| | | <div className={`edit-table-columns ${config.setting.laypage} ${config.wrap.mode || ''}`} id={tableId}> |
| | | <div className="col-control"> |
| | |
| | | rowKey="uuid" |
| | | size={config.wrap.size || 'middle'} |
| | | rowClassName="editable-row" |
| | | style={style} |
| | | bordered={config.wrap.bordered !== 'false'} |
| | | rowSelection={rowSelection} |
| | | components={components} |
| | |
| | | .edit-table-columns { |
| | | position: relative; |
| | | --mk-table-border-color: #e8e8e8; |
| | | --mk-table-color: rgba(0, 0, 0, 0.65); |
| | | --mk-table-font-size: 14px; |
| | | --mk-table-font-weight: normal; |
| | | |
| | | .ant-table { |
| | | color: inherit; |
| | | font-size: inherit; |
| | |
| | | .ant-table-small > .ant-table-content > .ant-table-body { |
| | | margin: 0; |
| | | } |
| | | |
| | | table, tr, th, td { |
| | | border-color: var(--mk-table-border-color)!important; |
| | | } |
| | | table tr { |
| | | th .ant-table-column-title, th .ant-table-column-title > span { |
| | | // color: var(--mk-table-color)!important; |
| | | font-size: var(--mk-table-font-size)!important; |
| | | font-weight: var(--mk-table-font-weight)!important; |
| | | } |
| | | td { |
| | | color: var(--mk-table-color)!important; |
| | | font-size: var(--mk-table-font-size)!important; |
| | | font-weight: var(--mk-table-font-weight)!important; |
| | | } |
| | | } |
| | | } |
| | | .edit-table-columns.false { |
| | | .ant-pagination { |
| | |
| | | changeStyle = () => { |
| | | const { card } = this.state |
| | | |
| | | MKEmitter.emit('changeStyle', [card.uuid], ['background', 'border', 'padding', 'margin', 'shadow'], card.style) |
| | | let style = {...card.style} |
| | | style.color = card.wrap.color || 'rgba(0, 0, 0, 0.65)' |
| | | style.fontSize = card.wrap.fontSize || 14 |
| | | style.fontWeight = card.wrap.fontWeight || 'normal' |
| | | |
| | | MKEmitter.emit('changeStyle', [card.uuid], ['font1', 'background', 'border', 'padding', 'margin', 'shadow'], style) |
| | | } |
| | | |
| | | getStyle = (comIds, style) => { |
| | |
| | | |
| | | if (comIds[0] !== card.uuid || comIds.length !== 1) return |
| | | |
| | | let _card = {...card, style} |
| | | let _card = fromJS(card).toJS() |
| | | let _style = fromJS(style).toJS() |
| | | |
| | | let color = style.color |
| | | let fontSize = style.fontSize |
| | | let fontWeight = style.fontWeight |
| | | |
| | | delete _style.color |
| | | delete _style.fontSize |
| | | delete _style.fontWeight |
| | | |
| | | _card.style = _style |
| | | _card.wrap.color = color |
| | | _card.wrap.fontSize = fontSize |
| | | _card.wrap.fontWeight = fontWeight |
| | | |
| | | this.setState({ |
| | | card: _card |
| | |
| | | } |
| | | |
| | | updateWrap = (res) => { |
| | | let card = {...this.state.card, wrap: res} |
| | | const { card } = this.state |
| | | |
| | | res.color = card.wrap.color |
| | | res.fontSize = card.wrap.fontSize |
| | | res.fontWeight = card.wrap.fontWeight |
| | | |
| | | let _card = {...card, wrap: res} |
| | | |
| | | if (res.tableType) { |
| | | card.switchable = true |
| | | _card.switchable = true |
| | | } |
| | | |
| | | this.updateComponent(card) |
| | | this.updateComponent(_card) |
| | | } |
| | | |
| | | clickComponent = (e) => { |
| | |
| | | <SearchComponent config={card} updatesearch={this.updateconfig}/> |
| | | <ActionComponent type="editable" config={card} setSubConfig={this.setSubConfig} updateaction={this.updateComponent}/> |
| | | <ColumnComponent config={card} updatecolumn={this.updateconfig}/> |
| | | <div className="component-name"><div className="center">{card.name}</div></div> |
| | | </div> |
| | | ) |
| | | } |
| | |
| | | {value: 'default', label: '大'}, |
| | | {value: 'middle', label: '中'}, |
| | | {value: 'small', label: '小'}, |
| | | // {value: 'mini', label: '微'}, |
| | | {value: 'mini', label: '迷你'}, |
| | | ] |
| | | }, |
| | | { |
| | |
| | | tooltip: '默认值 #e8e8e8。', |
| | | required: false |
| | | }, |
| | | { |
| | | type: 'color', |
| | | field: 'color', |
| | | label: '字体颜色', |
| | | initval: wrap.color || 'rgba(0, 0, 0, 0.65)', |
| | | tooltip: '默认值 rgba(0, 0, 0, 0.65)。', |
| | | required: false |
| | | }, |
| | | { |
| | | type: 'number', |
| | | field: 'fontSize', |
| | | label: '字体大小', |
| | | initval: wrap.fontSize || 14, |
| | | min: 12, |
| | | max: 30, |
| | | precision: 0, |
| | | required: false |
| | | }, |
| | | // { |
| | | // type: 'color', |
| | | // field: 'color', |
| | | // label: '字体颜色', |
| | | // initval: wrap.color || 'rgba(0, 0, 0, 0.65)', |
| | | // tooltip: '默认值 rgba(0, 0, 0, 0.65)。', |
| | | // required: false |
| | | // }, |
| | | // { |
| | | // type: 'number', |
| | | // field: 'fontSize', |
| | | // label: '字体大小', |
| | | // initval: wrap.fontSize || 14, |
| | | // min: 12, |
| | | // max: 30, |
| | | // precision: 0, |
| | | // required: false |
| | | // }, |
| | | { |
| | | type: 'number', |
| | | field: 'advanceWidth', |
| | |
| | | val = column.formula |
| | | if (column.eval === 'false') { |
| | | val = val.replace(/\n/ig, '<br/>').replace(/\s/ig, ' ') |
| | | val = <span dangerouslySetInnerHTML={{__html: val}}></span> |
| | | val = <span style={{fontWeight: 'inherit'}} dangerouslySetInnerHTML={{__html: val}}></span> |
| | | } |
| | | } |
| | | return ( |
| | |
| | | return uuid.join('') |
| | | }) () |
| | | |
| | | if (config.wrap && config.wrap.borderColor) { // 边框颜色 |
| | | let style = `#${tableId} table, #${tableId} tr, #${tableId} th, #${tableId} td {border-color: ${config.wrap.borderColor}}` |
| | | let ele = document.createElement('style') |
| | | ele.innerHTML = style |
| | | document.getElementsByTagName('head')[0].appendChild(ele) |
| | | } |
| | | |
| | | this.setState({ |
| | | tableId, |
| | | columns: fromJS(config.cols).toJS(), |
| | | fields: fromJS(config.columns).toJS(), |
| | | lineMarks: config.lineMarks ? fromJS(config.lineMarks).toJS() : [] |
| | | }, () => { |
| | | const element = document.getElementById(tableId) |
| | | element && element.style.setProperty('--mk-table-border-color', config.wrap.borderColor || '#e8e8e8') |
| | | element && element.style.setProperty('--mk-table-color', config.wrap.color || 'rgba(0, 0, 0, 0.65)') |
| | | element && element.style.setProperty('--mk-table-font-size', config.wrap.fontSize || '14px') |
| | | element && element.style.setProperty('--mk-table-font-weight', config.wrap.fontWeight || 'normal') |
| | | }) |
| | | } |
| | | |
| | |
| | | } |
| | | } else if (!is(fromJS(this.state.fields), fromJS(nextProps.config.columns))) { |
| | | this.setState({fields: fromJS(nextProps.config.columns).toJS()}) |
| | | } else if (this.props.config.wrap.borderColor !== nextProps.config.wrap.borderColor) { |
| | | let style = `#${this.state.tableId} table, #${this.state.tableId} tr, #${this.state.tableId} th, #${this.state.tableId} td {border-color: ${nextProps.config.wrap.borderColor}}` |
| | | let ele = document.createElement('style') |
| | | ele.innerHTML = style |
| | | document.getElementsByTagName('head')[0].appendChild(ele) |
| | | } else if (!is(fromJS(this.props.config.wrap), fromJS(nextProps.config.wrap))) { |
| | | const element = document.getElementById(this.state.tableId) |
| | | element && element.style.setProperty('--mk-table-border-color', nextProps.config.wrap.borderColor || '#e8e8e8') |
| | | element && element.style.setProperty('--mk-table-color', nextProps.config.wrap.color || 'rgba(0, 0, 0, 0.65)') |
| | | element && element.style.setProperty('--mk-table-font-size', nextProps.config.wrap.fontSize || '14px') |
| | | element && element.style.setProperty('--mk-table-font-weight', nextProps.config.wrap.fontWeight || 'normal') |
| | | } |
| | | } |
| | | |
| | |
| | | |
| | | const columns = this.handlecolumns(this.state.columns, fields, config) |
| | | |
| | | let style = {} |
| | | if (config.wrap.color) { |
| | | style.color = config.wrap.color |
| | | } |
| | | if (config.wrap.fontSize) { |
| | | style.fontSize = config.wrap.fontSize |
| | | } |
| | | |
| | | return ( |
| | | <div className={`normal-table-columns ${config.setting.laypage} ${config.wrap.tableType} ${config.wrap.mode || ''}`} id={tableId}> |
| | | <div className="col-control"> |
| | |
| | | rowKey="uuid" |
| | | size={config.wrap.size || 'middle'} |
| | | rowClassName="editable-row" |
| | | style={style} |
| | | bordered={config.wrap.bordered !== 'false'} |
| | | components={components} |
| | | dataSource={this.state.data} |
| | |
| | | .normal-table-columns { |
| | | position: relative; |
| | | --mk-table-border-color: #e8e8e8; |
| | | --mk-table-color: rgba(0, 0, 0, 0.65); |
| | | --mk-table-font-size: 14px; |
| | | --mk-table-font-weight: normal; |
| | | |
| | | .ant-table { |
| | | color: inherit; |
| | | font-size: inherit; |
| | | font-weight: inherit; |
| | | } |
| | | .ant-table-body { |
| | | overflow-x: auto; |
| | |
| | | .ant-table-small > .ant-table-content > .ant-table-body { |
| | | margin: 0; |
| | | } |
| | | |
| | | table, tr, th, td { |
| | | border-color: var(--mk-table-border-color)!important; |
| | | } |
| | | table tr { |
| | | th .ant-table-column-title { |
| | | // color: var(--mk-table-color)!important; |
| | | font-size: var(--mk-table-font-size)!important; |
| | | font-weight: var(--mk-table-font-weight)!important; |
| | | } |
| | | td { |
| | | color: var(--mk-table-color)!important; |
| | | font-size: var(--mk-table-font-size)!important; |
| | | font-weight: var(--mk-table-font-weight)!important; |
| | | } |
| | | } |
| | | } |
| | | .normal-table-columns.false { |
| | | .ant-pagination { |
| | |
| | | changeStyle = () => { |
| | | const { card } = this.state |
| | | |
| | | MKEmitter.emit('changeStyle', [card.uuid], ['background', 'border', 'padding', 'margin', 'shadow'], card.style) |
| | | let style = {...card.style} |
| | | style.color = card.wrap.color || 'rgba(0, 0, 0, 0.65)' |
| | | style.fontSize = card.wrap.fontSize || 14 |
| | | style.fontWeight = card.wrap.fontWeight || 'normal' |
| | | |
| | | MKEmitter.emit('changeStyle', [card.uuid], ['font1', 'background', 'border', 'padding', 'margin', 'shadow'], style) |
| | | } |
| | | |
| | | getStyle = (comIds, style) => { |
| | | const { card } = this.state |
| | | |
| | | if (comIds[0] !== card.uuid) return |
| | | if (comIds[0] !== card.uuid || comIds.length !== 1) return |
| | | |
| | | let _card = {} |
| | | if (comIds.length === 1) { |
| | | _card = {...card, style} |
| | | } else { |
| | | return |
| | | } |
| | | let _card = fromJS(card).toJS() |
| | | let _style = fromJS(style).toJS() |
| | | |
| | | let color = style.color |
| | | let fontSize = style.fontSize |
| | | let fontWeight = style.fontWeight |
| | | |
| | | delete _style.color |
| | | delete _style.fontSize |
| | | delete _style.fontWeight |
| | | |
| | | _card.style = _style |
| | | _card.wrap.color = color |
| | | _card.wrap.fontSize = fontSize |
| | | _card.wrap.fontWeight = fontWeight |
| | | |
| | | this.setState({ |
| | | card: _card |
| | |
| | | } |
| | | |
| | | updateWrap = (res) => { |
| | | this.updateComponent({...this.state.card, wrap: res}) |
| | | const { card } = this.state |
| | | |
| | | res.color = card.wrap.color |
| | | res.fontSize = card.wrap.fontSize |
| | | res.fontWeight = card.wrap.fontWeight |
| | | |
| | | this.updateComponent({...card, wrap: res}) |
| | | } |
| | | |
| | | clickComponent = (e) => { |
| | |
| | | <SearchComponent config={card} updatesearch={this.updateconfig}/> |
| | | <ActionComponent config={card} setSubConfig={this.setSubConfig} updateaction={this.updateComponent}/> |
| | | <ColumnComponent config={card} updatecolumn={this.updateconfig}/> |
| | | <div className="component-name"><div className="center">{card.name}</div></div> |
| | | </div> |
| | | ) |
| | | } |
| | |
| | | {value: 'default', label: '大'}, |
| | | {value: 'middle', label: '中'}, |
| | | {value: 'small', label: '小'}, |
| | | // {value: 'mini', label: '微'}, |
| | | {value: 'mini', label: '迷你'}, |
| | | ] |
| | | }, |
| | | { |
| | |
| | | tooltip: '默认值 #e8e8e8。', |
| | | required: false |
| | | }, |
| | | { |
| | | type: 'color', |
| | | field: 'color', |
| | | label: '字体颜色', |
| | | initval: wrap.color || 'rgba(0, 0, 0, 0.65)', |
| | | tooltip: '默认值 rgba(0, 0, 0, 0.65)。', |
| | | required: false |
| | | }, |
| | | { |
| | | type: 'number', |
| | | field: 'fontSize', |
| | | label: '字体大小', |
| | | initval: wrap.fontSize || 14, |
| | | min: 12, |
| | | max: 30, |
| | | precision: 0, |
| | | required: false |
| | | }, |
| | | // { |
| | | // type: 'color', |
| | | // field: 'color', |
| | | // label: '字体颜色', |
| | | // initval: wrap.color || 'rgba(0, 0, 0, 0.65)', |
| | | // tooltip: '默认值 rgba(0, 0, 0, 0.65)。', |
| | | // required: false |
| | | // }, |
| | | // { |
| | | // type: 'number', |
| | | // field: 'fontSize', |
| | | // label: '字体大小', |
| | | // initval: wrap.fontSize || 14, |
| | | // min: 12, |
| | | // max: 30, |
| | | // precision: 0, |
| | | // required: false |
| | | // }, |
| | | { |
| | | type: 'number', |
| | | field: 'advanceWidth', |
| | |
| | | </Popover> |
| | | <NormalHeader hideSearch="true" config={card} updateComponent={this.updateComponent}/> |
| | | {card.subcards.map(subcard => (<CardSimpleComponent key={subcard.uuid} cards={card} card={subcard} updateElement={this.updateCard}/>))} |
| | | <div className="component-name"><div className="center">{card.name}</div></div> |
| | | </div> |
| | | ) |
| | | } |
| | |
| | | </TreeNode> |
| | | </Tree> |
| | | </div> |
| | | <div className="component-name"><div className="center">{card.name}</div></div> |
| | | </div> |
| | | ) |
| | | } |
| | |
| | | index = i |
| | | } |
| | | |
| | | let label = item.label || '' |
| | | if (item.field && item.field.toLowerCase() !== label.toLowerCase()) { |
| | | label = label + ' (' + item.field + ')' |
| | | } |
| | | |
| | | if (['text', 'number', 'textarea', 'color'].includes(item.type) && card.field !== item.field) { |
| | | _inputfields.push({ |
| | | field: item.field, |
| | | label: _inputIndex + '、' + item.label |
| | | label: _inputIndex + '、' + label |
| | | }) |
| | | _inputIndex++ |
| | | } |
| | | if (card.field !== item.field && item.hidden !== 'true' && ['text', 'number', 'select', 'link'].includes(item.type)) { |
| | | _tabfields.push({ |
| | | field: item.field, |
| | | label: _tabIndex + '、' + item.label |
| | | label: _tabIndex + '、' + label |
| | | }) |
| | | _tabIndex++ |
| | | } |
| | |
| | | if (item.type === 'switch') { |
| | | _linksupFields.push({ |
| | | field: item.field, |
| | | label: _linkIndex + '、' + item.label |
| | | label: _linkIndex + '、' + label |
| | | }) |
| | | } |
| | | |
| | |
| | | }) |
| | | _linksupFields.push({ |
| | | field: item.field, |
| | | label: _linkIndex + '、' + item.label |
| | | label: _linkIndex + '、' + label |
| | | }) |
| | | _linkIndex++ |
| | | } |
| | |
| | | message: '色值最多100个字符!' |
| | | } |
| | | ] |
| | | })(<Input onPressEnter={() => this.props.inputSubmit()}/>)} |
| | | })(<Input placeholder="例如:#1890ff、blue、rgba(0,0,0,0.65)" onPressEnter={() => this.props.inputSubmit()}/>)} |
| | | </Form.Item> |
| | | </Col> : null} |
| | | <Col span={24}> |
| | |
| | | let videos = sessionStorage.getItem('app_videos') |
| | | let colorlist = sessionStorage.getItem('app_colors') |
| | | |
| | | if (!pictures) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '未获取到资源信息,请稍后或刷新重试。', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } |
| | | |
| | | try { |
| | | pictures = JSON.parse(pictures) |
| | | videos = JSON.parse(videos) |
| | |
| | | import moment from 'moment' |
| | | import HTML5Backend from 'react-dnd-html5-backend' |
| | | import { notification, Modal, Collapse, Card, Switch, Button } from 'antd' |
| | | import { EyeOutlined, EyeInvisibleOutlined } from '@ant-design/icons' |
| | | |
| | | import Api from '@/api' |
| | | import Utils from '@/utils/utils.js' |
| | |
| | | oriConfig: null, |
| | | config: null, |
| | | customComponents: [], |
| | | comloading: false |
| | | comloading: false, |
| | | eyeopen: false |
| | | } |
| | | |
| | | UNSAFE_componentWillMount() { |
| | |
| | | }) |
| | | } |
| | | |
| | | getMenuMessage = () => { |
| | | getMenuMessage = (delButtons) => { |
| | | const { config } = this.state |
| | | let buttons = [] |
| | | let _sort = 1 |
| | |
| | | traversal(item.components) |
| | | } else if (item.type === 'card' || (item.type === 'table' && item.subtype === 'tablecard')) { |
| | | item.action && item.action.forEach(btn => { |
| | | if (btn.hidden === 'true') { |
| | | delButtons.push(btn.uuid) |
| | | return |
| | | } |
| | | this.checkBtn(btn) |
| | | buttons.push(`select '${btn.uuid}' as menuid, '${item.name + '-' + btn.label}' as menuname, '${_sort * 10}' as Sort`) |
| | | _sort++ |
| | |
| | | item.subcards && item.subcards.forEach(card => { |
| | | card.elements && card.elements.forEach(cell => { |
| | | if (cell.eleType !== 'button') return |
| | | if (cell.hidden === 'true') { |
| | | delButtons.push(cell.uuid) |
| | | return |
| | | } |
| | | this.checkBtn(cell) |
| | | buttons.push(`select '${cell.uuid}' as menuid, '${item.name + '-' + cell.label}' as menuname, '${_sort * 10}' as Sort`) |
| | | _sort++ |
| | | }) |
| | | card.backElements && card.backElements.forEach(cell => { |
| | | if (cell.eleType !== 'button') return |
| | | if (cell.hidden === 'true') { |
| | | delButtons.push(cell.uuid) |
| | | return |
| | | } |
| | | this.checkBtn(cell) |
| | | buttons.push(`select '${cell.uuid}' as menuid, '${item.name + '-' + cell.label}' as menuname, '${_sort * 10}' as Sort`) |
| | | _sort++ |
| | |
| | | item.subcards.forEach(card => { |
| | | card.elements && card.elements.forEach(cell => { |
| | | if (cell.eleType !== 'button') return |
| | | if (cell.hidden === 'true') { |
| | | delButtons.push(cell.uuid) |
| | | return |
| | | } |
| | | this.checkBtn(cell) |
| | | buttons.push(`select '${cell.uuid}' as menuid, '${item.name + '-' + cell.label}' as menuname, '${_sort * 10}' as Sort`) |
| | | _sort++ |
| | |
| | | } else if (item.type === 'balcony') { |
| | | item.elements && item.elements.forEach(cell => { |
| | | if (cell.eleType !== 'button') return |
| | | if (cell.hidden === 'true') { |
| | | delButtons.push(cell.uuid) |
| | | return |
| | | } |
| | | this.checkBtn(cell) |
| | | buttons.push(`select '${cell.uuid}' as menuid, '${item.name + '-' + cell.label}' as menuname, '${_sort * 10}' as Sort`) |
| | | _sort++ |
| | | }) |
| | | } else if (item.type === 'line' || item.type === 'bar' || item.type === 'chart') { |
| | | item.action && item.action.forEach(btn => { |
| | | if (btn.hidden === 'true') { |
| | | delButtons.push(btn.uuid) |
| | | return |
| | | } |
| | | this.checkBtn(btn) |
| | | buttons.push(`select '${btn.uuid}' as menuid, '${item.name + '-' + btn.label}' as menuname, '${_sort * 10}' as Sort`) |
| | | _sort++ |
| | | }) |
| | | } else if (item.type === 'table' && (item.subtype === 'normaltable' || item.subtype === 'editable')) { |
| | | item.action && item.action.forEach(btn => { |
| | | if (btn.hidden === 'true') { |
| | | delButtons.push(btn.uuid) |
| | | return |
| | | } |
| | | this.checkBtn(btn) |
| | | buttons.push(`select '${btn.uuid}' as menuid, '${item.name + '-' + btn.label}' as menuname, '${_sort * 10}' as Sort`) |
| | | _sort++ |
| | |
| | | item.cols && item.cols.forEach(col => { |
| | | if (col.type !== 'action') return |
| | | col.elements.forEach(btn => { |
| | | if (btn.hidden === 'true') { |
| | | delButtons.push(btn.uuid) |
| | | return |
| | | } |
| | | this.checkBtn(btn) |
| | | buttons.push(`select '${btn.uuid}' as menuid, '${item.name + '-' + btn.label}' as menuname, '${_sort * 10}' as Sort`) |
| | | _sort++ |
| | |
| | | |
| | | submitConfig = () => { |
| | | const { btn } = this.props |
| | | const { delButtons } = this.state |
| | | let config = fromJS(this.state.config).toJS() |
| | | |
| | | if ((config.cacheUseful === 'true' && !config.cacheTime) || !config.MenuNo || !config.MenuName) { |
| | |
| | | LText: [] |
| | | } |
| | | |
| | | let delButtons = fromJS(this.state.delButtons).toJS() |
| | | if (sessionStorage.getItem('appType') === 'pc') { |
| | | param.TypeCharOne = sessionStorage.getItem('kei_no') |
| | | param.Typename = 'pc' |
| | | |
| | | btnParam.LText = '' |
| | | } else { |
| | | btnParam.LText = this.getMenuMessage() |
| | | btnParam.LText = this.getMenuMessage(delButtons) |
| | | btnParam.LText = btnParam.LText.join(' union all ') |
| | | btnParam.LText = Utils.formatOptions(btnParam.LText) |
| | | btnParam.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') |
| | |
| | | |
| | | render () { |
| | | const { btn } = this.props |
| | | const { activeKey, comloading, dict, config, menuloading, customComponents, MenuId } = this.state |
| | | const { activeKey, comloading, dict, config, menuloading, customComponents, MenuId, eyeopen } = this.state |
| | | |
| | | return ( |
| | | <div className="pc-poper-view"> |
| | |
| | | </Panel> |
| | | </Collapse> |
| | | </div> |
| | | <div className={'menu-view ' + (menuloading ? 'saving' : '')}> |
| | | <div className={'menu-view' + (menuloading ? ' saving' : '') + (eyeopen ? ' eye-open' : '')}> |
| | | <Card title={ |
| | | <div> {config && config.MenuName} </div> |
| | | } bordered={false} extra={ |
| | | <div> |
| | | <Button className="mk-border-purple" onClick={() => this.setState({eyeopen: !eyeopen})}>{!eyeopen ? <EyeOutlined /> : <EyeInvisibleOutlined />} 组件名</Button> |
| | | <Versions MenuId={MenuId} open_edition={config ? config.open_edition : ''} updateConfig={this.refreshConfig}/> |
| | | <ReplaceField type="custom" config={config} updateConfig={this.resetConfig}/> |
| | | <StyleCombControlButton menu={config} /> |
| | |
| | | .pc-poper-view { |
| | | background: #000; |
| | | min-height: 100vh; |
| | | |
| | | .eye-open { |
| | | .component-name { |
| | | display: block; |
| | | } |
| | | .anticon-tool { |
| | | display: none; |
| | | } |
| | | } |
| | | |
| | | >.menu-body { |
| | | width: 100vw; |
| | | height: 100vh; |
| | |
| | | changeFontSize = (val) => { |
| | | let value = parseInt(val) |
| | | |
| | | if (isNaN(value) || value < 12 || value > 100) return |
| | | if (isNaN(value)) return |
| | | |
| | | if (value < 12) { |
| | | value = 12 |
| | | } else if (value > 300) { |
| | | value = 300 |
| | | } |
| | | |
| | | this.updateStyle({fontSize: `${value}px`}) |
| | | } |
| | |
| | | {options.includes('font') ? <Panel header="字体" key="font"> |
| | | <Col span={12}> |
| | | <Form.Item colon={false} label={<FontSizeOutlined title="字体大小"/>}> |
| | | <InputNumber defaultValue={card.fontSize || 14} min={12} max={100} precision={0} onChange={this.changeFontSize} /> |
| | | <InputNumber defaultValue={card.fontSize || 14} min={12} max={300} precision={0} onChange={this.changeFontSize} /> |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={12}> |
| | |
| | | </Form.Item> |
| | | </Col> |
| | | </Panel> : null} |
| | | {options.includes('font1') ? <Panel header="字体" key="font1"> |
| | | <Col span={12}> |
| | | <Form.Item colon={false} label={<FontSizeOutlined title="字体大小"/>}> |
| | | <InputNumber defaultValue={card.fontSize || 14} min={12} max={300} precision={0} onChange={this.changeFontSize} /> |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={12}> |
| | | <Form.Item colon={false} label={<BoldOutlined title="字体粗细"/>}> |
| | | <Select defaultValue={card.fontWeight || 'normal'} onChange={this.boldChange}> |
| | | <Option value="normal">normal</Option> |
| | | <Option value="bold">bold</Option> |
| | | <Option value="bolder">bolder</Option> |
| | | <Option value="lighter">lighter</Option> |
| | | <Option value="100">100</Option> |
| | | <Option value="200">200</Option> |
| | | <Option value="300">300</Option> |
| | | <Option value="400">400</Option> |
| | | <Option value="500">500</Option> |
| | | <Option value="600">600</Option> |
| | | <Option value="700">700</Option> |
| | | <Option value="800">800</Option> |
| | | <Option value="900">900</Option> |
| | | </Select> |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={24}> |
| | | <Form.Item |
| | | colon={false} |
| | | label={<FontColorsOutlined title="字体颜色"/>} |
| | | labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} } |
| | | > |
| | | <ColorSketch value={card.color || 'rgba(0, 0, 0, 0.85)'} onChange={this.changeFontColor} /> |
| | | </Form.Item> |
| | | </Col> |
| | | </Panel> : null} |
| | | {options.includes('background') || options.includes('backgroundColor') ? <Panel header="背景" key="background"> |
| | | <Col span={24}> |
| | | <Form.Item |
New file |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { is, fromJS } from 'immutable' |
| | | import { Modal, Button, notification, Spin } from 'antd' |
| | | import { ForkOutlined } from '@ant-design/icons' |
| | | |
| | | import Api from '@/api' |
| | | import G6 from "@antv/g6" |
| | | import MKEmitter from '@/utils/events.js' |
| | | import './index.scss' |
| | | |
| | | class Versions extends Component { |
| | | static propTpyes = { |
| | | config: PropTypes.object, |
| | | MenuId: PropTypes.string |
| | | } |
| | | |
| | | state = { |
| | | visible: false, |
| | | loading: false, |
| | | empty: false |
| | | } |
| | | |
| | | shouldComponentUpdate (nextProps, nextState) { |
| | | return !is(fromJS(this.state), fromJS(nextState)) |
| | | } |
| | | |
| | | trigger = () => { |
| | | const { MenuId, config } = this.props |
| | | |
| | | this.setState({visible: true, loading: true, empty: false}, () => { |
| | | let param = { |
| | | func: 's_get_menu_used_list', |
| | | TypeCharOne: sessionStorage.getItem('kei_no'), |
| | | typename: sessionStorage.getItem('typename'), |
| | | par_menuid: MenuId |
| | | } |
| | | |
| | | Api.getSystemConfig(param).then(result => { |
| | | if (!result.status) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: result.message, |
| | | duration: 5 |
| | | }) |
| | | |
| | | this.setState({empty: true, loading: false}) |
| | | |
| | | return |
| | | } |
| | | |
| | | let data = { |
| | | label: config.MenuName || '空', |
| | | id: MenuId, |
| | | MenuID: config.MenuID, |
| | | MenuName: config.MenuName, |
| | | MenuNo: config.MenuNo, |
| | | children: [] |
| | | } |
| | | |
| | | let allMenus = JSON.parse(sessionStorage.getItem('allMenus')) |
| | | let menuObj = {} |
| | | |
| | | allMenus.forEach(item => { |
| | | menuObj[item.MenuID] = item |
| | | }) |
| | | |
| | | if (result.par_data) { |
| | | result.par_data.forEach((item, i) => { |
| | | |
| | | let cell = { |
| | | label: item.par_menuname, |
| | | id: 'par' + i, |
| | | MenuID: item.par_menuid, |
| | | MenuName: item.par_menuname, |
| | | MenuNo: item.par_menuno, |
| | | deleted: false, |
| | | direction: 'left' |
| | | } |
| | | |
| | | if (menuObj[item.par_menuid]) { |
| | | cell.color = '#5AD8A6' |
| | | |
| | | cell.label = menuObj[item.par_menuid].MenuName || item.par_menuname |
| | | cell.MenuName = menuObj[item.par_menuid].MenuName || item.par_menuname |
| | | cell.MenuNo = menuObj[item.par_menuid].MenuNo || item.par_menuno |
| | | } else { |
| | | cell.color = '#dddddd' |
| | | cell.deleted = true |
| | | } |
| | | |
| | | data.children.push(cell) |
| | | }) |
| | | } |
| | | |
| | | if (result.used_data) { |
| | | result.used_data.forEach((item, i) => { |
| | | |
| | | let cell = { |
| | | label: item.used_menuname, |
| | | id: 'sub' + i, |
| | | MenuID: item.used_menuid, |
| | | MenuName: item.used_menuname, |
| | | MenuNo: '', |
| | | deleted: false, |
| | | direction: 'right' |
| | | } |
| | | |
| | | if (menuObj[item.used_menuid]) { |
| | | cell.color = '#5AD8A6' |
| | | |
| | | cell.label = menuObj[item.used_menuid].MenuName || item.used_menuname |
| | | cell.MenuName = menuObj[item.used_menuid].MenuName || item.used_menuname |
| | | cell.MenuNo = menuObj[item.used_menuid].MenuNo |
| | | } else { |
| | | cell.color = '#dddddd' |
| | | cell.deleted = true |
| | | } |
| | | |
| | | data.children.push(cell) |
| | | }) |
| | | } |
| | | |
| | | if (data.children.length === 0) { |
| | | this.setState({empty: true, loading: false}) |
| | | } else { |
| | | this.setState({loading: false}) |
| | | this.getForks(data) |
| | | } |
| | | }) |
| | | }) |
| | | } |
| | | |
| | | changeMenu = (menu) => { |
| | | if (menu.depth === 0) return |
| | | |
| | | MKEmitter.emit('changeEditMenu', menu) |
| | | } |
| | | |
| | | getForks = (data) => { |
| | | const { Util } = G6 |
| | | const that = this |
| | | |
| | | G6.registerNode( |
| | | 'dice-mind-map-root', { |
| | | jsx: (cfg) => { |
| | | const width = Util.getTextSize(cfg.label, 14)[0] + 12; |
| | | const stroke = cfg.style.stroke || '#096dd9'; |
| | | |
| | | return ` |
| | | <group> |
| | | <rect draggable="true" style={{width: ${width}, height: 30, stroke: ${stroke}, radius: 4}} keyshape> |
| | | <text style={{ fontSize: 14, marginLeft: 6, marginTop: 6 }}>${cfg.label}</text> |
| | | </rect> |
| | | </group> |
| | | `; |
| | | }, |
| | | getAnchorPoints() { |
| | | return [ |
| | | [0, 0.5], |
| | | [1, 0.5], |
| | | ]; |
| | | }, |
| | | }, |
| | | 'single-node', |
| | | ); |
| | | |
| | | G6.registerNode( |
| | | 'dice-mind-map-leaf', { |
| | | jsx: (cfg) => { |
| | | const width = Util.getTextSize(cfg.label, 12)[0] + 24; |
| | | const color = cfg.color; |
| | | |
| | | return ` |
| | | <group> |
| | | <rect draggable="true" style={{width: ${width}, height: 26, cursor: 'pointer', fill: 'transparent' }}> |
| | | <text style={{ fontSize: 12, fill: ${cfg.deleted ? '#959595' : 'black'}, marginLeft: 12, marginTop: 6 }}>${cfg.label}</text> |
| | | </rect> |
| | | <rect style={{ fill: ${color}, width: ${width}, cursor: 'pointer', height: 2, x: 0, y: 32 }} /> |
| | | </group> |
| | | `; |
| | | }, |
| | | getAnchorPoints() { |
| | | return [ |
| | | [0, 0.965], |
| | | [1, 0.965], |
| | | ]; |
| | | }, |
| | | }, |
| | | 'single-node', |
| | | ); |
| | | G6.registerBehavior('dice-mindmap', { |
| | | getEvents() { |
| | | return { |
| | | 'node:dblclick': 'editNode', |
| | | }; |
| | | }, |
| | | editNode(evt) { |
| | | const item = evt.item; |
| | | const model = item.get('model'); |
| | | |
| | | that.changeMenu(model) |
| | | } |
| | | }); |
| | | G6.registerBehavior('scroll-canvas', { |
| | | getEvents: function getEvents() { |
| | | return { |
| | | wheel: 'onWheel', |
| | | }; |
| | | }, |
| | | |
| | | onWheel: function onWheel(ev) { |
| | | const { |
| | | graph |
| | | } = this; |
| | | if (!graph) { |
| | | return; |
| | | } |
| | | if (ev.ctrlKey) { |
| | | const canvas = graph.get('canvas'); |
| | | const point = canvas.getPointByClient(ev.clientX, ev.clientY); |
| | | let ratio = graph.getZoom(); |
| | | if (ev.wheelDelta > 0) { |
| | | ratio += ratio * 0.05; |
| | | } else { |
| | | ratio *= ratio * 0.05; |
| | | } |
| | | graph.zoomTo(ratio, { |
| | | x: point.x, |
| | | y: point.y, |
| | | }); |
| | | } else { |
| | | const x = ev.deltaX || ev.movementX; |
| | | const y = ev.deltaY || ev.movementY || (-ev.wheelDelta * 125) / 3; |
| | | graph.translate(-x, -y); |
| | | } |
| | | ev.preventDefault(); |
| | | }, |
| | | }); |
| | | |
| | | const dataTransform = (data) => { |
| | | const changeData = (d, level = 0, color) => { |
| | | const data = { |
| | | ...d, |
| | | }; |
| | | switch (level) { |
| | | case 0: |
| | | data.type = 'dice-mind-map-root'; |
| | | break; |
| | | default: |
| | | data.type = 'dice-mind-map-leaf'; |
| | | break; |
| | | } |
| | | |
| | | data.hover = false; |
| | | |
| | | if (color) { |
| | | data.color = color; |
| | | } |
| | | |
| | | if (d.children) { |
| | | data.children = d.children.map((child) => changeData(child, level + 1, data.color)); |
| | | } |
| | | return data; |
| | | }; |
| | | return changeData(data); |
| | | }; |
| | | |
| | | const tree = new G6.TreeGraph({ |
| | | container: 'mountNode', |
| | | width: 600, |
| | | height: 350, |
| | | fitView: true, |
| | | fitViewPadding: [10, 20], |
| | | layout: { |
| | | type: 'mindmap', |
| | | direction: 'H', |
| | | getHeight: () => { |
| | | return 16; |
| | | }, |
| | | getWidth: (node) => { |
| | | return node.level === 0 ? |
| | | Util.getTextSize(node.label, 16)[0] + 12 : |
| | | Util.getTextSize(node.label, 12)[0]; |
| | | }, |
| | | getVGap: () => { |
| | | return 10; |
| | | }, |
| | | getHGap: () => { |
| | | return 60; |
| | | }, |
| | | getSide: (node) => { |
| | | return node.data.direction; |
| | | }, |
| | | }, |
| | | defaultEdge: { |
| | | type: 'cubic-horizontal', |
| | | style: { |
| | | lineWidth: 2, |
| | | }, |
| | | }, |
| | | minZoom: 0.5, |
| | | modes: { |
| | | default: ['drag-canvas', 'zoom-canvas', 'dice-mindmap'], |
| | | }, |
| | | }); |
| | | |
| | | tree.data(dataTransform(data)); |
| | | |
| | | tree.render(); |
| | | } |
| | | |
| | | render() { |
| | | const { visible, loading, empty } = this.state |
| | | |
| | | return ( |
| | | <div style={{display: 'inline-block'}}> |
| | | <Button style={{borderColor: 'orange', color: 'orange'}} onClick={this.trigger}><ForkOutlined /> 页面关系图</Button> |
| | | <Modal |
| | | title="" |
| | | wrapClassName="view-nodes-modal" |
| | | visible={visible} |
| | | width={700} |
| | | closable={false} |
| | | maskClosable={false} |
| | | footer={[]} |
| | | destroyOnClose |
| | | > |
| | | <div className="header">页面关系图</div> |
| | | <div className="wrap"> |
| | | {loading ? <Spin size="large" /> : null} |
| | | {empty ? <div className="empty">未查询到页面关联菜单。</div> : null} |
| | | <div className="mountNode" id="mountNode"></div> |
| | | </div> |
| | | <div className="footer"> |
| | | <Button key="cancel" onClick={() => { this.setState({ visible: false })}}>关闭</Button> |
| | | </div> |
| | | </Modal> |
| | | </div> |
| | | ) |
| | | } |
| | | } |
| | | |
| | | export default Versions |
New file |
| | |
| | | .view-nodes-modal { |
| | | .ant-modal-body { |
| | | padding: 20px 50px 20px; |
| | | user-select: none; |
| | | } |
| | | .ant-modal-footer { |
| | | display: none; |
| | | } |
| | | .wrap { |
| | | position: relative; |
| | | height: 350px; |
| | | margin: 10px 0px; |
| | | overflow: hidden; |
| | | |
| | | .ant-spin { |
| | | position: absolute; |
| | | top: calc(50% - 16px); |
| | | left: calc(50% - 16px); |
| | | } |
| | | .empty { |
| | | position: relative; |
| | | text-align: center; |
| | | color: #959595; |
| | | padding-top: 200px; |
| | | } |
| | | .empty + .mountNode { |
| | | opacity: 0; |
| | | } |
| | | } |
| | | .header { |
| | | color: #1890ff; |
| | | font-weight: 500; |
| | | text-align: center; |
| | | font-size: 18px; |
| | | } |
| | | |
| | | .footer { |
| | | text-align: center; |
| | | } |
| | | } |
| | |
| | | </div> |
| | | </Col> |
| | | </div> |
| | | <div className="component-name"><div className="center">{card.name}</div></div> |
| | | </div> |
| | | ) |
| | | } |
| | |
| | | <div className={(card.wrap.layout || 'grid') + '-layout'}> |
| | | {card.subMenus.map((menu, index) => (<MenuComponent key={menu.uuid} cards={card} card={menu} move={this.move} updateElement={this.updateCard} deleteElement={this.deleteCard}/>))} |
| | | </div> |
| | | <div className="component-name"><div className="center">{card.name}</div></div> |
| | | </div> |
| | | ) |
| | | } |
| | |
| | | label: '字体大小', |
| | | initval: setting.iconFont || 20, |
| | | min: 12, |
| | | max: 200, |
| | | max: 300, |
| | | precision: 0, |
| | | required: true |
| | | }, |
| | |
| | | } trigger="hover"> |
| | | <ToolOutlined /> |
| | | </Popover> |
| | | <div className="component-name"><div className="center">{card.name}</div></div> |
| | | </div> |
| | | ) |
| | | } |
| | |
| | | index = i |
| | | } |
| | | |
| | | let label = item.label || '' |
| | | if (item.field && item.field.toLowerCase() !== label.toLowerCase()) { |
| | | label = label + ' (' + item.field + ')' |
| | | } |
| | | |
| | | if (['text', 'number', 'textarea', 'color'].includes(item.type) && card.field !== item.field) { |
| | | _inputfields.push({ |
| | | field: item.field, |
| | | label: _inputIndex + '、' + item.label |
| | | label: _inputIndex + '、' + label |
| | | }) |
| | | _inputIndex++ |
| | | } |
| | | if (card.field !== item.field && item.hidden !== 'true' && ['text', 'number', 'select', 'link'].includes(item.type)) { |
| | | _tabfields.push({ |
| | | field: item.field, |
| | | label: _tabIndex + '、' + item.label |
| | | label: _tabIndex + '、' + label |
| | | }) |
| | | _tabIndex++ |
| | | } |
| | |
| | | if (item.type === 'switch') { |
| | | _linksupFields.push({ |
| | | field: item.field, |
| | | label: _linkIndex + '、' + item.label |
| | | label: _linkIndex + '、' + label |
| | | }) |
| | | } |
| | | |
| | |
| | | }) |
| | | _linksupFields.push({ |
| | | field: item.field, |
| | | label: _linkIndex + '、' + item.label |
| | | label: _linkIndex + '、' + label |
| | | }) |
| | | _linkIndex++ |
| | | } |
| | |
| | | <ToolOutlined /> |
| | | </Popover> |
| | | <LoginForm loginWays={card.loginWays} wrap={card.wrap} /> |
| | | <div className="component-name"><div className="center">{card.name}</div></div> |
| | | </div> |
| | | ) |
| | | } |
| | |
| | | // const host = 'http://qingqiumarket.cn' |
| | | // const service = 'mkwms/' |
| | | |
| | | module.exports = function() {} |
| | | module.exports = function(app) {} |
| | | // module.exports = function(app) { |
| | | // app.use(proxy('/webapi', { |
| | | // target: `${host}/${service}webapi`, |
| | |
| | | // })) |
| | | |
| | | // app.use(proxy('/trans', { |
| | | // target: `${host}/${service}trans`, |
| | | // target: `${host}/${service}`, |
| | | // secure: false, |
| | | // changeOrigin: true, |
| | | // pathRewrite: { |
| | | // '^/trans': '/' |
| | | // } |
| | | // changeOrigin: true |
| | | // })) |
| | | |
| | | // app.use(proxy('/api', { // 旷视面板机接口测试 |
| | | // target: `http://192.168.1.66:80`, |
| | | // secure: false, |
| | | // changeOrigin: true |
| | | // })) |
| | | // } |
| | |
| | | |
| | | // 权限过滤 |
| | | if (this.props.menuType !== 'HS') { |
| | | config.action = config.action.filter(item => permAction[item.uuid]) |
| | | config.action = config.action.filter(item => item.hidden !== 'true' && permAction[item.uuid]) |
| | | config.tabgroups.forEach(group => { |
| | | group.sublist = group.sublist.filter(tab => { |
| | | if (tab.supMenu === 'mainTable') { |
| | |
| | | }) |
| | | }) |
| | | } else { |
| | | config.action = config.action.filter(item => item.hidden !== 'true') |
| | | config.tabgroups.forEach(group => { |
| | | group.sublist = group.sublist.map(tab => { |
| | | if (tab.supMenu === 'mainTable') { |
| | |
| | | config.tabgroups = config.tabgroups.filter(group => group.sublist.length > 0) |
| | | |
| | | let roleId = sessionStorage.getItem('role_id') || '' // 角色ID |
| | | // 视图权限 |
| | | config.charts = config.charts.filter(item => { |
| | | if (item.Hide === 'true') return false |
| | | if (!item.blacklist || item.blacklist.length === 0) return true |
| | | return item.blacklist.filter(v => roleId.indexOf(v) > -1).length === 0 |
| | | }) |
| | | |
| | | if (config.charts.length <= 1) { |
| | | config.expand = true |
| | | let chartId = '' |
| | | |
| | | if (config.charts) { |
| | | // 视图权限 |
| | | config.charts = config.charts.filter(item => { |
| | | if (item.Hide === 'true') return false |
| | | if (!item.blacklist || item.blacklist.length === 0) return true |
| | | return item.blacklist.filter(v => roleId.indexOf(v) > -1).length === 0 |
| | | }) |
| | | |
| | | if (config.charts.length <= 1) { |
| | | config.expand = true |
| | | } |
| | | chartId = config.charts[0] ? config.charts[0].uuid : '' |
| | | } |
| | | let chartId = config.charts[0] ? config.charts[0].uuid : '' |
| | | |
| | | config.search = Utils.initSearchVal(config.search) |
| | | |
| | |
| | | {searchlist && searchlist.length ? |
| | | <MainSearch BID={BID} searchlist={searchlist} setting={setting} menuType={this.props.menuType} refreshdata={this.refreshbysearch}/> : null |
| | | } |
| | | {setting ? <Row className="chart-view" gutter={16}> |
| | | {setting && config.charts ? <Row className="chart-view" gutter={16}> |
| | | {/* 视图组 */} |
| | | {!config.expand ? <Tabs activeKey={chartId} onChange={this.changeChart}> |
| | | {config.charts.map(item => ( |
| | |
| | | } |
| | | })} |
| | | </Row> : null } |
| | | {setting && !config.charts ? <div className="chart-view"> |
| | | <div className="commontable-main-action"> |
| | | <MainAction |
| | | BID={BID} |
| | | setting={setting} |
| | | actions={actions} |
| | | columns={columns} |
| | | dict={this.state.dict} |
| | | MenuID={MenuID} |
| | | selectedData={selectedData} |
| | | ContainerId={this.state.ContainerId} |
| | | /> |
| | | </div> |
| | | <div className="main-table-box"> |
| | | {(setting.tableType === 'radio' || setting.tableType === 'checkbox') && this.state.data && this.state.data.length > 0 ? |
| | | <Switch title="收起" className="main-pickup" checkedChildren="开" unCheckedChildren="关" checked={pickup} onChange={this.pickupChange} /> : null |
| | | } |
| | | <MainTable |
| | | MenuID={MenuID} |
| | | tableId={MenuID} |
| | | pickup={pickup} |
| | | setting={setting} |
| | | columns={columns} |
| | | pageSize={pageSize} |
| | | dict={this.state.dict} |
| | | data={this.state.data} |
| | | total={this.state.total} |
| | | loading={this.state.loading} |
| | | statFValue={this.state.statFValue} |
| | | ContainerId={this.state.ContainerId} |
| | | refreshdata={this.refreshbytable} |
| | | chgSelectData={this.changeSelectedData} |
| | | /> |
| | | </div> |
| | | </div> : null } |
| | | {setting && config.tabgroups.map(group => ( |
| | | <Tabs key={group.uuid}> |
| | | {group.sublist.map(_tab => { |
| | |
| | | MKEmitter.addListener('reloadData', this.reloadData) |
| | | MKEmitter.addListener('syncBalconyData', this.syncBalconyData) |
| | | MKEmitter.addListener('resetSelectLine', this.resetParentParam) |
| | | MKEmitter.addListener('queryModuleParam', this.queryModuleParam) |
| | | MKEmitter.addListener('refreshByButtonResult', this.refreshByButtonResult) |
| | | this.handleTimer() |
| | | } |
| | |
| | | MKEmitter.removeListener('reloadData', this.reloadData) |
| | | MKEmitter.removeListener('syncBalconyData', this.syncBalconyData) |
| | | MKEmitter.removeListener('resetSelectLine', this.resetParentParam) |
| | | MKEmitter.removeListener('queryModuleParam', this.queryModuleParam) |
| | | MKEmitter.removeListener('refreshByButtonResult', this.refreshByButtonResult) |
| | | } |
| | | |
| | |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * @description 导出Excel时,获取页面搜索排序等参数 |
| | | */ |
| | | queryModuleParam = (menuId, btnId) => { |
| | | const { config } = this.state |
| | | |
| | | if (config.uuid !== menuId) return |
| | | |
| | | MKEmitter.emit('returnModuleParam', config.uuid, btnId, { |
| | | arr_field: '', |
| | | orderBy: '', |
| | | search: [], |
| | | menuName: config.name |
| | | }) |
| | | } |
| | | |
| | | reloadData = (menuId) => { |
| | | const { config } = this.state |
| | | |
| | |
| | | const NewPageButton = asyncComponent(() => import('@/tabviews/zshare/actionList/newpagebutton')) |
| | | const ChangeUserButton = asyncComponent(() => import('@/tabviews/zshare/actionList/changeuserbutton')) |
| | | const PrintButton = asyncComponent(() => import('@/tabviews/zshare/actionList/printbutton')) |
| | | const FuncMegvii = asyncComponent(() => import('@/tabviews/zshare/actionList/funcMegvii')) |
| | | const BarCode = asyncElementComponent(() => import('@/components/barcode')) |
| | | const QrCode = asyncElementComponent(() => import('@/components/qrcode')) |
| | | const MkProgress = asyncElementComponent(() => import('@/components/mkProgress')) |
| | |
| | | |
| | | openNewView = (e, card) => { |
| | | const { cardCell, data, cards } = this.props |
| | | |
| | | if (data.$disabled) return |
| | | |
| | | if (card.anchors && card.anchors.length > 0) { |
| | | let id = card.anchors[card.anchors.length - 1] |
| | | let node = document.getElementById('anchor' + id) |
| | | node && node.scrollIntoView({behavior: 'smooth', block: 'center', inline: 'nearest'}) |
| | | } |
| | | |
| | | if (!card.link) return |
| | | e.stopPropagation() |
| | |
| | | } |
| | | } |
| | | |
| | | if (card.link) { |
| | | if (card.link || (card.anchors && card.anchors.length > 0)) { |
| | | _style.cursor = 'pointer' |
| | | } |
| | | |
| | | |
| | | if (card.bgImage && data[card.bgImage]) { |
| | | _style.backgroundImage = `url('${data[card.bgImage]}')` |
| | | } |
| | |
| | | /> |
| | | </Col> |
| | | ) |
| | | } else if (card.funcType === 'megvii') { |
| | | return ( |
| | | <Col key={card.uuid} className="mk-cell-btn" style={card.wrapStyle} span={card.width}> |
| | | <FuncMegvii |
| | | BID={data.$$BID} |
| | | disabled={_disabled} |
| | | lineId={data.$$key || ''} |
| | | btn={card} |
| | | show={card.show} |
| | | style={card.style} |
| | | setting={cards.setting} |
| | | selectedData={_data} |
| | | /> |
| | | </Col> |
| | | ) |
| | | } |
| | | } |
| | | } |
| | |
| | | } |
| | | |
| | | return ( |
| | | <div className="custom-data-card-box" style={config.style}> |
| | | <div className="custom-data-card-box" id={'anchor' + config.uuid} style={config.style}> |
| | | {loading ? |
| | | <div className="loading-mask"> |
| | | {data ? <div className="ant-spin-blur"></div> : null} |
| | |
| | | componentDidMount () { |
| | | MKEmitter.addListener('reloadData', this.reloadData) |
| | | MKEmitter.addListener('resetSelectLine', this.resetParentParam) |
| | | MKEmitter.addListener('queryModuleParam', this.queryModuleParam) |
| | | MKEmitter.addListener('refreshByButtonResult', this.refreshByButtonResult) |
| | | this.handleTimer() |
| | | } |
| | |
| | | } |
| | | MKEmitter.removeListener('reloadData', this.reloadData) |
| | | MKEmitter.removeListener('resetSelectLine', this.resetParentParam) |
| | | MKEmitter.removeListener('queryModuleParam', this.queryModuleParam) |
| | | MKEmitter.removeListener('refreshByButtonResult', this.refreshByButtonResult) |
| | | } |
| | | |
| | |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * @description 导出Excel时,获取页面搜索排序等参数 |
| | | */ |
| | | queryModuleParam = (menuId, btnId) => { |
| | | const { mainSearch } = this.props |
| | | const { config } = this.state |
| | | |
| | | if (config.uuid !== menuId) return |
| | | |
| | | let searches = config.setting.useMSearch && mainSearch ? mainSearch : [] |
| | | |
| | | MKEmitter.emit('returnModuleParam', config.uuid, btnId, { |
| | | arr_field: '', |
| | | orderBy: '', |
| | | search: searches, |
| | | menuName: config.name |
| | | }) |
| | | } |
| | | |
| | | reloadData = (menuId) => { |
| | | const { config } = this.state |
| | | |
| | |
| | | if (config.wrap.empty === 'hidden' && (!data || data.$$empty)) return null |
| | | |
| | | return ( |
| | | <div className="custom-prop-card-box" style={config.style}> |
| | | <div className="custom-prop-card-box" id={'anchor' + config.uuid} style={config.style}> |
| | | {loading ? |
| | | <div className="loading-mask"> |
| | | <div className="ant-spin-blur"></div> |
| | |
| | | if (config.wrap.empty === 'hidden' && (!data || data.length === 0)) return null |
| | | |
| | | return ( |
| | | <div className="custom-table-card-box" style={{...config.style}}> |
| | | <div className="custom-table-card-box" id={'anchor' + config.uuid} style={{...config.style}}> |
| | | {loading ? |
| | | <div className="loading-mask"> |
| | | {data ? <div className="ant-spin-blur"></div> : null} |
| | |
| | | if (config.wrap.empty === 'hidden' && (!data || data.length === 0)) return null |
| | | |
| | | return ( |
| | | <div className="custom-data-carousel-box" style={config.style}> |
| | | <div className="custom-data-carousel-box" id={'anchor' + config.uuid} style={config.style}> |
| | | {loading ? |
| | | <div className="loading-mask"> |
| | | {data ? <div className="ant-spin-blur"></div> : null} |
| | |
| | | componentDidMount () { |
| | | MKEmitter.addListener('reloadData', this.reloadData) |
| | | MKEmitter.addListener('resetSelectLine', this.resetParentParam) |
| | | MKEmitter.removeListener('refreshByButtonResult', this.refreshByButtonResult) |
| | | MKEmitter.addListener('queryModuleParam', this.queryModuleParam) |
| | | MKEmitter.addListener('refreshByButtonResult', this.refreshByButtonResult) |
| | | } |
| | | |
| | | shouldComponentUpdate (nextProps, nextState) { |
| | |
| | | } |
| | | MKEmitter.removeListener('reloadData', this.reloadData) |
| | | MKEmitter.removeListener('resetSelectLine', this.resetParentParam) |
| | | MKEmitter.removeListener('queryModuleParam', this.queryModuleParam) |
| | | MKEmitter.removeListener('refreshByButtonResult', this.refreshByButtonResult) |
| | | } |
| | | |
| | |
| | | this.loadData() |
| | | }) |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * @description 导出Excel时,获取页面搜索排序等参数 |
| | | */ |
| | | queryModuleParam = (menuId, btnId) => { |
| | | const { mainSearch } = this.props |
| | | const { config } = this.state |
| | | |
| | | if (config.uuid !== menuId) return |
| | | |
| | | let searches = config.setting.useMSearch && mainSearch ? mainSearch : [] |
| | | |
| | | MKEmitter.emit('returnModuleParam', config.uuid, btnId, { |
| | | arr_field: '', |
| | | orderBy: '', |
| | | search: searches, |
| | | menuName: config.name |
| | | }) |
| | | } |
| | | |
| | | reloadData = (menuId) => { |
| | |
| | | if (config.wrap.empty === 'hidden' && (!data || data.$$empty)) return null |
| | | |
| | | return ( |
| | | <div className="custom-prop-carousel-box" style={config.style}> |
| | | <div className="custom-prop-carousel-box" id={'anchor' + config.uuid} style={config.style}> |
| | | {loading ? |
| | | <div className="loading-mask"> |
| | | <div className="ant-spin-blur"></div> |
| | |
| | | marker: { symbol: item.chartType === 'bar' ? 'square' : 'hyphen', style: { stroke: item.color,fill: item.color, r: 5, lineWidth: 2 } } |
| | | }) |
| | | |
| | | if ((!_config.plot.Bar_axis || item.chartType !== 'bar') && item.show) { // 折线图或重叠下的柱状图可单独设置显示类型 |
| | | vFieldsShow[item.type] = item.show |
| | | if (!_config.plot.Bar_axis || item.chartType !== 'bar') { // 折线图或重叠下的柱状图可单独设置显示类型 |
| | | if (item.show) { |
| | | vFieldsShow[item.type] = item.show |
| | | } else { |
| | | item.show = _config.plot.show |
| | | } |
| | | } |
| | | }) |
| | | _config.plot.customs = fields |
| | |
| | | |
| | | chart.on('element:click', (ev) => { |
| | | let data = ev.data.data |
| | | |
| | | MKEmitter.emit('resetSelectLine', config.uuid, (data ? data.$$uuid : ''), data) |
| | | |
| | | if (plot.click === 'menus') { |
| | | let menu = null |
| | | |
| | | if (plot.menus && plot.menus.length > 0) { |
| | | let s = data[plot.menuType] || '' |
| | | plot.menus.forEach(m => { |
| | | if (s !== m.sign) return |
| | | menu = m |
| | | }) |
| | | } |
| | | if (!menu || !menu.MenuID) return |
| | | |
| | | menu.type = menu.tabType |
| | | |
| | | let newtab = { |
| | | ...menu, |
| | | param: {} |
| | | } |
| | | |
| | | if (plot.joint === 'true') { |
| | | newtab.param.$BID = data.$$uuid || '' |
| | | } |
| | | |
| | | if (['linkage_navigation', 'linkage', 'menu_board'].includes(window.GLOB.navBar)) { |
| | | MKEmitter.emit('modifyTabs', newtab, 'replace') |
| | | } else { |
| | | MKEmitter.emit('modifyTabs', newtab, 'plus', true) |
| | | } |
| | | } else if (plot.click === 'menu' && plot.MenuID) { |
| | | let menu = { |
| | | MenuID: plot.MenuID, |
| | | MenuName: plot.MenuName, |
| | | MenuNo: plot.MenuNo, |
| | | type: plot.tabType |
| | | } |
| | | |
| | | let newtab = { |
| | | ...menu, |
| | | param: {} |
| | | } |
| | | |
| | | if (plot.joint === 'true') { |
| | | newtab.param.$BID = data.$$uuid || '' |
| | | } |
| | | |
| | | if (['linkage_navigation', 'linkage', 'menu_board'].includes(window.GLOB.navBar)) { |
| | | MKEmitter.emit('modifyTabs', newtab, 'replace') |
| | | } else { |
| | | MKEmitter.emit('modifyTabs', newtab, 'plus', true) |
| | | } |
| | | } |
| | | }) |
| | | |
| | | if (plot.interaction && plot.interaction.length) { |
| | |
| | | } |
| | | |
| | | return ( |
| | | <div className="custom-line-chart-plot-box" style={style}> |
| | | <div className="custom-line-chart-plot-box" id={'anchor' + config.uuid} style={style}> |
| | | {loading ? |
| | | <div className="loading-mask"> |
| | | <div className="ant-spin-blur"></div> |
| | |
| | | const { config, loading } = this.state |
| | | |
| | | return ( |
| | | <div className="custom-dashboard-plot-box" style={config.style}> |
| | | <div className="custom-dashboard-plot-box" id={'anchor' + config.uuid} style={config.style}> |
| | | {loading ? |
| | | <div className="loading-mask"> |
| | | <div className="ant-spin-blur"></div> |
| | |
| | | } |
| | | |
| | | return ( |
| | | <div className="custom-pie-chart-plot-box" style={style}> |
| | | <div className="custom-pie-chart-plot-box" id={'anchor' + config.uuid} style={style}> |
| | | {loading ? |
| | | <div className="loading-mask"> |
| | | <div className="ant-spin-blur"></div> |
| | |
| | | } |
| | | |
| | | return ( |
| | | <div className="custom-scatter-plot-box" style={style}> |
| | | <div className="custom-scatter-plot-box" id={'anchor' + config.uuid} style={style}> |
| | | {loading ? |
| | | <div className="loading-mask"> |
| | | <div className="ant-spin-blur"></div> |
| | |
| | | const { config, loading, empty, BID } = this.state |
| | | |
| | | return ( |
| | | <div className="custom-chart-plot-box" style={config.style}> |
| | | <div className="custom-chart-plot-box" id={'anchor' + config.uuid} style={config.style}> |
| | | {loading ? |
| | | <div className="loading-mask"> |
| | | <div className="ant-spin-blur"></div> |
| | |
| | | const { config, loading, html } = this.state |
| | | |
| | | return ( |
| | | <div className="custom-sand-box" style={{...config.style}}> |
| | | <div className="custom-sand-box" id={'anchor' + config.uuid} style={{...config.style}}> |
| | | {loading ? |
| | | <div className="loading-mask"> |
| | | <div className="ant-spin-blur"></div> |
| | |
| | | const { config, loading, data } = this.state |
| | | |
| | | return ( |
| | | <div className="custom-braft-editor-box" style={config.style}> |
| | | <div className="custom-braft-editor-box" id={'anchor' + config.uuid} style={config.style}> |
| | | {loading ? |
| | | <div className="loading-mask"> |
| | | <div className="ant-spin-blur"></div> |
| | |
| | | const { config, loading, BID, data, group, dict, step } = this.state |
| | | |
| | | return ( |
| | | <div className="custom-normal-form-box" style={{...config.style}}> |
| | | <div className="custom-normal-form-box" id={'anchor' + config.uuid} style={{...config.style}}> |
| | | {loading ? |
| | | <div className="loading-mask"> |
| | | <div className="ant-spin-blur"></div> |
| | |
| | | const { config, loading, BID, data, group, dict } = this.state |
| | | |
| | | return ( |
| | | <div className="custom-tab-form-box" style={{...config.style}}> |
| | | <div className="custom-tab-form-box" id={'anchor' + config.uuid} style={{...config.style}}> |
| | | {loading ? |
| | | <div className="loading-mask"> |
| | | <div className="ant-spin-blur"></div> |
| | |
| | | content = content.replace(/\d{1,3}(?=(\d{3})+(\.\d*)?$)/g, '$&,') |
| | | } |
| | | |
| | | content = col.prefix + content + col.postfix |
| | | content = (col.prefix || '') + content + (col.postfix || '') |
| | | } |
| | | |
| | | if (col.marks) { |
| | |
| | | let photos = '' |
| | | if (record[col.field]) { |
| | | photos = `${record[col.field]}` |
| | | photos = photos.split(',') |
| | | } |
| | | |
| | | if (/^data:image/.test(photos)) { |
| | | photos = [photos] |
| | | } else { |
| | | photos = photos.split(',').filter(Boolean) |
| | | } |
| | | |
| | | let cols = 24 / (col.picSort || 1) |
| | |
| | | } |
| | | |
| | | if (content) { |
| | | content = col.prefix + content + col.postfix |
| | | content = (col.prefix || '') + content + (col.postfix || '') |
| | | } |
| | | |
| | | if (col.blur) { |
| | |
| | | return uuid.join('') |
| | | }) () |
| | | |
| | | if (setting.borderColor) { // 边框颜色 |
| | | let style = `#${tableId} table, #${tableId} tr, #${tableId} th, #${tableId} td {border-color: ${setting.borderColor}}` |
| | | let ele = document.createElement('style') |
| | | ele.innerHTML = style |
| | | document.getElementsByTagName('head')[0].appendChild(ele) |
| | | } |
| | | // if (setting.borderColor) { // 边框颜色 |
| | | // let style = `#${tableId} table, #${tableId} tr, #${tableId} th, #${tableId} td {border-color: ${setting.borderColor}}` |
| | | // let ele = document.createElement('style') |
| | | // ele.innerHTML = style |
| | | // document.getElementsByTagName('head')[0].appendChild(ele) |
| | | // } |
| | | |
| | | let size = (setting.pageSize || 10) + '' |
| | | let pageOptions = ['10', '25', '50', '100', '500', '1000'] |
| | |
| | | rowspans, |
| | | tableId, |
| | | orderfields |
| | | }, () => { |
| | | const element = document.getElementById(tableId) |
| | | element && element.style.setProperty('--mk-table-border-color', setting.borderColor || '#e8e8e8') |
| | | element && element.style.setProperty('--mk-table-color', setting.color || 'rgba(0, 0, 0, 0.65)') |
| | | element && element.style.setProperty('--mk-table-font-size', setting.fontSize || '14px') |
| | | element && element.style.setProperty('--mk-table-font-weight', setting.fontWeight || 'normal') |
| | | }) |
| | | } |
| | | |
| | |
| | | } |
| | | <Table |
| | | components={components} |
| | | style={setting.style} |
| | | // style={setting.style} |
| | | size={setting.size || 'middle'} |
| | | bordered={setting.bordered !== 'false'} |
| | | rowSelection={rowSelection} |
| | |
| | | .normal-custom-table { |
| | | position: relative; |
| | | padding: 0px; |
| | | --mk-table-border-color: #e8e8e8; |
| | | --mk-table-color: rgba(0, 0, 0, 0.65); |
| | | --mk-table-font-size: 14px; |
| | | --mk-table-font-weight: normal; |
| | | |
| | | .normal-table-footer { |
| | | padding: 10px 0px; |
| | |
| | | display: block; |
| | | } |
| | | } |
| | | |
| | | table, tr, th, td { |
| | | border-color: var(--mk-table-border-color)!important; |
| | | } |
| | | table tr { |
| | | th .ant-table-column-title { |
| | | // color: var(--mk-table-color)!important; |
| | | font-size: var(--mk-table-font-size)!important; |
| | | font-weight: var(--mk-table-font-weight)!important; |
| | | } |
| | | td { |
| | | color: var(--mk-table-color)!important; |
| | | font-size: var(--mk-table-font-size)!important; |
| | | font-weight: var(--mk-table-font-weight)!important; |
| | | |
| | | >span, div:not(.card-cell-list), div:not(.card-cell-list) div, div:not(.card-cell-list) span { |
| | | font-weight: var(--mk-table-font-weight)!important; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | .normal-custom-table:not(.fixed-height) { |
| | | .ant-table-body::-webkit-scrollbar { |
| | |
| | | const { BID, BData } = this.props |
| | | let _config = fromJS(this.props.config).toJS() |
| | | let _cols = new Map() |
| | | let setting = {..._config.setting, ..._config.wrap, style: {}} |
| | | let setting = {..._config.setting, ..._config.wrap} |
| | | setting.tableId = Utils.getuuid() |
| | | |
| | | _config.submit.style = _config.submit.style || {} |
| | |
| | | } |
| | | } |
| | | |
| | | if (setting.color) { |
| | | setting.style.color = setting.color |
| | | } |
| | | if (setting.fontSize) { |
| | | setting.style.fontSize = setting.fontSize |
| | | } |
| | | // if (setting.color) { |
| | | // setting.style.color = setting.color |
| | | // } |
| | | // if (setting.fontSize) { |
| | | // setting.style.fontSize = setting.fontSize |
| | | // } |
| | | |
| | | if (!_config.lineMarks || _config.lineMarks.length === 0) { |
| | | _config.lineMarks = null |
| | |
| | | const { BID, setting, searchlist, actions, config, columns, BData, selectedData, lock } = this.state |
| | | |
| | | return ( |
| | | <div className="custom-edit-table" style={config.style}> |
| | | <div className="custom-edit-table" id={'anchor' + config.uuid} style={config.style}> |
| | | <NormalHeader config={config}/> |
| | | {searchlist && searchlist.length ? |
| | | <MainSearch BID={BID} setting={config.wrap} searchlist={searchlist} menuType={this.props.menuType} refreshdata={this.refreshbysearch}/> : null |
| | |
| | | content = content.replace(/\d{1,3}(?=(\d{3})+(\.\d*)?$)/g, '$&,') |
| | | } |
| | | |
| | | content = col.prefix + content + col.postfix |
| | | content = (col.prefix || '') + content + (col.postfix || '') |
| | | } |
| | | |
| | | if (col.marks) { |
| | |
| | | } |
| | | |
| | | if (content) { |
| | | content = col.prefix + content + col.postfix |
| | | content = (col.prefix || '') + content + (col.postfix || '') |
| | | } |
| | | |
| | | children = ( |
| | |
| | | content = content.replace(/\d{1,3}(?=(\d{3})+(\.\d*)?$)/g, '$&,') |
| | | } |
| | | |
| | | content = col.prefix + content + col.postfix |
| | | content = (col.prefix || '') + content + (col.postfix || '') |
| | | } |
| | | |
| | | if (col.marks) { |
| | |
| | | } |
| | | |
| | | if (content) { |
| | | content = col.prefix + content + col.postfix |
| | | content = (col.prefix || '') + content + (col.postfix || '') |
| | | } |
| | | |
| | | children = ( |
| | |
| | | }) |
| | | } |
| | | |
| | | if (setting.borderColor) { // 边框颜色 |
| | | let style = `#${setting.tableId} table, #${setting.tableId} tr, #${setting.tableId} th, #${setting.tableId} td {border-color: ${setting.borderColor}}` |
| | | let ele = document.createElement('style') |
| | | ele.innerHTML = style |
| | | document.getElementsByTagName('head')[0].appendChild(ele) |
| | | } |
| | | // if (setting.borderColor) { // 边框颜色 |
| | | // let style = `#${setting.tableId} table, #${setting.tableId} tr, #${setting.tableId} th, #${setting.tableId} td {border-color: ${setting.borderColor}}` |
| | | // let ele = document.createElement('style') |
| | | // ele.innerHTML = style |
| | | // document.getElementsByTagName('head')[0].appendChild(ele) |
| | | // } |
| | | |
| | | let size = (setting.pageSize || 10) + '' |
| | | let pageOptions = ['10', '25', '50', '100', '500', '1000'] |
| | |
| | | if (deForms.length > 0) { |
| | | this.improveActionForm(deForms) |
| | | } |
| | | |
| | | const element = document.getElementById(setting.tableId) |
| | | element && element.style.setProperty('--mk-table-border-color', setting.borderColor || '#e8e8e8') |
| | | element && element.style.setProperty('--mk-table-color', setting.color || 'rgba(0, 0, 0, 0.65)') |
| | | element && element.style.setProperty('--mk-table-font-size', setting.fontSize || '14px') |
| | | element && element.style.setProperty('--mk-table-font-weight', setting.fontWeight || 'normal') |
| | | }) |
| | | } |
| | | |
| | |
| | | <Table |
| | | rowKey="$$uuid" |
| | | components={components} |
| | | style={setting.style} |
| | | // style={setting.style} |
| | | size={setting.size || 'middle'} |
| | | bordered={setting.bordered !== 'false'} |
| | | rowSelection={rowSelection} |
| | |
| | | position: relative; |
| | | min-height: 150px; |
| | | padding: 0px; |
| | | --mk-table-border-color: #e8e8e8; |
| | | --mk-table-color: rgba(0, 0, 0, 0.65); |
| | | --mk-table-font-size: 14px; |
| | | --mk-table-font-weight: normal; |
| | | |
| | | .normal-table-footer { |
| | | padding: 10px 0px; |
| | |
| | | bottom: 2px; |
| | | right: 5px; |
| | | opacity: 0.7; |
| | | font-size: 14px; |
| | | } |
| | | |
| | | table { |
| | |
| | | margin-top: 10px!important; |
| | | margin-right: 10px!important; |
| | | } |
| | | |
| | | table, tr, th, td { |
| | | border-color: var(--mk-table-border-color)!important; |
| | | } |
| | | table tr { |
| | | th .ant-table-column-title, th .ant-table-column-title span:not(.anticon) { |
| | | // color: var(--mk-table-color)!important; |
| | | font-size: var(--mk-table-font-size)!important; |
| | | font-weight: var(--mk-table-font-weight)!important; |
| | | } |
| | | td { |
| | | color: var(--mk-table-color)!important; |
| | | font-size: var(--mk-table-font-size)!important; |
| | | font-weight: var(--mk-table-font-weight)!important; |
| | | |
| | | >span, div:not(.card-cell-list), div:not(.card-cell-list) div, div:not(.card-cell-list) span { |
| | | font-weight: var(--mk-table-font-weight)!important; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | .edit-custom-table.buoyMode { |
| | | .ant-table-scroll { |
| | |
| | | } |
| | | } |
| | | |
| | | let setting = {..._config.setting, ..._config.wrap, style: {}} |
| | | let setting = {..._config.setting, ..._config.wrap} |
| | | |
| | | if (setting.selected !== 'always' && setting.selected !== 'init') { |
| | | setting.selected = 'false' |
| | |
| | | } |
| | | }) |
| | | |
| | | if (setting.color) { |
| | | setting.style.color = setting.color |
| | | } |
| | | if (setting.fontSize) { |
| | | setting.style.fontSize = setting.fontSize |
| | | } |
| | | // if (setting.color) { |
| | | // setting.style.color = setting.color |
| | | // } |
| | | // if (setting.fontSize) { |
| | | // setting.style.fontSize = setting.fontSize |
| | | // } |
| | | |
| | | if (_config.wrap.collapse === 'true') { |
| | | _config.wrap.title = _config.wrap.title || ' ' |
| | |
| | | } |
| | | |
| | | return ( |
| | | <div className="custom-normal-table" style={style}> |
| | | <div className="custom-normal-table" id={'anchor' + config.uuid} style={style}> |
| | | {config.wrap.collapse === 'true' ? <Collapse bordered={false} defaultActiveKey="1" expandIconPosition="right"> |
| | | <Panel forceRender={true} header={<NormalHeader config={config}/>} key="1"> |
| | | {searchlist && searchlist.length ? |
| | |
| | | const { config, loading, data } = this.state |
| | | |
| | | return ( |
| | | <div className="normal-timeline-box" style={{...config.style}}> |
| | | <div className="normal-timeline-box" id={'anchor' + config.uuid} style={{...config.style}}> |
| | | {loading ? |
| | | <div className="loading-mask"> |
| | | {data ? <div className="ant-spin-blur"></div> : null} |
| | |
| | | const { config, loading, treeNodes, expandedKeys, selectedKeys } = this.state |
| | | |
| | | return ( |
| | | <div className="custom-tree-box" style={config.style}> |
| | | <div className="custom-tree-box" id={'anchor' + config.uuid} style={config.style}> |
| | | {loading ? |
| | | <div className="loading-mask"> |
| | | <div className="ant-spin-blur"></div> |
| | |
| | | delete item.style.shadowColor |
| | | } |
| | | |
| | | item.$menuname = this.props.MenuName + '-' + (item.name || '') |
| | | item.$menuname = (this.props.MenuName || '') + '-' + (item.name || '') |
| | | |
| | | if (item.type === 'tabs') { |
| | | if ( |
| | |
| | | let tabId = this.props.Tab ? this.props.Tab.uuid : '' // 弹窗标签按钮Id |
| | | if (item.action && item.action.length > 0) { |
| | | item.action = item.action.filter(cell => { |
| | | if (item.hidden === 'true') return false |
| | | |
| | | cell.logLabel = item.$menuname + '-' + cell.label |
| | | cell.ContainerId = this.state.ContainerId |
| | | cell.syncComponentId = cell.syncComponent ? (cell.syncComponent.pop() || '') : '' |
| | |
| | | |
| | | card.elements = card.elements.filter(cell => { |
| | | if (cell.eleType === 'button') { |
| | | if (cell.hidden === 'true') return false |
| | | |
| | | cell.logLabel = item.$menuname + '-' + cell.label |
| | | cell.Ot = cell.Ot || 'requiredSgl' |
| | | cell.ContainerId = this.state.ContainerId |
| | |
| | | }) |
| | | card.backElements = card.backElements.filter(cell => { |
| | | if (cell.eleType === 'button') { |
| | | if (cell.hidden === 'true') return false |
| | | |
| | | cell.logLabel = item.$menuname + '-' + cell.label |
| | | cell.Ot = cell.Ot || 'requiredSgl' |
| | | cell.ContainerId = this.state.ContainerId |
| | |
| | | } |
| | | item.elements = item.elements.filter(cell => { |
| | | if (cell.eleType === 'button') { |
| | | if (cell.hidden === 'true') return false |
| | | |
| | | cell.logLabel = item.$menuname + '-' + cell.label |
| | | cell.ContainerId = this.state.ContainerId |
| | | cell.syncComponentId = cell.syncComponent ? (cell.syncComponent.pop() || '') : '' |
| | |
| | | let _hasheight = card.style.height && card.style.height !== 'auto' |
| | | card.elements = card.elements.filter(cell => { |
| | | if (cell.eleType === 'button') { |
| | | if (cell.hidden === 'true') return false |
| | | |
| | | cell.logLabel = item.$menuname + '-' + cell.label |
| | | cell.Ot = cell.Ot || 'requiredSgl' |
| | | cell.ContainerId = this.state.ContainerId |
| | |
| | | item.cols = item.cols.filter(col => { |
| | | if (col.type !== 'action') return true |
| | | col.elements = col.elements.filter(cell => { |
| | | if (cell.hidden === 'true') return false |
| | | |
| | | cell.logLabel = item.$menuname + '-' + cell.label |
| | | cell.Ot = cell.Ot || 'requiredSgl' |
| | | cell.ContainerId = this.state.ContainerId |
| | |
| | | |
| | | // 权限过滤 |
| | | if (this.props.menuType !== 'HS') { |
| | | config.action = config.action.filter(item => permAction[item.uuid]) |
| | | config.action = config.action.filter(item => item.hidden !== 'true' && permAction[item.uuid]) |
| | | } else { |
| | | config.action = config.action.filter(item => item.hidden !== 'true') |
| | | } |
| | | |
| | | config.search = Utils.initSearchVal(config.search) |
| | |
| | | return col |
| | | }) |
| | | |
| | | // 视图权限 |
| | | config.charts = config.charts.filter(item => { |
| | | if (item.Hide === 'true') return false |
| | | if (!item.blacklist || item.blacklist.length === 0) return true |
| | | return item.blacklist.filter(v => roleId.indexOf(v) > -1).length === 0 |
| | | }) |
| | | |
| | | if (config.charts.length <= 1) { |
| | | config.expand = true |
| | | let chartId = '' |
| | | if (config.charts) { |
| | | // 视图权限 |
| | | config.charts = config.charts.filter(item => { |
| | | if (item.Hide === 'true') return false |
| | | if (!item.blacklist || item.blacklist.length === 0) return true |
| | | return item.blacklist.filter(v => roleId.indexOf(v) > -1).length === 0 |
| | | }) |
| | | |
| | | if (config.charts.length <= 1) { |
| | | config.expand = true |
| | | } |
| | | |
| | | chartId = config.charts[0] ? config.charts[0].uuid : '' |
| | | } |
| | | |
| | | let chartId = config.charts[0] ? config.charts[0].uuid : '' |
| | | |
| | | // 1、筛选字段集,2、过滤隐藏列及合并列中的字段uuid |
| | | config.columns.forEach(col => { |
| | |
| | | {searchlist && searchlist.length ? |
| | | <SubSearch BID={BID} setting={setting} searchlist={searchlist} menuType={this.props.menuType} refreshdata={this.refreshbysearch}/> : null |
| | | } |
| | | {config ? <Row className="chart-view" gutter={16}> |
| | | {config && config.charts ? <Row className="chart-view" gutter={16}> |
| | | {/* 视图组 */} |
| | | {!config.expand ? <Tabs activeKey={chartId} onChange={this.changeChart}> |
| | | {config.charts.map(item => ( |
| | |
| | | } |
| | | })} |
| | | </Row> : null } |
| | | {config && !config.charts ? <> |
| | | <div className="sub-action"> |
| | | <SubAction |
| | | BID={BID} |
| | | BData={BData} |
| | | setting={setting} |
| | | actions={actions} |
| | | columns={columns} |
| | | Tab={this.props.Tab} |
| | | MenuID={this.props.MenuID} |
| | | selectedData={selectedData} |
| | | ContainerId={this.props.ContainerId} |
| | | /> |
| | | </div> |
| | | <div className="subtable-box"> |
| | | {(setting.tableType === 'radio' || setting.tableType === 'checkbox') && this.state.data && this.state.data.length > 0 ? |
| | | <Switch title="收起" className="subtable-pickup" checkedChildren="开" unCheckedChildren="关" checked={pickup} onChange={this.pickupChange} /> : null |
| | | } |
| | | <SubTable |
| | | BData={BData} |
| | | tableId={this.props.Tab.uuid} |
| | | pickup={pickup} |
| | | setting={setting} |
| | | columns={columns} |
| | | pageSize={pageSize} |
| | | dict={this.state.dict} |
| | | data={this.state.data} |
| | | total={this.state.total} |
| | | MenuID={this.props.MenuID} |
| | | loading={this.state.loading} |
| | | statFValue={this.state.statFValue} |
| | | ContainerId={this.props.ContainerId} |
| | | refreshdata={this.refreshbytable} |
| | | chgSelectData={this.changeSelectedData} |
| | | /> |
| | | </div> |
| | | </> : null } |
| | | {viewlost ? <NotFount msg={this.state.lostmsg} /> : null} |
| | | </div> |
| | | ) |
| | |
| | | |
| | | // 权限过滤 |
| | | if (this.props.menuType !== 'HS') { |
| | | config.action = config.action.filter(item => permAction[item.uuid]) |
| | | config.action = config.action.filter(item => item.hidden !== 'true' && permAction[item.uuid]) |
| | | } else { |
| | | config.action = config.action.filter(item => item.hidden !== 'true') |
| | | } |
| | | |
| | | config.search = Utils.initSearchVal(config.search) |
| | |
| | | btn.verify.columns.forEach(op => { |
| | | 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) { |
| | | |
| | | if (!_name && !iserror) { |
| | | iserror = true |
| | | errors = 'headerError' |
| | | errDetail = `Excel中不存在(${_text})列!` |
| | | } else if (_name !== _text && !iserror) { |
| | | iserror = true |
| | | errors = 'headerError' |
| | | errDetail = `Excel中(${_name})与按钮列信息(${_text})不一致!` |
| | |
| | | MKEmitter.emit('popclose') |
| | | } else if (btn.execSuccess !== 'never') { |
| | | MKEmitter.emit('refreshByButtonResult', btn.$menuId, btn.execSuccess, btn, '', this.state.selines) |
| | | } else { |
| | | btn.syncComponentId && MKEmitter.emit('reloadData', btn.syncComponentId) |
| | | } |
| | | |
| | | if (btn.switchTab && btn.switchTab.length > 0) { |
| | | let id = btn.switchTab[btn.switchTab.length - 1] |
| | | let node = document.getElementById('tab' + id) |
| | |
| | | return |
| | | } |
| | | |
| | | if (btn.intertype === 'system' && setting.interType !== 'system') { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '导出按钮配置错误!', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } else if (btn.intertype === 'inner' && !btn.innerFunc) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '导出按钮配置错误!', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } else if (!btn.verify || !btn.verify.columns || btn.verify.columns.length === 0) { |
| | | if (!btn.verify || !btn.verify.columns || btn.verify.columns.length === 0) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '请设置导出列!', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } else if (btn.intertype === 'system' && setting.interType !== 'system' && btn.verify.dataType !== 'custom') { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '导出按钮配置错误!', |
| | | duration: 5 |
| | | }) |
| | | return |
| | |
| | | let name = `${viewParam.menuName}${moment().format('YYYYMMDDHHmmss')}.xlsx` |
| | | let pageSize = 1000 |
| | | |
| | | if (btn.search === 'true' && viewParam.search && viewParam.search.length > 0) { |
| | | if (((btn.intertype === 'system' && btn.verify.dataType === 'custom' && btn.verify.useSearch === 'true') || btn.intertype !== 'system' || btn.verify.dataType !== 'custom') && btn.search === 'true' && viewParam.search && viewParam.search.length > 0) { |
| | | let valid = false |
| | | viewParam.search.forEach(item => { |
| | | if (item.value || item.value === 0) { |
| | |
| | | } |
| | | } |
| | | |
| | | if (btn.intertype === 'system' && !viewParam.arr_field) { // 使用系统函数 |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '未设置显示列!', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } else if (btn.intertype === 'system' && btn.verify && btn.verify.enable === 'true') { |
| | | if (btn.intertype === 'system') { // 使用系统函数 |
| | | if (btn.verify.dataType !== 'custom' && !viewParam.arr_field) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '按钮需自定义导出数据!', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } else if (btn.verify.dataType === 'custom') { |
| | | viewParam.arr_field = [] |
| | | btn.verify.columns.forEach(col => { |
| | | if (col.Column && col.Column !== '$Index') { |
| | | viewParam.arr_field.push(col.Column) |
| | | } |
| | | }) |
| | | viewParam.arr_field = viewParam.arr_field.join(',') |
| | | |
| | | viewParam.orderBy = btn.verify.order || viewParam.orderBy |
| | | } |
| | | } |
| | | if (btn.intertype === 'system' && btn.verify.enable === 'true') { |
| | | this.setState({search: fromJS(viewParam.search).toJS()}) |
| | | } |
| | | if (btn.intertype === 'system' && btn.verify.dataType === 'custom' && btn.verify.useSearch === 'false') { |
| | | viewParam.search = [] |
| | | } |
| | | |
| | | viewParam.orderBy = viewParam.orderBy || viewParam.arr_field.split(',')[0] |
| | | |
| | | this.updateStatus('start', name) |
| | | |
| | |
| | | getExcelDefaultParam = (arr_field, orderBy, search, pagination = false, pageIndex = 1, pageSize = 100) => { |
| | | const { setting, btn } = this.props |
| | | |
| | | let defaultSql = setting.execute || setting.default || 'true' |
| | | let customScript = setting.customScript || '' |
| | | let _dataresource = setting.dataresource || '' |
| | | let queryType = setting.queryType |
| | | let transaction = setting.transaction |
| | | |
| | | if (btn.verify.dataType === 'custom') { |
| | | defaultSql = btn.verify.defaultSql || 'true' |
| | | _dataresource = btn.verify.dataresource || '' |
| | | queryType = btn.verify.queryType |
| | | transaction = btn.verify.transaction |
| | | |
| | | if (/\s/.test(_dataresource)) { |
| | | _dataresource = '(' + _dataresource + ') tb' |
| | | } |
| | | customScript = '' |
| | | btn.verify.scripts && btn.verify.scripts.forEach(script => { |
| | | if (script.status !== 'false') { |
| | | customScript += ` |
| | | ${script.sql} |
| | | ` |
| | | } |
| | | }) |
| | | |
| | | if (sessionStorage.getItem('dataM') === 'true') { // 数据权限 |
| | | _dataresource = _dataresource.replace(/\$@/ig, '/*') |
| | | _dataresource = _dataresource.replace(/@\$/ig, '*/') |
| | | customScript = customScript.replace(/\$@/ig, '/*') |
| | | customScript = customScript.replace(/@\$/ig, '*/') |
| | | } else { |
| | | _dataresource = _dataresource.replace(/@\$|\$@/ig, '') |
| | | customScript = customScript.replace(/@\$|\$@/ig, '') |
| | | } |
| | | } |
| | | |
| | | let _search = Utils.joinMainSearchkey(search) |
| | | |
| | | _search = _search ? 'where ' + _search : '' |
| | |
| | | func: 'sPC_Get_TableData', |
| | | obj_name: 'data', |
| | | arr_field: arr_field, |
| | | custom_script: setting.customScript, |
| | | default_sql: setting.default || 'true', |
| | | custom_script: customScript, |
| | | default_sql: defaultSql, |
| | | menuname: btn.logLabel |
| | | } |
| | | |
| | |
| | | userName = sessionStorage.getItem('CloudUserName') || '' |
| | | fullName = sessionStorage.getItem('CloudFullName') || '' |
| | | } |
| | | |
| | | let _dataresource = setting.dataresource |
| | | |
| | | let regoptions = null |
| | | if (setting.queryType === 'statistics' || param.custom_script) { |
| | | if (queryType === 'statistics' || param.custom_script) { |
| | | let allSearch = Utils.getAllSearchOptions(search) |
| | | |
| | | regoptions = allSearch.map(item => { |
| | |
| | | value: fullName |
| | | }, { |
| | | reg: new RegExp('@orderBy@', 'ig'), |
| | | value: orderBy |
| | | value: orderBy || '' |
| | | }, { |
| | | reg: new RegExp('@pageSize@', 'ig'), |
| | | value: pageSize |
| | |
| | | }) |
| | | } |
| | | |
| | | if (setting.queryType === 'statistics') { // 统计数据源,内容替换 |
| | | if (queryType === 'statistics') { // 统计数据源,内容替换 |
| | | regoptions.forEach(item => { |
| | | _dataresource = _dataresource.replace(item.reg, item.value) |
| | | }) |
| | |
| | | |
| | | let LText = '' |
| | | |
| | | if (setting.default !== 'false' && !pagination) { |
| | | if (defaultSql !== 'false' && !pagination) { |
| | | LText = ` select ${arr_field} from (select ${arr_field} ,ROW_NUMBER() over(order by ${orderBy}) as rows from ${_dataresource} ${_search}) tmptable order by tmptable.rows ` |
| | | } else if (setting.default !== 'false') { |
| | | } else if (defaultSql !== 'false') { |
| | | LText = ` select top ${pageSize} ${arr_field} from (select ${arr_field} ,ROW_NUMBER() over(order by ${orderBy}) as rows from ${_dataresource} ${_search}) tmptable where rows > ${pageSize * (pageIndex - 1)} order by tmptable.rows ` |
| | | } |
| | | |
| | |
| | | insert into tmp_err_retmsg (ID, ErrorCode, retmsg, CreateUserID) select @time_id@,@ErrorCode, @retmsg,@UserID@ |
| | | ` |
| | | } |
| | | } else if (LText) { |
| | | LText = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(50),@mk_organization nvarchar(50),@login_city nvarchar(50) select @ErrorCode='',@retmsg ='',@UserName='${userName}', @FullName='${fullName}', @RoleID='${RoleID}', @mk_departmentcode='${departmentcode}', @mk_organization='${organization}', @login_city='${city}' |
| | | ${LText} |
| | | ` |
| | | } |
| | | |
| | | // 测试系统打印查询语句 |
| | |
| | | param.open_key = Utils.encryptOpenKey(param.secretkey, param.timestamp) |
| | | } |
| | | |
| | | if (setting.transaction === 'true') { |
| | | if (transaction === 'true') { |
| | | param.func = 'sPC_Get_TableData_try' |
| | | } |
| | | |
| | |
| | | MKEmitter.emit('popclose') |
| | | } else if (btn.execSuccess !== 'never') { |
| | | MKEmitter.emit('refreshByButtonResult', btn.$menuId, btn.execSuccess, btn, '', []) |
| | | } else { |
| | | btn.syncComponentId && MKEmitter.emit('reloadData', btn.syncComponentId) |
| | | } |
| | | |
| | | if (btn.switchTab && btn.switchTab.length > 0) { |
| | | let id = btn.switchTab[btn.switchTab.length - 1] |
| | | let node = document.getElementById('tab' + id) |
New file |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { withRouter } from 'react-router' |
| | | import { is, fromJS } from 'immutable' |
| | | import { Button, Modal, notification, message } from 'antd' |
| | | import CryptoJS from 'crypto-js' |
| | | import moment from 'moment' |
| | | |
| | | import NApi from '@/api' |
| | | import Utils from '@/utils/utils.js' |
| | | import Api from '@/api/w4k.js' |
| | | import MKEmitter from '@/utils/events.js' |
| | | import MkIcon from '@/components/mk-icon' |
| | | |
| | | // import { mockdata } from './mock' |
| | | |
| | | import './index.scss' |
| | | |
| | | class FuncButton extends Component { |
| | | static propTpyes = { |
| | | btn: PropTypes.object, // 按钮 |
| | | disabled: PropTypes.any, // 行按钮禁用 |
| | | } |
| | | |
| | | state = { |
| | | loading: false, |
| | | disabled: false, |
| | | loadingNumber: '', |
| | | hidden: false, |
| | | IpList: [], |
| | | lines: [], |
| | | selectIp: {}, |
| | | visible: false |
| | | } |
| | | |
| | | UNSAFE_componentWillMount () { |
| | | const { btn, selectedData } = this.props |
| | | let disabled = false |
| | | |
| | | if (btn.controlField && selectedData && selectedData.length > 0) { // 表格中按钮隐藏控制 |
| | | selectedData.forEach(item => { |
| | | let s = item[btn.controlField] !== undefined ? item[btn.controlField] + '' : '' |
| | | if (btn.controlVals.includes(s)) { |
| | | disabled = true |
| | | } |
| | | }) |
| | | this.setState({hidden: disabled && btn.control === 'hidden'}) |
| | | } |
| | | |
| | | if (this.props.disabled || disabled) { |
| | | this.setState({disabled: true}) |
| | | } |
| | | } |
| | | |
| | | componentDidMount () { |
| | | MKEmitter.addListener('triggerBtnId', this.actionTrigger) |
| | | } |
| | | |
| | | UNSAFE_componentWillReceiveProps (nextProps) { |
| | | const { btn, selectedData } = this.props |
| | | |
| | | let disabled = false |
| | | if (btn.controlField && !is(fromJS(nextProps.selectedData || []), fromJS(selectedData || []))) { |
| | | if (nextProps.selectedData && nextProps.selectedData.length > 0) { // 表格中按钮隐藏控制 |
| | | nextProps.selectedData.forEach(item => { |
| | | let s = item[btn.controlField] !== undefined ? item[btn.controlField] + '' : '' |
| | | if (btn.controlVals.includes(s)) { |
| | | disabled = true |
| | | } |
| | | }) |
| | | } |
| | | this.setState({hidden: disabled && btn.control === 'hidden'}) |
| | | } |
| | | |
| | | if (nextProps.disabled || disabled) { |
| | | this.setState({disabled: true}) |
| | | } else { |
| | | this.setState({disabled: false}) |
| | | } |
| | | } |
| | | |
| | | shouldComponentUpdate (nextProps, nextState) { |
| | | return !is(fromJS(this.state), fromJS(nextState)) |
| | | } |
| | | |
| | | componentWillUnmount () { |
| | | this.setState = () => { |
| | | return |
| | | } |
| | | MKEmitter.removeListener('triggerBtnId', this.actionTrigger) |
| | | } |
| | | |
| | | /** |
| | | * @description 触发按钮操作 |
| | | */ |
| | | actionTrigger = (triggerId, record, type) => { |
| | | const { Tab, BID, btn, selectedData, setting } = this.props |
| | | const { loading, disabled } = this.state |
| | | |
| | | if (loading || disabled) return |
| | | if (triggerId) { |
| | | if (btn.uuid !== triggerId) return |
| | | if (this.props.lineId && record && record[0] && this.props.lineId !== record[0].$$key) { |
| | | return |
| | | } |
| | | } |
| | | |
| | | if (((Tab && Tab.supMenu) || setting.supModule) && !BID) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '需要上级主键值!', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } else if (type === 'linkbtn' && selectedData && selectedData.length === 1) { |
| | | if (record[0].$Index !== selectedData[0].$Index) { |
| | | return |
| | | } |
| | | } |
| | | |
| | | let data = record || selectedData || [] |
| | | // let data = fromJS(mockdata.data).toJS() |
| | | |
| | | if (data.length === 0) { |
| | | // 需要选择行时,校验数据 |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '请选择行!', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } |
| | | |
| | | this.setState({ |
| | | loading: true, |
| | | lines: data |
| | | }) |
| | | |
| | | this.getIpList() |
| | | } |
| | | |
| | | getIpList = () => { |
| | | let _scriptSql = `select ID,data_code,data_name,Remark,face_ip,face_uname,face_pwd from bd_data where typecharone='face_device' and deleted=0` |
| | | |
| | | _scriptSql = Utils.formatOptions(_scriptSql) |
| | | |
| | | let _sParam = { |
| | | func: 'sPC_Get_SelectedList', |
| | | LText: _scriptSql, |
| | | obj_name: 'data', |
| | | arr_field: 'ID,data_code,data_name,Remark,face_ip,face_uname,face_pwd' |
| | | } |
| | | |
| | | _sParam.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') |
| | | _sParam.secretkey = Utils.encrypt(_sParam.LText, _sParam.timestamp) |
| | | |
| | | NApi.getSystemCacheConfig(_sParam).then(res => { |
| | | if (res.status) { |
| | | let IpList = res.data || [] |
| | | |
| | | if (IpList.length === 0) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '未获取到设备信息!', |
| | | duration: 5 |
| | | }) |
| | | this.setState({ |
| | | loading: false |
| | | }) |
| | | } else { |
| | | this.setState({ |
| | | IpList: IpList.map(item => { |
| | | if (item.face_ip) { |
| | | if (!/^http:/.test(item.face_ip)) { |
| | | item.face_ip = 'http://' + item.face_ip |
| | | } |
| | | if (!/:\d{2,4}$/.test(item.face_ip)) { |
| | | item.face_ip = item.face_ip + ':80' |
| | | } |
| | | } |
| | | return item |
| | | }), |
| | | selectIp: {}, |
| | | visible: true |
| | | }) |
| | | } |
| | | } else { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: res.message, |
| | | duration: 5 |
| | | }) |
| | | } |
| | | }) |
| | | } |
| | | |
| | | loginDevice = () => { |
| | | const { lines, selectIp } = this.state |
| | | |
| | | // 上报接口设置:工程模式-场景模式-开放接口设置-数据上报设置-数据上报服务器地址(开启服务器二次鉴权) |
| | | // let ip = 'http://localhost:3001' |
| | | let ip = selectIp.face_ip |
| | | |
| | | Api.login(ip, selectIp.face_uname, selectIp.face_pwd).then(result => { |
| | | if (result.errors) { |
| | | this.execPreError(result) |
| | | return |
| | | } |
| | | |
| | | document.cookie = 'sessionID=' + result.session_id |
| | | |
| | | Api.queryUsers(ip).then(res => { |
| | | if (res.errors) { |
| | | this.execPreError(res) |
| | | return |
| | | } |
| | | |
| | | let persons = {} |
| | | res.data.forEach(item => { |
| | | persons[item.id] = true |
| | | }) |
| | | |
| | | let data = lines.map(cell => { |
| | | let item = {} |
| | | Object.keys(cell).forEach(key => { |
| | | item[key.toLowerCase()] = cell[key] |
| | | }) |
| | | |
| | | return { |
| | | deleted: persons[item.id] || false, |
| | | recognition_type: item.recognition_type || 'staff', |
| | | is_admin: item.is_admin === 'true', |
| | | person_name: item.person_name || '', |
| | | id: item.id || '', |
| | | card_number: item.card_number || '', |
| | | person_code: item.person_code || '', |
| | | group_list: item.group_list ? item.group_list.split(',') : [1], |
| | | password: item.password || '', |
| | | id_number: item.id_number || '', |
| | | face_list: [{ |
| | | idx: item.face_idx || 0, |
| | | data: item.face_data ? item.face_data.replace(/^data:image\/(jpeg|png|jpg|gif);base64,/, '') : '', |
| | | }] |
| | | } |
| | | }) |
| | | |
| | | this.addUser(ip, data, result.session_id) |
| | | }) |
| | | }, err => { |
| | | this.execPreError(err) |
| | | }) |
| | | } |
| | | |
| | | addUser = (ip, datas, sessionId) => { |
| | | let data = datas.shift() |
| | | |
| | | this.setState({ |
| | | loadingNumber: datas.length || '' |
| | | }) |
| | | |
| | | let error = '' |
| | | if (!data.person_name) { |
| | | error = '人员名称不可为空' |
| | | } else if (!data.id) { |
| | | error = '人员id不可为空' |
| | | } else if (!data.face_list[0].data) { |
| | | error = '人员图片不可为空' |
| | | } else if (data.password) { |
| | | if (/^\d{6}$/.test(data.password)) { |
| | | let key = CryptoJS.enc.Utf8.parse(sessionId) |
| | | let srcs = CryptoJS.enc.Utf8.parse(data.password) |
| | | let encrypted = CryptoJS.AES.encrypt(srcs, key, {mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7}) |
| | | |
| | | data.password = CryptoJS.enc.Base64.stringify(encrypted.ciphertext) |
| | | } else { |
| | | error = '密码使用6位数字' |
| | | } |
| | | } |
| | | |
| | | if (error) { |
| | | this.execError({ErrCode: 'E', ErrMesg: error}) |
| | | return |
| | | } |
| | | |
| | | if (data.id_number) { |
| | | let key = CryptoJS.enc.Utf8.parse(sessionId) |
| | | let srcs = CryptoJS.enc.Utf8.parse(data.id_number) |
| | | let encrypted = CryptoJS.AES.encrypt(srcs, key, {mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7}) |
| | | |
| | | data.id_number = CryptoJS.enc.Base64.stringify(encrypted.ciphertext) |
| | | } |
| | | |
| | | Api.addUsers(ip, data).then(res => { |
| | | if (res.errors) { |
| | | this.execPreError(res, data) |
| | | return |
| | | } |
| | | if (datas.length > 0) { |
| | | this.addUser(ip, datas, sessionId) |
| | | } else { |
| | | this.execSuccess({ErrCode: 'S', ErrMesg: '执行成功。'}) |
| | | } |
| | | }, (err) => { |
| | | this.execPreError(err, data) |
| | | }) |
| | | } |
| | | |
| | | /** |
| | | * @description 操作成功后处理 |
| | | * 1、excel导出,成功后取消导出按钮加载中状态 |
| | | * 2、状态码为 S 时,显示成功信息后系统默认信息 |
| | | * 3、状态码为 -1 时,不显示任何信息 |
| | | * 4、模态框执行成功后是否关闭 |
| | | * 5、通知主列表刷新 |
| | | */ |
| | | execSuccess = (res) => { |
| | | const { btn } = this.props |
| | | |
| | | if (res && (res.ErrCode === 'S' || !res.ErrCode)) { // 执行成功 |
| | | notification.success({ |
| | | top: 92, |
| | | message: res.ErrMesg || '执行成功', |
| | | duration: btn.verify && btn.verify.stime ? btn.verify.stime : 2 |
| | | }) |
| | | } else if (res && res.ErrCode === 'Y') { // 执行成功 |
| | | Modal.success({ |
| | | title: res.ErrMesg || '执行成功' |
| | | }) |
| | | } else if (res && res.ErrCode === '-1') { // 完成后不提示 |
| | | |
| | | } |
| | | |
| | | this.setState({ |
| | | loading: false, |
| | | loadingNumber: '' |
| | | }) |
| | | |
| | | // if (btn.execSuccess !== 'never') { |
| | | // MKEmitter.emit('refreshByButtonResult', btn.$menuId, btn.execSuccess, btn) |
| | | // } |
| | | } |
| | | |
| | | execPreError = (err, data) => { |
| | | if (err.data && err.data.errors && err.data.errors[0]) { |
| | | let error = err.data.errors[0] |
| | | let message = error.detail |
| | | if (error.source.pointer === '/api/persons/item' && error.error_code) { |
| | | let list = [ |
| | | {val: 1, msg: '图片格式错误'}, |
| | | {val: 2, msg: '图片大小超出限制'}, |
| | | {val: 3, msg: '图片分辨率超出限制'}, |
| | | {val: 16, msg: '人脸无特征值'}, |
| | | {val: 17, msg: '入库无图片'}, |
| | | {val: 18, msg: '未检测到人脸'}, |
| | | {val: 19, msg: '检测到多个人脸'}, |
| | | {val: 20, msg: '人脸太小'}, |
| | | {val: 21, msg: '图片太亮'}, |
| | | {val: 22, msg: '图片太暗'}, |
| | | {val: 23, msg: '人脸太模糊'}, |
| | | {val: 24, msg: '人脸方向错误'}, |
| | | {val: 32, msg: '数据库满'}, |
| | | {val: 33, msg: '人脸图片重复'}, |
| | | {val: 34, msg: '人员编号重复'}, |
| | | {val: 35, msg: '卡号重复'}, |
| | | {val: 48, msg: '人员名称重复'}, |
| | | {val: -1, msg: '未知错误'}, |
| | | {val: -2141716476, msg: '系统参数错误,有可能是人员组不存在。'}, |
| | | ] |
| | | |
| | | list.forEach(item => { |
| | | if (item.val === error.error_code) { |
| | | message = (data ? data.person_name + ' - ' : '') + item.msg |
| | | } |
| | | }) |
| | | } |
| | | |
| | | this.execError({ |
| | | ErrCode: 'E', |
| | | message: message |
| | | }) |
| | | } else { |
| | | this.execError({ |
| | | ErrCode: 'E', |
| | | message: '请检查设备状态!' |
| | | }) |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * @description 操作失败后处理 |
| | | */ |
| | | execError = (res) => { |
| | | const { btn } = this.props |
| | | |
| | | if (res.ErrCode === 'E') { |
| | | Modal.error({ |
| | | title: res.message || res.ErrMesg, |
| | | }) |
| | | } else if (res.ErrCode === 'N') { |
| | | notification.error({ |
| | | top: 92, |
| | | message: res.message || res.ErrMesg, |
| | | duration: btn.verify && btn.verify.ntime ? btn.verify.ntime : 10 |
| | | }) |
| | | } else if (res.ErrCode === 'F') { |
| | | notification.error({ |
| | | className: 'notification-custom-error', |
| | | top: 92, |
| | | message: res.message || res.ErrMesg, |
| | | duration: btn.verify && btn.verify.ftime ? btn.verify.ftime : 10 |
| | | }) |
| | | } else if (res.ErrCode === 'NM') { |
| | | message.error(res.message || res.ErrMesg) |
| | | } |
| | | |
| | | this.setState({ |
| | | loading: false, |
| | | loadingNumber: '' |
| | | }) |
| | | |
| | | // if (btn.execError !== 'never') { |
| | | // MKEmitter.emit('refreshByButtonResult', btn.$menuId, btn.execError, btn) |
| | | // } |
| | | } |
| | | |
| | | handleOk = () => { |
| | | const { selectIp } = this.state |
| | | |
| | | if (!selectIp.ID) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '请选择面板机!', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } else if (!selectIp.face_ip) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '面板机IP缺失!', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } else if (!selectIp.face_uname) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '面板机用户名缺失!', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } else if (!selectIp.face_pwd) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '面板机密码缺失!', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } |
| | | |
| | | this.setState({ |
| | | visible: false |
| | | }) |
| | | |
| | | this.loginDevice() |
| | | } |
| | | |
| | | getModels = () => { |
| | | const { IpList, visible, selectIp } = this.state |
| | | |
| | | return ( |
| | | <Modal |
| | | title="请选择面板机" |
| | | maskClosable={false} |
| | | getContainer={document.body} |
| | | wrapClassName='ip-list-modal' |
| | | visible={visible} |
| | | width={700} |
| | | onOk={this.handleOk} |
| | | onCancel={() => this.setState({visible: false, loading: false})} |
| | | destroyOnClose |
| | | > |
| | | {IpList.map(item => { |
| | | return <div className={'ip-item' + (selectIp.ID === item.ID ? ' active' : '')} key={item.ID} onClick={() => {this.setState({selectIp: item})}}> |
| | | <div className="ip">IP:{item.face_ip}</div> |
| | | <div className="user">用户:{item.face_uname}</div> |
| | | <div className="remark">备注:{item.Remark}</div> |
| | | </div> |
| | | })} |
| | | </Modal> |
| | | ) |
| | | } |
| | | |
| | | render() { |
| | | const { btn, show } = this.props |
| | | const { loading, disabled, hidden, loadingNumber } = this.state |
| | | |
| | | if (hidden) return null |
| | | |
| | | if (show === 'actionList') { |
| | | return ( |
| | | <> |
| | | <Button |
| | | icon={btn.icon} |
| | | loading={loading} |
| | | disabled={disabled} |
| | | title={disabled ? (btn.reason || '') : ''} |
| | | className={'mk-btn mk-' + btn.class} |
| | | onClick={(e) => {e.stopPropagation(); this.actionTrigger()}} |
| | | >{(loadingNumber ? `(${loadingNumber})` : '') + btn.label}</Button> |
| | | {this.getModels()} |
| | | </> |
| | | ) |
| | | } else { // icon、text、 all 卡片 |
| | | let label = '' |
| | | let icon = '' |
| | | |
| | | if (show === 'button') { |
| | | label = btn.label |
| | | icon = btn.icon || '' |
| | | } else if (show === 'link') { |
| | | label = <span>{btn.label}{btn.icon ? <MkIcon style={{marginLeft: '8px'}} type={btn.icon}/> : ''}</span> |
| | | icon = '' |
| | | } else if (show === 'icon') { |
| | | icon = btn.icon || '' |
| | | } else { |
| | | label = btn.label |
| | | } |
| | | |
| | | return ( |
| | | <> |
| | | <Button |
| | | type="link" |
| | | title={disabled ? (btn.reason || '') : (show === 'icon' ? btn.label : '')} |
| | | loading={loading} |
| | | disabled={disabled} |
| | | style={btn.style} |
| | | icon={icon} |
| | | onClick={(e) => {e.stopPropagation(); this.actionTrigger()}} |
| | | >{label}</Button> |
| | | {this.getModels()} |
| | | </> |
| | | ) |
| | | } |
| | | } |
| | | } |
| | | |
| | | export default withRouter(FuncButton) |
New file |
| | |
| | | .ip-list-modal { |
| | | .ip-item { |
| | | display: inline-block; |
| | | border: 1px solid #d9d9d9; |
| | | padding: 10px; |
| | | height: 100px; |
| | | width: calc(33% - 20px); |
| | | margin: 10px; |
| | | cursor: pointer; |
| | | .ip { |
| | | color: #000000; |
| | | } |
| | | .remark { |
| | | word-break: break-all; |
| | | text-overflow: ellipsis; |
| | | display: -webkit-box; |
| | | -webkit-box-orient: vertical; |
| | | -webkit-line-clamp: 2; |
| | | overflow: hidden; |
| | | } |
| | | } |
| | | .ip-item.active { |
| | | border-color: var(--antd-wave-shadow-color); |
| | | box-shadow: 0 0 2px var(--antd-wave-shadow-color); |
| | | } |
| | | } |
New file |
| | |
| | | export const mockdata = { |
| | | data: [ |
| | | { |
| | | "recognition_type": "staff", |
| | | "id": "2226169", |
| | | "type": "persons", |
| | | "is_admin": "true", |
| | | "person_name": "king", |
| | | "card_number": "mk001", |
| | | "person_code": "2018", |
| | | "id_number": "130982193002054729", |
| | | "group_list": "1", |
| | | "face_data":"" |
| | | }, |
| | | { |
| | | "recognition_type": "staff", |
| | | "id": "3272487", |
| | | "is_admin": 'false', |
| | | "person_name": "jinfei", |
| | | "card_number": "mk002", |
| | | "person_code": "02", |
| | | "id_number": "", |
| | | "group_list": "1", |
| | | "face_data": "" |
| | | } |
| | | ] |
| | | } |
| | |
| | | const NewPageButton = asyncComponent(() => import('./newpagebutton')) |
| | | const ChangeUserButton = asyncComponent(() => import('./changeuserbutton')) |
| | | const PrintButton = asyncComponent(() => import('./printbutton')) |
| | | const FuncMegvii = asyncComponent(() => import('./funcMegvii')) |
| | | |
| | | class ActionList extends Component { |
| | | static propTpyes = { |
| | |
| | | |
| | | getButtonList = (actions) => { |
| | | const { BID, BData, MenuID, Tab, columns, setting, ContainerId, selectedData, lock } = this.props |
| | | |
| | | return actions.map(item => { |
| | | if (['exec', 'prompt', 'pop'].includes(item.OpenType)) { |
| | | return ( |
| | |
| | | return ( |
| | | <NewPageButton |
| | | key={item.uuid} |
| | | show="actionList" |
| | | show={item.show || 'actionList'} |
| | | disabled={lock || false} |
| | | btn={item} |
| | | BData={BData} |
| | |
| | | selectedData={selectedData} |
| | | /> |
| | | ) |
| | | } else if (item.funcType === 'megvii') { |
| | | return ( |
| | | <FuncMegvii |
| | | key={item.uuid} |
| | | show={item.show || 'actionList'} |
| | | disabled={lock || false} |
| | | BID={BID} |
| | | Tab={Tab} |
| | | btn={item} |
| | | setting={setting} |
| | | selectedData={selectedData} |
| | | /> |
| | | ) |
| | | } |
| | | } |
| | | return null |
| | |
| | | MKEmitter.emit('popclose') |
| | | } else if (btn.execSuccess !== 'never') { |
| | | MKEmitter.emit('refreshByButtonResult', btn.$menuId, btn.execSuccess, btn, id, this.state.selines) |
| | | } else { |
| | | btn.syncComponentId && MKEmitter.emit('reloadData', btn.syncComponentId) |
| | | } |
| | | |
| | | if (tabId) { |
| | |
| | | let id = btn.switchTab[btn.switchTab.length - 1] |
| | | let node = document.getElementById('tab' + id) |
| | | node && node.click() |
| | | } |
| | | if (btn.anchors && btn.anchors.length > 0) { |
| | | let id = btn.anchors[btn.anchors.length - 1] |
| | | let node = document.getElementById('anchor' + id) |
| | | node && node.scrollIntoView({behavior: 'smooth', block: 'center', inline: 'nearest'}) |
| | | } |
| | | |
| | | if (btn.openmenu && btn.openmenu.length > 0 && btn.MenuID) { |
| | |
| | | */ |
| | | improveAction = () => { |
| | | const { btn } = this.props |
| | | const { btnconfig, autoMatic } = this.state |
| | | const { btnconfig } = this.state |
| | | |
| | | if (btnconfig) { |
| | | if (!autoMatic && (btnconfig.setting.display === 'prompt' || btnconfig.setting.display === 'exec')) { // 如果表单以是否框展示 |
| | | if (btnconfig.setting.display === 'prompt' || btnconfig.setting.display === 'exec') { // 如果表单以是否框展示 |
| | | this.modelconfirm() |
| | | } else { |
| | | this.setState({ |
| | |
| | | this.setState({ |
| | | btnconfig: _LongParam |
| | | }, () => { |
| | | if (!autoMatic && (_LongParam.setting.display === 'prompt' || _LongParam.setting.display === 'exec')) { // 如果表单以是否框展示 |
| | | if (_LongParam.setting.display === 'prompt' || _LongParam.setting.display === 'exec') { // 如果表单以是否框展示 |
| | | this.modelconfirm() |
| | | } else { |
| | | this.setState({ |
| | |
| | | */ |
| | | handleOk = () => { |
| | | if (!this.formRef) return |
| | | |
| | | this.formRef.handleConfirm().then(res => { |
| | | this.setState({ confirmLoading: true }) |
| | | |
| | |
| | | BID={popData ? primaryId : this.props.BID} |
| | | BData={popData || this.props.BData} |
| | | /> : null} |
| | | {btn.$view === 'CustomPage' ? <CustomPage Tab={btn} MenuID={btn.uuid} param={{$BID: (popData ? primaryId : this.props.BID), ...(popData || this.props.BData || {})}} /> : null} |
| | | {btn.$view === 'CustomPage' ? <CustomPage Tab={btn} MenuID={btn.uuid} MenuName={btn.label} param={{$BID: (popData ? primaryId : this.props.BID), ...(popData || this.props.BData || {})}} /> : null} |
| | | </Modal> |
| | | } else { |
| | | let height = '100vh' |
| | |
| | | let node = document.querySelector('.ant-modal-confirm-btns >.ant-btn-primary') |
| | | node && node.click() |
| | | } else if (autoMatic.OpenType === 'pop') { |
| | | MKEmitter.emit('triggerBtnPopSubmit', autoMatic.action) |
| | | let node = document.querySelector('.ant-modal-confirm-btns >.ant-btn-primary') |
| | | |
| | | if (node) { |
| | | node.click() |
| | | } else { |
| | | MKEmitter.emit('triggerBtnPopSubmit', autoMatic.action) |
| | | } |
| | | } |
| | | }, delay) |
| | | } |
New file |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { is, fromJS } from 'immutable' |
| | | import moment from 'moment' |
| | | import { Upload, Button, Progress, notification } from 'antd' |
| | | import { UploadOutlined } from '@ant-design/icons' |
| | | import SparkMD5 from 'spark-md5' |
| | | import Api from '@/api' |
| | | import './index.scss' |
| | | |
| | | let service = '' |
| | | if (process.env.NODE_ENV === 'production') { |
| | | service = document.location.origin + '/' + window.GLOB.service |
| | | } else { |
| | | service = window.GLOB.location + '/' + window.GLOB.service |
| | | } |
| | | |
| | | class FileUpload extends Component { |
| | | static propTpyes = { |
| | | config: PropTypes.object, // 表单信息 |
| | | onChange: PropTypes.func, // 表单变化 |
| | | } |
| | | |
| | | state = { |
| | | percent: 0, |
| | | accept: '', |
| | | accepts: null, |
| | | maxFile: null, |
| | | rduri: '', |
| | | limit: 2, |
| | | compress: false, |
| | | fileType: 'text', |
| | | showprogress: false, |
| | | filelist: [] |
| | | } |
| | | |
| | | UNSAFE_componentWillMount () { |
| | | const { config } = this.props |
| | | |
| | | let filelist = [] |
| | | if (config.initval) { |
| | | if (/^data:image/.test(config.initval)) { |
| | | filelist = [{ |
| | | uid: '0', |
| | | name: 'data:image/jpeg;base64', |
| | | status: 'done', |
| | | url: config.initval, |
| | | origin: true |
| | | }] |
| | | } else { |
| | | try { |
| | | filelist = config.initval.split(',').map((url, index) => { |
| | | return { |
| | | uid: `${index}`, |
| | | name: url.slice(url.lastIndexOf('/') + 1), |
| | | status: 'done', |
| | | url: url, |
| | | origin: true |
| | | } |
| | | }) |
| | | } catch (e) { |
| | | filelist = [] |
| | | } |
| | | } |
| | | } |
| | | |
| | | let accept = '' |
| | | let accepts = null |
| | | let compress = false |
| | | let maxFile = config.maxfile && config.maxfile > 0 ? config.maxfile : null |
| | | if (config.compress === 'true' || config.compress === 'base64') { |
| | | compress = true |
| | | accepts = ['.jpg', '.png', '.gif', '.jpeg'] |
| | | accept = accepts.join(',') |
| | | if (config.compress === 'base64') { |
| | | maxFile = 1 |
| | | } |
| | | } else if (config.suffix) { |
| | | accepts = config.suffix.split(',').map(item => { |
| | | if (!/^\./ig.test(item)) { |
| | | item = '.' + item |
| | | } |
| | | return item |
| | | }) |
| | | accept = accepts.join(',') |
| | | } |
| | | let rduri = config.rduri || '' |
| | | |
| | | if (window.GLOB.systemType === 'production') { |
| | | rduri = config.proRduri || '' |
| | | } |
| | | |
| | | this.setState({ |
| | | rduri, |
| | | accept, |
| | | accepts, |
| | | filelist, |
| | | compress, |
| | | limit: config.limit || 2, |
| | | maxFile: maxFile, |
| | | fileType: config.fileType || 'text' |
| | | }) |
| | | } |
| | | |
| | | shouldComponentUpdate (nextProps, nextState) { |
| | | return !is(fromJS(this.state), fromJS(nextState)) |
| | | } |
| | | |
| | | onChange = ({ fileList }) => { |
| | | fileList = fileList.map(item => { |
| | | if (item.status === 'error' && /^<!DOCTYPE html>/.test(item.response)) { |
| | | item.response = '' |
| | | } |
| | | return item |
| | | }) |
| | | |
| | | this.setState({filelist: fileList}) |
| | | } |
| | | |
| | | onRemove = file => { |
| | | const files = this.state.filelist.filter(v => v.uid !== file.uid) |
| | | |
| | | this.setState({filelist: files}) |
| | | |
| | | let vals = [] |
| | | |
| | | files.forEach(item => { |
| | | if (item.origin && item.url) { |
| | | vals.push(item.url) |
| | | } else if (!item.origin && item.status === 'done' && item.response) { |
| | | vals.push(item.response) |
| | | } |
| | | }) |
| | | |
| | | this.props.onChange(vals.join(',')) |
| | | } |
| | | |
| | | onUpdate = (url) => { |
| | | let filelist = fromJS(this.state.filelist).toJS() |
| | | |
| | | if (filelist[filelist.length -1]) { |
| | | filelist[filelist.length -1].status = 'done' |
| | | filelist[filelist.length -1].response = url |
| | | filelist[filelist.length -1].origin = false |
| | | } |
| | | |
| | | filelist = filelist.filter(item => !!(item.url || item.response)) |
| | | |
| | | let vals = [] |
| | | |
| | | filelist.forEach(item => { |
| | | if (item.origin && item.url) { |
| | | vals.push(item.url) |
| | | } else if (!item.origin && item.status === 'done' && item.response) { |
| | | vals.push(item.response) |
| | | } |
| | | }) |
| | | |
| | | this.setState({filelist}) |
| | | this.props.onChange(vals.join(',')) |
| | | } |
| | | |
| | | onFail = (msg) => { |
| | | let filelist = this.state.filelist.map(item => { |
| | | if (!item.url && !item.response && !item.status) { |
| | | item.status = 'error' |
| | | } |
| | | return item |
| | | }) |
| | | |
| | | this.setState({filelist, showprogress: false, percent: 0}) |
| | | |
| | | notification.warning({ |
| | | top: 92, |
| | | message: msg || '文件上传失败!', |
| | | duration: 5 |
| | | }) |
| | | } |
| | | |
| | | shardupload = (params) => { |
| | | let param = params.chunks.shift() |
| | | let form = new FormData() |
| | | |
| | | form.append('file', param.binary) |
| | | form.append('fileMd5', params.file.fileMd5) |
| | | form.append('shardingMd5', param.chunkMd5) |
| | | form.append('baseDomain', service) |
| | | form.append('rootPath', 'Content/images/upload/') |
| | | form.append('fileName', params.file.fileName) |
| | | form.append('fileExt', params.file.fileType) |
| | | form.append('shardingCnt', param.chunks) |
| | | form.append('shardingNo', param.chunk) |
| | | form.append('LoginUID', sessionStorage.getItem('LoginUID') || '') |
| | | form.append('UserID', sessionStorage.getItem('UserID') || '') |
| | | |
| | | Api.getLargeFileUpload(form).then(res => { |
| | | if (res.status) { |
| | | if (params.chunks.length > 0) { |
| | | this.setState({ |
| | | percent: Math.floor(100 * (param.chunk / param.chunks)) |
| | | }) |
| | | this.shardupload(params) |
| | | } else { |
| | | if (res.urlPath) { |
| | | this.onUpdate(res.urlPath) |
| | | } else { |
| | | this.onFail() |
| | | } |
| | | this.setState({ |
| | | percent: 100 |
| | | }, () => { |
| | | setTimeout(() => { |
| | | this.setState({ |
| | | showprogress: false, |
| | | percent: 0 |
| | | }) |
| | | }, 200) |
| | | }) |
| | | } |
| | | } else { |
| | | this.onFail(res.message) |
| | | } |
| | | }) |
| | | } |
| | | |
| | | getuuid = () => { |
| | | let uuid = [] |
| | | let _options = '0123456789abcdefghigklmnopqrstuv' |
| | | for (let i = 0; i < 19; i++) { |
| | | uuid.push(_options.substr(Math.floor(Math.random() * 0x20), 1)) |
| | | } |
| | | uuid = uuid.join('') |
| | | return uuid |
| | | } |
| | | |
| | | beforeUpload = (file) => { |
| | | const { accepts, compress, limit, rduri } = this.state |
| | | |
| | | if (accepts && file.name) { |
| | | let pass = false |
| | | accepts.forEach(type => { |
| | | if (new RegExp(type + '$', 'ig').test(file.name)) { |
| | | pass = true |
| | | } |
| | | }) |
| | | |
| | | if (!pass) { |
| | | setTimeout(() => { |
| | | this.onFail('文件格式错误!') |
| | | }, 10) |
| | | return false |
| | | } |
| | | } |
| | | |
| | | this.setState({ |
| | | showprogress: true, |
| | | percent: 0 |
| | | }) |
| | | |
| | | if (compress) { |
| | | let reader = new FileReader() |
| | | let fileSize = file.size / 1024 / 1024 |
| | | let compressRate = 0.9 |
| | | |
| | | if (fileSize / limit > 5) { |
| | | compressRate = 0.4 |
| | | } else if (fileSize / limit > 4) { |
| | | compressRate = 0.5 |
| | | } else if (fileSize / limit > 3) { |
| | | compressRate = 0.6 |
| | | } else if (fileSize / limit > 2) { |
| | | compressRate = 0.7 |
| | | } else if (fileSize > limit) { |
| | | compressRate = 0.8 |
| | | } |
| | | |
| | | reader.onload = (e) => { |
| | | let img = new Image() |
| | | let maxW = 640 |
| | | |
| | | img.onload = () => { |
| | | let cvs = document.createElement( 'canvas') |
| | | let ctx = cvs.getContext( '2d') |
| | | |
| | | if (img.width > maxW) { |
| | | img.height *= maxW / img.width |
| | | img.width = maxW |
| | | } |
| | | |
| | | cvs.width = img.width |
| | | cvs.height = img.height |
| | | |
| | | ctx.clearRect(0, 0, cvs.width, cvs.height) |
| | | ctx.drawImage(img, 0, 0, img.width, img.height) |
| | | |
| | | let param = {Base64Img: cvs.toDataURL('image/jpeg', compressRate)} |
| | | |
| | | if (this.props.config.compress === 'base64') { |
| | | this.onUpdate(param.Base64Img) |
| | | |
| | | this.setState({ |
| | | percent: 100 |
| | | }, () => { |
| | | setTimeout(() => { |
| | | this.setState({ |
| | | showprogress: false, |
| | | percent: 0 |
| | | }) |
| | | }, 200) |
| | | }) |
| | | } else { |
| | | if (rduri) { |
| | | param.rduri = rduri |
| | | } |
| | | |
| | | Api.fileuploadbase64(param).then(result => { |
| | | if (result.status && result.Images) { |
| | | let url = service + result.Images |
| | | |
| | | if (rduri) { |
| | | url = rduri.replace(/webapi(.*)$/, '') + result.Images |
| | | } |
| | | |
| | | this.onUpdate(url) |
| | | |
| | | this.setState({ |
| | | percent: 100 |
| | | }, () => { |
| | | setTimeout(() => { |
| | | this.setState({ |
| | | showprogress: false, |
| | | percent: 0 |
| | | }) |
| | | }, 200) |
| | | }) |
| | | } else { |
| | | this.onFail(result.message) |
| | | } |
| | | }) |
| | | } |
| | | } |
| | | |
| | | img.onerror = () => { |
| | | this.onFail('图片读取失败!') |
| | | } |
| | | |
| | | img.src = e.target.result |
| | | } |
| | | |
| | | reader.onerror = () => { |
| | | this.onFail('文件读取失败!') |
| | | } |
| | | |
| | | reader.readAsDataURL(file) |
| | | return false |
| | | } |
| | | |
| | | // 兼容性的处理 |
| | | let blobSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice |
| | | let chunkSize = 1024 * 1024 * 2 // 切片每次2M |
| | | let chunks = Math.ceil(file.size / chunkSize) // 切片总数 |
| | | let currentChunk = 0 // 当前上传的chunk |
| | | let spark = new SparkMD5.ArrayBuffer() // 对arrayBuffer数据进行md5加密,产生一个md5字符串 |
| | | let chunkFileReader = new FileReader() // 用于计算出每个chunkMd5 |
| | | let totalFileReader = new FileReader() // 用于计算出总文件的fileMd5 |
| | | let params = {chunks: [], file: {}} // 用于上传所有分片的md5信息 |
| | | |
| | | params.file.fileName = file.name.replace(/\.{1}[^.]*$/ig, '') // 文件名(去除后缀名) |
| | | params.file.fileType = file.name.replace(/^.*\.{1}/ig, '') // 文件类型 |
| | | params.file.fileSize = file.size // 文件大小 |
| | | params.file.fileChunks = chunks // 记录所有chunks的长度 |
| | | |
| | | if (!/^[A-Za-z0-9]+$/.test(params.file.fileName)) { // 文件名称含有英文及数字之外字符时,名称系统生成 |
| | | params.file.fileName = moment().format('YYYYMMDDHHmmss') + this.getuuid() |
| | | } |
| | | |
| | | totalFileReader.readAsArrayBuffer(file) |
| | | totalFileReader.onload = (e) => { // 对整个totalFile生成md5 |
| | | spark.append(e.target.result) |
| | | params.file.fileMd5 = spark.end() // 计算整个文件的fileMd5 |
| | | |
| | | let _param = new FormData() |
| | | _param.append('fileMd5', params.file.fileMd5) |
| | | |
| | | Api.getFilePreUpload(_param).then(res => { |
| | | if (res.status && res.urlPath) { |
| | | this.onUpdate(res.urlPath) |
| | | this.setState({ |
| | | percent: 100 |
| | | }, () => { |
| | | setTimeout(() => { |
| | | this.setState({ |
| | | showprogress: false, |
| | | percent: 0 |
| | | }) |
| | | }, 200) |
| | | }) |
| | | } else if (res.shardings && res.shardings.length > 0) { |
| | | res.shardings.forEach(shard => { |
| | | if (shard.shardingNo && parseInt(shard.shardingNo) > currentChunk) { |
| | | currentChunk = parseInt(shard.shardingNo) |
| | | } |
| | | }) |
| | | loadNext() |
| | | } else { |
| | | loadNext() |
| | | } |
| | | }) |
| | | } |
| | | |
| | | chunkFileReader.onload = (e) => { |
| | | spark.append(e.target.result) // 对每一片分片进行md5加密 |
| | | |
| | | params.chunks[params.chunks.length - 1].chunkMd5 = spark.end() // 添加切片md5 |
| | | |
| | | currentChunk++ // 每一次分片onload,currentChunk都需要增加,以便来计算分片的次数 |
| | | |
| | | if (currentChunk < chunks) { // 当前切片总数没有达到总数时 |
| | | loadNext() |
| | | } else { |
| | | this.shardupload(params) |
| | | } |
| | | } |
| | | |
| | | chunkFileReader.onerror = () => { |
| | | this.onFail('文件读取失败!') |
| | | } |
| | | totalFileReader.onerror = () => { |
| | | this.onFail('文件读取失败!') |
| | | } |
| | | |
| | | let loadNext = () => { |
| | | let start = currentChunk * chunkSize // 计算分片的起始位置 |
| | | let end = Math.min(file.size, start + chunkSize) // 计算分片的结束位置 |
| | | |
| | | let obj = { // 每一个分片需要包含的信息 |
| | | chunk: currentChunk + 1, |
| | | binary: file.slice(start, end), |
| | | start: start, |
| | | end: end, |
| | | chunks |
| | | } |
| | | |
| | | params.chunks.push(obj) |
| | | chunkFileReader.readAsArrayBuffer(blobSlice.call(file, start, end)) |
| | | } |
| | | |
| | | return false |
| | | } |
| | | |
| | | /** |
| | | * @description 组件销毁,清除state更新 |
| | | */ |
| | | componentWillUnmount () { |
| | | this.setState = () => { |
| | | return |
| | | } |
| | | } |
| | | |
| | | render() { |
| | | const { showprogress, percent, filelist, maxFile, fileType, accept } = this.state |
| | | |
| | | let uploadable = 'fileupload-form-container ' |
| | | |
| | | if (maxFile && filelist.length >= maxFile) { |
| | | uploadable += 'limit-fileupload' |
| | | } |
| | | |
| | | const props = { |
| | | name: 'file', |
| | | disabled: showprogress, |
| | | listType: fileType, |
| | | fileList: filelist, |
| | | action: null, |
| | | accept: accept, |
| | | method: 'post', |
| | | multiple: false, |
| | | onChange: this.onChange, |
| | | onRemove: this.onRemove, |
| | | beforeUpload: this.beforeUpload, |
| | | className: uploadable |
| | | } |
| | | |
| | | return ( |
| | | <Upload {...props}> |
| | | {fileType !== 'picture-card' ? <Button> |
| | | <UploadOutlined /> 点击上传 |
| | | </Button> : null} |
| | | {fileType === 'picture-card' ? <span style={{whiteSpace: 'nowrap'}}> |
| | | <UploadOutlined /> 点击上传 |
| | | </span> : null} |
| | | {showprogress ? <Progress percent={percent} size="small" /> : null} |
| | | </Upload> |
| | | ) |
| | | } |
| | | } |
| | | |
| | | export default FileUpload |
New file |
| | |
| | | .fileupload-form-container { |
| | | .ant-progress-small.ant-progress-line { |
| | | position: absolute; |
| | | bottom: -20px; |
| | | left: 0px; |
| | | } |
| | | |
| | | .ant-upload-select-picture-card { |
| | | .ant-progress-small.ant-progress-line { |
| | | bottom: 0px; |
| | | } |
| | | } |
| | | .ant-upload-list-picture-card-container { |
| | | width: 90px; |
| | | height: 90px; |
| | | } |
| | | // .ant-upload-list-picture-card .ant-upload-list-item-undefined { |
| | | // border-color: #f5222d; |
| | | // .ant-upload-list-item-name { |
| | | // color: #f5222d; |
| | | // } |
| | | // } |
| | | .ant-upload-list-picture-card .ant-upload-list-item { |
| | | width: 90px; |
| | | height: 90px; |
| | | } |
| | | .ant-upload.ant-upload-select-picture-card { |
| | | width: 90px; |
| | | height: 90px; |
| | | } |
| | | a[href^="data"] { |
| | | pointer-events: none; |
| | | .anticon-eye-o { |
| | | display: none; |
| | | } |
| | | } |
| | | } |
| | | .fileupload-form-container.limit-fileupload { |
| | | > .ant-upload { |
| | | display: inline; |
| | | >.ant-upload { |
| | | >input { |
| | | display: none; |
| | | } |
| | | >button { |
| | | display: none; |
| | | } |
| | | } |
| | | } |
| | | > .ant-upload-select-picture-card { |
| | | display: none; |
| | | } |
| | | } |
| | |
| | | |
| | | let filelist = [] |
| | | if (config.initval) { |
| | | try { |
| | | filelist = config.initval.split(',').map((url, index) => { |
| | | return { |
| | | uid: `${index}`, |
| | | name: url.slice(url.lastIndexOf('/') + 1), |
| | | status: 'done', |
| | | url: url, |
| | | origin: true |
| | | } |
| | | }) |
| | | } catch (e) { |
| | | filelist = [] |
| | | if (/^data:image/.test(config.initval)) { |
| | | filelist = [{ |
| | | uid: '0', |
| | | name: 'data:image/jpeg;base64', |
| | | status: 'done', |
| | | url: config.initval, |
| | | origin: true |
| | | }] |
| | | } else { |
| | | try { |
| | | filelist = config.initval.split(',').map((url, index) => { |
| | | return { |
| | | uid: `${index}`, |
| | | name: url.slice(url.lastIndexOf('/') + 1), |
| | | status: 'done', |
| | | url: url, |
| | | origin: true |
| | | } |
| | | }) |
| | | } catch (e) { |
| | | filelist = [] |
| | | } |
| | | } |
| | | } |
| | | |
| | | let accept = '' |
| | | let accepts = null |
| | | let compress = false |
| | | if (config.compress === 'true') { |
| | | let maxFile = config.maxfile && config.maxfile > 0 ? config.maxfile : null |
| | | if (config.compress === 'true' || config.compress === 'base64') { |
| | | compress = true |
| | | accepts = ['.jpg', '.png', '.gif', '.jpeg'] |
| | | accept = accepts.join(',') |
| | | if (config.compress === 'base64') { |
| | | maxFile = 1 |
| | | } |
| | | } else if (config.suffix) { |
| | | accepts = config.suffix.split(',').map(item => { |
| | | if (!/^\./ig.test(item)) { |
| | |
| | | filelist, |
| | | compress, |
| | | limit: config.limit || 2, |
| | | maxFile: config.maxfile && config.maxfile > 0 ? config.maxfile : null, |
| | | maxFile: maxFile, |
| | | fileType: config.fileType || 'text' |
| | | }) |
| | | } |
| | |
| | | }) |
| | | } |
| | | |
| | | shardupload = (params) => { |
| | | let param = params.chunks.shift() |
| | | shardupload = (param) => { |
| | | let form = new FormData() |
| | | |
| | | form.append('file', param.binary) |
| | | form.append('fileMd5', params.file.fileMd5) |
| | | form.append('shardingMd5', param.chunkMd5) |
| | | form.append('fileMd5', param.fileMd5) |
| | | form.append('shardingMd5', param.fileMd5) |
| | | form.append('baseDomain', service) |
| | | form.append('rootPath', 'Content/images/upload/') |
| | | form.append('fileName', params.file.fileName) |
| | | form.append('fileExt', params.file.fileType) |
| | | form.append('shardingCnt', param.chunks) |
| | | form.append('shardingNo', param.chunk) |
| | | form.append('fileName', param.fileName) |
| | | form.append('fileExt', param.fileType) |
| | | form.append('shardingCnt', 1) |
| | | form.append('shardingNo', 1) |
| | | form.append('LoginUID', sessionStorage.getItem('LoginUID') || '') |
| | | form.append('UserID', sessionStorage.getItem('UserID') || '') |
| | | |
| | | Api.getLargeFileUpload(form).then(res => { |
| | | if (res.status) { |
| | | if (params.chunks.length > 0) { |
| | | this.setState({ |
| | | percent: Math.floor(100 * (param.chunk / param.chunks)) |
| | | }) |
| | | this.shardupload(params) |
| | | if (res.urlPath) { |
| | | this.onUpdate(res.urlPath) |
| | | } else { |
| | | if (res.urlPath) { |
| | | this.onUpdate(res.urlPath) |
| | | } else { |
| | | this.onFail() |
| | | } |
| | | this.setState({ |
| | | percent: 100 |
| | | }, () => { |
| | | setTimeout(() => { |
| | | this.setState({ |
| | | showprogress: false, |
| | | percent: 0 |
| | | }) |
| | | }, 200) |
| | | }) |
| | | this.onFail() |
| | | } |
| | | this.setState({ |
| | | percent: 100 |
| | | }, () => { |
| | | setTimeout(() => { |
| | | this.setState({ |
| | | showprogress: false, |
| | | percent: 0 |
| | | }) |
| | | }, 200) |
| | | }) |
| | | } else { |
| | | this.onFail(res.message) |
| | | } |
| | |
| | | |
| | | let param = {Base64Img: cvs.toDataURL('image/jpeg', compressRate)} |
| | | |
| | | if (rduri) { |
| | | param.rduri = rduri |
| | | } |
| | | |
| | | Api.fileuploadbase64(param).then(result => { |
| | | if (result.status && result.Images) { |
| | | let url = service + result.Images |
| | | |
| | | if (rduri) { |
| | | url = rduri.replace(/webapi(.*)$/, '') + result.Images |
| | | } |
| | | |
| | | this.onUpdate(url) |
| | | |
| | | this.setState({ |
| | | percent: 100 |
| | | }, () => { |
| | | setTimeout(() => { |
| | | this.setState({ |
| | | showprogress: false, |
| | | percent: 0 |
| | | }) |
| | | }, 200) |
| | | }) |
| | | } else { |
| | | this.onFail(result.message) |
| | | if (this.props.config.compress === 'base64') { |
| | | this.onUpdate(param.Base64Img) |
| | | |
| | | this.setState({ |
| | | percent: 100 |
| | | }, () => { |
| | | setTimeout(() => { |
| | | this.setState({ |
| | | showprogress: false, |
| | | percent: 0 |
| | | }) |
| | | }, 200) |
| | | }) |
| | | } else { |
| | | if (rduri) { |
| | | param.rduri = rduri |
| | | } |
| | | }) |
| | | |
| | | Api.fileuploadbase64(param).then(result => { |
| | | if (result.status && result.Images) { |
| | | let url = service + result.Images |
| | | |
| | | if (rduri) { |
| | | url = rduri.replace(/webapi(.*)$/, '') + result.Images |
| | | } |
| | | |
| | | this.onUpdate(url) |
| | | |
| | | this.setState({ |
| | | percent: 100 |
| | | }, () => { |
| | | setTimeout(() => { |
| | | this.setState({ |
| | | showprogress: false, |
| | | percent: 0 |
| | | }) |
| | | }, 200) |
| | | }) |
| | | } else { |
| | | this.onFail(result.message) |
| | | } |
| | | }) |
| | | } |
| | | } |
| | | |
| | | img.onerror = () => { |
| | |
| | | } |
| | | |
| | | // 兼容性的处理 |
| | | let blobSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice |
| | | let chunkSize = 1024 * 1024 * 2 // 切片每次2M |
| | | let chunks = Math.ceil(file.size / chunkSize) // 切片总数 |
| | | let currentChunk = 0 // 当前上传的chunk |
| | | let spark = new SparkMD5.ArrayBuffer() // 对arrayBuffer数据进行md5加密,产生一个md5字符串 |
| | | let chunkFileReader = new FileReader() // 用于计算出每个chunkMd5 |
| | | let totalFileReader = new FileReader() // 用于计算出总文件的fileMd5 |
| | | let params = {chunks: [], file: {}} // 用于上传所有分片的md5信息 |
| | | let param = {} |
| | | |
| | | params.file.fileName = file.name.replace(/\.{1}[^.]*$/ig, '') // 文件名(去除后缀名) |
| | | params.file.fileType = file.name.replace(/^.*\.{1}/ig, '') // 文件类型 |
| | | params.file.fileSize = file.size // 文件大小 |
| | | params.file.fileChunks = chunks // 记录所有chunks的长度 |
| | | param.fileName = file.name.replace(/\.{1}[^.]*$/ig, '') // 文件名(去除后缀名) |
| | | param.fileType = file.name.replace(/^.*\.{1}/ig, '') // 文件类型 |
| | | |
| | | if (!/^[A-Za-z0-9]+$/.test(params.file.fileName)) { // 文件名称含有英文及数字之外字符时,名称系统生成 |
| | | params.file.fileName = moment().format('YYYYMMDDHHmmss') + this.getuuid() |
| | | if (!/^[A-Za-z0-9]+$/.test(param.fileName)) { // 文件名称含有英文及数字之外字符时,名称系统生成 |
| | | param.fileName = moment().format('YYYYMMDDHHmmss') + this.getuuid() |
| | | } |
| | | |
| | | totalFileReader.readAsArrayBuffer(file) |
| | | totalFileReader.onload = (e) => { // 对整个totalFile生成md5 |
| | | spark.append(e.target.result) |
| | | params.file.fileMd5 = spark.end() // 计算整个文件的fileMd5 |
| | | param.fileMd5 = spark.end() // 计算整个文件的fileMd5 |
| | | param.binary = file |
| | | |
| | | let _param = new FormData() |
| | | _param.append('fileMd5', params.file.fileMd5) |
| | | _param.append('fileMd5', param.fileMd5) |
| | | |
| | | Api.getFilePreUpload(_param).then(res => { |
| | | if (res.status && res.urlPath) { |
| | |
| | | }) |
| | | }, 200) |
| | | }) |
| | | } else if (res.shardings && res.shardings.length > 0) { |
| | | res.shardings.forEach(shard => { |
| | | if (shard.shardingNo && parseInt(shard.shardingNo) > currentChunk) { |
| | | currentChunk = parseInt(shard.shardingNo) |
| | | } |
| | | }) |
| | | loadNext() |
| | | } else { |
| | | loadNext() |
| | | this.shardupload(param) |
| | | } |
| | | }) |
| | | } |
| | | |
| | | chunkFileReader.onload = (e) => { |
| | | spark.append(e.target.result) // 对每一片分片进行md5加密 |
| | | |
| | | params.chunks[params.chunks.length - 1].chunkMd5 = spark.end() // 添加切片md5 |
| | | |
| | | currentChunk++ // 每一次分片onload,currentChunk都需要增加,以便来计算分片的次数 |
| | | |
| | | if (currentChunk < chunks) { // 当前切片总数没有达到总数时 |
| | | loadNext() |
| | | } else { |
| | | this.shardupload(params) |
| | | } |
| | | } |
| | | |
| | | chunkFileReader.onerror = () => { |
| | | this.onFail('文件读取失败!') |
| | | } |
| | | totalFileReader.onerror = () => { |
| | | this.onFail('文件读取失败!') |
| | | } |
| | | |
| | | let loadNext = () => { |
| | | let start = currentChunk * chunkSize // 计算分片的起始位置 |
| | | let end = Math.min(file.size, start + chunkSize) // 计算分片的结束位置 |
| | | |
| | | let obj = { // 每一个分片需要包含的信息 |
| | | chunk: currentChunk + 1, |
| | | binary: file.slice(start, end), |
| | | start: start, |
| | | end: end, |
| | | chunks |
| | | } |
| | | |
| | | params.chunks.push(obj) |
| | | chunkFileReader.readAsArrayBuffer(blobSlice.call(file, start, end)) |
| | | } |
| | | |
| | | return false |
| | |
| | | width: 90px; |
| | | height: 90px; |
| | | } |
| | | .ant-upload-list-picture-card .ant-upload-list-item-undefined { |
| | | border-color: #f5222d; |
| | | .ant-upload-list-item-name { |
| | | color: #f5222d; |
| | | } |
| | | } |
| | | // .ant-upload-list-picture-card .ant-upload-list-item-undefined { |
| | | // border-color: #f5222d; |
| | | // .ant-upload-list-item-name { |
| | | // color: #f5222d; |
| | | // } |
| | | // } |
| | | .ant-upload-list-picture-card .ant-upload-list-item { |
| | | width: 90px; |
| | | height: 90px; |
| | |
| | | let photos = '' |
| | | if (item.field && record.hasOwnProperty(item.field)) { |
| | | photos = record[item.field] + '' |
| | | photos = photos.split(',').filter(Boolean) |
| | | } |
| | | if (/^data:image/.test(photos)) { |
| | | photos = [photos] |
| | | } else { |
| | | photos = '' |
| | | photos = photos.split(',').filter(Boolean) |
| | | } |
| | | |
| | | let maxHeight = item.maxHeight || 128 |
| | |
| | | let photos = [] |
| | | try { |
| | | photos = record[col.field] + '' |
| | | photos = photos.split(',').filter(Boolean) |
| | | |
| | | if (/^data:image/.test(photos)) { |
| | | photos = [photos] |
| | | } else { |
| | | photos = photos.split(',').filter(Boolean) |
| | | } |
| | | } catch (e) { |
| | | photos = [] |
| | | } |
| | |
| | | } |
| | | |
| | | this.setState({ |
| | | chartview: _config.charts[0].uuid, |
| | | chartview: _config.charts ? _config.charts[0].uuid : '', |
| | | config: _config, |
| | | openEdition: menu.open_edition || '', |
| | | activeKey: menu.activeKey || '0', |
| | |
| | | } |
| | | |
| | | _config.action.forEach(item => { |
| | | if (item.hidden === 'true') return |
| | | _sort++ |
| | | if (item.OpenType === 'popview') { |
| | | btntabs.push({ |
| | |
| | | config: null |
| | | }, () => { |
| | | this.setState({ |
| | | chartview: _config.charts[0].uuid, |
| | | chartview: _config.charts ? _config.charts[0].uuid : '', |
| | | config: _config, |
| | | openEdition: res.open_edition || '', |
| | | activeKey: menu.activeKey || '0', |
| | |
| | | config={config} |
| | | updatesearch={this.updatesearch} |
| | | /> |
| | | <div className="chart-view" style={{position: 'relative'}}> |
| | | {/* 视图组 权限 会员等级20+ */} |
| | | {this.props.memberLevel >= 20 ? <ChartGroupComponent |
| | | {config.charts ? <div className="chart-view" style={{position: 'relative'}}> |
| | | {/* 视图组 已弃用 */} |
| | | <ChartGroupComponent |
| | | config={config} |
| | | updatechartgroup={this.updatechartgroup} |
| | | /> : null} |
| | | /> |
| | | {config.charts.map(item => { |
| | | if (!config.expand && chartview !== item.uuid) return '' |
| | | |
| | |
| | | ) |
| | | } |
| | | })} |
| | | </div> |
| | | </div> : <> |
| | | <ActionComponent |
| | | type="main" |
| | | menu={{ MenuID: this.props.menu.MenuID, MenuName: config.MenuName, MenuNo: config.MenuNo, fstMenuList: this.props.menu.fstMenuList }} |
| | | config={config} |
| | | tabs={this.state.tabviews} |
| | | setSubConfig={(_btn) => this.setSubConfig(_btn, 'button')} |
| | | updateaction={this.updateaction} |
| | | /> |
| | | <ColumnComponent |
| | | config={config} |
| | | menu={this.props.menu} |
| | | updatecolumn={this.updateconfig} |
| | | /> |
| | | </>} |
| | | {/* 标签组 */} |
| | | <TabsComponent |
| | | config={config} |
| | |
| | | let newLText = Utils.formatOptions(FuncUtils.getTableFunc(setting, menu, _config)) // 创建存储过程sql |
| | | let DelText = Utils.formatOptions(FuncUtils.dropfunc(setting.innerFunc)) // 删除存储过程sql |
| | | |
| | | this.refs.tableCreatFunc.exec(setting.innerFunc, newLText, DelText).then(result => { |
| | | if (result === 'success') { |
| | | this.setState({ |
| | | config: _config |
| | | }) |
| | | } |
| | | }) |
| | | this.refs.tableCreatFunc.exec(setting.innerFunc, newLText, DelText) |
| | | }) |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | previewPicture = (template) => { |
| | | if (template.disabled) return |
| | | // 图片预览 |
| | | this.setState({ |
| | | preview: template.url, |
| | |
| | | |
| | | Api.getSystemConfig({func: 'sPC_Get_UserTemp', TypeCharTwo: 'menu'}).then(res => { |
| | | let _templates = [] |
| | | let hasRolePermission = false |
| | | |
| | | res.UserTemp.forEach(temp => { |
| | | if (temp.Template === 'NewPage') { |
| | | return |
| | | } else if (temp.Template === 'RolePermission') { |
| | | hasRolePermission = true |
| | | if (temp.Template === 'NewPage' || temp.Template === 'RolePermission') { |
| | | return |
| | | } else if (temp.Template === 'CustomPage' && memberLevel < 20) { |
| | | return |
| | | temp.disabled = true |
| | | temp.disTitle = '会员等级不够,无开发权限。' |
| | | } |
| | | |
| | | _templates.push({ |
| | | uuid: temp.MenuID, |
| | | title: temp.MenuName, |
| | | type: temp.Template, |
| | | url: illust[temp.Template] |
| | | url: illust[temp.Template], |
| | | disabled: temp.disabled || false, |
| | | disTitle: temp.disTitle || '' |
| | | }) |
| | | }) |
| | | |
| | | sysTemplates = sysTemplates.map(temp => { |
| | | if (temp.type === 'RolePermission' && !hasRolePermission) { |
| | | temp.hidden = false |
| | | } else if (temp.type === 'CustomPage' && memberLevel < 20) { |
| | | temp.hidden = true |
| | | if (temp.type === 'CustomPage' && memberLevel < 20) { |
| | | temp.disabled = true |
| | | temp.disTitle = '会员等级不够,无开发权限。' |
| | | } |
| | | |
| | | return temp |
| | |
| | | let sysTemplates = fromJS(this.state.sysTemplates).toJS() |
| | | |
| | | // 角色权限分配模板,只可以添加一次 |
| | | if (sysMenu.isSystem && (sysMenu.Template === 'RolePermission')) { |
| | | sysTemplates = sysTemplates.map(temp => { |
| | | if (temp.type === sysMenu.type) { |
| | | temp.hidden = true |
| | | } |
| | | // if (sysMenu.isSystem && (sysMenu.Template === 'RolePermission')) { |
| | | // sysTemplates = sysTemplates.map(temp => { |
| | | // if (temp.type === sysMenu.type) { |
| | | // temp.hidden = true |
| | | // } |
| | | |
| | | return temp |
| | | }) |
| | | } |
| | | // return temp |
| | | // }) |
| | | // } |
| | | |
| | | this.menuFormRef.handleConfirm().then(res => { |
| | | let PageParam = { |
| | |
| | | <TabPane tab="系统模板" key="1"> |
| | | <Row> |
| | | {this.state.sysTemplates.map((template, index) => { |
| | | if (template.hidden) return null |
| | | // if (template.hidden) return null |
| | | |
| | | return ( |
| | | <Col key={`${index}`} span={8}> |
| | | <Col key={`${index}`} className={template.disabled ? 'disabled' : ''} title={template.disTitle || ''} span={8}> |
| | | <Card |
| | | title={template.title}> |
| | | <img onClick={() => {this.previewPicture(template)}} src={template.url} alt=""/> |
| | |
| | | {this.state.usedTemplates && this.state.usedTemplates.map((template, index) => { |
| | | if (template.title.toLowerCase().indexOf(this.state.tempSearchKey.toLowerCase()) >= 0) { |
| | | return ( |
| | | <Col key={template.type + index} span={8}> |
| | | <Col key={template.type + index} className={template.disabled ? 'disabled' : ''} title={template.disTitle || ''} span={8}> |
| | | <Card |
| | | title={template.title}> |
| | | <img onClick={() => {this.previewPicture(template)}} src={template.url} alt=""/> |
| | |
| | | .ant-col { |
| | | padding: 10px; |
| | | } |
| | | .ant-col.disabled { |
| | | cursor: not-allowed; |
| | | .ant-card-head-title { |
| | | color: #959595; |
| | | } |
| | | .card-operation { |
| | | display: none; |
| | | } |
| | | img { |
| | | cursor: not-allowed; |
| | | } |
| | | } |
| | | .ant-card-head-title { |
| | | text-align: center; |
| | | } |
| | |
| | | </div> |
| | | {/* 自定义模板,在新页面编辑 */} |
| | | {!card.forbidden && card.type !== 'CustomPage' ? <EditOutlined className="edit" onClick={edit} /> : null} |
| | | {card.type === 'CustomPage' ? <EditOutlined className="edit" onClick={() => {window.open(`#/menudesign/${_param}`)}}/> : null} |
| | | {!card.forbidden && card.type === 'CustomPage' ? <EditOutlined className="edit" onClick={() => {window.open(`#/menudesign/${_param}`)}}/> : null} |
| | | {card.forbidden && card.type === 'CustomPage' ? <EditOutlined className="edit" style={{color: '#959595', cursor: 'not-allowed'}} title="会员等级不够,无开发权限。"/> : null} |
| | | <CloseOutlined className="close" onClick={close} /> |
| | | </div> |
| | | ) |
| | |
| | | index = i |
| | | } |
| | | |
| | | let label = item.label || '' |
| | | if (item.field && item.field.toLowerCase() !== label.toLowerCase()) { |
| | | label = label + ' (' + item.field + ')' |
| | | } |
| | | |
| | | if (['text', 'number', 'textarea', 'color'].includes(item.type) && card.field !== item.field) { |
| | | _inputfields.push({ |
| | | field: item.field, |
| | | label: _inputIndex + '、' + item.label |
| | | label: _inputIndex + '、' + label |
| | | }) |
| | | _inputIndex++ |
| | | } |
| | | if (card.field !== item.field && item.hidden !== 'true' && ['text', 'number', 'select', 'link'].includes(item.type)) { |
| | | _tabfields.push({ |
| | | field: item.field, |
| | | label: _tabIndex + '、' + item.label |
| | | label: _tabIndex + '、' + label |
| | | }) |
| | | _tabIndex++ |
| | | } |
| | |
| | | if (item.type === 'switch') { |
| | | _linksupFields.push({ |
| | | field: item.field, |
| | | label: _linkIndex + '、' + item.label |
| | | label: _linkIndex + '、' + label |
| | | }) |
| | | } |
| | | |
| | |
| | | }) |
| | | _linksupFields.push({ |
| | | field: item.field, |
| | | label: _linkIndex + '、' + item.label |
| | | label: _linkIndex + '、' + label |
| | | }) |
| | | _linkIndex++ |
| | | } |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { fromJS } from 'immutable' |
| | | import { Form, Row, Col, Input, Select, Radio, notification, Tooltip, InputNumber, Cascader } from 'antd' |
| | | import { Form, Row, Col, Input, Select, Radio, Tooltip, InputNumber, Cascader } from 'antd' |
| | | import { QuestionCircleOutlined } from '@ant-design/icons' |
| | | |
| | | import { formRule } from '@/utils/option.js' |
| | |
| | | |
| | | const { TextArea } = Input |
| | | const actionTypeOptions = { |
| | | pop: ['label', 'position', 'OpenType', 'intertype', 'Ot', 'icon', 'class', 'execSuccess', 'execError', 'openmenu', 'output', 'tipTitle'], |
| | | prompt: ['label', 'position', 'OpenType', 'intertype', 'Ot', 'icon', 'class', 'execSuccess', 'execError', 'openmenu', 'output', 'tipTitle'], |
| | | exec: ['label', 'position', 'OpenType', 'intertype', 'Ot', 'icon', 'class', 'execSuccess', 'execError', 'openmenu', 'output'], |
| | | excelIn: ['label', 'Ot', 'OpenType', 'intertype', 'icon', 'class', 'sheet', 'execSuccess', 'execError'], |
| | | excelOut: ['label', 'OpenType', 'intertype', 'icon', 'class', 'execSuccess', 'execError', 'pagination', 'search'], |
| | | popview: ['label', 'Ot', 'OpenType', 'icon', 'class', 'position', 'tabType', 'linkTab', 'popClose', 'display', 'ratio', 'clickouter'], |
| | | tab: ['label', 'Ot', 'OpenType', 'icon', 'class', 'position', 'linkmenu'], |
| | | innerpage: ['label', 'Ot', 'OpenType', 'pageTemplate', 'icon', 'class', 'position'], |
| | | funcbutton: ['label', 'OpenType', 'funcType', 'icon', 'class'] |
| | | pop: ['label', 'position', 'OpenType', 'intertype', 'Ot', 'icon', 'class', 'execSuccess', 'execError', 'openmenu', 'output', 'tipTitle', 'hidden'], |
| | | prompt: ['label', 'position', 'OpenType', 'intertype', 'Ot', 'icon', 'class', 'execSuccess', 'execError', 'openmenu', 'output', 'tipTitle', 'hidden'], |
| | | exec: ['label', 'position', 'OpenType', 'intertype', 'Ot', 'icon', 'class', 'execSuccess', 'execError', 'openmenu', 'output', 'hidden'], |
| | | excelIn: ['label', 'Ot', 'OpenType', 'intertype', 'icon', 'class', 'sheet', 'execSuccess', 'execError', 'hidden'], |
| | | excelOut: ['label', 'OpenType', 'intertype', 'icon', 'class', 'execSuccess', 'execError', 'pagination', 'search', 'hidden'], |
| | | popview: ['label', 'Ot', 'OpenType', 'icon', 'class', 'position', 'tabType', 'linkTab', 'popClose', 'display', 'ratio', 'clickouter', 'hidden'], |
| | | tab: ['label', 'Ot', 'OpenType', 'icon', 'class', 'position', 'linkmenu', 'hidden'], |
| | | innerpage: ['label', 'Ot', 'OpenType', 'pageTemplate', 'icon', 'class', 'position', 'hidden'], |
| | | funcbutton: ['label', 'OpenType', 'funcType', 'icon', 'class', 'hidden'] |
| | | } |
| | | |
| | | class MainSearch extends Component { |
| | |
| | | setting: PropTypes.object, // 页面设置 |
| | | formlist: PropTypes.any, // 表单信息 |
| | | card: PropTypes.any, // 按钮信息 |
| | | inputSubmit: PropTypes.any // 回车提交事件 |
| | | inputSubmit: PropTypes.func, // 回车提交事件 |
| | | updRecord: PropTypes.func |
| | | } |
| | | |
| | | state = { |
| | |
| | | console.warn('表单focus失败!') |
| | | } |
| | | } |
| | | |
| | | this.props.updRecord && this.props.updRecord(this.record) |
| | | } |
| | | |
| | | getMutilOptions = () => { |
| | |
| | | } |
| | | } else if (_funcType === 'closetab') { |
| | | shows.push('refreshTab') |
| | | } else if (_funcType === 'megvii') { |
| | | shows.push('subFunc') |
| | | } |
| | | } |
| | | |
| | |
| | | if (!['funcbutton', 'excelIn', 'excelOut'].includes(value)) { |
| | | _fieldval.position = 'toolbar' |
| | | } |
| | | |
| | | this.props.updRecord && this.props.updRecord(this.record) |
| | | } else if (key === 'position') { |
| | | if (value === 'grid') { |
| | | _fieldval.Ot = 'requiredSgl' |
| | |
| | | } |
| | | } else if (key === 'intertype') { |
| | | this.record.sysInterface = 'false' |
| | | |
| | | this.props.updRecord && this.props.updRecord(this.record) |
| | | } else if (key === 'sysInterface') { |
| | | if (value === 'true') { |
| | | _fieldval.interface = window.GLOB.mainSystemApi || '' |
| | |
| | | } |
| | | |
| | | handleConfirm = () => { |
| | | const { setting, card } = this.props |
| | | const { card } = this.props |
| | | // 表单提交时检查输入值是否正确 |
| | | return new Promise((resolve, reject) => { |
| | | this.props.form.validateFieldsAndScroll((err, values) => { |
| | |
| | | values.position = values.position || 'toolbar' |
| | | |
| | | if (values.OpenType === 'excelOut') { |
| | | if (values.intertype === 'system' && setting.interType !== 'system') { // 导出excel需使用查询数据源 |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '表格数据查询未使用系统函数,导出Excel不可使用系统函数!', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } |
| | | |
| | | values.Ot = 'notRequired' |
| | | } else if (values.OpenType === 'popview' && !values.linkTab) { // 没有关联标签(新建时),创建新标签Id |
| | | values.linkTab = Utils.getuuid() |
| | |
| | | } |
| | | } else if (card.funcType === 'print') { |
| | | hasProfile = true |
| | | } else if (card.funcType === 'megvii') { |
| | | hasProfile = true |
| | | } |
| | | |
| | | return ( |
| | |
| | | <div className="page-card" style={{ opacity: opacity}}> |
| | | <div ref={node => drag(drop(node))}> |
| | | <Button |
| | | className={'mk-btn mk-' + card.class} |
| | | className={'mk-btn mk-' + card.class + (card.hidden === 'true' ? ' mk-hidden' : '')} |
| | | icon={card.icon} |
| | | key={card.uuid} |
| | | onDoubleClick={() => doubleClickCard(id)} |
| | |
| | | const VerifyCard = asyncSpinComponent(() => import('@/templates/zshare/verifycard')) |
| | | const VerifyPrint = asyncSpinComponent(() => import('@/templates/sharecomponent/actioncomponent/verifyprint')) |
| | | const VerifyExcelIn = asyncSpinComponent(() => import('@/templates/sharecomponent/actioncomponent/verifyexcelin')) |
| | | const VerifyMegvii = asyncSpinComponent(() => import('@/templates/sharecomponent/actioncomponent/verifymegvii')) |
| | | const VerifyExcelOut = asyncSpinComponent(() => import('@/templates/sharecomponent/actioncomponent/verifyexcelout')) |
| | | |
| | | class ActionComponent extends Component { |
| | |
| | | copying: false, // 按钮复制中 |
| | | visible: false, // 模态框控制 |
| | | printTemps: [], // 单据打印模板 |
| | | profVisible: false // 验证信息模态框 |
| | | profVisible: false, // 验证信息模态框 |
| | | record: null |
| | | } |
| | | |
| | | /** |
| | |
| | | MKEmitter.removeListener('pasteButton', this.pasteButton) |
| | | } |
| | | |
| | | getVerify = (card) => { |
| | | const { config } = this.props |
| | | const { dict } = this.state |
| | | |
| | | if (!card) return null |
| | | |
| | | if (['pop', 'prompt', 'exec'].includes(card.OpenType)) { |
| | | return <VerifyCard |
| | | card={card} |
| | | dict={dict} |
| | | config={config} |
| | | columns={config.columns} |
| | | wrappedComponentRef={(inst) => this.verifyRef = inst} |
| | | /> |
| | | } else if (card.OpenType === 'excelIn') { |
| | | return <VerifyExcelIn |
| | | card={card} |
| | | dict={dict} |
| | | columns={config.columns} |
| | | wrappedComponentRef={(inst) => this.verifyRef = inst} |
| | | /> |
| | | } else if (card.OpenType === 'excelOut') { |
| | | return <VerifyExcelOut |
| | | card={card} |
| | | dict={dict} |
| | | config={config} |
| | | wrappedComponentRef={(inst) => this.verifyRef = inst} |
| | | /> |
| | | } else if (card.OpenType === 'funcbutton' && card.funcType === 'print') { |
| | | return <VerifyPrint |
| | | card={card} |
| | | dict={dict} |
| | | columns={config.columns} |
| | | wrappedComponentRef={(inst) => this.verifyRef = inst} |
| | | /> |
| | | } else if (card.OpenType === 'funcbutton' && card.funcType === 'megvii') { |
| | | return <VerifyMegvii |
| | | card={card} |
| | | dict={dict} |
| | | columns={config.columns} |
| | | wrappedComponentRef={(inst) => this.verifyRef = inst} |
| | | /> |
| | | } |
| | | } |
| | | |
| | | render() { |
| | | const { config } = this.props |
| | | const { actionlist, visible, card, dict, copying, profVisible } = this.state |
| | | const { actionlist, visible, card, dict, copying, profVisible, record } = this.state |
| | | |
| | | return ( |
| | | <div className="model-table-action-list" style={config.charts.length > 1 ? {paddingTop: 25} : null}> |
| | | <div className="model-table-action-list" style={config.charts && config.charts.length > 1 ? {paddingTop: 25} : null}> |
| | | <Tooltip placement="bottomLeft" overlayClassName="middle" title="在左侧工具栏《按钮》中,选择对应类型的按钮拖至此处添加,如选择按钮类型为表单、新标签页等含有配置页面的按钮,可在左侧工具栏-按钮-可配置按钮处,点击按钮完成相关配置。注:当设置按钮显示位置为表格时,显示列会增加操作列。"> |
| | | <QuestionCircleOutlined style={{color: '#c49f47', position: 'absolute', left: '5px', top: '5px'}} /> |
| | | </Tooltip> |
| | |
| | | maskClosable={false} |
| | | onCancel={this.editModalCancel} |
| | | footer={[ |
| | | <CreateInterface key="interface" dict={dict} ref="btnCreatInterface" trigger={this.btnCreatInterface}/>, |
| | | <CreateFunc key="create" dict={dict} ref="btnCreatFunc" trigger={this.creatFunc}/>, |
| | | record && ['pop', 'exec', 'prompt'].includes(record.OpenType) && record.intertype === 'system' ? <CreateInterface key="interface" dict={dict} ref="btnCreatInterface" trigger={this.btnCreatInterface}/> : null, |
| | | record && record.intertype === 'inner' ? <CreateFunc key="create" dict={dict} ref="btnCreatFunc" trigger={this.creatFunc}/> : null, |
| | | <Button key="cancel" onClick={this.editModalCancel}>{dict['model.cancel']}</Button>, |
| | | <Button key="confirm" type="primary" loading={copying} onClick={this.handleSubmit}>{dict['model.confirm']}</Button> |
| | | ]} |
| | |
| | | formlist={this.state.formlist} |
| | | inputSubmit={this.handleSubmit} |
| | | setting={config.setting} |
| | | updRecord={(record) => this.setState({record: fromJS(record).toJS()})} |
| | | wrappedComponentRef={(inst) => this.actionFormRef = inst} |
| | | /> |
| | | </Modal> |
| | |
| | | }} |
| | | destroyOnClose |
| | | > |
| | | {card && !card.execMode && card.OpenType !== 'excelIn' && card.OpenType !== 'excelOut' ? |
| | | <VerifyCard |
| | | card={card} |
| | | dict={dict} |
| | | config={config} |
| | | columns={config.columns} |
| | | wrappedComponentRef={(inst) => this.verifyRef = inst} |
| | | /> : null |
| | | } |
| | | {card && card.execMode ? |
| | | <VerifyPrint |
| | | card={card} |
| | | dict={dict} |
| | | columns={config.columns} |
| | | wrappedComponentRef={(inst) => this.verifyRef = inst} |
| | | /> : null |
| | | } |
| | | {card && card.OpenType === 'excelIn' ? |
| | | <VerifyExcelIn |
| | | card={card} |
| | | dict={dict} |
| | | columns={config.columns} |
| | | wrappedComponentRef={(inst) => this.verifyRef = inst} |
| | | /> : null |
| | | } |
| | | {card && card.OpenType === 'excelOut' ? |
| | | <VerifyExcelOut |
| | | card={card} |
| | | dict={dict} |
| | | config={config} |
| | | wrappedComponentRef={(inst) => this.verifyRef = inst} |
| | | /> : null |
| | | } |
| | | {this.getVerify(card)} |
| | | </Modal> |
| | | </div> |
| | | ) |
| | |
| | | > .ant-row { |
| | | min-height: 65px; |
| | | } |
| | | .mk-hidden { |
| | | text-decoration: line-through!important; |
| | | span { |
| | | text-decoration: line-through!important; |
| | | } |
| | | } |
| | | .page-card { |
| | | display: inline-block; |
| | | margin: 0px 0px 0px 0px; |
| | |
| | | |
| | | class CustomForm extends Component { |
| | | static propTpyes = { |
| | | dict: PropTypes.object, // 字典项 |
| | | btn: PropTypes.object, // 按钮信息 |
| | | scripts: PropTypes.array, // 自定义脚本列表 |
| | | usefulfields: PropTypes.any, // 可用字段 |
| | |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: this.props.dict['form.required.input'] + 'sql!' |
| | | message: '请输入sql!' |
| | | } |
| | | ] |
| | | })(<CodeMirror />)} |
| | |
| | | </span> |
| | | } key="scripts"> |
| | | <CustomScript |
| | | dict={this.props.dict} |
| | | btn={this.props.card} |
| | | usefulfields={verify.columns} |
| | | scripts={verify.scripts} |
| | |
| | | wrappedComponentRef={(inst) => this.scriptsForm = inst} |
| | | /> |
| | | <EditTable actions={['move']} data={verify.scripts} columns={scriptsColumns} onChange={(scripts) => {this.setState({verify: {...verify, scripts}})}}/> |
| | | {/* <Table |
| | | bordered |
| | | rowKey="uuid" |
| | | className="custom-table" |
| | | dataSource={verify.scripts} |
| | | columns={scriptsColumns} |
| | | pagination={false} |
| | | /> */} |
| | | </TabPane> : null} |
| | | <TabPane tab="信息提示" key="tip"> |
| | | <Form {...formItemLayout}> |
New file |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { is, fromJS } from 'immutable' |
| | | import { Form, Row, Col, Button, notification, Modal, Tooltip, Radio, Select } from 'antd' |
| | | import { QuestionCircleOutlined } from '@ant-design/icons' |
| | | import moment from 'moment' |
| | | |
| | | import Api from '@/api' |
| | | import Utils from '@/utils/utils.js' |
| | | import CodeMirror from '@/templates/zshare/codemirror' |
| | | import './index.scss' |
| | | |
| | | class CustomForm extends Component { |
| | | static propTpyes = { |
| | | scripts: PropTypes.array, // 自定义脚本列表 |
| | | usefulfields: PropTypes.any, // 可用字段 |
| | | systemScripts: PropTypes.array, // 系统脚本 |
| | | scriptsChange: PropTypes.func // 表单 |
| | | } |
| | | |
| | | state = { |
| | | editItem: null, |
| | | usefulfields: null, |
| | | loading: false, |
| | | verifySql: '' |
| | | } |
| | | |
| | | UNSAFE_componentWillMount () { |
| | | this.resetfield(this.props.usefulfields) |
| | | } |
| | | |
| | | UNSAFE_componentWillReceiveProps (nextProps) { |
| | | if (nextProps.usefulfields && !is(fromJS(this.props.usefulfields), fromJS(nextProps.usefulfields))) { |
| | | this.resetfield(nextProps.usefulfields) |
| | | } |
| | | } |
| | | |
| | | resetfield = (columns) => { |
| | | columns = columns.filter(item => item.Column !== '$Index') |
| | | let fields = columns.map(item => item.Column) |
| | | |
| | | let _sql = `Declare @UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(50),@mk_organization nvarchar(50),@login_city nvarchar(50),@ErrorCode nvarchar(50), @retmsg nvarchar(4000) |
| | | ` |
| | | |
| | | this.setState({ |
| | | verifySql: _sql, |
| | | usefulfields: fields.join(', ') |
| | | }) |
| | | } |
| | | |
| | | edit = (record) => { |
| | | this.setState({ |
| | | editItem: record |
| | | }) |
| | | |
| | | this.props.form.setFieldsValue({ |
| | | sql: record.sql, |
| | | position: record.position || 'back' |
| | | }) |
| | | } |
| | | |
| | | handleConfirm = () => { |
| | | // 表单提交时检查输入值是否正确 |
| | | this.props.form.validateFieldsAndScroll((err, values) => { |
| | | if (!err) { |
| | | values.uuid = this.state.editItem ? this.state.editItem.uuid : '' |
| | | |
| | | let _quot = values.sql.match(/'{1}/g) |
| | | let _lparen = values.sql.match(/\({1}/g) |
| | | let _rparen = values.sql.match(/\){1}/g) |
| | | |
| | | _quot = _quot ? _quot.length : 0 |
| | | _lparen = _lparen ? _lparen.length : 0 |
| | | _rparen = _rparen ? _rparen.length : 0 |
| | | |
| | | if (_quot % 2 !== 0) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: 'sql中\'必须成对出现', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } else if (_lparen !== _rparen) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: 'sql中()必须成对出现', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } else if (/--/ig.test(values.sql)) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '自定义sql语句中,不可出现字符 -- ,注释请用 /*内容*/', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } |
| | | |
| | | let error = Utils.verifySql(values.sql, 'customscript') |
| | | |
| | | if (error) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: 'sql中不可使用' + error, |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } |
| | | |
| | | let tail = ` |
| | | aaa: |
| | | ` |
| | | |
| | | let _initCustomScript = '' // 初始化脚本 |
| | | let _prevCustomScript = '' // 默认sql前执行脚本 |
| | | let _backCustomScript = '' // 默认sql后执行脚本 |
| | | |
| | | this.props.scripts.forEach(item => { |
| | | if (item.status === 'false') return |
| | | |
| | | if (item.position === 'init') { |
| | | _initCustomScript += ` |
| | | /* 初始化脚本 */ |
| | | ${values.uuid === item.uuid ? values.sql : item.sql} |
| | | ` |
| | | } else if (item.position === 'front') { |
| | | _prevCustomScript += ` |
| | | /* 默认sql前脚本 */ |
| | | ${values.uuid === item.uuid ? values.sql : item.sql} |
| | | ` |
| | | } else { |
| | | _backCustomScript += ` |
| | | /* 默认sql后脚本 */ |
| | | ${values.uuid === item.uuid ? values.sql : item.sql} |
| | | ` |
| | | } |
| | | }) |
| | | |
| | | if (!values.uuid) { |
| | | if (values.position === 'init') { |
| | | _initCustomScript += ` |
| | | /* 初始化脚本 */ |
| | | ${values.sql} |
| | | ` |
| | | } else if (values.position === 'front') { |
| | | _prevCustomScript += ` |
| | | /* 默认sql前脚本 */ |
| | | ${values.sql} |
| | | ` |
| | | } else { |
| | | _backCustomScript += ` |
| | | /* 默认sql后脚本 */ |
| | | ${values.sql} |
| | | ` |
| | | } |
| | | } |
| | | |
| | | let param = { |
| | | func: 's_debug_sql', |
| | | exec_type: 'y', |
| | | LText: this.state.verifySql + _initCustomScript + _prevCustomScript + _backCustomScript + tail |
| | | } |
| | | |
| | | param.LText = param.LText.replace(/@\$|\$@/ig, '') |
| | | |
| | | // 外联数据库替换 |
| | | if (window.GLOB.externalDatabase !== null) { |
| | | param.LText = param.LText.replace(/@db@/ig, window.GLOB.externalDatabase) |
| | | } |
| | | |
| | | param.LText = Utils.formatOptions(param.LText) |
| | | param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') |
| | | param.secretkey = Utils.encrypt('', param.timestamp) |
| | | |
| | | this.setState({loading: true}) |
| | | Api.getLocalConfig(param).then(res => { |
| | | if (res.status) { |
| | | this.setState({ |
| | | loading: false, |
| | | editItem: null |
| | | }, () => { |
| | | this.props.scriptsChange(values) |
| | | }) |
| | | this.props.form.setFieldsValue({ |
| | | sql: '' |
| | | }) |
| | | } else { |
| | | this.setState({loading: false}) |
| | | |
| | | Modal.error({ |
| | | title: res.message |
| | | }) |
| | | } |
| | | }) |
| | | } |
| | | }) |
| | | } |
| | | |
| | | handleCancel = () => { |
| | | this.setState({ |
| | | editItem: null |
| | | }) |
| | | |
| | | this.props.form.setFieldsValue({ |
| | | sql: '' |
| | | }) |
| | | } |
| | | |
| | | selectScript = (value, option) => { |
| | | const { usefulfields, sheet } = this.props |
| | | |
| | | let _value = '' |
| | | if (value === 'default') { |
| | | let fields = usefulfields.filter(item => item.import !== 'false') |
| | | fields = fields.map(col => col.Column).join(',') |
| | | |
| | | let _sheet = sheet.replace(/(.*)\.(.*)\.|@db@/ig, '') |
| | | |
| | | _value = `Select ${fields} From ${_sheet}` |
| | | } else { |
| | | _value = value |
| | | } |
| | | |
| | | let _sql = this.props.form.getFieldValue('sql') |
| | | if (_sql) { |
| | | _sql = _sql + ` |
| | | |
| | | ` |
| | | } |
| | | |
| | | _sql = _sql.replace(/\s{6}$/, '') |
| | | _sql = _sql + `/*${option.props.children}*/ |
| | | ` |
| | | _sql = _sql.replace(/\s{4}$/, '') |
| | | _sql = _sql + _value |
| | | |
| | | this.props.form.setFieldsValue({ |
| | | sql: _sql |
| | | }) |
| | | } |
| | | |
| | | render() { |
| | | const { systemScripts, sheet } = this.props |
| | | const { usefulfields } = this.state |
| | | const { getFieldDecorator } = this.props.form |
| | | const formItemLayout = { |
| | | labelCol: { |
| | | xs: { span: 24 }, |
| | | sm: { span: 8 } |
| | | }, |
| | | wrapperCol: { |
| | | xs: { span: 24 }, |
| | | sm: { span: 16 } |
| | | } |
| | | } |
| | | |
| | | return ( |
| | | <Form {...formItemLayout} className="verify-form" id="verify-excelin-custom-scripts"> |
| | | <Row gutter={24}> |
| | | <Col span={8}> |
| | | <Form.Item label={'表名'} style={{whiteSpace: 'nowrap', margin: 0}}> |
| | | {sheet} |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={10}> |
| | | <Form.Item label={'报错字段'} style={{margin: 0, whiteSpace: 'nowrap'}}> |
| | | ErrorCode(增加后缀NT表示数据不回滚,如ENT、NNT、FNT、NMNT), retmsg |
| | | </Form.Item> |
| | | </Col> |
| | | {usefulfields ? <Col span={24} className="sqlfield"> |
| | | <Form.Item label={'可用字段'}> |
| | | BID, ID, LoginUID, SessionUid, UserID, Appkey, UserName, FullName, RoleID, mk_departmentcode, mk_organization, login_city, {usefulfields} |
| | | </Form.Item> |
| | | </Col> : null} |
| | | <Col span={8} style={{whiteSpace: 'nowrap'}}> |
| | | <Form.Item style={{marginBottom: 0}} label={ |
| | | <Tooltip placement="bottomLeft" title={'自定义脚本与默认sql位置关系。'}> |
| | | <QuestionCircleOutlined className="mk-form-tip" /> |
| | | 执行位置 |
| | | </Tooltip> |
| | | }> |
| | | {getFieldDecorator('position', { |
| | | initialValue: 'front' |
| | | })( |
| | | <Radio.Group> |
| | | <Radio value="init">初始化</Radio> |
| | | <Radio value="front">sql前</Radio> |
| | | <Radio value="back">sql后</Radio> |
| | | </Radio.Group> |
| | | )} |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={10}> |
| | | <Form.Item style={{marginBottom: 0}} label={'快捷添加'}> |
| | | <Select |
| | | showSearch |
| | | filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0} |
| | | onSelect={this.selectScript} |
| | | getPopupContainer={() => document.getElementById('verify-excelin-custom-scripts')} |
| | | > |
| | | <Select.Option key="default" value={'default'}> |
| | | 默认sql |
| | | </Select.Option> |
| | | <Select.Option key="debugger" value={`z_debug: select @ErrorCode='E',@retmsg='测试断点' goto aaa`}> |
| | | 测试断点 |
| | | </Select.Option> |
| | | {systemScripts.map((option, i) => |
| | | <Select.Option key={i} value={option.value}> |
| | | {option.name} |
| | | </Select.Option> |
| | | )} |
| | | </Select> |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={6} className="add"> |
| | | <Button onClick={this.handleConfirm} loading={this.state.loading} className="mk-green" style={{marginBottom: 15, marginLeft: 40}}> |
| | | 保存 |
| | | </Button> |
| | | <Button onClick={this.handleCancel} style={{marginBottom: 15, marginLeft: 10}}> |
| | | 取消 |
| | | </Button> |
| | | </Col> |
| | | <Col span={24} className="sql"> |
| | | <Form.Item label={'sql'}> |
| | | {getFieldDecorator('sql', { |
| | | initialValue: '', |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: '请输入sql!' |
| | | } |
| | | ] |
| | | })(<CodeMirror />)} |
| | | </Form.Item> |
| | | </Col> |
| | | </Row> |
| | | </Form> |
| | | ) |
| | | } |
| | | } |
| | | |
| | | export default Form.create()(CustomForm) |
New file |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { Form, Row, Col, Input, Radio, Tooltip, notification } from 'antd' |
| | | import { QuestionCircleOutlined } from '@ant-design/icons' |
| | | |
| | | import Utils from '@/utils/utils.js' |
| | | import asyncComponent from '@/utils/asyncComponent' |
| | | import './index.scss' |
| | | |
| | | const CodeMirror = asyncComponent(() => import('@/templates/zshare/codemirror')) |
| | | |
| | | class SettingForm extends Component { |
| | | static propTpyes = { |
| | | setting: PropTypes.object, // 数据源配置 |
| | | } |
| | | |
| | | state = { |
| | | dataType: '', |
| | | defaultSql: 'true' |
| | | } |
| | | |
| | | UNSAFE_componentWillMount () { |
| | | const { setting } = this.props |
| | | |
| | | this.setState({ |
| | | dataType: setting.dataType, |
| | | defaultSql: setting.defaultSql || 'true' |
| | | }) |
| | | } |
| | | |
| | | handleConfirm = () => { |
| | | // 表单提交时检查输入值是否正确 |
| | | return new Promise((resolve, reject) => { |
| | | this.props.form.validateFieldsAndScroll((err, values) => { |
| | | if (!err) { |
| | | // 数据源前端验证 |
| | | if (values.defaultSql === 'true' && !values.dataresource) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '请填写数据源!', |
| | | duration: 5 |
| | | }) |
| | | reject() |
| | | return |
| | | } else if (values.defaultSql === 'true' && values.dataresource) { |
| | | let _quot = values.dataresource.match(/'{1}/g) |
| | | let _lparen = values.dataresource.match(/\({1}/g) |
| | | let _rparen = values.dataresource.match(/\){1}/g) |
| | | |
| | | _quot = _quot ? _quot.length : 0 |
| | | _lparen = _lparen ? _lparen.length : 0 |
| | | _rparen = _rparen ? _rparen.length : 0 |
| | | |
| | | if (_quot % 2 !== 0) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '数据源中\'必须成对出现', |
| | | duration: 5 |
| | | }) |
| | | reject() |
| | | return |
| | | } else if (_lparen !== _rparen) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '数据源中()必须成对出现', |
| | | duration: 5 |
| | | }) |
| | | reject() |
| | | return |
| | | } else if (/--/ig.test(values.dataresource)) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '数据源中,不可出现字符 -- ,注释请用 /*内容*/', |
| | | duration: 5 |
| | | }) |
| | | reject() |
| | | return |
| | | } |
| | | |
| | | let error = Utils.verifySql(values.dataresource) |
| | | |
| | | if (error) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '数据源中不可使用' + error, |
| | | duration: 5 |
| | | }) |
| | | reject() |
| | | return |
| | | } |
| | | } |
| | | |
| | | resolve(values) |
| | | } else { |
| | | reject(err) |
| | | } |
| | | }) |
| | | }) |
| | | } |
| | | |
| | | updateDataType = (e) => { |
| | | this.setState({dataType: e.target.value}) |
| | | this.props.updateDataType(e.target.value) |
| | | } |
| | | |
| | | render() { |
| | | const { setting } = this.props |
| | | const { getFieldDecorator } = this.props.form |
| | | const { dataType, defaultSql } = this.state |
| | | |
| | | const formItemLayout = { |
| | | labelCol: { |
| | | xs: { span: 24 }, |
| | | sm: { span: 8 } |
| | | }, |
| | | wrapperCol: { |
| | | xs: { span: 24 }, |
| | | sm: { span: 16 } |
| | | } |
| | | } |
| | | |
| | | return ( |
| | | <div className="excelout-datasource-wrap"> |
| | | <Form {...formItemLayout}> |
| | | <Row gutter={24}> |
| | | <Col span={8}> |
| | | <Form.Item label="导出数据"> |
| | | {getFieldDecorator('dataType', { |
| | | initialValue: setting.dataType |
| | | })( |
| | | <Radio.Group onChange={this.updateDataType}> |
| | | <Radio value="default">默认</Radio> |
| | | <Radio value="custom">自定义</Radio> |
| | | </Radio.Group> |
| | | )} |
| | | </Form.Item> |
| | | </Col> |
| | | {dataType === 'custom' ? <Col className="short-label" span={8}> |
| | | <Form.Item label="表名"> |
| | | {getFieldDecorator('tableName', { |
| | | initialValue: setting.tableName || '', |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: '请输入表名!' |
| | | }, |
| | | { |
| | | max: 50, |
| | | message: '表名最长为50个字符!' |
| | | } |
| | | ] |
| | | })(<Input placeholder={''} autoComplete="off" />)} |
| | | </Form.Item> |
| | | </Col> : null} |
| | | {dataType === 'custom' ? <Col span={8}> |
| | | <Form.Item label="默认sql"> |
| | | {getFieldDecorator('defaultSql', { |
| | | initialValue: setting.defaultSql || 'true' |
| | | })( |
| | | <Radio.Group onChange={(e) => this.setState({defaultSql: e.target.value})}> |
| | | <Radio value="true">执行</Radio> |
| | | <Radio value="false">不执行</Radio> |
| | | </Radio.Group>)} |
| | | </Form.Item> |
| | | </Col> : null} |
| | | {dataType === 'custom' && defaultSql === 'true' ? <Col span={24} className="data-source" style={{paddingLeft: '7px'}}> |
| | | <Form.Item labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} } label={ |
| | | <Tooltip placement="topLeft" title={`注:数据权限替换符 $@ -> /* 或 ''、 @$ -> */ 或 ''。`}> |
| | | <QuestionCircleOutlined className="mk-form-tip" /> |
| | | 数据源 |
| | | </Tooltip> |
| | | }> |
| | | {getFieldDecorator('dataresource', { |
| | | initialValue: setting.dataresource || '', |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: '请填写数据源!' |
| | | } |
| | | ] |
| | | })(<CodeMirror />)} |
| | | </Form.Item> |
| | | </Col> : null} |
| | | {dataType === 'custom' ? <Col span={8}> |
| | | <Form.Item label={ |
| | | <Tooltip placement="topLeft" title={'查询时,搜索条件以where条件拼接进入sql,统计时,将数据源中以“@+搜索字段+@”的内容,以搜索条件中的值进行替换后,提交查询,注:查询类型仅在使用系统函数时有效。'}> |
| | | <QuestionCircleOutlined className="mk-form-tip" /> |
| | | 查询类型 |
| | | </Tooltip> |
| | | }> |
| | | {getFieldDecorator('queryType', { |
| | | initialValue: setting.queryType || 'query' |
| | | })( |
| | | <Radio.Group> |
| | | <Radio value="query">查询</Radio> |
| | | <Radio value="statistics">统计</Radio> |
| | | </Radio.Group>)} |
| | | </Form.Item> |
| | | </Col> : null} |
| | | {dataType === 'custom' && defaultSql === 'true' ? <Col className="short-label" span={8}> |
| | | <Form.Item label={ |
| | | <Tooltip placement="topLeft" title="排序方式为空时,使用表格或组件中的排序方式。"> |
| | | <QuestionCircleOutlined className="mk-form-tip" /> |
| | | 排序方式 |
| | | </Tooltip> |
| | | }> |
| | | {getFieldDecorator('order', { |
| | | initialValue: setting.order || '' |
| | | })(<Input placeholder={'ID asc, UID desc'} autoComplete="off" />)} |
| | | </Form.Item> |
| | | </Col> : null} |
| | | {dataType === 'custom' ? <Col span={8}> |
| | | <Form.Item label={ |
| | | <Tooltip placement="topLeft" title="不使用搜索条件时,不会进行搜索条件的拼接与相关统计字段的替换。注:自定义数据来源时,只使用内部搜索。"> |
| | | <QuestionCircleOutlined className="mk-form-tip" /> |
| | | 搜索条件 |
| | | </Tooltip> |
| | | }> |
| | | {getFieldDecorator('useSearch', { |
| | | initialValue: setting.useSearch || 'true' |
| | | })( |
| | | <Radio.Group> |
| | | <Radio value="true">使用</Radio> |
| | | <Radio value="false">不使用</Radio> |
| | | </Radio.Group>)} |
| | | </Form.Item> |
| | | </Col> : null} |
| | | {dataType === 'custom' ? <Col span={8}> |
| | | <Form.Item label="事务"> |
| | | {getFieldDecorator('transaction', { |
| | | initialValue: setting.transaction || 'false' |
| | | })( |
| | | <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 |
| | |
| | | .excelout-datasource-wrap { |
| | | position: relative; |
| | | |
| | | .data-source { |
| | | .ant-form-item-label { |
| | | width: 11%; |
| | | } |
| | | .ant-form-item-control-wrapper { |
| | | width: 83%; |
| | | } |
| | | .CodeMirror { |
| | | height: 270px; |
| | | } |
| | | } |
| | | .short-label { |
| | | .ant-form-item-control-wrapper { |
| | | width: 55%; |
| | | } |
| | | } |
| | | } |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { fromJS } from 'immutable' |
| | | import { Form, Tabs, Row, Col, Button, notification, Modal, message, InputNumber, Radio } from 'antd' |
| | | import { Form, Tabs, Row, Col, Button, notification, Modal, message, InputNumber, Radio, Spin, Typography, Popconfirm } from 'antd' |
| | | import { EditOutlined, StopOutlined, CheckCircleOutlined, SwapOutlined, DeleteOutlined } from '@ant-design/icons' |
| | | import moment from 'moment' |
| | | |
| | | import Api from '@/api' |
| | | import Utils from '@/utils/utils.js' |
| | | |
| | | import SettingUtils from './utils.jsx' |
| | | import ColumnForm from './columnform' |
| | | import DataSource from './datasource' |
| | | import CustomScript from './customscript' |
| | | import CodeMirror from '@/templates/zshare/codemirror' |
| | | import asyncComponent from '@/utils/asyncComponent' |
| | | import './index.scss' |
| | | |
| | | const { TabPane } = Tabs |
| | | const { confirm } = Modal |
| | | const { Paragraph } = Typography |
| | | const EditTable = asyncComponent(() => import('@/templates/zshare/editTable')) |
| | | |
| | | class VerifyCard extends Component { |
| | |
| | | |
| | | state = { |
| | | verify: {}, |
| | | activeKey: 'setting', |
| | | systemScripts: [], |
| | | defaultscript: '', // 自定义脚本 |
| | | excelColumns: [ |
| | | { |
| | |
| | | {value: 'false', text: '否'} |
| | | ] |
| | | } |
| | | ], |
| | | scriptsColumns: [ |
| | | { |
| | | title: 'SQL', |
| | | dataIndex: 'sql', |
| | | width: '60%', |
| | | render: (text) => { |
| | | let title = text.match(/^\s*\/\*.+\*\//) |
| | | title = title && title[0] ? title[0] : '' |
| | | let _text = title ? text.replace(title, '') : text |
| | | |
| | | return ( |
| | | <div> |
| | | {title ? <span style={{color: '#a50'}}>{title}<span style={{fontSize: '12px', marginLeft: '5px'}}>{_text.length}</span></span> : null} |
| | | <Paragraph copyable={{ text: text }} ellipsis={{ rows: 4, expandable: true }}>{_text}</Paragraph> |
| | | </div> |
| | | ) |
| | | } |
| | | }, |
| | | { |
| | | title: '执行位置', |
| | | dataIndex: 'position', |
| | | width: '10%', |
| | | render: (text, record) => { |
| | | if (record.position === 'init') { |
| | | return <span style={{color: 'orange'}}>初始化</span> |
| | | } else if (record.position === 'front') { |
| | | return <span style={{color: '#26C281'}}>sql前</span> |
| | | } else { |
| | | return <span style={{color: '#1890ff'}}>sql后</span> |
| | | } |
| | | } |
| | | }, |
| | | { |
| | | title: '状态', |
| | | dataIndex: 'status', |
| | | width: '10%', |
| | | render: (text, record) => record.status === 'false' ? |
| | | ( |
| | | <div style={{color: '#ff4d4f'}}> |
| | | {this.props.dict['model.status.forbidden']} |
| | | <StopOutlined style={{marginLeft: '5px'}} /> |
| | | </div> |
| | | ) : |
| | | ( |
| | | <div style={{color: '#26C281'}}> |
| | | {this.props.dict['model.status.open']} |
| | | <CheckCircleOutlined style={{marginLeft: '5px'}}/> |
| | | </div> |
| | | ) |
| | | }, |
| | | { |
| | | title: '操作', |
| | | align: 'center', |
| | | width: '140px', |
| | | dataIndex: 'operation', |
| | | render: (text, record) => |
| | | (<div style={{textAlign: 'center'}}> |
| | | <span className="operation-btn" title={this.props.dict['model.edit']} onClick={() => this.handleEdit(record, 'scripts')} style={{color: '#1890ff'}}><EditOutlined /></span> |
| | | <span className="operation-btn" title={this.props.dict['header.form.status.change']} onClick={() => this.handleStatus(record, 'scripts')} style={{color: '#8E44AD'}}><SwapOutlined /></span> |
| | | <Popconfirm |
| | | overlayClassName="popover-confirm" |
| | | title={this.props.dict['model.query.delete']} |
| | | onConfirm={() => this.handleDelete(record, 'scripts') |
| | | }> |
| | | <span className="operation-btn" style={{color: '#ff4d4f'}}><DeleteOutlined /></span> |
| | | </Popconfirm> |
| | | </div>) |
| | | } |
| | | ] |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | _verify.enable = _verify.enable || 'false' |
| | | _verify.dataType = _verify.dataType || 'default' |
| | | _verify.columns = _verify.columns || [] |
| | | _verify.scripts = _verify.scripts || [] |
| | | |
| | | if (card.intertype !== 'system') { |
| | | _verify.enable = 'false' |
| | |
| | | defaultscript = `update ${config.setting.tableName || ''} set idefine5= idefine5+1 ,modifydate=getdate(),cdefine5='已导出',modifyuserid=@userid@ ${search}` |
| | | } |
| | | |
| | | let search = [] |
| | | |
| | | if (config.setting && config.setting.useMSearch === 'true' && window.GLOB.customMenu) { |
| | | let menu = fromJS(window.GLOB.customMenu).toJS() |
| | | let _search = null |
| | | let filterComponent = (box) => { |
| | | box.components.forEach(item => { |
| | | if (_search) return |
| | | |
| | | if (item.type === 'search') { |
| | | box.slist = [...box.slist, item.search] |
| | | } else if (item.uuid === config.uuid) { |
| | | _search = box.slist.pop() |
| | | } else if (item.type === 'group') { |
| | | item.components.forEach(m => { |
| | | if (m.uuid !== config.uuid) return |
| | | _search = box.slist.pop() |
| | | }) |
| | | } else if (item.type === 'tabs') { |
| | | item.subtabs.forEach(tab => { |
| | | tab.slist = [...box.slist] |
| | | filterComponent(tab) |
| | | }) |
| | | } |
| | | }) |
| | | } |
| | | menu.slist = [] |
| | | filterComponent(menu) |
| | | |
| | | if (_search) { |
| | | search = _search |
| | | } else { |
| | | menu.components.forEach(item => { |
| | | if (item.type !== 'search') return |
| | | search = item.search |
| | | }) |
| | | } |
| | | } |
| | | |
| | | let searches = fromJS(config.search || []).toJS() |
| | | |
| | | if (search.length > 0) { |
| | | let keys = searches.map(item => (item.field ? item.field.toLowerCase() : '')) |
| | | search.forEach(item => { |
| | | if (item.field && !keys.includes(item.field.toLowerCase())) { |
| | | searches.push(item) |
| | | } |
| | | }) |
| | | } |
| | | |
| | | this.setState({ |
| | | verify: _verify, |
| | | searches: searches, |
| | | activeKey: card.intertype === 'system' && _verify.dataType === 'custom' ? 'setting' : 'columns', |
| | | defaultscript: defaultscript |
| | | }) |
| | | } |
| | | |
| | | componentDidMount () { |
| | | let _scriptSql = `Select distinct func+Remark as funcname,longparam, s.Sort from s_custom_script s inner join (select OpenID from sapp where ID=@Appkey@) p on s.openid = case when s.appkey='' then s.openid else p.OpenID end order by s.Sort` |
| | | |
| | | _scriptSql = Utils.formatOptions(_scriptSql) |
| | | |
| | | let _sParam = { |
| | | func: 'sPC_Get_SelectedList', |
| | | LText: _scriptSql, |
| | | obj_name: 'data', |
| | | arr_field: 'funcname,longparam' |
| | | } |
| | | |
| | | _sParam.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') |
| | | _sParam.secretkey = Utils.encrypt(_sParam.LText, _sParam.timestamp) |
| | | |
| | | _sParam.open_key = Utils.encryptOpenKey(_sParam.secretkey, _sParam.timestamp) // 云端数据验证 |
| | | |
| | | Api.getSystemConfig(_sParam).then(res => { |
| | | if (res.status) { |
| | | this.setState({ |
| | | systemScripts: res.data.map(item => { |
| | | return { |
| | | name: item.funcname, |
| | | value: window.decodeURIComponent(window.atob(item.longparam)) |
| | | } |
| | | }) |
| | | }) |
| | | } else { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: res.message, |
| | | duration: 5 |
| | | }) |
| | | } |
| | | }) |
| | | } |
| | | |
| | | handleEdit = (record, type) => { |
| | | if (type === 'scripts') { |
| | | this.scriptsForm.edit(record) |
| | | } |
| | | |
| | | let node = document.getElementById('verify-excelout-box-tab').parentNode |
| | | |
| | | if (node && node.scrollTop) { |
| | | let inter = Math.ceil(node.scrollTop / 10) |
| | | |
| | | let timer = setInterval(() => { |
| | | if (node.scrollTop - inter > 0) { |
| | | node.scrollTop = node.scrollTop - inter |
| | | } else { |
| | | node.scrollTop = 0 |
| | | clearInterval(timer) |
| | | } |
| | | }, 10) |
| | | } |
| | | } |
| | | |
| | | handleStatus = (record, type) => { |
| | | let verify = JSON.parse(JSON.stringify(this.state.verify)) |
| | | record.status = record.status === 'false' ? 'true' : 'false' |
| | | |
| | | if (type === 'scripts') { |
| | | verify.scripts = verify.scripts.map(item => { |
| | | if (item.uuid === record.uuid) { |
| | | return record |
| | | } else { |
| | | return item |
| | | } |
| | | }) |
| | | } |
| | | |
| | | this.setState({ |
| | | verify: verify |
| | | }) |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | handleConfirm = () => { |
| | | let verify = fromJS(this.state.verify).toJS() |
| | | const { activeKey, verify } = this.state |
| | | |
| | | // 表单提交时检查输入值是否正确 |
| | | return new Promise((resolve, reject) => { |
| | |
| | | return |
| | | } |
| | | |
| | | if (verify.enable === 'true') { |
| | | this.props.form.validateFieldsAndScroll((err, values) => { |
| | | if (!err) { |
| | | values.sql = values.sql || '' |
| | | if (activeKey === 'backscript' && verify.enable === 'true') { |
| | | this.checkScript(resolve, reject) |
| | | } else if (activeKey === 'setting') { |
| | | this.settingForm.handleConfirm().then(res => { |
| | | let _verify = {...verify, ...res} |
| | | this.setState({ |
| | | verify: _verify |
| | | }, () => { |
| | | this.setState({loading: true}) |
| | | this.sqlverify(() => { // 验证成功 |
| | | this.setState({ |
| | | loading: false |
| | | }) |
| | | resolve(_verify) |
| | | }, () => { // 验证失败 |
| | | this.setState({ |
| | | loading: false |
| | | }) |
| | | reject() |
| | | }, verify.scripts) |
| | | }) |
| | | }) |
| | | } else if (activeKey === 'columns') { |
| | | if (this.columnRef && this.columnRef.state.editingKey) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '字段未保存!', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } |
| | | |
| | | let _quot = values.sql.match(/'{1}/g) |
| | | let _lparen = values.sql.match(/\({1}/g) |
| | | let _rparen = values.sql.match(/\){1}/g) |
| | | if (this.props.card.intertype !== 'system' || verify.dataType !== 'custom') { |
| | | resolve(verify) |
| | | } else { |
| | | this.setState({loading: true}) |
| | | |
| | | _quot = _quot ? _quot.length : 0 |
| | | _lparen = _lparen ? _lparen.length : 0 |
| | | _rparen = _rparen ? _rparen.length : 0 |
| | | |
| | | if (_quot % 2 !== 0) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: 'sql中\'必须成对出现', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } else if (_lparen !== _rparen) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: 'sql中()必须成对出现', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } else if (/--/ig.test(values.sql)) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '自定义sql语句中,不可出现字符 -- ,注释请用 /*内容*/', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } |
| | | |
| | | let error = Utils.verifySql(values.sql, 'customscript') |
| | | |
| | | if (error) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: 'sql中不可使用' + error, |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } |
| | | |
| | | let param = { |
| | | func: 's_debug_sql', |
| | | exec_type: 'y', |
| | | LText: values.sql |
| | | } |
| | | |
| | | 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) |
| | | |
| | | Api.getLocalConfig(param).then(res => { |
| | | if (res.status) { |
| | | resolve({...verify, script: values.sql}) |
| | | } else { |
| | | Modal.error({ |
| | | title: res.message |
| | | }) |
| | | } |
| | | this.sqlverify(() => { // 验证成功 |
| | | this.setState({ |
| | | loading: false |
| | | }) |
| | | resolve(verify) |
| | | }, () => { // 验证失败 |
| | | this.setState({ |
| | | loading: false |
| | | }) |
| | | reject() |
| | | }, verify.scripts) |
| | | } |
| | | } else if (activeKey === 'scripts') { |
| | | if (this.scriptsForm && this.scriptsForm.props.form.getFieldValue('sql') && !/^\s+$/.test(this.scriptsForm.props.form.getFieldValue('sql'))) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '存在未保存脚本,请点击确定保存,或点击取消放弃修改!', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } |
| | | |
| | | this.setState({loading: true}) |
| | | this.sqlverify(() => { // 验证成功 |
| | | this.setState({ |
| | | loading: false |
| | | }) |
| | | resolve(verify) |
| | | }, () => { // 验证失败 |
| | | this.setState({ |
| | | loading: false |
| | | }) |
| | | reject() |
| | | }, verify.scripts) |
| | | } else { |
| | | resolve(verify) |
| | | } |
| | | }) |
| | | } |
| | | |
| | | checkScript = (_resolve, _reject) => { |
| | | this.props.form.validateFieldsAndScroll((err, values) => { |
| | | if (!err) { |
| | | values.sql = values.sql || '' |
| | | |
| | | let _quot = values.sql.match(/'{1}/g) |
| | | let _lparen = values.sql.match(/\({1}/g) |
| | | let _rparen = values.sql.match(/\){1}/g) |
| | | |
| | | _quot = _quot ? _quot.length : 0 |
| | | _lparen = _lparen ? _lparen.length : 0 |
| | | _rparen = _rparen ? _rparen.length : 0 |
| | | |
| | | if (_quot % 2 !== 0) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: 'sql中\'必须成对出现', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } else if (_lparen !== _rparen) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: 'sql中()必须成对出现', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } else if (/--/ig.test(values.sql)) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '自定义sql语句中,不可出现字符 -- ,注释请用 /*内容*/', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } |
| | | |
| | | let error = Utils.verifySql(values.sql, 'customscript') |
| | | |
| | | if (error) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: 'sql中不可使用' + error, |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } |
| | | |
| | | let param = { |
| | | func: 's_debug_sql', |
| | | exec_type: 'y', |
| | | LText: values.sql |
| | | } |
| | | |
| | | 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) |
| | | |
| | | this.setState({ |
| | | loading: true |
| | | }) |
| | | Api.getLocalConfig(param).then(res => { |
| | | this.setState({ |
| | | loading: false |
| | | }) |
| | | if (res.status) { |
| | | let verify = {...this.state.verify, script: values.sql} |
| | | |
| | | this.setState({verify: verify}, () => { |
| | | _resolve(verify) |
| | | }) |
| | | } else { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '自定义脚本不可为空!', |
| | | duration: 5 |
| | | Modal.error({ |
| | | title: res.message |
| | | }) |
| | | } |
| | | }) |
| | | } else { |
| | | resolve(verify) |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '自定义脚本不可为空!', |
| | | duration: 5 |
| | | }) |
| | | _reject() |
| | | } |
| | | }) |
| | | } |
| | |
| | | this.setState({verify: {...verify, columns}}) |
| | | } |
| | | |
| | | // 标签切换 |
| | | tabchange = (val) => { |
| | | const { card } = this.props |
| | | const { activeKey, verify } = this.state |
| | | |
| | | if (activeKey === 'backscript' && verify.enable === 'true') { |
| | | this.checkScript(() => { |
| | | this.setState({ |
| | | activeKey: val |
| | | }) |
| | | }, () => {}) |
| | | } else if (card.intertype !== 'system' || verify.dataType !== 'custom') { |
| | | this.setState({activeKey: val}) |
| | | return |
| | | } else if (activeKey === 'setting') { |
| | | this.settingForm.handleConfirm().then(res => { |
| | | this.setState({ |
| | | verify: {...verify, ...res} |
| | | }, () => { |
| | | this.setState({loading: true}) |
| | | this.sqlverify(() => { // 验证成功 |
| | | this.setState({ |
| | | activeKey: val, |
| | | loading: false |
| | | }) |
| | | }, () => { // 验证失败 |
| | | this.setState({ |
| | | activeKey: val, |
| | | loading: false |
| | | }) |
| | | }, verify.scripts) |
| | | }) |
| | | }) |
| | | } else if (activeKey === 'columns') { |
| | | if (this.columnRef && this.columnRef.state.editingKey) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '字段未保存!', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } |
| | | |
| | | this.setState({loading: true}) |
| | | |
| | | this.sqlverify(() => { // 验证成功 |
| | | this.setState({ |
| | | activeKey: val, |
| | | loading: false |
| | | }) |
| | | }, () => { // 验证失败 |
| | | this.setState({ |
| | | activeKey: val, |
| | | loading: false |
| | | }) |
| | | }, verify.scripts) |
| | | } else if (activeKey === 'scripts') { |
| | | if (this.scriptsForm && this.scriptsForm.props.form.getFieldValue('sql') && !/^\s+$/.test(this.scriptsForm.props.form.getFieldValue('sql'))) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '存在未保存脚本,请点击确定保存,或点击取消放弃修改!', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } |
| | | |
| | | this.setState({loading: true}) |
| | | this.sqlverify(() => { // 验证成功 |
| | | this.setState({ |
| | | activeKey: val, |
| | | loading: false |
| | | }) |
| | | }, () => { // 验证失败 |
| | | this.setState({ |
| | | activeKey: val, |
| | | loading: false |
| | | }) |
| | | }, verify.scripts) |
| | | } else { |
| | | this.setState({ |
| | | activeKey: val |
| | | }) |
| | | } |
| | | } |
| | | |
| | | scriptsChange = (values) => { |
| | | let verify = JSON.parse(JSON.stringify(this.state.verify)) |
| | | |
| | | if (values.uuid) { |
| | | verify.scripts = verify.scripts.map(item => { |
| | | if (item.uuid === values.uuid) { |
| | | return values |
| | | } else { |
| | | return item |
| | | } |
| | | }) |
| | | } else { |
| | | values.uuid = Utils.getuuid() |
| | | verify.scripts.push(values) |
| | | } |
| | | |
| | | this.setState({loading: true}) |
| | | |
| | | this.sqlverify(() => { // 验证成功 |
| | | this.setState({ |
| | | loading: false, |
| | | verify: verify |
| | | }) |
| | | }, () => { // 验证失败 |
| | | this.setState({ |
| | | loading: false |
| | | }) |
| | | }, verify.scripts) |
| | | } |
| | | |
| | | sqlverify = (_resolve, _reject, scripts) => { |
| | | const { searches, verify } = this.state |
| | | |
| | | let sql = SettingUtils.getDebugSql(verify, scripts, searches, Utils) |
| | | let param = { |
| | | func: 's_debug_sql', |
| | | exec_type: 'y', |
| | | LText: sql |
| | | } |
| | | param.LText = Utils.formatOptions(param.LText) |
| | | param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') |
| | | param.secretkey = Utils.encrypt('', param.timestamp) |
| | | |
| | | Api.getLocalConfig(param).then(result => { |
| | | if (result.status) { |
| | | _resolve() |
| | | } else { |
| | | _reject() |
| | | Modal.error({ |
| | | title: result.message |
| | | }) |
| | | } |
| | | }) |
| | | } |
| | | |
| | | updateDataType = (val) => { |
| | | this.setState({verify: {...this.state.verify, dataType: val}}) |
| | | } |
| | | |
| | | render() { |
| | | const { card } = this.props |
| | | const { verify, excelColumns, defaultscript } = this.state |
| | | const { verify, excelColumns, defaultscript, scriptsColumns, activeKey, loading } = this.state |
| | | const { getFieldDecorator } = this.props.form |
| | | const formItemLayout = { |
| | | labelCol: { |
| | |
| | | |
| | | return ( |
| | | <div id="verify-excelout-box-tab"> |
| | | <Tabs defaultActiveKey="1" className="excelout-verify-card-box" onChange={this.tabchange}> |
| | | {loading && <Spin size="large" />} |
| | | <Tabs activeKey={activeKey} className="excelout-verify-card-box" onChange={this.tabchange}> |
| | | {card.intertype === 'system' ? <TabPane tab="基础验证" key="setting"> |
| | | <DataSource setting={verify} updateDataType={this.updateDataType} wrappedComponentRef={(inst) => this.settingForm = inst}/> |
| | | </TabPane> : null} |
| | | <TabPane tab={ |
| | | <span> |
| | | Excel导出列 |
| | | {verify.columns.length ? <span className="count-tip">{verify.columns.length}</span> : null} |
| | | </span> |
| | | } key="1"> |
| | | } key="columns"> |
| | | <ColumnForm dict={this.props.dict} columnChange={this.columnChange}/> |
| | | <Button className="excel-col-add mk-green" title="添加显示列字段" onClick={this.columnFieldInput}> |
| | | 同步显示列 |
| | |
| | | 清空Excel列 |
| | | </Button> |
| | | <div style={{color: '#959595', fontSize: '13px', paddingLeft: '10px'}}>如需导出序号,请使用字段 $Index。</div> |
| | | <EditTable actions={['edit', 'move', 'copy', 'del']} type="excelcolumn" data={verify.columns} columns={excelColumns} onChange={this.changeColumns}/> |
| | | <EditTable actions={['edit', 'move', 'copy', 'del']} type="excelcolumn" wrappedComponentRef={(inst) => this.columnRef = inst} data={verify.columns} columns={excelColumns} onChange={this.changeColumns}/> |
| | | </TabPane> |
| | | {card.intertype === 'system' ? <TabPane tab={ |
| | | <span> |
| | | 自定义脚本 |
| | | {verify.scripts.length ? <span className="count-tip">{verify.scripts.length}</span> : null} |
| | | </span> |
| | | } key="scripts" disabled={verify.dataType !== 'custom'}> |
| | | <CustomScript |
| | | btn={card} |
| | | sheet={verify.tableName} |
| | | usefulfields={verify.columns} |
| | | scripts={verify.scripts} |
| | | systemScripts={this.state.systemScripts} |
| | | scriptsChange={this.scriptsChange} |
| | | wrappedComponentRef={(inst) => this.scriptsForm = inst} |
| | | /> |
| | | <EditTable actions={['move']} data={verify.scripts} columns={scriptsColumns} onChange={(scripts) => {this.setState({verify: {...verify, scripts}})}}/> |
| | | </TabPane> : null} |
| | | {card.intertype === 'system' ? <TabPane tab={ |
| | | <span> |
| | | 回调脚本 |
| | | {verify.enable === 'true' ? <span className="count-tip">1</span> : null} |
| | | </span> |
| | | } key="6"> |
| | | } key="backscript"> |
| | | <Form {...formItemLayout} className="verify-form"> |
| | | <Row gutter={24}> |
| | | <Col span={8}> |
| | |
| | | </Row> |
| | | </Form> |
| | | </TabPane> : null} |
| | | <TabPane tab="信息提示" key="7"> |
| | | <TabPane tab="信息提示" key="message"> |
| | | <Form {...formItemLayout}> |
| | | <Row gutter={24}> |
| | | <Col offset={6} span={6}> |
| | |
| | | } |
| | | } |
| | | #verify-excelout-box-tab { |
| | | >.ant-spin { |
| | | position: absolute; |
| | | top: calc(50% - 16px); |
| | | left: calc(50% - 16px); |
| | | z-index: 1; |
| | | } |
| | | .ant-tabs-tabpane { |
| | | position: relative; |
| | | .excel-col-add { |
New file |
| | |
| | | |
| | | import moment from 'moment' |
| | | |
| | | export default class SettingUtils { |
| | | /** |
| | | * @description 生成页面查询语句 |
| | | */ |
| | | static getDebugSql (verify, scripts, searches, Utils) { |
| | | let sql = '' |
| | | let _dataresource = verify.dataresource || '' |
| | | let regoptions = this.getRegOptions(searches) |
| | | let _search = this.formatSearch(searches) |
| | | _search = Utils.joinMainSearchkey(_search) |
| | | |
| | | _search = _search.replace(/@\$@/ig, '') |
| | | _search = _search ? 'where ' + _search : '' |
| | | |
| | | let arr_field = [] |
| | | verify.columns.forEach(item => { |
| | | if (item.Column !== '$Index') { |
| | | arr_field.push(item.Column) |
| | | } |
| | | }) |
| | | arr_field = arr_field.join(',') |
| | | |
| | | let _customScript = '' |
| | | scripts && scripts.forEach(script => { |
| | | if (script.status === 'false') return |
| | | _customScript += ` |
| | | ${script.sql} |
| | | ` |
| | | }) |
| | | |
| | | if (_customScript) { |
| | | _customScript = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(50),@mk_organization nvarchar(50),@login_city nvarchar(50) select @ErrorCode='',@retmsg ='' |
| | | ${_customScript} |
| | | ` |
| | | } |
| | | |
| | | if (verify.defaultSql === 'false') { |
| | | _dataresource = '' |
| | | } |
| | | |
| | | if (window.GLOB.funcs && window.GLOB.funcs.length > 0) { |
| | | window.GLOB.funcs.forEach(item => { |
| | | let reg = new RegExp('\\$ex@' + item.func_code + '@ex\\$', 'ig') |
| | | _dataresource = _dataresource.replace(reg, `/*$ex@${item.func_code}-begin*/\n${item.key_sql}\n/*@ex$-end*/`) |
| | | _customScript = _customScript.replace(reg, `/*$ex@${item.func_code}-begin*/\n${item.key_sql}\n/*@ex$-end*/`) |
| | | }) |
| | | } |
| | | |
| | | _dataresource = _dataresource.replace(/@\$|\$@/ig, '') |
| | | _customScript = _customScript.replace(/@\$|\$@/ig, '') |
| | | |
| | | // 外联数据库替换 |
| | | if (window.GLOB.externalDatabase !== null) { |
| | | _dataresource = _dataresource.replace(/@db@/ig, window.GLOB.externalDatabase) |
| | | _customScript = _customScript.replace(/@db@/ig, window.GLOB.externalDatabase) |
| | | } |
| | | |
| | | // 正则替换 |
| | | let _regoptions = regoptions.map(item => { |
| | | return { |
| | | reg: new RegExp('@' + item.key + '@', 'ig'), |
| | | value: `'0'`, |
| | | type: item.type || '' |
| | | } |
| | | }) |
| | | |
| | | _regoptions.push({ |
| | | reg: new RegExp('@login_city@', 'ig'), |
| | | value: `''` |
| | | }, { |
| | | reg: new RegExp('@userName@', 'ig'), |
| | | value: `''` |
| | | }, { |
| | | reg: new RegExp('@fullName@', 'ig'), |
| | | value: `''` |
| | | }, { |
| | | reg: new RegExp('@orderBy@', 'ig'), |
| | | value: verify.order |
| | | }, { |
| | | reg: new RegExp('@pageSize@', 'ig'), |
| | | value: 10 |
| | | }, { |
| | | reg: new RegExp('@pageIndex@', 'ig'), |
| | | value: 1 |
| | | }) |
| | | |
| | | if (verify.queryType === 'statistics' && _dataresource) { |
| | | _regoptions.forEach(item => { |
| | | _dataresource = _dataresource.replace(item.reg, item.value) |
| | | }) |
| | | _search = '' |
| | | } else if (_dataresource) { |
| | | _regoptions.forEach(item => { |
| | | if (item.type !== 'url') return |
| | | _dataresource = _dataresource.replace(item.reg, item.value) |
| | | }) |
| | | } |
| | | |
| | | if (_customScript) { |
| | | _regoptions.forEach(item => { |
| | | _customScript = _customScript.replace(item.reg, item.value) |
| | | }) |
| | | } |
| | | |
| | | // 数据源处理, 存在显示列时 |
| | | if (arr_field && _dataresource) { |
| | | if (/\s/.test(_dataresource)) { |
| | | _dataresource = '(' + _dataresource + ') tb' |
| | | } |
| | | |
| | | if (verify.order) { |
| | | _dataresource = `select ${arr_field} from (select ${arr_field} ,ROW_NUMBER() over(order by ${verify.order}) as rows from ${_dataresource} ${_search}) tmptable order by tmptable.rows` |
| | | } else { |
| | | _dataresource = `select ${arr_field} from ${_dataresource} ${_search}` |
| | | } |
| | | } |
| | | |
| | | if (_customScript) { |
| | | sql = `/* sql 验证 */ |
| | | ${_customScript} |
| | | ${_dataresource} |
| | | aaa: |
| | | if @ErrorCode!='' |
| | | insert into tmp_err_retmsg (ID, ErrorCode, retmsg, CreateUserID) select @time_id@,@ErrorCode, @retmsg,@UserID@ |
| | | ` |
| | | } else { |
| | | sql = `/* sql 验证 */ |
| | | declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(50),@mk_organization nvarchar(50),@login_city nvarchar(50) select @ErrorCode='',@retmsg ='' |
| | | ${_dataresource}` |
| | | } |
| | | sql = sql.replace(/\n\s{8}/ig, '\n') |
| | | console.info(sql) |
| | | |
| | | return sql |
| | | } |
| | | |
| | | /** |
| | | * @description 获取全部搜索条件 |
| | | * @param {Array} searches 搜索条件数组 |
| | | */ |
| | | static formatSearch (searches) { |
| | | if (!searches || searches.length === 0) return [] |
| | | |
| | | let newsearches = [] |
| | | searches.forEach(search => { |
| | | if (!search.field) return |
| | | |
| | | let item = { |
| | | key: search.field, |
| | | match: search.match, |
| | | type: search.type, |
| | | label: search.label, |
| | | value: search.initval, |
| | | required: search.required === 'true' |
| | | } |
| | | |
| | | if (item.type === 'group') { |
| | | item.key = search.datefield |
| | | item.type = 'daterange' |
| | | item.match = 'between' |
| | | item.value = [moment().format('YYYY-MM-DD'), moment().format('YYYY-MM-DD')].join(',') |
| | | |
| | | newsearches.push(item) |
| | | return |
| | | } else if (item.type === 'date') { |
| | | item.value = moment().format('YYYY-MM-DD') |
| | | } else if (item.type === 'datemonth') { |
| | | item.value = moment().format('YYYY-MM') |
| | | } else if (item.type === 'dateweek') { |
| | | item.value = moment().format('YYYY-MM-DD') |
| | | } else if (item.type === 'daterange') { |
| | | item.value = [moment().format('YYYY-MM-DD'), moment().format('YYYY-MM-DD')].join(',') |
| | | } else if (item.type === 'multiselect' || (item.type === 'checkcard' && search.multiple === 'true')) { |
| | | item.type = 'multi' |
| | | item.value = '@$@' |
| | | } else { |
| | | item.value = '@$@' |
| | | } |
| | | newsearches.push(item) |
| | | }) |
| | | |
| | | return newsearches |
| | | } |
| | | |
| | | /** |
| | | * @description 获取搜索用于正则替换 |
| | | * @param {Array} searches 搜索条件 |
| | | * @return {String} searchText 拼接结果 |
| | | */ |
| | | static getRegOptions (searches) { |
| | | if (!searches || searches.length === 0) return [] |
| | | |
| | | let options = [] |
| | | let fieldmap = new Map() |
| | | searches.forEach(search => { |
| | | let item = { |
| | | key: search.field, |
| | | value: '0' |
| | | } |
| | | |
| | | if (fieldmap.has(item.key)) { |
| | | item.key = item.key + '1' |
| | | } |
| | | |
| | | fieldmap.set(item.key, true) |
| | | |
| | | if (search.type === 'group') { |
| | | options.push({ |
| | | key: search.field, |
| | | value: '0' |
| | | }) |
| | | options.push({ |
| | | key: search.datefield, |
| | | value: '0' |
| | | }) |
| | | options.push({ |
| | | key: search.datefield + '1', |
| | | value: '0' |
| | | }) |
| | | options.push(item) |
| | | } else if (['datemonth', 'dateweek', 'daterange'].includes(search.type)) { |
| | | options.push(item) |
| | | options.push({ |
| | | key: item.key + '1', |
| | | value: '0' |
| | | }) |
| | | } else if (search.type === 'text' || search.type === 'select') { |
| | | item.key.split(',').forEach(field => { |
| | | let cell = JSON.parse(JSON.stringify(item)) |
| | | cell.key = field |
| | | |
| | | options.push(cell) |
| | | }) |
| | | } else { |
| | | options.push(item) |
| | | } |
| | | }) |
| | | |
| | | return options |
| | | } |
| | | } |
New file |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { fromJS } from 'immutable' |
| | | import { Form, Tabs, Table, Row, Col, Button, notification, Modal, message, InputNumber } from 'antd' |
| | | |
| | | import './index.scss' |
| | | |
| | | const { TabPane } = Tabs |
| | | |
| | | class MegviiCard extends Component { |
| | | static propTpyes = { |
| | | columns: PropTypes.array, // 显示列 |
| | | dict: PropTypes.object, // 字典项 |
| | | card: PropTypes.object, |
| | | } |
| | | |
| | | state = { |
| | | verify: {}, |
| | | activeKey: 'excelcolumn', |
| | | excelColumns: [ |
| | | { |
| | | title: '名称', |
| | | dataIndex: 'field', |
| | | width: '20%' |
| | | }, |
| | | { |
| | | title: '数据类型', |
| | | dataIndex: 'datatype', |
| | | width: '20%' |
| | | }, |
| | | { |
| | | title: '变量类型', |
| | | dataIndex: 'type', |
| | | width: '20%' |
| | | }, |
| | | { |
| | | title: '是否必须', |
| | | dataIndex: 'required', |
| | | width: '15%' |
| | | }, |
| | | { |
| | | title: '备注', |
| | | dataIndex: 'remark', |
| | | width: '25%', |
| | | } |
| | | ], |
| | | excelData: [ |
| | | {field: 'id', datatype: 'string', type: 'nvarchar(50)', required: '必须', remark: '人员id'}, |
| | | {field: 'person_name', datatype: 'string', type: 'nvarchar(50)', required: '必须', remark: '人员名称'}, |
| | | {field: 'face_data', datatype: 'string', type: 'text', required: '必须', remark: 'Base64编码的照片数据(人脸信息)'}, |
| | | {field: 'group_list', datatype: 'string', type: 'nvarchar(50)', required: '非必须', remark: '绑定人员组的列表,多个使用逗号分隔,示例:\'1,2\''}, |
| | | {field: 'face_idx', datatype: 'integer', type: 'int', required: '非必须', remark: '照片索引,默认为0'}, |
| | | {field: 'is_admin', datatype: 'string', type: 'nvarchar(50)', required: '非必须', remark: '是否启用管理员权限,默认为\'false\''}, |
| | | {field: 'recognition_type', datatype: 'string', type: 'nvarchar(50)', required: '非必须', remark: '人员类型,staff – 普通人员(默认),visitor – 访客,blacklist – 黑名单'}, |
| | | {field: 'password', datatype: 'string', type: 'nvarchar(50)', required: '非必须', remark: '密码使用6位数字(AES加密)'}, |
| | | {field: 'id_number', datatype: 'string', type: 'nvarchar(50)', required: '非必须', remark: '身份证号码(AES加密)'}, |
| | | {field: 'person_code', datatype: 'string', type: 'nvarchar(50)', required: '非必须', remark: '人员编号'}, |
| | | {field: 'card_number', datatype: 'string', type: 'nvarchar(50)', required: '非必须', remark: '卡号,最大20位数字'}, |
| | | ] |
| | | } |
| | | |
| | | UNSAFE_componentWillMount() { |
| | | const { card } = this.props |
| | | let _verify = fromJS(card.verify || {}).toJS() |
| | | |
| | | this.setState({ |
| | | verify: _verify |
| | | }) |
| | | } |
| | | |
| | | componentDidMount () { |
| | | |
| | | } |
| | | |
| | | handleConfirm = () => { |
| | | const { verify } = this.state |
| | | |
| | | return Promise.resolve(verify) |
| | | } |
| | | |
| | | showError = (errorType) => { |
| | | if (errorType === 'S') { |
| | | notification.success({ |
| | | top: 92, |
| | | message: '执行成功!', |
| | | duration: 2 |
| | | }) |
| | | } else if (errorType === 'Y') { |
| | | Modal.success({ |
| | | title: '执行成功!' |
| | | }) |
| | | } else if (errorType === 'F') { |
| | | notification.error({ |
| | | className: 'notification-custom-error', |
| | | top: 92, |
| | | message: '执行失败!', |
| | | duration: 10 |
| | | }) |
| | | } else if (errorType === 'N') { |
| | | notification.error({ |
| | | top: 92, |
| | | message: '执行失败!', |
| | | duration: 10 |
| | | }) |
| | | } else if (errorType === 'E') { |
| | | Modal.error({ |
| | | title: '执行失败!' |
| | | }) |
| | | } else if (errorType === 'NM') { |
| | | message.error('执行失败!') |
| | | } |
| | | } |
| | | |
| | | timeChange = (val, type) => { |
| | | const { verify } = this.state |
| | | |
| | | this.setState({ |
| | | verify: {...verify, [type]: val} |
| | | }) |
| | | } |
| | | |
| | | tabchange = (val) => { |
| | | this.setState({activeKey: val}) |
| | | } |
| | | |
| | | render() { |
| | | const { verify, excelColumns, excelData, activeKey } = this.state |
| | | const formItemLayout = { |
| | | labelCol: { |
| | | xs: { span: 24 }, |
| | | sm: { span: 8 } |
| | | }, |
| | | wrapperCol: { |
| | | xs: { span: 24 }, |
| | | sm: { span: 16 } |
| | | } |
| | | } |
| | | |
| | | return ( |
| | | <div> |
| | | <Tabs activeKey={activeKey} className="megvii-verify-card-box" onChange={this.tabchange}> |
| | | <TabPane tab={ |
| | | <span> |
| | | 列设置 |
| | | </span> |
| | | } key="excelcolumn"> |
| | | <Table |
| | | bordered |
| | | rowKey="field" |
| | | className="custom-table" |
| | | dataSource={excelData} |
| | | columns={excelColumns} |
| | | pagination={false} |
| | | /> |
| | | </TabPane> |
| | | <TabPane tab="信息提示" key="tip"> |
| | | <Form {...formItemLayout}> |
| | | <Row gutter={24}> |
| | | <Col offset={6} span={6}> |
| | | <Form.Item label={'提示编码'}> |
| | | <span className="errorval"> S </span> |
| | | <Button onClick={() => {this.showError('S')}} type="primary" size="small"> |
| | | 查看 |
| | | </Button> |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={8}> |
| | | <Form.Item label={'停留时间'}> |
| | | <InputNumber defaultValue={verify.stime || 2} min={1} max={10000} precision={0} onChange={(val) => {this.timeChange(val, 'stime')}} /> |
| | | </Form.Item> |
| | | </Col> |
| | | </Row> |
| | | <Row gutter={24}> |
| | | <Col offset={6} span={6}> |
| | | <Form.Item label={'提示编码'}> |
| | | <span className="errorval"> Y </span> |
| | | <Button onClick={() => {this.showError('Y')}} type="primary" size="small"> |
| | | 查看 |
| | | </Button> |
| | | </Form.Item> |
| | | </Col> |
| | | </Row> |
| | | <Row gutter={24}> |
| | | <Col offset={6} span={6}> |
| | | <Form.Item label={'提示编码'}> |
| | | <span className="errorval"> N </span> |
| | | <Button onClick={() => {this.showError('N')}} type="primary" size="small"> |
| | | 查看 |
| | | </Button> |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={8}> |
| | | <Form.Item label={'停留时间'}> |
| | | <InputNumber defaultValue={verify.ntime || 10} min={1} max={10000} precision={0} onChange={(val) => {this.timeChange(val, 'ntime')}} /> |
| | | </Form.Item> |
| | | </Col> |
| | | </Row> |
| | | <Row gutter={24}> |
| | | <Col offset={6} span={6}> |
| | | <Form.Item label={'提示编码'}> |
| | | <span className="errorval"> F </span> |
| | | <Button onClick={() => {this.showError('F')}} type="primary" size="small"> |
| | | 查看 |
| | | </Button> |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={8}> |
| | | <Form.Item label={'停留时间'}> |
| | | <InputNumber defaultValue={verify.ftime || 10} min={1} max={10000} precision={0} onChange={(val) => {this.timeChange(val, 'ftime')}} /> |
| | | </Form.Item> |
| | | </Col> |
| | | </Row> |
| | | <Row gutter={24}> |
| | | <Col offset={6} span={6}> |
| | | <Form.Item label={'提示编码'}> |
| | | <span className="errorval"> E </span> |
| | | <Button onClick={() => {this.showError('E')}} type="primary" size="small"> |
| | | 查看 |
| | | </Button> |
| | | </Form.Item> |
| | | </Col> |
| | | </Row> |
| | | <Row gutter={24}> |
| | | <Col offset={6} span={6}> |
| | | <Form.Item label={'提示编码'}> |
| | | <span className="errorval"> NM </span> |
| | | <Button onClick={() => {this.showError('NM')}} type="primary" size="small"> |
| | | 查看 |
| | | </Button> |
| | | </Form.Item> |
| | | </Col> |
| | | </Row> |
| | | <Row gutter={24}> |
| | | <Col offset={6} span={6}> |
| | | <Form.Item label={'提示编码'}> |
| | | <span className="errorval"> -1 </span> |
| | | 不提示 |
| | | </Form.Item> |
| | | </Col> |
| | | </Row> |
| | | </Form> |
| | | </TabPane> |
| | | </Tabs> |
| | | </div> |
| | | ) |
| | | } |
| | | } |
| | | |
| | | export default Form.create()(MegviiCard) |
New file |
| | |
| | | .megvii-verify-card-box { |
| | | .ant-tabs-nav-scroll { |
| | | text-align: center; |
| | | } |
| | | .ant-tabs-content { |
| | | min-height: 40vh; |
| | | } |
| | | table tr td { |
| | | word-wrap: break-word; |
| | | word-break: break-word; |
| | | } |
| | | |
| | | .excel-custom-table { |
| | | position: relative; |
| | | top: -25px; |
| | | } |
| | | .errorval { |
| | | display: inline-block; |
| | | width: 30px; |
| | | } |
| | | .operation-btn { |
| | | display: inline-block; |
| | | font-size: 16px; |
| | | padding: 0 5px; |
| | | cursor: pointer; |
| | | } |
| | | .ant-tabs-tabpane { |
| | | position: relative; |
| | | .excel-col-add { |
| | | position: relative; |
| | | float: right; |
| | | right: -9px; |
| | | margin-right: 10px; |
| | | top: 10px; |
| | | z-index: 1; |
| | | } |
| | | } |
| | | } |
| | |
| | | } |
| | | } |
| | | |
| | | // 已弃用,不在开放添加通道 |
| | | render() { |
| | | const { config } = this.props |
| | | const { dict, chartlist, modaltype, card, chartview } = this.state |
| | |
| | | let param = { |
| | | func: 's_debug_sql', |
| | | exec_type: 'y', |
| | | LText: SettingUtils.getDebugSql(setting, _scripts, columns, Utils.getRegOptions(searches), config.calendar, config.urlFields) |
| | | LText: SettingUtils.getDebugSql(setting, _scripts, columns, this.getRegOptions(searches), config.calendar, config.urlFields) |
| | | } |
| | | param.LText = Utils.formatOptions(param.LText) |
| | | param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') |
| | |
| | | } |
| | | } |
| | | |
| | | getRegOptions = (searches) => { |
| | | if (!searches || searches.length === 0) return [] |
| | | |
| | | let options = [] |
| | | let fieldmap = new Map() |
| | | searches.forEach(search => { |
| | | let item = { |
| | | key: search.field, |
| | | value: '0' |
| | | } |
| | | |
| | | if (fieldmap.has(item.key)) { |
| | | item.key = item.key + '1' |
| | | } |
| | | |
| | | fieldmap.set(item.key, true) |
| | | |
| | | if (search.type === 'group') { |
| | | options.push({ |
| | | key: search.field, |
| | | value: '0' |
| | | }) |
| | | options.push({ |
| | | key: search.datefield, |
| | | value: '0' |
| | | }) |
| | | options.push({ |
| | | key: search.datefield + '1', |
| | | value: '0' |
| | | }) |
| | | options.push(item) |
| | | } else if (['datemonth', 'dateweek', 'daterange'].includes(search.type)) { |
| | | options.push(item) |
| | | options.push({ |
| | | key: item.key + '1', |
| | | value: '0' |
| | | }) |
| | | } else if (search.type === 'text' || search.type === 'select') { |
| | | item.key.split(',').forEach(field => { |
| | | let cell = JSON.parse(JSON.stringify(item)) |
| | | cell.key = field |
| | | |
| | | options.push(cell) |
| | | }) |
| | | } else { |
| | | options.push(item) |
| | | } |
| | | }) |
| | | |
| | | return options |
| | | } |
| | | |
| | | updatefields = (columns) => { |
| | | this.setState({ |
| | | columns: columns |
| | |
| | | search: null, // 搜索条件,包括主表搜索 |
| | | formlist: null, // 表单信息 |
| | | visible: false, // 模态框控制 |
| | | loading: false // 设置信息验证保存中 |
| | | loading: false, // 设置信息验证保存中 |
| | | record: null |
| | | |
| | | } |
| | | |
| | | /** |
| | |
| | | const { config } = this.props |
| | | const { menu } = this.state |
| | | |
| | | this.settingRef.handleConfirm('func').then(setting => { |
| | | this.settingRef.handleConfirm('loading').then(setting => { |
| | | let res = this.resetSetting(setting) |
| | | let _config = {...config, setting: res} |
| | | let newLText = Utils.formatOptions(FuncUtils.getTableFunc(setting, menu, _config)) // 创建存储过程sql |
| | | let DelText = Utils.formatOptions(FuncUtils.dropfunc(setting.innerFunc)) // 删除存储过程sql |
| | | |
| | | this.refs.funcCreatComponent.exec(setting.innerFunc, newLText, DelText).then(result => { |
| | | if (result === 'success') { |
| | | this.props.updatesetting(_config) |
| | | } |
| | | }) |
| | | this.refs.funcCreatComponent.exec(setting.innerFunc, newLText, DelText) |
| | | }) |
| | | } |
| | | |
| | |
| | | const { config } = this.props |
| | | const { menu } = this.state |
| | | |
| | | this.settingRef.handleConfirm('interface').then(setting => { |
| | | this.settingRef.handleConfirm('loading').then(setting => { |
| | | let res = this.resetSetting(setting) |
| | | let _config = {...config, setting: res} |
| | | let _menu = { |
| | |
| | | |
| | | render() { |
| | | const { config } = this.props |
| | | const { dict, visible, search, menu } = this.state |
| | | const { dict, visible, search, menu, record } = this.state |
| | | |
| | | return ( |
| | | <div className="model-menu-setting"> |
| | |
| | | maskClosable={false} |
| | | onCancel={() => { this.setState({ visible: false, loading: false })}} |
| | | footer={[ |
| | | <CreateInterface key="interface" loading={this.state.interloading} dict={dict} ref="tableCreatInterface" trigger={this.tableCreatInterface}/>, |
| | | <CreateFunc key="create" dict={dict} ref="funcCreatComponent" trigger={this.tableCreatFunc}/>, |
| | | record && record.interType === 'system' ? <CreateInterface key="interface" loading={this.state.interloading} dict={dict} ref="tableCreatInterface" trigger={this.tableCreatInterface}/> : null, |
| | | record && record.interType === 'inner' ? <CreateFunc key="create" dict={dict} ref="funcCreatComponent" trigger={this.tableCreatFunc}/> : null, |
| | | <Button key="cancel" onClick={() => { this.setState({ visible: false, loading: false }) }}>{this.state.dict['model.cancel']}</Button>, |
| | | <Button key="confirm" type="primary" loading={this.state.loading} onClick={this.settingSave}>{this.state.dict['model.confirm']}</Button> |
| | | ]} |
| | |
| | | menu={menu} |
| | | config={config} |
| | | search={search} |
| | | updRecord={(record) => this.setState({record: fromJS(record).toJS()})} |
| | | wrappedComponentRef={(inst) => this.settingRef = inst} |
| | | /> |
| | | </Modal> |
| | |
| | | <Radio value="default">大</Radio> |
| | | <Radio value="middle">中</Radio> |
| | | <Radio value="small">小</Radio> |
| | | {/* <Radio value="mini">微</Radio> */} |
| | | <Radio value="mini">迷你</Radio> |
| | | </Radio.Group>)} |
| | | </Form.Item> |
| | | </Col> |
| | |
| | | dict: PropTypes.object, // 字典项 |
| | | menu: PropTypes.object, // 菜单信息 |
| | | config: PropTypes.object, // 页面配置信息 |
| | | search: PropTypes.array // 搜索条件 |
| | | search: PropTypes.array, // 搜索条件 |
| | | updRecord: PropTypes.func |
| | | } |
| | | |
| | | state = { |
| | |
| | | status.requestMode = status.requestMode || 'system' |
| | | status.procMode = status.procMode || 'script' |
| | | status.callbackType = status.callbackType || 'script' |
| | | let regoptions = Utils.getRegOptions(search) |
| | | let regoptions = this.getRegOptions(search) |
| | | |
| | | if (config.urlFields && config.urlFields.length > 0) { |
| | | config.urlFields.forEach(field => { |
| | |
| | | cbScripts: _cbScripts, |
| | | status |
| | | }) |
| | | } |
| | | |
| | | componentDidMount () { |
| | | this.props.updRecord(this.state.status) |
| | | } |
| | | |
| | | getRegOptions = (searches) => { |
| | | if (!searches || searches.length === 0) return [] |
| | | |
| | | let options = [] |
| | | let fieldmap = new Map() |
| | | searches.forEach(search => { |
| | | let item = { |
| | | key: search.field, |
| | | value: '0' |
| | | } |
| | | |
| | | if (fieldmap.has(item.key)) { |
| | | item.key = item.key + '1' |
| | | } |
| | | |
| | | fieldmap.set(item.key, true) |
| | | |
| | | if (search.type === 'group') { |
| | | options.push({ |
| | | key: search.field, |
| | | value: '0' |
| | | }) |
| | | options.push({ |
| | | key: search.datefield, |
| | | value: '0' |
| | | }) |
| | | options.push({ |
| | | key: search.datefield + '1', |
| | | value: '0' |
| | | }) |
| | | options.push(item) |
| | | } else if (['datemonth', 'dateweek', 'daterange'].includes(search.type)) { |
| | | options.push(item) |
| | | options.push({ |
| | | key: item.key + '1', |
| | | value: '0' |
| | | }) |
| | | } else if (search.type === 'text' || search.type === 'select') { |
| | | item.key.split(',').forEach(field => { |
| | | let cell = JSON.parse(JSON.stringify(item)) |
| | | cell.key = field |
| | | |
| | | options.push(cell) |
| | | }) |
| | | } else { |
| | | options.push(item) |
| | | } |
| | | }) |
| | | |
| | | return options |
| | | } |
| | | |
| | | /** |
| | |
| | | if (activeKey === 'setting') { |
| | | return new Promise((resolve, reject) => { |
| | | this.settingForm.handleConfirm().then(res => { |
| | | if (trigger === 'func' && res.interType !== 'inner') { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '使用内部接口,才可以创建存储过程!', |
| | | duration: 5 |
| | | }) |
| | | this.setState({loading: false}) |
| | | reject() |
| | | return |
| | | } else if (trigger === 'interface' && res.interType !== 'system') { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '使用系统接口时,才可以创建接口!', |
| | | duration: 5 |
| | | }) |
| | | this.setState({loading: false}) |
| | | reject() |
| | | return |
| | | } |
| | | |
| | | this.setState({ |
| | | setting: res |
| | | }, () => { |
| | |
| | | }) |
| | | } else if (activeKey === 'scripts') { |
| | | return new Promise((resolve, reject) => { |
| | | if (trigger === 'func' && setting.interType !== 'inner') { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '使用内部接口,才可以创建存储过程!', |
| | | duration: 5 |
| | | }) |
| | | this.sqlverify(() => { |
| | | this.setState({loading: false}) |
| | | resolve({...setting, scripts, preScripts, cbScripts}) |
| | | }, () => { |
| | | this.setState({loading: false}) |
| | | reject() |
| | | } else { |
| | | this.sqlverify(() => { |
| | | this.setState({loading: false}) |
| | | resolve({...setting, scripts, preScripts, cbScripts}) |
| | | }, () => { |
| | | this.setState({loading: false}) |
| | | reject() |
| | | }, 'submit') |
| | | } |
| | | }, 'submit') |
| | | }) |
| | | } else { |
| | | this.setState({loading: false}) |
| | |
| | | } |
| | | |
| | | updateStatus = (status) => { |
| | | this.setState({status: {...this.state.status, ...status}}) |
| | | let _status = {...this.state.status, ...status} |
| | | this.setState({status: _status}) |
| | | this.props.updRecord(_status) |
| | | } |
| | | |
| | | render() { |
| | |
| | | |
| | | this.setState({ |
| | | openEdition: editSubTab ? (editSubTab.open_edition || '') : (editTab.open_edition || ''), |
| | | chartview: _config.charts[0].uuid, |
| | | chartview: _config.charts ? _config.charts[0].uuid : '', |
| | | originActions: _oriActions, |
| | | config: _config, |
| | | activeKey: _activeKey || '0', |
| | |
| | | let btntabs = [] |
| | | |
| | | _config.action.forEach((item, index) => { |
| | | if (item.hidden === 'true') return |
| | | if (item.OpenType === 'popview') { |
| | | btntabs.push(`select '${item.uuid}' as MenuID ,'${item.linkTab}' as Tabid,'${item.label}' as TabName ,'${(index + 1) * 10}' as Sort`) |
| | | } |
| | |
| | | config: null |
| | | }, () => { |
| | | this.setState({ |
| | | chartview: _config.charts[0].uuid, |
| | | chartview: _config.charts ? _config.charts[0].uuid : '', |
| | | config: _config, |
| | | openEdition: res.open_edition || '', |
| | | activeKey: '0', |
| | |
| | | config={config} |
| | | updatesearch={this.updatesearch} |
| | | /> |
| | | <div className="chart-view" style={{position: 'relative'}}> |
| | | {/* 视图组 权限 会员等级20+ */} |
| | | {this.props.memberLevel >= 20 ? <ChartGroupComponent |
| | | {config.charts ? <div className="chart-view" style={{position: 'relative'}}> |
| | | {/* 视图组 已弃用 */} |
| | | <ChartGroupComponent |
| | | config={config} |
| | | updatechartgroup={this.updatechartgroup} |
| | | /> : null} |
| | | /> |
| | | {config.charts.map(item => { |
| | | if (!config.expand && chartview !== item.uuid) return '' |
| | | |
| | |
| | | ) |
| | | } |
| | | })} |
| | | </div> |
| | | </div> : <> |
| | | <ActionComponent |
| | | type="subtable" |
| | | menu={{MenuID: config.uuid, MenuName: config.tabName, MenuNo: config.tabNo, fstMenuList: this.props.menu.fstMenuList}} |
| | | config={config} |
| | | tabs={this.state.tabviews} |
| | | setSubConfig={this.setSubConfig} |
| | | updateaction={this.updateaction} |
| | | /> |
| | | <ColumnComponent |
| | | config={config} |
| | | menu={this.props.menu} |
| | | updatecolumn={this.updateconfig} |
| | | /> |
| | | </>} |
| | | </Card> |
| | | </div> |
| | | </DndProvider> |
| | |
| | | import Api from '@/api' |
| | | import './index.scss' |
| | | |
| | | class CreateFunc extends Component { |
| | | class CreateInterface extends Component { |
| | | static propTypes = { |
| | | dict: PropTypes.object, // 字典项 |
| | | trigger: PropTypes.func |
| | |
| | | } |
| | | } |
| | | |
| | | export default CreateFunc |
| | | export default CreateInterface |
| | |
| | | }, { |
| | | value: 'closetab', |
| | | text: '标签关闭' |
| | | }, { |
| | | value: 'megvii', |
| | | text: '旷视面板机' |
| | | }] |
| | | }, |
| | | { // 旷视面板机接口 待扩展 |
| | | type: 'radio', |
| | | key: 'subFunc', |
| | | label: '接口名称', |
| | | initVal: card.subFunc || 'addUser', |
| | | required: true, |
| | | options: [ |
| | | { value: 'addUser', text: '添加用户' }, |
| | | ] |
| | | }, |
| | | { |
| | | type: 'select', |
| | |
| | | precision: 0, |
| | | label: '比例', |
| | | initVal: card.ratio || 85, |
| | | tooltip: '小于100为宽度(或高度)百分比,大于100为像素值。', |
| | | tooltip: '模态框或抽屉的宽度,小于100为窗口宽度(或高度)百分比,大于100为像素值。', |
| | | required: true |
| | | }, |
| | | { |
| | |
| | | initVal: card.reason || '', |
| | | required: false |
| | | }, |
| | | { |
| | | type: 'radio', |
| | | key: 'hidden', |
| | | label: '隐藏', |
| | | initVal: card.hidden || 'false', |
| | | tooltip: '隐藏后按钮在页面中不显示,且不参与权限分配。', |
| | | required: false, |
| | | options: [{ |
| | | value: 'false', |
| | | text: '否' |
| | | }, { |
| | | value: 'true', |
| | | text: '是' |
| | | }] |
| | | } |
| | | ] |
| | | } |
| | | |
| | |
| | | { |
| | | type: 'radio', |
| | | key: 'compress', |
| | | label: '压缩', |
| | | label: '文件处理', |
| | | initVal: card.compress || 'false', |
| | | tooltip: '文件压缩必须为图片,图片格式为jpg、png、gif 或 jpeg', |
| | | tooltip: '文件压缩或base64必须为图片,图片格式为jpg、png、gif 或 jpeg。注:base64只可上传一张图片。', |
| | | options: [{ |
| | | value: 'true', |
| | | text: Formdict['model.true'] |
| | | }, { |
| | | value: 'false', |
| | | text: Formdict['model.false'] |
| | | text: '无' |
| | | }, { |
| | | value: 'true', |
| | | text: '压缩' |
| | | }, { |
| | | value: 'base64', |
| | | text: 'base64' |
| | | }] |
| | | }, |
| | | { |
| | |
| | | |
| | | state = { |
| | | enable: this.props.autoMatic.enable, |
| | | onFinish: this.props.autoMatic.onFinish || 'over' |
| | | onFinish: this.props.autoMatic.onFinish || 'restart' |
| | | } |
| | | |
| | | handleConfirm = () => { |
| | |
| | | {enable === 'true' ? <Col span={12}> |
| | | <Form.Item label="完成后"> |
| | | {getFieldDecorator('onFinish', { |
| | | initialValue: autoMatic.onFinish || 'over', |
| | | initialValue: autoMatic.onFinish || 'restart', |
| | | })( |
| | | <Radio.Group onChange={(e) => this.setState({onFinish: e.target.value})}> |
| | | <Radio value="over">结束</Radio> |
| | | <Radio value="restart">重新启动</Radio> |
| | | <Radio value="over">结束</Radio> |
| | | </Radio.Group> |
| | | )} |
| | | </Form.Item> |
| | |
| | | isSubtable: true |
| | | }, |
| | | { |
| | | title: '自定义', |
| | | type: 'CustomPage', |
| | | url: customImg, |
| | | baseconfig: '', |
| | | isSystem: true |
| | | }, |
| | | { |
| | | title: '树形页面', |
| | | type: 'TreePage', |
| | | url: treepage, |
| | |
| | | isSystem: true |
| | | }, |
| | | { |
| | | title: '自定义', |
| | | type: 'CustomPage', |
| | | url: customImg, |
| | | baseconfig: '', |
| | | isSystem: true |
| | | }, |
| | | { |
| | | title: '外部页面', |
| | | type: 'NewPage', |
| | | url: customImg, |
| | |
| | | title: '角色权限分配', |
| | | type: 'RolePermission', |
| | | url: rolemanage, |
| | | isSystem: true, |
| | | hidden: true |
| | | isSystem: true |
| | | } |
| | | ] |
| | | |
| | |
| | | } |
| | | |
| | | /** |
| | | * @description 获取下级模块 |
| | | * @return {String} selfId 当前组件id |
| | | */ |
| | | static getAnchors (components, selfId) { |
| | | let modules = components.map(item => { |
| | | if (item.uuid === selfId) { |
| | | return { |
| | | children: null |
| | | } |
| | | } else if (item.type === 'tabs') { |
| | | let _item = { |
| | | type: 'tabs', |
| | | value: item.uuid, |
| | | label: item.name, |
| | | children: item.subtabs.map(f_tab => { |
| | | let subItem = { |
| | | type: 'tab', |
| | | value: f_tab.uuid, |
| | | label: f_tab.label, |
| | | children: this.getSubModules(f_tab.components, selfId) |
| | | } |
| | | |
| | | if (!subItem.children || subItem.children.length === 0) { |
| | | return {children: null} |
| | | } |
| | | return subItem |
| | | }) |
| | | } |
| | | |
| | | _item.children = _item.children.filter(t => t.children !== null) |
| | | |
| | | if (_item.children.length === 0) { |
| | | return {children: null} |
| | | } |
| | | |
| | | return _item |
| | | } else if (item.type === 'group') { |
| | | let _item = { |
| | | value: item.uuid, |
| | | label: item.name, |
| | | children: item.components.map(f_tab => { |
| | | if (f_tab.uuid === selfId) { |
| | | return { |
| | | children: null |
| | | } |
| | | } else if (f_tab.format) { |
| | | return { |
| | | value: f_tab.uuid, |
| | | label: f_tab.name |
| | | } |
| | | } |
| | | return { |
| | | children: null |
| | | } |
| | | }) |
| | | } |
| | | |
| | | _item.children = _item.children.filter(t => t.children !== null) |
| | | |
| | | if (_item.children.length === 0) { |
| | | return {children: null} |
| | | } |
| | | |
| | | return _item |
| | | } else if (!['login', 'navbar', 'topbar', 'tabs', 'search', 'group', 'balcony'].includes(item.type)) { // 数据格式,存在数据源 |
| | | return { |
| | | value: item.uuid, |
| | | label: item.name |
| | | } |
| | | } else { |
| | | return { |
| | | children: null |
| | | } |
| | | } |
| | | }) |
| | | |
| | | modules = modules.filter(mod => mod.children !== null) |
| | | |
| | | if (modules.length === 0) { |
| | | return null |
| | | } |
| | | return modules |
| | | } |
| | | |
| | | /** |
| | | * @description 获取上级模块 |
| | | * @return {String} selfId 当前组件id |
| | | */ |
| | |
| | | }) |
| | | } |
| | | |
| | | if (config.version < '2.0') { |
| | | config.version = '2.0' |
| | | // 去除传统table中的标签,调整数据结构 |
| | | if (config.charts && config.charts.length === 1) { |
| | | config.charts = null |
| | | } |
| | | } |
| | | |
| | | config.Template = 'CommonTable' |
| | | |
| | | return config |
| | |
| | | return item |
| | | }) |
| | | } |
| | | |
| | | if (config.version < '2.0') { |
| | | config.version = '2.0' |
| | | // 去除传统table中的标签,调整数据结构 |
| | | if (config.charts && config.charts.length === 1) { |
| | | config.charts = null |
| | | } |
| | | } |
| | | |
| | | config.Template = 'SubTable' |
| | | |
| | |
| | | } |
| | | |
| | | /** |
| | | * @description 获取搜索用于正则替换 |
| | | * @param {Array} searches 搜索条件 |
| | | * @return {String} searchText 拼接结果 |
| | | */ |
| | | static getRegOptions (searches) { |
| | | if (!searches || searches.length === 0) return [] |
| | | |
| | | let options = [] |
| | | let fieldmap = new Map() |
| | | searches.forEach(search => { |
| | | let item = { |
| | | key: search.field, |
| | | value: '0' |
| | | } |
| | | |
| | | if (fieldmap.has(item.key)) { |
| | | item.key = item.key + '1' |
| | | } |
| | | |
| | | fieldmap.set(item.key, true) |
| | | |
| | | if (search.type === 'group') { |
| | | options.push({ |
| | | key: search.field, |
| | | value: '0' |
| | | }) |
| | | options.push({ |
| | | key: search.datefield, |
| | | value: '0' |
| | | }) |
| | | options.push({ |
| | | key: search.datefield + '1', |
| | | value: '0' |
| | | }) |
| | | options.push(item) |
| | | } else if (['datemonth', 'dateweek', 'daterange'].includes(search.type)) { |
| | | options.push(item) |
| | | options.push({ |
| | | key: item.key + '1', |
| | | value: '0' |
| | | }) |
| | | } else if (search.type === 'text' || search.type === 'select') { |
| | | item.key.split(',').forEach(field => { |
| | | let cell = JSON.parse(JSON.stringify(item)) |
| | | cell.key = field |
| | | |
| | | options.push(cell) |
| | | }) |
| | | } else { |
| | | options.push(item) |
| | | } |
| | | }) |
| | | |
| | | return options |
| | | } |
| | | |
| | | /** |
| | | * @description 获取图片真实路径 |
| | | * @return {String} url 图片路径 |
| | | */ |
| | |
| | | Declare @tbid nvarchar(50),@ErrorCode nvarchar(50),@retmsg nvarchar(4000),@BillCode nvarchar(50),@BVoucher nvarchar(50),@FIBVoucherDate nvarchar(50), @FiYear nvarchar(50), @UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(50),@mk_organization nvarchar(50),@login_city nvarchar(50),@bid nvarchar(50),@ModularDetailCode nvarchar(50)${_declarefields} |
| | | ` |
| | | |
| | | let userName = sessionStorage.getItem('User_Name') || '' |
| | | let fullName = sessionStorage.getItem('Full_Name') || '' |
| | | let RoleID = sessionStorage.getItem('role_id') || '' |
| | | let departmentcode = sessionStorage.getItem('departmentcode') || '' |
| | | let organization = sessionStorage.getItem('organization') || '' |
| | | let city = sessionStorage.getItem('city') || '' |
| | | |
| | | if (sessionStorage.getItem('isEditState') === 'true') { |
| | | userName = sessionStorage.getItem('CloudUserName') || '' |
| | | fullName = sessionStorage.getItem('CloudFullName') || '' |
| | | } |
| | | |
| | | // 初始化凭证及用户信息字段 |
| | | _sql += ` |
| | | /* 凭证及用户信息初始化赋值 */ |
| | | select @BVoucher='',@FIBVoucherDate='',@FiYear='',@ErrorCode='',@retmsg='',@UserName='${userName}', @FullName='${fullName}', @RoleID='${RoleID}', @mk_departmentcode='${departmentcode}', @mk_organization='${organization}', @login_city='${city}', @BillCode='', @ModularDetailCode='' |
| | | ` |
| | | |
| | | // 表单变量赋值 |
| | | if (_initFormfields.length > 0) { |
| | | _sql += ` |
| | |
| | | if (verify.billcodes) { |
| | | verify.billcodes = verify.billcodes.filter(item => item.status !== 'false') |
| | | } |
| | | |
| | | let userName = sessionStorage.getItem('User_Name') || '' |
| | | let fullName = sessionStorage.getItem('Full_Name') || '' |
| | | let RoleID = sessionStorage.getItem('role_id') || '' |
| | | let departmentcode = sessionStorage.getItem('departmentcode') || '' |
| | | let organization = sessionStorage.getItem('organization') || '' |
| | | let city = sessionStorage.getItem('city') || '' |
| | | |
| | | if (sessionStorage.getItem('isEditState') === 'true') { |
| | | userName = sessionStorage.getItem('CloudUserName') || '' |
| | | fullName = sessionStorage.getItem('CloudFullName') || '' |
| | | } |
| | | |
| | | // 初始化凭证及用户信息字段 |
| | | _sql += ` |
| | | /* 凭证及用户信息初始化赋值 */ |
| | | select @BVoucher='',@FIBVoucherDate='',@FiYear='',@ErrorCode='',@retmsg='',@UserName='${userName}', @FullName='${fullName}', @RoleID='${RoleID}', @mk_departmentcode='${departmentcode}', @mk_organization='${organization}', @login_city='${city}', @BillCode='', @ModularDetailCode='' |
| | | ` |
| | | |
| | | if (retmsg) { |
| | | _callbacksql = _sql |
| | |
| | | background: transparent!important; |
| | | border-radius: 0!important; |
| | | } |
| | | .ant-table.ant-table-mini .ant-table-thead > tr > th { |
| | | padding: 8px 8px!important; |
| | | } |
| | | .ant-table.ant-table-mini .ant-table-tbody > tr > td { |
| | | padding: 2px 8px!important; |
| | | line-height: 1.5; |
| | | } |
| | | } |
| | | .print-page.auto:last-child { |
| | | height: auto!important; |
| | |
| | | {editLevel === 'HS' ? <Button className="level4-close" type="primary" onClick={this.exitManage}>退出</Button> : null} |
| | | {/* 进入编辑按钮 */} |
| | | {!editLevel && menulist ? <EditOutlined onClick={this.enterEdit} className="edit-check" /> : null} |
| | | {!editLevel && options.sysType === 'local' && window.GLOB.systemType !== 'production' && this.props.memberLevel >= 20 ? |
| | | {!editLevel && window.GLOB.systemType !== 'production' ? |
| | | <div className="app-entrance entrance"> |
| | | <div className="icon"><AppstoreOutlined /></div> |
| | | <div className="title">应用管理</div> |
| | | <div className="detail">可创建及管理PC、pad及移动端等不同设备的应用,实现明科云APP、微信公众号、小程序等多平台的应用共享。</div> |
| | | <Button type="primary" onClick={() => {window.open('#/appmanage')}}> |
| | | <Button type="primary" disabled={!(this.props.memberLevel >= 20)} title={this.props.memberLevel >= 20 ? '' : '会员等级不够,无开发权限。'} onClick={() => {window.open('#/appmanage')}}> |
| | | 编辑 |
| | | </Button> |
| | | </div> : null |
| | | } |
| | | {editLevel === 'HS' && options.sysType === 'local' && window.GLOB.systemType === 'production' && this.props.memberLevel >= 20 ? |
| | | {editLevel === 'HS' && window.GLOB.systemType === 'production' ? |
| | | <div className="app-prod-entrance entrance"> |
| | | <div className="icon"><AppstoreOutlined /></div> |
| | | <div className="title">应用管理</div> |
| | | <div className="detail">可创建及管理PC、pad及移动端等不同设备的应用,实现明科云APP、微信公众号、小程序等多平台的应用共享。</div> |
| | | <Button type="primary" onClick={() => {window.open('#/appcheck')}}> |
| | | <Button type="primary" disabled={!(this.props.memberLevel >= 20)} title={this.props.memberLevel >= 20 ? '' : '会员等级不够,无开发权限。'} onClick={() => {window.open('#/appcheck')}}> |
| | | 查看 |
| | | </Button> |
| | | </div> : null |
| | | } |
| | | {!editLevel && options.sysType === 'local' && this.props.memberLevel >= 20 ? |
| | | {!editLevel ? |
| | | <div className="api-entrance entrance"> |
| | | <div className="icon"><ApiOutlined /></div> |
| | | <div className="title">接口调试</div> |
| | | <div className="detail">可自动处理登录接口的参数加密,以及业务接口的签名计算,方便开发人员的接口测试工作。</div> |
| | | <Button type="primary" onClick={() => {window.open('#/interface')}}> |
| | | <Button type="primary" disabled={!(this.props.memberLevel >= 20)} title={this.props.memberLevel >= 20 ? '' : '会员等级不够,无开发权限。'} onClick={() => {window.open('#/interface')}}> |
| | | 编辑 |
| | | </Button> |
| | | </div> : null |
| | | } |
| | | {/* window.btoa(window.encodeURIComponent(JSON.stringify({ MenuType: 'home', MenuId: 'home_page_id', MenuName: '首页' }))) */} |
| | | {!editLevel && window.GLOB.systemType !== 'production' && this.props.memberLevel >= 20 ? |
| | | {!editLevel && window.GLOB.systemType !== 'production' ? |
| | | <div className="home-entrance entrance"> |
| | | <div className="icon"><HomeOutlined /></div> |
| | | <div className="title">首页</div> |
| | | <div className="detail">基于自定义页面的首页设计,可实现灵活的元素配置及样式调整,展现当前系统的风格。</div> |
| | | <Button type="primary" onClick={() => {window.open('#/menudesign/JTdCJTIyTWVudVR5cGUlMjIlM0ElMjJob21lJTIyJTJDJTIyTWVudUlkJTIyJTNBJTIyaG9tZV9wYWdlX2lkJTIyJTJDJTIyTWVudU5hbWUlMjIlM0ElMjIlRTklQTYlOTYlRTklQTElQjUlMjIlN0Q=')}}> |
| | | <Button type="primary" disabled={!(this.props.memberLevel >= 20)} title={this.props.memberLevel >= 20 ? '' : '会员等级不够,无开发权限。'} onClick={() => {window.open('#/menudesign/JTdCJTIyTWVudVR5cGUlMjIlM0ElMjJob21lJTIyJTJDJTIyTWVudUlkJTIyJTNBJTIyaG9tZV9wYWdlX2lkJTIyJTJDJTIyTWVudU5hbWUlMjIlM0ElMjIlRTklQTYlOTYlRTklQTElQjUlMjIlN0Q=')}}> |
| | | 编辑 |
| | | </Button> |
| | | </div> : null |
| | |
| | | style: res.CSS || '', |
| | | showline: res.split_line_show || 'true', |
| | | webSite: res.WebSite || '', |
| | | navBar: res.menu_type, |
| | | navBar: res.menu_type, // shutter 百叶窗、linkage_navigation 联动菜单、linkage 联动菜单_无导航栏、menu_board 菜单面板、menu_board_navigation 菜单面板_标签页 |
| | | app_version: res.app_version |
| | | } |
| | | |
| | |
| | | import moment from 'moment' |
| | | import HTML5Backend from 'react-dnd-html5-backend' |
| | | import { ConfigProvider, notification, Modal, Collapse, Card, Switch, Button, Typography } from 'antd' |
| | | import { DoubleLeftOutlined, DoubleRightOutlined, EyeOutlined, EyeInvisibleOutlined } from '@ant-design/icons' |
| | | import html2canvas from 'html2canvas' |
| | | |
| | | import Api from '@/api' |
| | |
| | | popBtn: null, // 弹窗标签页 |
| | | visible: false, |
| | | customComponents: [], |
| | | comloading: false |
| | | comloading: false, |
| | | settingshow: true, |
| | | eyeopen: false |
| | | } |
| | | |
| | | UNSAFE_componentWillMount() { |
| | |
| | | }) |
| | | } |
| | | |
| | | getMenuMessage = () => { |
| | | getMenuMessage = (delButtons) => { |
| | | const { config } = this.state |
| | | let buttons = [] |
| | | let _sort = 1 |
| | |
| | | traversal(item.components) |
| | | } else if (item.type === 'card' || (item.type === 'table' && item.subtype === 'tablecard')) { |
| | | item.action && item.action.forEach(btn => { |
| | | if (btn.hidden === 'true') { |
| | | delButtons.push(btn.uuid) |
| | | return |
| | | } |
| | | this.checkBtn(btn) |
| | | buttons.push(`select '${btn.uuid}' as menuid, '${item.name + '-' + btn.label}' as menuname, '${_sort * 10}' as Sort`) |
| | | _sort++ |
| | |
| | | item.subcards.forEach(card => { |
| | | card.elements && card.elements.forEach(cell => { |
| | | if (cell.eleType !== 'button') return |
| | | if (cell.hidden === 'true') { |
| | | delButtons.push(cell.uuid) |
| | | return |
| | | } |
| | | this.checkBtn(cell) |
| | | buttons.push(`select '${cell.uuid}' as menuid, '${item.name + '-' + cell.label}' as menuname, '${_sort * 10}' as Sort`) |
| | | _sort++ |
| | | }) |
| | | card.backElements && card.backElements.forEach(cell => { |
| | | if (cell.eleType !== 'button') return |
| | | if (cell.hidden === 'true') { |
| | | delButtons.push(cell.uuid) |
| | | return |
| | | } |
| | | this.checkBtn(cell) |
| | | buttons.push(`select '${cell.uuid}' as menuid, '${item.name + '-' + cell.label}' as menuname, '${_sort * 10}' as Sort`) |
| | | _sort++ |
| | |
| | | item.subcards.forEach(card => { |
| | | card.elements && card.elements.forEach(cell => { |
| | | if (cell.eleType !== 'button') return |
| | | if (cell.hidden === 'true') { |
| | | delButtons.push(cell.uuid) |
| | | return |
| | | } |
| | | this.checkBtn(cell) |
| | | buttons.push(`select '${cell.uuid}' as menuid, '${item.name + '-' + cell.label}' as menuname, '${_sort * 10}' as Sort`) |
| | | _sort++ |
| | |
| | | } else if (item.type === 'balcony') { |
| | | item.elements && item.elements.forEach(cell => { |
| | | if (cell.eleType !== 'button') return |
| | | if (cell.hidden === 'true') { |
| | | delButtons.push(cell.uuid) |
| | | return |
| | | } |
| | | this.checkBtn(cell) |
| | | buttons.push(`select '${cell.uuid}' as menuid, '${item.name + '-' + cell.label}' as menuname, '${_sort * 10}' as Sort`) |
| | | _sort++ |
| | | }) |
| | | } else if (item.type === 'line' || item.type === 'bar' || item.type === 'chart') { |
| | | item.action && item.action.forEach(btn => { |
| | | if (btn.hidden === 'true') { |
| | | delButtons.push(btn.uuid) |
| | | return |
| | | } |
| | | this.checkBtn(btn) |
| | | buttons.push(`select '${btn.uuid}' as menuid, '${item.name + '-' + btn.label}' as menuname, '${_sort * 10}' as Sort`) |
| | | _sort++ |
| | | }) |
| | | } else if (item.type === 'table' && (item.subtype === 'normaltable' || item.subtype === 'editable')) { |
| | | item.action && item.action.forEach(btn => { |
| | | if (btn.hidden === 'true') { |
| | | delButtons.push(btn.uuid) |
| | | return |
| | | } |
| | | this.checkBtn(btn) |
| | | buttons.push(`select '${btn.uuid}' as menuid, '${item.name + '-' + btn.label}' as menuname, '${_sort * 10}' as Sort`) |
| | | _sort++ |
| | |
| | | item.cols && item.cols.forEach(col => { |
| | | if (col.type !== 'action') return |
| | | col.elements.forEach(btn => { |
| | | if (btn.hidden === 'true') { |
| | | delButtons.push(btn.uuid) |
| | | return |
| | | } |
| | | this.checkBtn(btn) |
| | | buttons.push(`select '${btn.uuid}' as menuid, '${item.name + '-' + btn.label}' as menuname, '${_sort * 10}' as Sort`) |
| | | _sort++ |
| | |
| | | } |
| | | |
| | | submitConfig = () => { |
| | | const { MenuType, delButtons, copyButtons, thawButtons } = this.state |
| | | const { MenuType, copyButtons, thawButtons } = this.state |
| | | let config = fromJS(this.state.config).toJS() |
| | | |
| | | if (MenuType === 'billPrint' && (!config.firstCount || !config.everyPCount)) { |
| | |
| | | LText: [] |
| | | } |
| | | |
| | | let delButtons = fromJS(this.state.delButtons).toJS() |
| | | let btnIds = '' // 用于复制按钮的过滤 |
| | | if (MenuType !== 'billPrint') { |
| | | btnParam.LText = this.getMenuMessage() |
| | | btnParam.LText = this.getMenuMessage(delButtons) |
| | | btnParam.LText = btnParam.LText.join(' union all ') |
| | | |
| | | btnIds = btnParam.LText |
| | |
| | | }) |
| | | } |
| | | |
| | | changeSetting = () => { |
| | | this.setState({settingshow: !this.state.settingshow}) |
| | | |
| | | setTimeout(() => { |
| | | MKEmitter.emit('tabsChange', 'all') |
| | | }, 400) |
| | | } |
| | | |
| | | render () { |
| | | const { activeKey, comloading, MenuType, popBtn, visible, dict, MenuId, config, ParentId, MenuName, MenuNo, menuloading, customComponents } = this.state |
| | | const { activeKey, comloading, MenuType, popBtn, visible, dict, MenuId, config, settingshow, ParentId, MenuName, MenuNo, menuloading, customComponents, eyeopen } = this.state |
| | | |
| | | return ( |
| | | <ConfigProvider locale={_locale}> |
| | |
| | | <Header /> |
| | | {!popBtn && !visible ? <DndProvider backend={HTML5Backend}> |
| | | <div className="menu-body"> |
| | | <div className="menu-setting"> |
| | | <div className={'menu-setting ' + (!settingshow ? 'hidden' : '')}> |
| | | <div className="draw"> |
| | | {settingshow ? <DoubleLeftOutlined onClick={this.changeSetting}/> : <DoubleRightOutlined onClick={this.changeSetting}/>} |
| | | </div> |
| | | <Collapse accordion activeKey={activeKey} bordered={false} onChange={(key) => this.setState({activeKey: key})}> |
| | | {/* 基本信息 */} |
| | | <Panel header={dict['mob.basemsg']} key="basedata"> |
| | |
| | | </Panel> |
| | | </Collapse> |
| | | </div> |
| | | <div className={'menu-view ' + (menuloading ? 'saving' : '')}> |
| | | <div className={'menu-view' + (menuloading ? ' saving' : '') + (eyeopen ? ' eye-open' : '')}> |
| | | <Card title={ |
| | | <div> {config && config.MenuName} </div> |
| | | <div style={{paddingLeft: '15px'}}> {config && config.MenuName} </div> |
| | | } bordered={false} extra={ |
| | | <div> |
| | | <Button className="mk-border-purple" onClick={() => this.setState({eyeopen: !eyeopen})}>{!eyeopen ? <EyeOutlined /> : <EyeInvisibleOutlined />} 组件名</Button> |
| | | <Versions MenuId={MenuId} open_edition={config ? config.open_edition : ''}/> |
| | | <ReplaceField type="custom" config={config} updateConfig={this.resetConfig}/> |
| | | <SysInterface config={config} updateConfig={this.updateConfig}/> |
| | |
| | | .pc-menu-view { |
| | | background: #000; |
| | | min-height: 100vh; |
| | | .mk-hidden { |
| | | text-decoration: line-through!important; |
| | | span { |
| | | text-decoration: line-through!important; |
| | | } |
| | | } |
| | | .eye-open { |
| | | .component-name { |
| | | display: block; |
| | | } |
| | | .anticon-tool { |
| | | display: none; |
| | | } |
| | | } |
| | | .component-name { |
| | | position: absolute; |
| | | z-index: 9; |
| | | display: none; |
| | | left: 0; |
| | | right: 0; |
| | | top: 0; |
| | | bottom: 0; |
| | | background: rgba(255, 255, 255, 0.8); |
| | | border: 1px solid #1890ff; |
| | | .center { |
| | | position: absolute; |
| | | font-size: 16px; |
| | | left: 50%; |
| | | top: 50%; |
| | | color: #1890ff; |
| | | transform: translate(-50%, -50%); |
| | | } |
| | | } |
| | | >.menu-body { |
| | | width: 100vw; |
| | | height: 100vh; |
| | |
| | | width: 300px; |
| | | background: #ffffff; |
| | | box-shadow: 0px 2px 5px #bcbcbc; |
| | | overflow-y: auto; |
| | | overflow-x: hidden; |
| | | transition: left 0.3s; |
| | | |
| | | .draw { |
| | | position: absolute; |
| | | z-index: 11; |
| | | background: #ffffff; |
| | | right: -20px; |
| | | top: 0px; |
| | | box-shadow: 0 0 1px #959595; |
| | | border-radius: 0 2px 2px 0px; |
| | | |
| | | .anticon { |
| | | padding: 12px 3px; |
| | | } |
| | | } |
| | | > .ant-collapse { |
| | | height: 100%; |
| | | overflow-y: auto; |
| | | overflow-x: hidden; |
| | | background-color: #ffffff; |
| | | border-radius: 0px; |
| | | padding-bottom: 30px; |
| | | .ant-collapse-item.ant-collapse-item-active { |
| | | border-bottom: 1px solid #d9d9d9; |
| | | } |
| | |
| | | } |
| | | } |
| | | } |
| | | .menu-setting::-webkit-scrollbar { |
| | | .menu-setting >.ant-collapse::-webkit-scrollbar { |
| | | width: 4px; |
| | | } |
| | | .menu-setting::-webkit-scrollbar-thumb { |
| | | .menu-setting >.ant-collapse::-webkit-scrollbar-thumb { |
| | | border-radius: 5px; |
| | | box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.08); |
| | | background: rgba(0, 0, 0, 0.08); |
| | | } |
| | | .menu-setting::-webkit-scrollbar-track { |
| | | .menu-setting >.ant-collapse::-webkit-scrollbar-track { |
| | | box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.05); |
| | | border-radius: 3px; |
| | | border: 1px solid rgba(0, 0, 0, 0.07); |
| | | background: rgba(0, 0, 0, 0); |
| | | } |
| | | |
| | | .menu-setting.hidden { |
| | | left: -300px; |
| | | } |
| | | .menu-setting.hidden + .menu-view { |
| | | width: 100vw; |
| | | margin-left: 0px; |
| | | } |
| | | |
| | | .menu-view { |
| | |
| | | margin-left: 300px; |
| | | height: calc(100vh - 50px); |
| | | overflow-y: auto; |
| | | transition: all 0.3s; |
| | | |
| | | > .ant-card { |
| | | >.ant-card-head { |
| | |
| | | import moment from 'moment' |
| | | import HTML5Backend from 'react-dnd-html5-backend' |
| | | import { ConfigProvider, notification, Modal, Collapse, Switch, Button, message, Spin, Typography } from 'antd' |
| | | import { DoubleLeftOutlined, DoubleRightOutlined, HomeOutlined, LoginOutlined, RedoOutlined, ArrowLeftOutlined } from '@ant-design/icons' |
| | | import { DoubleLeftOutlined, DoubleRightOutlined, HomeOutlined, LoginOutlined, RedoOutlined, ArrowLeftOutlined, EyeOutlined, EyeInvisibleOutlined } from '@ant-design/icons' |
| | | |
| | | import Api from '@/api' |
| | | import Utils, { setGLOBFuncs } from '@/utils/utils.js' |
| | |
| | | const CreateView = asyncComponent(() => import('@/pc/createview')) |
| | | const Transfer = asyncComponent(() => import('@/pc/transfer')) |
| | | const Versions = asyncComponent(() => import('@/menu/versions')) |
| | | const ViewNodes = asyncComponent(() => import('@/menu/viewnodes')) |
| | | const SourceWrap = asyncComponent(() => import('@/mob/modulesource')) |
| | | const BgController = asyncComponent(() => import('@/pc/bgcontroller')) |
| | | const ReplaceField = asyncComponent(() => import('@/menu/replaceField')) |
| | |
| | | controlshow: true, |
| | | comloading: false, |
| | | adapters: [], |
| | | viewType: 'menu' |
| | | viewType: 'menu', |
| | | eyeopen: false |
| | | } |
| | | |
| | | UNSAFE_componentWillMount() { |
| | |
| | | viewType: /^userbind/.test(param.MenuID) ? 'userbind' : 'menu' |
| | | }, () => { |
| | | this.getMenuParam(param) |
| | | this.getRelationMenus() |
| | | }) |
| | | } |
| | | } catch (e) { |
| | |
| | | this.getAppMenus() |
| | | } |
| | | |
| | | getRelationMenus = () => { |
| | | const { MenuId } = this.state |
| | | |
| | | let param = { |
| | | func: 's_get_menu_used_list', |
| | | TypeCharOne: sessionStorage.getItem('kei_no'), |
| | | typename: sessionStorage.getItem('typename'), |
| | | par_menuid: MenuId, |
| | | // used_menuid: MenuId |
| | | } |
| | | |
| | | Api.getSystemConfig(param).then(result => { |
| | | if (!result.status) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: result.message, |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } |
| | | }) |
| | | } |
| | | |
| | | setUserBindMenu = (config, result) => { |
| | | const { MenuId } = this.state |
| | | let isCreate = !config |
| | |
| | | return item |
| | | }) |
| | | sessionStorage.setItem('appMenus', JSON.stringify(menus)) |
| | | sessionStorage.setItem('allMenus', JSON.stringify(res.menus || [])) |
| | | }) |
| | | } |
| | | |
| | |
| | | return null |
| | | } else if (item.type === 'card' || (item.type === 'table' && item.subtype === 'tablecard')) { |
| | | item.action && item.action.forEach(btn => { |
| | | if (btn.hidden === 'true') return |
| | | |
| | | this.checkBtn(btn) |
| | | m.children.push({ |
| | | key: btn.uuid, |
| | |
| | | item.subcards.forEach(card => { |
| | | card.elements && card.elements.forEach(cell => { |
| | | if (cell.eleType !== 'button') return |
| | | if (cell.hidden === 'true') return |
| | | |
| | | this.checkBtn(cell) |
| | | m.children.push({ |
| | | key: cell.uuid, |
| | |
| | | item.subcards.forEach(card => { |
| | | card.elements && card.elements.forEach(cell => { |
| | | if (cell.eleType !== 'button') return |
| | | if (cell.hidden === 'true') return |
| | | |
| | | this.checkBtn(cell) |
| | | m.children.push({ |
| | | key: cell.uuid, |
| | |
| | | } else if (item.type === 'balcony') { |
| | | item.elements && item.elements.forEach(cell => { |
| | | if (cell.eleType !== 'button') return |
| | | if (cell.hidden === 'true') return |
| | | |
| | | this.checkBtn(cell) |
| | | m.children.push({ |
| | | key: cell.uuid, |
| | |
| | | }) |
| | | } else if (item.type === 'table' && item.subtype === 'normaltable') { |
| | | item.action && item.action.forEach(btn => { |
| | | if (btn.hidden === 'true') return |
| | | |
| | | this.checkBtn(btn) |
| | | m.children.push({ |
| | | key: btn.uuid, |
| | |
| | | item.cols && item.cols.forEach(col => { |
| | | if (col.type !== 'action') return |
| | | col.elements.forEach(btn => { |
| | | if (btn.hidden === 'true') return |
| | | |
| | | this.checkBtn(btn) |
| | | m.children.push({ |
| | | key: btn.uuid, |
| | |
| | | let trees = traversal(config.components) |
| | | |
| | | return trees |
| | | } |
| | | |
| | | getSubMenus = () => { |
| | | const { config } = this.state |
| | | let menus = [] |
| | | let menuObj = {} |
| | | let allMenus = JSON.parse(sessionStorage.getItem('allMenus')) |
| | | |
| | | allMenus.forEach(item => { |
| | | menuObj[item.MenuID] = item |
| | | }) |
| | | |
| | | let traversal = (components) => { |
| | | components.forEach(item => { |
| | | if (item.type === 'topbar') { |
| | | if (item.wrap.linkmenu && menuObj[item.wrap.linkmenu]) { |
| | | menus.push(menuObj[item.wrap.linkmenu]) |
| | | } |
| | | if (item.wrap.menus) { |
| | | item.wrap.menus.forEach(m => { |
| | | if (!menuObj[m.menu]) return |
| | | |
| | | menus.push(menuObj[m.menu]) |
| | | }) |
| | | } |
| | | } else if (item.type === 'login') { |
| | | if (item.wrap.linkmenu && menuObj[item.wrap.linkmenu]) { |
| | | menus.push(menuObj[item.wrap.linkmenu]) |
| | | } |
| | | } else if (item.type === 'menubar' && item.subtype !== 'commonbar') { |
| | | item.subMenus.forEach(m => { |
| | | if (m.setting.type === 'menu') { |
| | | if (menuObj[m.uuid]) { |
| | | menus.push(menuObj[m.uuid]) |
| | | } else { |
| | | menus.push({ |
| | | MenuID: m.uuid, |
| | | MenuName: m.setting.name, |
| | | MenuNo: m.setting.MenuNo |
| | | }) |
| | | } |
| | | } else if (m.setting.type === 'linkmenu' && menuObj[m.setting.linkMenuId]) { |
| | | menus.push(menuObj[m.setting.linkMenuId]) |
| | | } |
| | | }) |
| | | } else if (item.type === 'tabs') { |
| | | item.subtabs.forEach(tab => { |
| | | traversal(tab.components) |
| | | }) |
| | | } else if (item.type === 'group') { |
| | | traversal(item.components) |
| | | } else if (item.type === 'card' || (item.type === 'table' && item.subtype === 'tablecard')) { |
| | | item.action && item.action.forEach(btn => { |
| | | if (btn.linkmenu && menuObj[btn.linkmenu]) { |
| | | menus.push(menuObj[btn.linkmenu]) |
| | | } else if (btn.openmenu && menuObj[btn.openmenu]) { |
| | | menus.push(menuObj[btn.openmenu]) |
| | | } |
| | | }) |
| | | item.subcards.forEach(card => { |
| | | if (card.setting.click === 'menu' && menuObj[card.setting.menu]) { |
| | | menus.push(menuObj[card.setting.menu]) |
| | | } else if (card.setting.click === 'menus' && card.menus) { |
| | | card.menus.forEach(m => { |
| | | if (menuObj[m.menu]) { |
| | | menus.push(menuObj[m.menu]) |
| | | } |
| | | }) |
| | | } |
| | | card.elements && card.elements.forEach(cell => { |
| | | if (cell.eleType !== 'button') return |
| | | |
| | | if (cell.linkmenu && menuObj[cell.linkmenu]) { |
| | | menus.push(menuObj[cell.linkmenu]) |
| | | } else if (cell.openmenu && menuObj[cell.openmenu]) { |
| | | menus.push(menuObj[cell.openmenu]) |
| | | } |
| | | }) |
| | | }) |
| | | } else if (item.type === 'carousel' || item.type === 'timeline') { |
| | | item.subcards.forEach(card => { |
| | | if (card.setting.click === 'menu' && menuObj[card.setting.menu]) { |
| | | menus.push(menuObj[card.setting.menu]) |
| | | } |
| | | card.elements && card.elements.forEach(cell => { |
| | | if (cell.eleType !== 'button') return |
| | | |
| | | if (cell.linkmenu && menuObj[cell.linkmenu]) { |
| | | menus.push(menuObj[cell.linkmenu]) |
| | | } else if (cell.openmenu && menuObj[cell.openmenu]) { |
| | | menus.push(menuObj[cell.openmenu]) |
| | | } |
| | | }) |
| | | }) |
| | | } else if (item.type === 'balcony') { |
| | | item.elements && item.elements.forEach(cell => { |
| | | if (cell.eleType !== 'button') return |
| | | |
| | | if (cell.linkmenu && menuObj[cell.linkmenu]) { |
| | | menus.push(menuObj[cell.linkmenu]) |
| | | } else if (cell.openmenu && menuObj[cell.openmenu]) { |
| | | menus.push(menuObj[cell.openmenu]) |
| | | } |
| | | }) |
| | | } else if (item.type === 'form') { |
| | | item.subcards.forEach(m => { |
| | | if (m.subButton && m.subButton.linkmenu && menuObj[m.subButton.linkmenu]) { |
| | | menus.push(menuObj[m.subButton.linkmenu]) |
| | | } |
| | | }) |
| | | } else if (item.type === 'table' && item.subtype === 'normaltable') { |
| | | item.action && item.action.forEach(btn => { |
| | | if (btn.linkmenu && menuObj[btn.linkmenu]) { |
| | | menus.push(menuObj[btn.linkmenu]) |
| | | } else if (btn.openmenu && menuObj[btn.openmenu]) { |
| | | menus.push(menuObj[btn.openmenu]) |
| | | } |
| | | }) |
| | | item.cols && item.cols.forEach(col => { |
| | | if (col.type !== 'action') return |
| | | col.elements.forEach(btn => { |
| | | if (btn.linkmenu && menuObj[btn.linkmenu]) { |
| | | menus.push(menuObj[btn.linkmenu]) |
| | | } else if (btn.openmenu && menuObj[btn.openmenu]) { |
| | | menus.push(menuObj[btn.openmenu]) |
| | | } |
| | | }) |
| | | }) |
| | | } |
| | | }) |
| | | } |
| | | |
| | | traversal(config.components) |
| | | |
| | | let map = new Map() |
| | | menus = menus.filter(m => { |
| | | if (map.has(m.MenuID)) return false |
| | | map.set(m.MenuID, true) |
| | | return true |
| | | }) |
| | | |
| | | return menus |
| | | } |
| | | |
| | | checkBtn = (btn) => { |
| | |
| | | config = this.getMiniStyle(config) |
| | | } |
| | | |
| | | let subMenus = this.getSubMenus() |
| | | let menus_used_list = subMenus.map(m => `'${config.uuid}','${config.MenuName || ''}','${config.MenuNo || ''}','${m.MenuID}','${m.MenuName}'`).join(';') |
| | | menus_used_list = window.btoa(window.encodeURIComponent(menus_used_list || 'del')) |
| | | |
| | | let param = { |
| | | func: 'sPC_TrdMenu_AddUpt', |
| | | FstID: 'mk_app', |
| | |
| | | open_edition: config.open_edition, |
| | | menus_rolelist: window.btoa(window.encodeURIComponent(JSON.stringify(roleParam))), |
| | | LText: '', |
| | | LTexttb: '' |
| | | LTexttb: '', |
| | | menus_used_list |
| | | } |
| | | |
| | | param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') |
| | |
| | | |
| | | |
| | | render () { |
| | | const { viewType, localedict, comloading, loading, settingshow, controlshow, activeKey, dict, MenuId, config, menuloading, customComponents, adapters } = this.state |
| | | const { viewType, localedict, comloading, loading, settingshow, controlshow, activeKey, dict, MenuId, config, menuloading, customComponents, adapters, eyeopen } = this.state |
| | | |
| | | return ( |
| | | <ConfigProvider locale={localedict}> |
| | |
| | | </Collapse> |
| | | </div> |
| | | </div> |
| | | <div className={'menu-control ' + (!controlshow ? 'hidden' : '')}> |
| | | <div className={'menu-control' + (!controlshow ? ' hidden' : '')}> |
| | | <div className="draw"> |
| | | {controlshow ? <DoubleRightOutlined onClick={() => {this.setState({controlshow: false})}}/> : null} |
| | | {!controlshow ? <DoubleLeftOutlined onClick={() => {this.setState({controlshow: true})}}/> : null} |
| | |
| | | <Button type="primary" onClick={this.submitConfig} id="save-config" loading={menuloading}>{dict['mob.save']}</Button> |
| | | <Switch className="big" checkedChildren={dict['mob.enable']} unCheckedChildren={dict['mob.disable']} checked={config && config.enabled} onChange={this.onEnabledChange} /> |
| | | <ArrowLeftOutlined title="后退" className="back-view" onClick={this.backView}/> |
| | | <Button className="mk-border-purple" onClick={() => this.setState({eyeopen: !eyeopen})}>{!eyeopen ? <EyeOutlined /> : <EyeInvisibleOutlined />} 组件名</Button> |
| | | <CreateView resetmenu={this.getAppMenus} /> |
| | | <PasteController insert={this.insert} /> |
| | | <StyleCombControlButton menu={config} /> |
| | | <ViewNodes config={config} MenuId={MenuId}/> |
| | | <SysInterface config={config} updateConfig={this.updateConfig}/> |
| | | <PictureController/> |
| | | <Quotecomponent config={config} updateConfig={this.updateConfig}/> |
| | |
| | | <ReplaceField type="custom" config={config} updateConfig={this.resetConfig}/> |
| | | <Transfer MenuID={MenuId} /> |
| | | <Versions MenuId={MenuId} open_edition={config ? config.open_edition : ''}/> |
| | | <StyleCombControlButton menu={config} /> |
| | | <Button className="mk-border-danger" onClick={this.refreshView}><RedoOutlined /> 强制刷新</Button> |
| | | <Button type="default" onClick={this.closeView}>关闭</Button> |
| | | </div> |
| | | </div> |
| | | <div className={'menu-body menu-view' + (menuloading ? 'saving' : '')}> |
| | | <div className={'menu-body menu-view' + (menuloading ? ' saving' : '') + (eyeopen ? ' eye-open' : '')}> |
| | | {config && !comloading ? <div className="mob-shell" style={{width: window.GLOB.shellWidth, height: window.GLOB.shellHeight}}> |
| | | <MobShell menu={config} handleList={this.updateConfig} /> |
| | | </div> : null} |
| | |
| | | .mk-mob-view { |
| | | min-height: 100vh; |
| | | |
| | | .eye-open { |
| | | .component-name { |
| | | display: block; |
| | | } |
| | | .anticon-tool { |
| | | display: none; |
| | | } |
| | | } |
| | | .component-name { |
| | | position: absolute; |
| | | z-index: 9; |
| | | display: none; |
| | | left: 0; |
| | | right: 0; |
| | | top: 0; |
| | | bottom: 0; |
| | | background: rgba(255, 255, 255, 0.8); |
| | | border: 1px solid #1890ff; |
| | | .center { |
| | | position: absolute; |
| | | font-size: 16px; |
| | | left: 50%; |
| | | top: 50%; |
| | | color: #1890ff; |
| | | transform: translate(-50%, -50%); |
| | | } |
| | | } |
| | | |
| | | .mk-hidden { |
| | | text-decoration: line-through!important; |
| | | span { |
| | | text-decoration: line-through!important; |
| | | } |
| | | } |
| | | >.view-spin { |
| | | position: absolute; |
| | | z-index: 3; |
| | |
| | | import moment from 'moment' |
| | | import HTML5Backend from 'react-dnd-html5-backend' |
| | | import { ConfigProvider, notification, Modal, Collapse, Switch, Button, message, Spin, Typography } from 'antd' |
| | | import { DoubleLeftOutlined, DoubleRightOutlined, HomeOutlined, LoginOutlined, RedoOutlined, ArrowLeftOutlined } from '@ant-design/icons' |
| | | import { DoubleLeftOutlined, DoubleRightOutlined, HomeOutlined, LoginOutlined, RedoOutlined, ArrowLeftOutlined, EyeOutlined, EyeInvisibleOutlined } from '@ant-design/icons' |
| | | |
| | | import Api from '@/api' |
| | | import Utils, { setGLOBFuncs } from '@/utils/utils.js' |
| | |
| | | const PopviewController = asyncComponent(() => import('@/menu/popview')) |
| | | const Versions = asyncComponent(() => import('@/menu/versions')) |
| | | const MenuShell = asyncComponent(() => import('@/pc/menushell')) |
| | | const ViewNodes = asyncComponent(() => import('@/menu/viewnodes')) |
| | | const SourceWrap = asyncComponent(() => import('@/pc/modulesource')) |
| | | const CreateView = asyncComponent(() => import('@/pc/createview')) |
| | | const BgController = asyncComponent(() => import('@/pc/bgcontroller')) |
| | |
| | | customComponents: [], |
| | | settingshow: sessionStorage.getItem('settingshow') !== 'false', |
| | | controlshow: sessionStorage.getItem('controlshow') !== 'false', |
| | | comloading: false |
| | | comloading: false, |
| | | eyeopen: false |
| | | } |
| | | |
| | | UNSAFE_componentWillMount() { |
| | |
| | | return item |
| | | }) |
| | | sessionStorage.setItem('appMenus', JSON.stringify(menus)) |
| | | sessionStorage.setItem('allMenus', JSON.stringify(res.menus || [])) |
| | | }) |
| | | } |
| | | |
| | |
| | | return null |
| | | } else if (item.type === 'card' || (item.type === 'table' && item.subtype === 'tablecard')) { |
| | | item.action && item.action.forEach(btn => { |
| | | if (btn.hidden === 'true') return |
| | | |
| | | this.checkBtn(btn) |
| | | m.children.push({ |
| | | key: btn.uuid, |
| | |
| | | item.subcards.forEach(card => { |
| | | card.elements && card.elements.forEach(cell => { |
| | | if (cell.eleType !== 'button') return |
| | | if (cell.hidden === 'true') return |
| | | |
| | | this.checkBtn(cell) |
| | | m.children.push({ |
| | | key: cell.uuid, |
| | |
| | | }) |
| | | card.backElements && card.backElements.forEach(cell => { |
| | | if (cell.eleType !== 'button') return |
| | | if (cell.hidden === 'true') return |
| | | |
| | | this.checkBtn(cell) |
| | | m.children.push({ |
| | | key: cell.uuid, |
| | |
| | | item.subcards.forEach(card => { |
| | | card.elements && card.elements.forEach(cell => { |
| | | if (cell.eleType !== 'button') return |
| | | if (cell.hidden === 'true') return |
| | | |
| | | this.checkBtn(cell) |
| | | m.children.push({ |
| | | key: cell.uuid, |
| | |
| | | } else if (item.type === 'balcony') { |
| | | item.elements && item.elements.forEach(cell => { |
| | | if (cell.eleType !== 'button') return |
| | | if (cell.hidden === 'true') return |
| | | |
| | | this.checkBtn(cell) |
| | | m.children.push({ |
| | | key: cell.uuid, |
| | |
| | | }) |
| | | } else if (item.type === 'table' && (item.subtype === 'normaltable' || item.subtype === 'editable')) { |
| | | item.action && item.action.forEach(btn => { |
| | | if (btn.hidden === 'true') return |
| | | |
| | | this.checkBtn(btn) |
| | | m.children.push({ |
| | | key: btn.uuid, |
| | |
| | | item.cols && item.cols.forEach(col => { |
| | | if (col.type !== 'action') return |
| | | col.elements.forEach(btn => { |
| | | if (btn.hidden === 'true') return |
| | | |
| | | this.checkBtn(btn) |
| | | m.children.push({ |
| | | key: btn.uuid, |
| | |
| | | } |
| | | } |
| | | |
| | | getSubMenus = () => { |
| | | const { config } = this.state |
| | | let menus = [] |
| | | let menuObj = {} |
| | | let allMenus = JSON.parse(sessionStorage.getItem('allMenus')) |
| | | |
| | | allMenus.forEach(item => { |
| | | menuObj[item.MenuID] = item |
| | | }) |
| | | |
| | | let traversal = (components) => { |
| | | components.forEach(item => { |
| | | if (item.type === 'login') { |
| | | if (item.wrap.linkmenu && menuObj[item.wrap.linkmenu]) { |
| | | menus.push(menuObj[item.wrap.linkmenu]) |
| | | } |
| | | } else if (item.type === 'tabs') { |
| | | item.subtabs.forEach(tab => { |
| | | traversal(tab.components) |
| | | }) |
| | | } else if (item.type === 'group') { |
| | | traversal(item.components) |
| | | } else if (item.type === 'card' || (item.type === 'table' && item.subtype === 'tablecard')) { |
| | | item.action && item.action.forEach(btn => { |
| | | if (btn.linkmenu && menuObj[btn.linkmenu]) { |
| | | menus.push(menuObj[btn.linkmenu]) |
| | | } else if (btn.openmenu && menuObj[btn.openmenu]) { |
| | | menus.push(menuObj[btn.openmenu]) |
| | | } |
| | | }) |
| | | item.subcards.forEach(card => { |
| | | if (card.setting.click === 'menu' && menuObj[card.setting.menu]) { |
| | | menus.push(menuObj[card.setting.menu]) |
| | | } else if (card.setting.click === 'menus' && card.menus) { |
| | | card.menus.forEach(m => { |
| | | if (menuObj[m.menu]) { |
| | | menus.push(menuObj[m.menu]) |
| | | } |
| | | }) |
| | | } |
| | | card.elements && card.elements.forEach(cell => { |
| | | if (cell.eleType !== 'button') return |
| | | |
| | | if (cell.linkmenu && menuObj[cell.linkmenu]) { |
| | | menus.push(menuObj[cell.linkmenu]) |
| | | } else if (cell.openmenu && menuObj[cell.openmenu]) { |
| | | menus.push(menuObj[cell.openmenu]) |
| | | } |
| | | }) |
| | | }) |
| | | } else if (item.type === 'carousel' || item.type === 'timeline') { |
| | | item.subcards.forEach(card => { |
| | | if (card.setting.click === 'menu' && menuObj[card.setting.menu]) { |
| | | menus.push(menuObj[card.setting.menu]) |
| | | } |
| | | card.elements && card.elements.forEach(cell => { |
| | | if (cell.eleType !== 'button') return |
| | | |
| | | if (cell.linkmenu && menuObj[cell.linkmenu]) { |
| | | menus.push(menuObj[cell.linkmenu]) |
| | | } else if (cell.openmenu && menuObj[cell.openmenu]) { |
| | | menus.push(menuObj[cell.openmenu]) |
| | | } |
| | | }) |
| | | }) |
| | | } else if (item.type === 'balcony') { |
| | | item.elements && item.elements.forEach(cell => { |
| | | if (cell.eleType !== 'button') return |
| | | |
| | | if (cell.linkmenu && menuObj[cell.linkmenu]) { |
| | | menus.push(menuObj[cell.linkmenu]) |
| | | } else if (cell.openmenu && menuObj[cell.openmenu]) { |
| | | menus.push(menuObj[cell.openmenu]) |
| | | } |
| | | }) |
| | | } else if (item.type === 'form') { |
| | | item.subcards.forEach(m => { |
| | | if (m.subButton && m.subButton.linkmenu && menuObj[m.subButton.linkmenu]) { |
| | | menus.push(menuObj[m.subButton.linkmenu]) |
| | | } |
| | | }) |
| | | } else if (item.type === 'table' && item.subtype === 'normaltable') { |
| | | item.action && item.action.forEach(btn => { |
| | | if (btn.linkmenu && menuObj[btn.linkmenu]) { |
| | | menus.push(menuObj[btn.linkmenu]) |
| | | } else if (btn.openmenu && menuObj[btn.openmenu]) { |
| | | menus.push(menuObj[btn.openmenu]) |
| | | } |
| | | }) |
| | | item.cols && item.cols.forEach(col => { |
| | | if (col.type !== 'action') return |
| | | col.elements.forEach(btn => { |
| | | if (btn.linkmenu && menuObj[btn.linkmenu]) { |
| | | menus.push(menuObj[btn.linkmenu]) |
| | | } else if (btn.openmenu && menuObj[btn.openmenu]) { |
| | | menus.push(menuObj[btn.openmenu]) |
| | | } |
| | | }) |
| | | }) |
| | | } |
| | | }) |
| | | } |
| | | |
| | | traversal(config.components) |
| | | |
| | | let map = new Map() |
| | | menus = menus.filter(m => { |
| | | if (map.has(m.MenuID)) return false |
| | | map.set(m.MenuID, true) |
| | | return true |
| | | }) |
| | | |
| | | return menus |
| | | } |
| | | |
| | | submitConfig = () => { |
| | | const { delButtons, copyButtons, thawButtons } = this.state |
| | | let config = fromJS(this.state.config).toJS() |
| | |
| | | |
| | | let roleParam = this.getMenuMessage() |
| | | |
| | | let subMenus = this.getSubMenus() |
| | | let menus_used_list = subMenus.map(m => `'${config.uuid}','${config.MenuName || ''}','${config.MenuNo || ''}','${m.MenuID}','${m.MenuName}'`).join(';') |
| | | menus_used_list = window.btoa(window.encodeURIComponent(menus_used_list || 'del')) |
| | | |
| | | let param = { |
| | | func: 'sPC_TrdMenu_AddUpt', |
| | | FstID: 'mk_app', |
| | |
| | | menus_rolelist: window.btoa(window.encodeURIComponent(JSON.stringify(roleParam))), |
| | | open_edition: config.open_edition, |
| | | LText: '', |
| | | LTexttb: '' |
| | | LTexttb: '', |
| | | menus_used_list |
| | | } |
| | | |
| | | param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') |
| | |
| | | } |
| | | |
| | | render () { |
| | | const { localedict, loading, visible, popBtn, comloading, activeKey, settingshow, controlshow, dict, MenuId, config, menuloading, customComponents } = this.state |
| | | const { localedict, loading, visible, popBtn, comloading, activeKey, settingshow, controlshow, dict, MenuId, config, menuloading, customComponents, eyeopen } = this.state |
| | | |
| | | return ( |
| | | <ConfigProvider locale={localedict}> |
| | |
| | | <Button type="primary" id="save-config" onClick={this.submitConfig} loading={menuloading}>{dict['mob.save']}</Button> |
| | | <Switch className="big" checkedChildren={dict['mob.enable']} unCheckedChildren={dict['mob.disable']} checked={config && config.enabled} onChange={this.onEnabledChange} /> |
| | | <ArrowLeftOutlined title="后退" className="back-view" onClick={this.backView}/> |
| | | <Button className="mk-border-purple" onClick={() => this.setState({eyeopen: !eyeopen})}>{!eyeopen ? <EyeOutlined /> : <EyeInvisibleOutlined />} 组件名</Button> |
| | | <CreateView resetmenu={this.getAppMenus} /> |
| | | <PasteController insert={this.insert} /> |
| | | <StyleCombControlButton menu={config} /> |
| | | <ViewNodes config={config} MenuId={MenuId}/> |
| | | <SysInterface config={config} updateConfig={this.updateConfig}/> |
| | | <PictureController/> |
| | | <Quotecomponent config={config} updateConfig={this.updateConfig}/> |
| | |
| | | <ReplaceField type="custom" config={config} updateConfig={this.resetConfig}/> |
| | | <Transfer MenuID={MenuId} /> |
| | | <Versions MenuId={MenuId} open_edition={config ? config.open_edition : ''}/> |
| | | <StyleCombControlButton menu={config} /> |
| | | <Button className="mk-border-danger" onClick={this.refreshView}><RedoOutlined /> 强制刷新</Button> |
| | | <Button type="default" onClick={this.closeView}>关闭</Button> |
| | | </div> |
| | | </div> |
| | | <div className={'menu-body menu-view' + (menuloading ? 'saving' : '')}> |
| | | <div className={'menu-body menu-view' + (menuloading ? ' saving' : '') + (eyeopen ? ' eye-open' : '')}> |
| | | {config && !comloading ? <MenuShell menu={config} handleList={this.updateConfig} /> : null} |
| | | </div> |
| | | </DndProvider> : null} |
| | |
| | | background: #000; |
| | | min-height: 100vh; |
| | | |
| | | .eye-open { |
| | | .component-name { |
| | | display: block; |
| | | } |
| | | .anticon-tool { |
| | | display: none; |
| | | } |
| | | } |
| | | .component-name { |
| | | position: absolute; |
| | | z-index: 9; |
| | | display: none; |
| | | left: 0; |
| | | right: 0; |
| | | top: 0; |
| | | bottom: 0; |
| | | background: rgba(255, 255, 255, 0.8); |
| | | border: 1px solid #1890ff; |
| | | .center { |
| | | position: absolute; |
| | | font-size: 16px; |
| | | left: 50%; |
| | | top: 50%; |
| | | color: #1890ff; |
| | | transform: translate(-50%, -50%); |
| | | } |
| | | } |
| | | |
| | | .mk-hidden { |
| | | text-decoration: line-through!important; |
| | | span { |
| | | text-decoration: line-through!important; |
| | | } |
| | | } |
| | | >.view-spin { |
| | | position: absolute; |
| | | z-index: 3; |
| | |
| | | } |
| | | |
| | | saveTree = () => { |
| | | const { trees } = this.state |
| | | // const { trees } = this.state |
| | | const _this = this |
| | | |
| | | if (!trees || trees.length === 0) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '未获取到权限信息!', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } |
| | | // if (!trees || trees.length === 0) { |
| | | // notification.warning({ |
| | | // top: 92, |
| | | // message: '未获取到权限信息!', |
| | | // duration: 5 |
| | | // }) |
| | | // return |
| | | // } |
| | | |
| | | confirm({ |
| | | content: '确定执行吗?', |