<template>
  <div class="app-container">
    <el-row class="m-t-0" :gutter="10">
      <!-- 分类树窗口 -->
      <el-col :span="10" :xs="24" class="m-b-10">
        <el-container>
          <el-header height="42px" class="l-h-42 p-l-10 p-r-10 border border-b-n">
            <div class="l">
              <i class="iconfont icon-a-ziliaocaozuoxianshifenleishu f-s-20"></i>
              <font class="m-l-10 f-s-18 fb">分类树</font>
            </div>
          </el-header>
          <el-main class="border p-20">
            <!-- 用户select选项 -->
            <el-button-group class="m-b-10">
              <SelectionShopId v-model="form.shop_id" />
            </el-button-group>
            <!-- 分类树 -->
            <div>
              <el-button type="text" @click="openWin('添加根分类', { id: 0, path: '', photo: '' })">
                添加根分类
              </el-button>
            </div>
            <el-tree :data="categoryListData" :default-expand-all="true">
              <span class="custom-tree-node" slot-scope="{ data }">
                <span :class="data.show == 0 ? 'hideColor' : ''">{{ data.name }}</span>
                <span>
                  <el-button type="text" @click.stop=""
                    @click="openWin(`${data.name} : 添加子分类`, { id: data.id, path: data.path, photo: '' })" disabled>
                    添加子分类
                  </el-button>
                  <el-button type="text" class="textEditBut" @click.stop="" @click="openWin(`${data.name} : 编辑`, data)">
                    编辑
                  </el-button>
                  <el-button type="text" class="textDelBut" @click.stop="" @click="delCategory(data.id)">
                    删除
                  </el-button>
                </span>
              </span>
            </el-tree>
            <!-- END 分类树 -->
          </el-main>
        </el-container>
      </el-col>
      <!-- 分类操作窗口 -->
      <el-col v-if="winIsShow" :span="14" :xs="24" class="m-b-20">
        <el-container>
          <el-header height="42px" class="l-h-42 p-l-10 p-r-10 border border-b-n">
            <div class="l">
              <template v-if="winTitle.indexOf('添加') > -1">
                <i class=" iconfont el-icon-plus f-s-20"></i>
              </template>
              <template v-else>
                <i class=" iconfont el-icon-edit f-s-20"></i>
              </template>
              <font class="m-l-10 f-s-18 fb">{{ winTitle }}</font>
            </div>
          </el-header>
          <el-main class="border p-20">
            <el-form ref="form" :model="form" label-width="120px" :label-position="$store.state.app.isWideScreen?'top':'right'">
              <el-form-item label="分类名称">
                <el-input v-model="form.name" placeholder="分类的名称" />
              </el-form-item>
              <el-form-item label="排序">
                <el-input v-model="form.sort" placeholder="数值大排在前面,缺省值为0" />
              </el-form-item>
              <el-form-item :label="form.show === true ? '前台显示' : '前台隐藏'">
                <el-switch v-model="form.show" />
              </el-form-item>
              <el-form-item label="图标上传">
                <el-upload class="avatar-uploader" drag name="file" :action="action" :headers="myheader"
                  :show-file-list="false" :on-success="handleUpSuccess" :on-error="handleUpErr"
                  :before-upload="beforeAvatarUpload">
                  <img v-if="form.upFile != ''"
                    :src="$store.state.settings.tempPath + form.upFile" class="avatar" />
                  <img v-else-if="form.oldFile != [] && form.upFile == ''"
                    :src="form.oldFile[0]" class="avatar" />
                  <template v-else>
                    <i class="el-icon-plus f-s-30 m-t-70 seatFontColor"></i>
                    <div class="el-upload__text"><em>建议40*40像素 <br>svg jpg png gif </em></div>
                  </template>
                </el-upload>
              </el-form-item>
              <el-form-item label="分类描述">
                <el-input v-model="form.desc" type="textarea" placeholder="非必填" />
              </el-form-item>
              <el-form-item v-if="winTitle.indexOf('添加') > -1 ? true : false">
                <el-button type="primary" icon="el-icon-plus" @click="addCategory">创建</el-button>
                <el-button @click="setForm({})" class="iconfont icon-qingchu">
                  <font class="m-l-5">重填</font>
                </el-button>
              </el-form-item>
              <el-form-item v-else>
                <el-button type="primary" icon="el-icon-edit" @click="saveCategory">更新</el-button>
              </el-form-item>
            </el-form>
          </el-main>
        </el-container>
      </el-col>
    </el-row>
  </div>
</template>

<script>
import SelectionShopId from '@/components/SelectionShopId'

export default {
  name: 'Category',
  data () {
    return {
      action: this.$store.state.settings.baseURL + this.$store.state.settings.apiAdminPath + 'upImgFile',
      myheader: { token: this.$store.state.user.token },
      form: {
        shop_id: '',
        id: '',
        pid: '',
        path: '',
        name: '',
        sort: '',
        show: false,
        upFile: '',
        oldFile: [],
        desc: ''
      },
      isStartDel: false,
      delIdArr: [],
      categoryListData: [], // 分类树结构 数据
      winIsShow: false, // 操做窗口 显隐
      winTitle: ''// 操做窗口 标题
    }
  },
  components: {
    SelectionShopId
  },
  computed: {
    shop_id () {
      return this.form.shop_id
    },
    /**
     * @description: 分类列表
     */
    categoryList () {
      return this.$store.state.categoryList
    }
  },
  methods: {
    /**
     * @description: 构建分类树
     */
    buildTree (inputArray) {
      inputArray = inputArray.filter(item => item.shop_id === this.shop_id)// 用户过滤
      const map = {}// 创建一个空的映射对象，用于将每个id映射到相应的对象上
      const result = []// 存储最终结果的数组
      // 第一遍循环，将原始数组中的每个对象加入到映射对象中
      inputArray.forEach(item => {
        item.children = []// 给每个对象添加一个children属性，用于存储子节点
        map[item.id] = item// 将当前对象以其id为键，放入映射对象中
      })
      // 第二遍循环，构建嵌套结构
      inputArray.forEach(item => {
        const parent = map[item.pid]// 查找当前对象的父级对象
        if (parent) { // 如果找到父级对象，则将当前对象加入到父级对象的children数组中
          parent.children.push(item)
        } else { // 如果没有找到父级对象，说明当前对象是顶级节点，直接加入到最终结果数组中
          result.push(item)
        }
      })
      return result.filter(item => item.pid === '0')// 筛选出顶级节点，即pid为'0'的项，作为最终结果
    },
    /* 文件上传表单 */
    handleUpSuccess (res) {
      if (res.status === 0) {
        this.$message.error(res.msg)
      } else {
        this.form.upFile = res.data
        this.$message.success(res.msg)
      }
    },
    beforeAvatarUpload (file) {
      const isJPG = file.type === 'image/jpeg' || file.type === 'image/png' || file.type === 'image/gif' || file.type === 'image/svg+xml'
      if (!isJPG) {
        this.$message.error('上传图片只能是SVG|JPG|PNG|GIF格式!')
      }
      return isJPG
    },
    handleUpErr () {
      this.$message.error('接口访问失败')
    },
    // 设置表单
    setForm (data) {
      if (data.desc == null) {
        data.desc = ''
      }
      this.form.id = data.id
      this.form.pid = data.pid
      this.form.path = data.path
      this.form.name = data.name
      this.form.sort = data.sort
      this.form.show = data.show === '1'
      this.form.desc = data.desc
      this.form.oldFile = data.photo
      this.form.upFile = ''
      if (Object.keys(data).length === 0) {
        this.$message.warning('清空表单')
      }
    },
    /**
     * @description: 打开添加 编辑分类窗口
     * @param {*} title 窗口标题
     * @param {*} data 当前点击的分类属性
     */
    openWin (title, data) {
      this.winIsShow = true
      this.winTitle = title
      this.setForm(data)// 设置表单
    },
    /**
     * @description: 添加分类
     */
    async addCategory () {
      const res = await this.$store.dispatch('fetchAddCategory', this.form)
      if (res.data.status === 1) {
        this.winIsShow = false
      }
    },
    /**
     * @description: 更新分类
     */
    async saveCategory () {
      const res = await this.$store.dispatch('fetchSaveCategory', this.form)
      if (res.data.status === 1) {
        this.winIsShow = false
      }
    },
    /**
     * @description: 删除分类 及其 子分类
     */
    delCategory (id) {
      this.$confirm('删除分类及其子分类, 并且旗下的所有商品会被归为"未分类", 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.delIdArr = []// 用于存储删除的ID的数组
        this.findCategoryChildren(this.categoryListData, id)// 调用递归函数，查找指定ID及其子元素的ID，并将它们存储到delIdArr数组中
        const data = { delIdArr: this.delIdArr, shop_id: this.form.shop_id }
        this.$store.dispatch('fetchDelCategory', data)// 删除指定分类和旗下所有子分类
      }).catch(() => {
        this.$message.info('已取消删除')
      })
    },
    // 递归遍历 所有分类和子分类  找到指定分类id 和 指定id下所有子分类的id 并push到this.delIdArr里面
    findCategoryChildren (data, id) {
      // 遍历数据数组中的每个元素
      data.forEach(item => {
        // 如果当前元素的ID与指定ID相等
        if (item.id === id) {
          this.isStartDel = true
        }
        if (this.isStartDel) {
          this.delIdArr.push(item.id)
        }
        this.findCategoryChildren(item.children, id)
        if (item.id === id) {
          this.isStartDel = false
        }
      })
    }
  },
  watch: {
    /**
     * @description: 拿到shop_id和分类列表 初始化分类树结构
     */
    shop_id () {
      this.categoryListData = this.buildTree(this.categoryList)
    },
    categoryList () {
      this.categoryListData = this.buildTree(this.categoryList)
    }
  },
  created () {
  }
}
</script>

<style lang="scss" scoped>
@import "@/styles/theme.scss";

.custom-tree-node {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 14px;
  padding-right: 8px;
}

.hideColor {
  color: $holdtext-color !important;
}

.el-upload__text {
  line-height: 1.2em !important;
}

.textEditBut {
  color: $warning-color !important;
}

.textDelBut {
  color: $danger-color !important;
}
</style>
