<template>
  <div class="full-size">
    <div class="main-header">
      <el-form inline :model="searchForm" @keyup.enter.native="search" @submit.native.prevent>
        <el-form-item>
          <el-select v-model="searchForm.policyType" placeholder="权限策略类型">
            <el-option label="全部" value=""></el-option>
            <el-option label="系统策略" value="system"></el-option>
            <el-option label="自定义策略" value="custom"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item>
          <el-input v-model.trim="searchForm.policyName" clearable placeholder="权限策略名称"></el-input>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" size="mini" @click="search" :disabled="loading">搜索</el-button>
        </el-form-item>
        <el-form-item class="right">
          <el-button v-permission="'policy:CreateInstance'"  @click.stop="toCreate" size="mini" icon="el-icon-plus" type="success">新建权限策略</el-button>
        </el-form-item>
      </el-form>
    </div>
    <div class="main-content">
      <div class="main-content-table-wrapper">
        <el-table ref="groupTable" :data="tableData" row-key="id" @row-click="tableCurrentChange" @selection-change="handleSelectionChange">
          <!--<el-table-column type="selection" width="45"></el-table-column>-->
          <el-table-column type="index" label="序号" width="50"></el-table-column>
          <el-table-column prop="policyName"  label="权限策略名称" width="250"></el-table-column>
          <el-table-column prop="description" label="备注"  width=""></el-table-column>
          <el-table-column prop="policyType" label="权限策略类型" width="180">
            <template slot-scope="scope">
              {{ scope.row.policyType | filterPolicyType }}
            </template>
          </el-table-column>
          <el-table-column prop="attachmentCount" label="被引用次数" width="120"></el-table-column>
        </el-table>
      </div>
      <div class="main-content-page">
        <el-pagination
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
          :current-page="pagination.currentPage"
          :page-size="pagination.pageSize" :page-sizes="$pagination.defaultPageSizes"
          :total="pagination.total"
          layout="prev, pager, next, total, sizes,  jumper"
          background>
        </el-pagination>
      </div>
    </div>

    <!--创建权限策略-->
    <transition name="slide-fade-form-panel">
      <slide-form-panel v-if="createPolicyFormShow">
        <div class="form-panel-title">
          <div class="form-panel-title-desc">
            <div class="form-panel-title-desc-button">
              <div v-permission="'user:ModifyInstanceStatusEnable'" class="plain-button" @click="createPolicy">
                <i class="font_family icon-check-circle plain-button-icon"></i><span class="plain-button-text">保存</span>
              </div>
            </div>
            <div class="form-panel-title-desc-text">新建自定义权限策略</div>
          </div>
          <div class="form-panel-title-close" @click="closeCreatePolicyForm"><i class="el-icon-close"></i></div>
        </div>
        <div class="form-panel-content-wrapper">
          <el-form ref="createPolicyForm"  label-width="120px" :model="policyForm"  :rules="policyFormRules" :inline-message="true">
            <el-form-item label="权限策略名称：" prop="policyName">
              <el-input v-model="policyForm.policyName"></el-input>
            </el-form-item>
            <el-form-item label="备注：">
              <el-input
                type="textarea"
                :autosize="{ minRows: 3, maxRows: 5}"
                placeholder=""
                v-model="policyForm.description">
              </el-input>
            </el-form-item>
          </el-form>
          <div class="policy-c">
            <div style="margin: 15px">
              <span class="policy-c-title">权限策略语法</span>
              <div style="height: 20px"></div>
              <el-button type="primary" size="mini" @click="searchDiv">选择权限策略语法模版</el-button>
              <div style="height: 20px"></div>
              <JsonEditor v-model="policyForm.document"></JsonEditor>
            </div>
          </div>
        </div>
      </slide-form-panel>
    </transition>

    <!--编辑权限策略-->
    <transition name="slide-fade-form-panel">
      <slide-form-panel v-if="editPolicyFormShow">
        <div class="form-panel-title">
          <div class="form-panel-title-desc">
            <div class="form-panel-title-desc-text">{{ policyForm.policyName }}</div>
            <div class="form-panel-title-desc-button">
              <div v-if="policyForm.policyType !== 'system'" class="plain-button" @click="toDeletePolicy(policyForm)">
                <i class="font_family icon-delete1 plain-button-icon"></i><span class="plain-button-text">删除</span>
              </div>
              <div v-if="policyForm.policyType !== 'system'" class="plain-button" @click="updatePolicy">
                <i class="font_family icon-check-circle plain-button-icon"></i><span class="plain-button-text">保存</span>
              </div>
              <div v-if="policyForm.policyType == 'system'" class="plain-button" @click="updateSystemPolicy">
                <i class="font_family icon-fund plain-button-icon"></i><span class="plain-button-text">刷新系统策略</span>
              </div>
            </div>
          </div>
          <div class="form-panel-title-close" @click="closeEditPolicyForm"><i class="el-icon-close"></i></div>
        </div>
        <div class="form-panel-content-wrapper" style="display: flex; flex-direction: column;">
          <el-form ref="policyForm"  label-width="120px" :model="policyForm"  :rules="policyFormRules" :inline-message="true">
            <el-form-item label="权限策略名称："  prop="policyName">
              {{ policyForm.policyName }}
              <!--<el-input readonly v-model="policyForm.policyName"></el-input>-->
            </el-form-item>
            <el-form-item label="权限策略类型：" prop="policyType">
                {{ policyForm.policyType | filterPolicyType }}
            </el-form-item>
            <el-form-item label="备注：">
              <template v-if="policyForm.policyType === 'system'">
                {{ policyForm.description }}
              </template>
              <el-input
                v-else
                type="textarea"
                :autosize="{ minRows: 3, maxRows: 5}"
                placeholder=""
                v-model="policyForm.description">
              </el-input>
            </el-form-item>
          </el-form>
          <el-tabs style="margin: 10px 0px; flex: 1; border: 1px solid #E4E4E4;overflow: hidden;background: white; padding: 10px;" v-model="activeTabName">
            <el-tab-pane lazy label="策略内容" name="document">
              <div v-if="policyForm.policyType !== 'system'">
                <el-button type="primary" size="mini" @click="searchDiv">选择权限策略语法模版</el-button>
                <div style="height: 20px"></div>
              </div>
              <div class="full-size" :style="{ pointerEvents : policyForm.policyType == 'system' ?  'none' : '' }">
                <JsonEditor v-model="policyForm.document"></JsonEditor>
              </div>
            </el-tab-pane>
            <el-tab-pane lazy label="引用记录" name="attachList">
              <div class="full-size">
                <el-table
                key="listAttachListTable"
                :data="attachList"
              >
                <el-table-column type="index" label="序号" width="50"></el-table-column>
                <el-table-column prop="principalId" label="被授权主体"></el-table-column>
                <el-table-column prop="principalType" label="主体类型">
                  <template slot-scope="scope">
                    {{ scope.row.principalType | filterPrincipalType }}
                  </template>
                </el-table-column>
                <el-table-column prop="attachTime" label="授权时间"></el-table-column>
                <el-table-column
                  label="操作"
                  min-width="80">
                  <template slot-scope="scope">
                    <el-button v-permission="'policy:DeletePolicyAttachment'" type="text" @click="removePolicyAttachment(scope.$index)" >移除权限</el-button>
                  </template>
                </el-table-column>
              </el-table>
              </div>
            </el-tab-pane>
          </el-tabs>
        </div>
      </slide-form-panel>
    </transition>
    <el-dialog :append-to-body="true" :modal="true" top="100px" :close-on-click-modal="false" v-if="showSelectPolicy" :visible.sync="showSelectPolicy">
      <div slot="title" class="custom-el-dialog-header-title">
        <span>选择权限策略语法模版</span>
        <div class="plain-button" @click="selectPolicy">
          <i class="font_family icon-save plain-button-icon"></i><span class="plain-button-text">&nbsp;选择</span>
        </div>
      </div>
      <div class="policy-s">
        <div v-for="(item, index) in allPolicyList" :key="item.id" class="policy-s-i">
          <el-radio v-model="selectAttachment" :label="index">{{ item.policyName }}</el-radio>
          <div class="policy-s-i-d">{{ item.description }}</div>
        </div>
      </div>
    </el-dialog>
  </div>
</template>

<script>
export default {
  name: 'Policy',
  data () {
    return {
      cmOptions: {
        // codemirror options
        tabSize: 4,
        lineNumbers: true,
        line: true,
        cursorHeight: 0.8,
        viewportMargin: Infinity,
        autofocus: false,
        pollInterval: 2000
      },
      selectAttachment: '',
      tenantId: this.$util.getTenantId(),
      showSelectPolicy: false,
      createPolicyFormShow: false,
      createPolicyComplete: false,
      editPolicyFormShow: false,
      isDisplayMoreSearch: true, // 是否显示更多搜索
      currentRow: null,
      nowSelectChangeRows: [],
      pagination: {
        currentPage: 1,
        pageSize: 20,
        total: 0
      },
      lastSearchForm: '',
      searchForm: {
        policyType: '',
        policyName: ''
      },
      policyForm: {
        id: '',
        policyName: '',
        policyType: '',
        description: '',
        document: ''
      },
      policyFormRules: {
        policyName: [
          { required: true, message: '请输入权限策略名称' },
          // { pattern: /^[a-zA-Z]{1}[a-zA-Z\d_.-]{0,29}$/, message: '名称以字母开头，英文字母、数字、“.”、“_”或“-”， 1-30位' },
          { min: 1, max: 30, message: '长度在 1 到 30 个字符' }
        ]
      },
      activeTabName: 'document',
      ruleForm: {},
      tableData: [],
      loading: false,
      saving: false,
      addData: {},
      attachList: [],
      allPolicyList: []
    }
  },
  computed: {
  },
  filters: {
    filterPolicyType: function (value) {
      return value === 'system' ? '系统策略' : '自定义策略'
    },
    filterPrincipalType: function (value) {
      return value === 'user' ? '用户' : '用户组'
    }
  },
  created () {
    this.listAllPolicy()
  },
  mounted () {
    this.search()
  },
  methods: {
    listAllPolicy () {
      this.$http.get(this.$apiUrl('listAllPolicy'))
        .then(response => {
          this.allPolicyList = response.data.data
        })
        .catch((error) => {
          this.$message.error(error.message)
        })
    },
    handleSizeChange (val) {
      this.pagination.pageSize = val
      this.search()
      console.log(`每页 ${val} 条`)
    },
    handleCurrentChange (val) {
      this.pagination.currentPage = val
      this.search()
      console.log(`当前页: ${val}`)
    },
    selectPolicy () {
      this.policyForm.document = JSON.parse(this.allPolicyList[this.selectAttachment].document)
      this.showSelectPolicy = false
    },
    searchDiv () {
      this.selectAttachment = ''
      this.showSelectPolicy = true
    },
    search () {
      this.loading = true
      // 变更检索条件，设置到第一页
      const _lastSearchForm = this.$qs.stringify(this.searchForm)
      if (this.lastSearchForm !== _lastSearchForm) {
        this.pagination.currentPage = 1
      }
      this.lastSearchForm = _lastSearchForm

      this.$http.get(this.$apiUrl('listPolicy') + `?page=${this.pagination.currentPage - 1}&size=${this.pagination.pageSize}&${_lastSearchForm}`)
        .then(response => {
          this.tableData = response.data.data
          console.log(this.tableData)
          // 重新设置总页数
          this.pagination.total = response.data.total
        })
        .catch((error) => {
          console.dir(error)
          this.$message.error(error.message)
        }).always(() => {
          this.loading = false
        })
    },
    toCreate () {
      this.resetForm()
      this.showCreatePolicyForm()
    },
    updatePolicy () {
      this.$refs.policyForm && this.$refs.policyForm.validate((valid) => {
        if (valid) {
          this.saving = true
          // 更新权限策略
          this.$http.put(this.$apiUrl('updatePolicy'), this.$qs.stringify(this.policyForm))
            .then(response => {
              this.$message.success('修改成功')
              this.closeEditPolicyForm()
              this.search()
            })
            .catch(error => {
              if (error.response) {
                this.$message.error(`修改失败! ${error.response.data.message}`)
              } else {
                this.$message.error(`修改失败! ${error.message}`)
              }
            })
            .always(() => {
              this.saving = false
            })
        } else {
          return false
        }
      })
    },
    isJsonString (str) {
      try {
        if (typeof JSON.parse(str) === 'object') {
          return true
        }
      } catch (e) {
      }
      return false
    },
    // 创建权限策略
    createPolicy () {
      this.$refs.createPolicyForm.validate((valid) => {
        if (valid) {
          if (!this.isJsonString(this.policyForm.document)) {
            this.$message.warning('策略内容不合法，请检查是否合法json')
            return
          }
          this.saving = true
          this.$http.post(this.$apiUrl('createPolicy'), this.policyForm)
            .then(response => {
              this.$message.success('创建成功')
              this.createPolicyComplete = true
              this.policyForm.id = response.data.data.id
              this.closeCreatePolicyForm()
              this.search()
            })
            .catch(error => {
              if (error.response) {
                this.$message.error(`创建失败! ${error.response.data.message}`)
              } else {
                this.$message.error(`创建失败! ${error.message}`)
              }
            })
            .always(() => {
              this.saving = false
            })
        }
      })
    },
    updateSystemPolicy () {
      this.$http.put(this.$apiUrl('updateSystemPolicy'))
        .then(response => {
          this.$message.success('同步完成')
          this.closeEditPolicyForm()
          this.search()
        })
        .catch((error) => {
          this.$message.error(error.message)
        })
    },
    // 删除权限策略
    toDeletePolicy (selection) {
      if (!selection.id && selection.length === 0) {
        this.$message.warning('请选择要删除的权限策略')
      } else {
        this.$confirm('删除权限策略将删除所有用户及用户组的授权, 是否确认?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
          this.deletePolicy(selection)
        })
      }
    },
    deletePolicy (selection) {
      let _id = selection.id
      if (Array.isArray(selection)) {
        _id = selection.map(row => row.id).join(',')
      }
      this.$http.delete(this.$apiUrl('deletePolicy') + `?id=${_id}`)
        .then(response => {
          this.$message.success('删除成功!')
          this.closeEditPolicyForm()
          this.search()
        })
        .catch((error) => {
          if (error.response) {
            this.$message.error(`删除失败! ${error.response.data.message}`)
          } else {
            this.$message.error(`删除失败! ${error.message}`)
          }
        })
    },
    toEditPolicy () {
      if (!this.currentRow) {
        this.$message.warning('请选择要编辑的权限策略')
      } else {
        this.closeEditPolicyForm()
        this.$nextTick(() => {
          Object.keys(this.policyForm).forEach(k => {
            this.policyForm[k] = this.currentRow[k]
          })
          this.showEditPolicyForm()
          this.loadPolicyAttachList()
        })
      }
      this.clearValidate()
    },
    loadPolicyAttachList () {
      this.$http.get(this.$apiUrl('getAttachmentsPolicy') + `?id=${this.policyForm.id}`)
        .then(response => {
          this.attachList = response.data.data
        })
        .catch((error) => {
          this.$message.error(error.message)
        })
    },
    removePolicyAttachment (index) {
      const id = [this.attachList[index].id]
      const url = this.$apiUrl('deleteAttachmentOfPolicy') + `?id=${id}`
      this.$http.delete(url)
        .then(response => {
          this.$message.success('移除成功')
          this.attachList.splice(index, 1)
        })
        .catch(error => {
          this.$message.error(`移除失败! ${error.message}`)
        })
    },
    showCreatePolicyForm () {
      this.createPolicyFormShow = true
      this.editPolicyFormShow = false
    },
    closeCreatePolicyForm () {
      this.createPolicyFormShow = false
    },
    showEditPolicyForm () {
      this.editPolicyFormShow = true
      this.createPolicyFormShow = false
    },
    closeEditPolicyForm () {
      this.editPolicyFormShow = false
    },
    // 清空form表单
    resetForm () {
      this.$resetToEmpty(this.policyForm)
      this.saving = false
    },
    clearValidate () {
      // 移除整个表单的校验结果
      this.$nextTick(() => {
        this.$refs.policyForm && this.$refs.policyForm.clearValidate()
      })
    },
    handleSelectionChange (val) {
      this.nowSelectChangeRows = val
    },
    tableCurrentChange (currentRow, oldCurrentRow) {
      this.currentRow = currentRow
      if (this.currentRow) this.toEditPolicy()
    }
  }
}
</script>
<style lang="scss" scoped>
  @import '../../style/mixin';
  .table-height-auto.el-table {
    height: auto !important;
  }
  .policy-c {
    height: 500px;
    margin-top: 20px;
    border: 1px solid #e4e4e4;
    .policy-c-title {
      width: 84px;
      height: 19px;
      opacity: 1;
      font-size: 14px;
      font-family: MicrosoftYaHei, MicrosoftYaHei-Bold;
      font-weight: 700;
      text-align: left;
      color: #666666;
      line-height: 19px;
    }
  }
  .policy-s {
    height: 100%;
    max-height: 650px;
    overflow-y: auto;
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    .policy-s-i {
      width: 44%;
      height: 86px;
      opacity: 1;
      background: #ffffff;
      border: 1px solid #e4e4e4;
      border-radius: 5px;
      margin-right: 15px;
      margin-bottom: 15px;
      padding: 15px;
      .policy-s-i-d {
        height: 16px;
        opacity: 1;
        font-size: 12px;
        font-family: MicrosoftYaHei;
        text-align: left;
        color: #999999;
        line-height: 16px;
        padding: 10px;
      }
    }
  }
</style>
