添加相似和推荐功能

This commit is contained in:
2023-06-14 19:10:31 +08:00
parent c1438af1e4
commit 2019e15b7a
13 changed files with 715 additions and 91 deletions

View File

@@ -51,11 +51,14 @@
</template>
</el-table-column>
<el-table-column prop="createTime" label="创建时间" width="180"></el-table-column>
<el-table-column label="操作" width="100">
<el-table-column label="操作" width="150">
<template slot-scope="scope">
<el-button @click.native.prevent="modifyRow(scope.row)" type="text" size="small">
编辑
</el-button>
<el-button @click.native.prevent="similarItem(scope.row)" type="text" size="small">
相似条目
</el-button>
<el-button @click.native.prevent="removeRow(scope.row)" type="text" size="small">
删除
</el-button>
@@ -180,6 +183,10 @@ export default {
},
mounted() {
_this = this;
let _qo = _this.$route.query.qo;
if (_qo) {
_this.qo = JSON.parse(_qo);
}
_this.queryData();
},
methods: {
@@ -202,6 +209,14 @@ export default {
_this.qo.pageNo = val;
_this.queryData();
},
similarItem(item) {
_this.$router.push({
path: "similarItem", query: {
itemId: item.fid,
qo: JSON.stringify(_this.qo)
}
});
},
removeRow(item) {
_this.$confirm('此操作将永久删除记录, 是否继续?', '提示', {
confirmButtonText: '确定',

View File

@@ -21,9 +21,22 @@
<el-table :data="result.records" style="width: 100%">
<el-table-column type="index" label="行号" width="60"></el-table-column>
<el-table-column prop="fid" label="fid"></el-table-column>
<el-table-column prop="createTime" label="创建时间" width="180"></el-table-column>
<el-table-column label="操作" width="100">
<el-table-column prop="labels" label="标签">
<div slot-scope="scope">
<template v-for="(tag,index) in scope.row.labelsArr">
<el-tag :key="index" v-if="index < 5">{{ tag }}</el-tag>
</template>
<el-tag v-if="scope.row.labelsArr.length > 5">...</el-tag>
</div>
</el-table-column>
<el-table-column label="操作" width="180">
<template slot-scope="scope">
<el-button @click.native.prevent="similarUser(scope.row)" type="text" size="small">
相似
</el-button>
<el-button @click.native.prevent="recommendItem(scope.row)" type="text" size="small">
洞悉
</el-button>
<el-button @click.native.prevent="modifyRow(scope.row)" type="text" size="small">
编辑
</el-button>
@@ -90,6 +103,10 @@ export default {
},
mounted() {
_this = this;
let _qo = _this.$route.query.qo;
if (_qo) {
_this.qo = JSON.parse(_qo);
}
_this.queryData();
},
methods: {
@@ -99,6 +116,9 @@ export default {
method: 'post',
data: _this.qo
}).then(res => {
res.data.records.forEach(row => {
row.labelsArr = row.labels ? row.labels.split(',') : [];
});
_this.result.records = res.data.records;
_this.result.total = res.data.total;
});
@@ -107,6 +127,22 @@ export default {
_this.qo.pageNo = val;
_this.queryData();
},
similarUser(item) {
_this.$router.push({
path: "similarUser", query: {
userId: item.fid,
qo: JSON.stringify(_this.qo)
}
});
},
recommendItem(item) {
_this.$router.push({
path: "recommendItem", query: {
userId: item.fid,
qo: JSON.stringify(_this.qo)
}
});
},
removeRow(item) {
_this.$confirm('此操作将永久删除记录, 是否继续?', '提示', {
confirmButtonText: '确定',
@@ -126,7 +162,7 @@ export default {
createRow() {
_this.dialogName = '新建';
_this.cmdDialogVisible = true;
_this.$nextTick(_=> {
_this.$nextTick(_ => {
_this.$refs['cmd'].clearValidate();
_this.cmd = {
fid: '',
@@ -136,7 +172,7 @@ export default {
modifyRow(item) {
_this.dialogName = '编辑';
_this.cmdDialogVisible = true;
_this.$nextTick(_=> {
_this.$nextTick(_ => {
_this.$refs['cmd'].clearValidate();
_this.cmd = JSON.parse(JSON.stringify(item));
})

View File

@@ -0,0 +1,178 @@
<template>
<div style="height: 100%">
<div class="menu-title">
洞悉{{ gorseQo.userId }}
<div class="icon icon-back" @click="backBtn">
<i title="返回"></i>
</div>
</div>
<div class="block_box" style="margin-top: 0">
<div class="title">推荐</div>
<el-form :inline="true" class="demo-form-inline">
<el-form-item>
<el-select v-model="gorseQo.recommendation" @change="getRecommendItem">
<el-option :key="item.value" :value="item.value" :label="item.label"
v-for="item in recommendList"></el-option>
</el-select>
</el-form-item>
<el-form-item label="categories">
<el-select v-model="gorseQo.category" @change="getRecommendItem">
<el-option value="" label="无"></el-option>
<el-option :key="item.id" :value="item.name" :label="item.name"
v-for="item in categoryList"></el-option>
</el-select>
</el-form-item>
</el-form>
<div class="line-item-box">
<div class="line-item" v-for="item in list" :key="item.id">
<div class="title-time">
<div>{{ item.ItemId }}</div>
<div>{{ item.Timestamp }}</div>
</div>
<div class="description">{{ item.Comment }}</div>
<div class="labels">
<el-tag v-for="la in item.Labels">{{ la }}</el-tag>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import request from '@/utils/request';
var _this;
export default {
name: "RecommendItem",
data() {
return {
qo: "",
gorseQo: {
userId: '',
n: 10,
recommendation: '_',
category: ''
},
user: {},
categoryList: [],
recommendList: [{
label: 'Recommendation',
value: '_'
}, {
label: 'Offline Recommendation',
value: 'offline'
}, {
label: 'Collaborative Recommendation',
value: 'collaborative'
}, {
label: 'Item-based Recommendation',
value: 'item_based'
}, {
label: 'User-based Recommendation',
value: 'user_based'
}],
list: []
}
},
mounted() {
_this = this;
_this.qo = _this.$route.query.qo;
_this.gorseQo.userId = _this.$route.query.userId;
_this.queryCategoryList();
_this.getRecommendItem();
},
methods: {
queryCategoryList() {
request({
url: '/category/query_list',
method: 'post',
data: {}
}).then(res => {
_this.categoryList = res.data;
});
},
getRecommendItem() {
request({
url: '/gorse/get_recommend_by_user',
method: 'post',
data: _this.gorseQo
}).then(res => {
res.data.forEach(row => {
row.labelsArr = row.labels ? row.labels.split(',') : [];
});
_this.list = res.data;
});
},
backBtn() {
this.$router.push({
path: "userManage", query: {
qo: _this.qo
}
});
},
}
}
</script>
<style src="../../../css/back.css" scoped></style>
<style scoped lang="scss">
.block_box {
margin: 25px;
background: #FFFFFF;
border-radius: 3px;
height: calc(100% - 160px);
.title {
border-bottom: 1px solid #ccc;
padding: 15px 25px;
}
}
.demo-form-inline {
padding: 25px 25px 0 25px;
}
.line-item-box {
height: calc(100% - 140px);
overflow-y: auto;
.line-item {
font-size: 14px;
line-height: 32px;
padding: 0 25px 10px 25px;
margin: 20px 0;
border-bottom: 1px solid #dee0e2;
.title-time {
display: flex;
div:first-child {
font-weight: bold;
font-size: 18px;
color: #9da2a8;
}
div:last-child {
margin-left: auto;
color: #bbbcbd;
}
}
.description {
color: #bbbcbd;
}
.labels {
color: #9da2a8;
.el-tag {
margin: 0 10px 10px 0;
}
}
}
}
</style>

View File

@@ -0,0 +1,175 @@
<template>
<div class="similar-item-box">
<div class="menu-title">
相似用户{{ gorseQo.itemId }}
<div class="icon icon-back" @click="backBtn">
<i title="返回"></i>
</div>
</div>
<div class="block_box" style="margin-top: 0">
<div class="title">信息</div>
<div >
<el-form label-width="50px">
<el-form-item label="时间">{{ item.createTime }}</el-form-item>
<el-form-item label="类别">
<template v-for="(tag,index) in item.categoriesArr">
<el-tag :key="index">{{ tag }}</el-tag>
</template>
</el-form-item>
<el-form-item label="标签">
<template v-for="(tag,index) in item.labelsArr">
<el-tag :key="index">{{ tag }}</el-tag>
</template>
</el-form-item>
<el-form-item label="描述">
{{ item.description }}
</el-form-item>
</el-form>
</div>
</div>
<div class="block_box">
<div class="title">Related Items</div>
<el-form :inline="true" class="demo-form-inline">
<el-form-item label="categories">
<el-select v-model="gorseQo.category" @change="getSimilarItem">
<el-option value="" label="无"></el-option>
<el-option :key="item.id" :value="item.name" :label="item.name"
v-for="item in categoryList"></el-option>
</el-select>
</el-form-item>
</el-form>
<div style="padding-top: 0">
<el-table :data="list" style="width: 100%">
<el-table-column type="index" label="行号" width="60"></el-table-column>
<el-table-column prop="ItemId" label="fid"></el-table-column>
<el-table-column prop="labels" label="类别">
<div slot-scope="scope">
<template v-for="(tag,index) in scope.row.Categories">
<el-tag :key="index" v-if="index < 5">{{ tag }}</el-tag>
</template>
<el-tag v-if="scope.row.Categories.length > 5">...</el-tag>
</div>
</el-table-column>
<el-table-column prop="labels" label="标签">
<div slot-scope="scope">
<template v-for="(tag,index) in scope.row.Labels">
<el-tag :key="index" v-if="index < 5">{{ tag }}</el-tag>
</template>
<el-tag v-if="scope.row.Labels.length > 5">...</el-tag>
</div>
</el-table-column>
<el-table-column prop="Comment" label="描述">
<template slot-scope="scope" v-if="scope.row.Comment">
{{ scope.row.Comment.substring(0, 100) }}
</template>
</el-table-column>
<el-table-column prop="Score" label="Score" width="100">
<template slot-scope="scope">
{{ scope.row.Score.toFixed(5) }}
</template>
</el-table-column>
<el-table-column prop="Timestamp" label="创建时间" width="200"></el-table-column>
</el-table>
</div>
</div>
</div>
</template>
<script>
import request from '@/utils/request';
var _this;
export default {
name: "similarItem",
data() {
return {
qo: "",
gorseQo: {
itemId: '',
category: '',
n: 10
},
item: {},
list: [],
categoryList: []
}
},
mounted() {
_this = this;
_this.qo = _this.$route.query.qo;
_this.gorseQo.itemId = _this.$route.query.itemId;
_this.queryCategoryList();
_this.queryItem();
_this.getSimilarItem();
},
methods: {
queryCategoryList() {
request({
url: '/category/query_list',
method: 'post',
data: {}
}).then(res => {
_this.categoryList = res.data;
});
},
queryItem() {
request({
url: '/entrys/query_unique',
method: 'post',
data: {
EQS_fid: _this.gorseQo.itemId
}
}).then(res => {
res.data.labelsArr = res.data.labels ? res.data.labels.split(',') : [];
res.data.categoriesArr = res.data.categories ? res.data.categories.split(',') : [];
_this.item = res.data;
});
},
getSimilarItem() {
request({
url: '/gorse/get_similar_item',
method: 'post',
data: _this.gorseQo
}).then(res => {
_this.list = res.data;
});
},
backBtn() {
this.$router.push({
path: "entrysManage", query: {
qo: _this.qo
}
});
},
}
}
</script>
<style src="../../../css/back.css" scoped></style>
<style scoped lang="scss">
.similar-item-box {
height: 100%;
overflow-y: auto;
}
.block_box {
margin: 25px;
background: #FFFFFF;
border-radius: 3px;
.title {
border-bottom: 1px solid #ccc;
padding: 15px 25px;
}
> div {
padding: 25px;
}
}
.demo-form-inline {
padding: 25px 25px 0 25px;
}
</style>

View File

@@ -0,0 +1,122 @@
<template>
<div>
<div class="menu-title">
相似用户{{ userId }}
<div class="icon icon-back" @click="backBtn">
<i title="返回"></i>
</div>
</div>
<div class="block_box" style="margin-top: 0">
<div class="title">信息</div>
<div>
<el-form label-width="100px">
<el-form-item label="标签">
<template v-for="(tag,index) in user.labelsArr">
<el-tag :key="index">{{ tag }}</el-tag>
</template>
</el-form-item>
</el-form>
</div>
</div>
<div class="block_box">
<div class="title">Related Items</div>
<div>
<el-table :data="list" style="width: 100%">
<el-table-column type="index" label="行号" width="60"></el-table-column>
<el-table-column prop="UserId" label="UserId"></el-table-column>
<el-table-column prop="labels" label="标签">
<div slot-scope="scope">
<template v-for="(tag,index) in scope.row.labelsArr">
<el-tag :key="index" v-if="index < 5">{{ tag }}</el-tag>
</template>
<el-tag v-if="scope.row.labelsArr.length > 5">...</el-tag>
</div>
</el-table-column>
<el-table-column prop="Score" label="Score">
<template slot-scope="scope">
{{scope.row.Score.toFixed(5)}}
</template>
</el-table-column>
</el-table>
</div>
</div>
</div>
</template>
<script>
import request from '@/utils/request';
var _this;
export default {
name: "similarUser",
data() {
return {
qo: "",
userId: '',
user: {},
list: []
}
},
mounted() {
_this = this;
_this.qo = _this.$route.query.qo;
_this.userId = _this.$route.query.userId;
_this.queryUser();
_this.getSimilarUser();
},
methods: {
queryUser() {
request({
url: '/risk-user/query_unique',
method: 'post',
data: {
EQS_fid: _this.userId
}
}).then(res => {
res.data.labelsArr = res.data.labels ? res.data.labels.split(',') : [];
_this.user = res.data;
});
},
getSimilarUser() {
request({
url: '/gorse/get_similar_user',
method: 'post',
data: {
userId: _this.userId
}
}).then(res => {
res.data.forEach(row => {
row.labelsArr = row.labels ? row.labels.split(',') : [];
});
_this.list = res.data;
});
},
backBtn() {
this.$router.push({
path: "userManage", query: {
qo: _this.qo
}
});
},
}
}
</script>
<style src="../../../css/back.css" scoped></style>
<style scoped lang="scss">
.block_box {
margin: 25px;
background: #FFFFFF;
border-radius: 3px;
.title {
border-bottom: 1px solid #ccc;
padding: 15px 25px;
}
>div {
padding: 25px;
}
}
</style>

25
web/src/css/back.css Normal file
View File

@@ -0,0 +1,25 @@
div.icon {
display: inline-block;
cursor: pointer;
height: 50px;
background-color: #fff;
border-radius: 2.08333vw;
float: right;
width: 50px;
text-align: center;
line-height: 50px;
margin-right: 80px;
margin-top: 9px;
}
div.icon i {
width: 25px;
height: 25px;
margin: auto;
display: inline-block;
vertical-align: sub;
}
.icon-back i {
background: url("../assets/image/icon/fanhui.png") no-repeat center/contain;
}

View File

@@ -63,6 +63,18 @@ export default new Router({
path: 'intelligenceRecommend',
component: () => import('@/components/menus/IntelligenceRecommend')
},
{
path: 'similarUser',
component: () => import('@/components/menus/user/SimilarUser')
},
{
path: 'recommendItem',
component: () => import('@/components/menus/item/RecommendItem')
},
{
path: 'similarItem',
component: () => import('@/components/menus/item/SimilarItem')
},
{
path: '/',
redirect: "homePage"