478 lines
13 KiB
Vue
478 lines
13 KiB
Vue
<template>
|
||
<div class="mb-2">
|
||
<div class="container-fluid similar-section firefox-scrollbar">
|
||
<div class="row mt-2 main-similar justify-content-center">
|
||
<!-- border-similar remov -->
|
||
<div
|
||
class="col-12 d-flex my-2 content"
|
||
v-for="(item, index) in listSimilar"
|
||
:key="index"
|
||
>
|
||
<div class="row d-flex flex-column border-bottom pb-2 ">
|
||
<div class="d-flex align-items-center link-similar">
|
||
<button-component
|
||
title="کپی لینک"
|
||
buttonText=""
|
||
classes="color-1 "
|
||
@click="copyToClipboard()"
|
||
>
|
||
<svg class="icon icon-copy2">
|
||
<use xlink:href="#icon-copy2"></use>
|
||
</svg>
|
||
</button-component>
|
||
<div class="">
|
||
<router-link
|
||
:to="{ name: 'searchResult' }"
|
||
class="text-title-QSection1"
|
||
>قوانین</router-link
|
||
>
|
||
<span class="me-2">❯</span>
|
||
<a
|
||
class="text-title-QSection2"
|
||
:href="urlResolver(item._source.qanon_id, 'qasection')"
|
||
target="_blank"
|
||
>
|
||
{{ item._source.qanon_title }}
|
||
</a>
|
||
<span class="me-2 ms-2">❯</span>
|
||
<a
|
||
class="text-title-QSection2"
|
||
v-if="item._source.other_info?.full_path"
|
||
:href="getDetailUrl(item)"
|
||
target="_blank"
|
||
>{{ item._source.other_info.full_path }}</a
|
||
>
|
||
</div>
|
||
</div>
|
||
<div class="d-flex me-5 date-content">
|
||
<span class="" v-if="item._source.ts_ref" style="color: #4b5567"
|
||
><span class="text__dark-gray">مرجع تصویب :</span>
|
||
{{ item._source.ts_ref }}</span
|
||
>
|
||
<span
|
||
class="me-2"
|
||
v-if="item._source.ts_date"
|
||
style="color: #4b5567"
|
||
><span class="text__dark-gray">تاریخ تصویب :</span>
|
||
{{ item._source.ts_date }}</span
|
||
>
|
||
</div>
|
||
<div v-html="getSimilarHtml(item)" class="me-5 mt-2 ms-2 list-similar"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<jahat-Pagination
|
||
:paginationInfo="pagination"
|
||
@page-changed="pageChanged"
|
||
@page-limit-changed="pageLimitChanged"
|
||
@sort-changed="sortChanged"
|
||
></jahat-Pagination>
|
||
</div>
|
||
</template>
|
||
|
||
<script>
|
||
import { mapState, mapActions } from "pinia";
|
||
|
||
import entityApi from "~/apis/entityApi";
|
||
import searchApi from "~/apis/searchApi";
|
||
|
||
const Diffcomponent = require("diff");
|
||
|
||
export default {
|
||
props: {
|
||
bmCurrentItemEntity: {
|
||
default: "",
|
||
},
|
||
currentSchemaEntityContent: {
|
||
type: Object,
|
||
default() {
|
||
return {};
|
||
},
|
||
},
|
||
},
|
||
beforeMount() {
|
||
this.httpService = useNuxtApp()["$http"];
|
||
},
|
||
mounted() {
|
||
this.similarStart();
|
||
this.getSimilar();
|
||
},
|
||
|
||
|
||
data() {
|
||
return {
|
||
httpService: undefined,
|
||
listSimilar: [],
|
||
pagination: {
|
||
page: 1,
|
||
pages: 0,
|
||
total: 0,
|
||
offset: 0, // page * per_page
|
||
limit: 10, //per_page
|
||
},
|
||
};
|
||
},
|
||
computed: {
|
||
...mapState("entity", [
|
||
"entityViewSchemaGetter",
|
||
"activeEntityViewSchemaGetter",
|
||
"similarInfoGetter",
|
||
]),
|
||
},
|
||
methods: {
|
||
...mapActions("entity", ["similarInfoSetter"]),
|
||
getSimilarHtml(item) {
|
||
let res = [];
|
||
if (item["highlight"]["rules.text"])
|
||
res = item["highlight"]["rules.text"];
|
||
if (item["highlight"]["rules_logics.text"])
|
||
res = item["highlight"]["rules_logics.text"];
|
||
if (item["highlight"]["rules_logics_triples.text"])
|
||
res = item["highlight"]["rules_logics_triples.text"];
|
||
|
||
let result = "";
|
||
res.forEach((el) => {
|
||
if(result != "")
|
||
result += "<br>"
|
||
result += '<span class="similar-text">' + el + "</span>";
|
||
});
|
||
return result;
|
||
},
|
||
similarStart() {
|
||
// let sm = smObject ? smObject : this.similarInfoGetter;
|
||
let sm = this.similarInfoGetter;
|
||
// console.log(sm);
|
||
if (sm?.text || sm?.id) {
|
||
if (sm?.type == "vector") this.getVectorSimilar(sm.text, sm.id);
|
||
else this.getSimilar(sm.text, sm.id);
|
||
}
|
||
},
|
||
/**
|
||
* ساخت نشانی پیوند انتقال به جزئیات هر بخش قانون.
|
||
* @param {Object} item - شیء اصلی.
|
||
*/
|
||
getDetailUrl(item) {
|
||
let key = "";
|
||
key = this.myKey;
|
||
if (!key) key = "qasection"; // برای شرایطی که بصورت مدال استفاده می شود گتر بالا پر نیست
|
||
|
||
let id = item._id;
|
||
let hash = "";
|
||
hash = "#qmodel";
|
||
key = "qsection";
|
||
id = item._source?.ref_id ? item._source.ref_id : id;
|
||
|
||
if (key == "qasection") {
|
||
key = "qsection";
|
||
}
|
||
|
||
let name = "detail";
|
||
const routeData = this.$router.resolve({
|
||
name: name,
|
||
params: {
|
||
id: id,
|
||
key: key,
|
||
},
|
||
hash: hash,
|
||
query: {},
|
||
});
|
||
return routeData.href;
|
||
},
|
||
|
||
getSimilar(text, id = undefined) {
|
||
let url = repoUrl()+entityApi.similar.textual;
|
||
url = url.replace("{{index_key}}", "qmodel");
|
||
url = url.replace("{{field}}", this.currentSchemaEntityContent.key +"__text");
|
||
url = url.replace("{{offset}}", this.pagination.offset);
|
||
url = url.replace("{{limit}}", this.pagination.limit);
|
||
|
||
const payload = {
|
||
text: this.bmCurrentItemEntity.text,
|
||
};
|
||
// url = url.replace("/q={{text}}", "");
|
||
|
||
this.httpService.postRequest(url, payload).then((res) => {
|
||
this.listSimilar = res.hits.hits;
|
||
// PAGA
|
||
const total = res.hits.total.value;
|
||
const pages = Math.ceil(total / this.pagination.limit);
|
||
const pagination = {
|
||
total: total,
|
||
pages: pages == 0 ? 1 : pages,
|
||
};
|
||
|
||
this.pagination = { ...this.pagination, ...pagination };
|
||
});
|
||
},
|
||
pageLimitChanged(paging) {
|
||
this.resetPagination();
|
||
this.pagination.limit = paging.limit;
|
||
this.getSimilar();
|
||
},
|
||
pageChanged(paging) {
|
||
let page = paging.pageNumber;
|
||
page -= 1;
|
||
this.pagination.offset = page * paging.limit;
|
||
this.pagination.limit = paging.limit;
|
||
this.pagination.page = paging.pageNumber;
|
||
this.getSimilar();
|
||
},
|
||
sortChanged(sorting) {
|
||
this.pagination.page = this.pagination.offset = 0;
|
||
this.sorting = sorting;
|
||
this.getSimilar();
|
||
},
|
||
resetPagination() {
|
||
this.pagination = {
|
||
pages: 0,
|
||
total: 0,
|
||
page: 1,
|
||
offset: 0,
|
||
limit: 10,
|
||
};
|
||
},
|
||
|
||
getVectorSimilar(text, id = undefined) {
|
||
// console.log("getRequestSimilar", text);
|
||
|
||
// let url = entityApi.similar.vector;
|
||
// url = url.replace("{{index_key}}", "qmodel");
|
||
// url = url.replace("{{sort_state}}", "searchsort");
|
||
// url = url.replace("{{offset}}", 0);
|
||
// url = url.replace("{{limit}}", 10);
|
||
|
||
let url = repoUrl()+searchApi.search.queryNormal;
|
||
url = url.replace("{{appname}}", buildName());
|
||
url = url.replace("{{index_key}}", "qmodel");
|
||
url = url.replace("{{search_type}}", "vector");
|
||
url = url.replace("{{sortKey}}", "searchsort");
|
||
url = url.replace("{{field_collapse}}", this.activeEntityViewSchemaGetter?.field_collapse);
|
||
url = url.replace("{{offset}}", 0);
|
||
url = url.replace("{{limit}}", 10);
|
||
url = url.replace("/{{filter}}", "");
|
||
|
||
|
||
const payload = {
|
||
text: text,
|
||
id: id,
|
||
};
|
||
|
||
this.httpService.postRequest(url, payload).then((res) => {
|
||
this.listSimilar = res.hits.hits;
|
||
});
|
||
},
|
||
similarHandler(key, list) {
|
||
return list[key];
|
||
},
|
||
|
||
similarHref(key, list) {
|
||
return this.urlResolver(list._source.qanon_id, "qmodel");
|
||
|
||
// if (key == "qanon_title")
|
||
// return this.urlResolver(list._source?.qanon_id, "mqanon");
|
||
// else return this.urlResolver(list._id, "mqsection");
|
||
},
|
||
|
||
closedSimiler() {
|
||
this.$emit("setShowSimilar", false);
|
||
// let sm = this.similarInfoGetter;
|
||
// sm.show = false;
|
||
// this.similarInfoSetter(sm);
|
||
},
|
||
normalizdPersain(text) {
|
||
text = text.replaceAll("ي", "ی");
|
||
text = text.replaceAll("ك", "ک");
|
||
text = text.replaceAll("ة", "ه");
|
||
// text = text.replaceAll(/[ىی]/g, 'ي');
|
||
return text;
|
||
},
|
||
similarDiff(newText, oldText = undefined) {
|
||
let diffType = "diffWords"; // تعریف متغیر diffType
|
||
let resText; // تعریف متغیر resText
|
||
oldText = oldText ? oldText : this.similarInfoGetter?.text;
|
||
|
||
oldText = this.normalizdPersain(oldText);
|
||
newText = this.normalizdPersain(newText);
|
||
const extractedDifferences = Diffcomponent[diffType](oldText, newText);
|
||
let res = extractedDifferences;
|
||
resText = this.makeCorrectedText(res);
|
||
|
||
return resText;
|
||
},
|
||
makeCorrectedText(extractedDifferences) {
|
||
var newItem = "";
|
||
|
||
// var result = diff(good, bad);
|
||
// [[-1, "Goo"], [1, "Ba"], [0, "d dog"]]
|
||
|
||
// -1 : removed
|
||
// 0 : no change
|
||
// 1 : added change
|
||
let i = 0;
|
||
|
||
for (i = 0; i < extractedDifferences.length; i++) {
|
||
var diffItem = extractedDifferences[i];
|
||
// var diffItem1 = p2e(diffItem[1]);
|
||
// var diffItem1 = diffItem[1]?.value;
|
||
// if (!diffItem1) continue;
|
||
|
||
if (!diffItem.added && !diffItem.removed) {
|
||
newItem += diffItem.value;
|
||
} else {
|
||
if (diffItem.removed) {
|
||
newItem += `<a target="_blank" class="removed-change">${diffItem.value}</a>`;
|
||
} else if (diffItem.added) {
|
||
newItem += `<a target="_blank" class="added-change">${diffItem.value}</a>`;
|
||
}
|
||
}
|
||
}
|
||
|
||
return newItem;
|
||
},
|
||
|
||
// urlResolver(_parent, key = "") {
|
||
// if (key == "") key = this.myKey;
|
||
// if (!key) key = "qasection"; // برای شرایطی که بصورت مدال استفاده می شود گتر بالا پر نیست
|
||
|
||
// let name = "navigationView";
|
||
// if (key == "qsection") name = "detail";
|
||
|
||
// const routeData = this.$router.resolve({
|
||
// name: name,
|
||
// params: {
|
||
// id: _parent,
|
||
// key: key,
|
||
// },
|
||
// query: {},
|
||
// });
|
||
// return routeData.href;
|
||
// },
|
||
|
||
urlResolver(_id, key = "") {
|
||
if (key == "") key = "qmodel";
|
||
const routeData = this.$router.resolve({
|
||
name: "navigationView",
|
||
params: {
|
||
id: _id,
|
||
key: key,
|
||
},
|
||
query: {},
|
||
});
|
||
return routeData.href;
|
||
},
|
||
},
|
||
|
||
|
||
};
|
||
</script>
|
||
<style lang="scss" scoped>
|
||
.content {
|
||
text-align: justify;
|
||
}
|
||
.text-title-QSection2 {
|
||
color: #3279C7 !important;
|
||
&:hover {
|
||
// color: blue !important;
|
||
text-decoration: underline !important;
|
||
}
|
||
}
|
||
.text-title-QSection1 {
|
||
color: #3279C7 !important;
|
||
&:hover {
|
||
// color: blue !important;
|
||
text-decoration: underline !important;
|
||
}
|
||
}
|
||
.icon-copy2 {
|
||
font-size: 0.7rem;
|
||
}
|
||
.similar-section {
|
||
height: 21em;
|
||
overflow: auto;
|
||
}
|
||
.link-similar{
|
||
font-size: 0.97rem;
|
||
}
|
||
.list-similar{
|
||
font-size: 0.91rem;
|
||
}
|
||
.date-content{
|
||
font-size: 0.92rem;
|
||
|
||
}
|
||
|
||
// .added-change {
|
||
// font-family: sahel-bold;
|
||
// color: green;
|
||
// }
|
||
// .removed-change {
|
||
// // font-family: sahel-bold;
|
||
// color: red;
|
||
// text-decoration: line-through;
|
||
// }
|
||
//
|
||
</style>
|
||
//
|
||
<style scoped lang="scss">
|
||
// .label-text {
|
||
// }
|
||
// .P-text {
|
||
// color: var(--text-primary);
|
||
// }
|
||
|
||
// .similar-row {
|
||
// font-size: 12px;
|
||
// line-height: 1rem;
|
||
// p {
|
||
// overflow: hidden;
|
||
// white-space: nowrap;
|
||
// text-overflow: ellipsis;
|
||
// }
|
||
// }
|
||
|
||
// .header-similar {
|
||
// width: 95%;
|
||
// margin: 0 auto;
|
||
// height: 6em;
|
||
// }
|
||
// .main-similar {
|
||
// // height: calc(100vh - 16em);
|
||
// height: 19em;
|
||
// overflow: auto;
|
||
// overflow-x: hidden;
|
||
// padding: 0 1em;
|
||
// }
|
||
// .similar-title {
|
||
// max-width: 14em;
|
||
// width: 100%;
|
||
// overflow: hidden;
|
||
// text-overflow: ellipsis;
|
||
// white-space: nowrap;
|
||
// font-weight: normal;
|
||
// font-size: 14px;
|
||
// text-align: right;
|
||
// color: var(--blue-color);
|
||
// border: 1px solid rgba(0, 0, 0, 0);
|
||
// text-decoration: none;
|
||
// }
|
||
|
||
// .border-similar {
|
||
// position: relative;
|
||
|
||
// &::after {
|
||
// content: "";
|
||
// position: absolute;
|
||
// width: 18.5em;
|
||
// border-bottom: 1px solid #dee2e6;
|
||
// // background-color: #dee2e6;
|
||
// }
|
||
// }
|
||
// @media only screen and (min-width: 768px) and (max-width: 991.98px) {
|
||
// }
|
||
// @media only screen and (min-width: 576px) and (max-width: 766.98px) {
|
||
// }
|
||
// @media (max-width: 575.98px) {
|
||
// }
|
||
</style>
|