pan dd9940e78e 1、新增文档和工具统计
2、样式调整
3、文件下载分页(还有一部分没有调整)
2024-09-05 22:35:43 +08:00

812 lines
28 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="app-container">
<el-card>
<el-form :model="queryParams" label-width="70px" ref="queryForm">
<div class="grab" id="add">
<div class="search">
<div class="sl">
<el-form-item label="工具编号" prop="toolCode">
<el-input
v-model="queryParams.toolCode"
placeholder="请输入工具编号"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="工具名称" prop="toolName">
<el-input
v-model="queryParams.toolName"
placeholder="请输入工具名称"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="创建时间">
<el-date-picker
v-model="dateRange"
value-format="yyyy-MM-dd"
type="daterange"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
@change="handleQuery"
></el-date-picker>
</el-form-item>
<el-form-item label="状态" prop="status">
<el-select
v-model="queryParams.status"
placeholder="状态"
clearable
@change="handleQuery"
>
<el-option
v-for="dict in dict.type.tool_status"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
</div>
<div class="sr">
<el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh-left" @click="resetQuery">重置</el-button>
</div>
</div><!--search 默认查询-->
</div><!--grab-->
</el-form><!--el-form-->
</el-card><!--el-card-->
<el-card class="lrtt">
<div class="lt" v-hasPermi="['tool:org:tree']">
<el-input
v-model="deptName"
placeholder="请输入部门名称"
clearable
size="small"
prefix-icon="el-icon-search"
style="margin-bottom: 20px"
/>
<div class="divide"></div><!--divide 分隔-->
<el-tree
:data="deptOptions"
:props="defaultProps"
:expand-on-click-node="false"
:filter-node-method="filterNode"
ref="tree"
node-key="id"
default-expand-all
highlight-current
@node-click="handleNodeClick"
/>
</div><!--lt 左-->
<div class="rt">
<div class="operate">
<el-button
type="primary"
plain
icon="el-icon-plus"
@click="handleAdd"
>工具发布</el-button>
<el-button icon="el-icon-delete" @click="handleDelete(selection)" v-hasPermi="['tool:batch:remove']">批量删除</el-button>
<el-button icon="el-icon-download" @click="handleOpenExport()" v-hasPermi="['tool:export']">导出</el-button>
<el-button icon="el-icon-download" @click="handleOpenBatchExport()" v-hasPermi="['tool:batch:export']">批量导出</el-button>
</div><!--operate 操作按钮-->
<el-table v-loading="loading" :data="toolList" ref="tableRef" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="50" align="center"/>
<el-table-column label="工具编号" key="toolCode" prop="toolCode" v-if="columns[0].visible" />
<el-table-column label="工具名称" key="toolName" prop="toolName" v-if="columns[1].visible" :show-overflow-tooltip="true" />
<el-table-column label="工具类别" key="toolType" prop="toolType" v-if="columns[2].visible" :show-overflow-tooltip="true" >
<template slot-scope="scope">
<dict-tag :options="dict.type.tool_type" :value="scope.row.toolType"/>
</template>
</el-table-column>
<el-table-column label="归属单位" key="toolRespDeptName" prop="toolRespDeptName" v-if="columns[3].visible" :show-overflow-tooltip="true" />
<el-table-column label="负责人" key="toolPrincipalsName" prop="toolPrincipalsName" v-if="columns[4].visible" width="120" />
<el-table-column label="状态" align="center" key="status" v-if="columns[5].visible">
<template slot-scope="scope">
<dict-tag :options="dict.type.tool_status" :value="scope.row.status"/>
</template>
</el-table-column>
<el-table-column label="流程状态" align="center" key="recordStatus" width="90">
<template slot-scope="scope">
<dict-tag :options="dict.type.flow_status" :value="scope.row.recordStatus"/>
</template>
</el-table-column>
<!-- <el-table-column label="引用工具" align="center" :show-overflow-tooltip="true">
<template slot-scope="scope">
<span v-if="handleRelationTool(scope.row.relationToolList)">
<el-link target="_blank" v-for="assItem in scope.row.relationToolList" :key="assItem.id" @click="handleToolDetail(assItem)">{{assItem.toolName}}</el-link>
</span>
</template>
</el-table-column>-->
<el-table-column label="引用工具" align="center" :show-overflow-tooltip="true" width="100">
<template slot-scope="scope">
<el-popover
trigger="click"
placement="top-start"
v-if="Array.isArray(scope.row.relationToolList) && scope.row.relationToolList.length > 0"
>
<!-- 这里展示引用工具的详细信息 -->
<ul>
<li v-for="assItem in scope.row.relationToolList" :key="assItem.id">
<el-link target="_blank" @click="handleToolDetail(assItem)">
{{ assItem.toolName }}
</el-link>
</li>
</ul>
<!-- 弹出框触发器 -->
<el-link slot="reference">
引用工具 ({{ scope.row.relationToolList.length }})
</el-link>
</el-popover>
</template>
</el-table-column>
<el-table-column label="创建时间" align="center" prop="createTime" v-if="columns[6].visible" width="160">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column>
<el-table-column
label="操作"
align="center"
fixed="right"
width="270px"
class-name="small-padding fixed-width"
>
<template slot-scope="scope">
<!-- && !scope.row.downloadStatus-->
<el-button type="text" icon="el-icon-info" v-if="checkApplyUseBtn(scope.row)" @click="applyUse(scope.row)">申请使用</el-button>
<el-button type="text" icon="el-icon-info" @click="handleDetail(scope.row)">详情</el-button>
<el-button type="text" icon="el-icon-download" v-if="scope.row.downloadStatus" @click="handleFileDownload(scope.row)">下载</el-button>
<el-dropdown size="mini" v-if="selectable(scope.row)" @command="(command) => handleCommand(command, scope.row)">
<el-button size="mini" type="text" icon="el-icon-d-arrow-right" >更多</el-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item command="handleUpdate" icon="el-icon-edit">编辑</el-dropdown-item>
<el-dropdown-item command="handleDelete" icon="el-icon-delete">删除</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
</div><!--rt 右-->
</el-card><!--el-card-->
<!-- 工具导出对话框 -->
<el-dialog :title="exportTitle" :visible.sync="exoportDrawerOpen" width="980px" append-to-body :close-on-press-escape="false" :close-on-click-modal="false" :show-close="false">
<div class="el-form-border">
<el-form ref="exportFrom" label-width="180px">
<el-row>
<el-col :span="24">
<el-form-item label="导出格式">
<el-radio-group v-model="statevalue">
<el-radio v-for="item in stateoptions" :key="item.value" :label="item.value" >{{item.label}}</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
</el-form>
</div><!--el-form-border 表单-->
<div class="el-form-border">
<el-form ref="form" label-width="180px">
<el-row>
<el-col :span="24">
<el-form-item label="导出字段">
<el-checkbox-group v-model="checkList">
<el-checkbox label="toolName">工具名称</el-checkbox>
<el-checkbox label="toolType">工具类别</el-checkbox>
<el-checkbox label="toolSource">工具来源</el-checkbox>
<el-checkbox label="toolPrincipalsName">负责人</el-checkbox>
<el-checkbox label="toolRespDeptName">归属单位</el-checkbox>
<el-checkbox label="status">状态</el-checkbox>
<el-checkbox label="toolUse">工具用途</el-checkbox>
<el-checkbox label="testSituation">测评情况</el-checkbox>
<el-checkbox label="functionDesc">功能描述</el-checkbox>
<el-checkbox label="applyCondition">适用条件</el-checkbox>
<el-checkbox label="operateExplain">操作说明</el-checkbox>
<el-checkbox label="remark">备注</el-checkbox>
</el-checkbox-group>
</el-form-item>
</el-col>
</el-row>
</el-form><!--el-form-->
</div><!--el-form-border 表单-->
<span slot="footer" class="dialog-footer">
<el-button type="primary" @click="handleExport"> </el-button>
<el-button @click="exoportDrawerOpen=false"> </el-button>
</span>
</el-dialog>
<el-drawer
:visible.sync="drawerShow"
direction="rtl"
size="80%"
:with-header="false"
:wrapperClosable="false"
:show-close="false"
modal-append-to-body
:destroy-on-close="true"
:close-on-press-escape="false"
>
<main-component ref="mainComponent" :code="path + code" :data="data" @close="handleClose"></main-component>
</el-drawer>
<!-- 工具详情对话框 -->
<el-drawer :visible.sync="detailDrawerOpen" :modal-append-to-body="false" :show-close="false"
size="80%" class="no-padding" :close-on-press-escape="false" @close="handleCloseDetail()">
<template #title>
<span>{{toolTitle}}</span>
<div class="drawer-head-btn">
<el-button @click="detailDrawerOpen = false"> </el-button>
</div><!--drawer-head-btn 抽屉顶部按钮区域-->
</template>
<template v-if="detailOpen">
<tool-detail ref="toolDetailRef" :toolDetail="toolDetail"/>
</template>
</el-drawer><!--el-drawer 详情-抽屉-->
<!-- 工具详情对话框 -->
<el-drawer :visible.sync="fileDetailDrawerOpen" :modal-append-to-body="false" :show-close="false"
size="80%" class="no-padding" :close-on-press-escape="false" @close="handleFileCloseDetail()">
<template #title>
<span>工具附件下载</span>
<div class="drawer-head-btn">
<el-button @click="fileDetailDrawerOpen = false"> </el-button>
</div><!--drawer-head-btn 抽屉顶部按钮区域-->
</template>
<template v-if="fileDetailOpen">
<download-file-detail ref="downloadFileDetailRef" :toolDetail="toolDetail"/>
</template>
</el-drawer><!--el-drawer 详情-抽屉-->
</div><!--app-container-->
</template>
<script>
import { listTool, getTool, delTool, addTool, updateTool, exportWordList} from "@/api/tool/tool";
import { deptTreeSelect } from "@/api/system/user";
import { getToken } from "@/utils/auth";
import { Base64 } from 'js-base64'
import Treeselect from "@riophae/vue-treeselect";
import toolDetail from "./toolDetail";
import downloadFileDetail from "./downloadFileDetail.vue";
import AddDoc from './AddDoc'
import mainComponent from "@/components/mainComponent/index.vue";
import { exportDocx } from '@/utils/docUtil/docutil.js';
import { addCount } from "@/api/tool/downloadCount";
export default {
name: "User",
dicts: ['sys_normal_disable', 'tool_type', 'tool_status','flow_status'],
components: { Treeselect, toolDetail, AddDoc,mainComponent,downloadFileDetail },
data() {
return {
userInfo: this.$store.getters.userInfo,
drawerShow: false,
path: 'views/workflowList/addWorkflow/',
code: '',
data: undefined,
// 遮罩层
loading: true,
// 选中数组
ids: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 显示搜索条件
showSearch: true,
selection: undefined,
toolPrincipalsChoose: false,
// 总条数
total: 0,
// 工具表格数据
toolList: null,
// 弹出层标题
title: "",
// 部门树选项
deptOptions: undefined,
toolPrincipalsData: [],
columnList: ['toolName', 'toolType', 'toolSource', 'toolPrincipalsName', 'toolRespDeptName', 'status', 'toolUse', 'testSituation', 'functionDesc', 'applyCondition', 'operateExplain', 'remark'],
checkList: [],
toolDetail: {},
// 是否显示弹出层
addDrawerOpen: false,
exoportDrawerOpen: false,
detailDrawerOpen: false,
detailOpen: false,
detailActiveName: 'first',
// 部门名称
deptName: undefined,
// 默认密码
initPassword: undefined,
// 日期范围
dateRange: [],
// 岗位选项
postOptions: [],
// 角色选项
roleOptions: [],
// 表单参数
form: {},
defaultProps: {
children: "children",
label: "label"
},
// 用户导入参数
upload: {
// 是否显示弹出层(用户导入)
open: false,
// 弹出层标题(用户导入)
title: "",
// 是否禁用上传
isUploading: false,
// 是否更新已经存在的用户数据
updateSupport: 0,
// 设置上传的请求头部
headers: { Authorization: "Bearer " + getToken() },
// 上传的地址
url: process.env.VUE_APP_BASE_API + "/system/user/importData"
},
// 查询参数
queryParams: {
pageNum: 1,
pageSize: 10,
toolCode: undefined,
toolName: undefined,
status: undefined,
createBy: this.$store.getters.userId,
permissionCheck: true,
downloadCheck:true
},
// 列信息
columns: [
{ key: 0, label: `工具编号`, visible: true },
{ key: 1, label: `工具名称`, visible: true },
{ key: 2, label: `工具类别`, visible: true },
{ key: 3, label: `部门`, visible: true },
{ key: 4, label: `负责人`, visible: true },
{ key: 5, label: `状态`, visible: true },
{ key: 6, label: `创建时间`, visible: true }
],
// 新增时的关联附件
docList: [],
addDocShow: false,
viewDialogOpen: false,
viewDialogTitle: '',
previewUrl: '',
fileDetailDrawerOpen: false,
fileDetailOpen: false,
//导出类型
statevalue: 1,
stateoptions: [
{
value: 1,
label: 'excel'
},
{
value: 2,
label: 'word'
}
],
//详情名称
toolTitle:'',
exportTitle:'',
batchExportFlag: false,
selectedRows: [], // 保存所有选中的数据
};
},
watch: {
// 根据名称筛选部门树
deptName(val) {
this.$refs.tree.filter(val);
}
},
created() {
this.getList();
this.getDeptTree();
this.getConfigKey("sys.user.initPassword").then(response => {
this.initPassword = response.msg;
});
},
methods: {
handlePriew(row){
this.previewUrl = process.env.VUE_APP_TOOL_TECH_FILE_VIEW_API + '/onlinePreview?url=' + encodeURIComponent(Base64.encode(process.env.VUE_APP_BASE_API + row.docUrl));
this.viewDialogTitle = '文档在线预览'
this.viewDialogOpen = true;
},
/**
* 新增上传附件
*/
handleDocAdd() {
this.addDocShow = true
},
handleClick(){
},
/** 查询用户列表 */
getList() {
this.loading = true;
listTool(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
this.toolList = response.rows;
for(let itemData of this.toolList){
this.$set(itemData, "relationToolList", [])
if(itemData.association != null && itemData.association != '' && itemData.association != undefined){
itemData.relationToolList = JSON.parse(itemData.association)
}
}
this.total = response.total;
this.loading = false;
}
);
},
/** 查询部门下拉树结构 */
getDeptTree() {
deptTreeSelect().then(response => {
this.deptOptions = response.data;
});
},
getDeptName(items, id) {
let label = ''
items.forEach(item => {
if(item['id'] == id){
label = item['label']
return
}
})
if(label == ''){
items.forEach(item => {
if (item.children) {
label = this.getDeptName(item.children, id)
}
})
}
return label
},
// 筛选节点
filterNode(value, data) {
if (!value) return true;
return data.label.indexOf(value) !== -1;
},
// 节点单击事件
handleNodeClick(data) {
this.queryParams.toolRespDept = data.id;
this.handleQuery();
},
// 用户状态修改
handleStatusChange(row) {
let text = row.status === "0" ? "启用" : "停用";
this.$modal.confirm('确认要"' + text + '""' + row.userName + '"用户吗?').then(function() {
return changeUserStatus(row.userId, row.status);
}).then(() => {
this.$modal.msgSuccess(text + "成功");
}).catch(function() {
row.status = row.status === "0" ? "1" : "0";
});
},
// 取消按钮
cancel() {
this.addDrawerOpen = false;
this.reset();
},
// 表单重置
reset() {
this.toolList = []
this.resetForm("queryForm")
this.handleQuery()
},
/**=============================申请使用Start================================*/
applyUse(row){
let _this = this
_this.handleOpen({...row,type:'use_apply',procInstId:undefined})
},
checkApplyUseBtn(row){
let result = false;
if(row.recordStatus=='done' && !row.downloadStatus){
result = true;
}
if(row.isHasApplyUse){
result = false;
}
return result;
},
/**=============================申请使用End================================*/
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.dateRange = [];
this.resetForm("queryForm");
this.queryParams.deptId = undefined;
this.queryParams.toolRespDept = undefined;
this.$refs.tree.setCurrentKey(null);
this.handleQuery();
},
// 多选框选中数据
handleSelectionChange(selection) {
this.selection=selection
// this.ids = selection.map(item => item.userId);
// this.single = selection.length != 1;
// this.multiple = !selection.length;
},
handleDetail(row){
if(row.recordStatus === 'done'){
this.detailDrawerOpen = true
this.detailOpen = true
this.toolDetail = row
this.toolTitle = '工具详情'
} else {
let status = row.recordStatus === 'draft' ? '1' : '0'
this.handleOpen({type:'tool_release', procInstId:row.procInstId, status:status, title: '工具发布'})
}
},
handleFileDownload(row){
this.fileDetailDrawerOpen = true
this.fileDetailOpen = true
this.toolDetail = row
},
// 更多操作触发
handleCommand(command, row) {
switch (command) {
case "handleUpdate":
this.handleUpdate(row);
break;
case "handleDelete":
this.handleDelete([{...row}]);
break;
default:
break;
}
},
/** 新增按钮操作 */
handleAdd() {
let _this = this
_this.handleOpen({type:'tool_release'})
},
handleOpen(row){
let _this = this
_this.code = row.type
_this.data = row
_this.drawerShow = true
},
/** 修改按钮操作 */
handleUpdate(row) {
let _this = this
_this.handleOpen({type:'tool_release',procInstId:row.procInstId,status:'1'})
},
/** 导出 */
handleOpenExport() {
if (this.checkList.length<1) {
this.checkList = JSON.parse(JSON.stringify(this.columnList))
}
this.exportTitle = '导出'
this.batchExportFlag = false
this.exoportDrawerOpen = true
},
/** 批量导出 */
handleOpenBatchExport() {
let self = this
if(self.selection == null || self.selection == '' || self.selection == undefined || self.selection.length <= 0){
this.$modal.msgError(`最少选择一条数据`);
return;
}
if (this.checkList.length<1) {
this.checkList = JSON.parse(JSON.stringify(this.columnList))
}
this.exportTitle = '批量导出'
this.batchExportFlag = true
this.exoportDrawerOpen = true
},
/** 导出按钮操作 */
handleExport() {
let self = this
if (this.statevalue == 1) {
let excludeFields = this.columnList.filter(item=>!this.checkList.includes(item))
let params = {
...this.queryParams,
downloadCheck:false,
excludeFields:excludeFields,
}
if(this.batchExportFlag){
params = {
downloadCheck:false,
toolIdList: self.selection.map(item=>item.toolId),
excludeFields:excludeFields,
}
}
this.download('/tool/export',params, `工具信息数据_${new Date().getTime()}.xlsx`)
setTimeout(() => {
if(self.batchExportFlag){
self.clearSelected()
}
self.exoportDrawerOpen = false;
}, 1000);
}
if (this.statevalue == 2) {
let params = {
...this.queryParams
}
if(this.batchExportFlag){
params = {
toolIdList: self.selection.map(item=>item.toolId)
}
}
exportWordList(params).then(r => {
if (r.data.length != 0) {
const data = {
form: null,
list: r.data
}
//模板文件位置在public文件夹里N
exportDocx('tool.docx', data, `tool.docx`)
setTimeout(() => {
if(self.batchExportFlag){
self.clearSelected()
}
self.exoportDrawerOpen = false;
}, 1000);
} else {
this.$message.error('没有数据');
}
})
}
},
// 文件上传中处理
handleFileUploadProgress(event, file, fileList) {
this.upload.isUploading = true;
},
// 文件上传成功处理
handleFileSuccess(response, file, fileList) {
this.upload.open = false;
this.upload.isUploading = false;
this.$refs.upload.clearFiles();
this.$alert("<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>" + response.msg + "</div>", "导入结果", { dangerouslyUseHTMLString: true });
this.getList();
},
// 提交上传文件
submitFileForm() {
this.$refs.upload.submit();
},
handleClose(){
this.drawerShow = false
this.getList();
},
handleDelete(list){
let _this = this
if (!list||list.length<1) {
this.$modal.msgError(`最少选择一条数据`);
return
}
//只能删除草稿数据
let delFlag = false;
for(let item of list){
if(!(item.recordStatus == 'draft')){
delFlag = true;
}
}
if(delFlag){
this.$modal.msgError(`只能删除流程状态为[拟稿]数据,请重新选择`);
return
}
_this.$modal.confirm('删除后该流程待办任务将会被删除请谨慎操作是否确认执行')
.then(async() => {
_this.loading = true
for (let row of list) {
let formData = {
toolId: row.toolId,
bpmClientInputModel: {
model: {
wf_procInstId: row.procInstId,
wf_sendUserId: _this.userInfo.userName,
wf_sendUserOrgId: _this.userInfo.deptId,
},
},
review: false,
recordStatus: 'cancel',
editStatus: false
}
await addTool(formData)
}
_this.$modal.msgSuccess("删除成功");
_this.loading = false
_this.getList();
})
},
selectable(row,index){
return row.recordStatus==='draft'&&row.createBy==this.userInfo.userId
},
/** 关闭详情 **/
handleCloseDetail(){
this.detailDrawerOpen = false;
this.detailOpen = false;
this.$refs.toolDetailRef.$destroy(); // 销毁组件
this.$nextTick(() => {
this.$refs.toolDetailRef = null; // 清空引用
});
},
/** 关闭详情 **/
handleFileCloseDetail(){
this.fileDetailDrawerOpen = false;
this.fileDetailOpen = false;
this.$refs.downloadFileDetailRef.$destroy(); // 销毁组件
this.$nextTick(() => {
this.$refs.downloadFileDetailRef = null; // 清空引用
});
},
/** 详情 **/
handleToolDetail(row){
this.detailDrawerOpen = true
this.detailOpen = true
let data = {
"toolId": row.toolId
}
this.toolDetail = data
},
/** association **/
handleRelationTool(value){
if(value == null || value == '' || value == undefined){
return false
}
if(value.length > 1){
return true
}
},
clearSelected() {
// 清空选中的tab
this.$refs.tableRef.clearSelection();
},
onPopoverShow(list) {
this.relationToolList = list; // 更新要显示的工具列表
},
/* handlePageChange(page) {
this.$nextTick(() => {
this.restoreSelection();
});
},
// 根据保存的选中数据,恢复选中状态
restoreSelection() {
this.$refs.tableRef.clearSelection();
this.toolList.forEach(row => {
if (this.selectedRows.some(selected => selected.toolId == row.toolId)) {
this.$refs.tableRef.toggleRowSelection(row, true);
}
});
}, */
}
};
</script>
<style scoped>
.box-title{
margin-bottom: 3px;
}
.box-title:before {
display: inline-block;
content: "";
height: 14px;
width: 3px;
background-color: #034aac;
margin-right: 5px;
}
</style>