<template>
|
<a-card :bordered='false' class='card-area'>
|
<!-- 查询区域 -->
|
<div class='table-page-search-wrapper'>
|
<a-form layout='inline' @keyup.enter.native='searchQuery'>
|
<a-row :gutter='24'>
|
|
<a-col :md='6' :sm='12'>
|
<a-form-item label='项目名称'>
|
<j-input placeholder='输入项目名称模糊查询' v-model='queryParam.xmmc'></j-input>
|
</a-form-item>
|
</a-col>
|
|
<a-col :md='6' :sm='12'>
|
<a-form-item label='项目编号'>
|
<j-input placeholder='输入项目编号模糊查询' v-model='queryParam.xmbh'></j-input>
|
</a-form-item>
|
</a-col>
|
|
<a-col :md='6' :sm='12'>
|
<a-form-item label='本周更新'>
|
<a-select v-model='queryParam.renewal' placeholder='请选择'>
|
<a-select-option value=''>请选择</a-select-option>
|
<a-select-option :value='1'>是</a-select-option>
|
<a-select-option :value='0'>否</a-select-option>
|
</a-select>
|
</a-form-item>
|
</a-col>
|
|
<template v-if='toggleSearchStatus'>
|
|
<a-col :md='6' :sm='12'>
|
<a-form-item label='项目状态'>
|
<j-dict-select-tag
|
placeholder='请选择项目状态'
|
dictCode='xmzt'
|
v-model='queryParam.xmzt'
|
/>
|
</a-form-item>
|
</a-col>
|
|
<a-col :md='6' :sm='12'>
|
<a-form-item label='负责组'>
|
<j-search-select-tag
|
placeholder='请选择负责组别'
|
v-model='queryParam.xmfzz'
|
dict='sys_depart,depart_name,id'
|
:pageSize='1000'
|
:async='true'>
|
</j-search-select-tag>
|
</a-form-item>
|
</a-col>
|
|
<a-col :md='6' :sm='12'>
|
<a-form-item label='立项'>
|
<a-select v-model='queryParam.approval' placeholder='请选择'>
|
<a-select-option value=''>请选择</a-select-option>
|
<a-select-option :value='1'>是</a-select-option>
|
<a-select-option :value='0'>否</a-select-option>
|
</a-select>
|
</a-form-item>
|
</a-col>
|
|
<a-col :md='6' :sm='12'>
|
<a-form-item label='里程碑'>
|
<j-dict-select-tag
|
placeholder='请选择项目里程碑'
|
dictCode='lcb'
|
v-model='queryParam.lcb'
|
/>
|
</a-form-item>
|
</a-col>
|
|
<a-col :md='6' :sm='12'>
|
<a-form-item label='负责人'>
|
<j-search-select-tag
|
placeholder='请选择负责人'
|
v-model='queryParam.xmfzr'
|
dict='sys_user,realname,username'
|
:pageSize='10'
|
>
|
</j-search-select-tag>
|
</a-form-item>
|
</a-col>
|
|
|
<a-col :md='6' :sm='12'>
|
<a-form-item label='时间区间'>
|
<j-date v-model='queryParam.ksrq_begin' date-format='YYYY-MM-DD' placeholder='请选择项目开始时间'></j-date>
|
|
</a-form-item>
|
</a-col>
|
|
<a-col :md='6' :sm='12'>
|
<a-form-item label='时间区间'>
|
<j-date v-model='queryParam.ksrq_end' date-format='YYYY-MM-DD' placeholder='请选择项目开始时间'></j-date>
|
</a-form-item>
|
</a-col>
|
|
</template>
|
|
<a-col :md='6' :sm='8'>
|
<span style='float: left;overflow: hidden;' class='table-page-search-submitButtons'>
|
<a-button type='primary' @click='searchQuery' icon='search'>查询</a-button>
|
<a-button type='primary' @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>
|
|
<!-- 操作按钮区域 -->
|
<div class='table-operator' style='border-top: 5px'>
|
<a-button @click='handleAdd' type='primary' icon='plus'>添加项目</a-button>
|
<a-button type='primary' icon='download' @click="handleExportXls('项目信息')">导出</a-button>
|
<a-upload name='file' :showUploadList='false' :multiple='false' :headers='tokenHeader' :action='importExcelUrl'
|
@change='handleImportExcel'>
|
<a-button type='primary' icon='import'>导入</a-button>
|
</a-upload>
|
<a-dropdown v-if='selectedRowKeys.length > 0'>
|
<a-menu slot='overlay' @click='handleMenuClick'>
|
<a-menu-item key='1'>
|
<a-icon type='delete' @click='batchDel' />
|
删除
|
</a-menu-item>
|
</a-menu>
|
<a-button style='margin-left: 8px'>
|
批量操作
|
<a-icon type='down' />
|
</a-button>
|
</a-dropdown>
|
<j-super-query :fieldList='superQueryFieldList' @handleSuperQuery='handleSuperQuery' />
|
|
|
<a-tooltip placement='top'>
|
<template slot='title'>
|
<span>一键导出项目工作看板</span>
|
</template>
|
<a-button @click='handleExport' type='primary' icon='export' :loading="downloadLoading">一键导出</a-button>
|
</a-tooltip>
|
|
</div>
|
|
<!-- table区域-begin -->
|
<div>
|
<div class='ant-alert ant-alert-info' style='margin-bottom: 16px;'>
|
<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>
|
<span style='float:right;'>
|
<a @click='loadData()'><a-icon type='sync' />刷新</a>
|
<a-divider type='vertical' />
|
<a-popover title='自定义列' trigger='click' placement='leftBottom'>
|
<template slot='content'>
|
<a-checkbox-group @change='onColSettingsChange' v-model='settingColumns' :defaultValue='settingColumns'>
|
<a-row style='width: 400px'>
|
<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'><j-ellipsis :value='item.title'
|
:length='10'></j-ellipsis></a-checkbox></a-col>
|
</template>
|
</template>
|
</a-row>
|
</a-checkbox-group>
|
</template>
|
<a><a-icon type='setting' />设置</a>
|
</a-popover>
|
</span>
|
</div>
|
|
<a-table
|
style='height: 500px'
|
:scroll='{ x: 2000 }'
|
ref='table'
|
bordered
|
size='middle'
|
rowKey='id'
|
:columns='columns'
|
:dataSource='dataSource'
|
:pagination='ipagination'
|
:loading='loading'
|
:rowSelection='{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}'
|
@change='handleTableChange'>
|
|
<!-- 字符串超长截取省略号显示-->
|
<span slot='esContent6' slot-scope='text'>
|
<j-ellipsis :value='text' :length='6' />
|
</span>
|
<span slot='esContent10' slot-scope='text'>
|
<j-ellipsis :value='text' :length='10' />
|
</span>
|
<span slot='esContent12' slot-scope='text'>
|
<j-ellipsis :value='text' :length='12' />
|
</span>
|
<span slot='esContent15' slot-scope='text'>
|
<j-ellipsis :value='text' :length='15' />
|
</span>
|
<span slot='esContent20' slot-scope='text'>
|
<j-ellipsis :value='text' :length='20' />
|
</span>
|
<template slot='renewal' slot-scope='text'>
|
<template v-if='text == 1'>
|
<a-badge status='success' text='是' />
|
</template>
|
<span v-else>否</span>
|
</template>
|
|
<template slot='approval' slot-scope='text'>
|
<template v-if='text == 1'>
|
<a-badge status='success' text='是' />
|
</template>
|
<span v-else>否</span>
|
</template>
|
|
|
<span slot='action' slot-scope='text, record'>
|
<a @click='openBoard(record)'>看板</a>
|
|
<a-divider v-has="'project:edit'" type='vertical' />
|
<a v-has="'project:edit'" @click='handleEdit(record)'>编辑</a>
|
|
<a-divider type='vertical' />
|
<a-dropdown>
|
<a class='ant-dropdown-link'>
|
更多 <a-icon type='down' />
|
</a>
|
<a-menu slot='overlay'>
|
<a-menu-item>
|
<a href='javascript:;' @click='handleMilestone(record)'>里程碑</a>
|
</a-menu-item>
|
<a-menu-item>
|
<a href='javascript:;' @click='handleDetail(record)'>详情</a>
|
</a-menu-item>
|
|
<a-menu-item v-has="'project:edit'">
|
<a-popconfirm title='确定删除吗?' @confirm='() => handleDelete(record.id)'>
|
<a>删除</a>
|
</a-popconfirm>
|
</a-menu-item>
|
|
</a-menu>
|
</a-dropdown>
|
</span>
|
|
|
</a-table>
|
</div>
|
|
<!-- 添加项目 -->
|
<project-modal ref='modalForm' @ok='modalFormOk'></project-modal>
|
|
<!-- table区域-end -->
|
</a-card>
|
</template>
|
|
<script>
|
import { JeecgListMixin } from '@/mixins/JeecgListMixin'
|
import ProjectModal from '@views/pro/modules/ProjectModal'
|
import Vue from 'vue'
|
import { USER_INFO } from '@/store/mutation-types'
|
import { getAction, getFileAccessHttpUrl } from '@api/manage'
|
import { PRO_WORK_BOARD } from '@/vuebus/event-bus'
|
|
export default {
|
name: 'ProjectList',
|
mixins: [JeecgListMixin],
|
components: {
|
ProjectModal
|
},
|
watch: {
|
dataSource: {
|
deep: true,
|
handler() {
|
this.initFilterData()
|
}
|
}
|
},
|
data() {
|
return {
|
description: '',
|
filterColumns: {},
|
queryParam: {},
|
downloadLoading:false,
|
tipFlag:true,
|
disableMixinCreated: true,
|
//表头
|
columns: [],
|
//列设置
|
settingColumns: [],
|
/* 分页参数 */
|
ipagination: {
|
current: 1,
|
pageSize: 10,
|
pageSizeOptions: ['10', '20', '30', '50',, '100', '200'],
|
showTotal: (total, range) => {
|
return range[0] + '-' + range[1] + ' 共' + total + '条'
|
},
|
showQuickJumper: true,
|
showSizeChanger: true,
|
total: 0
|
},
|
/* 排序参数 */
|
isorter: {
|
column: 'sortNo,createTime',
|
order: 'desc'
|
},
|
|
superQueryFieldList: [
|
{ type: 'input', value: 'xmmc', text: '项目名称' },
|
{ type: 'input', value: 'xmbh', text: '项目编号' }
|
],
|
url: {
|
list: 'pro/project/list',
|
delete: 'pro/project/delete',
|
deleteBatch: 'pro/project/deleteBatch',
|
exportXlsUrl: '/pro/project/exportXls',
|
customExport: '/pro/project/customExport',
|
importExcelUrl: 'pro/project/importExcel'
|
}
|
}
|
},
|
mounted() {
|
this.$bus.$on(PRO_WORK_BOARD, (args) => {
|
this.downloadLoading = false
|
|
//节流
|
if(!this.tipFlag){
|
return false;
|
}
|
this.tipFlag = false;
|
setTimeout(()=>{
|
this.tipFlag = true;
|
},1000)
|
|
if(args && args.file_path){
|
this.openNotification('success', '项目看板生成成功,开始下载!', 4)
|
this.downloadFile(args.file_path)
|
|
}else{
|
setTimeout(()=>{
|
this.openNotification('error', '导出失败,请重试或联系管理员', 10)
|
},1000)
|
}
|
|
|
})
|
},
|
methods: {
|
initFilterData() {
|
if (!this.dataSource) return
|
var result = {}
|
var colmuns = ['xmfzr_dictText', 'xmfzz_dictText']
|
let that = this
|
colmuns.forEach(function(col, index) {
|
var arr = that.dataSource.map(function(item, index, arr) { // 第一个参数是数组的当前元素,第二个参数是当前元素下标,第三个参数是操作数组
|
var i = {}
|
i.text = item[col]
|
i.value = item[col]
|
return i
|
})
|
console.info(arr)
|
arr = arr.filter(o => o.text)
|
arr = that.unique(arr, 'text')
|
// newData 一个新的数组来接受 方法中传需要去重的数组和根据数组中某个去重字段
|
|
result[col] = arr
|
})
|
this.filterColumns = result
|
console.info(this.filterColumns)
|
this.initColumns()
|
|
},
|
handleMenuClick(e) {
|
if (e.key == 1) {
|
this.batchDel()
|
}
|
},
|
handleExport() {
|
if (this.selectedRowKeys.length < 1) {
|
this.$message.warning('请选择需要导出的项目!')
|
return
|
}
|
let ids = this.selectedRowKeys.join(',')
|
// this.selectedRowKeys.forEach(item=>{
|
// console.info(item)
|
// ids += item
|
// ids += ","
|
// })
|
this.downloadLoading = true;
|
//避免
|
setTimeout(()=>{
|
this.downloadLoading = false
|
},60*1000)
|
|
getAction(this.url.customExport, { ids: ids, base: this.downloadBaseUrl }).then(res => {
|
if (res.success) {
|
console.info(res)
|
if (res.result.filePath) {
|
this.openNotification('success', '导出成功,正在下载文件!', 2)
|
this.downloadFile(res.result.filePath)
|
} else {
|
this.openNotification('info', '等待系统生成项目报告,完成后将自动下载文件',10)
|
}
|
|
} else {
|
this.openNotification('error', '导出失败,请联系管理员---', 10)
|
}
|
})
|
|
},
|
downloadFile(text) {
|
if (!text) {
|
this.$message.warning('未知的文件')
|
return
|
}
|
if (text.indexOf(',') > 0) {
|
text = text.substring(0, text.indexOf(','))
|
}
|
let url = getFileAccessHttpUrl(text)
|
console.info(url)
|
window.open(url, '_self')
|
},
|
//提示
|
openNotification(type, message, time) {
|
this.$notification[type]({
|
message: '提示',
|
description:
|
message,
|
duration: time
|
})
|
},
|
onSyncFinally({ isToLocal }) {
|
// 同步到本地时刷新下数据
|
if (isToLocal) {
|
this.loadData()
|
}
|
},
|
openBoard(record) {
|
//this.$refs.boardModal.show(record)
|
//this.$router.push({path:"/pro/board",query:{id:record.id}})
|
this.$router.push({ name: 'pro-board', params: { id: record.id } })
|
|
},
|
unique(arr, val) {
|
const res = new Map()
|
return arr.filter((item) => !res.has(item[val]) && res.set(item[val], 1))
|
},
|
|
boardModalOk() {
|
|
},
|
handleMilestone(record) {
|
this.$router.push({ name: 'pro-milestone', params: { id: record.id } })
|
},
|
|
//列设置更改事件
|
onColSettingsChange(checkedValues) {
|
var key = this.$route.name + ':colsettings'
|
Vue.ls.set(key, checkedValues)
|
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'
|
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
|
}
|
}
|
},
|
created() {
|
const user = Vue.ls.get(USER_INFO)
|
/*if(user&&user.departIds){
|
if(user.departIds.indexOf(",")){
|
var departIds = user.departIds.split(",")
|
this.queryParam.xmfzz = departIds[0]
|
}else {
|
this.queryParam.xmfzz = user.departIds
|
}
|
|
}*/
|
this.loadData()
|
this.initDictConfig()
|
|
|
},
|
computed: {
|
defColumns() {
|
let that = this
|
const columns = [
|
{
|
title: '#',
|
dataIndex: '',
|
key: 'rowIndex',
|
width: 40,
|
align: 'center',
|
customRender: function(t, r, index) {
|
return parseInt(index) + 1
|
}
|
},
|
{
|
title: '项目集名称',
|
dataIndex: 'groupCode_dictText',
|
width: 200,
|
sorter: true,
|
scopedSlots: { customRender: 'esContent15' }
|
},
|
{
|
title: '项目集编号',
|
dataIndex: 'groupCode',
|
width: 120,
|
sorter: true,
|
scopedSlots: { customRender: 'esContent15' }
|
},
|
{
|
title: '项目名称',
|
dataIndex: 'xmmc',
|
width: 240,
|
sorter: true,
|
scopedSlots: { customRender: 'esContent15' }
|
},
|
{
|
title: '项目编号',
|
width: 120,
|
dataIndex: 'xmbh'
|
},
|
{
|
title: '立项',
|
align: 'center',
|
width: 80,
|
dataIndex: 'approval',
|
scopedSlots: { customRender: 'approval' }
|
|
},
|
{
|
title: '负责人',
|
align: 'center',
|
width: 120,
|
dataIndex: 'xmfzr_dictText',
|
sorter: true,
|
filters: that.filterColumns['xmfzr_dictText'],
|
onFilter: (value, record) => {
|
if (record.xmfzr_dictText) {
|
return record.xmfzr_dictText.includes(value)
|
}
|
|
}
|
},
|
{
|
title: '项目负责组',
|
align: 'center',
|
width: 120,
|
dataIndex: 'xmfzz_dictText',
|
filters: that.filterColumns['xmfzz_dictText'],
|
onFilter: (value, record) => {
|
if (record.xmfzz_dictText) {
|
return record.xmfzz_dictText.includes(value)
|
}
|
|
}
|
},
|
{
|
title: '本周更新',
|
align: 'center',
|
width: 80,
|
dataIndex: 'renewal',
|
scopedSlots: { customRender: 'renewal' }
|
|
},
|
{
|
title: '项目类型',
|
align: 'center',
|
width: 100,
|
dataIndex: 'xmlx_dictText',
|
filters: that.filterColumns['xmlx_dictText'],
|
onFilter: (value, record) => record.xmlx_dictText.includes(value)
|
},
|
/* {
|
title: '当前阶段',
|
align: "center",
|
width: 60,
|
dataIndex: 'dqjd_dictText',
|
},*/
|
|
{
|
title: '项目状态',
|
align: 'center',
|
width: 80,
|
dataIndex: 'xmzt_dictText'
|
},
|
{
|
title: '项目来源',
|
align: 'center',
|
width: 100,
|
dataIndex: 'xmly_dictText'
|
},
|
|
{
|
title: '报告日期',
|
align: 'center',
|
width: 100,
|
dataIndex: 'bgrq',
|
sorter: true
|
},
|
{
|
title: '里程碑',
|
align: 'center',
|
width: 100,
|
dataIndex: 'lcb_dictText',
|
filters: that.filterColumns['lcb_dictText'],
|
onFilter: (value, record) => record.lcb_dictText.includes(value)
|
},
|
|
{
|
title: '开始日期',
|
align: 'center',
|
width: 100,
|
dataIndex: 'ksrq',
|
sorter: true
|
},
|
{
|
title: '项目成员',
|
align: 'center',
|
width: 120,
|
dataIndex: 'xmcy_dictText',
|
scopedSlots: { customRender: 'esContent6' }
|
},
|
{
|
title: '排序',
|
align: 'center',
|
width: 80,
|
dataIndex: 'sortNo'
|
},
|
|
{
|
title: '操作',
|
dataIndex: 'action',
|
fixed: 'right',
|
scopedSlots: { customRender: 'action' },
|
align: 'center',
|
width: 170
|
}
|
|
]
|
return columns
|
},
|
importExcelUrl: function() {
|
return `${window._CONFIG['domianURL']}/${this.url.importExcelUrl}`
|
},
|
downloadBaseUrl: function() {
|
return `${window._CONFIG['staticDomainURL']}/`
|
}
|
}
|
}
|
</script>
|
|
<style scoped>
|
@import '~@assets/less/common.less';
|
</style>
|