148 lines
5.4 KiB
Handlebars
148 lines
5.4 KiB
Handlebars
<script setup lang="ts">
|
|
import { computed, onMounted, onBeforeUnmount, ref } from 'vue';
|
|
import { Plus, Delete, Grid } from '@element-plus/icons-vue';
|
|
import { useI18n } from 'vue-i18n';
|
|
import Sortable from 'sortablejs';
|
|
import { perm } from '@/stores/useCurrentUser';
|
|
import { toParams, resetParams } from '@/utils/common';
|
|
import { delete{{pascalCase name}}, query{{pascalCase name}}List, update{{pascalCase name}}Order } from '@/api/{{kebabCase path}}';
|
|
import { ColumnList, ColumnSetting } from '@/components/TableList';
|
|
import { QueryForm, QueryItem } from '@/components/QueryForm';
|
|
import {{pascalCase name}}Form from './{{pascalCase name}}Form.vue';
|
|
|
|
defineOptions({
|
|
name: '{{pascalCase name}}List',
|
|
});
|
|
const { t } = useI18n();
|
|
const params = ref<any>({});
|
|
const sort = ref<any>();
|
|
const table = ref<any>();
|
|
const data = ref<any[]>([]);
|
|
const selection = ref<any[]>([]);
|
|
const loading = ref<boolean>(false);
|
|
const formVisible = ref<boolean>(false);
|
|
const beanId = ref<string>();
|
|
const beanIds = computed(() => data.value.map((row) => row.id));
|
|
const isSorted = ref<boolean>(false);
|
|
const fetchData = async () => {
|
|
loading.value = true;
|
|
try {
|
|
data.value = await query{{pascalCase name}}List({ ...toParams(params.value), Q_OrderBy: sort.value });
|
|
isSorted.value = sort.value !== undefined;
|
|
} finally {
|
|
loading.value = false;
|
|
}
|
|
};
|
|
let sortable;
|
|
const initDragTable = () => {
|
|
const tbody = document.querySelector('#dataTable .el-table__body-wrapper tbody');
|
|
sortable = Sortable.create(tbody, {
|
|
handle: '.drag-handle',
|
|
onEnd: async function (event: any) {
|
|
const { oldIndex, newIndex } = event;
|
|
if (oldIndex !== newIndex) {
|
|
await update{{pascalCase name}}Order(data.value[oldIndex].id, data.value[newIndex].id);
|
|
data.value.splice(newIndex, 0, data.value.splice(oldIndex, 1)[0]);
|
|
ElMessage.success(t('success'));
|
|
}
|
|
},
|
|
});
|
|
};
|
|
onMounted(() => {
|
|
fetchData();
|
|
initDragTable();
|
|
});
|
|
onBeforeUnmount(() => {
|
|
if (sortable !== undefined) {
|
|
sortable.destroy();
|
|
}
|
|
});
|
|
|
|
const handleSort = ({ column, prop, order }: { column: any; prop: string; order: string }) => {
|
|
if (prop && order) {
|
|
sort.value = (column.sortBy ?? prop) + (order === 'descending' ? '_desc' : '');
|
|
} else {
|
|
sort.value = undefined;
|
|
}
|
|
fetchData();
|
|
};
|
|
const handleSearch = () => fetchData();
|
|
const handleReset = () => {
|
|
table.value.clearSort();
|
|
resetParams(params.value);
|
|
sort.value = undefined;
|
|
fetchData();
|
|
};
|
|
|
|
const handleAdd = () => {
|
|
beanId.value = undefined;
|
|
formVisible.value = true;
|
|
};
|
|
const handleEdit = (id: string) => {
|
|
beanId.value = id;
|
|
formVisible.value = true;
|
|
};
|
|
const handleDelete = async (ids: string[]) => {
|
|
await delete{{pascalCase name}}(ids);
|
|
fetchData();
|
|
ElMessage.success(t('success'));
|
|
};
|
|
</script>
|
|
|
|
<template>
|
|
<div>
|
|
<div class="mb-3">
|
|
<query-form :params="params" @search="handleSearch" @reset="() => handleReset()">
|
|
<query-item :label="$t('{{camelCase name}}.name')" name="Q_Contains_name"></query-item>
|
|
</query-form>
|
|
</div>
|
|
<div class="space-x-2">
|
|
<el-button type="primary" :disabled="perm('{{camelCase name}}:create')" :icon="Plus" @click="() => handleAdd()">\{{ $t('add') }}</el-button>
|
|
<el-popconfirm :title="$t('confirmDelete')" @confirm="() => handleDelete(selection.map((row) => row.id))">
|
|
<template #reference>
|
|
<el-button :disabled="selection.length <= 0 || perm('{{camelCase name}}:delete')" :icon="Delete">\{{ $t('delete') }}</el-button>
|
|
</template>
|
|
</el-popconfirm>
|
|
<column-setting name="{{camelCase name}}" />
|
|
</div>
|
|
<div class="mt-3 app-block">
|
|
<el-table
|
|
id="dataTable"
|
|
ref="table"
|
|
v-loading="loading"
|
|
row-key="id"
|
|
:data
|
|
@selection-change="(rows) => (selection = rows)"
|
|
@row-dblclick="(row) => handleEdit(row.id)"
|
|
@sort-change="handleSort"
|
|
>
|
|
<column-list name="{{camelCase name}}">
|
|
<el-table-column type="selection" width="45"></el-table-column>
|
|
<el-table-column width="42">
|
|
<el-icon
|
|
class="text-lg align-middle text-gray-secondary"
|
|
:class="isSorted || perm('{{camelCase name}}:update') ? ['cursor-not-allowed', 'text-gray-disabled'] : ['cursor-move', 'text-gray-regular', 'drag-handle']"
|
|
disalbed
|
|
>
|
|
<Grid />
|
|
</el-icon>
|
|
</el-table-column>
|
|
<el-table-column property="id" label="ID" width="180" sortable="custom"></el-table-column>
|
|
<el-table-column property="name" :label="$t('{{camelCase name}}.name')" sortable="custom" show-overflow-tooltip></el-table-column>
|
|
<el-table-column :label="$t('table.action')">
|
|
<template #default="{ row }">
|
|
<el-button type="primary" :disabled="perm('{{camelCase name}}:update')" size="small" link @click="() => handleEdit(row.id)">\{{ $t('edit') }}</el-button>
|
|
<el-popconfirm :title="$t('confirmDelete')" @confirm="() => handleDelete([row.id])">
|
|
<template #reference>
|
|
<el-button type="primary" :disabled="perm('{{camelCase name}}:delete')" size="small" link>\{{ $t('delete') }}</el-button>
|
|
</template>
|
|
</el-popconfirm>
|
|
</template>
|
|
</el-table-column>
|
|
</column-list>
|
|
</el-table>
|
|
</div>
|
|
<{{kebabCase name}}-form v-model="formVisible" :bean-id="beanId" :bean-ids="beanIds" @finished="() => fetchData()" />
|
|
</div>
|
|
</template>
|