<template>
  <div class="page-view flex-row-sb">
    <app-sync-tree
      ref="appAsyncTree"
      lazy
      :actions="treeActions"
      :formRules="formRules"
      :default-expanded-keys="defaultExpandedKeys"
      :default-data="defaultData"
      :expand-all="expandAll"
      :props="treeProps"
      formWidth="100%"
      :request-method="getTreeNodes"
      highlighhighlightFirstt-first
      title="行政区划目录"
      @select="onTreeNodeClick"
      @beforeActionsClick="beforeActionsClick"
    >
      <template #form="{ form: treeForm }">
        <app-filter-item :span="24" label="父级">
          <el-input v-if="actionType === 'add'" v-model="curData.name" disabled readonly />
          <el-input v-else v-model="curData.parentName" disabled readonly />
        </app-filter-item>
        <app-filter-item prop="name" :rules="formRules.name" :span="24" label="名称">
          <el-input v-model="treeForm.name" placeholder="请输入名称" />
        </app-filter-item>
        <app-filter-item prop="code" :rules="formRules.code" :span="24" label="编码">
          <el-input v-model="treeForm.code" placeholder="请输入编码" />
          <div>
            <i class="tips">
              每三位编码组成一个识别码，12位-15位数，依次指定：
              <br />
              省（自治区、直辖市、特别行政区），
              <br />
              市（地区、自治州、盟），
              <br />
              县（市辖区、县级市、旗），乡镇，村
            </i>
          </div>
        </app-filter-item>
        <app-filter-item prop="longitude" :rules="formRules.longitude" :span="24" label="经度">
          <el-input v-model="treeForm.longitude" placeholder="请输入经度" />
          <div>
            <i class="tips"> 经度整数部分为0-180，小数部分为0到6位! </i>
          </div>
        </app-filter-item>
        <app-filter-item prop="latitude" :rules="formRules.latitude" :span="24" label="纬度">
          <el-input v-model="treeForm.latitude" placeholder="请输入纬度" />
          <div>
            <i class="tips"> 纬度整数部分为0-90，小数部分为0到6位! </i>
          </div>
        </app-filter-item>
      </template>
    </app-sync-tree>

    <div class="page-view flex-1 ml-15 h-100">
      <app-filter ref="app-filter" :model="filters" class="bg-white px-15 border-radius-5" label-width="110px" @query="onQuery" @reset="onReset">
        <app-filter-item :filter-config="{ operation: 'LIKE' }" :span="6" el-type="input" label="行政区划名称">
          <el-input v-model="filters.name_" clearable placeholder="请输入" @keyup.enter.native="$refs['app-filter'].query" />
        </app-filter-item>
        <app-filter-item :filter-config="{ operation: 'LIKE' }" :span="6" el-type="input" label="行政区划编码">
          <el-input v-model="filters.code_" clearable placeholder="请输入" @keyup.enter.native="$refs['app-filter'].query" />
        </app-filter-item>
      </app-filter>

      <div class="pa-11 bg-white h-100 flex-col mt-11 border-radius-5">
        <div class="mb-11">
          <el-button icon="el-icon-plus" size="mini" type="primary" @click="addSubNode"> 新增</el-button>
          <el-button icon="el-icon-delete" :disabled="selections.length === 0" size="mini" type="danger" @click="deleteSubNode"> 删除</el-button>
          <el-button icon="el-icon-sort" type="primary" plain @click="updateSequence">保存排序号 </el-button>
        </div>
        <app-table
          ref="table"
          :column="columns"
          :pagination="pagination"
          :table-data="tableData"
          :checkbox="true"
          :table-loading="tableLoading"
          :total="total"
          row-key="id"
          @pagination-change="onPaginationChange"
          @row-dblclick="editSubNode"
          @select-change="handleSelectsChange"
        >
          <template #sn="scope">
            <el-input-number v-model="scope.row.sn" controls-position="right" @change="handleChangeSequ(scope.row)" :min="1"></el-input-number>
          </template>
        </app-table>
      </div>
    </div>
    <area-dialog v-model="dialogVisible" :data="currentRow" :title="dialogTitle" @confirm="onDialogConfirm" />
  </div>
</template>

<script>
import utils from '@/utils';
import { getDictionaryByCode } from '@/utils/dictionary.js';
import tableMixin from '@/mixins/table.js'; // 列表mixins
import areaDialog from './areaDialog.vue';
import API from '@/api/business/area.js';

export default {
  name: 'DataDimension',
  components: { areaDialog },
  mixins: [tableMixin],
  data() {
    var checkLg = (rule, value, callback) => {
      if (!value) {
        callback();
      } else {
        let numTemp = value;
        let num = parseFloat(numTemp);
        if (num < 0 || num > 180) {
          callback(new Error('经度在0-180之间,请根据提示填写!'));
        } else {
          callback();
        }
      }
    };
    var checklt = (rule, value, callback) => {
      if (!value) {
        callback();
      } else {
        let numTemp = value;
        let num = parseFloat(numTemp);
        if (num < 0 || num > 90) {
          callback(new Error('经度在0-90之间,请根据提示填写!'));
        } else {
          callback();
        }
      }
    };
    const TREE_CONFIG = {
      treeProps: {
        children: 'children',
        label: 'name',
        isLeaf: 'isLeaf',
      },
      expandAll: false,
      defaultExpandedKeys: [],
      defaultData: {
        name: '',
        code: '',
        longitude: '',
        latitude: '',
      },
      // 当前选择节点
      curData: {
        id: 'root',
        name: '中国',
      },
      curNode: {},
      actionType: '',

      formRules: {
        name: [
          {
            required: true,
            message: '名称不能为空',
            trigger: 'change',
          },
        ],
        code: [
          {
            required: true,
            message: '编码不能为空',
            trigger: 'change',
          },
          { pattern: '^[0-9]+$', message: '编码为 12 到 15 位数字,请根据提示填写', trigger: 'change' },
          { min: 12, max: 15, message: '编码为 12 到 15 位数字,请根据提示填写', trigger: 'change' },
        ],
        longitude: [
          { validator: checkLg, trigger: 'blur' },
          { pattern: '^[0-9]+(.[0-9]{1,6})?$', message: '格式错误,请根据提示填写', trigger: 'change' },
        ],
        latitude: [
          { validator: checklt, trigger: 'blur' },
          { pattern: '^[0-9]+(.[0-9]{1,6})?$', message: '格式错误,请根据提示填写', trigger: 'change' },
        ],
      },
    };
    const TABLE_CONFIG = {
      // 列表表头
      columns: [
        { label: '行政区划名称', prop: 'name', align: 'center' },
        { label: '行政区划编码', prop: 'code', align: 'center' },
        { label: '经度', prop: 'key', align: 'center' },
        { label: '纬度', prop: 'key', align: 'center' },
        { label: '排序号', prop: 'sn', dataType: 'slot', slot: 'sn', align: 'center' },
      ],
      defaultFilter: [
        {
          operation: 'EQUAL',
          property: 'parentId',
          relation: 'AND',
          value: '',
        },
      ],
      rowData: {},
      selections: [],
      sequence: {},
    };
    const DIALOG_CONFIG = {
      dialogVisible: false,
      dialogTitle: '新增',
      fieldDialogVisible: false,
      dialogdData: {},
      drawerVisible: false,
      drawerTitle: '',
      parentRow: {},
    };

    return {
      treeData: [],
      ...TREE_CONFIG,
      ...TABLE_CONFIG,
      ...DIALOG_CONFIG,
      uploadVisible: false,
      uploadLoading: false,
      sorter: [
        {
          direction: 'ASC',
          property: 'sn_',
        },
      ],
    };
  },
  computed: {
    // 配置列表接口方法：只有配置了该计算属性 才会执行 table mixins中的getData方法
    dataMethod() {
      return API.getAreaList;
    },
  },
  methods: {
    getDictionaryByCode,
    async getTreeNodes(node, resolve) {
      if (node.level === 0) {
        return resolve([
          {
            code: 'China',
            fullId: '/root',
            fullName: '/China',
            children: [],
            hasChildren: 0,
            isLeaf: false,
            id: 'root',
            latitude: 0,
            levelCode: 'COUNTRY',
            longitude: 0,
            name: '中国',
            parentId: null,
            pkVal: '',
            sn: 0,
          },
        ]);
      } else if (node.data.id) {
        let params = this.qs.stringify({
          parentId: node.data.id,
        });
        API.queryAreaByParentId(params)
          .then((res) => {
            let treeData = res.map((item) => {
              item.isLeaf = item.hasChildren === 0 ? true : false;
              return item;
            });
            return resolve(treeData);
          })
          .finally(() => {});
      } else {
        resolve({});
      }
    },
    formatAreaTree(value) {
      return [];
    },

    reloadTree() {
      this.$refs.appAsyncTree.getTreeData();
    },

    /**
     * @description: treeActions支持函数也支持数组，由于实际场景当中 可能会动态设置按钮，故以函数示例来展示
     * @param {*} data 当前点击节点数据
     * @return {*} 当前节点展示的操作项数组
     */
    treeActions(data) {
      // 根节点判断方式以业务为准，此处仅为示例
      return [
        { label: '添加', type: 'add', method: this.addNode },
        {
          label: '编辑',
          type: 'edit',
          method: this.editNode,
          showHide: (row) => {
            return row.id !== 'root';
          },
        },
        {
          label: '删除',
          type: 'delete',
          method: this.delNode,
          showHide: (row) => {
            return row.id !== 'root';
          },
          tips: '及其子节点',
        },
      ];
    },
    onTreeNodeClick(data) {
      if (data.id === this.curData?.id) return;
      this.curData = { ...data };
      this.getData();
    },
    getLevenlCode(plevelcode) {
      let levelCode = '';
      switch (plevelcode) {
        case 'COUNTRY':
          levelCode = 'province';
          break;
        case 'province': //省
          levelCode = 'city';
          break;
        case 'city': //市
          levelCode = 'country';
          break;
        case 'country': //区县
          levelCode = 'town';
          break;
        case 'town': //乡镇
          levelCode = 'village';
          break;
        case 'village': //村
          break;
        default:
          levelCode = '';
          break;
      }
      return levelCode;
    },
    beforeActionsClick(action) {
      const { data, node, type } = action;
      const parentName = node?.parent?.data?.name || '';
      this.curData = { ...data, parentName };
      this.actionType = type;
    },
    async addNode(params, node) {
      const { code, name, latitude, longitude } = params;
      const { id, PlevelCode, pname } = node;
      const newNode = {
        parentId: id,
        code,
        name,
        latitude,
        longitude,
        levelCode: this.getLevenlCode(PlevelCode),
      };
      try {
        const { state, message } = await API.saveArea(newNode);
        if (state) {
          this.refreshTreeNode();
        } else {
          this.$message.warning(message || '添加区划失败！');
        }
      } catch (err) {
        this.$message.warning(err || '添加区划失败！');
      }
    },
    async editNode(params) {
      const newNode = {
        ...params,
      };
      try {
        const { state, message } = await API.saveArea(newNode);
        if (state) {
          this.refreshTreeNode(true);
        } else {
          this.$message.warning(message || '编辑区划失败！');
        }
      } catch (err) {
        this.$message.warning(err || '编辑区划失败！');
      }
    },
    async delNode(params, data) {
      let queryParams = 'ids=' + data.id;
      try {
        const { state, message } = await API.deleteArea(queryParams);
        if (state) {
          this.refreshTreeNode(true);
          this.$message.success('删除区划成功！');
        } else {
          this.$message.warning(message || '删除区划失败！');
        }
      } catch (err) {
        this.$message.warning(err || '删除区划失败！');
      }
    },
    // 列表 -----------------
    onBeforeGetData(queryParams, formData) {
      this.setFilterValue(this.queryParams, this.defaultFilter, 'parentId', this.curData.id);
    },
    handleSelectsChange(arr) {
      this.selections = arr;
    },
    addSubNode() {
      this.dialogTitle = '新增区划';
      this.currentRow = {
        code: '',
        name: '',
        parentId: this.curData.id,
        longitude: '',
        latitude: '',
      };
      this.dialogVisible = true;
    },
    editSubNode(row) {
      this.dialogTitle = `编辑 - ${row.name}`;
      this.currentRow = row;
      this.dialogVisible = true;
    },
    deleteSubNode() {
      this.$confirm(`此操作将删除选中区划, 是否继续?`, '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
      })
        .then(async () => {
          let ids = this.selections.map((item) => item.id);
          let data = 'ids=' + ids.join(',');
          try {
            const { state, message } = await API.deleteArea(data);
            if (state) {
              this.getData();
              this.refreshTreeNode();
              this.$message.success('删除区划成功！');
            } else {
              this.$message.warning(message || '删除区划失败！');
            }
          } catch (err) {
            this.$message.warning(err || '删除区划失败！');
          }
        })
        .catch(() => {});
    },
    updateSequence() {
      if (Object.keys(this.sequence).length) {
        API.updateSequence(this.sequence).then((res) => {
          if (res.state) {
            this.getData();
            this.$message({
              type: 'success',
              message: res.message,
            });
          }
        });
      } else {
        this.$message({
          type: 'warning',
          message: '保存号未修改',
        });
      }
    },
    handleChangeSequ(row) {
      this.sequence[row.id] = row.sn;
    },
    onDialogConfirm() {
      this.getData();
      this.refreshTreeNode();
    },

    refreshTreeNode(isParent = false) {
      const tree = this.$refs.appAsyncTree.getElTree();
      let node = isParent ? tree.getNode(this.curData.parentId) : tree.getNode(this.curData.id);
      if (node) {
        node.loaded = false;
        node.expand(); // 主动调用展开节点方法，重新查询该节点下的所有子节点
      }
    },
  },
};
</script>

<style lang="scss" scoped>
.tips {
  color: #aaa;
  font-style: normal;
}
</style>
