| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291 |
- <script setup lang="ts">
- import {defineProps, defineEmits, ref, onMounted, watch, computed, nextTick} from 'vue'
- import {componentType} from "@/components/query-components/page-help-type";
- import {useVModels, useWindowSize} from "@vueuse/core";
- import XcElOption from "@/components/xiao-chan/xc-el-option/XcElOption.vue";
- import sleep from "@/utils/sleep";
- import {useCompRef} from "@/utils/useCompRef";
- import {ElTable} from "element-plus";
- import XEUtils from "xe-utils";
- //@ts-ignore
- import Sortable from 'sortablejs'
- import EditColumnRender from "@/views/utilities/page-editor-help/components/EditColumnRender.vue";
- const props = defineProps<{
- modelValue: boolean
- pageJson: componentType,
- }>()
- const emits = defineEmits(['update:pageJson', 'update:modelValue'])
- const {pageJson, modelValue} = useVModels(props, emits)
- const {width, height: winHeight} = useWindowSize();
- const dialog = ref(true)
- const tableRef = useCompRef(ElTable)
- const columnsTableRef = useCompRef(ElTable)
- const addTableColumn = async () => {
- pageJson.value.columns.push({
- bind: {
- prop: '',
- label: '',
- showOverflowTooltip: false,
- },
- render: '',
- exportColumns: true,
- })
- await nextTick()
- let scroll = columnsTableRef.value.scrollBarRef.wrap$ as HTMLHtmlElement;
- columnsTableRef.value.setScrollTop(scroll.scrollHeight)
- }
- const close = async () => {
- if (changeColumns) {
- pageJson.value.isShow = false
- await sleep(500)
- pageJson.value.isShow = true
- }
- watchColumns()
- }
- let watchColumns = null
- let changeColumns = false
- const dataTemp = computed(() => {
- let obj = []
- if (pageJson.value.tableConfig.data.length > 0) {
- for (let key in pageJson.value.tableConfig.data[0]) {
- obj.push({code: key})
- }
- }
- return obj
- })
- const columnsKey = computed(() => {
- let data = []
- if (pageJson.value.columns.length > 0) {
- XEUtils.arrayEach(pageJson.value.columns, (item) => {
- data.push(item.bind.prop)
- })
- }
- return data
- })
- const selectedClick = () => {
- let tempData = <any[]>tableRef.value.getSelectionRows()
- if (tempData.length === 0) {
- return
- }
- tempData.forEach(item => {
- if (!columnsKey.value.includes(item.code)) {
- pageJson.value.columns.push({
- bind: {
- prop: item.code,
- label: item.code,
- showOverflowTooltip: false,
- },
- render: '',
- exportColumns: true,
- })
- }
- })
- }
- /**
- * 设置表格列排序
- */
- const columnsTableSortable = () => {
- const el = columnsTableRef.value.$el.querySelector('tbody')
- const ops = {
- animation: 200, //动画时长
- handle: '.shangxiatuodong',
- onEnd({newIndex, oldIndex}) {
- const currRow = pageJson.value.columns.splice(oldIndex, 1)[0]
- pageJson.value.columns.splice(newIndex, 0, currRow)
- }
- }
- Sortable.create(el, ops)
- }
- const labelInputRef = new Map<number, any>()
- const setLabelInputRef = (el, index) => {
- labelInputRef.set(index, el)
- }
- const findNextInput = (index) => {
- findInput(index + 1)
- }
- const findPrevInput = (index) => {
- findInput(index - 1)
- }
- const findInput = async (index) => {
- let inputRef = labelInputRef.get(index);
- if (inputRef) {
- inputRef.focus();
- await sleep(200)
- inputRef.select();
- }
- }
- const columnData = ref()
- const columnDialog = ref(false)
- const editColumnClick = (row) => {
- columnData.value = row
- columnDialog.value = true
- }
- onMounted(async () => {
- watchColumns = watch(() => pageJson.value.columns, () => {
- changeColumns = true
- }, {deep: true})
- await nextTick()
- columnsTableSortable()
- tableRef.value.toggleAllSelection()
- })
- </script>
- <template>
- <EditColumnRender v-model:data="columnData"
- v-model:page-json="pageJson"
- v-model="columnDialog"
- v-if="columnDialog"/>
- <el-dialog v-model="dialog"
- title="表格列配置"
- fullscreen
- @close="close"
- @closed="modelValue = false">
- <div :style="{height:winHeight - 120 + 'px' }">
- <el-auto-resizer>
- <template #default="{ height, width }">
- <el-table :data="pageJson.columns"
- :height="height / 2"
- row-key="bind.prop"
- ref="columnsTableRef">
- <el-table-column label="排序" width="50">
- <template #default>
- <el-button class="shangxiatuodong"><i class="iconfont icon-shangxiatuodong"></i></el-button>
- </template>
- </el-table-column>
- <el-table-column prop="bind.type" label="类型" width="80">
- <template #header>
- <span>类型</span>
- </template>
- <template #default="scope">
- <el-select v-model="scope.row.bind.type" :clearable="true">
- <xc-el-option :data="[{code: 'index' , name: '排序'}, {code: 'selected' , name: '多选'}]"/>
- </el-select>
- </template>
- </el-table-column>
- <el-table-column prop="bind.prop" label="字段" width="150">
- <template #default="scope">
- <el-input v-model.trim="scope.row.bind.prop"/>
- </template>
- </el-table-column>
- <el-table-column prop="bind.label" label="表头名" width="150">
- <template #header>
- <span title="可以按方向键盘来跳转到下一个或上一个">
- 表头名
- <el-icon>
- <InfoFilled/>
- </el-icon>
- </span>
- </template>
- <template #default="scope">
- <el-input v-model.trim="scope.row.bind.label"
- @click="labelInputRef.get(scope.$index).select()"
- @keydown.up="findPrevInput(scope.$index)"
- @keydown.down="findNextInput(scope.$index)"
- :ref="(el) => setLabelInputRef(el, scope.$index)"/>
- </template>
- </el-table-column>
- <el-table-column prop="bind.width" label="宽度" width="70">
- <template #default="scope">
- <el-input-number style="width: 60px" :min="0" :controls="false" v-model="scope.row.bind.width"/>
- </template>
- </el-table-column>
- <el-table-column prop="bind.fixed" label="固定" width="75">
- <template #default="scope">
- <el-select v-model="scope.row.bind.fixed" :clearable="true">
- <xc-el-option :data="[{code: 'left' , name: '左'}, {code: 'right' , name: '右'}]"/>
- </el-select>
- </template>
- </el-table-column>
- <el-table-column prop="bind.showOverflowTooltip" label="超出宽度显示省略号" width="100">
- <template #default="scope">
- <el-switch v-model="scope.row.bind.showOverflowTooltip"
- :active-value="true"
- :inactive-value="false"/>
- </template>
- </el-table-column>
- <el-table-column prop="exportColumns" label="导出列" width="100">
- <template #default="scope">
- <el-switch v-model="scope.row.exportColumns"
- :active-value="true"
- :inactive-value="false"/>
- </template>
- </el-table-column>
- <el-table-column prop="render" label="插槽" show-overflow-tooltip width="260"/>
- <el-table-column min-width="80" fixed="right">
- <template #header>
- <el-button @click="addTableColumn" type="primary">添加</el-button>
- </template>
- <template #default="scope">
- <el-button type="primary"
- @click="editColumnClick(scope.row)">
- 编辑
- </el-button>
- <el-button type="danger"
- @click="pageJson.columns.splice(scope.$index,1)">
- 删除
- </el-button>
- </template>
- </el-table-column>
- </el-table>
- <div :style="{height: height / 2 + 'px'}" class="data_info">
- <div class="selected_fields">
- <el-table :data="dataTemp" :height="height / 2" ref="tableRef">
- <el-table-column type="selection" width="45"/>
- <el-table-column prop="code" label="字段">
- <template #header>
- <el-button @click="selectedClick">选中</el-button>
- </template>
- </el-table-column>
- </el-table>
- </div>
- <div class="json_show">
- <div v-if="pageJson.tableConfig.data.length > 0">
- <el-tag type="warning" effect="dark">默认展示第一条数据</el-tag>
- <JsonViewer :value="pageJson.tableConfig.data[0]"
- style="height: 100%" copyable :expandDepth="3"/>
- </div>
- </div>
- </div>
- </template>
- </el-auto-resizer>
- </div>
- </el-dialog>
- </template>
- <style scoped lang="scss">
- .data_info {
- display: flex;
- .json_show {
- flex: 1;
- }
- .selected_fields {
- width: 400px;
- }
- }
- </style>
|