index.vue 8.27 KB
<script lang="ts" setup>
import { ref } from "vue";
import { ElMessage } from "element-plus"
import PageNav from "@/components/PageNav/index.vue";
import dayjs from "dayjs";
const props = defineProps({
  tableInfo: {
    type: Object,
    default: {} as any,
  },
  colums: {
    type: Array<any>,
    default: [],
  },
  columnInfo: {
    type: Object,
    default: {} as any,
  },
  page: {
    type: Object,
    default: {} as any,
  },
})

const colums = computed(() => {
  return props.colums
})
const tableDataLoading = computed(() => {
  return props?.tableInfo?.loading;
});
const data = computed(() => props?.tableInfo?.data)
const tableInfo = computed(() => props?.tableInfo || {})
const columnInfo = ref({ ...props?.columnInfo?.value })
const isEdit = computed(() => props?.tableInfo?.isEdit)
const flag = computed(() => props?.tableInfo?.flag)
const page = computed(() => props?.page)
const emits = defineEmits(["pageChange", "columnSave", "columnCancel", "columnDel", "columnEdit", "handelSelect", "handelInput", "searchSelect", "selectScroll"])

const selectRef = ref()
const columnEdit = (row) => {
  if (!tableInfo.value.isEdit) {
    columnInfo.value = { ...row }

    emits("columnEdit", { ...row })
  }

}
const columnDel = (row) => {
  if (!tableInfo.value.isEdit) {
    columnInfo.value = { ...row }
    emits("columnDel", { ...row })
  }

}
const columnDel1 = (row) => {
  //columnInfo.value = {}
  columnInfo.value = { ...row }
  emits("columnDel", { ...row })

}
const columnSave = (row) => {
  emits("columnSave", { ...columnInfo.value })
}
const columnCancel = (row) => {
  columnInfo.value = {}
  emits("columnCancel")
}
const pageChange = (page) => {
  let info = { ...page };
  emits("pageChange", info)
}
const handelSelect = (value, item, row) => {
  const selectOption = item.selectOption()
  const optionItem = selectOption.find(option => option[item.selectKey] === value)
  console.log(optionItem)
  emits("handelSelect", { ...optionItem }, item.prop, row)
}
const searchSelect = (value) => {
  emits("searchSelect", value)
}
const secectClick = (value) => {
  emits("handelSelect", value)
}
const selectInput = (value) => {
  emits("searchSelect", value)
}
const selectScroll = () => {
  emits("selectScroll")
}
const numberChange = (value, key, fn) => {
  //console.log(value,key,fn)
  const value1 = fn(value, key)
  //console.log(value1)
  //columnInfo.value[key] = columnInfo.value[key].toString().slice(0,12)
  //const string = columnInfo.value[key]
  // console.log(columnInfo.value[key])
}
const numberChange1 = (value, key, fn) => {
  const value1 = fn && fn(value, key)
}
const numberWidthCommas = (num) => {
  if (num == null) {
    return '--'
  }
  let parts = num.toFixed(2).split(".")
  parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",")
  return parts.join(".")
}
defineExpose({
  columnInfo,
  selectRef
})
</script>

<template>
  <div class="table_panel" style="height: 100%;">
    <el-table :data="data" v-loading="tableDataLoading" height="100%" tooltip-effect="light"
      max-height="calc(100% - 44px)" :style="{ 'min-height': 'calc(100% - 44px)', }" border>
      <el-table-column v-for="item in colums" :prop="item?.prop" :type="item?.type" :align="item.align || 'left'"
        :label="item.label" :width="item.width" :show-overflow-tooltip="true" :key="item.prop">
        <template #default="{ row }">
          <template v-if="item.componentType === 'dateTime' && row.guid === tableInfo.currentId && !item.type">
            <el-date-picker v-model="columnInfo[item.prop]" type="date" placeholder="选择日期"
              :disabled="item.componentDisabled === false ? item.componentDisabled : true" size="small">
            </el-date-picker>
          </template>
          <template v-else-if="item.componentType === 'dateTime' && row.guid != tableInfo.currentId && !item.type">
            {{ !row[item.prop] ? '--' : dayjs(row[item.prop]).format("YYYY-MM-DD") }}
          </template>
          <template v-else-if="item.componentType === 'number' && row.guid === tableInfo.currentId && !item.type">
            <div class="price">
              <el-input size="small" style="width: 100%;" v-model="columnInfo[item.prop]"
                @input="numberChange($event, item.prop, item.input)"
                @change="numberChange1($event, item.prop, item.change)" v-bind="item.config || {}"
                :placeholder="item.placeholder">
              </el-input>
              <span>{{ item.propType }}</span>
            </div>
          </template>
          <template
            v-else-if="item.componentType === 'number' && row.guid != tableInfo.currentId && !item.type && item.toFixed">
            {{ numberWidthCommas(row[item.prop]) }} {{ item.propType }}
          </template>
          <template
            v-else-if="item.componentType === 'number' && row.guid != tableInfo.currentId && !item.type && !item.toFixed">
            {{ row[item.prop] }}
          </template>
          <template v-else-if="item.componentType === 'select' && row.guid === tableInfo.currentId && !item.type">
            <el-select v-model="columnInfo[item.prop]" filterable
              :disabled="item?.editDisabled ? item?.editDisabled() : false" @change="handelSelect($event, item, row)"
              size="small" placeholder="请选择">
              <el-option v-for="option in item.selectOption()" :key="option" :label="option[item.selectKey]"
                :value="option[item.selectKey]">
              </el-option>
            </el-select>
          </template>
          <template
            v-else-if="item.componentType !== 'dateTime' && item.componentType !== 'number' && row.guid === tableInfo.currentId && !item.type">
            <el-input v-model="columnInfo[item.prop]" style="width: 100%;" placeholder="请输入内容" size="small"
              :disabled="item.componentDisabled === false ? item.componentDisabled : true"></el-input>
          </template>
          <template
            v-else-if="item.componentType !== 'dateTime' && item.componentType !== 'number' && row.guid != tableInfo.currentId && !item.type">
            {{ row[item.prop] ? row[item.prop] : '--' }}
          </template>
        </template>

      </el-table-column>
      <el-table-column label="操作" width="160px" fixed="right">
        <template #default="{ row }">
          <template v-if="row.guid === tableInfo.currentId">
            <span class=" operate_btn active" @click="columnSave(row)">保存</span>
            <span class="operate_btn active" @click="columnCancel(row)">取消</span>
            <span class="operate_btn active" v-if="flag === 'edit'" @click="columnDel1(row)">删除</span>
          </template>
          <template v-else>
            <span class=" operate_btn active" :class="[isEdit ? 'disabled' : '']" @click="columnEdit(row)">编辑</span>
            <span class="operate_btn active" :class="[isEdit ? 'disabled' : '']" @click="columnDel(row)">删除</span>
          </template>
        </template>
      </el-table-column>
    </el-table>
    <PageNav :pageInfo="page" @pageChange="pageChange" />
  </div>
</template>



<style lang="scss" scoped>
.table_panel {
  width: 100%;
  height: 100%;
  min-height: 300px;
  overflow: hidden;
  position: relative;
}

:deep(.el-table) {
  .header_title {
    display: flex;
    align-items: center;

    .el-icon {
      color: #b2b2b2;
      width: 16px;
      height: 16px;
      margin-left: 8px;

      svg {
        width: 100%;
        height: 100%;
      }
    }
  }

  .input_comb {
    >span:not(:last-child) {
      margin-right: 12px;

      >span {
        margin-right: 4px;
      }
    }

    >span:last-child {
      >span {
        margin-right: 4px;
      }
    }
  }

  .operate_btn {
    color: var(--el-color-primary);
    cursor: pointer;

    &.active {
      padding-right: 4px;
      position: relative;

      &~.active {
        padding-left: 4px;
        margin-left: 1px;

        &::before {
          content: "";
          width: 1px;
          height: 8px;
          background-color: var(--el-disabled-border-color);
          position: absolute;
          left: -1px;
          top: 50%;
          transform: translateY(-50%);
        }
      }

      &:last-child {
        padding-right: 0;
      }
    }
  }
}

.disabled {
  color: #BDBDBD !important;
  cursor: not-allowed;
}

.price {
  display: flex;
  align-items: center;
  justify-content: space-between;
}
</style>