Поиск, работа над query в js
This commit is contained in:
@@ -11,9 +11,15 @@ class IndexController extends Controller
|
|||||||
{
|
{
|
||||||
public function index(Request $request)
|
public function index(Request $request)
|
||||||
{
|
{
|
||||||
$pageSize = $request->get('pageSize', 15);
|
$pageSize = $request->get('page_size', 15);
|
||||||
|
$searchText = $request->get('search', null);
|
||||||
|
|
||||||
$cards = SttMedicalHistory::query();
|
$cards = SttMedicalHistory::query();
|
||||||
|
|
||||||
|
if (!empty($searchText)) {
|
||||||
|
$cards = $cards->search($searchText);
|
||||||
|
}
|
||||||
|
|
||||||
$cards = SttMedicalHistoryResource::collection($cards->paginate($pageSize));
|
$cards = SttMedicalHistoryResource::collection($cards->paginate($pageSize));
|
||||||
|
|
||||||
return Inertia::render('Home/Index', [
|
return Inertia::render('Home/Index', [
|
||||||
|
|||||||
@@ -32,4 +32,18 @@ class SttMedicalHistory extends Model
|
|||||||
{
|
{
|
||||||
return $this->morphMany(ArchiveHistory::class, 'historyable');
|
return $this->morphMany(ArchiveHistory::class, 'historyable');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function scopeSearch($query, $searchText)
|
||||||
|
{
|
||||||
|
return $query->where(function($q) use ($searchText) {
|
||||||
|
if (is_numeric($searchText)) {
|
||||||
|
$q->where('nkarta', 'LIKE', "$searchText%");
|
||||||
|
} else {
|
||||||
|
// Ищем по всем частям ФИО
|
||||||
|
$q->where('fam', 'LIKE', "%$searchText%")
|
||||||
|
->orWhere('im', 'LIKE', "%$searchText%")
|
||||||
|
->orWhere('ot', 'LIKE', "%$searchText%");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
52
package-lock.json
generated
52
package-lock.json
generated
@@ -8,7 +8,9 @@
|
|||||||
"@arco-design/color": "^0.4.0",
|
"@arco-design/color": "^0.4.0",
|
||||||
"@inertiajs/vue3": "^2.2.19",
|
"@inertiajs/vue3": "^2.2.19",
|
||||||
"@vitejs/plugin-vue": "^6.0.2",
|
"@vitejs/plugin-vue": "^6.0.2",
|
||||||
|
"@vueuse/core": "^14.1.0",
|
||||||
"pinia": "^3.0.4",
|
"pinia": "^3.0.4",
|
||||||
|
"ufo": "^1.6.1",
|
||||||
"vue": "^3.5.25"
|
"vue": "^3.5.25"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@@ -1193,6 +1195,12 @@
|
|||||||
"@types/lodash": "*"
|
"@types/lodash": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/web-bluetooth": {
|
||||||
|
"version": "0.0.21",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.21.tgz",
|
||||||
|
"integrity": "sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/@vitejs/plugin-vue": {
|
"node_modules/@vitejs/plugin-vue": {
|
||||||
"version": "6.0.2",
|
"version": "6.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-6.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-6.0.2.tgz",
|
||||||
@@ -1342,6 +1350,44 @@
|
|||||||
"integrity": "sha512-AbOPdQQnAnzs58H2FrrDxYj/TJfmeS2jdfEEhgiKINy+bnOANmVizIEgq1r+C5zsbs6l1CCQxtcj71rwNQ4jWg==",
|
"integrity": "sha512-AbOPdQQnAnzs58H2FrrDxYj/TJfmeS2jdfEEhgiKINy+bnOANmVizIEgq1r+C5zsbs6l1CCQxtcj71rwNQ4jWg==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/@vueuse/core": {
|
||||||
|
"version": "14.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@vueuse/core/-/core-14.1.0.tgz",
|
||||||
|
"integrity": "sha512-rgBinKs07hAYyPF834mDTigH7BtPqvZ3Pryuzt1SD/lg5wEcWqvwzXXYGEDb2/cP0Sj5zSvHl3WkmMELr5kfWw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/web-bluetooth": "^0.0.21",
|
||||||
|
"@vueuse/metadata": "14.1.0",
|
||||||
|
"@vueuse/shared": "14.1.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/antfu"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"vue": "^3.5.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@vueuse/metadata": {
|
||||||
|
"version": "14.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-14.1.0.tgz",
|
||||||
|
"integrity": "sha512-7hK4g015rWn2PhKcZ99NyT+ZD9sbwm7SGvp7k+k+rKGWnLjS/oQozoIZzWfCewSUeBmnJkIb+CNr7Zc/EyRnnA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/antfu"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@vueuse/shared": {
|
||||||
|
"version": "14.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-14.1.0.tgz",
|
||||||
|
"integrity": "sha512-EcKxtYvn6gx1F8z9J5/rsg3+lTQnvOruQd8fUecW99DCK04BkWD7z5KQ/wTAx+DazyoEE9dJt/zV8OIEQbM6kw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/antfu"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"vue": "^3.5.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/ansi-regex": {
|
"node_modules/ansi-regex": {
|
||||||
"version": "5.0.1",
|
"version": "5.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
|
||||||
@@ -2832,6 +2878,12 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "0BSD"
|
"license": "0BSD"
|
||||||
},
|
},
|
||||||
|
"node_modules/ufo": {
|
||||||
|
"version": "1.6.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.1.tgz",
|
||||||
|
"integrity": "sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/vdirs": {
|
"node_modules/vdirs": {
|
||||||
"version": "0.1.8",
|
"version": "0.1.8",
|
||||||
"resolved": "https://registry.npmjs.org/vdirs/-/vdirs-0.1.8.tgz",
|
"resolved": "https://registry.npmjs.org/vdirs/-/vdirs-0.1.8.tgz",
|
||||||
|
|||||||
@@ -19,7 +19,9 @@
|
|||||||
"@arco-design/color": "^0.4.0",
|
"@arco-design/color": "^0.4.0",
|
||||||
"@inertiajs/vue3": "^2.2.19",
|
"@inertiajs/vue3": "^2.2.19",
|
||||||
"@vitejs/plugin-vue": "^6.0.2",
|
"@vitejs/plugin-vue": "^6.0.2",
|
||||||
|
"@vueuse/core": "^14.1.0",
|
||||||
"pinia": "^3.0.4",
|
"pinia": "^3.0.4",
|
||||||
|
"ufo": "^1.6.1",
|
||||||
"vue": "^3.5.25"
|
"vue": "^3.5.25"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
28
resources/js/Composables/useMedicalHistory.js
Normal file
28
resources/js/Composables/useMedicalHistory.js
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
import {router, usePage} from "@inertiajs/vue3";
|
||||||
|
import {ref} from "vue";
|
||||||
|
import {encodeQueryValue, stringifyQuery} from "ufo";
|
||||||
|
|
||||||
|
export const useMedicalHistory = (url) => {
|
||||||
|
const meta = ref(usePage().props.cards.meta)
|
||||||
|
|
||||||
|
const navigate = (search, page, page_size) => {
|
||||||
|
const params = {
|
||||||
|
search,
|
||||||
|
page,
|
||||||
|
page_size
|
||||||
|
}
|
||||||
|
if (typeof params.page_size === 'undefined') {
|
||||||
|
params.page_size = meta.value.per_page
|
||||||
|
}
|
||||||
|
const query = stringifyQuery(params)
|
||||||
|
|
||||||
|
router.visit(`${url}?${query}`, {
|
||||||
|
preserveState: true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
meta,
|
||||||
|
navigate
|
||||||
|
}
|
||||||
|
}
|
||||||
16
resources/js/Pages/Home/ArchiveHistoryModal/Index.vue
Normal file
16
resources/js/Pages/Home/ArchiveHistoryModal/Index.vue
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<script setup>
|
||||||
|
import { NModal } from 'naive-ui'
|
||||||
|
const open = defineModel('open')
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<NModal v-model:show="open">
|
||||||
|
<template #header>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
</NModal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
@@ -1,12 +1,18 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import {NDataTable, NEllipsis} from "naive-ui"
|
import {NDataTable, NEllipsis} from "naive-ui"
|
||||||
import {h, ref} from "vue"
|
import {h, reactive, ref} from "vue"
|
||||||
|
import {useMedicalHistory} from "../../../Composables/useMedicalHistory.js";
|
||||||
|
|
||||||
|
const { navigate } = useMedicalHistory('/')
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
data: {
|
data: {
|
||||||
type: Array,
|
type: Array,
|
||||||
default: []
|
default: []
|
||||||
},
|
},
|
||||||
|
meta: {
|
||||||
|
type: Object,
|
||||||
|
default: {}
|
||||||
|
},
|
||||||
maxHeight: {
|
maxHeight: {
|
||||||
type: String,
|
type: String,
|
||||||
default: null
|
default: null
|
||||||
@@ -67,10 +73,28 @@ const columns = ref([
|
|||||||
render: (row) => h(NEllipsis, null, { default: () => row.status || '-' })
|
render: (row) => h(NEllipsis, null, { default: () => row.status || '-' })
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
|
|
||||||
|
const paginationReactive = reactive({
|
||||||
|
page: props.meta.current_page,
|
||||||
|
pageCount: props.meta.last_page,
|
||||||
|
pageSize: props.meta.per_page,
|
||||||
|
itemCount: props.meta.total,
|
||||||
|
pageSizes: [15, 50, 100],
|
||||||
|
showSizePicker: true,
|
||||||
|
prefix({ itemCount }) {
|
||||||
|
return `Всего карт ${itemCount}.`
|
||||||
|
},
|
||||||
|
onUpdatePage(page) {
|
||||||
|
navigate(undefined, page)
|
||||||
|
},
|
||||||
|
onUpdatePageSize(pageSize) {
|
||||||
|
navigate(undefined, 1, pageSize)
|
||||||
|
}
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<NDataTable remote striped :columns="columns" :max-height="maxHeight" size="small" :min-height="minHeight" :data="data" />
|
<NDataTable remote striped :columns="columns" :pagination="paginationReactive" :max-height="maxHeight" size="small" :min-height="minHeight" :data="data" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
import AppLayout from "../../Layouts/AppLayout.vue"
|
import AppLayout from "../../Layouts/AppLayout.vue"
|
||||||
import TableCards from './DataTable/Index.vue'
|
import TableCards from './DataTable/Index.vue'
|
||||||
import { NInput, NFlex, NDivider, NDatePicker } from 'naive-ui'
|
import { NInput, NFlex, NDivider, NDatePicker } from 'naive-ui'
|
||||||
|
import {useMedicalHistory} from "../../Composables/useMedicalHistory.js";
|
||||||
|
import {useDebounceFn} from "@vueuse/core";
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
cards: {
|
cards: {
|
||||||
@@ -9,18 +11,28 @@ const props = defineProps({
|
|||||||
default: []
|
default: []
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const { navigate } = useMedicalHistory('/')
|
||||||
|
|
||||||
|
const search = (value) => {
|
||||||
|
navigate(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
const debounceSearch = useDebounceFn((searchValue) => {
|
||||||
|
search(searchValue)
|
||||||
|
}, 500)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<AppLayout>
|
<AppLayout>
|
||||||
<template #header>
|
<template #header>
|
||||||
<NFlex class="py-4" align="center" :wrap="false">
|
<NFlex class="py-4" align="center" :wrap="false">
|
||||||
<NInput placeholder="Поиск по ФИО, № карты" />
|
<NInput placeholder="Поиск по ФИО, № карты" @update:value="val => debounceSearch(val)"/>
|
||||||
<NDivider vertical />
|
<NDivider vertical />
|
||||||
<NDatePicker type="daterange" clearable start-placeholder="Дата выписки с" end-placeholder="по" />
|
<NDatePicker type="daterange" clearable format="dd.MM.yyyy" start-placeholder="Дата выписки с" end-placeholder="по" />
|
||||||
</NFlex>
|
</NFlex>
|
||||||
</template>
|
</template>
|
||||||
<TableCards :data="cards.data" min-height="calc(100vh - 136px)" max-height="calc(100vh - 136px)" />
|
<TableCards :data="cards.data" :meta="cards.meta" min-height="calc(100vh - 179px)" max-height="calc(100vh - 196px)" />
|
||||||
</AppLayout>
|
</AppLayout>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user