Skip to content

Commit 90c8eab

Browse files
authored
[PORT] 고시상품 서치 엔진을 엘라스틱서치로 포팅하였습니다.(#81)
* [EDIT] Briefcase와 Search 컴포넌트에서 payload 변수명을 searchbar 변수명으로 변경하였습니다. Search 컴포넌트에서 네트워크 에러를 예외처리하였습니다. * [PORT] AWS CloudSearch -> ElasticSearch 포팅을 완료하였습니다. ⭐ * [EDIT] ProductAdder에 고시/비고시 상품을 분류하는 기능을 추가합니다. 본래 searchManager에서 수행하던 기능을 productAdder로 위임하였습니다. TODO: #80, search시 autocomplete 기능 구현하기 * [EDIT] HOST address changed since applying elastic IP on EC2
1 parent b34418e commit 90c8eab

6 files changed

Lines changed: 202 additions & 201 deletions

File tree

patent-calculator/package-lock.json

Lines changed: 67 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

patent-calculator/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
},
1111
"dependencies": {
1212
"axios": "^0.18.0",
13+
"elasticsearch": "^15.2.0",
1314
"vue": "^2.5.17",
1415
"vue-session": "^1.0.0",
1516
"vuetify": "^1.0.19",

patent-calculator/src/components/Briefcase.vue

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@
55
<h1 class="headline font-weight-bold mb-2">상품 관리</h1>
66
<v-layout row>
77
<v-flex xs4>
8-
<v-select v-model="search._class" :items="classes" label="분류"></v-select>
8+
<v-select v-model="searchbar.classification" :items="classes" label="분류"></v-select>
99
</v-flex>
1010
<v-spacer></v-spacer>
1111
<v-flex xs7>
1212
<v-text-field
13-
v-model="search.name"
13+
v-model="searchbar.keywords"
1414
append-icon="search"
1515
label="명칭"
1616
single-line
@@ -22,7 +22,7 @@
2222
<v-data-table
2323
:headers="headers"
2424
:items="selected"
25-
:search="search.name"
25+
:search="searchbar.keywords"
2626
:rows-per-page-items="rowsPerPageItems"
2727
no-data-text="선택된 지정상품이 없습니다."
2828
class="mt-3"
@@ -64,7 +64,7 @@
6464
:value="true"
6565
color="error"
6666
icon="warning"
67-
>"{{ search.name }}"을(를) 찾을 수 없습니다.</v-alert>
67+
>"{{ searchbar.keywords }}"을(를) 찾을 수 없습니다.</v-alert>
6868
</v-data-table>
6969
<v-dialog v-model="dialog" width="500">
7070
<v-card>
@@ -111,9 +111,9 @@ export default {
111111
dialog: false,
112112
productClass: "",
113113
rowsPerPageItems: [10, 25, 100],
114-
search: {
115-
_class: "전체",
116-
name: ""
114+
searchbar: {
115+
classification: "전체",
116+
keywords: ""
117117
},
118118
headers: [
119119
{
@@ -194,8 +194,8 @@ export default {
194194
},
195195
selected() {
196196
const selected = this.$store.getters.selected;
197-
const classId = this.classes.indexOf(this.search._class);
198-
if (this.search._class === "전체") {
197+
const classId = this.classes.indexOf(this.searchbar.classification);
198+
if (this.searchbar.classification === "전체") {
199199
return Object.values(selected).reduce((acc, val) => {
200200
return acc.concat(Object.values(val));
201201
}, []);

patent-calculator/src/components/ProductAdder.vue

Lines changed: 61 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,16 @@
1414
<v-stepper-items class="elevation-0">
1515
<v-stepper-content step="1" class="pt-0">
1616
<v-layout column wrap>
17-
<v-flex v-for="payload in payloads" :key="payload.id" class="my-2">
17+
<v-flex v-for="searchbar in searchbars" :key="searchbar.id" class="my-2">
1818
<v-layout column wrap>
1919
<v-flex>
2020
<v-layout row>
2121
<v-flex xs4 class="ml-2">
22-
<v-select v-model="payload.classString" :items="classes" label="분류"></v-select>
22+
<v-select v-model="searchbar.classification" :items="classes" label="분류"></v-select>
2323
</v-flex>
2424
<v-flex xs8 class="ml-5">
2525
<v-textarea
26-
v-model="payload.searchingProducts"
26+
v-model="searchbar.keywords"
2727
append-icon="search"
2828
placeholder="명칭 (붕산비료, 생물 비료, 도매업)"
2929
auto-grow
@@ -38,7 +38,7 @@
3838
color="secondary"
3939
flat
4040
slot="activator"
41-
@click="deleteForm(payload.id)"
41+
@click="deleteForm(searchbar.id)"
4242
>
4343
<v-icon>delete</v-icon>
4444
</v-btn>
@@ -105,16 +105,15 @@ export default {
105105
},
106106
data() {
107107
return {
108-
payloads: [
108+
searchbars: [
109109
{
110110
id: 1,
111-
classString: "",
112-
_class: -1,
113-
searchingProducts: ""
111+
classification: "",
112+
keywords: ""
114113
}
115114
],
116115
curStep: 0,
117-
formCount: 1,
116+
searchbarId: 1,
118117
searchLoading: false
119118
};
120119
},
@@ -124,27 +123,59 @@ export default {
124123
}
125124
},
126125
methods: {
126+
isNoticed(keyword, checklist) {
127+
return (
128+
Object.keys(checklist).length > 0 &&
129+
checklist.hasOwnProperty(this.trim(keyword))
130+
);
131+
},
132+
trim(keyword) {
133+
return keyword.replace(/\s/g, "");
134+
},
127135
classifyProducts() {
128136
this.searchLoading = true;
129-
for (let i = 0; i < this.payloads.length; i++) {
130-
this.payloads[i]._class = this.classes.indexOf(
131-
this.payloads[i].classString
132-
);
133-
}
134137
const requests = [];
135-
for (let i = 0; i < this.payloads.length; i++) {
138+
for (const searchbar of this.searchbars) {
139+
const classification = this.classes.indexOf(searchbar.classification);
136140
requests.push(
137-
this.$searchManager.search(this.payloads[i]).then(response => {
138-
return response;
141+
this.$searchManager.search(0, searchbar.keywords).then(response => {
142+
const checklist = response.reduce((acc, val) => {
143+
acc[this.trim(val["지정상품(국문)"])] = val;
144+
return acc;
145+
}, {});
146+
147+
const keywords = this.$searchManager.trimKeywords(
148+
searchbar.keywords
149+
);
150+
151+
const noticed = keywords
152+
.filter(keyword => this.isNoticed(keyword, checklist))
153+
.map(keyword => checklist[this.trim(keyword)]);
154+
155+
const unnoticed = keywords
156+
.filter(keyword => !this.isNoticed(keyword, checklist))
157+
.map(keyword => {
158+
return {
159+
id: Math.random(),
160+
NICE분류: classification,
161+
"지정상품(국문)": keyword,
162+
"지정상품(영문)": "",
163+
유사군코드: "",
164+
고시명칭: false
165+
};
166+
});
167+
168+
return { noticed: [...new Set(noticed)], unnoticed: unnoticed };
139169
})
140170
);
141171
}
172+
142173
let productAdderPointer = this;
143174
Promise.all(requests).then(responses => {
144175
let result = { noticed: [], unnoticed: [] };
145-
for (let i = 0; i < responses.length; i++) {
146-
result.noticed = result.noticed.concat(responses[i].noticed);
147-
result.unnoticed = result.unnoticed.concat(responses[i].unnoticed);
176+
for (const response of responses) {
177+
result.noticed = result.noticed.concat(response.noticed);
178+
result.unnoticed = result.unnoticed.concat(response.unnoticed);
148179
}
149180
productAdderPointer.$productTransmissionBus.$emit(
150181
"transmitClassified",
@@ -155,24 +186,24 @@ export default {
155186
});
156187
},
157188
addProducts() {
158-
this.$submissionAlarmBus.$emit('submitProductsToBriefcase');
189+
this.$submissionAlarmBus.$emit("submitProductsToBriefcase");
159190
},
160191
addForm() {
161-
this.payloads.push({
162-
id: ++this.formCount,
163-
_class: -1,
164-
searchingProducts: ""
192+
this.searchbars.push({
193+
id: ++this.searchbarId,
194+
classificationEdited: -1,
195+
keywords: ""
165196
});
166197
},
167-
deleteForm(payloadId) {
168-
const deletedIndex = this.payloads.findIndex(
169-
payload => payload["id"] == payloadId
198+
deleteForm(searchbarId) {
199+
const deletedIndex = this.searchbars.findIndex(
200+
searchbar => searchbar["id"] == searchbarId
170201
);
171-
this.payloads.splice(deletedIndex, 1);
202+
this.searchbars.splice(deletedIndex, 1);
172203
}
173204
},
174205
mounted() {
175-
this.$submissionAlarmBus.$on('submissionComplete', () => {
206+
this.$submissionAlarmBus.$on("submissionComplete", () => {
176207
this.curStep = 3;
177208
});
178209
},

0 commit comments

Comments
 (0)