123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521 |
- <template>
- <div class="excel-data-container" v-loading="saveLoading" element-loading-text="保存中,请稍后······" element-loading-spinner="el-icon-loading"
- element-loading-background="rgba(0, 0, 0, 0.8)">
- <div class="online-excel">
- <div id="luckysheet"></div>
- </div>
- <div class="data-options-box">
- <div class="data-options-buttons">
- <el-button type="primary" style="width: 80px;font-size: 16px;" @click="saveExcel">保存</el-button>
- <el-button plain style="width: 80px;font-size: 16px;" @click="cancel">取消</el-button>
- </div>
- <div class="data-options" >
- <el-form :model="dataForm" label-position="top" ref="dataOptions">
- <el-form-item label="一级分类" prop="firstClassify" :rules="[{required:true,message:'一级分类不能为空',trigger:'change'}]">
- <el-select v-model="dataForm.firstClassify" placeholder="请选择一级分类" style="width: 100%;" @change="changeFirstClassify">
- <el-option :label="item.ClassifyName" :value="item.ClassifyId" v-for="item in classifyArray" :key="item.ClassifyId"></el-option>
- </el-select>
- </el-form-item>
- <el-form-item label="指标分类" prop="secondClassify" :rules="[{required:true,message:'指标分类不能为空',trigger:'change'}]">
- <el-select v-model="dataForm.secondClassify" placeholder="请选择指标分类" style="width: 100%;" @change="changeSecondClassify">
- <el-option :label="item.ClassifyName" :value="item.ClassifyId" v-for="item in secondClassifyArray" :key="item.ClassifyId"></el-option>
- </el-select>
- </el-form-item>
- <el-form-item label="频度" prop="frequency" :rules="[{required:true,message:'频度不能为空',trigger:'change'}]">
- <el-select v-model="dataForm.frequency" placeholder="请选择频度" style="width: 100%;" @change="changeFrequency">
- <el-option :label="item" :value="item" v-for="item in frequencyList" :key="item"></el-option>
- </el-select>
- </el-form-item>
- </el-form>
- <el-tooltip :open-delay="400">
- <div slot="content">
- <p class="hint-message">1、新增指标:在预设好的指标列下输入指标名称、单位、数值并保存;</p>
- <p class="hint-message">2、新增日期:在第一列选择日期或插入日期行(需复制已有日期格式)输入数值并保存;</p>
- <p class="hint-message">3、删除指标:清空该指标下所有数据并保存,请勿直接删除指标列;</p>
- <p class="hint-message">4、删除日期:清空该日期对应所有数据并保存,请勿直接删除日期行;</p>
- </div>
- <div class="instruction-hint" >
- <span>使用说明</span>
- <i class="el-icon-question" style="color: #999;"></i>
- </div>
- </el-tooltip>
- </div>
- </div>
- </div>
- </template>
- <script>
- import { dataInterence } from "@/api/api.js";
- import EventBus from '@/api/bus.js'
- export default {
- name:'onlineExcelCopy',
- data() {
- return {
- // 初始化数据
- options:{
- container:'luckysheet',
- lang: 'zh',
- gridKey:'handmade-excel',
- showinfobar:false,
- row:300,
- column:60,
- data:[
- {
- "name":"test",
- "celldata":[
- {
- "r":0,
- "c":0,
- "v":{
- ct: {fa: "General", t: "g"},
- m:"一级分类",
- v:"一级分类",
- bg:'#b4a7d6'
- },
- },
- {
- "r":1,
- "c":0,
- "v":{
- ct: {fa: "General", t: "g"},
- m:"指标分类",
- v:"指标分类",
- bg:'#b4a7d6'
- },
- },
- {
- "r":2,
- "c":0,
- "v":{
- ct: {fa: "General", t: "g"},
- m:"频度",
- v:"频度",
- bg:'#b4a7d6'
- },
- },
- {
- "r":3,
- "c":0,
- "v":{
- ct: {fa: "General", t: "g"},
- m:"指标名称",
- v:"指标名称",
- bg:'#b4a7d6'
- },
- },
- {
- "r":4,
- "c":0,
- "v":{
- ct: {fa: "General", t: "g"},
- m:"单位",
- v:"单位",
- bg:'#b4a7d6'
- },
- },
- ],
- "config":{
- "borderInfo":[{
- "rangeType": "range",
- "borderType": "border-all",
- "style": "1",
- "color": "#fff",
- "range": [{
- "row": [0,4],
- "column": [0,0]
- }]
- }],
- },
- "frozen":{
- type: 'rangeBoth',
- range: {row_focus: 4, column_focus: 0}
- },
- "dataVerification":{}
- }
- ],
- hook:{
- cellUpdateBefore(r,c){
- // 禁止更新的单元格
- if([0,1,2,3,4].includes(r) && c==0){
- return false
- }
- },
- cellMousedownBefore(e,position){
- // 禁止鼠标选中的单元格
- if([0,1,2].includes(position.r) || ([3,4].includes(position.r) && position.c==0)){
- return false
- }
- }
- },
- showsheetbar:false
- },
- dataForm:{
- firstClassify:'',
- secondClassify:'',
- frequency:'',
- tradeCode:''
- },
- copyDataForm:{},
- firstClassName:'',
- secondClassName:'',
- frequencyList: ['日度','周度','旬度','月度','季度','半年度','年度'],
- classifyArray:[],
- unitList:[],
- secondClassifyArray:[],
- // 保存时候的加载框
- saveLoading:false,
- isEdit:"false"
- }
- },
- created() {
- this.dataForm.firstClassify = parseInt(this.$route.query.parentClassifyId) || ''
- this.dataForm.secondClassify = parseInt(this.$route.query.ClassifyId) || ''
- this.dataForm.frequency = this.$route.query.Frequency || ''
- this.dataForm.tradeCode = this.$route.query.TradeCode || ''
- this.dataForm.tradeName = this.$route.query.TradeName || ''
- this.copyDataForm = JSON.parse(JSON.stringify(this.dataForm))
- // 字符串
- this.isEdit = this.$route.query.isEdit.toString()
- this.initExcelOptions()
- // 监听折叠导航栏事件
- EventBus.$off('collapseHandle')
- EventBus.$on('collapseHandle',(params)=>{
- luckysheet.destroy()
- luckysheet.create(this.options)
- })
- },
- beforeRouteEnter(to, from, next){
- if(to.query.isEdit=='true'){
- to.matched[1].name='编辑excel数据'
- }else{
- to.matched[1].name='复制excel数据'
- }
- next()
- },
- beforeRouteLeave(to, from, next) {
- luckysheet.destroy()
- next();
- },
- // 监听浏览器返回事件
- mounted() {
- window.addEventListener('popstate',this.setCache)
- },
- unmounted() {
- window.removeEventListener('popstate',this.setCache)
- },
- methods: {
- async initExcelOptions(){
- // 获取单位接口
- await this.getTargetUnitList()
- // 获取分类
- await this.getClassify()
- let dataList = []
- // 编辑才请求数据
- if(this.dataForm.secondClassify && this.isEdit == "true"){
- let res = await dataInterence.getTargetList({
- Frequency: this.dataForm.frequency,
- ClassifyId: this.dataForm.secondClassify,
- TradeCode:this.dataForm.tradeCode,
- EdbShowType: this.dataForm.tradeCode?0:1,
- })
- if(res.Ret == 200){
- dataList = res.Data.List || []
- // if(res.Data.FrequencyList) this.dataForm.frequency = res.Data.FrequencyList[0]
- }
- }
- // 拿出所有数组
- let arr = dataList.map((item => item.DataList)).flat()
- // 拿出所有数组的日期并展平排序
- let dateArr = [...new Set(arr.map((item) => item.Dt))].sort().reverse()
- // 组合成需要的数据格式
- let excelData=dateArr.map(date =>{
- let objList = [date]
- dataList.forEach(element => {
- let obj = element.DataList.find((time) => time.Dt === date)
- objList.push(obj?obj.Close : '')
- });
- return objList
- })
- /**
- * 当数据的长度大于默认的84时,行数需要设置成数据的长度+15
- */
- this.options.row = dateArr.length>(this.options.row-15) ? (dateArr.length+15):this.options.row
- /**
- * 设置列数
- * 当数据的长度大于默认的60时,列数需要设置成数据的长度+10
- */
- this.options.column = dataList.length>(this.options.column-10) ? (dataList.length+10):this.options.column
- let row = this.options.row
- let col = this.options.column
- // 初始化数据
- dataList.map((item,index) =>{
- this.options.data[0].celldata.push(
- {
- "r":3,
- "c":1+index,
- "v":{
- ct: {fa: "General", t: "g"},
- m:item.SecName,
- v:item.SecName
- }
- },
- {
- "r":4,
- "c":1+index,
- "v":{
- ct: {fa: "General", t: "g"},
- m:item.Unit,
- v:item.Unit
- }
- })
- })
- for (let i = 0; i < col; i++) {
- // let item =dataList[0]
- this.options.data[0].celldata.push(
- {
- "r":0,
- "c":1+i,
- "v":{
- ct: {fa: "General", t: "g"},
- m:this.firstClassName || '',
- v:this.firstClassName || '',
- bg:'#cccccc'
- }
- },
- {
- "r":1,
- "c":1+i,
- "v":{
- ct: {fa: "General", t: "g"},
- m:this.secondClassName || '',
- v:this.secondClassName || '',
- bg:'#cccccc'
- }
- },
- {
- "r":2,
- "c":1+i,
- "v":{
- ct: {fa: "General", t: "g"},
- m:this.dataForm.frequency || '',
- v:this.dataForm.frequency || '',
- bg:'#cccccc'
- }
- })
- }
- for (let i = 0; i < row-5; i++) {
- for (let j = 0; j < (col+1); j++) {
- this.options.data[0].celldata.push(
- {
- "r":5+i,
- "c":0+j,
- "v":{
- ct: j==0?{fa: "yyyy-MM-dd", t: "d"}:{fa: "0.0000", t: "n"},
- m:excelData[i]?excelData[i][j]:'',
- v:excelData[i]?excelData[i][j]:'',
- }
- })
- }
- }
- // // 设置日期单元格颜色
- this.options.data[0].celldata.forEach(element => {
- if(element.c==0 && (![0,1,2,3,4].includes(element.r))){
- element.v.bg = '#ff9900'
- }
- });
- // 设置边框颜色
- this.options.data[0].config.borderInfo.push({
- "rangeType": "range",
- "borderType": "border-all",
- "style": "1",
- "color": "#fff",
- "range": [{
- "row": [0,2],
- "column": [1,col]
- }]
- },{
- "rangeType": "range",
- "borderType": "border-all",
- "style": "1",
- "color": "#fff",
- "range": [{
- "row": [5,row],
- "column": [0,0]
- }]
- })
- // 设置数据验证
- for (let i = 0; i < col; i++) {
- this.options.data[0].dataVerification[`4_${1+i}`]={
- "type": "dropdown",
- "type2": null,
- "value1": this.unitList.join(','),
- "value2": "",
- "prohibitInput": false,
- // "hintShow": false,
- // "hintText": ""
- }
- }
- this.$nextTick(()=>{
- luckysheet.create(this.options)
- })
- },
- // 获取分类
- async getClassify() {
- let res=await dataInterence.getClassify()
- if(res.Ret===200){
- this.classifyArray = res.Data.List || []
- let item = this.classifyArray.find(item => item.ClassifyId == this.dataForm.firstClassify)
- this.firstClassName = item && item.ClassifyName
- this.secondClassifyArray = item ? item.Child : []
- if(this.secondClassifyArray.length>0){
- let item2 = this.secondClassifyArray.find(item => item.ClassifyId == this.dataForm.secondClassify)
- this.secondClassName = item2 && item2.ClassifyName
- }
- }
- },
- // 获取指标单位
- async getTargetUnitList(){
- let res=await dataInterence.getTargetUnitList()
- if(res.Ret===200){
- this.unitList = res.Data || []
- }
- },
- // 切换选择一级分类
- changeFirstClassify(id){
- let col = this.options.column
- let item = this.classifyArray.find(item => item.ClassifyId == id)
- this.firstClassName = item.ClassifyName
- // 指标分类数组
- this.secondClassifyArray = item.Child || []
- if(this.secondClassifyArray.length >0){
- // 默认选择第一个指标分类
- this.dataForm.secondClassify = this.secondClassifyArray[0].ClassifyId
- this.secondClassName = this.secondClassifyArray[0].ClassifyName
- }
- for (let i= 1; i< col+1 ; i++) {
- luckysheet.setCellValue(0,i,this.firstClassName,{isRefresh:false})
- luckysheet.setCellValue(1,i,this.secondClassName,{isRefresh:i==col?true:false})
- }
- },
- // 切换选择二级分类
- changeSecondClassify(id){
- let col = this.options.column
- let item = this.secondClassifyArray.find(item => item.ClassifyId == id)
- for (let i= 1; i< col+1; i++) {
- luckysheet.setCellValue(1,i,item.ClassifyName,{isRefresh:i==col?true:false})
- }
- },
- // 切换选择频度
- changeFrequency(value){
- let col = this.options.column
- for (let i= 1; i< col+1; i++) {
- luckysheet.setCellValue(2,i,value,{isRefresh:i==col?true:false})
- }
- },
- saveExcel(){
- this.$refs.dataOptions.validate((valid)=>{
- if(valid){
- this.saveLoading=true
- let data = luckysheet.getAllSheets()
- dataInterence.saveOnlineExcel({...data[0],ClassifyId:this.dataForm.secondClassify}).then(res=>{
- if(res.Ret == 200) {
- this.setCache('submit')
- this.$router.push({path:'/dataList'})
- }
- }).finally(()=>{
- this.saveLoading=false
- })
- }
- })
- },
- cancel(){
- this.setCache()
- this.$router.back()
- },
- // 设置sessionStorage缓存
- setCache(type = 'cancel'){
- // 提交
- let params={}
- if(type == 'submit'){
- params = this.dataForm
- }else{
- params = this.copyDataForm
- }
- let query={
- tradeCode:params.tradeCode,
- secondClassify:params.secondClassify,
- frequency:params.frequency,
- firstClassify:params.firstClassify,
- tradeName:params.tradeName
- }
- sessionStorage.setItem('onlineExcelBack',JSON.stringify(query))
- }
- },
- }
- </script>
- <style lang="scss" scoped>
- .excel-data-container{
- display: flex;
- height: calc(100vh - 110px);
- .online-excel{
- flex-grow: 1;
- height: 100%;
- padding: 10px;
- border: 1px solid #ECECEC;
- box-sizing: border-box;
- #luckysheet{
- height: 100%;
- width: 100%;
- margin: 0;
- padding: 0;
- }
- }
- .data-options-box{
- min-width: 270px;
- height: 100%;
- margin-left: 20px;
- width: 270px;
- box-sizing: border-box;
- .data-options-buttons{
- border: 1px solid #ECECEC;
- box-sizing: border-box;
- padding: 20px 15px;
- }
- .data-options{
- padding: 25px 15px;
- box-sizing: border-box;
- .instruction-hint{
- display: inline-flex;
- align-items: center;
- cursor: pointer;
- span{
- font-size: 16px;
- margin-right: 4px;
- }
- }
- }
- }
- }
- .hint-message{
- font-size: 14px;
- line-height: 22px;
- }
- </style>
- <style lang="scss">
- // .online-excel{
- // }
- .data-options{
- .el-form--label-top .el-form-item__label{
- line-height: 16px;
- color: #333333;
- font-size: 16px;
- }
- }
- .luckysheet .toolbar {
- background: none;
- margin: 0;
- padding: 0;
- }
- </style>
|