Merge branch 'master' of http://nas.zhengjl.com:10880/wan/recom-gorse
This commit is contained in:
@@ -6,10 +6,7 @@ import java.util.Map;
|
|||||||
|
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
import com.wx.application.adapter.dto.qo.GorseQ;
|
import com.wx.application.adapter.dto.qo.GorseQ;
|
||||||
import com.wx.application.base.BaseController;
|
import com.wx.application.base.BaseController;
|
||||||
@@ -47,6 +44,7 @@ public class GorseController extends BaseController {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 推荐根据userId
|
* 推荐根据userId
|
||||||
|
*
|
||||||
* @param gQo
|
* @param gQo
|
||||||
* @return
|
* @return
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
@@ -54,7 +52,7 @@ public class GorseController extends BaseController {
|
|||||||
@PostMapping(value = "/recommend_by_userid")
|
@PostMapping(value = "/recommend_by_userid")
|
||||||
public ResponseData recommendByUserId(@RequestBody GorseQ gQo) throws Exception {
|
public ResponseData recommendByUserId(@RequestBody GorseQ gQo) throws Exception {
|
||||||
List<String> res = gorseService.getRecommend(gQo.getUserId());
|
List<String> res = gorseService.getRecommend(gQo.getUserId());
|
||||||
if(res == null || res.size() == 0) {
|
if (res == null || res.size() == 0) {
|
||||||
return success();
|
return success();
|
||||||
}
|
}
|
||||||
Map mQ = new HashMap<>();
|
Map mQ = new HashMap<>();
|
||||||
@@ -64,6 +62,7 @@ public class GorseController extends BaseController {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据列表推荐
|
* 根据列表推荐
|
||||||
|
*
|
||||||
* @param gQo
|
* @param gQo
|
||||||
* @return
|
* @return
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
@@ -83,6 +82,7 @@ public class GorseController extends BaseController {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 推荐根据知识图谱
|
* 推荐根据知识图谱
|
||||||
|
*
|
||||||
* @param gQo
|
* @param gQo
|
||||||
* @return
|
* @return
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
@@ -93,12 +93,12 @@ public class GorseController extends BaseController {
|
|||||||
NebulaModel nebulaModel = nebulaOperateService.findOnePathById("", gQo.getUserId());
|
NebulaModel nebulaModel = nebulaOperateService.findOnePathById("", gQo.getUserId());
|
||||||
List<NebulaNode> nodes = nebulaModel.getNodes();
|
List<NebulaNode> nodes = nebulaModel.getNodes();
|
||||||
|
|
||||||
if(nodes != null && nodes.size() > 0) {
|
if (nodes != null && nodes.size() > 0) {
|
||||||
nodes.get(0).getVid();
|
nodes.get(0).getVid();
|
||||||
}
|
}
|
||||||
|
|
||||||
List<String> res = gorseService.getRecommend(gQo.getUserId());
|
List<String> res = gorseService.getRecommend(gQo.getUserId());
|
||||||
if(res == null || res.size() == 0) {
|
if (res == null || res.size() == 0) {
|
||||||
return success();
|
return success();
|
||||||
}
|
}
|
||||||
Map mQ = new HashMap<>();
|
Map mQ = new HashMap<>();
|
||||||
@@ -106,5 +106,20 @@ public class GorseController extends BaseController {
|
|||||||
return success(entrysService.queryList(mQ));
|
return success(entrysService.queryList(mQ));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PostMapping(value = "/get_similar_user")
|
||||||
|
public ResponseData getSimilarUser(@RequestBody GorseQ gQo) throws Exception {
|
||||||
|
return success(gorseService.getSimilarUser(gQo.getUserId()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping(value = "/get_recommend_by_user")
|
||||||
|
public ResponseData getRecommendByUser(@RequestBody GorseQ gQo) throws Exception {
|
||||||
|
return success(gorseService.getRecommendByUser(gQo.getUserId(), gQo.getRecommendation(), gQo.getCategory(), gQo.getN()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping(value = "/get_similar_item")
|
||||||
|
public ResponseData getSimilarItem(@RequestBody GorseQ gQo) throws Exception {
|
||||||
|
return success(gorseService.getSimilarItem(gQo.getItemId(), gQo.getCategory(), gQo.getN()));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,5 +9,11 @@ public class GorseQ {
|
|||||||
|
|
||||||
private String userId;
|
private String userId;
|
||||||
|
|
||||||
|
private String itemId;
|
||||||
|
|
||||||
private String category;
|
private String category;
|
||||||
|
|
||||||
|
private Integer n;
|
||||||
|
|
||||||
|
private String recommendation;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,4 +34,9 @@ public class RiskUserController extends BaseController {
|
|||||||
return success(userService.queryPage(entrysQ));
|
return success(userService.queryPage(entrysQ));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PostMapping(value = "/query_unique")
|
||||||
|
public ResponseData queryUnique(@RequestBody Map entrysQ) {
|
||||||
|
return success(userService.queryUnique(entrysQ));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import java.net.URL;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@@ -66,6 +67,33 @@ public class GorseService {
|
|||||||
return Arrays.asList(this.request("GET", this.endpoint + "/api/dashboard/popular/" + category, null, Item[].class));
|
return Arrays.asList(this.request("GET", this.endpoint + "/api/dashboard/popular/" + category, null, Item[].class));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 相似(获取相似用户)
|
||||||
|
*/
|
||||||
|
public List<User> getSimilarUser(String userId) throws IOException {
|
||||||
|
return Arrays.asList(this.request("GET", this.endpoint + "/api/dashboard/user/" + userId + "/neighbors", null, User[].class));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 洞悉(根据用户获取推荐)
|
||||||
|
*/
|
||||||
|
public List<Item> getRecommendByUser(String userId, String recommendation, String category, Integer n) throws IOException {
|
||||||
|
return Arrays.asList(this.request("GET", this.endpoint + "/api/dashboard/recommend/" + userId
|
||||||
|
+ "/" + recommendation + "/" + category + "?n=" + ((n == null || n <= 0) ? 10 : n), null, Item[].class));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 相似物品(根据物品ID和分类获取相似物品)
|
||||||
|
*/
|
||||||
|
public List<Item> getSimilarItem(String itemId, String category, Integer n) throws IOException {
|
||||||
|
String url = this.endpoint + "/api/dashboard/item/" + itemId + "/neighbors";
|
||||||
|
if (StringUtils.isNotBlank(category)) {
|
||||||
|
// 当默认查询10条
|
||||||
|
url += "/" + category + "?n=" + ((n == null || n <= 0) ? 10 : n);
|
||||||
|
}
|
||||||
|
System.out.println(url);
|
||||||
|
return Arrays.asList(this.request("GET", url, null, Item[].class));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private <Request, Response> Response request(String method, String url, Request request, Class<Response> responseClass) throws IOException {
|
private <Request, Response> Response request(String method, String url, Request request, Class<Response> responseClass) throws IOException {
|
||||||
|
|||||||
@@ -14,12 +14,12 @@ public class Item {
|
|||||||
private String timestamp;
|
private String timestamp;
|
||||||
private String comment;
|
private String comment;
|
||||||
|
|
||||||
private Integer score;
|
private Float score;
|
||||||
|
|
||||||
public Item() {
|
public Item() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Item(String itemId, Boolean isHidden, List<String> labels, List<String> categories, String timestamp, String comment,Integer score) {
|
public Item(String itemId, Boolean isHidden, List<String> labels, List<String> categories, String timestamp, String comment,Float score) {
|
||||||
this.itemId = itemId;
|
this.itemId = itemId;
|
||||||
this.isHidden = isHidden;
|
this.isHidden = isHidden;
|
||||||
this.labels = labels;
|
this.labels = labels;
|
||||||
@@ -60,7 +60,7 @@ public class Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@JsonProperty("Score")
|
@JsonProperty("Score")
|
||||||
public Integer getScore() {
|
public Float getScore() {
|
||||||
return score;
|
return score;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ public class User {
|
|||||||
private String userId;
|
private String userId;
|
||||||
private List<String> labels;
|
private List<String> labels;
|
||||||
|
|
||||||
|
private Float score;
|
||||||
|
|
||||||
public User() {
|
public User() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -30,6 +32,11 @@ public class User {
|
|||||||
return labels;
|
return labels;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JsonProperty("Score")
|
||||||
|
public Float getScore() {
|
||||||
|
return score;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
|
|||||||
@@ -51,11 +51,14 @@
|
|||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="createTime" label="创建时间" width="180"></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">
|
<template slot-scope="scope">
|
||||||
<el-button @click.native.prevent="modifyRow(scope.row)" type="text" size="small">
|
<el-button @click.native.prevent="modifyRow(scope.row)" type="text" size="small">
|
||||||
编辑
|
编辑
|
||||||
</el-button>
|
</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 @click.native.prevent="removeRow(scope.row)" type="text" size="small">
|
||||||
删除
|
删除
|
||||||
</el-button>
|
</el-button>
|
||||||
@@ -180,6 +183,10 @@ export default {
|
|||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
_this = this;
|
_this = this;
|
||||||
|
let _qo = _this.$route.query.qo;
|
||||||
|
if (_qo) {
|
||||||
|
_this.qo = JSON.parse(_qo);
|
||||||
|
}
|
||||||
_this.queryData();
|
_this.queryData();
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@@ -202,6 +209,14 @@ export default {
|
|||||||
_this.qo.pageNo = val;
|
_this.qo.pageNo = val;
|
||||||
_this.queryData();
|
_this.queryData();
|
||||||
},
|
},
|
||||||
|
similarItem(item) {
|
||||||
|
_this.$router.push({
|
||||||
|
path: "similarItem", query: {
|
||||||
|
itemId: item.fid,
|
||||||
|
qo: JSON.stringify(_this.qo)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
removeRow(item) {
|
removeRow(item) {
|
||||||
_this.$confirm('此操作将永久删除记录, 是否继续?', '提示', {
|
_this.$confirm('此操作将永久删除记录, 是否继续?', '提示', {
|
||||||
confirmButtonText: '确定',
|
confirmButtonText: '确定',
|
||||||
|
|||||||
@@ -21,9 +21,22 @@
|
|||||||
<el-table :data="result.records" style="width: 100%">
|
<el-table :data="result.records" style="width: 100%">
|
||||||
<el-table-column type="index" label="行号" width="60"></el-table-column>
|
<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="fid" label="fid"></el-table-column>
|
||||||
<el-table-column prop="createTime" label="创建时间" width="180"></el-table-column>
|
<el-table-column prop="labels" label="标签">
|
||||||
<el-table-column label="操作" width="100">
|
<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">
|
<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 @click.native.prevent="modifyRow(scope.row)" type="text" size="small">
|
||||||
编辑
|
编辑
|
||||||
</el-button>
|
</el-button>
|
||||||
@@ -90,6 +103,10 @@ export default {
|
|||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
_this = this;
|
_this = this;
|
||||||
|
let _qo = _this.$route.query.qo;
|
||||||
|
if (_qo) {
|
||||||
|
_this.qo = JSON.parse(_qo);
|
||||||
|
}
|
||||||
_this.queryData();
|
_this.queryData();
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@@ -99,6 +116,9 @@ export default {
|
|||||||
method: 'post',
|
method: 'post',
|
||||||
data: _this.qo
|
data: _this.qo
|
||||||
}).then(res => {
|
}).then(res => {
|
||||||
|
res.data.records.forEach(row => {
|
||||||
|
row.labelsArr = row.labels ? row.labels.split(',') : [];
|
||||||
|
});
|
||||||
_this.result.records = res.data.records;
|
_this.result.records = res.data.records;
|
||||||
_this.result.total = res.data.total;
|
_this.result.total = res.data.total;
|
||||||
});
|
});
|
||||||
@@ -107,6 +127,22 @@ export default {
|
|||||||
_this.qo.pageNo = val;
|
_this.qo.pageNo = val;
|
||||||
_this.queryData();
|
_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) {
|
removeRow(item) {
|
||||||
_this.$confirm('此操作将永久删除记录, 是否继续?', '提示', {
|
_this.$confirm('此操作将永久删除记录, 是否继续?', '提示', {
|
||||||
confirmButtonText: '确定',
|
confirmButtonText: '确定',
|
||||||
@@ -126,7 +162,7 @@ export default {
|
|||||||
createRow() {
|
createRow() {
|
||||||
_this.dialogName = '新建';
|
_this.dialogName = '新建';
|
||||||
_this.cmdDialogVisible = true;
|
_this.cmdDialogVisible = true;
|
||||||
_this.$nextTick(_=> {
|
_this.$nextTick(_ => {
|
||||||
_this.$refs['cmd'].clearValidate();
|
_this.$refs['cmd'].clearValidate();
|
||||||
_this.cmd = {
|
_this.cmd = {
|
||||||
fid: '',
|
fid: '',
|
||||||
@@ -136,7 +172,7 @@ export default {
|
|||||||
modifyRow(item) {
|
modifyRow(item) {
|
||||||
_this.dialogName = '编辑';
|
_this.dialogName = '编辑';
|
||||||
_this.cmdDialogVisible = true;
|
_this.cmdDialogVisible = true;
|
||||||
_this.$nextTick(_=> {
|
_this.$nextTick(_ => {
|
||||||
_this.$refs['cmd'].clearValidate();
|
_this.$refs['cmd'].clearValidate();
|
||||||
_this.cmd = JSON.parse(JSON.stringify(item));
|
_this.cmd = JSON.parse(JSON.stringify(item));
|
||||||
})
|
})
|
||||||
|
|||||||
178
web/src/components/menus/item/RecommendItem.vue
Normal file
178
web/src/components/menus/item/RecommendItem.vue
Normal 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>
|
||||||
175
web/src/components/menus/item/SimilarItem.vue
Normal file
175
web/src/components/menus/item/SimilarItem.vue
Normal 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>
|
||||||
122
web/src/components/menus/user/SimilarUser.vue
Normal file
122
web/src/components/menus/user/SimilarUser.vue
Normal 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
25
web/src/css/back.css
Normal 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;
|
||||||
|
}
|
||||||
@@ -63,6 +63,18 @@ export default new Router({
|
|||||||
path: 'intelligenceRecommend',
|
path: 'intelligenceRecommend',
|
||||||
component: () => import('@/components/menus/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: '/',
|
path: '/',
|
||||||
redirect: "homePage"
|
redirect: "homePage"
|
||||||
|
|||||||
Reference in New Issue
Block a user