Browse Source

Merge branch 'Luckysheet-mk' into luckysheet

luckysheet-xiaowang-Intelligen
mk 8 months ago
parent
commit
336b8028cd
  1. BIN
      public/test.xlsx
  2. BIN
      public/test1.xlsx
  3. 4
      src/App.vue
  4. 346
      src/views/modules/base/smartExcel/cpts/excel-add.vue
  5. 10
      src/views/modules/base/smartExcel/cpts/excel-summary.vue
  6. 102
      src/views/modules/base/smartExcel/cpts/excel-template-confirmation.vue
  7. 119
      src/views/modules/base/smartExcel/cpts/excel-view.vue
  8. 5
      src/views/modules/base/smartExcel/index.vue
  9. 1
      src/views/modules/shequzhili/eventOld/cpts/add.vue

BIN
public/test.xlsx

Binary file not shown.

BIN
public/test1.xlsx

Binary file not shown.

4
src/App.vue

@ -275,4 +275,8 @@ export default {
color: #fff;
}
}
input[aria-hidden=true]{
display: none !important;
}
</style>

346
src/views/modules/base/smartExcel/cpts/excel-add.vue

@ -1,36 +1,254 @@
<template>
<!-- 新建任务 -->
<div class=''>
<el-upload :headers="$getElUploadHeaders()" ref="upload" class="upload-btn" :action="uploadUlr" :limit="1"
:accept="'.xlsx'" :with-credentials="true" :show-file-list="false" :auto-upload="true"
:on-success="handleExcelSuccess" :before-upload="beforeExcelUpload">
<template #trigger>
<el-button type="primary">上传报表模板</el-button>
</template>
</el-upload>
<div class="g-add">
<div class='card' :style="{ height: tableHeight }">
<div class="flex title">
<h3>新建任务</h3>
<el-button type="text" round @click="handelClickBack" icon="el-icon-back">返回</el-button>
</div>
<el-form :model="form" label-width="120px" :rules="dataRule" ref="dataForm">
<el-form-item prop="theme" label="任务主题">
<el-input v-model="form.theme" placeholder="请输入内容" clearable class="cell-width-1"></el-input>
</el-form-item>
<el-form-item label="任务类型" prop="type">
<el-select v-model.trim="form.type" placeholder="请选择" size="small" clearable class="cell-width-1">
<el-option v-for="item in typeList" :key="item.value" :label="item.label" :value="item.value">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="任务周期" prop="cycle">
<el-radio-group v-model.trim="form.cycle" @change="handleChangeCycle">
<el-radio label="once">一次性</el-radio>
<el-radio label="week">每周</el-radio>
<!-- <el-radio label="halfAMonth">每半月</el-radio>
<el-radio label="month">每月</el-radio>
<el-radio label="quarter">每季度</el-radio> -->
</el-radio-group>
<span>说明当任务周期选择每周/每月/每半月/每季度时系统会于每个时间阶段的第一天自动创建阶段性子任务</span>
</el-form-item>
<el-form-item label="完成时限" prop="timeLimit" v-if="form.cycle">
<template v-if="form.cycle === 'once'">
<el-date-picker v-model="form.timeLimit" type="datetime" placeholder="选择日期时间">
</el-date-picker>
</template>
<template v-if="form.cycle === 'week'">
<el-select v-model.trim="form.week" placeholder="请选择" size="small" clearable
class="cell-width-1" style="margin-left: 10px;">
<el-option v-for="item in weekList" :key="item.value" :label="item.label"
:value="item.value">
</el-option>
</el-select>
<el-time-picker class="cell-width-1" v-model="form.timeLimit" placeholder="选择时间" style="margin-left: 10px;">
</el-time-picker>
</template>
</el-form-item>
<el-form-item label="分发人员" prop="distributionPersonnel">
<el-cascader class="u-item-width-normal" size="small" ref="myCascader" v-model="cascaderAgencyId"
@change="handleChangeAgency" :options="orgOptions" :props="orgOptionProps"
:show-all-levels="false" clearable></el-cascader>
<el-select v-model.trim="form.distributionPersonnel" placeholder="请选择" size="small" clearable
@remove-tag="removeTag" multiple class="cell-width-1" collapse-tags style="margin-left: 10px;"
@change="changeTag" c>
<el-option v-for="item in allStafflist" :key="item.value" :label="item.name"
:value="item.staffId">
</el-option>
</el-select>
</el-form-item>
<el-form-item :label="`已选(${selfTag.length})人`" v-if="selfTag.length != 0">
<div>
<el-tag v-for="tag in selfTag" :key="tag.staffId" closable @close="removeTag(tag)"
style="margin-right: 10px;">
<span> {{ tag.name }}</span>
</el-tag>
</div>
</el-form-item>
<el-form-item label="上传模板" prop="templateUrl">
<el-upload :headers="$getElUploadHeaders()" ref="upload" class="upload-btn" :action="uploadUlr"
v-if="!form.templateUrl" :limit="1" :accept="'.xlsx'" :with-credentials="true"
:show-file-list="false" :auto-upload="true" :on-success="handleExcelSuccess"
:before-upload="beforeExcelUpload">
<template #trigger>
<el-button type="primary">上传报表模板</el-button>
</template>
</el-upload>
<section v-else class="upload">
<img :src="require(`@/assets/images/index/Excel.png`)" alt="">
<span>{{ fileName }}</span>
<el-button type="text" @click="removeFile(file)" style="margin-left: 16px;"> 删除</el-button>
</section>
</el-form-item>
<el-form-item label="任务要求" prop="taskRequirements" style="display: block">
<el-input class="cell-width-2" type="textarea" maxlength="500" show-word-limit :rows="5"
placeholder="请输入事件内容,不超过500字" v-model.trim="form.taskRequirements"></el-input>
</el-form-item>
</el-form>
<div class="div-btn">
<el-button style="margin-left: 10px" size="small" class="diy-button--white" @click="handelClickBack">
</el-button>
<el-button style="margin-left: 20px" type="primary" size="small"
@click="handleClickSave">发布任务</el-button>
</div>
</div>
<div v-if="showTemplate">
<ExcelTemplateConfirmation :showTemplate="showTemplate" :fileUrl="fileUrl"/>
<ExcelTemplateConfirmation :showTemplate="showTemplate" :fileUrl="form.templateUrl" :fileName="fileName"
@handelHideTemplate="handelHideTemplate" @saveLuckysheetJson="getSheetJson" />
</div>
</div>
</template>
<script>
import ExcelTemplateConfirmation from './excel-template-confirmation.vue';
import { mapGetters } from 'vuex'
import { requestPost } from "@/js/dai/request";
export default {
data() {
return {
uploadUlr:window.SITE_CONFIG["apiURL"] +
cascaderAgencyId: [],
fileName: '',
orgOptions: [],
orgOptionProps: {
// multiple: false,
value: 'agencyId',
label: 'agencyName',
children: 'subAgencyList',
checkStrictly: true
}, uploadUlr: window.SITE_CONFIG["apiURL"] +
"/oss/file/upload",
fileUrl:'',
showTemplate:false
showTemplate: false,
form: {
theme: '',//
type: '1',//
cycle: 'once',//
timeLimit: '',//
week: '',//
distributionPersonnel: [],//
templateUrl: '',//
taskRequirements: '',//
},
dataRule: {
theme: [{ required: true, message: "任务主题不能为空", trigger: "blur" },],
cycle: [{ required: 'true', message: '任务周期不能为空', trigger: 'blur' }],
distributionPersonnel: [{ required: 'true', message: '分发人员不能为空', trigger: 'blur' }],
templateUrl: [{ required: 'true', message: '模板不能为空', trigger: 'blur' }],
timeLimit: [{ required: 'true', message: '完成时限不能为空', trigger: 'blur' }],
},
typeList: [
{
label: '数据提报',
value: '1'
}
],
weekList: [
{
label: '每周一',
value: '1'
},
{
label: '每周二',
value: '2'
},
{
label: '每周三',
value: '3'
},
{
label: '每周四',
value: '4'
},
{
label: '每周五',
value: '5'
},
{
label: '每周六',
value: '6'
},
{
label: '每周日',
value: '7'
}
],
// workPersonnelList: [],
allStafflist: [],
selfTag: [],
sarr: [],
agencyId: '',
agencylevel: ''
};
},
created() { },
methods: {
async handleChangeAgency(val) {
this.sarr = []
this.getLastItem(
this.orgOptions,
val,
"agencyId"
);
this.agencylevel = this.sarr[this.sarr.length - 1].level;
this.agencyId = this.sarr[this.sarr.length - 1].agencyId;
this.getStafflist()
},
getLastItem(list, vals, key) {
let LIST = list || [];
for (let item of LIST) {
for (let i of vals) {
if (item[key] === i) {
this.sarr.push(item);
} else {
this.getLastItem(item.subAgencyList, vals, key);
}
}
}
},
getStafflist() {
let parms = {
orgId: this.agencyId,
orgType: 'agency',
pageNo: 1,
pageSize: 100,
};
this.$http.post("data/aggregator/org/stafflist", parms).then((resp) => {
// this.workPersonnelList = resp.data.data.staffList;
if (resp.data.data.staffList) {
this.allStafflist = this.allStafflist.concat(resp.data.data.staffList)
console.log(this.allStafflist);
}
});
},
getOrgTreeList() {
this.$http
.post('/gov/org/customeragency/agencygridtree', {})
.then(({ data: res }) => {
if (res.code !== 0) {
return this.$message.error(res.msg)
} else {
this.orgOptions = []
this.orgOptions.push(res.data)
}
})
.catch(() => {
return this.$message.error('网络错误')
})
},
handelClickBack() {
this.$emit('handleShowPage')
},
handelHideTemplate() {
this.showTemplate = false;
this.fileUrl = '';
},
getSheetJson(val) {
this.luckysheetJson = val.sheets;
this.showTemplate = false;
},
handleExcelSuccess(e) {
if(e.code === 0){
if (e.code === 0) {
this.showTemplate = true;
this.fileUrl = e.data.url
this.form.templateUrl = e.data.url
}
},
beforeExcelUpload(file) {
@ -47,6 +265,7 @@ export default {
if (!isLt1M) {
this.$message.error("上传文件大小不能超过 10MB!");
}
this.fileName = file.name
return fileType && isLt1M;
},
handleFileChange(file, newFileList) {
@ -63,12 +282,105 @@ export default {
return;
}
},
removeTag(val) {
const valueToRemove = val.staffId || val[0];
this.form.distributionPersonnel = this.form.distributionPersonnel.filter(item => item != valueToRemove);
this.selfTag = this.workPersonnelList.filter(item => this.form.distributionPersonnel.includes(item.staffId));
},
changeTag() {
this.selfTag = this.allStafflist.filter(item => this.form.distributionPersonnel.includes(item.staffId));
},
handleChangeCycle(val){
if(val === 'once'){
this.form.week = '';
this.form.timeLimit = '';
}else{
this.form.timeLimit = '';
}
},
handleClickSave() {
console.log(this.form, 'addForm');
this.$refs['dataForm'].validate(valid => {
if (valid) {
this.saveLuckysheet()
}
})
},
async saveLuckysheet() {
delete this.luckysheetJson[0].data
console.log(this.luckysheetJson);
const { data, code, msg } = await requestPost(`/actual/base/luckySheet/workbook/createByJson?fileName=${this.fileName}`, this.luckysheetJson)
if (code === 0) {
console.log(data, '新建成功');
} else {
console.log(msg);
}
},
removeFile() {
this.form.templateUrl = '';
this.fileName = '';
this.luckysheetJson = {}
},
},
mounted() {
this.getOrgTreeList()
},
components: { ExcelTemplateConfirmation },
computed: {
tableHeight() {
return (this.clientHeight - 140) + 'px'
},
...mapGetters(['clientHeight', 'resolution']),
},
components: {ExcelTemplateConfirmation},
computed: {},
watch: {},
}
</script>
<style lang='scss' scoped></style>
<style lang='scss' scoped>
@import "@/assets/scss/modules/shequzhili/event-info.scss";
.title {
position: relative;
margin: 0 16px;
&::after {
content: '';
width: 4px;
height: 16px;
background: #5493ff;
display: block;
position: absolute;
top: 16px;
left: -16px;
}
}
.card {
background-color: #ffffff;
border-radius: 5px;
margin: 10px 16px;
}
.div-btn {
position: absolute;
bottom: 30px;
right: 30px;
}
.cell-width-2 {
width: 500px;
}
.upload {
display: flex;
align-items: center;
img {
width: 50px;
height: 50px;
margin-right: 16px;
}
}
</style>

10
src/views/modules/base/smartExcel/cpts/excel-summary.vue

@ -12,7 +12,7 @@
</div>
<h3 class="title">提报的文件</h3>
<div class="flex-wrap flex">
<div class="item flex flex-y flex-center-deputy" v-for="(item, index) in list" @click="handleClickShowView" :key="index">
<div class="item flex flex-y flex-center-deputy" v-for="(item, index) in list" @click="handleClickShowView('1876571135966158850')" :key="index">
<img :src="require(`@/assets/images/index/Excel.png`)" alt="">
<div class="agencyName">{{ item.title }}周期更新表</div>
<div>{{ item.state }}</div>
@ -20,7 +20,7 @@
</div>
</div>
<div v-if="showView">
<excel-view @close="close"></excel-view>
<excel-view @close="close" :workbookId="workbookId"></excel-view>
</div>
</div>
</template>
@ -66,7 +66,8 @@ export default {
title: '嘉定山社区',
state: '未提交'
},
]
],
workbookId:''
};
},
created() { },
@ -77,9 +78,10 @@ export default {
handleClickBack() {
this.$emit('close')
},
handleClickShowView(){
handleClickShowView(val){
this.$store.state.sidebarFold = true;
this.showView = true;
this.workbookId = val
},
},
components: { excelView },

102
src/views/modules/base/smartExcel/cpts/excel-template-confirmation.vue

@ -1,11 +1,11 @@
<template>
<!-- 确认模板 -->
<div class=''>
<el-dialog title="模板确认" :visible.sync="showTemplate" width="50%" >
<el-dialog title="模板确认" :visible.sync="showTemplate" width="50%" :close-on-click-modal="false">
<div id="luckysheet"></div>
<span slot="footer" class="dialog-footer">
<el-button @click="showTemplate = false"> </el-button>
<el-button type="primary" @click="showTemplate = false"> </el-button>
<el-button @click="handleCancel"> </el-button>
<el-button type="primary" @click="handleConfirm"> </el-button>
</span>
</el-dialog>
</div>
@ -26,54 +26,54 @@ export default {
let column = parseInt(e[0].column[0]) + 1, row = parseInt(e[0].row[0]) + 1;
this.selectedCell = "第" + row + "行" + "第" + column + "列";
},
async urlToFile(url, fileName = 'file') {
try {
// 使 fetch
const response = await fetch(url);
//
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
// Blob
const blob = await response.blob();
// Blob File
const file = new File([blob], fileName, { type: 'excel/xlsx' });
this.uploadExcel(file)
} catch (error) {
console.error('Error fetching or converting file:', error);
throw error;
}
},
uploadExcel(files) {
if (!files) return alert('没有文件等待导入');
let that = this
LuckyExcel.transformExcelToLucky(files, function (exportJson, luckysheetfile) {
console.log(exportJson,'获取到导入的JSON');
that.exportJson = exportJson
if (exportJson.sheets == null || exportJson.sheets.length == 0) return alert('读取excel文件内容失败, 目前不支持XLS文件!');
window.luckysheet.destroy();
window.luckysheet.create({
...options,
data: exportJson.sheets,
title: exportJson.info.name,
hook: {},
});
});
},
handleCancel(){
this.$emit('handelHideTemplate')
},
handleConfirm(){
this.$emit('saveLuckysheetJson',this.exportJson)
}
},
mounted() {
console.log(this.fileUrl, 'fileUrl===');
this.urlToFile('http://localhost:9001/epmet-work-pc/test1.xlsx',this.fileName)
this.$nextTick(() => {
window.luckysheet.destroy();
options.title = '模板确认'
options.data = [
{
"name": "Cell", //
"color": "", //
"index": 0, //
"status": 1, //
"order": 0, //
"hide": 0,//
"row": 36, //
"column": 18, //
"defaultRowHeight": 19, //
"defaultColWidth": 73, //
"celldata": [{ r: 0, c: 0, v: { m: "1", v: 'value', bg: "#00FF00", ct: { fa: 'General', t: 'g' } } }], //使
"config": {
"merge": {}, //
"rowlen": {}, //
"columnlen": {}, //
"rowhidden": {}, //
"colhidden": {}, //
"borderInfo": {}, //
"authority": {}, //
},
"scrollLeft": 0, //
"scrollTop": 315, //
"luckysheet_select_save": [], //
"calcChain": [],//
"isPivotTable": false,//
"pivotTable": {},//
"filter_select": {},//
"filter": null,//
"luckysheet_alternateformat_save": [], //
"luckysheet_alternateformat_save_modelCustom": [], //
"luckysheet_conditionformat_save": {},//
"frozen": {}, //
"chart": [], //
"zoomRatio": 1, //
"image": [], //
"showGridLines": 1, //线
"dataVerification": {} //
},
]
window.luckysheet.create({
...options,
hook: {
@ -91,7 +91,11 @@ export default {
fileUrl: {
type: String,
default: ''
}
},
fileName: {
type: String,
default: ''
},
},
components: {},
computed: {},
@ -100,7 +104,7 @@ export default {
</script>
<style lang='scss' scoped>
#luckysheet{
height: 500px;
}
#luckysheet {
height: 500px;
}
</style>

119
src/views/modules/base/smartExcel/cpts/excel-view.vue

@ -9,8 +9,8 @@
<template #trigger>
<el-button type="primary">上传报表模板</el-button>
</template>
</el-upload> -->
</el-upload> -->
<div :class="{ 'menu_item': true, 'active': menuActive === index }" v-for="(item, index) in menuList"
:key="index" @click="handleClickMenu(index)">
<span>{{ item.name }}</span>
@ -27,7 +27,7 @@
<el-button type="primary"> 审核存档</el-button>
</div>
</div>
<div id="luckysheet" ></div>
<div id="luckysheet"></div>
</div>
</div>
<!-- <el-drawer title="设置面板" :visible.sync="drawer" :direction="direction" :before-close="handleClose">
@ -94,6 +94,7 @@
import LuckyExcel from 'luckyexcel';
import options from "@/utils/luckysheetConfig.js";
import { mapGetters } from 'vuex'
import { requestPost, requestGet } from "@/js/dai/request";
export default {
data() {
@ -126,7 +127,12 @@ export default {
};
},
props: {
workbookId: {
type: String,
default: ''
}
},
computed: {
tableHeight() {
return (this.clientHeight - 140) + 'px'
@ -140,81 +146,29 @@ export default {
watch: {},
mounted() {
this.initSocket()
window.luckysheet.destroy();
options.data = [
{
"name": "Cell", //
"color": "", //
"index": 0, //
"status": 1, //
"order": 0, //
"hide": 0,//
"row": 36, //
"column": 18, //
"defaultRowHeight": 19, //
"defaultColWidth": 73, //
"celldata": [{ r: 0, c: 0, v: { m: "1", v: 'value', bg: "#00FF00", ct: { fa: 'General', t: 'g' } } }], //使
"config": {
"merge": {}, //
"rowlen": {}, //
"columnlen": {}, //
"rowhidden": {}, //
"colhidden": {}, //
"borderInfo": {}, //
"authority": {}, //
},
"scrollLeft": 0, //
"scrollTop": 315, //
"luckysheet_select_save": [], //
"calcChain": [],//
"isPivotTable": false,//
"pivotTable": {},//
"filter_select": {},//
"filter": null,//
"luckysheet_alternateformat_save": [], //
"luckysheet_alternateformat_save_modelCustom": [], //
"luckysheet_conditionformat_save": {},//
"frozen": {}, //
"chart": [], //
"zoomRatio": 1, //
"image": [], //
"showGridLines": 1, //线
"dataVerification": {} //
},
{
"name": "Sheet2",
"color": "",
"index": 1,
"status": 0,
"order": 1,
"celldata": [],
"config": {}
},
{
"name": "Sheet3",
"color": "",
"index": 2,
"status": 0,
"order": 2,
"celldata": [],
"config": {},
}
]
window.luckysheet.create({
...options,
hook: {
cellEditBefore: this.handleCellEditBefore,
// cellUpdateBefore: this.handleCellUpdateBefore,
sheetCreateAfter:this.handleSheetCreateAfter
},
});
this.loadWorkBook()
},
methods: {
handleSheetCreateAfter(e){
console.log('setsheet',e);
async loadWorkBook() {
const { data, code, msg } = await requestGet(`/actual/base/luckySheet/workbook/load?workbookId=${this.workbookId}`)
if (code === 0) {
window.luckysheet.destroy();
options.data = data
window.luckysheet.create({
...options,
hook: {
cellEditBefore: this.handleCellEditBefore,
// cellUpdateBefore: this.handleCellUpdateBefore,
sheetCreateAfter: this.handleSheetCreateAfter
},
});
} else {
console.log(msg);
}
},
handleSheetCreateAfter(e) {
console.log('setsheet', e);
},
initSocket() {
this.socket = new WebSocket('');
@ -222,7 +176,7 @@ export default {
console.log('WebSocket连接已打开');
});
this.socket.addEventListener('message', (event) => {
console.log(event,'接收到消息了');
console.log(event, '接收到消息了');
});
},
sendMessage() {
@ -255,8 +209,8 @@ export default {
let name = files[0].name;
let suffixArr = name.split('.'),
suffix = suffixArr[suffixArr.length - 1];
debugger
if (suffix != 'xlsx') return alert('目前只支持导入xlsx文件');
let that = this
LuckyExcel.transformExcelToLucky(files[0], function (exportJson, luckysheetfile) {
if (exportJson.sheets == null || exportJson.sheets.length == 0) return alert('读取excel文件内容失败, 目前不支持XLS文件!');
window.luckysheet.destroy();
@ -373,7 +327,7 @@ export default {
this.socket.close();
}
},
props: {},
};
</script>
<style lang="scss" scoped>
@ -384,17 +338,20 @@ export default {
width: calc(100% - 240px);
height: calc(100% - 20px);
}
#luckysheet{
#luckysheet {
width: 100%;
padding: 0px;
z-index: 2;
height: calc(100% - 80px);
margin: 10px;
}
.top_btn{
.top_btn {
height: 60px;
width: 100%;
}
.upload-demo {
position: absolute;
z-index: 999999;

5
src/views/modules/base/smartExcel/index.vue

@ -100,7 +100,7 @@
<excel-info></excel-info>
</div>
<div v-if="pageType == 'add'">
<excel-add></excel-add>
<excel-add @handleShowPage="handleShowPage"></excel-add>
</div>
</div>
</template>
@ -195,6 +195,9 @@ export default {
this.getOrgTreeList()
},
methods: {
handleShowPage(){
this.pageType = 'list';
},
handleAdd() {
this.pageType = 'add';
console.log(this.pageType);

1
src/views/modules/shequzhili/eventOld/cpts/add.vue

@ -88,7 +88,6 @@
</div>
</el-upload>
</el-form-item>
<el-form-item label="地图位置" prop="longitude" label-width="150px" style="display: block">
<div style="width: 500px">
<el-form-item prop="location" style="display: block">

Loading…
Cancel
Save