11 changed files with 1850 additions and 74 deletions
@ -0,0 +1,998 @@ |
|||||
|
<template> |
||||
|
<div class="app-container" v-loading="state.loading"> |
||||
|
<!-- 查询头部 --> |
||||
|
<el-card class="search-container" v-if="!(props.hideSearch && props.hideSetColums)"> |
||||
|
<el-form :inline="true" v-if="!props.hideSearch"> |
||||
|
<el-form-item |
||||
|
v-auth="props.apiName + state.searchBtnOptions['search'].auth" |
||||
|
v-for="(item,index) in props.searchOptions" |
||||
|
:key="index" |
||||
|
:label="item.label"> |
||||
|
<!-- 文本 --> |
||||
|
<el-input |
||||
|
v-if="item.type == 'input'" |
||||
|
v-model="props.searchFilter[item.prop]" |
||||
|
:placeholder="item.label" |
||||
|
:clearable="!item.noClear" |
||||
|
/> |
||||
|
<!-- 数字 --> |
||||
|
<el-input-number |
||||
|
v-if="item.type == 'number'" |
||||
|
v-model="props.searchFilter[item.prop]" |
||||
|
:min="item.min" |
||||
|
:max="item.max" |
||||
|
/> |
||||
|
<!-- 时间区域 --> |
||||
|
<el-date-picker |
||||
|
v-if="item.type == 'datetimerange'" |
||||
|
v-model="props.searchFilter[item.prop]" |
||||
|
type="datetimerange" |
||||
|
start-placeholder="起始时间" |
||||
|
end-placeholder="结束时间" |
||||
|
format="YYYY-MM-DD HH:mm:ss" |
||||
|
value-format="YYYY-MM-DD HH:mm:ss" |
||||
|
style="width:370px" |
||||
|
/> |
||||
|
<!-- 选择框 --> |
||||
|
<el-select |
||||
|
v-if="item.type == 'select'" |
||||
|
v-model="props.searchFilter[item.prop]" |
||||
|
:filterable="!item.noSearch" |
||||
|
placeholder="请选择" |
||||
|
style="width: 240px" |
||||
|
:clearable="!item.noClear" |
||||
|
> |
||||
|
<el-option |
||||
|
v-for="(op,op_index) in item.options" |
||||
|
:key="op_index" |
||||
|
:label="op.label" |
||||
|
:value="op.value" |
||||
|
/> |
||||
|
</el-select> |
||||
|
</el-form-item> |
||||
|
<el-form-item> |
||||
|
<div style="margin-right:10px" v-for="(btn,btn_key) in props.searchButtons" :key="btn_key"> |
||||
|
<!-- 导出 --> |
||||
|
<!-- <el-dropdown |
||||
|
v-auth="(props.authName || props.apiName) + state.searchBtnOptions[btn].auth" |
||||
|
:hide-on-click="false" |
||||
|
v-if="state.searchBtnOptions[btn].auth == ':export'" |
||||
|
> |
||||
|
<el-button |
||||
|
:icon="state.searchBtnOptions[btn].icon" |
||||
|
:type="state.searchBtnOptions[btn].type"> |
||||
|
{{state.searchBtnOptions[btn].label}} |
||||
|
<el-icon class="el-icon--right"><arrow-down /></el-icon> |
||||
|
</el-button> |
||||
|
<template #dropdown> |
||||
|
<el-dropdown-menu> |
||||
|
<el-dropdown-item @click="exportHandle()">按条件导出【当前页】</el-dropdown-item> |
||||
|
<el-dropdown-item divided @click="exportHandle(true)">按条件导出【全部】</el-dropdown-item> |
||||
|
</el-dropdown-menu> |
||||
|
</template> |
||||
|
</el-dropdown> --> |
||||
|
<!-- 其他按钮 --> |
||||
|
<el-button |
||||
|
:icon="state.searchBtnOptions[btn].icon" |
||||
|
v-auth="(props.authName || props.apiName) + state.searchBtnOptions[btn].auth" |
||||
|
:type="state.searchBtnOptions[btn].type" |
||||
|
@click="searchBtnHandle(btn)" |
||||
|
>{{state.searchBtnOptions[btn].label}}</el-button> |
||||
|
</div> |
||||
|
</el-form-item> |
||||
|
</el-form> |
||||
|
<!-- 右侧按钮(如:保存页面) --> |
||||
|
<div> |
||||
|
<el-button |
||||
|
v-for="(btn,btn_key) in state.searchRightBtn" |
||||
|
:key="btn_key" |
||||
|
:icon="btn.icon" |
||||
|
v-auth="btn.sAuth || props.apiName + btn.auth" |
||||
|
:type="btn.type" |
||||
|
@click="searchRightBtnHandle(btn)" |
||||
|
style="margin-right: 10px" |
||||
|
>{{btn.label}}</el-button> |
||||
|
<!-- 字段设置 --> |
||||
|
<setColumsPop |
||||
|
style="margin-left: auto;" |
||||
|
:localTableColumnsName="state.localTableColumnsName" |
||||
|
:initTableColums="state.initTableColums" |
||||
|
:tableColumns="getTableColumns()" |
||||
|
v-if="!props.hideSetColums" |
||||
|
></setColumsPop> |
||||
|
</div> |
||||
|
</el-card> |
||||
|
<!-- 头部详情 --> |
||||
|
<el-card v-loading="state.detailLoading" class="headerInfo-container" v-if="!props.hideHeaderInfo"> |
||||
|
<el-descriptions label-width="120" :title="`当前页【第${getIndexById()}行】数据信息`" :border="true" :column="5" v-if="state.headerInfoData && state.headerInfoData.length > 0"> |
||||
|
<el-descriptions-item |
||||
|
v-for="(item,index) in state.headerInfoData" |
||||
|
:key="index" |
||||
|
:label="item.label"> |
||||
|
{{item.value}} |
||||
|
</el-descriptions-item> |
||||
|
</el-descriptions> |
||||
|
<el-empty v-else description="暂无数据" class="headerInfoEmpty"/> |
||||
|
</el-card> |
||||
|
<!-- 列表 --> |
||||
|
<el-card class="paged-table-container"> |
||||
|
<elTable |
||||
|
ref="table_Ref" |
||||
|
:columnWidth="props.columnWidth" |
||||
|
:columnHeaderAlign="props.columnHeaderAlign" |
||||
|
:columnAlign="props.columnAlign" |
||||
|
:tableData="state.tableData" |
||||
|
:tableColumns="getTableColumns()" |
||||
|
@sortChange="sortChange" |
||||
|
:leftOperation="props.leftOperation" |
||||
|
@leftOperationHadel="leftOperationHadel" |
||||
|
:rightOperation="getRightOperation()" |
||||
|
@rightOperationHadel="rightOperationHadel" |
||||
|
:multipleTable="props.multipleTable" |
||||
|
@tableSelectionHandle="tableSelectionHandle" |
||||
|
@editItemFocusHandle="(item,scope,event)=>{getItemDetail(item.type,scope.row,'focus')}" |
||||
|
@editItemChangeHandle="editItemChangeHandle" |
||||
|
@cell-click="(row,column,cell,event)=>{getItemDetail('cell',row,'cellClick')}" |
||||
|
@editItemClearHandle="(item,scope)=>{getItemDetail(item.type,scope.row,'clear')}" |
||||
|
:getEditItemDisabled="getEditItemDisabled" |
||||
|
:selectableDisabled="selectableDisabled" |
||||
|
:tableRowClassName="tableRowClassName" |
||||
|
:showTableIndex="props.showTableIndex" |
||||
|
></elTable> |
||||
|
|
||||
|
<!-- :tableFormRules="state.tableFormRulesData" --> |
||||
|
|
||||
|
<elPager |
||||
|
v-loading="state.pageLoading" |
||||
|
style="margin-top: 15px;float:right" |
||||
|
:pager="state.pager" |
||||
|
@size-change="pageSizeChange" |
||||
|
@current-change="pageCurrentChange" |
||||
|
></elPager> |
||||
|
</el-card> |
||||
|
|
||||
|
<!-- 导入弹窗 --> |
||||
|
<importPop |
||||
|
ref="importPopRef" |
||||
|
:apiName="props.apiName" |
||||
|
@success="importSuccess" |
||||
|
/> |
||||
|
|
||||
|
<!-- 编辑弹窗 --> |
||||
|
<apiEditPop |
||||
|
ref="apiEditPopRef" |
||||
|
:apiName="props.apiName" |
||||
|
@submitEditForm="submitEditForm" |
||||
|
:formRules="props.apiEditFormRules" |
||||
|
/> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script setup> |
||||
|
defineOptions({ name: 'ediTtablePage' }) |
||||
|
import store from '@/stores' |
||||
|
import apiTableColumns from '@/utils/common/apiTableColumns' |
||||
|
import { reactive, ref, onMounted,computed } from 'vue' |
||||
|
import { |
||||
|
getCommonPaged, |
||||
|
getCommonDeatailPaged, |
||||
|
postCommonExport, |
||||
|
postCommonCreate, |
||||
|
putCommonUpdate, |
||||
|
deleteCommonApi, |
||||
|
getCommonCustominvoke, |
||||
|
getCommonDetailById, |
||||
|
postCommonConfirmMany, |
||||
|
postCommonUpdateMany |
||||
|
} from '@/api/common/index' |
||||
|
import { ElMessageBox, ElMessage,ElTable, ElTableColumn } from 'element-plus' |
||||
|
import elTable from '@/components/elTable/index.vue' |
||||
|
import elPager from '@/components/elPager/index.vue' |
||||
|
import setColumsPop from '@/components/setColumsPop/index.vue' |
||||
|
import { getPageParamsForFilter,getLocalTableColumnsName } from '@/utils/common/index' |
||||
|
import { downloadByData } from '@/utils/download' |
||||
|
import importPop from '@/components/importPop/index.vue' |
||||
|
import apiEditPop from '@/components/apiEditPop/index.vue' |
||||
|
import { formatDate } from '@/utils/formatTime' |
||||
|
import apiServeNames from '@/utils/common/apiServeNames' |
||||
|
|
||||
|
import { useRoute } from 'vue-router' |
||||
|
|
||||
|
const route = useRoute() |
||||
|
const userStore = store.userStore() |
||||
|
const userInfo = userStore.state |
||||
|
const auths = store.permissionStore() |
||||
|
|
||||
|
const state = reactive({ |
||||
|
loading:false, |
||||
|
detailLoading:false, |
||||
|
pageLoading:false, |
||||
|
searchBtnOptions:{ |
||||
|
search:{icon:'Search',auth:':page',label:'查询',type:null}, |
||||
|
create:{icon:'Plus',auth:':create',label:'新增',type:'primary'}, |
||||
|
import:{icon:'BottomRight',auth:':import',label:'导入',type:'warning'}, |
||||
|
export:{icon:'TopRight',auth:':export',label:'导出',type:'success'}, |
||||
|
custominvoke:{icon:'Position',auth:':custominvoke',label:'手动开关',type:'primary'}, |
||||
|
outputMany:{icon:'Position',auth:':outputMany',label:'手动传出',type:'primary'}, |
||||
|
}, |
||||
|
searchRightBtn:[{name:'pageSave',icon:'Check',auth:':pageSave',label:'保存页面',type:'warning'}], |
||||
|
tableData:[], |
||||
|
// table排序处理 |
||||
|
sortFilter:{ |
||||
|
sortBy:undefined, |
||||
|
isAscending:undefined |
||||
|
}, |
||||
|
pager:{ |
||||
|
page: 1, |
||||
|
pageSize: 10, |
||||
|
total: 1, |
||||
|
}, |
||||
|
tableSelectList:[], |
||||
|
leaveSaveTip:'此操作将重新渲染页面,检测有数据【未保存】,操作后将【清空未保存数据】,是否确定继续?', |
||||
|
// 头部明细数据 |
||||
|
headerInfoData:[], |
||||
|
currentDetailId:null,//当前详情id暂存,避免重复获取 |
||||
|
// 暂存原始数据(用于校验是否更改) |
||||
|
stage_tableData:[], |
||||
|
// 暂存更改的行数(用于保留校验更改行数) |
||||
|
stage_indexs:[], |
||||
|
//初始化表头,未从缓存获取之前 |
||||
|
initTableColums:[], |
||||
|
localTableColumnsName:null, |
||||
|
//tabel内部表单验证 |
||||
|
tableFormRulesData:null, |
||||
|
}) |
||||
|
|
||||
|
const props = defineProps({ |
||||
|
// api名称 |
||||
|
apiName: { |
||||
|
type: String, |
||||
|
default: null |
||||
|
}, |
||||
|
// 查看明细colum名称 |
||||
|
detailColumName:{ |
||||
|
type: String, |
||||
|
default: null |
||||
|
}, |
||||
|
// api类型 detailApi:走getdetail接口,不传或者pageApi:走getdatapaged接口 |
||||
|
apiType: { |
||||
|
type: String, |
||||
|
default: null |
||||
|
}, |
||||
|
// 隐藏表头搜索 |
||||
|
hideSearch:{ |
||||
|
type: Boolean, |
||||
|
default: false |
||||
|
}, |
||||
|
// 多选 |
||||
|
multipleTable:{ |
||||
|
type: Boolean, |
||||
|
default: false |
||||
|
}, |
||||
|
// 序号 |
||||
|
showTableIndex:{ |
||||
|
type: Boolean, |
||||
|
default: true |
||||
|
}, |
||||
|
// 左侧操作列 |
||||
|
leftOperation:{ |
||||
|
type: Object, |
||||
|
default: null |
||||
|
}, |
||||
|
// 右侧操作列 |
||||
|
rightOperation:{ |
||||
|
type: [Object,String], |
||||
|
default: null |
||||
|
}, |
||||
|
// 右侧操作列,特殊自定义格式下,包含api操作 |
||||
|
showApiRightOperation:{ |
||||
|
type: Object, |
||||
|
default: null |
||||
|
}, |
||||
|
// 右侧通用按钮特殊字段判断隐藏规则,默认为编辑删除,readState=true不可操作, |
||||
|
// 如有特殊规则,则使用该方法特殊处理,当前判断方式为“=”,如后期有其他需求再进行封装 |
||||
|
apiRightHideConfig:{ |
||||
|
type: Object, |
||||
|
default: { |
||||
|
apiUpdate:{prop:'readState',ruleValue:true}, |
||||
|
apiDelete:{prop:'readState',ruleValue:true}, |
||||
|
} |
||||
|
}, |
||||
|
// table表头 |
||||
|
tableColumns: { |
||||
|
type: Object, |
||||
|
default: null |
||||
|
}, |
||||
|
// 查询配置 |
||||
|
searchOptions: { |
||||
|
type: Object, |
||||
|
default: [] |
||||
|
}, |
||||
|
// 查询按钮 |
||||
|
searchButtons: { |
||||
|
type: Object, |
||||
|
default: ['search','export'] |
||||
|
}, |
||||
|
// table查询数据filter |
||||
|
searchFilter: { |
||||
|
type: Object, |
||||
|
default: {} |
||||
|
}, |
||||
|
// 表头宽度 |
||||
|
columnWidth:{ |
||||
|
type: Number, |
||||
|
default: 120 |
||||
|
}, |
||||
|
// 表头对齐 |
||||
|
columnHeaderAlign:{ |
||||
|
type: String, |
||||
|
default: 'center' |
||||
|
}, |
||||
|
// 表内容对齐 |
||||
|
columnAlign:{ |
||||
|
type: String, |
||||
|
default: 'center' |
||||
|
}, |
||||
|
// 表单规则 |
||||
|
apiEditFormRules:{ |
||||
|
type: Object, |
||||
|
default: null |
||||
|
}, |
||||
|
// table内表单规则 |
||||
|
tableFormRules:{ |
||||
|
type: Object, |
||||
|
default: null |
||||
|
}, |
||||
|
// 隐藏头部明细 |
||||
|
hideHeaderInfo:{ |
||||
|
type: Boolean, |
||||
|
default: false |
||||
|
}, |
||||
|
// 可编辑单元格/勾选框判断禁用规则,默认为readState=true为禁用, |
||||
|
// 如有特殊规则,则使用该方法特殊处理,当前判断方式为“=”,如后期有其他需求再进行封装 |
||||
|
editDisabledConfig:{ |
||||
|
type: Object, |
||||
|
default: [ |
||||
|
{prop:'readState',ruleValue:true}, |
||||
|
// {prop:'releaseEdition',ruleValue:'2024121901'}, |
||||
|
] |
||||
|
}, |
||||
|
// 隐藏字段设置 |
||||
|
hideSetColums:{ |
||||
|
type: Boolean, |
||||
|
default: false |
||||
|
} |
||||
|
}) |
||||
|
|
||||
|
// 获取表头 noFilter 获取不需要处理字段设置的值 |
||||
|
function getTableColumns(noFilter){ |
||||
|
if(noFilter){ |
||||
|
return props.tableColumns || apiTableColumns[props.apiName] |
||||
|
}else{ |
||||
|
state.localTableColumnsName = getLocalTableColumnsName(useRoute().name) |
||||
|
if(props.apiType == 'detailApi'){ |
||||
|
state.localTableColumnsName = getLocalTableColumnsName(props.apiName+'Detail') |
||||
|
} |
||||
|
let _local = JSON.parse(localStorage.getItem(state.localTableColumnsName)) |
||||
|
state.initTableColums = props.tableColumns || apiTableColumns[props.apiName] |
||||
|
let _list = _local && _local != null && _local != undefined ? _local : JSON.parse(JSON.stringify(state.initTableColums)) |
||||
|
return _list |
||||
|
} |
||||
|
// return props.tableColumns || apiTableColumns[props.apiName] |
||||
|
} |
||||
|
|
||||
|
const emits = defineEmits([ |
||||
|
'leftOperationHadel', |
||||
|
'rightOperationHadel', |
||||
|
'tableSelectionHandle' |
||||
|
]) |
||||
|
|
||||
|
// table多选 |
||||
|
function tableSelectionHandle (val){ |
||||
|
state.tableSelectList = val |
||||
|
emits('tableSelectionHandle',val) |
||||
|
} |
||||
|
|
||||
|
// 左侧操作列 |
||||
|
function leftOperationHadel(btn,scope) { |
||||
|
emits('leftOperationHadel',btn,scope) |
||||
|
} |
||||
|
|
||||
|
// 获取右侧操作列 |
||||
|
function getRightOperation() { |
||||
|
// 自定义右侧列,且不需要默认api通用操作 |
||||
|
if(typeof props.rightOperation == 'object' && !props.showApiRightOperation){ |
||||
|
return props.rightOperation |
||||
|
} |
||||
|
// 无自定义操作,或者有自定义且需要默认api操作 |
||||
|
else if( |
||||
|
(typeof props.rightOperation == 'object' && props.showApiRightOperation) |
||||
|
|| typeof props.rightOperation == 'string' |
||||
|
){ |
||||
|
// 格式化默认api按钮合集 |
||||
|
let _apiArr = props.showApiRightOperation || props.rightOperation.split(',') |
||||
|
let _config = { |
||||
|
apiUpdate:{label:'编辑',type:'warning'}, |
||||
|
apiDelete:{label:'删除',type:'danger'}, |
||||
|
} |
||||
|
let _btns = [] |
||||
|
if(_apiArr && _apiArr.length > 0){ |
||||
|
_apiArr.forEach(item => { |
||||
|
_btns.push({ |
||||
|
label:_config[item].label, |
||||
|
name:item, |
||||
|
link:true, |
||||
|
type:_config[item].type, |
||||
|
auth:props.apiName+':'+item, |
||||
|
hide:(row,scope) => {return row[props.apiRightHideConfig[item].prop] == props.apiRightHideConfig[item].ruleValue} |
||||
|
}) |
||||
|
}); |
||||
|
} |
||||
|
// 如果有自定义按钮,合并默认api按钮 |
||||
|
if(typeof props.rightOperation == 'object'){ |
||||
|
_btns = [..._btns,...props.rightOperation] |
||||
|
} |
||||
|
return _btns |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// 右侧操作列操作 |
||||
|
const apiEditPopRef = ref() |
||||
|
function rightOperationHadel(btn,scope) { |
||||
|
// 通用编辑 |
||||
|
if(btn.name == 'apiUpdate'){ |
||||
|
let _tableColums = props.tableColumns || apiTableColumns[props.apiName] |
||||
|
let _list = _tableColums.filter(item => !item.noEdit) |
||||
|
apiEditPopRef.value.open(_list,scope.row) |
||||
|
} |
||||
|
// 通用删除 |
||||
|
if(btn.name == 'apiDelete'){ |
||||
|
ElMessageBox.confirm(`是否确定删除?`, '提示', { |
||||
|
confirmButtonText: '确定', |
||||
|
cancelButtonText: '取消', |
||||
|
type: 'warning' |
||||
|
}).then(() => { |
||||
|
state.loading = true |
||||
|
deleteCommonApi(props.apiName,scope.row.uId) |
||||
|
.then(res=>{ |
||||
|
ElMessage.success('操作成功!') |
||||
|
getTableData(1); |
||||
|
}) |
||||
|
.catch(err=>{ElMessage.error('操作失败!')}) |
||||
|
.finally(()=>{state.loading = false}) |
||||
|
}) |
||||
|
} |
||||
|
emits('rightOperationHadel',btn,scope) |
||||
|
} |
||||
|
|
||||
|
// 编辑表单提交 |
||||
|
const submitEditForm = async (type,formData,formConfig) => { |
||||
|
apiEditPopRef.value.validate((valid) => { |
||||
|
if(valid){ |
||||
|
// 新增 |
||||
|
if(type == 'create'){ |
||||
|
if(formData.hasOwnProperty('createUser')){formData.createUser = userInfo.realName} |
||||
|
if(formData.hasOwnProperty('createByUser')){formData.createByUser = userInfo.realName} |
||||
|
if(formData.hasOwnProperty('createTime')){formData.createTime = formatDate(new Date(), "YYYY-mm-dd HH:MM:SS")} |
||||
|
apiEditPopRef.value.changeLoading(true) |
||||
|
postCommonCreate(props.apiName,formData) |
||||
|
.then(res=>{ |
||||
|
apiEditPopRef.value.close() |
||||
|
ElMessage.success('操作成功!') |
||||
|
getTableData(1); |
||||
|
}) |
||||
|
.catch(err=>{ElMessage.error('操作失败!')}) |
||||
|
.finally(()=>{apiEditPopRef.value.changeLoading(false)}) |
||||
|
}else{ |
||||
|
// 修改人信息处理 |
||||
|
if( |
||||
|
(formData.hasOwnProperty('updateByUser') && formData.hasOwnProperty('updateTime')) |
||||
|
|| (formData.hasOwnProperty('updateUser') && formData.hasOwnProperty('updateTime')) |
||||
|
){ |
||||
|
if(formData.hasOwnProperty('updateByUser')){formData.updateByUser = userInfo.realName} |
||||
|
if(formData.hasOwnProperty('updateUser')){formData.updateUser = userInfo.realName} |
||||
|
if(formData.hasOwnProperty('updateTime')){formData.updateTime = formatDate(new Date(), "YYYY-mm-dd HH:MM:SS")} |
||||
|
}else{ |
||||
|
// 特殊不处理页面 |
||||
|
let _notChange=['taskconifgure'] |
||||
|
if(_notChange.indexOf(props.apiName) < 0){ |
||||
|
formData.remark= `修改信息:${userInfo.realName} ${formatDate(new Date(), "YYYY-mm-dd HH:MM:SS")}` |
||||
|
} |
||||
|
} |
||||
|
apiEditPopRef.value.changeLoading(true) |
||||
|
putCommonUpdate(props.apiName,formData) |
||||
|
.then(res=>{ |
||||
|
apiEditPopRef.value.close() |
||||
|
ElMessage.success('操作成功!') |
||||
|
getTableData(1); |
||||
|
}) |
||||
|
.catch(err=>{ElMessage.error('操作失败!')}) |
||||
|
.finally(()=>{apiEditPopRef.value.changeLoading(false)}) |
||||
|
} |
||||
|
} |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
// 格式化页面传参 |
||||
|
function getPageParams(pageSize){ |
||||
|
let _filters = [] |
||||
|
if(props.hideSearch){ |
||||
|
_filters = props.searchFilter |
||||
|
}else{ |
||||
|
for(let i in props.searchFilter){ |
||||
|
let _item = props.searchOptions.filter(item=>item.prop == i) |
||||
|
let _type = (_item && _item.length > 0) ? _item[0].type : null |
||||
|
if((props.searchFilter[i] || props.searchFilter[i] == 0) && props.searchFilter[i] != ""){ |
||||
|
// 时间区域格式 |
||||
|
if(_type == 'datetimerange'){ |
||||
|
_filters.push( |
||||
|
{ |
||||
|
logic: "And", |
||||
|
column: i, |
||||
|
action: '>=', |
||||
|
value: props.searchFilter[i][0] |
||||
|
} |
||||
|
) |
||||
|
_filters.push( |
||||
|
{ |
||||
|
logic: "And", |
||||
|
column: i, |
||||
|
action: '<=', |
||||
|
value: props.searchFilter[i][1] |
||||
|
} |
||||
|
) |
||||
|
}else{ |
||||
|
let _action = 'like' |
||||
|
let _EqualTypes = ['tagFilter','filter','number','select']//等于情况的类型 |
||||
|
if(_EqualTypes.indexOf(_type) >= 0){ |
||||
|
_action = '==' |
||||
|
} |
||||
|
_filters.push( |
||||
|
{ |
||||
|
logic: "And", |
||||
|
column: i, |
||||
|
action: _action, |
||||
|
value: props.searchFilter[i] |
||||
|
} |
||||
|
) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
let _pageParams = getPageParamsForFilter({ |
||||
|
pageNumber:state.pager.page, |
||||
|
pageSize:pageSize || state.pager.pageSize, |
||||
|
sortBy:state.sortFilter.sortBy, |
||||
|
isAscending:state.sortFilter.isAscending, |
||||
|
condition:{ |
||||
|
filters:_filters |
||||
|
} |
||||
|
}) |
||||
|
return _pageParams |
||||
|
} |
||||
|
|
||||
|
// 获取页面数据 |
||||
|
function getTableData(page,callback) { |
||||
|
state.stage_indexs = [] |
||||
|
state.currentDetailId = null |
||||
|
state.headerInfoData = [] |
||||
|
state.tableSelectList = [] |
||||
|
if(props.apiType == 'detailApi'){ |
||||
|
state.loading = true |
||||
|
if(!page)page = state.pager.page |
||||
|
if(page)state.pager.page = page |
||||
|
getCommonDeatailPaged(props.apiName,getPageParams()) |
||||
|
.then((resp) => { |
||||
|
state.headerInfoData = [] |
||||
|
state.tableData = resp.data.data |
||||
|
state.stage_tableData = JSON.parse(JSON.stringify(resp.data.data)) |
||||
|
state.pager.total = resp.data.totalCount |
||||
|
if(callback)callback(resp) |
||||
|
}) |
||||
|
.catch(err=>{ElMessage.error('数据获取失败!')}) |
||||
|
.finally(() => (state.loading = false)) |
||||
|
}else{ |
||||
|
state.loading = true |
||||
|
if(!page)page = state.pager.page |
||||
|
if(page)state.pager.page = page |
||||
|
getCommonPaged(props.apiName,getPageParams()) |
||||
|
.then((resp) => { |
||||
|
state.headerInfoData = [] |
||||
|
state.tableData = resp.data.data |
||||
|
state.stage_tableData = JSON.parse(JSON.stringify(resp.data.data)) |
||||
|
state.pager.total = resp.data.totalCount |
||||
|
if(callback)callback(resp) |
||||
|
}) |
||||
|
.catch(err=>{ElMessage.error('数据获取失败!')}) |
||||
|
.finally(() => (state.loading = false)) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
// 导出 |
||||
|
function exportHandle(isAll){ |
||||
|
state.loading = true |
||||
|
//同步数据查询 |
||||
|
getTableData(1,(res=>{ |
||||
|
let _params = getPageParams() |
||||
|
if(isAll){_params = getPageParams(res.data.totalCount)} |
||||
|
postCommonExport(props.apiName,_params) |
||||
|
.then((res) => { |
||||
|
let _str = isAll ? '全部' : '当页' |
||||
|
downloadByData(res.data,route.meta.title+`.xlsx`) |
||||
|
}) |
||||
|
.catch(err=>{ElMessage.error('操作失败!')}) |
||||
|
.finally(() => (state.loading = false)) |
||||
|
})) |
||||
|
|
||||
|
} |
||||
|
|
||||
|
const importPopRef = ref() |
||||
|
// 头部查询按钮功能 |
||||
|
function searchBtnHandle(btn){ |
||||
|
// 查询 |
||||
|
if(btn == 'search'){ |
||||
|
beforClearEdit().then(() => { |
||||
|
getTableData() |
||||
|
}) |
||||
|
} |
||||
|
// 新增 |
||||
|
else if (btn == 'create'){ |
||||
|
beforClearEdit().then(() => { |
||||
|
let _tableColums = props.tableColumns || apiTableColumns[props.apiName] |
||||
|
let _list = _tableColums.filter(item => !item.noEdit) |
||||
|
apiEditPopRef.value.open(_list) |
||||
|
}) |
||||
|
} |
||||
|
// 导入 |
||||
|
else if (btn == 'import'){ |
||||
|
beforClearEdit().then(() => { |
||||
|
importPopRef.value.open() |
||||
|
}) |
||||
|
} |
||||
|
// 导出(按条件导出当前页) |
||||
|
else if (btn == 'export'){ |
||||
|
exportHandle() |
||||
|
} |
||||
|
// 手动开关 |
||||
|
else if (btn == 'custominvoke'){ |
||||
|
beforClearEdit().then(() => { |
||||
|
state.loading = true |
||||
|
let _data = { |
||||
|
taskName:apiServeNames[props.apiName].taskName, |
||||
|
client:'Chery' |
||||
|
} |
||||
|
getCommonCustominvoke(_data) |
||||
|
.then((res) => { |
||||
|
ElMessage.success('操作成功!') |
||||
|
getTableData(1)//同步数据查询 |
||||
|
}) |
||||
|
.finally(() => (state.loading = false)) |
||||
|
}) |
||||
|
} |
||||
|
// 手动传出(多选) |
||||
|
else if (btn == 'outputMany'){ |
||||
|
let _idEditData = checkPageEditList() |
||||
|
if(_idEditData && _idEditData.length > 0){ |
||||
|
return ElMessage.warning('当前有未保存修改项,请先保存页面') |
||||
|
} |
||||
|
if(!state.tableSelectList || state.tableSelectList.length <= 0 ){ |
||||
|
return ElMessage.warning('未选中任何数据') |
||||
|
} |
||||
|
ElMessageBox.confirm('是否确定手动传出?', '提示', { |
||||
|
confirmButtonText: '确定', |
||||
|
cancelButtonText: '取消', |
||||
|
type: 'warning' |
||||
|
}).then(() => { |
||||
|
state.loading = true |
||||
|
postCommonConfirmMany(props.apiName,state.tableSelectList) |
||||
|
.then(res=>{ |
||||
|
ElMessage.success('操作成功!') |
||||
|
getTableData(1) |
||||
|
}) |
||||
|
.finally(()=>{state.loading = false}) |
||||
|
}) |
||||
|
} |
||||
|
} |
||||
|
const table_Ref = ref(null) |
||||
|
// 头部右侧按钮功能 |
||||
|
function searchRightBtnHandle(btn){ |
||||
|
// 保存页面 |
||||
|
if(btn.name == 'pageSave'){ |
||||
|
// table_Ref.value.tableForm_Ref.validate((valid)=>{ |
||||
|
// if(valid){ |
||||
|
let _idEditData = checkPageEditList() |
||||
|
if(!_idEditData || _idEditData.length <= 0)return ElMessage.warning('暂无数据修改') |
||||
|
// 判断规则 目前风险页面通用,暂时写在通用方式中,如果后期有区别,可拿到页面外处理 |
||||
|
// 规则:反馈结果[feedbackResults]=1时,风险类型[ventureType],具体风险[ventureSpecific],应对措施[measures]必填 |
||||
|
let _indexs = [] |
||||
|
_idEditData.forEach(item=>{ |
||||
|
if(item.feedbackResults == '1' && ( |
||||
|
!item.ventureType || item.ventureType == '' || |
||||
|
!item.ventureSpecific || item.ventureSpecific == '' || |
||||
|
!item.measures || item.measures == '' |
||||
|
)){ |
||||
|
_indexs.push(getIndexById(item.id)) |
||||
|
} |
||||
|
}) |
||||
|
if(_indexs && _indexs.length > 0){ |
||||
|
return ElMessage.error(`修改数据中【第${_indexs}行】数据中,【反馈结果】为异常,但【风险类型】或【具体风险】或【应对措施】为空,请修改后重新提交!`) |
||||
|
} |
||||
|
ElMessageBox.confirm('是否确定提交更改?', '提示', { |
||||
|
confirmButtonText: '确定', |
||||
|
cancelButtonText: '取消', |
||||
|
type: 'warning' |
||||
|
}).then(() => { |
||||
|
state.loading = true |
||||
|
postCommonUpdateMany(props.apiName,_idEditData) |
||||
|
.then(res=>{ |
||||
|
ElMessage.success('操作成功!') |
||||
|
getTableData(1) |
||||
|
}) |
||||
|
.finally(()=>{state.loading = false}) |
||||
|
}) |
||||
|
// } |
||||
|
// }) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// 排序 |
||||
|
function sortChange(data) { |
||||
|
beforClearEdit().then(() => { |
||||
|
const { prop, order } = data; |
||||
|
if (!prop || !order) { |
||||
|
state.sortFilter.sortBy = undefined; |
||||
|
state.sortFilter.isAscending = undefined; |
||||
|
getTableData(1); |
||||
|
return; |
||||
|
} |
||||
|
state.sortFilter.sortBy = prop; |
||||
|
state.sortFilter.isAscending = (order == "ascending"); |
||||
|
getTableData(1); |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
// 导入成功之后 |
||||
|
function importSuccess(response,importDate){ |
||||
|
getTableData() |
||||
|
} |
||||
|
|
||||
|
// size-change |
||||
|
function pageSizeChange(pageSize,returnSize){ |
||||
|
state.pageLoading=true |
||||
|
let _oldSize = state.pager.pageSize |
||||
|
state.pager.pageSize = pageSize |
||||
|
beforClearEdit() |
||||
|
.then(res => { |
||||
|
getTableData(1) |
||||
|
state.pageLoading=false |
||||
|
}) |
||||
|
.catch(res=>{ |
||||
|
state.pager.pageSize = _oldSize |
||||
|
state.pageLoading=false |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
// current-change |
||||
|
function pageCurrentChange(page){ |
||||
|
beforClearEdit().then(res => { |
||||
|
getTableData(page) |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
// 获取当前第几行数据的明细 |
||||
|
function getIndexById(id){ |
||||
|
let _id = id || state.currentDetailId |
||||
|
for(let i=0;i<state.stage_tableData.length;i++){ |
||||
|
if(state.stage_tableData[i].id == _id){ |
||||
|
return i + 1 |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// 检查行数据是否符合禁用规则 |
||||
|
function checkDisableByRowRule(row,item){ |
||||
|
let hasDisable = false |
||||
|
// 根据editDisabledConfig规则处理禁用 |
||||
|
for(let i = 0;i<props.editDisabledConfig.length;i++){ |
||||
|
if(row[props.editDisabledConfig[i].prop] == props.editDisabledConfig[i].ruleValue){ |
||||
|
hasDisable = true |
||||
|
break |
||||
|
} |
||||
|
} |
||||
|
// 根据反馈结果特殊处理,如果为无异常,其他不可编辑 |
||||
|
// (现所有风险页面,规则相同,所以统一再此处理,如果有更改需要重新做封装处理) |
||||
|
// 如果上方规则为可编辑则再进行此判断 |
||||
|
if(!hasDisable && row.feedbackResults == '0' && item.prop != 'feedbackResults'){ |
||||
|
hasDisable = true |
||||
|
} |
||||
|
return hasDisable |
||||
|
} |
||||
|
|
||||
|
// 检查行的勾选框是否符合禁用规则 |
||||
|
function checkDisableCheckByRowRule(row){ |
||||
|
// 暂时与编辑页面用一个条件【editDisabledConfig】,如有区别再进行封装 |
||||
|
let hasDisable = false |
||||
|
// 根据editDisabledConfig规则处理禁用 |
||||
|
for(let i = 0;i<props.editDisabledConfig.length;i++){ |
||||
|
if(row[props.editDisabledConfig[i].prop] == props.editDisabledConfig[i].ruleValue){ |
||||
|
hasDisable = true |
||||
|
break |
||||
|
} |
||||
|
} |
||||
|
return hasDisable |
||||
|
} |
||||
|
|
||||
|
// 判断可编辑元素是否禁用 |
||||
|
function getEditItemDisabled(item,row,index){ |
||||
|
// 无权限禁用 |
||||
|
let _auth = auths.hasPermission(props.apiName+':pageSave') |
||||
|
if(item.disabled || !_auth){ |
||||
|
return true |
||||
|
} |
||||
|
// 已勾选禁用 |
||||
|
if(state.tableSelectList && state.tableSelectList.length > 0){ |
||||
|
return true |
||||
|
} |
||||
|
// 行条件禁用 |
||||
|
return checkDisableByRowRule(row,item) |
||||
|
} |
||||
|
|
||||
|
// table的复选框是否禁用判断 |
||||
|
function selectableDisabled(row,index){ |
||||
|
// 无权限禁用 |
||||
|
let _auth = auths.hasPermission(props.apiName+':outputMany') |
||||
|
// 已修改禁用 |
||||
|
let _idEditData = checkPageEditList() |
||||
|
// 行条件禁用 |
||||
|
let checkRow = checkDisableCheckByRowRule(row) |
||||
|
return _auth && (!_idEditData || _idEditData.length <= 0) && !checkRow |
||||
|
} |
||||
|
|
||||
|
// 可编辑元素Focus事件 todo:如果加上表单验证后,需要处理表单点击 |
||||
|
function getItemDetail(type,row,eventType) { |
||||
|
if(!row.id){return ElMessage.error('该数据无id')} |
||||
|
// 如果是相同id,避免重复:阻止接口 |
||||
|
if(row.id == state.currentDetailId){return} |
||||
|
let _focuseExt = ['input','numberInput'] |
||||
|
// 如果是focus事件,避免重复:阻止_focuseExt以内的触发事件,走cell事件 |
||||
|
if(eventType == 'focus' && _focuseExt.indexOf(type) >= 0){return} |
||||
|
console.log(type,row,eventType) |
||||
|
console.log('------------') |
||||
|
state.currentDetailId = row.id |
||||
|
state.detailLoading = true |
||||
|
getCommonDetailById(props.apiName,row.id) |
||||
|
.then((res) => { |
||||
|
state.headerInfoData = [] |
||||
|
let _colums = apiTableColumns[props.detailColumName] |
||||
|
_colums.forEach(item=>{ |
||||
|
state.headerInfoData.push({ |
||||
|
label:item.title, |
||||
|
value:res.data[item.prop], |
||||
|
prop:item.prop |
||||
|
}) |
||||
|
}) |
||||
|
}) |
||||
|
.finally(() => (state.detailLoading = false)) |
||||
|
|
||||
|
} |
||||
|
|
||||
|
// 可编辑元素change事件 |
||||
|
function editItemChangeHandle(item,scope,data) { |
||||
|
if(state.stage_indexs.indexOf(scope.$index) < 0){ |
||||
|
state.stage_indexs.push(scope.$index) |
||||
|
} |
||||
|
// 更改反馈结果 |
||||
|
// 现所有风险页面,规则相同,所以统一再此处理,如果有更改需要重新做封装处理 |
||||
|
if(item.prop == "feedbackResults"){ |
||||
|
// 如果反馈结果更改为无异常 |
||||
|
if(scope.row.feedbackResults == '0'){ |
||||
|
// 清空类型,风险,措施 |
||||
|
scope.row.ventureType = "" |
||||
|
scope.row.ventureSpecific = "" |
||||
|
scope.row.measures = "" |
||||
|
// 其他数值恢复为原数据(明细中的值) |
||||
|
// 风险页面与明细对应数量匹配prop |
||||
|
let _tableColums = props.tableColumns || apiTableColumns[props.apiName] |
||||
|
for(let prop in scope.row){ |
||||
|
let _item = _tableColums.filter(item=>item.prop == prop) |
||||
|
if(_item && _item.length > 0 && _item[0].relevProp){ |
||||
|
let _relevProp = _item[0].relevProp |
||||
|
let _list = state.headerInfoData.filter(item=>item.prop == _relevProp) |
||||
|
if(_list && _list.length>0){ |
||||
|
scope.row[prop] = _list[0].value |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// 其他操作清空保存前提示 |
||||
|
function beforClearEdit(){ |
||||
|
return new Promise((resolve, reject) => { |
||||
|
let _idEditData = checkPageEditList() |
||||
|
if(!_idEditData || _idEditData.length <= 0){ |
||||
|
resolve() |
||||
|
}else{ |
||||
|
ElMessageBox.confirm(state.leaveSaveTip, '提示', { |
||||
|
confirmButtonText: '确定', |
||||
|
cancelButtonText: '取消', |
||||
|
type: 'warning' |
||||
|
}).then(() => { |
||||
|
resolve() |
||||
|
}).catch(()=>{ |
||||
|
reject() |
||||
|
}) |
||||
|
} |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
// 处理页面更改数据 |
||||
|
function checkPageEditList(){ |
||||
|
if(!state.stage_indexs || state.stage_indexs.length<=0){ |
||||
|
return false |
||||
|
} |
||||
|
else{ |
||||
|
let _changeArr = [] |
||||
|
state.stage_indexs.forEach(item=>{ |
||||
|
if(JSON.stringify(state.stage_tableData[item]) != JSON.stringify(state.tableData[item])){ |
||||
|
_changeArr.push(state.tableData[item]) |
||||
|
} |
||||
|
}) |
||||
|
return _changeArr |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// 行变色 |
||||
|
function tableRowClassName(data){ |
||||
|
if(data.row.id && (data.row.id == state.currentDetailId)){return 'current-select-tableRow'} |
||||
|
else{return 'normal-tableRow'} |
||||
|
} |
||||
|
|
||||
|
// 根据apiTableColumns转义table内表单默认规则 |
||||
|
function getTableFormRules(){ |
||||
|
if(props.tableFormRules) { |
||||
|
state.tableFormRulesData = props.tableFormRules |
||||
|
}else{ |
||||
|
state.tableFormRulesData = {} |
||||
|
apiTableColumns[props.apiName].forEach(item=>{ |
||||
|
if(item.required){ |
||||
|
state.tableFormRulesData[item.prop] = [{ required: true, message: '必填项', trigger: 'change' }] |
||||
|
} |
||||
|
}) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
onMounted(() => { |
||||
|
// getTableFormRules() |
||||
|
getTableData() |
||||
|
}) |
||||
|
|
||||
|
</script> |
||||
|
<style scoped lang="scss"> |
||||
|
::v-deep .search-container{ |
||||
|
.el-card__body{ |
||||
|
width: 100%; |
||||
|
display: flex; |
||||
|
justify-content: space-between; |
||||
|
} |
||||
|
} |
||||
|
::v-deep .headerInfo-container{ |
||||
|
margin-top:10px; |
||||
|
.el-card__body{ |
||||
|
padding-bottom: 10px !important; |
||||
|
min-height:66px |
||||
|
} |
||||
|
} |
||||
|
::v-deep .headerInfoEmpty{ |
||||
|
height:195px; |
||||
|
.el-empty__image{ |
||||
|
width:90px !important |
||||
|
} |
||||
|
} |
||||
|
::v-deep .el-descriptions__body{ |
||||
|
max-height: 165px; |
||||
|
overflow: auto; |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,689 @@ |
|||||
|
<template> |
||||
|
<div class="app-container" v-loading="state.loading"> |
||||
|
<el-card class="search-container" v-if="!(props.hideSearch && props.hideSetColums)"> |
||||
|
<el-form :inline="true" v-if="!props.hideSearch"> |
||||
|
<el-form-item |
||||
|
v-auth="(props.authName || props.apiName) + state.searchBtnOptions['search'].auth" |
||||
|
v-for="(item,index) in props.searchOptions" |
||||
|
:key="index" |
||||
|
:label="item.label"> |
||||
|
<!-- 文本 --> |
||||
|
<el-input |
||||
|
v-if="item.type == 'input' && !item.hide" |
||||
|
v-model="props.searchFilter[item.prop]" |
||||
|
:placeholder="item.label" |
||||
|
:clearable="!item.noClear" |
||||
|
/> |
||||
|
<!-- 数字 --> |
||||
|
<el-input-number |
||||
|
v-if="item.type == 'number' && !item.hide" |
||||
|
v-model="props.searchFilter[item.prop]" |
||||
|
:min="item.min" |
||||
|
:max="item.max" |
||||
|
/> |
||||
|
<!-- 时间区域 --> |
||||
|
<el-date-picker |
||||
|
v-if="item.type == 'datetimerange' && !item.hide" |
||||
|
v-model="props.searchFilter[item.prop]" |
||||
|
type="datetimerange" |
||||
|
start-placeholder="起始时间" |
||||
|
end-placeholder="结束时间" |
||||
|
format="YYYY-MM-DD HH:mm:ss" |
||||
|
value-format="YYYY-MM-DD HH:mm:ss" |
||||
|
style="width:370px" |
||||
|
/> |
||||
|
<!-- 选择框 --> |
||||
|
<el-select |
||||
|
v-if="item.type == 'select' && !item.hide" |
||||
|
v-model="props.searchFilter[item.prop]" |
||||
|
:filterable="!item.noSearch" |
||||
|
placeholder="请选择" |
||||
|
style="width: 240px" |
||||
|
:clearable="!item.noClear" |
||||
|
> |
||||
|
<el-option |
||||
|
v-for="(op,op_index) in item.options" |
||||
|
:key="op_index" |
||||
|
:label="op.label" |
||||
|
:value="op.value" |
||||
|
/> |
||||
|
</el-select> |
||||
|
</el-form-item> |
||||
|
<el-form-item> |
||||
|
<div style="margin-right:10px" v-for="(btn,btn_key) in props.searchButtons" :key="btn_key"> |
||||
|
<!-- 导出 --> |
||||
|
<!-- <el-dropdown |
||||
|
v-auth="(props.authName || props.apiName) + state.searchBtnOptions[btn].auth" |
||||
|
:hide-on-click="false" |
||||
|
v-if="state.searchBtnOptions[btn].auth == ':export'" |
||||
|
> |
||||
|
<el-button |
||||
|
:icon="state.searchBtnOptions[btn].icon" |
||||
|
:type="state.searchBtnOptions[btn].type"> |
||||
|
{{state.searchBtnOptions[btn].label}} |
||||
|
<el-icon class="el-icon--right"><arrow-down /></el-icon> |
||||
|
</el-button> |
||||
|
<template #dropdown> |
||||
|
<el-dropdown-menu> |
||||
|
<el-dropdown-item @click="exportHandle()">按条件导出【当前页】</el-dropdown-item> |
||||
|
<el-dropdown-item divided @click="exportHandle(true)">按条件导出【全部】</el-dropdown-item> |
||||
|
</el-dropdown-menu> |
||||
|
</template> |
||||
|
</el-dropdown> --> |
||||
|
<!-- 其他按钮 --> |
||||
|
<el-button |
||||
|
:icon="state.searchBtnOptions[btn].icon" |
||||
|
v-auth="(props.authName || props.apiName) + state.searchBtnOptions[btn].auth" |
||||
|
:type="state.searchBtnOptions[btn].type" |
||||
|
@click="searchBtnHandle(btn)" |
||||
|
>{{state.searchBtnOptions[btn].label}}</el-button> |
||||
|
</div> |
||||
|
</el-form-item> |
||||
|
</el-form> |
||||
|
<!-- 字段设置 --> |
||||
|
<setColumsPop |
||||
|
style="margin-left: auto;" |
||||
|
v-if="!props.hideSetColums && state.innerTableColumns" |
||||
|
:localTableColumnsName="state.localTableColumnsName" |
||||
|
:initTableColums="state.initTableColums" |
||||
|
:tableColumns="state.innerTableColumns" |
||||
|
></setColumsPop> |
||||
|
</el-card> |
||||
|
|
||||
|
<el-card class="paged-table-container"> |
||||
|
<elTable |
||||
|
v-if="state.innerTableColumns" |
||||
|
:specialLocalColumnName="props.specialLocalColumnName" |
||||
|
:columnWidth="props.columnWidth" |
||||
|
:columnHeaderAlign="props.columnHeaderAlign" |
||||
|
:columnAlign="props.columnAlign" |
||||
|
:tableData="state.tableData" |
||||
|
:tableColumns="state.innerTableColumns" |
||||
|
@sortChange="sortChange" |
||||
|
:leftOperation="props.leftOperation" |
||||
|
@leftOperationHadel="leftOperationHadel" |
||||
|
:leftOperationColumnWidth="props.leftOperationColumnWidth" |
||||
|
:rightOperation="getRightOperation()" |
||||
|
@rightOperationHadel="rightOperationHadel" |
||||
|
:multipleTable="props.multipleTable" |
||||
|
@tableSelectionHandle="tableSelectionHandle" |
||||
|
:tableRowClassName="props.tableRowClassName" |
||||
|
:tableCellClassName="props.tableCellClassName" |
||||
|
></elTable> |
||||
|
|
||||
|
<elPager |
||||
|
style="margin-top: 15px;float:right" |
||||
|
:pager="state.pager" |
||||
|
@pageSizeChange="pageSizeChange" |
||||
|
@pageCurrentChange="pageCurrentChange" |
||||
|
></elPager> |
||||
|
</el-card> |
||||
|
|
||||
|
<!-- 导入弹窗 --> |
||||
|
<importPop |
||||
|
ref="importPopRef" |
||||
|
:apiName="props.apiName" |
||||
|
@success="importSuccess" |
||||
|
/> |
||||
|
|
||||
|
<!-- 编辑弹窗 --> |
||||
|
<apiEditPop |
||||
|
ref="apiEditPopRef" |
||||
|
:apiName="props.apiName" |
||||
|
@submitEditForm="submitEditForm" |
||||
|
:formRules="props.apiEditFormRules" |
||||
|
/> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script setup> |
||||
|
defineOptions({ name: 'tablePage' }) |
||||
|
import store from '@/stores' |
||||
|
import apiTableColumns from '@/utils/common/apiTableColumns' |
||||
|
import { reactive, ref, onMounted,computed,defineExpose } from 'vue' |
||||
|
import { |
||||
|
getCommonPost, |
||||
|
getCommonPaged, |
||||
|
getCommonDeatailPaged, |
||||
|
postCommonExport, |
||||
|
postCommonCreate, |
||||
|
putCommonUpdate, |
||||
|
deleteCommonApi, |
||||
|
getCommonCustominvoke |
||||
|
} from '@/api/common/index' |
||||
|
import { ElMessageBox, ElMessage,ElTable, ElTableColumn } from 'element-plus' |
||||
|
import elTable from '@/components/elTable/index.vue' |
||||
|
import elPager from '@/components/elPager/index.vue' |
||||
|
import setColumsPop from '@/components/setColumsPop/index.vue' |
||||
|
import { getPageParamsForFilter,getLocalTableColumnsName } from '@/utils/common/index' |
||||
|
import { downloadByData } from '@/utils/download' |
||||
|
import importPop from '@/components/importPop/index.vue' |
||||
|
import apiEditPop from '@/components/apiEditPop/index.vue' |
||||
|
import { formatDate } from '@/utils/formatTime' |
||||
|
import apiServeNames from '@/utils/common/apiServeNames' |
||||
|
|
||||
|
import { useRoute } from 'vue-router' |
||||
|
const route = useRoute() |
||||
|
const userStore = store.userStore() |
||||
|
const userInfo = userStore.state |
||||
|
|
||||
|
const state = reactive({ |
||||
|
loading:false, |
||||
|
searchBtnOptions:{ |
||||
|
search:{icon:'Search',auth:':page',label:'查询',type:null}, |
||||
|
create:{icon:'Plus',auth:':create',label:'新增',type:'primary'}, |
||||
|
import:{icon:'BottomRight',auth:':import',label:'导入',type:'warning'}, |
||||
|
export:{icon:'TopRight',auth:':export',label:'导出',type:'success'}, |
||||
|
custominvoke:{icon:'Position',auth:':custominvoke',label:'手动开关',type:'primary'}, |
||||
|
}, |
||||
|
innerTableColumns:null, |
||||
|
tableData:[], |
||||
|
// table排序处理 |
||||
|
sortFilter:{ |
||||
|
sortBy:undefined, |
||||
|
isAscending:undefined |
||||
|
}, |
||||
|
pager:{ |
||||
|
page: 1, |
||||
|
pageSize: 10, |
||||
|
total: 1, |
||||
|
}, |
||||
|
tableSelectList:[], |
||||
|
initTableColums:[],//初始化表头,未从缓存获取之前 |
||||
|
localTableColumnsName:null |
||||
|
}) |
||||
|
|
||||
|
const props = defineProps({ |
||||
|
// api名称 |
||||
|
apiName: { |
||||
|
type: String, |
||||
|
default: null |
||||
|
}, |
||||
|
// 特殊的分页api |
||||
|
specialPageApi:{ |
||||
|
type: String, |
||||
|
default: null |
||||
|
}, |
||||
|
// 特殊的column名称(没有默认apiName) |
||||
|
specialColumnName:{ |
||||
|
type: String, |
||||
|
default: null |
||||
|
}, |
||||
|
// 特殊的存储column名称(没有默认apiName) |
||||
|
specialLocalColumnName:{ |
||||
|
type: String, |
||||
|
default: null |
||||
|
}, |
||||
|
// 特殊权限前缀(如果没有默认使用apiName) |
||||
|
authName:{ |
||||
|
type: String, |
||||
|
default: null |
||||
|
}, |
||||
|
// api类型 detailApi:走getdetail接口,不传或者pageApi:走getdatapaged接口 |
||||
|
apiType: { |
||||
|
type: String, |
||||
|
default: null |
||||
|
}, |
||||
|
// 隐藏表头搜索 |
||||
|
hideSearch:{ |
||||
|
type: Boolean, |
||||
|
default: false |
||||
|
}, |
||||
|
// 行class |
||||
|
tableRowClassName:{ |
||||
|
type: Function, |
||||
|
default: null |
||||
|
}, |
||||
|
// 单元格class |
||||
|
tableCellClassName:{ |
||||
|
type: Function, |
||||
|
default: null |
||||
|
}, |
||||
|
// 多选 |
||||
|
multipleTable:{ |
||||
|
type: Boolean, |
||||
|
default: false |
||||
|
}, |
||||
|
// 左侧操作列 |
||||
|
leftOperation:{ |
||||
|
type: Object, |
||||
|
default: null |
||||
|
}, |
||||
|
// 左侧操作列宽度 |
||||
|
leftOperationColumnWidth:{ |
||||
|
type: Number, |
||||
|
default: 120 |
||||
|
}, |
||||
|
// 右侧操作列 |
||||
|
rightOperation:{ |
||||
|
type: [Object,String], |
||||
|
default: null |
||||
|
}, |
||||
|
// 右侧操作列,特殊自定义格式下,包含api操作 |
||||
|
showApiRightOperation:{ |
||||
|
type: Object, |
||||
|
default: null |
||||
|
}, |
||||
|
// 右侧通用按钮特殊字段判断隐藏规则,默认为编辑删除,writeState=true不可操作, |
||||
|
// 如有特殊规则,则使用该方法特殊处理,当前判断方式为“=”,如后期有其他需求再进行封装 |
||||
|
apiRightHideConfig:{ |
||||
|
type: Object, |
||||
|
default: { |
||||
|
apiUpdate:{prop:'writeState',ruleValue:true}, |
||||
|
apiDelete:{prop:'writeState',ruleValue:true}, |
||||
|
} |
||||
|
}, |
||||
|
// table表头 |
||||
|
tableColumns: { |
||||
|
type: Object, |
||||
|
default: null |
||||
|
}, |
||||
|
// 查询配置 |
||||
|
searchOptions: { |
||||
|
type: Object, |
||||
|
default: [] |
||||
|
}, |
||||
|
// 查询按钮 |
||||
|
searchButtons: { |
||||
|
type: Object, |
||||
|
default: ['search','export'] |
||||
|
}, |
||||
|
// table查询数据filter |
||||
|
searchFilter: { |
||||
|
type: Object, |
||||
|
default: {} |
||||
|
}, |
||||
|
// table查询数据filter的特殊条件,如果没有则走colum中的配置 |
||||
|
// 示例:infoSearchFilterOptions:{ TableName:{action:'=='}}, |
||||
|
searchFilterOptions: { |
||||
|
type: Object, |
||||
|
default: {} |
||||
|
}, |
||||
|
// 表头宽度 |
||||
|
columnWidth:{ |
||||
|
type: Number, |
||||
|
default: 120 |
||||
|
}, |
||||
|
// 表头对齐 |
||||
|
columnHeaderAlign:{ |
||||
|
type: String, |
||||
|
default: 'center' |
||||
|
}, |
||||
|
// 表内容对齐 |
||||
|
columnAlign:{ |
||||
|
type: String, |
||||
|
default: 'center' |
||||
|
}, |
||||
|
// 表单规则 |
||||
|
apiEditFormRules:{ |
||||
|
type: Object, |
||||
|
default: null |
||||
|
}, |
||||
|
// 隐藏字段设置 |
||||
|
hideSetColums:{ |
||||
|
type: Boolean, |
||||
|
default: false |
||||
|
} |
||||
|
}) |
||||
|
|
||||
|
|
||||
|
// 获取表头 noFilter 不需要处理字段设置(用于编辑和新增) |
||||
|
function getTableColumns(noFilter){ |
||||
|
if(noFilter){ |
||||
|
return props.tableColumns || apiTableColumns[props.apiName] |
||||
|
}else{ |
||||
|
// 字段设置中,存入location的名字 |
||||
|
let _localColumName = props.specialLocalColumnName || useRoute().name |
||||
|
state.localTableColumnsName = getLocalTableColumnsName(_localColumName) |
||||
|
let _local = JSON.parse(localStorage.getItem(state.localTableColumnsName)) |
||||
|
// 获取列表配置 |
||||
|
let _apiColums = props.specialColumnName || props.apiName |
||||
|
state.initTableColums = props.tableColumns || apiTableColumns[_apiColums] |
||||
|
let _list = (_local && _local != null && _local != undefined) ? _local : JSON.parse(JSON.stringify(state.initTableColums)) |
||||
|
state.innerTableColumns = _list |
||||
|
return _list |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
const emits = defineEmits([ |
||||
|
'leftOperationHadel', |
||||
|
'rightOperationHadel', |
||||
|
'tableSelectionHandle' |
||||
|
]) |
||||
|
|
||||
|
// table多选 |
||||
|
function tableSelectionHandle (val){ |
||||
|
state.tableSelectList = val |
||||
|
emits('tableSelectionHandle',val) |
||||
|
} |
||||
|
|
||||
|
// 左侧操作列 |
||||
|
function leftOperationHadel(btn,scope) { |
||||
|
emits('leftOperationHadel',btn,scope) |
||||
|
} |
||||
|
|
||||
|
// 获取右侧操作列 |
||||
|
function getRightOperation() { |
||||
|
// 自定义右侧列,且不需要默认api通用操作 |
||||
|
if(typeof props.rightOperation == 'object' && !props.showApiRightOperation){ |
||||
|
return props.rightOperation |
||||
|
} |
||||
|
// 无自定义操作,或者有自定义且需要默认api操作 |
||||
|
else if( |
||||
|
(typeof props.rightOperation == 'object' && props.showApiRightOperation) |
||||
|
|| typeof props.rightOperation == 'string' |
||||
|
){ |
||||
|
// 格式化默认api按钮合集 |
||||
|
let _apiArr = props.showApiRightOperation || props.rightOperation.split(',') |
||||
|
let _config = { |
||||
|
apiUpdate:{label:'编辑',type:'warning'}, |
||||
|
apiDelete:{label:'删除',type:'danger'}, |
||||
|
} |
||||
|
let _btns = [] |
||||
|
if(_apiArr && _apiArr.length > 0){ |
||||
|
_apiArr.forEach(item => { |
||||
|
_btns.push({ |
||||
|
label:_config[item].label, |
||||
|
name:item, |
||||
|
link:true, |
||||
|
type:_config[item].type, |
||||
|
auth:(props.authName || props.apiName)+':'+item, |
||||
|
hide:(row,scope) => {return row[props.apiRightHideConfig[item].prop] == props.apiRightHideConfig[item].ruleValue} |
||||
|
}) |
||||
|
}); |
||||
|
} |
||||
|
// 如果有自定义按钮,合并默认api按钮 |
||||
|
if(typeof props.rightOperation == 'object'){ |
||||
|
_btns = [..._btns,...props.rightOperation] |
||||
|
} |
||||
|
return _btns |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// 右侧操作列操作 |
||||
|
const apiEditPopRef = ref() |
||||
|
function rightOperationHadel(btn,scope) { |
||||
|
// 通用编辑 |
||||
|
if(btn.name == 'apiUpdate'){ |
||||
|
let _tableColums = props.tableColumns || apiTableColumns[props.apiName] |
||||
|
let _list = _tableColums.filter(item => !item.noEdit) |
||||
|
apiEditPopRef.value.open(_list,scope.row) |
||||
|
} |
||||
|
// 通用删除 |
||||
|
if(btn.name == 'apiDelete'){ |
||||
|
ElMessageBox.confirm(`是否确定删除?`, '提示', { |
||||
|
confirmButtonText: '确定', |
||||
|
cancelButtonText: '取消', |
||||
|
type: 'warning' |
||||
|
}).then(() => { |
||||
|
state.loading = true |
||||
|
deleteCommonApi(props.apiName,scope.row.uId) |
||||
|
.then(res=>{ |
||||
|
ElMessage.success('操作成功!') |
||||
|
getTableData(1); |
||||
|
}) |
||||
|
.finally(()=>{state.loading = false}) |
||||
|
}) |
||||
|
} |
||||
|
emits('rightOperationHadel',btn,scope) |
||||
|
} |
||||
|
|
||||
|
// 编辑表单提交 |
||||
|
const submitEditForm = async (type,formData,formConfig) => { |
||||
|
apiEditPopRef.value.validate((valid) => { |
||||
|
if(valid){ |
||||
|
// 新增 |
||||
|
if(type == 'create'){ |
||||
|
if(formData.hasOwnProperty('createUser')){formData.createUser = userInfo.realName} |
||||
|
if(formData.hasOwnProperty('createByUser')){formData.createByUser = userInfo.realName} |
||||
|
if(formData.hasOwnProperty('createTime')){formData.createTime = formatDate(new Date(), "YYYY-mm-dd HH:MM:SS")} |
||||
|
apiEditPopRef.value.changeLoading(true) |
||||
|
postCommonCreate(props.apiName,formData) |
||||
|
.then(res=>{ |
||||
|
apiEditPopRef.value.close() |
||||
|
ElMessage.success('操作成功!') |
||||
|
getTableData(1); |
||||
|
}) |
||||
|
.catch(err=>{ElMessage.error('操作失败!')}) |
||||
|
.finally(()=>{apiEditPopRef.value.changeLoading(false)}) |
||||
|
}else{ |
||||
|
// 修改人信息处理 |
||||
|
if( |
||||
|
(formData.hasOwnProperty('updateByUser') && formData.hasOwnProperty('updateTime')) |
||||
|
|| (formData.hasOwnProperty('updateUser') && formData.hasOwnProperty('updateTime')) |
||||
|
){ |
||||
|
if(formData.hasOwnProperty('updateByUser')){formData.updateByUser = userInfo.realName} |
||||
|
if(formData.hasOwnProperty('updateUser')){formData.updateUser = userInfo.realName} |
||||
|
if(formData.hasOwnProperty('updateTime')){formData.updateTime = formatDate(new Date(), "YYYY-mm-dd HH:MM:SS")} |
||||
|
}else{ |
||||
|
// 特殊不处理页面 |
||||
|
let _notChange=['taskconifgure','customlog'] |
||||
|
if(_notChange.indexOf(props.apiName) < 0){ |
||||
|
formData.remark= `修改信息:${userInfo.realName} ${formatDate(new Date(), "YYYY-mm-dd HH:MM:SS")}` |
||||
|
} |
||||
|
} |
||||
|
apiEditPopRef.value.changeLoading(true) |
||||
|
putCommonUpdate(props.apiName,formData) |
||||
|
.then(res=>{ |
||||
|
apiEditPopRef.value.close() |
||||
|
ElMessage.success('操作成功!') |
||||
|
getTableData(1); |
||||
|
}) |
||||
|
.catch(err=>{ElMessage.error('操作失败!')}) |
||||
|
.finally(()=>{apiEditPopRef.value.changeLoading(false)}) |
||||
|
} |
||||
|
} |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
// 格式化页面传参 |
||||
|
function getPageParams(pageSize){ |
||||
|
let _filters = [] |
||||
|
if(props.hideSearch){ |
||||
|
_filters = props.searchFilter |
||||
|
}else{ |
||||
|
function __getAction (prop,action){ |
||||
|
if(props.searchFilterOptions && props.searchFilterOptions[prop] && props.searchFilterOptions[prop].action){ |
||||
|
return props.searchFilterOptions[prop].action |
||||
|
}else{ |
||||
|
return action |
||||
|
} |
||||
|
} |
||||
|
for(let i in props.searchFilter){ |
||||
|
let _item = props.searchOptions.filter(item=>item.prop == i) |
||||
|
let _type = (_item && _item.length > 0) ? _item[0].type : null |
||||
|
if((props.searchFilter[i] || props.searchFilter[i] == 0) && props.searchFilter[i] != ""){ |
||||
|
// 时间区域格式 |
||||
|
if(_type == 'datetimerange'){ |
||||
|
_filters.push( |
||||
|
{ |
||||
|
logic: "And", |
||||
|
column: i, |
||||
|
action: __getAction(i,'>='), |
||||
|
value: props.searchFilter[i][0] |
||||
|
} |
||||
|
) |
||||
|
_filters.push( |
||||
|
{ |
||||
|
logic: "And", |
||||
|
column: i, |
||||
|
action: __getAction(i,'<='), |
||||
|
value: props.searchFilter[i][1] |
||||
|
} |
||||
|
) |
||||
|
}else{ |
||||
|
let _action = 'like' |
||||
|
let _EqualTypes = ['tagFilter','filter','number','select']//等于情况的类型 |
||||
|
if(_EqualTypes.indexOf(_type) >= 0){ |
||||
|
_action = '==' |
||||
|
} |
||||
|
_filters.push( |
||||
|
{ |
||||
|
logic: "And", |
||||
|
column: i, |
||||
|
action: __getAction(i,_action), |
||||
|
value: props.searchFilter[i] |
||||
|
} |
||||
|
) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
let _pageParams = getPageParamsForFilter({ |
||||
|
pageNumber:state.pager.page, |
||||
|
pageSize:pageSize || state.pager.pageSize, |
||||
|
sortBy:state.sortFilter.sortBy, |
||||
|
isAscending:state.sortFilter.isAscending, |
||||
|
condition:{ |
||||
|
filters:_filters |
||||
|
} |
||||
|
}) |
||||
|
return _pageParams |
||||
|
} |
||||
|
|
||||
|
// 获取页面数据 |
||||
|
function getTableData(page,callback) { |
||||
|
state.loading = true |
||||
|
if(!page)page = state.pager.page |
||||
|
if(page)state.pager.page = page |
||||
|
if(props.apiType == 'detailApi'){ |
||||
|
getCommonDeatailPaged(props.apiName,getPageParams()) |
||||
|
.then((resp) => { |
||||
|
state.tableData = resp.data.data |
||||
|
state.pager.total = resp.data.totalCount |
||||
|
if(callback)callback(resp) |
||||
|
}) |
||||
|
.catch(err=>{ElMessage.error('数据获取失败!')}) |
||||
|
.finally(() => (state.loading = false)) |
||||
|
}else if(props.specialPageApi){ |
||||
|
getCommonPost(props.specialPageApi,getPageParams()) |
||||
|
.then((resp) => { |
||||
|
state.tableData = resp.data.data |
||||
|
state.pager.total = resp.data.totalCount |
||||
|
if(callback)callback(resp) |
||||
|
}) |
||||
|
.catch(err=>{ElMessage.error('数据获取失败!')}) |
||||
|
.finally(() => (state.loading = false)) |
||||
|
} |
||||
|
else{ |
||||
|
getCommonPaged(props.apiName,getPageParams()) |
||||
|
.then((resp) => { |
||||
|
state.tableData = resp.data.data |
||||
|
state.pager.total = resp.data.totalCount |
||||
|
if(callback)callback(resp) |
||||
|
}) |
||||
|
.catch(err=>{ElMessage.error('数据获取失败!')}) |
||||
|
.finally(() => (state.loading = false)) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// 导出 |
||||
|
function exportHandle(isAll){ |
||||
|
state.loading = true |
||||
|
//同步数据查询 |
||||
|
getTableData(1,(res=>{ |
||||
|
let _params = getPageParams() |
||||
|
if(isAll){_params = getPageParams(res.data.totalCount)} |
||||
|
postCommonExport(props.apiName,_params) |
||||
|
.then((res) => { |
||||
|
let _str = isAll ? '全部' : '当页' |
||||
|
downloadByData(res.data,route.meta.title+`.xlsx`) |
||||
|
}) |
||||
|
.catch(err=>{ElMessage.error('操作失败!')}) |
||||
|
.finally(() => (state.loading = false)) |
||||
|
})) |
||||
|
|
||||
|
} |
||||
|
|
||||
|
const importPopRef = ref() |
||||
|
// 按钮功能 |
||||
|
function searchBtnHandle(btn){ |
||||
|
// 查询 |
||||
|
if(btn == 'search'){ |
||||
|
getTableData(1) |
||||
|
} |
||||
|
// 新增 |
||||
|
else if (btn == 'create'){ |
||||
|
let _tableColums = props.tableColumns || apiTableColumns[props.apiName] |
||||
|
let _list = _tableColums.filter(item => !item.noEdit) |
||||
|
apiEditPopRef.value.open(_list) |
||||
|
} |
||||
|
// 导入 |
||||
|
else if (btn == 'import'){ |
||||
|
importPopRef.value.open() |
||||
|
} |
||||
|
// 导出(按条件导出当前页) |
||||
|
else if (btn == 'export'){ |
||||
|
exportHandle() |
||||
|
} |
||||
|
// 手动开关 |
||||
|
else if (btn == 'custominvoke'){ |
||||
|
ElMessageBox.confirm('是否确定操作手动开关?', '提示', { |
||||
|
confirmButtonText: '确定', |
||||
|
cancelButtonText: '取消', |
||||
|
type: 'warning' |
||||
|
}).then(() => { |
||||
|
state.loading = true |
||||
|
let _data = { |
||||
|
taskName:apiServeNames[props.apiName].taskName, |
||||
|
client:'Chery' |
||||
|
} |
||||
|
getCommonCustominvoke(_data) |
||||
|
.then((res) => { |
||||
|
ElMessage.success('操作成功!') |
||||
|
getTableData(1)//同步数据查询 |
||||
|
}) |
||||
|
.finally(() => (state.loading = false)) |
||||
|
}) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// 排序 |
||||
|
function sortChange(data) { |
||||
|
const { prop, order } = data; |
||||
|
if (!prop || !order) { |
||||
|
state.sortFilter.sortBy = undefined; |
||||
|
state.sortFilter.isAscending = undefined; |
||||
|
getTableData(1); |
||||
|
return; |
||||
|
} |
||||
|
state.sortFilter.sortBy = prop; |
||||
|
state.sortFilter.isAscending = (order == "ascending"); |
||||
|
getTableData(1); |
||||
|
} |
||||
|
|
||||
|
// 导入成功之后todo |
||||
|
function importSuccess(response,importDate){ |
||||
|
getTableData() |
||||
|
} |
||||
|
|
||||
|
// size-change |
||||
|
function pageSizeChange(pageSize){ |
||||
|
state.pager.pageSize = pageSize |
||||
|
getTableData(1) |
||||
|
} |
||||
|
|
||||
|
// current-change |
||||
|
function pageCurrentChange(page){ |
||||
|
getTableData(page) |
||||
|
} |
||||
|
|
||||
|
onMounted(() => { |
||||
|
getTableColumns() |
||||
|
getTableData() |
||||
|
}) |
||||
|
|
||||
|
defineExpose({ |
||||
|
state, |
||||
|
getTableData |
||||
|
}); |
||||
|
</script> |
||||
|
|
||||
|
<style scoped lang="scss"> |
||||
|
::v-deep .search-container { |
||||
|
.el-card__body{ |
||||
|
display:flex; |
||||
|
justify-content: space-between; |
||||
|
} |
||||
|
} |
||||
|
</style> |
@ -1,28 +1,39 @@ |
|||||
<template> |
<template> |
||||
<div class="dashboard-container"> |
<div class="homeMenuPage"> |
||||
<div class="dashboard-text">name: {{ name }}</div> |
<menu-Item |
||||
|
v-for="(item,index) in treeData" |
||||
|
:key="index" |
||||
|
:item="item" |
||||
|
></menu-Item> |
||||
</div> |
</div> |
||||
</template> |
</template> |
||||
|
|
||||
<script setup> |
<script setup> |
||||
defineOptions({ name: 'dashboardIndex' }) |
defineOptions({ name: 'dashboardIndex' }) |
||||
|
import { getCurrentMenu } from '@/api/system/userApi' |
||||
import store from '@/stores' |
import store from '@/stores' |
||||
import { computed } from 'vue' |
import menuItem from './menuItem.vue' |
||||
|
import { onMounted,computed,ref } from 'vue' |
||||
|
import { asyncRoutes } from '@/router/index' |
||||
|
|
||||
const userStore = store.userStore() |
const userStore = store.userStore() |
||||
const name = computed(() => userStore.state.name) |
// const name = computed(() => userStore.state.name) |
||||
|
|
||||
|
let loading = ref(false) |
||||
|
let treeData = asyncRoutes |
||||
|
const defaultProps = ref({ |
||||
|
children: 'children', |
||||
|
label: 'menuName', |
||||
|
}) |
||||
|
|
||||
|
onMounted(() => { |
||||
|
}) |
||||
|
|
||||
</script> |
</script> |
||||
|
|
||||
<style lang="scss" scoped> |
<style lang="scss" scoped> |
||||
.dashboard { |
.homeMenuPage{ |
||||
&-container { |
width:100%; |
||||
margin: 30px; |
overflow:auto |
||||
} |
|
||||
|
|
||||
&-text { |
|
||||
font-size: 30px; |
|
||||
line-height: 46px; |
|
||||
} |
|
||||
} |
} |
||||
</style> |
</style> |
||||
|
@ -0,0 +1,72 @@ |
|||||
|
<template> |
||||
|
<div :class="[(!props.item.children || props.item.children.length <= 0) ? 'childBlock':'menuBlock clearfix']"> |
||||
|
<div class="firstTitle" v-if="props.item.children && props.item.children.length > 0">{{props.item.meta.title}}</div> |
||||
|
<router-link v-else class="itemTitle" :to="props.item.path"> |
||||
|
{{props.item.meta.title}}</router-link> |
||||
|
<div v-if="props.item.children && props.item.children.length > 0" class="isNestBolck"> |
||||
|
<menu-Item |
||||
|
v-for="child in props.item.children" |
||||
|
:key="child.path" |
||||
|
:item="child" |
||||
|
/> |
||||
|
</div> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script setup> |
||||
|
defineOptions({ name: 'menuItem' }) |
||||
|
import menuItem from './menuItem.vue' |
||||
|
import { onMounted,ref } from 'vue' |
||||
|
|
||||
|
const props = defineProps({ |
||||
|
// 数据 |
||||
|
item:{ |
||||
|
type: Object, |
||||
|
default: null |
||||
|
}, |
||||
|
}) |
||||
|
|
||||
|
onMounted(() => { |
||||
|
console.log(props.item) |
||||
|
}) |
||||
|
|
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss" scoped> |
||||
|
.clearfix{ |
||||
|
zoom:1; |
||||
|
} |
||||
|
.clearfix:after{ |
||||
|
clear:both; |
||||
|
display:block; |
||||
|
visibility:hidden; |
||||
|
height:0; |
||||
|
line-height:0; |
||||
|
content:''; |
||||
|
} |
||||
|
.menuBlock{ |
||||
|
margin-bottom:16px; |
||||
|
border-bottom:#e5e5e5 solid 1px; |
||||
|
box-shadow:#f2f2f2 1px 3px 5px; |
||||
|
padding:20px 20px 0; |
||||
|
|
||||
|
.childBlock{ |
||||
|
.itemTitle{ |
||||
|
float:left; |
||||
|
margin-bottom:13px; |
||||
|
margin-right:30px; |
||||
|
color:#555; |
||||
|
&:hover{ |
||||
|
color:var(--el-color-primary) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
.firstTitle{ |
||||
|
border-left: var(--el-color-primary) solid 5px; |
||||
|
padding-left:15px; |
||||
|
margin-bottom:20px; |
||||
|
color:#333; |
||||
|
font-weight:bold |
||||
|
} |
||||
|
} |
||||
|
</style> |
Loading…
Reference in new issue