<script lang="ts" setup>
|
import { computed, nextTick, reactive, toRefs } from 'vue';
|
|
import { useMessage } from '@jnpf/hooks';
|
import { BasicModal, useModalInner } from '@jnpf/ui/modal';
|
import { buildUUID } from '@jnpf/utils';
|
|
import { cloneDeep } from 'lodash-es';
|
import Sortablejs from 'sortablejs';
|
|
const emit = defineEmits(['register', 'confirm']);
|
|
interface State {
|
sortList: any[];
|
fieldOptions: any[];
|
activeKey: String;
|
}
|
|
const state = reactive<State>({
|
sortList: [],
|
fieldOptions: [],
|
activeKey: '',
|
});
|
const { sortList, fieldOptions, activeKey } = toRefs(state);
|
const [registerModal, { closeModal }] = useModalInner(init);
|
const { createMessage } = useMessage();
|
|
const columns = [
|
{ title: '拖动', dataIndex: 'drag', key: 'drag', align: 'center', width: 50 },
|
{ title: '字段', dataIndex: 'vModel', key: 'vModel', width: 340 },
|
{ title: '类型', dataIndex: 'type', key: 'type', width: 160 },
|
{ title: '操作', dataIndex: 'action', key: 'action', width: 50, align: 'center' },
|
];
|
const sortTypeOptions = [
|
{ id: 'asc', fullName: '升序' },
|
{ id: 'desc', fullName: '降序' },
|
];
|
|
const getParameterColumns = computed(() => columns.map((o) => ({ ...o, customCell: () => ({ class: 'align-top' }) })));
|
|
function onChange() {
|
nextTick(() => {
|
initSortable();
|
});
|
}
|
|
function init(data: any) {
|
state.sortList = getSortList(data);
|
state.activeKey = state.sortList[0].sheet;
|
state.fieldOptions = cloneDeep(data.dataSetList ?? []);
|
nextTick(() => {
|
initSortable();
|
});
|
}
|
function initSortable() {
|
const columnTable: any = document.querySelector(`.columnTable${state.activeKey} .ant-table-tbody`);
|
Sortablejs.create(columnTable, {
|
handle: '.drag-handler',
|
animation: 150,
|
easing: 'cubic-bezier(1, 0, 0, 1)',
|
onStart: () => {},
|
onEnd: ({ newIndex, oldIndex }: any) => {
|
const sheetIndex = state.sortList.findIndex((item) => item.sheet === state.activeKey);
|
const currRow = state.sortList[sheetIndex].sortList.splice(oldIndex, 1)[0];
|
state.sortList[sheetIndex].sortList.splice(newIndex, 0, currRow);
|
},
|
});
|
}
|
function getSortList(data) {
|
const sheetList = data.sheetList.map((item) => ({ sheet: item.id, sheetName: item.fullName, sortList: [] }));
|
if (!data.sortList?.length) return sheetList;
|
for (const element of sheetList) {
|
for (let i = 0; i < data.sortList.length; i++) {
|
const el = data.sortList[i];
|
if (element.sheet == el.sheet) element.sortList = el.sortList || [];
|
}
|
}
|
return sheetList;
|
}
|
function handleAdd(pIndex) {
|
state.sortList[pIndex].sortList.push({
|
id: buildUUID(),
|
vModel: '',
|
type: 'asc',
|
});
|
}
|
function handleDel(pIndex: number, index: number) {
|
state.sortList[pIndex].sortList.splice(index, 1);
|
}
|
function handleSubmit() {
|
for (let index = 0; index < state.sortList.length; index++) {
|
const e = state.sortList[index];
|
for (let i = 0; i < e.sortList.length; i++) {
|
const item = e.sortList[i];
|
if (!item.vModel) {
|
createMessage.warning(`${e.sheetName}第${i + 1}项的字段不能为空`);
|
return;
|
}
|
}
|
}
|
emit('confirm', state.sortList);
|
nextTick(() => closeModal());
|
}
|
</script>
|
<template>
|
<BasicModal v-bind="$attrs" width="600px" class="jnpf-parameter-modal" @register="registerModal" title="排序配置" @ok="handleSubmit" destroy-on-close>
|
<a-tabs v-model:active-key="activeKey" @change="onChange">
|
<a-tab-pane v-for="(item, pIndex) in sortList" :key="item.sheet" :tab="item.sheetName">
|
<a-table
|
:data-source="item.sortList"
|
row-key="id"
|
:columns="getParameterColumns"
|
size="small"
|
:pagination="false"
|
:class="`columnTable${activeKey}`"
|
v-if="item.sheet == activeKey">
|
<template #bodyCell="{ column, record, index }">
|
<template v-if="column.key === 'drag'">
|
<i class="drag-handler icon-ym icon-ym-darg" title="点击拖动"></i>
|
</template>
|
<template v-if="column.key === 'vModel'">
|
<JnpfTreeSelect
|
v-model:value="record.vModel"
|
placeholder="请选择"
|
allow-clear
|
last-level
|
last-level-key="children"
|
:options="fieldOptions"
|
:field-names="{ value: 'jnpfId' }"
|
class="!w-[324px]" />
|
</template>
|
<template v-if="column.key === 'type'">
|
<jnpf-radio v-model:value="record.type" :options="sortTypeOptions" button-style="solid" class="!w-[140px]" />
|
</template>
|
<template v-if="column.key === 'action'">
|
<a-button type="link" danger @click="handleDel(pIndex, index)" class="!px-[5px]"><i class="icon-ym icon-ym-app-delete"></i></a-button>
|
</template>
|
</template>
|
</a-table>
|
<div class="table-add-action" @click="handleAdd(pIndex)">
|
<a-button type="link" pre-icon="icon-ym icon-ym-btn-add">新增</a-button>
|
</div>
|
</a-tab-pane>
|
</a-tabs>
|
</BasicModal>
|
</template>
|