完整代码如下:
<template>
<!-- 资源列表页 -->
<div>
<div>
<i
@click="$router.go(-1)"
style="
color: #409eff;
cursor: pointer;
margin-right: 5px;
font-size: 18px;
"
class="el-icon-back"
></i
>{{ getCurrentPageTitle }}
</div>
<br />
<el-row class="contentTop">
<el-col :span="12">
<el-button type="primary" size="mini" @click="doAdd">新建</el-button>
<el-button
size="mini"
@click="
drawerImportant = true;
active = 0;
currentFile = null;
"
>导入</el-button
>
<!-- <el-button size="mini">批量更新</el-button>
<el-button size="mini">删除</el-button> -->
<el-button size="mini" @click="doExport">导出</el-button>
<el-button size="mini" @click="doExportTemplate">导出模板</el-button>
</el-col>
<el-col :span="10">
<el-input
placeholder="请输入内容"
v-model="inputValue"
class="input-with-select"
size="mini"
clearable
>
<el-select
v-model="selectValue"
slot="prepend"
style="width: 120px"
placeholder="请选择"
clearable
@change="changeSelect"
>
<el-option
:label="item.label"
:value="item.value"
v-for="item in searchList"
:key="item.value"
></el-option>
</el-select>
<el-button
slot="append"
icon="el-icon-search"
@click="doSearch"
></el-button>
</el-input>
</el-col>
<el-col :span="0.5">
<el-button
icon="el-icon-setting"
size="mini"
@click="doSetting"
></el-button>
</el-col>
</el-row>
<br />
<el-row>
<!-- @cell-click="doClickCell" -->
<el-table
:data="tableInfo.list"
size="mini"
@selection-change="handleSelectionChange"
fit
:stripe="true"
:row-key="rowKey"
ref="multipleTable"
max-height="500"
border
id="tableId"
@sort-change="sortChange"
>
<!-- <el-table-column
type="selection"
:reserve-selection="true"
width="55"
></el-table-column> -->
<el-table-column
v-for="(item, index) in tableInfo.columns"
v-if="!item.hide"
:prop="item.name"
:label="item.label"
:key="index"
:show-overflow-tooltip="true"
sortable="custom"
>
<!-- <template slot-scope="scope">
<el-button
v-if="item.name == 'example'"
type="text"
@click="doClickCell(scope.row)"
>{{ scope.row[item.name] }}</el-button
>
<span v-else>{{ scope.row[item.name] }}</span>
</template> -->
</el-table-column>
<el-table-column fixed="right" label="操作" width="180">
<template slot-scope="scope">
<el-button @click="doClickCell(scope.row)" type="text" size="small"
>详情</el-button
>
<el-button
@click.stop="deleteRow(scope.row.id)"
type="text"
size="small"
>删除</el-button
>
</template>
</el-table-column>
</el-table>
<div style="text-align: center">
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="paramsPage.pageNum"
:page-sizes="[10, 20, 30, 50, 100]"
:page-size="paramsPage.pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="tableInfo.total"
></el-pagination>
</div>
</el-row>
<el-drawer
title="列表显示属性配置"
:visible.sync="drawer"
direction="rtl"
size="45%"
>
<el-transfer
style="text-align: left; display: inline-block"
v-model="transferValue"
filterable
:left-default-checked="[]"
:right-default-checked="[]"
:render-content="renderFunc"
:titles="['未选属性', '已选属性']"
:format="{
noChecked: '${total}',
hasChecked: '${checked}/${total}',
}"
:props="{
key: 'name',
label: 'label',
}"
@change="handleChange"
:data="dataList"
>
</el-transfer>
<br />
<br />
<div style="padding: 0 20px">
<el-button type="primary" size="small" @click="doSettingConfirm"
>应用</el-button
>
<el-button size="small" @click="drawer = false">取消</el-button>
<el-button style="float: right" size="small" @click="doRest"
>还原默认</el-button
>
</div>
</el-drawer>
<el-drawer
title="创建"
:visible.sync="drawerAdd"
direction="rtl"
size="30%"
>
<div style="padding-left: 20px">
<el-form
label-position="top"
label-width="80px"
:model="formLabelAlign"
>
<el-collapse
v-model="activeNames"
v-for="(item, index) in modelList"
:key="index"
>
<el-collapse-item :title="item.name" :name="index">
<el-row :gutter="40" v-for="(v, i) in item.infoList" :key="i">
<el-col :span="20">
<el-form-item :label="v.label">
<el-input
v-if="v.typeValue == 'input'"
v-model="formLabelAlign[v.name]"
placeholder="请输入"
style="width: 570px"
></el-input>
<el-input
v-else-if="v.typeValue == 'number'"
type="number"
v-model="formLabelAlign[v.name]"
placeholder="请输入"
style="width: 570px"
></el-input>
<el-date-picker
v-else-if="v.typeValue == 'date'"
value-format="yyyy-MM-dd"
type="date"
v-model="formLabelAlign[v.name]"
placeholder="请输入"
style="width: 570px"
></el-date-picker>
<el-date-picker
v-else-if="v.typeValue == 'time'"
value-format="yyyy-MM-dd HH:mm:ss"
type="datetime"
v-model="formLabelAlign[v.name]"
placeholder="请输入"
style="width: 570px"
></el-date-picker>
<el-select
v-else-if="
v.typeValue == 'select' &&
v[`valueAttribute${i}`] &&
v[`valueAttribute${i}`].length > 0
"
v-model="formLabelAlign[v.name]"
clearable
style="width: 570px"
>
<el-option
v-for="w in v[`valueAttribute${i}`]"
:key="w.key"
:label="w.value"
:value="w.key"
>
</el-option>
</el-select>
<el-cascader
v-else-if="
v.typeValue == 'isCascade' &&
v[`valueAttribute${i}`] &&
v[`valueAttribute${i}`].length > 0
"
v-model="formLabelAlign[v.name]"
:options="v[`valueAttribute${i}`]"
:props="propsCascader"
@change="handleChangeCas"
></el-cascader>
</el-form-item>
</el-col>
</el-row>
</el-collapse-item>
</el-collapse>
<div class="bottomButton">
<el-button type="primary" @click="doConfirm">提交</el-button>
<el-button @click="drawerAdd = false">取消</el-button>
</div>
</el-form>
</div>
</el-drawer>
<el-drawer
title="批量导入"
:visible.sync="drawerImportant"
direction="rtl"
size="45%"
>
<div style="padding-left: 20px">
<el-steps :active="active" finish-status="success" align-center>
<el-step title="上传文件"></el-step>
<el-step title="选择关联模型"></el-step>
</el-steps>
<div style="padding-left: 20px">
<div v-if="active == 0">
<div
style="
margin: 20px 0;
background: rgb(255, 244, 226);
border: 1px solid rgb(255, 223, 172);
"
>
<i style="color: rgb(255, 156, 1)" class="el-icon-info"></i>
说明:导入编辑需要先导出需要修改的实例,并完成编辑修改后才能进行导入编辑操作
</div>
<el-upload
class="upload-demo"
drag
action
multiple
:http-request="uploadFiles"
>
<i class="el-icon-upload"></i>
<div class="el-upload__text">
将文件拖到此处,或<em>点击上传</em>
</div>
<div class="el-upload__tip" slot="tip">
只能上传jpg/png文件,且不超过500kb
<el-button
type="primary"
icon="el-icon-download"
size="mini"
@click="downloadTemplate"
>下载模板</el-button
>
</div>
</el-upload>
</div>
<div style="margin: 20px 0" v-if="active == 1">
<el-checkbox v-model="checked">是否导入关联的模型实例</el-checkbox>
</div>
<div style="margin-top: 20px">
<el-button
v-if="active == 0"
type="primary"
:disabled="!currentFile"
@click="active = 1"
>下一步</el-button
>
<el-button v-if="active == 1" @click="active = 0">上一步</el-button>
<el-button v-if="active == 1" type="primary" @click="doImportant"
>开始导入</el-button
>
<el-button @click="drawerImportant = false">取消</el-button>
</div>
</div>
</div>
</el-drawer>
</div>
</template>
<script>
import { mapGetters, mapMutations } from "vuex";
import tableCell from "./tableCell";
import { unique } from "@/utils/index";
import {
resourceList,
deleteResource,
queryResource,
findAllModel,
getAddress,
exportTemplate,
uploadResource,
exportResource,
exportResourceTemplate,
addResource,
batchUpdateField,
findAll,
querySelect,
} from "@/api/cmdb/model";
export default {
data() {
return {
inputValue: "",
select: "",
valueCade: [],
selectValue: "",
drawer: false,
drawerAdd: false,
drawerImportant: false,
checked: false,
active: 0,
activeNames: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
multipleSelection: [],
searchList: [],
modelList: [],
currentArgs: [],
formInline: {},
formLabelAlign: {},
currentFile: null,
tableInfo: {
columns: [],
list: [],
total: 0,
},
paramsPage: {
pageNum: 1,
pageSize: 10,
},
dataList: [], // 所有字段数据
selectFieldList: [],
transferValue: [], // 右侧数据
renderFunc(h, option) {
return (
<span>
{/* {option.key} - {option.label} */}
{option.label}
</span>
);
},
propsCascader: {
value: "key",
label: "value",
children: "child",
},
};
},
computed: {
...mapGetters(["getCurrentPageTitle", "getActiveModel"]),
},
// watch: {
// $route: {
// handler(to, from) {
// this.$set(this.tableInfo, "columns", tableCell[to.params.id]);
// this.paramsPage.pageSize = 10;
// this.paramsPage.pageNum = 1; //重置页面
// },
// immediate: true,
// },
// },
mounted() {
this.getList();
this.getSearchList();
this.getFields();
},
methods: {
...mapMutations(["setDetailTitle", "setResourceId"]),
// 当前模型详情查询(新建字段)
getFields() {
let params = {
args: this.getActiveModel.uniqueId,
};
findAllModel(params)
.then((res) => {
if (res.code == 0) {
this.modelList = res.data; // 当前模型下包含的分组
this.modelList.forEach(v1 => {
v1.infoList.forEach((v2,i2)=> {
if(v2.typeValue == 'isCascade' || v2.typeValue == 'select') {
getAddress(v2.dateTypeValue,{}).then(res2 => {
v2[`valueAttribute${i2}`] = res2
})
}
})
})
// 列表字段显示隐藏
let arr = [];
res.data.forEach((v) => {
arr.push(v.infoList);
});
this.dataList = arr.flat(); // 二维数组转一维
// 右侧数据
this.transferValue = this.dataList.map((v) => {
if (v.show) {
return v.name;
}
});
} else {
res.desc && this.$message.error(res.desc);
}
})
.catch((err) => {
err.desc && this.$message.error(err.desc);
});
},
getList(id = "id", order = "", args) {
let params = {
currPage: this.paramsPage.pageNum,
pageSize: this.paramsPage.pageSize,
uniqueId: this.getActiveModel.uniqueId,
args: args || [],
sortName: id,
sortValue: order == "descending" ? false : true, // true = ASC,false = DESC
};
resourceList(params)
.then((res) => {
if (res.code == 0) {
this.tableInfo.columns = res.data.headers;
this.tableInfo.list = res.data.bodyData.list;
this.tableInfo.total = res.data.bodyData.total;
} else {
res.desc && this.$message.error(res.desc);
}
})
.catch((err) => {
err.desc && this.$message.error(err.desc);
});
},
// 排序
sortChange({ column, prop, order }) {
// console.log(column, prop, order );
this.getList(prop, order, []);
},
changeSelect(key) {
this.currentKey = key;
},
// 按条件搜索
doSearch() {
// if (!this.currentKey) {
// return this.$message.warning("请选择需要查询的字段名称");
// }
let args = [
{
key: this.currentKey,
value: this.inputValue,
select: false, // true为下拉搜索,一般默认都是输入框
},
];
this.currentArgs = args;
this.getList("id", "", this.inputValue ? args : []);
},
// 查询下拉
getSearchList() {
let params = {
args: this.getActiveModel.uniqueId,
};
queryResource(params).then((res) => {
if (res.code == 0) {
this.searchList = res.data;
}
});
},
rowKey(row) {
return row.id;
},
handleSizeChange(val) {
this.paramsPage.pageSize = val;
this.getList();
},
handleCurrentChange(val) {
this.paramsPage.pageNum = val;
this.getList();
},
//多选
handleSelectionChange(val) {
// console.log(val);
this.multipleSelection = val;
},
doSetting() {
this.drawer = true;
},
// 还原默认
doRest() {
this.dataList.forEach((v) => {
v.createTime && delete v.createTime;
v.updateTime && delete v.updateTime;
// 第一次保存的设置true,其他都隐藏false
if (v.showDefault) {
v.show = true;
} else {
v.show = false;
}
});
batchUpdateField(this.dataList)
.then((res) => {
if (res.code == 0) {
this.drawer = false;
this.getList();
this.getFields();
this.$message.success(res.desc);
} else {
this.drawer = false;
res.desc && this.$message.error(res.desc);
}
})
.catch((err) => {
this.drawer = false;
err.desc && this.$message.error(err.desc);
});
},
// 字段显示配置--应用
doSettingConfirm() {
let arr = [];
arr = this.selectFieldList.map((v) => {
return v.showDefault;
});
// 如果包含true,说明保存过一次,如果不包含true,说明第一次保存,为还原默认设置数据
if (arr.includes(true)) {
// console.log('保存过一次');
} else {
// console.log('第一次保存');
// 第一次保存-应用,右侧showDefault设为true
this.selectFieldList.forEach((v1) => {
this.transferValue.forEach((v2) => {
if (v2 == v1.name) {
v1.showDefault = true;
}
});
});
}
batchUpdateField(this.selectFieldList)
.then((res) => {
if (res.code == 0) {
this.drawer = false;
this.getList();
this.getFields();
this.$message.success(res.desc);
} else {
this.drawer = false;
res.desc && this.$message.error(res.desc);
}
})
.catch((err) => {
this.drawer = false;
err.desc && this.$message.error(err.desc);
});
},
handleChangeCas(val) {},
handleChange(value, direction, movedKeys) {
// console.log(value, direction, movedKeys);
let arr = [];
// value为右侧数据;左侧dataList为所有数据
// 默认全部show设为false,右侧是选中的需要show设为true,否则就为false
this.dataList.forEach((v1) => {
v1.show = false;
v1.createTime && delete v1.createTime;
v1.updateTime && delete v1.updateTime;
});
this.dataList.forEach((v1) => {
value.forEach((v2) => {
if (v2 == v1.name) {
v1.show = true;
arr.push(v1);
} else {
arr.push(v1);
}
});
});
this.selectFieldList = unique(arr, "id"); // 根据id去重
},
doClickCell(row) {
this.setDetailTitle(row.example);
this.setResourceId(row.id);
this.$router.push({ path: `/resource/detail` });
},
next() {
this.active = 2;
},
deleteRow(id) {
let that = this;
let params = {
uniqueId: this.getActiveModel.uniqueId,
id: id,
};
that
.$confirm("确认要删除这条数据?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(() => {
deleteResource(params)
.then((res) => {
if (res.code == 0) {
that.$message.success(res.desc);
that.getList();
} else {
if (res.desc) {
that.$message.error(res.desc);
}
}
})
.catch((err) => {
err.desc && that.$message.error(err.desc);
});
})
.catch(() => {
that.$message({
type: "info",
message: "已取消删除",
});
});
},
doAdd() {
this.drawerAdd = true;
this.formLabelAlign = {};
},
// 新建--提交
doConfirm() {
if (
this.formLabelAlign.example_department &&
this.formLabelAlign.example_department.length > 0
) {
this.formLabelAlign.example_department =
this.formLabelAlign.example_department.join();
}
let params = {
uniqueId: this.getActiveModel.uniqueId,
args: this.formLabelAlign,
};
addResource(params)
.then((res) => {
if (res.code == 0) {
this.getList();
this.drawerAdd = false;
this.$message.success(res.desc);
} else {
res.desc && this.$message.error(res.desc);
}
})
.catch((err) => {
err.desc && this.$message.error(err.desc);
});
},
getDownload(res) {
const blob = new Blob([res]);
// const fileName = res.headers["content-disposition"].split("=")[1];
const fileName = this.getActiveModel.uniqueId;
const elink = document.createElement("a");
elink.download = window.decodeURIComponent(fileName);
elink.style.display = "none";
elink.href = URL.createObjectURL(blob);
elink.setAttribute("download", `${fileName}.xlsx`); // 下载文件的名称及文件类型后缀
document.body.appendChild(elink);
elink.click();
URL.revokeObjectURL(elink.href); // 释放URL 对象
document.body.removeChild(elink);
},
// 下载模板
downloadTemplate() {
let params = {
uniqueId: this.getActiveModel.uniqueId,
};
exportTemplate(params).then((res) => {
this.getDownload(res);
});
},
// 导出
doExport() {
let params = {
uniqueId: this.getActiveModel.uniqueId,
currPage: this.paramsPage.pageNum,
pageSize: this.paramsPage.pageSize,
args: this.currentArgs,
titleList: this.multipleSelection.map((v) => v.id),
};
exportResource(params).then((res) => {
this.getDownload(res);
});
},
// 导出模板
doExportTemplate() {
let params = {
uniqueId: this.getActiveModel.uniqueId,
};
exportResourceTemplate(params).then((res) => {
this.getDownload(res);
});
},
// 导入--上传
uploadFiles(files) {
const _file = files.file;
this.currentFile = _file;
// var formData = new FormData();
// formData.append("file", _file);
// formData.append("uniqueId", this.getActiveModel.uniqueId);
// uploadResource(formData)
// .then((res) => {
// if (res.code == 0) {
// this.getList();
// this.drawerImportant = false;
// this.$message.success(res.desc);
// } else {
// res.desc && this.$message.error(res.desc);
// }
// })
// .catch((err) => {
// err.desc && this.$message.error(err.desc);
// });
},
// 开始导入
doImportant() {
var formData = new FormData();
formData.append("file", this.currentFile);
formData.append("uniqueId", this.getActiveModel.uniqueId);
uploadResource(formData)
.then((res) => {
if (res.type == "application/json") {
this.$message.success("导入成功");
this.drawerImportant = false;
this.getList();
} else {
this.drawerImportant = false;
this.$message.error("导入失败");
}
})
.catch((err) => {
this.drawerImportant = false;
this.$message.error("导入失败");
});
},
},
};
</script>
<style scoped lang="scss">
.contentTop {
display: flex;
justify-content: space-between;
align-items: center;
}
::v-deep .el-drawer__open .el-drawer.rtl {
-webkit-animation: rtl-drawer-in 0.3s 1ms;
animation: rtl-drawer-in 0.3s 1ms;
width: 38% !important;
}
::v-deep .el-transfer-panel {
height: 660px !important;
}
::v-deep .el-transfer-panel__list.is-filterable {
height: 660px !important;
}
::v-deep .el-upload-dragger {
width: 530px !important;
}
.bottomButton {
position: sticky;
bottom: 0;
left: 0;
margin-top: 10px;
}
</style>