<template>
  <div class="customer-css">
    <!-- 查询条件 -->
    <el-form :inline="true" label-position="top" class="pi-search-form">
      <el-form-item label="字典名称">
        <el-input v-model="typeSearch.dictName" clearable placeholder="字典名称" style="width:160px" @keyup.enter.native="loadTypeList" />
      </el-form-item>
      <el-form-item label="字典类型">
        <el-input v-model="typeSearch.dictType" clearable placeholder="字典类型" style="width:200px" @keyup.enter.native="loadTypeList" />
      </el-form-item>
      <el-form-item label="状态">
        <el-select v-model="typeSearch.status" clearable placeholder="请选择" style="width:100px">
          <el-option label="全部" value="" />
          <el-option label="启用" value="Y" />
          <el-option label="停用" value="N" />
        </el-select>
      </el-form-item>
      <el-form-item label=" ">
        <el-button type="primary" class="customer-bun-min" @click="loadTypeList">查询</el-button>
      </el-form-item>
    </el-form>

    <!-- 主表：字典类型（系统配置，只读） -->
    <el-table
      ref="typeTable"
      :data="typeList"
      :height="tableHeight"
      border
      highlight-current-row
      v-loading="typeLoading"
      style="width:100%"
      @row-click="selectDictType">
<!--      <el-table-column prop="dictType" label="字典类型" min-width="120" header-align="center" align="left" show-overflow-tooltip />-->
      <el-table-column prop="dictName" label="字典名称" min-width="120" header-align="center" align="left" show-overflow-tooltip />
      <el-table-column prop="status" label="状态" width="80" header-align="center" align="center">
        <template slot-scope="scope">
          {{ scope.row.status === 'Y' ? '启用' : '停用' }}
        </template>
      </el-table-column>
      <el-table-column label="操作" width="70" fixed="right" header-align="center" align="center">
        <template slot-scope="scope">
          <el-link
            v-if="canDeleteType(scope.row)"
            style="cursor:pointer"
            @click.stop="handleDeleteType(scope.row)">删除</el-link>
          <span v-else>-</span>
        </template>
      </el-table-column>
      <el-table-column prop="remark" label="备注" min-width="300" header-align="center" align="left" show-overflow-tooltip />
<!--      <el-table-column prop="createBy" label="创建人" width="100" header-align="center" align="center" />-->
<!--      <el-table-column prop="createDate" label="创建时间" min-width="140" header-align="center" align="center" />-->
    </el-table>

    <el-pagination
      style="margin-top:5px"
      @size-change="typeSizeChange"
      @current-change="typePageChange"
      :current-page="typePageIndex"
      :page-sizes="[20, 50, 100]"
      :page-size="typePageSize"
      :total="typeTotal"
      layout="total, sizes, prev, pager, next, jumper" />

    <!-- 子表：字典明细 -->
    <div class="sub-title">
      字典明细列表
      <el-button
        type="primary"
        class="customer-bun-min"
        style="margin-left:10px"
        :disabled="!currentType.dictType"
        @click="openDataDialog()">
        新增明细
      </el-button>
    </div>

    <el-form :inline="true" label-position="top" class="pi-search-form" style="margin-top:0">
      <el-form-item label="字典标签">
        <el-input v-model="dataSearch.dictLabel" clearable placeholder="标签" style="width:160px" @keyup.enter.native="loadDataList" />
      </el-form-item>
      <el-form-item label="作用范围">
        <el-select v-model="dataSearch.scope" clearable placeholder="请选择" style="width:120px" @change="applyDataFilterAndPage">
          <el-option label="全部" value="" />
          <el-option label="所有工厂" value="all" />
          <el-option label="当前工厂" value="current" />
        </el-select>
      </el-form-item>
      <el-form-item label="状态">
        <el-select v-model="dataSearch.status" clearable placeholder="请选择" style="width:100px">
          <el-option label="全部" value="" />
          <el-option label="启用" value="Y" />
          <el-option label="停用" value="N" />
        </el-select>
      </el-form-item>
      <el-form-item label=" ">
        <el-button type="primary" class="customer-bun-min" :disabled="!currentType.dictType" @click="loadDataList">查询</el-button>
      </el-form-item>
    </el-form>

    <el-table
      :data="dataList"
      :height="subTableHeight"
      border
      v-loading="dataLoading"
      style="width:100%">
      <el-table-column fixed="right" label="操作" header-align="center" align="center" width="160">
        <template slot-scope="scope">
          <el-link style="cursor:pointer" @click="openDataDialog(scope.row)">编辑 |</el-link>
          <el-link style="cursor:pointer" @click="handleDeleteData(scope.row)">删除 |</el-link>
          <el-link style="cursor:pointer" @click="handleDisableData(scope.row)">停用</el-link>
        </template>
      </el-table-column>
      <el-table-column prop="dictLabel" label="字典标签" min-width="120" header-align="center"  align="left" show-overflow-tooltip />
      <el-table-column prop="dictValue" label="字典键值" min-width="120" header-align="center" align="left" show-overflow-tooltip />
      <el-table-column label="作用范围" width="80" header-align="center" align="center">
        <template slot-scope="scope">
          {{ formatDataScope(scope.row.site) }}
        </template>
      </el-table-column>
      <el-table-column prop="dictSort" label="排序" width="60" header-align="center" align="center" />
      <el-table-column prop="status" label="状态" width="80" header-align="center" align="center">
        <template slot-scope="scope">
          {{ scope.row.status === 'Y' ? '启用' : '停用' }}
        </template>
      </el-table-column>
      <el-table-column prop="isDefault" label="默认" width="70" header-align="center" align="center">
        <template slot-scope="scope">
          {{ scope.row.isDefault === 'Y' ? '是' : '否' }}
        </template>
      </el-table-column>
      <el-table-column prop="remark" label="备注" min-width="300" header-align="center" align="left" show-overflow-tooltip />
      <el-table-column prop="createBy" label="创建人" width="100" header-align="center" align="center" />
      <el-table-column prop="createDate" label="创建时间" min-width="140" header-align="center" align="center" />
    </el-table>

    <el-pagination
      style="margin-top:5px"
      @size-change="dataSizeChange"
      @current-change="dataPageChange"
      :current-page="dataPageIndex"
      :page-sizes="[20, 50, 100, 200]"
      :page-size="dataPageSize"
      :total="dataTotal"
      layout="total, sizes, prev, pager, next, jumper" />

    <div v-if="dataList.length === 0 && !dataLoading" style="margin-top:8px;color:#909399;font-size:12px;text-align:center">
      {{ currentType.dictType ? '暂无字典明细' : '请点击上方字典类型查看明细' }}
    </div>

    <!-- 字典明细弹窗 -->
    <el-dialog
      :title="dataDialogTitle"
      :visible.sync="dataDialogVisible"
      width="420px"
      :close-on-click-modal="false"
      append-to-body
      v-drag
      @close="resetDataForm">
      <el-form ref="dataFormRef" label-position="top" :model="dataForm" :rules="dataRules">
        <el-form-item label="字典类型">
          <el-input v-model="dataForm.dictType" disabled />
        </el-form-item>
        <el-form-item label="作用范围" prop="dataScope">
          <el-select v-model="dataForm.dataScope" :disabled="dataEditMode" placeholder="请选择" style="width:100%">
            <el-option label="所有工厂" value="all" />
            <el-option label="当前工厂" value="current" />
          </el-select>
        </el-form-item>
        <el-form-item label="字典标签" prop="dictLabel">
          <el-input v-model="dataForm.dictLabel" @blur="dictLabel()" maxlength="255" />
        </el-form-item>
        <el-form-item label="字典键值" prop="dictValue">
          <el-input v-model="dataForm.dictValue" :disabled="dataEditMode" maxlength="255" />
        </el-form-item>
        <el-form-item label="排序" prop="dictSort">
          <el-input-number v-model="dataForm.dictSort" :min="0" :controls="false" style="width:100%" />
        </el-form-item>
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="状态" prop="status">
              <el-radio-group v-model="dataForm.status">
                <el-radio label="Y">启用</el-radio>
                <el-radio label="N">停用</el-radio>
              </el-radio-group>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label=" ">
              <el-checkbox v-model="dataForm.isDefault" true-label="Y" false-label="N">默认</el-checkbox>
            </el-form-item>
          </el-col>
        </el-row>
        <el-form-item label="备注">
          <el-input v-model="dataForm.remark" type="textarea" :rows="2" />
        </el-form-item>
      </el-form>
      <el-footer style="height:30px;margin-top: 30px;text-align:center">
        <el-button type="primary" :loading="dataSubmitLoading" @click="submitDataForm">保存</el-button>
        <el-button @click="dataDialogVisible = false">取消</el-button>
      </el-footer>
    </el-dialog>
  </div>
</template>

<script>
import {
  listDictMaintenanceType,
  listDictMaintenanceData,
  saveDictMaintenanceData,
  updateDictMaintenanceData,
  deleteDictMaintenanceData,
  disableDictMaintenanceData,
  deleteDictMaintenanceType
} from '@/api/base/dictMaintenance'

const ALL_SITE = '*'

export default {
  name: 'DictMaintenance',
  data () {
    const userSite = this.$store.state.user.site
    return {
      userSite,
      tableHeight: 200,
      subTableHeight: 200,
      typeLoading: false,
      dataLoading: false,
      dataSubmitLoading: false,
      typeList: [],
      dataList: [],
      dataListAll: [],
      typePageIndex: 1,
      typePageSize: 20,
      typeTotal: 0,
      dataPageIndex: 1,
      dataPageSize: 20,
      dataTotal: 0,
      typeSearch: {
        dictName: '',
        dictType: '',
        status: ''
      },
      dataSearch: {
        dictLabel: '',
        scope: '',
        status: ''
      },
      currentType: {},
      dataDialogVisible: false,
      dataDialogTitle: '新增字典明细',
      dataEditMode: false,
      dataForm: this.buildEmptyDataForm(),
      dataRules: {
        dataScope: [{ required: true, message: ' ', trigger: 'change' }],
        dictLabel: [{ required: true, message: ' ', trigger: 'blur' }],
        dictValue: [{ required: true, message: ' ', trigger: 'blur' }],
        dictSort: [{ required: true, type: 'number', message: ' ', trigger: 'blur' }],
        status: [{ required: true, message: ' ', trigger: 'change' }]
      }
    }
  },
  mounted () {
    this.calcHeight()
    window.addEventListener('resize', this.calcHeight)
    this.loadTypeList()
  },
  beforeDestroy () {
    window.removeEventListener('resize', this.calcHeight)
  },
  methods: {
    buildEmptyDataForm () {
      return {
        dictCode: undefined,
        dictLabel: '',
        dictValue: '',
        dictType: '',
        dictSort: 1,
        isDefault: 'N',
        status: 'Y',
        remark: '',
        site: ALL_SITE,
        dataScope: 'all',
        createBy: this.$store.state.user.name,
        updateBy: this.$store.state.user.name
      }
    },
    formatDataScope (site) {
      return site === ALL_SITE ? '所有工厂' : '当前工厂'
    },
    resolveDataSite (scope) {
      return scope === 'current' ? this.userSite : ALL_SITE
    },
    buildQueryParams (extra = {}) {
      return {
        site: this.userSite,
        ...extra
      }
    },
    applyDataFilterAndPage () {
      let rows = [...this.dataListAll]
      if (this.dataSearch.scope === 'all') {
        rows = rows.filter(r => r.site === ALL_SITE)
      } else if (this.dataSearch.scope === 'current') {
        rows = rows.filter(r => r.site === this.userSite)
      }
      rows.sort((a, b) => (a.dictSort || 0) - (b.dictSort || 0))
      this.dataTotal = rows.length
      const start = (this.dataPageIndex - 1) * this.dataPageSize
      this.dataList = rows.slice(start, start + this.dataPageSize)
    },
    calcHeight () {
      this.$nextTick(() => {
        const h = (window.innerHeight - 320) / 2
        this.tableHeight = h > 180 ? h : 180
        this.subTableHeight = h > 180 ? h : 180
      })
    },
    loadTypeList () {
      this.typeLoading = true
      listDictMaintenanceType(this.buildQueryParams({
        dictName: this.typeSearch.dictName,
        dictType: this.typeSearch.dictType,
        status: this.typeSearch.status
      })).then(({ data }) => {
        if (data && data.code === 0) {
          const rows = this.normalizeTypeRows(data.rows || [])
          this.applyTypeListResult(rows, rows.length)
        } else {
          this.$message.error((data && data.msg) || '查询字典类型失败')
        }
      }).catch(() => {
        this.$message.error('查询字典类型失败')
      }).finally(() => {
        this.typeLoading = false
      })
    },
    applyTypeListResult (rows, total) {
      const start = (this.typePageIndex - 1) * this.typePageSize
      this.typeList = rows.slice(start, start + this.typePageSize)
      this.typeTotal = total
      if (this.typeList.length > 0) {
        const currentId = this.currentType.dictId
        const matched = currentId ? this.typeList.find(r => r.dictId === currentId) : null
        const row = matched || this.typeList[0]
        this.$nextTick(() => {
          this.$refs.typeTable && this.$refs.typeTable.setCurrentRow(row)
        })
        this.selectDictType(row)
      } else {
        this.currentType = {}
        this.dataList = []
        this.dataTotal = 0
      }
    },
    dictLabel(){
      this.dataForm.dictValue = JSON.parse(JSON.stringify(this.dataForm.dictLabel));
    },
    normalizeTypeRows (rows) {
      if (!Array.isArray(rows)) {
        return []
      }
      return rows.map(row => this.normalizeTypeRow(row))
    },
    normalizeTypeRow (row) {
      const normalized = { ...(row || {}) }
      normalized.dictId = normalized.dictId != null ? normalized.dictId : normalized.dict_id
      normalized.dictType = this.firstText(
        normalized.dictType,
        normalized.dict_type
      )
      normalized.status = this.normalizeStatus(
        this.firstText(normalized.status, normalized.STATUS, normalized.active)
      )
      normalized.createBy = this.firstText(normalized.createBy, normalized.create_by)
      normalized.site = this.firstText(normalized.site, normalized.SITE)
      normalized.remark = this.firstText(normalized.remark)
      normalized.dictName = this.resolveTypeDisplayName(normalized)
      return normalized
    },
    resolveTypeDisplayName (row) {
      const direct = this.firstText(row && row.dictName, row && row.dict_name)
      if (direct && !this.isStatusText(direct)) {
        return direct
      }
      const remark = this.firstText(row && row.remark)
      if (remark) {
        const sep = remark.indexOf('-')
        if (sep > 0) {
          const prefix = remark.substring(0, sep).trim()
          if (prefix && !this.isStatusText(prefix)) {
            return prefix
          }
        }
        if (!this.isStatusText(remark)) {
          return remark
        }
      }
      return this.firstText(row && row.dictType, row && row.dict_type)
    },
    normalizeStatus (raw) {
      const text = this.firstText(raw)
      if (!text) {
        return ''
      }
      const upper = text.toUpperCase()
      if (upper === 'Y' || text === '启用') {
        return 'Y'
      }
      if (upper === 'N' || text === '停用') {
        return 'N'
      }
      return text
    },
    isStatusText (text) {
      const val = this.firstText(text)
      if (!val) {
        return false
      }
      const upper = val.toUpperCase()
      return upper === 'Y' || upper === 'N' || val === '启用' || val === '停用'
    },
    firstText (...vals) {
      for (const val of vals) {
        if (val === null || val === undefined) {
          continue
        }
        const text = String(val).trim()
        if (text) {
          return text
        }
      }
      return ''
    },
    selectDictType (row) {
      if (!row || !row.dictType) return
      this.currentType = { ...row }
      this.dataPageIndex = 1
      this.loadDataList()
    },
    loadDataList () {
      if (!this.currentType.dictType) {
        this.dataList = []
        this.dataListAll = []
        this.dataTotal = 0
        return
      }
      this.dataLoading = true
      listDictMaintenanceData(this.buildQueryParams({
        dictType: this.currentType.dictType,
        dictLabel: this.dataSearch.dictLabel,
        status: this.dataSearch.status
      })).then(({ data }) => {
        if (data && data.code === 0) {
          this.dataListAll = data.rows || []
          this.dataPageIndex = 1
          this.applyDataFilterAndPage()
        } else {
          this.$message.error((data && data.msg) || '查询字典明细失败')
        }
      }).catch(() => {
        this.$message.error('查询字典明细失败')
      }).finally(() => {
        this.dataLoading = false
      })
    },
    canDeleteType (row) {
      return !!(row && row.createBy === '订单扩展字段')
    },
    handleDeleteType (row) {
      if (!row || !row.dictType) {
        return
      }
      if (!this.canDeleteType(row)) {
        this.$message.warning('仅支持删除“订单扩展字段”自动维护的字典类型')
        return
      }
      const label = row.dictName || row.dictType
      this.$confirm('确定删除字典类型「' + label + '」及其明细数据吗？', '提示', { type: 'warning' }).then(() => {
        deleteDictMaintenanceType({
          dictId: row.dictId,
          dictType: row.dictType,
          site: row.site
        }).then(({ data }) => {
          if (data && data.code === 0) {
            this.$message.success(data.msg || '删除成功')
            this.currentType = {}
            this.dataList = []
            this.dataListAll = []
            this.dataTotal = 0
            this.loadTypeList()
          } else {
            this.$message.error((data && data.msg) || '删除失败')
          }
        }).catch(err => {
          this.$message.error((err && err.message) || '删除失败')
        })
      }).catch(() => {})
    },
    typeSizeChange (val) {
      this.typePageSize = val
      this.typePageIndex = 1
      this.loadTypeList()
    },
    typePageChange (val) {
      this.typePageIndex = val
      this.loadTypeList()
    },
    dataSizeChange (val) {
      this.dataPageSize = val
      this.dataPageIndex = 1
      this.applyDataFilterAndPage()
    },
    dataPageChange (val) {
      this.dataPageIndex = val
      this.applyDataFilterAndPage()
    },
    openDataDialog (row) {
      if (!this.currentType.dictType) {
        this.$message.warning('请先选择字典类型')
        return
      }
      if (row) {
        this.dataEditMode = true
        this.dataDialogTitle = '编辑字典明细'
        this.dataForm = {
          ...row,
          dataScope: row.site === ALL_SITE ? 'all' : 'current',
          updateBy: this.$store.state.user.name
        }
      } else {
        this.dataEditMode = false
        this.dataDialogTitle = '新增字典明细'
        this.dataForm = {
          ...this.buildEmptyDataForm(),
          dictType: this.currentType.dictType,
          dictSort: (this.dataListAll.length + 1) || 1
        }
      }
      this.dataDialogVisible = true
    },
    resetDataForm () {
      this.$refs.dataFormRef && this.$refs.dataFormRef.resetFields()
      this.dataForm = this.buildEmptyDataForm()
    },
    submitDataForm () {
      this.$refs.dataFormRef.validate(valid => {
        if (!valid) {
          this.$message.warning('请填写完整字典明细信息')
          return
        }
        this.dataForm.site = this.resolveDataSite(this.dataForm.dataScope)
        this.dataSubmitLoading = true
        const api = this.dataEditMode ? updateDictMaintenanceData : saveDictMaintenanceData
        api(this.dataForm).then(({ data }) => {
          if (data && data.code === 0) {
            this.$message.success(data.msg || '保存成功')
            this.dataDialogVisible = false
            this.loadDataList()
          } else {
            this.$message.error((data && data.msg) || '保存失败')
          }
        }).catch(err => {
          this.$message.error(err.message || '保存失败')
        }).finally(() => {
          this.dataSubmitLoading = false
        })
      })
    },
    handleDeleteData (row) {
      if (row.isSystem === 'Y') {
        this.$message.warning('系统字典不可删除')
        return
      }
      this.$confirm('确定删除字典明细「' + row.dictLabel + '」吗？', '提示', { type: 'warning' }).then(() => {
        deleteDictMaintenanceData(row).then(({ data }) => {
          if (data && data.code === 0) {
            this.$message.success(data.msg || '删除成功')
            this.loadDataList()
          } else {
            this.$message.error((data && data.msg) || '删除失败')
          }
        })
      }).catch(() => {})
    },
    handleDisableData (row) {
      if (row.isSystem === 'Y') {
        this.$message.warning('系统字典不可停用')
        return
      }
      this.$confirm('确定停用字典明细「' + row.dictLabel + '」吗？', '提示', { type: 'warning' }).then(() => {
        disableDictMaintenanceData(row).then(({ data }) => {
          if (data && data.code === 0) {
            this.$message.success(data.msg || '操作成功')
            this.loadDataList()
          } else {
            this.$message.error((data && data.msg) || '操作失败')
          }
        })
      }).catch(() => {})
    }
  }
}
</script>

<style scoped>
.pi-search-form { margin-top: 0; }
.sub-title {
  font-weight: 600;
  margin: 16px 0 8px 0;
  padding-left: 4px;
  border-left: 4px solid #409eff;
  line-height: 1.2;
  color: #303133;
}
.customer-bun-min {
  margin-right: 8px;
}
.dialog-footer {
  text-align: center;
}
</style>
