Compare commits

..

1 Commits

Author SHA1 Message Date
pan
a07f109631 原型调整 2024-08-20 15:24:26 +08:00
109 changed files with 4428 additions and 14497 deletions

View File

@ -1,5 +1,5 @@
# 页面标题
VUE_APP_TITLE = 工具管理技术交流平台
VUE_APP_TITLE = 工具管理技术交流平台
# 开发环境配置
ENV = 'development'
@ -7,14 +7,14 @@ ENV = 'development'
VUE_APP_CONTEXT_PATH = '/tool-tech'
# 工具与技术交流管理系统/开发环境
VUE_APP_BASE_API = 'http://localhost:8080/tool-tech-admin'
VUE_APP_WS_URL = 'ws://localhost:8080/tool-tech-admin/websocket'
VUE_APP_BASE_API = 'http://192.168.2.85:8080/tool-tech-admin'
VUE_APP_WS_URL = 'ws://192.168.2.85:8080/tool-tech-admin/websocket'
# 文档在线预览服务
VUE_APP_TOOL_TECH_FILE_VIEW_API = 'http://127.0.0.1:8012/tool-tech-file-view'
VUE_APP_TOOL_TECH_FILE_VIEW_API = 'http://192.168.1.2:8012/tool-tech-file-view'
# 流程管理服务地址
VUE_APP_WORKFLOW_MANAGE_URL = '/ebpm-process-manage'
VUE_APP_WORKFLOW_MANAGE_URL = 'http://192.168.1.2:8080/ebpm-process-manage'
# 路由懒加载
VUE_CLI_BABEL_TRANSPILE_MODULES = true

View File

@ -1,5 +1,5 @@
# 页面标题
VUE_APP_TITLE = 工具管理技术交流平台
VUE_APP_TITLE = 工具管理技术交流平台
# 生产环境配置
ENV = 'production'
@ -7,11 +7,11 @@ ENV = 'production'
VUE_APP_CONTEXT_PATH = '/tool-tech'
# 工具与技术交流管理系统/生产环境
VUE_APP_BASE_API = '/tool-tech-admin'
VUE_APP_WS_URL = '/tool-tech-admin/websocket'
VUE_APP_BASE_API = '/prod-api'
VUE_APP_WS_URL = 'wss://www.rzdata.net/tool-tech-admin/websocket'
# 文档在线预览服务
VUE_APP_TOOL_TECH_FILE_VIEW_API = '/tool-tech-file-view'
VUE_APP_TOOL_TECH_FILE_VIEW_API = 'http://localhost:8012/tool-tech-file-view'
# 流程管理服务地址
VUE_APP_WORKFLOW_MANAGE_URL = '/ebpm-process-manage'
VUE_APP_WORKFLOW_MANAGE_URL = 'http://localhost:8085/ebpm-process-manage'

View File

@ -1,5 +1,5 @@
# 页面标题
VUE_APP_TITLE = 工具管理技术交流平台
VUE_APP_TITLE = 工具管理技术交流平台
NODE_ENV = production
@ -9,8 +9,8 @@ ENV = 'staging'
VUE_APP_CONTEXT_PATH = '/tool-tech'
# 工具与技术交流管理系统/测试环境
VUE_APP_BASE_API = '/tool-tech-admin'
VUE_APP_WS_URL = '/tool-tech-admin/websocket'
VUE_APP_BASE_API = 'https://www.rzdata.net/tool-tech-admin'
VUE_APP_WS_URL = 'wss://www.rzdata.net/tool-tech-admin/websocket'
# 文档在线预览服务
VUE_APP_TOOL_TECH_FILE_VIEW_API = '/tool-tech-file-view'

27
.idea/codeStyles/Project.xml generated Normal file
View File

@ -0,0 +1,27 @@
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<JSCodeStyleSettings version="0">
<option name="USE_SEMICOLON_AFTER_STATEMENT" value="false" />
<option name="FORCE_SEMICOLON_STYLE" value="true" />
<option name="SPACE_BEFORE_GENERATOR_MULT" value="true" />
<option name="SPACE_BEFORE_FUNCTION_LEFT_PARENTH" value="false" />
<option name="USE_DOUBLE_QUOTES" value="false" />
<option name="FORCE_QUOTE_STYlE" value="true" />
<option name="ENFORCE_TRAILING_COMMA" value="Remove" />
<option name="SPACES_WITHIN_OBJECT_LITERAL_BRACES" value="true" />
<option name="SPACES_WITHIN_IMPORTS" value="true" />
<option name="SPACE_BEFORE_ASYNC_ARROW_LPAREN" value="false" />
</JSCodeStyleSettings>
<codeStyleSettings language="JavaScript">
<option name="KEEP_BLANK_LINES_IN_CODE" value="1" />
<option name="IF_BRACE_FORCE" value="1" />
<option name="DOWHILE_BRACE_FORCE" value="1" />
<option name="WHILE_BRACE_FORCE" value="1" />
<option name="FOR_BRACE_FORCE" value="1" />
<indentOptions>
<option name="INDENT_SIZE" value="2" />
<option name="CONTINUATION_INDENT_SIZE" value="2" />
</indentOptions>
</codeStyleSettings>
</code_scheme>
</component>

5
.idea/codeStyles/codeStyleConfig.xml generated Normal file
View File

@ -0,0 +1,5 @@
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
</state>
</component>

View File

@ -0,0 +1,6 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
</profile>
</component>

9
.idea/misc.xml generated Normal file
View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="JavaScriptSettings">
<option name="languageLevel" value="ES6" />
</component>
<component name="WebPackConfiguration">
<option name="mode" value="DISABLED" />
</component>
</project>

8
.idea/modules.xml generated Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/tool-tech-front.iml" filepath="$PROJECT_DIR$/.idea/tool-tech-front.iml" />
</modules>
</component>
</project>

12
.idea/tool-tech-front.iml generated Normal file
View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
<excludeFolder url="file://$MODULE_DIR$/temp" />
<excludeFolder url="file://$MODULE_DIR$/tmp" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

6
.idea/vcs.xml generated Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

973
.idea/workspace.xml generated Normal file
View File

@ -0,0 +1,973 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ChangeListManager">
<list default="true" id="880b2c9e-bb63-49b5-a9b3-35bf50aa9da8" name="Default Changelist" comment="">
<change beforePath="$PROJECT_DIR$/.env.staging" beforeDir="false" afterPath="$PROJECT_DIR$/.env.staging" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/default.conf" beforeDir="false" afterPath="$PROJECT_DIR$/default.conf" afterDir="false" />
</list>
<ignored path="$PROJECT_DIR$/.tmp/" />
<ignored path="$PROJECT_DIR$/temp/" />
<ignored path="$PROJECT_DIR$/tmp/" />
<option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="FileEditorManager">
<leaf SIDE_TABS_SIZE_LIMIT_KEY="300">
<file pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/src/views/workstuff/message/index.vue">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="722">
<caret line="38" column="4" selection-start-line="38" selection-start-column="4" selection-end-line="45" selection-end-column="40" />
</state>
</provider>
</entry>
</file>
<file pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/src/views/tool/index.vue">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="2356">
<caret line="177" column="132" selection-start-line="177" selection-start-column="96" selection-end-line="177" selection-end-column="132" />
<folding>
<element signature="n#el-form#0;n#el-card#0;n#div#0;n#template#0;n#!!top" />
<element signature="n#style#0;n#el-select#0;n#el-form-item#2;n#div#0;n#div#0;n#div#0;n#el-form#0;n#el-card#0;n#div#0;n#template#0;n#!!top" expanded="true" />
<element signature="n#style#0;n#el-date-picker#0;n#el-form-item#3;n#div#0;n#div#0;n#div#0;n#el-form#0;n#el-card#0;n#div#0;n#template#0;n#!!top" expanded="true" />
<element signature="n#style#0;n#el-input#0;n#div#0;n#el-card#1;n#div#0;n#template#0;n#!!top" expanded="true" />
<element signature="n#style#0;n#el-select#0;n#el-form-item#0;n#el-col#0;n#el-row#3;n#el-form#0;n#div#0;n#el-drawer#0;n#div#0;n#template#0;n#!!top" expanded="true" />
<element signature="n#el-drawer#2;n#div#0;n#template#0;n#!!top" />
</folding>
</state>
</provider>
</entry>
</file>
<file pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/src/views/tool/toolDetail.vue">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="2451">
<caret line="129" column="50" selection-start-line="129" selection-start-column="50" selection-end-line="129" selection-end-column="50" />
</state>
</provider>
</entry>
</file>
<file pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/src/plugins/modal.js">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="266">
<caret line="14" column="2" selection-start-line="14" selection-start-column="2" selection-end-line="14" selection-end-column="2" />
</state>
</provider>
</entry>
</file>
<file pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/src/views/document/editDocument.vue">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="2603">
<caret line="139" column="12" lean-forward="true" selection-start-line="139" selection-start-column="12" selection-end-line="139" selection-end-column="12" />
<folding>
<element signature="n#style#0;n#el-table#0;n#div#0;n#el-dialog#0;n#div#0;n#template#0;n#!!top" expanded="true" />
</folding>
</state>
</provider>
</entry>
</file>
<file pinned="false" current-in-tab="true">
<entry file="file://$PROJECT_DIR$/.env.staging">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="342">
<caret line="18" column="31" selection-start-line="18" selection-start-column="31" selection-end-line="18" selection-end-column="31" />
</state>
</provider>
</entry>
</file>
<file pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/default.conf">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="475">
<caret line="25" column="36" lean-forward="true" selection-start-line="25" selection-start-column="36" selection-end-line="25" selection-end-column="36" />
</state>
</provider>
</entry>
</file>
<file pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/.env.development">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="228">
<caret line="12" selection-start-line="12" selection-end-line="16" selection-end-column="75" />
</state>
</provider>
</entry>
</file>
<file pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/.env.production">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="19">
<caret line="1" column="27" selection-start-line="1" selection-start-column="27" selection-end-line="1" selection-end-column="27" />
</state>
</provider>
</entry>
</file>
<file pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/src/views/workflow/config/index.vue">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="247">
<caret line="13" column="103" selection-start-line="13" selection-start-column="72" selection-end-line="13" selection-end-column="103" />
</state>
</provider>
</entry>
</file>
</leaf>
</component>
<component name="FileTemplateManagerImpl">
<option name="RECENT_TEMPLATES">
<list>
<option value="Vue Single File Component" />
</list>
</option>
</component>
<component name="FindInProjectRecents">
<findStrings>
<find>deptName</find>
<find>peopleSelect</find>
<find>onChange</find>
<find>submitForm</find>
<find>initWebSocket</find>
<find>generateUniqueID</find>
<find>progress</find>
<find>listDocument</find>
<find>previewUrl</find>
<find>toolPrincipalsChoose</find>
<find>showOpenHandle</find>
<find>toolDetail</find>
<find>editDocumentRef</find>
<find>checkDuplicate</find>
<find>申请使用</find>
<find>applyDrawerOpen</find>
<find>cancelApply</find>
<find>submitApply</find>
<find>applyUse</find>
<find>handleDelete</find>
<find>监控</find>
<find>审批记录</find>
<find>tableData4</find>
<find>drawer2</find>
<find>tableData7</find>
<find>getClassName</find>
<find>已通过</find>
<find>el-dialog</find>
<find>ids</find>
<find>drawer1</find>
</findStrings>
<replaceStrings>
<replace>docList</replace>
<replace>toolList</replace>
<replace>handlePublish</replace>
<replace>applyDrawerOpen</replace>
<replace>exoportDrawerOpen</replace>
<replace>detailDrawerOpen</replace>
<replace>通过</replace>
</replaceStrings>
<dirStrings>
<dir>D:\rzdata\ToolTech\tool-tech-front</dir>
<dir>D:\rzdata\ToolTech\tool-tech-front\src</dir>
</dirStrings>
</component>
<component name="Git.Settings">
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
</component>
<component name="IdeDocumentHistory">
<option name="CHANGED_PATHS">
<list>
<option value="$PROJECT_DIR$/src/views/system/user/profile/userAvatar.vue" />
<option value="$PROJECT_DIR$/src/api/system/user.js" />
<option value="$PROJECT_DIR$/src/api/document/document.js" />
<option value="$PROJECT_DIR$/src/views/workflow/index.vue" />
<option value="$PROJECT_DIR$/src/views/workflow/config/index.vue" />
<option value="$PROJECT_DIR$/src/views/workflow/task/index.vue" />
<option value="$PROJECT_DIR$/src/api/tool/tool.js" />
<option value="$PROJECT_DIR$/public/css/poctstyle.css" />
<option value="$PROJECT_DIR$/src/components/userSelector/userSelect.vue" />
<option value="$PROJECT_DIR$/src/components/user-selector/src/user-selector.vue" />
<option value="$PROJECT_DIR$/vue.config.js" />
<option value="$PROJECT_DIR$/Dockerfile" />
<option value="$PROJECT_DIR$/public/css/index.css" />
<option value="$PROJECT_DIR$/src/main.js" />
<option value="$PROJECT_DIR$/src/utils/request.js" />
<option value="$PROJECT_DIR$/src/views/login.vue" />
<option value="$PROJECT_DIR$/src/views/statistic/index.vue" />
<option value="$PROJECT_DIR$/src/store/getters.js" />
<option value="$PROJECT_DIR$/src/store/modules/user.js" />
<option value="$PROJECT_DIR$/public/css/tool.css" />
<option value="$PROJECT_DIR$/.env.production" />
<option value="$PROJECT_DIR$/src/layout/components/Navbar.vue" />
<option value="$PROJECT_DIR$/src/components/Breadcrumb/index.vue" />
<option value="$PROJECT_DIR$/src/router/index.js" />
<option value="$PROJECT_DIR$/src/views/index.vue" />
<option value="$PROJECT_DIR$/src/views/system/user/index.vue" />
<option value="$PROJECT_DIR$/src/views/system/user/authRole.vue" />
<option value="$PROJECT_DIR$/src/views/system/role/index.vue" />
<option value="$PROJECT_DIR$/src/views/system/menu/index.vue" />
<option value="$PROJECT_DIR$/src/views/system/post/index.vue" />
<option value="$PROJECT_DIR$/src/views/system/dict/index.vue" />
<option value="$PROJECT_DIR$/src/views/system/config/index.vue" />
<option value="$PROJECT_DIR$/src/views/system/notice/index.vue" />
<option value="$PROJECT_DIR$/src/views/monitor/operlog/index.vue" />
<option value="$PROJECT_DIR$/src/views/monitor/logininfor/index.vue" />
<option value="$PROJECT_DIR$/src/views/system/tool/gen/index.vue" />
<option value="$PROJECT_DIR$/src/views/system/dict/data.vue" />
<option value="$PROJECT_DIR$/src/views/system/dept/index.vue" />
<option value="$PROJECT_DIR$/src/views/system/role/authUser.vue" />
<option value="$PROJECT_DIR$/src/views/document/addDocument.vue" />
<option value="$PROJECT_DIR$/src/views/tool/toolDetail.vue" />
<option value="$PROJECT_DIR$/src/views/document/uploadProgress.vue" />
<option value="$PROJECT_DIR$/src/views/document/index.vue" />
<option value="$PROJECT_DIR$/src/views/tool/index.vue" />
<option value="$PROJECT_DIR$/src/views/workstuff/apply/index.vue" />
<option value="$PROJECT_DIR$/src/views/workstuff/dispose/index.vue" />
<option value="$PROJECT_DIR$/src/views/workstuff/message/index.vue" />
<option value="$PROJECT_DIR$/src/views/document/editDocument.vue" />
<option value="$PROJECT_DIR$/.env.development" />
<option value="$PROJECT_DIR$/default.conf" />
<option value="$PROJECT_DIR$/.env.staging" />
</list>
</option>
</component>
<component name="ProjectFrameBounds" extendedState="6">
<option name="x" value="-12" />
<option name="y" value="-12" />
<option name="width" value="2904" />
<option name="height" value="1752" />
</component>
<component name="ProjectView">
<navigator proportions="" version="1">
<foldersAlwaysOnTop value="true" />
</navigator>
<panes>
<pane id="ProjectPane">
<subPane>
<expand>
<path>
<item name="tool-tech-front" type="b2602c69:ProjectViewProjectNode" />
<item name="tool-tech-front" type="462c0819:PsiDirectoryNode" />
</path>
<path>
<item name="tool-tech-front" type="b2602c69:ProjectViewProjectNode" />
<item name="tool-tech-front" type="462c0819:PsiDirectoryNode" />
<item name="public" type="462c0819:PsiDirectoryNode" />
</path>
<path>
<item name="tool-tech-front" type="b2602c69:ProjectViewProjectNode" />
<item name="tool-tech-front" type="462c0819:PsiDirectoryNode" />
<item name="public" type="462c0819:PsiDirectoryNode" />
<item name="images" type="462c0819:PsiDirectoryNode" />
</path>
<path>
<item name="tool-tech-front" type="b2602c69:ProjectViewProjectNode" />
<item name="tool-tech-front" type="462c0819:PsiDirectoryNode" />
<item name="src" type="462c0819:PsiDirectoryNode" />
</path>
<path>
<item name="tool-tech-front" type="b2602c69:ProjectViewProjectNode" />
<item name="tool-tech-front" type="462c0819:PsiDirectoryNode" />
<item name="src" type="462c0819:PsiDirectoryNode" />
<item name="views" type="462c0819:PsiDirectoryNode" />
</path>
<path>
<item name="tool-tech-front" type="b2602c69:ProjectViewProjectNode" />
<item name="tool-tech-front" type="462c0819:PsiDirectoryNode" />
<item name="src" type="462c0819:PsiDirectoryNode" />
<item name="views" type="462c0819:PsiDirectoryNode" />
<item name="document" type="462c0819:PsiDirectoryNode" />
</path>
<path>
<item name="tool-tech-front" type="b2602c69:ProjectViewProjectNode" />
<item name="tool-tech-front" type="462c0819:PsiDirectoryNode" />
<item name="src" type="462c0819:PsiDirectoryNode" />
<item name="views" type="462c0819:PsiDirectoryNode" />
<item name="tool" type="462c0819:PsiDirectoryNode" />
</path>
<path>
<item name="tool-tech-front" type="b2602c69:ProjectViewProjectNode" />
<item name="tool-tech-front" type="462c0819:PsiDirectoryNode" />
<item name="src" type="462c0819:PsiDirectoryNode" />
<item name="views" type="462c0819:PsiDirectoryNode" />
<item name="workflow" type="462c0819:PsiDirectoryNode" />
</path>
<path>
<item name="tool-tech-front" type="b2602c69:ProjectViewProjectNode" />
<item name="tool-tech-front" type="462c0819:PsiDirectoryNode" />
<item name="src" type="462c0819:PsiDirectoryNode" />
<item name="views" type="462c0819:PsiDirectoryNode" />
<item name="workflow" type="462c0819:PsiDirectoryNode" />
<item name="config" type="462c0819:PsiDirectoryNode" />
</path>
<path>
<item name="tool-tech-front" type="b2602c69:ProjectViewProjectNode" />
<item name="tool-tech-front" type="462c0819:PsiDirectoryNode" />
<item name="src" type="462c0819:PsiDirectoryNode" />
<item name="views" type="462c0819:PsiDirectoryNode" />
<item name="workstuff" type="462c0819:PsiDirectoryNode" />
</path>
<path>
<item name="tool-tech-front" type="b2602c69:ProjectViewProjectNode" />
<item name="tool-tech-front" type="462c0819:PsiDirectoryNode" />
<item name="src" type="462c0819:PsiDirectoryNode" />
<item name="views" type="462c0819:PsiDirectoryNode" />
<item name="workstuff" type="462c0819:PsiDirectoryNode" />
<item name="apply" type="462c0819:PsiDirectoryNode" />
</path>
<path>
<item name="tool-tech-front" type="b2602c69:ProjectViewProjectNode" />
<item name="tool-tech-front" type="462c0819:PsiDirectoryNode" />
<item name="src" type="462c0819:PsiDirectoryNode" />
<item name="views" type="462c0819:PsiDirectoryNode" />
<item name="workstuff" type="462c0819:PsiDirectoryNode" />
<item name="dispose" type="462c0819:PsiDirectoryNode" />
</path>
<path>
<item name="tool-tech-front" type="b2602c69:ProjectViewProjectNode" />
<item name="tool-tech-front" type="462c0819:PsiDirectoryNode" />
<item name="src" type="462c0819:PsiDirectoryNode" />
<item name="views" type="462c0819:PsiDirectoryNode" />
<item name="workstuff" type="462c0819:PsiDirectoryNode" />
<item name="message" type="462c0819:PsiDirectoryNode" />
</path>
</expand>
<select />
</subPane>
</pane>
<pane id="Scope" />
</panes>
</component>
<component name="PropertiesComponent">
<property name="SHARE_PROJECT_CONFIGURATION_FILES" value="true" />
<property name="WebServerToolWindowFactoryState" value="false" />
<property name="editor.config.ad.shown" value="true" />
<property name="last_opened_file_path" value="$PROJECT_DIR$" />
<property name="node.js.detected.package.eslint" value="true" />
<property name="node.js.path.for.package.eslint" value="project" />
<property name="node.js.selected.package.eslint" value="(autodetect)" />
<property name="nodejs_interpreter_path.stuck_in_default_project" value="undefined stuck path" />
<property name="nodejs_npm_path_reset_for_default_project" value="true" />
<property name="nodejs_package_manager_path" value="npm" />
<property name="ts.external.directory.path" value="D:\Program Files\JetBrains\WebStorm 2019.1.1\plugins\JavaScriptLanguage\jsLanguageServicesImpl\external" />
</component>
<component name="RecentsManager">
<key name="MoveFile.RECENT_KEYS">
<recent name="D:\rzdata\ToolTech\tool-tech-front\public" />
<recent name="D:\rzdata\ToolTech\tool-tech-front\public\css" />
<recent name="D:\rzdata\ToolTech\tool-tech-front\src\components" />
<recent name="D:\rzdata\ToolTech\tool-tech-front\src\components\userSelector" />
<recent name="D:\rzdata\ToolTech\tool-tech-front\src\views\workflow\config" />
</key>
<key name="CopyFile.RECENT_KEYS">
<recent name="D:\rzdata\ToolTech\tool-tech-front\src\views\workstuff\message" />
<recent name="D:\rzdata\ToolTech\tool-tech-front\src\views\workstuff\apply" />
<recent name="D:\rzdata\ToolTech\tool-tech-front\src\assets\logo" />
<recent name="D:\rzdata\ToolTech\tool-tech-front\public" />
<recent name="D:\rzdata\ToolTech\tool-tech-front\src\views\tool" />
</key>
</component>
<component name="RunDashboard">
<option name="ruleStates">
<list>
<RuleState>
<option name="name" value="ConfigurationTypeDashboardGroupingRule" />
</RuleState>
<RuleState>
<option name="name" value="StatusDashboardGroupingRule" />
</RuleState>
</list>
</option>
</component>
<component name="RunManager">
<configuration name="dev" type="js.build_tools.npm" temporary="true" nameIsGenerated="true">
<package-json value="$PROJECT_DIR$/package.json" />
<command value="run" />
<scripts>
<script value="dev" />
</scripts>
<node-interpreter value="project" />
<envs />
<method v="2" />
</configuration>
<recent_temporary>
<list>
<item itemvalue="npm.dev" />
</list>
</recent_temporary>
</component>
<component name="SvnConfiguration">
<configuration />
</component>
<component name="TaskManager">
<task active="true" id="Default" summary="Default task">
<changelist id="880b2c9e-bb63-49b5-a9b3-35bf50aa9da8" name="Default Changelist" comment="" />
<created>1720405215626</created>
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1720405215626</updated>
<workItem from="1720405216920" duration="31083000" />
<workItem from="1720607146890" duration="646000" />
<workItem from="1721005856925" duration="23394000" />
<workItem from="1721114973364" duration="3160000" />
<workItem from="1721185818138" duration="662000" />
<workItem from="1721611088644" duration="28182000" />
<workItem from="1721717492928" duration="8889000" />
<workItem from="1721783250517" duration="9602000" />
<workItem from="1721886425310" duration="2104000" />
<workItem from="1721896582395" duration="232000" />
</task>
<task id="LOCAL-00001" summary="update">
<created>1721110878122</created>
<option name="number" value="00001" />
<option name="presentableId" value="LOCAL-00001" />
<option name="project" value="LOCAL" />
<updated>1721110878122</updated>
</task>
<task id="LOCAL-00002" summary="update">
<created>1721118453675</created>
<option name="number" value="00002" />
<option name="presentableId" value="LOCAL-00002" />
<option name="project" value="LOCAL" />
<updated>1721118453676</updated>
</task>
<task id="LOCAL-00003" summary="update">
<created>1721122463517</created>
<option name="number" value="00003" />
<option name="presentableId" value="LOCAL-00003" />
<option name="project" value="LOCAL" />
<updated>1721122463517</updated>
</task>
<task id="LOCAL-00004" summary="update">
<created>1721123161293</created>
<option name="number" value="00004" />
<option name="presentableId" value="LOCAL-00004" />
<option name="project" value="LOCAL" />
<updated>1721123161293</updated>
</task>
<task id="LOCAL-00005" summary="update">
<created>1721632270841</created>
<option name="number" value="00005" />
<option name="presentableId" value="LOCAL-00005" />
<option name="project" value="LOCAL" />
<updated>1721632270841</updated>
</task>
<task id="LOCAL-00006" summary="update">
<created>1721886526500</created>
<option name="number" value="00006" />
<option name="presentableId" value="LOCAL-00006" />
<option name="project" value="LOCAL" />
<updated>1721886526500</updated>
</task>
<task id="LOCAL-00007" summary="update">
<created>1721888702083</created>
<option name="number" value="00007" />
<option name="presentableId" value="LOCAL-00007" />
<option name="project" value="LOCAL" />
<updated>1721888702083</updated>
</task>
<option name="localTasksCounter" value="8" />
<servers />
</component>
<component name="TimeTrackingManager">
<option name="totallyTimeSpent" value="107954000" />
</component>
<component name="TodoView">
<todo-panel id="selected-file">
<is-autoscroll-to-source value="true" />
</todo-panel>
<todo-panel id="all">
<are-packages-shown value="true" />
<is-autoscroll-to-source value="true" />
</todo-panel>
</component>
<component name="ToolWindowManager">
<frame x="-7" y="-7" width="1935" height="1167" extended-state="6" />
<editor active="true" />
<layout>
<window_info active="true" content_ui="combo" id="Project" order="0" sideWeight="0.4925865" visible="true" weight="0.24960506" />
<window_info id="Structure" order="1" side_tool="true" weight="0.25" />
<window_info id="npm" order="2" sideWeight="0.5074135" side_tool="true" weight="0.24960506" />
<window_info id="Favorites" order="3" side_tool="true" />
<window_info anchor="bottom" id="Message" order="0" />
<window_info anchor="bottom" id="Find" order="1" />
<window_info anchor="bottom" id="Run" order="2" weight="0.27439612" />
<window_info anchor="bottom" id="Debug" order="3" weight="0.4" />
<window_info anchor="bottom" id="Cvs" order="4" weight="0.25" />
<window_info anchor="bottom" id="Inspection" order="5" weight="0.4" />
<window_info anchor="bottom" id="TODO" order="6" weight="0.3291506" />
<window_info anchor="bottom" id="Docker" order="7" show_stripe_button="false" />
<window_info anchor="bottom" id="Version Control" order="8" />
<window_info anchor="bottom" id="TypeScript" order="9" />
<window_info anchor="bottom" id="Event Log" order="10" side_tool="true" />
<window_info anchor="bottom" id="Terminal" order="11" weight="0.3291506" />
<window_info anchor="right" id="Commander" internal_type="SLIDING" order="0" type="SLIDING" weight="0.4" />
<window_info anchor="right" id="Ant Build" order="1" weight="0.25" />
<window_info anchor="right" content_ui="combo" id="Hierarchy" order="2" weight="0.25" />
</layout>
</component>
<component name="TypeScriptGeneratedFilesManager">
<option name="version" value="1" />
</component>
<component name="VcsManagerConfiguration">
<MESSAGE value="update" />
<option name="LAST_COMMIT_MESSAGE" value="update" />
</component>
<component name="editorHistoryManager">
<entry file="file://$PROJECT_DIR$/src/views/tool/index2.vue" />
<entry file="file://D:/日常工作文件库/泛联睿展联合项目/工具管理及技术交流平台/昆明军工/原型静态页面/工具管理及技术交流平台/我的申请.html">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="213">
<caret line="167" column="3" lean-forward="true" selection-start-line="167" selection-start-column="3" selection-end-line="342" selection-end-column="6" />
<folding>
<element signature="n#div#0;n#div#0;n#body#0;n#html#0;n#!!top" />
</folding>
</state>
</provider>
</entry>
<entry file="file://D:/日常工作文件库/泛联睿展联合项目/工具管理及技术交流平台/昆明军工/原型静态页面/工具管理及技术交流平台/我的办理.html">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="211">
<caret line="178" column="4" selection-start-line="178" selection-start-column="4" selection-end-line="551" selection-end-column="5" />
<folding>
<element signature="n#div#0;n#div#0;n#body#0;n#html#0;n#!!top" />
<element signature="e#8535#15422#0" />
</folding>
</state>
</provider>
</entry>
<entry file="file://D:/日常工作文件库/泛联睿展联合项目/工具管理及技术交流平台/昆明军工/原型静态页面/工具管理及技术交流平台/消息中心.html">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="460">
<caret line="93" column="5" selection-start-line="53" selection-start-column="4" selection-end-line="93" selection-end-column="5" />
<folding>
<element signature="n#div#0;n#div#0;n#body#0;n#html#0;n#!!top" />
<element signature="e#1925#2492#0" />
</folding>
</state>
</provider>
</entry>
<entry file="file://D:/日常工作文件库/泛联睿展联合项目/工具管理及技术交流平台/昆明军工/原型静态页面/工具管理及技术交流平台/文档资源统计.html">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="228">
<caret line="44" column="30" lean-forward="true" selection-start-line="12" selection-start-column="4" selection-end-line="44" selection-end-column="30" />
<folding>
<element signature="n#div#0;n#div#0;n#body#0;n#html#0;n#!!top" />
</folding>
</state>
</provider>
</entry>
<entry file="file://D:/日常工作文件库/泛联睿展联合项目/工具管理及技术交流平台/昆明军工/原型静态页面/工具管理及技术交流平台/工具统计.html">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="228">
<caret line="44" column="30" lean-forward="true" selection-start-line="12" selection-start-column="4" selection-end-line="44" selection-end-column="30" />
<folding>
<element signature="n#div#0;n#div#0;n#body#0;n#html#0;n#!!top" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/views/statistic/index.vue">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="19">
<caret line="1" column="27" selection-start-line="1" selection-start-column="27" selection-end-line="1" selection-end-column="27" />
<folding>
<element signature="n#div#0;n#el-tab-pane#1;n#el-tabs#0;n#div#0;n#template#0;n#!!top" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/store/getters.js">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="190">
<caret line="10" column="10" selection-start-line="10" selection-start-column="10" selection-end-line="10" selection-end-column="10" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/store/modules/user.js">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="190">
<caret line="70" column="47" selection-start-line="70" selection-start-column="47" selection-end-line="70" selection-end-column="47" />
<folding>
<element signature="e#0#52#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/layout/components/Sidebar/Logo.vue">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="152">
<caret line="8" column="60" lean-forward="true" selection-start-line="8" selection-start-column="60" selection-end-line="8" selection-end-column="60" />
<folding>
<element signature="e#930#974#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/layout/components/Navbar.vue">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="266">
<caret line="14" selection-start-line="14" selection-end-line="14" />
<folding>
<element signature="n#style#0;n#span#0;n#div#0;n#el-dropdown#0;n#div#0;n#div#0;n#template#0;n#!!top" expanded="true" />
<element signature="e#1293#1326#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/views/login.vue">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="95">
<caret line="5" column="46" selection-start-line="5" selection-start-column="46" selection-end-line="5" selection-end-column="46" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/components/Breadcrumb/index.vue">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="205">
<caret line="36" column="8" selection-start-line="36" selection-start-column="6" selection-end-line="38" selection-end-column="9" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/router/index.js">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="395">
<caret line="72" column="63" selection-start-line="71" selection-start-column="8" selection-end-line="72" selection-end-column="63" />
<folding>
<element signature="e#0#21#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/views/index.vue">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="537">
<caret line="63" column="13" selection-start-line="63" selection-start-column="13" selection-end-line="63" selection-end-column="13" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/views/system/user/authRole.vue">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="347">
<caret line="40" column="37" lean-forward="true" selection-start-line="40" selection-start-column="37" selection-end-line="40" selection-end-column="37" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/views/monitor/job/index.vue">
<provider selected="true" editor-type-id="text-editor" />
</entry>
<entry file="file://D:/日常工作文件库/泛联睿展联合项目/工具管理及技术交流平台/昆明军工/原型静态页面/工具管理及技术交流平台/用户管理.html">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="266">
<caret line="14" column="30" lean-forward="true" selection-start-line="14" selection-start-column="8" selection-end-line="14" selection-end-column="30" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/views/system/post/index.vue">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="423">
<caret line="64" column="17" lean-forward="true" selection-start-line="64" selection-start-column="17" selection-end-line="64" selection-end-column="17" />
<folding>
<element signature="n#el-form#0;n#el-card#0;n#div#0;n#template#0;n#!!top" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/views/system/config/index.vue">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="95">
<caret line="85" column="17" lean-forward="true" selection-start-line="85" selection-start-column="17" selection-end-line="85" selection-end-column="17" />
<folding>
<element signature="n#el-form#0;n#el-card#0;n#div#0;n#template#0;n#!!top" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/views/system/menu/index.vue">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="133">
<caret line="30" column="29" lean-forward="true" selection-start-line="28" selection-start-column="4" selection-end-line="30" selection-end-column="29" />
<folding>
<element signature="n#el-form#0;n#el-card#0;n#div#0;n#template#0;n#!!top" />
<element signature="n#el-table#0;n#div#0;n#el-card#1;n#div#0;n#template#0;n#!!top" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/views/system/notice/index.vue">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="494">
<caret line="57" column="17" lean-forward="true" selection-start-line="57" selection-start-column="17" selection-end-line="57" selection-end-column="17" />
<folding>
<element signature="n#el-form#0;n#el-card#0;n#div#0;n#template#0;n#!!top" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/views/monitor/operlog/index.vue">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="119">
<caret line="82" column="29" lean-forward="true" selection-start-line="80" selection-start-column="4" selection-end-line="82" selection-end-column="29" />
<folding>
<element signature="n#el-form#0;n#el-card#0;n#div#0;n#template#0;n#!!top" />
<element signature="n#el-table#0;n#div#0;n#el-card#1;n#div#0;n#template#0;n#!!top" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/views/system/tool/gen/index.vue">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="38">
<caret line="2" column="4" selection-start-line="2" selection-start-column="4" selection-end-line="2" selection-end-column="13" />
<folding>
<element signature="n#el-form#0;n#el-card#0;n#div#0;n#template#0;n#!!top" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/views/system/dict/index.vue">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="152">
<caret line="57" column="29" lean-forward="true" selection-start-line="55" selection-start-column="4" selection-end-line="57" selection-end-column="29" />
<folding>
<element signature="n#el-form#0;n#el-card#0;n#div#0;n#template#0;n#!!top" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/views/system/dict/data.vue">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="133">
<caret line="67" column="17" lean-forward="true" selection-start-line="67" selection-start-column="17" selection-end-line="67" selection-end-column="17" />
<folding>
<element signature="n#el-form#0;n#el-card#0;n#div#0;n#template#0;n#!!top" />
<element signature="n#el-table#0;n#div#0;n#el-card#1;n#div#0;n#template#0;n#!!top" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/views/system/dept/index.vue">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="266">
<caret line="55" column="55" selection-start-line="55" selection-start-column="55" selection-end-line="55" selection-end-column="55" />
<folding>
<element signature="n#el-form#0;n#el-card#0;n#div#0;n#template#0;n#!!top" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/views/system/role/index.vue">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="95">
<caret line="54" column="4" selection-start-line="54" selection-start-column="4" selection-end-line="56" selection-end-column="29" />
<folding>
<element signature="n#el-form#0;n#el-card#0;n#div#0;n#template#0;n#!!top" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/views/system/role/authUser.vue">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="423">
<caret line="53" column="25" selection-start-line="53" selection-start-column="25" selection-end-line="53" selection-end-column="25" />
<folding>
<element signature="n#el-form#0;n#el-card#0;n#div#0;n#template#0;n#!!top" />
<element signature="n#el-table#0;n#div#0;n#el-card#1;n#div#0;n#template#0;n#!!top" />
</folding>
</state>
</provider>
</entry>
<entry file="file://D:/日常工作文件库/泛联睿展联合项目/工具管理及技术交流平台/昆明军工/原型静态页面/工具管理及技术交流平台/文档资源管理.html">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="195">
<caret line="85" selection-start-line="85" selection-end-line="143" />
<folding>
<element signature="n#style#0;n#el-table#0;n#div#1;n#el-card#0;n#div#0;n#div#0;n#body#0;n#html#0;n#!!top" expanded="true" />
<element signature="n#el-drawer#0;n#div#0;n#div#0;n#body#0;n#html#0;n#!!top" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/api/document/document.js">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="551">
<caret line="29" column="38" selection-start-line="29" selection-start-column="38" selection-end-line="29" selection-end-column="38" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/components/user-selector/src/user-selector.vue">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="3040">
<caret line="164" column="6" selection-start-line="164" selection-start-column="6" selection-end-line="167" selection-end-column="8" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/public/css/tool.css">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="12996">
<caret line="684" column="37" selection-start-line="684" selection-start-column="31" selection-end-line="684" selection-end-column="37" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/public/css/poctstyle.css">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="114">
<caret line="6" column="14" selection-start-line="6" selection-start-column="14" selection-end-line="6" selection-end-column="14" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/views/monitor/logininfor/index.vue">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="152">
<caret line="58" column="29" lean-forward="true" selection-start-line="58" selection-start-column="29" selection-end-line="58" selection-end-column="29" />
<folding>
<element signature="n#el-form#0;n#el-card#0;n#div#0;n#template#0;n#!!top" />
<element signature="n#el-table#0;n#div#0;n#el-card#1;n#div#0;n#template#0;n#!!top" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/views/system/user/index.vue">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="3610">
<caret line="287" column="12" lean-forward="true" selection-start-line="284" selection-start-column="6" selection-end-line="287" selection-end-column="12" />
<folding>
<element signature="n#el-form#0;n#el-dialog#0;n#div#0;n#template#0;n#!!top" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/views/document/uploadProgress.vue">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="722">
<caret line="38" column="32" selection-start-line="38" selection-start-column="10" selection-end-line="38" selection-end-column="32" />
<folding>
<element signature="n#style#0;n#el-button#0;n#div#0;n#el-card#0;n#div#0;n#div#0;n#template#0;n#!!top" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/views/document/index.vue">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="1311">
<caret line="69" column="40" selection-start-line="69" selection-start-column="22" selection-end-line="69" selection-end-column="40" />
<folding>
<element signature="n#pagination#0;n#div#1;n#el-card#1;n#div#0;n#template#0;n#!!top" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/views/workstuff/apply/index.vue">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="646">
<caret line="34" column="38" selection-start-line="34" selection-start-column="26" selection-end-line="34" selection-end-column="38" />
<folding>
<element signature="n#style#0;n#el-table#0;n#el-card#1;n#div#0;n#template#0;n#!!top" expanded="true" />
<element signature="n#style#0;n#img#0;n#el-drawer#1;n#div#0;n#template#0;n#!!top" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/main.js">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="114">
<caret line="6" column="18" selection-start-line="6" selection-start-column="12" selection-end-line="6" selection-end-column="18" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/views/workstuff/dispose/index.vue">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="6099">
<caret line="321" column="10" selection-start-line="298" selection-start-column="8" selection-end-line="321" selection-end-column="10" />
<folding>
<element signature="n#style#0;n#img#0;n#el-drawer#1;n#div#0;n#template#0;n#!!top" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/views/workstuff/message/index.vue">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="722">
<caret line="38" column="4" selection-start-line="38" selection-start-column="4" selection-end-line="45" selection-end-column="40" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/views/tool/index.vue">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="2356">
<caret line="177" column="132" selection-start-line="177" selection-start-column="96" selection-end-line="177" selection-end-column="132" />
<folding>
<element signature="n#el-form#0;n#el-card#0;n#div#0;n#template#0;n#!!top" />
<element signature="n#style#0;n#el-select#0;n#el-form-item#2;n#div#0;n#div#0;n#div#0;n#el-form#0;n#el-card#0;n#div#0;n#template#0;n#!!top" expanded="true" />
<element signature="n#style#0;n#el-date-picker#0;n#el-form-item#3;n#div#0;n#div#0;n#div#0;n#el-form#0;n#el-card#0;n#div#0;n#template#0;n#!!top" expanded="true" />
<element signature="n#style#0;n#el-input#0;n#div#0;n#el-card#1;n#div#0;n#template#0;n#!!top" expanded="true" />
<element signature="n#style#0;n#el-select#0;n#el-form-item#0;n#el-col#0;n#el-row#3;n#el-form#0;n#div#0;n#el-drawer#0;n#div#0;n#template#0;n#!!top" expanded="true" />
<element signature="n#el-drawer#2;n#div#0;n#template#0;n#!!top" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/views/tool/toolDetail.vue">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="2451">
<caret line="129" column="50" selection-start-line="129" selection-start-column="50" selection-end-line="129" selection-end-column="50" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/plugins/modal.js">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="266">
<caret line="14" column="2" selection-start-line="14" selection-start-column="2" selection-end-line="14" selection-end-column="2" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/views/document/editDocument.vue">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="2603">
<caret line="139" column="12" lean-forward="true" selection-start-line="139" selection-start-column="12" selection-end-line="139" selection-end-column="12" />
<folding>
<element signature="n#style#0;n#el-table#0;n#div#0;n#el-dialog#0;n#div#0;n#template#0;n#!!top" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/.env.development">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="228">
<caret line="12" selection-start-line="12" selection-end-line="16" selection-end-column="75" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/.env.production">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="19">
<caret line="1" column="27" selection-start-line="1" selection-start-column="27" selection-end-line="1" selection-end-column="27" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/views/workflow/config/index.vue">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="247">
<caret line="13" column="103" selection-start-line="13" selection-start-column="72" selection-end-line="13" selection-end-column="103" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/default.conf">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="475">
<caret line="25" column="36" lean-forward="true" selection-start-line="25" selection-start-column="36" selection-end-line="25" selection-end-column="36" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/.env.staging">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="342">
<caret line="18" column="31" selection-start-line="18" selection-start-column="31" selection-end-line="18" selection-end-column="31" />
</state>
</provider>
</entry>
</component>
</project>

View File

@ -1,4 +1,4 @@
FROM docker.m.daocloud.io/nginx:1.21.1-alpine
FROM nginx:1.21.1-alpine
COPY ./dist /usr/share/nginx/html/tool-tech
COPY default.conf /etc/nginx/conf.d/
EXPOSE 80

View File

@ -15,28 +15,20 @@ server {
}
}
location ^~/tool-tech-admin/ {
proxy_pass http://124.223.108.21:8080/tool-tech-admin/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_ssl_verify off;
location /ebpm-process-manage/ {
proxy_pass http://192.168.1.2:8080/ebpm-process-manage/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location ^~/tool-tech-file-view/ {
proxy_pass http://124.223.108.21:8012/tool-tech-file-view/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_ssl_verify off;
}
location ^~/ebpm-process-manage/ {
proxy_pass http://124.223.108.21:9080/ebpm-process-manage/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_ssl_verify off;
location /tool-tech-file-view/ {
proxy_pass http://192.168.1.2:8012/tool-tech-file-view/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
error_page 500 502 503 504 /50x.html;

View File

@ -32,40 +32,30 @@
],
"dependencies": {
"@riophae/vue-treeselect": "0.4.0",
"@vue-office/docx": "1.6.1",
"@vue-office/pdf": "1.6.5",
"axios": "0.24.0",
"clipboard": "2.0.8",
"core-js": "3.37.1",
"docxtemplater": "3.50.0",
"docxtemplater-image-module-free": "1.1.1",
"echarts": "5.4.0",
"element-ui": "2.15.14",
"file-save": "0.2.0",
"file-saver": "2.0.5",
"fuse.js": "6.4.3",
"highlight.js": "9.18.5",
"js-base64": "^3.7.7",
"js-cookie": "3.0.1",
"jsencrypt": "3.0.0-rc.1",
"jszip": "3.10.1",
"jszip-utils": "0.1.0",
"nprogress": "0.2.0",
"pizzip": "3.1.7",
"quill": "1.3.7",
"screenfull": "5.0.2",
"sockjs-client": "^1.6.1",
"sortablejs": "1.10.2",
"v-viewer": "1.6.4",
"vue": "2.6.12",
"vue-count-to": "1.0.13",
"vue-cropper": "0.5.5",
"vue-demi": "^0.14.10",
"vue-iframe": "0.0.0",
"vue-json-viewer": "2.2.22",
"vue-meta": "2.4.0",
"vue-router": "3.4.9",
"vue-video-player": "5.0.1",
"vuex": "3.6.0"
"vuex": "3.6.0",
"websocket": "^1.0.35"
},
"devDependencies": {
"@vue/cli-plugin-babel": "4.4.6",
@ -84,7 +74,6 @@
"sass-loader": "10.1.1",
"script-ext-html-webpack-plugin": "2.1.5",
"svg-sprite-loader": "5.1.1",
"@vue/composition-api": "1.7.2",
"vue-template-compiler": "2.6.12"
},
"engines": {

File diff suppressed because it is too large Load Diff

View File

@ -1,19 +0,0 @@
{#list}
{resName}
文档编号
{docCode}
文档名称
{docName}
文档类别
{docTypeName}
负责人
{docPrincipals}
归属单位
{docRespDeptName}
文档来源
{docSourceName}
文档状态
{statusName}
创建时间
{createTime}
{/list}

View File

@ -197,12 +197,12 @@
</head>
<body>
<div id="app">
<!-- <div id="loader-wrapper">
<div id="loader-wrapper">
<div id="loader"></div>
<div class="loader-section section-left"></div>
<div class="loader-section section-right"></div>
<div class="load_title">正在加载系统资源,请耐心等待</div>
</div>-->
</div>
</div>
</body>
</html>

View File

@ -1,34 +0,0 @@
{#list}
{index}、{toolName}
编号
{toolCode}
中文别名
{toolName}
来源
{toolSourceName}
形态
{statusName}
类别
{toolTypeName}
用途
{toolUse}
测评机构
{testSituation}
功能简介
{functionDesc}
适用条件
{applyCondition}
加密方式
{encryptionMode}
服务时间
{serviceTime}
归属单位
{toolRespDeptName}
联系人
{contactPerson}
联系方式
{contactPhone}
备注
{remark}
表 {index}
{/list}

View File

@ -7,9 +7,6 @@
<script>
import ThemePicker from "@/components/ThemePicker";
import store from '@/store'
import { Message } from 'element-ui'
import { getToken } from '@/utils/auth'
export default {
name: "App",
@ -21,14 +18,6 @@ export default {
return title ? `${title} - ${process.env.VUE_APP_TITLE}` : process.env.VUE_APP_TITLE
}
}
},
created() {
if (getToken()) {
store.dispatch('GetUserMsgCount').then(() => { })
}
},
methods:{
}
};
</script>

View File

@ -1,44 +0,0 @@
import request from '@/utils/request'
// 查询附件列表
export function listAttachment(query) {
return request({
url: '/system/attachment/list',
method: 'get',
params: query
})
}
// 查询附件详细
export function getAttachment(id) {
return request({
url: '/system/attachment/' + id,
method: 'get'
})
}
// 新增附件
export function addAttachment(data) {
return request({
url: '/system/attachment',
method: 'post',
data: data
})
}
// 修改附件
export function updateAttachment(data) {
return request({
url: '/system/attachment',
method: 'put',
data: data
})
}
// 删除附件
export function delAttachment(id) {
return request({
url: '/system/attachment/' + id,
method: 'delete'
})
}

View File

@ -42,33 +42,3 @@ export function delDocument(id) {
method: 'delete'
})
}
// 发布文档
export function pushDoc(id) {
return request({
url: '/document/pushDoc/' + id,
method: 'put'
})
}
// 获取统计信息
export function getStatistics(query) {
return request({
url: '/document/statistics',
method: 'get',
params: query
})
}
// 查询【请填写功能名称】列表
export function getExportWordList(query) {
return request({
url: '/document/export/word/list',
method: 'post',
data: query
})
}

View File

@ -1,55 +0,0 @@
import request from '@/utils/request'
// 查询文档资源分类管理列表
export function listCategory(query) {
return request({
url: '/system/category/list',
method: 'get',
params: query
})
}
// 查询文档资源分类管理详细
export function getCategory(id) {
return request({
url: '/system/category/' + id,
method: 'get'
})
}
// 新增文档资源分类管理
export function addCategory(data) {
return request({
url: '/system/category',
method: 'post',
data: data
})
}
// 修改文档资源分类管理
export function updateCategory(data) {
return request({
url: '/system/category',
method: 'put',
data: data
})
}
// 删除文档资源分类管理
export function delCategory(id) {
return request({
url: '/system/category/' + id,
method: 'delete'
})
}
// 获取文档分类树列表
export function documentTree(query) {
return request({
url: '/system/category/documentTree',
method: 'get',
params: query
})
}

View File

@ -1,63 +1,45 @@
import request from '@/utils/request'
// 查询消息列表
export function listMessage(query) {
return request({
url: '/system/message/list',
method: 'get',
params: query
/**
* 查询消息列表
* @returns
*/
export function getMessageList(params) {
return Promise.resolve({
total: 5,
rows: [
{ id: 1, msgContent: '工具名称为00071已发布成功', msgRecTime: '2024-08-05 12:31:59', msgStatus: 'unread' },
{ id: 2, msgContent: '工具名称为00071申请使用已审核通过', msgRecTime: '2024-08-05 13:32:01', msgStatus: 'readed' },
{ id: 3, msgContent: '工具名称为00073已发布成功', msgRecTime: '2024-08-05 14:09:07', msgStatus: 'unread' },
// { id: 4, msgContent: '测试4444', msgRecTime: '2024-08-05 15:37:10', msgStatus: 'readed' },
// { id: 5, msgContent: '测试5555', msgRecTime: '2024-08-05 17:29:39', msgStatus: 'unread' }
],
code: 200,
msg: '操作成功'
})
}
// 查询消息详细
export function getMessage(id) {
return request({
url: '/system/message/' + id,
method: 'get'
/**
* 标记所有已读
* @returns
*/
export function markAllRead() {
return Promise.resolve({
result: {},
code: 200,
msg: '操作成功'
})
}
// 新增消息
export function addMessage(data) {
return request({
url: '/system/message',
method: 'post',
data: data
/**
* 根据id标记单个已读
* @returns
*/
export function markReadById(id) {
return Promise.resolve({
result: {},
code: 200,
msg: '操作成功'
})
}
// 修改消息
export function updateMessage(data) {
return request({
url: '/system/message',
method: 'put',
data: data
})
}
// 删除消息
export function delMessage(id) {
return request({
url: '/system/message/' + id,
method: 'delete'
})
}
// 全部标记已读
export function allMarkedRead(data) {
return request({
url: '/system/message/allMarkedRead',
method: 'post',
data: data
})
}
// 获取用户统计
export function getUserMsgCount(id) {
return request({
url: '/system/message/user/msg/count/' + id,
method: 'get'
})
}

View File

@ -1,195 +0,0 @@
import request from '@/utils/request'
// 审批记录
export function workflowGetLog(data) {
return request({
url: '/workflow/getLog',
method: 'post',
data: data
})
}
//流程实例撤回到拟稿人环节
export function workflowbacktostart(data) {
return request({
url: '/workflow/backtostart',
method: 'post',
data: data,
timeout: 30*60*1000
})
}
// 获取流程环节定义信息
export function activitydefinition(procDefId, actDefId) {
return request({
url: '/workflow/activitydefinition/' + procDefId + '/' + actDefId,
method: 'get',
})
}
// 查询列表
export function workflowToDoList(data) {
return request({
url: '/workflow/toDoList',
method: 'post',
data: data
})
}
// 新建流程,获取下一环节流程定义信息
export function workflowNextactsNew(data) {
return request({
url: '/workflow/nextacts/new',
method: 'post',
data: data
})
}
// 新建流程,获取下一环节流程定义信息
// 获取下一环节集合,并可以标识已办和自动将未办理环节优先排序
export function workflowNextactsNew2(data) {
return request({
url: '/workflow/nextacts/new2',
method: 'post',
data: data
})
}
// 查询流程审批记录列表
export function processWorkflowGetList(businessId) {
return request({
url: '/process/workflowLog/list' + '?pageNum=1&pageSize=100&businessId=' + businessId,
method: 'get',
})
}
export function getNextactuserByPending(query) {
return request({
url: '/workflow/nextactuser/pending',
method: 'get',
params: query
})
}
export function getNextActUsersByNew(query) {
return request({
url: '/workflow/nextactuser/new',
method: 'get',
params: query
})
}
export function workflowSubmit(data) {
return request({
url: '/workflow/submit',
method: 'post',
data: data
})
}
export function workflowCancel(data) {
return request({
url: '/workflow/cancel',
method: 'post',
data: data
})
}
export function workflowReject(data) {
return request({
url: '/workflow/reject',
method: 'post',
data: data
})
}
export function workflowBacktoprev(data) {
return request({
url: '/workflow/backtoprev',
method: 'post',
data: data
})
}
export function getHistAskLogUrl(procInstId) {
return request({
url: '/workflow/histasklogurl/' + procInstId,
method: 'get',
})
}
export function getExtAttributeModel(procDefId, actDefId) {
return request({
url: '/workflow/getExtAttributeModel/?procDefId=' + procDefId + "&actDefId=" + actDefId,
method: 'get',
})
}
export function selectLogByBusinessId(query) {
return request({
url: '/process/workflowLog/selectLogByBusinessId?businessId' + query,
method: 'get',
})
}
export function workflowprocesskey(query) {
return request({
url: '/workflow/process/key/' + query,
method: 'get',
})
}
export function getStartActdef(procDefId) {
return request({
url: '/workflow/startactdef/' + procDefId,
method: 'get',
})
}
// 根据流程实例id获取流程实例信息和流程状态
export function procInstInfoAndStatus(procInstId) {
return request({
url: '/workflow/procInstInfoAndStatus/' + procInstId,
method: 'get',
})
}
// 根据流程实例id获取流程实例信息
export function getProcInstInfo(procInstId) {
return request({
url: '/workflow/procInstInfo/' + procInstId,
method: 'get',
})
}
export function selectLogByProcInstId(query) {
return request({
url: '/web/log/list',
method: 'get',
params: query
})
}
// 获取流程待选人员展示方式
export function selectUserStyle() {
return request({
url: '/workflow/selectUserStyle',
method: 'get',
})
}
// 根据流程实例id获取流程实例信息
export function getRecordbyPorcInstId(procInstId) {
return request({
url: '/workflow/getRecord/' + procInstId,
method: 'get',
})
}
export function getUserMsgCount() {
return request({
url: '/workflow/msg/count/',
method: 'get',
})
}

View File

@ -9,15 +9,6 @@ export function listType(query) {
})
}
// 查询业务字典类型列表(扩展)
export function bizListType(query) {
return request({
url: '/system/dict/type/bizlist',
method: 'get',
params: query
})
}
// 查询字典类型详细
export function getType(dictId) {
return request({

View File

@ -127,11 +127,10 @@ export function updateAuthRole(data) {
}
// 查询部门下拉树结构
export function deptTreeSelect(query) {
export function deptTreeSelect() {
return request({
url: '/system/user/deptTree',
method: 'get',
params: query
method: 'get'
})
}

View File

@ -1,44 +0,0 @@
import request from '@/utils/request'
// 查询讨论列表
export function listDiscussions(query) {
return request({
url: '/discussions/list',
method: 'get',
params: query
})
}
// 查询讨论详细
export function getDiscussions(id) {
return request({
url: '/discussions/' + id,
method: 'get'
})
}
// 新增讨论
export function addDiscussions(data) {
return request({
url: '/discussions',
method: 'post',
data: data
})
}
// 修改讨论
export function updateDiscussions(data) {
return request({
url: '/discussions',
method: 'put',
data: data
})
}
// 删除讨论
export function delDiscussions(id) {
return request({
url: '/discussions/' + id,
method: 'delete'
})
}

View File

@ -1,65 +0,0 @@
import request from '@/utils/request'
// 查询工具下载统计列表
export function listCount(query) {
return request({
url: '/system/count/list',
method: 'get',
params: query
})
}
// 查询工具下载统计列表
export function listDocCount(query) {
return request({
url: '/system/count/doc/list',
method: 'get',
params: query
})
}
// 根据详情统计
export function userDownList(query) {
return request({
url: '/system/count/user/down/list',
method: 'get',
params: query
})
}
// 查询工具下载统计详细
export function getCount(id) {
return request({
url: '/system/count/' + id,
method: 'get'
})
}
// 新增工具下载统计
export function addCount(data) {
return request({
url: '/system/count',
method: 'post',
data: data
})
}
// 修改工具下载统计
export function updateCount(data) {
return request({
url: '/system/count',
method: 'put',
data: data
})
}
// 删除工具下载统计
export function delCount(id) {
return request({
url: '/system/count/' + id,
method: 'delete'
})
}

View File

@ -1,44 +0,0 @@
import request from '@/utils/request'
// 查询回复列表
export function listReplies(query) {
return request({
url: '/system/replies/list',
method: 'get',
params: query
})
}
// 查询回复详细
export function getReplies(id) {
return request({
url: '/replies/' + id,
method: 'get'
})
}
// 新增回复
export function addReplies(data) {
return request({
url: '/replies',
method: 'post',
data: data
})
}
// 修改回复
export function updateReplies(data) {
return request({
url: '/replies',
method: 'put',
data: data
})
}
// 删除回复
export function delReplies(id) {
return request({
url: '/replies/' + id,
method: 'delete'
})
}

View File

@ -17,29 +17,20 @@ export function getTool(toolId) {
})
}
export function getInfoByBpmcId(bpmcId) {
return request({
url: '/tool/bpmc/' + bpmcId,
method: 'get'
})
}
// 新增工具信息
export function addTool(data) {
return request({
url: '/tool',
method: 'post',
data: data,
timeout: 30*60*1000
data: data
})
}
// 修改工具信息
export function updateTool(data) {
return request({
url: '/tool/edit',
method: 'post',
url: '/tool',
method: 'put',
data: data
})
}
@ -51,30 +42,3 @@ export function delTool(toolId) {
method: 'delete'
})
}
export function checkToolExist(params) {
return request({
url: '/tool/checkToolExist',
method: 'get',
params: params
})
}
// 获取统计信息
export function getStatistics(query) {
return request({
url: '/tool/statistics',
method: 'get',
params: query
})
}
// get导出word字段
export function exportWordList(query) {
return request({
url: '/tool/export/word/list',
method: 'post',
data: query
})
}

View File

@ -1,51 +0,0 @@
import request from '@/utils/request'
// 查询使用申请列表
export function listApply(query) {
return request({
url: '/tool/apply/list',
method: 'get',
params: query
})
}
// 查询使用申请详细
export function getApply(id) {
return request({
url: '/tool/apply/' + id,
method: 'get'
})
}
export function getInfoByBpmcId(bpmcId) {
return request({
url: '/tool/apply/bpmc/' + bpmcId,
method: 'get'
})
}
// 新增使用申请
export function addApply(data) {
return request({
url: '/tool/apply',
method: 'post',
data: data
})
}
// 修改使用申请
export function updateApply(data) {
return request({
url: '/tool/apply/edit',
method: 'post',
data: data
})
}
// 删除使用申请
export function delApply(id) {
return request({
url: '/tool/apply/' + id,
method: 'delete'
})
}

View File

@ -1,53 +0,0 @@
import request from '@/utils/request'
// 查询tool_relation列表
export function listRelation(query) {
return request({
url: '/system/relation/list',
method: 'get',
params: query
})
}
// 查询tool_relation详细
export function getRelation(id) {
return request({
url: '/system/relation/' + id,
method: 'get'
})
}
// 新增tool_relation
export function addRelation(data) {
return request({
url: '/system/relation',
method: 'post',
data: data
})
}
// 修改tool_relation
export function updateRelation(data) {
return request({
url: '/system/relation',
method: 'put',
data: data
})
}
// 删除tool_relation
export function delRelation(id) {
return request({
url: '/system/relation/' + id,
method: 'delete'
})
}
// 获取关联树列表
export function getDataThree(data) {
return request({
url: '/system/relation/get/three',
method: 'post',
data: data
})
}

View File

@ -1,44 +0,0 @@
import request from '@/utils/request'
// 查询使用申请详情列表
export function listItem(query) {
return request({
url: '/use/apply/item/list',
method: 'get',
params: query
})
}
// 查询使用申请详情详细
export function getItem(id) {
return request({
url: '/use/apply/item/' + id,
method: 'get'
})
}
// 新增使用申请详情
export function addItem(data) {
return request({
url: '/use/apply/item',
method: 'post',
data: data
})
}
// 修改使用申请详情
export function updateItem(data) {
return request({
url: '/use/apply/item',
method: 'put',
data: data
})
}
// 删除使用申请详情
export function delItem(id) {
return request({
url: '/use/apply/item/' + id,
method: 'delete'
})
}

View File

@ -25,7 +25,7 @@
<el-form-item>
<el-radio v-model='radioValue' :label="4">
指定
<el-select clearable v-model="checkboxList" placeholder="可多选" multiple ·>
<el-select clearable v-model="checkboxList" placeholder="可多选" multiple style="width:100%">
<el-option v-for="item in 24" :key="item" :value="item-1">{{item-1}}</el-option>
</el-select>
</el-radio>

View File

@ -1,107 +0,0 @@
<template>
<div>
<el-drawer
:wrapperClosable="false"
:visible.sync="visible"
:append-to-body="true"
direction="rtl"
size="80%"
:with-header="false"
:show-close="false"
modal-append-to-body
:destroy-on-close="true"
>
<div style="width:100%; height:100%;overflow: hidden">
<iframe :src="src" width="100%" name="dmsDrawer" height="100%" title="myFrame" style="border: 0"></iframe>
</div>
</el-drawer>
<el-drawer
:visible.sync="drawerShow"
direction="rtl"
size="80%"
:append-to-body="true"
:with-header="false"
:wrapperClosable="false"
:show-close="false"
modal-append-to-body
:destroy-on-close="true"
>
<main-component ref="mainComponent" :code="path" :data="data" @close="handleCodeCloseChange"></main-component>
</el-drawer>
</div>
</template>
<script>
/*
流程处理抽屉组件
*/
import MainComponent from '@/components/mainComponent/index.vue'
export default {
name: 'DealDrawer',
components: { MainComponent },
data() {
return {
workflowMessageCbAdded: false,
visible: false,
drawerShow: false,
data: undefined,
path: '',
src: ''
}
},
activated() {
this.setupMessageListener()
},
created() {
this.setupMessageListener()
},
deactivated() {
this.removeMessageListener()
},
beforeDestroy() {
this.removeMessageListener()
},
methods: {
//addEventListener
setupMessageListener() {
if (!this.workflowMessageCbAdded) {
window.addEventListener('message', this.handleMsg)
this.workflowMessageCbAdded = true
}
},
//addEventListener
removeMessageListener() {
window.removeEventListener('message', this.handleMsg)
this.workflowMessageCbAdded = false
},
handleMsg(event) {
let _this = this
let data = event.data
if (data.type === 'close') {
_this.visible = false
if (data.msgType) {
_this.$modal[data.msgType](data.msg)
}
_this.$emit('closeDrawer')
}else if(data.type === 'pdfPreview'){
this.pdfPreview(data.pdfId)
}
},
pdfPreview(pdfId){
this.path = 'views/components/pdfPreview/index'
this.data = pdfId
this.drawerShow = true
},
init(url) {
let _this = this
_this.visible = true
// iframeURL
_this.src = url
},
handleCodeCloseChange() {
this.drawerShow = false
},
}
}
</script>

View File

@ -196,7 +196,7 @@ export default {
};
</script>
<style scoped>
<style>
.editor, .ql-toolbar {
white-space: pre-wrap !important;
line-height: normal !important;

View File

@ -15,7 +15,7 @@
ref="fileUpload"
>
<!-- 上传按钮 -->
<el-button size="mini" type="primary">上传文件</el-button>
<el-button size="mini" type="primary">选取文件</el-button>
<!-- 上传提示 -->
<div class="el-upload__tip" slot="tip" v-if="showTip">
请上传

View File

@ -1,649 +0,0 @@
<template>
<div>
<el-upload class="upload-demo" ref="upload" action="#"
:before-upload="beforeUpload"
:on-change="onChange"
:on-remove="handleRemove"
:multiple="false"
:on-exceed="handleExceed"
:accept="acceptType"
:file-list="fileList"
:auto-upload="true"
:http-request="uploadFile"
show-file-list>
<el-button slot="trigger" size="small" type="primary" @click="isFolder = false">上传文件</el-button>
<el-button size="small" type="primary" @click="handleUploadFile" >
上传文件夹
</el-button>
<!-- 上传-->
<input v-show="false" ref="fileRef" id="fileFolder" type="file" @change="handleFolderUpload" webkitdirectory
multiple="multiple" />
<div slot="tip" class="el-upload__tip" >只能上传{{acceptType}}格式</div>
</el-upload>
<div v-show="progressFlag" class="head-img">
<el-progress :text-inside="true" :stroke-width="14" :percentage="progressPercent" status="success"></el-progress>
</div>
</div>
</template>
<script>
import axios from 'axios'
import {
getToken
} from "@/utils/auth";
export default {
props: {
uploadUrl: {
type: String,
required: false
},
//
isMultiple: {
type: Boolean,
default() {
return false
},
required: false
},
//
type: {
type: Array,
default() {
return []
},
required: false
},
//
acceptType: {
type: String,
required: false
},
//
limit: {
type: Number,
default() {
return 1
},
required: false
},
//
dataFile: {
type: [Object, Array, String],
default() {
return ''
},
required: false
},
isDetail: {
type: Boolean,
default: false
},
},
data() {
return {
fileList: [],
progress: 0,
isUploading: false,
progressFlag: false, //
progressPercent: 0, //
partSize: 5 * 1024 * 1024,
fileDetailName: null,
uploadedNum: 0,
_shardCount: null, //
isFolder: false,
totalFiles: 0, //
uploadedCount: 0, //
};
},
watch: {
dataFile: {
handler(newValue, oldValue) {
if (newValue && newValue.length > 0) {
this.fileList = Array.isArray(newValue) ? newValue : [newValue]
this.fileDetailName = this.fileList[0].name
} else {
this.fileList = []
}
},
immediate: true
}
},
methods: {
created(){
this.clearFile()
},
//
beforeUpload(file) {
/* const fileType = file.type.toLowerCase()
console.info("fileType=======", fileType)
const typeFlag = this.type.some(item => {
return fileType.indexOf(item) != -1
})
if (!typeFlag) {
this.$message.error('上传类型有误,请重新上传')
return false
}*/
},
//
onChange(file, fileList) {
this.fileList = fileList;
},
handleRemove(file, fileList) {
this.fileList = fileList;
},
handleExceed(files, fileList) {
/* this.$message.warning(
"最多之能上传"+ this.limit +"个附件"
); */
},
async uploadFile({ data, file }) {
let self = this
//
if (file.size < this.partSize) {
let formData = new FormData()
formData.append("file", file)
self.progressFlag = true;
axios({
url: self.uploadUrl,
method: 'post',
data: formData,
headers: {
'Authorization': 'Bearer ' + getToken(),
'Content-Type': 'multipart/form-data'
},
onUploadProgress: progressEvent => {
// progressEvent.loaded:
// progressEvent.total:
//
self.progressPercent = ((progressEvent.loaded / progressEvent.total) * 100) | 0;
}
}).then(res => {
setTimeout(() => {
if (res.data.code == 200) {
setTimeout(function () {
//
if(self.isFolder){
self.fileList.push(file)
}
self.$message({
message: '上传成功!',
type: 'success',
duration: '2000'
});
self.progressFlag = false;
self.progressPercent = 0
self.handleResult(res,file);
}, 500);
} else {
self.progressFlag = false;
self.progressPercent = 0
if(self.$refs.upload){
self.$refs.upload.clearFiles();
}
self.$message({
message: '上传失败!',
type: 'error',
duration: '2000'
});
}
}, 1000);
}).catch(error => {
console.error(error)
self.progressFlag = false;
self.progressPercent = 0
if(self.$refs.upload){
self.$refs.upload.clearFiles();
}
self.$message({
message: '上传失败!',
type: 'error',
duration: '2000'
});
})
} else {
self.uploadIdSharding(file);
}
},
uploadIdSharding(file){
let self = this
self.uploadedNum = 0
file._shardCount = Math.ceil(file.size / this.partSize) //
file.uploaded = 0
let formData = new FormData()
formData.append('fileName', file.name)
//,uploadId initUpload(formData)
axios({
url: process.env.VUE_APP_BASE_API + "/common/initUpload",
method: 'post',
data: formData,
headers: {
'Authorization': 'Bearer ' + getToken(),
'Content-Type': 'multipart/form-data'
},
}).then(function (res) {
if (res.status == 200) {
//0
file.uploadId = res.data.uploadId
file.objectKey = res.data
file.chunkId = 0
self.uploadByChunk(file)
} else {
this.progress--
self.$message.error(res.msg)
}
}).catch(error => {
self.progressPercent = 0
self.progressFlag = false;
console.error(error)
})
},
//
uploadByChunk(file) {
this._start = file.chunkId * this.partSize
this._end = Math.min(file.size, this._start + this.partSize)// +
let self = this
let fileData = file.slice(this._start, this._end)
//MD5
let reader = new FileReader()
reader.readAsBinaryString(fileData)
let form1 = new FormData()//newform
form1.append('chunkFile', fileData) //slice
form1.append('uploadId', file.uploadId)
form1.append('chunkId', (file.chunkId + 1).toString())
form1.append('shardCount', file._shardCount.toString()) //
self.progressFlag = true;
//Chunk chunkMD5 uploadChunk(form1)
axios({
url: process.env.VUE_APP_BASE_API + "/common/uploadChunk",
method: 'post',
data: form1,
headers: {
'Authorization': 'Bearer ' + getToken(),
'Content-Type': 'multipart/form-data'
},
}).then(response => {
if (response.status == 200) {
//MD5MD5
// self.md5Str[index] === response.msg ||
if (true) {
// this.$message.success('' + (index + 1).toString() + '')
self.uploadedNum++
let percent = Math.floor((self.uploadedNum / file._shardCount) * 100)
self.percentageSend(file, percent)
//
file.chunkId++
if (file.chunkId < file._shardCount) {
this.uploadByChunk(file)
}
} else {
//
this.$message.success('第' + (file.chunkId + 1).toString() + '块文件上传不成功,重新上传')
this.uploadByChunk(file.chunkId)
}
} else {
//
this.progress--
this.$message.error(response.msg)
}
})
},
//
percentageSend(file, perNum) {
let self = this
self.progressPercent = perNum
//
if (perNum === 100) {
let form2 = new FormData()//newform
form2.append('uploadId', file.uploadId)
form2.append('fileName', file.name)
//
// 访URL
axios({
url: process.env.VUE_APP_BASE_API + "/common/mergeFile",
method: 'post',
data: form2,
headers: {
'Authorization': 'Bearer ' + getToken(),
'Content-Type': 'multipart/form-data'
},
}).then(res => {
if (res.status == 200) {
setTimeout(function () {
self.$message({
message: '上传成功!',
type: 'success',
duration: '2000'
});
self.progressFlag = false;
self.progressPercent = 0
self.handleResult(res,file);
}, 500);
//
if(self.isFolder){
self.fileList.push(file)
}
} else {
self.progressFlag = false;
self.progressPercent = 0
if(self.$refs.upload){
self.$refs.upload.clearFiles();
}
self.$message({
message: '上传失败!',
type: 'error',
duration: '2000'
});
}
}).catch(error => {
self.progressFlag = false;
self.progressPercent = 0
if(self.$refs.upload){
self.$refs.upload.clearFiles();
}
self.$message({
message: '上传失败!',
type: 'error',
duration: '2000'
});
});
}
},
resetData() {
this.progress = 0;
},
handleResult(res, file) {
let self = this
const data = {
fileName: file.name,
fileSize: file.size,
fileUrl: res.data.url,
filePath: res.data.filePath,
fileOldName: res.data.originalFilename,
fileNewName: res.data.newFileName,
suffixType: res.data.suffixType
}
self.$emit("handleSuccess", data)
self.clearFile()
},
/** 清空文件 **/
clearFile(){
if(this.$refs.upload){
this.$refs.upload.clearFiles();
}
this.fileList = []
},
handleUploadFile() {
document.getElementById("fileFolder").value = null;
this.$refs.fileRef.dispatchEvent(new MouseEvent("click"));
},
/* async handleFolderUpload(event) {
let self = this;
self.isFolder = true
const files = event.target.files;
self.fileslength = files.length;
let filesper = Math.floor( 100 / files.length * 100)/100;
self.progressShow = true;
if (self.fileslength == 0) {
self.progressShow = false;
self.$modal.msg("上传完成0个未完成0个");
}
for (const file of files) {
let temp = {
"data": null,
"file": file
}
await self.uploadFile(temp);
}
}, */
/* // 处理文件夹上传
async handleFolderUpload(event) {
const files = event.target.files;
this.isFolder = true;
this.progressFlag = true;
if (files.length === 0) {
this.$message.warning('没有选择文件');
return;
}
let successCount = 0;
let failCount = 0;
for (const file of files) {
try {
await this.uploadFolderFile({ file });
successCount++;
} catch (error) {
failCount++;
}
}
this.$message.success(`上传完成!成功:${successCount},失败:${failCount}`);
this.progressFlag = false;
this.progressPercent = 0;
}, */
//
uploadFolderFile({ data, file }) {
let self = this
//
if (file.size < this.partSize) {
return new Promise((resolve, reject) => {
const formData = new FormData();
formData.append("file", file);
this.progressFlag = true;
axios({
url: self.uploadUrl,
method: 'post',
data: formData,
headers: {
'Authorization': 'Bearer ' + getToken(),
'Content-Type': 'multipart/form-data'
},
/* onUploadProgress: progressEvent => {
this.progressPercent = ((progressEvent.loaded / progressEvent.total) * 100) | 0;
} */
}).then(res => {
setTimeout(() => {
if (res.data.code === 200) {
// self.progressFlag = false;
// self.progressPercent = 0;
self.handleResult(res,file);
resolve(); // resolve
} else {
// self.progressFlag = false;
self.$message.error(file.name + '上传失败!');
reject(); // reject
}
}, 500);
}).catch(error => {
// self.progressFlag = false;
// self.progressPercent = 0;
self.$message.error(file.name + '上传失败!');
reject(error); // reject
});
});
}else{
return new Promise((resolve, reject) => {
self.uploadIdShardingFolder(file)
.then(() => {
resolve(); //
})
.catch(error => {
reject(error); // reject
});
});
}
},
async handleFolderUpload(event) {
let self = this
const files = Array.from(event.target.files);
this.totalFiles = files.length;
this.uploadedCount = 0;
this.progressFlag = true;
let failCount = 0;
for (let i = 0; i < files.length; i++) {
const file = files[i];
const fileExtension = file.name.slice(file.name.lastIndexOf('.')).toLowerCase();
//
if (!self.acceptType.includes(fileExtension)) {
failCount++;
this.$message.error('文件格式不支持: ' + file.name);
continue;
}
try {
await this.uploadFolderFile(
{
data: null,
file: file
}
);
this.uploadedCount++;
this.updateProgress();
} catch (error) {
failCount++;
}
}
setTimeout(function () {
self.$message.success('上传完成!成功:' + self.uploadedCount+',失败:' + failCount);
self.progressFlag = false;
self.progressPercent = 0;
}, 500);
},
updateProgress() {
if (this.uploadedCount === this.totalFiles) {
this.progressPercent = 100;
} else {
this.progressPercent = Math.min(100, Math.floor((this.uploadedCount / this.totalFiles) * 100));
}
/*
if (this.uploadedCount % 10 === 0 || this.uploadedCount === this.totalFiles) {
this.$message.success(`已上传 ${this.uploadedCount} 个文件`);
} */
},
//
uploadIdShardingFolder(file) {
let self = this
return new Promise((resolve, reject) => {
file._shardCount = Math.ceil(file.size / this.partSize); //
file.uploaded = 0;
const formData = new FormData();
formData.append('fileName', file.name);
// , uploadId
axios({
url: process.env.VUE_APP_BASE_API + "/common/initUpload",
method: 'post',
data: formData,
headers: {
'Authorization': 'Bearer ' + getToken(),
'Content-Type': 'multipart/form-data'
},
}).then(res => {
if (res.status === 200) {
file.uploadId = res.data.uploadId;
file.chunkId = 0;
this.uploadByChunkFolder(file)
.then(() => resolve()) // resolve
.catch(error => reject(error)); // reject
} else {
reject(new Error('初始化上传失败'));
}
}).catch(error => {
reject(error);
});
});
},
//
uploadByChunkFolder(file) {
let self = this
return new Promise((resolve, reject) => {
const uploadChunk = (chunkId) => {
const _start = chunkId * this.partSize;
const _end = Math.min(file.size, _start + this.partSize);
const fileData = file.slice(_start, _end);
const form1 = new FormData();
form1.append('chunkFile', fileData);
form1.append('uploadId', file.uploadId);
form1.append('chunkId', (chunkId + 1).toString());
form1.append('shardCount', file._shardCount.toString());
axios({
url: process.env.VUE_APP_BASE_API + "/common/uploadChunk",
method: 'post',
data: form1,
headers: {
'Authorization': 'Bearer ' + getToken(),
'Content-Type': 'multipart/form-data'
},
}).then(response => {
if (response.status === 200) {
file.uploadedNum++;
// const percent = Math.floor((file.uploadedNum / file._shardCount) * 100);
// this.percentageSend(file, percent);
if (chunkId + 1 < file._shardCount) {
//
uploadChunk(chunkId + 1);
} else {
//
this.mergeFileFolder(file).then(() => resolve()).catch(error => reject(error));
}
} else {
reject(new Error('分片上传失败'));
}
}).catch(error => {
reject(error);
});
};
// 0
uploadChunk(0);
});
},
//
mergeFileFolder(file) {
let self = this
return new Promise((resolve, reject) => {
const form2 = new FormData();
form2.append('uploadId', file.uploadId);
form2.append('fileName', file.name);
axios({
url: process.env.VUE_APP_BASE_API + "/common/mergeFile",
method: 'post',
data: form2,
headers: {
'Authorization': 'Bearer ' + getToken(),
'Content-Type': 'multipart/form-data'
},
}).then(res => {
if (res.status === 200) {
self.handleResult(res,file);
resolve(); //
} else {
reject(new Error('文件合并失败'));
}
}).catch(error => {
reject(error);
});
});
}
}
};
</script>

View File

@ -1,484 +0,0 @@
<template>
<div v-if="!isDetail">
<el-upload class="upload-demo" ref="upload" action="#"
:before-upload="beforeUpload"
:on-change="onChange"
:on-remove="handleRemove"
:multiple="isMultiple"
:on-exceed="handleExceed"
:accept="acceptType"
:limit="limit"
:file-list="fileList"
:auto-upload="true"
:http-request="uploadFile"
show-file-list>
<el-button slot="trigger" size="small" type="primary" >上传文件</el-button>
<el-button size="small" type="primary" @click="handleUploadFile" >
上传文件夹
</el-button>
<!-- 上传-->
<input v-show="false" ref="fileRef" id="fileFolder" type="file" @change="handleFolderUpload" webkitdirectory
multiple="multiple" />
<!-- <input v-show="false" type="file" ref="fileRef" webkitdirectory @change="handleFolderUpload">
<el-button slot="trigger" size="small" type="primary">上传文件夹</el-button>-->
</el-upload>
<div slot="tip" class="el-upload__tip" >只能上传{{acceptType}}文件</div>
<div v-show="progressFlag" class="head-img">
<el-progress :text-inside="true" :stroke-width="14" :percentage="progressPercent" status="success"></el-progress>
</div>
</div>
<div v-else>
{{fileDetailName}}
<!-- {{fileList[0].name}}-->
</div>
</template>
<script>
import axios from 'axios'
import {
getToken
} from "@/utils/auth";
import JSZip from 'jszip'
export default {
props: {
uploadUrl: {
type: String,
required: false
},
//
isMultiple: {
type: Boolean,
default() {
return false
},
required: false
},
//
type: {
type: Array,
default() {
return []
},
required: false
},
//
acceptType: {
type: String,
required: false
},
//
limit: {
type: Number,
default() {
return 1
},
required: false
},
//
dataFile: {
type: [Object, Array, String],
default() {
return ''
},
required: false
},
isDetail: {
type: Boolean,
default: false
},
},
data() {
return {
fileList: [{name:null}],
progress: 0,
isUploading: false,
progressFlag: false, //
progressPercent: 0, //
partSize: 5 * 1024 * 1024,
fileDetailName: null
};
},
watch: {
dataFile: {
handler(newValue, oldValue) {
if (newValue && newValue.length > 0) {
this.fileList = Array.isArray(newValue) ? newValue : [newValue]
this.fileDetailName = this.fileList[0].name
} else {
this.fileList = [{name:null}]
}
},
immediate: true
}
},
methods: {
//
beforeUpload(file) {
/* const fileType = file.type.toLowerCase()
console.info("fileType=======", fileType)
const typeFlag = this.type.some(item => {
return fileType.indexOf(item) != -1
})
if (!typeFlag) {
this.$message.error('上传类型有误,请重新上传')
return false
}*/
},
//
onChange(file, fileList) {
this.fileList = fileList;
},
handleRemove(file, fileList) {
this.fileList = fileList;
},
handleExceed(files, fileList) {
this.$message.warning(
"最多之能上传"+ this.limit +"个附件"
);
},
async uploadFile({ data, file }) {
let self = this
//
if (file.size < this.partSize) {
let formData = new FormData()
formData.append("file", file)
self.progressFlag = true;
axios({
url: self.uploadUrl,
method: 'post',
data: formData,
headers: {
'Authorization': 'Bearer ' + getToken(),
'Content-Type': 'multipart/form-data'
},
onUploadProgress: progressEvent => {
// progressEvent.loaded:
// progressEvent.total:
//
self.progressPercent = ((progressEvent.loaded / progressEvent.total) * 100) | 0;
}
}).then(res => {
setTimeout(() => {
if (res.data.code == 200 && self.progressPercent === 100) {
setTimeout(function () {
self.$message({
message: '上传成功!',
type: 'success',
duration: '2000'
});
self.progressFlag = false;
self.progressPercent = 0
self.handleResult(res,file);
}, 500);
} else {
self.progressFlag = false;
self.$message({
message: '上传失败!',
type: 'error',
duration: '2000'
});
}
}, 1000);
}).catch(error => {
console.error(error)
self.progressFlag = false;
self.progressPercent = 0
self.$refs.upload.clearFiles();
self.$message({
message: '上传失败!',
type: 'error',
duration: '2000'
});
})
} else {
file._shardCount = Math.ceil(file.size / this.partSize) //
file.uploaded = 0
let formData = new FormData()
formData.append('fileName', file.name)
let self = this
//,uploadId initUpload(formData)
axios({
url: process.env.VUE_APP_BASE_API + "/common/initUpload",
method: 'post',
data: formData,
headers: {
'Authorization': 'Bearer ' + getToken(),
'Content-Type': 'multipart/form-data'
},
}).then(function (res) {
if (res.status == 200) {
//0
file.uploadId = res.data.uploadId
file.objectKey = res.data
file.chunkId = 0
self.uploadByChunk(file)
} else {
this.progress--
self.$message.error(res.msg)
}
}).catch(error => {
self.progressPercent = 0
self.progressFlag = false;
console.error(error)
})
}
},
//
uploadByChunk(file) {
this._start = file.chunkId * this.partSize
this._end = Math.min(file.size, this._start + this.partSize)// +
let self = this
let fileData = file.slice(this._start, this._end)
//MD5
let reader = new FileReader()
reader.readAsBinaryString(fileData)
let form1 = new FormData()//newform
form1.append('chunkFile', fileData) //slice
form1.append('uploadId', file.uploadId)
form1.append('chunkId', (file.chunkId + 1).toString())
form1.append('shardCount', file._shardCount.toString()) //
self.progressFlag = true;
//Chunk chunkMD5 uploadChunk(form1)
axios({
url: process.env.VUE_APP_BASE_API + "/common/uploadChunk",
method: 'post',
data: form1,
headers: {
'Authorization': 'Bearer ' + getToken(),
'Content-Type': 'multipart/form-data'
},
onUploadProgress: progressEvent => {
// progressEvent.loaded:
// progressEvent.total:
//
self.progressPercent = ((progressEvent.loaded / progressEvent.total) * 100) | 0;
}
}).then(response => {
if (response.status == 200) {
//MD5MD5
// self.md5Str[index] === response.msg ||
if (true) {
// this.$message.success('' + (index + 1).toString() + '')
file.uploaded++
self.percentageSend(file)
//
file.chunkId++
if (file.chunkId < file._shardCount) {
this.uploadByChunk(file)
}
} else {
//
this.$message.success('第' + (file.chunkId + 1).toString() + '块文件上传不成功,重新上传')
this.uploadByChunk(file.chunkId)
}
} else {
//
this.progress--
this.$message.error(response.msg)
}
})
},
//
percentageSend(file) {
let self = this
let perNum = Math.floor((file.uploaded / file._shardCount) * 100)
this.progressPercent = perNum
//
if (perNum === 100) {
let form2 = new FormData()//newform
form2.append('uploadId', file.uploadId)
form2.append('fileName', file.name)
//
// 访URL
axios({
url: process.env.VUE_APP_BASE_API + "/common/mergeFile",
method: 'post',
data: form2,
headers: {
'Authorization': 'Bearer ' + getToken(),
'Content-Type': 'multipart/form-data'
},
}).then(res => {
if (res.status == 200) {
setTimeout(function () {
self.$message({
message: '上传成功!',
type: 'success',
duration: '2000'
});
self.progressFlag = false;
self.progressPercent = 0
self.handleResult(res,file);
}, 500);
} else {
self.progressFlag = false;
self.$message({
message: '上传失败!',
type: 'error',
duration: '2000'
});
}
})
}
},
resetData() {
this.progress = 0;
},
handleResult(res, file) {
let self = this
const data = {
fileName: file.name,
fileSize: file.size,
fileUrl: res.data.url,
filePath: res.data.filePath,
fileOldName: res.data.originalFilename,
fileNewName: res.data.newFileName,
suffixType: res.data.suffixType
}
self.$emit("handleSuccess", data)
},
/** 清空文件 **/
clearFile(){
this.progressFlag = false;
if(this.$refs.upload){
this.$refs.upload.clearFiles();
}
this.fileList = []
},
handleUploadFile() {
document.getElementById("fileFolder").value = null;
this.$refs.fileRef.dispatchEvent(new MouseEvent("click"));
},
async handleFolderUpload(event) {
let self = this;
const files = event.target.files;
this.fileslength = files.length;
//
let folderName = "";
if (files.length > 0) {
let relativePath = files[0].webkitRelativePath;
folderName = relativePath.split("/")[0];
}
const zip = new JSZip();
// ZIP
Array.from(files).forEach(file => {
zip.file(file.webkitRelativePath, file);
});
// ZIP
const zipBlob = await zip.generateAsync({ type: "blob" });
// FormData
/* const formData = new FormData();
formData.append("file", zipBlob, folderName + ".zip");*/
let formData = new FormData()
formData.append('fileName', folderName + ".zip")
// shardCount
const _shardCount = Math.ceil(zipBlob.size / this.partSize);
const fileObj = {
_shardCount,
size: zipBlob.size,
file: zipBlob // zipBlob fileObj
};
self.$set(fileObj.file, '_shardCount', _shardCount);
self.$set(fileObj.file, 'uploaded', 0);
self.$set(fileObj.file, 'name', folderName + ".zip");
self.fileList.push(fileObj.file)
if (zipBlob.size < this.partSize) {
let formDataSign = new FormData()
formDataSign.append("file", zipBlob, folderName + ".zip")
self.progressFlag = true;
axios({
url: self.uploadUrl,
method: 'post',
data: formDataSign,
headers: {
'Authorization': 'Bearer ' + getToken(),
'Content-Type': 'multipart/form-data'
},
onUploadProgress: progressEvent => {
// progressEvent.loaded:
// progressEvent.total:
//
self.progressPercent = ((progressEvent.loaded / progressEvent.total) * 100) | 0;
}
}).then(res => {
setTimeout(() => {
if (res.data.code == 200 && self.progressPercent === 100) {
setTimeout(function () {
self.$message({
message: '上传成功!',
type: 'success',
duration: '2000'
});
self.progressFlag = false;
self.progressPercent = 0
self.handleResult(res,fileObj.file);
}, 500);
} else {
self.progressFlag = false;
self.$message({
message: '上传失败!',
type: 'error',
duration: '2000'
});
}
}, 1000);
}).catch(error => {
console.error(error)
self.progressFlag = false;
self.progressPercent = 0
self.$refs.upload.clearFiles();
self.$message({
message: '上传失败!',
type: 'error',
duration: '2000'
});
})
} else {
// uploadId
axios({
url: process.env.VUE_APP_BASE_API + "/common/initUpload",
method: 'post',
data: formData,
headers: {
'Authorization': 'Bearer ' + getToken(),
'Content-Type': 'multipart/form-data'
},
}).then(function (res) {
if (res.status === 200) {
self.$set(fileObj.file, 'uploadId', res.data.uploadId);
self.$set(fileObj.file, 'chunkId', 0);
self.$set(fileObj.file, 'objectKey', res.data);
/*//从第0块开始上传
fileObj.uploadId = res.data.uploadId;
fileObj.chunkId = 0;
fileObj.objectKey = res.data*/
self.uploadByChunk(fileObj.file);
} else {
self.progress--;
self.$message.error(res.msg);
}
}).catch(error => {
self.progressPercent = 0;
self.progressFlag = false;
console.error(error);
});
}
},
}
};
</script>

View File

@ -1,133 +0,0 @@
<template>
<div :class="$options.name" @click="show = !show" :placement="placement">
<div class="collapse-btns">
<div class="collapse-btn" v-if="show">
<i class="el-icon-caret-top"></i>
<div class="label">折叠{{ collapseLabel || expandLabel || `` }}</div>
</div>
<div class="collapse-btn" v-else>
<i class="el-icon-caret-bottom"></i>
<div class="label">展开{{ expandLabel || collapseLabel || `` }}</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: "sgCollapseBtn",
components: {},
data() {
return {
show: false,
};
},
props: ["data", "value", "collapseLabel", "expandLabel", "placement"],
watch: {
value: {
handler(d) {
this.show = d;
},
deep: true,
immediate: true,
},
show(d) {
this.$emit("input", d);
},
},
created() {},
mounted() {},
computed: {},
methods: {},
};
</script>
<style lang="scss" scoped>
.sgCollapseBtn {
position: relative;
z-index: 1;
/*禁止选中文本*/
user-select: none;
width: 100%;
height: 30px;
line-height: 30px;
background-color: white;
cursor: pointer;
&[placement="bottom"] {
position: absolute;
top: revert;
bottom: 0;
left: 0;
right: 0;
}
.collapse-btns {
width: 100%;
$side: 20%; //
/*左右渐变遮罩(兼容IOS)*/
-webkit-mask-image: linear-gradient(
to right,
transparent,
white $side,
white calc(100% - #{$side}),
transparent
);
display: flex;
justify-content: center;
align-items: center;
font-size: 14px;
background-color: white;
&::after {
content: "";
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 0;
background: linear-gradient(white, #e2f0ff);
opacity: 0;
transition: 1s ease !important;
z-index: -1;
}
.collapse-btn {
transition: 0.4s !important;
display: flex;
align-items: center;
transform: translateX(40%);
i {
transition: 0.4s !important;
color: #d3dce6;
}
.label {
transition: 0.2s !important;
margin-left: 25px;
color: #409eff;
opacity: 0;
}
}
}
&:active,
&:hover {
.collapse-btns {
&::after {
opacity: 1;
}
.collapse-btn {
transform: translateX(0%);
i {
color: #409eff;
}
.label {
margin-left: 5px;
color: #409eff;
opacity: 1;
// width: 100%;
}
}
}
}
}
</style>

View File

@ -1,255 +0,0 @@
<template>
<div :class="$options.name"></div>
</template>
<script>
export default {
name: "sgDragMove",
data() {
return {
offset: { x: 0, y: 0 }, //
style: { top: "0px", left: "0px" },
canDragDom: null, //
moveDom: null, //
};
},
props: [
"data", //()
/* data
[
...
{
canDragDom: elementDOM,//or
moveDom: elementDOM,//or
},
...
]
*/
"disabled", //
"mousedownNearSide", //
"mousemoveNearSide", //
"mouseupNearSide", //
"nearPadding", //mousedownNearSide||mousemoveNearSide||mouseupNearSide=truenumberarray5[5,5,5,5],[,,,]
"stopBoundary", //mousedownNearSide||mousemoveNearSide||mouseupNearSide=truenumberarray5[5,5,5,5],[,,,]
"cursor", //
/*cursor{
grab:'default',//
grabbing:'default',//
} */
],
watch: {
data: {
handler(newValue, oldValue) {
newValue ? this.__addDragsEvents(newValue) : this.__removeDragsEvents(oldValue);
},
deep: true,
immediate: true,
},
disabled: {
handler(newValue, oldValue) {
newValue ? this.__removeAllEvents() : this.__addAllEvents();
},
deep: true,
immediate: true,
},
style: {
handler(newValue, oldValue) {
if (this.moveDom && newValue && Object.keys(newValue).length) {
let d = newValue;
Object.keys(d).forEach((k) => (this.moveDom.style[k] = d[k]));
this.moveDom.style.right = "revert";
this.moveDom.style.bottom = "revert";
this.$emit(`getStyle`, d); //DOM
}
},
deep: true, //
immediate: true, //
},
},
destroyed() {
this.__removeAllEvents();
},
mounted() {
this.$parent.$el.style.setProperty(
"--sgDragMove-grab",
(this.cursor || {}).grab || "grab"
); //jscss
this.$parent.$el.style.setProperty(
"--sgDragMove-grabbing",
(this.cursor || {}).grabbing || "grabbing"
); //jscss
},
methods: {
__addAllEvents() {
this.__addDragsEvents(this.data);
},
__removeAllEvents() {
this.__removeWindowEvents();
this.__removeDragsEvents(this.data);
},
__addWindowEvents() {
this.__removeWindowEvents();
addEventListener("mousemove", this.mousemove_window);
addEventListener("mouseup", this.mouseup_window);
},
__removeWindowEvents() {
removeEventListener("mousemove", this.mousemove_window);
removeEventListener("mouseup", this.mouseup_window);
},
// DIV
__addDragsEvents(doms) {
(doms || []).forEach((dom) => {
this.__removeDraggedEvents(dom.canDragDom);
this.__addDraggedEvents(dom.canDragDom);
});
},
__removeDragsEvents(doms) {
(doms || []).forEach((dom) => {
this.__removeDraggedEvents(dom.canDragDom);
});
},
__addDraggedEvents(dom) {
dom.setAttribute("sgDragMove_grab", "ready");
dom.addEventListener("dragstart", this.dragstart);
dom.addEventListener("mousedown", this.mousedown);
},
__removeDraggedEvents(dom) {
dom.removeEventListener("dragstart", this.dragstart);
dom.removeEventListener("mousedown", this.mousedown);
},
dragstart(e) {
e.stopPropagation();
e.preventDefault();
return false;
},
mousedown(e) {
if (this.disabled) return this.mouseup_window(e);
if (e.button === 2) return this.mouseup_window(e); //
this.canDragDom = e.currentTarget;
this.moveDom = this.data.find((v) => v.canDragDom == this.canDragDom).moveDom;
this.canDragDom.setAttribute("sgDragMove_grab", "down");
this.moveDom.setAttribute("sgDragMove_move", "ready");
let or = this.moveDom.getBoundingClientRect();
this.offset = { x: e.clientX - or.x, y: e.clientY - or.y };
(this.mousedownNearSide || this.mousedownNearSide === "") && this.nearSide();
this.$emit("dragStart", this.getResult(e));
this.__addWindowEvents();
},
setOffset(d) {
this.offset = {
...this.offset,
...d,
};
},
mousemove_window(e) {
this.canDragDom.setAttribute("sgDragMove_grab", "down");
this.moveDom.setAttribute("sgDragMove_move", "ing");
let x = e.clientX - this.offset.x;
let y = e.clientY - this.offset.y;
this.style = { left: x + "px", top: y + "px" };
this.style["transition-property"] = "left,top";
this.style["transition-duration"] = "0s,0s";
this.$nextTick(() => {
(this.mousemoveNearSide || this.mousemoveNearSide === "") && this.nearSide();
this.$emit("dragging", this.getResult(e));
});
},
mouseup_window(e) {
this.$emit("dragEnd", this.getResult(e));
(this.mouseupNearSide || this.mouseupNearSide === "") && this.nearSide();
this.offset = null;
this.style = null;
this.canDragDom.setAttribute("sgDragMove_grab", "ready");
this.moveDom.setAttribute("sgDragMove_move", "end");
setTimeout(() => {
this.moveDom && this.moveDom.removeAttribute("sgDragMove_move");
}, 100);
this.canDragDom = null;
this.moveDom = null;
this.__removeWindowEvents();
},
//
nearSide() {
let arr = this.nearPadding ? JSON.parse(JSON.stringify(this.nearPadding)) : 0;
Array.isArray(arr) || (arr = [...Array(4)].map((v) => arr));
let [dis_top, dis_right, dis_bottom, dis_left] = arr;
arr = this.stopBoundary ? JSON.parse(JSON.stringify(this.stopBoundary)) : 0;
Array.isArray(arr) || (arr = [...Array(4)].map((v) => arr));
let [
stopBoundary_top,
stopBoundary_right,
stopBoundary_bottom,
stopBoundary_left,
] = arr;
let x = parseFloat(this.moveDom.style.left);
let y = parseFloat(this.moveDom.style.top);
let rect = this.moveDom.getBoundingClientRect();
let min_side_x = 0,
min_x = min_side_x + dis_left,
min_left = min_side_x + stopBoundary_left;
let min_side_y = 0,
min_y = min_side_y + dis_top,
min_top = min_side_y + stopBoundary_top;
x < min_x && (this.moveDom.style.left = `${min_left}px`);
y < min_y && (this.moveDom.style.top = `${min_top}px`);
let max_side_x = innerWidth - rect.width,
max_x = max_side_x - dis_right,
max_right = max_side_x - stopBoundary_right;
let max_side_y = innerHeight - rect.height,
max_y = max_side_y - dis_bottom,
max_bottom = max_side_y - stopBoundary_bottom;
x > max_x && (this.moveDom.style.left = `${max_right}px`);
y > max_y && (this.moveDom.style.top = `${max_bottom}px`);
},
getResult(e) {
return {
$event: e,
canDragDom: this.canDragDom,
moveDom: this.moveDom,
canDragDomRect: this.canDragDom ? this.canDragDom.getBoundingClientRect() : null,
moveDomRect: this.moveDom ? this.moveDom.getBoundingClientRect() : null,
};
},
},
};
</script>
<style lang="scss" scoped>
[sgDragMove_grab="ready"] {
cursor: var(--sgDragMove-grab); //cssjs
* {
cursor: var(--sgDragMove-grab); //cssjs
}
&:hover {
opacity: 1;
}
&:active {
opacity: 0.9;
}
}
[sgDragMove_grab="down"] {
cursor: var(--sgDragMove-grabbing); //cssjs
* {
cursor: var(--sgDragMove-grabbing); //cssjs
}
}
[sgDragMove_move="ready"] {
opacity: 1;
}
[sgDragMove_move="ing"] {
opacity: 0.9;
}
[sgDragMove_move="end"] {
transition: 0.1s;
}
</style>

View File

@ -1,281 +0,0 @@
<template>
<div :class="$options.name" :disabled="disabled" draggable="false">
<div :class="`resize-handle resize-${a}`" draggable="false" @mousedown.stop="clickResizeHandle(a)"
@dblclick="dblclickResizeHandle(a, $event)" v-for="(a, i) in sizeIndexs" :key="i"></div>
</div>
</template>
<script>
export default {
name: 'sgDragSize',
data() {
return {
tbHeight: 0,
dragSizeIndex: '',
originRect: {},
dblclickOriginRect: {},
sizeIndexs: [
'top',
'right',
'bottom',
'left',
'top-left',
'top-right',
'bottom-left',
'bottom-right',
],
}
},
props: [
"disabled",//
"taskbarHeight",//
"minWidth",//
"minHeight",//
"maxWidth",//
"maxHeight",//
],
watch: {
disabled: {
handler(newValue, oldValue) {
newValue && this.__removeWindowEvents();
}, deep: true, immediate: true,
},
taskbarHeight: {
handler(d) {
this.tbHeight = d || 0;
}, deep: true, immediate: true,
},
},
destroyed() {
this.__removeWindowEvents();
},
methods: {
view_innerHeight() {
return innerHeight - this.tbHeight;
},
clickResizeHandle(d) {
this.dragSizeIndex = d;
this.mousedown(d);
},
dblclickResizeHandle(d, $event) {
let rect = this.$el.getBoundingClientRect();
rect.width < innerWidth && rect.height < this.view_innerHeight() && (this.dblclickOriginRect = rect);
this.dblResize(d, rect, $event);
},
__addWindowEvents() {
this.__removeWindowEvents();
addEventListener('mousemove', this.mousemove_window);
addEventListener('mouseup', this.mouseup_window);
},
__removeWindowEvents() {
removeEventListener('mousemove', this.mousemove_window);
removeEventListener('mouseup', this.mouseup_window);
},
mousedown(e) {
this.originRect = this.$el.getBoundingClientRect();
this.originRect.bottomRightX = this.originRect.x + this.originRect.width;//.x
this.originRect.bottomRightY = this.originRect.y + this.originRect.height;//.y
this.$emit('dragStart', e);
this.__addWindowEvents();
},
mousemove_window(e) {
let { x, y } = e;
let minWidth = this.minWidth || 50, minHeight = this.minHeight || 50, maxWidth = this.maxWidth || innerWidth, maxHeight = this.maxHeight || innerHeight;
x < 0 && (x = 0), y < 0 && (y = 0), x > innerWidth && (x = innerWidth), y > this.view_innerHeight() && (y = this.view_innerHeight());
let style = {};
switch (this.dragSizeIndex) {
case 'top-left':
style.left = x;
style.top = y;
style.width = this.originRect.bottomRightX - x;
style.width <= minWidth && (style.width = minWidth, style.left = this.originRect.bottomRightX - minWidth);
style.height = this.originRect.bottomRightY - y;
style.height <= minHeight && (style.height = minHeight, style.top = this.originRect.bottomRightY - minHeight);
break;
case 'top':
style.left = this.originRect.x;
style.top = y;
style.width = this.originRect.width;
style.height = this.originRect.bottomRightY - y;
style.height <= minHeight && (style.height = minHeight, style.top = this.originRect.bottomRightY - minHeight);
break;
case 'top-right':
style.left = this.originRect.x;
style.top = y;
style.width = x - this.originRect.x;
style.width <= minWidth && (style.width = minWidth, style.left = this.originRect.x);
style.height = this.originRect.bottomRightY - y;
style.height <= minHeight && (style.height = minHeight, style.top = this.originRect.bottomRightY - minHeight);
break;
case 'left':
style.left = x;
style.top = this.originRect.y;
style.width = this.originRect.bottomRightX - x;
style.width <= minWidth && (style.width = minWidth, style.left = this.originRect.bottomRightX - minWidth);
style.height = this.originRect.height;
break;
case 'right':
style.left = this.originRect.x;
style.top = this.originRect.y;
style.width = x - this.originRect.x;
style.width <= minWidth && (style.width = minWidth, style.left = this.originRect.x);
style.height = this.originRect.height;
break;
case 'bottom-left':
style.left = x;
style.top = this.originRect.y;
style.width = this.originRect.bottomRightX - x;
style.width <= minWidth && (style.width = minWidth, style.left = this.originRect.bottomRightX - minWidth);
style.height = y - this.originRect.y;
style.height <= minHeight && (style.height = minHeight, style.top = this.originRect.y);
break;
case 'bottom':
style.left = this.originRect.x;
style.top = this.originRect.y;
style.width = this.originRect.width;
style.height = y - this.originRect.y;
style.height <= minHeight && (style.height = minHeight, style.top = this.originRect.y);
break;
case 'bottom-right':
style.left = this.originRect.x;
style.top = this.originRect.y;
style.width = x - this.originRect.x;
style.width <= minWidth && (style.width = minWidth, style.left = this.originRect.x);
style.height = y - this.originRect.y;
style.height <= minHeight && (style.height = minHeight, style.top = this.originRect.y);
break;
default:
}
style.width > maxWidth && (style.width = maxWidth);
style.height > maxHeight && (style.height = maxHeight);
Object.keys(style).forEach(k => style[k] = `${style[k]}px`);
style['transition-property'] = 'width,height';
style['transition-duration'] = '0,0';
this.$emit('dragging', { e, style });
},
dblResize(d, rect, e) {
let style = {};
switch (d) {
case 'top-left':
break;
case 'top':
case 'bottom':
style.left = this.originRect.x;
style.top = rect.height >= this.view_innerHeight() ? this.dblclickOriginRect.y : 0;
style.width = this.originRect.width;
style.height = rect.height >= this.view_innerHeight() ? this.dblclickOriginRect.height : this.view_innerHeight();
break;
case 'top-right':
break;
case 'left':
case 'right':
style.left = rect.width >= innerWidth ? this.dblclickOriginRect.x : 0;
style.top = this.originRect.y;
style.width = rect.width >= innerWidth ? this.dblclickOriginRect.width : innerWidth;
style.height = this.originRect.height;
break;
case 'bottom-left':
break;
case 'bottom-right':
break;
default:
}
Object.keys(style).forEach(k => style[k] = `${style[k]}px`);
style['transition-property'] = 'width,height';
style['transition-duration'] = '0.1s,0.1s';
this.$emit('dragging', { e, style });
},
mouseup_window(e) {
this.$emit('dragEnd', e);
this.__removeWindowEvents();
},
}
};
</script>
<style lang="scss" scoped>
.sgDragSize {
position: absolute;
width: 100%;
height: 100%;
left: 0;
top: 0;
pointer-events: none;
.resize-handle {
position: absolute;
z-index: 100;
display: block;
pointer-events: auto;
}
&[disabled] {
.resize-handle {
pointer-events: none;
}
}
.resize-top {
cursor: n-resize;
top: -3px;
left: 0px;
height: 7px;
width: 100%;
}
.resize-right {
cursor: e-resize;
right: -3px;
top: 0px;
width: 7px;
height: 100%;
}
.resize-bottom {
cursor: s-resize;
bottom: -3px;
left: 0px;
height: 7px;
width: 100%;
}
.resize-left {
cursor: w-resize;
left: -3px;
top: 0px;
width: 7px;
height: 100%;
}
.resize-top-right {
cursor: ne-resize;
width: 16px;
height: 16px;
right: -8px;
top: -8px;
}
.resize-bottom-right {
cursor: se-resize;
width: 20px;
height: 20px;
right: -8px;
bottom: -8px;
background: url('/static/img/desktop/Windows7/sgDragSize/resize_corner.png') no-repeat;
}
.resize-bottom-left {
cursor: sw-resize;
width: 16px;
height: 16px;
left: -8px;
bottom: -8px;
}
.resize-top-left {
cursor: nw-resize;
width: 16px;
height: 16px;
left: -8px;
top: -8px;
}
}
</style>

View File

@ -1,999 +0,0 @@
<template>
<div :class="$options.name" :show="show" :size="size" :style="style">
<div class="upload-list-tray">
<!-- 托盘头部 -->
<div class="header" ref="header" @dblclick.stop.prevent="dblclickHeader">
<div class="left">
<div class="title">
<span class="upload-count" slot="reference">上传队列</span>
<div class="upload-info" v-if="liveSpeed && liveSpeed > 0">
<el-divider :direction="`vertical`" />
<div class="info-item live-speed">
<label>速度</label>
<span>{{ $g.getSize(liveSpeed) }}/s</span>
</div>
<div class="info-item taken-time" v-if="takenTime && takenTime > 0">
<label>已耗时</label>
<span>{{
$g.date.toHourMinuteSecondByMillisecond(takenTime * 1000, {
zh: true,
hideMilliSecond: true,
hideZero: true,
})
}}</span>
</div>
<div class="info-item remain-time" v-if="remainTime && remainTime > 0">
<label>剩余</label
><span>{{
$g.date.toHourMinuteSecondByMillisecond(remainTime * 1000, {
zh: true,
hideMilliSecond: true,
hideZero: true,
})
}}</span>
</div>
</div>
</div>
</div>
<div class="right" @mousedown.stop>
<!-- 控制文件的图标按钮 -->
<div class="file-btns" v-if="showDelSuccessIconBtn || showErrorIconBtn">
<div
class="icon-btn"
v-if="showDelSuccessIconBtn"
@click.stop="clearAllSuccessFile"
title="清除所有已经成功的上传记录"
>
<i class="el-icon-delete" style="color: #67c23a"></i>
</div>
<div
class="icon-btn"
v-if="showErrorIconBtn"
@click.stop="clearAllErrorFile"
title="清除所有失败的上传记录"
>
<i class="el-icon-delete-solid" style="color: #f56c6c"></i>
</div>
<div
class="icon-btn"
v-if="showErrorIconBtn"
@click.stop="uploadAllErrorFile"
title="重新上传所有失败的文件"
>
<i class="el-icon-upload2" style="color: #409eff"></i>
</div>
<template v-if="uploadList.length > maxShowUploadFileCount">
<div
class="icon-btn"
v-if="expandAllUploadList"
@click.stop="expandAllUploadList = false"
title="折叠只显示前10条上传记录"
>
<i class="el-icon-folder" style="color: #409eff"></i>
</div>
<el-tooltip
v-else
:content="`请谨慎展开列表,这将导致您的网页很卡!`"
:effect="`dark`"
:enterable="false"
:placement="`top-start`"
:popper-class="`sg-el-tooltip`"
:transition="`none`"
:disabled="uploadList.length < 200"
>
<div
class="icon-btn"
@click.stop="expandAllUploadList = true"
title="展开所有上传记录"
>
<i class="el-icon-folder-opened" style="color: #409eff"></i>
</div>
</el-tooltip>
</template>
</div>
<!-- 控制托盘的图标按钮 -->
<div class="tray-btns">
<div
class="icon-btn"
v-if="size !== 'lg' && showRightBottomBtn"
@click.stop="toRightBottomPosition"
title="回到原来的位置"
>
<i class="el-icon-bottom-right"></i>
</div>
<div
class="icon-btn"
v-if="size !== 'mn'"
@click.stop="size = 'mn'"
title="最小化"
>
<i class="el-icon-minus"></i>
</div>
<div
class="icon-btn"
v-if="size !== 'md'"
@click.stop="size = 'md'"
title="还原"
>
<i :class="size === 'lg' ? 'el-icon-copy-document' : 'el-icon-d-caret'"></i>
</div>
<div
class="icon-btn"
v-if="size !== 'lg'"
@click.stop="size = 'lg'"
title="全屏"
>
<i class="el-icon-full-screen"></i>
</div>
<div class="icon-btn" @click.stop="close">
<i class="el-icon-close"></i>
</div>
</div>
</div>
</div>
<!-- 上传中的文件列表 -->
<div class="upload-file-list">
<ul>
<li
v-for="(a, i) in expandAllUploadList ? uploadList : uploadList.slice(0, 10)"
:key="i"
:title="
a.size > 1024 * 1024 * 500
? `超大文件上传中,请耐心等待,切勿关闭或刷新浏览器!`
: ''
"
>
<div class="left">
<div class="icon-btns">
<el-button
title="移出上传队列"
:show="a.status === 'error'"
class="remove-icon-btn icon-btn"
type="danger"
icon="el-icon-delete-solid"
size="mini"
plain
circle
@click.stop="removeUploadFile(a)"
></el-button>
</div>
<!-- 动画加载旋转 -->
<div
class="fileLoading"
v-loading="a.percent < 100"
v-if="a.percent < 100 && a.status !== 'error'"
></div>
<!-- 上传成功icon -->
<div class="loadingSuccessIcon" v-if="a.percent === 100">
<i class="el-icon-success" style="color: #67c23a"></i>
</div>
<!-- 上传失败icon -->
<div class="loadingEorrorIcon" v-if="a.status === 'error'">
<i class="el-icon-error" style="color: #f56c6c"></i>
</div>
<span class="name" :title="a.filePath || a.name">
{{ a.filePath || a.name }}
<!-- {{ a.filePath && a.filePath.includes(`/`) ? `[路径:${a.filePath}]` : "" }} -->
</span>
<el-tag class="size" size="mini"
>{{ $g.getSize(a.size * (a.percent / 100)) }}/{{
$g.getSize(a.size)
}}</el-tag
>
<!-- <el-progress class="progress" :percentage="a.percent"></el-progress> -->
<el-progress
class="progress"
style="width: 100%"
type="line"
:percentage="parseInt(a.percent)"
:show-text="true"
:stroke-width="10"
:text-inside="false"
:color="'#409EFF'"
:define-back-color="'#eee'"
/>
</div>
<div class="right">
<span class="tip" :color="a.color">{{ a.tip }}</span>
<div class="icon-btns">
<el-button
:show="a.status === 'error'"
title="重新上传"
class="upload-icon-btn icon-btn"
type="primary"
icon="el-icon-upload2"
size="mini"
plain
circle
@click.stop="startUploadFile(a)"
></el-button>
</div>
</div>
</li>
</ul>
</div>
<!-- 折叠按钮 -->
<sgCollapseBtn
style="z-index: 1"
:collapseLabel="`上传记录`"
v-model="expandAllUploadList"
v-if="uploadList.length > maxShowUploadFileCount"
/>
<div class="footer">
<div class="text" v-html="popoverContent"></div>
<div class="progress" v-if="uploadList.length > 1 && totalPercentage < 100">
<label>总进度</label>
<el-progress
style="width: 100%"
type="line"
:percentage="parseInt(totalPercentage)"
:show-text="true"
:stroke-width="10"
:text-inside="false"
:color="'#409EFF'"
:define-back-color="'#eee'"
/>
</div>
</div>
</div>
<!-- 拖拽移动窗体 -->
<sgDragMove
:data="dragMoveDoms"
:cursor="{
grab: 'default',
grabbing: 'default',
}"
nearPadding="10"
:disabled="size === 'lg' && disabledDragMove"
@dragStart="$emit(`dragStart`, dragMoveDoms)"
@dragging="
showRightBottomBtn = true;
$emit(`dragging`, dragMoveDoms);
"
@dragEnd="$emit(`dragEnd`, dragMoveDoms)"
mousemoveNearSide
/>
<!-- 拖拽改变窗体尺寸 -->
<sgDragSize
v-if="resizeable_"
:disabled="size === 'lg'"
@dragStart="disabledDragMove = true"
@dragging="draggingSize"
@dragEnd="disabledDragMove = false"
:minWidth="minWidth"
:minHeight="minHeight"
/>
</div>
</template>
<script>
import sgCollapseBtn from "./sgCollapseBtn";
import sgDragMove from "./sgDragMove";
import sgDragSize from "./sgDragSize";
export default {
name: "sgUploadTray",
components: {
sgCollapseBtn,
sgDragMove,
sgDragSize,
},
data() {
return {
maxShowUploadFileCount: 10, //
expandAllUploadList: false, //
minWidth: 800,
minHeight: 40,
style_bk: null,
style: {},
resizeable_: true,
disabledDragMove: false, //
show: false,
showRightBottomBtn: false,
size: "md", //lgmdmn
uploadList: [],
dragMoveDoms: [
/* {
canDragDom: elementDOM,//
moveDom: elementDOM,//
} */
], //
lastUploadedTotalSize: 0, //
liveSpeed: 0, //(B)
takenTime: 0, //
remainTime: 0, //
interval: null,
second: 1, //
successFileList: [], //
errorFileList: [], //
remainFileList: [], //
};
},
props: ["data", "value", "resizeable", "position"],
watch: {
value: {
handler(d) {
this.show = d;
},
deep: true,
immediate: true,
},
show: {
handler(d) {
this.$emit(`input`, d);
},
deep: true,
immediate: true,
},
data: {
handler(d) {
this.uploadList = d || [];
},
deep: true,
immediate: true,
},
uploadList: {
handler(newValue, oldValue) {
if (newValue && Object.keys(newValue).length) {
this.interval || this.startUploadCalcLiveSpeed();
this.successFileList = newValue.filter((v) => v.percent == 100);
this.errorFileList = newValue.filter((v) => v.status === "error");
this.remainFileList = newValue.filter(
(v) => v.status !== "error" && v.status !== "success"
);
} else {
this.successFileList = [];
this.errorFileList = [];
this.remainFileList = [];
}
},
deep: true, //
immediate: true, //
},
resizeable: {
handler(newValue, oldValue) {
this.resizeable_ = newValue === "" || newValue;
},
deep: true, //
immediate: true, //
},
size: {
handler(newValue, oldValue) {
switch (newValue) {
case "lg":
case "mn":
this.style_bk = JSON.parse(JSON.stringify(this.style));
delete this.style.width, delete this.style.height;
break;
case "md":
this.style_bk && (this.style = JSON.parse(JSON.stringify(this.style_bk)));
break;
}
},
deep: true, //
immediate: true, //
},
},
computed: {
showDelSuccessIconBtn(d) {
return this.uploadList.some((v) => v.percent == 100);
},
showErrorIconBtn(d) {
return this.uploadList.some((v) => v.status == "error");
},
popoverContent(d) {
let r = [];
this.successFileList.length &&
r.push(
`已上传成功<span style="color: #67C23A;">${this.successFileList.length}</span>个`
);
this.errorFileList.length &&
r.push(`失败<span style="color: #F56C6C;">${this.errorFileList.length}</span>个`);
this.remainFileList.length &&
r.push(
`剩余<span style="color: #409EFF;">${this.remainFileList.length}</span>个`
);
if (this.uploadList.length) {
return `共计${this.uploadList.length}个文件,${
r.length ? `${r.join("")}文件` : ``
}`;
} else {
return `暂无待上传文件`;
}
},
//
totalPercentage() {
if (this.uploadList.length) {
return parseFloat(
((this.successFileList.length / this.uploadList.length) * 100).toFixed(2)
);
} else {
return 0;
}
},
//
uploadingFiles(d) {
let uploadingFiles_ = (this.uploadList || []).filter(
(v) => v.percent < 100 && v.status !== "error" && v.status !== "success"
);
if (uploadingFiles_.length) {
this.$emit(`changeUploadingListClose`, {
path: this.position,
close: this.close,
});
} else {
this.$emit(`changeUploadingListClose`, null);
}
return uploadingFiles_;
},
},
mounted() {
this.$el.style.setProperty("--minWidth", `${this.minWidth}px`); //jscss
this.$el.style.setProperty("--minHeight", `${this.minHeight}px`); //jscss
this.dragMoveDoms = [
{
canDragDom: this.$refs.header, //
moveDom: this.$el, //
},
];
},
destroyed() {
clearInterval(this.interval);
},
methods: {
//
startUploadCalcLiveSpeed() {
clearInterval(this.interval);
this.interval = setInterval(() => {
this.calcLiveSpeed();
}, 1000 * this.second);
},
//
endUploadCalcLiveSpeed(d) {
clearInterval(this.interval);
this.interval = null;
this.liveSpeed = 0;
this.takenTime = 0;
this.remainTime = 0;
},
//
ifNoUploadingFile_EndCalcLiveSpeed(d) {
this.uploadingFiles.length || this.endUploadCalcLiveSpeed();
},
//
calcLiveSpeed(d) {
this.takenTime++;
let uploadList = this.uploadList;
if (uploadList.length) {
let totalSize = uploadList.reduce(
(prevResult, current) => prevResult + current.size,
0
); //
let uploadedTotalSize = uploadList.reduce(
(prevResult, current) => prevResult + current.size * (0.01 * current.percent),
0
); //
let remainTotalSize = totalSize - uploadedTotalSize; //
if (this.lastUploadedTotalSize) {
this.liveSpeed = (uploadedTotalSize - this.lastUploadedTotalSize) / this.second; //
this.remainTime = remainTotalSize / this.liveSpeed; //
} else {
this.liveSpeed = 0;
}
this.lastUploadedTotalSize = uploadedTotalSize; //
} else {
this.endUploadCalcLiveSpeed();
}
},
clearAllSuccessFile() {
let successFileList = this.uploadList.filter((v) => v.percent == 100);
if (successFileList.length === 0)
return this.$message(`暂无可以移除的成功记录,请稍后再试!`);
this.$emit(`clearAllSuccessFile`, successFileList);
this.$nextTick(() => {
successFileList.forEach((file) => {
file.removeFile(); //
});
this.uploadList = this.uploadList.filter((v) => v.percent < 100);
});
},
clearAllErrorFile() {
let errorFileList = this.uploadList.filter((v) => v.status == "error");
if (errorFileList.length === 0)
return this.$message(`暂无可以移除的失败记录,请稍后再试!`);
this.$emit(`clearAllErrorFile`, errorFileList);
this.$nextTick(() => {
errorFileList.forEach((file) => {
file.removeFile(); //
});
this.uploadList = this.uploadList.filter((v) => v.status !== "error");
});
},
uploadAllErrorFile(d) {
let errorFileList = this.uploadList.filter((v) => v.status == "error");
errorFileList.forEach((fileData) => this.startUploadFile(fileData));
if (errorFileList.length === 0) return this.$message(`暂无失败记录,请稍后再试!`);
this.$emit(`uploadAllErrorFile`, errorFileList);
},
draggingSize({ style }) {
this.disabledDragMove = true;
this.style = style;
},
toRightBottomPosition(d) {
this.showRightBottomBtn = false;
let rect = this.$el.getBoundingClientRect();
this.$el.style.left = `${innerWidth - rect.width}px`;
this.$el.style.top = `${innerHeight - rect.height}px`;
// setProperty
/* this.$el.style = {
left: innerWidth - rect.width + "px",
top: innerHeight - rect.height + "px",
}; */
},
dblclickHeader(d) {
switch (this.size) {
case "lg":
this.size = "md";
break;
case "md":
this.size = "mn";
break;
case "mn":
this.size = "md";
break;
default:
}
},
removeAllFilesFromList() {
this.uploadList.forEach((file) => {
file.removeFile(); //
});
this.uploadList = []; //
},
removeFileFromList(d) {
let file = this.uploadList.find((v) => v.uid == d.uid);
file.removeFile(); //
this.uploadList.splice(
this.uploadList.findIndex((v) => v.uid == d.uid),
1
); //
},
//
startUploadFile(fileData) {
fileData.startUpload({ handleTrigger: true });
},
//
removeUploadFile(d) {
if (d.status === "error" || d.status === "success") {
this.removeFileFromList(d);
} else if (d.percent < 100) {
this.$confirm(`${d.name}正在上传中,确定要取消吗?`, `提示`, {
dangerouslyUseHTMLString: true,
confirmButtonText: `确定`,
cancelButtonText: `取消`,
type: "warning",
})
.then(() => {
this.$emit(`stopUpload`, [d]);
this.$nextTick(() => {
this.removeFileFromList(d);
this.ifNoUploadingFile_EndCalcLiveSpeed();
});
})
.catch(() => {});
} else {
this.removeFileFromList(d);
}
},
//
close({ cb } = {}) {
let stopUploadList = this.uploadingFiles;
if (stopUploadList.length) {
this.$confirm(`您还有正在上传中的文件,确定要取消吗?`, `提示`, {
dangerouslyUseHTMLString: true,
confirmButtonText: `确定`,
cancelButtonText: `取消`,
type: "warning",
})
.then(() => {
this.show = false;
this.$emit(`stopUpload`, stopUploadList);
this.$nextTick(() => {
this.endUploadCalcLiveSpeed();
this.removeAllFilesFromList();
cb && cb(stopUploadList); //
});
})
.catch(() => {});
} else {
this.show = false;
}
},
},
};
</script>
<style lang="scss" scoped>
.sgUploadTray {
$headerHeight: 40px; //
$footerHeight: 40px; //
$collapseBtnHeight: 30px; //
$minWidth: var(--minWidth); //
$minHeight: var(--minHeight); //
$loadingWidth: 30px; //
$rightWidth: 200px; //
$sizeWidth: 200px; //
$progressWidth: 100px; //
$tipWidth: 100px; //
// ----------------------------------------
z-index: 2001; //(element)v-loading2000z-index
user-select: none;
position: fixed;
right: 10px;
bottom: 10px;
width: $minWidth;
background-color: white;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
border-radius: 4px;
overflow: hidden;
border: 1px solid #eee;
font-size: 14px;
display: none;
&[show] {
display: block;
}
&[size="lg"] {
left: 0 !important;
top: 0 !important;
width: 100vw;
height: 100vh;
transition: none;
.upload-file-list {
max-height: calc(100vh - 60px) !important;
}
}
&[size="md"] {
width: $minWidth;
height: revert;
}
&[size="mn"] {
width: $minWidth;
height: $minHeight;
}
.upload-list-tray {
display: flex;
flex-direction: column;
box-sizing: border-box;
padding-bottom: 20px;
width: 100%;
height: 100%;
position: relative;
.header {
flex-shrink: 0;
font-size: 16px;
font-weight: bold;
width: 100%;
height: $headerHeight;
box-sizing: border-box;
padding: 10px 20px;
/*从上往下线性渐变背景*/
background: linear-gradient(#409eff11, white);
color: #409eff;
display: flex;
justify-content: space-between;
align-items: center;
.left {
display: flex;
align-items: center;
flex-grow: 1;
.title {
display: flex;
align-items: center;
flex-wrap: nowrap;
.upload-info {
display: flex;
align-items: center;
color: black;
flex-shrink: 0;
align-items: center;
font-weight: normal;
.info-item {
margin-right: 5px;
&:last-of-type {
margin-right: 0;
}
span {
font-family: DIN-Light;
color: #409eff;
}
&.live-speed {
span {
font-family: DIN-Black;
}
}
}
}
}
.icon-btns {
display: flex;
align-items: center;
flex-wrap: nowrap;
.icon-btn {
cursor: pointer;
margin-right: 5px;
&:last-of-type {
margin-right: 0;
}
i {
pointer-events: none;
}
&:hover {
opacity: 0.618;
}
}
}
}
.right {
display: flex;
align-items: center;
justify-content: flex-end;
flex-shrink: 0;
pointer-events: auto;
.icon-btn {
margin-left: 10px;
cursor: pointer;
i {
pointer-events: none;
}
&:hover {
opacity: 0.618;
}
&:first-of-type {
margin-left: 0;
}
}
.file-btns {
margin-left: 10px;
display: flex;
flex-wrap: nowrap;
justify-content: flex-end;
box-sizing: border-box;
padding: 0 10px;
border-right: 1px solid #eee;
}
.tray-btns {
margin-left: 10px;
display: flex;
flex-wrap: nowrap;
justify-content: flex-end;
}
}
}
.upload-file-list {
width: 100%;
flex-grow: 1;
overflow-y: auto;
height: max-content;
max-height: calc(
100vh - #{$headerHeight} - #{$footerHeight} - #{$collapseBtnHeight} - 40px
);
box-sizing: border-box;
padding: 0 20px;
ul {
width: 100%;
li {
line-height: 1.6;
box-sizing: border-box;
padding: 10px;
border-radius: 4px;
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
.left {
width: calc(100% - #{$rightWidth});
display: flex;
align-items: center;
flex-grow: 1;
flex-shrink: 0;
//
.icon-btns {
display: flex;
flex-wrap: nowrap;
.icon-btn {
display: none;
&[show] {
margin-right: 15px;
display: block;
}
}
}
.fileLoading {
flex-shrink: 0;
width: 30px;
margin-right: 5px;
height: 0;
transform: scale(0.5);
}
.loadingSuccessIcon,
.loadingEorrorIcon {
margin-right: 5px;
width: 30px;
height: 30px;
display: flex;
justify-content: center;
align-items: center;
flex-shrink: 0;
}
.name {
text-align: left;
margin-right: 10px;
width: calc(
100% - #{$loadingWidth} - #{$sizeWidth} - #{$progressWidth} - #{$rightWidth} -
20px
);
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
flex-shrink: 0;
flex-grow: 1;
}
.size {
margin-right: 10px;
max-width: $sizeWidth;
/*单行省略号*/
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
flex-shrink: 0;
}
.progress {
max-width: $progressWidth;
display: flex;
align-items: center;
flex-wrap: nowrap;
flex-shrink: 0;
}
}
.right {
display: flex;
align-items: center;
justify-content: flex-end;
width: $rightWidth;
.tip {
width: $tipWidth;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
flex-shrink: 0;
text-align: right;
&[color="red"] {
color: #f56c6c;
}
&[color="green"] {
color: #67c23a;
}
&[color="blue"] {
color: #409eff;
}
}
//
.icon-btns {
display: flex;
flex-wrap: nowrap;
.icon-btn {
display: none;
&[show] {
margin-left: 15px;
display: block;
}
}
}
}
&:hover {
background-color: #409eff11;
color: #409eff;
.left {
//
.icon-btns {
.icon-btn {
display: block;
&:last-of-type {
margin-right: 10px;
}
}
}
}
.right {
.tip {
margin-right: 15px;
}
//
.icon-btns {
.icon-btn {
display: block;
&:first-of-type {
margin-left: 0;
}
}
}
}
}
}
}
}
.footer {
font-weight: normal;
flex-shrink: 0;
font-size: 14px;
font-weight: bold;
width: 100%;
height: $footerHeight;
box-sizing: border-box;
padding: 10px 20px;
margin-bottom: -20px;
background: linear-gradient(white, #eff2f7);
color: #909399;
display: flex;
align-items: center;
flex-wrap: nowrap;
white-space: nowrap;
* {
font-weight: normal;
}
.text {
white-space: nowrap;
}
.progress {
max-width: 200px;
flex-grow: 1;
white-space: nowrap;
display: flex;
align-items: center;
flex-wrap: nowrap;
label {
white-space: nowrap;
flex-shrink: 0;
margin-right: 5px;
}
>>> .el-progress {
white-space: nowrap;
.el-progress__text {
font-weight: normal;
font-size: 14px !important;
}
}
}
}
}
}
</style>

View File

@ -1,47 +0,0 @@
<template>
<el-drawer
:wrapperClosable='false'
size="65%"
:modal="true"
:visible.sync="visible"
:show-close="false"
:append-to-body="true"
>
<template #title>
<span>流程监控</span>
<div class="drawer-head-btn">
<el-button @click="visible = false"><i class="el-icon-close"></i> 关闭</el-button>
</div><!--drawer-head-btn 抽屉顶部按钮区域-->
</template>
<div style="width:100%;height:100%">
<iframe :src="src" width="100%" height="100%" title="myFrame" style="border: 0;"></iframe>
</div>
</el-drawer>
</template>
<script>
import { getHistAskLogUrl } from "@/api/my_business/workflow";
export default {
data() {
return {
visible: false,
src: ''
};
},
methods: {
init(procInstId) {
this.visible = true
let protocol = window.location.protocol
let hostname = window.location.hostname;
let workflowManageUrl = protocol + '//' + hostname + ':9080' + process.env.VUE_APP_WORKFLOW_MANAGE_URL
// workflowManageUrl = 'http://124.223.108.21:9080/ebpm-process-manage'
this.src = workflowManageUrl + '/workflow/trace/traceProcess.do?processInstanceId=' + procInstId
}
}
}
</script>
<style scoped>
.el-drawer .el-drawer__body{
padding: 0px 0px !important;
}
</style>

View File

@ -1,248 +0,0 @@
<template>
<el-dialog
:close-on-click-modal="false"
title="预览文件"
:visible.sync="dialogVisible"
width="70%"
:destroy-on-close="true"
:append-to-body="true"
:close-on-press-escape="false"
@close="handleClose"
style="height: 100%"
>
<template v-if="isTxt">
<!-- 在文本框中预览文件内容 -->
<el-input type="textarea" :rows="30" v-model="resultContentObj" >
</el-input>
</template>
<template v-if="isDocx">
<vue-office-docx
:src="docxData"
style="height: 600px;"
@rendered="rendered"
/>
</template>
<template v-if="isPdf">
<vue-office-pdf
:src="pdfFileData"
style="height: 600px;"
@rendered="renderedHandler"
@error="errorHandler"
/>
</template>
<template v-if="isVideos">
<div class="input_video">
<video-player class="video-player vjs-custom-skin"
ref="videoPlayer"
:playsinline="true"
:options="playerOptions"
></video-player>
</div>
</template>
</el-dialog>
</template>
<script>
import axios from 'axios'
import {
getToken
} from "@/utils/auth";
import { videoPlayer } from "vue-video-player";
export default {
components: { videoPlayer},
props: {
uploadUrl: {
type: String,
required: false
},
//
isMultiple: {
type: Boolean,
default() {
return false
},
required: false
},
//
type: {
type: Array,
default() {
return []
},
required: false
},
//
acceptType: {
type: String,
required: false
},
//
limit: {
type: Number,
default() {
return 1
},
required: false
},
//
dataFile: {
type: [Object, Array, String],
default() {
return ''
},
required: false
},
isDetail: {
type: Boolean,
default: false
},
},
data() {
return {
// txt
dialogVisible:false,
isTxt:false,
resultContentObj:'',
// docx
isDocx:false,
docxData: null,
//pdf
isPdf:false,
pdfFileData: null, //
previewLoading:false,
previewUseFront: "txt,doc,docx,pdf",
isVideos:false,
//
playerOptions : {
playbackRates : [ 0.5, 1.0, 1.5, 2.0 ], //
autoplay : false, //true,
muted : false, //
loop : false, //
preload : 'auto', // <video>auto,
language : 'zh-CN',
aspectRatio : '16:9', // 使 - "16:9""4:3"
fluid : true, // trueVideo.js player
sources : [],
poster : "", //
// width: document.documentElement.clientWidth,
notSupportedMessage : '此视频暂无法播放,请稍后再试', //Video.js
controlBar : {
timeDivider : true,//
durationDisplay : true,//
remainingTimeDisplay : false,//
fullscreenToggle : true //
}
}
};
},
watch: {
},
methods: {
//
frontModulePreview(row){
let self = this
self.initPreviewData()
self.previewLoading = true
if(row.fileName.endsWith(".jpg") || row.fileName.endsWith(".png")){
this.$viewerApi({images: [row.fileUrl]})
self.previewLoading = false
self.$emit('previewLoadingClose')
return
}
if(row.fileName.endsWith(".mp4") || row.fileName.endsWith(".webm")){
if(row.fileName.endsWith(".mp4")){
this.playerOptions.sources = [
{
src: row.fileUrl,
type: 'video/mp4'
}
]
}else{
this.playerOptions.sources = [
{
src: row.fileUrl,
type: 'video/webm'
}
]
}
self.dialogVisible = true
self.isVideos = true;
self.previewLoading = false
self.$emit('previewLoadingClose')
return
}
axios({
method: 'post',
url: process.env.VUE_APP_BASE_API + "/common/preview/download",
responseType: 'blob',
data: {
'filePath': row.filePath,
'fileOldName': row.fileOldName
},
headers: { 'Authorization': 'Bearer ' + getToken() }
}).then(res => {
const content = res.data;
if(row.fileName.endsWith(".txt")){
self.dialogVisible = true
self.previewLoading = false
let blob = new Blob([res.data]);
blob.text().then(data =>{
self.resultContentObj = data;
self.isTxt = true;
self.previewLoading = false; //
self.$emit('previewLoadingClose')
})
// self.previewLoading = false
}else if (row.fileName.endsWith(".docx")) {
// renderAsync(response.data, self.$refs.file);
self.isDocx = true
self.dialogVisible = true; //
content.arrayBuffer().then(res=>{
self.docxData = res
})
self.previewLoading = false
self.$emit('previewLoadingClose')
}else if(row.fileName.endsWith(".doc") || row.fileName.endsWith(".pdf")){
self.isPdf = true
self.dialogVisible = true; //
content.arrayBuffer().then(res=>{
self.pdfFileData = res
})
self.previewLoading = false
self.$emit('previewLoadingClose')
}
}).catch(err => {
console.info("err===============", err)
self.previewLoading = false
self.$emit('previewLoadingClose')
});
},
//
initPreviewData(){
this.isTxt = false
this.isDocx = false
this.isPdf = false
this.resultcontentObj = ''
this.docxData = null
this.pdfFileData = null
},
rendered(){
console.log("渲染完成1")
},
renderedHandler(){
console.log("pdf渲染完成2")
},
errorHandler(){
console.log("pdf渲染失败3")
},
handleClose(){
this.$emit("previewClose");
}
}
};
</script>

View File

@ -155,7 +155,7 @@ export default {
}
</script>
<style scoped>
<style>
.theme-message,
.theme-picker-dropdown {
z-index: 99999 !important;

View File

@ -168,7 +168,7 @@ export default {
};
</script>
<style lang="scss" scoped>
<style lang="scss">
.topmenu-container.el-menu--horizontal > .el-menu-item {
float: left;
height: 50px !important;

View File

@ -1,36 +0,0 @@
<template>
<component :is="dashboard" ref="component" :data="data" :dataType="dataType" @close="close" style="padding: 16px 32px">
<slot></slot>
</component>
</template>
<script>
export default {
name: 'MainComponent',
props: ['code','data','dataType'],
data () {
return {
dashboard: null,
}
},
watch: {
code (val) {
this.init(val)
},
},
mounted () {
this.init(this.code)
},
methods: {
init (val) {
try {
if (val) {
this.dashboard = resolve => require(['@/' + val + '.vue'], resolve)
}
}catch (e) {}
},
close (value) {
this.$emit('close', value)
},
}
}
</script>

View File

@ -1,189 +0,0 @@
<template>
<el-dialog
title="工具选择"
:visible.sync="visible"
:close-on-click-modal="false"
width="80%"
append-to-body
:show-close="false"
>
<div class="el-card__body">
<el-form :model="queryParams" ref="queryForm" v-show="showSearch" label-width="68px" :inline="true">
<el-form-item label="编号" prop="toolCode">
<el-input
v-model.trim="queryParams.toolCode"
placeholder="请输入编号"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="中文别名" prop="toolName">
<el-input
v-model.trim="queryParams.toolName"
placeholder="请输入中文别名"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-card class="gray-card">
<el-table
v-loading="loading"
:data="dataList"
border
@selection-change="handleSelectionChange"
ref="multipleTable"
header-align="left"
>
<el-table-column type="selection" width="50" align="center" v-if="multiple" :selectable="(row,index)=>selectableFun(row,index,toolData,selectInfoData)"/>
<el-table-column label="编号" key="toolCode" prop="toolCode"/>
<el-table-column label="中文别名" key="toolName" prop="toolName":show-overflow-tooltip="true" />
<el-table-column label="类别" key="toolType" prop="toolType" :show-overflow-tooltip="true" >
<template slot-scope="scope">
<dict-tag :options="dict.type.tool_type" :value="scope.row.toolType"/>
</template>
</el-table-column>
<el-table-column label="归属单位" key="toolRespDeptName" prop="toolRespDeptName" :show-overflow-tooltip="true" />
<el-table-column label="负责人" key="toolPrincipalsName" prop="toolPrincipalsName" width="120" />
<el-table-column label="操作" v-if="!multiple" width="100px" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
@click="selectHandle(scope.row)"
>选择</el-button>
</template>
</el-table-column>
</el-table>
</el-card>
<pagination
v-show="total > 0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
</div>
<div slot="footer" v-if="multiple">
<el-button @click="visible = false"> </el-button>
<el-button type="primary" @click="selectHandle(selectInfoData)"> </el-button>
</div>
</el-dialog>
</template>
<script>
import { listTool } from '@/api/tool/tool'
export default {
name: "ToolSelector",
components: {},
dicts:['tool_type'],
props: {
toolData: {
type: Array,
default: ()=>[],
},
selectableFun: {
type: Function,
default: (row, index, toolData, selectInfoData)=>{
if (toolData) {
return toolData.findIndex(item=>item.toolId===row.toolId)<0
}else {
return true
}
},
},
selectValidate:{
type: Boolean,
default: false,
}
},
data() {
return {
visible: false,
source: undefined,
index: undefined,
multiple: false,
//
loading: true,
//
ids: [],
//
single: true,
//
showSearch: true,
//
total: 0,
//
dataList: [],
//
title: "",
//
queryParams: {
pageNum: 1,
pageSize: 10,
toolCode: undefined,
toolName: undefined,
status: undefined,
recordStatus: 'done',
},
selectInfoData: [],
//ids
filterToolIds: [],
};
},
methods: {
//
init(source,index,multiple,ids){
this.filterToolIds = []
this.visible = true
this.source = source
this.index = index
this.multiple= multiple
this.filterToolIds = ids
this.resetQuery()
},
/** 查询列表 */
getList() {
this.loading = true;
if(this.filterToolIds && this.filterToolIds.length > 0){
this.$set(this.queryParams, "filterToolIds", this.filterToolIds )
}
listTool(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
this.dataList = response.rows;
this.total = response.total;
this.loading = false;
}
);
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm('queryForm')
this.handleQuery();
},
//
handleSelectionChange(selection) {
this.selectInfoData = selection;
},
selectHandle(data){
let _this = this
if (_this.selectValidate) {
this.$emit("selectHandle", this.source, this.index, data,(res)=>{_this.visible = !res})
}else{
this.$emit("selectHandle", this.source, this.index, data)
_this.visible = false
}
},
},
};
</script>

View File

@ -6,9 +6,6 @@
:width="width || '900px'"
:height="height || '650px'"
:before-close="handleClose"
:show-close="false"
:close-on-press-escape="false"
:close-on-click-modal="false"
append-to-body
>
@ -28,6 +25,18 @@
/>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="手机号码" prop="phonenumber">
<el-input
v-model="queryParams.phonenumber"
placeholder="请输入手机号码"
clearable
style="width: 200px"
size="mini"
@keyup.enter.native="getList"
/>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="getList">搜索</el-button>
@ -168,10 +177,6 @@
open: {
type: Boolean,
default:false,
},
deptFilter: {
type: Boolean,
default:false,
}
// value: {
// type: Object,
@ -186,7 +191,9 @@
},
data() {
return {
loading: false,
// open: false,
activeName: 'first',
defaultProps: {
@ -197,7 +204,7 @@
deptOptions: undefined,
deptName: '',
showSearch: true,
userInfo: this.$store.getters.userInfo,
userList: [],
allUserList: [],
allUserMap: new Map(),
@ -233,7 +240,11 @@
},
methods: {
handleClose(done) {
this.cancel();
this.$confirm('确认关闭?')
.then(_ => {
this.cancel();
})
.catch(_ => {});
},
handleClick(tab, event) {
console.log(tab, event);
@ -265,16 +276,15 @@
return result;
},
submitForm() {
// let checkedUserArr = []
// let checkedUser = {}
// this.checkedUsers.forEach(userName => {
// checkedUser['userName'] = userName
// checkedUser['userId'] = this.getUserIdByUserName(userName)
// checkedUser['nickName'] = this.getNickNameByUserName(userName)
// checkedUserArr.push(checkedUser)
// })
// this.$emit("submit", checkedUserArr); //usernamenickname
this.$emit("submit", JSON.parse(JSON.stringify(this.selectedUserList)));
let checkedUserArr = []
let checkedUser = {}
this.checkedUsers.forEach(userName => {
checkedUser['userName'] = userName
checkedUser['userId'] = this.getUserIdByUserName(userName)
checkedUser['nickName'] = this.getNickNameByUserName(userName)
checkedUserArr.push(checkedUser)
})
this.$emit("submit", checkedUserArr); //usernamenickname
},
cancel() {
this.$emit('cancel');
@ -291,8 +301,7 @@
},
/** 查询部门下拉树结构 */
getDeptTree() {
let deptId = this.deptFilter ? this.userInfo.dept.deptId : ''
deptTreeSelect({deptId: deptId}).then(response => {
deptTreeSelect().then(response => {
this.deptOptions = response.data;
});
},
@ -300,15 +309,18 @@
// checkedUsers ['admin','ry']
getAllUserList(checkedUsers = []) {
//
let deptId = this.deptFilter ? this.userInfo.dept.deptId : ''
listUser({pageNum: 1, pageSize: 2147483647, status: "0", deptId: deptId}).then(response => {
listUser({pageNum: 1,pageSize: 2147483647,status: "0"}).then(response => {
this.allUserList = response.rows;
this.allUserMap = new Map();
this.checkedUsers = checkedUsers;
this.allUserList.forEach(item => {
this.allUserMap.set(item.userName, item);
});
this.updateCheckedUsers();
// console.log(this.allUserList, this.allUserMap);
this.getList();
}
);
@ -316,7 +328,6 @@
/** 查询用户列表 */
getList() {
this.queryParams.deptId = this.deptFilter ? this.userInfo.dept.deptId : ''
listUser(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
this.userList = response.rows;
// console.log(this.userList);

View File

@ -51,7 +51,7 @@ export default {
}
</style>
<style lang="scss" scoped>
<style lang="scss">
// fix css style bug in open el-dialog
.el-popup-parent--hidden {
.fixed-header {

View File

@ -5,55 +5,13 @@
<breadcrumb id="breadcrumb-container" class="breadcrumb-container" v-if="!topNav"/>
<top-nav id="topmenu-container" class="topmenu-container" v-if="topNav"/>
<div class="right-menu">
<!-- <span @click="toMyCartPage">
<el-badge :value="totalCartCount >= 99 ? '99+' : totalCartCount" class="item">
<span class="top-msg">消息</span>
</el-badge>
</span>-->
<span class="top-version">v1.0.0</span>
<el-popover
placement="right"
width="400"
trigger="hover">
<el-table
:data="msgTableData"
border
style="width: 100%">
<el-table-column
prop="name"
label="消息通知类型">
</el-table-column>
<el-table-column
prop="count"
label="消息通知数量">
</el-table-column>
<el-table-column label="操作" width="100" >
<template slot-scope="scope">
<el-button type="text" @click="handleToMsgView(scope.row)">前往查看</el-button>
</template>
</el-table-column>
</el-table>
<span style="cursor: pointer;" @mouseover="toMyCartPage" slot="reference">
<template v-if="totalCartCount == 0">
<el-badge value="" class="item">
<el-tooltip class="item" effect="light" content="消息通知" placement="bottom">
<i class="el-icon-bell"></i>
</el-tooltip>
</el-badge>
</template>
<template v-else>
<el-badge :value="totalCartCount >= 99 ? '99+' : totalCartCount" class="item">
<el-tooltip class="item" effect="light" content="消息通知" placement="bottom">
<i class="el-icon-bell"></i>
</el-tooltip>
</el-badge>
</template>
</span>
</el-popover>
<!--<template v-if="device!=='mobile'">
<search id="header-search" class="right-menu-item" />
<screenfull id="screenfull" class="right-menu-item hover-effect" />
</template>-->
<el-dropdown class="avatar-container right-menu-item hover-effect" trigger="click">
<div class="avatar-wrapper">
<span style="font-size: 16px"><i class="el-icon-user"/> {{nickName}}</span>
@ -68,7 +26,6 @@
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
</div>
</template>
@ -80,7 +37,6 @@ import TopNav from '@/components/TopNav'
import Hamburger from '@/components/Hamburger'
import Screenfull from '@/components/Screenfull'
import Search from '@/components/HeaderSearch'
import { getUserMsgCount } from '@/api/my_business/workflow'
export default {
components: {
@ -112,15 +68,6 @@ export default {
get() {
return this.$store.state.settings.topNav
}
},
totalCartCount() {
return this.$store.state.user.unreadMsgNumber ? this.$store.state.user.unreadMsgNumber : 0
},
},
data() {
return {
msgVisible: false,
msgTableData: []
}
},
methods: {
@ -137,32 +84,6 @@ export default {
location.href = '/index';
})
}).catch(() => {});
},
//
toMyCartPage() {
getUserMsgCount().then(res => {
this.msgTableData = [];
let msgItem = {};
msgItem['type'] = 'msg';
msgItem['name'] = '消息中心数量';
msgItem['count'] = res.msgCount;
let taskItem = {};
taskItem['type'] = 'task';
taskItem['name'] = '待办消息数量';
taskItem['count'] = res.taskCount;
this.msgTableData.push(msgItem);
this.msgTableData.push(taskItem);
}).catch(error => {
})
this.msgVisible = true;
},
handleToMsgView(row){
this.msgVisible = false;
if(row.type === 'msg'){
this.$router.push({ path: '/message', query: {'states':'1'} })
} else {
this.$router.push({ path: '/workstuff/dispose'})
}
}
}
}

View File

@ -35,7 +35,6 @@ export default {
},
data() {
return {
// title: "",
title: process.env.VUE_APP_TITLE,
logo: logoImg
}

View File

@ -45,7 +45,7 @@ export default {
},
computed: {
visitedViews() {
return this.$store.state.tagsView.visitedViews ? this.$store.state.tagsView.visitedViews : []
return this.$store.state.tagsView.visitedViews
},
routes() {
return this.$store.state.permission.routes
@ -140,15 +140,14 @@ export default {
return false
},
moveToCurrentTag() {
let self = this
const tags = this.$refs.tag
self.$nextTick(() => {
this.$nextTick(() => {
for (const tag of tags) {
if (tag.to.path === this.$route.path) {
self.$refs.scrollPane.moveToTarget(tag)
this.$refs.scrollPane.moveToTarget(tag)
// when query is different then update
if (tag.to.fullPath !== this.$route.fullPath) {
self.$store.dispatch('tagsView/updateVisitedView', self.$route)
this.$store.dispatch('tagsView/updateVisitedView', this.$route)
}
break
}
@ -306,7 +305,7 @@ export default {
}
</style>
<style lang="scss" scoped>
<style lang="scss">
//reset element css of el-icon-close
.tags-view-wrapper {
.tags-view-item {

View File

@ -8,7 +8,6 @@ import '../public/css/poctstyle.css'
import '../public/css/tool.css'
import '@/assets/styles/index.scss' // global css
import '@/assets/styles/ruoyi.scss' // ruoyi css
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
import App from './App'
import store from './store'
import router from './router'
@ -39,17 +38,6 @@ import DictTag from '@/components/DictTag'
import VueMeta from 'vue-meta'
// 字典数据组件
import DictData from '@/components/DictData'
// 图形监控组件
import MonitorDrawer from "@/components/MonitorDrawer"
//引入VueOfficeDocx组件
import VueOfficeDocx from '@vue-office/docx'
//引入相关样式
import '@vue-office/docx/lib/index.css'
import VueOfficePdf from '@vue-office/pdf'
//视频组件
import 'video.js/dist/video-js.css'
import 'vue-video-player/src/custom-theme.css'
// 全局方法挂载
Vue.prototype.getDicts = getDicts
@ -61,9 +49,6 @@ Vue.prototype.selectDictLabel = selectDictLabel
Vue.prototype.selectDictLabels = selectDictLabels
Vue.prototype.download = download
Vue.prototype.handleTree = handleTree
import 'viewerjs/dist/viewer.css'
import Viewer from 'v-viewer'
// 全局组件挂载
Vue.component('DictTag', DictTag)
@ -73,15 +58,7 @@ Vue.component('Editor', Editor)
Vue.component('FileUpload', FileUpload)
Vue.component('ImageUpload', ImageUpload)
Vue.component('ImagePreview', ImagePreview)
Vue.component('MonitorDrawer', MonitorDrawer)
Vue.component('VueOfficeDocx', VueOfficeDocx)
Vue.component('VueOfficePdf', VueOfficePdf)
Vue.use(Viewer, {
defaultOptions: {
zIndex: 9999
}
})
Vue.use(directive)
Vue.use(plugins)
Vue.use(VueMeta)

View File

@ -8,7 +8,7 @@ import { isRelogin } from '@/utils/request'
NProgress.configure({ showSpinner: false })
const whiteList = ['/login', '/register', '/workflow/msg/count/']
const whiteList = ['/login', '/register']
router.beforeEach((to, from, next) => {
NProgress.start()
@ -37,7 +37,6 @@ router.beforeEach((to, from, next) => {
next({ path: '/' })
})
})
store.dispatch('GetUserMsgCount').then(() => { })
} else {
next()
}

View File

@ -9,7 +9,7 @@ const baseURL = process.env.VUE_APP_BASE_API
let downloadLoadingInstance;
export default {
downloadByName(name, isDelete) {
name(name, isDelete = true) {
var url = baseURL + "/common/download?fileName=" + encodeURIComponent(name) + "&delete=" + isDelete
axios({
method: 'get',

View File

@ -41,12 +41,6 @@ export const constantRoutes = [
}
]
},
{
// 统一流程处理前端页面(涉及待办、已办、办结)
path: '/workflowRouter',
component: (resolve) => require(['@/views/workflowList/workflowRouter.vue'], resolve),
hidden: true
},
{
path: '/login',
component: () => import('@/views/login'),

View File

@ -7,11 +7,8 @@ const getters = {
cachedViews: state => state.tagsView.cachedViews,
token: state => state.user.token,
avatar: state => state.user.avatar,
userId: state => state.user.id,
userInfo: state => state.user.info,
name: state => state.user.name,
nickName: state => state.user.nickName,
unreadMsgNumber: state => state.user.unreadMsgNumber,
introduction: state => state.user.introduction,
roles: state => state.user.roles,
permissions: state => state.user.permissions,

View File

@ -1,6 +1,5 @@
import { login, logout, getInfo } from '@/api/login'
import { getToken, setToken, removeToken } from '@/utils/auth'
import { getUserMsgCount } from '@/api/my_business/workflow'
const user = {
state: {
@ -8,11 +7,9 @@ const user = {
id: '',
name: '',
nickName: '',
info: {},
avatar: '',
roles: [],
permissions: [],
unreadMsgNumber: 0,
permissions: []
},
mutations: {
@ -36,12 +33,6 @@ const user = {
},
SET_PERMISSIONS: (state, permissions) => {
state.permissions = permissions
},
SET_INFO:(state, info) => {
state.info = info
},
SET_UNREAD_MSG_NUMBER:(state, info) => {
state.unreadMsgNumber = info
}
},
@ -76,12 +67,9 @@ const user = {
commit('SET_ROLES', ['ROLE_DEFAULT'])
}
commit('SET_ID', user.userId)
commit('SET_UNREAD_MSG_NUMBER', res.unMsgNumber)
commit('SET_NAME', user.userName)
commit('SET_NICK_NAME', user.nickName)
commit('SET_AVATAR', avatar)
commit('SET_INFO', user)
resolve(res)
}).catch(error => {
reject(error)
@ -103,16 +91,6 @@ const user = {
})
})
},
GetUserMsgCount({ commit, state }) {
return new Promise((resolve, reject) => {
getUserMsgCount().then(res => {
commit('SET_UNREAD_MSG_NUMBER', res.totalMsgCount)
resolve()
}).catch(error => {
reject(error)
})
})
},
// 前端 登出
FedLogOut({ commit }) {

View File

@ -1,6 +1,6 @@
import Cookies from 'js-cookie'
const TokenKey = 'Admin-Token-Tool'
const TokenKey = 'Admin-Token'
export function getToken() {
return Cookies.get(TokenKey)

View File

@ -1,58 +0,0 @@
import docxtemplater from 'docxtemplater';
import PizZip from 'pizzip';
import JSZipUtils from 'jszip-utils';
import {saveAs} from 'file-saver';
/**
导出docx,导出word
@param { String } tempDocxPath 模板文件路径
@param { Object } data 文件中传入的数据
@param { String } fileName 导出文件名称
*/
export const exportDocx = (tempDocxPath, data, fileName) => {
// 读取并获得模板文件的二进制内容
JSZipUtils.getBinaryContent(tempDocxPath, (error, content) => {
// input.docx是模板。我们在导出的时候会根据此模板来导出对应的数据
// 抛出异常
if (error) {
throw error
}
// 创建一个JSZip实例内容为模板的内容
const zip = new PizZip(content)
// 创建并加载docxtemplater实例对象
const doc = new docxtemplater().loadZip(zip)
// 设置模板变量的值
doc.setData({
...data.form,
list: data.list
})
// 模板导出word,去除未定义值所显示的undefined
doc.setOptions({nullGetter: function() {
return "";
}}); // 设置角度解析器
try {
// render the document (replace all occurences of {first_name} by John, {last_name} by Doe, ...)
doc.render()
} catch (error) {
const e = {
message: error.message,
name: error.name,
stack: error.stack,
properties: error.properties
}
console.log({
error: e
})
// The error thrown here contains additional information when logged with JSON.stringify (it contains a property object).
throw error
}
const out = doc.getZip().generate({
type: 'blob',
mimeType: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
}) // Output the document using Data-URI
saveAs(out, fileName)
})
}

View File

@ -17,7 +17,7 @@ const service = axios.create({
// axios中请求配置有baseURL选项表示请求URL公共部分
baseURL: process.env.VUE_APP_BASE_API,
// 超时
timeout: 200000
timeout: 10000
})
// request拦截器

View File

@ -1,624 +0,0 @@
<template>
<div class="fbox1">
<div class="fl" v-loading="detailLoading">
<el-tabs v-model="detailActiveName">
<el-tab-pane label="基本信息" name="first">
<div class="el-form-border">
<el-form ref="form" label-width="150px">
<el-row>
<el-col :span="24"> <el-form-item label="文件分类">{{form.docCategoryName}}</el-form-item> </el-col>
<el-col :span="12"> <el-form-item label="文档编号">{{form.docCode}}</el-form-item> </el-col>
<el-col :span="12"> <el-form-item label="文档名称">{{form.docName}}</el-form-item> </el-col>
<el-col :span="12"> <el-form-item label="文档类别"><dict-tag :options="dict.type.doc_class" :value="form.docType"/></el-form-item> </el-col>
<el-col :span="12"> <el-form-item label="文档来源"><dict-tag :options="dict.type.doc_source" :value="form.docSource"/></el-form-item> </el-col>
<el-col :span="12"> <el-form-item label="负责人">{{form.docPrincipalsName}}</el-form-item> </el-col>
<el-col :span="12"> <el-form-item label="归属单位">{{form.docRespDeptName}}</el-form-item> </el-col>
<el-col :span="24"> <el-form-item label="备注">{{form.remark}}</el-form-item> </el-col>
</el-row>
</el-form><!--el-form-->
</div><!--el-form-border 表单-->
</el-tab-pane><!--el-tab-pane-->
<el-tab-pane label="关联附件" name="second" v-loading="previewLoading" element-loading-text="预览转换中,请耐心等待">
<el-table :data="attachmentList" style="width: 100%">
<el-table-column label="序号" width="60" type="index" align="center"></el-table-column>
<el-table-column label="附件名称" prop="fileName" :show-overflow-tooltip="true" />
<el-table-column label="操作" align="center" width="150px">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-view"
v-if="previewAuth(scope.row)"
@click="handlePreview(scope.row)"
>预览</el-button>
<el-button type="text" icon="el-icon-download" v-if="form.downloadStatus"
@click="handleDownload(scope.row)" v-loading="loadingDownload">下载</el-button>
</template>
</el-table-column>
</el-table><!--el-table-->
<!-- 分页组件 -->
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getAttachmentList"
/>
</el-tab-pane><!--el-tab-pane-->
</el-tabs><!--el-tabs-->
</div><!--fl 左侧页签-->
<div class="fr" v-if="isComment && form.docStatus == 'yfb'">
<div class="tboper">
<div class="tit">评论{{ reviewTotal }}</div>
</div><!--tboper 标题与操作按钮-->
<div class="pltextarea">
<el-input v-model="discussionContent" type="textarea" placeholder="请输入您的意见" :rows="4" maxlength="1000" show-word-limit></el-input>
<div class="plbtn"><el-button @click="handleDiscussions">发布</el-button></div>
</div><!--pltextarea-->
<div class="pllist">
<template v-if="discussionsList && discussionsList.length > 0">
<div class="list" v-for="(item,index) in discussionsList" :key="item.id">
<div class="luser"><span class="xuser" :style="{backgroundColor: extractColorByName(item.nickName)}">{{getFirstChar(item.nickName)}}</span></div>
<div class="ltext">
<div class="nt"><span class="name">{{item.nickName}}</span><span class="time">{{ parseTime(item.createTime, '{y}-{m}-{d} {h}:{i}') }}</span></div>
<div class="te">{{item.content}}</div>
<div class="hb">
<a class="btn" @click="toggleReplyForm(index)">
<i class="el-icon-chat-line-round"></i>回复
</a>
</div>
<div class="pltextarea" v-if="showReplyForm[index]">
<el-input type="textarea" v-model="replyContent[index]" placeholder="请输入您的意见" :rows="2" maxlength="1000" show-word-limit></el-input>
<div class="plbtn">
<el-button @click="cancelReply(index)">取消</el-button>
<el-divider direction="vertical"></el-divider>
<el-button @click="submitReply(index, item)">发布</el-button>
</div>
</div>
<!--第二层级-->
<template v-if="item.repliesList && item.repliesList.length > 0">
<div class="list" v-for="(repItem,repIdex) in item.repliesList" :key="repItem.id">
<div class="luser">
<span class="xuser" :style="{width:'28px',height:'28px',lineHeight:'28px',backgroundColor: extractColorByName(repItem.nickName)}">{{getFirstChar(repItem.nickName)}}</span>
</div>
<div class="ltext">
<div class="nt">
<span class="name">{{repItem.nickName}}</span>
<template v-if="repItem.repTargetNickName">
<span>回复</span>
<span class="name">{{ repItem.repTargetNickName }}</span>
</template>
<span class="time">{{ parseTime(repItem.createTime, '{y}-{m}-{d} {h}:{i}') }}</span>
</div>
<div class="te">{{repItem.content}}</div>
<div class="hb"><a class="btn" @click="toggleReplyFormSon(index,repIdex)"><i class="el-icon-chat-line-round"></i>回复</a></div>
<div class="pltextarea" v-if="item.showReplyFormSon[repIdex]">
<el-input type="textarea" v-model="item.replyContentSon[repIdex]" placeholder="请输入您的意见" :rows="2" maxlength="1000" show-word-limit></el-input>
<div class="plbtn">
<el-button @click="cancelReplySon(index,repIdex)">取消</el-button>
<el-divider direction="vertical"></el-divider>
<el-button @click="submitReplySon(index, repIdex, item, repItem.id)">发布</el-button>
</div>
</div>
</div>
</div>
</template>
</div>
</div>
</template>
</div>
</div>
<preview-util v-if="isPreviewDisable" ref="previewForm" @previewClose="previewClose" @previewLoadingClose="previewLoadingClose"></preview-util>
</div><!--el-form-border 表单-->
</template>
<script>
import { addDocument, updateDocument, getDocument } from "@/api/document/document";
import { deptTreeSelect } from "@/api/system/user";
import { documentTree } from "@/api/documentCategory/documentCategory.js";
import { listReplies, addReplies} from "@/api/tool/replies.js";
import { listAttachment } from "@/api/attachment/attachment";
import { addCount } from "@/api/tool/downloadCount";
import previewUtil from '@/components/PreviewUtil/previewUtil.vue'
import { listDiscussions, addDiscussions } from "@/api/tool/discussions.js";
export default {
name: 'editDocument',
components: {previewUtil},
dicts:['doc_class','doc_source'],
props: {
tooId: {
type: String,
default: "",
required: false
},
relatedTool: {
type: Boolean,
default: true,
},
//
isDownload: {
type: Boolean,
default() {
return true
},
required: false
},
//
isComment: {
type: Boolean,
default() {
return true
},
required: false
},
},
data(){
return{
detailActiveName: 'first',
templateSelection: '',
drawer1: false,
reviewTotal: 0,
checkList: [],
//
form: {
docId: undefined,
docCategoryId: undefined,
docCode: '',
docName: '',
docType: '',
docPrincipals: null,
docPrincipalsName: null,
docRespDept: this.$store.getters.userInfo.deptId,
docSource: '',
toolId: '',
remark: undefined,
docCategoryName: undefined,
},
fileList: [],
progress: 0,
//
rules: {
},
docCategory:[],
deptOptions:[],
uploadFileUrl: process.env.VUE_APP_BASE_API + "/common/upload", //
fileData: null,
editStatus: true,
toolDataInfo: [],
dataFile: [],
//
detailBoolean: false,
discussionContent: null, //
repliesContent: null, //
//
discussionsList: [],
//
repliesList: [],
showReplyForm: [],
replyContent: [],
detailLoading: false,
attachmentList: [],
attFileType: "zip,rar,7z",
isPreviewDisable: false,
loadingDownload: false,
userInfo: this.$store.getters.userInfo,
toolPrincipalsChoose: false,
docQueryParams: {
pageNum: 1,
pageSize: 10,
},
queryParams: {
pageNum: 1,
pageSize: 10,
},
total: 0,
previewLoading: false,
}
},
computed: {
},
created(){
// this.getDeptTree();
this.getDocumentTree();
this.getDiscussionsList()
},
mounted(){
},
methods:{
chooseToolConfirm(){
this.$set(this.form, "toolId", this.templateSelection)
this.drawer1 = false;
},
getCurrentRow(row){
// row
},
showOpenHandle(){
this.reset();
this.title = "上传文档";
},
//
reset() {
this.form = {
docName: '',
docType: '',
docPrincipals: '',
docRespDept: '',
docSource: '',
toolId: ''
};
this.fileList = []
this.resetForm("form");
},
//
cancel() {
this.drawer1 = false;
this.reset();
},
generateUniqueID() {
// 使ID
const timestamp = new Date().getTime();
// IDID
const uniqueID = 'file_' + timestamp;
return uniqueID;
},
/** 查询部门下拉树结构 */
getDeptTree() {
deptTreeSelect().then(response => {
this.deptOptions = response.data;
});
},
/** 查询树形下拉树结构 */
getDocumentTree() {
documentTree().then(res => {
this.docCategory = res.data;
});
},
/**初始化 **/
resetForm() {
let self = this
self.form.docPrincipalsName = null
this.$refs.form.resetFields();
this.toolDataInfo = []
this.fileList = []
this.attachmentList = []
this.detailBoolean = false
this.setAllRequiredTrue(true)
this.$nextTick(()=>{
if(self.$refs.uploadFile){
self.$refs.uploadFile.clearFile();
}
})
},
editInit(docId, type){
let self = this
if(type == "detail"){
this.detailBoolean = true
self.setAllRequiredTrue(false)
}
self.$refs.form.resetFields();
self.toolDataInfo = []
self.$nextTick(()=>{
if(self.$refs.uploadFile){
self.$refs.uploadFile.clearFile();
}
getDocument(docId).then(res => {
self.form = res.data
self.toolDataInfo = []
let toolInfo = {toolId:self.form.toolId,toolName:self.form.toolName}
self.toolDataInfo.push(toolInfo)
self.dataFile = []
/* let fileData = res.data.attachment
self.$set(fileData, "name", fileData.fileOldName)
self.$set(fileData, "size", fileData.fileSize)
self.dataFile.push(fileData) */
self.getAttachmentList()
self.getDiscussionsList()
setTimeout(() => {
self.$set(self.form, "docCategoryName" , self.findLabelById(self.docCategory, self.form.docCategoryId) )
}, 300);
});
})
},
/** 评论 **/
handleDiscussions(){
let self = this
if (this.discussionContent == '' || this.discussionContent == null || this.discussionContent == undefined) {
self.$message({
message: '内容不能为空',//
type:'warning',  //
duration:1200,  //, 0 1200
});
return;
}
let data = {
businessId: this.form.docId,
content: this.discussionContent,
type: "doc",
}
self.$modal.confirm('是否确认发布?').then(()=> {
addDiscussions(data).then(res => {
this.discussionContent = null
self.$message({
message: '发布成功',//
type:'success',  //
duration:1200,  //, 0 1200
});
self.getDiscussionsList()
}).catch(err =>{
this.discussionContent = null
console.error("handleDiscussions==err==", err)
self.$modal.msgError("发布失败");
});
})
},
getAttachmentList() {
let self = this
this.$set(this.queryParams,'del',"0")
this.$set(this.queryParams,'businessId',this.form.docId)
listAttachment(this.queryParams).then(res => {
self.attachmentList = res.rows;
self.total = res.total;
self.loading = false;
});
},
getFirstChar(value) {
if(!value){return ''}
return value.charAt(0);
},
toggleReplyForm(index) {
this.$set(this.showReplyForm, index, !this.showReplyForm[index]);
},
cancelReply(index) {
this.$set(this.showReplyForm, index, false);
this.$set(this.replyContent, index, '');
},
extractColorByName(name) {
let temp = [];
temp.push("#");
for (let index = 0; index < name.length; index++) {
temp.push(parseInt(name[index].charCodeAt(0), 10).toString(16));
}
return temp.slice(0, 5).join('').slice(0, 4);
},
/** 第二级 **/
toggleReplyFormSon(parentIndex, repIndex) {
const parentItem = this.discussionsList[parentIndex];
this.$set(parentItem.showReplyFormSon, repIndex, !parentItem.showReplyFormSon[repIndex]);
// this.$set(this.showReplyFormSon, index, !this.showReplyFormSon[index]);
},
/** 第二级,取消回复 **/
cancelReplySon(parentIndex, repIndex) {
const parentItem = this.discussionsList[parentIndex];
this.$set(parentItem.showReplyFormSon, repIndex, false);
this.$set(parentItem.replyContentSon, repIndex, '');
},
/** 第二级回复 **/
submitReplySon(parentIndex, repIndex, repItem, repId) {
let self = this
const parentItem = this.discussionsList[parentIndex];
const content = parentItem.replyContentSon[repIndex];
if (content.trim() == '' || content == null || content == undefined) {
self.$message({
message: '回复内容不能为空',//
type:'warning',  //
duration:1200,  //, 0 1200
});
return;
}
let data = {
"discussionId": repItem.id,
"repId": repId,
"content": content,
}
self.$modal.confirm('是否确认发布?').then(()=> {
addReplies(data).then(res => {
self.$message({
message: '发布成功',//
type:'success',  //
duration:1200,  //, 0 1200
});
self.cancelReplySon(parentIndex, repIndex)
self.getDiscussionsList()
//
this.$set(parentItem.replyContentSon, repIndex, '');
this.$set(parentItem.showReplyFormSon, repIndex, false);
}).catch(err =>{
console.error("submitReplySon==err==", err)
self.$modal.msgError("发布失败");
});
})
},
/** 回复 **/
submitReply(index, item) {
let self = this
const content = this.replyContent[index];
if (content == '' || content == null || content == undefined) {
self.$message({
message: '回复内容不能为空',//
type:'warning',  //
duration:1200,  //, 0 1200
});
return;
}
let data = {
"discussionId": item.id,
"content": content,
}
self.$modal.confirm('是否确认发布?').then(()=> {
addReplies(data).then(res => {
self.$message({
message: '发布成功',//
type:'success',  //
duration:1200,  //, 0 1200
});
self.cancelReply(index)
self.getDiscussionsList()
}).catch(err =>{
console.error("handleDiscussions==err==", err)
self.$modal.msgError("发布失败");
});
})
//
this.replyContent[index] = '';
this.showReplyForm[index] = false;
},
previewAuth(row){
if(row.fileUrl == null || row.fileUrl == '' || row.fileUrl == undefined){
return false
}
let extension = this.getExtension(row.fileUrl);
const acceptedExtensions = this.attFileType.toLowerCase().split(',');
if(acceptedExtensions.includes(extension)){
return false
}
return true
},
getExtension(filePath) {
// '.'
const parts = filePath.split('.');
//
const extension = parts.pop();
return extension;
},
handlePreview(row){
this.isPreviewDisable = true
this.previewLoading = true
this.$nextTick(() => {
this.$refs.previewForm.frontModulePreview(row)
})
},
/** 关闭预览 **/
previewClose(){
this.isPreviewDisable = false
},
/** 关闭预览遮罩 **/
previewLoadingClose(){
this.previewLoading = false
},
/**
* 处理下载
* **/
handleDownload(row){
let self = this
self.loadingDownload = true
this.$download.resource(row.fileUrl);
//
if(row.businessId){
let formData = {
'businessId': row.businessId,
'businessType': 'doc',
'attId': row.id,
'attName': row.fileOldName
}
addCount(formData).then(res => {
});
}
setTimeout(()=>{
self.loadingDownload = false
},1000)
},
handleDelete(row){
const index = this.attachmentList.findIndex(item => item.fileNewName == row.fileNewName);
if (index !== -1) {
// attachmentList
this.attachmentList.splice(index, 1);
//
if (this.paginatedData.length === 0 && this.currentPage > 1) {
this.currentPage--;
}
}
// this.attachmentList.splice(row,1)
},
handleBeforeClose() {
this.viewDialogOpen = false
},
handleUploadSuccess(res) {
this.attachmentList.push(res)
//
},
handleUploadError(error) {
//
},
isShowOperation(row){
let self = this
if(row.businessId == null || row.businessId == undefined || row.businessId == ''){
return false
}
return true
},
submitPeople(peopleList){
this.$set(this.form,'docPrincipals',peopleList[0]['userId'])
this.$set(this.form,'docPrincipalsName',peopleList[0]['nickName'])
this.toolPrincipalsChoose = false;
},
setAllRequiredTrue(value) {
Object.keys(this.rules).forEach(key => {
this.rules[key].forEach(rule => {
rule.required = value;
});
});
},
handlePageChange(newPage) {
this.currentPage = newPage;
},
//
findLabelById(treeData, id) {
for (let i = 0; i < treeData.length; i++) {
let item = treeData[i];
if (item.id == id) {
return item.label;
}
if (item.children && item.children.length) {
const label = this.findLabelById(item.children, id);
if (label) {
return label;
}
}
}
return null;
},
getDiscussionsList() {
let _this = this
_this.reviewTotal = 0
listDiscussions({businessId:_this.form.docId}).then(res => {
_this.discussionsList = res.rows
let reviewTotal = 0
_this.discussionsList.forEach(item => {
if(item.repliesList && item.repliesList.length > 0){
reviewTotal += item.repliesList.length
_this.$set(item, 'showReplyFormSon', new Array(item.repliesList.length).fill(false))
_this.$set(item, 'replyContentSon', new Array(item.repliesList.length).fill(''))
}else{
_this.$set(item, 'showReplyFormSon', false)
_this.$set(item, 'replyContentSon', '')
}
});
_this.reviewTotal = _this.discussionsList.length + reviewTotal
});
},
}
}
</script>
<style scoped>
</style>

View File

@ -1,164 +0,0 @@
<template>
<div class="fbox1">
<div class="fl">
<el-tabs v-model="detailActiveName">
<el-tab-pane label="附件信息" name="first" v-loading="previewLoading" element-loading-text="预览转换中,请耐心等待">
<el-table :data="attachmentList" style="width: 100%">
<el-table-column label="序号" width="60" align="center" type="index"></el-table-column>
<el-table-column label="附件名称" prop="fileName" :show-overflow-tooltip="true" />
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createDate) }}</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="180" v-if="docDetail.downloadStatus">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-view"
@click="handlePreview(scope.row)"
>预览</el-button>
<el-button type="text" icon="el-icon-download" @click="handleDownload(scope.row)" v-loading="loadingDownload">下载</el-button>
</template>
</el-table-column>
</el-table><!--el-table-->
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getAttachmentList"
/>
</el-tab-pane><!--el-tab-pane-->
</el-tabs><!--el-tabs-->
</div><!--fl 左侧页签-->
<preview-util v-if="isPreviewDisable" ref="previewForm" @previewClose="previewClose" @previewLoadingClose="previewLoadingClose"></preview-util>
</div><!--fbox1 左右分栏-->
</template>
<script>
import previewUtil from '@/components/PreviewUtil/previewUtil.vue'
import { listAttachment } from "@/api/attachment/attachment";
import { addCount } from "@/api/tool/downloadCount";
export default {
name: 'docDetailFile',
components: { previewUtil},
dicts:[],
props: {
docDetail: {
type: Object,
default: {},
}
},
data(){
return{
detailActiveName: 'first',
attachmentList: [],
queryParams: {
pageNum: 1,
pageSize: 10,
docId: ''
},
previewUrl: '',
viewDialogTitle: "",
viewDialogOpen: false,
open: false,
loadingDownload: false,
discussionContent: null, //
repliesContent: null, //
//
discussionsList: [],
//
repliesList: [],
showReplyForm: [],
replyContent: [],
isPreviewDisable: false,
attFileType: "zip,rar,7z",
total: 0,
previewLoading: false,
}
},
created(){
this.previewLoading = false
this.getAttachmentList()
},
methods:{
getAttachmentList() {
this.loading = true;
this.$set(this.queryParams,'del',"0")
this.$set(this.queryParams,'businessId',this.docDetail.docId)
listAttachment(this.queryParams).then(response => {
this.attachmentList = response.rows;
this.total = response.total;
this.loading = false;
}
);
},
handlePreview(row){
this.isPreviewDisable = true
this.previewLoading = true
this.$nextTick(() => {
this.$refs.previewForm.frontModulePreview(row)
})
},
/** 关闭预览 **/
previewClose(){
this.isPreviewDisable = false
},
/** 关闭预览遮罩 **/
previewLoadingClose(){
this.previewLoading = false
},
previewAuth(row){
if(row.fileUrl == null || row.fileUrl == '' || row.fileUrl == undefined){
return false
}
let extension = this.getExtension(row.fileUrl);
const acceptedExtensions = this.attFileType.toLowerCase().split(',');
if(acceptedExtensions.includes(extension)){
return false
}
return true
},
getExtension(filePath) {
// '.'
const parts = filePath.split('.');
//
const extension = parts.pop();
return extension;
},
/**
* 处理下载
* **/
handleDownload(row){
let self = this
self.loadingDownload = true
this.$download.resource(row.fileUrl);
//
if(row.businessId){
let formData = {
'businessId': row.businessId,
'businessType': 'doc',
'attId': row.id,
'attName': row.fileOldName
}
addCount(formData).then(res => {
});
}
setTimeout(()=>{
self.loadingDownload = false
},1000)
},
}
}
</script>
<style scoped>
</style>

File diff suppressed because it is too large Load Diff

View File

@ -1,84 +1,18 @@
<template>
<div class="app-container">
<el-card>
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="70px">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch">
<div class="search">
<div class="sl">
<el-form-item label="文档编号" prop="docCode">
<el-input
v-model="queryParams.docCode"
placeholder="请输入文档名称"
clearable
@clear="handleQuery"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="文档名称" prop="docName">
<el-form-item label="文档名称" prop="roleName">
<el-input
v-model="queryParams.docName"
placeholder="请输入文档名称"
clearable
@clear="handleQuery"
style="width: 240px"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="文档类别" prop="docType">
<el-select v-model="queryParams.docType" placeholder="请选择" @change="handleQuery">
<el-option
v-for="dict in dict.type.doc_class"
:key="dict.value"
:label="dict.label"
:value="dict.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="文档来源" prop="docSource">
<el-select v-model="queryParams.docSource" placeholder="请选择" @change="handleQuery">
<el-option
v-for="dict in dict.type.doc_source"
:key="dict.value"
:label="dict.label"
:value="dict.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="创建时间">
<el-date-picker
v-model="dateRange"
value-format="yyyy-MM-dd"
type="daterange"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
@change="handleQuery"
></el-date-picker>
</el-form-item>
<el-form-item label="负责人" prop="docPrincipalsName">
<el-input
v-model="queryParams.docPrincipalsName"
placeholder="请输入负责人名称"
clearable
@clear="handleQuery"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<!-- <el-form-item label="归属单位" prop="docRespDept">
<treeselect v-model="queryParams.docRespDept" :options="deptOptions"
placeholder="请选择归属单位"
:show-count="true" style="width: 150px"/>
</el-form-item>-->
<el-form-item label="状态" prop="docStatus">
<el-select v-model="queryParams.docStatus" placeholder="请选择" @change="handleQuery">
<el-option
v-for="dict in dict.type.doc_upload_status"
:key="dict.value"
:label="dict.label"
:value="dict.value"
></el-option>
</el-select>
</el-form-item>
</div>
<div class="sr">
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
@ -90,36 +24,25 @@
<el-card class="lrtt">
<div class="lt">
<el-input
v-model="categoryNameParam"
placeholder="请输入文档分类名称"
v-model="deptName"
placeholder="请输入部门名称"
clearable
size="small"
prefix-icon="el-icon-search"
style="margin-bottom: 20px"
/>
<!-- <el-input placeholder="请输入..." prefix-icon="el-icon-search"
clearable size="small" style="margin-bottom: 20px"
v-model="categoryNameParam"></el-input>-->
<div class="divide"></div><!--divide 分隔-->
<el-tree :data="docCategory" :props="docCategoryProps"
ref="tree" :expand-on-click-node="false"
:filter-node-method="filterNode"
node-key="id"
default-expand-all
highlight-current
@node-click="handleNodeClick">
<span class="custom-tree-node" slot-scope="{ node, data }">
<span>{{ node.label }}</span>
<el-dropdown>
<span class="el-dropdown-link"><i class="el-icon-more"></i></span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item @click.native="handleDocCategoryAdd(data)"><i class="el-icon-plus"></i>添加</el-dropdown-item>
<el-dropdown-item v-if="data.types != 'system'" @click.native="handleDocCategoryUpdate(data)"><i class="el-icon-edit"></i>编辑</el-dropdown-item>
<el-dropdown-item v-if="data.types != 'system'" @click.native="handleDocCategoryDelete(data)"><i class="el-icon-delete"></i>删除</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</span>
</el-tree>
<el-tree
:data="deptOptions"
:props="defaultProps"
:expand-on-click-node="false"
:filter-node-method="filterNode"
ref="tree"
node-key="id"
default-expand-all
highlight-current
@node-click="handleNodeClick"
/>
</div><!--lt -->
<div class="rt">
<div class="operate">
@ -129,89 +52,46 @@
icon="el-icon-upload2"
size="mini"
@click="handleAdd"
v-hasPermi="['document:add']"
>上传文档</el-button>
<el-button type="primary" icon="el-icon-position" @click="handlePush" v-hasPermi="['document:push']">发布</el-button>
<el-button type="primary" icon="el-icon-download" @click="handleOpenExport()" v-hasPermi="['document:export']">全量导出</el-button>
<el-button type="primary" icon="el-icon-download" @click="handleOpenBatchExport()" v-hasPermi="['document:batch:export']">批量导出</el-button>
<el-button icon="el-icon-delete" @click="handleDelete" v-hasPermi="['document:batch:remove']">批量删除</el-button>
<el-button type="primary" icon="el-icon-position">发布</el-button>
<el-button icon="el-icon-delete" @click="handleDelete">批量删除</el-button>
</div><!--operate 操作按钮-->
<el-table v-loading="loading" :data="docList" ref="tableRef" @selection-change="handleSelectionChange">
<el-table v-loading="loading" :data="docList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="文档编号" prop="docCode" width="120" />
<el-table-column label="文档名称" prop="docName" :show-overflow-tooltip="true" />
<el-table-column label="文档类别" prop="docType" :show-overflow-tooltip="true" width="80">
<el-table-column label="文档编号" prop="docCode" width="120" />
<el-table-column label="文档名称" prop="docName" :show-overflow-tooltip="true" />
<el-table-column label="类别" prop="docType" :show-overflow-tooltip="true" width="80" />
<el-table-column label="负责人" prop="docPrincipals" :show-overflow-tooltip="true" width="80" />
<el-table-column label="归属部门" prop="docRespDept" :show-overflow-tooltip="true" width="150" />
<el-table-column label="来源" prop="docSource" width="100" />
<el-table-column label="关联工具" prop="roleSort" width="100" />
<el-table-column label="上传状态" prop="docUploadProgress" width="100" >
<template slot-scope="scope">
<dict-tag :options="dict.type.doc_class" :value="scope.row.docType"/>
</template>
</el-table-column>·
<el-table-column label="负责人" prop="docPrincipalsName" :show-overflow-tooltip="true" width="100" />
<el-table-column label="归属单位" prop="docRespDeptName" :show-overflow-tooltip="true" width="80" />
<el-table-column label="文档来源" prop="docSource" width="100">
<template slot-scope="scope">
<dict-tag :options="dict.type.doc_source" :value="scope.row.docSource"/>
<el-tag type="success" v-if="scope.row.docStatus == 'ysc'">已上传</el-tag>
<el-tag type="danger" v-else>上传失败</el-tag>
</template>
</el-table-column>
<!-- <el-table-column label="关联工具" align="center" prop="toolName" width="100" />-->
<el-table-column label="文档状态" align="center" prop="docStatus" width="100" >
<template slot-scope="scope">
<dict-tag :options="dict.type.doc_upload_status" :value="scope.row.docStatus"/>
</template>
<!--
<template slot-scope="scope">
<el-tag type="info" v-if="scope.row.docStatus == 'ysc'">已上传</el-tag>
<el-tag type="success" v-else-if="scope.row.docStatus == 'yfb'">已发布</el-tag>
<el-tag type="warning" v-else-if="scope.row.docStatus == 'shz'">审核中</el-tag>
</template>-->
</el-table-column>
<el-table-column label="创建时间" align="center" prop="createTime" width="180" :show-overflow-tooltip="true">
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="160px" fixed="right">
<template slot-scope="scope">
<!-- <el-button
<el-table-column label="操作" align="center" width="180">
<template slot-scope="scope" v-if="scope.row.roleId !== 1">
<el-button
size="mini"
type="text"
icon="el-icon-view"
v-if="previewAuth(scope.row)"
@click="handlePreview(scope.row)"
v-hasPermi="['document:preview']"
>预览</el-button>-->
<el-button type="text" icon="el-icon-download" @click="handleDownload(scope.row)"
v-if="scope.row.downloadStatus"
v-loading="loadingDownload">下载</el-button>
<!-- <el-button
size="mini"
type="text"
icon="el-icon-edit"
v-if="scope.row.docStatus != 'yfb' && scope.row.docStatus != 'shz'"
@click="handleEdit(scope.row)"
v-hasPermi="['document:edit']"
>编辑</el-button>
<el-button type="text" icon="el-icon-info" @click="handleDetail(scope.row)">详情</el-button>
@click="handlePriew(scope.row)"
>预览</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
v-if="scope.row.docStatus != 'yfb' && scope.row.docStatus != 'shz'"
@click="handleDelete(scope.row)"
v-hasPermi="['document:remove']"
>删除</el-button>-->
<el-dropdown size="mini" @command="(command) => handleCommand(command, scope.row)">
<el-button size="mini" type="text" icon="el-icon-d-arrow-right" >更多</el-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item command="handleDetail" icon="el-icon-info" >详情</el-dropdown-item>
<el-dropdown-item command="handleEdit" icon="el-icon-edit" v-if="scope.row.docStatus != 'yfb' && scope.row.docStatus != 'shz'">编辑</el-dropdown-item>
<el-dropdown-item command="handleDelete" icon="el-icon-delete" v-if="scope.row.docStatus != 'yfb' && scope.row.docStatus != 'shz'">删除</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
>删除</el-button>
<el-button type="text" icon="el-icon-download">下载</el-button>
</template>
</el-table-column>
</el-table>
@ -226,149 +106,37 @@
</div>
</el-card>
<el-dialog :title="docCategoryTitle" :visible.sync="docCategoryOpen" width="50%"
:close-on-press-escape="false" :close-on-click-modal="false" :destroy-on-close="true"
:show-close="false" :wrapperClosable="false"
append-to-body>
<el-form ref="docCategoryFormRefs" :model="docCategoryForm" :rules="docCategoryRules" label-width="80px">
<el-form-item label="父分类" prop="parentId">
<treeselect v-if="docCategoryOpen" v-model="docCategoryForm.parentId" :options="docCategory" :show-count="true" placeholder="如果不选择,默认为一级分类" />
</el-form-item>
<el-form-item label="分类名称" prop="categoryName">
<el-input v-model="docCategoryForm.categoryName" placeholder="请输入分类名称" maxlength="50" show-word-limit/>
</el-form-item>
<el-form-item label="分类描述" prop="categoryDescription">
<el-input v-model="docCategoryForm.categoryDescription"
type="textarea" :rows="3" maxlength="500" show-word-limit
placeholder="请输入分类描述" />
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button type="primary" @click="docCategorySubmitForm"> </el-button>
<el-button @click="docCategoryCancel"> </el-button>
</span>
<el-dialog :title="viewDialogTitle" :visible.sync="viewDialogOpen" fullscreen width="500px" append-to-body>
<i-frame :src="previewUrl" />
</el-dialog>
<!--文档修改-->
<el-drawer :visible.sync="open"
:wrapperClosable="false"
:modal-append-to-body="false" :show-close="false" :close-on-press-escape="false"
size="75%">
<el-drawer :visible.sync="open" :modal-append-to-body="false" size="75%">
<template #title>
<span class="title">{{docTitle}}</span>
<div class="drawer-head-btn" v-if="docDetailDisable">
<el-button icon="el-icon-check" type="primary" @click="docConfrim()"> </el-button>
<el-button icon="el-icon-close" @click="docCancel()"> </el-button>
</div><!--drawer-head-btn 抽屉顶部按钮区域-->
<div class="drawer-head-btn" v-else>
<el-button icon="el-icon-close" @click="docCancel()"> </el-button>
<span class="title">新增文档资源</span>
<div class="drawer-head-btn">
<el-button type="primary" @click="$refs.editDocumentRef.submitForm()"> </el-button>
<el-button @click="$refs.editDocumentRef.cancel()"> </el-button>
</div><!--drawer-head-btn 抽屉顶部按钮区域-->
</template>
<edit-document v-if="open" ref="editDocumentRef" @submit="editDocumentSubmit"/>
<edit-document ref="editDocumentRef" @submit="editDocumentSubmit"/>
</el-drawer>
<!--文档详情-->
<el-drawer :visible.sync="detailDocOpen"
:wrapperClosable="false"
:modal-append-to-body="false" :show-close="false" :close-on-press-escape="false"
size="75%">
<template #title>
<span class="title">{{docTitle}}</span>
<div class="drawer-head-btn">
<el-button icon="el-icon-close" @click="docDetailCancel()"> </el-button>
</div><!--drawer-head-btn 抽屉顶部按钮区域-->
</template>
<template v-if="detailOpen">
<doc-detail ref="docDetailRef" @submit="docDetailFormSubmit"/>
</template>
</el-drawer>
<!-- 文档导出对话框 -->
<el-dialog :title="exportTitle" :visible.sync="exportDrawerOpen"
:wrapperClosable="false"
:modal-append-to-body="false" :show-close="false" :close-on-press-escape="false"
v-loading="wordLoading" element-loading-text="正在下载数据,请稍候"
width="980px" append-to-body>
<div class="el-form-border">
<el-form ref="exportFrom" label-width="180px">
<el-row>
<el-col :span="24">
<el-form-item label="导出格式">
<el-radio-group v-model="statevalue">
<el-radio v-for="item in stateoptions" :key="item.value" :label="item.value" >{{item.label}}</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
</el-form>
</div><!--el-form-border 表单-->
<div class="el-form-border">
<el-form ref="form" label-width="180px">
<el-row>
<el-col :span="24">
<el-form-item label="导出字段">
<el-checkbox-group v-model="checkList">
<el-checkbox label="docCode">文档编号</el-checkbox>
<el-checkbox label="docName">文档名称</el-checkbox>
<el-checkbox label="docType">文档类别</el-checkbox>
<el-checkbox label="docPrincipalsName">负责人</el-checkbox>
<el-checkbox label="docRespDeptName">归属单位</el-checkbox>
<el-checkbox label="docSource">文档来源</el-checkbox>
<el-checkbox label="docStatus">文档状态</el-checkbox>
<el-checkbox label="createTime">创建时间</el-checkbox>
</el-checkbox-group>
</el-form-item>
</el-col>
</el-row>
</el-form><!--el-form-->
</div><!--el-form-border 表单-->
<span slot="footer" class="dialog-footer">
<el-button type="primary" @click="handleExport"> </el-button>
<el-button @click="exportDrawerOpen=false"> </el-button>
</span>
</el-dialog>
<!-- 文档下载对话框 -->
<el-drawer :visible.sync="fileDetailDrawerOpen"
:wrapperClosable="false"
:modal-append-to-body="false" :show-close="false" :close-on-press-escape="false"
size="80%" class="no-padding" @close="handleFileCloseDetail()">
<template #title>
<span>文档附件下载</span>
<div class="drawer-head-btn">
<el-button icon="el-icon-close" @click="fileDetailDrawerOpen = false"> </el-button>
</div><!--drawer-head-btn 抽屉顶部按钮区域-->
</template>
<template v-if="fileDetailOpen">
<download-file-detail ref="downloadFileDetailRef" :docDetail="docDetail"/>
</template>
</el-drawer><!--el-drawer 详情-抽屉-->
<upload-progress/>
</div>
</template>
<script>
import { listDocument, getDocument, delDocument, addDocument, updateDocument,pushDoc, getExportWordList} from "@/api/document/document";
import { listDocument, getDocument, delDocument, addDocument, updateDocument } from "@/api/document/document";
import { deptTreeSelect } from "@/api/system/user";
import { documentTree,addCategory,updateCategory,delCategory,getCategory } from "@/api/documentCategory/documentCategory.js";
import { Base64 } from 'js-base64';
import iFrame from "@/components/iFrame/index"
import editDocument from "./editDocument";
import uploadProgress from "./uploadProgress";
import Treeselect from "@riophae/vue-treeselect";
import { exportDocx } from '@/utils/docUtil/docutil.js';
import downloadFileDetail from "./downloadFileDetail.vue";
import docDetail from "@/views/document/detail";
import store from "@/store";
import { w3cwebsocket as WebSocket } from 'websocket';
export default {
name: "Document",
components: { editDocument, uploadProgress, Treeselect, downloadFileDetail, docDetail},
dicts:['doc_class','doc_source','doc_upload_status'],
components: { iFrame, editDocument, uploadProgress },
data() {
return {
//
@ -389,12 +157,6 @@ export default {
children: "children",
label: "label"
},
//
docCategory: undefined,
docCategoryProps: {
children: "children",
label: "label"
},
//
total: 0,
//
@ -414,22 +176,7 @@ export default {
queryParams: {
pageNum: 1,
pageSize: 10,
docName: '',
docCode: '',
docType: '',
docPrincipalsName: '',
docSource: '',
docStatus: '',
createById: this.$store.getters.userId,
permissionCheck: true,
downloadCheck:true
},
//
queryCategoryParams: {
pageNum: 1,
pageSize: 10,
docCategoryId: '',
categoryName: '',
docName: undefined
},
//
form: {
@ -447,77 +194,12 @@ export default {
docSource: [
{ required: true, message: "文档来源不能为空", trigger: "blur" }
]
},
docCategoryRules: {
categoryName: [
{ required: true, message: "分类名称不能为空", trigger: "blur" }
],
createBy: [
{ required: true, message: "创建人名称不能为空", trigger: "blur" }
],
createById: [
{ required: true, message: "创建人id不能为空", trigger: "blur" }
],
createTime: [
{ required: true, message: "创建时间不能为空", trigger: "blur" }
],
},
docCategoryTitle: "",
docCategoryOpen: false,
//
docCategoryForm: {
categoryName: null,
categoryDescription: null,
parentId: null
},
loadingDownload: false,
acceptType: "zip,rar,7z",
//
columnList: ['docCode', 'docName', 'docType', 'docPrincipalsName', 'docRespDeptName', 'docSource', 'docStatus', 'createTime'],
checkList: [],
exportDrawerOpen: false,
docTitle: '',
//
docDetailDisable: true,
//
statevalue: 1,
stateoptions: [
{
value: 1,
label: 'excel'
},
{
value: 2,
label: 'word'
}
],
docTipAddOrEdit: null,
//
fileDetailDrawerOpen: false,
fileDetailOpen: false,
toolDetail: {},
//
exportTitle:'',
batchExportFlag: false,
//
selection: undefined,
docDetail: {},
detailDocOpen: false,
detailOpen: false,
categoryNameParam: undefined,
wordLoading: false,
}
};
},
watch: {
//
categoryNameParam(val) {
this.$refs.tree.filter(val);
}
},
created() {
this.getList();
this.getDeptTree();
this.getDocumentTree();
},
methods: {
/** 查询部门下拉树结构 */
@ -526,12 +208,6 @@ export default {
this.deptOptions = response.data;
});
},
/** 查询树形下拉树结构 */
getDocumentTree() {
documentTree().then(response => {
this.docCategory = response.data;
});
},
//
filterNode(value, data) {
if (!value) return true;
@ -539,22 +215,18 @@ export default {
},
//
handleNodeClick(data) {
this.queryParams.docCategoryId = data.id;
this.queryParams.toolRespDept = data.id;
this.handleQuery();
},
/** 查询列表 */
getList() {
let self = this
self.loading = true;
this.loading = true;
listDocument(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
self.docList = response.rows;
self.total = response.total;
self.loading = false;
this.docList = response.rows;
this.total = response.total;
this.loading = false;
}
).catch(err=>{
console.error("getList=======", err)
self.loading = false;
});
);
},
/** 搜索按钮操作 */
handleQuery() {
@ -564,51 +236,21 @@ export default {
/** 重置按钮操作 */
resetQuery() {
this.dateRange = [];
this.queryParams.docCategoryId = '';
this.resetForm("queryForm");
this.$refs.tree.setCurrentKey(null);
this.handleQuery();
},
/** 新增按钮操作 */
handleAdd() {
this.docTitle="新增文档资源"
this.docTipAddOrEdit = 'add'
this.docDetailDisable=true
this.open = true
this.$nextTick(()=>{
this.$refs.editDocumentRef.resetForm();
})
},
handleEdit(row){
this.docTitle="编辑文档资源"
this.docTipAddOrEdit = 'edit'
this.docDetailDisable=true
this.open = true
this.$nextTick(()=>{
this.$refs.editDocumentRef.editInit(row.docId, "edit");
})
},
handleDetail(row){
this.docTitle="文档详情"
this.docTipAddOrEdit = 'detail'
this.docDetailDisable=false
this.detailDocOpen = true
this.detailOpen = true
this.$nextTick(()=>{
this.$refs.docDetailRef.editInit(row.docId, "detail");
})
},
handlePreview(row){
this.viewDialogOpen = true;
let protocol = window.location.protocol
let hostname = window.location.hostname;
let getDocUrl = protocol + '//' + hostname + ':8080' + process.env.VUE_APP_BASE_API
this.previewUrl = process.env.VUE_APP_TOOL_TECH_FILE_VIEW_API + '/onlinePreview?url=' + encodeURIComponent(Base64.encode(getDocUrl + row.docUrl));
handlePriew(row){
console.log('mmmmmmmmmmm',process.env.VUE_APP_BASE_API + row.docUrl)
this.previewUrl = process.env.VUE_APP_TOOL_TECH_FILE_VIEW_API + '/onlinePreview?url=' + encodeURIComponent(Base64.encode(process.env.VUE_APP_BASE_API + row.docUrl));
this.viewDialogTitle = '文档在线预览'
this.viewDialogOpen = true;
},
//
handleSelectionChange(selection) {
this.selection=selection
this.ids = selection.map(item => item.docId)
this.single = selection.length!=1
this.multiple = !selection.length
@ -617,306 +259,16 @@ export default {
this.open = false;
this.getList();
},
docDetailFormSubmit: function() {
this.detailDocOpen = false;
this.detailOpen = false;
this.getList();
},
/** 删除按钮操作 */
handleDelete(row) {
let self = this
const docIds = row.docId || this.ids;
if(docIds == null || docIds == undefined || docIds =='' || docIds.length < 0){
this.$modal.msgWarning(`最少选择一条数据`);
return;
}
//
let delFlag = false;
if(self.selection){
for(let item of self.selection){
if(!(item.docStatus == 'ysc')){
delFlag = true;
}
}
}
if(row.docStatus && row.docStatus != 'ysc'){
delFlag = true;
}
if(delFlag){
this.$modal.msgError(`只能删除文档状态为[已上传]数据,请重新选择`);
return
}
this.$modal.confirm('是否确认删除?').then(function() {
return delDocument(docIds);
}).then(() => {
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch((err) => {console.error(err)});
},
/** 新增按钮操作 */
handleDocCategoryAdd(data) {
this.docCategoryOpen = true;
// this.docCategoryForm.parentId = data.id;
this.$nextTick(() => {
this.resetDocCategoryForm();
this.docCategoryForm.parentId = data.id;
})
this.docCategoryTitle = "添加文档资源分类";
},
/** 删除按钮操作 */
handleDocCategoryDelete(row) {
this.$modal.confirm('是否删除该项数据?').then(function() {
return delCategory(row.id);
}).then(() => {
this.getDocumentTree();
this.$modal.msgSuccess("删除成功");
}).catch((err) => {
console.error("err============", err)
});
},
/** 修改按钮操作 */
handleDocCategoryUpdate(row) {
let self = this
self.docCategoryOpen = true;
self.$nextTick(() => {
self.resetDocCategoryForm();
})
const id = row.id;
getCategory(id).then(response => {
self.docCategoryForm = response.data;
self.docCategoryTitle = "修改文档资源分类";
});
},
/** 提交按钮 */
docCategorySubmitForm() {
this.$refs["docCategoryFormRefs"].validate(valid => {
if (valid) {
if (this.docCategoryForm.id != null) {
updateCategory(this.docCategoryForm).then(response => {
this.$modal.msgSuccess("修改成功");
this.docCategoryOpen = false;
this.getDocumentTree();
});
} else {
this.$set(this.docCategoryForm, "types", "user")
addCategory(this.docCategoryForm).then(response => {
this.$modal.msgSuccess("新增成功");
this.docCategoryOpen = false;
this.getDocumentTree();
});
}
}
});
},
//
docCategoryCancel() {
this.docCategoryOpen = false;
this.resetDocCategoryForm();
},
/** 重置 **/
resetDocCategoryForm(){
this.docCategoryForm = {
categoryName: null,
categoryDescription: null,
parentId: null
},
this.$refs.docCategoryFormRefs.resetFields();
},
/**
* 处理下载
* **/
handleDownload(row){
this.fileDetailDrawerOpen = true
this.fileDetailOpen = true
this.docDetail = row
},
/** 发布操作 */
handlePush(row) {
let self = this
const docIds = row.docId || this.ids;
if(docIds == null || docIds == undefined || docIds =='' || docIds.length < 0){
this.$modal.msgWarning(`最少选择一条数据`);
return;
}
//
let delFlag = false;
for(let item of self.selection){
if(!(item.docStatus == 'ysc')){
delFlag = true;
}
}
if(delFlag){
this.$modal.msgError(`只能发布文档状态为[已上传]数据,请重新选择`);
return
}
this.$modal.confirm('是否确认发布?').then(function() {
return pushDoc(docIds);
}).then(() => {
self.getList();
store.commit('SET_UNREAD_MSG_NUMBER', this.$store.state.user.unreadMsgNumber+1);
self.$modal.msgSuccess("发布成功");
}).catch((err) => {
console.error(err)
});
},
/**
* 确认
*/
docConfrim(){
this.$refs.editDocumentRef.submitForm();
},
docCancel(){
this.$refs.editDocumentRef.resetForm();
this.open = false
},
docDetailCancel(){
this.$refs.docDetailRef.resetForm();
this.detailDocOpen = false
this.detailOpen = false
},
previewAuth(row){
if(row.docUrl == null || row.docUrl == '' || row.docUrl == undefined){
return false
}
let extension = this.getExtension(row.docUrl);
const acceptedExtensions = this.acceptType.toLowerCase().split(',');
if(acceptedExtensions.includes(extension)){
return false
}
return true
},
getExtension(filePath) {
// '.'
const parts = filePath.split('.');
//
const extension = parts.pop();
return extension;
},
isSelectable(row) {
return row.docStatus !== 'yfb' && row.docStatus !== 'shz';
},
/** 批量导出 */
handleOpenBatchExport() {
let self = this
if(self.selection == null || self.selection == '' || self.selection == undefined || self.selection.length <= 0){
this.$modal.msgWarning(`最少选择一条数据`);
return;
}
if (this.checkList.length<1) {
this.checkList = JSON.parse(JSON.stringify(this.columnList))
}
this.exportTitle = '批量导出'
this.batchExportFlag = true
this.exportDrawerOpen = true
},
/** 导出按钮操作 */
handleOpenExport() {
if (this.checkList.length<1) {
this.checkList = JSON.parse(JSON.stringify(this.columnList))
}
this.exportTitle = '全量导出'
this.exportDrawerOpen = true
this.batchExportFlag = false
},
/** 导出按钮操作 */
handleExport() {
let self = this
if(this.checkList.length == 0){
this.$modal.msgWarning(`最少选择一个字段`);
return
}
if (this.statevalue == 1) {
let excludeFields = this.columnList.filter(item=>!this.checkList.includes(item))
let params = {
...this.queryParams,
downloadCheck:false,
excludeFields:excludeFields,
}
if(this.batchExportFlag){
params = {
downloadCheck:false,
docIdList: self.selection.map(item=>item.docId),
excludeFields:excludeFields,
}
}
this.download('/document/export', params , `document_${new Date().getTime()}.xlsx`)
}
if (this.statevalue == 2) {
let params = {
...this.queryParams
}
if(this.batchExportFlag){
params = {
docIdList: self.selection.map(item=>item.docId)
}
}
self.wordLoading = true
getExportWordList(params).then(r => {
if (r.data.length != 0) {
const data = {
form: null,
list: r.data
}
exportDocx('document.docx', data, `document_${new Date().getTime()}.docx`)
setTimeout(() => {
if(self.batchExportFlag){
self.clearSelected()
}
self.wordLoading = false
self.exoportDrawerOpen = false;
}, 1000);
} else {
self.wordLoading = false
self.exportDrawerOpen = false
this.$message.error('没有数据');
}
}).catch((err) => {
console.error("err=============", err)
self.wordLoading = false
self.exportDrawerOpen = false
})
}
},
handleBeforeClose() {
this.viewDialogOpen = false
},
//
handleCommand(command, row) {
switch (command) {
case "handleEdit":
this.handleEdit(row);
break;
case "handleUpdate":
this.handleUpdate(row);
break;
case "handleDelete":
this.handleDelete(row);
break;
case "handleDetail":
this.handleDetail(row);
break;
default:
break;
}
},
clearSelected() {
// tab
this.$refs.tableRef.clearSelection();
},
/** 关闭详情 **/
handleFileCloseDetail(){
this.fileDetailDrawerOpen = false;
this.fileDetailOpen = false;
this.$refs.downloadFileDetailRef.$destroy(); //
this.$nextTick(() => {
this.$refs.downloadFileDetailRef = null; //
});
},
}).catch(() => {});
}
}
};
</script>

View File

@ -30,10 +30,10 @@
}
},
created(){
// this.initWebSocket();
this.initWebSocket();
},
methods: {
/* initWebSocket() {
initWebSocket() {
this.websocket = new WebSocket(process.env.VUE_APP_WS_URL);
this.websocket.onmessage = (event) => {
this.uploading = true;
@ -52,8 +52,8 @@
}
})
console.log('this.progressArr=' + this.progressArr);
/!* let progress = msgStr.substring(msgStr.indexOf("/") + 1, msgStr.length);
this.progress = parseInt(msgArr[2])*!/
/* let progress = msgStr.substring(msgStr.indexOf("/") + 1, msgStr.length);
this.progress = parseInt(msgArr[2])*/
// if (progress === '100%') {
// this.websocket.close();
// }
@ -61,7 +61,7 @@
this.websocket.onclose = () => {
console.log('WebSocket connection closed');
};
}, */
},
checkDuplicate(docId) {
return this.progressArr.findIndex(t => t['docId'] == docId) == -1
}
@ -69,7 +69,7 @@
};
</script>
<style scoped>
<style>
.progress-bar {
position: fixed;
bottom: 10px;

View File

@ -1,87 +0,0 @@
<template>
<el-dialog
:title="`${toolName}下载详情统计`"
:visible.sync="visible"
width="85%"
append-to-body
@open="openEvent"
@close="visible = false"
>
<el-table v-loading="loading" :data="toolDownDetailStatList">
<el-table-column label="下载用户" align="center" key="userName" prop="userName" min-width="120" />
<el-table-column label="下载次数" align="center" key="toolDownNum" prop="toolDownNum" min-width="120" />
<el-table-column label="下载时间" align="center" key="donwTime" prop="donwTime" min-width="120" />
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="detailQueryParams.pageNum"
:limit.sync="detailQueryParams.pageSize"
@pagination="getToolDownDetailStatistics"
/>
</el-dialog>
</template>
<script>
import { getToolDownDetailStatistics } from '@/api/statistic/statistic'
export default {
props: {
/**
* 控制显示/隐藏
*/
show: {
type: Boolean,
default: false
},
/**
* 工具id
*/
toolId: {
type: String,
default: ''
},
/**
* 工具名称
*/
toolName: {
type: String,
default: ''
}
},
computed: {
visible: {
get() {
return this.show
},
set(val) {
this.$emit('update:show', false)
}
}
},
data () {
return {
toolDownDetailStatList: [],
total: 0,
loading: false,
//
detailQueryParams: {
pageNum: 1,
pageSize: 10
}
}
},
methods: {
openEvent(){
this.visible = false
this.getToolDownDetailStatistics()
},
getToolDownDetailStatistics() {
this.loading = true
getToolDownDetailStatistics({ ...this.detailQueryParams, toolId: this.toolId }).then(response => {
this.total = response?.total
this.toolDownDetailStatList = response?.rows || []
this.loading = false
}).catch(() => { this.loading = false });
}
}
}
</script>

View File

@ -1,102 +0,0 @@
<template>
<div :class="className" :style="{height:height,width:width}" />
</template>
<script>
import * as echarts from 'echarts'
require('echarts/theme/macarons') // echarts theme
import resize from '@/views/dashboard/mixins/resize'
export default {
mixins: [resize],
props: {
className: {
type: String,
default: 'chart'
},
width: {
type: String,
default: '100%'
},
height: {
type: String,
default: '300px'
},
/**
* 饼图数据
*/
data: {
type: Array,
default: () => []
},
/**
* 底部提示数据
*/
legendData: {
type: Array,
default: () => []
},
/**
* 底部提示距底部距离
*/
legendBottom: {
type: String,
default: '5'
},
roseType: {
type: String,
default: 'radius'
},
radius: {
type: Array | String | Number,
default: 50
}
},
data() {
return {
chart: null
}
},
mounted() {
this.$nextTick(() => {
this.initChart()
})
},
beforeDestroy() {
if (!this.chart) {
return
}
this.chart.dispose()
this.chart = null
},
methods: {
initChart() {
this.chart = echarts.init(this.$el, 'macarons')
this.chart.setOption({
tooltip: {
trigger: 'item',
formatter: '{a} <br/>{b} : {c} ({d}%)'
},
legend: {
left: 'center',
bottom: this.legendBottom,
data: this.legendData
},
series: [
{
name: '',
type: 'pie',
roseType: this.roseType,
radius: this.radius,
center: ['50%', '50%'],
data: this.data,
animationEasing: 'cubicInOut',
animationDuration: 2600
}
]
})
}
}
}
</script>

View File

@ -1,301 +0,0 @@
<template>
<div class="app-container" v-loading="pageloading">
<el-row :gutter="24">
<el-col :span="12">
<el-card>
<div slot="header" class="clearfix"><span class="tline">文档类别统计</span></div>
<!-- -->
<div class="tjbox2" v-if="isPieChart">
<PieChart
height="285px"
:data="toolTypeData"
:legendData="toolTypeLegendData"
legendBottom="5"
chartRef="toolType"
:radius="['40%', '70%']"
/>
</div>
</el-card><!--el-card-->
</el-col><!--el-col-->
<el-col :span="12">
<el-card>
<div slot="header" class="clearfix"><span class="tline">文档来源统计</span></div>
<div class="tjbox2" v-if="isPieChart">
<PieChart
height="285px"
:data="toolSourceData"
:legendData="toolSourceLegendData"
legendBottom="5"
:radius="['40%', '70%']"
chartRef="toolStatus"
/>
</div>
</el-card><!--el-card-->
</el-col><!--el-col-->
</el-row><!--el-row-->
<el-row :gutter="20">
<el-col :span="24">
<el-card>
<div slot="header" class="clearfix"><span class="tline">文档下载统计</span></div>
<div class="tjbox2">
<el-form label-width="70px" ref="queryForm" :model="queryParams">
<div class="search">
<div class="sl">
<el-form-item label="下载时间">
<el-date-picker
v-model="dateRange"
value-format="yyyy-MM-dd"
type="daterange"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
></el-date-picker>
</el-form-item>
<el-form-item label="文档编号" prop="docCode">
<el-input
v-model="queryParams.docCode"
placeholder="请输入文档编号"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="文档名称" prop="docName">
<el-input
v-model="queryParams.docName"
placeholder="请输入文档名称"
clearable
@clear="handleQuery"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
</div>
<div class="sr">
<el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh-left" @click="reset">重置</el-button>
</div>
</div>
</el-form>
<!-- <img src="images/tjt6.jpg" /> -->
</div>
<div class="rt">
<el-table v-loading="downLoading" :data="toolDownStatList">
<el-table-column type="index" label="序号" width="50" align="center"/>
<el-table-column label="文档编号" key="docCode" prop="docCode" />
<el-table-column label="文档名称" key="docName" prop="docName" :show-overflow-tooltip="true" />
<el-table-column label="下载次数" align="center" key="docDownNum" prop="docDownNum"/>
<el-table-column
label="操作"
align="center"
width="100"
class-name="small-padding fixed-width"
>
<template slot-scope="scope">
<el-button type="text" icon="el-icon-info" @click="handleDetail(scope.row)">详情</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="downTotal>0"
:total="downTotal"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getDocDownStatistics"
/>
</div><!--rt -->
</el-card><!--el-card-->
</el-col><!--el-col-->
</el-row><!--el-row-->
<!-- <DownStatDetail :show.sync="detailDrawerOpen" :toolId="toolId" :toolName="toolName" /> -->
<el-dialog
:title="`${toolName}下载详情统计`"
:visible.sync="detailDrawerOpen"
width="85%"
append-to-body
@open="openEvent"
@close="detailDrawerOpen = false"
>
<el-table :data="toolDownDetailStatList" v-loading="loading">
<el-table-column type="index" label="序号" width="50" align="center"/>
<el-table-column label="附件名称" key="attName" prop="attName" :show-overflow-tooltip="true" />
<el-table-column label="下载用户" key="nickName" prop="nickName" width="120" />
<el-table-column label="下载次数" align="center" key="toolDownNum" prop="toolDownNum" width="120" />
<el-table-column label="下载时间" align="center" key="createTime" prop="createTime" width="200" />
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams1.pageNum"
:limit.sync="queryParams1.pageSize"
@pagination="getDocDownDetailStatistics"
/>
</el-dialog>
</div>
</template>
<script>
import { getStatistics } from "@/api/document/document";
import { listDocCount,userDownList } from "@/api/tool/downloadCount";
import PieChart from './PieChart'
export default {
name: 'statistic',
dicts: ['tool_type', 'flow_status', 'tool_source'],
components: {
PieChart
},
data() {
return {
toolDownDetailStatList: [],
activeName: 'first',
toolTypeData: [
/*{ value: 320, name: '' },
{ value: 240, name: '服务型' }*/
],
// toolTypeLegendData:['', ''],
toolTypeLegendData:[],
toolStatusData: [
/* { value: 212, name: '' },
{ value: 76, name: '审批中' },
{ value: 32, name: '审批不通过' },
{ value: 971, name: '已发布' }*/
],
// toolStatusLegendData: ['','','',''],
toolStatusLegendData: [],
toolSourceData: [
/*{ value: 20, name: 'QQ' },
{ value: 60, name: '微信' },
{ value: 18, name: '官网' },
{ value: 47, name: '熟人介绍' }*/
],
// toolSourceLegendData: ['QQ', '', '', ''],
toolSourceLegendData: [],
//
dateRange: [],
toolDownStatList: [],
downTotal: 0,
downLoading: false,
//
queryParams: {
pageNum: 1,
pageSize: 10,
docCode: null,
docName: null,
},
queryParams1: {
pageNum: 1,
pageSize: 10,
businessId: ''
},
//
detailDrawerOpen: false,
// id
toolId: '',
//
toolName: '',
total: 0,
loading: false,
isPieChart: false,
}
},
created () {
this.getCountData()
this.getDocDownStatistics()
},
methods: {
openEvent() {
this.getDocDownDetailStatistics()
},
getDocDownDetailStatistics() {
let self = this
this.loading = true
userDownList(this.addDateRange(this.queryParams1)).then(res => {
self.total = res?.total
self.toolDownDetailStatList = res?.rows || []
self.loading = false
}).catch(() => { self.loading = false });
},
//
reset() {
this.toolDownStatList = []
this.dateRange = []
this.resetForm("queryForm")
this.handleQuery()
},
/**
* 工具下载搜索
*/
handleQuery() {
this.queryParams.pageNum = 1
this.getDocDownStatistics()
},
/** 统计类型、类别、状态**/
getCountData(){
let self = this
//
self.toolTypeData = []
self.toolTypeLegendData = []
//
self.toolSourceData = []
self.toolSourceLegendData = []
self.pageloading = true
getStatistics(this.queryParams).then(res => {
if(res.data){
const countType = JSON.parse(JSON.stringify(res.data.countType)).filter(item => item.name)
//
self.toolTypeData = countType
self.toolTypeData.forEach(item => {
if(item && item.name){
self.toolTypeLegendData.push(item.name)
}
})
const countSource = JSON.parse(JSON.stringify(res.data.countSource)).filter(item => item.name)
//
self.toolSourceData = countSource
self.toolSourceData.forEach(item => {
if(item && item.name){
self.toolSourceLegendData.push(item.name)
}
})
self.isPieChart= true
self.pageloading= false
}
/* console.info("countToolType==============", this.dict.type.tool_type)
console.info("res===========", res)*/
}).catch((err) => {
self.isPieChart= true
self.pageloading= false
console.error(err)
});
},
handleDetail(row){
this.$set(this.queryParams1, "businessId", row.businessId)
this.detailDrawerOpen = true
},
/**
* 获取工具下载列表数据
*/
getDocDownStatistics() {
let self = this
this.downLoading = true
listDocCount(this.addDateRange(this.queryParams, this.dateRange)).then(res => {
self.downTotal = res.total
self.toolDownStatList = res?.rows || []
self.downLoading = false
}).catch(() => { self.downLoading = false });
},
}
}
</script>
<style scoped>
</style>

View File

@ -5,37 +5,37 @@
<div class="grab" id="add">
<div class="search">
<div class="sl">
<el-form-item label="编号" prop="toolCode">
<el-form-item label="工具编号" prop="toolCode">
<el-input
v-model="queryParams.toolCode"
placeholder="请输入编号"
placeholder="请输入工具编号"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="中文别名" prop="toolName">
<el-form-item label="工具名称" prop="toolName">
<el-input
v-model="queryParams.toolName"
placeholder="请输入中文别名"
placeholder="请输入工具名称"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="态" prop="status">
<!-- <el-form-item label="态" prop="status">
<el-select
v-model="queryParams.status"
placeholder="态"
placeholder="态"
clearable
style="width: 240px"
>
<el-option
v-for="dict in dict.type.sys_normal_disable"
v-for="dict in dict.type.flow_business_status"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
</el-form-item>-->
<el-form-item label="创建时间">
<el-date-picker
v-model="dateRange"
@ -49,7 +49,7 @@
</el-form-item>
</div>
<div class="sr">
<el-button type="primary" icon="el-icon-search">搜索</el-button>
<el-button type="primary" icon="el-icon-search" @click="getList">搜索</el-button>
<el-button icon="el-icon-refresh-left">重置</el-button>
</div>
</div><!--search 默认查询-->
@ -82,9 +82,9 @@
</div><!--lt -->
<div class="rt">
<el-table v-loading="loading" :data="toolList">
<el-table-column label="编号" align="center" key="toolCode" prop="toolCode" v-if="columns[0].visible" />
<el-table-column label="中文别名" align="center" key="toolName" prop="toolName" v-if="columns[1].visible" :show-overflow-tooltip="true" />
<el-table-column label="类别" align="center" key="toolType" prop="toolType" v-if="columns[2].visible" :show-overflow-tooltip="true" >
<el-table-column label="工具编号" align="center" key="toolCode" prop="toolCode" v-if="columns[0].visible" />
<el-table-column label="工具名称" align="center" key="toolName" prop="toolName" v-if="columns[1].visible" :show-overflow-tooltip="true" />
<el-table-column label="工具类别" align="center" key="toolType" prop="toolType" v-if="columns[2].visible" :show-overflow-tooltip="true" >
<template slot-scope="scope">
<template v-for="dict in dict.type.tool_type">
<span v-if="scope.row.toolType == dict.value">{{ dict.label }}</span>
@ -93,10 +93,11 @@
</el-table-column>
<el-table-column label="部门" align="center" key="deptName" prop="dept.deptName" v-if="columns[3].visible" :show-overflow-tooltip="true" />
<el-table-column label="负责人" align="center" key="toolPrincipalsName" prop="toolPrincipalsName" v-if="columns[4].visible" width="120" />
<el-table-column label="态" align="center" key="status" v-if="columns[5].visible">
<el-table-column label="态" align="center" key="status" v-if="columns[5].visible">
<template slot-scope="scope">
<el-tag type="success" v-if="scope.row.status == '0'">正常</el-tag>
<el-tag type="info" v-if="scope.row.status == '1'">禁用</el-tag>
<el-tag type="info" v-if="scope.row.status == '0'">已保存</el-tag>
<el-tag type="info" v-if="scope.row.status == '1'">审核中</el-tag>
<el-tag type="success" v-if="scope.row.status == '2'">已发布</el-tag>
</template>
</el-table-column>
<el-table-column label="创建时间" align="center" prop="createTime" v-if="columns[6].visible" width="160">
@ -155,11 +156,12 @@ import { getToken } from "@/utils/auth";
import { Base64 } from 'js-base64'
import Treeselect from "@riophae/vue-treeselect";
import blUserSelector from "@/components/user-selector/src/user-selector";
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
import toolDetail from "./toolDetail";
export default {
name: "User",
dicts: ['sys_normal_disable', 'tool_type'],
dicts: ['sys_normal_disable', 'tool_type','flow_business_status'],
components: { Treeselect, blUserSelector, toolDetail },
data() {
return {
@ -209,31 +211,32 @@ export default {
},
//
columns: [
{ key: 0, label: `编号`, visible: true },
{ key: 1, label: `中文别名`, visible: true },
{ key: 2, label: `类别`, visible: true },
{ key: 0, label: `工具编号`, visible: true },
{ key: 1, label: `工具名称`, visible: true },
{ key: 2, label: `工具类别`, visible: true },
{ key: 3, label: `部门`, visible: true },
{ key: 4, label: `负责人`, visible: true },
{ key: 5, label: ``, visible: true },
{ key: 5, label: ``, visible: true },
{ key: 6, label: `创建时间`, visible: true }
],
//
rules: {
toolCode: [
{ required: true, message: "编号不能为空", trigger: "blur" },
{ min: 2, max: 30, message: '编号长度必须介于 2 和 30 之间', trigger: 'blur' }
{ required: true, message: "工具编号不能为空", trigger: "blur" },
{ min: 2, max: 30, message: '工具编号长度必须介于 2 和 30 之间', trigger: 'blur' }
],
toolName: [
{ max: 50, message: '中文别名不能超过50个字', trigger: 'blur' }
{ required: true, message: "工具名称不能为空", trigger: "blur" },
{ max: 50, message: '工具名称不能超过50个字', trigger: 'blur' }
],
toolPrincipals: [
{ required: true, message: "负责人不能为空", trigger: "blur" }
],
toolSource: [
{ max: 50, message: '来源不能超过50个字', trigger: 'blur' }
{ max: 50, message: '工具来源不能超过50个字', trigger: 'blur' }
],
toolUse: [
{ max: 50, message: '用途不能超过50个字', trigger: 'blur' }
{ max: 50, message: '工具用途不能超过50个字', trigger: 'blur' }
]
},
//
@ -286,6 +289,7 @@ export default {
/** 查询用户列表 */
getList() {
this.loading = true;
this.queryParams.status = '2'
listTool(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
this.toolList = response.rows;
this.total = response.total;

View File

@ -7,14 +7,15 @@
<div class="el-form-border">
<el-form ref="form" label-width="150px">
<el-row>
<el-col :span="12"> <el-form-item label="工具编号">0001</el-form-item> </el-col>
<el-col :span="12"> <el-form-item label="工具名称">工具名称2</el-form-item> </el-col>
<el-col :span="12"> <el-form-item label="工具类别">网络工具</el-form-item> </el-col>
<el-col :span="12"> <el-form-item label="工具来源">单位自建</el-form-item> </el-col>
<el-col :span="12"> <el-form-item label="负责人">赵宁宇</el-form-item> </el-col>
<el-col :span="12"> <el-form-item label="归属单位">人力资源部/员工关系组</el-form-item> </el-col>
<el-col :span="12"> <el-form-item label="状态"><span class="green">启用中</span></el-form-item> </el-col>
<el-col :span="12"> <el-form-item label="归属单位">人力资源部</el-form-item> </el-col>
<el-col :span="12"> <el-form-item label="状态"><span class="green">在用</span></el-form-item> </el-col>
<el-col :span="12"> <el-form-item label="工具用途">主要用于单位网络使用</el-form-item> </el-col>
<el-col :span="12"> <el-form-item label="测情况">运行良好可正常使用</el-form-item> </el-col>
<el-col :span="12"> <el-form-item label="测情况">运行良好可正常使用</el-form-item> </el-col>
<el-col :span="12"> <el-form-item label="功能描述">单位网络使用</el-form-item> </el-col>
<el-col :span="12"> <el-form-item label="适用条件">网络正常</el-form-item> </el-col>
<el-col :span="12"> <el-form-item label="操作说明">正常开启即可用</el-form-item> </el-col>

View File

@ -41,8 +41,8 @@ export default {
return {
codeUrl: "",
loginForm: {
username: "",
password: "",
username: "admin",
password: "admin123",
rememberMe: false,
code: "",
uuid: ""
@ -124,7 +124,7 @@ export default {
};
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
<style rel="stylesheet/scss" lang="scss">
.login {
display: flex;
justify-content: center;

View File

@ -4,84 +4,46 @@
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch">
<div class="search">
<div class="sl">
<el-form-item label="消息内容" prop="content">
<el-form-item label="消息内容" prop="mesContent">
<el-input
v-model="queryParams.content"
v-model="queryParams.mesContent"
placeholder="请输入消息内容"
clearable
style="width: 240px"
@clear="handleQuery"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="消息类型" prop="businessType">
<el-select v-model="queryParams.businessType" placeholder="请选择消息类型" clearable @change="handleQuery">
<el-option
v-for="dict in dict.type.msg_type"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="状态" prop="states">
<el-select v-model="queryParams.states" placeholder="请选择状态" clearable @change="handleQuery">
<el-option
v-for="dict in dict.type.msg_status"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
</div>
<div class="sr">
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery"></el-button>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜5索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</div>
</div>
</el-form>
</el-card>
<el-card class="lrtt">
<div class="rt">
<el-card >
<div >
<div class="operate">
<el-button type="primary" v-if="tableList && tableList.length > 0" @click="setAllMarkedRead" icon="el-icon-check">全部标记已读</el-button>
<el-button type="primary" @click="markRead(null)">全部标记已读</el-button>
</div><!--operate 操作按钮-->
<el-table v-loading="loading" :data="tableList">
<el-table-column type="index" label="序号" width="50" align="center" />
<el-table-column label="消息内容" prop="content" min-width="120">
<template v-slot="{ row }">
<el-link target="_blank" @click="handleDetail(row)">
{{ row.content }}
</el-link>
</template>
</el-table-column>
<el-table-column label="消息类型" align="center" prop="businessType" width="80px">
<template v-slot="{ row }">
<template v-for="dict in dict.type.msg_type">
<!-- {{ dict }} -->
<el-tag :type="dict.raw.listClass" v-if="row.businessType == dict.value" :key="dict.value">{{ dict.label }}</el-tag>
</template>
</template>
</el-table-column>
<el-table-column label="接收时间" prop="createTime" :show-overflow-tooltip="true" width="160px"/>
<el-table-column label="消息状态" prop="states" align="center" :show-overflow-tooltip="true" width="80px" >
<el-table-column label="消息内容" prop="msgContent" min-width="120" />
<el-table-column label="接收时间" prop="msgRecTime" :show-overflow-tooltip="true" min-width="120"/>
<el-table-column label="消息状态" prop="msgStatus" :show-overflow-tooltip="true" min-width="80" >
<template v-slot="{ row }">
<template v-for="dict in dict.type.msg_status">
<!-- {{ dict }} -->
<el-tag :type="dict.raw.listClass" v-if="row.states == dict.value" :key="dict.value">{{ dict.label }}</el-tag>
<el-tag :type="dict.raw.listClass" v-if="row.msgStatus == dict.value" :key="dict.value">{{ dict.label }}</el-tag>
</template>
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="160px" fixed="right">
<el-table-column label="操作" align="center" min-width="100">
<template v-slot="{ row }">
<el-button
size="mini"
type="text"
icon="el-icon-check"
v-if="row.states == '1'"
@click="markRead(row)"
v-if="row.msgStatus === 'unread'"
@click="markRead(row.id)"
>标记已读</el-button>
</template>
</el-table-column>
@ -95,53 +57,16 @@
/>
</div>
</el-card>
<!-- 工具详情对话框 -->
<el-drawer :visible.sync="detailDrawerOpen" :modal-append-to-body="false" :show-close="false" :wrapperClosable="false"
size="80%" class="no-padding" :close-on-press-escape="false" @close="handleCloseDetail()">
<template #title>
<span>{{toolTitle}}</span>
<div class="drawer-head-btn">
<el-button icon="el-icon-close" @click="detailDrawerOpen = false"> </el-button>
</div><!--drawer-head-btn 抽屉顶部按钮区域-->
</template>
<template v-if="detailOpen">
<tool-detail ref="toolDetailRef" :toolDetail="toolDetail" :isDownload="false" :isComment="false"/>
</template>
</el-drawer><!--el-drawer 详情-抽屉-->
<!--文档详情-->
<el-drawer :visible.sync="detailDocOpen"
:modal-append-to-body="false" :show-close="false" :close-on-press-escape="false"
size="75%">
<template #title>
<span class="title">{{docTitle}}</span>
<div class="drawer-head-btn">
<el-button icon="el-icon-close" @click="docCancel()"> </el-button>
</div><!--drawer-head-btn 抽屉顶部按钮区域-->
</template>
<doc-detail ref="editDocumentRef" @submit="editDocumentSubmit" :isDownload="false" :isComment="false"/>
</el-drawer>
</div>
</template>
<script>
import { listMessage, updateMessage,allMarkedRead } from "@/api/message/message"
import { markAllRead, markReadById, getMessageList } from "@/api/message/message"
import { deptTreeSelect } from "@/api/system/user";
import docDetail from "@/views/document/detail";
import toolDetail from "@/views/tool/toolDetail";
import { getUserMsgCount } from "@/api/message/message"
import store from '@/store'
export default {
name: "Document",
dicts: ['msg_status', 'msg_type'],
components: { docDetail, toolDetail},
dicts: ['msg_status'],
data() {
return {
//
@ -176,34 +101,18 @@ export default {
previewUrl: '',
progress: 0,
fileList: [],
// websocket: null,
websocket: null,
//
queryParams: {
pageNum: 1,
pageSize: 10,
content: '',
states: '',
businessType: '',
mesContent: ''
},
//
detailDrawerOpen: false,
toolTitle:'',
detailOpen: false,
toolDetail: {},
//
docTitle: '',
detailDocOpen: false,
docTipAddOrEdit: null,
docDetailDisable: true,
};
},
created() {
if(this.$route.query.states){
this.queryParams.states = this.$route.query.states
}
this.getList();
this.getDeptTree();
},
methods: {
/** 查询部门下拉树结构 */
@ -214,8 +123,8 @@ export default {
},
getList() {
this.loading = true
this.$set(this.queryParams,"receiverId", this.$store.getters.userId)
listMessage(this.queryParams).then(response => {
getMessageList(this.queryParams).then(response => {
console.info("response============", response)
this.total = response?.total
this.tableList = response?.rows || []
this.loading = false
@ -230,7 +139,6 @@ export default {
resetQuery() {
this.tableList = []
this.resetForm("queryForm")
this.queryParams.states = null
this.handleQuery()
},
//
@ -247,77 +155,24 @@ export default {
* 标记已读id为null时表示标记全部已读
* @param id
*/
markRead(row) {
let self = this
let formData = JSON.parse(JSON.stringify(row))
self.$set(formData, "states", 2)
updateMessage(formData).then(response => {
self.$modal.msgSuccess(response?.msg || '操作成功')
store.dispatch('GetUserMsgCount').then(() => { })
self.getList();
}).catch((err) => {console.error(err)});
/* self.$confirm('', '', {
markRead(id) {
this.$confirm('确认标记已读吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
}).catch((err) => {console.error(err)}); */
},
/**
* 标记已读id为null时表示标记全部已读
* @param id
*/
setAllMarkedRead() {
let self = this
self.$confirm('确认全部标记已读吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
let formData = {
"states": 2
if(id) {
markReadById(id).then(response => {
this.$modal.msgSuccess(response?.msg || '操作成功')
this.getList();
})
} else {
markAllRead().then(response => {
this.$modal.msgSuccess(response?.msg || '操作成功')
this.getList();
})
}
allMarkedRead(formData).then(response => {
self.$modal.msgSuccess(response?.msg || '操作成功')
store.dispatch('GetUserMsgCount').then(() => { })
self.getList();
})
}).catch((err) => {console.error(err)});
},
/** 查看详情 **/
handleDetail(row){
if(row.businessType == 'tool'){
this.detailDrawerOpen = true
this.detailOpen = true
this.toolDetail = {toolId: row.businessId}
this.toolTitle = '工具详情'
}else if(row.businessType == 'doc'){
this.docTitle="文档详情"
this.docTipAddOrEdit = 'detail'
this.docDetailDisable=false
this.detailDocOpen = true
this.$nextTick(()=>{
this.$refs.editDocumentRef.editInit(row.businessId, "detail");
})
}
},
/** 关闭详情 **/
handleCloseDetail(){
this.detailDrawerOpen = false;
this.detailOpen = false;
this.$refs.toolDetailRef.$destroy(); //
this.$nextTick(() => {
this.$refs.toolDetailRef = null; //
});
},
docCancel(){
this.$refs.editDocumentRef.resetForm();
this.detailDocOpen = false
},
editDocumentSubmit: function() {
this.detailDocOpen = false;
}).catch(() => {});
},
}
};

View File

@ -23,7 +23,6 @@
<el-table-column
label="序号"
width="60"
align="center"
type="index"
></el-table-column>
@ -82,7 +81,6 @@
<el-table-column
label="序号"
width="60"
align="center"
type="index"
></el-table-column>
<el-table-column

View File

@ -284,7 +284,7 @@
</el-row>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button icon="el-icon-close" @click="openView = false"> </el-button>
<el-button @click="openView = false"> </el-button>
</div>
</el-dialog>
</div>

View File

@ -173,7 +173,7 @@
</el-row>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button icon="el-icon-close" @click="open = false"> </el-button>
<el-button @click="open = false"> </el-button>
</div>
</el-dialog>
</div>

View File

@ -195,7 +195,7 @@
</el-row>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button icon="el-icon-close" @click="open = false"> </el-button>
<el-button @click="open = false"> </el-button>
</div>
</el-dialog>
</div>

View File

@ -146,7 +146,7 @@ export default {
};
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
<style rel="stylesheet/scss" lang="scss">
.register {
display: flex;
justify-content: center;

View File

@ -85,7 +85,7 @@ export default {
},
series: [
{
name: '',
name: 'WEEKLY WRITE ARTICLES',
type: 'pie',
roseType: this.roseType,
radius: this.radius,

View File

@ -1,28 +1,28 @@
<template>
<div class="app-container" v-loading="pageloading">
<el-row :gutter="24">
<el-col :span="8">
<div class="app-container">
<el-row :gutter="20">
<el-col :span="12">
<el-card>
<div slot="header" class="clearfix"><span class="tline">工具类别统计</span></div>
<!-- -->
<div class="tjbox2" v-if="isPieChart">
<div class="tjbox2">
<PieChart
height="285px"
height="207px"
:data="toolTypeData"
:legendData="toolTypeLegendData"
legendBottom="5"
chartRef="toolType"
:radius="['40%', '70%']"
:radius="50"
/>
</div>
</el-card><!--el-card-->
</el-col><!--el-col-->
<el-col :span="8">
<el-col :span="12">
<el-card>
<div slot="header" class="clearfix"><span class="tline">工具状态统计</span></div>
<div class="tjbox2" v-if="isPieChart">
<div class="tjbox2">
<PieChart
height="285px"
height="207px"
:data="toolStatusData"
:legendData="toolStatusLegendData"
legendBottom="5"
@ -33,12 +33,15 @@
</div>
</el-card><!--el-card-->
</el-col><!--el-col-->
<el-col :span="8">
</el-row><!--el-row-->
<el-row :gutter="20">
<el-col :span="12">
<el-card>
<div slot="header" class="clearfix"><span class="tline">工具来源统计</span></div>
<div class="tjbox2" v-if="isPieChart">
<div class="tjbox2">
<PieChart
height="285px"
height="207px"
:data="toolSourceData"
:legendData="toolSourceLegendData"
legendBottom="5"
@ -48,19 +51,19 @@
</div>
</el-card><!--el-card-->
</el-col><!--el-col-->
</el-row><!--el-row-->
</el-row>
<el-row :gutter="20">
<el-col :span="24">
<el-card>
<div slot="header" class="clearfix"><span class="tline">工具下载统计</span></div>
<div slot="header" class="clearfix"><span class="tline">工具下载</span></div>
<div class="tjbox2">
<el-form label-width="70px" ref="queryForm" :model="queryParams" >
<el-form label-width="80px" ref="queryForm">
<div class="search">
<div class="sl">
<el-form-item label="下载时间">
<el-date-picker
v-model="dateRange"
style="width: 240px"
value-format="yyyy-MM-dd"
type="daterange"
range-separator="-"
@ -68,23 +71,6 @@
end-placeholder="结束日期"
></el-date-picker>
</el-form-item>
<el-form-item label="编号" prop="toolCode">
<el-input
v-model="queryParams.toolCode"
placeholder="请输入编号"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="中文别名" prop="toolName">
<el-input
v-model="queryParams.toolName"
placeholder="请输入中文别名"
clearable
@clear="handleQuery"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
</div>
<div class="sr">
<el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button>
@ -96,14 +82,13 @@
</div>
<div class="rt">
<el-table v-loading="downLoading" :data="toolDownStatList">
<el-table-column type="index" label="序号" width="50" align="center"/>
<el-table-column label="编号" key="toolCode" prop="toolCode" />
<el-table-column label="中文别名" key="toolName" prop="toolName" :show-overflow-tooltip="true" />
<el-table-column label="下载次数" align="center" key="toolDownNum" prop="toolDownNum" />
<el-table-column label="工具编号" align="center" key="toolCode" prop="toolCode" />
<el-table-column label="工具名称" align="center" key="toolName" prop="toolName" :show-overflow-tooltip="true" />
<el-table-column label="下载数量" align="center" key="toolDownNum" prop="toolDownNum" width="120" />
<el-table-column
label="操作"
align="center"
width="100"
width="250"
class-name="small-padding fixed-width"
>
<template slot-scope="scope">
@ -131,12 +116,10 @@
@open="openEvent"
@close="detailDrawerOpen = false"
>
<el-table :data="toolDownDetailStatList" v-loading="loading" height="500px">
<el-table-column label="序号" width="60" type="index" align="center"></el-table-column>
<el-table-column label="附件名称" key="attName" prop="attName" :show-overflow-tooltip="true" />
<el-table-column label="下载用户" key="nickName" prop="nickName" width="120" />
<el-table-column label="下载次数" align="center" key="toolDownNum" prop="toolDownNum" width="120" />
<el-table-column label="下载时间" align="center" key="createTime" prop="createTime" width="220" />
<el-table :data="toolDownDetailStatList" v-loading="loading">
<el-table-column label="下载用户" align="center" key="userName" prop="userName" min-width="120" />
<el-table-column label="下载次数" align="center" key="toolDownNum" prop="toolDownNum" min-width="120" />
<el-table-column label="下载时间" align="center" key="donwTime" prop="donwTime" min-width="120" />
</el-table>
<pagination
v-show="total>0"
@ -146,20 +129,15 @@
@pagination="getToolDownDetailStatistics"
/>
</el-dialog>
</div>
</template>
<script>
import { getStatistics } from "@/api/tool/tool";
import { listCount,userDownList } from "@/api/tool/downloadCount";
import PieChart from './PieChart'
import DownStatDetail from './DownStatDetail'
import { getToolDownStat, getToolDownDetailStatistics } from '@/api/statistic/statistic'
export default {
name: 'statistic',
dicts: ['tool_type', 'flow_status', 'tool_source'],
components: {
PieChart,
DownStatDetail
@ -169,27 +147,24 @@ export default {
toolDownDetailStatList: [],
activeName: 'first',
toolTypeData: [
/*{ value: 320, name: '' },
{ value: 240, name: '服务型' }*/
{ value: 320, name: '检测型' },
{ value: 240, name: '服务型' }
],
// toolTypeLegendData:['', ''],
toolTypeLegendData:[],
toolTypeLegendData:['检测型', '服务型'],
toolStatusData: [
/* { value: 212, name: '' },
{ value: 212, name: '已保存' },
{ value: 76, name: '审批中' },
{ value: 32, name: '审批不通过' },
{ value: 971, name: '已发布' }*/
{ value: 971, name: '已发布' }
],
// toolStatusLegendData: ['','','',''],
toolStatusLegendData: [],
toolStatusLegendData: ['已保存','审批中','审批不通过','已发布'],
toolSourceData: [
/*{ value: 20, name: 'QQ' },
{ value: 20, name: 'QQ' },
{ value: 60, name: '微信' },
{ value: 18, name: '官网' },
{ value: 47, name: '熟人介绍' }*/
{ value: 47, name: '熟人介绍' }
],
// toolSourceLegendData: ['QQ', '', '', ''],
toolSourceLegendData: [],
toolSourceLegendData: ['QQ', '微信', '官网', '熟人介绍'],
//
dateRange: [],
toolDownStatList: [],
@ -199,13 +174,12 @@ export default {
queryParams: {
pageNum: 1,
pageSize: 10,
toolCode: null,
toolName: null,
mesContent: ''
},
queryParams1: {
pageNum: 1,
pageSize: 10,
businessId: ''
mesContent: ''
},
//
detailDrawerOpen: false,
@ -214,12 +188,10 @@ export default {
//
toolName: '',
total: 0,
loading: false,
isPieChart: false,
loading: false
}
},
created () {
this.getCountData()
this.getToolDownStatistics()
},
methods: {
@ -227,18 +199,16 @@ export default {
this.getToolDownDetailStatistics()
},
getToolDownDetailStatistics() {
let self = this
this.loading = true
userDownList(this.addDateRange(this.queryParams1)).then(res => {
self.total = res?.total
self.toolDownDetailStatList = res?.rows || []
self.loading = false
}).catch(() => { self.loading = false });
getToolDownDetailStatistics({ ...this.detailQueryParams, toolId: this.toolId }).then(response => {
this.total = response?.total
this.toolDownDetailStatList = response?.rows || []
this.loading = false
}).catch(() => { this.loading = false });
},
//
reset() {
this.toolDownStatList = []
this.dateRange = []
this.resetForm("queryForm")
this.handleQuery()
},
@ -253,71 +223,18 @@ export default {
* 获取工具下载列表数据
*/
getToolDownStatistics() {
let self = this
this.downLoading = true
listCount(this.addDateRange(this.queryParams, this.dateRange)).then(res => {
self.downTotal = res?.total
self.toolDownStatList = res?.rows || []
self.downLoading = false
}).catch(() => { self.downLoading = false });
getToolDownStat(this.queryParams).then(response => {
this.downTotal = response?.total
this.toolDownStatList = response?.rows || []
this.downLoading = false
}).catch(() => { this.downLoading = false });
},
handleDetail(row){
this.$set(this.queryParams1, "businessId", row.businessId)
this.toolId = row.id
this.toolName = row.toolName
this.detailDrawerOpen = true
},
/** 统计类型、类别、状态**/
getCountData(){
let self = this
self.toolTypeData = []
self.toolTypeLegendData = []
self.toolStatusData = []
self.toolStatusLegendData = []
self.toolSourceData = []
self.toolSourceLegendData = []
self.pageloading = true
getStatistics(this.queryParams).then(res => {
if(res.data){
const countToolType = JSON.parse(JSON.stringify(res.data.countToolType)).filter(item => item.name)
//
self.toolTypeData = countToolType
self.toolTypeData.forEach(item => {
if(item && item.name){
self.toolTypeLegendData.push(item.name)
}
})
const recordStatus = JSON.parse(JSON.stringify(res.data.recordStatus)).filter(item => item.name)
//
self.toolStatusData = recordStatus
self.toolStatusData.forEach(item => {
if(item && item.name){
self.toolStatusLegendData.push(item.name)
}
})
const toolSource = JSON.parse(JSON.stringify(res.data.toolSource)).filter(item => item.name)
//
self.toolSourceData = toolSource
self.toolSourceData.forEach(item => {
if(item && item.name){
self.toolSourceLegendData.push(item.name)
}
})
self.isPieChart= true
self.pageloading= false
}
/* console.info("countToolType==============", this.dict.type.tool_type)
console.info("res===========", res)*/
}).catch((err) => {
self.isPieChart= true
self.pageloading= false
console.error(err)
});
}
}
}
</script>

View File

@ -1,392 +0,0 @@
<template>
<div class="app-container">
<el-card>
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="字典名称" prop="dictType">
<el-select v-model="queryParams.dictType">
<el-option
v-for="item in typeOptions"
:key="item.dictId"
:label="item.dictName"
:value="item.dictType"
/>
</el-select>
</el-form-item>
<el-form-item label="字典标签" prop="dictLabel">
<el-input
v-model="queryParams.dictLabel"
placeholder="请输入字典标签"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="状态" prop="status">
<el-select v-model="queryParams.status" placeholder="数据状态" clearable>
<el-option
v-for="dict in dict.type.sys_normal_disable"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
</el-card>
<el-card class="lrtt">
<div class="rt">
<div class="operate">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['system:dict:add']"
>新增</el-button>
<el-button
plain
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
v-hasPermi="['system:dict:edit']"
>修改</el-button>
<el-button
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['system:dict:remove']"
>删除</el-button>
<el-button
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['system:dict:export']"
>导出</el-button>
<el-button
plain
icon="el-icon-close"
size="mini"
@click="handleClose"
>关闭</el-button>
</div>
<el-table v-loading="loading" :data="dataList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="字典编码" align="center" prop="dictCode" />
<el-table-column label="字典标签" align="center" prop="dictLabel">
<template slot-scope="scope">
<span v-if="(scope.row.listClass == '' || scope.row.listClass == 'default') && (scope.row.cssClass == '' || scope.row.cssClass == null)">{{ scope.row.dictLabel }}</span>
<el-tag v-else :type="scope.row.listClass == 'primary' ? '' : scope.row.listClass" :class="scope.row.cssClass">{{ scope.row.dictLabel }}</el-tag>
</template>
</el-table-column>
<el-table-column label="字典键值" align="center" prop="dictValue" />
<el-table-column label="字典排序" align="center" prop="dictSort" />
<el-table-column label="状态" align="center" prop="status">
<template slot-scope="scope">
<dict-tag :options="dict.type.sys_normal_disable" :value="scope.row.status"/>
</template>
</el-table-column>
<el-table-column label="备注" align="center" prop="remark" :show-overflow-tooltip="true" />
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['system:dict:edit']"
>修改</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['system:dict:remove']"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
</div>
</el-card>
<!-- 添加或修改参数配置对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="字典类型">
<el-input v-model="form.dictType" :disabled="true" />
</el-form-item>
<el-form-item label="数据标签" prop="dictLabel">
<el-input v-model="form.dictLabel" placeholder="请输入数据标签" />
</el-form-item>
<el-form-item label="数据键值" prop="dictValue">
<el-input v-model="form.dictValue" placeholder="请输入数据键值" />
</el-form-item>
<el-form-item label="样式属性" prop="cssClass">
<el-input v-model="form.cssClass" placeholder="请输入样式属性" />
</el-form-item>
<el-form-item label="显示排序" prop="dictSort">
<el-input-number v-model="form.dictSort" controls-position="right" :min="0" />
</el-form-item>
<el-form-item label="回显样式" prop="listClass">
<el-select v-model="form.listClass">
<el-option
v-for="item in listClassOptions"
:key="item.value"
:label="item.label + '(' + item.value + ')'"
:value="item.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="状态" prop="status">
<el-radio-group v-model="form.status">
<el-radio
v-for="dict in dict.type.sys_normal_disable"
:key="dict.value"
:label="dict.value"
>{{dict.label}}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { listData, getData, delData, addData, updateData } from "@/api/system/dict/data";
import { optionselect as getDictOptionselect, getType } from "@/api/system/dict/type";
export default {
name: "Data",
dicts: ['sys_normal_disable'],
data() {
return {
//
loading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
dataList: [],
//
defaultDictType: "",
//
title: "",
//
open: false,
//
listClassOptions: [
{
value: "default",
label: "默认"
},
{
value: "primary",
label: "主要"
},
{
value: "success",
label: "成功"
},
{
value: "info",
label: "信息"
},
{
value: "warning",
label: "警告"
},
{
value: "danger",
label: "危险"
}
],
//
typeOptions: [],
//
queryParams: {
pageNum: 1,
pageSize: 10,
dictType: undefined,
dictLabel: undefined,
status: undefined
},
//
form: {},
//
rules: {
dictLabel: [
{ required: true, message: "数据标签不能为空", trigger: "blur" }
],
dictValue: [
{ required: true, message: "数据键值不能为空", trigger: "blur" }
],
dictSort: [
{ required: true, message: "数据顺序不能为空", trigger: "blur" }
]
}
};
},
created() {
const dictId = this.$route.params && this.$route.params.dictId;
this.getType(dictId);
this.getTypeList();
},
methods: {
/** 查询字典类型详细 */
getType(dictId) {
getType(dictId).then(response => {
this.queryParams.dictType = response.data.dictType;
this.defaultDictType = response.data.dictType;
this.getList();
});
},
/** 查询字典类型列表 */
getTypeList() {
getDictOptionselect().then(response => {
this.typeOptions = response.data;
});
},
/** 查询字典数据列表 */
getList() {
this.loading = true;
listData(this.queryParams).then(response => {
this.dataList = response.rows;
this.total = response.total;
this.loading = false;
});
},
//
cancel() {
this.open = false;
this.reset();
},
//
reset() {
this.form = {
dictCode: undefined,
dictLabel: undefined,
dictValue: undefined,
cssClass: undefined,
listClass: 'default',
dictSort: 0,
status: "0",
remark: undefined
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 返回按钮操作 */
handleClose() {
const obj = { path: "/system/dict" };
this.$tab.closeOpenPage(obj);
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.queryParams.dictType = this.defaultDictType;
this.handleQuery();
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = "添加字典数据";
this.form.dictType = this.queryParams.dictType;
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.dictCode)
this.single = selection.length!=1
this.multiple = !selection.length
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const dictCode = row.dictCode || this.ids
getData(dictCode).then(response => {
this.form = response.data;
this.open = true;
this.title = "修改字典数据";
});
},
/** 提交按钮 */
submitForm: function() {
this.$refs["form"].validate(valid => {
if (valid) {
if (this.form.dictCode != undefined) {
updateData(this.form).then(response => {
this.$store.dispatch('dict/removeDict', this.queryParams.dictType);
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
});
} else {
addData(this.form).then(response => {
this.$store.dispatch('dict/removeDict', this.queryParams.dictType);
this.$modal.msgSuccess("新增成功");
this.open = false;
this.getList();
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const dictCodes = row.dictCode || this.ids;
this.$modal.confirm('是否确认删除字典编码为"' + dictCodes + '"的数据项?').then(function() {
return delData(dictCodes);
}).then(() => {
this.getList();
this.$modal.msgSuccess("删除成功");
this.$store.dispatch('dict/removeDict', this.queryParams.dictType);
}).catch(() => {});
},
/** 导出按钮操作 */
handleExport() {
this.download('system/dict/data/export', {
...this.queryParams
}, `data_${new Date().getTime()}.xlsx`)
}
}
};
</script>

View File

@ -1,355 +0,0 @@
<template>
<div class="app-container">
<el-card>
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
<div class="search">
<div class="sl">
<el-form-item label="字典名称" prop="dictName">
<el-input
v-model="queryParams.dictName"
placeholder="请输入字典名称"
clearable
style="width: 240px"
@keyup.enter.native="handleQuery"
@clear="handleQuery"
/>
</el-form-item>
<el-form-item label="字典类型" prop="dictType">
<el-input
v-model="queryParams.dictType"
placeholder="请输入字典类型"
clearable
style="width: 240px"
@keyup.enter.native="handleQuery"
@clear="handleQuery"
/>
</el-form-item>
<el-form-item label="状态" prop="status">
<el-select
v-model="queryParams.status"
placeholder="字典状态"
clearable
style="width: 240px"
@change="handleQuery"
@clear="handleQuery"
>
<el-option
v-for="dict in dict.type.sys_normal_disable"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="创建时间">
<el-date-picker
v-model="dateRange"
style="width: 240px"
value-format="yyyy-MM-dd"
type="daterange"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
@change="handleQuery"
@clear="handleQuery"
></el-date-picker>
</el-form-item>
</div>
<div class="sr">
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</div>
</div>
<!-- <el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>-->
</el-form>
</el-card>
<el-card class="lrtt">
<div class="rt">
<div class="operate">
<!--
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['system:dict:add']"
>新增</el-button>
<el-button
plain
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
v-hasPermi="['system:dict:edit']"
>修改</el-button>
<el-button
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['system:dict:remove']"
>删除</el-button>-->
<!--
<el-button
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['system:dict:export']"
>导出</el-button>-->
<el-button
plain
icon="el-icon-refresh"
size="mini"
@click="handleRefreshCache"
v-hasPermi="['system:dict:remove']"
>刷新缓存</el-button>
</div>
<el-table v-loading="loading" :data="typeList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="字典编号" align="center" prop="dictId" width="100px" :show-overflow-tooltip="true"/>
<el-table-column label="字典名称" align="center" prop="dictName" width="200px" :show-overflow-tooltip="true" />
<el-table-column label="字典类型" align="center" :show-overflow-tooltip="true">
<template slot-scope="scope">
<router-link :to="'/system/dict-data/index/' + scope.row.dictId" class="link-type">
<span>{{ scope.row.dictType }}</span>
</router-link>
</template>
</el-table-column>
<el-table-column label="状态" align="center" prop="status" width="70px" :show-overflow-tooltip="true">
<template slot-scope="scope">
<dict-tag :options="dict.type.sys_normal_disable" :value="scope.row.status"/>
</template>
</el-table-column>
<el-table-column label="备注" align="center" prop="remark" :show-overflow-tooltip="true" />
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column>
<!--
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['system:dict:edit']"
>修改</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['system:dict:remove']"
>删除</el-button>
</template>
</el-table-column>
-->
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
</div>
</el-card>
<!-- 添加或修改参数配置对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="字典名称" prop="dictName">
<el-input v-model="form.dictName" placeholder="请输入字典名称" />
</el-form-item>
<el-form-item label="字典类型" prop="dictType">
<el-input v-model="form.dictType" placeholder="请输入字典类型" />
</el-form-item>
<el-form-item label="状态" prop="status">
<el-radio-group v-model="form.status">
<el-radio
v-for="dict in dict.type.sys_normal_disable"
:key="dict.value"
:label="dict.value"
>{{dict.label}}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { bizListType, getType, delType, addType, updateType, refreshCache } from "@/api/system/dict/type";
export default {
name: "Dict",
dicts: ['sys_normal_disable'],
data() {
return {
//
loading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
typeList: [],
//
title: "",
//
open: false,
//
dateRange: [],
//
queryParams: {
pageNum: 1,
pageSize: 10,
dictName: undefined,
dictType: undefined,
status: undefined
},
//
form: {},
//
rules: {
dictName: [
{ required: true, message: "字典名称不能为空", trigger: "blur" }
],
dictType: [
{ required: true, message: "字典类型不能为空", trigger: "blur" }
]
}
};
},
created() {
this.getList();
},
methods: {
/** 查询字典类型列表 */
getList() {
this.loading = true;
bizListType(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
this.typeList = response.rows;
this.total = response.total;
this.loading = false;
}
);
},
//
cancel() {
this.open = false;
this.reset();
},
//
reset() {
this.form = {
dictId: undefined,
dictName: undefined,
dictType: undefined,
status: "0",
remark: undefined
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.dateRange = [];
this.resetForm("queryForm");
this.handleQuery();
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = "添加字典类型";
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.dictId)
this.single = selection.length!=1
this.multiple = !selection.length
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const dictId = row.dictId || this.ids
getType(dictId).then(response => {
this.form = response.data;
this.open = true;
this.title = "修改字典类型";
});
},
/** 提交按钮 */
submitForm: function() {
this.$refs["form"].validate(valid => {
if (valid) {
if (this.form.dictId != undefined) {
updateType(this.form).then(response => {
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
});
} else {
addType(this.form).then(response => {
this.$modal.msgSuccess("新增成功");
this.open = false;
this.getList();
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const dictIds = row.dictId || this.ids;
this.$modal.confirm('是否确认删除字典编号为"' + dictIds + '"的数据项?').then(function() {
return delType(dictIds);
}).then(() => {
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {});
},
/** 导出按钮操作 */
handleExport() {
this.download('system/dict/type/export', {
...this.queryParams
}, `type_${new Date().getTime()}.xlsx`)
},
/** 刷新缓存按钮操作 */
handleRefreshCache() {
refreshCache().then(() => {
this.$modal.msgSuccess("刷新成功");
this.$store.dispatch('dict/cleanDict');
});
}
}
};
</script>

View File

@ -2,53 +2,49 @@
<div class="app-container">
<el-card>
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
<div class="search">
<div class="sl">
<el-form-item label="参数名称" prop="configName">
<el-input
v-model="queryParams.configName"
placeholder="请输入参数名称"
clearable
style="width: 240px"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="参数键名" prop="configKey">
<el-input
v-model="queryParams.configKey"
placeholder="请输入参数键名"
clearable
style="width: 240px"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="系统内置" prop="configType">
<el-select v-model="queryParams.configType" placeholder="系统内置" clearable>
<el-option
v-for="dict in dict.type.sys_yes_no"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="创建时间">
<el-date-picker
v-model="dateRange"
style="width: 240px"
value-format="yyyy-MM-dd"
type="daterange"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
></el-date-picker>
</el-form-item>
</div>
<div class="sr">
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</div>
</div>
<el-form-item label="参数名称" prop="configName">
<el-input
v-model="queryParams.configName"
placeholder="请输入参数名称"
clearable
style="width: 240px"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="参数键名" prop="configKey">
<el-input
v-model="queryParams.configKey"
placeholder="请输入参数键名"
clearable
style="width: 240px"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="系统内置" prop="configType">
<el-select v-model="queryParams.configType" placeholder="系统内置" clearable>
<el-option
v-for="dict in dict.type.sys_yes_no"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="创建时间">
<el-date-picker
v-model="dateRange"
style="width: 240px"
value-format="yyyy-MM-dd"
type="daterange"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
></el-date-picker>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
</el-card>

View File

@ -2,34 +2,28 @@
<div class="app-container">
<el-card>
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch">
<div class="search">
<div class="sl">
<el-form-item label="部门名称" prop="deptName">
<el-input
v-model="queryParams.deptName"
placeholder="请输入部门名称"
clearable
@keyup.enter.native="handleQuery"
@clear="handleQuery"
/>
</el-form-item>
<el-form-item label="状态" prop="status">
<el-select v-model="queryParams.status" placeholder="部门状态" clearable @change="handleQuery"
@clear="handleQuery">
<el-option
v-for="dict in dict.type.sys_normal_disable"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
</div>
<div class="sr">
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</div>
</div>
<el-form-item label="部门名称" prop="deptName">
<el-input
v-model="queryParams.deptName"
placeholder="请输入部门名称"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="状态" prop="status">
<el-select v-model="queryParams.status" placeholder="部门状态" clearable>
<el-option
v-for="dict in dict.type.sys_normal_disable"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
</el-card>
<el-card class="lrtt">
@ -60,8 +54,8 @@
:tree-props="{children: 'children', hasChildren: 'hasChildren'}"
>
<el-table-column prop="deptName" label="部门名称"></el-table-column>
<el-table-column prop="orderNum" label="排序" width="70px"></el-table-column>
<el-table-column prop="status" label="状态" width="70px" :show-overflow-tooltip="true">
<el-table-column prop="orderNum" label="排序" width="200"></el-table-column>
<el-table-column prop="status" label="状态" width="100">
<template slot-scope="scope">
<dict-tag :options="dict.type.sys_normal_disable" :value="scope.row.status"/>
</template>
@ -102,10 +96,7 @@
</el-card>
<!-- 添加或修改部门对话框 -->
<el-dialog :title="title" :visible.sync="open" width="600px"
:close-on-press-escape="false" :close-on-click-modal="false"
:show-close="false" :wrapperClosable="false"
append-to-body>
<el-dialog :title="title" :visible.sync="open" width="600px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-row>
<el-col :span="24" v-if="form.parentId !== 0">
@ -117,7 +108,7 @@
<el-row>
<el-col :span="12">
<el-form-item label="部门名称" prop="deptName">
<el-input v-model="form.deptName" placeholder="请输入部门名称" maxlength="50" show-word-limit/>
<el-input v-model="form.deptName" placeholder="请输入部门名称" />
</el-form-item>
</el-col>
<el-col :span="12">
@ -129,19 +120,19 @@
<el-row>
<el-col :span="12">
<el-form-item label="负责人" prop="leader">
<el-input v-model="form.leader" placeholder="请输入负责人" maxlength="50" show-word-limit/>
<el-input v-model="form.leader" placeholder="请输入负责人" maxlength="20" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="联系电话" prop="phone">
<el-input v-model="form.phone" placeholder="请输入联系电话" maxlength="11" show-word-limit/>
<el-input v-model="form.phone" placeholder="请输入联系电话" maxlength="11" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="邮箱" prop="email">
<el-input v-model="form.email" placeholder="请输入邮箱" maxlength="50" show-word-limit/>
<el-input v-model="form.email" placeholder="请输入邮箱" maxlength="50" />
</el-form-item>
</el-col>
<el-col :span="12">
@ -168,6 +159,7 @@
<script>
import { listDept, getDept, delDept, addDept, updateDept, listDeptExcludeChild } from "@/api/system/dept";
import Treeselect from "@riophae/vue-treeselect";
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
export default {
name: "Dept",

View File

@ -71,12 +71,12 @@
@click="handleExport"
v-hasPermi="['system:dict:export']"
>导出</el-button>
<!-- <el-button
<el-button
plain
icon="el-icon-close"
size="mini"
@click="handleClose"
>关闭</el-button>-->
>关闭</el-button>
</div>
<el-table v-loading="loading" :data="dataList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />

View File

@ -2,62 +2,54 @@
<div class="app-container">
<el-card>
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
<div class="search">
<div class="sl">
<el-form-item label="字典名称" prop="dictName">
<el-input
v-model="queryParams.dictName"
placeholder="请输入字典名称"
clearable
style="width: 240px"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="字典类型" prop="dictType">
<el-input
v-model="queryParams.dictType"
placeholder="请输入字典类型"
clearable
style="width: 240px"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="状态" prop="status">
<el-select
v-model="queryParams.status"
placeholder="字典状态"
clearable
style="width: 240px"
>
<el-option
v-for="dict in dict.type.sys_normal_disable"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="创建时间">
<el-date-picker
v-model="dateRange"
style="width: 240px"
value-format="yyyy-MM-dd"
type="daterange"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
></el-date-picker>
</el-form-item>
</div>
<div class="sr">
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</div>
</div>
<!-- <el-form-item>
<el-form-item label="字典名称" prop="dictName">
<el-input
v-model="queryParams.dictName"
placeholder="请输入字典名称"
clearable
style="width: 240px"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="字典类型" prop="dictType">
<el-input
v-model="queryParams.dictType"
placeholder="请输入字典类型"
clearable
style="width: 240px"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="状态" prop="status">
<el-select
v-model="queryParams.status"
placeholder="字典状态"
clearable
style="width: 240px"
>
<el-option
v-for="dict in dict.type.sys_normal_disable"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="创建时间">
<el-date-picker
v-model="dateRange"
style="width: 240px"
value-format="yyyy-MM-dd"
type="daterange"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
></el-date-picker>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>-->
</el-form-item>
</el-form>
</el-card>
@ -88,14 +80,13 @@
@click="handleDelete"
v-hasPermi="['system:dict:remove']"
>删除</el-button>
<!--
<el-button
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['system:dict:export']"
>导出</el-button>-->
>导出</el-button>
<el-button
plain
icon="el-icon-refresh"

View File

@ -2,38 +2,28 @@
<div class="app-container">
<el-card>
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch">
<div class="search">
<div class="sl">
<el-form-item label="菜单名称" prop="menuName">
<el-input
v-model="queryParams.menuName"
placeholder="请输入菜单名称"
clearable
@keyup.enter.native="handleQuery"
@clear="handleQuery"
/>
</el-form-item>
<el-form-item label="状态" prop="status">
<el-select v-model="queryParams.status" placeholder="菜单状态" clearable @change="handleQuery"
@clear="handleQuery">
<el-option
v-for="dict in dict.type.sys_normal_disable"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
</div>
<div class="sr">
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</div>
</div>
<!-- <el-form-item>
<el-form-item label="菜单名称" prop="menuName">
<el-input
v-model="queryParams.menuName"
placeholder="请输入菜单名称"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="状态" prop="status">
<el-select v-model="queryParams.status" placeholder="菜单状态" clearable>
<el-option
v-for="dict in dict.type.sys_normal_disable"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>-->
</el-form-item>
</el-form>
</el-card>
<el-card class="lrtt">
@ -285,6 +275,7 @@
<script>
import { listMenu, getMenu, delMenu, addMenu, updateMenu } from "@/api/system/menu";
import Treeselect from "@riophae/vue-treeselect";
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
import IconSelect from "@/components/IconSelect";
export default {

View File

@ -2,41 +2,36 @@
<div class="app-container">
<el-card>
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
<div class="search">
<div class="sl">
<el-form-item label="公告标题" prop="noticeTitle">
<el-input
v-model="queryParams.noticeTitle"
placeholder="请输入公告标题"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="操作人员" prop="createBy">
<el-input
v-model="queryParams.createBy"
placeholder="请输入操作人员"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="类型" prop="noticeType">
<el-select v-model="queryParams.noticeType" placeholder="公告类型" clearable>
<el-option
v-for="dict in dict.type.sys_notice_type"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
</div>
<div class="sr">
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</div>
</div>
<el-form-item label="公告标题" prop="noticeTitle">
<el-input
v-model="queryParams.noticeTitle"
placeholder="请输入公告标题"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="操作人员" prop="createBy">
<el-input
v-model="queryParams.createBy"
placeholder="请输入操作人员"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="类型" prop="noticeType">
<el-select v-model="queryParams.noticeType" placeholder="公告类型" clearable>
<el-option
v-for="dict in dict.type.sys_notice_type"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
</el-card>

View File

@ -2,40 +2,36 @@
<div class="app-container">
<el-card>
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
<div class="search">
<div class="sl">
<el-form-item label="岗位编码" prop="postCode">
<el-input
v-model="queryParams.postCode"
placeholder="请输入岗位编码"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="岗位名称" prop="postName">
<el-input
v-model="queryParams.postName"
placeholder="请输入岗位名称"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="状态" prop="status">
<el-select v-model="queryParams.status" placeholder="岗位状态" clearable>
<el-option
v-for="dict in dict.type.sys_normal_disable"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
</div>
<div class="sr">
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</div>
</div>
<el-form-item label="岗位编码" prop="postCode">
<el-input
v-model="queryParams.postCode"
placeholder="请输入岗位编码"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="岗位名称" prop="postName">
<el-input
v-model="queryParams.postName"
placeholder="请输入岗位名称"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="状态" prop="status">
<el-select v-model="queryParams.status" placeholder="岗位状态" clearable>
<el-option
v-for="dict in dict.type.sys_normal_disable"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
</el-card>
<el-card class="lrtt">

View File

@ -2,64 +2,54 @@
<div class="app-container">
<el-card>
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch">
<div class="search">
<div class="sl">
<el-form-item label="角色名称" prop="roleName">
<el-input
v-model="queryParams.roleName"
placeholder="请输入角色名称"
clearable
style="width: 240px"
@keyup.enter.native="handleQuery"
@clear="handleQuery"
/>
</el-form-item>
<el-form-item label="权限字符" prop="roleKey">
<el-input
v-model="queryParams.roleKey"
placeholder="请输入权限字符"
clearable
style="width: 240px"
@keyup.enter.native="handleQuery"
@clear="handleQuery"
/>
</el-form-item>
<el-form-item label="状态" prop="status">
<el-select
v-model="queryParams.status"
placeholder="角色状态"
clearable
style="width: 240px"
@change="handleQuery"
@clear="handleQuery"
>
<el-option
v-for="dict in dict.type.sys_normal_disable"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="创建时间">
<el-date-picker
v-model="dateRange"
style="width: 240px"
value-format="yyyy-MM-dd"
type="daterange"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
@change="handleQuery"
@clear="handleQuery"
></el-date-picker>
</el-form-item>
</div>
<div class="sr">
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</div>
</div>
<el-form-item label="角色名称" prop="roleName">
<el-input
v-model="queryParams.roleName"
placeholder="请输入角色名称"
clearable
style="width: 240px"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="权限字符" prop="roleKey">
<el-input
v-model="queryParams.roleKey"
placeholder="请输入权限字符"
clearable
style="width: 240px"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="状态" prop="status">
<el-select
v-model="queryParams.status"
placeholder="角色状态"
clearable
style="width: 240px"
>
<el-option
v-for="dict in dict.type.sys_normal_disable"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="创建时间">
<el-date-picker
v-model="dateRange"
style="width: 240px"
value-format="yyyy-MM-dd"
type="daterange"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
></el-date-picker>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
</el-card>
<el-card class="lrtt">
@ -73,7 +63,7 @@
@click="handleAdd"
v-hasPermi="['system:role:add']"
>新增</el-button>
<el-button
<!-- <el-button
plain
icon="el-icon-edit"
size="mini"
@ -89,7 +79,6 @@
@click="handleDelete"
v-hasPermi="['system:role:remove']"
>删除</el-button>
<!--
<el-button
plain
icon="el-icon-download"
@ -101,10 +90,10 @@
<el-table v-loading="loading" :data="roleList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="角色编号" prop="roleId" width="90px" :show-overflow-tooltip="true"/>
<el-table-column label="角色编号" prop="roleId" />
<el-table-column label="角色名称" prop="roleName" :show-overflow-tooltip="true" />
<el-table-column label="权限字符" prop="roleKey" :show-overflow-tooltip="true" />
<el-table-column label="显示顺序" prop="roleSort" width="80px" :show-overflow-tooltip="true" />
<el-table-column label="显示顺序" prop="roleSort" width="100" />
<el-table-column label="状态" align="center" width="100">
<template slot-scope="scope">
<el-switch
@ -160,13 +149,10 @@
</el-card>
<!-- 添加或修改角色配置对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px"
append-to-body :close-on-press-escape="false" :close-on-click-modal="false"
:show-close="false" :wrapperClosable="false"
append-to-body>
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="100px">
<el-form-item label="角色名称" prop="roleName">
<el-input v-model="form.roleName" placeholder="请输入角色名称" maxlength="50" show-word-limit/>
<el-input v-model="form.roleName" placeholder="请输入角色名称" />
</el-form-item>
<el-form-item prop="roleKey">
<span slot="label">
@ -175,7 +161,7 @@
</el-tooltip>
权限字符
</span>
<el-input v-model="form.roleKey" placeholder="请输入权限字符" maxlength="70" show-word-limit/>
<el-input v-model="form.roleKey" placeholder="请输入权限字符" />
</el-form-item>
<el-form-item label="角色顺序" prop="roleSort">
<el-input-number v-model="form.roleSort" controls-position="right" :min="0" />
@ -215,10 +201,7 @@
</el-dialog>
<!-- 分配角色数据权限对话框 -->
<el-dialog :title="title" :visible.sync="openDataScope" width="500px"
:close-on-press-escape="false" :close-on-click-modal="false"
:show-close="false" :wrapperClosable="false"
append-to-body>
<el-dialog :title="title" :visible.sync="openDataScope" width="500px" append-to-body>
<el-form :model="form" label-width="80px">
<el-form-item label="角色名称">
<el-input v-model="form.roleName" :disabled="true" />
@ -309,8 +292,7 @@ export default {
{
value: "3",
label: "本部门数据权限"
}
,
},
{
value: "4",
label: "本部门及以下数据权限"

View File

@ -224,6 +224,7 @@
<script>
import Treeselect from "@riophae/vue-treeselect";
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
export default {
components: { Treeselect },

View File

@ -2,64 +2,54 @@
<div class="app-container">
<el-card>
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
<div class="search">
<div class="sl">
<el-form-item label="用户名称" prop="userName">
<el-input
v-model="queryParams.userName"
placeholder="请输入用户名称"
clearable
style="width: 240px"
@keyup.enter.native="handleQuery"
@clear="handleQuery"
/>
</el-form-item>
<el-form-item label="手机号码" prop="phonenumber">
<el-input
v-model="queryParams.phonenumber"
placeholder="请输入手机号码"
clearable
style="width: 240px"
@keyup.enter.native="handleQuery"
@clear="handleQuery"
/>
</el-form-item>
<el-form-item label="状态" prop="status">
<el-select
v-model="queryParams.status"
placeholder="用户状态"
clearable
style="width: 240px"
@change="handleQuery"
@clear="handleQuery"
>
<el-option
v-for="dict in dict.type.sys_normal_disable"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="创建时间">
<el-date-picker
v-model="dateRange"
style="width: 240px"
value-format="yyyy-MM-dd"
type="daterange"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
@change="handleQuery"
@clear="handleQuery"
></el-date-picker>
</el-form-item>
</div>
<div class="sr">
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</div>
</div>
<el-form-item label="用户名称" prop="userName">
<el-input
v-model="queryParams.userName"
placeholder="请输入用户名称"
clearable
style="width: 240px"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="手机号码" prop="phonenumber">
<el-input
v-model="queryParams.phonenumber"
placeholder="请输入手机号码"
clearable
style="width: 240px"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="状态" prop="status">
<el-select
v-model="queryParams.status"
placeholder="用户状态"
clearable
style="width: 240px"
>
<el-option
v-for="dict in dict.type.sys_normal_disable"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="创建时间">
<el-date-picker
v-model="dateRange"
style="width: 240px"
value-format="yyyy-MM-dd"
type="daterange"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
></el-date-picker>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
</el-card>
<el-card class="lrtt">
@ -95,7 +85,7 @@
@click="handleAdd"
v-hasPermi="['system:user:add']"
>新增</el-button>
<el-button
<!-- <el-button
plain
icon="el-icon-edit"
size="mini"
@ -111,10 +101,9 @@
@click="handleDelete"
v-hasPermi="['system:user:remove']"
>删除</el-button>
<!--
<el-button
plain
icon="el-icon-upload2"
icon="el-icon-upload2"
size="mini"
@click="handleImport"
v-hasPermi="['system:user:import']"
@ -194,10 +183,7 @@
</el-card>
<!-- 添加或修改用户配置对话框 -->
<el-dialog :title="title" :visible.sync="open" width="600px"
:close-on-press-escape="false" :close-on-click-modal="false"
:show-close="false" :wrapperClosable="false"
append-to-body>
<el-dialog :title="title" :visible.sync="open" width="600px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-row>
<el-col :span="12">
@ -207,7 +193,7 @@
</el-col>
<el-col :span="12">
<el-form-item label="归属部门" prop="deptId">
<treeselect v-model="form.deptId" :options="deptOptions" :show-count="true" :disable-branch-nodes="true" placeholder="请选择归属部门" />
<treeselect v-model="form.deptId" :options="deptOptions" :show-count="true" placeholder="请选择归属部门" />
</el-form-item>
</el-col>
</el-row>
@ -275,7 +261,7 @@
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="角色" prop="roleIds">
<el-form-item label="角色">
<el-select v-model="form.roleIds" multiple placeholder="请选择角色">
<el-option
v-for="item in roleOptions"
@ -303,10 +289,7 @@
</el-dialog>
<!-- 用户导入对话框 -->
<el-dialog :title="upload.title" :visible.sync="upload.open" width="400px"
:close-on-press-escape="false" :close-on-click-modal="false"
:show-close="false" :wrapperClosable="false"
append-to-body>
<el-dialog :title="upload.title" :visible.sync="upload.open" width="400px" append-to-body>
<el-upload
ref="upload"
:limit="1"
@ -342,6 +325,7 @@ import { listUser, getUser, delUser, addUser, updateUser, resetUserPwd, changeUs
import { getToken } from "@/utils/auth";
import { Base64 } from 'js-base64'
import Treeselect from "@riophae/vue-treeselect";
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
export default {
name: "User",
@ -428,9 +412,6 @@ export default {
nickName: [
{ required: true, message: "用户昵称不能为空", trigger: "blur" }
],
deptId: [
{ required: true, message: "归属部门不能为空", trigger: "blur" }
],
password: [
{ required: true, message: "用户密码不能为空", trigger: "blur" },
{ min: 5, max: 20, message: '用户密码长度必须介于 5 和 20 之间', trigger: 'blur' },
@ -449,10 +430,7 @@ export default {
message: "请输入正确的手机号码",
trigger: "blur"
}
],
roleIds: [
{ required: true, message: "角色不能为空", trigger: "blur" }
],
]
}
};
},

View File

@ -7,9 +7,9 @@
<span>个人信息</span>
</div>
<div>
<!-- <div class="text-center">
<div class="text-center">
<userAvatar />
</div>-->
</div>
<ul class="list-group list-group-striped">
<li class="list-group-item">
<svg-icon icon-class="user" />用户名称
@ -19,10 +19,10 @@
<svg-icon icon-class="phone" />手机号码
<div class="pull-right">{{ user.phonenumber }}</div>
</li>
<!-- <li class="list-group-item">
<li class="list-group-item">
<svg-icon icon-class="email" />用户邮箱
<div class="pull-right">{{ user.email }}</div>
</li>-->
</li>
<li class="list-group-item">
<svg-icon icon-class="tree" />所属部门
<div class="pull-right" v-if="user.dept">{{ user.dept.deptName }} / {{ postGroup }}</div>

View File

@ -2,13 +2,13 @@
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="用户昵称" prop="nickName">
<el-input v-model="form.nickName" maxlength="30" />
</el-form-item>
</el-form-item>
<el-form-item label="手机号码" prop="phonenumber">
<el-input v-model="form.phonenumber" maxlength="11" />
</el-form-item>
<!-- <el-form-item label="邮箱" prop="email">
<el-form-item label="邮箱" prop="email">
<el-input v-model="form.email" maxlength="50" />
</el-form-item>-->
</el-form-item>
<el-form-item label="性别">
<el-radio-group v-model="form.sex">
<el-radio label="0"></el-radio>

View File

@ -1,9 +1,9 @@
<template>
<el-dialog title="新增附件信息" :visible.sync="visible" width="85%" append-to-body>
<edit-document ref="editDocumentRef" :toolId="toolId" @docSubmitData="editDocumentSubmit" :relatedTool="false"/>
<el-dialog title="新增文档" :visible.sync="visible" width="85%" append-to-body>
<edit-document ref="editDocumentRef" :toolId="toolId" @submit="editDocumentSubmit"/>
<div slot="footer" class="dialog-footer">
<el-button type="primary" icon="el-icon-check" @click="submitForm()"> </el-button>
<el-button icon="el-icon-close" @click="cancel()"></el-button>
<el-button type="primary" @click="$refs.editDocumentRef.submitForm()"> </el-button>
<el-button @click="cancel()"></el-button>
</div>
</el-dialog>
</template>
@ -26,7 +26,7 @@ export default {
*/
toolId: {
type: String,
default: ''
default: true
}
},
computed: {
@ -45,19 +45,13 @@ export default {
}
},
methods: {
editDocumentSubmit(data){
this.$emit("addFileData", data)
editDocumentSubmit(){
this.$emit('callback')
this.visible = false
},
cancel() {
this.$refs.editDocumentRef.cancel()
this.visible = false
},
submitForm(){
this.$refs.editDocumentRef.assembleSubmit()
},
resetForm(){
this.$refs.editDocumentRef.resetForm()
}
}
}

View File

@ -1,165 +0,0 @@
<template>
<div class="fbox1">
<div class="fl">
<el-tabs v-model="detailActiveName">
<el-tab-pane label="附件信息" name="first" v-loading="previewLoading" element-loading-text="预览转换中,请耐心等待">
<el-table :data="attachmentList" style="width: 100%">
<el-table-column label="序号" width="60" align="center" type="index"></el-table-column>
<el-table-column label="附件名称" prop="fileName" :show-overflow-tooltip="true" />
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createDate) }}</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="180" v-if="toolDetail.downloadStatus">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-view"
v-if="previewAuth(scope.row)"
@click="handlePreview(scope.row)"
>预览</el-button>
<el-button type="text" icon="el-icon-download" @click="handleDownload(scope.row)" v-loading="loadingDownload">下载</el-button>
</template>
</el-table-column>
</el-table><!--el-table-->
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getAttachmentList"
/>
</el-tab-pane><!--el-tab-pane-->
</el-tabs><!--el-tabs-->
</div><!--fl 左侧页签-->
<preview-util v-if="isPreviewDisable" ref="previewForm" @previewClose="previewClose" @previewLoadingClose="previewLoadingClose"></preview-util>
</div><!--fbox1 左右分栏-->
</template>
<script>
import { addCount } from "@/api/tool/downloadCount";
import { listAttachment } from "@/api/attachment/attachment";
import previewUtil from '@/components/PreviewUtil/previewUtil.vue'
export default {
name: 'toolDetail',
components: { previewUtil},
dicts:[],
props: {
toolDetail: {
type: Object,
default: {},
}
},
data(){
return{
detailActiveName: 'first',
attachmentList: [],
queryParams: {
pageNum: 1,
pageSize: 10,
toolId: ''
},
previewUrl: '',
viewDialogTitle: "",
viewDialogOpen: false,
title: '新增文档',
open: false,
loadingDownload: false,
discussionContent: null, //
repliesContent: null, //
//
discussionsList: [],
//
repliesList: [],
showReplyForm: [],
replyContent: [],
isPreviewDisable: false,
attFileType: "zip,rar,7z",
total: 0,
previewLoading:false,
}
},
created(){
this.getAttachmentList()
},
methods:{
getAttachmentList() {
this.loading = true;
this.$set(this.queryParams,'del',"0")
this.$set(this.queryParams,'businessId',this.toolDetail.toolId)
listAttachment(this.queryParams).then(response => {
this.attachmentList = response.rows;
this.total = response.total;
this.loading = false;
}
);
},
handlePreview(row){
this.isPreviewDisable = true
this.previewLoading = true
this.$nextTick(() => {
this.$refs.previewForm.frontModulePreview(row)
})
},
/** 关闭预览 **/
previewClose(){
this.isPreviewDisable = false
},
/** 关闭预览遮罩 **/
previewLoadingClose(){
this.previewLoading = false
},
previewAuth(row){
if(row.fileUrl == null || row.fileUrl == '' || row.fileUrl == undefined){
return false
}
let extension = this.getExtension(row.fileUrl);
const acceptedExtensions = this.attFileType.toLowerCase().split(',');
if(acceptedExtensions.includes(extension)){
return false
}
return true
},
getExtension(filePath) {
// '.'
const parts = filePath.split('.');
//
const extension = parts.pop();
return extension;
},
/**
* 处理下载
* **/
handleDownload(row){
let self = this
self.loadingDownload = true
this.$download.resource(row.fileUrl);
//
if(row.businessId){
let formData = {
'businessId': row.businessId,
'businessType': 'tool',
'attId': row.id,
'attName': row.fileOldName
}
addCount(formData).then(res => {
});
}
setTimeout(()=>{
self.loadingDownload = false
},1000)
},
}
}
</script>
<style scoped>
</style>

File diff suppressed because it is too large Load Diff

View File

@ -1,300 +1,99 @@
<template>
<div class="fbox1">
<div class="fl" v-loading="detailLoading">
<el-tabs v-model="detailActiveName">
<el-tab-pane label="基本信息" name="first">
<div class="app-container">
<!-- <div class="fl">-->
<!-- <el-tabs v-model="detailActiveName">-->
<div class="el-form-border">
<el-form ref="form" label-width="150px">
<div class="box-title">
基本信息
</div>
<el-row>
<el-col :span="12"> <el-form-item label="中文别名">{{detailData.toolName}}</el-form-item> </el-col>
<el-col :span="12"> <el-form-item label="类别"><dict-tag :options="dict.type.tool_type" :value="detailData.toolType"/></el-form-item> </el-col>
<el-col :span="12"> <el-form-item label="来源"><dict-tag :options="dict.type.tool_source" :value="detailData.toolSource"/></el-form-item> </el-col>
<el-col :span="12"> <el-form-item label="负责人">{{detailData.toolPrincipalsName}}</el-form-item> </el-col>
<el-col :span="12"> <el-form-item label="归属单位">{{detailData.toolRespDeptName}}</el-form-item> </el-col>
<el-col :span="12"> <el-form-item label="形态"><dict-tag :options="dict.type.tool_status" :value="detailData.status"/></el-form-item> </el-col>
<el-col :span="12"> <el-form-item label="加密方式">{{detailData.encryptionMode}}</el-form-item> </el-col>
<el-col :span="12"> <el-form-item label="服务时间">{{detailData.serviceTime}}</el-form-item> </el-col>
<el-col :span="12"> <el-form-item label="联系人">{{detailData.contactPerson}}</el-form-item> </el-col>
<el-col :span="12"> <el-form-item label="联系方式">{{detailData.contactPhone}}</el-form-item> </el-col>
<el-col :span="12"> <el-form-item label="用途">{{detailData.toolUse}}</el-form-item> </el-col>
<el-col :span="12"> <el-form-item label="测评机构">{{detailData.testSituation}}</el-form-item> </el-col>
<el-col :span="12"> <el-form-item label="功能简介">{{detailData.functionDesc}}</el-form-item> </el-col>
<el-col :span="12"> <el-form-item label="适用条件">{{detailData.applyCondition}}</el-form-item> </el-col>
<el-col :span="12"> <el-form-item label="操作说明">{{detailData.operateExplain}}</el-form-item> </el-col>
<el-col :span="12"> <el-form-item label="备注">{{detailData.remark}}</el-form-item> </el-col>
<el-col :span="24">
<el-form-item label="关联工具">
<span v-if="detailData.association != null && detailData.association != '' && detailData.association != undefined">
<el-tag :key="tag.toolId" v-for="tag in detailData.association" type="info" style="margin-right: 5px">{{tag.toolName}}</el-tag>
</span>
</el-form-item>
</el-col>
<el-col :span="12"> <el-form-item label="工具编号">工具编号</el-form-item> </el-col>
<el-col :span="12"> <el-form-item label="工具名称">工具名称2</el-form-item> </el-col>
<el-col :span="12"> <el-form-item label="工具类别">网络工具</el-form-item> </el-col>
<el-col :span="12"> <el-form-item label="工具来源">单位自建</el-form-item> </el-col>
<el-col :span="12"> <el-form-item label="负责人">赵宁宇</el-form-item> </el-col>
<el-col :span="12"> <el-form-item label="归属单位">人力资源部</el-form-item> </el-col>
<el-col :span="12"> <el-form-item label="状态"><span class="green">在用</span></el-form-item> </el-col>
<el-col :span="12"> <el-form-item label="工具用途">主要用于单位网络使用</el-form-item> </el-col>
<el-col :span="12"> <el-form-item label="测试情况">运行良好可正常使用</el-form-item> </el-col>
<el-col :span="12"> <el-form-item label="功能描述">单位网络使用</el-form-item> </el-col>
<el-col :span="12"> <el-form-item label="适用条件">网络正常</el-form-item> </el-col>
<el-col :span="12"> <el-form-item label="操作说明">正常开启即可用</el-form-item> </el-col>
<el-col :span="12"> <el-form-item label="备注">工具使用完成后请做好保养工作</el-form-item> </el-col>
</el-row>
</el-form><!--el-form-->
</div><!--el-form-border 表单-->
</el-tab-pane><!--el-tab-pane-->
<el-tab-pane label="关联附件" name="second" v-loading="previewLoading" element-loading-text="预览转换中,请耐心等待">
<el-table :data="attachmentList" style="width: 100%">
<el-table-column label="附件名称" prop="fileName" :show-overflow-tooltip="true" />
<!-- <el-table-column label="类别" prop="docType" :show-overflow-tooltip="true" width="80" >
<template slot-scope="scope">
<dict-tag :options="dict.type.doc_class" :value="scope.row.docType"/>
</template>
</el-table-column>
<el-table-column label="负责人" prop="docPrincipals" :show-overflow-tooltip="true" width="80" />
<el-table-column label="归属单位" align="center" prop="docRespDeptName" :show-overflow-tooltip="true" width="80" />
<el-table-column label="来源" prop="docSource" width="100" >
<template slot-scope="scope">
<dict-tag :options="dict.type.doc_source" :value="scope.row.docSource"/>
</template>
</el-table-column>-->
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createDate) }}</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="150px">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-view"
v-if="previewAuth(scope.row)"
@click="handlePreview(scope.row)"
>预览</el-button>
<el-button type="text" icon="el-icon-download" v-if="detailData.downloadStatus" @click="handleDownload(scope.row)" v-loading="loadingDownload">
下载
</el-button>
</template>
</el-table-column>
</el-table><!--el-table-->
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getAttachmentList"
/>
</el-tab-pane><!--el-tab-pane-->
</el-tabs><!--el-tabs-->
</div><!--fl 左侧页签-->
<div class="fr" v-if="isComment">
<div class="tboper">
<div class="tit">评论{{ reviewTotal }}</div>
</div><!--tboper 标题与操作按钮-->
<div class="pltextarea">
<el-input v-model="discussionContent" type="textarea" placeholder="请输入您的意见" :rows="4" maxlength="1000" show-word-limit></el-input>
<div class="plbtn"><el-button @click="handleDiscussions">发布</el-button></div>
</div><!--pltextarea-->
<div class="pllist">
<template v-if="discussionsList && discussionsList.length > 0">
<div class="list" v-for="(item,index) in discussionsList" :key="item.id">
<div class="luser"><span class="xuser" :style="{backgroundColor: extractColorByName(item.nickName)}">{{getFirstChar(item.nickName)}}</span></div>
<div class="ltext">
<div class="nt"><span class="name">{{item.nickName}}</span><span class="time">{{ parseTime(item.createTime, '{y}-{m}-{d} {h}:{i}') }}</span></div>
<div class="te">{{item.content}}</div>
<div class="hb">
<a class="btn" @click="toggleReplyForm(index)">
<i class="el-icon-chat-line-round"></i>回复
</a>
<div>
<div class="box-title">
关联附件
</div>
<div class="pltextarea" v-if="showReplyForm[index]">
<el-input type="textarea" v-model="replyContent[index]" placeholder="请输入您的意见" :rows="2" maxlength="1000" show-word-limit></el-input>
<div class="plbtn">
<el-button @click="cancelReply(index)">取消</el-button>
<el-divider direction="vertical"></el-divider>
<el-button @click="submitReply(index, item)">发布</el-button>
</div>
</div>
<!--第二层级-->
<template v-if="item.repliesList && item.repliesList.length > 0">
<div class="list" v-for="(repItem, repIdex) in item.repliesList" :key="repItem.id">
<div class="luser">
<span class="xuser" :style="{width:'28px',height:'28px',lineHeight:'28px',backgroundColor: extractColorByName(repItem.nickName)}">{{getFirstChar(repItem.nickName)}}</span>
</div>
<div class="ltext">
<div class="nt">
<span class="name">{{repItem.nickName}}</span>
<template v-if="repItem.repTargetNickName">
<span>回复</span>
<span class="name">{{ repItem.repTargetNickName }}</span>
</template>
<span class="time">{{ parseTime(repItem.createTime, '{y}-{m}-{d} {h}:{i}') }}</span>
</div>
<div class="te">{{repItem.content}}</div>
<div class="hb"><a class="btn" @click="toggleReplyFormSon(index,repIdex)"><i class="el-icon-chat-line-round"></i>回复</a></div>
<div class="pltextarea" v-if="item.showReplyFormSon[repIdex]">
<el-input type="textarea" v-model="item.replyContentSon[repIdex]" placeholder="请输入您的意见" :rows="2" maxlength="1000" show-word-limit></el-input>
<div class="plbtn">
<el-button @click="cancelReplySon(index,repIdex)">取消</el-button>
<el-divider direction="vertical"></el-divider>
<el-button @click="submitReplySon(index, repIdex, item, repItem.id)">发布</el-button>
</div>
</div>
</div>
</div>
</template>
<el-table :data="docList" style="width: 100%">
<!-- <el-table-column type="selection" width="50" align="center"> </el-table-column>-->
<el-table-column label="文档名称" prop="docName" :show-overflow-tooltip="true" />
<el-table-column label="类别" prop="docType" :show-overflow-tooltip="true" width="80" />
<el-table-column label="负责人" prop="docPrincipals" :show-overflow-tooltip="true" width="80" />
<el-table-column label="归属部门" prop="docRespDept" :show-overflow-tooltip="true" width="150" />
<el-table-column label="来源" prop="docSource" width="100" />
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="180">
<template slot-scope="scope" v-if="scope.row.roleId !== 1">
<el-button type="text" icon="el-icon-download">下载</el-button>
</template>
</el-table-column>
</el-table><!--el-table-->
</div>
</div>
</template>
</div>
</div>
<el-dialog :title="viewDialogTitle" :visible.sync="viewDialogOpen" fullscreen width="500px" append-to-body :before-close="handleBeforeClose">
<i-frame :src="previewUrl" v-if="viewDialogOpen"/>
</el-dialog>
<preview-util v-if="isPreviewDisable" ref="previewForm" @previewClose="previewClose" @previewLoadingClose="previewLoadingClose"></preview-util>
<!-- 关联工具展示 -->
<el-dialog title="关联工具" :visible.sync="toolTreeVisible" width="980px" append-to-body :close-on-press-escape="false" :close-on-click-modal="false"
:show-close="false" :wrapperClosable="false" v-loading="toolTreeLoading">
<el-tree :data="toolRelationOptions" :props="defaultProps"></el-tree>
<!-- <el-table
:data="relationToolData"
border
ref="multipleTable"
header-align="left"
>
<el-table-column label="序号" width="60" type="index" align="center"></el-table-column>
<el-table-column label="工具编号" key="toolCode" prop="toolCode"/>
<el-table-column label="工具名称" key="toolName" prop="toolName":show-overflow-tooltip="true" />
<el-table-column label="操作" width="100px" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
@click="selectDelete(scope.row)"
>删除</el-button>
</template>
</el-table-column>
</el-table>
&lt;!&ndash; 分页组件 &ndash;&gt;
<el-pagination
v-show="relationToolTotal > 0"
:current-page.sync="currentToolPage"
:page-size.sync="pageToolSize"
:total="relationToolTotal"
@current-change="handlePageToolChange"
layout="total, prev, pager, next"
/>-->
<span slot="footer" class="dialog-footer">
<el-button icon="el-icon-close" @click="toolTreeVisible = false"> </el-button>
</span>
</el-dialog>
</div><!--el-form-border 表单-->
<AddDoc :show.sync="open" :toolId="toolDetail.toolId" @callback="getDocList"/>
</div><!--fl 左侧页签-->
<!-- 上传 -->
<!-- <AddDoc :show.sync="open" :toolId="detailData.toolId" @callback="getAttachmentList"/>-->
</div><!--fbox1 左右分栏-->
</template>
<script>
import { listDocument, getDocument, delDocument, addDocument, updateDocument } from "@/api/document/document";
import { listDiscussions, addDiscussions } from "@/api/tool/discussions.js";
import { listReplies, addReplies} from "@/api/tool/replies.js";
import { getTool } from "@/api/tool/tool.js";
import iFrame from "@/components/iFrame/index"
import { addCount } from "@/api/tool/downloadCount";
import { listAttachment } from "@/api/attachment/attachment";
import previewUtil from '@/components/PreviewUtil/previewUtil.vue'
import { getDataThree } from '@/api/tool/toolRelation'
import AddDoc from './AddDoc'
import editDocument from "../document/editDocument";
import { Base64 } from 'js-base64';
export default {
name: 'toolDetail',
components: { iFrame, previewUtil },
dicts:['sys_normal_disable','tool_type','tool_source','tool_status','doc_class','doc_source'],
components: { editDocument, AddDoc },
props: {
toolDetail: {
type: Object,
default: {},
required: false
},
//
isDownload: {
type: Boolean,
default: true,
required: false
},
//
isComment: {
type: Boolean,
default: true,
required: false
},
}
},
data(){
return{
detailActiveName: 'first',
attachmentList: [],
docList: [],
queryParams: {
pageNum: 1,
pageSize: 10,
toolId: ''
},
reviewTotal: 0,
previewUrl: '',
viewDialogTitle: "",
viewDialogOpen: false,
title: '新增文档',
open: false,
loadingDownload: false,
discussionContent: null, //
repliesContent: null, //
//
discussionsList: [],
//
repliesList: [],
showReplyForm: [],
replyContent: [],
detailLoading: false,
//
detailData:{},
attFileType: "zip,rar,7z",
// json
dialogVisible:false,
isJson:false,
resultContentObj:[],
// docx
isDocx:false,
docxData: null,
//pdf
isPdf:false,
pdfFileData: null, //
previewLoading:false,
previewUseFront: "txt,doc,docx,pdf",
isPreviewDisable: false,
total: 0,
//
toolTreeVisible: false,
toolTreeLoading: false,
toolDataList: [],
defaultProps: {
children: 'children',
label: 'label'
},
//
toolRelationOptions: [],
}
},
created(){
this.getDetail()
this.getAttachmentList()
this.getDiscussionsList()
},
watch: {
discussionsList(newList) {
this.showReplyForm = new Array(newList.length).fill(false);
this.replyContent = new Array(newList.length).fill('');
}
this.getDocList()
},
methods:{
getAttachmentList() {
getDocList() {
this.loading = true;
this.$set(this.queryParams,'del',"0")
this.$set(this.queryParams,'businessId',this.toolDetail.toolId)
listAttachment(this.queryParams).then(response => {
this.attachmentList = response.rows;
this.queryParams.toolId = this.toolDetail.toolId
listDocument(this.queryParams).then(response => {
this.docList = response.rows;
this.total = response.total;
this.loading = false;
}
@ -305,21 +104,12 @@
},
editDocumentSubmit(){
this.open = false
this.getAttachmentList()
this.getDocList()
},
handlePreview(row){
this.isPreviewDisable = true
this.$nextTick(() => {
this.$refs.previewForm.frontModulePreview(row)
})
},
/** 关闭预览 **/
previewClose(){
this.isPreviewDisable = false
},
/** 关闭预览遮罩 **/
previewLoadingClose(){
this.previewLoading = false
handlePriew(row){
this.previewUrl = process.env.VUE_APP_TOOL_TECH_FILE_VIEW_API + '/onlinePreview?url=' + encodeURIComponent(Base64.encode(process.env.VUE_APP_BASE_API + row.docUrl));
this.viewDialogTitle = '文档在线预览'
this.viewDialogOpen = true;
},
/** 删除按钮操作 */
handleDelete(row) {
@ -330,263 +120,7 @@
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {});
},
/**
* 处理下载
* **/
handleDownload(row){
let self = this
self.loadingDownload = true
this.$download.resource(row.fileUrl);
//
if(row.businessId){
let formData = {
'businessId': row.businessId,
'businessType': 'tool',
'attId': row.id,
'attName': row.fileOldName
}
addCount(formData).then(res => {
});
}
setTimeout(()=>{
self.loadingDownload = false
},1000)
},
getDiscussionsList() {
let _this = this
_this.reviewTotal = 0
listDiscussions({businessId: _this.toolDetail.toolId}).then(res => {
_this.discussionsList = res.rows
let reviewTotal = 0
_this.discussionsList.forEach(item => {
if(item.repliesList && item.repliesList.length > 0){
reviewTotal += item.repliesList.length
_this.$set(item, 'showReplyFormSon', new Array(item.repliesList.length).fill(false))
_this.$set(item, 'replyContentSon', new Array(item.repliesList.length).fill(''))
}else{
_this.$set(item, 'showReplyFormSon', false)
_this.$set(item, 'replyContentSon', '')
}
});
_this.reviewTotal = _this.discussionsList.length + reviewTotal
});
},
/** 评论 **/
handleDiscussions(){
let self = this
if (this.discussionContent == '' || this.discussionContent == null || this.discussionContent == undefined) {
self.$message({
message: '内容不能为空',//
type:'warning',  //
duration:1200,  //, 0 1200
});
return;
}
let data = {
businessId: this.toolDetail.toolId,
content: this.discussionContent,
type: "tool",
}
self.$modal.confirm('是否确认发布?').then(()=> {
addDiscussions(data).then(res => {
this.discussionContent = null
self.$message({
message: '发布成功',//
type:'success',  //
duration:1200,  //, 0 1200
});
self.getDiscussionsList()
}).catch(err =>{
this.discussionContent = null
console.error("handleDiscussions==err==", err)
self.$modal.msgError("发布失败");
});
})
},
extractColorByName(name) {
let temp = [];
temp.push("#");
for (let index = 0; index < name.length; index++) {
temp.push(parseInt(name[index].charCodeAt(0), 10).toString(16));
}
return temp.slice(0, 5).join('').slice(0, 4);
},
getFirstChar(value) {
if(!value){return ''}
return value.charAt(0);
},
toggleReplyForm(index) {
this.$set(this.showReplyForm, index, !this.showReplyForm[index]);
},
cancelReply(index) {
this.$set(this.showReplyForm, index, false);
this.$set(this.replyContent, index, '');
},
/** 回复 **/
submitReply(index, item) {
let self = this
const content = this.replyContent[index];
if (content == '' || content == null || content == undefined) {
self.$message({
message: '回复内容不能为空',//
type:'warning',  //
duration:1200,  //, 0 1200
});
return;
}
let data = {
"discussionId": item.id,
"content": content,
}
self.$modal.confirm('是否确认发布?').then(()=> {
addReplies(data).then(res => {
self.$message({
message: '发布成功',//
type:'success',  //
duration:1200,  //, 0 1200
});
self.cancelReply(index)
self.getDiscussionsList()
}).catch(err =>{
console.error("handleDiscussions==err==", err)
self.$modal.msgError("发布失败");
});
})
//
this.replyContent[index] = '';
this.showReplyForm[index] = false;
},
/** 第二级 **/
toggleReplyFormSon(parentIndex, repIndex) {
const parentItem = this.discussionsList[parentIndex];
this.$set(parentItem.showReplyFormSon, repIndex, !parentItem.showReplyFormSon[repIndex]);
// this.$set(this.showReplyFormSon, index, !this.showReplyFormSon[index]);
},
/** 第二级,取消回复 **/
cancelReplySon(parentIndex, repIndex) {
const parentItem = this.discussionsList[parentIndex];
this.$set(parentItem.showReplyFormSon, repIndex, false);
this.$set(parentItem.replyContentSon, repIndex, '');
},
/** 第二级回复 **/
submitReplySon(parentIndex, repIndex, repItem, repId) {
let self = this
const parentItem = this.discussionsList[parentIndex];
const content = parentItem.replyContentSon[repIndex];
if (content.trim() == '' || content == null || content == undefined) {
self.$message({
message: '回复内容不能为空',//
type:'warning',  //
duration:1200,  //, 0 1200
});
return;
}
let data = {
"discussionId": repItem.id,
"repId": repId,
"content": content,
}
self.$modal.confirm('是否确认发布?').then(()=> {
addReplies(data).then(res => {
self.$message({
message: '发布成功',//
type:'success',  //
duration:1200,  //, 0 1200
});
self.cancelReplySon(parentIndex, repIndex)
self.getDiscussionsList()
//
this.$set(parentItem.replyContentSon, repIndex, '');
this.$set(parentItem.showReplyFormSon, repIndex, false);
}).catch(err =>{
console.error("submitReplySon==err==", err)
self.$modal.msgError("发布失败");
});
})
},
handleBeforeClose() {
this.viewDialogOpen = false
},
/** 获取详情信息 **/
getDetail(){
let self = this
self.detailLoading = true
getTool(self.toolDetail.toolId).then((res) => {
self.detailData = res.data
self.detailData.association = JSON.parse(res.data.association)
/*let formData = res.data;
formData.type = _this.form.type
_this.form = formData*/
}).finally(()=>{
self.detailLoading = false
});
},
previewAuth(row){
if(row.fileUrl == null || row.fileUrl == '' || row.fileUrl == undefined){
return false
}
let extension = this.getExtension(row.fileUrl);
const acceptedExtensions = this.attFileType.toLowerCase().split(',');
if(acceptedExtensions.includes(extension)){
return false
}
return true
},
getExtension(filePath) {
// '.'
const parts = filePath.split('.');
//
const extension = parts.pop();
return extension;
},
/** 获取工具关联树展示 */
getToolRelationTree() {
let self = this
let toolRelation ={
resourceId: "",
}
let toolIds = []
if(self.detailData.toolId){
self.$set(toolRelation,"resourceIds",[self.detailData.toolId])
}else if(self.detailData.association && self.detailData.association.length > 0){
self.detailData.association.forEach(item=>{
toolIds.push(item.toolId)
})
self.$set(toolRelation,"resourceIds",toolIds)
}
self.toolTreeVisible = true;
self.toolTreeLoading = true;
getDataThree(toolRelation).then(res => {
if(self.detailData.toolName){
let treeArray = []
let treeData = {
"id": "20240908001",
"label": self.detailData.toolName,
"types": null,
"children": res.data
}
treeArray.push(treeData)
this.toolRelationOptions = treeArray;
self.toolTreeLoading = false;
return
}
this.toolRelationOptions = res.data;
self.toolTreeLoading = false;
}).catch(err => {
console.error("err========", err)
self.toolTreeLoading = false;
});
},
}
}
}
</script>

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