<template>
  <div class="app-container">
    <ContainerLayout :options="view.layout" ref="layout" class="body-content" @resize="resize">
      <div slot="north">
        <div class="title" v-if="view.showTitle" ref="title">{{$_i18n(view.title)||"未设置标题"}}</div>
        <CustomToolbar v-show="view.showToolbar" ref="toolbar" :fid="fid" @click="$page_toolbar_clickHandler"
                       @ready="$_page_toolbar_initComplete" @resize="resize" @completed="completed"
                        :queryParams="queryParams" page="list" :active-oa="queryParams.cid!=null&&view.oa"></CustomToolbar>
      </div>
      <div ref="middle">
        <el-table ref="table" v-loading="queryParams.loading" :data="items.rows" element-loading-text="Loading"
                  :border="view.border" :stripe="view.stripe" size="mini" @selection-change="checked"
                  :row-class-name="tableRowClassName" @row-click="rowClick" @row-dblclick="rowDbClick"
                  @current-change="selected"  @sort-change="sorted" :style="{width:view.width}" :row-key="view.idKey"
                  :highlight-current-row="view.select" :height="view.height" :max-height="view.maxHeight"
                  :empty-text="view.emptyText" :fit="view.fit">
          <el-table-column v-if="view.showCheckbox" type="selection" width="40">
          </el-table-column>
          <el-table-column  v-if="view.showSeq" align="center" label="序号" width="50" :fixed="view.seqFixed">
            <template slot-scope="scope">{{ scope.$index+1 }}</template>
          </el-table-column>
          <template v-for="column in items.columns" v-if="column.visible!==false">
            <el-table-column v-if="column.name==null" :label="$_i18n(column.text)" header-align="center" :height="view.height">
              <template v-for="child in column.children" v-if="child.visible!==false">
                <el-table-column v-if="view.row.list.indexOf(child.name)<0"  :label="$_i18n(child.text)"
                                 :width="adapterWidth(column)" :prop="child.name" :align="child.align"
                                 header-align="center" :min-width="column.minWidth"
                                 :fixed="child.fixed" :sortable="child.sortable" show-overflow-tooltip >
                  <template slot-scope="scope">
                    <div v-if="!view.editable&&hasRichText(scope.row[column.name])" v-html="$_i18n(scope.row[column.name])"></div>
                    <template v-else slot-scope="scope">
                      {{$_i18n(scope.row[column.name])}}
                    </template>
                  </template>
                </el-table-column>
                <el-table-column v-else align="center" :label="$_i18n(child.text)" :width="child.width"
                                 header-align="center" >
                  <template slot-scope="scope">
                    <template v-for="name in stringArray(child.name)">
                      <el-button size="mini"
                                 @click="handle($event , view.row.buttons[name], scope.row)"
                                 :type="$d.adapterType(view.row.buttons[name])" v-if="view.row.buttons[name]"
                                 :icon="view.buttonIcon?getStyle(view.row.buttons[name].style||'icon-search'):''"
                                 :title="$_i18n(view.row.buttons[name].remark||view.row.buttons[name].tooltip)">
                        {{$_i18n(view.row.buttons[name].name)}}
                      </el-button>
                    </template>
                  </template>
                </el-table-column>
              </template>
            </el-table-column>
            <template v-else>
              <el-table-column v-if="view.row.list.indexOf(column.name)<0&&column.name!='star_score'"  :label="$_i18n(column.text)"
                               :width="adapterWidth(column)" :prop="column.name" :align="column.align"
                               header-align="center" :min-width="column.minWidth"
                               :fixed="column.fixed" :sortable="column.sortable" show-overflow-tooltip >
                <template slot-scope="scope">
                 <div v-if="!view.editable&&hasRichText(scope.row[column.name])" v-html="$_i18n(scope.row[column.name])"></div>
                  <template v-else slot-scope="scope">
                    {{$_i18n(scope.row[column.name])}}
                  </template>
                </template>
              </el-table-column>
              <el-table-column v-else align="center" :label="$_i18n(column.text)" :width="column.width"
                               header-align="center" >
                <template slot-scope="scope">
                  <template v-if="column.name=='star_score'">
                    <el-rate v-model="scope.row[column.name]" disabled show-score text-color="#ff9900" score-template="{value}">
                    </el-rate>
                  </template>
                  <template v-else v-for="name in stringArray(column.name)">
                    <template v-if="view.row.buttons[name]">
                      <LinkButton v-if="view.row.buttons[name].type=='link'" :type="$d.adapterType(view.row.buttons[name])"
                                  :href="view.row.buttons[name].href||'javascript:void(0);'"  target="_blank"
                                  :ref="view.row.buttons[name].code"
                                  @click="handle($event , view.row.buttons[name], scope.row)"
                                  :size="$store.state.settings.Size" :disabled="view.row.buttons[name].readonly===false"
                                  :underline="false" :icon="view.buttonIcon?getStyle(view.row.buttons[name]):''" >
                        {{$_i18n(view.row.buttons[name].name)}}</LinkButton>
                      <el-button v-else :size="$store.state.settings.Size"
                                 @click="handle($event , view.row.buttons[name], scope.row)"
                                 :type="$d.adapterType(view.row.buttons[name])"
                                 :icon="view.buttonIcon?getStyle(view.row.buttons[name].style||'icon-search'):''"
                                 :title="$_i18n(view.row.buttons[name].remark||view.row.buttons[name].tooltip)">
                        {{$_i18n(view.row.buttons[name].name)}}
                      </el-button>
                    </template>
                  </template>
                </template>
              </el-table-column>
            </template>
          </template>
        </el-table>
        <el-pagination v-if="view.pageControl.visible!==false" @size-change="handleSizeChange"
                       @current-change="handleCurrentChange" :small="view.pageControl.small"
          :current-page.sync="queryParams.p" :page-sizes="view.pageControl.pageSizes" :page-size="queryParams.s"
          layout="total, sizes, prev, pager, next, jumper" :total="(items&&items.total)||0" :pager-count="view.pageControl.pageCount">
        </el-pagination>
      </div>
      <!--使用vue动态组件加载适配-->
      <component v-if="view.layout.south && view.layout.south.component!=null && view.layout.south.visible"
                 slot="south" ref="south" :is="view.layout.south.component" :params="view.layout.south.params">
      </component>
      <!--使用vue动态组件加载适配-->
      <component v-if="view.layout.east && view.layout.east.component!=null && view.layout.east.visible"
                 slot="east" ref="east" :is="view.layout.east.component" :params="view.layout.east.params">
      </component>
    </ContainerLayout>
    <template>
      <Dialog refs="dialog" :title="dialog.title" :visible.sync="dialog.visible" :destroy-on-close="dialog.destroyOnClose"
              :width="dialog.width" :height="dialog.height" :close-on-click-modal="dialog.modalClose"
              :parentClass="view.parentClass" @close="handleDialogClose" :custom-class="view.customClass"
              :modal-append-to-body="false" :close-on-press-escape="false">
        <component v-if="dialog.visible" :is="dialog.component" :params="dialog.params"></component>
        <span v-if="dialog.footer&&dialog.footer.visible" slot="footer" class="dialog-footer">
            <el-button @click="dialog.visible = false">{{$_i18n("form.cancel")}}</el-button>
            <el-button type="primary" @click="dialog.visible = false">{{$_i18n("form.ok")}}</el-button>
          </span>
      </Dialog>
    </template>
  </div>
</template>
<script>
    import resize from '../../utils/mixins/resize';
    import page from '../Common/page';
    import LinkButton from '../LinkButton';
    export default {
      name: "ListView",
      mixins: [resize, page],//监听外部框架的大小改变事件
      components:{
        LinkButton
      },data() {
        return {
          rid: null,
          checkedItems: [],
          items: {columns: null, rows: [], total: 0, page: 1},
          queryParams: {s: 20, p: 1, paging: "pagecount"},
          view: {//布局控制配置
            row: {list: [], buttons: {}},
            editable:false,
            //phy_del:false,//是否物理删除
            select: true,
            showCheckbox: true,
            showSeq: false,
            seqFixed: false,
            stripe: true,
            border: true,
            fit: true,
            width: "100%",
            pageControl: {
              pageSizes: [20, 50, 100, 200, 500, 1000],
              height: 26,
              pageCount: 11,
              visible: true,
              small: true
            },
            layout: {
              north: {visible: true, resize: false, size: "auto"},
              south: {visible: false, size: "50%", params: {showTitle: true, inited: false}},
              east: {visible: false, params: {showTitle: true, inited: false}},
            }
          }
        }
      }, async created() {
        this.$_page_getRouter();
        await this.initFormConfig();
      }, mounted() {
        this.$refs.layout.updateLayout(this.view.layout);
      }, computed: {},
      methods: {
        tableRowClassName({row, rowIndex}) { //用于控制删除掉的数据变成灰色
          return (row.active === false) ? "dis-active" : "active";
        }, visible(item) {
          return item.visible ? undefined : "hide";
        },adapterWidth(item){
          if(!item.width&&!item.minWidth)
            return 100;
          return item.width;
        },customQuery(params) {
          if (this.$refs.toolbar && this.$refs.toolbar.loaded) {
            // let needData = (params.data !== false && params.noQuery!==true);
            // delete params.data;
            this.$d.extend(this.queryParams, params);//解决搜索时，不会联动分页控件的问题
            let options = this.$d.extend({export: "json", head: !this.items.columns}, this.queryParams);
            this.clearData();
            if ((this.rid || this.view.dataUrl) && (options.head || this.queryParams.data)) {
              this.queryParams.loading = true;
              if (this.queryParams.data) { //当启用数据查询后,空数据提示,需要变更
                this.view.emptyText =this.view.queryEmptyText||"查无数据";
              }else{
                this.view.emptyText =this.view.noQueryText||"当前页面需要手动查询！";
              }
              let url = this.view.dataUrl || this.$store.state.api.report.loadReport + this.rid;
              this.$http(url, {data: options}).then((res) => {
                if(res.success!=false) {
                  if (options.head) {
                    this.items.columns = res.columns;
                    if (this.view.headers && this.view.headers.length) {
                      let columnMap = {};
                      for (let i in res.columns) {
                        columnMap[res.columns[i].name] = res.columns[i];
                      }
                      let result = [];
                      for (let i in this.view.headers) {
                        if (typeof this.view.headers[i] == "string") {
                          let name = this.view.headers[i];
                          result[i] = columnMap[name];
                        } else {
                          let obj = this.view.headers[i];
                          result[i] = obj;
                          for (let j in obj.children) {
                            if (typeof obj.children[j] == "string") {
                              let name = obj.children[j];
                              obj.children[j] = columnMap[name];
                            }
                          }
                        }
                      }
                      this.items.columns = result;
                    }
                  }
                  if (this.queryParams.data) {//有查数据才更新分页
                    this.items.rows = res.rows;
                    this.items.total = res.total;
                    this.queryParams.p = res.page;
                  // }else{
                  //   this.items.total = 0;
                  //   this.queryParams.p = 1;
                  }
                  //自动选中之前的数据的功能
                  let item = this.$_page_keepSelectedCallback(this.items.rows);
                  this.queryParams.loading = false;
                  this.$nextTick(() => {
                    this.resize();
                    // this.$refs.table.doLayout();//解决表格存在fixed时,布局出错的问题
                    if (this.queryParams.data && this.items.rows.length > 0) {
                      this.$refs.table.setCurrentRow(item || this.items.rows[0])
                    }else{
                      this.$refs.table.setCurrentRow({});
                    }
                  });
                }else{
                  this.$_page_message(res);
                  this.queryParams.loading = false;
                }
              })
            }
          } else {
            if (this.queryHandle != null) {
              clearTimeout(this.queryHandle);
              delete this.queryHandle;
            }
            this.queryHandle = setTimeout(this.customQuery, 50, params);
          }
        }, calcHeight() {
          let height = this.$refs.middle.offsetHeight - (this.view.pageControl.visible !== false ? this.view.pageControl.height : 0);
          return height;
        }, updatePageParams(pageParams) {
          if (pageParams.reportname) {
            this.view.title = pageParams.reportname;
            delete pageParams.reportname;
          }
          if (pageParams.rid) {
            this.rid = pageParams.rid; //拦截无穷递归
          }
        }, resize() {
          this.$nextTick(() => {
            if (this.$refs.layout)
              this.view.width = this.$refs.layout.$refs.center.$el.offsetWidth + 'px';
            let height = this.calcHeight();
            if (height > 0) { //&& this.view.height != height
              this.$set(this.view, "height", height);
              this.$nextTick(() => {
                this.$refs.table.layout.setHeight(height);

              });
            }
            this.$refs.table.doLayout();
            if (this.view.layout.south.visible && this.$refs.south) {
              // this.$d.debug().log("调整底部组件大小");
              this.$refs.south.resize();
            }
            if (this.view.layout.east.visible && this.$refs.east) {
              // this.$d.debug().log("调整底部组件大小");
              this.$refs.east.resize();
            }
          })
        }, completed() {
          // this.$d.debug().log(this.$options.name,"收到工具栏加载完成事件");
        }, selected(newRow,oldRow) {
          this.selectedItem = newRow;
          if (this.view.layout.south.visible)
            this.$_page_linkageLayout("south");
          if (this.view.layout.east.visible)
            this.$_page_linkageLayout("east");
        }, sorted(e) {
          this.$d.debug().log("排序改变事件", e);
        }, checked(e) {
          this.checkedItems = e;
          // this.checkedIds = [];
          // for (let i in e) {
          //   this.checkedIds.push(e[i][this.view.idKey]);
          //   this.checkedItems.push(e[i]);
          // }
        }, handleSizeChange(e) {
          // this.queryParams.s =( e>0?e:20）;
          // this.queryParams.p = 1;
          this.customQuery({s:e>0?e:20,p:1});
        }, handleCurrentChange(e) {
          let pages=Math.ceil(this.items.total/this.queryParams.s);
          if(e>pages)
            e=pages;
          // this.queryParams.p = e;
          this.customQuery({p:e});
        }, handle(evt,target, e) {
          //这边需要链接工具栏配置，其实包括这个按钮样式也是需要根据工具栏指示来做的，如果工具栏没有这个按钮，也是不允许在这边显示的，以保证安全协议的唯一性
          this.selectedItem = e;
          this.$refs.toolbar.handleClick(evt,target);
        }, clearData() {
          this.items.rows = [];
          this.items.total = 0;
          this.checkedItems=[];
          this.queryParams.p = 1;
          if (this.view.layout.south.visible && this.$refs.south && this.$refs.south.clearData) {
            this.$refs.south.clearData();
          }
          if (this.view.layout.east.visible && this.$refs.east && this.$refs.east.clearData) {
            this.$refs.east.clearData();
          }
        }, validateCallback(item, key,data) {
          if(data==null){
            data=this.$d.extend({},this.queryParams,this.selectedItem);
          }
          this.$d.debug().log("执行表格内容验证", item, data);
          if (item.required) {
            if (!(data && data[key]!=null && ("" + data[key]).length > 0)) {
              if (key == "list") {//增加对列表参数的判断支持
                let datas = this.checkedItems;
                if (this.checkedItems.length == 0)
                  datas = [data];
                for(let i in datas){//遍历数据进行验证
                  let dataItem=datas[i];
                  if(!dataItem[this.view.idKey]){//id没有
                    return  false;
                  }
                  if (item.validate) {//如果还需要验证扩展属性，则进行验证，此模式仅支持批量同步验证
                    for (let c_key in item.validate) {
                      if (item.validate[c_key].required !== false && !(this.validateCallback(item.validate[c_key], c_key,dataItem))) {
                        this.$notify({title: '警告', message: item.validate[c_key].errmsg || "未输入正确的提示信息", type: 'warning'});
                        return null;
                      }
                    }
                  }
                }
                return true;
              }
              return false;
            }
          } else if (item.regex) {//支持正则配置，相关正则，请自行参考百度
            return new RegExp(item.regex).test(data[key]);
          } else if (item.indexOf!=null) {//包含在数组内
            return item.indexOf.indexOf(data[key]) >= 0;
          } else if (item.notIndexOf!=null) {//不包含在数组内
            return item.notIndexOf.indexOf(data[key]) < 0;
          } else if (item.notEquals!=null) {//不等于
            return data[key] != item.notEquals;
          } else if (item.equals!=null) {//等于
            return data[key] == item.equals;
          } else if (item.equalsIgnoreCase!=null) {
            if (data[key] == item.equalsIgnoreCase) {
              return true;
            } else if (data[key] != null && item.equalsIgnoreCase != null) {
              return data[key].toLowerCase() == item.equalsIgnoreCase.toLowerCase();
            }
            return false;
          } else if (item.expression) {//使用表达式需要注意，最后返回的结果是 null，0，"",false均为false，其他为true
            let result = eval(item.expression.urlFormat(data));
            return result;
          }
          //todo其他的验证模式
          return true;
        }, stringArray(data) {
          return data.split(",");
        }, rowClick(row,column,e) {
          if (this.rowClickHandle) {
            this.$d.debug().log("点击了行", row, this.view.rowClick);
            this.selectedItem = row;
            this.$refs.toolbar.handleClick(e,this.rowClickHandle);
          }
        }, rowDbClick(row,column,e) {
          if (this.rowDbClickHandle) {
            this.$d.debug().log("双击了行", row, this.view.rowDbClick);
            this.selectedItem = row;
            this.$refs.toolbar.handleClick(e,this.rowDbClickHandle);
          }
        },hasRichText(text){
          return /^[<][-\w]+([ ].*)*[>].*[<][/][-\w]+[>]$/.test(text);
        }
      }
    }
</script>

