Роли, переделывание отчета, изменение на главной странице

This commit is contained in:
brusnitsyn
2026-01-11 23:37:18 +09:00
parent eb019504d7
commit d4f077cdaf
59 changed files with 2099 additions and 366 deletions

View File

@@ -0,0 +1,166 @@
<script setup>
import {NDataTable} from "naive-ui";
import {useReportStore} from "../../../Stores/report.js";
import {computed, h, onMounted, ref, watch} from "vue";
import { VueDraggableNext } from 'vue-draggable-next'
import {storeToRefs} from "pinia";
const props = defineProps({
mode: {
type: String,
default: 'fillable' // 'fillable', 'readonly'
},
keys: {
type: Array,
default: ['num', 'fullname', 'age', 'birth_date', 'ds']
},
status: {
type: String,
default: null // 'plan'
}
})
const isFillableMode = computed(() => props.mode.toLowerCase() === 'fillable')
const isReadonlyMode = computed(() => props.mode.toLowerCase() === 'readonly')
const emit = defineEmits(['item-dragged', 'item-dropped'])
const reportStore = useReportStore()
const {patientsData} = storeToRefs(reportStore)
// Получаем базовые колонки
const baseColumns = reportStore.getColumnsByKey(props.keys)
const data = ref([])
const isLoading = ref(true)
// Добавляем drag колонку если режим fillable
const columns = computed(() => {
if (!isFillableMode.value) return baseColumns
const dragColumn = {
title: '',
key: 'drag',
width: 40,
render: (row) => h('div', {
style: {
cursor: 'grab',
color: '#666',
textAlign: 'center',
userSelect: 'none'
}
}, '⋮⋮')
}
return [dragColumn, ...baseColumns]
})
const handleDragStart = (e, row) => {
// Устанавливаем данные о перетаскиваемом элементе
e.dataTransfer.setData('application/json', JSON.stringify({
row: row,
fromStatus: props.status
}))
e.dataTransfer.effectAllowed = 'copy'
const rowElement = e.target
// Эмитим событие для родителя
emit('item-dragged', { row, fromStatus: props.status })
// Добавляем класс для визуальной обратной связи
e.target.classList.add('dragging')
}
const handleDragEnd = (e) => {
if (e.target) {
e.target.classList.remove('dragging')
}
}
const handleDragOver = (e) => {
e.preventDefault()
}
const handleDrop = (e) => {
e.preventDefault()
try {
const dragData = JSON.parse(e.dataTransfer.getData('application/json'))
// Эмитим событие для родителя
emit('item-dropped', {
item: dragData.row,
fromStatus: dragData.fromStatus,
toStatus: props.status
})
} catch (error) {
console.error('Drop error:', error)
}
}
const fetchPatients = async () => {
if (props.status === 'plan' || props.status === 'emergency') {
isLoading.value = true
await axios.post('/api/mis/patients', {
status: props.status
}).then((res) => {
patientsData.value[props.status] = res.data
}).finally(() => {
isLoading.value = false
})
} else {
isLoading.value = false
}
}
function rowProps(row) {
return {
draggable: true,
style: 'cursor: grab;',
onDragstart: (e) => {
handleDragStart(e, row)
},
onDragend: (e) => {
handleDragEnd(e)
},
onDragover: (e) => {
handleDragOver(e)
},
onDrop: (e) => {
handleDrop(e)
}
}
}
onMounted(async () => {
await fetchPatients()
})
</script>
<template>
<NDataTable :columns="columns"
:data="patientsData[status]"
size="small"
@drop="handleDrop"
@dragover="handleDragOver"
:loading="isLoading"
virtual-scroll
max-height="200"
min-height="200"
:row-props="rowProps"
class="text-sm!">
</NDataTable>
<!-- <NDataTable :columns="columns"-->
<!-- :data="data"-->
<!-- size="small"-->
<!-- max-height="200"-->
<!-- class="text-sm!">-->
<!-- </NDataTable>-->
</template>
<style scoped>
:deep(.n-data-table-th),
:deep(.n-data-table-td) {
white-space: nowrap !important;
font-size: var(--n-font-size);
}
</style>