django-vue-admin/dvadmin-ui/src/components/ModelDisplay/index.vue

1120 lines
35 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<!--
@description: 强大的CRUD组件封装
-->
<template>
<div style="padding-left: 10px;padding-top: 10px;">
<div class="grid-content bg-purple">
<el-form ref="queryForm" :model="queryParams" :inline="true" label-width="90px">
<el-row>
<el-form-item
v-for="(value,index) in fields"
v-if="value.search"
:key="index"
:label="value.label"
:prop="value.prop"
>
<!-- date/option/bool/users/depts -->
<el-switch
v-if="value.type==='boolean'"
v-model="queryParams[value.prop]"
active-color="#13ce66"
inactive-color="#ff4949"
/>
<model-select
v-else-if="value.type==='model_select' && value.select_data"
:value.sync="queryParams[value.prop]"
:prop="value.prop"
:placeholder="value.select_data.placeholder|| '请选择'"
:multiple="value.select_data.multiple|| false"
:disable_branch_nodes="value.select_data.disable_branch_nodes|| false"
:label_name="value.select_data.label_name|| 'name'"
:select_options="modelSelect[value.prop] || []"
style="width: 180px;line-height: 20px;"
/>
<dept-tree
v-else-if="value.type==='depts'"
ref="dept_tree"
:value.sync="queryParams[value.prop]"
style="width: 150px;"
/>
<users-tree
v-else-if="value.type==='users'"
ref="users_tree"
:value.sync="queryParams[value.prop]"
style="width: 150px;"
/>
<el-cascader
v-else-if="value.type === 'cascader' && value.select_data"
v-model="queryParams[value.prop]"
:placeholder="value.select_data.placeholder || '请选择'"
:options="modelSelect[value.prop] || []"
:clearable="value.select_data.clearable || false"
:filterable="value.select_data.filterable || false"
style="width: 100%"
/>
<el-date-picker
v-else-if="value.type === 'date'"
v-model="dateRange[value.prop + '__range']"
size="small"
style="width: 240px"
value-format="yyyy-MM-dd"
type="daterange"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
:default-time="['00:00:00', '23:59:59']"
></el-date-picker>
<el-date-picker
v-else-if="value.type === 'datetime'"
v-model="dateRange[value.prop + '__range']"
size="small"
style="width: 240px"
value-format="yyyy-MM-dd HH:mm:ss"
type="daterange"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
:default-time="['00:00:00', '23:59:59']"
></el-date-picker>
<el-time-select
v-else-if="value.type === 'time'"
v-model="dateRange[value.prop + '__range']"
:picker-options="value.options"
placeholder="选择时间"
:default-time="['00:00:00', '23:59:59']"
>
<el-select
v-else-if="value.type==='option' && value.option_key"
v-model="queryParams[value.prop]"
:placeholder="value.label"
clearable
size="small"
>
<el-option
v-for="dict in DictsOptions[value.option_key]"
:key="dict.dictValue"
:label="dict.dictLabel"
:value="dict.dictValue"
/>
</el-select>
<el-input
v-else
v-model="queryParams[value.prop]"
:placeholder="value.label"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item>
<el-col :offset="8">
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleSearchFormSubmit">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-col>
</el-form-item>
</el-row>
</el-form>
</div>
<el-row v-if="topLayout" style="margin-bottom: 20px">
<el-col v-if="topLayoutLeft" :span="18">
<el-row :gutter="10" class="mb8">
<el-col v-for="(func,index) in funcs" :key="index" :span="1.5">
<el-button
v-if="func.type==='add'"
v-hasPermi="func.permis"
type="primary"
plain
:icon="func.icon||'el-icon-plus'"
size="mini"
@click="handleAdd(func)"
>{{ func.label }}
</el-button>
<el-button
v-else-if="func.type==='update'"
v-hasPermi="func.permis"
type="success"
plain
:disabled="multipleSelection.length!==1"
:icon="func.icon||'el-icon-edit'"
size="mini"
@click="handleUpdate(func,{})"
>{{ func.label }}
</el-button>
<el-button
v-else-if="func.type==='delete'"
v-hasPermi="func.permis"
type="danger"
plain
:disabled="multipleSelection.length===0"
:icon="func.icon||'el-icon-delete'"
size="mini"
@click="handleDelete(func,{})"
>{{ func.label }}
</el-button>
<el-button
v-else-if="func.type==='export'"
v-hasPermi="func.permis"
type="warning"
plain
:icon="func.icon||'el-icon-download'"
size="mini"
@click="handleExport(func)"
>{{ func.label }}
</el-button>
<el-button
v-else-if="func.type==='import'"
v-hasPermi="func.permis"
type="info"
plain
:icon="func.icon||'el-icon-upload2'"
size="mini"
@click="handleImport(func.api)"
>{{ func.label }}
</el-button>
</el-col>
<slot name="head_button" />
</el-row>
</el-col>
<el-col v-if="topLayoutRight" :span="6">
<div class="grid-content bg-purple-light" style="text-align: right">
<slot name="tools" />
<el-popover
placement="bottom"
width="200"
trigger="click"
>
<div style="width: 50px;">
<el-checkbox-group v-model="showFields">
<el-checkbox
v-for="(field, index) in fields"
:key="index"
:label="field"
:checked="field.show"
style="width: 100%"
@change="handleSelectField($event, field)"
>{{ field.label }}
</el-checkbox>
</el-checkbox-group>
</div>
<el-button
slot="reference"
:size="$ELEMENT.size"
name="refresh"
type="info"
icon="el-icon-s-fold"
title="设置显示的字段"
/>
</el-popover>
</div>
</el-col>
</el-row>
<el-table
ref="tableData"
v-loading="tableLoading"
:span-method="spanMethod"
:data="tableData"
:max-height="maxHeight"
:row-key="getRowKeys"
:stripe="stripe"
:fit="fit"
:border="border"
:empty-text="emptyText"
:highlight-current-row="highlightCurrentRow"
:show-overflow-tooltip="showOverflowTooltip"
@sort-change="handleSortChange"
@cell-click="handleCellClick"
@cell-dblclick="handleCellDbClick"
@header-click="handleHeaderClick"
@row-click="handleRowClick"
@row-dblclick="handleRowDblClick"
@selection-change="handleSelectionChange"
>
<el-table-column v-if="selection" :reserve-selection="true" type="selection" width="50" />
<slot name="prependColumn" />
<!--<el-table-column v-if="false" :index="getRowIndex" label="序号" type="index" width="50"/>-->
<template v-for="field in fields">
<el-table-column
v-if="field.show"
:key="field.prop"
:prop="field.prop"
:label="field.label"
:sortable="field.sortable"
:width="field.width || ''"
show-overflow-tooltip
>
<template slot-scope="scope">
<slot :name="field.prop" :values="scope.row" :prop="field.prop" :field="field">
<span v-html="formatColumnData(scope.row, field)" />
</slot>
</template>
</el-table-column>
</template>
<el-table-column
v-if="hasPermi(getOperationPermis())"
label="操作"
align="center"
width="220"
class-name="small-padding fixed-width"
>
<template slot-scope="scope">
<span v-for="(func,index) in funcs" :key="index">
<el-button
v-if="func.type==='select'"
v-hasPermi="func.permis"
size="mini"
type="text"
:icon="func.icon||'el-icon-view'"
@click="handleSelect(func,scope.row)"
>{{ func.label }}</el-button>
&nbsp;
<el-button
v-if="func.type==='update'"
v-hasPermi="func.permis"
size="mini"
type="text"
:icon="func.icon||'el-icon-edit'"
@click="handleUpdate(func,scope.row)"
>{{ func.label }}</el-button>
&nbsp;
<el-button
v-else-if="func.type==='delete'"
v-hasPermi="func.permis"
size="mini"
type="text"
:icon="func.icon||'el-icon-delete'"
@click="handleDelete(func,scope.row)"
>{{ func.label }}</el-button>
</span>
</template>
</el-table-column>
<slot name="appendColumn" />
<slot name="column" />
</el-table>
<el-row>
<el-col v-if="selection" :span="6" style="margin-top: 20px">
<span>已选择:<span style="color: #ff00ff;font-weight: bold;">{{ multipleSelection.length }}</span>条</span>
<el-button
v-show="multipleSelection.length"
type="info"
size="mini"
title="清空多选"
@click="clearMultipleSelection"
>清空
</el-button>
</el-col>
<el-pagination
:current-page="pagination.page"
:page-size="pagination.page_size"
:total="pagination.total"
:page-sizes="paginationStyle.pageSizes || [10, 20, 50, 100]"
:disabled="tableLoading"
:small="paginationStyle.small || false"
:layout="paginationStyle.layout || 'total, sizes, prev, pager, next, jumper'"
background
class="right_pagination"
@size-change="handleChangePageSize"
@current-change="handleChangeCurrentPage"
/>
</el-row>
<!-- 添加或修改参数配置对话框 -->
<el-dialog
:title="title"
:visible.sync="open"
width="500px"
append-to-body
:close-on-click-modal="close_on_click_modal"
@close="close"
>
<el-form ref="ruleForm" :model="form" :rules="rules" label-width="100px">
<el-form-item
v-for="(value,index) in fields"
v-if="value.form"
:key="index"
:label="value.label"
:prop="value.prop"
>
<!-- date/option/bool/users/depts -->
<el-switch
v-if="value.type==='boolean'"
v-model="form[value.prop]"
active-color="#13ce66"
inactive-color="#ff4949"
/>
<el-input-number
v-else-if="value.type==='number'"
v-model="form[value.prop]"
:precision="value.precision || 0"
:step="value.step || 1"
:max="value.step || Infinity"
:min="value.min || Infinity"
/>
<dept-tree
v-else-if="value.type==='depts'"
ref="dept_tree"
:value.sync="form[value.prop]"
/>
<users-tree
v-else-if="value.type==='users'"
ref="users_tree"
:value.sync="form[value.prop]"
/>
<el-date-picker
v-else-if="value.type==='date' || value.type==='datetime'"
v-model="form[value.prop]"
type="date"
size="small"
style="width: 240px"
value-format="yyyy-MM-dd HH:mm:ss"
placeholder="选择日期"
/>
<el-select
v-else-if="value.type==='option' && value.option_key"
v-model="form[value.prop]"
:placeholder="value.label"
clearable
size="small"
style="width: 100%"
>
<el-option
v-for="dict in DictsOptions[value.option_key]"
:key="dict.dictValue"
:label="dict.dictLabel"
:value="dict.dictValue"
/>
</el-select>
<el-input
v-else-if="value.type==='text'"
v-model="form[value.prop]"
:placeholder="value.label"
type="textarea"
clearable
size="small"
/>
<model-select
v-else-if="value.type==='model_select' && value.select_data"
:value.sync="form[value.prop]"
:placeholder="value.select_data.placeholder|| '请选择'"
:multiple="value.select_data.multiple|| false"
:disable_branch_nodes="value.select_data.disable_branch_nodes|| false"
:label_name="value.select_data.label_name|| 'name'"
:select_options="modelSelect[value.prop] || []"
style="line-height: 20px;"
/>
<el-cascader
v-else-if="value.type==='cascader' && value.select_data"
v-model="form[value.prop]"
:placeholder="value.select_data.placeholder|| '请选择'"
:options="modelSelect[value.prop] || []"
:clearable="value.select_data.clearable|| false"
:filterable="value.select_data.filterable|| false"
style="width: 100%"
/>
<el-input
v-else
v-model="form[value.prop]"
:placeholder="value.label"
clearable
size="small"
/>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button v-if="this.title!=='详情'" type="primary" @click="submitForm">确 定</el-button>
<el-button @click="cancel">取 消</el-button>
</div>
</el-dialog>
<!-- 导入对话框 -->
<el-dialog :title="upload.title" :visible.sync="upload.open" width="400px" append-to-body>
<el-upload
ref="upload"
:limit="1"
accept=".xlsx, .xls"
:headers="upload.headers"
:action="upload.url + '?updateSupport=' + upload.updateSupport"
:disabled="upload.isUploading"
:on-progress="handleFileUploadProgress"
:on-success="handleFileSuccess"
:auto-upload="false"
drag
>
<i class="el-icon-upload" />
<div class="el-upload__text">
将文件拖到此处,或
<em>点击上传</em>
</div>
<div slot="tip" class="el-upload__tip">
<el-checkbox v-model="upload.updateSupport" />
是否更新已经存在的数据
<el-link type="info" style="font-size:12px" @click="importTemplate">下载模板</el-link>
</div>
<div slot="tip" class="el-upload__tip" style="color:red">提示仅允许导入“xls”或“xlsx”格式文件</div>
</el-upload>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitFileForm">确 定</el-button>
<el-button @click="upload.open = false"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import moment from "moment";
import * as Utils from "@/utils";
import { getToken } from "@/utils/auth";
import ModelSelect from "../ModelSelect/index";
import { listUser } from "@/api/vadmin/permission/user";
import { treeselect } from "@/api/vadmin/permission/dept";
export default {
name: "ModelDisplay",
components: { ModelSelect },
props: {
value: {
// table的Data
type: Array,
default: () => []
},
spanMethod: {
type: Function,
default: null
},
// eslint-disable-next-line vue/require-prop-types
maxHeight: {
default: 700
},
stripe: {
type: Boolean,
default: true
},
// 是否可以通过点击 窗口外 关闭 Dialog
close_on_click_modal: {
type: Boolean,
default: true
},
fit: {
type: Boolean,
default: true
},
highlightCurrentRow: {
type: Boolean,
default: true
},
showOverflowTooltip: {
type: Boolean,
default: true
},
border: {
type: Boolean,
default: false
},
emptyText: {
type: String,
default: "暂无数据"
},
paginationParams: {
// 新增。分页参数, 当分页格式返回的属性名称不同使用, 可使用该属性覆盖默认分页属性名称
// 例如:{ page: 'page', pageSize: 'pageSize', count: 'total',results: 'list' }
type: Object,
default: () => {
return {
page: "pageNum",
pageSize: "pageSize",
count: "count",
results: "results"
};
}
},
listApi: {
// 用于替换method + url属性
type: Function,
default: null
},
topLayout: {
// 用于控制表格顶部的按钮、工具的显示。默认左右的按钮、功能都显示
type: Array,
default: () => {
return ["left", "right"];
}
},
fields: {
// 后端返回的字段
type: Array,
default: () => {
return [];
}
},
funcs: {
// 菜单配置字段
type: Array,
default: () => {
return [];
}
},
selection: {
// 开始开启多选(默认开启, true)
type: Boolean,
default: true
},
params: {
// 基本请求参数,最终请求参数=基本参数+基本高级搜索参数+组件封装的基本参数+租金组件封装的高级搜索参数
type: Object,
default: () => {
return {};
}
},
// 默认分页样式
paginationStyle: {
type: Object,
default: () => {
return {};
}
},
// 默认页面大小
pageSizes: {
type: Array,
default: () => {
return [10, 20, 50, 100, 500];
}
}
},
data() {
return {
showFields: [], // 显示的字段
searchForm: {
search: "",
ordering: ""
},
queryParams: {},
tableLoading: false,
tableData: [],
rowKey: "",
dateRange: [],
multipleSelection: [],
pagination: {
page: 1,
page_size: 10,
total: 0
},
// 表单参数
form: {},
rules: this.getFormRules(),
open: false,
// 提交时api
submitFormApi: "",
// 单个查询api
selectApi: "",
// 导入api
importApi: "",
DictsOptions: {},
modelSelect: {},
getRowKeys: row => {
if (this.rowKey) {
return row[this.rowKey];
}
return row.id || row.uuid;
},
title: "",
// 用户导入参数
upload: {
// 是否显示弹出层(用户导入)
open: false,
// 弹出层标题(用户导入)
title: "",
// 是否禁用上传
isUploading: false,
// 是否更新已经存在的用户数据
updateSupport: 0,
// 设置上传的请求头部
headers: { Authorization: "Bearer " + getToken() },
// 上传的地址
url: process.env.VUE_APP_BASE_API + "/admin/system/savefile/"
}
};
},
computed: {
topLayoutLeft() {
return this.topLayout.indexOf("left") >= 0;
},
topLayoutRight() {
return this.topLayout.indexOf("right") >= 0;
}
},
watch: {
params: {
deep: true,
handler: function(newValue, oldValue) {
this.getTableData();
}
}
},
mounted() {
},
created() {
this.initComponentData();
this.initOptions();
this.getOperationPermis();
// this.getTableData();
this.funcs.map(value => {
if (value.type === "select") {
this.selectApi = value.api;
}
});
},
methods: {
initComponentData() {
this.pagination.page_size = this.pageSizes[0];
this.fields.forEach(field => {
field.show = (!!field.show);
field.type = (field.type || "string").toLocaleLowerCase();
if (field.type.startsWith("bool")) {
field.type = "boolean";
}
field.label = field.label || field.prop;
field.search = (!!field.search);
field.sortable = (!!field.sortable);
if (field.ordering && field.ordering.startsWith("desc")) {
this.searchForm.ordering = `-${field.prop}`;
} else if (field.ordering && field.ordering.startsWith("asc")) {
this.searchForm.ordering = `${field.prop}`;
}
field.width = field.width || "";
if (field.type === "choices") {
if (Utils.isArray(field.choices) && field.choices.length > 0) {
if (!Utils.isObj(field.choices[0])) {
field.choices = field.choices.map(value => {
return {
label: value,
value: value
};
});
}
}
}
field.unique = (!!field.unique);
if (field.unique) {
this.rowKey = field.prop;
}
});
},
formatColumnData(row, field) {
const type = field.type || "string";
const prop = field.prop;
if (field.formatter && typeof field.formatter === "function") {
return field.formatter(row, prop, type);
}
if (type === "string") {
return row[prop];
} else if (type === "datetime") {
return this.formatDatetime(row[prop]);
} else if (type === "date") {
return this.formatDate(row[prop]);
} else if (type === "time") {
return this.formatTime(row[prop]);
} else if (type === "option") {
return this.formatOptions(field.option_key, row[prop]);
} else if (type === "users") {
return this.formatSelect(row[prop], prop);
} else if (type === "depts") {
return this.formatSelect(row[prop], prop);
} else if (type === "model_select") {
return this.formatSelect(row[prop], prop);
} else if (type.startsWith("bool")) {
return row[prop] ? "是" : "否";
} else if (type === "choices") {
const choices = field.choices;
return this.formatChoices(choices, row[prop]);
} else {
return row[prop];
}
},
formatChoices(choices, value) {
for (const choice of choices) {
if (choice.value === value) {
return choice.label;
}
}
return value;
},
formatDatetime(datetime) {
return moment(datetime).format("YYYY-MM-DD HH:mm:ss");
},
formatDate(date) {
return moment(date).format("YYYY-MM-DD");
},
formatTime(time) {
return moment(time).format("HH:mm:ss");
},
formatOptions(option_key, id) {
var data = this.DictsOptions[option_key];
if (id === null || !data) return "";
for (var i = 0; i < data.length; i++) {
if (data[i].dictValue === id) {
return data[i].dictLabel;
}
}
return "";
},
formatSelect(id, prop) {
var data = this.modelSelect[prop];
if (!id || !data) return "";
for (var i = 0; i < data.length; i++) {
if (data[i].id === id) {
return data[i].label;
}
}
return "";
},
getTableData() {
this.listInterfaceData(this.getRequestParams());
return this.tableData;
},
getFormattedPaginationParams() {
const pageParamName = this.paginationParams.page;
const pageSizeParamName = this.paginationParams.pageSize;
const params = {};
params[pageParamName] = this.pagination.page;
params[pageSizeParamName] = this.pagination.page_size;
return params;
},
// 根据搜索框的内容, 组装请求参数
getRequestParams() {
// 组装分页参数、高级搜索参数
const tmpParams = { ...this.params, ...this.getFormattedPaginationParams(), ...this.queryParams };
const params = {};
for (const prop of Object.keys(tmpParams)) {
if (tmpParams[prop]) {
params[prop] = tmpParams[prop];
}
}
// 组装普遍模糊搜索的参数
if (this.searchForm.search) {
params["search"] = this.searchForm.search;
}
// 组装普遍排序搜索的参数
if (this.searchForm.ordering) {
params["ordering"] = this.searchForm.ordering;
}
// console.dir(params);
return this.addDateRange(params, this.dateRange);
},
// 封装后端接口, 后端接口返回数据必须规范一致
listInterfaceData(params) {
this.tableLoading = true;
this.listApi(params).then(response => {
this.tableLoading = false;
if (response.status === "success") {
const resultsParamName = this.paginationParams.results;
const countParamName = this.paginationParams.count;
this.tableData = response.data[resultsParamName] || [];
this.pagination.total = response.data[countParamName] || 0;
} else {
this.$message.warning(response.msg || "获取接口信息失败!");
}
}).catch(error => {
this.tableLoading = false;
console.error(error);
});
},
/** 清空已选择 */
clearMultipleSelection() {
this.clearSelection();
},
/** 清空已选择 */
clearSelection() {
this.$refs.tableData.clearSelection();
},
handleSelectField(e, field) {
field.show = e;
},
// 处理提交表单, 点击搜索按钮事件
handleSearchFormSubmit() {
this.pagination.page = 1;
this.getTableData();
},
/** 搜索按钮操作 */
handleQuery() {
this.pagination.page = 1;
this.getTableData();
},
/** 重置按钮操作 */
resetQuery() {
this.dateRange = [];
this.queryParams = {};
this.resetForm("queryForm");
this.handleQuery();
},
/** 初始化 Options */
initOptions() {
const Promises = [];
this.fields.map(value => {
if (value.option_key) {
Promises.push(this.getDicts(value.option_key).then(response => {
this.DictsOptions[value.option_key] = response.data;
}));
}
if (value.type === "model_select" && value.select_data) {
Promises.push(this.getModelSelect(value.prop, value.select_data.label_name, value.select_data.listApi).then(response => {
this.modelSelect[value.prop] = response;
}));
}
if (value.type === "cascader" && value.select_data) {
Promises.push(value.select_data.listApi().then(response => {
this.modelSelect[value.prop] = response.data;
}));
}
if (value.type === "users") {
Promises.push(this.getModelSelect(value.prop, "name", listUser, { _fields: "id,name" }).then(response => {
this.modelSelect[value.prop] = response;
}));
}
if (value.type === "depts") {
Promises.push(this.getModelSelect(value.prop, "label", treeselect).then(response => {
this.modelSelect[value.prop] = response;
}));
}
});
Promise.all(Promises).then(() => {
this.getTableData();
});
},
// 处理修改多选的值
handleSelectionChange(val) {
this.$emit("selection-change", val);
this.multipleSelection = val;
},
// 处理修改表格分页器的页面大小(再次获取接口数据)
handleChangePageSize(val) {
this.pagination.page_size = val;
this.getTableData();
},
// 处理修改表格分页器的页码(再次获取接口数据)
handleChangeCurrentPage(val) {
this.pagination.page = val;
this.getTableData();
},
handleSortChange(info) {
const { prop, order } = info;
if (!order) {
this.searchForm.ordering = "";
} else if (order.startsWith("desc")) {
this.searchForm.ordering = `-${prop}`;
} else {
this.searchForm.ordering = `${prop}`;
}
this.getTableData();
},
handleCellClick(row, column, cell, event) {
this.$emit("cell-click", row, column, cell, event);
},
handleCellDbClick(row, column, cell, event) {
this.$emit("cell-dblclick", row, column, cell, event);
},
handleRowClick(row, column, event) {
this.$emit("row-click", row, column, event);
},
handleRowDblClick(row, column, event) {
this.$emit("row-dblclick", row, column, event);
},
handleHeaderClick(column, event) {
this.$emit("header-click", column, event);
},
/** 新增按钮*/
handleAdd(func) {
this.dateRange = [];
this.queryParams = {};
this.resetForm("queryForm");
this.open = true;
this.title = func.label;
this.submitFormApi = func.api;
},
/** 修改按钮*/
handleUpdate(func, row) {
this.dateRange = [];
this.queryParams = {};
this.resetForm("queryForm");
this.submitFormApi = func.api;
const id = row.id || this.multipleSelection.map(item => item.id);
if (this.selectApi) {
this.selectApi(id).then(response => {
const data = response.data;
if (data && typeof data === "object") {
this.form = data;
}
this.open = true;
});
} else {
this.open = true;
}
this.title = func.label;
},
/** 详情按钮*/
handleSelect(func, row) {
this.dateRange = [];
this.queryParams = {};
this.resetForm("queryForm");
this.submitFormApi = func.api;
const id = row.id || this.multipleSelection.map(item => item.id);
if (this.selectApi) {
this.selectApi(id).then(response => {
const data = response.data;
if (data && typeof data === "object") {
this.form = data;
}
this.open = true;
});
} else {
this.open = true;
}
this.title = func.label;
},
/** 删除按钮操作 */
handleDelete(func, row) {
const ids = row.id || this.multipleSelection.map(item => item.id);
this.$confirm("是否确认" + func.label + '编号为"' + ids + '"的数据项?', "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(function() {
return func.api(ids);
}).then(() => {
this.getTableData();
this.$emit("delete", ids);
this.msgSuccess("删除成功");
});
},
/** 导出按钮操作 */
handleExport(func) {
const queryParams = this.queryParams;
this.$confirm("是否确认导出所有符合条件的数据项?", "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(function() {
return func.api(queryParams);
}).then(response => {
this.download(response.data.file_url, response.data.name);
});
},
/** 导入按钮操作 */
handleImport() {
this.upload.title = "导入";
this.upload.open = true;
}, /** 获取表单校验 */
getFormRules() {
const dict = {};
this.fields.map(value => {
if (value.form) {
if (value.required) {
dict[value.prop] = [{
required: value.required,
message: value.rules_message || value.label + "不能为空",
trigger: value.trigger || "change"
}];
if (value.validator) {
dict[value.prop][1] = {
validator: value.validator,
trigger: value.trigger || "change"
};
}
}
}
});
return dict;
},
/** 提交按钮 */
submitForm() {
this.$refs["ruleForm"].validate(valid => {
if (valid) {
if (this.form.id !== undefined) {
this.submitFormApi(this.form).then(() => {
this.msgSuccess("修改成功");
this.open = false;
this.getTableData();
this.$emit("update", this.form);
});
} else {
this.submitFormApi(this.form).then(() => {
this.msgSuccess("新增成功");
this.open = false;
this.getTableData();
this.$emit("add", this.form);
});
}
}
});
},
// 取消按钮
cancel() {
this.open = false;
},
close() {
this.$refs["ruleForm"].resetFields();
this.form = {};
},
// 获取操作的权限列表
getOperationPermis() {
let Permis = [];
this.funcs.map(value => {
if (["update", "delete", "select"].indexOf(value.type) !== -1) {
Permis = Permis + value.permis;
}
});
return Permis;
},
/** 下载模板操作 */
importTemplate() {
this.funcs.map(value => {
if (value.type === "import") {
this.importApi = value;
}
});
this.importApi.template_api().then(response => {
this.download(response.data.file_url, response.data.name);
});
},
// 文件上传中处理
handleFileUploadProgress(event, file, fileList) {
this.upload.isUploading = true;
},
// 文件上传成功处理
handleFileSuccess(response, file, fileList) {
this.funcs.map(value => {
if (value.type === "import") {
this.importApi = value;
}
});
this.upload.open = false;
this.upload.isUploading = false;
this.$refs.upload.clearFiles();
// 是否更新已经存在的用户数据
this.importApi.api({
file_url: response.data.file_url,
updateSupport: this.upload.updateSupport
}).then(response => {
this.$alert("导入成功!", "导入结果", { dangerouslyUseHTMLString: true });
this.getTableData();
});
},
// 提交上传文件
submitFileForm() {
this.$refs.upload.submit();
}
}
};
</script>
<style scoped>
.picker {
width: 240px;
}
.el-pagination {
padding: 5px;
}
.right_pagination {
text-align: right;
padding-top: 20px;
}
</style>