feat: ค้นหาตรงตัว
This commit is contained in:
parent
65b05737fb
commit
2e54da99e1
2 changed files with 152 additions and 115 deletions
|
|
@ -1,4 +1,3 @@
|
||||||
divdivdivdivdivdiv
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { storeToRefs } from 'pinia'
|
import { storeToRefs } from 'pinia'
|
||||||
|
|
||||||
|
|
@ -22,10 +21,12 @@ const props = defineProps<{
|
||||||
AND: {
|
AND: {
|
||||||
field: string
|
field: string
|
||||||
value: string
|
value: string
|
||||||
|
exact: boolean
|
||||||
}[]
|
}[]
|
||||||
OR: {
|
OR: {
|
||||||
field: string
|
field: string
|
||||||
value: string
|
value: string
|
||||||
|
exact: boolean
|
||||||
}[]
|
}[]
|
||||||
}
|
}
|
||||||
}>()
|
}>()
|
||||||
|
|
@ -35,6 +36,7 @@ function addAdvSearchData() {
|
||||||
op: 'AND',
|
op: 'AND',
|
||||||
field: 'title',
|
field: 'title',
|
||||||
value: '',
|
value: '',
|
||||||
|
exact: false,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
function delAdvSearchData(index: number) {
|
function delAdvSearchData(index: number) {
|
||||||
|
|
@ -47,6 +49,7 @@ function clearAdvSearchData() {
|
||||||
op: 'AND',
|
op: 'AND',
|
||||||
field: 'title',
|
field: 'title',
|
||||||
value: '',
|
value: '',
|
||||||
|
exact: false,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
advSearchDataField.value = {
|
advSearchDataField.value = {
|
||||||
|
|
@ -71,7 +74,7 @@ function clearAdvSearchData() {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="isAdvSearchCall === true">
|
<div v-if="isAdvSearchCall === true">
|
||||||
<div class="column bg-white q-pa-sm">
|
<div class="col bg-white q-pa-sm">
|
||||||
<div class="row items-center justify-between q-pb-md">
|
<div class="row items-center justify-between q-pb-md">
|
||||||
<span class="text-primary text-weight-medium q-pl-md q-pt-xs"
|
<span class="text-primary text-weight-medium q-pl-md q-pt-xs"
|
||||||
><q-icon name="mdi-tools" class="q-pr-sm" size="sm" />
|
><q-icon name="mdi-tools" class="q-pr-sm" size="sm" />
|
||||||
|
|
@ -87,112 +90,123 @@ function clearAdvSearchData() {
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="column q-px-lg">
|
<div
|
||||||
|
class="row q-px-lg items-center justify-start q-pb-md q-col-gutter-md"
|
||||||
|
v-for="(item, index) in advSearchDataRow"
|
||||||
|
:key="index"
|
||||||
|
>
|
||||||
<div
|
<div
|
||||||
class="row items-center q-pb-xs q-col-gutter-md"
|
class="col-md-1 col-1 row content-center"
|
||||||
v-for="(item, index) in advSearchDataRow"
|
style="width: 45px; height: 45px"
|
||||||
:key="index"
|
|
||||||
>
|
>
|
||||||
<div class="row content-center" style="width: 45px; height: 45px">
|
<q-btn
|
||||||
<q-btn
|
dense
|
||||||
dense
|
color="teal-5"
|
||||||
color="teal-5"
|
icon="mdi-plus"
|
||||||
icon="mdi-plus"
|
v-if="index === advSearchDataRow.length - 1"
|
||||||
v-if="index === advSearchDataRow.length - 1"
|
@click="addAdvSearchData"
|
||||||
@click="addAdvSearchData"
|
id="addAdvSearchData"
|
||||||
id="addAdvSearchData"
|
/>
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class="col-4 col-md-2">
|
|
||||||
<q-select
|
|
||||||
id="advSearchOp"
|
|
||||||
dense
|
|
||||||
outlined
|
|
||||||
emit-value
|
|
||||||
map-options
|
|
||||||
v-model="item.op"
|
|
||||||
:options="optionsOp"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class="col-grow col-md-3">
|
|
||||||
<q-select
|
|
||||||
id="advSearchField"
|
|
||||||
dense
|
|
||||||
outlined
|
|
||||||
emit-value
|
|
||||||
map-options
|
|
||||||
v-model="item.field"
|
|
||||||
:options="optionsField"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class="col-grow">
|
|
||||||
<q-input
|
|
||||||
id="advSearchValue"
|
|
||||||
dense
|
|
||||||
outlined
|
|
||||||
v-model="item.value"
|
|
||||||
placeholder="เอกสาร"
|
|
||||||
@keydown.enter.prevent="submitSearch()"
|
|
||||||
><template v-slot:append>
|
|
||||||
<q-icon
|
|
||||||
v-if="item.value"
|
|
||||||
name="close"
|
|
||||||
@click="() => (item.value = '')"
|
|
||||||
class="cursor-pointer"
|
|
||||||
/>
|
|
||||||
</template>
|
|
||||||
</q-input>
|
|
||||||
</div>
|
|
||||||
<div class="row content-center" style="width: 45px; height: 45px">
|
|
||||||
<q-btn
|
|
||||||
dense
|
|
||||||
flat
|
|
||||||
icon="mdi-trash-can-outline"
|
|
||||||
v-if="advSearchDataRow.length > 1"
|
|
||||||
color="red"
|
|
||||||
@click="() => delAdvSearchData(index)"
|
|
||||||
id="delAdvSearchData"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div class="col-4 col-md-2">
|
||||||
|
<q-select
|
||||||
|
id="advSearchOp"
|
||||||
|
dense
|
||||||
|
outlined
|
||||||
|
emit-value
|
||||||
|
map-options
|
||||||
|
v-model="item.op"
|
||||||
|
:options="optionsOp"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="col-grow col-md-3">
|
||||||
|
<q-select
|
||||||
|
id="advSearchField"
|
||||||
|
dense
|
||||||
|
outlined
|
||||||
|
emit-value
|
||||||
|
map-options
|
||||||
|
v-model="item.field"
|
||||||
|
:options="optionsField"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-grow col-grow">
|
||||||
|
<q-input
|
||||||
|
id="advSearchValue"
|
||||||
|
dense
|
||||||
|
outlined
|
||||||
|
v-model="item.value"
|
||||||
|
placeholder="เอกสาร"
|
||||||
|
@keydown.enter.prevent="submitSearch()"
|
||||||
|
><template v-slot:append>
|
||||||
|
<q-icon
|
||||||
|
v-if="item.value"
|
||||||
|
name="close"
|
||||||
|
@click="() => (item.value = '')"
|
||||||
|
class="cursor-pointer"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</q-input>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-1 q-mr-xl">
|
||||||
|
<q-checkbox
|
||||||
|
id="specificBox"
|
||||||
|
style="width: 200%"
|
||||||
|
v-model="item.exact"
|
||||||
|
label="ค้นหาตรงตัว"
|
||||||
|
color="grey"
|
||||||
|
keep-color
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="row content-center">
|
||||||
|
<q-btn
|
||||||
|
dense
|
||||||
|
flat
|
||||||
|
icon="mdi-trash-can-outline"
|
||||||
|
v-if="advSearchDataRow.length > 1"
|
||||||
|
color="red"
|
||||||
|
@click="() => delAdvSearchData(index)"
|
||||||
|
id="delAdvSearchData"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<q-separator class="q-mb-md q-mt-sm" />
|
<q-separator class="q-mb-md q-mt-sm" />
|
||||||
|
|
||||||
<div class="row q-col-gutter-md q-pb-md">
|
<div class="row q-col-gutter-md q-pb-md q-pt-sm">
|
||||||
<div class="col-12 col-md-5">
|
<div class="col-12 col-md-5">
|
||||||
<q-select
|
<q-select
|
||||||
outlined
|
outlined
|
||||||
dense
|
dense
|
||||||
v-model="advSearchDataField.keyword"
|
v-model="advSearchDataField.keyword"
|
||||||
use-input
|
use-input
|
||||||
use-chips
|
use-chips
|
||||||
multiple
|
multiple
|
||||||
hide-dropdown-icon
|
hide-dropdown-icon
|
||||||
input-debounce="0"
|
input-debounce="0"
|
||||||
new-value-mode="add-unique"
|
new-value-mode="add-unique"
|
||||||
><template v-slot:prepend
|
><template v-slot:prepend
|
||||||
><span class="text-subtitle2">คำสำคัญ:</span></template
|
><span class="text-subtitle2">คำสำคัญ:</span></template
|
||||||
></q-select
|
></q-select
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-12 col-md-grow">
|
<div class="col-12 col-md-grow">
|
||||||
<q-input
|
<q-input
|
||||||
id="advSearchDes"
|
id="advSearchDes"
|
||||||
dense
|
dense
|
||||||
outlined
|
outlined
|
||||||
@keydown.enter.prevent="submitSearch()"
|
@keydown.enter.prevent="submitSearch()"
|
||||||
v-model="advSearchDataField.description"
|
v-model="advSearchDataField.description"
|
||||||
><template v-slot:prepend
|
><template v-slot:prepend
|
||||||
><span class="text-subtitle2">รายละเอียด:</span></template
|
><span class="text-subtitle2">รายละเอียด:</span></template
|
||||||
><template v-slot:append>
|
><template v-slot:append>
|
||||||
<q-icon
|
<q-icon
|
||||||
v-if="advSearchDataField.description"
|
v-if="advSearchDataField.description"
|
||||||
name="close"
|
name="close"
|
||||||
@click="() => (advSearchDataField.description = '')"
|
@click="() => (advSearchDataField.description = '')"
|
||||||
class="cursor-pointer"
|
class="cursor-pointer"
|
||||||
/> </template
|
/> </template
|
||||||
></q-input>
|
></q-input>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ const loaderStore = useLoader()
|
||||||
const { isFilePreview } = storeToRefs(useFileInfoStore())
|
const { isFilePreview } = storeToRefs(useFileInfoStore())
|
||||||
const {
|
const {
|
||||||
foundFile,
|
foundFile,
|
||||||
|
isExact,
|
||||||
isSearch,
|
isSearch,
|
||||||
isAdvSearchCall,
|
isAdvSearchCall,
|
||||||
isActFoundFile,
|
isActFoundFile,
|
||||||
|
|
@ -31,8 +32,8 @@ const optionsField = [
|
||||||
{ label: 'เนื้อหาในไฟล์ (content)', value: 'attachment.content' },
|
{ label: 'เนื้อหาในไฟล์ (content)', value: 'attachment.content' },
|
||||||
]
|
]
|
||||||
const submitSearchData = ref<{
|
const submitSearchData = ref<{
|
||||||
AND: { field: string; value: string }[]
|
AND: { field: string; value: string; exact: boolean }[]
|
||||||
OR: { field: string; value: string }[]
|
OR: { field: string; value: string; exact: boolean }[]
|
||||||
}>({
|
}>({
|
||||||
AND: [],
|
AND: [],
|
||||||
OR: [],
|
OR: [],
|
||||||
|
|
@ -40,7 +41,6 @@ const submitSearchData = ref<{
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
mode: 'admin' | 'user'
|
mode: 'admin' | 'user'
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const socket = io(import.meta.env.VITE_API_HOST)
|
const socket = io(import.meta.env.VITE_API_HOST)
|
||||||
|
|
||||||
socket.on('FileUpdate', (data: StorageFile) =>
|
socket.on('FileUpdate', (data: StorageFile) =>
|
||||||
|
|
@ -68,36 +68,47 @@ async function submitSearch() {
|
||||||
submitSearchData.value.OR.push({
|
submitSearchData.value.OR.push({
|
||||||
field: option.value,
|
field: option.value,
|
||||||
value: searchData.value.value,
|
value: searchData.value.value,
|
||||||
|
exact: true,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
submitSearchData.value.OR.push({
|
submitSearchData.value.OR.push({
|
||||||
field: 'fileName',
|
field: 'fileName',
|
||||||
value: searchData.value.value,
|
value: searchData.value.value,
|
||||||
|
exact: true,
|
||||||
})
|
})
|
||||||
submitSearchData.value.OR.push({
|
submitSearchData.value.OR.push({
|
||||||
field: 'fileType',
|
field: 'fileType',
|
||||||
value: mime.getType(searchData.value.value) || '',
|
value: mime.getType(searchData.value.value) || '',
|
||||||
|
exact: true,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
submitSearchData.value.OR.push({
|
submitSearchData.value.OR.push({
|
||||||
field: searchData.value.field,
|
field: searchData.value.field,
|
||||||
value: searchData.value.value,
|
value: searchData.value.value,
|
||||||
|
exact: isExact.value,
|
||||||
})
|
})
|
||||||
if (isAdvSearchCall.value) {
|
if (isAdvSearchCall.value) {
|
||||||
let advField = advSearchDataField.value
|
let advField = advSearchDataField.value
|
||||||
let advRow = advSearchDataRow.value
|
let advRow = advSearchDataRow.value
|
||||||
|
|
||||||
advRow.forEach((d: { field: string; value: string; op: string }) => {
|
advRow.forEach(
|
||||||
if (d.field && d.value.trim() !== '') {
|
(d: { field: string; value: string; op: string; exact: boolean }) => {
|
||||||
const op = d.op === 'AND' ? 'AND' : 'OR'
|
if (d.field && d.value.trim() !== '') {
|
||||||
submitSearchData.value[op].push({ field: d.field, value: d.value })
|
const op = d.op === 'AND' ? 'AND' : 'OR'
|
||||||
}
|
submitSearchData.value[op].push({
|
||||||
})
|
field: d.field,
|
||||||
|
value: d.value,
|
||||||
|
exact: d.exact,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
if (advField.keyword.length > 0) {
|
if (advField.keyword.length > 0) {
|
||||||
for (let i = 0; i < advField.keyword.length; i++) {
|
for (let i = 0; i < advField.keyword.length; i++) {
|
||||||
submitSearchData.value.AND.push({
|
submitSearchData.value.AND.push({
|
||||||
field: 'keyword',
|
field: 'keyword',
|
||||||
value: advField.keyword[i],
|
value: advField.keyword[i],
|
||||||
|
exact: true,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -105,6 +116,7 @@ async function submitSearch() {
|
||||||
submitSearchData.value.AND.push({
|
submitSearchData.value.AND.push({
|
||||||
field: 'description',
|
field: 'description',
|
||||||
value: advField.description,
|
value: advField.description,
|
||||||
|
exact: true,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -116,6 +128,7 @@ async function submitSearch() {
|
||||||
`${import.meta.env.VITE_API_ENDPOINT}/search`,
|
`${import.meta.env.VITE_API_ENDPOINT}/search`,
|
||||||
submitSearchData.value,
|
submitSearchData.value,
|
||||||
)
|
)
|
||||||
|
|
||||||
getFoundFile(res.data)
|
getFoundFile(res.data)
|
||||||
isSearch.value = true
|
isSearch.value = true
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|
@ -133,7 +146,7 @@ watch(
|
||||||
submitSearch()
|
submitSearch()
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
isActFoundFile.value = false
|
isActFoundFile.value = false
|
||||||
}, 300)
|
}, 1000)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
@ -206,11 +219,20 @@ watch(
|
||||||
</template>
|
</template>
|
||||||
</q-input>
|
</q-input>
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
<q-checkbox
|
||||||
|
id="specificBox"
|
||||||
|
v-model="isExact"
|
||||||
|
label="ค้นหาตรงตัว"
|
||||||
|
color="grey"
|
||||||
|
keep-color
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="column">
|
<div class="col">
|
||||||
<div class="row items-center justify-between q-gutter-y-md q-pt-sm">
|
<div class="row items-center justify-between q-gutter-y-md q-pt-sm">
|
||||||
<div class="column col-grow">
|
<div class="col-grow">
|
||||||
<advanced-search
|
<advanced-search
|
||||||
:submitSearch="submitSearch"
|
:submitSearch="submitSearch"
|
||||||
:submit-search-data="submitSearchData"
|
:submit-search-data="submitSearchData"
|
||||||
|
|
@ -221,6 +243,7 @@ watch(
|
||||||
style="width: 150px"
|
style="width: 150px"
|
||||||
color="primary"
|
color="primary"
|
||||||
label="ค้นหา"
|
label="ค้นหา"
|
||||||
|
class="q-mt-sm"
|
||||||
icon="mdi-magnify"
|
icon="mdi-magnify"
|
||||||
@click="submitSearch"
|
@click="submitSearch"
|
||||||
id="submitSearch"
|
id="submitSearch"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue