灵山工作端前端代码
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

974 lines
22 KiB

<template>
<div class="div_main">
<div v-show="true">
<div class="div_search" ref="ref_search">
<el-form
:inline="true"
ref="ref_searchform"
label-width="100px"
>
<div>
<el-form-item
v-for="item in searchParams"
:key="'serach' + item.keyName"
:label="item.field"
:prop="item.keyName"
>
<template v-if="item.type == 'input'">
<el-input
v-model="item.value"
style="width: 240px"
size="small"
clearable
:placeholder="item.placeholder || '请输入'"
>
</el-input>
</template>
<template v-else-if="item.type == 'select'">
<el-select
v-model="item.value"
:placeholder="item.placeholder || '请选择'"
size="small"
clearable
style="width: 240px"
:multiple="item.multiple || false"
>
<el-option
v-for="item in item.optionList"
:key="
'serach' + item.keyName + item.value
"
:label="item.label"
:value="item.value"
>
</el-option>
</el-select>
</template>
<template v-else-if="item.type == 'cascader'">
<el-cascader
v-model="item.value"
:placeholder="item.placeholder || '请选择'"
:options="item.optionList"
:props="item.optionProps"
:show-all-levels="false"
size="small"
clearable
style="width: 240px"
@change="
(e) => handleChangeCascader(e, item)
"
>
</el-cascader>
</template>
<template v-if="item.type == 'date-range'">
<el-date-picker
v-model="item.supValues[0]"
type="date"
placeholder="开始时间"
style="width: 150px"
value-format="yyyy-MM-dd"
clearable
>
</el-date-picker>
<span
style="
display: inline-block;
margin: 0 10px;
"
>至</span
>
<el-date-picker
v-model="item.supValues[1]"
type="date"
placeholder="结束时间"
style="width: 150px"
value-format="yyyy-MM-dd"
clearable
>
</el-date-picker>
</template>
</el-form-item>
<el-button
style="margin-left: 30px; margin-bottom: 20px"
size="small"
class="diy-button--search"
@click="handleSearch"
>查询</el-button
>
<el-button
style="margin-left: 10px; margin-bottom: 20px"
size="small"
class="diy-button--reset"
@click="resetSearch"
>重置</el-button
>
</div>
</el-form>
</div>
<div
class="div_table"
:style="{ height: maxTableHeight + 130 + 'px' }"
>
<div class="div_btn">
<el-button
class="diy-button--add"
v-if="addUrl"
size="small"
@click="handleAdd"
>新增</el-button
>
<el-button
v-if="mubanUrl"
class="btn_upload diy-button--export"
size="small"
@click="handleExportModule('room')"
>下载模板</el-button
>
<el-upload
:headers="$getElUploadHeaders()"
v-if="importUrl"
ref="upload"
class="upload-btn"
action="uploadUlr"
:limit="1"
:accept="'.xls,.xlsx'"
:with-credentials="true"
:show-file-list="false"
:auto-upload="true"
:before-upload="beforeExcelUpload"
:http-request="uploadHttpRequest"
>
<el-button
size="small"
class="btn_upload diy-button--delete"
>导入</el-button
>
</el-upload>
<el-button
v-if="exportUrl"
@click="handleExport"
class="btn_upload diy-button--reset"
size="small"
>导出</el-button
>
<el-button
v-if="qrCodeExportUrl"
@click="handleExportQrcode"
class="btn_upload diy-button--reset"
size="small"
>导出员工登记码</el-button
>
<el-button
v-if="delMultipleUrl"
size="small"
@click="handleDeleteMultiple"
>批量删除</el-button
>
<slot
name="listBtn"
v-bind:multipleSelection="multipleSelection"
></slot>
</div>
<el-table
ref="ref_table"
:data="tableData"
border
:empty-text="loadInfo"
:header-cell-style="{
background: '#2195FE',
color: '#FFFFFF',
}"
class="table"
style="width: 100%"
:height="maxTableHeight"
@selection-change="handleSelectionChange"
>
<template
v-for="(item, index) in tableParams"
:prop="item.keyName"
>
<el-table-column
v-if="item.type == 'selection'"
:key="'table-selection' + index"
type="selection"
align="center"
width="50"
/>
<el-table-column
v-if="item.type == 'no'"
:key="'table-no' + item.keyName"
:label="item.field"
fixed="left"
type="index"
align="center"
width="50"
/>
<el-table-column
v-else-if="item.type == 'text'"
:key="'table' + item.keyName"
:prop="item.keyName"
:label="item.field"
align="center"
:width="item.width || ''"
:show-overflow-tooltip="true"
>
</el-table-column>
<el-table-column
v-else-if="item.type == 'array'"
:key="'table-array' + item.keyName"
:prop="item.keyName"
:label="item.field"
align="center"
:width="item.width || ''"
:show-overflow-tooltip="true"
>
<template slot-scope="scope">
{{
scope.row[item.keyName].join(
item.arrayDiv || ","
)
}}
</template>
</el-table-column>
</template>
<el-table-column
v-if="operateCol"
fixed="right"
label="操作"
align="center"
width="200"
>
<template slot-scope="scope">
<slot
name="listBtnbefore"
v-bind:item="scope.row"
></slot>
<el-button
v-if="infoUrl && infoAuth(scope.row)"
@click="handleWatch(scope.row)"
type="text"
size="small"
class=".div-table-button--detail"
>查看</el-button
>
<el-button
v-if="editUrl && editAuth(scope.row)"
@click="handleEdit(scope.row)"
type="text"
size="small"
class="div-table-button--edit"
>{{ editBtnName(scope.row) }}</el-button
>
<el-popconfirm
v-if="delUrl && delAuth(scope.row)"
title="删除之后无法回复,确认删除?"
@onConfirm="
handleDelete(scope.row, scope.$index)
"
@confirm="handleDelete(scope.row, scope.$index)"
>
<el-button
slot="reference"
type="text"
size="small"
style="margin-left: 10px"
class="div-table-button--delete"
>删除</el-button
>
</el-popconfirm>
<slot
name="listBtnSup"
v-bind:item="scope.row"
></slot>
</template>
</el-table-column>
</el-table>
<div>
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page.sync="pageNo"
:page-sizes="[20, 50, 100, 200]"
:page-size="parseInt(pageSize)"
layout="sizes, prev, pager, next, total"
:total="total"
>
</el-pagination>
</div>
</div>
</div>
<!-- 修改弹出框 -->
<el-dialog
v-if="formShow"
:visible.sync="formShow"
:close-on-click-modal="false"
:close-on-press-escape="false"
:title="formTitle"
:width="editParamsDiv ? '1100px' : '850px'"
top="5vh"
class="dialog-h"
@closed="handleClose"
>
<edit-form
v-if="formShow"
ref="editForm"
:idName="idName"
:formId="formId"
:formType="formType"
:infoUrl="infoUrl"
:addUrl="addUrl"
:editUrl="editUrl"
:editParams="editParams"
:editParamsDiv="editParamsDiv"
:editElseRules="editElseRules"
:editFixedParams="editFixedParams"
:formBtnFixed="formBtnFixed"
:editConfig="editConfig"
@close="handleClose"
@afterEdit="handleEditSuccess"
>
<template v-slot:bottomSup="{ id, formType, info }">
<slot
name="editBottomSup"
v-bind:id="id"
v-bind:formType="formType"
v-bind:info="info"
></slot>
</template>
<template v-slot:operateSup="{ id, formType, info }">
<slot
name="editOperateSup"
v-bind:id="id"
v-bind:formType="formType"
v-bind:info="info"
></slot>
</template>
</edit-form>
</el-dialog>
</div>
</template>
<script>
import { requestPost, requestGet } from "@/js/dai/request";
import { mapGetters } from "vuex";
import axios from "axios";
import editForm from "./cpts/edit";
import nextTick from "dai-js/tools/nextTick";
export default {
components: { editForm },
props: {
searchParams: {
type: Array,
default: () => [],
},
searchUrl: {
type: String,
default: "",
},
searchFixedParams: {
type: Object,
default: () => ({}),
},
tableParams: {
type: Array,
default: () => [],
},
tableUrl: {
type: String,
default: "",
},
addUrl: {
type: String,
default: "",
},
editUrl: {
type: String,
default: "",
},
delUrl: {
type: String,
default: "",
},
delMultipleUrl: {
type: String,
default: "",
},
infoUrl: {
type: String,
default: "",
},
exportUrl: {
type: String,
default: "",
},
qrCodeExportUrl: {
type: String,
default: "",
},
importUrl: {
type: String,
default: "",
},
mubanUrl: {
type: String,
default: "",
},
infoAuth: {
type: Function,
default: () => true,
},
editAuth: {
type: Function,
default: () => true,
},
editBtnName: {
type: Function,
default: () => "修改",
},
delAuth: {
type: Function,
default: () => true,
},
editParams: {
type: Array,
default: () => [],
},
editElseRules: {
type: Object,
default: () => ({}),
},
editConfig: {
type: Object,
default: () => ({}),
},
editFixedParams: {
type: Object,
default: () => ({}),
},
editParamsDiv: {
type: Number,
default: 0,
},
idName: {
type: String,
default: "id",
},
formBtnFixed: {
type: Boolean,
default: true,
},
operateCol: {
type: Boolean,
default: true,
},
cookTableData: {
type: Function,
default: (val) => val,
},
},
data() {
return {
tableData: [],
loadInfo: "",
pageNo: 1,
pageSize: window.localStorage.getItem("pageSize") || 20,
total: 1,
formId: "",
formShow: false,
formTitle: "详情",
formType: "", // 列表list 新增add 修改edit 详情info
ref_search_height: 100,
multipleSelection: [],
};
},
computed: {
maxTableHeight() {
const { ref_search_height } = this;
return this.$store.state.inIframe
? this.clientHeight -
ref_search_height -
265 +
this.iframeHeight
: this.clientHeight - ref_search_height - 265;
},
...mapGetters(["clientHeight", "iframeHeight"]),
},
watch: {},
async mounted() {
console.log(this.$store.state);
this.user = this.$store.state.user;
this.agencyId = this.user.agencyId;
this.iniSearchData();
this.getTableData();
await nextTick(100);
this.computeSearchHeight();
},
activated() {
console.log("-------------activated");
this.$refs["ref_table"].doLayout();
},
methods: {
handleSelectionChange(val) {
console.log(val);
this.multipleSelection = val;
},
computeSearchHeight() {
this.ref_search_height = this.$refs["ref_search"].clientHeight;
console.log(this.$refs["ref_search"]);
console.log(this.ref_search_height);
},
iniSearchData() {
const { searchParams } = this;
searchParams.forEach((item, index) => {
if (item.type == "select" || item.type == "cascader") {
if (item.optionUrl) {
if (item.optionUrlMethod == "get") {
this.getFmOptionsGet(
index,
item.optionUrl,
item.optionUrlParams || {},
item.optionCook || null
);
} else {
this.getFmOptions(
index,
item.optionUrl,
item.optionUrlParams || {},
item.optionCook || null
);
}
}
}
});
},
async getFmOptions(index, url, params, cookFn) {
const { data, code, msg } = await requestPost(url, {
...params,
});
if (code === 0) {
this.searchParams[index].optionList =
typeof cookFn == "function" ? cookFn(data) : data || [];
} else {
this.$message.error("请求检索基础数据失败!");
}
},
async getFmOptionsGet(index, url, params, cookFn) {
const { data, code, msg } = await requestGet(url, {
...params,
});
if (code === 0) {
this.searchParams[index].optionList =
typeof cookFn == "function" ? cookFn(data) : data || [];
} else {
this.$message.error("请求检索基础数据失败!");
}
},
handleChangeCascader(vals, item) {
if (typeof item.handleChangeFn == "function") {
item.handleChangeFn(vals, item);
}
},
handleSearch(val) {
this.pageNo = 1;
this.getTableData();
},
beforeExcelUpload(file) {
console.log("file", file);
const isType = file.type === "application/vnd.ms-excel";
const isTypeComputer =
file.type ===
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
const fileType = isType || isTypeComputer;
const isLt1M = file.size / 1024 / 1024 < 10;
if (!fileType) {
this.$message.error("上传文件只能是xls/xlsx格式!");
}
if (!isLt1M) {
this.$message.error("上传文件大小不能超过 10MB!");
}
return fileType && isLt1M;
},
async uploadHttpRequest(file) {
let { importUrl: url } = this;
if (!url) return;
this.$message({
showClose: true,
message: "导入中,请到系统管理-导入记录中查看进度",
duration: 0,
});
const formData = new FormData(); //FormData对象,添加参数只能通过append('key', value)的形式添加
formData.append("file", file.file); //添加文件对象
await this.$http
.post(url, formData)
.then((res) => {
console.log("res-up", res);
if (res.data.code == 0 && res.data.msg == "success") {
// this.$message.success('导入成功')
this.getTableData();
this.$refs.upload.clearFiles();
} else this.$message.error(res.data.msg);
})
.catch((err) => {
console.log("失败", err);
file.onError(); //上传失败的文件会从文件列表中删除
// this.$message.error('导入失败')
});
},
async handleExportModule() {
let { mubanUrl: url } = this;
if (!url) return;
await this.$http({
method: "POST",
url,
responseType: "blob",
data: {},
})
.then((res) => {
// this.download(res.data, title + '.xls')
if (res.headers["content-disposition"]) {
let fileName = window.decodeURI(
res.headers["content-disposition"]
.split(";")[1]
.split("=")[1]
);
console.log("filename", fileName);
let blob = new Blob([res.data], {
type: "application/vnd.ms-excel",
});
var url = window.URL.createObjectURL(blob);
var aLink = document.createElement("a");
aLink.style.display = "none";
aLink.href = url;
aLink.setAttribute("download", fileName);
document.body.appendChild(aLink);
aLink.click();
document.body.removeChild(aLink); //下载完成移除元素
window.URL.revokeObjectURL(url); //释放掉blob对象
} else this.$message.error("下载失败");
})
.catch((err) => {
console.log("err", err);
return this.$message.error("网络错误");
});
},
async handleExport() {
const { exportUrl: url } = this;
if (!url) return;
const { pageSize, pageNo } = this;
axios({
url: window.SITE_CONFIG["apiURL"] + url,
method: "post",
data: {
pageSize,
pageNo,
...this.computeFmData(),
},
responseType: "blob",
})
.then((res) => {
let fileName = window.decodeURI(
res.headers["content-disposition"]
.split(";")[1]
.split("=")[1]
);
console.log("filename", fileName);
let blob = new Blob([res.data], {
type: "application/vnd.ms-excel",
});
var url = window.URL.createObjectURL(blob);
var aLink = document.createElement("a");
aLink.style.display = "none";
aLink.href = url;
aLink.setAttribute("download", fileName);
document.body.appendChild(aLink);
aLink.click();
document.body.removeChild(aLink); //下载完成移除元素
window.URL.revokeObjectURL(url); //释放掉blob对象
})
.catch((err) => {
console.log("获取导出情失败", err);
return this.$message.error("网络错误");
});
},
async handleExportQrcode() {
const { qrCodeExportUrl: url } = this;
if (!url) return;
const { pageSize, pageNo } = this;
axios({
url: window.SITE_CONFIG["apiURL"] + url,
method: "post",
data: {
pageSize,
pageNo,
...this.computeFmData(),
},
responseType: "blob",
})
.then((res) => {
let fileName = window.decodeURI(
res.headers["content-disposition"]
.split(";")[1]
.split("=")[1]
);
console.log("filename", fileName);
let blob = new Blob([res.data], {
type: "application/vnd.ms-excel",
});
var url = window.URL.createObjectURL(blob);
var aLink = document.createElement("a");
aLink.style.display = "none";
aLink.href = url;
aLink.setAttribute("download", fileName);
document.body.appendChild(aLink);
aLink.click();
document.body.removeChild(aLink); //下载完成移除元素
window.URL.revokeObjectURL(url); //释放掉blob对象
})
.catch((err) => {
console.log("获取导出情失败", err);
return this.$message.error("网络错误");
});
},
handleAdd() {
this.formType = "add";
this.formTitle = "新增";
this.formShow = true;
},
handleWatch(row) {
const { idName } = this;
this.formType = "watch";
this.formId = row[idName];
this.formTitle = "查看";
this.formShow = true;
},
handleEdit(row) {
const { idName } = this;
this.formType = "edit";
this.formId = row[idName];
this.formTitle = "修改";
this.formShow = true;
},
handleClose() {
this.formShow = false;
this.getTableData();
},
handleEditSuccess() {
this.handleClose();
// this.getTableData();
},
async handleDeleteMultiple() {
let { delMultipleUrl: url } = this;
if (!url) return;
const { multipleSelection, idName } = this;
const { data, code, msg } = await requestPost(url, [
...multipleSelection.map((item) => item[idName]),
]);
if (code === 0) {
this.$message.success("批量删除成功!");
this.getTableData();
} else {
this.$message.error("操作失败!");
}
},
async handleDelete(rowData, rowIndex) {
console.log(rowData, rowIndex);
let { delUrl: url } = this;
if (!url) return;
const { tableData, idName } = this;
const idValue = tableData[rowIndex][idName];
let param = {
[idName]: idValue,
};
if (url.endsWith("/")) {
url += idValue;
}
if (url.endsWith("批量")) {
url = url.slice(0, -2);
param = [idValue];
}
const { data, code, msg } = await requestPost(url, param);
if (code === 0) {
this.$message.success("删除成功!");
this.getTableData();
} else {
this.$message.error("操作失败!");
}
},
computeFmData() {
let fmData = {};
this.searchParams.forEach((item) => {
fmData[item.keyName] = item.value;
if (item.supValues) {
item.supValues.forEach((value, index) => {
fmData[item.supKeys[index]] = value;
});
}
});
return {...fmData, ...this.searchFixedParams};
},
refresh() {
this.getTableData();
},
async getTableData() {
this.loadInfo = "数据加载中";
let { tableUrl: url } = this;
if (!url) return;
let req = requestPost;
if (url.startsWith("【GET】")) {
url = url.substr(5);
req = requestGet;
}
const { pageSize, pageNo } = this;
const { data, code, msg } = await req(url, {
pageSize,
pageNo,
...this.computeFmData(),
});
if (code === 0) {
let total = 0,
list = [];
if (Array.isArray(data)) {
list = data;
} else if ((data.total || data.count) && data.list) {
list = data.list || [];
total = data.total || data.count;
} else if (typeof data == "object") {
let ks = Object.keys(data);
let totalKey =
ks.find((k) => k.indexOf("ount") != -1) ||
ks.find((k) => k.indexOf("otal") != -1);
let listKey = ks.find((k) => k.indexOf("ist") != -1);
if (totalKey && listKey) {
total = data[totalKey];
list = data[listKey] || [];
}
}
this.total = total;
this.tableData = this.cookTableData(list);
if (this.tableData.length === 0) {
this.loadInfo = "暂无数据";
} else {
this.loadInfo = "";
}
} else {
this.$message.error(msg);
}
},
handleSizeChange(val) {
this.pageSize = val;
window.localStorage.setItem("pageSize", val);
this.getTableData();
},
handleCurrentChange(val) {
this.pageNo = val;
this.getTableData();
},
resetSearch() {
console.log("----------------resetSearch", this.searchParams);
this.searchParams.forEach((item) => {
if (typeof item.value == "string") {
item.value = "";
} else if (Array.isArray(item.value)) {
item.value = [];
}
if (item.supValues) {
item.supValues = item.supValues.map((value, index) => {
if (typeof value == "string") {
return "";
} else if (Array.isArray(value)) {
return [];
}
return value;
});
}
});
},
},
};
</script>
<style lang="scss" scoped>
@import "@/assets/scss/buttonstyle.scss";
@import "@/assets/scss/modules/management/list-main.scss";
// @import "@/assets/scss/modules/shequzhili/event-info.scss";
</style>