大版本:专业版已经开源,详见business分支

pull/2/head
liuwx_gitee 2 years ago
parent 2ec2ed6ea2
commit af3f1d93c7

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 774 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 170 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

@ -3,7 +3,8 @@
科亿知识库 KYKMS
===============
当前最新版本: V1.0.1发布日期20230615
当前最新版本: V2.0.0发布日期20241025
- 版本备注专业版已经开源详见business分支。随着新版本功能迭代会持续把开源版也升级敬请期待。
项目简介:
-----------------------------------
@ -16,13 +17,14 @@
为什么选择科亿知识库?
-----------------------------------
- 两年多的产品运营历史,历经数百客户验证,背后是专业的技术团队支撑,让您使用无后顾之忧后。
- AI能力加持集成大语言模型结合本地知识库打造最懂您的知识智能管家在轻松的问答间获得最精准、扼要的关键信息。
- 自身集成本地化大语言模型亦支持扩展对接第三方主流的大模型如chat-GPT、通义千问、智普、文心一言、llama等。
- 图像内容自动转文本,让各种扫描件轻松实现知识提取,并支持全文检索。
- 大模型能力加持,结合本地知识库,打造最懂您的知识智能管家,让大模型帮您对知识进行分类、标签、摘要,并且在自然语言对话间获得精准、扼要的本地知识库信息。
- 支持本地化部署的大语言模型典型ollama亦支持扩展对接第三方主流的大模型如chat-GPT、通义千问、智普、文心一言等。
- 附件内图像内容自动转文本,让各种扫描件轻松实现知识提取,并支持全文检索、智能问答
- 灵活强大的知识访问权限管理模型,您能想到的都有。同时支持灵活分享、交流模式:站内、站外分享,评价与评论体系。
- 基于强大的 Elasticsearch 检索引擎技术构建,检索能力强大,支持最全面的检索特性,可以无限可能的集群扩展,支持高达百亿级别的数量。
- 全方位内容检索,包括文件内容、标题、关键字、知识摘要,并支持结果中二次检索、高级组合检索,支持精准匹配,关键词高亮显示。
- 全方位内容检索,包括附件文件内容、标题、关键字、知识摘要,并支持结果中二次检索、高级组合检索,支持精准匹配,关键词高亮显示。
- 全文检索与在线预览有着齐全的文件格式支持支持全文检索的文件格式office系列、文本、pdf、脑图支持在线预览的文件格式包括office系列、pdf、ofd、文本、脑图、图片、音频、视频等。
- 在线预览支持自定义水印,保护敏感信息截屏外流。
- 适配手机端 H5支持集成到钉钉、企业微信支持单点登录与对接第三方系统推送知识。
- 所有能力、服务均为在本地化部署,无须联网,无须依赖外网的服务,满足企业信息安全要求。
- 性能优秀最低配置2核4G即可运行典型配置4核8G。
@ -32,8 +34,7 @@
- 官方站点 [http://www.kykms.cn](http://www.kykms.cn)
- 技术文档 科亿知识库的使用、部署手册,技术说明,请访问 - [技术文档大全](http://docs.kykms.cn/docs/mindoc/mindoc-1ephusv88b42s)
- 本产品有五个版本:开源版、绿色单机版、专业版、旗舰版、智能版 - [版本功能比较](http://www.kykms.cn/edition)
- 旗舰版在线演示 [旗舰版](http://kg.kykms.cn) 账号admin/123456
- 专业在线演示 [专业版](http://test.kykms.cn) 账号admin/123456
- 智能版在线演示 [智能版](http://kg.kykms.cn/loginRandom)
- 绿色单机版 [试用下载](http://service.kykms.cn/download-index) - [更多介绍](http://docs.kykms.cn/docs/greenDesktop/greenDesktop-1et33iuds3f68)
- 开发环境准备与运行,请参考:[开发环境准备与运行](./开发环境准备与运行.MD)
- 本地部署试用:强烈建议[docker方式部署](http://docs.kykms.cn/docs/mindoc/mindoc-1f80r7nnv763o);此外提供多版本安装包直接下载 - [下载入口](http://service.kykms.cn/download-index)
@ -158,12 +159,13 @@ KMS技术架构图
----
##### 公共检索
![智能问答](./Docs/Pics/search_AI.jpg)
检索首页
![检索首页](./Docs/Pics/search_home.png)
![检索首页](./Docs/Pics/search_home.jpg)
检索结果
![检索结果](./Docs/Pics/search_result.png)
![检索结果](./Docs/Pics/search_result.jpg)
高级检索
![高级检索](./Docs/Pics/search_advance.png)
![高级检索](./Docs/Pics/search_advance.jpg)
知识专题
![知识专题](./Docs/Pics/km_topic.png)
知识详情

@ -1,3 +1,3 @@
NODE_ENV=docker
VUE_APP_PLATFORM_NAME=科亿知识库
NODE_ENV=development
VUE_APP_PLATFORM_NAME=VUE_APP_PLATFORM_NAME
VUE_APP_SSO=false

@ -1,4 +1,4 @@
NODE_ENV=docker
VUE_APP_API_BASE_URL=/api
VUE_APP_CAS_BASE_URL=http://localhost:8888/cas
VUE_APP_CAS_BASE_URL=/cas
VUE_APP_ONLINE_BASE_URL=http://localhost/onlinePreview

@ -1,4 +1,4 @@
NODE_ENV=production
VUE_APP_API_BASE_URL=http://localhost:8080/ky
VUE_APP_API_BASE_URL=http://119.29.145.199:8080/ky/
VUE_APP_CAS_BASE_URL=http://localhost:8888/cas
VUE_APP_ONLINE_BASE_URL=http://localhost/onlinePreview

@ -1,4 +1,4 @@
NODE_ENV=test
VUE_APP_API_BASE_URL=/api
VUE_APP_API_BASE_URL=http://119.29.145.199:8080/ky/
VUE_APP_CAS_BASE_URL=http://cas.example.org:8443/cas
VUE_APP_ONLINE_BASE_URL=http://localhost/onlinePreview

@ -1,7 +1,29 @@
FROM nginx:1.24.0
FROM nginx
MAINTAINER hnliuwx@gmail.com
VOLUME /tmp
ENV LANG en_US.UTF-8
RUN echo "server { \
listen 80; \
location ^~ /ky { \
proxy_pass http://124.71.194.56:8080/ky/; \
proxy_set_header Host localhost; \
proxy_set_header X-Real-IP \$remote_addr; \
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; \
} \
#解决Router(mode: 'history')模式下,刷新路由地址不能找到页面的问题 \
location / { \
root /var/www/html/; \
index index.html index.htm; \
if (!-e \$request_filename) { \
rewrite ^(.*)\$ /index.html?s=\$1 last; \
break; \
} \
} \
access_log /var/log/nginx/access.log ; \
} " > /etc/nginx/conf.d/default.conf \
&& mkdir -p /var/www \
&& mkdir -p /var/www/html
RUN rm -f /etc/nginx/conf.d/default.conf
ADD ./dist /usr/share/nginx/kykms-root/
ADD dist/ /var/www/html/
EXPOSE 80
EXPOSE 443

@ -4,14 +4,11 @@
当前最新版本: V0.0.1发布日期20220322
Overview
----
<h3 align="center">基于常用文档的知识库管理系统</h3>
科亿知识库 KY KMS 是一款面向常用文档的`文档型知识库管理系统`
强大灵活的知识访问权限管理组合,多种知识分享沟通方式,全文检索与在线预览有着齐全的文件格式支持,版本管理控制与回滚,丰富的扩展接口支持与第三方集成。
----
`科亿知识库宗旨是:` 文档简单整理,知识创造价值
基于 [Ant Design of Vue](https://vuecomponent.github.io/ant-design-vue/docs/vue/introduce-cn/) 实现的 Ant Design Pro Vue 版
Jeecg-boot 的前端UI框架采用前后端分离方案提供强大代码生成器的低代码平台。
前端页面代码和后端功能代码一键生成不需要写任何代码保持jeecg一贯的强大
@ -34,6 +31,8 @@ Overview
----
- [Ant Design Vue](https://vuecomponent.github.io/ant-design-vue/docs/vue/introduce-cn)
- [报表 viser-vue](https://viserjs.github.io/demo.html#/viser/bar/basic-bar)
- [Vue](https://cn.vuejs.org/v2/guide)
- [路由/菜单说明](https://github.com/zhangdaiscott/jeecg-boot/tree/master/ant-design-jeecg-vue/src/router/README.md)
@ -48,3 +47,4 @@ Overview
> @vue/cli 升级后eslint 规则更新了。由于影响到全部 .vue 文件,需要逐个验证。既暂时关闭部分原本不验证的规则,后期维护时,在逐步修正这些 rules

@ -3,4 +3,11 @@ module.exports = {
['@vue/app',
{ useBuiltIns: 'entry' }]
]
// plugins: [
// [ "import", {
// "libraryName": "ant-design-vue",
// "libraryDirectory": "es",
// "style": "css"
// } ]
// ]
}

@ -0,0 +1,11 @@
## 商业版试用镜像提供源下载,仅限于个人学习用途,如擅自用于商业用途,带来的一切后果由个人负责
## !!!!暂未完善,如有需求请联系作者!!!!!
##执行启动命令 docker-compose -f ./docker-compose-business_web.yml up
version: '2'
services:
kykms-nginx:
image: mahonelau/kykms-nginx:business_official
restart: always
container_name: kykms-nginx
ports:
- 80:80

@ -1,19 +1,17 @@
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;
events {
worker_connections 1024;
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
@ -21,58 +19,58 @@ http {
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 4096;
keepalive_timeout 65;
include /etc/nginx/mime.types;
default_type application/octet-stream;
gzip on;
gzip_buffers 16 8k;
gzip_comp_level 6;
gzip_http_version 1.1;
gzip_min_length 256;
gzip_proxied any;
# Load modular configuration files from the /etc/nginx/conf.d directory.
# See http://nginx.org/en/docs/ngx_core_module.html#include
# for more information.
# gzip config
gzip on;
gzip_min_length 1k;
gzip_comp_level 9;
gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
gzip_vary on;
gzip_types
text/xml application/xml application/atom+xml application/rss+xml application/xhtml+xml image/svg+xml
text/javascript application/javascript application/x-javascript
text/x-json application/json application/x-web-app-manifest+json
text/css text/plain text/x-component
font/opentype application/x-font-ttf application/vnd.ms-fontobject
image/x-icon;
gzip_disable "MSIE [1-6]\.(?!.*SV1)";
gzip_disable "MSIE [1-6]\.";
server {
listen 3000;
#include /etc/nginx/conf.d/*.conf;
#server添加下面内容 解决Router(mode: 'history')模式下,刷新路由地址不能找到页面的问题
location / {
root /usr/share/nginx/html;
index index.html index.htm;
if (!-e $request_filename) {
server {
listen 80;
listen [::]:80;
server_name _;
root /usr/share/nginx/html;
# Load configuration files for the default server block.
#include /etc/nginx/default.d/*.conf;
location / {
root html;
index index.html index.htm;
if (!-e $request_filename) {
rewrite ^(.*)$ /index.html?s=$1 last;
break;
}
}
location /api/{
if ($request_method = 'OPTIONS') { #处理预检请求
add_header 'Access-Control-Allow-Origin' '*'; #此处理客户端预检请求->nginx服务器跨域问题
add_header 'Access-Control-Allow-Headers' '*'; #此允许客户端请求携带header自定义参数也可以指定具体参数名称
return 204;
}
if ($request_method != 'OPTIONS') { #正常请求
#add_header 'Access-Control-Allow-Origin' '*'; #此处根据服务端api是否配置跨域决定是否配置不能重复配置
}
}
proxy_pass http://kykms:8080/ky/;
}
location /api/{
proxy_pass http://localhost:8080/ky/;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
error_page 404 /404.html;
location = /404.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}

@ -5,24 +5,23 @@
"scripts": {
"pre": "cnpm install || yarn --registry https://registry.npm.taobao.org || npm install --registry https://registry.npm.taobao.org ",
"serve:development": "vue-cli-service serve --mode development",
"build:test": "vue-cli-service build --mode test",
"build:docker": "vue-cli-service build --mode docker",
"serve:docker": "vue-cli-service serve --mode docker",
"serve:test": "vue-cli-service serve --mode test",
"serve:production": "vue-cli-service serve --mode production",
"build:production": "vue-cli-service build --mode production",
"build:docker": "vue-cli-service build --mode docker",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint",
"serve:test": "vue-cli-service serve --mode test"
"analyzer": "cross-env use_analyzer=true npm run build"
},
"dependencies": {
"@antv/data-set": "^0.11.4",
"@jeecg/antd-online-mini": "git+https://gitee.com/kyxxjs/antd-online-mini.git",
"@jeecg/antd-online-mini": "3.0.0-RC",
"@tinymce/tinymce-vue": "^2.1.0",
"@toast-ui/editor": "^2.1.2",
"ant-design-vue": "^1.7.2",
"ant-design-vue": "^1.7.8",
"area-data": "^5.0.6",
"axios": "^0.18.0",
"axios": "^1.4.0",
"clipboard": "^2.0.4",
"codemirror": "^5.46.0",
"cron-parser": "^2.10.0",
"dayjs": "^1.8.0",
"dom-align": "1.12.0",
@ -31,19 +30,20 @@
"lodash.get": "^4.4.2",
"lodash.pick": "^4.4.0",
"md5": "^2.2.1",
"moment": "^2.29.4",
"nprogress": "^0.2.0",
"tinymce": "^5.3.2",
"viser-vue": "^2.4.8",
"vue": "^2.6.10",
"vue-area-linkage": "^5.1.0",
"vue-cropper": "^0.5.4",
"vue-i18n": "^8.7.0",
"vue-loader": "^15.9.6",
"vue-ls": "^3.2.0",
"vue-photo-preview": "^1.1.3",
"vue-print-nb-jeecg": "^1.0.9",
"vue-router": "^3.0.1",
"vue-splitpane": "^1.0.4",
"vue-virtual-scroller": "^1.1.2",
"vuedraggable": "^2.20.0",
"vuex": "^3.1.0",
"vxe-table": "2.9.13",
@ -57,14 +57,18 @@
"@vue/cli-service": "^3.3.0",
"@vue/eslint-config-standard": "^4.0.0",
"babel-eslint": "7.2.3",
"babel-plugin-import": "^1.13.0",
"compression-webpack-plugin": "^3.1.0",
"eslint": "^5.16.0",
"eslint-plugin-vue": "^5.1.0",
"html-webpack-plugin": "^4.2.0",
"less": "^3.9.0",
"less-loader": "^4.1.0",
"vue-infinite-scroll": "^2.0.2",
"vue-template-compiler": "^2.6.10",
"webpack": "^4.0.0"
"webpack": "^4.0.0",
"webpack-cli": "^4.8.0",
"webpack-dev-server": "^4.0.0"
},
"eslintConfig": {
"root": true,

@ -0,0 +1,6 @@
let Global_Config = {
API_BASE_URL: '',
SITE_TITLE: '科亿知识库',
KYKMS_URL: 'http://113.125.46.255:8081',
COPYRIGHT: '科亿信息技术'
}

@ -0,0 +1,282 @@
<!DOCTYPE html>
<html lang="zh-cmn-Hans">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>首页</title>
<!-- <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14"></script>-->
<!-- <script src="https://cdn.jsdelivr.net/npm/moment@2.29.4/moment.min.js"></script>-->
<!-- <script src="https://cdn.jsdelivr.net/npm/moment@2.29.4/locale/zh-cn.js"></script>-->
<!-- <script src="https://cdn.jsdelivr.net/npm/ant-design-vue@1.7.2/dist/antd.min.js"></script>-->
<!-- <script src="http://cdn.kykms.cn/vue.js"></script>-->
<!-- <script src="http://cdn.kykms.cn/moment.min.js"></script>-->
<!-- <script src="http://cdn.kykms.cn/zh-cn.js"></script>-->
<!-- <script src="http://cdn.kykms.cn/antd.min.js"></script>-->
<!-- <script src="http://cdn.kykms.cn/polyfill_7_2_5.js"></script>-->
<!-- <script>-->
<!-- if (!global._babelPolyfill) {-->
<!-- document.write(unescape("%3Cscript src='<%= BASE_URL %>cdn/babel-polyfill/polyfill_7_2_5.js' type='text/javascript'%3E%3C/script%3E"));-->
<!-- }-->
<!-- </script>-->
<!-- <link rel="stylesheet"type="text/css" href="http://cdn.kykms.cn/antd.min.css">-->
<script src="<%= BASE_URL %>cdn/babel-polyfill/polyfill_7_2_5.js"></script>
<link rel="icon" href="<%= BASE_URL %>logo.png">
<script src="<%= BASE_URL %>config.js"></script>
<!-- 全局配置 -->
<script>
window._CONFIG = {};
</script>
<style>
html,
body,
#app {
height: 100%;
margin: 0px;
padding: 0px;
}
.chromeframe {
margin: 0.2em 0;
background: #ccc;
color: #000;
padding: 0.2em 0;
}
#loader-wrapper {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 999999;
}
#loader {
display: block;
position: relative;
left: 50%;
top: 50%;
width: 120px;
height: 120px;
margin: -75px 0 0 -75px;
border-radius: 50%;
border: 3px solid transparent;
/* COLOR 1 */
border-top-color: #FFF;
-webkit-animation: spin 2s linear infinite;
/* Chrome, Opera 15+, Safari 5+ */
-ms-animation: spin 2s linear infinite;
/* Chrome, Opera 15+, Safari 5+ */
-moz-animation: spin 2s linear infinite;
/* Chrome, Opera 15+, Safari 5+ */
-o-animation: spin 2s linear infinite;
/* Chrome, Opera 15+, Safari 5+ */
animation: spin 2s linear infinite;
/* Chrome, Firefox 16+, IE 10+, Opera */
z-index: 1001;
}
#loader:before {
content: "";
position: absolute;
top: 5px;
left: 5px;
right: 5px;
bottom: 5px;
border-radius: 50%;
border: 3px solid transparent;
/* COLOR 2 */
border-top-color: #FFF;
-webkit-animation: spin 3s linear infinite;
/* Chrome, Opera 15+, Safari 5+ */
-moz-animation: spin 3s linear infinite;
/* Chrome, Opera 15+, Safari 5+ */
-o-animation: spin 3s linear infinite;
/* Chrome, Opera 15+, Safari 5+ */
-ms-animation: spin 3s linear infinite;
/* Chrome, Opera 15+, Safari 5+ */
animation: spin 3s linear infinite;
/* Chrome, Firefox 16+, IE 10+, Opera */
}
#loader:after {
content: "";
position: absolute;
top: 15px;
left: 15px;
right: 15px;
bottom: 15px;
border-radius: 50%;
border: 3px solid transparent;
border-top-color: #FFF;
/* COLOR 3 */
-moz-animation: spin 1.5s linear infinite;
/* Chrome, Opera 15+, Safari 5+ */
-o-animation: spin 1.5s linear infinite;
/* Chrome, Opera 15+, Safari 5+ */
-ms-animation: spin 1.5s linear infinite;
/* Chrome, Opera 15+, Safari 5+ */
-webkit-animation: spin 1.5s linear infinite;
/* Chrome, Opera 15+, Safari 5+ */
animation: spin 1.5s linear infinite;
/* Chrome, Firefox 16+, IE 10+, Opera */
}
@-webkit-keyframes spin {
0% {
-webkit-transform: rotate(0deg);
/* Chrome, Opera 15+, Safari 3.1+ */
-ms-transform: rotate(0deg);
/* IE 9 */
transform: rotate(0deg);
/* Firefox 16+, IE 10+, Opera */
}
100% {
-webkit-transform: rotate(360deg);
/* Chrome, Opera 15+, Safari 3.1+ */
-ms-transform: rotate(360deg);
/* IE 9 */
transform: rotate(360deg);
/* Firefox 16+, IE 10+, Opera */
}
}
@keyframes spin {
0% {
-webkit-transform: rotate(0deg);
/* Chrome, Opera 15+, Safari 3.1+ */
-ms-transform: rotate(0deg);
/* IE 9 */
transform: rotate(0deg);
/* Firefox 16+, IE 10+, Opera */
}
100% {
-webkit-transform: rotate(360deg);
/* Chrome, Opera 15+, Safari 3.1+ */
-ms-transform: rotate(360deg);
/* IE 9 */
transform: rotate(360deg);
/* Firefox 16+, IE 10+, Opera */
}
}
#loader-wrapper .loader-section {
position: fixed;
top: 0;
width: 51%;
height: 100%;
background: #49a9ee;
/* Old browsers */
z-index: 1000;
-webkit-transform: translateX(0);
/* Chrome, Opera 15+, Safari 3.1+ */
-ms-transform: translateX(0);
/* IE 9 */
transform: translateX(0);
/* Firefox 16+, IE 10+, Opera */
}
#loader-wrapper .loader-section.section-left {
left: 0;
}
#loader-wrapper .loader-section.section-right {
right: 0;
}
/* Loaded */
.loaded #loader-wrapper .loader-section.section-left {
-webkit-transform: translateX(-100%);
/* Chrome, Opera 15+, Safari 3.1+ */
-ms-transform: translateX(-100%);
/* IE 9 */
transform: translateX(-100%);
/* Firefox 16+, IE 10+, Opera */
-webkit-transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000);
transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000);
}
.loaded #loader-wrapper .loader-section.section-right {
-webkit-transform: translateX(100%);
/* Chrome, Opera 15+, Safari 3.1+ */
-ms-transform: translateX(100%);
/* IE 9 */
transform: translateX(100%);
/* Firefox 16+, IE 10+, Opera */
-webkit-transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000);
transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000);
}
.loaded #loader {
opacity: 0;
-webkit-transition: all 0.3s ease-out;
transition: all 0.3s ease-out;
}
.loaded #loader-wrapper {
visibility: hidden;
-webkit-transform: translateY(-100%);
/* Chrome, Opera 15+, Safari 3.1+ */
-ms-transform: translateY(-100%);
/* IE 9 */
transform: translateY(-100%);
/* Firefox 16+, IE 10+, Opera */
-webkit-transition: all 0.3s 1s ease-out;
transition: all 0.3s 1s ease-out;
}
/* JavaScript Turned Off */
.no-js #loader-wrapper {
display: none;
}
.no-js h1 {
color: #222222;
}
#loader-wrapper .load_title {
font-family: 'Open Sans';
color: #FFF;
font-size: 14px;
width: 100%;
text-align: center;
z-index: 9999999999999;
position: absolute;
top: 60%;
opacity: 1;
line-height: 30px;
}
#loader-wrapper .load_title span {
font-weight: normal;
font-style: italic;
font-size: 14px;
color: #FFF;
opacity: 0.5;
}
/* 滚动条优化 start */
::-webkit-scrollbar{
width:8px;
height:8px;
}
::-webkit-scrollbar-track{
background: #f6f6f6;
border-radius:2px;
}
::-webkit-scrollbar-thumb{
background: #cdcdcd;
border-radius:2px;
}
::-webkit-scrollbar-thumb:hover{
background: #747474;
}
::-webkit-scrollbar-corner {
background: #f6f6f6;
}
/* 滚动条优化 end */
</style>
</head>
<body>
<div id="app">
<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>
</body>
<!--<script type="text/javascript" src= "{{Global_Config.ONLYOFFICE_SERVER_IP}} /web-apps/apps/api/documents/api.js"></script>-->
</html>

@ -5,16 +5,21 @@
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>科亿知识库</title>
<title>首页</title>
<link rel="icon" href="<%= BASE_URL %>logo.png">
<script src="<%= BASE_URL %>config.js"></script>
<script src="<%= BASE_URL %>cdn/babel-polyfill/polyfill_7_2_5.js"></script>
<script>
window._CONFIG = {};
</script>
<style>
html,
body,
#app {
height: 100%;
margin: 0;
padding: 0;
margin: 0px;
padding: 0px;
}
.chromeframe {
margin: 0.2em 0;
@ -240,9 +245,6 @@
/* 滚动条优化 end */
</style>
<!-- 全局配置 -->
<script>
window._CONFIG = {};
</script>
</head>
<body>
@ -251,12 +253,13 @@
<div id="loader"></div>
<div class="loader-section section-left"></div>
<div class="loader-section section-right"></div>
<div class="load_title">正在加载 科亿知识库,首次加载会比较慢,请耐心等待
<div class="load_title">正在加载系统,首次加载会比较慢,请耐心等待
</div>
</div>
</div>
</body>
<!--<script type="text/javascript" src= "{{Global_Config.ONLYOFFICE_SERVER_IP}} /web-apps/apps/api/documents/api.js"></script>-->
</html>

@ -31,7 +31,7 @@
position: absolute;
white-space: pre;
cursor: text;
transform-origin: 0 0;
transform-origin: 0% 0%;
}
.textLayer .highlight {
@ -1132,7 +1132,7 @@ html[dir="rtl"] #outerContainer.sidebarOpen #loadingBar {
position: absolute;
top: 0;
left: 0;
width: 0;
width: 0%;
height: 100%;
background-color: var(--progressBar-color);
overflow: hidden;

@ -2,6 +2,11 @@ import { getAction, deleteAction, putAction, postAction, httpAction } from '@/ap
import Vue from 'vue'
import {UI_CACHE_DB_DICT_DATA } from "@/store/mutation-types"
//获取站点信息
// const getSiteInfo = ()=>getAction("/KM/kmSysConfig/querySiteInfo");
//加载km_config
export const getAllKmConfig = ()=>getAction('/KM/kmSysConfig/listAllConfig');
//角色管理
const addRole = (params)=>postAction("/sys/role/add",params);
const editRole = (params)=>putAction("/sys/role/edit",params);

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

@ -146,3 +146,46 @@ div >.rank > .list > li > span{
}
/* 吉奥UI规范 */
/* 检索相关*/
.paramPathDiv{
display: inline-block;
margin: 3px 0px 0px 10px;
}
.paramPath{
margin :1px 0 1px 0;
padding: 0px 2px 0px 2px;
float: left;
display: inline-flex;
font-size: x-small;
border-radius:3px;
background: #D6E3F6FF;
border-style: solid;
border-width: 1px;
}
.historySearchHref{
color: #000c17;
font-weight: revert;
}
.paramPath:hover {
background-color: #ff9c00;
color: white;
border-style: solid;
border-width: 1px;
}
.paramPathTitle{
/*margin :5px 2px 5px 2px;*/
/*float: left;*/
/*display: inline;*/
font-weight: bold;
margin :2px 1px 0px 1px;
padding: 0px 1px 0px 1px;
float: left;
display: inline-flex;
}
.paramPathContainer{
display: inline-block;
margin: 0 1px 0px 1px;
padding: 1px 0 0 1px;
}

@ -1,9 +1,11 @@
<template>
<v-chart :forceFit="true" :height="height" :data="data" :scale="scale" :onClick="handleClick">
<div>{{title}}</div>
<a-divider ></a-divider>
<v-tooltip :showTitle="false" dataKey="item*percent"/>
<v-axis/>
<v-legend dataKey="item"/>
<v-pie position="percent" color="item" :v-style="pieStyle" :label="labelConfig"/>
<v-pie position="count" color="item" :v-style="pieStyle" :label="labelConfig"/>
<v-coord type="theta"/>
</v-chart>
</template>

@ -102,7 +102,7 @@ import BarMultid from '@/components/chart/BarMultid'
```json
[
{
"type": "Jeecg",
"type": "Jeecg", // 列名
"Jan.": 18.9,
"Feb.": 28.8,
"Mar.": 39.3,
@ -227,7 +227,7 @@ import LineChartMultid from '@/components/chart/LineChartMultid'
```json
[
{
"type": "Jan",
"type": "Jan", // 列名
"jeecg": 7,
"jeebt": 3.9
},
@ -264,6 +264,7 @@ import Pie from '@/components/chart/Pie'
```json
[
// 所有的 percent 相加等于 100
{ "item": "一月", "percent": 40 },
{ "item": "二月", "percent": 21 },
{ "item": "三月", "percent": 17 },
@ -291,6 +292,7 @@ import Radar from '@/components/chart/Radar'
```json
[
// score 最小值为 0最大值为 100
{ "item": "一月", "score": 40 },
{ "item": "二月", "score": 20 },
{ "item": "三月", "score": 67 },

@ -1,6 +1,7 @@
<template>
<div class="rank">
<h4 class="title">{{ title }}</h4>
<h4 class="title"><a-space><a-icon :type="icon" theme="filled" style="color: #1a53ba"></a-icon>{{ title }}</a-space></h4>
<ul class="list" :style="{height:height?`${height}px`:'auto',overflow:'auto'}">
<li :key="index" v-for="(item, index) in list">
<span :class="index < 3 ? 'active' : null">{{ index + 1 }}</span>
@ -16,6 +17,10 @@
name: "RankList",
// ['title', 'list']
props: {
icon: {
type: String,
default: ''
},
title: {
type: String,
default: ''
@ -35,15 +40,15 @@
<style lang="less" scoped>
.rank {
padding: 0 32px 32px 72px;
padding: 0 12px 16px 12px;
.list {
margin: 25px 0 0;
margin: 5px 0 0;
padding: 0;
list-style: none;
li {
margin-top: 16px;
margin-top: 6px;
span {
color: #606266;
@ -75,7 +80,7 @@
}
.mobile .rank {
padding: 0 32px 32px 32px;
padding: 0 12px 12px 12px;
}
</style>

@ -264,8 +264,8 @@
&.no-title {
.ant-modal-header {
padding: 0 12px;
border-bottom: 0 !important;
padding: 0px 12px;
border-bottom: 0px !important;
}
}
}

@ -247,8 +247,8 @@
&.no-title {
.ant-modal-header {
padding: 0 12px;
border-bottom: 0 !important;
padding: 0px 12px;
border-bottom: 0px !important;
}
}
}

@ -246,8 +246,8 @@
&.no-title {
.ant-modal-header {
padding: 0 12px;
border-bottom: 0 !important;
padding: 0px 12px;
border-bottom: 0px !important;
}
}
}

@ -6,7 +6,7 @@
:confirmLoading="uploading"
@cancel="handleClose">
<div style="margin: 0 0 5px 1px" v-if="online">
<div style="margin: 0px 0px 5px 1px" v-if="online">
<span style="display: inline-block;height: 32px;line-height: 32px;vertical-align: middle;">是否开启校验:</span>
<span style="display: inline-block;height: 32px;margin-left: 6px">
<a-switch :checked="validateStatus==1" @change="handleChangeValidateStatus" checked-children="" un-checked-children="" size="small"/>

@ -227,8 +227,8 @@
}
&.no-title{
.ant-modal-header {
padding: 0 24px;
border-bottom: 0 !important;
padding: 0px 24px;
border-bottom: 0px !important;
}
}
}

@ -2,7 +2,7 @@
<div class="drag" ref="dragDiv">
<div class="drag_bg"></div>
<div class="drag_text">{{confirmWords}}</div>
<div ref="moveDiv" @mousedown="mousedownFn($event)" :class="{'handler_ok_bg':confirmSuccess}" class="handler handler_bg" style="border: 0.5px solid #fff;height: 34px;position: absolute;top: 0;left: 0;"></div>
<div ref="moveDiv" @mousedown="mousedownFn($event)" :class="{'handler_ok_bg':confirmSuccess}" class="handler handler_bg" style="border: 0.5px solid #fff;height: 34px;position: absolute;top: 0px;left: 0px;"></div>
</div>
</template>
@ -101,11 +101,11 @@
.drag_bg{
background-color: #7ac23c;
height: 34px;
width: 0;
width: 0px;
}
.drag_text{
position: absolute;
top: 0;
top: 0px;
width: 100%;text-align: center;
-moz-user-select: none;
-webkit-user-select: none;

@ -7,7 +7,7 @@
</div>
<div style="color: #606266">
<iframe :v-show="showPDFModal" :id="iframeID" :width="iframeWidth" :height="iframeHeight">
<iframe style="border-top: none" :v-show="showPDFModal" :id="iframeID" :width="iframeWidth" :height="iframeHeight">
</iframe>
</div>
</div>
@ -67,11 +67,14 @@
let iframeID = document.querySelector("#" + this.iframeID);
getActionPDF(this.PDFurl).then((res) => {
this.pdfLoading = false;
console.log("res:",res)
//
let blobPDF = new Blob([res], {
type: `application/pdf;charset-UTF-8` // wordmsword,pdfpdf
});
iframeID.src = "/pdfjs/web/viewer.html?file="+window.URL.createObjectURL(blobPDF);
}).finally(()=>{
this.pdfLoading = false
})
}

@ -172,7 +172,7 @@ this.$refs.superQueryModal.show();
<div style="width: 100%;">
<span>{{ title }}</span>
<span style="display:inline-block;width:calc(100% - 51px);padding-right:10px;text-align: right">
<a-button @click="toggleScreen" icon="appstore" style="height:20px;width:20px;border:0"></a-button>
<a-button @click="toggleScreen" icon="appstore" style="height:20px;width:20px;border:0px"></a-button>
</span>
</div>
</template>

@ -0,0 +1,9 @@
import BJModal from './BJModal'
import PDFModal from './PDFModal'
export default {
install(Vue) {
Vue.component('BJModal',BJModal)
Vue.component('PDFModal',PDFModal)
}
}

@ -848,7 +848,7 @@
.ant-tabs-tab {
padding: 0 24px!important;
background-color: #f5f7fa!important;
margin-right: 0!important;
margin-right: 0px!important;
border-radius: 0;
line-height: 38px;
border: 1px solid transparent!important;

@ -60,6 +60,7 @@
{ key: '2', icon: 'arrow-right', text: '关闭右侧' },
{ key: '3', icon: 'close', text: '关闭其它' }
],
siteInfo:{},
reloadFlag:true
}
},
@ -81,6 +82,7 @@
}
},
created() {
this.siteInfo = this.$store.getters.siteInfo
if (this.$route.path != indexKey) {
this.addIndexToFirst()
}
@ -165,7 +167,7 @@
// update-begin-author:sunjianlei date:20200120 for:
changeTitle(title) {
let projectTitle = "科亿知识库"
let projectTitle = this.siteInfo.siteTitle //Global_Config.SITE_TITLE
//
if (this.$route.path === indexKey) {
document.title = projectTitle

@ -5,7 +5,7 @@
<div class="header">
<a href="/">
<!--<img src="~@/assets/logo.svg" class="logo" alt="logo">-->
<span class="title">科亿知识库</span>
<span class="title">{{ siteInfo.siteTitle }}</span>
</a>
</div>
</div>
@ -14,12 +14,12 @@
<div class="footer">
<div class="links">
<a href="http://www.kykms.cn" target="_blank">知识库首页</a>
<a :href= siteInfo.siteHomePageUrl target="_blank">{{ siteInfo.siteTitle }}首页</a>
</div>
<div class="copyright">
Copyright
<a-icon type="copyright"/>
2019 <span>科亿信息技术</span>
2019 <span>{{ siteInfo.siteCopyRight }}</span>
</div>
</div>
@ -36,7 +36,12 @@
components: { RouteView },
mixins: [mixinDevice],
data () {
return {}
return {
siteInfo:{}
}
},
created() {
this.siteInfo = this.$store.getters.siteInfo
},
mounted () {
document.body.classList.add('userLayout')

@ -5,6 +5,8 @@ import Vue from 'vue'
// base library
import {
BackTop,
Space,
ConfigProvider,
Layout,
Input,
@ -28,7 +30,7 @@ import {
List,
Avatar,
Breadcrumb,
Steps,
// Steps,
Spin,
Menu,
Drawer,
@ -39,13 +41,13 @@ import {
DatePicker,
TimePicker,
Upload,
Progress,
Skeleton,
// Progress,
// Skeleton,
Popconfirm,
PageHeader,
Result,
Statistic,
Descriptions,
// Result,
// Statistic,
// Descriptions,
message,
notification,
Empty,
@ -54,14 +56,16 @@ import {
Carousel,
Pagination,
FormModel,
Cascader,
Slider,
Transfer,
// Cascader,
// Slider,
// Transfer,
Rate,
Collapse,
// Collapse,
} from 'ant-design-vue'
import Viser from 'viser-vue'
Vue.use(BackTop)
Vue.use(Space)
Vue.use(ConfigProvider)
Vue.use(Layout)
Vue.use(Input)
@ -85,7 +89,7 @@ Vue.use(Dropdown)
Vue.use(List)
Vue.use(Avatar)
Vue.use(Breadcrumb)
Vue.use(Steps)
// Vue.use(Steps)
Vue.use(Spin)
Vue.use(Menu)
Vue.use(Drawer)
@ -96,24 +100,24 @@ Vue.use(Divider)
Vue.use(DatePicker)
Vue.use(TimePicker)
Vue.use(Upload)
Vue.use(Progress)
Vue.use(Skeleton)
// Vue.use(Progress)
// Vue.use(Skeleton)
Vue.use(Popconfirm)
Vue.use(PageHeader)
Vue.use(Result)
Vue.use(Statistic)
Vue.use(Descriptions)
// Vue.use(Result)
// Vue.use(Statistic)
// Vue.use(Descriptions)
Vue.use(Empty)
Vue.use(Tree)
Vue.use(TreeSelect)
Vue.use(Carousel)
Vue.use(Pagination)
Vue.use(FormModel)
Vue.use(Cascader)
Vue.use(Slider)
Vue.use(Transfer)
// Vue.use(Cascader)
// Vue.use(Slider)
// Vue.use(Transfer)
Vue.use(Rate)
Vue.use(Collapse)
// Vue.use(Collapse)
Vue.prototype.$confirm = Modal.confirm
Vue.prototype.$message = message

@ -1,26 +1,34 @@
<template>
<div class="footer">
<div class="links">
<a href="http://www.kykms.cn" target="_blank">知识库首页</a>
<a :href= siteInfo.siteHomePageUrl target="_blank">{{ siteInfo.siteTitle }}首页</a>
</div>
<div class="copyright">
Copyright
<a-icon type="copyright"/>
2021 <span>科亿信息技术</span>
2019 <span>{{ siteInfo.siteCopyRight }}</span>
</div>
</div>
</template>
<script>
export default {
name: "LayoutFooter"
name: "LayoutFooter",
data () {
return {
siteInfo:{}
}
},
created() {
this.siteInfo = this.$store.getters.siteInfo
},
}
</script>
<style lang="less" scoped>
.footer {
padding: 0 16px;
margin: 48px 0 24px;
padding: 16px;
margin: 20px 0 0 0;
text-align: center;
.links {
@ -30,7 +38,7 @@
color: rgba(0, 0, 0, .45);
&:hover {
color: rgba(0, 0, 0, .65);
color: darkorange;
}
&:not(:last-child) {

@ -19,6 +19,7 @@
<span >{{this.$route.meta.title}}</span>
<!-- <user-menu class="menu-txt"/>-->
<user-menu class="header-index-right" :theme="theme" :style="topMenuStyle.headerIndexRight"/>
</div>
<!-- 顶部导航栏模式 -->
@ -40,6 +41,7 @@
:type="collapsed ? 'menu-fold' : 'menu-unfold'"
@click="toggle"></a-icon>
</div>
<!-- <user-menu class="menu-txt"/>-->
<user-menu class="header-index-right" :theme="theme" :style="topMenuStyle.headerIndexRight"/>
</div>
</div>

File diff suppressed because it is too large Load Diff

@ -122,6 +122,6 @@
margin-top: 48px;
}
.page-header[data-v-6740ec88] {
margin: 0 24px 0;
margin: 0px 24px 0;
}
</style>

@ -286,8 +286,8 @@
float: left;
cursor: pointer;
margin-right: 8px;
padding-left: 0;
padding-right: 0;
padding-left: 0px;
padding-right: 0px;
text-align: center;
color: #fff;
font-weight: 700;

@ -0,0 +1,121 @@
<template>
<div class="user-wrapper" >
<a-dropdown>
<span class="action action-full ant-dropdown-link user-dropdown-menu"
style="line-height: 64px; height: 60px;color: #000c17;padding: 0px 20px;margin: 0">
<span style="margin: 0;padding-right: 10px;color: white">
<a-icon type="menu"/>
快捷菜单
</span>
</span>
<a-menu slot="overlay" class="user-dropdown-menu-wrapper">
<a-menu-item key="1" @click="jumpKmDocFavouritePage">
<a-icon type="star"/>
<span>我的收藏</span>
</a-menu-item>
<a-menu-item key="2" @click="jumpDraftsPage">
<a-icon type="home"/>
<span>我的知识</span>
</a-menu-item>
<a-menu-item key="3">
<a href="javascript:;" @click="jumpKmDashBoard">
<a-icon type="chrome"/>
<span>统计数据</span>
</a>
</a-menu-item>
</a-menu>
</a-dropdown>
<!-- <user-password ref="userPassword"></user-password>-->
</div>
</template>
<script>
import { mixinDevice } from '@/utils/mixin.js'
import Vue from 'vue'
import { ACCESS_TOKEN } from '@/store/mutation-types'
export default {
name: 'FilesMenu',
mixins: [mixinDevice],
data() {
return {
token:''
}
},
created() {
this.token = Vue.ls.get(ACCESS_TOKEN)
},
methods: {
jumpKmDocFavouritePage() {
let token = this.token
if (token === '' || token === null) {
this.$router.push('/front/user/login')
} else {
let routeData = this.$router.resolve({
path: '/km/filemanagement/KmDocFavouriteList',
query: {}
})
window.open(routeData.href, '_blank')
}
},
jumpKmDashBoard() {
let token = this.token
if (token === '' || token === null) {
this.$router.push('/front/user/login')
} else {
let routeData = this.$router.resolve({
path: '/dashboard/Analysis',
query: {}
})
window.open(routeData.href, '_blank')
}
},
// 稿
jumpDraftsPage() {
let token = this.token
if (token == '' || token == null) {
this.$router.push('/front/user/login')
} else {
let routeData = this.$router.resolve({
path: '/km/filemanagement/FilesList',
query: {}
})
window.open(routeData.href, '_blank')
}
},
}
}
</script>
<style lang="less" scoped>
/* update_begin author:zhaoxin date:20191129 for: 让搜索框颜色能随主题颜色变换*/
/* update-begin author:sunjianlei date:20191220 for: 解决全局样式冲突问题 */
.user-wrapper .search-input {
width: 180px;
color: inherit;
/deep/ .ant-select-selection {
background-color: inherit;
border: 0;
border-bottom: 1px solid white;
&__placeholder, &__field__placeholder {
color: inherit;
}
}
}
/* update-end author:sunjianlei date:20191220 for: 解决全局样式冲突问题 */
/* update_end author:zhaoxin date:20191129 for: 让搜索框颜色能随主题颜色变换*/
</style>
<style scoped>
.logout_title {
color: inherit;
text-decoration: none;
}
</style>

@ -32,7 +32,7 @@
<a-list-item :key="index" v-for="(record, index) in announcement1">
<div style="margin-left: 5%;width: 80%">
<p><a @click="showAnnouncement(record)">{{ record.titile }}</a></p>
<p style="color: rgba(0,0,0,.45);margin-bottom: 0">{{ record.createTime }} 发布</p>
<p style="color: rgba(0,0,0,.45);margin-bottom: 0px">{{ record.createTime }} 发布</p>
</div>
<div style="text-align: right">
<a-tag @click="showAnnouncement(record)" v-if="record.priority === 'L'" color="blue"></a-tag>
@ -50,7 +50,7 @@
<a-list-item :key="index" v-for="(record, index) in announcement2">
<div style="margin-left: 5%;width: 80%">
<p><a @click="showAnnouncement(record)">{{ record.titile }}</a></p>
<p style="color: rgba(0,0,0,.45);margin-bottom: 0">{{ record.createTime }} 发布</p>
<p style="color: rgba(0,0,0,.45);margin-bottom: 0px">{{ record.createTime }} 发布</p>
</div>
<div style="text-align: right">
<a-tag @click="showAnnouncement(record)" v-if="record.priority === 'L'" color="blue"></a-tag>
@ -198,7 +198,7 @@
initWebSocket: function () {
// WebSocketwshttpwsshttps
var userId = store.getters.userInfo.id;
var userId = this.$store.getters.userInfo.id;
var url = window._CONFIG['domianURL'].replace("https://","wss://").replace("http://","ws://")+"/websocket/"+userId;
//console.log(url);
this.websock = new WebSocket(url);

@ -1,19 +1,15 @@
<template>
<div class="logo">
<router-link :to="{name:'defaultDocSearch'}">
<!-- update-begin- author:sunjianlei --- date:20190814 --- for: logo颜色根据主题颜色变化 -->
<img v-if="navTheme === 'dark'" src="~@/assets/logo-white.png" alt="logo">
<img v-else src="~@/assets/logo.svg" alt="logo">
<!-- update-begin- author:sunjianlei --- date:20190814 --- for: logo颜色根据主题颜色变化 -->
<span v-if="showTitle" class="showTitle">{{ title }}</span>
</router-link>
<a @click="jumIndex">
<img :src = siteInfo.siteAvatar alt="logo">
<span v-if="showTitle" class="showTitle">{{ siteInfo.siteTitle }}</span>
</a>
</div>
</template>
<script>
import { mixin } from '@/utils/mixin.js'
import Vue from 'vue'
export default {
name: 'Logo',
@ -21,7 +17,7 @@
props: {
title: {
type: String,
default: '科亿知识库',
default: "科亿知识库",
required: false
},
showTitle: {
@ -29,6 +25,28 @@
default: true,
required: false
}
},
data () {
return {
siteInfo: {},
kmConfig: {},
indexUrl:'/front/DefaultDocSearch'
}
},
created() {
this.siteInfo = this.$store.getters.siteInfo
this.kmConfig = this.$store.getters.kmConfig
if(this.kmConfig !== undefined && this.kmConfig.DefaultPageUseTopicList === '1')
this.indexUrl = '/front/RecommendTopicList'
},
methods:{
jumIndex(){
let routeData = this.$router.resolve({
path: this.indexUrl,
query: {}
})
window.open(routeData.href, '_blank')
}
}
}
</script>
@ -41,8 +59,6 @@
font-weight: 600;
}
.sider {
box-shadow: none !important;
.logo {

@ -1,5 +1,5 @@
<template>
<div class="user-wrapper" :class="theme">
<div class="user-wrapper user-menu-dropdown" :class="theme">
<a-dropdown>
<span class="action action-full ant-dropdown-link user-dropdown-menu">
<!-- <a-avatar class="avatar" size="small" :src="getAvatar()"/>-->
@ -27,6 +27,12 @@
<span>退出登录</span>
</a>
</a-menu-item>
<!--<a-menu-item key="3" @click="systemSetting">-->
<!--<a-icon type="tool"/>-->
<!--<span>系统设置</span>-->
<!--</a-menu-item>-->
</a-menu>
</a-dropdown>
<user-password ref="userPassword"></user-password>
@ -134,7 +140,7 @@
onOk() {
return that.Logout({}).then(() => {
// update-begin author:wangshuai date:20200601 for: 退
that.$router.push({ path: '/user/login' });
that.$router.push({ path: '/front/user/login' });
window.location.reload()
// update-end author:wangshuai date:20200601 for: 退
}).catch(err => {
@ -238,4 +244,8 @@
color: inherit;
text-decoration: none;
}
.user-dropdown-menu{
line-height:64px!important;
background: darkorange;
}
</style>

@ -1,7 +1,7 @@
/** init domain config */
import Vue from 'vue'
//设置全局API_BASE_URL
Vue.prototype.API_BASE_URL = process.env.VUE_APP_API_BASE_URL
Vue.prototype.API_BASE_URL = Global_Config.API_BASE_URL? Global_Config.API_BASE_URL:process.env.VUE_APP_API_BASE_URL
window._CONFIG['domianURL'] = Vue.prototype.API_BASE_URL
//单点登录地址
window._CONFIG['casPrefixUrl'] = process.env.VUE_APP_CAS_BASE_URL

@ -39,25 +39,80 @@ export const constantRouterMap = [
},
]
},
{
path: '/404',
component: () => import(/* webpackChunkName: "fail" */ '@/views/exception/404')
},
// {
// path: '/defaultDocSearch',
// name:'defaultDocSearch',
// meta: { title: '首页' },
// component: () => import('@/views/km/search/DefaultDocSearch')
// },
// {
// path:'/advancedSearch',
// name:'advancedSearch',
// meta: { title: '高级检索' },
// component: () => import('@/views/km/search/AdvancedSearch')
// },
// {
// path:'/docSearch',
// name:'docSearch',
// meta: { title: '检索结果' },
// component: () => import('@/views/km/search/DocSearch')
// },
// {
// path:'/RecommendTopicList',
// name:'recommendTopicList',
// meta: { title: '知识专题' },
// component: () => import('@/views/km/search/RecommendTopicList')
// },
// {
// path:'/login',
// component: () => import('@/views/km/search/Login')
// },
{
path: '/draftDocEdit',
component: () => import('@/views/km/filemanagement/modules/DraftDocEdit')
},
//front
{
path: '/defaultDocSearch',
path: '/front/user',
name: 'frontLogin',
component: UserLayout,
redirect: '/front/user/login',
hidden: true,
children: [
{
path: 'login',
name: 'login',
component: () => import(/* webpackChunkName: "user" */ '@/views/user/Login')
},
]
},
{
path: '/front/defaultDocSearch',
name:'defaultDocSearch',
meta: { title: '首页' ,keepAlive: true },
component: () => import('@/views/km/search/DefaultDocSearch')
meta: { title: '首页' ,keepAlive: true},
component: () => import(/* webpackChunkName: "Home" */ '@/views/km/search/DefaultDocSearch')
},
{
path:'/docSearch',
path:'/front/advancedSearch',
name:'advancedSearch',
meta: { title: '高级检索',keepAlive: true },
component: () => import('@/views/km/search/AdvancedSearch')
},
{
path:'/front/docSearch',
name:'docSearch',
meta: { title: '检索结果' },
meta: { title: '检索结果' ,keepAlive: true},
component: () => import('@/views/km/search/DocSearch')
},
{
path:'/login',
component: () => import('@/views/km/search/Login')
}
path:'/front/RecommendTopicList',
name:'recommendTopicList',
meta: { title: '知识专题' ,keepAlive: true},
component: () => import('@/views/km/search/RecommendTopicList')
},
]

@ -0,0 +1,105 @@
/** init domain config */
import './config'
import Vue from 'vue'
import App from './App.vue'
import Storage from 'vue-ls'
import router from './router'
import store from './store/'
import { VueAxios } from "@/utils/request"
require('@jeecg/antd-online-mini')
require('@jeecg/antd-online-mini/dist/OnlineForm.css')
// import '@/components/lazy_antd'
import Antd from 'ant-design-vue'
import Viser from 'viser-vue'
import 'ant-design-vue/dist/antd.less'; // or 'ant-design-vue/dist/antd.less'
import '@/permission' // permission control
import '@/utils/filter' // base filter
import Print from 'vue-print-nb-jeecg'
import preview from 'vue-photo-preview'
import 'vue-photo-preview/dist/skin.css'
import SSO from '@/cas/sso.js'
import {
ACCESS_TOKEN,
DEFAULT_COLOR,
DEFAULT_THEME,
DEFAULT_LAYOUT_MODE,
DEFAULT_COLOR_WEAK,
SIDEBAR_TYPE,
DEFAULT_FIXED_HEADER,
DEFAULT_FIXED_HEADER_HIDDEN,
DEFAULT_FIXED_SIDEMENU,
DEFAULT_CONTENT_WIDTH_TYPE,
DEFAULT_MULTI_PAGE
} from "@/store/mutation-types"
import config from '@/defaultSettings'
import JDictSelectTag from './components/dict/index.js'
import hasPermission from '@/utils/hasPermission'
import vueBus from '@/utils/vueBus';
import JeecgComponents from '@/components/jeecg/index'
import '@/assets/less/JAreaLinkage.less'
// import VueAreaLinkage from 'vue-area-linkage'
import '@/components/jeecg/JVxeTable/install'
import '@/components/JVxeCells/install'
//表单验证
import { rules } from '@/utils/rules'
Vue.prototype.rules = rules
Vue.config.productionTip = false
Vue.use(Storage, config.storageOptions)
Vue.use(Antd)
Vue.use(VueAxios, router)
Vue.use(Viser)
Vue.use(hasPermission)
Vue.use(JDictSelectTag)
Vue.use(Print)
Vue.use(preview)
Vue.use(vueBus);
Vue.use(JeecgComponents);
// Vue.use(VueAreaLinkage);
SSO.init(() => {
main()
})
function main() {
new Vue({
router,
store,
mounted () {
getSiteInfo()
store.commit('SET_SIDEBAR_TYPE', Vue.ls.get(SIDEBAR_TYPE, true))
store.commit('TOGGLE_THEME', Vue.ls.get(DEFAULT_THEME, config.navTheme))
store.commit('TOGGLE_LAYOUT_MODE', Vue.ls.get(DEFAULT_LAYOUT_MODE, config.layout))
store.commit('TOGGLE_FIXED_HEADER', Vue.ls.get(DEFAULT_FIXED_HEADER, config.fixedHeader))
store.commit('TOGGLE_FIXED_SIDERBAR', Vue.ls.get(DEFAULT_FIXED_SIDEMENU, config.fixSiderbar))
store.commit('TOGGLE_CONTENT_WIDTH', Vue.ls.get(DEFAULT_CONTENT_WIDTH_TYPE, config.contentWidth))
store.commit('TOGGLE_FIXED_HEADER_HIDDEN', Vue.ls.get(DEFAULT_FIXED_HEADER_HIDDEN, config.autoHideHeader))
store.commit('TOGGLE_WEAK', Vue.ls.get(DEFAULT_COLOR_WEAK, config.colorWeak))
store.commit('TOGGLE_COLOR', Vue.ls.get(DEFAULT_COLOR, config.primaryColor))
store.commit('SET_TOKEN', Vue.ls.get(ACCESS_TOKEN))
store.commit('SET_MULTI_PAGE',Vue.ls.get(DEFAULT_MULTI_PAGE,config.multipage))
},
render: h => h(App)
}).$mount('#app')
}
function getSiteInfo(){
store.dispatch('GetSiteInfo').then(res => {
//this.departConfirm(res)
if(res.success){
console.log("GetSiteInfo Success.")
}else{
console.log("GetSiteInfo fail...............")
}
}).catch((err) => {
// console.log(err);
//that.requestFailed(err);
});
}

@ -11,8 +11,8 @@ import { VueAxios } from "@/utils/request"
require('@jeecg/antd-online-mini')
require('@jeecg/antd-online-mini/dist/OnlineForm.css')
import Antd, { version } from 'ant-design-vue'
console.log('ant-design-vue version:', version)
// import '@/components/lazy_antd'
import Antd from 'ant-design-vue'
import Viser from 'viser-vue'
import 'ant-design-vue/dist/antd.less'; // or 'ant-design-vue/dist/antd.less'
@ -43,7 +43,7 @@ import hasPermission from '@/utils/hasPermission'
import vueBus from '@/utils/vueBus';
import JeecgComponents from '@/components/jeecg/index'
import '@/assets/less/JAreaLinkage.less'
import VueAreaLinkage from 'vue-area-linkage'
// import VueAreaLinkage from 'vue-area-linkage'
import '@/components/jeecg/JVxeTable/install'
import '@/components/JVxeCells/install'
//表单验证
@ -60,8 +60,7 @@ Vue.use(Print)
Vue.use(preview)
Vue.use(vueBus);
Vue.use(JeecgComponents);
Vue.use(VueAreaLinkage);
// Vue.use(VueAreaLinkage);
SSO.init(() => {
main()
})
@ -70,6 +69,7 @@ function main() {
router,
store,
mounted () {
getSiteInfo()
store.commit('SET_SIDEBAR_TYPE', Vue.ls.get(SIDEBAR_TYPE, true))
store.commit('TOGGLE_THEME', Vue.ls.get(DEFAULT_THEME, config.navTheme))
store.commit('TOGGLE_LAYOUT_MODE', Vue.ls.get(DEFAULT_LAYOUT_MODE, config.layout))
@ -81,7 +81,23 @@ function main() {
store.commit('TOGGLE_COLOR', Vue.ls.get(DEFAULT_COLOR, config.primaryColor))
store.commit('SET_TOKEN', Vue.ls.get(ACCESS_TOKEN))
store.commit('SET_MULTI_PAGE',Vue.ls.get(DEFAULT_MULTI_PAGE,config.multipage))
},
render: h => h(App)
}).$mount('#app')
}
function getSiteInfo(){
store.dispatch('GetSiteInfo').then(res => {
//this.departConfirm(res)
if(res.success){
console.log("GetSiteInfo Success.")
}else{
console.log("GetSiteInfo fail...............")
}
}).catch((err) => {
console.log(err);
//that.requestFailed(err);
});
}

@ -9,14 +9,13 @@ import { generateIndexRouter } from "@/utils/util"
NProgress.configure({ showSpinner: false }) // NProgress Configuration
const whiteList = ['/user/login', '/user/register', '/user/register-result','/user/alteration','/login',] // no redirect whitelist
const whiteList = ['/user/login','/front/user/login', '/user/register', '/user/register-result','/user/alteration','/login',] // no redirect whitelist
router.beforeEach((to, from, next) => {
NProgress.start() // start progress bar
if (Vue.ls.get(ACCESS_TOKEN)) {
/* has token */
if (to.path === '/user/login') {
if (to.path === '/user/login' || to.path === '/front/user/login' || to.path == '/') {
next({ path: INDEX_MAIN_PAGE_PATH })
NProgress.done()
} else {
@ -51,8 +50,8 @@ router.beforeEach((to, from, next) => {
description: '请求用户信息失败,请重试!'
})*/
store.dispatch('Logout').then(() => {
next({path:'/user/login'});
// next({ path: '/user/login', query: { redirect: to.fullPath } })
// next({path:'/user/login'});
next({ path: '/user/login', query: { redirect: to.fullPath } })
})
})
} else {
@ -66,8 +65,8 @@ router.beforeEach((to, from, next) => {
} else {
// 调整没有token重定向问题默认为系统内登录
// 第三方登录为 /login
next({path:'/user/login'});
// next({ path: '/user/login', query: { redirect: to.fullPath } })
// next({path:'/user/login'});
next({ path: '/front/user/login', query: { redirect: to.fullPath } })
NProgress.done() // if current page is login will not trigger afterEach hook, so manually handle it
}
}

@ -1,6 +1,8 @@
import Vue from 'vue'
import { USER_INFO, ENHANCE_PRE } from "@/store/mutation-types"
import {USER_INFO, ENHANCE_PRE, SITE_INFO} from "@/store/mutation-types"
const getters = {
kmConfig: state => state.site.kmConfig,
siteInfo: state => state.site.siteInfo ,
device: state => state.app.device,
theme: state => state.app.theme,
color: state => state.app.color,

@ -7,6 +7,7 @@ import permission from './modules/permission'
import enhance from './modules/enhance'
import online from './modules/online'
import getters from './getters'
import site from './modules/site'
Vue.use(Vuex)
@ -16,7 +17,8 @@ export default new Vuex.Store({
user,
permission,
enhance,
online
online,
site
},
state: {

@ -0,0 +1,72 @@
import Vue from 'vue'
import {getAllKmConfig} from '@/api/api'
import {KM_ALL_CONFIG, SITE_INFO, USER_INFO} from '@/store/mutation-types'
import siteLogo from '@assets/logo.png'
import siteBannerLogo from '@assets/km_logo.png'
import { getFileAccessHttpUrl } from '@api/manage'
const site = {
state: {
siteInfo: {
siteTitle: '科亿知识库',
siteHomePageUrl: 'http://www.kykms.cn',
siteCopyRight: '科亿信息技术',
siteAvatar: siteLogo,
siteTitleBanner: siteBannerLogo
},
kmConfig: {
DefaultPageUseTopicList: '0',
HeaderBackgroundColor: '#001529'
}
},
mutations: {
SET_KMCONFIG: (state, config) => {
state.kmConfig = config
Vue.prototype.kmConfig = config
Vue.ls.set(KM_ALL_CONFIG, config, 7 * 24 * 60 * 60 * 1000)
},
SET_SITE_INFO: (state, siteInfo) => {
state.siteInfo.siteTitle = siteInfo.siteTitle !== undefined && siteInfo.siteTitle !== null? siteInfo.siteTitle : state.siteInfo.siteTitle
state.siteInfo.siteHomePageUrl = siteInfo.siteHomePageUrl !== undefined && siteInfo.siteHomePageUrl !== null ? siteInfo.siteHomePageUrl : state.siteInfo.siteHomePageUrl
state.siteInfo.siteCopyRight = siteInfo.siteCopyRight !== undefined && siteInfo.siteCopyRight !== null? siteInfo.siteCopyRight : state.siteInfo.siteCopyRight
state.siteInfo.siteAvatar = siteInfo.siteAvatar !== '' && siteInfo.siteAvatar !== undefined && siteInfo.siteAvatar !== null? getFileAccessHttpUrl(siteInfo.siteAvatar) : state.siteInfo.siteAvatar
state.siteInfo.siteTitleBanner = siteInfo.siteTitleBanner !== '' && siteInfo.siteTitleBanner !== undefined && siteInfo.siteTitleBanner !== null? getFileAccessHttpUrl(siteInfo.siteTitleBanner) : state.siteInfo.siteTitleBanner
Vue.ls.set(SITE_INFO, state.siteInfo, 7 * 24 * 60 * 60 * 1000)
}
},
actions: {
GetSiteInfo({ commit }) {
return new Promise((resolve, reject) => {
getAllKmConfig().then(response => {
let siteInfo = {}
console.log("----getSiteInfo--------",response);
if(response.success){
let result = response.result
console.log('result:',result)
commit('SET_KMCONFIG', result)
if(result !== null && result !== undefined ){
siteInfo.siteTitle = result['SiteTitle']
siteInfo.siteHomePageUrl = result['SiteHomePageUrl']
siteInfo.siteCopyRight = result['SiteCopyRight']
siteInfo.siteAvatar = result['SiteAvatar']
siteInfo.siteTitleBanner = result['SiteTitleBanner']
}
console.log("----siteInfo--------",siteInfo)
commit('SET_SITE_INFO', siteInfo)
// Vue.ls.set(SITE_INFO, siteInfo, 7 * 24 * 60 * 60 * 1000)
resolve(response)
}else{
resolve(response)
}
}).catch(error => {
reject(error)
})
})
}
}
}
export default site

@ -1,7 +1,7 @@
import Vue from 'vue'
import { login, logout, phoneLogin, thirdLogin ,loginFun} from "@/api/login"
import { ACCESS_TOKEN, USER_NAME,USER_INFO,USER_AUTH,SYS_BUTTON_AUTH,UI_CACHE_DB_DICT_DATA,TENANT_ID,CACHE_INCLUDED_ROUTES } from "@/store/mutation-types"
import { welcome } from "@/utils/util"
// import { welcome } from "@/utils/util"
import { queryPermissionsByUser } from '@/api/api'
import { getAction } from '@/api/manage'
@ -21,10 +21,10 @@ const user = {
SET_TOKEN: (state, token) => {
state.token = token
},
SET_NAME: (state, { username, realname, welcome }) => {
SET_NAME: (state, { username, realname }) => {
state.username = username
state.realname = realname
state.welcome = welcome
// state.welcome = welcome
},
SET_AVATAR: (state, avatar) => {
state.avatar = avatar
@ -54,7 +54,7 @@ const user = {
Vue.ls.set(USER_INFO, userInfo, 7 * 24 * 60 * 60 * 1000)
commit('SET_TOKEN', result.token)
commit('SET_INFO', userInfo)
commit('SET_NAME', { username: userInfo.username,realname: userInfo.realname, welcome: welcome() })
commit('SET_NAME', { username: userInfo.username,realname: userInfo.realname })
commit('SET_AVATAR', userInfo.avatar)
resolve(response)
}else{
@ -78,7 +78,7 @@ const user = {
Vue.ls.set(UI_CACHE_DB_DICT_DATA, result.sysAllDictItems, 7 * 24 * 60 * 60 * 1000)
commit('SET_TOKEN', result.token)
commit('SET_INFO', userInfo)
commit('SET_NAME', { username: userInfo.username,realname: userInfo.realname, welcome: welcome() })
commit('SET_NAME', { username: userInfo.username,realname: userInfo.realname })
commit('SET_AVATAR', userInfo.avatar)
resolve(response)
}else{
@ -103,7 +103,7 @@ const user = {
Vue.ls.set(UI_CACHE_DB_DICT_DATA, result.sysAllDictItems, 7 * 24 * 60 * 60 * 1000)
commit('SET_TOKEN', result.token)
commit('SET_INFO', userInfo)
commit('SET_NAME', { username: userInfo.username,realname: userInfo.realname, welcome: welcome() })
commit('SET_NAME', { username: userInfo.username,realname: userInfo.realname })
commit('SET_AVATAR', userInfo.avatar)
resolve(response)
}else{
@ -129,7 +129,7 @@ const user = {
Vue.ls.set(UI_CACHE_DB_DICT_DATA, result.sysAllDictItems, 7 * 24 * 60 * 60 * 1000)
commit('SET_TOKEN', result.token)
commit('SET_INFO', userInfo)
commit('SET_NAME', { username: userInfo.username,realname: userInfo.realname, welcome: welcome() })
commit('SET_NAME', { username: userInfo.username,realname: userInfo.realname })
commit('SET_AVATAR', userInfo.avatar)
resolve(response)
}else{
@ -211,7 +211,7 @@ const user = {
Vue.ls.set(USER_INFO, userInfo, 7 * 24 * 60 * 60 * 1000)
commit('SET_TOKEN', result.token)
commit('SET_INFO', userInfo)
commit('SET_NAME', { username: userInfo.username,realname: userInfo.realname, welcome: welcome() })
commit('SET_NAME', { username: userInfo.username,realname: userInfo.realname })
commit('SET_AVATAR', userInfo.avatar)
resolve(response)
}else{

@ -16,7 +16,7 @@ export const SYS_BUTTON_AUTH = 'SYS_BUTTON_AUTH'
export const ENCRYPTED_STRING = 'ENCRYPTED_STRING'
export const ENHANCE_PRE = 'enhance_'
export const UI_CACHE_DB_DICT_DATA = 'UI_CACHE_DB_DICT_DATA'
export const INDEX_MAIN_PAGE_PATH = '/defaultDocSearch'
export const INDEX_MAIN_PAGE_PATH = '/front/defaultDocSearch'
export const TENANT_ID = 'TENANT_ID'
export const ONL_AUTH_FIELDS = 'ONL_AUTH_FIELDS'
//路由缓存问题关闭了tab页时再打开就不刷新 #842
@ -24,4 +24,6 @@ export const CACHE_INCLUDED_ROUTES = 'CACHE_INCLUDED_ROUTES'
export const CONTENT_WIDTH_TYPE = {
Fluid: 'Fluid',
Fixed: 'Fixed'
}
}
export const SITE_INFO = 'Site_Info'
export const KM_ALL_CONFIG = 'KM_All_Config'

@ -127,9 +127,10 @@ service.interceptors.request.use(config => {
service.interceptors.response.use((response) => {
if (response.config.responseType === "blob") {
let subUrl = response.config.url.substring(response.config.url.length - 13)
// let subUrl = response.config.url.substring(response.config.url.length - 13)
// 自定义判断请求路径可以拿到headers的值
if (subUrl === 'downloadKmDoc') {
if (response.config.url.substring(response.config.url.length - 13) === 'downloadKmDoc'
|| response.config.url.substring(response.config.url.length - 12) === 'downloadById' ) {
return response
}
}

@ -1,6 +1,6 @@
import * as api from '@/api/api'
import { isURL } from '@/utils/validate'
import onlineCommons from '@jeecg/antd-online-mini'
// import onlineCommons from '@jeecg/antd-online-mini'
export function timeFix() {
const time = new Date()
@ -115,28 +115,29 @@ function generateChildRouters (data) {
item.meta.url = URL;
}
let componentPath
if(item.component=="modules/online/cgform/OnlCgformHeadList"){
componentPath = onlineCommons.OnlCgformHeadList
}else if(item.component=="modules/online/cgform/OnlCgformCopyList"){
componentPath = onlineCommons.OnlCgformCopyList
}else if(item.component=="modules/online/cgform/auto/OnlCgformAutoList"){
componentPath = onlineCommons.OnlCgformAutoList
}else if(item.component=="modules/online/cgform/auto/OnlCgformTreeList"){
componentPath = onlineCommons.OnlCgformTreeList
}else if(item.component=="modules/online/cgform/auto/erp/OnlCgformErpList"){
componentPath = onlineCommons.OnlCgformErpList
}else if(item.component=="modules/online/cgform/auto/tab/OnlCgformTabList"){
componentPath = onlineCommons.OnlCgformTabList
}else if(item.component=="modules/online/cgform/auto/innerTable/OnlCgformInnerTableList"){
componentPath = onlineCommons.OnlCgformInnerTableList
}else if(item.component=="modules/online/cgreport/OnlCgreportHeadList"){
componentPath = onlineCommons.OnlCgreportHeadList
}else if(item.component=="modules/online/cgreport/auto/OnlCgreportAutoList"){
componentPath = onlineCommons.OnlCgreportAutoList
}else{
componentPath = resolve => require(['@/' + component+'.vue'], resolve)
}
let componentPath= resolve => require(['@/' + component+'.vue'], resolve)
// let componentPath
// if(item.component=="modules/online/cgform/OnlCgformHeadList"){
// componentPath = onlineCommons.OnlCgformHeadList
// }else if(item.component=="modules/online/cgform/OnlCgformCopyList"){
// componentPath = onlineCommons.OnlCgformCopyList
// }else if(item.component=="modules/online/cgform/auto/OnlCgformAutoList"){
// componentPath = onlineCommons.OnlCgformAutoList
// }else if(item.component=="modules/online/cgform/auto/OnlCgformTreeList"){
// componentPath = onlineCommons.OnlCgformTreeList
// }else if(item.component=="modules/online/cgform/auto/erp/OnlCgformErpList"){
// componentPath = onlineCommons.OnlCgformErpList
// }else if(item.component=="modules/online/cgform/auto/tab/OnlCgformTabList"){
// componentPath = onlineCommons.OnlCgformTabList
// }else if(item.component=="modules/online/cgform/auto/innerTable/OnlCgformInnerTableList"){
// componentPath = onlineCommons.OnlCgformInnerTableList
// }else if(item.component=="modules/online/cgreport/OnlCgreportHeadList"){
// componentPath = onlineCommons.OnlCgreportHeadList
// }else if(item.component=="modules/online/cgreport/auto/OnlCgreportAutoList"){
// componentPath = onlineCommons.OnlCgreportAutoList
// }else{
// componentPath = resolve => require(['@/' + component+'.vue'], resolve)
// }
let menu = {
path: item.path,

@ -1,21 +1,21 @@
<template>
<div>
<index-chart v-if="indexStyle==1"></index-chart>
<index-km-chart ></index-km-chart>
</div>
</template>
<script>
import IndexChart from './IndexChart'
import IndexKmChart from './IndexKmChart'
export default {
name: "Analysis",
components: {
IndexChart,
IndexKmChart,
},
data() {
return {
indexStyle:1
}
},
created() {

@ -0,0 +1,308 @@
<template>
<div class="page-header-index-wide">
<a-row :gutter="24">
<a-col :sm="24" :md="12" :xl="12" :style="{ marginBottom: '24px' }">
<a-card >
<a-space>
<a-icon type="home" theme="filled" style="color: #1a53ba"></a-icon>
<span style="font-size: small">知识总数: </span> <span style="font-size: large;font-weight: bold">{{kmTotalAmount |numberFormat}}</span>
</a-space>
</a-card>
</a-col>
<a-col :sm="24" :md="12" :xl="12" :style="{ marginBottom: '24px' }">
<a-card>
<a-space>
<a-icon type="folder" theme="filled" style="color: #1a53ba"></a-icon>
<span style="font-size: small">存储使用: </span> <span style="font-size: large;font-weight: bold">{{spaceTotal}}</span>
</a-space>
</a-card>
</a-col>
</a-row>
<a-row :gutter="24">
<a-col :sm="24" :md="12" :xl="12" :style="{ marginBottom: '24px' }">
<a-card >
<pie title="分类数量占比" :data-source="categoryAmount">
</pie>
</a-card>
</a-col>
<a-col :sm="24" :md="12" :xl="12" :style="{ marginBottom: '24px' }">
<a-card >
<pie title="分类空间占比" :data-source="categorySpace">
</pie>
</a-card>
</a-col>
</a-row>
<a-row :gutter="24">
<a-col :sm="24" :md="12" :xl="12" :style="{ marginBottom: '24px' }">
<a-card>
<rank-list title="热词榜" icon="fire" :list="rankListKeyword"/>
</a-card>
</a-col>
<a-col :sm="24" :md="12" :xl="12" :style="{ marginBottom: '24px' }">
<a-card>
<rank-list title="热门专题榜" icon="fire" :list="rankListTopic"/>
</a-card>
</a-col>
</a-row>
<a-card :loading="loading" :bordered="false" :body-style="{padding: '0'}">
<div class="salesCard">
<a-tabs default-active-key="1" size="large" :tab-bar-style="{marginBottom: '24px', paddingLeft: '16px'}">
<a-tab-pane loading="true" tab="专题数量统计" key="1">
<a-row>
<a-col :xl="16" :lg="12" :md="12" :sm="24" :xs="24">
<bar :dataSource="topicAmount"/>
</a-col>
</a-row>
</a-tab-pane>
<a-tab-pane tab="专题空间统计" key="2">
<a-row>
<a-col :xl="16" :lg="12" :md="12" :sm="24" :xs="24">
<bar :dataSource="topicSpace"/>
</a-col>
</a-row>
</a-tab-pane>
</a-tabs>
</div>
</a-card>
<a-row>
<a-col :span="24">
<a-card :loading="loading" :bordered="false" title="最近一周访问量统计" :style="{ marginTop: '24px' }">
<a-row>
<a-col :span="6">
<head-info title="今日IP" :content="loginfo.todayIp"></head-info>
</a-col>
<a-col :span="2">
<a-spin class='circle-cust'>
<a-icon slot="indicator" type="environment" style="font-size: 24px" />
</a-spin>
</a-col>
<a-col :span="6">
<head-info title="今日访问" :content="loginfo.todayVisitCount"></head-info>
</a-col>
<a-col :span="2">
<a-spin class='circle-cust'>
<a-icon slot="indicator" type="team" style="font-size: 24px" />
</a-spin>
</a-col>
<a-col :span="6">
<head-info title="总访问量" :content="loginfo.totalVisitCount"></head-info>
</a-col>
<a-col :span="2">
<a-spin class='circle-cust'>
<a-icon slot="indicator" type="rise" style="font-size: 24px" />
</a-spin>
</a-col>
</a-row>
<line-chart-multid :fields="visitFields" :dataSource="visitInfo"></line-chart-multid>
</a-card>
</a-col>
</a-row>
</div>
</template>
<script>
import AreaChartTy from '@/components/chart/AreaChartTy'
import Pie from '@/components/chart/Pie'
import ChartCard from '@/components/ChartCard'
import ACol from "ant-design-vue/es/grid/Col"
import ATooltip from "ant-design-vue/es/tooltip/Tooltip"
import MiniArea from '@/components/chart/MiniArea'
import MiniBar from '@/components/chart/MiniBar'
import MiniProgress from '@/components/chart/MiniProgress'
import RankList from '@/components/chart/RankList'
import Bar from '@/components/chart/Bar'
import LineChartMultid from '@/components/chart/LineChartMultid'
import HeadInfo from '@/components/tools/HeadInfo.vue'
import Trend from '@/components/Trend'
import { getLoginfo,getVisitInfo } from '@/api/api'
import {httpAction} from "@api/manage";
export default {
name: "IndexKmChart",
components: {
AreaChartTy,
Pie,
ATooltip,
ACol,
ChartCard,
MiniArea,
MiniBar,
MiniProgress,
RankList,
Bar,
Trend,
LineChartMultid,
HeadInfo
},
data() {
return {
kmChartVO:{},
categoryAmount:[],
categorySpace:[],
topicAmount:[],
topicSpace:[],
rankListKeyword:[],
rankListTopic:[],
kmTotalAmount: 0,
spaceTotal:'0',
url: {
list: "/KM/HomePage/getCharData",
},
loading: true,
center: null,
loginfo:{},
visitFields:['ip','visit'],
visitInfo:[],
indicator: <a-icon type="loading" style="font-size: 24px" spin />
}
},
created() {
// setTimeout(() => {
// this.loading = !this.loading
// }, 1000)
this.listData();
},
methods: {
listData(){
console.log("listData...............")
let httpurl = ''
let method = ''
httpurl += this.url.list
method = 'get'
this.loading = true
httpAction(httpurl,null, method).then((res) => {
if (res.success) {
console.log("res.result:",res.result)
this.kmChartVO = res.result
this.kmTotalAmount = res.result.kmDocSummaryVO.kmAmount
this.spaceTotal = res.result.kmDocSummaryVO.fileSizeString
this.formHotKeywordList(res.result.hotKeywordList)
this.formHotTopicList(res.result.hotTopicList)
this.formCategoryChart(res.result.categoryChartList)
this.formTopicChart(res.result.topicChartList)
}
}).finally(() => {
this.loading = false
})
this.initLogInfo()
},
formHotKeywordList(hotKeywordList){
if(hotKeywordList === null || hotKeywordList === undefined)
return
for(let i = 0; i<hotKeywordList.length; i++){
this.rankListKeyword.push({name:hotKeywordList[i]})
}
},
formHotTopicList(hotTopicList){
if(hotTopicList === null || hotTopicList === undefined)
return
for(let i = 0; i<hotTopicList.length; i++){
this.rankListTopic.push({name:hotTopicList[i]})
}
},
formCategoryChart(categoryChartList){
if(categoryChartList === null || categoryChartList === undefined)
return
for(let i = 0; i<categoryChartList.length; i++){
this.categoryAmount.push({
item: categoryChartList[i].itemText,
count: categoryChartList[i].amount,
})
this.categorySpace.push({
item: categoryChartList[i].itemText,
count: categoryChartList[i].fileSizeInt,
})
}
},
formTopicChart(topicChartList){
if(topicChartList === null || topicChartList === undefined)
return
for(let i = 0; i<topicChartList.length; i++){
this.topicAmount.push({
x: topicChartList[i].itemText,
y: topicChartList[i].amount,
})
this.topicSpace.push({
x: topicChartList[i].itemText,
y: topicChartList[i].fileSizeInt,
})
}
},
initLogInfo () {
getLoginfo(null).then((res)=>{
if(res.success){
Object.keys(res.result).forEach(key=>{
res.result[key] =res.result[key]+""
})
this.loginfo = res.result;
}
})
getVisitInfo().then(res=>{
if(res.success){
this.visitInfo = res.result;
}
})
},
}
}
</script>
<style lang="less" scoped>
.circle-cust{
position: relative;
top: 28px;
left: -100%;
}
.extra-wrapper {
line-height: 55px;
padding-right: 24px;
.extra-item {
display: inline-block;
margin-right: 24px;
a {
margin-left: 24px;
}
}
}
/* 首页访问量统计 */
.head-info {
position: relative;
text-align: left;
padding: 0 32px 0 0;
min-width: 125px;
&.center {
text-align: center;
padding: 0 32px;
}
span {
color: rgba(0, 0, 0, .45);
display: inline-block;
font-size: .95rem;
line-height: 42px;
margin-bottom: 4px;
}
p {
line-height: 42px;
margin: 0;
a {
font-weight: 600;
font-size: 1rem;
}
}
}
</style>

@ -0,0 +1,186 @@
<template>
<div>
<a-comment>
<a-avatar
slot="avatar"
:src="getAvatarView(userInfo.avatar)"
alt="Han Solo"
/>
<div slot="content">
<a-form-item style="width:85%;float: left">
<a-textarea :rows="2" :value="value" @change="handleChange" />
</a-form-item>
<a-form-item style="float: right">
<a-button html-type="submit" :loading="submitting" type="primary" @click="handleSubmit">
评论
</a-button>
</a-form-item>
</div>
</a-comment>
<a-list item-layout="vertical" size="small" :split="false" :bordered="false" :loading="loading" :pagination="pagination" :data-source="comments">
<a-list-item slot="renderItem" key="item.id" slot-scope="item, index" class="ky-list-comment">
<a-comment :author="item.createBy" :avatar="getAvatarView(item.avatar)">
<p slot="content">
{{ item.comment }}
</p>
<a-tooltip slot="datetime" :title="item.createTime">
<span>{{ moment(item.createTime).fromNow() }}</span>
</a-tooltip>
</a-comment>
</a-list-item>
<a-spin v-if="loading" class="demo-loading" />
</a-list>
</div>
</template>
<script>
import moment from 'moment';
import { getFileAccessHttpUrl, httpAction, getAction } from '@/api/manage'
const getCommentsUrl = '/KM/KmDocComments/list';
const commitCommentsUrl = '/KM/KmDocComments/add';
export default {
name: 'DocComments',
props: {
docId: ''
},
created() {
this.init()
},
data() {
return {
comments: [],
userInfo:{},
pagination: {
onChange: page => {
console.log(page)
this.pagination.current = page
this.fetchData()
},
hideOnSinglePage: true,
pageSize: 10,
pageSizeOptions: ['10', '20', '30'],
showTotal: (total, range) => {
return range[0] + "-" + range[1] + " 共" + total + "条"
},
showQuickJumper: true,
showSizeChanger: true,
},
submitting: false,
value: '',
loading: false,
moment,
};
},
watch:{
docId(newVal,oldVal){
console.log("id changed:",newVal)
this.init()
}
},
methods: {
init(){
this.userInfo = this.$store.getters.userInfo
this.pagination.current =1
this.fetchData()
},
getAvatarView: function (avatar) {
return getFileAccessHttpUrl(avatar)
},
fetchData() {
let params = {
docId: this.docId,
pageNo: this.pagination.current,
pageSize: this.pagination.pageSize
}
getAction(getCommentsUrl, params).then((res) => {
console.log("comments res:",res)
if(res.success) {
this.comments = res.result.records
this.loading = false;
if(res.result.total)
{
this.pagination.total = res.result.total;
}else{
this.pagination.total = 0;
}
}else{
this.$message.warning("获取评论失败!" );
}
}).finally(() => {
})
},
handleSubmit() {
if (!this.value) {
return;
}
this.submitting = true;
let params = {
docId: this.docId,
comment: this.value
}
let passParam = Object.assign({}, params);
// console.log("pass param",passParam)
let method = 'post';
httpAction(commitCommentsUrl, passParam ,method).then((res) => {
console.log("comments res:",res)
if(res.success){
this.$message.success("评论成功!");
this.fetchData();
this.submitting = false;
this.value = ''
console.log("emit new ....res:",res)
this.$emit('new','')
}else {
this.$message.warning("评论失败!" );
}
}).finally(() => {
})
},
handleChange(e) {
this.value = e.target.value;
},
},
};
</script>
<style>
.demo-loading {
position: absolute;
bottom: 40px;
width: 100%;
text-align: center;
}
.ky-list-comment{
padding-top: 0px;
padding-bottom: 0px;
}
.ant-comment-inner{
padding-top: 0px;
padding-bottom: 0px;
margin-top: 0px;
margin-bottom: 0px;
}
.ant-comment-content-detail{
padding-top: 0px;
padding-bottom: 0px;
margin-top: 0px;
margin-bottom: 0px;
}
.ant-comment-content{
padding-top: 0px;
padding-bottom: 0px;
margin-top: 0px;
margin-bottom: 0px;
}
.ant-comment{
padding-top: 0px;
padding-bottom: 0px;
margin-top: 0px;
margin-bottom: 0px;
}
</style>

@ -0,0 +1,203 @@
<template>
<div>
<a-row v-if="businessTypeList !== null && businessTypeList.length>0">
<a-col >
<a-space>
<div v-for="(item,index) in businessTypeList" :key="index" class="key-word-wrap">
<div class="key-word-item">{{item}}</div>
</div>
</a-space>
</a-col>
</a-row>
<a-row style="margin-top: 10px;margin-bottom: 10px" v-if=" topicList!== null && topicList.length>0">
<a-col >
<a-space>
<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:</span>
<a-space v-if="topicList !== null && topicList.length>0">
<div v-for="(item,index) in topicList" :key="index" class="key-word-wrap">
<a-space>{{item}}</a-space>
</div>
</a-space>
</a-space>
</a-col>
</a-row>
<a-row :gutter="24" style="margin-top: 10px;margin-bottom: 10px">
<a-col :xl="6" :lg="7" :md="8" :sm="24">
<a-space>
<span>文件类型:</span><span>{{ model.fileType }}</span>
</a-space>
</a-col>
<a-col :xl="6" :lg="7" :md="8" :sm="24">
<a-space>
<span>大小:</span><span>{{ model.fileSize }}</span>
</a-space>
</a-col>
<a-col :xl="6" :lg="7" :md="8" :sm="24">
<a-space v-if="model.category_dictText !== null && model.category_dictText !== undefined">
<span>分类:</span><span>{{ model.category_dictText }}</span>
</a-space>
</a-col>
</a-row>
<div style="float:left;">
<a-space size="middle" >
<a-popover v-if="!model.favourite" content="收藏数">
<a-space>
<a-icon type="star" theme="twoTone" two-tone-color="#eb2f96" ></a-icon>{{ model.favourites === undefined? 0:model.favourites}}
</a-space>
</a-popover>
<a-popover v-else content="收藏数">
<a-space>
<a-icon type="star" theme="filled" :style="{ color: '#eb2f96'}"></a-icon>{{ model.favourites === undefined? 0:model.favourites}}
</a-space>
</a-popover>
<a-popover content="预览数">
<a-space>
<a-icon type="eye" theme="twoTone" two-tone-color="blue" ></a-icon>{{ model.views === undefined? 0: model.views }}
</a-space>
</a-popover>
<a-popover content="评论数">
<a-space>
<a-icon type="message" theme="twoTone" two-tone-color="blue" ></a-icon>{{ model.comments === undefined? 0: model.comments}}
</a-space>
</a-popover>
<a-popover content="下载数">
<a-space>
<a-icon type="download" ></a-icon>{{ model.downloads === undefined? 0: model.downloads}}
</a-space>
</a-popover>
</a-space>
</div>
<div style="float:right;">
<a-space>
<a-divider type="vertical"/>
<a-tooltip :title="model.createTime">
<span style="color: #2c3e50;padding-right: 3px;font-weight: bold">{{ model.createBy }}</span> 创建于{{ moment(model.createTime).fromNow() }}
</a-tooltip>
</a-space>
</div>
</div>
</template>
<script>
import moment from 'moment';
import {httpPostAction} from "@api/manage";
export default {
name: 'DocDetail',
props:{
record:{
type: Object
}
},
data(){
return {
url:{
queryById: "/KM/kmDoc/queryById",
addFavouriteKmDoc: '/KM/kmDocFavourite/add',
},
model:{},
keywordList: [],
businessTypeList: [],
topicList: [],
moment
}
},
methods:{
refreshDocDetail(){
let param = {id: this.model.id};
let httpUrl = this.url.queryById;
let method = 'get';
httpPostAction(httpUrl, param, method).then((res) => {
if (res.success) {
console.log("res.result",res.result)
this.model = res.result.records[0]
console.log("this.model",this.model)
} else {
this.$message.warning("刷新失败!");
}
}).finally(() => {
})
},
//
// addFavouriteKmDoc(record) {
// let httpurl = this.url.addFavouriteKmDoc;
// let method = 'post';
// httpPostAction(httpurl, {docId: record.id}, method).then((res) => {
// if (res.success) {
// this.$message.success("!");
// this.refreshDocDetail()
// model.favourite += 1;
// } else {
// this.$message.warning("!" + res.message);
// }
// }).finally(() => {
// })
// },
generateList(){
if(this.model.keywords !== undefined && this.model.keywords !== null && this.model.keywords.length !== 0) {
let words = this.model.keywords.split(' ')
this.keywordList = words;
}
if(this.model.businessTypes_dictText !== undefined && this.model.businessTypes_dictText !== null && this.model.businessTypes_dictText.length !== 0) {
this.businessTypeList = this.model.businessTypes_dictText.split(',')
}
if(this.model.topicIds_dictText !== undefined && this.model.topicIds_dictText !== null && this.model.topicIds_dictText.length !== 0) {
this.topicList = this.model.topicIds_dictText.split(',')
}else{
if(this.model.topicCodes_dictText !== undefined && this.model.topicCodes_dictText !== null && this.model.topicCodes_dictText.length !== 0) {
this.topicList = this.model.topicCodes_dictText.split(',')
}
}
}
},
computed:{
fileSize() {
if (this.model.fileSize > 1000000000) {
return Math.round(this.model.fileSize / 10000000000) + 'G'
} else if (this.model.fileSize > 1000000) {
return Math.round(this.model.fileSize / 1000000) + 'M'
} else if (this.model.fileSize > 1000) {
return Math.round(this.model.fileSize / 1000) + 'K'
}else {
return this.model.fileSize + 'B'
}
},
},
watch:{
record: {
immediate:true,
handler(newVal,loldVal) {
console.log("in docdetail props record newVal:", newVal)
this.keywordList = []
this.businessTypeList =[]
this.model = Object.assign({}, newVal)
this.generateList()
}
}
}
}
</script>
<style scoped>
.key-word-itemDiv{
display: inline-block;
margin: 3px 0px 0px 10px
}
.key-word-item{
margin :0px 3px 0px 3px;
padding: 0px 1px 0px 1px;
float: left;
display: inline-flex;
/*font-size: x-small;*/
border-radius:5px;
background: #D6E3F6FF;
border-style: solid;
border-width: 1px;
}
.key-word-wrap{
display: inline-block;
/*margin: 0px 3px 0px 3px*/
}
</style>

@ -1,61 +1,244 @@
<template>
<div>
<router-link :to="{name:'defaultDocSearch'}">
<span :style="{paddingLeft:'15px'}" >
<span :style="{verticalAlign: 'middle'}"><img :style="{ maxWidth:'22px'}" src="~@/assets/logo.png" alt="logo"></span>
<span :style="{verticalAlign: 'middle',fontSize: '20px',fontWeight: 'normal',color: '#FFFFFF',paddingLeft: '10px'}">科亿知识库</span>
</span>
<div :class="theme">
<router-link :to="{path:indexUrl}">
<span>
<span style="float: left;margin: -5px 10px 0 15px">
<img style="height: 35px;" :src="siteInfo.siteAvatar" alt="logo">
</span>
<span class="site-title site-title-txt show-txt url-txt">{{ siteInfo.siteTitle }}</span>
</span>
</router-link>
<span v-if="title != '' " :style="{verticalAlign: 'middle',fontSize: '20px',fontWeight: 'normal',color: '#FFFFFF',paddingLeft: '10px'}"> -> {{ title }} </span>
<span style="float: right" >
<user-menu :style="{verticalAlign: 'middle',fontSize: '15',fontWeight: 'normal',color: '#FFFFFF',float:'left'}" />
<a-icon @click="jumpKmDocFavouritePage" theme="twoTone" type='star' title="收藏夹" :style="{ fontSize:'23px',minWidth:'30px'}"/>
<a-icon @click="jumpDraftsPage" theme="twoTone" type='folder' title="上传文件" :style="{ fontSize:'23px',minWidth:'30px'}"/>
<a-icon @click="jumpManage()" type='setting' title="进入管理" theme="twoTone" :style="{ fontSize:'23px',minWidth:'30px'}"/>
</span>
<span class="header-option" style="float: right">
<user-menu class="menu-txt"/>
<files-menu class="top-txt show-txt" v-if="token!=null"/>
<!-- <span class="url-txt" v-if="token==null" @click="jumpLogin()"></span>-->
<span class="top-txt show-txt" @click="jumpManage()">
<a-space><a-icon type="setting" class="iconOfMenu"/>管理后台</a-space>
</span>
<span class="top-txt" v-if="token!=null" @click="jumpTopicPage()">
<a-space><a-icon type="folder" class="iconOfMenu"/>知识浏览</a-space>
</span>
<span class="top-txt" v-if="token!=null" @click="jumpSearchPage()">
<a-space><a-icon type="search" class="iconOfMenu"/>综合检索</a-space>
</span>
<!-- 小铃铛站内提醒消息-->
<!-- <div style="float: right;cursor: pointer;color: darkorange">-->
<!-- <header-notice class="action"/>-->
<!-- </div>-->
</span>
</div>
</template>
<script>
import UserMenu from '@/components/tools/UserMenu'
import { mixin } from '@/utils/mixin.js'
export default {
name: "SearchHeader",
mixins: [mixin],
components: {UserMenu},
props: {
title:{
type: String,
required: false,
default: ''
},
theme: {
type: String,
required: false,
default: 'white'
import UserMenu from '@/components/tools/UserMenu'
import FilesMenu from '@/components/tools/FilesMenu'
import { mixin } from '@/utils/mixin.js'
import Vue from 'vue'
import { ACCESS_TOKEN } from '@/store/mutation-types'
import HeaderNotice from '@/components/tools/HeaderNotice'
export default {
name: 'SearchHeader',
mixins: [mixin],
components: {
FilesMenu,
UserMenu,
HeaderNotice
},
data() {
return {
token: '',
siteInfo: {},
kmConfig: {},
indexUrl:'/front/DefaultDocSearch'
}
},
props: {
title: {
type: '',
required: false,
default: ''
},
theme: {
type: '',
required: false,
default: 'white'
}
},
created() {
let token = Vue.ls.get(ACCESS_TOKEN)
this.siteInfo = this.$store.getters.siteInfo
this.kmConfig = this.$store.getters.kmConfig
this.token = token
if(this.kmConfig !== undefined && this.kmConfig.DefaultPageUseTopicList === '1')
this.indexUrl = '/front/RecommendTopicList'
},
methods: {
//
jumpManage() {
let token = this.token
if (token == '' || token == null) {
this.$router.push('/front/user/login')
} else {
let routeData = this.$router.resolve({
path: '/dashboard/analysis',
query: {}
})
window.open(routeData.href, '_blank')
}
},
data() {
return {
// //
// jumpKmDocFavouritePage() {
// let token = this.token
// if (token == '' || token == null) {
// this.$router.push('/user/login')
// } else {
// let routeData = this.$router.resolve({
// path: '/km/filemanagement/KmDocFavouriteList',
// query: {}
// })
// window.open(routeData.href, '_blank')
// }
// },
//
jumpSearchPage() {
let token = this.token
if (token == '' || token == null) {
this.$router.push('/front/user/login')
} else {
this.$router.push('/front/DefaultDocSearch')
}
},
methods: {
//
jumpManage() {
this.$router.push('/dashboard/analysis');
},
//
jumpKmDocFavouritePage(){
this.$router.push('/km/filemanagement/KmDocFavouriteList');
},
// 稿
jumpDraftsPage(){
this.$router.push('/km/filemanagement/DraftsList');
},
//
jumpTopicPage() {
let token = this.token
if (token == '' || token == null) {
this.$router.push('/front/user/login')
} else {
this.$router.push('/front/RecommendTopicList')
}
},
// 稿
jumpDraftsPage() {
let token = this.token
if (token == '' || token == null) {
this.$router.push('/front/user/login')
} else {
let routeData = this.$router.resolve({
path: '/km/filemanagement/FilesList',
query: {}
})
window.open(routeData.href, '_blank')
}
}
}
}
</script>
<style >
/* 大屏幕 大于等于1200px*/
@media (min-width: 1200px) {
.show-txt {
}
.site-title-txt {
font-size: 20px;
}
}
/*默认*/
@media (min-width: 980px) {
.show-txt {
}
.site-title-txt {
font-size: 20px;
}
}
/* 平板电脑和小屏电脑之间的分辨率 */
@media (min-width: 768px) and (max-width: 979px) {
.show-txt {
}
.site-title-txt {
font-size: 20px;
}
}
/* 横向放置的手机和竖向放置的平板之间的分辨率 */
@media (max-width: 767px) {
.show-txt {
display: none;
}
.site-title-txt {
font-size: 18px;
}
}
/* 横向放置的手机及分辨率更小的设备 */
@media (max-width: 480px) {
.show-txt {
display: none;
}
.site-title-txt {
font-size: 16px;
}
}
.top-txt {
color: white;
cursor: pointer;
height: 60px;
float: right;
padding: 0px 10px;
}
.top-txt:hover {
/*border-radius: 2px;*/
/*height: 60px;*/
color: darkorange;
/*background-color: rgba(255, 255, 255, 0.3);*/
}
.url-txt:hover {
color: darkorange;
}
.site-title {
font-weight: normal;
color: white;
float: left;
margin-top: -3px;
}
.top-title {
vertical-align: middle;
font-size: 20px;
font-weight: normal;
color: #000c17;
padding-left: 10px;
}
.menu-txt {
line-height: 60px;
/*marginverticalAlign: 'middle';*/
font-size: 15px;
font-weight: normal;
color: #000c17;
float: right;
background: #0a84ff;
}
.iconOfMenu {
color: darkorange;
}
</style>

@ -0,0 +1,138 @@
<!--<template>-->
<!--<a-modal-->
<!--:width="modalWidth"-->
<!--:style="modalStyle"-->
<!--:visible="visible"-->
<!--:maskClosable="false"-->
<!--@cancel="handleCancel">-->
<!--<template slot="footer">-->
<!--<a-button @click="handleCancel"></a-button>-->
<!--</template>-->
<!--<a-table-->
<!--ref="table"-->
<!--rowKey="id"-->
<!--size="middle"-->
<!--:columns="columns"-->
<!--:loading="loading"-->
<!--:dataSource="dataSource"-->
<!--:pagination="false">-->
<!--<span slot="action" slot-scope="text, record">-->
<!--<a @click="handleBack(record.id)"><a-icon type="redo"/>字典取回</a>-->
<!--<a-divider type="vertical"/>-->
<!--<a @click="handleDelete(record.id)"><a-icon type="scissor"/>彻底删除</a>-->
<!--</span>-->
<!--</a-table>-->
<!--</a-modal>-->
<!--</template>-->
<!--<script>-->
<!--import { getAction,deleteAction,putAction } from '@/api/manage'-->
<!--export default {-->
<!--name: "DictDeleteList",-->
<!--data () {-->
<!--return {-->
<!--modalWidth: '90%',-->
<!--modalStyle: { 'top': '20px'},-->
<!--title: '操作',-->
<!--visible: false,-->
<!--loading: false,-->
<!--dataSource:[],-->
<!--columns:[-->
<!--{-->
<!--title: '#',-->
<!--dataIndex: '',-->
<!--key: 'rowIndex',-->
<!--width: 120,-->
<!--align: "center",-->
<!--customRender: function (t, r, index) {-->
<!--return parseInt(index) + 1;-->
<!--}-->
<!--},-->
<!--{-->
<!--title: '字典名称',-->
<!--align: "left",-->
<!--dataIndex: 'dictName'-->
<!--},-->
<!--{-->
<!--title: '字典编号',-->
<!--align: "left",-->
<!--dataIndex: 'dictCode'-->
<!--},-->
<!--{-->
<!--title: '描述',-->
<!--align: "left",-->
<!--dataIndex: 'description'-->
<!--},-->
<!--{-->
<!--title: '操作',-->
<!--dataIndex: 'action',-->
<!--align: "center",-->
<!--scopedSlots: {customRender: 'action'}-->
<!--}-->
<!--]-->
<!--}-->
<!--},-->
<!--methods: {-->
<!--handleCancel(){-->
<!--this.visible = false-->
<!--//-->
<!--this.$emit("refresh")-->
<!--},-->
<!--show(){-->
<!--this.visible = true-->
<!--this.loadData();-->
<!--},-->
<!--loadData(){-->
<!--this.loading = true-->
<!--getAction("/sys/dict/deleteList").then(res=>{-->
<!--this.loading = false-->
<!--if(res.success){-->
<!--this.dataSource = res.result-->
<!--}else{-->
<!--this.$message.warning(res.message)-->
<!--}-->
<!--})-->
<!--},-->
<!--handleBack(id){-->
<!--putAction("/sys/dict/back/"+id).then(res=>{-->
<!--if(res.success){-->
<!--this.$message.success(res.message)-->
<!--this.loadData();-->
<!--}else{-->
<!--this.$message.warning(res.message)-->
<!--}-->
<!--})-->
<!--},-->
<!--handleDelete(id){-->
<!--this.$confirm({-->
<!--title: '彻底删除字典',-->
<!--content: (<div>-->
<!--<p>您确定要彻底删除这个字典项吗</p>-->
<!--<p style="color:red;">注意彻底删除后将无法恢复请谨慎操作</p>-->
<!--</div>),-->
<!--centered: false,-->
<!--onOk: () => {-->
<!--var that = this;-->
<!--deleteAction("/sys/dict/deletePhysic/"+id).then((res) => {-->
<!--if (res.success) {-->
<!--this.$message.success(res.message)-->
<!--this.loadData();-->
<!--} else {-->
<!--that.$message.warning(res.message);-->
<!--}-->
<!--});-->
<!--},-->
<!--})-->
<!--}-->
<!--}-->
<!--}-->
<!--</script>-->
<!--<style scoped>-->
<!--@import '~@assets/less/common.less'-->
<!--</style>-->

@ -25,14 +25,17 @@
</a>
<a-divider type="vertical"/>
<a @click="editDictItem(record)"><a-icon type="setting"/> 属性配置</a>
<!--<a-divider type="vertical"/>-->
<!--<a-popconfirm title="确定删除吗?" @confirm="() =>handleDelete(record.id)">-->
<!--<a>删除</a>-->
<!--</a-popconfirm>-->
</span>
</a-table>
</div>
<dict-modal ref="modalForm" @ok="modalFormOk"></dict-modal> <!-- 属性类型 -->
<dict-item-list ref="dictItemList"></dict-item-list>
<!--<dict-delete-list ref="dictDeleteList" @refresh="() =>loadData()"></dict-delete-list>-->
<dict-delete-list ref="dictDeleteList" @refresh="() =>loadData()"></dict-delete-list>
</a-card>
</template>
@ -41,6 +44,7 @@
import { JeecgListMixin } from '@/mixins/JeecgListMixin'
import DictModal from './modules/DictModal'
import DictItemList from './DictItemList'
import DictDeleteList from './DictDeleteList'
import { getAction } from '@/api/manage'
import { UI_CACHE_DB_DICT_DATA } from "@/store/mutation-types"
import Vue from 'vue'
@ -48,7 +52,7 @@
export default {
name: "DictList",
mixins:[JeecgListMixin],
components: {DictModal, DictItemList},
components: {DictModal, DictItemList,DictDeleteList},
data() {
return {
description: '这是文档属性页面',

@ -0,0 +1,143 @@
<template>
<a-card :bordered="false">
<!-- 操作按钮区域 -->
<div class="table-operator">
<a-button type="primary" icon="upload" @click="newBackup"></a-button>
</div>
<!-- table区域-begin -->
<div>
<a-spin size="large" :spinning=spinning >
<a-table
ref="table"
size="middle"
:scroll="{x:true}"
bordered
rowKey="id"
:columns="columns"
:dataSource="dataSource"
:pagination="ipagination"
:loading="loading"
:rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
class="j-table-force-nowrap"
@change="handleTableChange">
<span slot="action" slot-scope="text, record">
<a-space>
<a-icon type="download" title="下载" @click="download(record)"
:style="{ fontSize: '16px', color: '#1890FF'}"/>
<a-divider type="vertical"/>
<a-icon type="delete" title="删除" @click="deleteBackup(record)"
:style="{ fontSize: '16px', color: '#1890FF' }"/>
</a-space>
</span>
</a-table>
</a-spin>
</div>
</a-card>
</template>
<script>
import '@/assets/less/TableExpand.less'
import { mixinDevice } from '@/utils/mixin'
import { JeecgListMixin } from '@/mixins/JeecgListMixin'
import { downloadFileName, httpPostAction } from '@api/manage'
export default {
name: 'KmSysDbBackupList',
mixins:[JeecgListMixin, mixinDevice],
data () {
return {
spinning: false,
description: '数据库备份管理页面',
//
columns: [
{
title:'文件名',
align:"left",
dataIndex: 'fileName'
},
{
title:'大小',
align:"center",
dataIndex: 'size'
},
{
title:'备份时间',
align:"left",
dataIndex: 'createTime'
},
{
title: '操作',
dataIndex: 'action',
align:"center",
fixed:"right",
width:80,
scopedSlots: { customRender: 'action' }
},
],
url: {
list: "/KM/kmSysDbBackup/list",
add: "/KM/kmSysDbBackup/add",
delete: "/KM/kmSysDbBackup/delete",
downloadById: "/KM/kmSysDbBackup/downloadById",
},
}
},
created() {
},
methods: {
//
download(record) {
this.$notification.success({
message: '文件开始下载...',
duration: 1,
});
downloadFileName(this.url.downloadById, {id: record.id})
},
//
newBackup(record) {
let httpurl = '';
let method = '';
httpurl += this.url.add;
method = 'post';
this.spinning = true
httpPostAction(httpurl, {}, method).then((res) => {
if (res.success) {
this.$message.success("创建备份成功!");
this.loadData();
} else {
this.$message.warning("创建备份失败!");
}
}).finally(() => {
this.spinning = false
})
},
//
deleteBackup(record) {
let httpurl = '';
let method = '';
httpurl += this.url.delete;
method = 'delete';
this.spinning = true
httpPostAction(httpurl, {id: record.id}, method).then((res) => {
if (res.success) {
this.$message.success("删除成功!");
this.loadData();
record.favourite = 0;
} else {
this.$message.warning("删除失败!");
}
}).finally(() => {
this.spinning = false
})
},
}
}
</script>
<style scoped>
@import '~@assets/less/common.less';
</style>

@ -0,0 +1,395 @@
<template>
<a-row :gutter="10">
<a-col :md="12" :sm="24">
<a-card :bordered="false">
<!-- 按钮操作区域 -->
<div>
<!-- -->
<a-col :md="24" :sm="48">
<div class="table-operator">
<a-button @click="handleAdd" type="primary" icon="plus">新增</a-button>
</div>
<a-table
ref="table"
size="middle"
rowKey="id"
:columns="columns"
:dataSource="dataSource"
:pagination="ipagination"
:loading="loading"
:expandedRowKeys="expandedRowKeys"
:customRow="clickThenCheck"
:rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange,type:type}"
@change="handleTableChange"
@expand="handleExpand"
v-bind="tableProps">
<span slot="action" slot-scope="text, record">
<a @click="handleEdit(record)"></a>
<a-divider type="vertical"/>
<a-popconfirm title="确定删除吗?" @confirm="() => handleDelete(record)">
<a>删除</a>
</a-popconfirm>
<a-divider type="vertical"/>
<a @click="handleAddSub(record)"></a>
</span>
</a-table>
</a-col>
</div>
<sysCategory-modal ref="modalForm" @ok="modalFormOk"></sysCategory-modal>
</a-card>
</a-col>
<a-col :md="12" :sm="24">
<project-modal ref="projectModal"/>
</a-col>
</a-row>
</template>
<script>
import SysCategoryModal from "./modules/SysCategoryModal";
import {getAction, deleteAction} from '@/api/manage'
import {JeecgListMixin} from '@/mixins/JeecgListMixin'
import ProjectModal from './modules/ProjectModal'
import Vue from "vue";
export default {
name: 'DepartList',
mixins: [JeecgListMixin],
components: {
ProjectModal,
SysCategoryModal
},
data() {
return {
description: '分类字典管理页面',
//
columns: [
{
title: '专题名称',
align: "left",
dataIndex: 'name'
},
{
title: '操作',
dataIndex: 'action',
align: "center",
scopedSlots: {customRender: 'action'},
}
],
//
type: "radio",
isorter: false,
url: {
list: "/sys/category/rootList",
childList: "/sys/category/childList",
getChildListBatch: "/sys/category/getChildListBatch",
delete: "/sys/category/delete"
},
expandedRowKeys: [],
hasChildrenField: "hasChild",
pidField: "pid",
dictOptions: {},
subExpandedKeys: [],
}
},
computed: {
tableProps() {
let _this = this
return {
//
rowSelection: {
selectedRowKeys: _this.selectedRowKeys,
onChange: (selectedRowKeys) => _this.selectedRowKeys = selectedRowKeys
}
}
}
},
methods: {
//
loadData(arg) {
if (arg == 1) {
this.ipagination.current = 1
}
this.loading = true
let params = this.getQueryParams()
return new Promise((resolve) => {
getAction(this.url.list, params).then(res => {
if (res.success) {
let result = res.result
if (Number(result.total) > 0) {
this.ipagination.total = Number(result.total)
this.dataSource = this.getDataByResult(res.result.records)
return this.loadDataByExpandedRows(this.dataSource)
//update--end--autor:lvdandan-----date:20201204------forJT-31
} else {
this.ipagination.total = 0
this.dataSource = []
}
} else {
this.$message.warning(res.message)
}
}).finally(() => {
this.loading = false
})
})
},
getDataByResult(result) {
if (result && result.length > 0) {
return result.map(item => {
//
if (item[this.hasChildrenField] == '1') {
let loadChild = {id: item.id + '_loadChild', name: 'loading...', isLoading: true}
item.children = [loadChild]
}
return item
})
}
},
handleExpand(expanded, record) {
//
if (expanded) {
this.expandedRowKeys.push(record.id)
if (record.children.length > 0 && record.children[0].isLoading === true) {
let params = this.getQueryParams();//
params[this.pidField] = record.id
getAction(this.url.childList, params).then((res) => {
if (res.success) {
if (res.result && res.result.length > 0) {
record.children = this.getDataByResult(res.result)
this.dataSource = [...this.dataSource]
} else {
record.children = ''
record.hasChildrenField = '0'
}
} else {
this.$message.warning(res.message)
}
})
}
} else {
let keyIndex = this.expandedRowKeys.indexOf(record.id)
if (keyIndex >= 0) {
this.expandedRowKeys.splice(keyIndex, 1);
}
}
},
initDictConfig() {
},
clickThenCheck(record) {
return {
on: {
click: () => {
this.onSelectChange(record.id.split(","), [record]);
}
}
};
},
onSelectChange(selectedRowKeys, selectionRows) {
this.selectedRowKeys = selectedRowKeys;
this.selectionRows = selectionRows;
this.$refs.projectModal.getOrderMain(this.selectedRowKeys[0]);
},
editOk(formData, arr) {
if (arr && arr.length > 0) {
for (let i = 0; i < arr.length; i++) {
if (arr[i].id == formData.id) {
arr[i] = formData
break
} else {
this.editOk(formData, arr[i].children)
}
}
}
},
async addOk(formData, arr) {
if (!formData[this.pidField]) {
this.loadData()
} else {
this.expandedRowKeys = []
console.log("22222", arr)
for (let i of arr) {
await this.expandTreeNode(i)
}
}
},
expandTreeNode(nodeId) {
return new Promise((resolve, reject) => {
this.getFormDataById(nodeId, this.dataSource)
let row = this.parentFormData
this.expandedRowKeys.push(nodeId)
let params = this.getQueryParams();//
params[this.pidField] = nodeId
getAction(this.url.childList, params).then((res) => {
console.log("11111", res)
if (res.success) {
if (res.result && res.result.length > 0) {
row.children = this.getDataByResult(res.result)
this.dataSource = [...this.dataSource]
resolve()
} else {
row.children = ''
row.hasChildrenField = '0'
reject()
}
} else {
reject()
}
})
})
},
getFormDataById(id, arr) {
if (arr && arr.length > 0) {
for (let i = 0; i < arr.length; i++) {
if (arr[i].id == id) {
this.parentFormData = arr[i]
} else {
this.getFormDataById(id, arr[i].children)
}
}
}
},
handleAddSub(record) {
this.subExpandedKeys = [];
this.getExpandKeysByPid(record.id, this.dataSource, this.dataSource)
this.$refs.modalForm.subExpandedKeys = this.subExpandedKeys;
this.$refs.modalForm.title = "添加子分类";
this.$refs.modalForm.edit({'pid': record.id});
this.$refs.modalForm.disableSubmit = false;
},
handleDelete: function (record) {
let that = this;
deleteAction(that.url.delete, {id: record.id}).then((res) => {
if (res.success) {
that.loadData();
this.$refs.projectModal.getOrderMain('');
} else {
that.$message.warning(res.message);
}
});
},
// id
getExpandKeysByPid(pid, arr, all) {
if (pid && arr && arr.length > 0) {
for (let i = 0; i < arr.length; i++) {
if (arr[i].id == pid) {
this.subExpandedKeys.push(arr[i].id)
this.getExpandKeysByPid(arr[i]['pid'], all, all)
} else {
this.getExpandKeysByPid(pid, arr[i].children, all)
}
}
}
},
//
loadDataByExpandedRows(dataList) {
if (this.expandedRowKeys.length > 0) {
return getAction(this.url.getChildListBatch, {parentIds: this.expandedRowKeys.join(',')}).then(res => {
if (res.success && res.result.records.length > 0) {
//
let records = res.result.records
const listMap = new Map();
for (let item of records) {
let pid = item[this.pidField];
if (this.expandedRowKeys.join(',').includes(pid)) {
let mapList = listMap.get(pid);
if (mapList == null) {
mapList = [];
}
mapList.push(item);
listMap.set(pid, mapList);
}
}
let childrenMap = listMap;
let fn = (list) => {
if (list) {
list.forEach(data => {
if (this.expandedRowKeys.includes(data.id)) {
data.children = this.getDataByResult(childrenMap.get(data.id))
fn(data.children)
}
})
}
}
fn(dataList)
}
})
} else {
return Promise.resolve()
}
},
}
}
</script>
<style scoped>
@import '~@assets/less/common.less';
.ant-card-body .table-operator {
margin: 5px;
}
.anty-form-btn {
width: 100%;
text-align: center;
}
.anty-form-btn button {
margin: 0 5px;
}
.anty-node-layout .ant-layout-header {
padding-right: 0
}
.header {
padding: 0 8px;
}
.header button {
margin: 0 3px
}
.ant-modal-cust-warp {
height: 100%
}
.ant-modal-cust-warp .ant-modal-body {
height: calc(100% - 110px) !important;
overflow-y: auto
}
.ant-modal-cust-warp .ant-modal-content {
height: 90% !important;
overflow-y: hidden
}
#app .desktop {
height: auto !important;
}
/** Button按钮间距 */
.ant-btn {
margin-left: 3px
}
.drawer-bootom-button {
/*position: absolute;*/
bottom: 0;
width: 100%;
border-top: 1px solid #e8e8e8;
padding: 10px 16px;
text-align: left;
left: 0;
background: #fff;
border-radius: 0 0 2px 2px;
}
</style>

@ -8,11 +8,23 @@
<a-input v-model="model.itemCode" :disabled="true" ></a-input>
</a-form-model-item>
</a-col>
<a-col :span="24">
<a-col v-if="model.valueType === 'text'" :span="24">
<a-form-model-item label="参数值" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="itemValue">
<a-input v-model="model.itemValue" placeholder="请输入itemValue" ></a-input>
</a-form-model-item>
</a-col>
<a-col v-else-if="model.valueType === 'checkBox'" :span="24">
<a-form-model-item label="是否" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-switch @change="switchChange" v-model:checked="model.itemValue === '1'"/>
</a-form-model-item>
</a-col>
<a-col v-else-if="model.valueType === 'img'" :span="24">
<a-form-model-item label="logo" :labelCol="labelCol" :wrapperCol="wrapperCol">
<j-image-upload class="avatar-uploader" text="上传" v-model="model.itemValue" ></j-image-upload>
</a-form-model-item>
</a-col>
<a-col :span="24">
<a-form-model-item label="参数说明" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="itemName">
<a-input v-model="model.itemName" :disabled="true"></a-input>
@ -82,6 +94,14 @@
this.model = Object.assign({}, record);
this.visible = true;
},
switchChange(value) {
console.log(value)
if (value) {
this.model.itemValue = '1'
} else {
this.model.itemValue = '0'
}
},
submitForm () {
const that = this;
//
@ -108,7 +128,7 @@
that.confirmLoading = false;
})
}
})
},
}

@ -0,0 +1,247 @@
<template>
<j-modal
:title="title"
:width="width"
:visible="visible"
@ok="handleOk"
:okButtonProps="{ class:{'jee-hidden': disableSubmit} }"
@cancel="handleCancel"
cancelText="关闭">
<!-- 查询区域 -->
<div class="table-page-search-wrapper">
<a-form layout="inline" @keyup.enter.native="searchQuery">
<a-row :gutter="24">
<a-col :xl="6" :lg="7" :md="8" :sm="24">
<a-form-item label="编号">
<a-input placeholder="请输入编号" v-model="queryParam.serialNumber"></a-input>
</a-form-item>
</a-col>
<a-col :xl="6" :lg="7" :md="8" :sm="24">
<a-form-item label="分类">
<j-dict-select-tag type="list" placeholder="请选择分类" v-model="queryParam.category"
dictCode="km_dict_category"></j-dict-select-tag>
</a-form-item>
</a-col>
<template v-if="toggleSearchStatus">
<a-col :xl="6" :lg="7" :md="8" :sm="24">
<a-form-item label="标题">
<a-input placeholder="请输入标题" v-model="queryParam.title"></a-input>
</a-form-item>
</a-col>
<a-col :xl="6" :lg="7" :md="8" :sm="24">
<a-form-model-item label="标签">
<j-multi-select-tag type="list_multi" v-model="queryParam.businessTypeList" :trigger-change="true"
placeholder="请选择标签" dictCode="km_dict_business"></j-multi-select-tag>
</a-form-model-item>
</a-col>
<a-col :xl="6" :lg="7" :md="8" :sm="24">
<a-form-item label="关键字">
<a-input placeholder="请输入关键字" v-model="queryParam.keywords"></a-input>
</a-form-item>
</a-col>
<a-col :xl="14" :lg="16" :md="18" :sm="47">
<a-form-item label="上传时间">
<j-date :show-time="true" date-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择开始时间"
class="query-group-cust" v-model="queryParam.createTimeStart"></j-date>
<span class="query-group-split-cust"></span>
<j-date :show-time="true" date-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择结束时间"
class="query-group-cust" v-model="queryParam.createTimeEnd"></j-date>
</a-form-item>
</a-col>
</template>
<a-col :xl="6" :lg="7" :md="8" :sm="24">
<span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
<a-button type="primary" @click="searchQuery" icon="search">查询</a-button>
<a-button @click="searchReset" icon="reload" style="margin-left: 8px">重置</a-button>
<a @click="handleToggleSearch" style="margin-left: 8px">
{{ toggleSearchStatus ? '收起' : '展开' }}
<a-icon :type="toggleSearchStatus ? 'up' : 'down'"/>
</a>
</span>
</a-col>
</a-row>
</a-form>
</div>
<!-- 查询区域-END -->
<a-table
ref="table"
size="middle"
:scroll="{x:true}"
bordered
rowKey="id"
:columns="columns"
:dataSource="dataSource"
:pagination="ipagination"
:loading="loading"
:rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
class="j-table-force-nowrap"
@change="handleTableChange">
</a-table>
</j-modal>
</template>
<script>
import {JeecgListMixin} from '@/mixins/JeecgListMixin'
import {httpPostAction} from '@/api/manage'
export default {
name: "ProjectListForm",
mixins:[JeecgListMixin],
data() {
return {
title: '收录文件到专题',
width: 1200,
visible: false,
disableSubmit: false,
topicId:'',
//
columns: [
{
title: '#',
dataIndex: '',
key: 'rowIndex',
width: 60,
align: "center",
customRender: function (t, r, index) {
return parseInt(index) + 1;
}
},
{
title: '标题',
align: "left",
dataIndex: 'title',
scopedSlots: {customRender: 'docTitle'},
customCell: () => {
return {
style: {
'max-width': '30em',
},
};
},
},
{
title: '分类',
align: "center",
dataIndex: 'category_dictText',
sorter: true,
customCell: () => {
return {
style: {
'max-width': '6em',
},
};
},
},
{
title: '标签',
align: "center",
dataIndex: 'businessTypes_dictText',
customCell: () => {
return {
style: {
'max-width': '10em',
overflow: 'hidden',
whiteSpace: 'nowrap',
textOverflow:'ellipsis'
},
};
},
},
{
title: '关键字',
align: "center",
dataIndex: 'keywords',
customCell: () => {
return {
style: {
'max-width': '10em',
overflow: 'hidden',
whiteSpace: 'nowrap',
textOverflow:'ellipsis'
},
};
},
},
{
title: '上传人',
align: "center",
dataIndex: 'createBy',
sorter: true,
customCell: () => {
return {
style: {
'max-width': '3em',
},
};
},
},
{
title: '归属部门',
align: "center",
dataIndex: 'orgCode_dictText',
sorter: true,
customCell: () => {
return {
style: {
'max-width': '5em',
},
};
},
},
],
url:{
list:'/KM/kmDoc/listPassed',
addDocToTopic:'/KM/kmDoc/addDocToTopic'
}
}
},
methods:{
init(topicId){
this.topicId=topicId;
this.visible=true;
},
handleOk(){
console.log("docIdsArr"+this.selectedRowKeys.toString());
console.log('topicId:'+this.topicId);
let httpurl = '';
let method = '';
let docIdsArr=this.selectedRowKeys.toString();
httpurl += this.url.addDocToTopic;
method = 'put';
httpPostAction(httpurl, {topicId:this.topicId,docIds:docIdsArr}, method).then((res) => {
console.log(res);
if (res.success) {
if(res.result==null || res.result == ""){
this.$message.success("收录成功!");
}else{
this.$message.warning(res.result+"文件收录失败");
}
this.$emit('ok');
this.visible = false;
} else {
this.$message.warning(res.message);
}
}).finally(() => {
})
},
handleCancel () {
this.close()
},
close () {
this.visible = false;
},
}
}
</script>
<style scoped>
@import '~@assets/less/common.less';
</style>

@ -0,0 +1,166 @@
<template>
<a-card :bordered="false" v-show="visible">
<div class="table-operator">
<a-button @click="handleAddModal()" type="primary" icon="plus">收录新文件</a-button>
</div>
<a-table
ref="table"
size="middle"
:scroll="{x:true}"
bordered
rowKey="id"
:columns="columns"
:dataSource="dataSource"
:pagination="ipagination"
:loading="loading"
@change="handleTableChange">
<span slot="action" slot-scope="text, record">
<a-popconfirm title="确定移除吗?" @confirm="() => removeTopic(record.id)">
<a>移除</a>
</a-popconfirm>
</span>
</a-table>
<project-list-form ref="modalForm" @ok="modalFormOk" />
</a-card>
</template>
<script>
import {JeecgListMixin} from '@/mixins/JeecgListMixin'
import ProjectListForm from "./ProjectListForm";
import {getAction,httpPostAction} from '@/api/manage'
export default {
name: 'DepartAuthModal',
mixins: [JeecgListMixin],
components:{
ProjectListForm
},
data(){
return {
visible:false,
columns: [
{
title: '#',
dataIndex: '',
key:'rowIndex',
align:"center",
customRender:function (t,r,index) {
return parseInt(index)+1;
}
},
{
title:'标题',
align:"left",
customCell: () => {
return {
style: {
'max-width': '30em',
},
};
},
dataIndex: 'title'
},
{
title:'关键字',
align:"left",
dataIndex: 'keywords'
},
{
title:'编号',
align:"center",
dataIndex: 'serialNumber'
},
{
title: '操作',
dataIndex: 'action',
align:"center",
fixed:"right",
width:"4em",
scopedSlots: { customRender: 'action' }
}
],
url: {
list: "/KM/kmDoc/listTopicPageList",
removeDocFromTopic:"KM/kmDoc/removeDocFromTopic",
},
dictOptions:{},
superFieldList:[],
topicId:'',
}
},
computed: {
importExcelUrl: function(){
return `${window._CONFIG['domianURL']}/${this.url.importExcelUrl}`;
},
},
methods: {
initDictConfig(){
},
created() {
this.getSuperFieldList();
},
getSuperFieldList(){
let fieldList=[];
fieldList.push({type:'string',value:'serialNumber',text:'编号',dictCode:''})
fieldList.push({type:'string',value:'title',text:'文件名',dictCode:''})
fieldList.push({type:'string',value:'keywords',text:'关键字',dictCode:''})
this.superFieldList = fieldList
},
getOrderMain(topicId) {
this.topicId=topicId;
if(this.topicId!==''){
this.visible=true;
}else{
this.visible=false;
}
this.loadData(1);
},
loadData(arg) {
if (arg === 1) {
this.ipagination.current = 1;
}
var params = this.getQueryParams();
if(this.topicId!=null) {
this.loading=true;
getAction(this.url.list, {
topicId: this.topicId, pageNo: this.ipagination.current,
pageSize: this.ipagination.pageSize
}).then((res) => {
if (res.success) {
this.dataSource = res.result.records;
console.log(this.dataSource);
this.ipagination.total = res.result.total;
} else {
this.dataSource = null;
}
this.loading=false;
})
}
},
handleAddModal(){
this.$refs.modalForm.init(this.topicId);
},
removeTopic(docId){
let httpurl = '';
let method = '';
httpurl += this.url.removeDocFromTopic;
method = 'put';
httpPostAction(httpurl, {topicId:this.topicId,docId:docId}, method).then((res) => {
if (res.success) {
this.$message.success("取消收录成功!");
this.loadData(1);
} else {
this.$message.warning("取消收录失败!");
}
}).finally(() => {})
}
},
}
</script>
<style scoped>
@import '~@assets/less/common.less';
</style>

@ -32,7 +32,7 @@
</a-form-model-item>
<a-form-model-item label="首页推荐" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="recommend">
<a-switch checked-children="" un-checked-children="" v-model="model.recommend"/>
<a-switch checked-children="" un-checked-children="" v-model="model.recommend" :disabled="recommendDisable"/>
</a-form-model-item>
</a-form-model>
@ -67,11 +67,6 @@
},
confirmLoading: false,
validatorRules:{
pid:{},
name: [{ required: true, message: '请输入类型名称!' }],
sortOrder: [{ required: true, message: '请输入序号!' }]
},
url: {
add: "/sys/category/add",
edit: "/sys/category/edit",
@ -81,6 +76,9 @@
pidField:"pid",
subExpandedKeys:[],
validatorRules:{
pid:{},
name: [{ required: true, message: '请输入类型名称!' }],
sortOrder: [{ required: true, message: '请输入序号!' }],
recommend: [
{ validator: this.validateRecommend}
]
@ -93,6 +91,9 @@
computed : {
disabled() {
return this.model.id?true : false;
},
recommendDisable() {
return !this.model.id;
}
},
methods: {
@ -123,7 +124,7 @@
httpurl+=this.url.edit;
method = 'put';
}
debugger
// debugger
httpAction(httpurl,this.model,method).then((res)=>{
if(res.success){
that.$message.success(res.message);
@ -171,7 +172,7 @@
},
validateRecommend(rule, value, callback){
if(value == true && this.model.pid !='0')
if(value == true && this.model.pid !=null && this.model.pid !='0')
callback("只允许推荐根节点专题");
else
callback();

@ -0,0 +1,622 @@
<template>
<a-card :bordered="false">
<!-- 查询区域 -->
<div class="table-page-search-wrapper">
<a-form layout="inline" @keyup.enter.native="searchQuery">
<a-row :gutter="24">
<a-col :xl="6" :lg="7" :md="8" :sm="24">
<a-form-item label="标题">
<a-input placeholder="请输入标题" v-model="queryParam.title"></a-input>
</a-form-item>
</a-col>
<a-col :xl="6" :lg="7" :md="8" :sm="24">
<a-form-item label="分类">
<j-dict-select-tag type="list" placeholder="请选择分类" v-model="queryParam.category"
dictCode="km_dict_category"></j-dict-select-tag>
</a-form-item>
</a-col>
<a-col :xl="6" :lg="7" :md="8" :sm="24">
<a-form-model-item label="归属部门" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="depId">
<j-select-depart v-model="queryParam.depId" :multi="true"></j-select-depart>
</a-form-model-item>
</a-col>
<template v-if="toggleSearchStatus">
<a-col :xl="6" :lg="7" :md="8" :sm="24">
<a-form-model-item label="标签">
<j-multi-select-tag type="list_multi" v-model="queryParam.businessTypeList" :trigger-change="true"
placeholder="请选择标签" dictCode="km_dict_business"></j-multi-select-tag>
</a-form-model-item>
</a-col>
<a-col :xl="6" :lg="7" :md="8" :sm="24">
<a-form-item label="关键字">
<a-input placeholder="请输入关键字" v-model="queryParam.keywords"></a-input>
</a-form-item>
</a-col>
<a-col :xl="6" :lg="7" :md="8" :sm="24">
<a-form-item label="文件类型">
<a-input placeholder="请输入文件类型" v-model="queryParam.fileType"></a-input>
</a-form-item>
</a-col>
<a-col :xl="12" :lg="14" :md="16" :sm="48">
<a-form-item label="上传时间">
<j-date :show-time="true" date-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择开始时间"
class="query-group-cust" v-model="queryParam.createTimeStart"></j-date>
<span class="query-group-split-cust"></span>
<j-date :show-time="true" date-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择结束时间"
class="query-group-cust" v-model="queryParam.createTimeEnd"></j-date>
</a-form-item>
</a-col>
</template>
<a-col :xl="6" :lg="7" :md="8" :sm="24">
<span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
<a-button type="primary" @click="searchQuery" icon="search">查询</a-button>
<a-button @click="searchReset" icon="reload" style="margin-left: 8px">重置</a-button>
<a @click="handleToggleSearch" style="margin-left: 8px">
{{ toggleSearchStatus ? '收起' : '展开' }}
<a-icon :type="toggleSearchStatus ? 'up' : 'down'"/>
</a>
</span>
</a-col>
</a-row>
</a-form>
</div>
<!-- 查询区域-END ant-alert ant-alert-info -->
<!-- config区域-BEGIN -->
<a-j-modal :width="width"
:visible="configVisible"
:show-return="true"
@cancel="handleCancel"
@close="handleCancel"
:destroyOnClose="true"
cancelText="关闭"
:okButtonProps="{ class:{'jee-hidden': true} }">
<draft-doc-edit :model="configDetail"
:release-button=false
:dup-check=false
@cancel="handleCancel"
@ok="editOk" >
</draft-doc-edit>
</a-j-modal>
<!-- config区域-END -->
<!-- 详情区域-BEGIN -->
<a-drawer
:title="showDocDetail.title"
:width="720"
:visible="drawerVisible"
:body-style="{ paddingBottom: '80px' }"
:footer-style="{ textAlign: 'right' }"
@close="onDrawerClose"
>
<doc-detail ref="docDetailRef" :record="showDocDetail"></doc-detail>
<br/>
<a-divider style="margin: 5px 0 15px 0 "></a-divider>
<doc-comments ref="comments"
@new="refreshDocDetail"
:doc-id="showDocDetail.id" >
</doc-comments>
</a-drawer>
<!-- 详情区域-END -->
<!-- table区域-begin -->
<div>
<div class="table-operator" style="margin-bottom: 8px;">
<!-- <a-button type="primary" icon="download" @click="handleExportXls('草稿文件夹')"></a-button>-->
<a-dropdown v-if="selectedRowKeys.length > 0">
<a-menu slot="overlay">
<a-menu-item key="1" @click="downloadKmDocBatch">
<a-icon type="vertical-align-bottom"/>
批量下载
</a-menu-item>
</a-menu>
<a-button style="margin-left: 8px"> 批量操作
<a-icon type="down"/>
</a-button>
</a-dropdown>
</div>
<div v-if="selectedRowKeys.length > 0" class="ant-alert ant-alert-info" style="margin-bottom: 8px;">
<i class="anticon anticon-info-circle ant-alert-icon"></i> 已选择 <a style="font-weight: 600">{{
selectedRowKeys.length }}</a>
<a style="margin-left: 24px" @click="onClearSelected"></a>
</div>
<a-table
ref="table"
size="middle"
:scroll="{x:true}"
bordered
rowKey="id"
:columns="columns"
:dataSource="dataSource"
:pagination="ipagination"
:loading="loading"
:rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
@change="handleTableChange">
//
<div slot="filterDropdown">
<a-card style="width: 350px">
<a-checkbox-group @change="onColSettingsChange" v-model="settingColumns" :defaultValue="settingColumns">
<a-row>
<template v-for="(item,index) in defColumns">
<template v-if="item.key!='rowIndex'&& item.dataIndex!='action'">
<a-col :span="12">
<a-checkbox :value="item.dataIndex">{{ item.title }}</a-checkbox>
</a-col>
</template>
</template>
</a-row>
</a-checkbox-group>
</a-card>
</div>
<a-icon slot="filterIcon" type='setting' title="自定义列"
:style="{ fontSize:'16px',color: '#108ee9',minWidth:'50px'}"/>
<template slot="htmlSlot" slot-scope="text">
<div v-html="text"></div>
</template>
<template slot="imgSlot" slot-scope="text">
<span v-if="!text" style="font-size: 12px;font-style: italic;"></span>
<img v-else :src="getImgView(text)" height="25px" alt=""
style="max-width:80px;font-size: 12px;font-style: italic;"/>
</template>
<template slot="fileSlot" slot-scope="text">
<span v-if="!text" style="font-size: 12px;font-style: italic;"></span>
<a-button
v-else
:ghost="true"
type="primary"
icon="download"
size="small"
@click="downloadFile(text)">
下载
</a-button>
</template>
<span slot="action" slot-scope="text, record">
<a-space>
<a-popover content="预览">
<a-icon type="read" title="预览" @click="previewKmDoc(record)"
:style="{ fontSize: '18px', color: '#1890FF', }"/>
</a-popover>
<a-popover content="配置">
<a-icon type="tool" title="配置" @click="configDoc(record)"
:style="{ fontSize: '18px', color: '#1890FF', }"/>
</a-popover>
<a-popover content="禁用与启用">
<span v-if="record.releaseFlag==1">
<a-icon v-if="record.ftiFlag === -1" type="lock" :title="record.processMsg"
:style="{ fontSize: '18px', color: '#d71345', }" style="margin-left: 5px"/>
<a-icon v-else-if="record.ftiFlag === 0" type="lock" title="错误:未入库"
:style="{ fontSize: '18px', color: '#fa8c16', }" style="margin-left: 5px"/>
<a-popconfirm v-else
title="你是否将文件禁用?"
ok-text="确定"
cancel-text="取消"
@confirm="confirm(record)">
<a-icon type="lock" title="禁用" href="#" :style="{ fontSize: '18px', color: '#1890FF', }"
style="margin-left: 5px"/>
</a-popconfirm>
</span>
<span v-if="record.releaseFlag==0">
<a-icon v-if="record.ftiFlag === -1" type="unlock" :title="record.processMsg"
:style="{ fontSize: '18px', color: '#d71345', }" style="margin-left: 5px"/>
<a-icon v-else-if="record.ftiFlag === 0" type="unlock" title="错误:未入库"
:style="{ fontSize: '18px', color: '#fa8c16', }" style="margin-left: 5px"/>
<a-popconfirm v-else
title="你是否将文件启用?"
ok-text="确定"
cancel-text="取消"
@confirm="confirm(record)">
<!--<a-icon type="unlock" title="启用" href="#" :style="{ fontSize: '18px', color: '#fa8c16', }"-->
<!--style="margin-left: 5px"/>-->
<a-icon type="unlock" title="启用"
:style="{ fontSize: '18px', color: '#1890FF', }" style="margin-left: 5px"/>
</a-popconfirm>
</span>
</a-popover>
<a-divider type="vertical"/>
<a-dropdown>
<a class="ant-dropdown-link"><a-icon :style="{ fontSize: '18px', color: '#1890FF'}" type="down-circle"/></a>
<a-menu slot="overlay">
<!-- <a-menu-item>-->
<!-- <a v-show="docEditable(record)" @click="editKmDoc(record)"></a>-->
<!-- </a-menu-item>-->
<a-menu-item>
<a @click="downloadKmDoc(record)"></a>
</a-menu-item>
<a-menu-item>
<a-popconfirm title="确定删除吗?" @confirm="() => handleDelete(record.id)">
<a>删除</a>
</a-popconfirm>
</a-menu-item>
</a-menu>
</a-dropdown>
</a-space>
</span>
<span slot="docTitle" slot-scope="text,record">
<span v-if="record.ftiFlag === -1" v-bind:title=record.processMsg><a
style="color: #d71345">{{record.title}}</a></span>
<span v-else-if="record.ftiFlag === 0" title="等待入库"><a style="color: #fa8c16">{{record.title}}</a></span>
<span v-else @click="showDrawer(record)" :title ="[ record.fileType + '文件-大小:'+ record.fileSize +' B'] "><a style="color: #303133">{{ record.title}}</a></span>
</span>
</a-table>
</div>
<b-j-modal :title="previewTitle"
:width="width"
:visible="previewVisible"
@cancel="handleCancel"
cancelText="关闭"
:okButtonProps="{ class:{'jee-hidden': true} }">
<div>
<div>
<p-d-f-modal :p-d-furl="PDFurl" :iframeWidth="width"/>
</div>
</div>
</b-j-modal>
</a-card>
</template>
<script>
import {ajaxGetDictItems, getDictItemsFromCache} from '@/api/api'
import {ACCESS_TOKEN, USER_INFO} from "@/store/mutation-types"
import SubjectModal from "./modules/SubjectModal";
import {downloadFileName, httpAction, httpPostAction, getAction} from '@/api/manage'
import '@/assets/less/TableExpand.less'
import {mixinDevice} from '@/utils/mixin'
import {JeecgListMixin} from '@/mixins/JeecgListMixin'
import Vue from "vue";
import DocComments from '@/views/km/Common/Comments'
import DocDetail from '@/views/km/Common/DocDetail'
import DraftDocEdit from '@/views/km/filemanagement/modules/DraftDocEdit'
import store from "@comp/tools/HeaderNotice";
export default {
name: 'AuditList',
mixins: [JeecgListMixin, mixinDevice],
components: {
SubjectModal,
DocComments,
DocDetail,
DraftDocEdit
},
data() {
return {
headers: {
authorization: 'authorization-text',
'X-Access-Token': Vue.ls.get(ACCESS_TOKEN)
},
//
columns: [],
//
settingColumns: [],
//filter
filterDictCode: 'km_dict_source',
//
filterOptions: [],
//
defColumns: [
{
title: '操作',
dataIndex: 'action',
align: "left",
fixed: "left",
width: 105,
scopedSlots: {
filterDropdown: 'filterDropdown',
filterIcon: 'filterIcon',
customRender: 'action'
}
},
{
title: '标题',
align: "left",
scopedSlots: {customRender: 'docTitle'},
customCell: () => {
return {
style: {
'max-width': '30em',
},
};
},
dataIndex: 'title'
},
{
title: '分类',
align: "center",
sorter: true,
customCell: () => {
return {
style: {
'max-width': '8em',
},
};
},
dataIndex: 'category_dictText'
},
{
title: '标签',
align: "center",
dataIndex: 'businessTypes_dictText',
customCell: () => {
return {
style: {
'max-width': '10em',
overflow: 'hidden',
whiteSpace: 'nowrap',
textOverflow:'ellipsis'
},
};
}
},
{
title: '关键字',
align: "center",
dataIndex: 'keywords',
customCell: () => {
return {
style: {
'max-width': '10em',
overflow: 'hidden',
whiteSpace: 'nowrap',
textOverflow:'ellipsis'
},
};
}
},
],
PDFurl: '',
labelCol: {
xs: {span: 24},
sm: {span: 6},
},
labelCol1: {
xs: {span: 12},
sm: {span: 12},
},
labelCol2: {
xs: {span: 3},
sm: {span: 3},
},
wrapperCol: {
xs: {span: 24},
sm: {span: 18},
},
wrapperCol1: {
xs: {span: 10},
sm: {span: 10},
},
wrapperCol2: {
xs: {span: 21},
sm: {span: 21},
},
confirmLoading: false,
pdfLoading: false,
//
validatorRules: {
depId: [{required: true, message: '请选择部门!'}],
},
// title: "",
width: '900',
url: {
list: "/KM/kmDoc/listPassed",
delete: "/KM/kmDoc/delete",
previewKmDoc: '/KM/kmDoc/previewKmDoc',
downloadKmDoc: "/KM/kmDoc/downloadKmDoc",
},
uid: '',
userInfo: {},
showDocDetail: {},
configDetail: {},
drawerVisible: false,
configVisible: false,
previewVisible: false,
previewTitle: "预览 - ",
}
},
created() {
//token
Vue.prototype.token = Vue.ls.get(ACCESS_TOKEN);
window._CONFIG['token'] = Vue.prototype.token
// table
this.initColumns();
this.initFilterDict();
// let userInfo = Vue.ls.get(USER_INFO)
let userInfo = this.$store.getters.userInfo
this.uid = userInfo.id
this.userInfo = userInfo
},
methods: {
//
showDrawer(record) {
this.showDocDetail = record
this.drawerVisible = true
},
onDrawerClose() {
this.drawerVisible = false
},
docEditable: function (record) {
let editAbleFileType = ['doc', 'docm', 'docx', 'dot', 'dotm', 'dotx', 'epub', 'fodt', 'htm', 'html', 'mht', 'odt', 'ott', 'pdf', 'rtf', 'txt', 'djvu', 'xps','csv', 'fods', 'ods', 'ots', 'xls', 'xlsm', 'xlsx', 'xlt', 'xltm', 'xltx','fodp', 'odp', 'otp', 'pot', 'potm', 'potx', 'pps', 'ppsm', 'ppsx', 'ppt', 'pptm', 'pptx' ]
return editAbleFileType.indexOf(record.fileType) >=0
},
//
editKmDoc(record){
let editorUrl = window._CONFIG['domianURL'] + '/onlyoffice/editor?'
editorUrl = editorUrl + 'docId=' + record.id
editorUrl = editorUrl + '&uid=' + this.uid
editorUrl = editorUrl + '&fileName=' + record.title + '.'+ record.fileType
window.open(editorUrl,"_blank")
// let option ={
// url: '',
// isEdit: '',
// fileType: '',
// title: '',
// lang: '',
// isPrint: '',
// user: { id:null,name:''}
// }
// this.$router.push({path: '/Km/filemanagement/VabOnlyOfficeEditor', query: {selected: "2"}})
},
configDoc(record){
this.configVisible = true
this.configDetail = record
},
//
previewKmDoc(record) {
this.PDFurl = this.url.previewKmDoc + "?docId=" + record.id;
this.pdfLoading = true;
this.previewVisible = true;
this.previewTitle = "预览 - " + record.title
},
//
handleCancel() {
console.log("cancel ")
this.configVisible = false
this.previewVisible = false;
this.model = {};
},
editOk(){
this.configVisible=false
this.loadData()
},
// filter
initFilterDict() {
//Code,
ajaxGetDictItems(this.filterDictCode, null).then((res) => {
if (res.success) {
let options = res.result
console.log(options);
options.forEach((item, index) => {
let filterOption = {};
filterOption.text = item.title;
filterOption.value = item.value;
this.filterOptions.push(filterOption);
});
this.defColumns[4].filters =this.filterOptions;
}
})
},
//
onColSettingsChange(checkedValues) {
var key = this.$route.name + ":colsettings";
console.log("colsettings", key);
Vue.ls.set(key, checkedValues, 30 * 7 * 24 * 60 * 60 * 1000)
this.settingColumns = checkedValues;
const cols = this.defColumns.filter(item => {
if (item.key == 'rowIndex' || item.dataIndex == 'action') {
return true
}
if (this.settingColumns.includes(item.dataIndex)) {
return true
}
return false
})
this.columns = cols;
},
//
initColumns() {
var key = this.$route.name + ":colsettings";
console.log("colsettings", key);
let colSettings = Vue.ls.get(key);
if (colSettings == null || colSettings == undefined) {
let allSettingColumns = [];
this.defColumns.forEach(function (item, i, array) {
allSettingColumns.push(item.dataIndex);
})
this.settingColumns = allSettingColumns;
this.columns = this.defColumns;
} else {
this.settingColumns = colSettings;
const cols = this.defColumns.filter(item => {
if (item.key == 'rowIndex' || item.dataIndex == 'action') {
return true;
}
if (colSettings.includes(item.dataIndex)) {
return true;
}
return false;
})
this.columns = cols;
}
},
//
downloadKmDoc(record) {
this.$notification.success({
message: '文件开始下载...',
duration: 1,
});
downloadFileName(this.url.downloadKmDoc, {docId: record.id})
},
//
confirm(record) {
let person = {id: record.id, releaseFlag: record.releaseFlag === 0 ? 1: 0};
let mes = record.releaseFlag === 0? "启用": "禁用";
let httpurl = this.url.editReleaseFlag;
let method = 'put';
httpAction(httpurl, person, method).then((res) => {
if (res.success) {
this.$message.success(mes + "成功!");
this.loadData();
} else {
this.$message.warning(mes + "失败!");
}
}).finally(() => {
})
},
//
downloadKmDocBatch() {
console.log("批量下载")
if (!this.url.downloadKmDoc) {
this.$message.error("请设置url.downloadKmDoc属性!")
return
}
if (this.selectionRows.length <= 0) {
this.$message.warning('请选择一条记录!');
return;
} else {
var that = this;
this.$confirm({
title: "确认下载",
content: "是否下载选中数据?",
onOk: function () {
for (var i = 0; i < that.selectionRows.length; i++) {
let fileName = i;
downloadFileName(that.url.downloadKmDoc, {docId: that.selectionRows[i].id})
}
that.loadData();
that.onClearSelected();
}
});
}
},
refreshDocDetail(){
console.log("emit new from comments and call docDetail refreshDocDetail....")
this.$refs.docDetailRef.refreshDocDetail()
}
}
}
</script>
<style scoped>
@import '~@assets/less/common.less';
</style>

@ -18,28 +18,15 @@
</a-form-item>
</a-col>
<template v-if="toggleSearchStatus">
<!-- <a-col :xl="6" :lg="7" :md="8" :sm="24">-->
<!-- <a-form-item label="编号">-->
<!-- <a-input placeholder="请输入编号" v-model="queryParam.serialNumber"></a-input>-->
<!-- </a-form-item>-->
<!-- </a-col>-->
<a-col :xl="6" :lg="7" :md="8" :sm="24">
<a-form-item label="编号">
<a-input placeholder="请输入编号" v-model="queryParam.serialNumber"></a-input>
</a-form-item>
</a-col>
<a-col :xl="6" :lg="7" :md="8" :sm="24">
<a-form-item label="来源">
<j-multi-select-tag type="list_multi" placeholder="请选择来源" v-model="queryParam.sourceList"
dictCode="km_dict_source"></j-multi-select-tag>
</a-form-item>
</a-col>
<a-col :xl="6" :lg="7" :md="8" :sm="24">
<a-form-model-item label="版本状态">
<j-multi-select-tag type="list_multi" v-model="queryParam.versionList" :trigger-change="true"
placeholder="请选择版本状态" dictCode="km_dict_versions"></j-multi-select-tag>
</a-form-model-item>
</a-col>
<a-col :xl="6" :lg="7" :md="8" :sm="24">
<a-form-model-item label="涉及业务">
<a-form-model-item label="标签">
<j-multi-select-tag type="list_multi" v-model="queryParam.businessTypeList" :trigger-change="true"
placeholder="请选择涉及业务" dictCode="km_dict_business"></j-multi-select-tag>
placeholder="请选择标签" dictCode="km_dict_business"></j-multi-select-tag>
</a-form-model-item>
</a-col>
@ -49,26 +36,12 @@
</a-form-item>
</a-col>
<a-col :xl="6" :lg="7" :md="8" :sm="24">
<a-form-item label="文号">
<a-input placeholder="请输入文号" v-model="queryParam.fileNo" @change="transitionQueryFileNo"></a-input>
</a-form-item>
</a-col>
<a-col :xl="6" :lg="7" :md="8" :sm="24">
<a-form-item label="文件类型">
<a-input placeholder="请输入文件类型" v-model="queryParam.fileType"></a-input>
</a-form-item>
</a-col>
<a-col :xl="12" :lg="14" :md="16" :sm="48">
<a-form-item label="发文时间">
<j-dict-select-tag type="list" placeholder="请选择开始时间" v-model="queryParam.pubTimeStart" style="width:40%"
dictCode="km_dict_year"></j-dict-select-tag>
<span class="query-group-split-cust"></span>
<j-dict-select-tag type="list" placeholder="请选择结束时间" v-model="queryParam.pubTimeEnd" style="width: 40%"
dictCode="km_dict_year"></j-dict-select-tag>
</a-form-item>
</a-col>
<a-col :xl="12" :lg="14" :md="16" :sm="48">
<a-form-item label="上传时间">
<j-date :show-time="true" date-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择开始时间"
@ -94,7 +67,28 @@
</a-form>
</div>
<!-- 查询区域-END ant-alert ant-alert-info -->
<!-- 详情区域-BEGIN -->
<a-drawer
:title="showDocDetail.title"
:width="720"
:visible="drawerVisible"
:body-style="{ paddingBottom: '80px' }"
:footer-style="{ textAlign: 'right' }"
@close="onDrawerClose"
>
<doc-detail ref="docDetailRef" :record="showDocDetail"></doc-detail>
<br/>
<a-divider style="margin: 5px 0 15px 0 "></a-divider>
<doc-comments
ref="comments"
@new="refreshDocDetail"
:doc-id="showDocDetail.id">
</doc-comments>
</a-drawer>
<!-- 详情区域-END -->
<!-- 操作按钮区域 -->
<div class="table-operator">
<!-- <a-button type="primary" icon="download" @click="handleExportXls('草稿文件夹')"></a-button>-->
@ -172,29 +166,26 @@
下载
</a-button>
</template>
<span slot="action" slot-scope="text, record">
<a-space>
<a-icon type="read" title="预览" @click="previewKmDoc(record)"
:style="{ fontSize: '18px', color: '#1890FF', }" style="margin-left: 5px"/>
<a-popconfirm title="确定取消收藏吗?" @confirm="() => delFavouriteKmDoc(record)">
<a-icon type="delete" title="取消收藏" :style="{ fontSize: '18px', color: '#1890FF', }" style="margin-left: 5px"/>
</a-popconfirm>
<!--<a-icon type="read" title="预览" @click="previewKmDoc(record,true)"-->
<!--:style="{ fontSize: '18px', color: '#1890FF', }" style="margin-left: 5px"/>-->
<a-icon type="download" title="下载" @click="downloadKmDoc(record)"
:style="{ fontSize: '18px', color: '#1890FF'}" style="margin-left: 5px"/>
</a-space>
</span>
<span slot="docTitle" slot-scope="text,record">
<span @click="previewKmDoc(record,true)"><a style="color: #303133">{{ record.title}}</a></span>
<span @click="showDrawer(record,true)" :title ="[ record.fileType + '文件-大小:'+ record.fileSize +' B'] "><a style="color: #303133">{{ record.title}}</a></span>
</span>
</a-table>
</div>
<b-j-modal :title="title"
<b-j-modal :title="previewTitle"
:width="width"
:visible="visibleB"
:visible="previewVisible"
@cancel="handleCancel"
cancelText="关闭"
:okButtonProps="{ class:{'jee-hidden': true} }">
@ -209,30 +200,26 @@
<script>
import {ajaxGetDictItems, getDictItemsFromCache} from '@/api/api'
import {ACCESS_TOKEN} from "@/store/mutation-types"
import {ACCESS_TOKEN, USER_INFO} from "@/store/mutation-types"
import '@/assets/less/TableExpand.less'
import {mixinDevice} from '@/utils/mixin'
import {JeecgListMixin} from '@/mixins/JeecgListMixin'
import SubjectModal from "./modules/SubjectModal";
import UploadModal from "./modules/UploadModal";
import {httpPostAction, httpAction, getAction, downloadFileName} from '@/api/manage'
import Vue from "vue";
import DocComments from '@/views/km/Common/Comments'
import DocDetail from '@/views/km/Common/DocDetail'
import store from "@comp/tools/HeaderNotice";
export default {
name: 'FavouriteList',
mixins: [JeecgListMixin, mixinDevice],
components: {
UploadModal,
SubjectModal,
components:{
DocComments,
DocDetail
},
data() {
return {
// switch
switchPublicFlag: true,
// switch
switchDownloadFlag: true,
description: '收藏夹',
//
columns: [],
//
@ -248,26 +235,13 @@
dataIndex: 'action',
align: "center",
fixed: "left",
width: 65,
width: 80,
scopedSlots: {
filterDropdown: 'filterDropdown',
filterIcon: 'filterIcon',
customRender: 'action'
}
},
{
title: '分类',
align: "center",
sorter: true,
customCell: () => {
return {
style: {
'max-width': '8em',
},
};
},
dataIndex: 'category_dictText'
},
{
title: '标题',
align: "left",
@ -282,74 +256,51 @@
dataIndex: 'title'
},
{
title: '来源',
align: "center",
customCell: () => {
return {
style: {
'max-width': '7em',
},
};
},
filters: [],
dataIndex: 'source_dictText'
},
{
title: '发文时间',
title: '分类',
align: "center",
sorter: true,
customCell: () => {
return {
style: {
'max-width': '11em',
},
};
},
dataIndex: 'pubTimeTxt'
},
{
title: '版本状态',
align: "center",
customCell: () => {
return {
style: {
'max-width': '12em',
'max-width': '8em',
},
};
},
dataIndex: 'versions_dictText'
dataIndex: 'category_dictText'
},
{
title: '涉及业务',
title: '标签',
align: "center",
dataIndex: 'businessTypes_dictText',
customCell: () => {
return {
style: {
'max-width': '12em',
'max-width': '10em',
overflow: 'hidden',
whiteSpace: 'nowrap',
textOverflow:'ellipsis'
},
};
},
dataIndex: 'businessTypes_dictText'
},
{
title: '文号',
title: '关键字',
align: "center",
dataIndex: 'keywords',
customCell: () => {
return {
style: {
'max-width': '12em',
'max-width': '10em',
overflow: 'hidden',
whiteSpace: 'nowrap',
textOverflow:'ellipsis'
},
};
},
dataIndex: 'fileNo'
},
}
}
],
PDFurl: '',
visible: false,
visibleB: false,
model: {},
urlAction: window._CONFIG['domianURL'] + "/KM/kmDoc/changePreviewFile?docId=",
headers: {
authorization: 'authorization-text',
'X-Access-Token': Vue.ls.get(ACCESS_TOKEN)
@ -370,17 +321,7 @@
xs: {span: 12},
sm: {span: 12},
},
confirmLoading: false,
loadedRatio: 0,
pdfLoading: false,
pdfShow: true,
resetPreviewShow: false,
validatorRules: {},
formDisabled: false,
versions: '',
businessTypes: '',
title: "编辑",
width: 900,
width: "900",
url: {
list: "/KM/kmDocFavourite/list",
delFavouriteKmDoc: '/KM/kmDocFavourite/delete',
@ -390,37 +331,30 @@
},
dictOptions: {},
superFieldList: [],
}
uid: '',
userInfo: {},
showDocDetail: {},
drawerVisible: false,
previewVisible: false,
previewTitle: "预览 - ", }
},
created() {
this.getSuperFieldList();
//token
Vue.prototype.token = Vue.ls.get(ACCESS_TOKEN);
window._CONFIG['token'] = Vue.prototype.token;
// table
this.initColumns();
this.initFilterDict();
},
computed: {
importExcelUrl: function () {
return `${window._CONFIG['domianURL']}/${this.url.importExcelUrl}`;
},
},
watch: {
loadedRatio: {
handler(newVal, oldVal) {
if (newVal === 1) {
this.pdfLoading = false;
}
}
}
// let userInfo = Vue.ls.get(USER_INFO)
let userInfo = this.$store.getters.userInfo
this.uid = userInfo.id
this.userInfo = userInfo
},
methods: {
// filter
initFilterDict() {
//Code,
ajaxGetDictItems(this.filterDictCode, null).then((res) => {
if (res.success) {
@ -435,7 +369,6 @@
this.defColumns[3].filters =this.filterOptions;
}
})
},
//
onColSettingsChange(checkedValues) {
@ -456,7 +389,6 @@
},
//
initColumns() {
var key = this.$route.name + ":colsettings";
console.log("colsettings", key);
let colSettings = Vue.ls.get(key);
@ -481,24 +413,6 @@
this.columns = cols;
}
},
initDictConfig() {
},
getSuperFieldList() {
let fieldList = [];
fieldList.push({type: 'string', value: 'serialNumber', text: '编号', dictCode: ''})
fieldList.push({type: 'string', value: 'category', text: '分类', dictCode: ''})
fieldList.push({type: 'string', value: 'title', text: '标题', dictCode: ''})
fieldList.push({type: 'string', value: 'source', text: '来源', dictCode: ''})
fieldList.push({type: 'datetime', value: 'pubTime', text: '发文时间'})
fieldList.push({type: 'string', value: 'versions', text: '版本状态', dictCode: ''})
fieldList.push({type: 'string', value: 'businessTypes', text: '涉及业务', dictCode: ''})
fieldList.push({type: 'string', value: 'keywords', text: '关键字', dictCode: ''})
fieldList.push({type: 'datetime', value: 'createTime', text: '上传时间'})
fieldList.push({type: 'string', value: 'fileType', text: '文件类型', dictCode: ''})
this.superFieldList = fieldList
},
//
downloadKmDoc(record) {
this.$notification.success({
@ -533,53 +447,33 @@
});
}
},
showDrawer(record) {
this.showDocDetail = record
this.drawerVisible = true
},
onDrawerClose() {
this.drawerVisible = false
},
//
editKmDoc(record){
let editorUrl = window._CONFIG['domianURL'] + '/onlyoffice/editor?'
editorUrl = editorUrl + 'docId=' + record.id
editorUrl = editorUrl + '&uid=' + this.uid
editorUrl = editorUrl + '&fileName=' + record.title + '.'+ record.fileType
window.open(editorUrl,"_blank")
},
//
previewKmDoc(record, boolFormDisabled) {
if (boolFormDisabled) {
this.title = "预览"
this.visibleB = true;
} else {
this.title = "编辑";
this.visible = true;
}
this.model = {};
this.model = Object.assign({}, record);
console.log("model", this.model);
if (this.model.depId == null || this.model.depId === "") {
var depId = Vue.ls.get("Dep_ID");
console.log("部门数据为空,从本地中获取数据", depId);
this.model.depId = depId
}
this.versions = this.model.versions;
this.formDisabled = boolFormDisabled;
this.businessTypes = this.model.businessTypes;
// this.PDFurl = window._CONFIG['domianURL'] + this.url.previewKmDoc + "?docId=" + record.id;
previewKmDoc(record) {
this.PDFurl = this.url.previewKmDoc + "?docId=" + record.id;
this.pdfLoading = true;
this.pdfShow = true;
if (this.model.previewFileId != this.model.originalPreviewFileId) {
this.resetPreviewShow = true;
}
// 1 0 switchtruefalse
if (this.model.publicFlag === 1) {
this.switchPublicFlag = true;
} else {
this.switchPublicFlag = false;
}
// 1 0 switchtruefalse
if (this.model.downloadFlag === 1) {
this.switchDownloadFlag = true;
} else {
this.switchDownloadFlag = false;
}
this.previewVisible = true;
this.previewTitle = "预览 - " + record.title
},
//
//
handleCancel() {
this.visible = false;
this.visibleB = false;
this.model = {};
console.log("cancel ")
this.configVisible = false
this.previewVisible = false;
},
//
@ -598,14 +492,10 @@
}).finally(() => {
})
},
transitionQueryFileNo() {
//
if (typeof (this.queryParam.fileNo) !== "undefined") {
this.queryParam.fileNo = this.queryParam.fileNo.replace(/\[/g, '');
this.queryParam.fileNo = this.queryParam.fileNo.replace(/\]/g, '');
}
},
refreshDocDetail(){
console.log("emit new from comments and call docDetail refreshDocDetail....")
this.$refs.docDetailRef.refreshDocDetail()
}
}
}

@ -0,0 +1,630 @@
<template>
<a-card :bordered="false">
<!-- 查询区域 -->
<div class="table-page-search-wrapper">
<a-form layout="inline" @keyup.enter.native="searchQuery">
<a-row :gutter="24">
<a-col :xl="6" :lg="7" :md="8" :sm="24">
<a-form-item label="标题">
<a-input placeholder="请输入标题" v-model="queryParam.title"></a-input>
</a-form-item>
</a-col>
<a-col :xl="6" :lg="7" :md="8" :sm="24">
<a-form-item label="分类">
<j-dict-select-tag type="list" placeholder="请选择分类" v-model="queryParam.category"
dictCode="km_dict_category"></j-dict-select-tag>
</a-form-item>
</a-col>
<a-col :xl="6" :lg="7" :md="8" :sm="24">
<a-form-model-item label="归属部门" prop="depId">
<j-select-depart v-model="queryParam.depId" :multi="true"></j-select-depart>
</a-form-model-item>
</a-col>
<template v-if="toggleSearchStatus">
<a-col :xl="6" :lg="7" :md="8" :sm="24">
<a-form-model-item label="标签">
<j-multi-select-tag type="list_multi" v-model="queryParam.businessTypeList" :trigger-change="true"
placeholder="请选择标签" dictCode="km_dict_business"></j-multi-select-tag>
</a-form-model-item>
</a-col>
<a-col :xl="6" :lg="7" :md="8" :sm="24">
<a-form-item label="关键字">
<a-input placeholder="请输入关键字" v-model="queryParam.keywords"></a-input>
</a-form-item>
</a-col>
<a-col :xl="6" :lg="7" :md="8" :sm="24">
<a-form-item label="文件类型">
<a-input placeholder="请输入文件类型" v-model="queryParam.fileType"></a-input>
</a-form-item>
</a-col>
<a-col :xl="12" :lg="14" :md="16" :sm="48">
<a-form-item label="上传时间">
<j-date :show-time="true" date-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择开始时间"
class="query-group-cust" v-model="queryParam.createTimeStart"></j-date>
<span class="query-group-split-cust"></span>
<j-date :show-time="true" date-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择结束时间"
class="query-group-cust" v-model="queryParam.createTimeEnd"></j-date>
</a-form-item>
</a-col>
</template>
<a-col :xl="6" :lg="7" :md="8" :sm="24">
<span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
<a-button type="primary" @click="searchQuery" icon="search">查询</a-button>
<a-button @click="searchReset" icon="reload" style="margin-left: 8px">重置</a-button>
<a @click="handleToggleSearch" style="margin-left: 8px">
{{ toggleSearchStatus ? '收起' : '展开' }}
<a-icon :type="toggleSearchStatus ? 'up' : 'down'"/>
</a>
</span>
</a-col>
</a-row>
</a-form>
</div>
<!-- 查询区域-END ant-alert ant-alert-info -->
<!-- config区域-BEGIN -->
<a-j-modal :width="width"
:visible="configVisible"
:show-return="true"
@cancel="handleCancel"
@close="handleCancel"
:destroyOnClose="true"
cancelText="关闭"
:okButtonProps="{ class:{'jee-hidden': true} }">
<draft-doc-edit :model="configDetail"
:release-button="true"
:dup-check=true
@cancel="handleCancel"
@ok="editOk" >
</draft-doc-edit>
</a-j-modal>
<!-- config区域-END -->
<!-- 详情区域-BEGIN -->
<a-drawer
:title="showDocDetail.title"
:width="720"
:visible="drawerVisible"
:body-style="{ paddingBottom: '80px' }"
:footer-style="{ textAlign: 'right' }"
@close="onDrawerClose"
>
<doc-detail ref="docDetailRef" :record="showDocDetail"></doc-detail>
<br/>
<a-divider style="margin: 5px 0 15px 0 "></a-divider>
<doc-comments ref="comments"
@new="refreshDocDetail"
:doc-id="showDocDetail.id">
</doc-comments>
</a-drawer>
<!-- 详情区域-END -->
<!-- 操作按钮区域 -->
<div class="table-operator">
<a-dropdown v-if="selectedRowKeys.length > 0">
<a-menu slot="overlay">
<a-menu-item key="1" @click="batchAuditPass">
<a-icon type="check"/>
批量通过
</a-menu-item>
<a-menu-item key="2" @click="batchAuditReject">
<a-icon type="close"/>
批量拒绝
</a-menu-item>
<a-menu-item key="3" @click="downloadKmDocBatch">
<a-icon type="vertical-align-bottom"/>
批量下载
</a-menu-item>
</a-menu>
<a-button style="margin-left: 8px"> 批量操作
<a-icon type="down"/>
</a-button>
</a-dropdown>
</div>
<!-- table区域-begin -->
<div>
<div v-if="selectedRowKeys.length > 0" class="ant-alert ant-alert-info" style="margin-bottom: 8px;">
<i class="anticon anticon-info-circle ant-alert-icon"></i> 已选择 <a style="font-weight: 600">{{
selectedRowKeys.length }}</a>
<a style="margin-left: 24px" @click="onClearSelected"></a>
</div>
<a-table
ref="table"
size="middle"
bordered
rowKey="id"
:columns="columns"
:dataSource="dataSource"
:pagination="ipagination"
:loading="loading"
:rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
@change="handleTableChange">
//
<div slot="filterDropdown">
<a-card style="width: 350px">
<a-checkbox-group @change="onColSettingsChange" v-model="settingColumns" :defaultValue="settingColumns">
<a-row>
<template v-for="(item,index) in defColumns">
<template v-if="item.key!='rowIndex'&& item.dataIndex!='action'">
<a-col :span="12">
<a-checkbox :value="item.dataIndex">{{ item.title }}</a-checkbox>
</a-col>
</template>
</template>
</a-row>
</a-checkbox-group>
</a-card>
</div>
<a-icon slot="filterIcon" type='setting' title="自定义列"
:style="{ fontSize:'16px',color: '#108ee9',minWidth:'50px'}"/>
<template slot="htmlSlot" slot-scope="text">
<div v-html="text"></div>
</template>
<template slot="imgSlot" slot-scope="text">
<span v-if="!text" style="font-size: 12px;font-style: italic;"></span>
<img v-else :src="getImgView(text)" height="25px" alt=""
style="max-width:80px;font-size: 12px;font-style: italic;"/>
</template>
<template slot="fileSlot" slot-scope="text">
<span v-if="!text" style="font-size: 12px;font-style: italic;"></span>
<a-button
v-else
:ghost="true"
type="primary"
icon="download"
size="small"
@click="downloadFile(text)">
下载
</a-button>
</template>
<span slot="action" slot-scope="text, record">
<a-space>
<a-popover content="通过审核">
<a-popconfirm title="确定通过吗?" @confirm="() => handleAuditPass(record.id)">
<a-icon type="check-circle" title="通过" :style="{ fontSize: '18px', color: 'green', }"/>
</a-popconfirm>
</a-popover>
<a-popover content="驳回">
<a-popconfirm title="确定驳回吗?" @confirm="() => handleAuditReject(record.id)">
<a-icon type="close-circle" title="驳回" :style="{ fontSize: '18px', color: 'red', }"/>
</a-popconfirm>
</a-popover>
<a-popover content="预览">
<a-icon type="read" title="预览" @click="previewKmDoc(record)"
:style="{ fontSize: '18px', color: '#1890FF', }"/>
</a-popover>
<a-popover content="下载">
<a-icon type="download" title="下载" @click="downloadKmDoc(record)"
:style="{ fontSize: '18px', color: '#1890FF'}" />
</a-popover>
<a-divider type="vertical"/>
<a-dropdown>
<a class="ant-dropdown-link"><a-icon :style="{ fontSize: '18px', color: '#1890FF'}" type="down-circle"/></a>
<a-menu slot="overlay">
<!-- <a-menu-item>-->
<!-- <a v-show="docEditable(record)" @click="editKmDoc(record)"></a>-->
<!-- </a-menu-item>-->
<a-menu-item>
<a @click="configDoc(record)"></a>
</a-menu-item>
<a-menu-item>
<a @click="downloadKmDoc(record)"></a>
</a-menu-item>
<a-menu-item>
<a-popconfirm title="确定删除吗?" @confirm="() => handleDelete(record.id)">
<a>删除</a>
</a-popconfirm>
</a-menu-item>
</a-menu>
</a-dropdown>
</a-space>
</span>
<span slot="docTitle" slot-scope="text,record">
<span v-if="record.convertFlag === -1" v-bind:title=record.processMsg><a style="color: #d71345">{{record.title}}</a></span>
<span v-else-if="record.convertFlag === 0" title="等待转换"><a style="color: #fa8c16">{{record.title}}</a></span>
<span v-else @click="showDrawer(record)" :title ="[ record.fileType + '文件-大小:'+ record.fileSize +' B'] "><a style="color: #303133">{{ record.title}}</a></span>
</span>
</a-table>
</div>
<b-j-modal :title="previewTitle"
:width="width"
:visible="previewVisible"
@cancel="handleCancel"
cancelText="关闭"
:okButtonProps="{ class:{'jee-hidden': true} }">
<div>
<div>
<p-d-f-modal :p-d-furl="PDFurl" :iframeWidth="width" :pdf-loading="pdfLoading" />
</div>
</div>
</b-j-modal>
</a-card>
</template>
<script>
import {ajaxGetDictItems, getDictItemsFromCache} from '@/api/api'
import {ACCESS_TOKEN, USER_INFO} from "@/store/mutation-types"
import {downloadFileName, httpPostAction, httpAction, getAction} from '@/api/manage'
import '@/assets/less/TableExpand.less'
import {mixinDevice} from '@/utils/mixin'
import {JeecgListMixin} from '@/mixins/JeecgListMixin'
import SubjectModal from "./modules/SubjectModal"
import Vue from "vue"
import DocComments from '@/views/km/Common/Comments'
import DocDetail from '@/views/km/Common/DocDetail'
import DraftDocEdit from '@/views/km/filemanagement/modules/DraftDocEdit'
import store from "@comp/tools/HeaderNotice";
export default {
name: 'PendingList',
mixins: [JeecgListMixin, mixinDevice],
components: {
SubjectModal,
DocComments,
DocDetail,
DraftDocEdit
},
data() {
return {
//
columns: [],
//
settingColumns: [],
//
filterOptions: [],
//
defColumns: [
{
title: '操作',
dataIndex: 'action',
align: "center",
fixed: "left",
width: 180,
scopedSlots: {
filterDropdown: 'filterDropdown',
filterIcon: 'filterIcon',
customRender: 'action'
}
},
{
title: '标题',
align: "left",
dataIndex: 'title',
scopedSlots: {customRender: 'docTitle'},
customCell: () => {
return {
style: {
'max-width': '30em',
},
};
},
},
{
title: '分类',
align: "center",
dataIndex: 'category_dictText',
sorter: true,
customCell: () => {
return {
style: {
'max-width': '6em',
},
};
},
},
{
title: '标签',
align: "center",
dataIndex: 'businessTypes_dictText',
customCell: () => {
return {
style: {
'max-width': '10em',
overflow: 'hidden',
whiteSpace: 'nowrap',
textOverflow:'ellipsis'
},
};
},
},
{
title: '关键字',
align: "center",
dataIndex: 'keywords',
customCell: () => {
return {
style: {
'max-width': '10em',
overflow: 'hidden',
whiteSpace: 'nowrap',
textOverflow:'ellipsis'
},
};
},
},
{
title: '上传人',
align: "center",
dataIndex: 'createBy',
sorter: true,
customCell: () => {
return {
style: {
'max-width': '3em',
},
};
},
},
{
title: '归属部门',
align: "center",
dataIndex: 'orgCode_dictText',
sorter: true,
customCell: () => {
return {
style: {
'max-width': '5em',
},
};
},
},
],
PDFurl: '',
model: {},
headers: {
authorization: 'authorization-text',
'X-Access-Token': Vue.ls.get(ACCESS_TOKEN)
},
confirmLoading: false,
pdfLoading: false,
title: "编辑",
width: "900",
url: {
list: "/KM/kmDoc/listWaitAudit",
auditPass: '/KM/kmDoc/auditPass',
auditReject: '/KM/kmDoc/auditReject',
batchAuditPass: '/KM/kmDoc/auditPassBatch',
batchAuditReject: 'KM/kmDoc/auditRejectBatch',
previewKmDoc: '/KM/kmDoc/previewKmDoc',
downloadKmDoc: "/KM/kmDoc/downloadKmDoc",
},
// superFieldList: [],
uid: '',
userInfo: {},
showDocDetail: {},
configDetail: {},
drawerVisible: false,
configVisible: false,
previewVisible: false,
previewTitle: "预览 - ",
}
},
created() {
// this.getSuperFieldList();
//token
Vue.prototype.token = Vue.ls.get(ACCESS_TOKEN);
window._CONFIG['token'] = Vue.prototype.token;
// table
this.initColumns();
this.initFilterDict();
// let userInfo = Vue.ls.get(USER_INFO)
let userInfo = this.$store.getters.userInfo
this.uid = userInfo.id
this.userInfo = userInfo
},
methods: {
//
showDrawer(record) {
this.showDocDetail = record
this.drawerVisible = true
},
onDrawerClose() {
this.drawerVisible = false
},
docEditable: function (record) {
let editAbleFileType = ['doc', 'docm', 'docx', 'dot', 'dotm', 'dotx', 'epub', 'fodt', 'htm', 'html', 'mht', 'odt', 'ott', 'pdf', 'rtf', 'txt', 'djvu', 'xps','csv', 'fods', 'ods', 'ots', 'xls', 'xlsm', 'xlsx', 'xlt', 'xltm', 'xltx','fodp', 'odp', 'otp', 'pot', 'potm', 'potx', 'pps', 'ppsm', 'ppsx', 'ppt', 'pptm', 'pptx' ]
// console.log(record.fileType+ ":"+editAbleFileType.indexOf(record.fileType))
return editAbleFileType.indexOf(record.fileType) >=0
},
//
editKmDoc(record){
let editorUrl = window._CONFIG['domianURL'] + '/onlyoffice/editor?'
editorUrl = editorUrl + 'docId=' + record.id
editorUrl = editorUrl + '&uid=' + this.uid
editorUrl = editorUrl + '&fileName=' + record.title + '.'+ record.fileType
// console.log("editorUrl:",editorUrl)
window.open(editorUrl,"_blank")
// let option ={
// url: '',
// isEdit: '',
// fileType: '',
// title: '',
// lang: '',
// isPrint: '',
// user: { id:null,name:''}
// }
// this.$router.push({path: '/Km/filemanagement/VabOnlyOfficeEditor', query: {selected: "2"}})
},
configDoc(record){
this.configVisible = true
this.configDetail = record
},
//
previewKmDoc(record) {
this.PDFurl = this.url.previewKmDoc + "?docId=" + record.id;
this.pdfLoading = true;
this.previewVisible = true;
this.previewTitle = "预览 - " + record.title
},
//
handleCancel() {
console.log("cancel ")
this.configVisible = false
this.previewVisible = false;
this.model = {};
},
editOk(){
this.configVisible=false
this.loadData()
},
// filter
initFilterDict() {
//Code,
ajaxGetDictItems(this.filterDictCode, null).then((res) => {
if (res.success) {
let options = res.result
console.log(options);
options.forEach((item, index) => {
let filterOption = {};
filterOption.text = item.title;
filterOption.value = item.value;
this.filterOptions.push(filterOption);
});
this.defColumns[2].filters =this.filterOptions;
}
})
},
//
onColSettingsChange(checkedValues) {
var key = this.$route.name + ":colsettings";
console.log("colsettings", key);
Vue.ls.set(key, checkedValues, 30 * 7 * 24 * 60 * 60 * 1000)
this.settingColumns = checkedValues;
const cols = this.defColumns.filter(item => {
if (item.key == 'rowIndex' || item.dataIndex == 'action') {
return true
}
if (this.settingColumns.includes(item.dataIndex)) {
return true
}
return false
})
this.columns = cols;
},
//
initColumns() {
//
//this.defColumns = colAuthFilter(this.defColumns,'testdemo:');
var key = this.$route.name + ":colsettings";
console.log("colsettings", key);
let colSettings = Vue.ls.get(key);
if (colSettings == null || colSettings == undefined) {
let allSettingColumns = [];
this.defColumns.forEach(function (item, i, array) {
allSettingColumns.push(item.dataIndex);
})
this.settingColumns = allSettingColumns;
this.columns = this.defColumns;
} else {
this.settingColumns = colSettings;
const cols = this.defColumns.filter(item => {
if (item.key == 'rowIndex' || item.dataIndex == 'action') {
return true;
}
if (colSettings.includes(item.dataIndex)) {
return true;
}
return false;
})
this.columns = cols;
}
},
//
downloadKmDoc(record) {
this.$notification.success({
message: '文件开始下载...',
duration: 1,
});
downloadFileName(this.url.downloadKmDoc, {docId: record.id})
},
//
handleAuditPass: function (id) {
if (!this.url.auditPass) {
this.$message.error("请设置url.auditPass属性!")
return
}
var that = this;
httpPostAction(that.url.auditPass, {id: id}, 'put').then((res) => {
if (res.success) {
//
that.reCalculatePage(1)
that.$message.success(res.message);
that.loadData();
} else {
that.$message.warning(res.message);
}
});
},
//
handleAuditReject: function (id) {
if (!this.url.auditReject) {
this.$message.error("请设置url.auditReject!")
return
}
var that = this;
httpPostAction(that.url.auditReject, {id: id}, 'put').then((res) => {
if (res.success) {
//
that.reCalculatePage(1)
that.$message.success(res.message);
that.loadData();
} else {
that.$message.warning(res.message);
}
});
},
//
downloadKmDocBatch() {
console.log("批量下载")
if (!this.url.downloadKmDoc) {
this.$message.error("请设置url.downloadKmDoc属性!")
return
}
if (this.selectionRows.length <= 0) {
this.$message.warning('请选择一条记录!');
return;
} else {
var that = this;
this.$confirm({
title: "确认下载",
content: "是否下载选中数据?",
onOk: function () {
for (var i = 0; i < that.selectionRows.length; i++) {
let fileName = i;
downloadFileName(that.url.downloadKmDoc, {docId: that.selectionRows[i].id})
}
that.loadData();
that.onClearSelected();
}
});
}
},
refreshDocDetail(){
console.log("emit new from comments and call docDetail refreshDocDetail....")
this.$refs.docDetailRef.refreshDocDetail()
}
}
}
</script>
<style scoped>
@import '~@assets/less/common.less';
</style>

@ -0,0 +1,471 @@
<template>
<div>
<h3 style="color: #303133;margin-left: 10px;padding:5px">
<div v-show="editOrCompareFlag>0" @click="navBack" style="float:left;color: #303133; ;width: 10%;text-align: left">
<a style="color:#303133;">
<a-space>
<a-icon type="arrow-left"/>
<span>返回</span>
</a-space>
</a>
</div>
<div style="color: #303133;float:right;width: 90%;text-align: center">
<b>{{ model.title+'.'+model.fileType}}</b>
</div>
</h3>
<a-divider style="margin:0px"></a-divider>
<a-spin :spinning="confirmLoading" style="margin-top: 10px;float: left;width: 690px">
<j-form-container v-if="editOrCompareFlag === 0">
<a-form-model ref="form" :model="model" :rules="validatorRules" slot="detail">
<a-row>
<a-col v-if="!dupCheck" :span="24">
<a-form-model-item label="标题" :labelCol="labelCol2" :wrapperCol="wrapperCol2"
prop="title">
<a-textarea v-model="model.title" placeholder="请输入标题"
:auto-size="{ minRows: 1, maxRows: 3 }"></a-textarea>
</a-form-model-item>
</a-col>
<a-col v-if="dupCheck" :span="21">
<a-form-model-item label="标题" style="margin-left: -15px" :labelCol="labelCol3" :wrapperCol="wrapperCol3"
prop="title">
<a-textarea v-model="model.title" placeholder="请输入标题"
:auto-size="{ minRows: 1, maxRows: 3 }"></a-textarea>
</a-form-model-item>
</a-col>
<a-col v-if="dupCheck" :span="3" style="text-align: center;margin-top: 4px">
<a-button type="primary" @click="searchTitleDupDoc"></a-button>
</a-col>
<a-col :span="12">
<a-form-model-item label="分类" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="category">
<j-dict-select-tag type="list" placeholder="请选择分类" v-model="model.category"
dictCode="km_dict_category"></j-dict-select-tag>
</a-form-model-item>
</a-col>
<a-col :span="12">
<a-form-model-item label="关键字" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="keywords">
<a-textarea v-model="model.keywords" placeholder="请输入关键字"
:auto-size="{ minRows: 1, maxRows: 3 }"></a-textarea>
</a-form-model-item>
</a-col>
<a-col :span="12">
<!--专题分类-->
<a-form-model-item label="专题分类" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-textarea @click="showModel(model)" v-model="model.topicIds_dictText"
placeholder="请点击选择专题" readOnly :auto-size="{ minRows: 1, maxRows: 3 }">
</a-textarea>
</a-form-model-item>
</a-col>
<a-col :span="12">
<a-form-model-item label="标签" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="businessTypes">
<j-multi-select-tag type="list_multi" v-model="model.businessTypes" :trigger-change="true"
placeholder="请选择标签" dictCode="km_dict_business"></j-multi-select-tag>
</a-form-model-item>
</a-col>
<a-col :span="12">
<a-form-model-item label="归属部门" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="depId">
<j-select-depart v-model="model.depId" :multi="false"></j-select-depart>
</a-form-model-item>
</a-col>
<a-col :span="12">
<a-form-model-item label="公开范围" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="publicRemark">
<j-dict-select-tag type="list" placeholder="请选择公开范围" v-model="model.publicRemark"
dictCode="dict_public_remark"></j-dict-select-tag>
</a-form-model-item>
</a-col>
<a-col :span="24">
<a-form-model-item label="备注" :labelCol="labelCol2" :wrapperCol="wrapperCol2" prop="remark">
<a-textarea v-model="model.remark" placeholder="请输入备注"
:auto-size="{ minRows: 1, maxRows: 3 }"></a-textarea>
</a-form-model-item>
</a-col>
<a-col :span="6">
<a-form-model-item label="允许下载" :labelCol="labelCol1" :wrapperCol="wrapperCol1"
prop="switchDownloadFlag">
<a-switch checked-children="" un-checked-children="" v-model="switchDownloadFlag"/>
</a-form-model-item>
</a-col>
<a-col :span="12">
<a-form-model-item label="预览文件" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="keywords">
<span>
<a-popconfirm v-if="resetPreviewShow"
title="你是否将文件恢复吗?"
ok-text="确定"
cancel-text="取消"
@confirm="resetPreviewFile(model)">
<a href="#" style="margin-left: 20px;color: #1890FF">恢复</a>
</a-popconfirm>
<a-upload
name="file"
:multiple="true"
:action="changePreviewFileUrl+model.id"
:headers="headers"
@change="handleChange"
:showUploadList="false"
>
<a-button type="link" style="color: #1890FF">更改</a-button>
</a-upload>
</span>
</a-form-model-item>
</a-col>
<a-col :span="24" style="text-align: center;margin-top: -10px">
<a-space>
<a-button type="primary" @click="editCommit(model,false)"></a-button>
<a-button v-if="releaseButton" style="margin-left: 40px" @click="editCommit(model,true)"></a-button>
<a-button style="margin-left: 40px" @click="handleCancel"></a-button>
<a-button v-if="dupCheck" style="margin-left: 40px;" @click="searchContentDupDoc"></a-button>
</a-space>
</a-col>
</a-row>
</a-form-model>
<subject-modal ref="modalForm"></subject-modal>
</j-form-container>
<div v-if="editOrCompareFlag === 1">
<a-form layout="inline" style="min-height: 10px">
<a-row>
<a-col v-for="(item,index) in dupDocList" :xl="24" :lg="24" :md="24" :sm="24" :key="index">
<p style="text-align: left;margin-left: 20px">
<span class="titleIndex"><b>{{index+1+'、'}}</b></span>
<span @click="compareDupDocPreview(item.id,item.title)"><a style="color: #303133" v-html="item.title"></a></span>
</p>
</a-col>
</a-row>
</a-form>
</div>
</a-spin>
<div style="float: left;width: 690px" v-if="editOrCompareFlag === 2" >
<div>
<div>
<p-d-f-modal :p-d-furl="TitlePDFurl" />
</div>
</div>
</div>
<div style="float: right;width: 700px" >
<div>
<div>
<p-d-f-modal :p-d-furl="PDFurl" />
</div>
</div>
</div>
</div>
</template>
<script>
import {ACCESS_TOKEN} from "@/store/mutation-types"
import '@/assets/less/TableExpand.less'
import SubjectModal from '../modules/SubjectModal'
import { httpPostAction, httpAction, getAction, downloadFileName } from '@/api/manage'
import Vue from 'vue'
export default {
name: 'DraftDocEdit',
props:{
releaseButton: Boolean,
dupCheck: Boolean,
model:{
type: Object
}
},
components: {
SubjectModal,
},
data() {
return {
// 0 1 2
editOrCompareFlag: 0,
//
dupDocList: [],
dataUpdated: false,
switchDownloadFlag: true,
PDFurl: '',
TitlePDFurl: '',
changePreviewFileUrl: window._CONFIG['domianURL'] + "/KM/kmDoc/changePreviewFile?docId=",
headers: {
authorization: 'authorization-text',
'X-Access-Token': Vue.ls.get(ACCESS_TOKEN)
},
labelCol: {
xs: {span: 24},
sm: {span: 6},
},
labelCol1: {
xs: {span: 12},
sm: {span: 12},
},
labelCol2: {
xs: {span: 3},
sm: {span: 3},
},
labelCol3: {
xs: {span: 4},
sm: {span: 4},
},
wrapperCol: {
xs: {span: 24},
sm: {span: 18},
},
wrapperCol1: {
xs: {span: 10},
sm: {span: 10},
},
wrapperCol2: {
xs: {span: 21},
sm: {span: 21},
},
wrapperCol3: {
xs: {span: 20},
sm: {span: 20},
},
confirmLoading: false,
pdfLoading: false,
pdfShow: true,
resetPreviewShow: false,
validatorRules: {
depId: [{required: true, message: '请选择部门!'}],
},
businessTypes: '',
title: "编辑",
width: "100%",
url: {
docDPCheck: '/KM/kmDoc/docDPCheck',
downloadKmDoc: '/KM/kmDoc/downloadKmDoc',
previewKmDoc: '/KM/kmDoc/previewKmDoc',
edit: '/KM/kmDoc/editDraft',
resetPreviewFile: '/KM/kmDoc/resetPreviewFile',
editAndRelease: '/KM/kmDoc/editAndRelease',
editRelease: '/KM/kmDoc/editRelease',
list: '/KM/kmDoc/listDraft',
delete: '/KM/kmDoc/delete',
deleteBatch: '/KM/kmDoc/deleteBatch',
editBatch: '/KM/kmDoc/submitAuditBatch',
},
}
},
created() {
this.init()
},
methods: {
navBack(){
if(this.editOrCompareFlag > 0)
this.editOrCompareFlag -= 1
},
//
searchTitleDupDoc() {
// this.title = '' + this.model.title
this.dupDocList = []
let params = {}
params['docId'] = this.model.id;
params['checkType'] = "1";
params['pageSize']="20";
getAction(this.url.docDPCheck, params).then((res) => {
if (res.success) {
this.dupDocList = res.result.kmSearchResultVOPage.records
} else {
this.$message.error('检索失败')
}
this.loading = false
})
this.editOrCompareFlag = 1
},
//
searchContentDupDoc() {
this.title = '查找相似内容:' + this.model.title
this.dupDocList = []
let params = {}
params['docId'] = this.model.id;
params['checkType'] = "2";
params['pageSize']="20";
getAction(this.url.docDPCheck, params).then((res) => {
if (res.success) {
this.dupDocList = res.result.kmSearchResultVOPage.records
} else {
this.$message.error('检索失败')
}
this.loading = false
})
// this.boolCheckTitle = false
this.editOrCompareFlag = 1
},
//
compareDupDocPreview(id,title) {
// this.showTitlePDF=true;
this.editOrCompareFlag = 2
this.title=" ";
this.TitlePDFurl = this.url.previewKmDoc + '?docId=' + id
},
initDictConfig() {
},
//
downloadKmDoc(record) {
this.$notification.success({
message: '文件开始下载...',
duration: 1,
});
downloadFileName(this.url.downloadKmDoc, {docId: record.id})
},
//
init() {
this.editOrCompareFlag = 0
if (this.model.depId == null || this.model.depId === "") {
var depId = Vue.ls.get("Dep_ID");
this.model.depId = depId
}
this.businessTypes = this.model.businessTypes;
this.PDFurl = this.url.previewKmDoc + "?docId=" + this.model.id;
this.pdfLoading = true;
this.pdfShow = true;
if (this.model.previewFileId !== this.model.originalPreviewFileId) {
this.resetPreviewShow = true;
}
// 1 0 switchtruefalse
if (this.model.downloadFlag === 1) {
this.switchDownloadFlag = true;
} else {
this.switchDownloadFlag = false;
}
console.log("init end.....this.editOrCompareFlag",this.editOrCompareFlag)
},
//
handleCancel() {
console.log("handleCancel, dataUpdated:", this.dataUpdated)
if(this.dataUpdated)
this.handleOK()
else
this.$emit("cancel")
},
//
handleOK() {
this.$emit("ok")
},
//
resetPreviewFile(model) {
let httpurl = '';
let method = '';
httpurl += this.url.resetPreviewFile;
method = 'post';
this.pdfLoading = true;
this.pdfShow = false;
httpPostAction(httpurl, {docId: model.id}, method).then((res) => {
if (res.success) {
this.$message.success("恢复成功!");
this.pdfShow = true;
this.resetPreviewShow = false;
this.dataUpdated = true
this.PDFurl =this.url.previewKmDoc + "?docId=" + this.model.id +"&nounce=" + Math.random();
// this.loadData();
} else {
this.$message.warning("恢复失败!");
this.pdfShow = true;
this.pdfLoading = false;
}
}).finally(() => {
this.pdfShow = true;
})
},
//
editCommit(model,releaseFlag) {
//
this.$refs.form.validate(valid => {
if (valid) {
if (model.businessTypes === this.businessTypes) {
console.log("不操作businessTypes");
} else if (model.businessTypes === "") {
model.removeBusinessTypeList = this.businessTypes.split(',');
} else if (this.businessTypes == null) {
model.addBusinessTypeList = model.businessTypes.split(',');
} else {
var businessTypesArr = model.businessTypes.split(',');
var businessTypesArrConst = this.businessTypes.split(',');
model.addBusinessTypeList = [];
model.removeBusinessTypeList = [];
for (let i = 0; i < businessTypesArr.length; i++) {
for (let j = 0; j < businessTypesArrConst.length; j++) {
if (businessTypesArr[i] === businessTypesArrConst[j]) {
delete businessTypesArr[i];
delete businessTypesArrConst[j];
}
}
}
for (let i = 0; i < businessTypesArr.length; i++) {
if (typeof (businessTypesArr[i]) != "undefined") {
model.addBusinessTypeList.push(businessTypesArr[i]);
}
}
for (let i = 0; i < businessTypesArrConst.length; i++) {
if (typeof (businessTypesArrConst[i]) != "undefined") {
model.removeBusinessTypeList.push(businessTypesArrConst[i]);
}
}
}
// 10 truefalse truefalse 10
if (this.switchDownloadFlag === false) {
this.model.downloadFlag = 0;
} else {
this.model.downloadFlag = 1;
}
Vue.ls.set("Dep_ID", this.model.depId, 7 * 24 * 60 * 60 * 1000)
console.log(this.model);
let actionUrl = this.url.edit
if(this.model.status === 2)
actionUrl = this.url.editRelease
if(releaseFlag)
actionUrl = this.url.editAndRelease
httpAction(actionUrl, model, 'put').then((res) => {
if (res.success) {
this.$message.success(res.message);
this.handleOK();
} else {
this.$message.warning(res.message);
}
}).finally(() => {
})
} else {
return false;
}
})
},
//
handleChange(info) {
this.pdfLoading = true
this.pdfShow = false
if (info.file.status === 'done') {
if (info.file.response.code === 200) {
this.$message.success(`${info.file.name} 文件上传成功`)
this.pdfShow = true;
this.resetPreviewShow = true
this.dataUpdated = true
this.PDFurl =this.url.previewKmDoc + "?docId=" + this.model.id +"&nounce=" + Math.random();
// this.loadData();
} else {
this.$message.error(`${info.file.name} 文件上传失败${info.file.response.message}`)
this.pdfShow = true
this.pdfLoading = false
}
} else if (info.file.status === 'error') {
this.$message.error(`${info.file.name} 文件上传失败`)
this.pdfShow = true
this.pdfLoading = false
}
},
//
showModel(model) {
this.$refs.modalForm.edit(model, 0);
this.$refs.modalForm.title = "选择专题"
},
}
}
</script>
<style scoped>
@import '~@assets/less/common.less';
</style>

@ -191,7 +191,7 @@
}
//
tempArray=[...new Set(temp)];
console.log("tempArray",tempArray);
// console.log("tempArray",tempArray);
checkedKeys.halfChecked=tempArray;
this.checkedTitle=checkedNodes.checkedNodes;
},
@ -210,10 +210,11 @@
} else {
this.topicCodesTree = [];
}
console.log(this.checkedKeys);
// console.log(this.checkedKeys);
},
//
submitForm() {
console.log("submitForm");
if (this.checkedArray.length > 0) {
this.model.topicIds = this.checkedArray.toString();
@ -254,14 +255,18 @@
}
}
this.model.topicIds_dictText="";
console.log("submitForm length:",this.checkedTitle.length);
for(let i=0;i<this.checkedTitle.length;i++){
console.log("submitForm topicIds_dictText:",this.checkedTitle[i].data.props.title);
if(this.model.topicIds_dictText===""){
this.model.topicIds_dictText=this.checkedTitle[i].data.props.title;
}else{
this.model.topicIds_dictText= this.model.topicIds_dictText+","+this.checkedTitle[i].data.props.title;
}
}
this.$emit('ok');
this.$emit('ok');
},
}

@ -1,11 +1,66 @@
<template>
<a-spin :spinning="confirmLoading">
<div>
<!--<a-spin :spinning="confirmLoading">-->
<div>
<a-form-model>
<a-row :gutter="24">
<a-col :span="12">
<a-form-item label="分类" :labelCol="labelCol" :wrapperCol="wrapperCol">
<j-dict-select-tag type="list" placeholder="请选择分类" v-model="model.category"
dictCode="km_dict_category"></j-dict-select-tag>
</a-form-item>
</a-col>
<!-- <a-col :xl="10" :lg="7" :md="8" :sm="24">-->
<a-col :span="12">
<a-form-model-item label="标签" :labelCol="labelCol" :wrapperCol="wrapperCol">
<j-multi-select-tag type="list_multi" v-model="model.businessTypes" :trigger-change="true"
placeholder="请选择标签" dictCode="km_dict_business"></j-multi-select-tag>
</a-form-model-item>
</a-col>
<a-col :span="12">
<a-form-model-item label="专题分类" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-textarea @click="showModel(model)" v-model="model.topicIds_dictText"
placeholder="请点击选择专题" readOnly :auto-size="{ minRows: 1, maxRows: 3 }">
</a-textarea>
</a-form-model-item>
</a-col>
<a-col :span="12">
<a-form-item label="关键字" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-input placeholder="请输入关键字" v-model="model.keywords"></a-input>
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-model-item label="归属部门" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="depId">
<j-select-depart v-model="model.depId" :multi="false"></j-select-depart>
</a-form-model-item>
</a-col>
<a-col :span="12">
<a-form-model-item label="公开范围" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="publicRemark">
<j-dict-select-tag type="list" placeholder="请选择公开范围" v-model="model.publicRemark"
dictCode="dict_public_remark"></j-dict-select-tag>
</a-form-model-item>
</a-col>
</a-row>
</a-form-model>
<div style="float:right;">
<subject-modal ref="modalForm" @ok='handleOk' ></subject-modal>
</div>
<div style="float:right;">
<a-button @click="searchReset" icon="reload" style="margin-left: 8px">重置</a-button>
</div>
</div>
<a-upload
name="file"
:multiple="true"
:action="url"
:headers="headers"
@change="handleChange"
:data= this.model
:file-list="fileList"
:showUploadList="{showPreviewIcon:true,showRemoveIcon:false}"
>
@ -15,24 +70,29 @@
</a-button>
</a-upload>
</a-spin>
<!--</a-spin>-->
</div>
</template>
<script>
import { ACCESS_TOKEN } from "@/store/mutation-types"
import JMultiSelectTag from "@/components/dict/JMultiSelectTag"
import SubjectModal from './SubjectModal'
import Vue from "vue";
import ACol from "ant-design-vue/es/grid/Col";
export default {
name: 'DraftsForm',
components: {
ACol,
SubjectModal,
JMultiSelectTag,
},
data() {
return {
model: {},
fileData:{category:'123'},
fileList:[],
url: window._CONFIG['domianURL']+"/KM/kmDoc/uploadDoc",
confirmLoading: false,
@ -40,6 +100,39 @@
authorization: 'authorization-text',
'X-Access-Token': Vue.ls.get(ACCESS_TOKEN)
},
labelCol: {
xs: {span: 24},
sm: {span: 6},
},
labelCol1: {
xs: {span: 12},
sm: {span: 12},
},
labelCol2: {
xs: {span: 3},
sm: {span: 3},
},
labelCol3: {
xs: {span: 4},
sm: {span: 4},
},
wrapperCol: {
xs: {span: 24},
sm: {span: 18},
},
wrapperCol1: {
xs: {span: 10},
sm: {span: 10},
},
wrapperCol2: {
xs: {span: 21},
sm: {span: 21},
},
wrapperCol3: {
xs: {span: 20},
sm: {span: 20},
},
}
},
computed: {
@ -48,15 +141,30 @@
},
},
methods: {
handleOk(){
this.$forceUpdate()
},
//
showModel(model) {
this.$refs.modalForm.edit(model, 0);
this.$refs.modalForm.title = "选择专题"
},
edit(record) {
this.model = Object.assign({}, record);
this.visible = true;
},
},
submitForm() {
this.$emit('ok');
},
searchReset(){
this.model = {};
this.$forceUpdate();
},
//
handleChange(info) {

@ -3,14 +3,14 @@
:title="title"
:width="width"
:visible="visible"
@ok="handleOk"
:okButtonProps="{ class:{'jee-hidden': true} }"
@cancel="handleCancel"
cancelText="关闭"
:cancelButtonProps="{ class:{'jee-hidden': false} }">
<upload-form ref="realForm" @ok="submitCallback" @nd="Newdate" :disabled="disableSubmit"></upload-form>
<span style="float: right"> 文件大小限制:<2M</span>
<span style="float: left"> 请先设定属性然后选择文件上传</span>
<span style="float: right"> 文件大小限制:<2G</span>
</j-modal>
</template>
@ -26,7 +26,7 @@
data () {
return {
title:'',
width:800,
width:1000,
visible: false,
disableSubmit: false
}

@ -0,0 +1,976 @@
<template>
<a-layout class="layout">
<a-layout-header class="searchHeader header-shadow"
:style="{background: kmConfig.HeaderBackgroundColor,width: '100%', height: '64px',position: 'fixed',top:'0',zIndex:'999'}">
<SearchHeader :title='pageTitle'/>
</a-layout-header>
<a-layout-content style=" background:#fff; minHeight: 680px;margin-top: 64px">
<div :bordered="false" style="background-color: #f2f2f2;height: 100%">
<div style="background-color: white">
<!-- 查询区域 -->
<div class="table-page-search-wrapper">
<a-form layout="inline">
<a-row>
<a-col :span="4"
style="text-align: left;background-color: #fafafa;height: 370px;overflow:auto;min-width: 200px">
<div>
<h3 style="margin-left: 20px;margin-top: 10px"><b>知识专题</b></h3>
</div>
<a-tree
checkStrictly
checkable
v-model="topicCodesTree"
:tree-data="treeData"
@check="onCheck"
:selectable="boolSelect"
/>
</a-col>
<a-col :span="18" style="margin-left: 80px;margin-top: 30px">
<a-form layout="inline">
<a-row :gutter="24">
<a-col :xl="14" :lg="14" :md="16" :sm="24">
<a-form-item label="标题" style="margin-left: 28px;margin-top: -10px">
<a-input placeholder="请输入标题" v-model="advance.title"></a-input>
</a-form-item>
</a-col>
<a-col :xl="14" :lg="14" :md="16" :sm="24">
<a-form-item label="关键字" style="margin-left: 14px;margin-top: -10px">
<a-input placeholder="请输入关键字" v-model="advance.keywords"></a-input>
</a-form-item>
</a-col>
<a-col :xl="14" :lg="14" :md="16" :sm="24">
<a-form-item label="全文" style="margin-left: 28px;margin-top: -10px">
<a-input placeholder="请输入内容" v-model="advance.content"></a-input>
</a-form-item>
</a-col>
<a-col :xl="14" :lg="14" :md="16" :sm="24">
<a-form-model-item label="标签" style="margin-left: 28px; margin-top: -10px">
<j-multi-select-tag type="list_multi" v-model="advance.businessTypes" :trigger-change="true"
placeholder="请选择标签" dictCode="km_dict_business" ></j-multi-select-tag>
</a-form-model-item>
</a-col>
<a-col :xl="14" :lg="14" :md="16" :sm="24">
<a-form-item label="上传时间">
<j-date :show-time="true" date-format="YYYY-MM-DD" placeholder="请选择开始时间"
class="query-group-cust" v-model="advance.createTimeStart"></j-date>
<span class="query-group-split-cust"></span>
<j-date :show-time="true" date-format="YYYY-MM-DD" placeholder="请选择结束时间"
class="query-group-cust" v-model="advance.createTimeEnd"></j-date>
</a-form-item>
</a-col>
<a-col :xl="14" :lg="14" :md="16" :sm="24" style="margin-top: -10px;margin-bottom: 10px">
<div style="width: 100%;margin-left: 80px">
<a-checkbox-group v-model="advance.category" :options="dicCategoryOptions" @change="advanceOnChange"/>
</div>
</a-col>
<a-col :xl="14" :lg="14" :md="16" :sm="48">
<span style="float: left;overflow: hidden;align: center;margin-left: 80px" class="table-page-search-submitButtons">
<span style="margin-left: 20px">
<span>精确匹配</span>
<a-checkbox class="checkbox" v-model="advance.phraseMatchSearchFlag" style="margin-left: 8px" />
</span>
<a-button type="primary" @click="advanceSearch(false)" style="width: 100px;margin-left: 30px">检索</a-button>
<a-button @click="advanceSearch(true)" style="margin-left: 30px">结果中检索</a-button>
<a-button @click="defaultSearch" style="margin-left: 50px">返回</a-button>
<!--<a-button @click="advanceReset" style="margin-left: 30px">重置条件</a-button>-->
</span>
</a-col>
</a-row>
</a-form>
</a-col>
</a-row>
</a-form>
</div>
<!-- 查询区域-END -->
</div>
<div class="paramPathDiv">
<div class="paramPathTitle"><span v-if="itemList.length >= 0"></span></div>
<div v-for="(item,index) in itemList" :key="index" class="paramPathContainer">
<!-- <a-space size="small">-->
<div class="paramPath">
<a href="#" class="historySearchHref" @click="historySearch(index)"> {{ item }} </a>
</div>
<template v-if="index != itemList.length-1">
<div style="float:left;display: inline-flex;font-size: x-small">></div>
</template>
</div>
</div>
<!-- 详情区域-BEGIN -->
<a-drawer
:title="docTitleOriginal"
:width="720"
:visible="drawerVisible"
:body-style="{ paddingBottom: '80px' }"
:footer-style="{ textAlign: 'right' }"
@close="onDrawerClose"
>
<doc-detail ref="docDetailRef" :record="showDocDetail"></doc-detail>
<br/>
<a-divider style="margin: 5px 0 15px 0 "></a-divider>
<doc-comments
ref="comments"
@new="refreshDocDetail"
:doc-id="showDocDetail.id">
</doc-comments>
</a-drawer>
<!-- 详情区域-END -->
<div style="background-color:white;margin: 15px;padding: 15px">
<!-- 操作按钮区域 -->
<div v-has="'searchList:batchDownload'" class="table-operator">
<a-dropdown v-if="selectedRowKeys.length > 0">
<a-menu slot="overlay">
<a-menu-item key="1" @click="downloadKmDocBatch">
<a-icon type="vertical-align-bottom"/>
批量下载
</a-menu-item>
</a-menu>
<a-button style="margin-left: 8px"> 批量操作
<a-icon type="down"/>
</a-button>
</a-dropdown>
</div>
<a-table
ref="table"
size="middle"
rowKey="id"
:columns="columns"
:dataSource="dataSource"
:pagination="ipagination"
:loading="loading"
:rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
@change="handleTableChange">
//
<div slot="filterDropdown">
<a-card style="width: 350px">
<a-checkbox-group @change="onColSettingsChange" v-model="settingColumns" :defaultValue="settingColumns">
<a-row>
<template v-for="(item,index) in defColumns">
<template v-if="item.key!='rowIndex'&& item.dataIndex!='action'">
<a-col :span="12">
<a-checkbox :value="item.dataIndex">{{ item.title }}</a-checkbox>
</a-col>
</template>
</template>
</a-row>
</a-checkbox-group>
</a-card>
</div>
<a-icon slot="filterIcon" type='setting' title="自定义列"
:style="{ fontSize:'16px',color: '#108ee9',minWidth:'35px'}"/>
<span slot="indexNum" slot-scope="text, record,index">
<p>{{index+1+(ipagination.current-1)*ipagination.pageSize}}</p>
</span>
<span slot="action" slot-scope="text, record">
<a-space>
<a-popover content="预览">
<a-icon type="read" title="预览" @click="previewKmDoc(record)"
:style="{ fontSize: '16px', color: '#1890FF'}"/>
</a-popover>
<a-popover :content="record.downloadFlag===1?'下载':'禁止下载'">
<a-icon v-if="record.downloadFlag===1" type="download" title="下载" @click="downloadKmDoc(record)"
:style="{ fontSize: '16px', color: '#1890FF'}"/>
<a-icon v-else type="download" title="禁止下载"
:style="{ fontSize: '16px', color: '#909399'}"/>
</a-popover>
<a-popover :content="record.favourite===0?'收藏':'取消收藏'">
<a-icon v-if="record.favourite===0" type="star" @click="addFavouriteKmDoc(record)"
:style="{ fontSize: '18px', color: '#1890FF', }"/>
<a-icon v-else type="star" theme="filled" @click="delFavouriteKmDoc(record)"
:style="{ fontSize: '18px', color: '#1890FF', }"/>
</a-popover>
</a-space>
</span>
<!-- <a-icon v-if="record.downloadFlag==1" type="download" title="下载" @click="downloadKmDoc(record)"-->
<!-- :style="{ fontSize: '16px', color: '#1890FF'}"/>-->
<!-- <a-icon v-else type="download" title="禁止下载" :style="{ fontSize: '16px', color: '#909399'}"/>-->
<!-- <a-divider type="vertical"/>-->
<!-- <a-icon v-if="record.favourite==0" type="star" title="收藏" @click="addFavouriteKmDoc(record)"-->
<!-- :style="{ fontSize: '18px', color: '#1890FF', }"/>-->
<!-- <a-icon v-else type="star" theme="filled" title="取消收藏" @click="delFavouriteKmDoc(record)"-->
<!-- :style="{ fontSize: '18px', color: '#1890FF', }"/>-->
<span slot="docTitle" slot-scope="text,record">
<!-- <span @click="previewKmDoc(record,true)" ><a style="color: #303133">-->
<a @click="showDrawer(record)" :title ="[ record.fileType + '文件 - 大小:' + record.fileSize +'B, By ' + record.createBy + '/' + record.orgCode_dictText + ' 下载 ' + record.downloads + ' 次' ] ">
<span style="color: #303133" v-html="concatTitleContent(record)"> </span>
</a>
<!-- <span style="color: #303133" v-html=" record.title "> </span>-->
<!-- <span v-html=" record.title " :title ="[ record.fileType + '文件 - 大小:' + record.fileSize +'B, By ' + record.createBy + '/' + record.orgCode_dictText + ' 下载 ' + record.downloads + ' 次' ] "></span></a></span>-->
</span>
</a-table>
</div>
<b-j-modal :title="title"
:width="width"
:visible="visible"
@cancel="handleCancel"
cancelText="关闭"
:okButtonProps="{ class:{'jee-hidden': true} }">
<div>
<div>
<p-d-f-modal :p-d-furl="PDFurl" :iframeWidth="width"/>
</div>
</div>
</b-j-modal>
</div>
</a-layout-content>
</a-layout>
</template>
<script>
import {ACCESS_TOKEN} from "@/store/mutation-types"
import {ajaxGetDictItems, getDictItemsFromCache} from '@/api/api'
import {downloadFileName, getAction, httpPostAction, postAction} from "@api/manage";
import {AJeecgListMixin} from '@/mixins/AJeecgListMixin'
import Vue from "vue";
import SearchHeader from '../Common/SearchHeader'
import DocComments from '@views/km/Common/Comments.vue'
import DocDetail from '@views/km/Common/DocDetail.vue'
export default {
name: "AdvancedSearch",
mixins: [AJeecgListMixin],
components: {
SearchHeader,
DocDetail,
DocComments
},
watch: {
loadedRatio: {
handler(newVal, oldVal) {
console.log(newVal)
if (newVal === 1) {
this.pdfLoading = false;
}
}
}
},
data() {
return {
phraseMatchSearchFlag: false,
pageTitle:"高级检索",
checkedArray: [],
isSearchResult: false,
// a-tree
boolSelect: false,
category: [],
loadedRatio: 0,
dictCode: 'km_dict_category',
dicCategoryOptions: [],
rangePickerArr: null,
topicCodesTree: {
checked: [],
halfChecked: [],
},
title: "预览",
width: '900',
treeData: [],
replaceFields: {
key: 'id',
parentId: "pid",
title: "name",
},
//
filterParamArray:[],
//
filterParamPaths:[],
filterOptions:[],
//filter
filterDictCode: 'km_dict_source',
advance: {},
itemList: [],
PDFurl: '',
visible: false,
pdfLoading: false,
pdfShow: true,
isorter: {
column: '_score',
order: 'desc',
},
//
columns: [],
//
settingColumns: [],
//
defColumns: [
{
title: '#',
dataIndex: '',
key: 'rowIndex',
width: 60,
align: "center",
scopedSlots: {customRender: 'indexNum'}
},
{
title: '标题',
align: "left",
dataIndex: 'title',
scopedSlots: {customRender: 'docTitle'}
},
{
title: '分类',
align: "left",
dataIndex: 'category_dictText',
width: 100,
filters: [],
customCell: () => {
return {
style: {
'max-width': '6em',
overflow: 'hidden',
whiteSpace: 'nowrap',
textOverflow: 'ellipsis'
},
};
},
},
{
title: '标签',
align: "left",
dataIndex: 'businessType_dictText',
customCell: () => {
return {
style: {
'max-width': '6em',
overflow: 'hidden',
whiteSpace: 'nowrap',
textOverflow:'ellipsis'
},
};
},
},
{
title: '操作',
dataIndex: 'action',
align: "center",
fixed: "right",
width: 80,
scopedSlots: {
filterDropdown: 'filterDropdown',
filterIcon: 'filterIcon',
customRender: 'action'
}
},
],
siteInfo: {},
kmConfig: {},
url: {
list: '/KM/kmDoc/searchDoc',
previewKmDoc: '/KM/kmDoc/previewKmDoc',
downloadKmDoc: "/KM/kmDoc/downloadKmDoc",
rootList: "/sys/category/loadTreeRoot",
childList: "/sys/category/childList",
advanceSearchDoc: '/KM/kmDoc/searchDoc',
addFavouriteKmDoc: '/KM/kmDocFavourite/add',
delFavouriteKmDoc: '/KM/kmDocFavourite/delete',
},
indexUrl:'/DefaultDocSearch',
showDocDetail:{},
docTitleOriginal:'',
drawerVisible: false,
}
},
created() {
this.siteInfo = this.$store.getters.siteInfo
this.kmConfig = this.$store.getters.kmConfig
console.log('siteInfo:',this.siteInfo)
if(this.kmConfig !== undefined && this.kmConfig.DefaultPageUseTopicList === '1')
this.indexUrl = '/RecommendTopicList'
//token
Vue.prototype.token = Vue.ls.get(ACCESS_TOKEN);
window._CONFIG['token'] = Vue.prototype.token;
this.initDict(this.dictCode);
this.loadTree();
// table
this.initColumns();
this.changeTitle(this.pageTitle);
let params = this.$route.params
this.advance = {}
this.advance.content =params.content
this.phraseMatchSearchFlag = params.phraseMatchSearchFlag
},
methods: {
concatTitleContent(record){
return '<h4>' +record.title +'</h4>' + '<span style="font-size: xx-small">' + record.content + '</span>'
},
onDrawerClose() {
this.drawerVisible = false
},
//
showDrawer(record) {
this.showDocDetail = record
this.docTitleOriginal = this.removeHTMLTag(record.title)
this.drawerVisible = true
},
removeHTMLTag(title){
var regex = /(<([^>]+)>)/ig
return title.replace(regex, "")
},
// filter
initFilterDict() {
//
// if (getDictItemsFromCache(this.dictCode)) {
let options = getDictItemsFromCache(this.filterDictCode)
if(options){
options.forEach((item, index) => {
let filterOption = {};
filterOption.text = item.title;
filterOption.value = item.value;
this.filterOptions.push(filterOption);
});
console.log(this.filterOptions);
this.defColumns[2].filters =this.filterOptions;
return
}
//Code,
ajaxGetDictItems(this.filterDictCode, null).then((res) => {
if (res.success) {
let options = res.result
console.log(options);
options.forEach((item, index) => {
let filterOption = {};
filterOption.text = item.title;
filterOption.value = item.value;
this.filterOptions.push(filterOption);
});
this.defColumns[2].filters =this.filterOptions;
}
})
},
//
changeTitle(title) {
let projectTitle = this.siteInfo.siteTitle
//
document.title = title + ' · ' + projectTitle
},
//
onColSettingsChange(checkedValues) {
var key = this.$route.name + ":colsettings";
console.log("colsettings", key);
Vue.ls.set(key, checkedValues, 30 * 7 * 24 * 60 * 60 * 1000)
this.settingColumns = checkedValues;
const cols = this.defColumns.filter(item => {
if (item.key == 'rowIndex' || item.dataIndex == 'action') {
return true
}
if (this.settingColumns.includes(item.dataIndex)) {
return true
}
return false
})
this.columns = cols;
},
//
initColumns() {
var key = this.$route.name + ":colsettings";
console.log("colsettings", key);
let colSettings = Vue.ls.get(key);
if (colSettings == null || colSettings == undefined) {
let allSettingColumns = [];
this.defColumns.forEach(function (item, i, array) {
allSettingColumns.push(item.dataIndex);
})
this.settingColumns = allSettingColumns;
this.columns = this.defColumns;
} else {
this.settingColumns = colSettings;
const cols = this.defColumns.filter(item => {
if (item.key == 'rowIndex' || item.dataIndex == 'action') {
return true;
}
if (colSettings.includes(item.dataIndex)) {
return true;
}
return false;
})
this.columns = cols;
}
},
loadData() {
this.advanceSearch(false);
},
//
loadTree() {
let params = {
async: false,
pcode: ""
};
getAction(this.url.rootList, params).then(res => {
if (res.success) {
if (res.result && res.result.length > 0) {
this.treeData = res.result
} else {
this.treeData = []
}
} else {
this.$message.warning(res.message)
}
}).finally(() => {
})
},
//
downloadKmDocBatch() {
console.log("批量下载")
if (!this.url.downloadKmDoc) {
this.$message.error("请设置url.downloadKmDoc属性!")
return
}
if (this.selectionRows.length <= 0) {
this.$message.warning('请选择一条记录!');
return;
} else {
var that = this;
this.$confirm({
title: "确认下载",
content: "是否下载选中数据?",
onOk: function () {
for (var i = 0; i < that.selectionRows.length; i++) {
let fileName = i;
downloadFileName(that.url.downloadKmDoc, {docId: that.selectionRows[i].id})
}
//that.loadData();
that.onClearSelected();
}
});
}
},
//
previewKmDoc(record, boolFormDisabled) {
this.PDFurl = this.url.previewKmDoc + "?docId=" + record.id;
this.visible = true;
this.pdfLoading = true;
this.pdfShow = true;
},
//
handleCancel() {
this.visible = false;
},
//
familyTree(treeData, id) {
var arrTree = [];
var forFn = function (arr, key) {
for (var i = 0; i < arr.length; i++) {
var item = arr[i]
if (item.key === key) {
if (item.parentId === "0") {
break;
} else {
console.log("父节点", item.parentId);
arrTree.push(item.parentId);
forFn(treeData, item.parentId);
}
break
} else {
if (item.children != null) {
forFn(item.children, key);
}
}
}
}
forFn(treeData, id);
return arrTree
},
//
downloadKmDoc(record) {
this.$notification.success({
message: '文件开始下载...',
duration: 1,
});
downloadFileName(this.url.downloadKmDoc, {docId: record.id})
},
//
onCheck(checkedKeys, checkedNodes) {
let temp = new Array();
let tempArray = new Array();
this.checkedArray = checkedKeys.checked;
for (let i = 0; i < this.checkedArray.length; i++) {
let arrTemp = this.familyTree(this.treeData, this.checkedArray[i]);
temp = temp.concat(arrTemp);
}
//
tempArray = [...new Set(temp)];
console.log("tempArray", tempArray);
checkedKeys.halfChecked = tempArray;
let checkedTitle = checkedNodes.checkedNodes;
this.advance.topicCodes = "";
for (let i = 0; i < checkedTitle.length; i++) {
if (this.advance.topicCodes === "") {
this.advance.topicCodes = checkedTitle[i].data.props.code;
} else {
if (checkedTitle[i].data.props.code != null) {
this.advance.topicCodes = this.advance.topicCodes + "," + checkedTitle[i].data.props.code;
}
}
}
},
initDict(dictCode) {
this.dicCategoryOptions = this.getDictOptions(dictCode);
},
getDictOptions(dictCode){
let dictOptions = [];
//
if (getDictItemsFromCache(dictCode)) {
let options = getDictItemsFromCache(dictCode)
options.forEach((item, index) => {
let person = {};
person.label = item.title;
person.value = item.value;
dictOptions.push(person);
});
return dictOptions
}
//Code,
ajaxGetDictItems(dictCode, null).then((res) => {
if (res.success) {
let options = res.result
options.forEach((item, index) => {
let person = {};
person.label = item.title;
person.value = item.value;
dictOptions.push(person);
});
}
})
return dictOptions
},
//
advanceOnChange(checkedValues) {
// this.category = checkedValues;
// this.advance.category = this.category.toString();
},
//
// advanceReset() {
// this.category = [];
// this.advance = {};
// this.topicCodesTree = [];
// this.rangePickerArr = null;
// this.itemList = [];
// },
defaultSearch() {
let params={
content: this.advance.content,
phraseMatchSearchFlag: this.advance.phraseMatchSearchFlag
}
this.$router.push({name: 'docSearch', params:params})
},
//
advanceSearch(withinSearchFlag) {
// this.isSearchResult = withinSearchFlag
if(withinSearchFlag) {
//
if(this.filterParamArray.length>=50){
alert("查询条件过多!请勿过度使用结果中检索")
this.loading = false;
return
}
}
let searchParam = Object.assign({},this.advance)
console.log("this.advance",this.advance)
// if (this.advance.topicCodes !== null && this.advance.topicCodes !== undefined) {
if (this.advance.topicCodes ) {
searchParam.topicCodes = this.advance.topicCodes.split(',');
}
if (this.advance.businessTypes ) {
searchParam.businessTypes = this.advance.businessTypes.split(',');
}
if (searchParam.keywords) {
searchParam.keywords = this.advance.keywords.split(',');
searchParam.keywords = this.advance.keywords.split(' ');
}
console.log("searchParam",searchParam)
if (this.empty(searchParam)) {
if (withinSearchFlag) {
// this.advance.withinSearchFlag = true
searchParam.withinSearchFlag = true
searchParam.filterParams = this.filterParamArray
console.log("searchParam this.filterParamArray:",this.filterParamArray)
}
else{
searchParam.withinSearchFlag = false
}
searchParam.advSearchFlag = true
searchParam.field = this.getQueryField();
searchParam.pageNo = this.ipagination.current;
searchParam.pageSize = this.ipagination.pageSize;
this.loading = true;
this.searchDoSend(searchParam)
} else {
this.$message.info("请输入搜索条件");
}
},
//
addFavouriteKmDoc(record) {
let httpurl = '';
let method = '';
httpurl += this.url.addFavouriteKmDoc;
method = 'post';
httpPostAction(httpurl, {docId: record.id}, method).then((res) => {
if (res.success) {
this.$message.success("收藏成功!");
// this.loadData();
record.favourite = 1;
} else {
this.$message.warning("收藏失败!");
}
}).finally(() => {
})
},
//
delFavouriteKmDoc(record) {
let httpurl = '';
let method = '';
httpurl += this.url.delFavouriteKmDoc;
method = 'delete';
httpPostAction(httpurl, {docId: record.id}, method).then((res) => {
if (res.success) {
this.$message.success("取消收藏成功!");
// this.loadData();
record.favourite = 0;
} else {
this.$message.warning("取消收藏失败!");
}
}).finally(() => {
})
},
//
empty(obj) {
console.log(obj)
for (let key in obj) {
return true;
}
return false;
},
//
backHomepage() {
this.$router.push(indexUrl);
},
advancedSearch() {
this.$router.push('/advancedSearch');
},
//
login() {
this.$router.push('/dashboard/analysis');
},
//
jumpKmDocFavouritePage(){
this.$router.push('/km/filemanagement/KmDocFavouriteList');
},
// 稿
jumpDraftsPage(){
this.$router.push('/km/filemanagement/DraftsList');
},
historyBack(){
history.back()
},
//dict
convertDictCodeToName(dictCode,codes){
let dictOptions = this.getDictOptions(dictCode)
let dictNames = ""
//console.log("convertDictCodeToName-----------",dictOptions)
//console.log("codes-----------",codes)
// debugger
if (dictOptions.length > 0) {
for(let code of codes) {
for (let item of dictOptions) {
if (item.value === code) {
dictNames = dictNames + item.label + "|"
}
}
}
}
if(dictNames.length >0)
dictNames = dictNames.substring(0,dictNames.length -1)
return dictNames
},
buildParamPath(params){
let paramPath = ""
let dictNames = ""
for (let key in params) {
if (params[key] !== '' && params[key] !== null) {
switch (key) {
case "title":
if(params.advSearchFlag )
paramPath = paramPath + "标题:" + params.title + ""
break
case "keywords":
if(params.advSearchFlag )
paramPath = paramPath + "关键字:" + params.keywords + ""
break
case "content":
if(params.advSearchFlag )
paramPath = paramPath +"全文:"+ params.content + ""
break
case "category":
if(params.category.length > 0) {
dictNames = this.convertDictCodeToName("km_dict_category",params.category )
paramPath = paramPath +"分类:" + dictNames + ""
}
break
case "businessTypes":
dictNames = this.convertDictCodeToName("km_dict_business",params.businessTypes )
paramPath = paramPath +"标签:" + dictNames + ""
break
case "topicCodes":
//console.log("params.topicCodes",params.topicCodes)
dictNames = this.convertTreeDateToName(params.topicCodes )
paramPath = paramPath +"专题:" + dictNames + ""
break
case "createTimeStart":
paramPath = paramPath +"时间起:" + params.createTimeStart + ""
break
case "createTimeEnd":
paramPath = paramPath +"时间止:" + params.createTimeEnd + ""
break
}
}
}
if(paramPath.length > 0){
paramPath = paramPath.substring(0,paramPath.length -1)
}
return paramPath
},
//
handleParamHistory(param){
// debugger
if(param.withinSearchFlag === undefined || !param.withinSearchFlag ) {
console.log("首次检索,清空历史路径",param.withinSearchFlag )
//
this.filterParamPaths = []
this.filterParamArray = []
}
//
delete param.filterParams
let hisParam = {...param}
this.filterParamArray.push(hisParam)
let paramPath = this.buildParamPath(hisParam)
this.filterParamPaths.push(paramPath)
console.log("filterParamArray",this.filterParamArray)
console.log("filterParamPaths",this.filterParamPaths)
},
//
buildHisFilterParams(params){
let hisParam = {}
for (let key in params) {
if (params[key] !== '' && params[key] !== null) {
if(key === "title"
|| key === "keywords"
|| key === "content"
|| key === "category"
|| key === "businessTypes"
|| key === "topicCodes"
|| key === "advSearchFlag"
|| key === "createTimeStart"
|| key === "createTimeEnd" ){
hisParam[key] = params[key]
}
}
}
return hisParam
},
//
historySearch(paramIndex){
let hisParams = this.filterParamArray
if(hisParams.length === 0 ||paramIndex<0 || paramIndex>=hisParams.length)
return
let newParam = hisParams[paramIndex]
//console.log("newParam",newParam)
this.filterParamArray.splice(paramIndex)
this.filterParamPaths.splice(paramIndex)
// console.log("newFilterParam",newFilterParam)
newParam.filterParams = this.filterParamArray
this.content = newParam.content
this.category = newParam.category
this.topicCodes = newParam.topicCodes
newParam.withinSearchFlag = true
newParam.advSearchFlag = true
newParam.pageNo = this.ipagination.current;
newParam.pageSize = this.ipagination.pageSize;
this.loading = true;
this.searchDoSend(newParam)
},
searchDoSend(params) {
//console.log("params before send",params)
postAction(this.url.list, params).then((res) => {
if (res.success) {
this.handleParamHistory(params)
this.dataSource = res.result.kmSearchResultVOPage.records;
this.itemList = this.filterParamPaths;
console.log("this.filterParamPaths",this.filterParamPaths)
// this.itemList = res.result.paramPath;
if (res.result.kmSearchResultVOPage.total) {
this.ipagination.total = res.result.kmSearchResultVOPage.total;
} else {
this.ipagination.total = 0;
}
} else {
this.$message.error(res.message);
}
this.loading = false
})
},
refreshDocDetail(){
this.$refs.docDetailRef.refreshDocDetail()
},
}
}
</script>
<style scoped>
@import '~@assets/less/common.less';
</style>

File diff suppressed because it is too large Load Diff

@ -0,0 +1,728 @@
<template>
<a-layout class="layout">
<a-layout-header class="searchHeader header-shadow"
:style="{background: kmConfig.HeaderBackgroundColor,width: '100%', height: '64px',position: 'fixed',top:'0',zIndex:'999'}">
<SearchHeader :title='pageTitle'/>
</a-layout-header>
<a-layout style="margin-top: 64px" >
<a-layout-sider width="250" style="background: #f2f2f2">
<div style="padding: 5px;overflow: auto" >
<!-- -->
<a-tree
checkStrictly
checkable
v-model="topicCodesTree"
@check="onCheck"
:selectable="boolSelect"
:tree-data="treeData"
/>
</div>
</a-layout-sider>
<a-layout :style="{ marginLeft: '0px' }">
<!--<a-layout-content>-->
<a-layout-content :style="{ background: '#fff', padding: '2px', margin: 0, minHeight: '280px' }">
<div :style="{ padding: '5px', background: '#fff' }">
<!-- 详情区域-BEGIN -->
<a-drawer
:title="showDocDetail.title"
:width="720"
:visible="drawerVisible"
:body-style="{ paddingBottom: '80px' }"
:footer-style="{ textAlign: 'right' }"
@close="onDrawerClose"
>
<doc-detail ref="docDetailRef" :record="showDocDetail"></doc-detail>
<br/>
<a-divider style="margin: 5px 0 15px 0 "></a-divider>
<doc-comments
ref="comments"
@new="refreshDocDetail"
:doc-id="showDocDetail.id">
</doc-comments>
</a-drawer>
<!-- 详情区域-END -->
<!-- 表格区域 -->
<div style="background-color:white" >
<!-- 操作按钮区域 -->
<div class="table-operator">
<a-dropdown v-has="'searchList:batchDownload'" v-if="selectedRowKeys.length > 0">
<a-menu slot="overlay">
<a-menu-item key="1" @click="downloadKmDocBatch">
<a-icon type="vertical-align-bottom"/>
批量下载
</a-menu-item>
</a-menu>
<a-button style="margin-left: 8px"> 批量操作
<a-icon type="down"/>
</a-button>
</a-dropdown>
</div>
<!-- table区域-begin -->
<div style="height: 100%;background-color: white" >
<a-table
ref="table"
size="middle"
rowKey="id"
:columns="columns"
:dataSource="dataSource"
:pagination="ipagination"
:loading="loading"
:rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
@change="handleTableChange">
<span slot="docTitle" slot-scope="text,record">
<a @click="showDrawer(record)" :title ="[ record.fileType + '文件 - 大小:' + record.fileSize +'B, By ' + record.createBy + '/' + record.orgCode_dictText + ' 下载 ' + record.downloads + ' 次' ] ">
<span style="color: #303133" v-html=" record.title "> </span>
</a>
</span>
//
<div slot="filterDropdown">
<a-card style="width: 350px">
<a-checkbox-group @change="onColSettingsChange" v-model="settingColumns" :defaultValue="settingColumns">
<a-row>
<template v-for="(item,index) in defColumns">
<template v-if="item.key!='rowIndex'&& item.dataIndex!='action'">
<a-col :span="12">
<a-checkbox :value="item.dataIndex">{{ item.title }}</a-checkbox>
</a-col>
</template>
</template>
</a-row>
</a-checkbox-group>
</a-card>
</div>
<a-icon slot="filterIcon" type='setting' title="自定义列"
:style="{ fontSize:'18px',color: '#108ee9',minWidth:'35px'}"/>
<span slot="indexNum" slot-scope="text, record,index">
<p>{{index+1+(ipagination.current-1)*ipagination.pageSize}}</p>
</span>
<span slot="action" slot-scope="text, record">
<a-space>
<a-popover content="预览">
<a-icon type="read" title="预览" @click="previewKmDoc(record)"
:style="{ fontSize: '16px', color: '#1890FF'}"/>
</a-popover>
<a-popover :content="record.downloadFlag===1?'下载':'禁止下载'">
<a-icon v-if="record.downloadFlag===1" type="download" title="下载" @click="downloadKmDoc(record)"
:style="{ fontSize: '16px', color: '#1890FF'}"/>
<a-icon v-else type="download" title="禁止下载"
:style="{ fontSize: '16px', color: '#909399'}"/>
</a-popover>
<a-popover :content="record.favourite===0?'收藏':'取消收藏'">
<a-icon v-if="record.favourite===0" type="star" @click="addFavouriteKmDoc(record)"
:style="{ fontSize: '18px', color: '#1890FF', }"/>
<a-icon v-else type="star" theme="filled" @click="delFavouriteKmDoc(record)"
:style="{ fontSize: '18px', color: '#1890FF', }"/>
</a-popover>
</a-space>
</span>
</a-table>
</div>
<b-j-modal :title="title"
:width="width"
:visible="visible"
@cancel="handleCancel"
cancelText="关闭"
:okButtonProps="{ class:{'jee-hidden': true} }">
<p-d-f-modal :p-d-furl="PDFurl" :iframeWidth="width"/>
</b-j-modal>
</div>
</div>
</a-layout-content>
</a-layout>
</a-layout>
</a-layout>
</template>
<script>
import {ajaxGetDictItems, getDictItemsFromCache} from '@/api/api'
import {ACCESS_TOKEN} from "@/store/mutation-types"
import {httpPostAction, getAction, downloadFileName, getActionPDF, postAction} from "../../../api/manage";
import {AJeecgListMixin} from '@/mixins/AJeecgListMixin'
import Vue from "vue";
import IframePageContent from "../../../components/layouts/IframeFReportView";
import ACol from "ant-design-vue/es/grid/Col";
import SearchHeader from '../Common/SearchHeader'
import DocDetail from '@views/km/Common/DocDetail.vue'
import DocComments from '@views/km/Common/Comments.vue'
export default {
name: "RecommendTopicList",
mixins: [AJeecgListMixin],
components: { DocComments, DocDetail, ACol, IframePageContent,SearchHeader},
data() {
return {
// boolCheckChange: true,
// knowledgeTitle: "",
pageTitle:"知识专题",
checkedArray: [],
topicCodesTree: {
checked: [],
halfChecked: [],
},
topicCodes:"",
// businessTypes:"",
boolSelect: false,
treeData: [],
confirmLoading: false,
PDFurl: '',
visible: false,
pdfLoading: false,
pdfShow: true,
isorter: {
column: '_score',
order: 'desc',
},
labelCol: {
xs: {span: 24},
sm: {span: 5},
},
wrapperCol: {
xs: {span: 24},
sm: {span: 16},
},
checkboxVuale: [],
title: "预览",
width: '900',
// hotTopicReportList: [],
docDataSource: [],
loadedRatio: 0,
isSearchResult: false,
filterOptions:[],
//filter
filterDictCode: 'km_dict_source',
//
columns: [],
//
settingColumns: [],
//
defColumns: [
{
title: '#',
dataIndex: '',
key: 'rowIndex',
width: 60,
align: "center",
scopedSlots: {customRender: 'indexNum'}
},
{
title: '标题',
align: "left",
dataIndex: 'title',
scopedSlots: {customRender: 'docTitle'}
},
{
title: '分类',
align: "left",
dataIndex: 'category_dictText',
width: 100,
filters: [],
customCell: () => {
return {
style: {
'max-width': '6em',
overflow: 'hidden',
whiteSpace: 'nowrap',
textOverflow: 'ellipsis'
},
};
},
},
{
title: '标签',
align: "left",
dataIndex: 'businessType_dictText',
customCell: () => {
return {
style: {
'max-width': '6em',
overflow: 'hidden',
whiteSpace: 'nowrap',
textOverflow:'ellipsis'
},
};
},
},
{
title: '操作',
dataIndex: 'action',
align: "center",
fixed: "right",
width: 80,
scopedSlots: {
filterDropdown: 'filterDropdown',
filterIcon: 'filterIcon',
customRender: 'action'
}
},
],
options: [],
content: '',
checkedValues: '',
itemList: [],
//
dictCode: 'km_dict_category',
siteInfo: {},
kmConfig: {},
url: {
rootList: "/sys/category/loadTreeRootRecommend",
rootListAll: "/sys/category/loadTreeRoot",
list: '/KM/kmDoc/searchDoc',
// hotTopicReport: '/KM/kmSearchRecord/hotTopicReport',
previewKmDoc: '/KM/kmDoc/previewKmDoc',
downloadKmDoc: "/KM/kmDoc/downloadKmDoc",
addFavouriteKmDoc: '/KM/kmDocFavourite/add',
delFavouriteKmDoc: '/KM/kmDocFavourite/delete',
},
recommendFlag: false,
showDocDetail:{},
drawerVisible: false
}
},
created() {
this.siteInfo = this.$store.getters.siteInfo
this.kmConfig = this.$store.getters.kmConfig
// this.loadTree();
// table
this.initColumns();
this.initFilterDict();
//token
Vue.prototype.token = Vue.ls.get(ACCESS_TOKEN);
window._CONFIG['token'] = Vue.prototype.token;
this.initDict();
let query = this.$route.query;
if(this.empty(query))
query = this.$route.params
console.log("query", query);
this.recommendFlag = query.recommendFlag
this.topicCodes = query.topicCodes;
this.loadTree();
if(this.topicCodes!=null){
this.topicCodesTree=query.topicCodesTree;
this.knowledgeTitle=query.knowledgeTitle;
this.searchDocFun(0);
}
this.changeTitle(this.pageTitle)
},
watch: {
loadedRatio: {
handler(newVal, oldVal) {
console.log(newVal)
if (newVal === 1) {
this.pdfLoading = false;
}
}
}
},
methods: {
//
showDrawer(record) {
this.showDocDetail = record
this.drawerVisible = true
},
onDrawerClose() {
this.drawerVisible = false
},
// filter
initFilterDict() {
//
// if (getDictItemsFromCache(this.dictCode)) {
let options = getDictItemsFromCache(this.filterDictCode)
if(options){
options.forEach((item, index) => {
let filterOption = {};
filterOption.text = item.title;
filterOption.value = item.value;
this.filterOptions.push(filterOption);
});
console.log(this.filterOptions);
this.defColumns[2].filters =this.filterOptions;
return
}
//Code,
ajaxGetDictItems(this.filterDictCode, null).then((res) => {
if (res.success) {
let options = res.result
console.log(options);
options.forEach((item, index) => {
let filterOption = {};
filterOption.text = item.title;
filterOption.value = item.value;
this.filterOptions.push(filterOption);
});
this.defColumns[2].filters =this.filterOptions;
}
})
},
//
changeTitle(title) {
let projectTitle = this.siteInfo.siteTitle
//
document.title = title + ' · ' + projectTitle
},
//
loadTree() {
let params = {
async: false,
pcode: ""
};
let topicListUrl = this.url.rootListAll
if(this.recommendFlag)
topicListUrl = this.url.rootList
getAction(topicListUrl, params).then(res => {
if (res.success) {
if (res.result && res.result.length > 0) {
this.treeData = res.result
} else {
this.treeData = []
}
} else {
this.$message.warning(res.message)
}
}).finally(() => {
})
},
//
familyTree(treeData, id) {
var arrTree = [];
var forFn = function (arr, key) {
for (var i = 0; i < arr.length; i++) {
var item = arr[i]
if (item.key === key) {
if (item.parentId === "0") {
break;
} else {
console.log("父节点", item.parentId);
arrTree.push(item.parentId);
forFn(treeData, item.parentId);
}
break
} else {
if (item.children != null) {
forFn(item.children, key);
}
}
}
}
forFn(treeData, id);
return arrTree
},
//
onCheck(checkedKeys, checkedNodes) {
if (checkedKeys.checked.length > 1) {
console.log("checkedKeys", checkedKeys);
console.log("checkedNodes", checkedNodes);
let checkKeys = checkedKeys.checked[1];
console.log("checkKeys",checkKeys)
checkedKeys.checked = [];
checkedKeys.checked.push(checkKeys);
let checkNodesTitle = checkedNodes.checkedNodes[1];
checkedNodes.checkedNodes = [];
checkedNodes.checkedNodes.push(checkNodesTitle);
}
console.log("checkedKeys", checkedKeys);
console.log("checkedNodes", checkedNodes);
let temp = new Array();
let tempArray = new Array();
this.checkedArray = checkedKeys.checked;
for (let i = 0; i < this.checkedArray.length; i++) {
let arrTemp = this.familyTree(this.treeData, this.checkedArray[i]);
temp = temp.concat(arrTemp);
}
//
tempArray = [...new Set(temp)];
// console.log("tempArray", tempArray);
checkedKeys.halfChecked = tempArray;
let checkedTitle = checkedNodes.checkedNodes;
console.log("checkedTitle", checkedTitle);
if (!checkedTitle[0]) {
// this.knowledgeTitle = ""
//this.$message.warning("!");
this.dataSource=null;
this.ipagination.total = 0;
this.topicCodes = null;
}
else {
let param = this.getQueryParams();//
this.topicCodes = checkedTitle[0].data.props.code;
param["topicCodes"] = this.topicCodes.split(',');
this.searchDocFun(param);
}
},
//
onColSettingsChange(checkedValues) {
var key = this.$route.name + ":colsettings";
console.log("colsettings", key);
Vue.ls.set(key, checkedValues, 30 * 7 * 24 * 60 * 60 * 1000)
this.settingColumns = checkedValues;
const cols = this.defColumns.filter(item => {
if (item.key == 'rowIndex' || item.dataIndex == 'action') {
return true
}
if (this.settingColumns.includes(item.dataIndex)) {
return true
}
return false
})
this.columns = cols;
},
//
initColumns() {
//
//this.defColumns = colAuthFilter(this.defColumns,'testdemo:');
var key = this.$route.name + ":colsettings";
console.log("colsettings", key);
let colSettings = Vue.ls.get(key);
if (colSettings == null || colSettings == undefined) {
let allSettingColumns = [];
this.defColumns.forEach(function (item, i, array) {
allSettingColumns.push(item.dataIndex);
})
this.settingColumns = allSettingColumns;
this.columns = this.defColumns;
} else {
this.settingColumns = colSettings;
const cols = this.defColumns.filter(item => {
if (item.key == 'rowIndex' || item.dataIndex == 'action') {
return true;
}
if (colSettings.includes(item.dataIndex)) {
return true;
}
return false;
})
this.columns = cols;
}
},
loadData() {
this.searchDocFun('2');
},
//
initDict() {
this.options = [];
//
if (getDictItemsFromCache(this.dictCode)) {
let options = getDictItemsFromCache(this.dictCode)
options.forEach((item, index) => {
let person = {};
person.label = item.title;
person.value = item.value;
this.options.push(person);
});
return
}
//Code,
ajaxGetDictItems(this.dictCode, null).then((res) => {
if (res.success) {
let options = res.result
options.forEach((item, index) => {
let person = {};
person.label = item.title;
person.value = item.value;
this.options.push(person);
});
}
})
},
//
onChange(checkedValues) {
this.checkedValues = checkedValues.toString();
console.log('checked = ', checkedValues);
},
//
pressEnterFun(e) {
this.$nextTick(() => {
this.searchDocFun('0');
})
},
//
searchDocFun(type) {
let params = {};
params = this.getQueryParams();//
if (type === '0') {
this.isSearchResult = false;
this.ipagination.current = 1;
//
this.defColumns[2].filters =this.filterOptions;
} else if (type === '1') {
this.isSearchResult = true;
this.ipagination.current = 1;
//
this.defColumns[2].filters = [];
}
this.loading = true;
if (this.content !== "" && this.content != null) {
//do nothing
}
params["advSearchFlag"] = 0;
if( this.topicCodes!=null){
params["topicCodes"]=this.topicCodes.split(',');
}
//
if (!this.empty(params)) {
params.withinSearchFlag = '0';
params.field = this.getQueryField();
params.pageNo = this.ipagination.current;
params.pageSize = this.ipagination.pageSize;
this.loading = true;
postAction(this.url.list, params).then((res) => {
if (res.success) {
this.dataSource = res.result.kmSearchResultVOPage.records;
this.itemList = res.result.paramPath;
if (res.result.kmSearchResultVOPage.total) {
this.ipagination.total = res.result.kmSearchResultVOPage.total;
} else {
this.ipagination.total = 0;
}
} else {
this.$message.error("检索失败");
}
this.loading = false;
})
} else {
this.loading = false;
this.$message.info("请选择专题");
}
},
//
empty(obj) {
for (let key in obj) {
return false;
}
return true;
},
//
downloadKmDocBatch() {
console.log("批量下载")
if (!this.url.downloadKmDoc) {
this.$message.error("请设置url.downloadKmDoc属性!")
return
}
if (this.selectionRows.length <= 0) {
this.$message.warning('请选择一条记录!');
return;
} else {
var that = this;
this.$confirm({
title: "确认下载",
content: "是否下载选中数据?",
onOk: function () {
for (var i = 0; i < that.selectionRows.length; i++) {
let fileName = i;
downloadFileName(that.url.downloadKmDoc, {docId: that.selectionRows[i].id})
}
that.onClearSelected();
}
});
}
},
//
addFavouriteKmDoc(record) {
let httpurl = '';
let method = '';
httpurl += this.url.addFavouriteKmDoc;
method = 'post';
httpPostAction(httpurl, {docId: record.id}, method).then((res) => {
if (res.success) {
this.$message.success("收藏成功!");
//this.loadData();
record.favourite = 1;
} else {
this.$message.warning("收藏失败!");
}
}).finally(() => {
})
},
//
delFavouriteKmDoc(record) {
let httpurl = '';
let method = '';
httpurl += this.url.delFavouriteKmDoc;
method = 'delete';
httpPostAction(httpurl, {docId: record.id}, method).then((res) => {
if (res.success) {
this.$message.success("取消收藏成功!");
// this.loadData();
record.favourite = 0;
} else {
this.$message.warning("取消收藏失败!");
}
}).finally(() => {
})
},
//
previewKmDoc(record) {
this.PDFurl = this.url.previewKmDoc + "?docId=" + record.id;
this.visible = true;
this.pdfLoading = true;
this.pdfShow = true;
},
//
handleCancel() {
this.visible = false;
},
//
downloadKmDoc(record) {
this.$notification.success({
message: '文件开始下载...',
duration: 1,
});
downloadFileName(this.url.downloadKmDoc, {docId: record.id})
},
refreshDocDetail(){
this.$refs.docDetailRef.refreshDocDetail()
},
}
}
</script>
<style scoped>
@import '~@assets/less/common.less';
</style>

@ -184,7 +184,7 @@
margin-bottom: 18px;
}
.anty-row-operator button{margin: 0 5px}
.ant-btn-danger{background-color: #ffffff}
.ant-btn-danger{background-color: #ffffff}z
.ant-modal-cust-warp{height: 100%}
.ant-modal-cust-warp .ant-modal-body{height:calc(100% - 110px) !important;overflow-y: auto}

@ -146,9 +146,6 @@
</script>
<style scoped>
@import '~@assets/less/index.less';
/*import '@/assets/less/index.less'*/
.anty-img-wrap {
height: 25px;
position: relative;
@ -162,4 +159,5 @@
margin-top: 20px;
}
@import '../../../assets/less/index.less';
</style>

@ -43,8 +43,9 @@
password:{
rules: [{
required: true,
pattern:/^(?=.*[a-zA-Z])(?=.*\d)(?=.*[~!@#$%^&*()_+`\-={}:";'<>?,./]).{8,}$/,
message: '密码由8位数字、大小写字母和特殊符号组成!'
pattern:/^\S{6,}$/,
// pattern:/^(?=.*[a-zA-Z])(?=.*\d)(?=.*[~!@#$%^&*()_+`\-={}:";'<>?,./]).{8,}$/,
message: '密码长度至少为6!'
}, {
validator: this.validateToNextPassword,
}],

@ -13,7 +13,7 @@
<div style="width: 100%;">
<span>{{ title }}</span>
<span style="display:inline-block;width:calc(100% - 51px);padding-right:10px;text-align: right">
<a-button @click="toggleScreen" icon="appstore" style="height:20px;width:20px;border:0"></a-button>
<a-button @click="toggleScreen" icon="appstore" style="height:20px;width:20px;border:0px"></a-button>
</span>
</div>
@ -59,7 +59,7 @@
<!--部门分配-->
<a-form-model-item label="部门分配" :labelCol="labelCol" :wrapperCol="wrapperCol" v-show="!departDisabled">
<j-select-depart v-model="model.selecteddeparts" :multi="true" @back="backDepartInfo" :backDepart="true"></j-select-depart>
<j-select-depart v-model="model.selecteddeparts" :multi="false" @back="backDepartInfo" :backDepart="true"></j-select-depart>
</a-form-model-item>
<!--租户分配-->
@ -87,9 +87,9 @@
<!--</j-multi-select-tag>-->
<!--</a-form-model-item>-->
<!--<a-form-model-item label="头像" :labelCol="labelCol" :wrapperCol="wrapperCol">-->
<!--<j-image-upload class="avatar-uploader" text="上传" v-model="model.avatar" ></j-image-upload>-->
<!--</a-form-model-item>-->
<a-form-model-item label="头像" :labelCol="labelCol" :wrapperCol="wrapperCol">
<j-image-upload class="avatar-uploader" text="上传" v-model="model.avatar" ></j-image-upload>
</a-form-model-item>
<!--<a-form-model-item label="生日" :labelCol="labelCol" :wrapperCol="wrapperCol">-->
<!--<a-date-picker-->
@ -163,8 +163,14 @@
validatorRules:{
username:[{required: true, message: '请输入用户账号!'},
{validator: this.validateUsername,}],
password: [{required: false,pattern:/^(?=.*[a-zA-Z])(?=.*\d)(?=.*[~!@#$%^&*()_+`\-={}:";'<>?,./]).{8,}$/,message: '密码由8位数字、大小写字母和特殊符号组成!'},
{validator: this.validateToNextPassword,trigger: 'change'}],
password: [{
required: true,
pattern:/^\S{6,}$/,
// pattern:/^(?=.*[a-zA-Z])(?=.*\d)(?=.*[~!@#$%^&*()_+`\-={}:";'<>?,./]).{8,}$/,
message: '密码长度至少为6!'
},
{
validator: this.validateToNextPassword,trigger: 'change'}],
confirmpassword: [{required: true, message: '请重新输入登录密码!',},
{ validator: this.compareToFirstPassword,}],
realname:[{ required: true, message: '请输入用户名称!' }],

@ -37,7 +37,7 @@
<script>
import Vue from 'vue'
import { ACCESS_TOKEN ,ENCRYPTED_STRING} from "@/store/mutation-types"
import ThirdLogin from './third/ThirdLogin'
// import ThirdLogin from './third/ThirdLogin'
import LoginSelectTenant from "./LoginSelectTenant"
import TwoStepCaptcha from '@/components/tools/TwoStepCaptcha'
import { encryption , getEncryptedString } from '@/utils/encryption/aesEncrypt'
@ -50,15 +50,17 @@
components: {
LoginSelectTenant,
TwoStepCaptcha,
ThirdLogin,
LoginAccount,
LoginPhone
// ThirdLogin,
LoginAccount
// LoginPhone
},
data () {
return {
DefaultPageUseTopicList: false,
customActiveKey: 'tab1',
rememberMe: true,
loginBtn: false,
kmConfig:{},
requiredTwoStepCaptcha: false,
stepCaptchaVisible: false,
encryptedString:{
@ -69,7 +71,7 @@
},
created() {
Vue.ls.remove(ACCESS_TOKEN)
this.getRouterData();
this.getRouterData()
this.rememberMe = true
},
methods:{
@ -127,13 +129,25 @@
},
//
loginSuccess () {
this.$router.push({ path: "/defaultDocSearch" }).catch(()=>{
console.log('登录跳转首页出错,这个错误从哪里来的')
let indexUrl = '/front/defaultDocSearch'
this.kmConfig = this.$store.getters.kmConfig
this.DefaultPageUseTopicList = this.kmConfig.DefaultPageUseTopicList === '1'
if(this.DefaultPageUseTopicList)
indexUrl = '/front/RecommendTopicList'
let routeData = this.$router.resolve({
path: indexUrl,
query: {}
})
this.$notification.success({
message: '欢迎',
description: `${timeFix()},欢迎回来`,
});
window.open(routeData.href, '_self')
// this.$router.push({ path: indexUrl }).catch(()=>{
// console.log(',')
// })
// this.$notification.success({
// message: '',
// description: `${timeFix()}`,
// });
},
stepCaptchaSuccess () {

@ -130,7 +130,7 @@
password: this.model.password,
captcha: this.model.inputCode,
checkKey: this.currdatetime,
remember_me: rememberMe,
// remember_me: rememberMe,
}
console.log("登录参数", loginParams)
this.Login(loginParams).then((res) => {

@ -5,6 +5,32 @@ function resolve(dir) {
return path.join(__dirname, dir)
}
// const isProd = process.env.NODE_ENV === 'production'
// const isProd = true
// const needCdn = isProd
// 'vue-router': 'VueRouter',
// 'ant': 'Antd'
// vue: 'Vue',
// const externals = {
// moment: 'moment'
// }
// cdn 外部扩展,通过 cdn 引入不会被webpack打包
// const assetsCDN = {
// // cdn的css链接
// css: [
// 'http://cdn.jsdelivr.net/npm/ant-design-vue@1.7.2/dist/antd.min.css'
// ],
// // cdn的js链接
// js: [
// 'http://cdn.jsdelivr.net/npm/moment@2.29.4/moment.min.js',
// 'http://cdn.jsdelivr.net/npm/moment@2.29.4/locale/zh-cn.js',
// 'http://cdn.jsdelivr.net/npm/ant-design-vue@1.7.2/dist/antd.min.js'
// ]
// }
// vue.config.js
module.exports = {
/*
@ -12,6 +38,28 @@ module.exports = {
Crashed when using Webpack `import()` #2463
https://github.com/vuejs/vue-cli/issues/2463
*/
pages: {
// // 先配置主页
// login: {
// entry: 'src/loginMain.js',
// template: 'public/login.html',
// title: '用户登录'
// },
// 先配置主页
front: {
entry: 'src/frontMain.js',
template: 'public/frontIndex.html',
title: '前端'
},
// 再配置后台管理页面
index: {
entry: 'src/main.js',
template: 'public/index.html',
title: '后台管理'
}
},
// 如果你不需要生产环境的 source map可以将其设置为 false 以加速生产环境构建。
productionSourceMap: false,
//打包app时放开该配置
@ -21,8 +69,15 @@ module.exports = {
if (process.env.NODE_ENV === 'production') {
config.optimization.minimizer[0].options.terserOptions.compress.drop_console = true
}
// config.externals = needCdn ? assetsCDN.externals : {}
},
chainWebpack: (config) => {
config.plugins.delete('prefetch')
// 移除 preload 插件,避免加载多余的资源
// config.plugins.delete('preload')
config.resolve.alias
.set('@$', resolve('src'))
.set('@api', resolve('src/api'))
@ -30,6 +85,11 @@ module.exports = {
.set('@comp', resolve('src/components'))
.set('@views', resolve('src/views'))
if (process.env.use_analyzer) {
config.plugin("webpack-bundle-analyzer").use(require("webpack-bundle-analyzer").BundleAnalyzerPlugin)
}
//生产环境开启js\css压缩
if (process.env.NODE_ENV === 'production') {
config.plugin('compressionPlugin').use(new CompressionPlugin({
@ -39,6 +99,35 @@ module.exports = {
}))
}
// 开启gzip压缩
// config.plugin('compressionPlugin').use(
// new CompressionPlugin(
// {
// filename: info => {
// return `${info.path}.gz${info.query}`
// },
// algorithm: 'gzip',
// threshold: 10240, // 只有大小大于该值的资源会被处理 10240
// test: new RegExp('\\.(' + ['js'].join('|') + ')$'
// ),
// minRatio: 0.8, // 只有压缩率小于这个值的资源才会被处理
// deleteOriginalAssets: false // 删除原文件
// }
// )
// )
// // 初始化页面的title为配置文件设置的值public/index.html中的htmlWebpackPlugin.options.title
// config.plugin('html').tap((args) => {
// if (needCdn) {
// args[0].cdn = assetsCDN
// }
// return args
// })
// 视为一个外部库,而不将它打包进来
// config.externals(externals)
// 配置 webpack 识别 markdown 为普通的文件
config.module
.rule('markdown')

File diff suppressed because it is too large Load Diff

@ -0,0 +1,204 @@
server:
port: 8080
tomcat:
max-swallow-size: -1
error:
include-exception: true
include-stacktrace: ALWAYS
include-message: ALWAYS
servlet:
context-path: /ky
compression:
enabled: true
min-response-size: 1024
mime-types: application/javascript,application/json,application/xml,text/html,text/xml,text/plain,text/css,image/*
management:
endpoints:
web:
exposure:
include: metrics,httptrace
##文件上传和转换工具的配置
base:
upload-dir: c:\KM\upload
soffice-path: c:\Program Files\LibreOffice\program\soffice.exe
one-system-url:
##ElasticSearch服务配置 for highLevelRestClient
esclient:
master-host: localhost
master-port: 9200
spring:
servlet:
multipart:
# 文件上传的大小限制
max-file-size: 1000MB
max-request-size: 1000MB
mail:
host: smtp.163.com
username: jeecgos@163.com
password: ??
properties:
mail:
smtp:
auth: true
starttls:
enable: true
required: true
#json 时间戳统一转换
jackson:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: GMT+8
aop:
proxy-target-class: true
#配置freemarker
freemarker:
# 设置模板后缀名
suffix: .ftl
# 设置文档类型
content-type: text/html
# 设置页面编码格式
charset: UTF-8
# 设置页面缓存
cache: false
prefer-file-system-access: false
# 设置ftl文件路径
template-loader-path:
- classpath:/templates
# 设置静态文件路径js,css等
mvc:
static-path-pattern: /**
resource:
static-locations: classpath:/static/,classpath:/public/
autoconfigure:
exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure
datasource:
druid:
stat-view-servlet:
enabled: true
loginUsername: admin
loginPassword: 123456
allow:
web-stat-filter:
enabled: true
dynamic:
druid: # 全局druid参数绝大部分值和默认保持一致。(现已支持的参数如下,不清楚含义不要乱设置)
# 连接池的配置信息
# 初始化大小,最小,最大
initial-size: 5
min-idle: 5
maxActive: 10
# 配置获取连接等待超时的时间
maxWait: 60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
timeBetweenEvictionRunsMillis: 60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
minEvictableIdleTimeMillis: 300000
validationQuery: SELECT 1 FROM DUAL
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
# 打开PSCache并且指定每个连接上PSCache的大小,mysql建议关闭
poolPreparedStatements: false
maxPoolPreparedStatementPerConnectionSize: -1
# 配置监控统计拦截的filters去掉后监控界面sql无法统计'wall'用于防火墙
filters: stat,wall,slf4j
# 通过connectProperties属性来打开mergeSql功能慢SQL记录
connectionProperties: druid.stat.mergeSql\=true;druid.stat.slowSqlMillis\=5000
datasource:
master:
url: jdbc:mysql://localhost:3306/km?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
#redis 配置
redis:
database: 0
host: localhost
lettuce:
pool:
max-active: 8 #最大连接数据库连接数,设 -1 为没有限制
max-idle: 8 #最大等待连接中的数量,设 0 为没有限制
max-wait: -1ms #最大建立连接等待时间。如果超过此时间将接到异常。设为-1表示无限制。
min-idle: 0 #最小等待连接中的数量,设 0 为没有限制
shutdown-timeout: 100ms
password: ''
port: 6379
#mybatis plus 设置
mybatis-plus:
mapper-locations: classpath*:org/jeecg/modules/**/xml/*Mapper.xml
global-config:
# 关闭MP3.0自带的banner
banner: false
db-config:
#主键类型 0:"数据库ID自增",1:"该类型为未设置主键类型", 2:"用户输入ID",3:"全局唯一ID (数字类型唯一ID)", 4:"全局唯一ID UUID",5:"字符串全局唯一ID (idWorker 的字符串表示)";
id-type: ASSIGN_ID
# 默认数据库表下划线命名
table-underline: true
configuration:
# 这个配置会将执行的sql打印出来在开发或测试的时候可以用
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
# 返回类型为Map,显示null对应的字段
call-setters-on-nulls: true
#jeecg专用配置
jeecg :
# 本地local\Miniominio\阿里云alioss
uploadType: local
path :
#文件上传根目录 设置
upload: /opt/upFiles
#webapp文件路径
webapp: /opt/webapp
shiro:
excludeUrls: /category/**,/sys/category/**,/sys/dictItem/**,/KM/EsMgnt/**
#阿里云oss存储和大鱼短信秘钥配置
oss:
accessKey: ??
secretKey: ??
endpoint: oss-cn-beijing.aliyuncs.com
bucketName: ??
# # minio文件上传
minio:
minio_url: http://minio.jeecg.com
minio_name: ??
minio_pass: ??
bucketName: otatest
#xxl-job配置
xxljob:
enabled: false
adminAddresses: http://127.0.0.1:9080/xxl-job-admin
appname: ${spring.application.name}
accessToken: ''
address: 127.0.0.1:30007
ip: 127.0.0.1
port: 30007
logPath: logs/jeecg/job/jobhandler/
logRetentionDays: 30
#自定义路由配置 yml nacos database
route:
config:
data-id: jeecg-gateway-router
group: DEFAULT_GROUP
data-type: yml
#分布式锁配置
redisson:
address: 127.0.0.1:6379
password:
type: STANDALONE
enabled: true
#cas单点登录
cas:
prefixUrl: http://cas.example.org:8443/cas
#Mybatis输出sql日志
logging:
level:
org.jeecg.modules.system.mapper : info
#swagger
knife4j:
production: false
basic:
enable: true
username: jeecg
password: jeecg1314

@ -0,0 +1,5 @@
spring:
application:
name: jeecg-system
profiles:
active: prod

@ -0,0 +1,14 @@
${AnsiColor.BRIGHT_BLUE}
___ ____ ____ ____ ___ ____ ____ ____ ______
|_ ||_ _||_ _||_ _| |_ ||_ _| |_ \ / _|.' ____ \
| |_/ / \ \ / /______ | |_/ / | \/ | | (___ \_|
| __'. \ \/ /|______|| __'. | |\ /| | _.____`.
_| | \ \_ _| |_ _| | \ \_ _| |_\/_| |_ | \____) |
|____||____| |______| |____||____||_____||_____| \______.'
${AnsiColor.BRIGHT_GREEN}
KY-KMS Version: 0.0.1
Spring Boot Version: ${spring-boot.version}${spring-boot.formatted-version}
${AnsiColor.BLACK}

@ -0,0 +1,77 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false">
<!--定义日志文件的存储地址 -->
<property name="LOG_HOME" value="logs" />
<!--<property name="COLOR_PATTERN" value="%black(%contextName-) %red(%d{yyyy-MM-dd HH:mm:ss}) %green([%thread]) %highlight(%-5level) %boldMagenta( %replace(%caller{1}){'\t|Caller.{1}0|\r\n', ''})- %gray(%msg%xEx%n)" />-->
<!-- 控制台输出 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!--格式化输出:%d表示日期%thread表示线程名%-5level级别从左显示5个字符宽度%msg日志消息%n是换行符
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}:%L - %msg%n</pattern>-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %highlight(%-5level) %cyan(%logger{50}:%L) - %msg%n</pattern>
</encoder>
</appender>
<!-- 按照每天生成日志文件 -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!--日志文件输出的文件名 -->
<FileNamePattern>${LOG_HOME}/jeecgboot-%d{yyyy-MM-dd}.%i.log</FileNamePattern>
<!--日志文件保留天数 -->
<MaxHistory>30</MaxHistory>
<maxFileSize>10MB</maxFileSize>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!--格式化输出:%d表示日期%thread表示线程名%-5level级别从左显示5个字符宽度%msg日志消息%n是换行符 -->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}:%L - %msg%n</pattern>
</encoder>
</appender>
<!-- 生成 error html格式日志开始 -->
<appender name="HTML" class="ch.qos.logback.core.FileAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<!--设置日志级别,过滤掉info日志,只输入error日志-->
<level>ERROR</level>
</filter>
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
<layout class="ch.qos.logback.classic.html.HTMLLayout">
<pattern>%p%d%msg%M%F{32}%L</pattern>
</layout>
</encoder>
<file>${LOG_HOME}/error-log.html</file>
</appender>
<!-- 生成 error html格式日志结束 -->
<!-- 每天生成一个html格式的日志开始 -->
<appender name="FILE_HTML" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!--日志文件输出的文件名 -->
<FileNamePattern>${LOG_HOME}/jeecgboot-%d{yyyy-MM-dd}.%i.html</FileNamePattern>
<!--日志文件保留天数 -->
<MaxHistory>30</MaxHistory>
<MaxFileSize>10MB</MaxFileSize>
</rollingPolicy>
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
<layout class="ch.qos.logback.classic.html.HTMLLayout">
<pattern>%p%d%msg%M%F{32}%L</pattern>
</layout>
</encoder>
</appender>
<!-- 每天生成一个html格式的日志结束 -->
<!--myibatis log configure -->
<logger name="com.apache.ibatis" level="TRACE" />
<logger name="java.sql.Connection" level="DEBUG" />
<logger name="java.sql.Statement" level="DEBUG" />
<logger name="java.sql.PreparedStatement" level="DEBUG" />
<!-- 日志输出级别 -->
<root level="INFO">
<appender-ref ref="STDOUT" />
<appender-ref ref="FILE" />
<appender-ref ref="HTML" />
<appender-ref ref="FILE_HTML" />
</root>
</configuration>

@ -0,0 +1 @@
java -Dloader.path=lib -jar jeecg-boot-module-system-2.4.5.jar

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

Loading…
Cancel
Save