城阳pc工作端前端代码
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.

836 lines
25 KiB

<template>
<div class="g-main">
<div v-show="true">
<div class="m-search"
3 years ago
ref="ref_search">
<section :class="
showSercahStatus
? 'm-form-box-height-auto'
: 'm-form-box-height'
">
<el-form :inline="true"
3 years ago
ref="ref_searchform"
label-width="100px">
<div>
3 years ago
<el-form-item v-for="item in searchParams"
:key="'serach' + item.keyName"
:label="item.field"
:prop="item.keyName">
<template v-if="item.type == 'input'">
3 years ago
<el-input v-model="item.value"
class="u-item-width-normal"
3 years ago
size="small"
clearable
:placeholder="item.placeholder || '请输入'">
</el-input>
</template>
<template v-else-if="item.type == 'select'">
3 years ago
<el-select v-model="item.value"
:placeholder="item.placeholder || '请选择'"
size="small"
class="u-item-width-normal"
3 years ago
clearable
: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'">
3 years ago
<el-cascader v-model="item.value"
:placeholder="item.placeholder || '请选择'"
:options="item.optionList"
:props="item.optionProps"
:show-all-levels="false"
class="u-item-width-normal"
3 years ago
size="small"
clearable
@change="(e) => handleChangeCascader(e, item)">
</el-cascader>
</template>
3 years ago
<template v-if="item.type == 'date-range'">
3 years ago
<el-date-picker v-model="item.supValues[0]"
type="date"
placeholder="开始时间"
value-format="yyyy-MM-dd"
class="u-item-width-daterange"
3 years ago
clearable>
3 years ago
</el-date-picker>
<span class="u-data-tag"></span>
3 years ago
<el-date-picker v-model="item.supValues[1]"
class="u-item-width-daterange u-data-tag"
3 years ago
type="date"
placeholder="结束时间"
value-format="yyyy-MM-dd"
clearable>
3 years ago
</el-date-picker>
</template>
</el-form-item>
</div>
</el-form>
</section>
<el-row>
<el-col :span="24" align="right">
<el-button style="margin-left: 30px;"
3 years ago
size="small"
class="diy-button--add"
3 years ago
@click="handleSearch">查询</el-button>
<el-button style="margin-left: 10px;"
3 years ago
size="small"
class="diy-button--white"
3 years ago
@click="resetSearch">重置</el-button>
<el-button v-if="heightBtn"
type="text"
size="small"
style="margin-left: 10px"
class="f-right5"
@click="showSercahStatus = !showSercahStatus">
<i :class="
showSercahStatus
? 'el-icon-arrow-up'
: 'el-icon-arrow-down'
"></i>
{{ showSercahStatus ? "收起" : "展开" }}
</el-button>
</el-col>
</el-row>
</div>
<div class="m-table"
3 years ago
:style="{ height: maxTableHeight + 130 + 'px' }">
<div class="div_btn">
3 years ago
<el-button class="diy-button--add"
v-if="addUrl"
size="small"
@click="handleAdd">新增</el-button>
<el-button v-if="mubanUrl"
:class="addUrl?'diy-button--white':'diy-button--add'"
3 years ago
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="mubanUrl?'diy-button--add':'diy-button--white'" style="margin-left:10px">导入</el-button>
</el-upload>
3 years ago
<el-button v-if="exportUrl"
@click="handleExport"
:class="importUrl?'diy-button--white':'diy-button--add'"
size="small" style="margin-left:10px">导出</el-button>
3 years ago
<el-button v-if="qrCodeExportUrl"
@click="handleExportQrcode"
:class="exportUrl?'diy-button--add':'diy-button--white'"
3 years ago
size="small">导出员工登记码</el-button>
<el-button v-if="delMultipleUrl"
size="small"
@click="handleDeleteMultiple">批量删除</el-button>
<slot name="listBtn"
v-bind:multipleSelection="multipleSelection"></slot>
</div>
<!--" -->
3 years ago
<el-table ref="ref_table"
:data="tableData"
border
class="table"
style="width: 100%;margin-top: 16px;"
3 years ago
: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>
3 years ago
<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>
3 years ago
<el-table-column v-if="operateCol"
fixed="right"
label="操作"
align="center"
width="200">
<template slot-scope="scope">
3 years ago
<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>
3 years ago
<slot name="listBtnSup"
v-bind:item="scope.row"></slot>
</template>
</el-table-column>
</el-table>
<div>
3 years ago
<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>
<!-- 修改弹出框 -->
3 years ago
<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 }">
3 years ago
<slot name="editBottomSup"
v-bind:id="id"
v-bind:formType="formType"
v-bind:info="info"></slot>
</template>
<template v-slot:operateSup="{ id, formType, info }">
3 years ago
<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 } 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: "",
},
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: "",
},
3 years ago
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,
3 years ago
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,
},
heightBtn:{
type: Boolean,
default: false,
},
showSercahStatus:{
type: Boolean,
default: false,
},
},
3 years ago
data () {
return {
tableData: [],
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: {
3 years ago
maxTableHeight () {
const { ref_search_height } = this;
return this.$store.state.inIframe
? this.clientHeight - ref_search_height - 270 + this.iframeHeight
: this.clientHeight - ref_search_height - 270;
},
...mapGetters(["clientHeight", "iframeHeight"]),
},
watch: {},
3 years ago
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();
},
3 years ago
activated () {
console.log("-------------activated");
this.$refs["ref_table"].doLayout();
},
methods: {
3 years ago
handleSelectionChange (val) {
console.log(val);
this.multipleSelection = val;
},
3 years ago
computeSearchHeight () {
this.ref_search_height = this.$refs["ref_search"].clientHeight;
console.log(this.$refs["ref_search"]);
console.log(this.ref_search_height);
},
3 years ago
iniSearchData () {
const { searchParams } = this;
searchParams.forEach((item, index) => {
if (item.type == "select" || item.type == "cascader") {
if (item.optionUrl) {
this.getFmOptions(
index,
item.optionUrl,
item.optionUrlParams || {},
item.optionCook || null
);
}
}
});
},
3 years ago
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("请求检索基础数据失败!");
}
},
3 years ago
handleChangeCascader (vals, item) {
if (typeof item.handleChangeFn == "function") {
item.handleChangeFn(vals, item);
}
},
3 years ago
handleSearch (val) {
this.pageNo = 1;
this.getTableData();
},
3 years ago
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;
},
3 years ago
async uploadHttpRequest (file) {
let { importUrl: url } = this;
if (!url) return;
this.$message({
showClose: true,
dangerouslyUseHTMLString: true,
message: "导入中,请到系统管理-<a id='clickA' style='cursor: pointer;'>导入记录</a>中查看进度",
duration: 3000
});
let than = this
document.getElementById('clickA').addEventListener('click',function(){
than.$router.replace('/main/importRecord-index');
})
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('导入失败')
});
},
3 years ago
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("网络错误");
});
},
3 years ago
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("网络错误");
});
},
3 years ago
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("网络错误");
});
},
3 years ago
handleAdd () {
this.formType = "add";
this.formTitle = "新增";
this.formShow = true;
},
3 years ago
handleWatch (row) {
const { idName } = this;
this.formType = "watch";
this.formId = row[idName];
this.formTitle = "查看";
this.formShow = true;
},
3 years ago
handleEdit (row) {
const { idName } = this;
this.formType = "edit";
this.formId = row[idName];
this.formTitle = "修改";
this.formShow = true;
},
3 years ago
handleClose () {
this.formShow = false;
3 years ago
this.getTableData();
},
3 years ago
handleEditSuccess () {
this.handleClose();
3 years ago
// this.getTableData();
},
3 years ago
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("操作失败!");
}
},
3 years ago
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("操作失败!");
}
},
3 years ago
computeFmData () {
let fmData = {};
this.searchParams.forEach((item) => {
fmData[item.keyName] = item.value;
3 years ago
if (item.supValues) {
item.supValues.forEach((value, index) => {
fmData[item.supKeys[index]] = value;
});
}
});
return fmData;
},
3 years ago
refresh () {
this.getTableData();
},
3 years ago
async getTableData () {
const { tableUrl: url } = this;
if (!url) return;
const { pageSize, pageNo } = this;
const { data, code, msg } = await requestPost(url, {
pageSize,
pageNo,
...this.computeFmData(),
});
if (code === 0) {
this.total = data.total || 0;
this.tableData = data.list ? this.cookTableData(data.list) : [];
} else {
this.$message.error(msg);
}
},
3 years ago
handleSizeChange (val) {
this.pageSize = val;
window.localStorage.setItem("pageSize", val);
this.getTableData();
},
3 years ago
handleCurrentChange (val) {
this.pageNo = val;
this.getTableData();
},
3 years ago
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>