Compare commits

...

2 Commits

Author SHA1 Message Date
LiuJiaNan 3cb9ef4d9e zy-gbs-cmd: update eightwork 2026-08-27 17:40:30 +08:00
zhaokai bc060341aa feat(work): 新增高处作业安全许可证导出功能 2026-08-27 17:38:07 +08:00
30 changed files with 1405 additions and 12 deletions

5
.gitignore vendored
View File

@ -36,6 +36,9 @@ build/
### Mac OS ###
.DS_Store
/start/src/main/resources/templates/
/start/src/main/resources/templates/*
!/start/src/main/resources/templates/template/
/start/src/main/resources/templates/template/*
!/start/src/main/resources/templates/template/high_work_permit_sign.docx
/start/src/main/resources/nacos/
/.idea/

View File

@ -3,8 +3,8 @@ spring:
import:
# - classpath:nacos.yml
# - classpath:sdk.yml
# - classpath:nacos-prod.yml
# - classpath:sdk-prod.yml
- classpath:nacos-prod-gwj.yml
- classpath:sdk-prod-gwj.yml
- classpath:nacos-prod.yml
- classpath:sdk-prod.yml
# - classpath:nacos-prod-gwj.yml
# - classpath:sdk-prod-gwj.yml
- classpath:swagger.yml

Binary file not shown.

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<License>
<Data>
<Products>
<Product>Aspose.Total for Java</Product>
<Product>Aspose.Words for Java</Product>
</Products>
<EditionType>Enterprise</EditionType>
<SubscriptionExpiry>20991231</SubscriptionExpiry>
<LicenseExpiry>20991231</LicenseExpiry>
<SerialNumber>8bfe198c-7f0c-4ef8-8ff0-acc3237bf0d7</SerialNumber>
</Data>
<Signature>
sNLLKGMUdF0r8O1kKilWAGdgfs2BvJb/2Xp8p5iuDVfZXmhppo+d0Ran1P9TKdjV4ABwAgKXxJ3jcQTqE/2IRfqwnPf8itN8aFZlV3TJPYeD3yWE7IT55Gz6EijUpC7aKeoohTb4w2fpox58wWoF3SNp6sK6jDfiAUGEHYJ9pjU=
</Signature>
</License>

View File

@ -53,5 +53,6 @@ message:
code:
taskLogTemplate: MS000106
file:
url: http://192.168.192.201:8991/file/uploadFiles2/

View File

@ -53,5 +53,6 @@ message:
code:
taskLogTemplate: MS000127
file:
url: https://jpfz.qhdsafety.com/gbsFileTest/

View File

@ -0,0 +1,23 @@
<!doctype html><html lang="zh"><head data-built-info="@cqsjjb/scripts@2.0.0-alpha-1 Env/production (2026/8/27 17:39:08) App/eightwork"><meta charset="UTF-8"/><meta name="renderer" content="webkit"/><meta http-equiv="X-UA-Compatible" content="IE=edge,Chrome=1"/><meta name="viewport" content="width=device-width,minimum-scale=1,maximum-scale=1,user-scalable=no,viewport-fit=cover"><title>--</title><script>(function () {
const APP_ENV = {
antd: {
'ant-prefix': 'micro-temp',
fontFamily: 'PingFangSC-Regular',
colorPrimary: '#1677ff',
borderRadius: parseInt('2')
},
appKey: '',
basename: 'eightwork',
API_HOST: ''
};
APP_ENV.API_HOST = sessionStorage.API_HOST || APP_ENV.API_HOST || window.location.origin;
window.process = {
env: { app: APP_ENV },
NODE_ENV: 'production'
};
window.__JJB_ENVIRONMENT__ = {
API_HOST: APP_ENV.API_HOST,
redirect: '',
FRAMEWORK: APP_ENV.antd
};
})();</script><script defer="defer" src="/eightwork/static/js/294.08b4c187b6115f95c749.js"></script><script defer="defer" src="/eightwork/static/js/263.04481293786545920a2c.js"></script><script defer="defer" src="/eightwork/static/js/main.b96f88f58ccf84a977c5.js"></script><link href="/eightwork/static/css/main.8865e458bd5e9fb78fb8.css" rel="stylesheet"></head><body><noscript>此网页需要开启JavaScript功能。</noscript><div id="root" style="width: 100%; height: 100%; position: relative;overflow-y: auto"></div><script type="text/javascript">/* @cqsjjb/script 输出当前应用基本信息、构建时间 */console.log("%c@cqsjjb/scripts@2.0.0-alpha-1 Env/production (2026/8/27 17:39:08) App/eightwork Version/master Java/dev_change_0814", "color: #1890ff; border-radius: 2px; padding: 0 4px; border: 1px solid #1890ff; background: #f9fcff")</script></body></html>

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
module.exports={compact:!1,plugins:[["@babel/plugin-proposal-decorators",{legacy:!0}]],presets:[["@babel/preset-env",{targets:{browsers:["ie >= 10"]}}],["@babel/preset-react",{runtime:"automatic"}]]};

View File

@ -0,0 +1 @@
module.exports={javaGit:"http://47.92.113.182:3000/zcloud_gbs/zcloud-gbs-eightwork.git",javaGitName:"zcloud-gbs-eightwork",environment:{development:{javaGitBranch:"<branch-name>",API_HOST:"https://gbs-gateway.qhdsafety.com"},production:{javaGitBranch:"dev_change_0814",API_HOST:""}},appIdentifier:"eightwork",contextInject:{appKey:"",fileUrl:"https://skqhdg.porthebei.com:9004/file/uploadFiles2/"},windowInject:{title:"微应用模板",links:[],element:{root:{id:"root"}},scripts:[]},server:{port:"8063",host:"127.0.0.1",open:!0},framework:{antd:{"ant-prefix":"micro-temp",fontFamily:"PingFangSC-Regular",colorPrimary:"#1677ff",borderRadius:2}},webpackConfig:{htmlWebpackPluginOption:{inject:!0}}};

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,109 @@
/*!
* is-plain-object <https://github.com/jonschlinkert/is-plain-object>
*
* Copyright (c) 2014-2017, Jon Schlinkert.
* Released under the MIT License.
*/
/*!
* isobject <https://github.com/jonschlinkert/isobject>
*
* Copyright (c) 2014-2017, Jon Schlinkert.
* Released under the MIT License.
*/
/*!
* screenfull
* v5.2.0 - 2021-11-03
* (c) Sindre Sorhus; MIT License
*/
/*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/babel/babel/blob/main/packages/babel-helpers/LICENSE */
/**
* @license React
* react-dom.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/**
* @license React
* react-is.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/**
* @license React
* react-jsx-runtime.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/**
* @license React
* react.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/**
* @license React
* scheduler.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/**
* @license React
* use-sync-external-store-shim.production.js
*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/**
* @license React
* use-sync-external-store-shim/with-selector.production.js
*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/** @license React v16.13.1
* react-is.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/** @license React v17.0.2
* react-is.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,87 @@
/*!
Copyright (c) 2018 Jed Watson.
Licensed under the MIT License (MIT), see
http://jedwatson.github.io/classnames
*/
/*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/babel/babel/blob/main/packages/babel-helpers/LICENSE */
/** @preserve
* Counter block mode compatible with Dr Brian Gladman fileenc.c
* derived from CryptoJS.mode.CTR
* Jan Hruby jhruby.web@gmail.com
*/
/** @preserve
(c) 2012 by Cédric Mesnil. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**![arrow-down](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjY0IDY0IDg5NiA4OTYiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTg2MiA0NjUuM2gtODFjLTQuNiAwLTkgMi0xMi4xIDUuNUw1NTAgNzIzLjFWMTYwYzAtNC40LTMuNi04LTgtOGgtNjBjLTQuNCAwLTggMy42LTggOHY1NjMuMUwyNTUuMSA0NzAuOGMtMy0zLjUtNy40LTUuNS0xMi4xLTUuNWgtODFjLTYuOCAwLTEwLjUgOC4xLTYgMTMuMkw0ODcuOSA4NjFhMzEuOTYgMzEuOTYgMCAwMDQ4LjMgMEw4NjggNDc4LjVjNC41LTUuMi44LTEzLjItNi0xMy4yeiIgLz48L3N2Zz4=) */
/**![arrow-up](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjY0IDY0IDg5NiA4OTYiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTg2OCA1NDUuNUw1MzYuMSAxNjNhMzEuOTYgMzEuOTYgMCAwMC00OC4zIDBMMTU2IDU0NS41YTcuOTcgNy45NyAwIDAwNiAxMy4yaDgxYzQuNiAwIDktMiAxMi4xLTUuNUw0NzQgMzAwLjlWODY0YzAgNC40IDMuNiA4IDggOGg2MGM0LjQgMCA4LTMuNiA4LThWMzAwLjlsMjE4LjkgMjUyLjNjMyAzLjUgNy40IDUuNSAxMi4xIDUuNWg4MWM2LjggMCAxMC41LTggNi0xMy4yeiIgLz48L3N2Zz4=) */
/**![calendar](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjY0IDY0IDg5NiA4OTYiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTg4MCAxODRINzEydi02NGMwLTQuNC0zLjYtOC04LThoLTU2Yy00LjQgMC04IDMuNi04IDh2NjRIMzg0di02NGMwLTQuNC0zLjYtOC04LThoLTU2Yy00LjQgMC04IDMuNi04IDh2NjRIMTQ0Yy0xNy43IDAtMzIgMTQuMy0zMiAzMnY2NjRjMCAxNy43IDE0LjMgMzIgMzIgMzJoNzM2YzE3LjcgMCAzMi0xNC4zIDMyLTMyVjIxNmMwLTE3LjctMTQuMy0zMi0zMi0zMnptLTQwIDY1NkgxODRWNDYwaDY1NnYzODB6TTE4NCAzOTJWMjU2aDEyOHY0OGMwIDQuNCAzLjYgOCA4IDhoNTZjNC40IDAgOC0zLjYgOC04di00OGgyNTZ2NDhjMCA0LjQgMy42IDggOCA4aDU2YzQuNCAwIDgtMy42IDgtOHYtNDhoMTI4djEzNkgxODR6IiAvPjwvc3ZnPg==) */
/**![caret-down](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjAgMCAxMDI0IDEwMjQiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTg0MC40IDMwMEgxODMuNmMtMTkuNyAwLTMwLjcgMjAuOC0xOC41IDM1bDMyOC40IDM4MC44YzkuNCAxMC45IDI3LjUgMTAuOSAzNyAwTDg1OC45IDMzNWMxMi4yLTE0LjIgMS4yLTM1LTE4LjUtMzV6IiAvPjwvc3ZnPg==) */
/**![caret-up](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjAgMCAxMDI0IDEwMjQiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTg1OC45IDY4OUw1MzAuNSAzMDguMmMtOS40LTEwLjktMjcuNS0xMC45LTM3IDBMMTY1LjEgNjg5Yy0xMi4yIDE0LjItMS4yIDM1IDE4LjUgMzVoNjU2LjhjMTkuNyAwIDMwLjctMjAuOCAxOC41LTM1eiIgLz48L3N2Zz4=) */
/**![clock-circle](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjY0IDY0IDg5NiA4OTYiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTUxMiA2NEMyNjQuNiA2NCA2NCAyNjQuNiA2NCA1MTJzMjAwLjYgNDQ4IDQ0OCA0NDggNDQ4LTIwMC42IDQ0OC00NDhTNzU5LjQgNjQgNTEyIDY0em0wIDgyMGMtMjA1LjQgMC0zNzItMTY2LjYtMzcyLTM3MnMxNjYuNi0zNzIgMzcyLTM3MiAzNzIgMTY2LjYgMzcyIDM3Mi0xNjYuNiAzNzItMzcyIDM3MnoiIC8+PHBhdGggZD0iTTY4Ni43IDYzOC42TDU0NC4xIDUzNS41VjI4OGMwLTQuNC0zLjYtOC04LThINDg4Yy00LjQgMC04IDMuNi04IDh2Mjc1LjRjMCAyLjYgMS4yIDUgMy4zIDYuNWwxNjUuNCAxMjAuNmMzLjYgMi42IDguNiAxLjggMTEuMi0xLjdsMjguNi0zOWMyLjYtMy43IDEuOC04LjctMS44LTExLjJ6IiAvPjwvc3ZnPg==) */
/**![column-height](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjY0IDY0IDg5NiA4OTYiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTg0MCA4MzZIMTg0Yy00LjQgMC04IDMuNi04IDh2NjBjMCA0LjQgMy42IDggOCA4aDY1NmM0LjQgMCA4LTMuNiA4LTh2LTYwYzAtNC40LTMuNi04LTgtOHptMC03MjRIMTg0Yy00LjQgMC04IDMuNi04IDh2NjBjMCA0LjQgMy42IDggOCA4aDY1NmM0LjQgMCA4LTMuNiA4LTh2LTYwYzAtNC40LTMuNi04LTgtOHpNNjEwLjggMzc4YzYgMCA5LjQtNyA1LjctMTEuN0w1MTUuNyAyMzguN2E3LjE0IDcuMTQgMCAwMC0xMS4zIDBMNDAzLjYgMzY2LjNhNy4yMyA3LjIzIDAgMDA1LjcgMTEuN0g0NzZ2MjY4aC02Mi44Yy02IDAtOS40IDctNS43IDExLjdsMTAwLjggMTI3LjVjMi45IDMuNyA4LjUgMy43IDExLjMgMGwxMDAuOC0xMjcuNWMzLjctNC43LjQtMTEuNy01LjctMTEuN0g1NDhWMzc4aDYyLjh6IiAvPjwvc3ZnPg==) */
/**![copy](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjY0IDY0IDg5NiA4OTYiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTgzMiA2NEgyOTZjLTQuNCAwLTggMy42LTggOHY1NmMwIDQuNCAzLjYgOCA4IDhoNDk2djY4OGMwIDQuNCAzLjYgOCA4IDhoNTZjNC40IDAgOC0zLjYgOC04Vjk2YzAtMTcuNy0xNC4zLTMyLTMyLTMyek03MDQgMTkySDE5MmMtMTcuNyAwLTMyIDE0LjMtMzIgMzJ2NTMwLjdjMCA4LjUgMy40IDE2LjYgOS40IDIyLjZsMTczLjMgMTczLjNjMi4yIDIuMiA0LjcgNCA3LjQgNS41djEuOWg0LjJjMy41IDEuMyA3LjIgMiAxMSAySDcwNGMxNy43IDAgMzItMTQuMyAzMi0zMlYyMjRjMC0xNy43LTE0LjMtMzItMzItMzJ6TTM1MCA4NTYuMkwyNjMuOSA3NzBIMzUwdjg2LjJ6TTY2NCA4ODhINDE0Vjc0NmMwLTIyLjEtMTcuOS00MC00MC00MEgyMzJWMjY0aDQzMnY2MjR6IiAvPjwvc3ZnPg==) */
/**![double-left](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjY0IDY0IDg5NiA4OTYiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTI3Mi45IDUxMmwyNjUuNC0zMzkuMWM0LjEtNS4yLjQtMTIuOS02LjMtMTIuOWgtNzcuM2MtNC45IDAtOS42IDIuMy0xMi42IDYuMUwxODYuOCA0OTIuM2EzMS45OSAzMS45OSAwIDAwMCAzOS41bDI1NS4zIDMyNi4xYzMgMy45IDcuNyA2LjEgMTIuNiA2LjFINTMyYzYuNyAwIDEwLjQtNy43IDYuMy0xMi45TDI3Mi45IDUxMnptMzA0IDBsMjY1LjQtMzM5LjFjNC4xLTUuMi40LTEyLjktNi4zLTEyLjloLTc3LjNjLTQuOSAwLTkuNiAyLjMtMTIuNiA2LjFMNDkwLjggNDkyLjNhMzEuOTkgMzEuOTkgMCAwMDAgMzkuNWwyNTUuMyAzMjYuMWMzIDMuOSA3LjcgNi4xIDEyLjYgNi4xSDgzNmM2LjcgMCAxMC40LTcuNyA2LjMtMTIuOUw1NzYuOSA1MTJ6IiAvPjwvc3ZnPg==) */
/**![double-right](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjY0IDY0IDg5NiA4OTYiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTUzMy4yIDQ5Mi4zTDI3Ny45IDE2Ni4xYy0zLTMuOS03LjctNi4xLTEyLjYtNi4xSDE4OGMtNi43IDAtMTAuNCA3LjctNi4zIDEyLjlMNDQ3LjEgNTEyIDE4MS43IDg1MS4xQTcuOTggNy45OCAwIDAwMTg4IDg2NGg3Ny4zYzQuOSAwIDkuNi0yLjMgMTIuNi02LjFsMjU1LjMtMzI2LjFjOS4xLTExLjcgOS4xLTI3LjkgMC0zOS41em0zMDQgMEw1ODEuOSAxNjYuMWMtMy0zLjktNy43LTYuMS0xMi42LTYuMUg0OTJjLTYuNyAwLTEwLjQgNy43LTYuMyAxMi45TDc1MS4xIDUxMiA0ODUuNyA4NTEuMUE3Ljk4IDcuOTggMCAwMDQ5MiA4NjRoNzcuM2M0LjkgMCA5LjYtMi4zIDEyLjYtNi4xbDI1NS4zLTMyNi4xYzkuMS0xMS43IDkuMS0yNy45IDAtMzkuNXoiIC8+PC9zdmc+) */
/**![download](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjY0IDY0IDg5NiA4OTYiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTUwNS43IDY2MWE4IDggMCAwMDEyLjYgMGwxMTItMTQxLjdjNC4xLTUuMi40LTEyLjktNi4zLTEyLjloLTc0LjFWMTY4YzAtNC40LTMuNi04LTgtOGgtNjBjLTQuNCAwLTggMy42LTggOHYzMzguM0g0MDBjLTYuNyAwLTEwLjQgNy43LTYuMyAxMi45bDExMiAxNDEuOHpNODc4IDYyNmgtNjBjLTQuNCAwLTggMy42LTggOHYxNTRIMjE0VjYzNGMwLTQuNC0zLjYtOC04LThoLTYwYy00LjQgMC04IDMuNi04IDh2MTk4YzAgMTcuNyAxNC4zIDMyIDMyIDMyaDY4NGMxNy43IDAgMzItMTQuMyAzMi0zMlY2MzRjMC00LjQtMy42LTgtOC04eiIgLz48L3N2Zz4=) */
/**![edit](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjY0IDY0IDg5NiA4OTYiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTI1Ny43IDc1MmMyIDAgNC0uMiA2LS41TDQzMS45IDcyMmMyLS40IDMuOS0xLjMgNS4zLTIuOGw0MjMuOS00MjMuOWE5Ljk2IDkuOTYgMCAwMDAtMTQuMUw2OTQuOSAxMTQuOWMtMS45LTEuOS00LjQtMi45LTcuMS0yLjlzLTUuMiAxLTcuMSAyLjlMMjU2LjggNTM4LjhjLTEuNSAxLjUtMi40IDMuMy0yLjggNS4zbC0yOS41IDE2OC4yYTMzLjUgMzMuNSAwIDAwOS40IDI5LjhjNi42IDYuNCAxNC45IDkuOSAyMy44IDkuOXptNjcuNC0xNzQuNEw2ODcuOCAyMTVsNzMuMyA3My4zLTM2Mi43IDM2Mi42LTg4LjkgMTUuNyAxNS42LTg5ek04ODAgODM2SDE0NGMtMTcuNyAwLTMyIDE0LjMtMzIgMzJ2MzZjMCA0LjQgMy42IDggOCA4aDc4NGM0LjQgMCA4LTMuNiA4LTh2LTM2YzAtMTcuNy0xNC4zLTMyLTMyLTMyeiIgLz48L3N2Zz4=) */
/**![enter](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjY0IDY0IDg5NiA4OTYiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTg2NCAxNzBoLTYwYy00LjQgMC04IDMuNi04IDh2NTE4SDMxMHYtNzNjMC02LjctNy44LTEwLjUtMTMtNi4zbC0xNDEuOSAxMTJhOCA4IDAgMDAwIDEyLjZsMTQxLjkgMTEyYzUuMyA0LjIgMTMgLjQgMTMtNi4zdi03NWg0OThjMzUuMyAwIDY0LTI4LjcgNjQtNjRWMTc4YzAtNC40LTMuNi04LTgtOHoiIC8+PC9zdmc+) */
/**![filter](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjY0IDY0IDg5NiA4OTYiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTM0OSA4MzhjMCAxNy43IDE0LjIgMzIgMzEuOCAzMmgyNjIuNGMxNy42IDAgMzEuOC0xNC4zIDMxLjgtMzJWNjQySDM0OXYxOTZ6bTUzMS4xLTY4NEgxNDMuOWMtMjQuNSAwLTM5LjggMjYuNy0yNy41IDQ4bDIyMS4zIDM3NmgzNDguOGwyMjEuMy0zNzZjMTIuMS0yMS4zLTMuMi00OC0yNy43LTQ4eiIgLz48L3N2Zz4=) */
/**![filter](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjY0IDY0IDg5NiA4OTYiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTg4MC4xIDE1NEgxNDMuOWMtMjQuNSAwLTM5LjggMjYuNy0yNy41IDQ4TDM0OSA1OTcuNFY4MzhjMCAxNy43IDE0LjIgMzIgMzEuOCAzMmgyNjIuNGMxNy42IDAgMzEuOC0xNC4zIDMxLjgtMzJWNTk3LjRMOTA3LjcgMjAyYzEyLjItMjEuMy0zLjEtNDgtMjcuNi00OHpNNjAzLjQgNzk4SDQyMC42VjY0MmgxODIuOXYxNTZ6bTkuNi0yMzYuNmwtOS41IDE2LjZoLTE4M2wtOS41LTE2LjZMMjEyLjcgMjI2aDU5OC42TDYxMyA1NjEuNHoiIC8+PC9zdmc+) */
/**![folder-open](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjY0IDY0IDg5NiA4OTYiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTkyOCA0NDRIODIwVjMzMC40YzAtMTcuNy0xNC4zLTMyLTMyLTMySDQ3M0wzNTUuNyAxODYuMmE4LjE1IDguMTUgMCAwMC01LjUtMi4ySDk2Yy0xNy43IDAtMzIgMTQuMy0zMiAzMnY1OTJjMCAxNy43IDE0LjMgMzIgMzIgMzJoNjk4YzEzIDAgMjQuOC03LjkgMjkuNy0yMGwxMzQtMzMyYzEuNS0zLjggMi4zLTcuOSAyLjMtMTIgMC0xNy43LTE0LjMtMzItMzItMzJ6TTEzNiAyNTZoMTg4LjVsMTE5LjYgMTE0LjRINzQ4VjQ0NEgyMzhjLTEzIDAtMjQuOCA3LjktMjkuNyAyMEwxMzYgNjQzLjJWMjU2em02MzUuMyA1MTJIMTU5bDEwMy4zLTI1Nmg2MTIuNEw3NzEuMyA3Njh6IiAvPjwvc3ZnPg==) */
/**![folder](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjY0IDY0IDg5NiA4OTYiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTg4MCAyOTguNEg1MjFMNDAzLjcgMTg2LjJhOC4xNSA4LjE1IDAgMDAtNS41LTIuMkgxNDRjLTE3LjcgMC0zMiAxNC4zLTMyIDMydjU5MmMwIDE3LjcgMTQuMyAzMiAzMiAzMmg3MzZjMTcuNyAwIDMyLTE0LjMgMzItMzJWMzMwLjRjMC0xNy43LTE0LjMtMzItMzItMzJ6TTg0MCA3NjhIMTg0VjI1NmgxODguNWwxMTkuNiAxMTQuNEg4NDBWNzY4eiIgLz48L3N2Zz4=) */
/**![fullscreen-exit](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjY0IDY0IDg5NiA4OTYiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTM5MSAyNDAuOWMtLjgtNi42LTguOS05LjQtMTMuNi00LjdsLTQzLjcgNDMuN0wyMDAgMTQ2LjNhOC4wMyA4LjAzIDAgMDAtMTEuMyAwbC00Mi40IDQyLjNhOC4wMyA4LjAzIDAgMDAwIDExLjNMMjgwIDMzMy42bC00My45IDQzLjlhOC4wMSA4LjAxIDAgMDA0LjcgMTMuNkw0MDEgNDEwYzUuMS42IDkuNS0zLjcgOC45LTguOUwzOTEgMjQwLjl6bTEwLjEgMzczLjJMMjQwLjggNjMzYy02LjYuOC05LjQgOC45LTQuNyAxMy42bDQzLjkgNDMuOUwxNDYuMyA4MjRhOC4wMyA4LjAzIDAgMDAwIDExLjNsNDIuNCA0Mi4zYzMuMSAzLjEgOC4yIDMuMSAxMS4zIDBMMzMzLjcgNzQ0bDQzLjcgNDMuN0E4LjAxIDguMDEgMCAwMDM5MSA3ODNsMTguOS0xNjAuMWMuNi01LjEtMy43LTkuNC04LjgtOC44em0yMjEuOC0yMDQuMkw3ODMuMiAzOTFjNi42LS44IDkuNC04LjkgNC43LTEzLjZMNzQ0IDMzMy42IDg3Ny43IDIwMGMzLjEtMy4xIDMuMS04LjIgMC0xMS4zbC00Mi40LTQyLjNhOC4wMyA4LjAzIDAgMDAtMTEuMyAwTDY5MC4zIDI3OS45bC00My43LTQzLjdhOC4wMSA4LjAxIDAgMDAtMTMuNiA0LjdMNjE0LjEgNDAxYy0uNiA1LjIgMy43IDkuNSA4LjggOC45ek03NDQgNjkwLjRsNDMuOS00My45YTguMDEgOC4wMSAwIDAwLTQuNy0xMy42TDYyMyA2MTRjLTUuMS0uNi05LjUgMy43LTguOSA4LjlMNjMzIDc4My4xYy44IDYuNiA4LjkgOS40IDEzLjYgNC43bDQzLjctNDMuN0w4MjQgODc3LjdjMy4xIDMuMSA4LjIgMy4xIDExLjMgMGw0Mi40LTQyLjNjMy4xLTMuMSAzLjEtOC4yIDAtMTEuM0w3NDQgNjkwLjR6IiAvPjwvc3ZnPg==) */
/**![fullscreen](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjY0IDY0IDg5NiA4OTYiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTI5MCAyMzYuNGw0My45LTQzLjlhOC4wMSA4LjAxIDAgMDAtNC43LTEzLjZMMTY5IDE2MGMtNS4xLS42LTkuNSAzLjctOC45IDguOUwxNzkgMzI5LjFjLjggNi42IDguOSA5LjQgMTMuNiA0LjdsNDMuNy00My43TDM3MCA0MjMuN2MzLjEgMy4xIDguMiAzLjEgMTEuMyAwbDQyLjQtNDIuM2MzLjEtMy4xIDMuMS04LjIgMC0xMS4zTDI5MCAyMzYuNHptMzUyLjcgMTg3LjNjMy4xIDMuMSA4LjIgMy4xIDExLjMgMGwxMzMuNy0xMzMuNiA0My43IDQzLjdhOC4wMSA4LjAxIDAgMDAxMy42LTQuN0w4NjMuOSAxNjljLjYtNS4xLTMuNy05LjUtOC45LTguOUw2OTQuOCAxNzljLTYuNi44LTkuNCA4LjktNC43IDEzLjZsNDMuOSA0My45TDYwMC4zIDM3MGE4LjAzIDguMDMgMCAwMDAgMTEuM2w0Mi40IDQyLjR6TTg0NSA2OTQuOWMtLjgtNi42LTguOS05LjQtMTMuNi00LjdsLTQzLjcgNDMuN0w2NTQgNjAwLjNhOC4wMyA4LjAzIDAgMDAtMTEuMyAwbC00Mi40IDQyLjNhOC4wMyA4LjAzIDAgMDAwIDExLjNMNzM0IDc4Ny42bC00My45IDQzLjlhOC4wMSA4LjAxIDAgMDA0LjcgMTMuNkw4NTUgODY0YzUuMS42IDkuNS0zLjcgOC45LTguOUw4NDUgNjk0Ljl6bS00NjMuNy05NC42YTguMDMgOC4wMyAwIDAwLTExLjMgMEwyMzYuMyA3MzMuOWwtNDMuNy00My43YTguMDEgOC4wMSAwIDAwLTEzLjYgNC43TDE2MC4xIDg1NWMtLjYgNS4xIDMuNyA5LjUgOC45IDguOUwzMjkuMiA4NDVjNi42LS44IDkuNC04LjkgNC43LTEzLjZMMjkwIDc4Ny42IDQyMy43IDY1NGMzLjEtMy4xIDMuMS04LjIgMC0xMS4zbC00Mi40LTQyLjR6IiAvPjwvc3ZnPg==) */
/**![holder](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjY0IDY0IDg5NiA4OTYiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTMwMCAyNzYuNWE1NiA1NiAwIDEwNTYtOTcgNTYgNTYgMCAwMC01NiA5N3ptMCAyODRhNTYgNTYgMCAxMDU2LTk3IDU2IDU2IDAgMDAtNTYgOTd6TTY0MCAyMjhhNTYgNTYgMCAxMDExMiAwIDU2IDU2IDAgMDAtMTEyIDB6bTAgMjg0YTU2IDU2IDAgMTAxMTIgMCA1NiA1NiAwIDAwLTExMiAwek0zMDAgODQ0LjVhNTYgNTYgMCAxMDU2LTk3IDU2IDU2IDAgMDAtNTYgOTd6TTY0MCA3OTZhNTYgNTYgMCAxMDExMiAwIDU2IDU2IDAgMDAtMTEyIDB6IiAvPjwvc3ZnPg==) */
/**![minus-square](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjY0IDY0IDg5NiA4OTYiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTMyOCA1NDRoMzY4YzQuNCAwIDgtMy42IDgtOHYtNDhjMC00LjQtMy42LTgtOC04SDMyOGMtNC40IDAtOCAzLjYtOCA4djQ4YzAgNC40IDMuNiA4IDggOHoiIC8+PHBhdGggZD0iTTg4MCAxMTJIMTQ0Yy0xNy43IDAtMzIgMTQuMy0zMiAzMnY3MzZjMCAxNy43IDE0LjMgMzIgMzIgMzJoNzM2YzE3LjcgMCAzMi0xNC4zIDMyLTMyVjE0NGMwLTE3LjctMTQuMy0zMi0zMi0zMnptLTQwIDcyOEgxODRWMTg0aDY1NnY2NTZ6IiAvPjwvc3ZnPg==) */
/**![paper-clip](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjY0IDY0IDg5NiA4OTYiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTc3OS4zIDE5Ni42Yy05NC4yLTk0LjItMjQ3LjYtOTQuMi0zNDEuNyAwbC0yNjEgMjYwLjhjLTEuNyAxLjctMi42IDQtMi42IDYuNHMuOSA0LjcgMi42IDYuNGwzNi45IDM2LjlhOSA5IDAgMDAxMi43IDBsMjYxLTI2MC44YzMyLjQtMzIuNCA3NS41LTUwLjIgMTIxLjMtNTAuMnM4OC45IDE3LjggMTIxLjIgNTAuMmMzMi40IDMyLjQgNTAuMiA3NS41IDUwLjIgMTIxLjIgMCA0NS44LTE3LjggODguOC01MC4yIDEyMS4ybC0yNjYgMjY1LjktNDMuMSA0My4xYy00MC4zIDQwLjMtMTA1LjggNDAuMy0xNDYuMSAwLTE5LjUtMTkuNS0zMC4yLTQ1LjQtMzAuMi03M3MxMC43LTUzLjUgMzAuMi03M2wyNjMuOS0yNjMuOGM2LjctNi42IDE1LjUtMTAuMyAyNC45LTEwLjNoLjFjOS40IDAgMTguMSAzLjcgMjQuNyAxMC4zIDYuNyA2LjcgMTAuMyAxNS41IDEwLjMgMjQuOSAwIDkuMy0zLjcgMTguMS0xMC4zIDI0LjdMMzcyLjQgNjUzYy0xLjcgMS43LTIuNiA0LTIuNiA2LjRzLjkgNC43IDIuNiA2LjRsMzYuOSAzNi45YTkgOSAwIDAwMTIuNyAwbDIxNS42LTIxNS42YzE5LjktMTkuOSAzMC44LTQ2LjMgMzAuOC03NC40cy0xMS01NC42LTMwLjgtNzQuNGMtNDEuMS00MS4xLTEwNy45LTQxLTE0OSAwTDQ2MyAzNjQgMjI0LjggNjAyLjFBMTcyLjIyIDE3Mi4yMiAwIDAwMTc0IDcyNC44YzAgNDYuMyAxOC4xIDg5LjggNTAuOCAxMjIuNSAzMy45IDMzLjggNzguMyA1MC43IDEyMi43IDUwLjcgNDQuNCAwIDg4LjgtMTYuOSAxMjIuNi01MC43bDMwOS4yLTMwOUM4MjQuOCA0OTIuNyA4NTAgNDMyIDg1MCAzNjcuNWMuMS02NC42LTI1LjEtMTI1LjMtNzAuNy0xNzAuOXoiIC8+PC9zdmc+) */
/**![picture](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjY0IDY0IDg5NiA4OTYiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTkyOCAxNjBIOTZjLTE3LjcgMC0zMiAxNC4zLTMyIDMydjY0MGMwIDE3LjcgMTQuMyAzMiAzMiAzMmg4MzJjMTcuNyAwIDMyLTE0LjMgMzItMzJWMTkyYzAtMTcuNy0xNC4zLTMyLTMyLTMyem0tNDAgNjMySDEzNnYtMzkuOWwxMzguNS0xNjQuMyAxNTAuMSAxNzhMNjU4LjEgNDg5IDg4OCA3NjEuNlY3OTJ6bTAtMTI5LjhMNjY0LjIgMzk2LjhjLTMuMi0zLjgtOS0zLjgtMTIuMiAwTDQyNC42IDY2Ni40bC0xNDQtMTcwLjdjLTMuMi0zLjgtOS0zLjgtMTIuMiAwTDEzNiA2NTIuN1YyMzJoNzUydjQzMC4yeiIgZmlsbD0iIzE2NzdmZiIgLz48cGF0aCBkPSJNNDI0LjYgNzY1LjhsLTE1MC4xLTE3OEwxMzYgNzUyLjFWNzkyaDc1MnYtMzAuNEw2NTguMSA0ODl6IiBmaWxsPSIjZTZmNGZmIiAvPjxwYXRoIGQ9Ik0xMzYgNjUyLjdsMTMyLjQtMTU3YzMuMi0zLjggOS0zLjggMTIuMiAwbDE0NCAxNzAuN0w2NTIgMzk2LjhjMy4yLTMuOCA5LTMuOCAxMi4yIDBMODg4IDY2Mi4yVjIzMkgxMzZ2NDIwLjd6TTMwNCAyODBhODggODggMCAxMTAgMTc2IDg4IDg4IDAgMDEwLTE3NnoiIGZpbGw9IiNlNmY0ZmYiIC8+PHBhdGggZD0iTTI3NiAzNjhhMjggMjggMCAxMDU2IDAgMjggMjggMCAxMC01NiAweiIgZmlsbD0iI2U2ZjRmZiIgLz48cGF0aCBkPSJNMzA0IDQ1NmE4OCA4OCAwIDEwMC0xNzYgODggODggMCAwMDAgMTc2em0wLTExNmMxNS41IDAgMjggMTIuNSAyOCAyOHMtMTIuNSAyOC0yOCAyOC0yOC0xMi41LTI4LTI4IDEyLjUtMjggMjgtMjh6IiBmaWxsPSIjMTY3N2ZmIiAvPjwvc3ZnPg==) */
/**![plus-square](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjY0IDY0IDg5NiA4OTYiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTMyOCA1NDRoMTUydjE1MmMwIDQuNCAzLjYgOCA4IDhoNDhjNC40IDAgOC0zLjYgOC04VjU0NGgxNTJjNC40IDAgOC0zLjYgOC04di00OGMwLTQuNC0zLjYtOC04LThINTQ0VjMyOGMwLTQuNC0zLjYtOC04LThoLTQ4Yy00LjQgMC04IDMuNi04IDh2MTUySDMyOGMtNC40IDAtOCAzLjYtOCA4djQ4YzAgNC40IDMuNiA4IDggOHoiIC8+PHBhdGggZD0iTTg4MCAxMTJIMTQ0Yy0xNy43IDAtMzIgMTQuMy0zMiAzMnY3MzZjMCAxNy43IDE0LjMgMzIgMzIgMzJoNzM2YzE3LjcgMCAzMi0xNC4zIDMyLTMyVjE0NGMwLTE3LjctMTQuMy0zMi0zMi0zMnptLTQwIDcyOEgxODRWMTg0aDY1NnY2NTZ6IiAvPjwvc3ZnPg==) */
/**![rotate-right](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjY0IDY0IDg5NiA4OTYiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PHN0eWxlIC8+PC9kZWZzPjxwYXRoIGQ9Ik00ODAuNSAyNTEuMmMxMy0xLjYgMjUuOS0yLjQgMzguOC0yLjV2NjMuOWMwIDYuNSA3LjUgMTAuMSAxMi42IDYuMUw2NjAgMjE3LjZjNC0zLjIgNC05LjIgMC0xMi4zbC0xMjgtMTAxYy01LjEtNC0xMi42LS40LTEyLjYgNi4xbC0uMiA2NGMtMTE4LjYuNS0yMzUuOCA1My40LTMxNC42IDE1NC4yQTM5OS43NSAzOTkuNzUgMCAwMDEyMy41IDYzMWg3NC45Yy0uOS01LjMtMS43LTEwLjctMi40LTE2LjEtNS4xLTQyLjEtMi4xLTg0LjEgOC45LTEyNC44IDExLjQtNDIuMiAzMS04MS4xIDU4LjEtMTE1LjggMjcuMi0zNC43IDYwLjMtNjMuMiA5OC40LTg0LjMgMzctMjAuNiA3Ni45LTMzLjYgMTE5LjEtMzguOHoiIC8+PHBhdGggZD0iTTg4MCA0MThIMzUyYy0xNy43IDAtMzIgMTQuMy0zMiAzMnY0MTRjMCAxNy43IDE0LjMgMzIgMzIgMzJoNTI4YzE3LjcgMCAzMi0xNC4zIDMyLTMyVjQ1MGMwLTE3LjctMTQuMy0zMi0zMi0zMnptLTQ0IDQwMkgzOTZWNDk0aDQ0MHYzMjZ6IiAvPjwvc3ZnPg==) */
/**![setting](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjY0IDY0IDg5NiA4OTYiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTkyNC44IDYyNS43bC02NS41LTU2YzMuMS0xOSA0LjctMzguNCA0LjctNTcuOHMtMS42LTM4LjgtNC43LTU3LjhsNjUuNS01NmEzMi4wMyAzMi4wMyAwIDAwOS4zLTM1LjJsLS45LTIuNmE0NDMuNzQgNDQzLjc0IDAgMDAtNzkuNy0xMzcuOWwtMS44LTIuMWEzMi4xMiAzMi4xMiAwIDAwLTM1LjEtOS41bC04MS4zIDI4LjljLTMwLTI0LjYtNjMuNS00NC05OS43LTU3LjZsLTE1LjctODVhMzIuMDUgMzIuMDUgMCAwMC0yNS44LTI1LjdsLTIuNy0uNWMtNTIuMS05LjQtMTA2LjktOS40LTE1OSAwbC0yLjcuNWEzMi4wNSAzMi4wNSAwIDAwLTI1LjggMjUuN2wtMTUuOCA4NS40YTM1MS44NiAzNTEuODYgMCAwMC05OSA1Ny40bC04MS45LTI5LjFhMzIgMzIgMCAwMC0zNS4xIDkuNWwtMS44IDIuMWE0NDYuMDIgNDQ2LjAyIDAgMDAtNzkuNyAxMzcuOWwtLjkgMi42Yy00LjUgMTIuNS0uOCAyNi41IDkuMyAzNS4ybDY2LjMgNTYuNmMtMy4xIDE4LjgtNC42IDM4LTQuNiA1Ny4xIDAgMTkuMiAxLjUgMzguNCA0LjYgNTcuMUw5OSA2MjUuNWEzMi4wMyAzMi4wMyAwIDAwLTkuMyAzNS4ybC45IDIuNmMxOC4xIDUwLjQgNDQuOSA5Ni45IDc5LjcgMTM3LjlsMS44IDIuMWEzMi4xMiAzMi4xMiAwIDAwMzUuMSA5LjVsODEuOS0yOS4xYzI5LjggMjQuNSA2My4xIDQzLjkgOTkgNTcuNGwxNS44IDg1LjRhMzIuMDUgMzIuMDUgMCAwMDI1LjggMjUuN2wyLjcuNWE0NDkuNCA0NDkuNCAwIDAwMTU5IDBsMi43LS41YTMyLjA1IDMyLjA1IDAgMDAyNS44LTI1LjdsMTUuNy04NWEzNTAgMzUwIDAgMDA5OS43LTU3LjZsODEuMyAyOC45YTMyIDMyIDAgMDAzNS4xLTkuNWwxLjgtMi4xYzM0LjgtNDEuMSA2MS42LTg3LjUgNzkuNy0xMzcuOWwuOS0yLjZjNC41LTEyLjMuOC0yNi4zLTkuMy0zNXpNNzg4LjMgNDY1LjljMi41IDE1LjEgMy44IDMwLjYgMy44IDQ2LjFzLTEuMyAzMS0zLjggNDYuMWwtNi42IDQwLjEgNzQuNyA2My45YTM3MC4wMyAzNzAuMDMgMCAwMS00Mi42IDczLjZMNzIxIDcwMi44bC0zMS40IDI1LjhjLTIzLjkgMTkuNi01MC41IDM1LTc5LjMgNDUuOGwtMzguMSAxNC4zLTE3LjkgOTdhMzc3LjUgMzc3LjUgMCAwMS04NSAwbC0xNy45LTk3LjItMzcuOC0xNC41Yy0yOC41LTEwLjgtNTUtMjYuMi03OC43LTQ1LjdsLTMxLjQtMjUuOS05My40IDMzLjJjLTE3LTIyLjktMzEuMi00Ny42LTQyLjYtNzMuNmw3NS41LTY0LjUtNi41LTQwYy0yLjQtMTQuOS0zLjctMzAuMy0zLjctNDUuNSAwLTE1LjMgMS4yLTMwLjYgMy43LTQ1LjVsNi41LTQwLTc1LjUtNjQuNWMxMS4zLTI2LjEgMjUuNi01MC43IDQyLjYtNzMuNmw5My40IDMzLjIgMzEuNC0yNS45YzIzLjctMTkuNSA1MC4yLTM0LjkgNzguNy00NS43bDM3LjktMTQuMyAxNy45LTk3LjJjMjguMS0zLjIgNTYuOC0zLjIgODUgMGwxNy45IDk3IDM4LjEgMTQuM2MyOC43IDEwLjggNTUuNCAyNi4yIDc5LjMgNDUuOGwzMS40IDI1LjggOTIuOC0zMi45YzE3IDIyLjkgMzEuMiA0Ny42IDQyLjYgNzMuNkw3ODEuOCA0MjZsNi41IDM5Ljl6TTUxMiAzMjZjLTk3LjIgMC0xNzYgNzguOC0xNzYgMTc2czc4LjggMTc2IDE3NiAxNzYgMTc2LTc4LjggMTc2LTE3Ni03OC44LTE3Ni0xNzYtMTc2em03OS4yIDI1NS4yQTExMS42IDExMS42IDAgMDE1MTIgNjE0Yy0yOS45IDAtNTgtMTEuNy03OS4yLTMyLjhBMTExLjYgMTExLjYgMCAwMTQwMCA1MDJjMC0yOS45IDExLjctNTggMzIuOC03OS4yQzQ1NCA0MDEuNiA0ODIuMSAzOTAgNTEyIDM5MGMyOS45IDAgNTggMTEuNiA3OS4yIDMyLjhBMTExLjYgMTExLjYgMCAwMTYyNCA1MDJjMCAyOS45LTExLjcgNTgtMzIuOCA3OS4yeiIgLz48L3N2Zz4=) */
/**![star](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjY0IDY0IDg5NiA4OTYiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTkwOC4xIDM1My4xbC0yNTMuOS0zNi45TDU0MC43IDg2LjFjLTMuMS02LjMtOC4yLTExLjQtMTQuNS0xNC41LTE1LjgtNy44LTM1LTEuMy00Mi45IDE0LjVMMzY5LjggMzE2LjJsLTI1My45IDM2LjljLTcgMS0xMy40IDQuMy0xOC4zIDkuM2EzMi4wNSAzMi4wNSAwIDAwLjYgNDUuM2wxODMuNyAxNzkuMS00My40IDI1Mi45YTMxLjk1IDMxLjk1IDAgMDA0Ni40IDMzLjdMNTEyIDc1NGwyMjcuMSAxMTkuNGM2LjIgMy4zIDEzLjQgNC40IDIwLjMgMy4yIDE3LjQtMyAyOS4xLTE5LjUgMjYuMS0zNi45bC00My40LTI1Mi45IDE4My43LTE3OS4xYzUtNC45IDguMy0xMS4zIDkuMy0xOC4zIDIuNy0xNy41LTkuNS0zMy43LTI3LTM2LjN6IiAvPjwvc3ZnPg==) */
/**![swap](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjY0IDY0IDg5NiA4OTYiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTg0Ny45IDU5MkgxNTJjLTQuNCAwLTggMy42LTggOHY2MGMwIDQuNCAzLjYgOCA4IDhoNjA1LjJMNjEyLjkgODUxYy00LjEgNS4yLS40IDEzIDYuMyAxM2g3Mi41YzQuOSAwIDkuNS0yLjIgMTIuNi02LjFsMTY4LjgtMjE0LjFjMTYuNS0yMSAxLjYtNTEuOC0yNS4yLTUxLjh6TTg3MiAzNTZIMjY2LjhsMTQ0LjMtMTgzYzQuMS01LjIuNC0xMy02LjMtMTNoLTcyLjVjLTQuOSAwLTkuNSAyLjItMTIuNiA2LjFMMTUwLjkgMzgwLjJjLTE2LjUgMjEtMS42IDUxLjggMjUuMSA1MS44aDY5NmM0LjQgMCA4LTMuNiA4LTh2LTYwYzAtNC40LTMuNi04LTgtOHoiIC8+PC9zdmc+) */
/**![vertical-align-bottom](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjY0IDY0IDg5NiA4OTYiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTg1OS45IDc4MEgxNjQuMWMtNC41IDAtOC4xIDMuNi04LjEgOHY2MGMwIDQuNCAzLjYgOCA4LjEgOGg2OTUuOGM0LjUgMCA4LjEtMy42IDguMS04di02MGMwLTQuNC0zLjYtOC04LjEtOHpNNTA1LjcgNjY5YTggOCAwIDAwMTIuNiAwbDExMi0xNDEuN2M0LjEtNS4yLjQtMTIuOS02LjMtMTIuOWgtNzQuMVYxNzZjMC00LjQtMy42LTgtOC04aC02MGMtNC40IDAtOCAzLjYtOCA4djMzOC4zSDQwMGMtNi43IDAtMTAuNCA3LjctNi4zIDEyLjlsMTEyIDE0MS44eiIgLz48L3N2Zz4=) */
/**![vertical-align-middle](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjY0IDY0IDg5NiA4OTYiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTg1OS45IDQ3NEgxNjQuMWMtNC41IDAtOC4xIDMuNi04LjEgOHY2MGMwIDQuNCAzLjYgOCA4LjEgOGg2OTUuOGM0LjUgMCA4LjEtMy42IDguMS04di02MGMwLTQuNC0zLjYtOC04LjEtOHptLTM1My42LTc0LjdjMi45IDMuNyA4LjUgMy43IDExLjMgMGwxMDAuOC0xMjcuNWMzLjctNC43LjQtMTEuNy01LjctMTEuN0g1NTBWMTA0YzAtNC40LTMuNi04LTgtOGgtNjBjLTQuNCAwLTggMy42LTggOHYxNTZoLTYyLjhjLTYgMC05LjQgNy01LjcgMTEuN2wxMDAuOCAxMjcuNnptMTEuNCAyMjUuNGE3LjE0IDcuMTQgMCAwMC0xMS4zIDBMNDA1LjYgNzUyLjNhNy4yMyA3LjIzIDAgMDA1LjcgMTEuN0g0NzR2MTU2YzAgNC40IDMuNiA4IDggOGg2MGM0LjQgMCA4LTMuNiA4LThWNzY0aDYyLjhjNiAwIDkuNC03IDUuNy0xMS43TDUxNy43IDYyNC43eiIgLz48L3N2Zz4=) */
/**![vertical-align-top](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjY0IDY0IDg5NiA4OTYiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTg1OS45IDE2OEgxNjQuMWMtNC41IDAtOC4xIDMuNi04LjEgOHY2MGMwIDQuNCAzLjYgOCA4LjEgOGg2OTUuOGM0LjUgMCA4LjEtMy42IDguMS04di02MGMwLTQuNC0zLjYtOC04LjEtOHpNNTE4LjMgMzU1YTggOCAwIDAwLTEyLjYgMGwtMTEyIDE0MS43YTcuOTggNy45OCAwIDAwNi4zIDEyLjloNzMuOVY4NDhjMCA0LjQgMy42IDggOCA4aDYwYzQuNCAwIDgtMy42IDgtOFY1MDkuN0g2MjRjNi43IDAgMTAuNC03LjcgNi4zLTEyLjlMNTE4LjMgMzU1eiIgLz48L3N2Zz4=) */
/**![zoom-in](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjY0IDY0IDg5NiA4OTYiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTYzNyA0NDNINTE5VjMwOWMwLTQuNC0zLjYtOC04LThoLTYwYy00LjQgMC04IDMuNi04IDh2MTM0SDMyNWMtNC40IDAtOCAzLjYtOCA4djYwYzAgNC40IDMuNiA4IDggOGgxMTh2MTM0YzAgNC40IDMuNiA4IDggOGg2MGM0LjQgMCA4LTMuNiA4LThWNTE5aDExOGM0LjQgMCA4LTMuNiA4LTh2LTYwYzAtNC40LTMuNi04LTgtOHptMjg0IDQyNEw3NzUgNzIxYzEyMi4xLTE0OC45IDExMy42LTM2OS41LTI2LTUwOS0xNDgtMTQ4LjEtMzg4LjQtMTQ4LjEtNTM3IDAtMTQ4LjEgMTQ4LjYtMTQ4LjEgMzg5IDAgNTM3IDEzOS41IDEzOS42IDM2MC4xIDE0OC4xIDUwOSAyNmwxNDYgMTQ2YzMuMiAyLjggOC4zIDIuOCAxMSAwbDQzLTQzYzIuOC0yLjcgMi44LTcuOCAwLTExek02OTYgNjk2Yy0xMTguOCAxMTguNy0zMTEuMiAxMTguNy00MzAgMC0xMTguNy0xMTguOC0xMTguNy0zMTEuMiAwLTQzMCAxMTguOC0xMTguNyAzMTEuMi0xMTguNyA0MzAgMCAxMTguNyAxMTguOCAxMTguNyAzMTEuMiAwIDQzMHoiIC8+PC9zdmc+) */
/**![zoom-out](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjY0IDY0IDg5NiA4OTYiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTYzNyA0NDNIMzI1Yy00LjQgMC04IDMuNi04IDh2NjBjMCA0LjQgMy42IDggOCA4aDMxMmM0LjQgMCA4LTMuNiA4LTh2LTYwYzAtNC40LTMuNi04LTgtOHptMjg0IDQyNEw3NzUgNzIxYzEyMi4xLTE0OC45IDExMy42LTM2OS41LTI2LTUwOS0xNDgtMTQ4LjEtMzg4LjQtMTQ4LjEtNTM3IDAtMTQ4LjEgMTQ4LjYtMTQ4LjEgMzg5IDAgNTM3IDEzOS41IDEzOS42IDM2MC4xIDE0OC4xIDUwOSAyNmwxNDYgMTQ2YzMuMiAyLjggOC4zIDIuOCAxMSAwbDQzLTQzYzIuOC0yLjcgMi44LTcuOCAwLTExek02OTYgNjk2Yy0xMTguOCAxMTguNy0zMTEuMiAxMTguNy00MzAgMC0xMTguNy0xMTguOC0xMTguNy0zMTEuMiAwLTQzMCAxMTguOC0xMTguNyAzMTEuMi0xMTguNyA0MzAgMCAxMTguNyAxMTguOCAxMTguNyAzMTEuMiAwIDQzMHoiIC8+PC9zdmc+) */

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
/*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/babel/babel/blob/main/packages/babel-helpers/LICENSE */

View File

@ -0,0 +1,51 @@
{
"name": "micro-app",
"version": "2.0.0",
"description": "建教帮微应用模板",
"author": "JJB",
"license": "MIT",
"main": "index.js",
"scripts": {
"serve": "node node_modules/@cqsjjb/scripts/webpack.dev.server.js",
"build": "node node_modules/@cqsjjb/scripts/webpack.build.js",
"push": "zy-gbs-cmd push java production",
"clean-cache": "rimraf node_modules/.cache/webpack",
"serve:development": "cross-env NODE_ENV=development npm run serve",
"serve:production": "cross-env NODE_ENV=production npm run serve",
"build:development": "cross-env NODE_ENV=development npm run build",
"build:production": "cross-env NODE_ENV=production npm run build",
"code-optimization": "node node_modules/@cqsjjb/scripts/code-optimization.js",
"lint": "eslint --ext .js,.jsx,.tsx --fix src"
},
"dependencies": {
"@ahooksjs/use-url-state": "^3.5.1",
"@ant-design/icons": "^5.6.1",
"@ant-design/pro-components": "^2.8.10",
"@cqsjjb/jjb-common-decorator": "latest",
"@cqsjjb/jjb-common-lib": "latest",
"@cqsjjb/jjb-dva-runtime": "latest",
"@cqsjjb/jjb-react-admin-component": "latest",
"@xyflow/react": "^12.10.1",
"ahooks": "^3.9.5",
"antd": "^5.27.6",
"dayjs": "^1.11.7",
"lodash-es": "^4.17.21",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-to-print": "^3.3.0",
"zy-react-data": "^1.0.2",
"zy-react-library": "^1.4.2"
},
"devDependencies": {
"@antfu/eslint-config": "^5.4.1",
"@babel/plugin-proposal-decorators": "^7.19.3",
"@cqsjjb/scripts": "2.0.0-alpha-1",
"@eslint-react/eslint-plugin": "^2.2.2",
"cross-env": "^7.0.3",
"eslint": "^9.37.0",
"eslint-plugin-format": "^1.0.2",
"eslint-plugin-react-hooks": "^7.0.0",
"eslint-plugin-react-refresh": "^0.4.23",
"typescript": "^5.9.3"
}
}

View File

@ -0,0 +1,58 @@
高处作业安全许可证
证书编号:{{checkNo}}
实施单位
{{implementationUnit}}
作业地点
{{workLocation}}
申请时间
{{applyYear}}年 {{applyMonth}}月 {{applyDay}}日 {{applyHour}}时 {{applyMinute}}分
作业级别
{{@level1}} 1级 {{@level2}} 2级{{@level3}} 3级 {{@level4}} 4级
项目批准人
{{projectApprover}}
方案编制人
{{planCompiler}}
方案批准人
{{planApprover}}
工作负责人
{{workLeader}}
高处作业人
{{highWorkPerson}}
监护人
{{guardian}}
工作内容{{workContent}}
预计作业时间: {{startYear}}年 {{startMonth}}月 {{startDay}}日 {{startHour}}时 {{startMinute}}分 至 {{endYear}}年 {{endMonth}}月 {{endDay}}日 {{endHour}}时 {{endMinute}}分
风险辨识及管控措施落实情况
确认人
1{{measureContent1}}
{{@measureSign1}}
2{{measureContent2}}
{{@measureSign2}}
3{{measureContent3}}
{{@measureSign3}}
4{{measureContent4}}
{{@measureSign4}}
5{{measureContent5}}
{{@measureSign5}}
6{{measureContent6}}
{{@measureSign6}}
7{{measureContent7}}
{{@measureSign7}}
8{{measureContent8}}
{{@measureSign8}}
9{{measureContent9}}
{{@measureSign9}}
10{{measureContent10}}
{{@measureSign10}}
安全交底人
{{@safetyDiscloserSign}}
被交底人
{{@safetyDisclosureRecipientSigns}}
实施单位意见
签名:{{@implementationSign}} {{implementationYear}}年{{implementationMonth}}月{{implementationDay}}日{{implementationHour}}时{{implementationMinute}}分
发包单位发包部门意见
签名:{{@contractSign}} {{contractYear}}年{{contractMonth}}月{{contractDay}}日{{contractHour}}时{{contractMinute}}分
发包单位安监部门意见
签名:{{@safetySupervisionSign}} {{safetySupervisionYear}}年{{safetySupervisionMonth}}月{{safetySupervisionDay}}日{{safetySupervisionHour}}时{{safetySupervisionMinute}}分
属地单位意见
签名:{{@territorialSign}} {{territorialYear}}年{{territorialMonth}}月{{territorialDay}}日{{territorialHour}}时{{territorialMinute}}分

View File

@ -8,6 +8,7 @@ import com.zcloud.eightwork.dto.EightworkInfoPageQry;
import com.zcloud.eightwork.dto.EightworkInfoUpdateCmd;
import com.zcloud.eightwork.dto.EightworkInfoWithdrawCmd;
import com.zcloud.eightwork.dto.ForceTerminateCmd;
import com.zcloud.eightwork.dto.HighWorkPermitExportQry;
import com.zcloud.eightwork.dto.ScreenDangerWorkDataStatisticsQry;
import com.zcloud.eightwork.dto.ScreenDepartmentStatisticsQry;
import com.zcloud.eightwork.dto.ScreenStatisticsQry;
@ -184,5 +185,21 @@ public class EightworkInfoController {
return MultiResponse.of(eightworkInfoService.screenWorkPieStatistics(qry));
}
/**
*
*
* <p>GET 使 HighWorkPermitExportQry ID PDF
* PDF </p>
*
* @param qry
* @param response
*/
@ApiOperation("高处作业安全许可证导出单张PDF多张压缩包")
@GetMapping("/exportHighWorkPermit")
public void exportHighWorkPermit(@Validated HighWorkPermitExportQry qry,
HttpServletResponse response) {
eightworkInfoService.exportHighWorkPermit(qry, response);
}
}

View File

@ -120,7 +120,7 @@ public class TaskLogAddExe {
log.info("撤回作业票(不生成新票号): workId={}, checkNo={}", existingInfo.getWorkId(), checkNo);
} else {
// 不是撤回作业票 , 生成新作业票
checkNo = generateFormalCheckNo(cmd.getWorkType());
checkNo = generateFormalCheckNo(cmd.getWorkType(), cmd.getCorpinfoId());
existingInfo.setCheckNo(checkNo);
log.info("(生成新票号): workId={}, checkNo={}", existingInfo.getWorkId(), checkNo);
}
@ -204,7 +204,11 @@ public class TaskLogAddExe {
/**
*
*/
private String generateFormalCheckNo(String workType) {
private String generateFormalCheckNo(String workType, Long corpinfoId) {
String corpName = eightworkInfoRepository.getCorpNameById(corpinfoId);
if (StringUtils.isBlank(corpName)) {
throw new BizException("未查询到企业名称,无法生成作业票号");
}
String workTypeCode = WorkCodeEnum.getCodeByWorkType(workType);
String date = DateUtil.getDays();
@ -220,8 +224,8 @@ public class TaskLogAddExe {
log.info("生成正式票号: workType={}, date={}, seq={}", workType, date, seq);
// 正式票号: QG + 作业类型代码 + 日期 + 4位序号
return "QG" + workTypeCode + date + String.format("%04d", seq);
// 正式票号: 企业名称 + 作业类型代码 + 日期 + 4位序号
return corpName + workTypeCode + date + String.format("%04d", seq);
}
/**
@ -346,7 +350,7 @@ public class TaskLogAddExe {
*/
private String saveWork(TaskLogAddCmd cmd) {
// 生成正式票号
String checkNo = generateFormalCheckNo(cmd.getWorkType());
String checkNo = generateFormalCheckNo(cmd.getWorkType(), cmd.getCorpinfoId());
EightworkInfoDO eightworkInfo = new EightworkInfoDO(
Tools.get32UUID(),

View File

@ -0,0 +1,888 @@
package com.zcloud.eightwork.command.query;
import com.alibaba.cola.exception.BizException;
import com.aspose.words.FolderFontSource;
import com.aspose.words.FontSettings;
import com.aspose.words.FontSourceBase;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.deepoove.poi.data.PictureRenderData;
import com.deepoove.poi.data.PictureType;
import com.deepoove.poi.data.Pictures;
import com.zcloud.eightwork.domain.model.enums.WorkCodeEnum;
import com.zcloud.eightwork.dto.HighWorkPermitExportQry;
import com.zcloud.eightwork.persistence.dataobject.EightworkInfoDO;
import com.zcloud.eightwork.persistence.dataobject.MeasuresLogsArchiveDO;
import com.zcloud.eightwork.persistence.dataobject.MeasuresLogsDO;
import com.zcloud.eightwork.persistence.dataobject.TaskLogDO;
import com.zcloud.eightwork.persistence.repository.EightworkInfoRepository;
import com.zcloud.eightwork.persistence.repository.MeasuresLogsArchiveRepository;
import com.zcloud.eightwork.persistence.repository.MeasuresLogsRepository;
import com.zcloud.eightwork.persistence.repository.TaskLogRepository;
import com.zcloud.gbscommon.utils.Tools;
import com.zcloud.gbscommon.utils.WordToPdfUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import javax.servlet.http.HttpServletResponse;
import java.awt.BasicStroke;
import java.awt.Color;
import javax.imageio.ImageIO;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URLEncoder;
import java.net.URL;
import java.net.URLConnection;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Base64;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
/**
*
*/
@Slf4j
@Component
@RequiredArgsConstructor
public class HighWorkPermitExportExe {
private static final String TEMPLATE_PATH = "templates/template/high_work_permit_sign.docx";
private static final String FONT_RESOURCE_PATH = "fonts/simsun.ttc";
private static final String FONT_FILE_NAME = "simsun.ttc";
private static final Object FONT_REGISTER_LOCK = new Object();
private static final DateTimeFormatter FILE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
private static final int MEASURE_SIGN_WIDTH = 70;
private static final int MEASURE_SIGN_HEIGHT = 18;
private static final int OPINION_SIGN_WIDTH = 76;
private static final int OPINION_SIGN_HEIGHT = 18;
private static final int DISCLOSER_SIGN_WIDTH = 72;
private static final int RECIPIENT_SIGN_WIDTH = 220;
private static final int DISCLOSURE_SIGN_HEIGHT = 20;
private static final long SAFETY_DISCLOSER_STEP_ID = 18L;
private static final long SAFETY_DISCLOSURE_RECIPIENT_STEP_ID = 19L;
private static final long IMPLEMENTATION_OPINION_STEP_ID = 41L;
private static final long CONTRACT_OPINION_STEP_ID = 42L;
private static final long SAFETY_SUPERVISION_OPINION_STEP_ID = 43L;
private static final long TERRITORIAL_OPINION_STEP_ID = 44L;
private static final int WORK_LEVEL_MARK_SIZE = 10;
private static final int SIGNATURE_RENDER_SCALE = 8;
private static volatile boolean fontRegistered;
private final EightworkInfoRepository eightworkInfoRepository;
private final MeasuresLogsRepository measuresLogsRepository;
private final MeasuresLogsArchiveRepository measuresLogsArchiveRepository;
private final TaskLogRepository taskLogRepository;
@Value("${file.url:}")
private String fileUrl;
public void execute(HighWorkPermitExportQry qry, HttpServletResponse response) {
try {
List<EightworkInfoDO> workList = getWorkList(qry.getIds());
registerPdfFont();
Map<String, byte[]> pdfFiles = new LinkedHashMap<>();
Map<String, Integer> fileNameCounts = new HashMap<>();
for (EightworkInfoDO work : workList) {
byte[] wordBytes = renderWord(work);
byte[] pdfBytes = WordToPdfUtil.convertWordBytesToPdfBytes(wordBytes);
String fileName = buildPdfFileName(work, fileNameCounts);
pdfFiles.put(fileName, pdfBytes);
}
if (pdfFiles.size() == 1) {
Map.Entry<String, byte[]> file = pdfFiles.entrySet().iterator().next();
writeResponse(response, file.getValue(), "application/pdf", file.getKey());
return;
}
byte[] zipBytes = buildZip(pdfFiles);
String zipName = "高处作业安全许可证_" + LocalDateTime.now().format(FILE_TIME_FORMATTER) + ".zip";
writeResponse(response, zipBytes, "application/zip", zipName);
} catch (BizException e) {
throw e;
} catch (Exception e) {
log.error("高处作业安全许可证导出失败", e);
throw new BizException("高处作业安全许可证导出失败");
}
}
private void registerPdfFont() throws Exception {
if (fontRegistered) {
return;
}
synchronized (FONT_REGISTER_LOCK) {
if (fontRegistered) {
return;
}
Path fontDirectory = Paths.get(System.getProperty("java.io.tmpdir"), "eightwork-pdf-fonts");
Path fontFile = fontDirectory.resolve(FONT_FILE_NAME);
Files.createDirectories(fontDirectory);
try (InputStream inputStream = HighWorkPermitExportExe.class.getClassLoader()
.getResourceAsStream(FONT_RESOURCE_PATH)) {
if (inputStream == null) {
throw new BizException("高处作业许可证中文字体资源不存在");
}
Files.copy(inputStream, fontFile, StandardCopyOption.REPLACE_EXISTING);
}
FontSourceBase[] currentSources = FontSettings.getFontsSources();
FontSourceBase[] fontSources = new FontSourceBase[currentSources.length + 1];
fontSources[0] = new FolderFontSource(fontDirectory.toString(), false, 100);
System.arraycopy(currentSources, 0, fontSources, 1, currentSources.length);
FontSettings.setFontsSources(fontSources);
FontSettings.addFontSubstitutes("宋体", "SimSun");
FontSettings.setDefaultFontName("SimSun");
fontRegistered = true;
}
}
private List<EightworkInfoDO> getWorkList(List<Long> requestIds) {
if (CollectionUtils.isEmpty(requestIds) || requestIds.contains(null)) {
throw new BizException("作业票主表ID不能为空");
}
List<Long> ids = new ArrayList<>(new LinkedHashSet<>(requestIds));
List<EightworkInfoDO> records = eightworkInfoRepository.listByIds(ids);
Map<Long, EightworkInfoDO> recordMap = new HashMap<>();
for (EightworkInfoDO record : records) {
recordMap.put(record.getId(), record);
}
List<EightworkInfoDO> result = new ArrayList<>();
for (Long id : ids) {
EightworkInfoDO record = recordMap.get(id);
if (record == null) {
throw new BizException("未查询到作业票ID" + id);
}
if (!WorkCodeEnum.HIGH_WORK.getWorkType().equals(record.getWorkType())) {
throw new BizException("仅支持导出高处作业票ID" + id);
}
result.add(record);
}
return result;
}
private byte[] renderWord(EightworkInfoDO work) throws Exception {
HighWorkPermitInfo info = parseInfo(work);
List<TaskLogDO> taskLogs = taskLogRepository.listAllByWorkId(work.getWorkId());
Map<String, Object> data = new HashMap<>();
data.put("checkNo", value(work.getCheckNo()));
data.put("implementationUnit", firstNonBlank(info.getImplementationUnit(), info.getImplementationUnitName(),
info.getWorkUnit(), info.getWorkUnitName(), info.getConstructionUnit()));
if (StringUtils.isBlank((String) data.get("implementationUnit"))) {
data.put("implementationUnit", value(eightworkInfoRepository.getCorpNameById(work.getCorpinfoId())));
}
data.put("workLocation", firstNonBlank(info.getWorkLocation(), info.getWorkPlace(), info.getOperationLocation(),
info.getWorkAddress(), info.getWorkSite(), info.getWorkPosition()));
data.put("workContent", firstNonBlank(info.getWorkContent(), info.getOperationContent(), info.getWorkDescription()));
String applyTime = firstNonBlank(info.getApplyTime(), info.getApplicationTime());
if (StringUtils.isBlank(applyTime) && work.getCreateTime() != null) {
applyTime = work.getCreateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
}
putDateParts(data, "apply", applyTime);
putDateParts(data, "start", firstNonBlank(info.getWorkStartTime(), info.getStartTime()));
putDateParts(data, "end", firstNonBlank(info.getWorkEndTime(), info.getEndTime()));
putWorkLevel(data, work.getCheckNo(), work.getWorkLevel(), info.getWorkLevel(), info.getWorkLevelName(),
info.getOperationLevel(), info.getHighWorkLevel());
data.put("projectApprover", firstNonBlank(
firstNonBlank(info.getProjectApproverName(), info.getProjectApprovalName()),
findStepActor(info, "项目批准")));
data.put("planCompiler", firstNonBlank(
firstNonBlank(info.getPlanPreparerName(), info.getPlanCompilerName(), info.getSchemeCompilerName()),
findStepActor(info, "方案编制")));
data.put("planApprover", firstNonBlank(
firstNonBlank(info.getPlanApproverName(), info.getSchemeApproverName()),
findStepActor(info, "方案批准")));
data.put("workLeader", firstNonBlank(
firstNonBlank(info.getWorkChargeUserName(), info.getWorkLeaderName(), info.getWorkResponsibleName(),
info.getOperationLeaderName()),
findStepActor(info, "工作负责人", "作业负责人")));
data.put("highWorkPerson", firstNonBlank(
firstNonBlank(textValue(info.getWorkUserName()), info.getHighWorkPersonName(), info.getWorkPersonName(),
info.getOperationPersonName()),
findStepActor(info, "高处作业人", "高处作业人员")));
data.put("guardian", firstNonBlank(
firstNonBlank(textValue(info.getWorkGuardianUserName()), info.getGuardianName(), info.getMonitorName()),
findStepActor(info, "监护人", "监护")));
putSafetyDisclosureSignatures(data, taskLogs, work.getCheckNo());
putOpinionSignatures(data, taskLogs, "implementation", work.getCheckNo(), IMPLEMENTATION_OPINION_STEP_ID);
putOpinionSignatures(data, taskLogs, "contract", work.getCheckNo(), CONTRACT_OPINION_STEP_ID);
putOpinionSignatures(data, taskLogs, "safetySupervision", work.getCheckNo(), SAFETY_SUPERVISION_OPINION_STEP_ID);
putOpinionSignatures(data, taskLogs, "territorial", work.getCheckNo(), TERRITORIAL_OPINION_STEP_ID);
putMeasureSignatures(data, work.getWorkId(), work.getCheckNo());
return Tools.renderTemplate(TEMPLATE_PATH, data).toByteArray();
}
/**
* 使 JSON
*/
private HighWorkPermitInfo parseInfo(EightworkInfoDO work) {
if (StringUtils.isBlank(work.getInfo())) {
return new HighWorkPermitInfo();
}
try {
return HighWorkPermitInfo.parse(work.getInfo());
} catch (Exception e) {
throw new BizException("作业票详情格式错误,票号:" + value(work.getCheckNo()));
}
}
/**
*
* 使
*/
private void putWorkLevel(Map<String, Object> data, String checkNo, String... workLevels) {
int selectedLevel = 0;
String originalValue = "";
for (String workLevel : workLevels) {
if (StringUtils.isBlank(workLevel)) {
continue;
}
if (StringUtils.isBlank(originalValue)) {
originalValue = workLevel;
}
selectedLevel = resolveWorkLevel(workLevel);
if (selectedLevel != 0) {
break;
}
}
if (selectedLevel == 0 && StringUtils.isNotBlank(originalValue)) {
log.warn("高处作业许可证未识别作业级别: checkNo={}, workLevel={}", checkNo, originalValue);
}
for (int level = 1; level <= 4; level++) {
data.put("level" + level, buildWorkLevelMark(selectedLevel == level));
}
}
/**
* 使 PDF
*/
private PictureRenderData buildWorkLevelMark(boolean selected) {
BufferedImage image = new BufferedImage(WORK_LEVEL_MARK_SIZE, WORK_LEVEL_MARK_SIZE, BufferedImage.TYPE_INT_ARGB);
Graphics2D graphics = image.createGraphics();
try {
graphics.setColor(Color.BLACK);
graphics.setStroke(new BasicStroke(1F));
graphics.drawRect(1, 1, WORK_LEVEL_MARK_SIZE - 3, WORK_LEVEL_MARK_SIZE - 3);
if (selected) {
graphics.setStroke(new BasicStroke(1.5F, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
graphics.drawLine(3, 5, 4, 7);
graphics.drawLine(4, 7, 8, 3);
}
} finally {
graphics.dispose();
}
return Pictures.ofBufferedImage(image, PictureType.PNG)
.size(WORK_LEVEL_MARK_SIZE, WORK_LEVEL_MARK_SIZE)
.create();
}
private int resolveWorkLevel(String workLevel) {
if (StringUtils.isBlank(workLevel)) {
return 0;
}
String normalized = workLevel.trim()
.replaceAll("\\s+", "")
.replace("_", "")
.replace("-", "")
.replace("", "1")
.replace("", "2")
.replace("", "3")
.replace("", "4")
.toUpperCase();
switch (normalized) {
case "HIGHWORKLEVEL0":
case "HIGHWORKLEVEL1":
return 1;
case "HIGHWORKLEVEL2":
return 2;
case "HIGHWORKLEVEL3":
return 3;
case "HIGHWORKLEVEL4":
return 4;
default:
break;
}
if (matchesWorkLevel(normalized, "1", "一级", "", "I")) {
return 1;
}
if (matchesWorkLevel(normalized, "2", "二级", "Ⅱ", "II")) {
return 2;
}
if (matchesWorkLevel(normalized, "3", "三级", "Ⅲ", "III")) {
return 3;
}
if (matchesWorkLevel(normalized, "4", "四级", "Ⅳ", "IV") || normalized.contains("特级")) {
return 4;
}
return 0;
}
private boolean matchesWorkLevel(String workLevel, String number, String chineseLevel,
String romanNumber, String asciiRomanNumber) {
return workLevel.equals(number)
|| workLevel.contains(number + "级")
|| workLevel.contains(chineseLevel)
|| workLevel.contains(romanNumber + "级")
|| workLevel.equals(romanNumber)
|| workLevel.contains("LEVEL" + number)
|| workLevel.contains("GC" + number)
|| workLevel.equals(asciiRomanNumber)
|| workLevel.equals(asciiRomanNumber + "级");
}
private void putDateParts(Map<String, Object> data, String prefix, String dateTime) {
List<String> parts = new ArrayList<>();
if (StringUtils.isNotBlank(dateTime)) {
for (String part : dateTime.split("[^0-9]+")) {
if (StringUtils.isNotBlank(part)) {
parts.add(part);
}
}
}
data.put(prefix + "Year", getPart(parts, 0));
data.put(prefix + "Month", getPart(parts, 1));
data.put(prefix + "Day", getPart(parts, 2));
data.put(prefix + "Hour", getPart(parts, 3));
data.put(prefix + "Minute", getPart(parts, 4));
}
private String getPart(List<String> parts, int index) {
return parts.size() > index ? parts.get(index) : "";
}
private void putDateParts(Map<String, Object> data, String prefix, LocalDateTime dateTime) {
putDateParts(data, prefix, dateTime == null ? "" : dateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
}
/**
* task_log 18 19
*
*/
private void putSafetyDisclosureSignatures(Map<String, Object> data, List<TaskLogDO> taskLogs,
String checkNo) {
data.put("safetyDiscloserSign", buildSignaturePicture(
getTaskLogSignPaths(taskLogs, SAFETY_DISCLOSER_STEP_ID),
DISCLOSER_SIGN_WIDTH, DISCLOSURE_SIGN_HEIGHT, checkNo));
data.put("safetyDisclosureRecipientSigns", buildSignaturePicture(
getTaskLogSignPaths(taskLogs, SAFETY_DISCLOSURE_RECIPIENT_STEP_ID),
RECIPIENT_SIGN_WIDTH, DISCLOSURE_SIGN_HEIGHT, checkNo));
}
/**
* 41 42 43 44
*/
private void putOpinionSignatures(Map<String, Object> data, List<TaskLogDO> taskLogs, String prefix,
String checkNo, long stepId) {
List<TaskLogDO> stepLogs = getTaskLogs(taskLogs, stepId);
data.put(prefix + "Sign", buildSignaturePicture(getTaskLogSignPaths(stepLogs),
OPINION_SIGN_WIDTH, OPINION_SIGN_HEIGHT, checkNo));
TaskLogDO latestLog = getLatestSignedTaskLog(stepLogs);
putDateParts(data, prefix, latestLog == null ? null : latestLog.getSignTime());
}
/**
* measures_logs order_by 1 10
*/
private void putMeasureSignatures(Map<String, Object> data, String workId, String checkNo) {
List<MeasureValue> measures = getMeasures(workId);
Map<Integer, List<String>> measureSignPaths = new HashMap<>();
for (int index = 1; index <= 10; index++) {
data.put("measureContent" + index, "");
data.put("measureSign" + index, null);
}
int sequentialIndex = 1;
Set<Integer> usedMeasureIndexes = new LinkedHashSet<>();
for (MeasureValue measure : measures) {
int targetIndex;
if (measure.orderBy != null && measure.orderBy >= 1 && measure.orderBy <= 10
&& !usedMeasureIndexes.contains(measure.orderBy)) {
targetIndex = measure.orderBy;
} else {
while (sequentialIndex <= 10 && usedMeasureIndexes.contains(sequentialIndex)) {
sequentialIndex++;
}
targetIndex = sequentialIndex++;
}
if (targetIndex > 10) {
continue;
}
usedMeasureIndexes.add(targetIndex);
appendMeasureContent(data, targetIndex, measure.content);
addSignPaths(measureSignPaths, targetIndex, measure.signPath);
}
for (int index = 1; index <= 10; index++) {
data.put("measureSign" + index, buildSignaturePicture(measureSignPaths.get(index),
MEASURE_SIGN_WIDTH, MEASURE_SIGN_HEIGHT, checkNo));
}
}
private void appendMeasureContent(Map<String, Object> data, int index, String content) {
if (StringUtils.isBlank(content)) {
return;
}
String key = "measureContent" + index;
String currentContent = String.valueOf(data.get(key));
data.put(key, StringUtils.isBlank(currentContent) ? content : currentContent + "\n" + content);
}
private List<MeasureValue> getMeasures(String workId) {
List<MeasuresLogsDO> currentMeasures = measuresLogsRepository.listAll(workId);
if (!CollectionUtils.isEmpty(currentMeasures)) {
List<MeasureValue> result = new ArrayList<>();
for (MeasuresLogsDO measure : currentMeasures) {
result.add(new MeasureValue(measure.getContent(), measure.getSignPath(), measure.getOrderBy()));
}
return result;
}
List<MeasuresLogsArchiveDO> archiveMeasures = measuresLogsArchiveRepository.list(
new LambdaQueryWrapper<MeasuresLogsArchiveDO>()
.eq(MeasuresLogsArchiveDO::getWorkId, workId)
.orderByAsc(MeasuresLogsArchiveDO::getType)
.orderByAsc(MeasuresLogsArchiveDO::getOrderBy)
.orderByAsc(MeasuresLogsArchiveDO::getCreateTime));
List<MeasureValue> result = new ArrayList<>();
for (MeasuresLogsArchiveDO measure : archiveMeasures) {
result.add(new MeasureValue(measure.getContent(), measure.getSignPath(), measure.getOrderBy()));
}
return result;
}
private List<TaskLogDO> getTaskLogs(List<TaskLogDO> taskLogs, long stepId) {
List<TaskLogDO> result = new ArrayList<>();
if (CollectionUtils.isEmpty(taskLogs)) {
return result;
}
for (TaskLogDO taskLog : taskLogs) {
if (taskLog != null && Long.valueOf(stepId).equals(taskLog.getStepId())) {
result.add(taskLog);
}
}
return result;
}
private List<String> getTaskLogSignPaths(List<TaskLogDO> taskLogs, long stepId) {
return getTaskLogSignPaths(getTaskLogs(taskLogs, stepId));
}
private List<String> getTaskLogSignPaths(List<TaskLogDO> taskLogs) {
List<String> result = new ArrayList<>();
if (CollectionUtils.isEmpty(taskLogs)) {
return result;
}
for (TaskLogDO taskLog : taskLogs) {
if (isSigned(taskLog)) {
addSignPaths(result, taskLog.getSignPath());
}
}
return result;
}
private void addSignPaths(Map<Integer, List<String>> signPaths, int index, String signPath) {
List<String> paths = signPaths.get(index);
if (paths == null) {
paths = new ArrayList<>();
signPaths.put(index, paths);
}
addSignPaths(paths, signPath);
}
private TaskLogDO getLatestSignedTaskLog(List<TaskLogDO> taskLogs) {
TaskLogDO latestLog = null;
if (CollectionUtils.isEmpty(taskLogs)) {
return null;
}
for (TaskLogDO taskLog : taskLogs) {
if (!isSigned(taskLog) || taskLog.getSignTime() == null) {
continue;
}
if (latestLog == null || taskLog.getSignTime().isAfter(latestLog.getSignTime())) {
latestLog = taskLog;
}
}
return latestLog;
}
private void addSignPaths(List<String> signPaths, String signPath) {
if (StringUtils.isNotBlank(signPath) && !signPaths.contains(signPath.trim())) {
signPaths.add(signPath.trim());
}
}
private boolean isSigned(TaskLogDO taskLog) {
return taskLog != null && (taskLog.getSignTime() != null || StringUtils.isNotBlank(taskLog.getSignPath()));
}
/**
* 访
*/
private PictureRenderData buildSignaturePicture(List<String> signPaths, int width, int height,
String checkNo) {
if (CollectionUtils.isEmpty(signPaths)) {
return null;
}
List<BufferedImage> images = new ArrayList<>();
for (String signPath : signPaths) {
try {
byte[] imageBytes = loadSignatureBytes(signPath, checkNo);
BufferedImage image = ImageIO.read(new ByteArrayInputStream(imageBytes));
if (image == null) {
log.warn("签字图片格式不支持,已跳过:票号={}, 路径={}", value(checkNo), signPath);
continue;
}
images.add(image);
} catch (Exception e) {
log.warn("签字图片加载失败,已跳过:票号={}, 路径={}, 原因={}",
value(checkNo), signPath, e.getMessage());
}
}
if (images.isEmpty()) {
return null;
}
BufferedImage signatureImage = composeSignatureImages(images, width, height);
return Pictures.ofBufferedImage(signatureImage, PictureType.PNG).size(width, height).create();
}
private byte[] loadSignatureBytes(String signPath, String checkNo) throws Exception {
if (signPath.startsWith("data:image")) {
int separatorIndex = signPath.indexOf(',');
if (separatorIndex < 0) {
throw new BizException("签字图片数据格式错误,票号:" + value(checkNo));
}
return Base64.getDecoder().decode(signPath.substring(separatorIndex + 1));
}
String imageUrl = buildSignatureUrl(signPath, checkNo);
URLConnection connection = new URL(imageUrl).openConnection();
connection.setConnectTimeout(10000);
connection.setReadTimeout(10000);
try {
if (connection instanceof HttpURLConnection) {
int responseCode = ((HttpURLConnection) connection).getResponseCode();
if (responseCode < HttpURLConnection.HTTP_OK || responseCode >= HttpURLConnection.HTTP_MULT_CHOICE) {
throw new IOException("签字图片请求失败,状态码:" + responseCode + ",地址:" + imageUrl);
}
}
try (InputStream inputStream = connection.getInputStream();
ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
byte[] buffer = new byte[4096];
int length;
while ((length = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, length);
}
return outputStream.toByteArray();
}
} finally {
if (connection instanceof HttpURLConnection) {
((HttpURLConnection) connection).disconnect();
}
}
}
private String buildSignatureUrl(String signPath, String checkNo) {
if (signPath.startsWith("http://") || signPath.startsWith("https://")) {
return signPath;
}
if (StringUtils.isBlank(fileUrl)) {
throw new BizException("签字图片地址配置不存在,票号:" + value(checkNo));
}
if (fileUrl.endsWith("/") && signPath.startsWith("/")) {
return fileUrl + signPath.substring(1);
}
if (!fileUrl.endsWith("/") && !signPath.startsWith("/")) {
return fileUrl + "/" + signPath;
}
return fileUrl + signPath;
}
private BufferedImage composeSignatureImages(List<BufferedImage> images, int width, int height) {
int renderWidth = width * SIGNATURE_RENDER_SCALE;
int renderHeight = height * SIGNATURE_RENDER_SCALE;
BufferedImage result = new BufferedImage(renderWidth, renderHeight, BufferedImage.TYPE_INT_ARGB);
Graphics2D graphics = result.createGraphics();
try {
graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BICUBIC);
graphics.setRenderingHint(RenderingHints.KEY_RENDERING,
RenderingHints.VALUE_RENDER_QUALITY);
graphics.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION,
RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
int slotWidth = Math.max(1, renderWidth / images.size());
int horizontalMargin = SIGNATURE_RENDER_SCALE * 4;
int verticalMargin = SIGNATURE_RENDER_SCALE * 2;
for (int index = 0; index < images.size(); index++) {
BufferedImage image = cropSignatureImage(images.get(index));
double scale = Math.min((double) Math.max(1, slotWidth - horizontalMargin) / image.getWidth(),
(double) Math.max(1, renderHeight - verticalMargin) / image.getHeight());
int drawWidth = Math.max(1, (int) Math.round(image.getWidth() * scale));
int drawHeight = Math.max(1, (int) Math.round(image.getHeight() * scale));
int x = index * slotWidth + horizontalMargin / 2;
int y = Math.max(0, (renderHeight - drawHeight) / 2);
graphics.drawImage(image, x, y, drawWidth, drawHeight, null);
}
} finally {
graphics.dispose();
}
return result;
}
/**
*
*/
private BufferedImage cropSignatureImage(BufferedImage image) {
BufferedImage source = removeSignatureFrame(image);
int minX = source.getWidth();
int minY = source.getHeight();
int maxX = -1;
int maxY = -1;
for (int y = 0; y < source.getHeight(); y++) {
for (int x = 0; x < source.getWidth(); x++) {
int pixel = source.getRGB(x, y);
int alpha = (pixel >>> 24) & 255;
int red = (pixel >>> 16) & 255;
int green = (pixel >>> 8) & 255;
int blue = pixel & 255;
if (alpha == 0 || (red >= 245 && green >= 245 && blue >= 245)) {
continue;
}
minX = Math.min(minX, x);
minY = Math.min(minY, y);
maxX = Math.max(maxX, x);
maxY = Math.max(maxY, y);
}
}
if (maxX < minX || maxY < minY) {
return source;
}
int padding = 2;
int left = Math.max(0, minX - padding);
int top = Math.max(0, minY - padding);
int right = Math.min(source.getWidth() - 1, maxX + padding);
int bottom = Math.min(source.getHeight() - 1, maxY + padding);
return makeSignatureBackgroundTransparent(source.getSubimage(left, top, right - left + 1, bottom - top + 1));
}
/**
*
*/
private BufferedImage makeSignatureBackgroundTransparent(BufferedImage image) {
BufferedImage result = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_ARGB);
for (int y = 0; y < image.getHeight(); y++) {
for (int x = 0; x < image.getWidth(); x++) {
int pixel = image.getRGB(x, y);
int alpha = (pixel >>> 24) & 255;
int red = (pixel >>> 16) & 255;
int green = (pixel >>> 8) & 255;
int blue = pixel & 255;
if (alpha == 0 || (red >= 245 && green >= 245 && blue >= 245)) {
result.setRGB(x, y, 0);
continue;
}
result.setRGB(x, y, pixel);
}
}
return result;
}
/**
*
*
*/
private BufferedImage removeSignatureFrame(BufferedImage image) {
int top = findSolidDarkEdge(image, true, false);
int bottom = findSolidDarkEdge(image, true, true);
int left = findSolidDarkEdge(image, false, false);
int right = findSolidDarkEdge(image, false, true);
if (top == 0 || bottom == 0 || left == 0 || right == 0) {
return image;
}
int width = image.getWidth() - left - right;
int height = image.getHeight() - top - bottom;
if (width < 2 || height < 2) {
return image;
}
return image.getSubimage(left, top, width, height);
}
private int findSolidDarkEdge(BufferedImage image, boolean horizontal, boolean reverse) {
int edgeLength = horizontal ? image.getHeight() : image.getWidth();
int crossLength = horizontal ? image.getWidth() : image.getHeight();
int scanLimit = Math.min(20, Math.max(1, edgeLength / 10));
int thickness = 0;
for (int offset = 0; offset < scanLimit; offset++) {
int edge = reverse ? edgeLength - 1 - offset : offset;
int darkCount = 0;
for (int cross = 0; cross < crossLength; cross++) {
int pixel = horizontal ? image.getRGB(cross, edge) : image.getRGB(edge, cross);
int alpha = (pixel >>> 24) & 255;
int red = (pixel >>> 16) & 255;
int green = (pixel >>> 8) & 255;
int blue = pixel & 255;
if (alpha > 0 && red < 50 && green < 50 && blue < 50) {
darkCount++;
}
}
if ((double) darkCount / crossLength < 0.98D) {
break;
}
thickness++;
}
return thickness;
}
private String findStepActor(HighWorkPermitInfo info, String... stepKeywords) {
Set<String> actors = new LinkedHashSet<>();
for (HighWorkPermitStepInfo step : findSteps(info, stepKeywords)) {
if (isSigned(step) && StringUtils.isNotBlank(step.getActUserName())) {
actors.add(step.getActUserName());
}
}
return String.join("、", actors);
}
/**
*
*/
private List<HighWorkPermitStepInfo> findSteps(HighWorkPermitInfo info, String... stepKeywords) {
List<HighWorkPermitStepInfo> result = new ArrayList<>();
if (info.getStepInfoMap() == null) {
return result;
}
List<String> keys = new ArrayList<>(info.getStepInfoMap().keySet());
Collections.sort(keys);
for (String key : keys) {
HighWorkPermitStepInfo step = info.getStepInfoMap().get(key);
if (step == null || StringUtils.isBlank(step.getStepName())) {
continue;
}
String stepName = step.getStepName();
for (String keyword : stepKeywords) {
if (stepName.contains(keyword)) {
result.add(step);
break;
}
}
}
return result;
}
private boolean isSigned(HighWorkPermitStepInfo step) {
Integer status = step.getStatus();
return Integer.valueOf(1).equals(status)
|| StringUtils.isNotBlank(step.getSignTime())
|| StringUtils.isNotBlank(step.getSignPath());
}
private String firstNonBlank(String... values) {
for (String current : values) {
if (StringUtils.isNotBlank(current)) {
return current;
}
}
return "";
}
private byte[] buildZip(Map<String, byte[]> pdfFiles) throws Exception {
try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ZipOutputStream zipOutputStream = new ZipOutputStream(outputStream)) {
for (Map.Entry<String, byte[]> file : pdfFiles.entrySet()) {
zipOutputStream.putNextEntry(new ZipEntry(file.getKey()));
zipOutputStream.write(file.getValue());
zipOutputStream.closeEntry();
}
zipOutputStream.finish();
return outputStream.toByteArray();
}
}
private String buildPdfFileName(EightworkInfoDO work, Map<String, Integer> fileNameCounts) {
String checkNo = StringUtils.isBlank(work.getCheckNo()) ? String.valueOf(work.getId()) : work.getCheckNo();
String baseName = sanitizeFileName("高处作业安全许可证_" + checkNo);
Integer count = fileNameCounts.get(baseName);
fileNameCounts.put(baseName, count == null ? 1 : count + 1);
return count == null ? baseName + ".pdf" : baseName + "_" + (count + 1) + ".pdf";
}
private String sanitizeFileName(String fileName) {
return fileName.replaceAll("[\\\\/:*?\"<>|\\r\\n]", "_");
}
private void writeResponse(HttpServletResponse response, byte[] bytes, String contentType, String fileName) throws Exception {
response.reset();
response.setCharacterEncoding("UTF-8");
response.setContentType(contentType);
response.setHeader("Content-Disposition",
"attachment; filename*=UTF-8''" + URLEncoder.encode(fileName, "UTF-8").replace("+", "%20"));
response.setContentLength(bytes.length);
try (OutputStream outputStream = response.getOutputStream()) {
outputStream.write(bytes);
outputStream.flush();
}
}
private String value(String value) {
return value == null ? "" : value;
}
/**
* 使
*/
private String textValue(Object value) {
if (value == null) {
return "";
}
if (value instanceof Iterable) {
List<String> values = new ArrayList<>();
for (Object item : (Iterable<?>) value) {
if (item != null && StringUtils.isNotBlank(String.valueOf(item))) {
values.add(String.valueOf(item));
}
}
return String.join("、", values);
}
return String.valueOf(value);
}
private static class MeasureValue {
private final String content;
private final String signPath;
private final Integer orderBy;
private MeasureValue(String content, String signPath, Integer orderBy) {
this.content = content;
this.signPath = signPath;
this.orderBy = orderBy;
}
}
}

View File

@ -0,0 +1,116 @@
package com.zcloud.eightwork.command.query;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import lombok.Data;
import java.util.LinkedHashMap;
import java.util.Map;
/**
*
*
* <p> eightwork_info.info JSON
* step_{ID}step_{ID}_{} stepInfoMap JSON</p>
*/
@Data
public class HighWorkPermitInfo {
private String implementationUnit;
private String implementationUnitName;
private String workUnit;
private String workUnitName;
private String constructionUnit;
private String workLocation;
private String workPlace;
private String operationLocation;
private String workAddress;
private String workSite;
private String workPosition;
private String workContent;
private String operationContent;
private String workDescription;
private String applyTime;
private String applicationTime;
private String workStartTime;
private String startTime;
private String workEndTime;
private String endTime;
private String workLevel;
private String workLevelName;
private String operationLevel;
private String highWorkLevel;
/** 项目批准人。 */
private Long projectApproverId;
private String projectApproverName;
private String projectApprovalName;
/** 方案编制人。 */
private Long planPreparerId;
private String planPreparerName;
/** 方案批准人。 */
private Long planApproverId;
private String planApproverName;
private String schemeApproverName;
private String planCompilerName;
private String schemeCompilerName;
/** 工作负责人。 */
private Long workChargeUserId;
private String workChargeUserName;
private String workLeaderName;
private String workResponsibleName;
private String operationLeaderName;
/** 高处作业人,多选时名称字段保存多个作业人名称。 */
private Object workUserId;
private Object workUserName;
private String highWorkPersonName;
private String workPersonName;
private String operationPersonName;
/** 监护人,多选时名称字段保存多个监护人名称。 */
private Object workGuardianUserId;
private Object workGuardianUserName;
private String guardianName;
private String monitorName;
/**
* step_3step_3_1
*/
private Map<String, HighWorkPermitStepInfo> stepInfoMap = new LinkedHashMap<>();
/**
* eightwork_info.info
*
* @param infoJson JSON
* @return
*/
public static HighWorkPermitInfo parse(String infoJson) {
HighWorkPermitInfo info = JSON.parseObject(infoJson, HighWorkPermitInfo.class);
if (info == null) {
info = new HighWorkPermitInfo();
}
Map<String, Object> values = JSON.parseObject(infoJson,
new TypeReference<LinkedHashMap<String, Object>>() {
});
Map<String, HighWorkPermitStepInfo> stepInfoMap = new LinkedHashMap<>();
if (values != null) {
for (Map.Entry<String, Object> entry : values.entrySet()) {
if (!entry.getKey().startsWith("step_")) {
continue;
}
HighWorkPermitStepInfo stepInfo = JSON.parseObject(JSON.toJSONString(entry.getValue()),
HighWorkPermitStepInfo.class);
if (stepInfo != null) {
stepInfoMap.put(entry.getKey(), stepInfo);
}
}
}
info.setStepInfoMap(stepInfoMap);
return info;
}
}

View File

@ -0,0 +1,18 @@
package com.zcloud.eightwork.command.query;
import lombok.Data;
/**
*
*
* <p> eightwork_info.info step_{ID} step_{ID}_{} </p>
*/
@Data
public class HighWorkPermitStepInfo {
private String stepName;
private String actUserName;
private Integer status;
private String signTime;
private String signPath;
}

View File

@ -10,6 +10,7 @@ import com.zcloud.eightwork.command.EightworkInfoRemoveExe;
import com.zcloud.eightwork.command.EightworkInfoUpdateExe;
import com.zcloud.eightwork.command.EightworkInfoWithdrawExe;
import com.zcloud.eightwork.command.query.EightworkInfoQueryExe;
import com.zcloud.eightwork.command.query.HighWorkPermitExportExe;
import com.zcloud.eightwork.domain.gateway.TaskLogGateway;
import com.zcloud.eightwork.domain.model.TaskLogE;
import com.zcloud.eightwork.domain.model.enums.TaskLogStatus;
@ -17,6 +18,7 @@ import com.zcloud.eightwork.dto.DangerWorkStatisticsQry;
import com.zcloud.eightwork.dto.EightworkInfoAddCmd;
import com.zcloud.eightwork.dto.EightworkInfoPageQry;
import com.zcloud.eightwork.dto.EightworkInfoUpdateCmd;
import com.zcloud.eightwork.dto.HighWorkPermitExportQry;
import com.zcloud.eightwork.dto.ScreenDangerWorkDataStatisticsQry;
import com.zcloud.eightwork.dto.ScreenDepartmentStatisticsQry;
import com.zcloud.eightwork.dto.ScreenStatisticsQry;
@ -65,6 +67,7 @@ public class EightworkInfoServiceImpl implements EightworkInfoServiceI {
private final TaskLogGateway taskLogGateway;
private final EightworkInfoRepository eightworkInfoRepository;
private final EightworkInfoWithdrawExe eightworkInfoWithdrawExe;
private final HighWorkPermitExportExe highWorkPermitExportExe;
@Override
public EightworkInfoCO queryById(Long id) {
@ -230,5 +233,10 @@ public class EightworkInfoServiceImpl implements EightworkInfoServiceI {
public List<ScreenWorkPieStatisticsCO> screenWorkPieStatistics(ScreenWorkPieStatisticsQry qry) {
return eightworkInfoQueryExe.screenWorkPieStatistics(qry);
}
@Override
public void exportHighWorkPermit(HighWorkPermitExportQry qry, HttpServletResponse response) {
highWorkPermitExportExe.execute(qry, response);
}
}

View File

@ -6,6 +6,7 @@ import com.zcloud.eightwork.dto.DangerWorkStatisticsQry;
import com.zcloud.eightwork.dto.EightworkInfoAddCmd;
import com.zcloud.eightwork.dto.EightworkInfoPageQry;
import com.zcloud.eightwork.dto.EightworkInfoUpdateCmd;
import com.zcloud.eightwork.dto.HighWorkPermitExportQry;
import com.zcloud.eightwork.dto.ScreenDangerWorkDataStatisticsQry;
import com.zcloud.eightwork.dto.ScreenDepartmentStatisticsQry;
import com.zcloud.eightwork.dto.ScreenStatisticsQry;
@ -85,5 +86,7 @@ public interface EightworkInfoServiceI {
ScreenWorkStatusStatisticsCO screenWorkStatusStatistics(ScreenWorkStatusStatisticsQry qry);
List<ScreenWorkPieStatisticsCO> screenWorkPieStatistics(ScreenWorkPieStatisticsQry qry);
void exportHighWorkPermit(HighWorkPermitExportQry qry, HttpServletResponse response);
}

View File

@ -0,0 +1,21 @@
package com.zcloud.eightwork.dto;
import com.alibaba.cola.dto.Query;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import javax.validation.constraints.NotEmpty;
import java.util.List;
/**
*
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class HighWorkPermitExportQry extends Query {
@ApiModelProperty(value = "作业票主表ID列表", name = "ids", required = true)
@NotEmpty(message = "作业票主表ID不能为空")
private List<Long> ids;
}

View File

@ -54,5 +54,7 @@ public interface EightworkInfoMapper extends BaseMapper<EightworkInfoDO> {
ScreenWorkStatusStatisticsDTO screenWorkStatusStatistics(@Param("params") Map<String, Object> params);
List<ScreenWorkPieStatisticsDTO> screenWorkPieStatistics(@Param("params") Map<String, Object> params);
String getCorpNameById(@Param("corpinfoId") Long corpinfoId);
}

View File

@ -51,6 +51,8 @@ public interface EightworkInfoRepository extends BaseRepository<EightworkInfoDO>
List<ScreenWorkPieStatisticsDTO> screenWorkPieStatistics(Map<String, Object> params);
String getCorpNameById(Long corpinfoId);
/**
* 使 CAS lockFlag
* lockFlag status

View File

@ -130,6 +130,11 @@ public class EightworkInfoRepositoryImpl extends BaseRepositoryImpl<EightworkInf
return eightworkInfoMapper.screenWorkPieStatistics(params);
}
@Override
public String getCorpNameById(Long corpinfoId) {
return eightworkInfoMapper.getCorpNameById(corpinfoId);
}
@Override
public boolean updateLockFlagToLocked(Long id, Integer expectedLockFlag, Integer newLockFlag, Integer expectedStatus) {
LambdaUpdateWrapper<EightworkInfoDO> updateWrapper = new LambdaUpdateWrapper<>();

View File

@ -340,4 +340,12 @@
group by t.work_type
</select>
<select id="getCorpNameById" resultType="java.lang.String">
select corp_name
from vi_corp_info
where id = #{corpinfoId}
and delete_enum = 'FALSE'
limit 1
</select>
</mapper>