Browse Source

智能报表。。

luckysheet-xiaowang-Intelligen
是小王呀\24601 6 months ago
parent
commit
b3ee675567
  1. 89
      src/views/modules/base/smartExcel/cpts/export-record.vue
  2. 361
      src/views/modules/base/smartExcel/cpts/export-view.vue
  3. 333
      src/views/modules/base/smartExcel/report.vue

89
src/views/modules/base/smartExcel/cpts/export-record.vue

@ -0,0 +1,89 @@
<template>
<div class="">
<el-table :data="tableData" border class="m-table-item">
<el-table-column label="序号" fixed="left" type="index" align="center" width="50" />
<el-table-column prop="taskTitle" label="导出报表" min-width="140" align="center" :show-overflow-tooltip="true" />
<el-table-column prop="totalNum" label="操作人" align="center" :show-overflow-tooltip="true" width="100">
</el-table-column>
<el-table-column prop="agencyName" align="center" label="操作时间" :show-overflow-tooltip="true">
</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>
</template>
<script>
import { requestPost, requestGet } from "@/js/dai/request";
import { mapGetters } from 'vuex'
export default {
data() {
return {
pageNo: 1,
pageSize: window.localStorage.getItem("pageSize") || 20,
taskId:"",
tableData:[],
total: 1,
};
},
created() {},
mounted() {
this.getTableData()
},
methods: {
handleSizeChange(val) {
this.pageSize = val;
window.localStorage.setItem("pageSize", val);
this.getTableData();
},
handleCurrentChange(val) {
this.pageNo = val;
this.getTableData();
},
async getTableData() {
const url = "/actual/base/communityOneTablePublish/page";
const { pageSize, pageNo, formData } = this;
const { data, code, msg } = await requestGet(url, {
pageSize,
pageNo,
...formData
});
if (code === 0) {
this.total = data.total || 0;
this.tableData = data.list
? data.list.map((item) => {
return item;
})
: [];
} else {
this.$message.error(msg);
}
},
},
components:{
},
computed:{
tableHeight() {
return (this.clientHeight - 140) + 'px'
},
...mapGetters(['clientHeight', 'resolution']),
},
props: {
taskId: {
type: String,
default: ""
},
},
watch: {},
}
</script>
<style lang='scss' scoped>
@import "@/assets/scss/pages/resiInfo.scss";
@import "@/assets/scss/modules/management/list-main.scss";
</style>

361
src/views/modules/base/smartExcel/cpts/export-view.vue

@ -0,0 +1,361 @@
<template>
<div class='flex'>
<div :class="['flex', 'flex-y', 'flex1', sheetTotal ? 'luckysheet-wrap' : 'luckysheet-wrap-all']">
<div class="top_btn flex flex-end">
<div>
<el-button type="text" round @click="handelClickBack"
icon="el-icon-back">返回</el-button>
<el-button type="warning" @click="handleClickInspect">上传统计模板
</el-button>
<el-button type="success" @click="onClickUplond()"> 数据列表导出</el-button>
</div>
<div>
<el-button type="danger"
@click="handleClickCurrencyEvent('rejected')"> 取消</el-button>
<el-button type="primary"
@click="handleClickCurrencyEvent('submit')"> 提交</el-button>
</div>
</div>
<div id="luckysheet"></div>
</div>
<el-dialog title="上传共享数据" v-if="showUploadData" :visible.sync="showUploadData" width="60%"
:close-on-click-modal="false">
<excelUploadData @handleUploadDataHide="handleUploadDataHide" :currentTable="currentTable"
:btnLoading="btnLoading">
</excelUploadData>
</el-dialog>
</div>
</template>
<script>
import excelUploadData from './excel-upload-data.vue';
import LuckyExcel from 'luckyexcel';
import options from "@/utils/luckysheetConfig.js";
import { mapGetters } from 'vuex'
import { requestPost, requestGet } from "@/js/dai/request";
import nextTick from "dai-js/tools/nextTick";
export default {
data() {
return {
showUploadData: false,
menuList: [],
menuActive: 0,
socket: null,
currentTable: null,
currentId: '',
btnLoading: false,
};
},
props: {
workbookId: {
type: String,
default: ''
},
pageType: {
type: String,
default: ''
},
sheetTotal: {
type: Boolean,
default: false
},
infoObj: {
type: Object,
default: () => { }
},
mergeObj: {
type: Object,
default: () => { }
},
userId: {
type: String,
default: ''
},
taskStateName: {
type: String,
default: ""
},
},
computed: {
tableHeight() {
return (this.clientHeight - 140) + 'px'
},
...mapGetters(['clientHeight', 'resolution']),
},
async created() {
},
watch: {},
async mounted() {
console.log( "dskjlfsdklf");
// if (this.sheetTotal) {
// this.currentId = this.workbookId;
// this.loadWorkBook()
// } else {
// this.getTaskList()
// }
this.loadWorkBook()
},
methods: {
async getTaskList() {
let parm = {
taskId: this.workbookId,//Id
pageNo: 1,
pageSize: 1000,
userId: this.userId
}
let { data, code, msg } = await requestGet('/actual/base/communityOneTablePeriodPublish/myPageList', parm)
if (code === 0) {
this.menuList = data.list;
this.currentId = this.menuList[0].subWorkBookId
this.loadWorkBook()
}
},
async handleClickInspect() {
// celldatalist
const list = luckysheet.getAllSheets()[0].celldata.map(item => ({
r: item.r,
c: item.c,
v: item.v.v || ''
}));
//
let { data, code, msg } = await requestPost('/actual/base/intelligentImportData/checkData', list);
if (code === 0) {
if (data && data.length > 0) {
for (const { r, c } of data) {
luckysheet.setCellFormat(r, c, 'bg', '#f5504a');
}
const findArr = this.findUniqueElements(luckysheet.getAllSheets()[0].celldata, data);
findArr.forEach(({ r, c, v }) => {
if (v.bg === "#f5504a") {
luckysheet.setCellFormat(r, c, 'bg', '#ffffff');
}
});
} else {
this.$message.success('没有找到异常');
}
}
},
findUniqueElements(A, B) {
// Brc
const bCombinations = new Set(B.map(item => `${item.r},${item.c}`));
// AB
return A.filter(item => !bCombinations.has(`${item.r},${item.c}`));
},
onClickUplond() {
this.showUploadData = true;
let list = luckysheet.getAllSheets()
this.currentTable = list.filter(item => item.status == '1')
},
async handleUploadDataHide(val) {
this.showUploadData = false;
luckysheet.insertRow(this.currentTable[0].data.length, 1)
const findLastNonNullIndex = (arr) => {
for (let i = arr.length - 1; i >= 0; i--) {
const subArray = arr[i];
// null
if (Array.isArray(subArray) && subArray.some(item => item !== null && item.v && item.v !== null && item.v !== '')) {
return i; //
}
}
return -1; // -1
};
this.sheetR = findLastNonNullIndex(this.currentTable[0].data)
console.log(this.currentTable[0].data.length, val.length);
luckysheet.insertRow(this.currentTable[0].data.length, { number: val.length });
await nextTick(2000)
let newArray = val.map(obj => {
return Object.keys(obj).map(key => {
return { m: obj[key], "ct": { "fa": "General", "t": "g" }, v: obj[key] };
});
});
console.log(newArray, '处理后数据');
let bottomRightCorner = this.numberToLetter(Object.keys(val[0]).length)//
luckysheet.setRangeValue(newArray, {
range: `A${this.sheetR + 2}:${bottomRightCorner}${this.sheetR + val.length}`,
})
},
//
numberToLetter(num) {
let letter = '';
while (num > 0) {
num -= 1; // 0 1 -> 'A'2 -> 'B'...
letter = String.fromCharCode(num % 26 + 65) + letter; // 65 'A' Unicode
num = Math.floor(num / 26);
}
return letter;
},
loadWorkBook() {
window.luckysheet.destroy();
const { id } = this.$store.state.user;
options.gridKey = this.currentId;
options.allowUpdate = true;
options.container = 'luckysheet'
// options.loadUrl = `${process.env.VUE_APP_API_SERVER}/actual/base/luckySheet/workbook/load?workbookId=${this.currentId}`
// options.updateUrl = `${process.env.VUE_APP_SOCKET_SERVER}/actual/base/ws/luckysheet/${this.currentId}/${id}`
// options.loadSheetUrl = `${process.env.VUE_APP_API_SERVER}/actual/base/luckySheet/workbook/loadSheets`
window.luckysheet.create({
...options,
hook: {
cellEditBefore: this.handleCellEditBefore,
sheetCreateAfter: this.handleSheetCreateAfter,
},
});
},
handleSheetCreateAfter(e) {
console.log('setsheet', e);
},
handleClickMenu(i, val) {
this.menuActive = i;
this.currentId = val.subWorkBookId;
this.loadWorkBook()
},
handelClickBack() {
this.$emit('close')
},
//
async handleClickCurrencyEvent(val) {
const url = '/actual/base/communityOneTablePeriodPublish/update'
let parm = {
...this.infoObj
}
parm.taskState = val;
if (val === 'archived') {
this.workbookMerge()
}
const { data, code, msg } = await requestPost(url, parm)
if (code === 0) {
this.$message.success('操作成功')
} else {
console.log(msg);
}
},
async workbookMerge() {
const url = '/actual/base/luckySheet/workbook/merge'
let parm = {
sourceWorkbookId: this.mergeObj.subWorkBookId,
targetWorkbookId: this.mergeObj.workBookId
}
const { data, code, msg } = await requestPost(url, parm)
if (code === 0) {
console.log('合并成功');
}
},
},
components: {
excelUploadData
},
components: {
excelUploadData
},
beforeDestroy() {
this.$store.state.sidebarFold = false;
if (this.socket) {
this.socket.close();
}
},
};
</script>
<style lang="scss" scoped>
.el-card {
margin: 10px auto;
padding: 0 16px;
box-sizing: border-box;
width: calc(100% - 40px);
border: none;
}
.luckysheet-wrap {
margin: 10px;
padding: 0px;
z-index: 2;
width: calc(100vw - 400px);
height: calc(100vh - 250px);
}
.luckysheet-wrap-all {
margin: 10px;
padding: 0px;
z-index: 2;
width: calc(100vw - 100px);
height: calc(100vh - 250px);
}
#luckysheet {
width: 100%;
padding: 0px;
z-index: 2;
height: calc(100% - 80px);
margin: 10px;
}
.top_btn {
height: 60px;
width: 100%;
}
.upload-demo {
position: absolute;
z-index: 999999;
margin: 20px 0 0 22px;
}
.right-slider {
position: absolute;
z-index: 999999;
border: 1px solid #eeeeee;
box-shadow: -5px 0px 5px 0px rgba(0, 0, 0, 0.2);
background: #ffffff;
margin: 10px 0 0 22px;
right: 10px;
width: 36%;
height: calc(100% - 20px);
}
.el-header,
.el-footer {
text-align: left;
line-height: 40px;
padding-top: 0;
padding-bottom: 0;
}
.el-main {
text-align: left;
line-height: 40px;
padding-top: 0;
padding-bottom: 0;
}
.el-container {
display: flex;
height: 100%;
flex-direction: column;
}
.left_menu {
width: 240px;
.menu_item {
cursor: pointer;
padding: 10px 16px;
box-sizing: border-box;
margin-bottom: 5px;
background-color: #f2f8fd;
border-radius: 5px;
font-size: 14px;
}
.active {
color: #3989eb;
}
}
</style>

333
src/views/modules/base/smartExcel/report.vue

@ -0,0 +1,333 @@
<template>
<div class="g-main">
<div v-show="pageType == 'list'">
<div class="m-search">
<el-form :inline="true" :model="formData" ref="ref_searchform" :label-width="'100px'">
<div>
<el-form-item label="所属组织" prop="orgId">
<el-cascader class="u-item-width-normal" size="small" ref="myCascader" v-model.trim="formData.orgId"
:options="orgOptions" :props="orgOptionProps" :show-all-levels="false" @change="handleChangeAgency"
clearable></el-cascader>
</el-form-item>
<el-form-item label="报表名称" prop="taskTitle">
<el-input v-model.trim="formData.taskTitle" class="u-item-width-normal" size="small" clearable
placeholder="请输入">
</el-input>
</el-form-item>
<el-form-item label="创建人" prop="createdBy">
<el-select class="u-item-width-normal" v-model.trim="formData.createdBy" placeholder="请选择" size="small"
clearable :disabled="manager">
<el-option v-for="item in createdByArray" :key="item.staffId" :label="item.name" :value="item.staffId">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="创建时间" prop="startTime">
<el-date-picker v-model.trim="formData.startTime" :picker-options="startPickerOptions"
class="u-item-width-daterange" size="small" type="date" value-format="yyyy-MM-dd HH:mm:ss"
value="yyyy-MM-dd" placeholder="开始时间">
</el-date-picker>
<span class="u-data-tag"></span>
<el-date-picker v-model.trim="formData.endTime" :picker-options="endPickerOptions"
class="u-item-width-daterange u-data-tag" size="small" type="date" value-format="yyyy-MM-dd HH:mm:ss"
value="yyyy-MM-dd" placeholder="结束时间">
</el-date-picker>
</el-form-item>
<el-row>
<el-col :span="24" align="right">
<el-button style="margin-left: 30px" size="small" type="primary " @click="handleSearch">查询</el-button>
<el-button style="margin-left: 10px" size="small" class="diy-button--white"
@click="resetSearch">重置</el-button>
</el-col>
</el-row>
</div>
</el-form>
</div>
<div class="m-table">
<div class="div_btn">
<el-button size="small" type="primary " @click="handleAdd">新增报表</el-button>
</div>
<el-table :data="tableData" border class="m-table-item" style="width: 100%" :height="maxTableHeight">
<el-table-column label="序号" fixed="left" type="index" align="center" width="50" />
<el-table-column prop="taskTitle" label="报表名称" min-width="140" align="center" :show-overflow-tooltip="true" />
<el-table-column prop="totalNum" label="导出记录" align="center" :show-overflow-tooltip="true" width="100">
<template slot-scope="scope">
<el-button @click=" handleRecord(scope.row)" type="text" size="small">{{scope.row.totalNum}}</el-button>
</template>
</el-table-column>
<el-table-column prop="agencyName" align="center" label="所属组织" :show-overflow-tooltip="true">
</el-table-column>
<el-table-column prop="createByName" align="center" width="100" label="创建人" :show-overflow-tooltip="true">
</el-table-column>
<el-table-column prop="createdTime" align="center" width="140" :show-overflow-tooltip="true" label="创建时间">
</el-table-column>
<el-table-column fixed="right" label="操作" align="center" width="200px">
<template slot-scope="scope">
<el-button @click=" handleInfo(scope.row)" type="text" size="small">查看</el-button>
</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>
<div class="m-search" v-if="pageType=='add'">
<exportlView @close="close" ></exportlView>
</div>
<div v-if="showRecord">
<el-dialog title="导出记录" :visible.sync="showRecord" width="50%" :close-on-click-modal="false">
<export-record :showType="showRecord" :taskId="formData.taskId"></export-record>
</el-dialog>
</div>
</div>
</template>
<script>
import exportlView from "./cpts/export-view.vue";
import { requestPost, requestGet } from "@/js/dai/request";
import nextTick from "dai-js/tools/nextTick";
import { mapGetters } from "vuex";
import excelInfo from "./cpts/excel-info";
import excelAdd from "./cpts/excel-add";
import exportRecord from "./cpts/export-record";
export default {
components: { excelInfo, excelAdd,exportRecord,exportlView },
data() {
let endDisabledDate = (time) => {
//datareturn
let nowData = Date.now();
if (this.formData.startTime) {
let startTime = new Date(this.formData.startTime);
return (
time.getTime() > nowData ||
time.getTime() < startTime ||
time.getTime() === startTime
);
} else {
return time.getTime() > nowData;
}
};
let startDisabledDate = (time) => {
//datareturn
let nowData = Date.now();
return time.getTime() > nowData;
};
return {
showRecord:false,
task: "",
pageType: "list", // list add info
tableData: [],
formData: {
orgId: '',//Id
taskTitle: '',//
taskType: '',//
startTime: '',//
endTime: '',//
createdBy: ''//
},
pageNo: 1,
pageSize: window.localStorage.getItem("pageSize") || 20,
total: 1,
sarr: [],
endPickerOptions: {
disabledDate: endDisabledDate,
},
startPickerOptions: {
disabledDate: startDisabledDate,
},
searchH: 180,
createdByArray: [],
statusArray: [
{
label: '已完成',
value: 'resolved'
},
{
label: '已取消',
value: 'cancel',
},
{
label: '进行中',
value: 'deal',
}
],
manager: false
};
},
computed: {
maxTableHeight() {
const h = this.clientHeight - this.searchH - 275;
const _h = this.clientHeight - 275 - this.searchH;
return this.$store.state.inIframe ? h : _h;
},
...mapGetters(["clientHeight"]),
},
watch: {
},
async mounted() {
const user = this.$store.state.user;
await this.getStafflist()
if (user) {
if (user.roleList.findIndex(item => item === "manager") !== -1) {
this.manager = false;
} else {
this.manager = true;
this.formData.createdBy = this.createdByArray.find(item => item.mobile === user.phone).staffId
}
}
this.getTableData()
},
methods: {
close() {
this.pageType = "list"
},
handleRecord() {
this.showRecord="ture"
},
async handleCancel(item) {
let parms = {
id: item.id,
};
this.$confirm("取消之后无法恢复,确认取消?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(() => {
requestPost('/actual/base/communityOneTablePublish/cancelTask', parms).then(res => {
if (res.code == 0) {
this.pageNo = 1
this.getTableData()
}
})
})
.catch((err) => {
if (err == "cancel") {
}
});
},
async getStafflist() {
let parms = {
orgId: this.$store.state.user.agencyId,
orgType: 'agency',
pageNo: 1,
pageSize: 100,
};
let { data, code } = await requestPost('/data/aggregator/org/stafflist', parms)
if (code === 0) {
this.createdByArray = data.staffList;
}
},
handleShowPage() {
this.pageType = 'list';
this.getTableData()
},
handleAdd() {
this.pageType = 'add';
console.log("dsfdsf");
},
handleInfo(item) {
console.log(item, "dkljsfdlk");
this.task = item.id
this.pageType = 'info'
},
getLastItem(list, vals, key) {
let LIST = list || [];
for (let item of LIST) {
// console.log(item[key]);
for (let i of vals) {
if (item[key] === i) {
this.sarr.push(item);
} else {
this.getLastItem(item.subAgencyList, vals, key);
}
}
}
},
handleSizeChange(val) {
this.pageSize = val;
window.localStorage.setItem("pageSize", val);
this.getTableData();
},
handleCurrentChange(val) {
this.pageNo = val;
this.getTableData();
},
async getTableData() {
const url = "/actual/base/communityOneTablePublish/page";
const { pageSize, pageNo, formData } = this;
const { data, code, msg } = await requestGet(url, {
pageSize,
pageNo,
...formData
});
if (code === 0) {
this.total = data.total || 0;
this.tableData = data.list
? data.list.map((item) => {
return item;
})
: [];
} else {
this.$message.error(msg);
}
},
handleSearch() {
this.pageNo = 1;
this.getTableData();
},
async handleDel(item) {
let parms = {
id: item.id,
};
this.$confirm("删除之后无法恢复,确认删除?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(() => {
requestPost('/actual/base/communityOneTablePublish/delete', parms).then(res => {
if (res.code == 0) {
this.getTableData()
}
})
})
.catch((err) => {
if (err == "cancel") {
}
});
},
async resetSearch() {
this.$refs.ref_searchform.resetFields();
this.pageNo = 1;
const user = this.$store.state.user;
if (user) {
if (user.roleList.findIndex(item => item === "manager") !== -1) {
this.manager = false;
} else {
this.manager = true;
this.formData.createdBy = this.createdByArray.find(item => item.mobile === user.phone).staffId
}
}
this.getTableData();
},
},
};
</script>
<style lang="scss" scoped>
@import "@/assets/scss/modules/management/list-main.scss";
.m-search {
.u-item-width-normal {
width: 200px;
}
}
</style>
Loading…
Cancel
Save