Compare commits
14 Commits
68ed8e92e7
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 9ae4a83573 | |||
| 9e3f0c440a | |||
| 20b77a119a | |||
| da3fb87975 | |||
| eeb87693d4 | |||
| a790a20f80 | |||
| 55dd565e92 | |||
| 66222d5d93 | |||
| 4eb096907b | |||
| a038772795 | |||
| dc1b11155a | |||
|
|
bbd24b24ae | ||
| 8cd092c4fd | |||
| ee0013fc18 |
3
api/path/to/file
Normal file
@@ -0,0 +1,3 @@
|
||||
user_id,comment,labels
|
||||
wxxwjef,This is a way,[]
|
||||
hahah,No matter,[]
|
||||
13
api/pom.xml
@@ -311,6 +311,19 @@
|
||||
<artifactId>client</artifactId>
|
||||
<version>3.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpcore</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpmime</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.wx.application.adapter.controller;
|
||||
|
||||
import com.wx.application.adapter.dto.qo.GorseQ;
|
||||
import com.wx.application.base.BaseController;
|
||||
import com.wx.application.base.ResponseData;
|
||||
import com.wx.application.core.service.EntrysService;
|
||||
import com.wx.application.core.service.RiskUserService;
|
||||
import com.wx.application.gorse4j.GorseService;
|
||||
import com.wx.application.gorse4j.Item;
|
||||
import com.wx.application.nebula.graph.query.NebulaModel;
|
||||
import com.wx.application.nebula.graph.query.NebulaNode;
|
||||
import com.wx.application.nebula.graph.service.ImportGraphService;
|
||||
import com.wx.application.nebula.graph.service.NebulaOperateService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Slf4j
|
||||
@RequestMapping("/bulk")
|
||||
@Controller("bulkController")
|
||||
public class BulkController extends BaseController {
|
||||
|
||||
@Autowired
|
||||
GorseService gorseService;
|
||||
|
||||
@GetMapping(value = "/get_bulk/{type}")
|
||||
public String getBulkUserOrItem(@PathVariable("type") String type) throws Exception {
|
||||
return gorseService.getBulkUserOrItem(type);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,9 +1,12 @@
|
||||
package com.wx.application.adapter.controller;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.wx.application.gorse4j.*;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
@@ -13,14 +16,13 @@ import com.wx.application.base.BaseController;
|
||||
import com.wx.application.base.ResponseData;
|
||||
import com.wx.application.core.service.EntrysService;
|
||||
import com.wx.application.core.service.RiskUserService;
|
||||
import com.wx.application.gorse4j.GorseService;
|
||||
import com.wx.application.gorse4j.Item;
|
||||
import com.wx.application.nebula.graph.query.NebulaModel;
|
||||
import com.wx.application.nebula.graph.query.NebulaNode;
|
||||
import com.wx.application.nebula.graph.service.ImportGraphService;
|
||||
import com.wx.application.nebula.graph.service.NebulaOperateService;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
@Slf4j
|
||||
@RequestMapping("/gorse")
|
||||
@@ -30,12 +32,6 @@ public class GorseController extends BaseController {
|
||||
@Autowired
|
||||
GorseService gorseService;
|
||||
|
||||
@Autowired
|
||||
RiskUserService riskUserService;
|
||||
|
||||
@Autowired
|
||||
EntrysService entrysService;
|
||||
|
||||
@Autowired
|
||||
NebulaOperateService nebulaOperateService;
|
||||
|
||||
@@ -51,13 +47,7 @@ public class GorseController extends BaseController {
|
||||
*/
|
||||
@PostMapping(value = "/recommend_by_userid")
|
||||
public ResponseData recommendByUserId(@RequestBody GorseQ gQo) throws Exception {
|
||||
List<String> res = gorseService.getRecommend(gQo.getUserId());
|
||||
if (res == null || res.size() == 0) {
|
||||
return success();
|
||||
}
|
||||
Map mQ = new HashMap<>();
|
||||
mQ.put("INS_fid", StringUtils.join(res, ","));
|
||||
return success(entrysService.queryList(mQ));
|
||||
return success(gorseService.getRecommend(gQo.getUserId()));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -80,6 +70,26 @@ public class GorseController extends BaseController {
|
||||
return success();
|
||||
}
|
||||
|
||||
@PostMapping(value = "/delete_user/{userId}")
|
||||
public ResponseData deleteUser(@PathVariable("userId") String userId) throws Exception {
|
||||
return success(gorseService.deleteUser(userId));
|
||||
}
|
||||
|
||||
@GetMapping(value = "/get_item/{itemId}")
|
||||
public ResponseData getItem(@PathVariable("itemId") String itemId) throws Exception {
|
||||
return success(gorseService.getItem(itemId));
|
||||
}
|
||||
|
||||
@GetMapping(value = "/get_user/{userId}")
|
||||
public ResponseData getUser(@PathVariable("userId") String userId) throws Exception {
|
||||
return success(gorseService.getUser(userId));
|
||||
}
|
||||
|
||||
@PostMapping(value = "/delete_item/{itemId}")
|
||||
public ResponseData deleteItem(@PathVariable("itemId") String itemId) throws Exception {
|
||||
return success(gorseService.deleteItem(itemId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 推荐根据知识图谱
|
||||
*
|
||||
@@ -97,13 +107,7 @@ public class GorseController extends BaseController {
|
||||
nodes.get(0).getVid();
|
||||
}
|
||||
|
||||
List<String> res = gorseService.getRecommend(gQo.getUserId());
|
||||
if (res == null || res.size() == 0) {
|
||||
return success();
|
||||
}
|
||||
Map mQ = new HashMap<>();
|
||||
mQ.put("INS_fid", StringUtils.join(res, ","));
|
||||
return success(entrysService.queryList(mQ));
|
||||
return success(gorseService.getRecommend(gQo.getUserId()));
|
||||
}
|
||||
|
||||
@PostMapping(value = "/get_similar_user")
|
||||
@@ -111,15 +115,60 @@ public class GorseController extends BaseController {
|
||||
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()));
|
||||
}
|
||||
|
||||
@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()));
|
||||
}
|
||||
|
||||
@GetMapping(value = "/get_feedback_list/{userId}/{type}")
|
||||
public ResponseData getFeedbackList(@PathVariable("userId") String userId, @PathVariable("type") String type) throws Exception {
|
||||
return success(gorseService.listFeedback(userId, type));
|
||||
}
|
||||
|
||||
@PostMapping(value = "/insert_feedback/{type}/{userId}/{itemId}")
|
||||
public ResponseData insertFeedback(@PathVariable("userId") String userId, @PathVariable("type") String type,
|
||||
@PathVariable("itemId") String itemId) throws Exception {
|
||||
List<Feedback> list = new ArrayList<>();
|
||||
Feedback fb = new Feedback();
|
||||
fb.init(userId, itemId, type);
|
||||
list.add(fb);
|
||||
return success(gorseService.insertFeedback(list));
|
||||
}
|
||||
|
||||
@PutMapping(value = "/bulk/{type}")
|
||||
public ResponseData bulkUserOrItem(@RequestParam Map<String, String> data, @RequestParam("file") MultipartFile file, @PathVariable("type") String type) throws Exception {
|
||||
return success(gorseService.bulkUserOrItem(data, file, type));
|
||||
}
|
||||
|
||||
@GetMapping(value = "/get_bulk/{type}")
|
||||
public String getBulkUserOrItem(@PathVariable("type") String type) {
|
||||
return gorseService.getBulkUserOrItem(type);
|
||||
}
|
||||
|
||||
@GetMapping(value = "/query_users")
|
||||
public ResponseData queryUsers(@RequestParam("cursor") String cursor) throws Exception {
|
||||
return success(gorseService.getUserPageByCursor(cursor));
|
||||
}
|
||||
|
||||
@GetMapping(value = "/query_user/{id}")
|
||||
public ResponseData queryUser(@PathVariable("id") String id) throws Exception {
|
||||
return success(gorseService.getUserById(id));
|
||||
}
|
||||
|
||||
@GetMapping(value = "/query_items")
|
||||
public ResponseData queryItems(@RequestParam("cursor") String cursor) throws Exception {
|
||||
return success(gorseService.getItemPageByCursor(cursor));
|
||||
}
|
||||
|
||||
@GetMapping(value = "/query_item/{id}")
|
||||
public ResponseData queryItem(@PathVariable("id") String id) throws Exception {
|
||||
return success(gorseService.getItemById(id));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -10,8 +10,15 @@ import javax.crypto.Cipher;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.api.R;
|
||||
import com.wx.application.core.mapper.RiskUserMapper;
|
||||
import com.wx.application.gorse4j.GorseService;
|
||||
import com.wx.application.gorse4j.User;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
//import org.redisson.api.RedissonClient;
|
||||
import org.checkerframework.checker.units.qual.A;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
@@ -40,11 +47,14 @@ import lombok.extern.slf4j.Slf4j;
|
||||
@RestController("loginController")
|
||||
public class LoginController extends BaseController {
|
||||
|
||||
@Autowired
|
||||
RiskUserService riskUserService;
|
||||
|
||||
/*@Autowired
|
||||
RedissonClient redissonClient;*/
|
||||
@Autowired
|
||||
RiskUserService riskUserService;
|
||||
|
||||
@Autowired
|
||||
RiskUserMapper userMapper;
|
||||
|
||||
@Autowired
|
||||
GorseService gorseService;
|
||||
|
||||
@Autowired
|
||||
private Kaptcha kaptcha;
|
||||
@@ -72,68 +82,75 @@ public class LoginController extends BaseController {
|
||||
kaptcha.render();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 登录
|
||||
*/
|
||||
@PostMapping(value = "/user")
|
||||
public ResponseData login(@RequestBody RiskUserQ loginQo) throws Exception {
|
||||
|
||||
// if(StringUtils.isBlank(loginQo.getCode())) {
|
||||
// Map<String,String> data = new HashMap<>();
|
||||
// data.put("msg", "验证码不能为空");
|
||||
// return error(ErrorCodeEnum.USER_NOT_EXIST,data);
|
||||
// }
|
||||
//
|
||||
// try {
|
||||
// kaptcha.validate(loginQo.getCode());
|
||||
// } catch (Exception e) {
|
||||
// Map<String,String> data = new HashMap<>();
|
||||
// data.put("msg", "验证码错误");
|
||||
// return error(ErrorCodeEnum.USER_NOT_EXIST,data);
|
||||
// }
|
||||
|
||||
/*if(StringUtils.isBlank(loginQo.getCode())) {
|
||||
Map<String,String> data = new HashMap<>();
|
||||
data.put("msg", "验证码不能为空");
|
||||
return error(ErrorCodeEnum.USER_NOT_EXIST,data);
|
||||
}
|
||||
|
||||
try {
|
||||
kaptcha.validate(loginQo.getCode());
|
||||
} catch (Exception e) {
|
||||
Map<String,String> data = new HashMap<>();
|
||||
data.put("msg", "验证码错误");
|
||||
return error(ErrorCodeEnum.USER_NOT_EXIST,data);
|
||||
}*/
|
||||
|
||||
/**
|
||||
* 将密码改成md5加密查询
|
||||
*/
|
||||
Map<String,Object> mQ = new HashMap<>();
|
||||
mQ.put("EQS_username", loginQo.getUsername());
|
||||
mQ.put("EQS_password", MD5Util.MD5(loginQo.getPassword()));
|
||||
mQ.put("EQS_type", loginQo.getType());
|
||||
|
||||
RiskUser riskUser = riskUserService.queryUnique(mQ);
|
||||
|
||||
if(riskUser != null) {
|
||||
String token = JwtUtils.generateJwtToken(riskUser.getId(), CONSTANT.LOGIN_TYPE_ADMIN, riskUser);
|
||||
|
||||
RiskUser _riskUser = new RiskUser();
|
||||
_riskUser.setRealname(riskUser.getRealname());
|
||||
_riskUser.setUsername(riskUser.getUsername());
|
||||
|
||||
return success(ImmutableMap.<String, Object>builder()
|
||||
.put("Authorization",token)
|
||||
.put("user", _riskUser)
|
||||
.build());
|
||||
}
|
||||
Map<String,String> data = new HashMap<>();
|
||||
data.put("msg", "用户名密码错误");
|
||||
return error(ErrorCodeEnum.USER_NOT_EXIST,data);
|
||||
/**
|
||||
* 登录
|
||||
*/
|
||||
@PostMapping(value = "/user")
|
||||
public ResponseData login(@RequestBody RiskUserQ loginQo) throws Exception {
|
||||
|
||||
/**
|
||||
* 将密码改成md5加密查询
|
||||
*/
|
||||
Map<String, Object> mQ = new HashMap<>();
|
||||
mQ.put("EQS_username", loginQo.getUsername());
|
||||
mQ.put("EQS_password", MD5Util.MD5(loginQo.getPassword()));
|
||||
mQ.put("EQS_type", loginQo.getType());
|
||||
|
||||
RiskUser riskUser = riskUserService.queryUnique(mQ);
|
||||
|
||||
if (riskUser != null) {
|
||||
String token = JwtUtils.generateJwtToken(riskUser.getId(), CONSTANT.LOGIN_TYPE_ADMIN, riskUser);
|
||||
|
||||
RiskUser _riskUser = new RiskUser();
|
||||
_riskUser.setRealname(riskUser.getUsername());
|
||||
_riskUser.setUsername(riskUser.getUsername());
|
||||
|
||||
return success(ImmutableMap.<String, Object>builder()
|
||||
.put("Authorization", token)
|
||||
.put("user", _riskUser)
|
||||
.build());
|
||||
}
|
||||
Map<String, String> data = new HashMap<>();
|
||||
data.put("msg", "用户名密码错误");
|
||||
return error(ErrorCodeEnum.USER_NOT_EXIST, data);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 注册
|
||||
*/
|
||||
@PostMapping(value = "/register")
|
||||
public ResponseData register(@RequestBody RiskUserQ registerQ) throws Exception {
|
||||
|
||||
|
||||
Map<String, String> data = new HashMap<>();
|
||||
if (StringUtils.isEmpty(registerQ.getUsername()) || StringUtils.isEmpty(registerQ.getPassword())) {
|
||||
data.put("msg", "用户名密码不能为空");
|
||||
return error(ErrorCodeEnum.PARAM_ERROR, data);
|
||||
}
|
||||
|
||||
int blankUserCount = userMapper.selectCount(new QueryWrapper<RiskUser>().lambda().eq(RiskUser::getUsername, registerQ.getUsername()));
|
||||
if (blankUserCount > 0) {
|
||||
data.put("msg", "用户名已存在");
|
||||
return error(ErrorCodeEnum.MOBILE_USED, data);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 将密码改成md5加密
|
||||
*/
|
||||
RiskUser nowUser = new RiskUser();
|
||||
nowUser.setUsername(registerQ.getUsername());
|
||||
nowUser.setPassword(MD5Util.MD5(registerQ.getPassword()));
|
||||
nowUser.setType(registerQ.getType());
|
||||
|
||||
userMapper.insert(nowUser);
|
||||
// User user = new User(registerQ.getUsername(), null);
|
||||
// gorseService.insertUser(user);
|
||||
return success();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 解密用户敏感数据获取用户信息
|
||||
*
|
||||
|
||||
@@ -21,7 +21,7 @@ public class FeedbackType extends BaseEntity<Long> {
|
||||
|
||||
private String name;
|
||||
|
||||
|
||||
private String type;
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -12,15 +12,23 @@ public class Feedback {
|
||||
private String userId;
|
||||
private String itemId;
|
||||
private String timestamp;
|
||||
private Item item;
|
||||
|
||||
public Feedback() {
|
||||
}
|
||||
|
||||
public Feedback(String feedbackType, String userId, String itemId, String timestamp) {
|
||||
public void init(String userId, String itemId, String feedbackType) {
|
||||
this.itemId = itemId;
|
||||
this.userId = userId;
|
||||
this.feedbackType = feedbackType;
|
||||
}
|
||||
|
||||
public Feedback(String feedbackType, String userId, String itemId, String timestamp, Item item) {
|
||||
this.feedbackType = feedbackType;
|
||||
this.userId = userId;
|
||||
this.itemId = itemId;
|
||||
this.timestamp = timestamp;
|
||||
this.item = item;
|
||||
}
|
||||
|
||||
@JsonProperty("FeedbackType")
|
||||
@@ -38,6 +46,11 @@ public class Feedback {
|
||||
return itemId;
|
||||
}
|
||||
|
||||
@JsonProperty("Item")
|
||||
public Item getItem() {
|
||||
return item;
|
||||
}
|
||||
|
||||
@JsonProperty("Timestamp")
|
||||
public String getTimestamp() {
|
||||
return timestamp;
|
||||
|
||||
38
api/src/main/java/com/wx/application/gorse4j/GorsePage.java
Normal file
@@ -0,0 +1,38 @@
|
||||
package com.wx.application.gorse4j;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 查询的分页结果
|
||||
*/
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class GorsePage {
|
||||
|
||||
/**
|
||||
* 下一页的查询码,查询首页可缺省
|
||||
*/
|
||||
private String cursor;
|
||||
|
||||
private List<User> users;
|
||||
|
||||
private List<Item> items;
|
||||
|
||||
@JsonProperty("Cursor")
|
||||
public String getCursor() {
|
||||
return cursor;
|
||||
}
|
||||
|
||||
@JsonProperty("Users")
|
||||
public List<User> getUsers() {
|
||||
return users;
|
||||
}
|
||||
|
||||
@JsonProperty("Items")
|
||||
public List<Item> getItems() {
|
||||
return items;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,17 +1,33 @@
|
||||
package com.wx.application.gorse4j;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import com.wx.application.util.CSVUtils;
|
||||
import com.wx.application.util.HttpUtils;
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.entity.ContentType;
|
||||
import org.apache.http.entity.mime.MultipartEntityBuilder;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
import org.apache.http.util.EntityUtils;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
@Service
|
||||
public class GorseService {
|
||||
@@ -50,12 +66,13 @@ public class GorseService {
|
||||
return this.request("DELETE", this.endpoint + "/api/item/" + itemId, null, RowAffected.class);
|
||||
}
|
||||
|
||||
public RowAffected insertFeedback(List<Feedback> feedbacks) throws IOException {
|
||||
return this.request("POST", this.endpoint + "/api/feedback", feedbacks, RowAffected.class);
|
||||
public Object insertFeedback(List<Feedback> feedbacks) throws IOException {
|
||||
return HttpUtils.doPost(this.endpoint + "/api/feedback", JSONObject.toJSONString(feedbacks));
|
||||
// return this.request("POST", this.endpoint + "/api/feedback", feedbacks, RowAffected.class);
|
||||
}
|
||||
|
||||
public List<Feedback> listFeedback(String userId, String feedbackType) throws IOException {
|
||||
return Arrays.asList(this.request("GET", this.endpoint + "/api/user/" + userId + "/feedback/" + feedbackType, null, Feedback[].class));
|
||||
return Arrays.asList(this.request("GET", this.endpoint + "/api/dashboard/user/" + userId + "/feedback/" + feedbackType, null, Feedback[].class));
|
||||
}
|
||||
|
||||
public List<String> getRecommend(String userId) throws IOException {
|
||||
@@ -74,6 +91,43 @@ public class GorseService {
|
||||
return Arrays.asList(this.request("GET", this.endpoint + "/api/dashboard/user/" + userId + "/neighbors", null, User[].class));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 分页查询用户
|
||||
*/
|
||||
public GorsePage getUserPageByCursor(String cursor) throws IOException {
|
||||
String baseUrl = this.endpoint + "/api/dashboard/users";
|
||||
if (StringUtils.isNotBlank(cursor)) {
|
||||
baseUrl += ("?cursor=" + cursor);
|
||||
}
|
||||
return this.request("GET", baseUrl, null, GorsePage.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询用户
|
||||
*/
|
||||
public User getUserById(String id) throws IOException {
|
||||
return this.request("GET", this.endpoint + "/api/dashboard/user/" + id, null, User.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询物品
|
||||
*/
|
||||
public GorsePage getItemPageByCursor(String cursor) throws IOException {
|
||||
String baseUrl = this.endpoint + "/api/items";
|
||||
if (StringUtils.isNotBlank(cursor)) {
|
||||
baseUrl += ("?cursor=" + cursor);
|
||||
}
|
||||
return this.request("GET", baseUrl, null, GorsePage.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询物品
|
||||
*/
|
||||
public Item getItemById(String id) throws IOException {
|
||||
return this.request("GET", this.endpoint + "/api/item/" + id, null, Item.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 洞悉(根据用户获取推荐)
|
||||
*/
|
||||
@@ -95,6 +149,57 @@ public class GorseService {
|
||||
return Arrays.asList(this.request("GET", url, null, Item[].class));
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件方式导入用户或者物品users\items
|
||||
*/
|
||||
public JSONObject bulkUserOrItem(Map<String, String> data, MultipartFile multipartFile, String type) throws IOException {
|
||||
File file = new File("path/to/file");
|
||||
|
||||
FileUtils.writeByteArrayToFile(file, multipartFile.getBytes());
|
||||
|
||||
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
|
||||
for (Map.Entry<String, String> entry : data.entrySet()) {
|
||||
builder.addTextBody(entry.getKey(), entry.getValue());
|
||||
}
|
||||
|
||||
// 导入附加的属性数据到mysql
|
||||
if ("users".equals(type)) {
|
||||
List<List<String>> rows = CSVUtils.parseCSV(file, data.get("sep"));
|
||||
|
||||
} else if ("items".equals(type)) {
|
||||
List<List<String>> rows = CSVUtils.parseCSV(file, data.get("sep"));
|
||||
}
|
||||
|
||||
builder.addBinaryBody("file", file, ContentType.APPLICATION_OCTET_STREAM, multipartFile.getOriginalFilename());
|
||||
return this.sendPostFormData(this.endpoint + "/api/bulk/" + type, builder);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 导出用户或物品信息
|
||||
*/
|
||||
public String getBulkUserOrItem(String type) {
|
||||
return "redirect:" + this.endpoint + "/api/bulk/" + type;
|
||||
}
|
||||
|
||||
public JSONObject sendPostFormData(String url, MultipartEntityBuilder builder) throws IOException {
|
||||
JSONObject resJson;
|
||||
HttpClient httpClient = HttpClientBuilder.create().build();
|
||||
HttpPost httpPost = new HttpPost(url);
|
||||
|
||||
HttpEntity entity = builder.build();
|
||||
httpPost.setEntity(entity);
|
||||
|
||||
HttpResponse response = null;
|
||||
try {
|
||||
response = httpClient.execute(httpPost);
|
||||
HttpEntity responseEntity = response.getEntity();
|
||||
resJson = JSONObject.parseObject(EntityUtils.toString(responseEntity));
|
||||
} catch (IOException e) {
|
||||
throw e;
|
||||
}
|
||||
return resJson;
|
||||
}
|
||||
|
||||
private <Request, Response> Response request(String method, String url, Request request, Class<Response> responseClass) throws IOException {
|
||||
HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
|
||||
@@ -106,12 +211,15 @@ public class GorseService {
|
||||
if (request != null) {
|
||||
connection.setDoOutput(true);
|
||||
String requestBody = mapper.writeValueAsString(request);
|
||||
DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream());
|
||||
OutputStream outputStream = connection.getOutputStream();
|
||||
outputStream.write(requestBody.getBytes());
|
||||
outputStream.flush();
|
||||
outputStream.close();
|
||||
}
|
||||
// Get Response
|
||||
InputStream inputStream = connection.getInputStream();
|
||||
return mapper.readValue(inputStream, responseClass);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -730,6 +730,19 @@ public class BaseGraphSerice {
|
||||
return ResultSetUtils.printResultPath(resultSet);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据明确关系查询一个节点的周边一层节点关系
|
||||
* @param nQ
|
||||
* @return
|
||||
*/
|
||||
public NebulaModel findOnePathById(final String space,final String vid, List<String> relations) {
|
||||
final String fmtVid = StrUtil.format("\"{}\"", vid);
|
||||
final String rl = StringUtils.join(relations, "|");
|
||||
final String fmtrl = StrUtil.format("[r:{}]", rl);
|
||||
final String nGql = StrUtil.format(GqlTemplate.WITHRELATIONBYID, fmtrl, fmtVid);
|
||||
ResultSet resultSet = executeGql(space, nGql);
|
||||
return ResultSetUtils.printResultPath(resultSet);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询一个头节点和尾结点的关系
|
||||
|
||||
@@ -49,6 +49,8 @@ public interface GqlTemplate {
|
||||
|
||||
final static String ONERELATIONBYID = "MATCH p=(n1)-->(n2) where id(n1)=={} RETURN p";
|
||||
|
||||
final static String WITHRELATIONBYID = "MATCH p=(n1)-{}->(n2) where id(n1)=={} RETURN p";
|
||||
|
||||
final static String ONERELATIONBYSRCIDANDDCTID = "MATCH p=(n1)-->(n2) where id(n1)=={} and id(n2)=={} RETURN p";
|
||||
|
||||
final static String PAGING =" | limit {},{}";
|
||||
|
||||
@@ -382,6 +382,20 @@ public class NebulaOperateController extends BaseController {
|
||||
return success(nebulaOperateService.findOnePathById(space, vid));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 查询一个节点和明确的关系查询周边一层节点关系
|
||||
* @param nQ
|
||||
* @return
|
||||
*/
|
||||
@PostMapping(value = "/findonepathbyidwithrelation/{space}/{vid}")
|
||||
public ResponseData findOnePathById(@PathVariable("space") String space,
|
||||
@PathVariable("vid") String vid,
|
||||
@RequestBody NebulaQo nebulaQo) {
|
||||
return success(nebulaOperateService.findOnePathById(space, vid, nebulaQo.getRelations()));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 查询一个头节点和尾结点的关系
|
||||
* @param nQ
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.wx.application.nebula.graph.query;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@@ -18,5 +20,7 @@ public class NebulaQo {
|
||||
private Integer page = 1;
|
||||
|
||||
private Integer pageSize = 200;
|
||||
|
||||
private List<String> relations;
|
||||
|
||||
}
|
||||
|
||||
52
api/src/main/java/com/wx/application/util/CSVUtils.java
Normal file
@@ -0,0 +1,52 @@
|
||||
package com.wx.application.util;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Scanner;
|
||||
|
||||
public class CSVUtils {
|
||||
|
||||
/**
|
||||
* @param file
|
||||
* @param sep 属性分隔符
|
||||
* @return
|
||||
* @throws FileNotFoundException
|
||||
*/
|
||||
public static List<List<String>> parseCSV(File file, String sep) throws FileNotFoundException {
|
||||
List<List<String>> rows = new ArrayList<>();
|
||||
|
||||
if (file == null) {
|
||||
return rows;
|
||||
}
|
||||
|
||||
if (StringUtils.isEmpty(sep)) {
|
||||
sep = ",";
|
||||
}
|
||||
|
||||
try {
|
||||
Scanner scanner = new Scanner(file);
|
||||
|
||||
while (scanner.hasNextLine()) {
|
||||
String line = scanner.nextLine();
|
||||
String[] values = line.split(sep);
|
||||
List<String> row = new ArrayList<>();
|
||||
|
||||
for (String value : values) {
|
||||
row.add(value);
|
||||
}
|
||||
|
||||
rows.add(row);
|
||||
}
|
||||
|
||||
scanner.close();
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return rows;
|
||||
}
|
||||
}
|
||||
191
api/src/main/java/com/wx/application/util/HttpUtils.java
Normal file
@@ -0,0 +1,191 @@
|
||||
package com.wx.application.util;
|
||||
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.client.config.RequestConfig;
|
||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.entity.StringEntity;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClients;
|
||||
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
|
||||
import org.apache.http.util.EntityUtils;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.PrintWriter;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class HttpUtils {
|
||||
|
||||
|
||||
private static PoolingHttpClientConnectionManager connMgr = new PoolingHttpClientConnectionManager();
|
||||
private static RequestConfig requestConfig;
|
||||
|
||||
/**
|
||||
* 情况方法直接放这里就行
|
||||
*/
|
||||
|
||||
|
||||
static {
|
||||
connMgr.setMaxTotal(100);
|
||||
connMgr.setDefaultMaxPerRoute(connMgr.getMaxTotal());
|
||||
RequestConfig.Builder configBuilder = RequestConfig.custom();
|
||||
configBuilder.setConnectTimeout(60000);
|
||||
configBuilder.setSocketTimeout(70000);
|
||||
configBuilder.setConnectionRequestTimeout(30000);
|
||||
requestConfig = configBuilder.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* 向指定URL发送GET方法的请求
|
||||
*
|
||||
* @param url 发送请求的URL
|
||||
* @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
|
||||
* @return URL 所代表远程资源的响应结果
|
||||
*/
|
||||
public Object sendGet(String url, String param) {
|
||||
String result = "";
|
||||
BufferedReader in = null;
|
||||
try {
|
||||
String urlNameString = url + "?" + param;
|
||||
URL realUrl = new URL(urlNameString);
|
||||
// 打开和URL之间的连接
|
||||
URLConnection connection = realUrl.openConnection();
|
||||
// 设置通用的请求属性
|
||||
connection.setRequestProperty("accept", "*/*");
|
||||
connection.setRequestProperty("connection", "Keep-Alive");
|
||||
connection.setRequestProperty("user-agent",
|
||||
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
|
||||
// 建立实际的连接
|
||||
connection.connect();
|
||||
// 获取所有响应头字段
|
||||
Map<String, List<String>> map = connection.getHeaderFields();
|
||||
// 遍历所有的响应头字段
|
||||
for (String key : map.keySet()) {
|
||||
System.out.println(key + "--->" + map.get(key));
|
||||
}
|
||||
// 定义 BufferedReader输入流来读取URL的响应
|
||||
in = new BufferedReader(new InputStreamReader(
|
||||
connection.getInputStream()));
|
||||
String line;
|
||||
while ((line = in.readLine()) != null) {
|
||||
result += line;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.out.println("发送GET请求出现异常!" + e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
// 使用finally块来关闭输入流
|
||||
finally {
|
||||
try {
|
||||
if (in != null) {
|
||||
in.close();
|
||||
}
|
||||
} catch (Exception e2) {
|
||||
e2.printStackTrace();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 向指定 URL 发送POST方法的请求
|
||||
*
|
||||
* @param url 发送请求的 URL
|
||||
* @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
|
||||
* @return 所代表远程资源的响应结果
|
||||
*/
|
||||
public static Object sendPost(String url, String param) {
|
||||
PrintWriter out = null;
|
||||
BufferedReader in = null;
|
||||
String result = "";
|
||||
try {
|
||||
URL realUrl = new URL(url);
|
||||
// 打开和URL之间的连接
|
||||
URLConnection conn = realUrl.openConnection();
|
||||
// 设置通用的请求属性
|
||||
conn.setRequestProperty("accept", "*/*");
|
||||
conn.setRequestProperty("connection", "Keep-Alive");
|
||||
conn.setRequestProperty("user-agent",
|
||||
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
|
||||
// 发送POST请求必须设置如下两行
|
||||
conn.setDoOutput(true);
|
||||
conn.setDoInput(true);
|
||||
// 获取URLConnection对象对应的输出流
|
||||
out = new PrintWriter(conn.getOutputStream());
|
||||
// 发送请求参数
|
||||
out.print(param);
|
||||
// flush输出流的缓冲
|
||||
out.flush();
|
||||
// 定义BufferedReader输入流来读取URL的响应
|
||||
in = new BufferedReader(
|
||||
new InputStreamReader(conn.getInputStream()));
|
||||
String line;
|
||||
while ((line = in.readLine()) != null) {
|
||||
result += line;
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
System.out.println("发送 POST 请求出现异常!" + e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
//使用finally块来关闭输出流、输入流
|
||||
finally {
|
||||
try {
|
||||
if (out != null) {
|
||||
out.close();
|
||||
}
|
||||
if (in != null) {
|
||||
in.close();
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* post,以 application/json 形式
|
||||
* @param apiUrl
|
||||
* @param json
|
||||
* @return
|
||||
*/
|
||||
public static String doPost(String apiUrl, String json) {
|
||||
long start = System.currentTimeMillis();
|
||||
CloseableHttpClient httpClient = HttpClients.createDefault();
|
||||
String httpStr = null;
|
||||
HttpPost httpPost = new HttpPost(apiUrl);
|
||||
CloseableHttpResponse response = null;
|
||||
int statusCode = -999;
|
||||
try {
|
||||
httpPost.setConfig(requestConfig);
|
||||
StringEntity stringEntity = new StringEntity(json.toString(), "UTF-8");
|
||||
stringEntity.setContentEncoding("UTF-8");
|
||||
stringEntity.setContentType("application/json");
|
||||
httpPost.setEntity(stringEntity);
|
||||
response = httpClient.execute(httpPost);
|
||||
HttpEntity entity = response.getEntity();
|
||||
statusCode = response.getStatusLine().getStatusCode();
|
||||
httpStr = EntityUtils.toString(entity, "UTF-8");
|
||||
} catch (Exception var20) {
|
||||
var20.printStackTrace();
|
||||
} finally {
|
||||
if (response != null) {
|
||||
try {
|
||||
EntityUtils.consume(response.getEntity());
|
||||
} catch (IOException var19) {
|
||||
var19.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return httpStr;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -11,6 +11,7 @@ spring.servlet.multipart.max-file-size=2048MB
|
||||
spring.servlet.multipart.max-request-size=2048MB
|
||||
server.port=@server_port@
|
||||
ignore.urls[0]=/login/**
|
||||
ignore.urls[1]=/bulk/get_bulk/**
|
||||
|
||||
upload.graph.path=@upload_graph_path@
|
||||
zbx.path=@zbx_path@
|
||||
|
||||
29
web/package-lock.json
generated
@@ -2141,7 +2141,7 @@
|
||||
},
|
||||
"ansi-styles": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||
"resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
@@ -2177,7 +2177,7 @@
|
||||
},
|
||||
"chalk": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
|
||||
"resolved": "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz",
|
||||
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
@@ -2188,7 +2188,7 @@
|
||||
},
|
||||
"color-convert": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||
"resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz",
|
||||
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
@@ -2198,7 +2198,7 @@
|
||||
},
|
||||
"color-name": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||
"resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz",
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
@@ -2217,14 +2217,14 @@
|
||||
},
|
||||
"has-flag": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
|
||||
"resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz",
|
||||
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"loader-utils": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz",
|
||||
"resolved": "https://registry.npmmirror.com/loader-utils/-/loader-utils-2.0.4.tgz",
|
||||
"integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
@@ -2252,7 +2252,7 @@
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
|
||||
"resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz",
|
||||
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
@@ -2279,7 +2279,7 @@
|
||||
},
|
||||
"vue-loader-v16": {
|
||||
"version": "npm:vue-loader@16.8.3",
|
||||
"resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-16.8.3.tgz",
|
||||
"resolved": "https://registry.npmmirror.com/vue-loader/-/vue-loader-16.8.3.tgz",
|
||||
"integrity": "sha512-7vKN45IxsKxe5GcVCbc2qFU5aWzyiLrYJyUuMz4BQLKctCj/fmCa0w6fGiiQ2cLFetNcek1ppGJQDCup0c1hpA==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
@@ -9996,6 +9996,11 @@
|
||||
"integrity": "sha1-bJWZ00DVTf05RjgCUqNXBaa5kr8=",
|
||||
"dev": true
|
||||
},
|
||||
"papaparse": {
|
||||
"version": "5.4.1",
|
||||
"resolved": "https://registry.npmmirror.com/papaparse/-/papaparse-5.4.1.tgz",
|
||||
"integrity": "sha512-HipMsgJkZu8br23pW15uvo6sib6wne/4woLZPlFf3rpDyMe9ywEXUsuD7+6K9PRkJlVT51j/sCOYDKGGS3ZJrw=="
|
||||
},
|
||||
"parallel-transform": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npm.taobao.org/parallel-transform/download/parallel-transform-1.2.0.tgz",
|
||||
@@ -14600,6 +14605,14 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"vue-papa-parse": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/vue-papa-parse/-/vue-papa-parse-3.1.0.tgz",
|
||||
"integrity": "sha512-5YdF3Dtf49EGfaz3+IgIpUw9yYuvV3HekZkob6jrK/Ffz1aCrWjevtcQByKxrNtK7RAL39B0ca93bogKuiQQKg==",
|
||||
"requires": {
|
||||
"papaparse": "^5.3.0"
|
||||
}
|
||||
},
|
||||
"vue-quill-editor": {
|
||||
"version": "3.0.6",
|
||||
"resolved": "https://registry.npm.taobao.org/vue-quill-editor/download/vue-quill-editor-3.0.6.tgz",
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
"vue": "^2.6.11",
|
||||
"vue-axios": "^3.2.4",
|
||||
"vue-json-editor": "^1.4.3",
|
||||
"vue-papa-parse": "^3.1.0",
|
||||
"vue-quill-editor": "^3.0.6",
|
||||
"vuex": "^3.1.0"
|
||||
},
|
||||
|
||||
@@ -21,17 +21,23 @@ html, body, #app {
|
||||
}
|
||||
|
||||
.el-table th.is-leaf {
|
||||
background: rgba(250, 250, 250, 1);
|
||||
background: rgba(235,241,255);
|
||||
border-top: 1px solid #EBEEF5;
|
||||
}
|
||||
|
||||
.el-table th.el-table__cell{
|
||||
background: rgba(235,241,255)!important;
|
||||
color: #333333!important;
|
||||
font-weight: normal!important;
|
||||
}
|
||||
|
||||
.menu-content {
|
||||
margin: 25px;
|
||||
background: #FFFFFF;
|
||||
overflow: auto;
|
||||
position: absolute;
|
||||
left: 290px;
|
||||
top: 100px;
|
||||
left: 260px;
|
||||
top: 40px;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
padding: 25px;
|
||||
@@ -70,4 +76,75 @@ html, body, #app {
|
||||
height: 178px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.login-input .el-input__inner{
|
||||
height: 60px!important;
|
||||
line-height: 60px!important;
|
||||
border-radius: 10px!important;
|
||||
font-size: 16px!important;
|
||||
padding: 0px 30px 0 60px!important;
|
||||
}
|
||||
|
||||
.login-input i{
|
||||
font-size: 30px!important;
|
||||
line-height: 60px!important;
|
||||
margin-left: 15px!important;
|
||||
}
|
||||
|
||||
.login-button{
|
||||
height: 60px!important;
|
||||
width: 100%!important;
|
||||
border-radius: 10px!important;
|
||||
//background: rgba(16,108,255, 1);
|
||||
border: none;
|
||||
font-size: 16px!important;
|
||||
letter-spacing:5px!important;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
/*滚动条样式*/
|
||||
::-webkit-scrollbar {/*滚动条整体样式*/
|
||||
width: 8px; /*高宽分别对应横竖滚动条的尺寸*/
|
||||
height: 1px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {/*滚动条里面小方块*/
|
||||
border-radius: 5px;
|
||||
-webkit-box-shadow: inset 0 0 5px #d9d9d9;
|
||||
background: #d9d9d9;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track { /*滚动条里面轨道*/
|
||||
-webkit-box-shadow: inset 0 0 5px #ffffff;
|
||||
border-radius: 0;
|
||||
background: #ffffff;
|
||||
}
|
||||
|
||||
.el-dialog__header{
|
||||
background: cornflowerblue;
|
||||
padding-bottom:15px!important;
|
||||
padding-top: 15px!important;
|
||||
}
|
||||
|
||||
.el-dialog__title{
|
||||
color: #ffffff!important;
|
||||
}
|
||||
|
||||
.el-dialog__headerbtn .el-dialog__close{
|
||||
color: #ffffff!important;
|
||||
}
|
||||
|
||||
.el-dialog__body{
|
||||
padding-bottom:20px!important;
|
||||
}
|
||||
|
||||
.content-box .el-input__inner{
|
||||
height: 33px!important;
|
||||
line-height: 33px!important;
|
||||
}
|
||||
|
||||
.content-box .el-button--primary,.content-box .el-button--default{
|
||||
padding: 9px 15px!important;
|
||||
font-size: 12px!important;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
Before Width: | Height: | Size: 171 KiB |
|
Before Width: | Height: | Size: 111 KiB |
|
Before Width: | Height: | Size: 234 KiB |
|
Before Width: | Height: | Size: 212 KiB |
|
Before Width: | Height: | Size: 249 KiB |
|
Before Width: | Height: | Size: 225 KiB |
|
Before Width: | Height: | Size: 277 KiB |
|
Before Width: | Height: | Size: 120 KiB |
|
Before Width: | Height: | Size: 131 KiB |
|
Before Width: | Height: | Size: 121 KiB |
|
Before Width: | Height: | Size: 137 KiB |
|
Before Width: | Height: | Size: 136 KiB |
|
Before Width: | Height: | Size: 122 KiB |
|
Before Width: | Height: | Size: 114 KiB |
|
Before Width: | Height: | Size: 121 KiB |
|
Before Width: | Height: | Size: 119 KiB |
|
Before Width: | Height: | Size: 132 KiB |
|
Before Width: | Height: | Size: 126 KiB |
|
Before Width: | Height: | Size: 129 KiB |
|
Before Width: | Height: | Size: 139 KiB |
|
Before Width: | Height: | Size: 124 KiB |
|
Before Width: | Height: | Size: 132 KiB |
|
Before Width: | Height: | Size: 135 KiB |
|
Before Width: | Height: | Size: 128 KiB |
|
Before Width: | Height: | Size: 104 KiB |
|
Before Width: | Height: | Size: 106 KiB |
|
Before Width: | Height: | Size: 92 KiB |
|
Before Width: | Height: | Size: 98 KiB |
|
Before Width: | Height: | Size: 88 KiB |
|
Before Width: | Height: | Size: 116 KiB |
|
Before Width: | Height: | Size: 109 KiB |
|
Before Width: | Height: | Size: 87 KiB |
|
Before Width: | Height: | Size: 92 KiB |
|
Before Width: | Height: | Size: 127 KiB |
|
Before Width: | Height: | Size: 140 KiB |
|
Before Width: | Height: | Size: 102 KiB |
|
Before Width: | Height: | Size: 152 KiB |
|
Before Width: | Height: | Size: 104 KiB |
|
Before Width: | Height: | Size: 160 KiB |
|
Before Width: | Height: | Size: 110 KiB |
|
Before Width: | Height: | Size: 85 KiB |
|
Before Width: | Height: | Size: 132 KiB |
|
Before Width: | Height: | Size: 129 KiB |
|
Before Width: | Height: | Size: 148 KiB |
|
Before Width: | Height: | Size: 129 KiB |
|
Before Width: | Height: | Size: 142 KiB |
|
Before Width: | Height: | Size: 144 KiB |
|
Before Width: | Height: | Size: 168 KiB |
BIN
web/src/assets/image/ambari-logo.png
Normal file
|
After Width: | Height: | Size: 6.6 KiB |
BIN
web/src/assets/image/background.png
Normal file
|
After Width: | Height: | Size: 112 KiB |
BIN
web/src/assets/image/content-logo.png
Normal file
|
After Width: | Height: | Size: 22 KiB |
BIN
web/src/assets/image/login-img.png
Normal file
|
After Width: | Height: | Size: 44 KiB |
BIN
web/src/assets/image/password.png
Normal file
|
After Width: | Height: | Size: 5.3 KiB |
BIN
web/src/assets/image/user.png
Normal file
|
After Width: | Height: | Size: 5.6 KiB |
@@ -20,13 +20,13 @@
|
||||
<label>查询中</label>
|
||||
</div>
|
||||
<el-form-item :label="item.comment" v-for="item in infoList" :key="item.field">
|
||||
<el-input v-model="item.value"></el-input>
|
||||
<el-input v-model="item.value" disabled></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div class="btn-box">
|
||||
<el-button type="danger" @click="removeItem" v-show="editFlag">删 除</el-button>
|
||||
<el-button type="primary" @click="submitUpdate">保 存</el-button>
|
||||
</div>
|
||||
<!-- <div class="btn-box">-->
|
||||
<!-- <el-button type="danger" @click="removeItem" v-show="editFlag">删 除</el-button>-->
|
||||
<!-- <el-button type="primary" @click="submitUpdate">保 存</el-button>-->
|
||||
<!-- </div>-->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -96,7 +96,9 @@ export default {
|
||||
method: 'get',
|
||||
data: {}
|
||||
}).then(res => {
|
||||
vm.form[comment] = getFirstStringProperty(res.data.properties);
|
||||
|
||||
// vm.form[comment] = getFirstStringProperty(res.data.properties);
|
||||
vm.form[comment] = vid;
|
||||
});
|
||||
},
|
||||
queryEdgeDetail(edgeType, srcVid, dstVid) {
|
||||
@@ -141,7 +143,8 @@ export default {
|
||||
let _infoList = [];
|
||||
Reflect.ownKeys(properties).forEach(key => {
|
||||
_infoList.push({
|
||||
comment: map[key],
|
||||
// comment: map[key],
|
||||
comment: key,
|
||||
field: key,
|
||||
value: properties[key]
|
||||
});
|
||||
|
||||
@@ -31,8 +31,8 @@
|
||||
<!-- <el-table-column prop="comment" label="描述"></el-table-column>-->
|
||||
<el-table-column prop="type" label="类型"></el-table-column>
|
||||
<el-table-column label="删除" width="80">
|
||||
<template slot-scope="scope">
|
||||
<el-button @click.native.prevent="removeField(scope.row,scope.$index)" type="text" size="small">
|
||||
<template slot-scope="scope" >
|
||||
<el-button @click.native.prevent="removeField(scope.row,scope.$index)" type="text" size="small" v-show="scope.row.type">
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
@@ -71,7 +71,7 @@
|
||||
</el-table-column>
|
||||
<el-table-column label="删除" width="80">
|
||||
<template slot-scope="scope">
|
||||
<el-button @click.native.prevent="removeRelation(scope.row,scope.$index)" type="text" size="small">
|
||||
<el-button @click.native.prevent="removeRelation(scope.row,scope.$index)" type="text" size="small" v-show="scope.row.label && scope.row.dstId">
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
|
||||
@@ -107,6 +107,11 @@ export default {
|
||||
|
||||
},
|
||||
methods: {
|
||||
handleCommentFormatter(row) {
|
||||
// for(let i in ) {
|
||||
//
|
||||
// }
|
||||
},
|
||||
updateValue(space, name) {
|
||||
vm.space = space;
|
||||
vm.modifyCmd.name = name;
|
||||
|
||||
@@ -258,7 +258,7 @@ var _ = require('lodash');
|
||||
var nodeProps = {
|
||||
id: 'vid',
|
||||
label: 'properties.label',
|
||||
name: 'properties.tagName',
|
||||
name: 'vid',
|
||||
labelName: 'properties.label'
|
||||
};
|
||||
var edgeProps = {
|
||||
@@ -873,6 +873,7 @@ function resolveGraphData(data) {
|
||||
Reflect.ownKeys(nodeProps).forEach(key => {
|
||||
node[key] = _.get(node, nodeProps[key], '');
|
||||
});
|
||||
console.log(node);
|
||||
});
|
||||
data.relations.forEach(edge => {
|
||||
Reflect.ownKeys(edgeProps).forEach(key => {
|
||||
|
||||
@@ -5,22 +5,22 @@
|
||||
<div class="graph-info-child">
|
||||
<div class="info-item" style="margin-bottom: 15px">
|
||||
<div class="info-item-title">
|
||||
<label>{{comment}}</label>
|
||||
<label>{{ comment }}</label>
|
||||
<!--<div class="add-attribute-box" style="float: right" @click="showAddGraphSpaceDialog({Name:''})">新建-->
|
||||
<!--</div>-->
|
||||
<!--<div class="add-attribute-box" style="float: right;margin-right: 10px" @click="removeGraphSpace()">-->
|
||||
<!--删除-->
|
||||
<!--删除-->
|
||||
<!--</div>-->
|
||||
</div>
|
||||
<div class="info-item-content">
|
||||
<!--<el-select v-model="space" filterable placeholder="请选择" @change="handleSpaceChange">-->
|
||||
<!--<el-option v-for="item in spaceList"-->
|
||||
<!--:key="item.name"-->
|
||||
<!--:label="item.comment"-->
|
||||
<!--:value="item.name">-->
|
||||
<!--</el-option>-->
|
||||
<!--<el-option v-for="item in spaceList"-->
|
||||
<!--:key="item.name"-->
|
||||
<!--:label="item.comment"-->
|
||||
<!--:value="item.name">-->
|
||||
<!--</el-option>-->
|
||||
<!--</el-select>-->
|
||||
<div style="margin-top: 20px;font-size: 14px;color: #606266">本体名称:{{ontologyName}}</div>
|
||||
<div style="margin-top: 20px;font-size: 14px;color: #606266">本体名称:{{ ontologyName }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<el-tabs v-model="activeTab" class="el-tabs-item">
|
||||
@@ -36,7 +36,7 @@
|
||||
<template slot-scope="scope">
|
||||
<div :style="scope.row.Name === activeSelectType ? 'color: #409EFF':''">
|
||||
<label>{{ scope.row.comment }}</label>
|
||||
<label>({{ scope.row.count }})</label>
|
||||
<!-- <label>({{ scope.row.count }})</label>-->
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
@@ -55,7 +55,7 @@
|
||||
<template slot-scope="scope">
|
||||
<div :style="scope.row.Name === activeSelectType ? 'color: #409EFF':''">
|
||||
<label>{{ scope.row.comment }}</label>
|
||||
<label>({{ scope.row.count }})</label>
|
||||
<!-- <label>({{ scope.row.count }})</label>-->
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
@@ -79,6 +79,9 @@
|
||||
<div v-show="tabModifyCmdType === 'nodeDetail'">
|
||||
<node-detail ref="nodeDetail"></node-detail>
|
||||
</div>
|
||||
<div v-show="tabModifyCmdType === 'edgeDetail'">
|
||||
<edge-detail ref="edgeDetail"></edge-detail>
|
||||
</div>
|
||||
<div v-show="tabModifyCmdType === 'edgeAdd'">
|
||||
<edge-add ref="edgeAdd"></edge-add>
|
||||
</div>
|
||||
@@ -92,7 +95,8 @@
|
||||
<div v-if="showFlag" style="display: inline-block;margin-right: 50px">
|
||||
<el-input placeholder="请输入关键词" v-model="keyword" style="width: 550px">
|
||||
<el-select v-model="searchTag" slot="prepend" placeholder="请选择概念" style="width: 150px" filterable>
|
||||
<el-option :label="item.comment" :value="item.Name" v-for="(item,index) in tagList" v-if="index != 0"></el-option>
|
||||
<el-option :label="item.comment" :value="item.Name" v-for="(item,index) in tagList"
|
||||
v-if="index != 0"></el-option>
|
||||
</el-select>
|
||||
<el-button slot="append" icon="el-icon-search" @click="searchBtn()"></el-button>
|
||||
</el-input>
|
||||
@@ -111,8 +115,8 @@
|
||||
<i title="返回"></i>
|
||||
</div>
|
||||
<!--<div title="按住shift点选两节点可新增关系" :class="['icon icon-arrow', createEdgeModelFlag ? 'active' : '']"-->
|
||||
<!--@click="changeCreateEdgeModel">-->
|
||||
<!--<i title="按住shift点选两节点可新增关系"></i>-->
|
||||
<!--@click="changeCreateEdgeModel">-->
|
||||
<!--<i title="按住shift点选两节点可新增关系"></i>-->
|
||||
<!--</div>-->
|
||||
<!-- <div class="icon icon-remove" @click="removeNode">-->
|
||||
<!-- <i title="删除"></i>-->
|
||||
@@ -212,7 +216,7 @@ export default {
|
||||
'node-detail': nodeDetail,
|
||||
'edge-detail': edgeDetail,
|
||||
'graph-space-add': graphSpaceAdd,
|
||||
'edge-add':edgeAdd
|
||||
'edge-add': edgeAdd
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@@ -233,15 +237,15 @@ export default {
|
||||
},
|
||||
tagMap: {},
|
||||
edgeMap: {},
|
||||
ontologyName:"",
|
||||
showFlag:false,
|
||||
keyword:"",
|
||||
searchTag:"",
|
||||
ontologyId:"",
|
||||
comment:"",
|
||||
qo:{
|
||||
pageNo:"",
|
||||
name:""
|
||||
ontologyName: "",
|
||||
showFlag: false,
|
||||
keyword: "",
|
||||
searchTag: "",
|
||||
ontologyId: "",
|
||||
comment: "",
|
||||
qo: {
|
||||
pageNo: "",
|
||||
name: ""
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -249,15 +253,15 @@ export default {
|
||||
vm = this;
|
||||
},
|
||||
mounted() {
|
||||
vm.qo = {
|
||||
pageNo: this.$route.query.pageNo,
|
||||
name: this.$route.query.name
|
||||
};
|
||||
vm.ontologyId = this.$route.query.ontologyId;
|
||||
vm.space = this.$route.query.space;
|
||||
vm.comment = this.$route.query.comment;
|
||||
vm.handleSpaceChange();
|
||||
// vm.querySpaceList();
|
||||
vm.qo = {
|
||||
pageNo: this.$route.query.pageNo,
|
||||
name: this.$route.query.name
|
||||
};
|
||||
vm.ontologyId = this.$route.query.ontologyId;
|
||||
vm.space = this.$route.query.space;
|
||||
vm.comment = this.$route.query.comment;
|
||||
vm.handleSpaceChange();
|
||||
// vm.querySpaceList();
|
||||
// vm.initGraph();
|
||||
},
|
||||
methods: {
|
||||
@@ -271,34 +275,34 @@ export default {
|
||||
if (res.data.length > 0) {
|
||||
vm.space = res.data[0].name;
|
||||
vm.handleSpaceChange();
|
||||
}else{
|
||||
vm.space = "";
|
||||
vm.tagMap = {};
|
||||
vm.edgeMap = {};
|
||||
vm.tagList = [];
|
||||
vm.edgeList = [];
|
||||
vm.ontologyName = "";
|
||||
vm.destroyGraph();
|
||||
} else {
|
||||
vm.space = "";
|
||||
vm.tagMap = {};
|
||||
vm.edgeMap = {};
|
||||
vm.tagList = [];
|
||||
vm.edgeList = [];
|
||||
vm.ontologyName = "";
|
||||
vm.destroyGraph();
|
||||
}
|
||||
});
|
||||
},
|
||||
queryOntologyDetail(){
|
||||
var id = vm.ontologyId;
|
||||
// vm.spaceList.forEach(item => {
|
||||
// if(item.name == vm.space){
|
||||
// id = item.OntologyId;
|
||||
// }
|
||||
// })
|
||||
queryOntologyDetail() {
|
||||
var id = vm.ontologyId;
|
||||
// vm.spaceList.forEach(item => {
|
||||
// if(item.name == vm.space){
|
||||
// id = item.OntologyId;
|
||||
// }
|
||||
// })
|
||||
|
||||
if(id){
|
||||
request({
|
||||
url: `/ontology/getone/`+id,
|
||||
method: 'post',
|
||||
data: {id:id}
|
||||
}).then(res => {
|
||||
vm.ontologyName = res.data.name;
|
||||
})
|
||||
}
|
||||
if (id) {
|
||||
request({
|
||||
url: `/ontology/getone/` + id,
|
||||
method: 'post',
|
||||
data: {id: id}
|
||||
}).then(res => {
|
||||
vm.ontologyName = res.data.name;
|
||||
})
|
||||
}
|
||||
},
|
||||
handleSpaceChange() {
|
||||
vm.initGraph();
|
||||
@@ -342,10 +346,10 @@ export default {
|
||||
method: 'get',
|
||||
data: {}
|
||||
}).then(res => {
|
||||
res.data.unshift({
|
||||
Name: `All`,
|
||||
comment: '实体数'
|
||||
});
|
||||
// res.data.unshift({
|
||||
// Name: `All`,
|
||||
// comment: '实体数'
|
||||
// });
|
||||
res.data.forEach(row => {
|
||||
row.count = vm.tagMap[row.Name] ? vm.tagMap[row.Name] : 0;
|
||||
});
|
||||
@@ -359,10 +363,10 @@ export default {
|
||||
method: 'get',
|
||||
data: {}
|
||||
}).then(res => {
|
||||
res.data.unshift({
|
||||
Name: `All`,
|
||||
comment: '三元组数'
|
||||
});
|
||||
// res.data.unshift({
|
||||
// Name: `All`,
|
||||
// comment: '三元组数'
|
||||
// });
|
||||
res.data.forEach(row => {
|
||||
row.count = vm.edgeMap[row.Name] ? vm.edgeMap[row.Name] : 0;
|
||||
});
|
||||
@@ -405,6 +409,7 @@ export default {
|
||||
queryDetail(type, obj) { // type : node/edge
|
||||
vm.tabModifyCmdType = type + 'Detail';
|
||||
vm.propsInfoVisible = true;
|
||||
console.log(type);
|
||||
vm.$nextTick(() => {
|
||||
vm.$refs[type + 'Detail'].queryDetail(vm.space, obj);
|
||||
});
|
||||
@@ -478,8 +483,17 @@ export default {
|
||||
});
|
||||
|
||||
if (node.properties) {
|
||||
node.label = node.name = getFirstStringProperty(node.properties);
|
||||
// node.label = node.name = getFirstStringProperty(node.properties);
|
||||
node.label = node.name = node.vid;
|
||||
}
|
||||
|
||||
if(node.labels === 'tag_1412011336') {
|
||||
node.style = {
|
||||
fill: '#3cec6c'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@@ -603,90 +617,90 @@ export default {
|
||||
vm.$refs['nodeDetail'].createItem(vm.space);
|
||||
});
|
||||
},
|
||||
showAddEdgeDialog(){
|
||||
vm.tabModifyCmdType = 'edgeAdd';
|
||||
vm.propsInfoVisible = true;
|
||||
vm.$nextTick(() => {
|
||||
vm.$refs['edgeAdd'].createItem(vm.space);
|
||||
});
|
||||
showAddEdgeDialog() {
|
||||
vm.tabModifyCmdType = 'edgeAdd';
|
||||
vm.propsInfoVisible = true;
|
||||
vm.$nextTick(() => {
|
||||
vm.$refs['edgeAdd'].createItem(vm.space);
|
||||
});
|
||||
},
|
||||
//搜索
|
||||
searchBtn(){
|
||||
if(!vm.searchTag){
|
||||
vm.$message.warning("请选择概念");
|
||||
return false;
|
||||
}
|
||||
if(!vm.keyword){
|
||||
vm.$message.warning("请输入关键字");
|
||||
return false;
|
||||
}
|
||||
vm.graphLoading = true;
|
||||
request({
|
||||
url: `/nebula_operate/findnodebykeyword/${vm.space}/${vm.searchTag}`,
|
||||
method: 'post',
|
||||
data: {keyword:vm.keyword}
|
||||
}).then(res => {
|
||||
if (res.data) {
|
||||
res.data.forEach(node => {
|
||||
Reflect.ownKeys(nodeProps).forEach(key => {
|
||||
node[key] = _.get(node, nodeProps[key], '');
|
||||
});
|
||||
searchBtn() {
|
||||
if (!vm.searchTag) {
|
||||
vm.$message.warning("请选择概念");
|
||||
return false;
|
||||
}
|
||||
if (!vm.keyword) {
|
||||
vm.$message.warning("请输入关键字");
|
||||
return false;
|
||||
}
|
||||
vm.graphLoading = true;
|
||||
request({
|
||||
url: `/nebula_operate/findnodebykeyword/${vm.space}/${vm.searchTag}`,
|
||||
method: 'post',
|
||||
data: {keyword: vm.keyword}
|
||||
}).then(res => {
|
||||
if (res.data) {
|
||||
res.data.forEach(node => {
|
||||
Reflect.ownKeys(nodeProps).forEach(key => {
|
||||
node[key] = _.get(node, nodeProps[key], '');
|
||||
});
|
||||
|
||||
if (node.properties) {
|
||||
node.label = node.name = getFirstStringProperty(node.properties);
|
||||
}
|
||||
});
|
||||
if (node.properties) {
|
||||
node.label = node.name = getFirstStringProperty(node.properties);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
graphData = {
|
||||
nodes: res.data ? res.data : [],
|
||||
edges: []
|
||||
};
|
||||
// 读取数据
|
||||
graph.data(graphData);
|
||||
// 渲染图
|
||||
graph.render();
|
||||
vm.graphLoading = false;
|
||||
});
|
||||
graphData = {
|
||||
nodes: res.data ? res.data : [],
|
||||
edges: []
|
||||
};
|
||||
// 读取数据
|
||||
graph.data(graphData);
|
||||
// 渲染图
|
||||
graph.render();
|
||||
vm.graphLoading = false;
|
||||
});
|
||||
},
|
||||
findOnePathBySrcidAndDctid(srcId, dstId){
|
||||
request({
|
||||
url: `/nebula_operate/findonepathbysrcidanddctid/${vm.space}/${srcId}/${dstId}`,
|
||||
method: 'get',
|
||||
data: {}
|
||||
}).then(res => {
|
||||
vm.resolveGraphData(res);
|
||||
});
|
||||
findOnePathBySrcidAndDctid(srcId, dstId) {
|
||||
request({
|
||||
url: `/nebula_operate/findonepathbysrcidanddctid/${vm.space}/${srcId}/${dstId}`,
|
||||
method: 'get',
|
||||
data: {}
|
||||
}).then(res => {
|
||||
vm.resolveGraphData(res);
|
||||
});
|
||||
},
|
||||
findNodeById(tag,vid){
|
||||
request({
|
||||
url: `/nebula_operate/findnodebyid/${vm.space}/${tag}/${vid}`,
|
||||
method: 'get',
|
||||
data: {}
|
||||
}).then(res => {
|
||||
if (res.data) {
|
||||
Reflect.ownKeys(nodeProps).forEach(key => {
|
||||
res.data[key] = _.get(res.data, nodeProps[key], '');
|
||||
});
|
||||
findNodeById(tag, vid) {
|
||||
request({
|
||||
url: `/nebula_operate/findnodebyid/${vm.space}/${tag}/${vid}`,
|
||||
method: 'get',
|
||||
data: {}
|
||||
}).then(res => {
|
||||
if (res.data) {
|
||||
Reflect.ownKeys(nodeProps).forEach(key => {
|
||||
res.data[key] = _.get(res.data, nodeProps[key], '');
|
||||
});
|
||||
|
||||
if (res.data.properties) {
|
||||
res.data.label = res.data.name = getFirstStringProperty(res.data.properties);
|
||||
}
|
||||
}
|
||||
if (res.data.properties) {
|
||||
res.data.label = res.data.name = getFirstStringProperty(res.data.properties);
|
||||
}
|
||||
}
|
||||
|
||||
graphData = {
|
||||
nodes: res.data ? [res.data] : [],
|
||||
edges: []
|
||||
};
|
||||
// 读取数据
|
||||
graph.data(graphData);
|
||||
// 渲染图
|
||||
graph.render();
|
||||
vm.graphLoading = false;
|
||||
});
|
||||
graphData = {
|
||||
nodes: res.data ? [res.data] : [],
|
||||
edges: []
|
||||
};
|
||||
// 读取数据
|
||||
graph.data(graphData);
|
||||
// 渲染图
|
||||
graph.render();
|
||||
vm.graphLoading = false;
|
||||
});
|
||||
},
|
||||
backGraph() { // 返回
|
||||
vm.$router.push({path: "/graphSpaceManage", query: {pageNo: vm.qo.pageNo, name: vm.qo.name}})
|
||||
vm.$router.push({path: "/graphSpaceManage", query: {pageNo: vm.qo.pageNo, name: vm.qo.name}})
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -777,7 +791,7 @@ function refreshDragedNodePosition(e) {
|
||||
}
|
||||
|
||||
.graph-info-box {
|
||||
left: 0;
|
||||
left: 20px;
|
||||
width: 230px;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,61 +1,76 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="menu-title">
|
||||
条目管理
|
||||
物类管理
|
||||
</div>
|
||||
<div class="menu-content">
|
||||
<div>
|
||||
<el-form :inline="true" :model="qo" class="demo-form-inline">
|
||||
<el-form-item label="唯一标识:">
|
||||
<el-input v-model="qo.LIKES_fid" placeholder="请输入唯一标识" clearable style="width: 300px"></el-input>
|
||||
</el-form-item>
|
||||
<!-- <el-form-item label="种类:">-->
|
||||
<!-- <el-input v-model="qo.LIKES_categories" placeholder="请输入种类" clearable style="width: 300px"></el-input>-->
|
||||
<!-- </el-form-item>-->
|
||||
<!-- <el-form-item label="标签:">-->
|
||||
<!-- <el-input v-model="qo.LIKES_labels" placeholder="请输入标签" clearable style="width: 300px"></el-input>-->
|
||||
<!-- </el-form-item>-->
|
||||
<el-form-item>
|
||||
<el-input v-model="qo.LIKES_categories" placeholder="请输入种类"></el-input>
|
||||
<el-button type="primary" icon="el-icon-search" @click="queryDataById()">搜 索</el-button>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-input v-model="qo.LIKES_labels" placeholder="请输入标签"></el-input>
|
||||
<el-button type="primary" @click="queryData(-1)">上一页</el-button>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="el-icon-search" @click="qo.pageNo=1;queryData()">搜 索</el-button>
|
||||
<el-button type="primary" @click="queryData(1)">下一页</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<div style="margin: 0px 0 20px 0">
|
||||
<el-button type="primary" @click="createRow()">添加</el-button>
|
||||
<!-- <el-button type="primary" @click="createRow()" icon="el-icon-plus">添 加</el-button>-->
|
||||
<el-button type="primary" @click="downloadItem()" icon="el-icon-download">导出物类</el-button>
|
||||
<el-button type="primary" @click="showImportItemPage()" icon="el-icon-upload2">导入物类</el-button>
|
||||
</div>
|
||||
<div>
|
||||
<el-table :data="result.records" style="width: 100%">
|
||||
<el-table :data="result.records" style="width: 100%" v-loading="loading">
|
||||
<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="categories" label="种类">
|
||||
<el-table-column prop="ItemId" label="唯一标识"></el-table-column>
|
||||
<el-table-column prop="Categories" label="种类">
|
||||
<div slot-scope="scope">
|
||||
<template v-for="(tag,index) in scope.row.categoriesArr">
|
||||
<el-tag :key="index" v-if="index < 5">{{ tag }}</el-tag>
|
||||
<template v-if="scope.row.Categories">
|
||||
<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 > 10">...</el-tag>
|
||||
</template>
|
||||
<el-tag v-if="scope.row.categoriesArr.length > 10">...</el-tag>
|
||||
</div>
|
||||
</el-table-column>
|
||||
<el-table-column prop="labels" label="标签">
|
||||
<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 v-if="scope.row.Labels">
|
||||
<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>
|
||||
</template>
|
||||
<el-tag v-if="scope.row.labelsArr.length > 5">...</el-tag>
|
||||
</div>
|
||||
</el-table-column>
|
||||
<el-table-column prop="isHidden" label="是否隐藏" width="100">
|
||||
<el-table-column prop="IsHidden" label="是否隐藏" width="100">
|
||||
<template slot-scope="scope">
|
||||
{{ scope.row.isHidden ? '是' : '否' }}
|
||||
{{ scope.row.IsHidden ? '是' : '否' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="description" label="描述">
|
||||
<template slot-scope="scope">
|
||||
{{ scope.row.description.substring(0, 100) }}{{ scope.row.description.length > 100 ? '...' : '' }}
|
||||
{{ scope.row.Comment.substring(0, 100) }}{{ scope.row.Comment.length > 100 ? '...' : '' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="createTime" label="创建时间" width="180"></el-table-column>
|
||||
<el-table-column label="操作" width="150">
|
||||
<el-table-column prop="Timestamp" label="创建时间" width="180"></el-table-column>
|
||||
<el-table-column label="操作" width="120">
|
||||
<template slot-scope="scope">
|
||||
<el-button @click.native.prevent="modifyRow(scope.row)" type="text" size="small">
|
||||
编辑
|
||||
</el-button>
|
||||
<!-- <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>
|
||||
@@ -66,15 +81,15 @@
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<div class="page-box">
|
||||
<el-pagination background
|
||||
@current-change="handleCurrentChange"
|
||||
:current-page="qo.pageNo"
|
||||
:page-size="qo.pageSize"
|
||||
layout="total, prev, pager, next"
|
||||
:total="result.total">
|
||||
</el-pagination>
|
||||
</div>
|
||||
<!-- <div class="page-box">-->
|
||||
<!-- <el-pagination background-->
|
||||
<!-- @current-change="handleCurrentChange"-->
|
||||
<!-- :current-page="qo.pageNo"-->
|
||||
<!-- :page-size="qo.pageSize"-->
|
||||
<!-- layout="total, prev, pager, next"-->
|
||||
<!-- :total="result.total">-->
|
||||
<!-- </el-pagination>-->
|
||||
<!-- </div>-->
|
||||
</div>
|
||||
<el-dialog
|
||||
:title="dialogName"
|
||||
@@ -143,7 +158,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import request from '@/utils/request';
|
||||
import request, {getBaseUrl} from '@/utils/request';
|
||||
|
||||
var _this;
|
||||
export default {
|
||||
@@ -153,6 +168,7 @@ export default {
|
||||
qo: {
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
LIKES_fid: '',
|
||||
LIKES_categories: '',
|
||||
LIKES_labels: '',
|
||||
},
|
||||
@@ -160,6 +176,8 @@ export default {
|
||||
records: [],
|
||||
total: 0
|
||||
},
|
||||
loading: false,
|
||||
cursorArr: [''],
|
||||
sourceTypeList: [
|
||||
{name: '自定义本体', value: 1},
|
||||
{name: '标注系统', value: 2}
|
||||
@@ -187,36 +205,62 @@ export default {
|
||||
if (_qo) {
|
||||
_this.qo = JSON.parse(_qo);
|
||||
}
|
||||
_this.queryData();
|
||||
_this.queryData(0);
|
||||
},
|
||||
methods: {
|
||||
queryData() {
|
||||
request({
|
||||
url: '/entrys/query_pages',
|
||||
method: 'post',
|
||||
data: _this.qo
|
||||
}).then(res => {
|
||||
res.data.records.forEach(row => {
|
||||
row.categoriesArr = row.categories ? row.categories.split(',') : [];
|
||||
row.labelsArr = row.labels ? row.labels.split(',') : [];
|
||||
queryDataById() {
|
||||
if (this.qo.LIKES_fid.length > 0) {
|
||||
this.loading = true;
|
||||
request({
|
||||
url: '/gorse/query_item/' + this.qo.LIKES_fid,
|
||||
method: 'get',
|
||||
}).then(res => {
|
||||
let item = res.data;
|
||||
if (!item) {
|
||||
_this.result.records = [];
|
||||
} else {
|
||||
_this.result.records = [item];
|
||||
}
|
||||
this.loading = false;
|
||||
});
|
||||
|
||||
_this.result.records = res.data.records;
|
||||
_this.result.total = res.data.total;
|
||||
} else {
|
||||
this.cursorArr = [''];
|
||||
this.queryData(1);
|
||||
}
|
||||
},
|
||||
queryData(index) {// index -1 上一页,0刷新, 1下一页
|
||||
this.loading = true;
|
||||
this.cursorArr = this.cursorArr.slice(0, this.cursorArr.length - 1 + index);
|
||||
this.cursorArr = this.cursorArr.length === 0 ? [''] : this.cursorArr;
|
||||
request({
|
||||
url: '/gorse/query_items?cursor=' + this.cursorArr[this.cursorArr.length - 1],
|
||||
method: 'get',
|
||||
}).then(res => {
|
||||
this.cursorArr.push(res.data.Cursor);
|
||||
_this.result.records = res.data.Items;
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
handleCurrentChange(val) {
|
||||
_this.qo.pageNo = val;
|
||||
_this.queryData();
|
||||
},
|
||||
downloadItem() {
|
||||
window.open(getBaseUrl() + '/bulk/get_bulk/items');
|
||||
},
|
||||
similarItem(item) {
|
||||
_this.$router.push({
|
||||
path: "similarItem", query: {
|
||||
itemId: item.fid,
|
||||
itemId: item.ItemId,
|
||||
qo: JSON.stringify(_this.qo)
|
||||
}
|
||||
});
|
||||
},
|
||||
showImportItemPage() {
|
||||
_this.$router.push({
|
||||
path: "importItem"
|
||||
});
|
||||
},
|
||||
removeRow(item) {
|
||||
_this.$confirm('此操作将永久删除记录, 是否继续?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
@@ -224,11 +268,11 @@ export default {
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
request({
|
||||
url: '/entrys/remove/' + item.id,
|
||||
url: '/gorse/delete_item/' + item.ItemId,
|
||||
method: 'post'
|
||||
}).then(res => {
|
||||
_this.$message.success("删除成功");
|
||||
_this.queryData();
|
||||
_this.queryData(0);
|
||||
});
|
||||
}).catch(() => {
|
||||
});
|
||||
@@ -236,7 +280,7 @@ export default {
|
||||
createRow() {
|
||||
_this.dialogName = '新建';
|
||||
_this.cmdDialogVisible = true;
|
||||
_this.$nextTick(_=> {
|
||||
_this.$nextTick(_ => {
|
||||
_this.$refs['cmd'].clearValidate();
|
||||
_this.cmd = {
|
||||
fid: '',
|
||||
@@ -250,7 +294,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));
|
||||
})
|
||||
@@ -258,10 +302,10 @@ export default {
|
||||
submitModify() {
|
||||
this.$refs.cmd.validate((valid) => {
|
||||
if (valid) {
|
||||
if(_this.cmd.categoriesArr) {
|
||||
if (_this.cmd.categoriesArr) {
|
||||
_this.cmd.categories = _this.cmd.categoriesArr.toString();
|
||||
}
|
||||
if(_this.cmd.labelsArr) {
|
||||
if (_this.cmd.labelsArr) {
|
||||
_this.cmd.labels = _this.cmd.labelsArr.toString();
|
||||
}
|
||||
|
||||
@@ -306,7 +350,7 @@ export default {
|
||||
},
|
||||
handleInputConfirm(typeName) {
|
||||
let inputValue = _this[typeName + "InputValue"];
|
||||
if(inputValue) {
|
||||
if (inputValue) {
|
||||
_this.cmd[typeName + "Arr"].push(inputValue);
|
||||
}
|
||||
_this[typeName + "InputVisible"] = false;
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="menu-title">
|
||||
反馈类型管理
|
||||
反馈类型
|
||||
</div>
|
||||
<div class="menu-content">
|
||||
<div>
|
||||
<el-form :inline="true" :model="qo" class="demo-form-inline">
|
||||
<el-form-item>
|
||||
<el-input v-model="qo.LIKES_name" placeholder="请输入名称"></el-input>
|
||||
<el-form-item label="名称:">
|
||||
<el-input v-model="qo.LIKES_name" placeholder="请输入名称" clearable style="width: 300px"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="el-icon-search" @click="qo.pageNo=1;queryData()">搜 索</el-button>
|
||||
@@ -15,23 +15,24 @@
|
||||
</el-form>
|
||||
</div>
|
||||
<div style="margin: 0px 0 20px 0">
|
||||
<el-button type="primary" @click="createRow()">添加</el-button>
|
||||
<el-button type="primary" @click="downloadFeedback()" icon="el-icon-download">导出反馈</el-button>
|
||||
<el-button type="primary" @click="showImportFeedbackPage()" icon="el-icon-upload2">导入反馈</el-button>
|
||||
</div>
|
||||
<div>
|
||||
<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 prop="name" label="名称"></el-table-column>
|
||||
<el-table-column prop="createTime" label="创建时间" width="180"></el-table-column>
|
||||
<el-table-column label="操作" width="100">
|
||||
<template slot-scope="scope">
|
||||
<el-button @click.native.prevent="modifyRow(scope.row)" type="text" size="small">
|
||||
编辑
|
||||
</el-button>
|
||||
<el-button @click.native.prevent="removeRow(scope.row)" type="text" size="small">
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="type" label="性质" :formatter="typeFormatter"></el-table-column>
|
||||
<!-- <el-table-column label="操作" width="100">-->
|
||||
<!-- <template slot-scope="scope">-->
|
||||
<!-- <el-button @click.native.prevent="modifyRow(scope.row)" type="text" size="small">-->
|
||||
<!-- 编辑-->
|
||||
<!-- </el-button>-->
|
||||
<!-- <el-button @click.native.prevent="removeRow(scope.row)" type="text" size="small">-->
|
||||
<!-- 删除-->
|
||||
<!-- </el-button>-->
|
||||
<!-- </template>-->
|
||||
<!-- </el-table-column>-->
|
||||
</el-table>
|
||||
</div>
|
||||
<div class="page-box">
|
||||
@@ -62,7 +63,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import request from '@/utils/request';
|
||||
import request, {getBaseUrl} from '@/utils/request';
|
||||
|
||||
var _this;
|
||||
export default {
|
||||
@@ -78,6 +79,10 @@ export default {
|
||||
records: [],
|
||||
total: 0
|
||||
},
|
||||
typeMap: {
|
||||
read: '已读反馈',
|
||||
positive: '正向反馈'
|
||||
},
|
||||
dialogName: '编辑',
|
||||
cmdDialogVisible: false,
|
||||
cmd: {},
|
||||
@@ -103,6 +108,17 @@ export default {
|
||||
_this.result.total = res.data.total;
|
||||
});
|
||||
},
|
||||
typeFormatter(row) {
|
||||
return this.typeMap[row.type] || "";
|
||||
},
|
||||
showImportFeedbackPage() {
|
||||
_this.$router.push({
|
||||
path: "importFeedback"
|
||||
});
|
||||
},
|
||||
downloadFeedback() {
|
||||
window.open(getBaseUrl() + '/bulk/get_bulk/feedback');
|
||||
},
|
||||
handleCurrentChange(val) {
|
||||
_this.qo.pageNo = val;
|
||||
_this.queryData();
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="menu-title">
|
||||
知识图谱导入
|
||||
图谱导入
|
||||
</div>
|
||||
<div class="menu-content">
|
||||
<el-tabs v-model="activeName" @tab-click="handleClick">
|
||||
@@ -26,12 +26,12 @@
|
||||
:on-change="handleFileChange"
|
||||
:limit="2"
|
||||
:show-file-list="false">
|
||||
<el-button type="primary">上传文件</el-button>
|
||||
<el-button type="primary" icon="el-icon-upload2">上传文件</el-button>
|
||||
</el-upload>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="2">
|
||||
<el-button type="primary" style="float:right;" @click="queryData" :loading="btLoading">执行</el-button>
|
||||
<el-button type="primary" style="float:right;" @click="queryData" :loading="btLoading" icon="el-icon-check">执行</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<div><a :href="path+'template.xlsx'" download="template.xlsx" style="text-decoration:underline;color: #0D6DFF">下载模板</a></div>
|
||||
@@ -58,7 +58,7 @@
|
||||
<el-col :span="10">
|
||||
<div >
|
||||
<label>请选择文件:</label>
|
||||
<el-input v-model="fileName" readonly style="margin-right: 20px;width: calc(100% - 204px)" disabled></el-input>
|
||||
<el-input v-model="fileName" readonly style="margin-right: 20px;width: calc(100% - 254px)" disabled></el-input>
|
||||
<el-upload
|
||||
ref="upload" style="display: inline-block"
|
||||
:auto-upload="false"
|
||||
@@ -66,19 +66,19 @@
|
||||
:on-change="handleFileChange"
|
||||
:limit="2"
|
||||
:show-file-list="false">
|
||||
<el-button type="primary">上传文件</el-button>
|
||||
<el-button type="primary" icon="el-icon-upload2">上传文件</el-button>
|
||||
</el-upload>
|
||||
</div>
|
||||
<div style="color: red;margin-top: 10px">* zip文件必须包含vertex.json、edge.json</div>
|
||||
</el-col>
|
||||
<el-col :span="2">
|
||||
<el-button type="primary" style="float:right;" @click="startSpace">执行</el-button>
|
||||
<el-button type="primary" style="float:right;" @click="startSpace" icon="el-icon-check">执行</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<div><a :href="path+'图谱数据.zip'" download="图谱数据.zip" style="text-decoration:underline;color: #0D6DFF">下载模板</a></div>
|
||||
<div class="result" style="width: 100%;margin-top: 20px;color: #5c5c5c;" v-if="showFlag && activeName == 'second'">{{message}}</div>
|
||||
<div style="margin-top: 20px;" v-if="showFlag && activeName == 'second'">
|
||||
<el-table :data="resultCmd1" border style="width: 100%" >
|
||||
<el-table :data="resultCmd1" border style="width: 100%" >
|
||||
<el-table-column prop="title" label="标题"></el-table-column>
|
||||
<el-table-column prop="gf_name" label="文件名"></el-table-column>
|
||||
<el-table-column prop="flag" label="状态">
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="menu-title">
|
||||
知识图谱本体管理
|
||||
本体管理
|
||||
</div>
|
||||
<div class="menu-content">
|
||||
<div>
|
||||
<el-form :inline="true" :model="qo" class="demo-form-inline">
|
||||
<el-form-item>
|
||||
<el-input v-model="qo.LIKES_name" placeholder="请输入本体名称"></el-input>
|
||||
<el-form-item label="本体名称:">
|
||||
<el-input v-model="qo.LIKES_name" placeholder="请输入本体名称" style="width: 300px"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="el-icon-search" @click="qo.pageNo=1;queryData()">搜 索</el-button>
|
||||
@@ -15,10 +15,10 @@
|
||||
</el-form>
|
||||
</div>
|
||||
<div style="margin: 0px 0 20px 0">
|
||||
<el-button type="primary" @click="createRow()">新建知识图谱本体</el-button>
|
||||
<el-button type="primary" @click="createRow()" icon="el-icon-plus">新建知识图谱本体</el-button>
|
||||
</div>
|
||||
<div>
|
||||
<el-table :data="result.records" style="width: 100%">
|
||||
<el-table :data="result.records" style="width: 100%">
|
||||
<el-table-column type="index" label="行号" width="100"></el-table-column>
|
||||
<el-table-column prop="name" label="本体名称"></el-table-column>
|
||||
<el-table-column prop="description" label="本体描述"></el-table-column>
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="menu-title">
|
||||
知识图谱管理
|
||||
图谱管理
|
||||
</div>
|
||||
<div class="menu-content">
|
||||
<div>
|
||||
<el-form :inline="true" :model="qo" class="demo-form-inline">
|
||||
<el-form-item>
|
||||
<el-input v-model="qo.LIKES_name" placeholder="请输入图谱名称"></el-input>
|
||||
<el-form-item label="图谱名称:">
|
||||
<el-input v-model="qo.LIKES_name" placeholder="请输入图谱名称" style="width: 300px"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="el-icon-search" @click="qo.pageNo=1;queryData()">搜 索</el-button>
|
||||
@@ -15,10 +15,10 @@
|
||||
</el-form>
|
||||
</div>
|
||||
<div style="margin: 0px 0 20px 0">
|
||||
<el-button type="primary" @click="createRow()">新建知识图谱</el-button>
|
||||
<el-button type="primary" @click="createRow()" icon="el-icon-plus">新建知识图谱</el-button>
|
||||
</div>
|
||||
<div>
|
||||
<el-table :data="result.records" style="width: 100%">
|
||||
<el-table :data="result.records" style="width: 100%">
|
||||
<el-table-column type="index" label="行号" width="100"></el-table-column>
|
||||
<el-table-column prop="name" label="图谱名称"></el-table-column>
|
||||
<el-table-column prop="comment" label="图谱描述"></el-table-column>
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<el-button type="primary" @click="createTag()">新建类</el-button>
|
||||
</div>
|
||||
<div>
|
||||
<el-table :data="tagList" style="width: 100%">
|
||||
<el-table :data="tagList" style="width: 100%">
|
||||
<el-table-column type="index" label="行号" width="100"></el-table-column>
|
||||
<el-table-column prop="Name" label="名称"></el-table-column>
|
||||
<el-table-column label="操作">
|
||||
@@ -45,7 +45,7 @@
|
||||
<el-button type="primary" @click="createEdge()">新建关系</el-button>
|
||||
</div>
|
||||
<div>
|
||||
<el-table :data="edgeList" style="width: 100%">
|
||||
<el-table :data="edgeList" style="width: 100%">
|
||||
<el-table-column type="index" label="行号" width="100"></el-table-column>
|
||||
<el-table-column prop="Name" label="名称"></el-table-column>
|
||||
<el-table-column label="操作">
|
||||
@@ -76,7 +76,7 @@
|
||||
<el-button type="primary" @click="createIndex()">新建索引</el-button>
|
||||
</div>
|
||||
<div>
|
||||
<el-table :data="indexList" style="width: 100%">
|
||||
<el-table :data="indexList" style="width: 100%">
|
||||
<el-table-column type="index" label="行号" width="100"></el-table-column>
|
||||
<el-table-column prop="name" label="名称"></el-table-column>
|
||||
<el-table-column prop="type" label="标签" v-if="activeIndexType == 'TAG'"></el-table-column>
|
||||
|
||||
@@ -5,13 +5,18 @@
|
||||
</div>
|
||||
<div class="home-box">
|
||||
<div class="counts-box">
|
||||
<div class="count-item" v-for="(value, key) in count" :key="key">
|
||||
<div>{{ key }}</div>
|
||||
<div>{{ value }}</div>
|
||||
<div class="count-item" v-for="(value, key, i) in count" :key="key">
|
||||
<div class="count-img" :style="{background:colorArray[i].color}">
|
||||
<i :class="colorArray[i].icon"></i>
|
||||
</div>
|
||||
<div class="count-title">
|
||||
<div class="name">{{ key }}</div>
|
||||
<div class="count">{{ value }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="chart-box">
|
||||
<div class="title">正反馈率</div>
|
||||
<div class="title"><i class="el-icon-s-data" style="margin-right: 10px;font-size: 18px"></i>正反馈率</div>
|
||||
<div id="chart"></div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -33,7 +38,14 @@ export default {
|
||||
'总反馈': '267,610',
|
||||
'正面反馈': '120,927',
|
||||
'负面反馈': '51,123'
|
||||
}
|
||||
},
|
||||
colorArray:[
|
||||
{color:"linear-gradient(#2196F3, #2196f394)",icon:"el-icon-user-solid",font:"#2196F3"},
|
||||
{color:"linear-gradient(#FF9800, #ff980094)",icon:"el-icon-s-goods",font:"#FF9800"},
|
||||
{color:"linear-gradient(#F44336, #f44336b5)",icon:"el-icon-document-remove",font:"#F44336"},
|
||||
{color:"linear-gradient(#4CAF50, #8bc34abf)",icon:"el-icon-document-checked",font:"#4CAF50"},
|
||||
{color:"linear-gradient(#c862d9, #c862d9bf)",icon:"el-icon-document-delete",font:"#c862d9"}
|
||||
]
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
@@ -46,8 +58,8 @@ export default {
|
||||
let chart = _this.$echarts.init(dom);
|
||||
chart.setOption({
|
||||
grid: {
|
||||
left: '3%',
|
||||
right: '3%'
|
||||
left: '5%',
|
||||
right: '5%'
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
@@ -60,12 +72,46 @@ export default {
|
||||
{
|
||||
name: 'like',
|
||||
data: [0.1, 0.23, 0.52, 0.44, 0.49, 0.78, 1],
|
||||
type: 'line'
|
||||
type: 'line',
|
||||
// 区域填充样式
|
||||
areaStyle: {
|
||||
color: {
|
||||
type: 'linear',
|
||||
x: 0,
|
||||
y: 0,
|
||||
x2: 0,
|
||||
y2: 1,
|
||||
colorStops: [{
|
||||
offset: 0, color: '#557cc7' // 0% 处的颜色
|
||||
},{
|
||||
offset: 0.2, color: 'rgba(85,124,199,0.2)' // 0% 处的颜色
|
||||
}, {
|
||||
offset: 1, color: 'rgba(58,132,255, 0)' // 100% 处的颜色
|
||||
}],
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'star',
|
||||
data: [0.92, 0.7, 0.65, 0.44, 0.55, 0.55, 0.78],
|
||||
type: 'line'
|
||||
type: 'line',
|
||||
// 区域填充样式
|
||||
areaStyle: {
|
||||
color: {
|
||||
type: 'linear',
|
||||
x: 0,
|
||||
y: 0,
|
||||
x2: 0,
|
||||
y2: 1,
|
||||
colorStops: [{
|
||||
offset: 0, color: 'rgb(145,204,117)' // 0% 处的颜色
|
||||
},{
|
||||
offset: 0.2, color: 'rgba(145,204,117,0.2)' // 0% 处的颜色
|
||||
}, {
|
||||
offset: 1, color: 'rgba(58,132,255, 0)' // 100% 处的颜色
|
||||
}],
|
||||
}
|
||||
},
|
||||
}
|
||||
]
|
||||
});
|
||||
@@ -80,30 +126,33 @@ export default {
|
||||
}
|
||||
|
||||
.home-box {
|
||||
padding: 0 30px;
|
||||
padding: 20px 30px 0 30px;
|
||||
|
||||
height: calc(100% - 160px);
|
||||
height: calc(100% - 100px);
|
||||
.chart-box {
|
||||
background-color: #fff;
|
||||
box-shadow: 0px 5px 12px 1px rgba(105, 105, 105, 0.12);
|
||||
border-radius: 10px;
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
margin-top: 30px;
|
||||
height: calc(100% - 200px);
|
||||
height: calc(100% - 130px);
|
||||
|
||||
#chart {
|
||||
width: 100%;
|
||||
height: calc(100% - 60px);
|
||||
height: calc(100% - 50px);
|
||||
}
|
||||
|
||||
.title {
|
||||
width: 100%;
|
||||
height: 60px;
|
||||
line-height: 60px;
|
||||
padding-left: 20px;
|
||||
font-size: 18px;
|
||||
color: #626672;
|
||||
border-bottom: 1px solid rgba(105, 105, 105, 0.12);
|
||||
height: 50px;
|
||||
margin-top: 10px;
|
||||
line-height: 50px;
|
||||
padding-left: 30px;
|
||||
font-size: 16px;
|
||||
color: #666666;
|
||||
font-weight: bold;
|
||||
//background: #f0f5fa;
|
||||
//border-bottom: 1px solid rgba(105, 105, 105, 0.12);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,26 +162,44 @@ export default {
|
||||
|
||||
.count-item {
|
||||
width: 18%;
|
||||
height: 165px;
|
||||
height: 100px;
|
||||
background-color: #fff;
|
||||
box-shadow: 0px 5px 12px 1px rgba(105, 105, 105, 0.12);
|
||||
text-align: center;
|
||||
border-radius: 10px;
|
||||
//text-align: center;
|
||||
border-radius: 4px;
|
||||
display: flex;
|
||||
|
||||
&:hover {
|
||||
transform: scale(1.03);
|
||||
}
|
||||
|
||||
> div:first-child {
|
||||
font-size: 18px;
|
||||
padding-top: 35px;
|
||||
color: rgba(103, 109, 122, 0.58);
|
||||
.count-img{
|
||||
width: 80px;
|
||||
color:#ffffff;
|
||||
font-size: 40px;
|
||||
text-align: center;
|
||||
line-height: 100px;
|
||||
height: 100px;
|
||||
border-top-left-radius: 4px;
|
||||
border-bottom-left-radius: 4px;
|
||||
}
|
||||
|
||||
> div:last-child {
|
||||
font-size: 40px;
|
||||
.count-title{
|
||||
flex: 1;
|
||||
margin: 0 20px;
|
||||
}
|
||||
|
||||
.name {
|
||||
font-size: 14px;
|
||||
padding-top: 20px;
|
||||
color: #333333;
|
||||
//font-weight: bold;
|
||||
}
|
||||
|
||||
.count {
|
||||
font-size: 30px;
|
||||
color: #3e4c5c;
|
||||
padding-top: 25px;
|
||||
padding-top: 15px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="menu-title">
|
||||
智能推荐
|
||||
快捷检索
|
||||
</div>
|
||||
<div class="menu-content">
|
||||
<el-tabs type="border-card">
|
||||
<el-tab-pane label="人物推荐">
|
||||
<el-tab-pane label="相似人物推荐">
|
||||
<div>
|
||||
<el-select
|
||||
style="width: 100%;"
|
||||
@@ -27,13 +27,13 @@
|
||||
</div>
|
||||
<div class="line-item" v-for="item in recommendByUserList" :key="item.id">
|
||||
<div class="title-time">
|
||||
<div>{{ item.fid }}</div>
|
||||
<div>{{ item.createTime }}</div>
|
||||
</div>
|
||||
<div class="description">{{ item.description }}</div>
|
||||
<div class="labels">
|
||||
<el-tag v-for="la in item.labelArr">{{la}}</el-tag>
|
||||
<div>{{ item }}</div>
|
||||
<div></div>
|
||||
</div>
|
||||
<!-- <div class="description">{{ item.Comment }}</div>-->
|
||||
<!-- <div class="labels" v-if="item.Labels">-->
|
||||
<!-- <el-tag v-for="(la,index) in item.Labels" :key="index">{{ la }}</el-tag>-->
|
||||
<!-- </div>-->
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="分类推荐">
|
||||
@@ -63,7 +63,7 @@
|
||||
</div>
|
||||
<div class="description">{{ item.Comment }}</div>
|
||||
<div class="labels">
|
||||
<el-tag v-for="la in item.Labels">{{la}}</el-tag>
|
||||
<el-tag v-for="(la,index) in item.Labels" :key="index">{{ la }}</el-tag>
|
||||
</div>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
@@ -120,11 +120,6 @@ export default {
|
||||
category: _this.selectCategory
|
||||
}
|
||||
}).then(res => {
|
||||
res.data.forEach(row => {
|
||||
if(row.labels) {
|
||||
row.labelArr = row.labels.split(',');
|
||||
}
|
||||
});
|
||||
this.recommendByCategoryList = res.data;
|
||||
});
|
||||
},
|
||||
@@ -153,11 +148,6 @@ export default {
|
||||
userId: _this.selectUserId
|
||||
}
|
||||
}).then(res => {
|
||||
res.data.forEach(row => {
|
||||
if(row.labels) {
|
||||
row.labelArr = row.labels.split(',');
|
||||
}
|
||||
});
|
||||
this.recommendByUserList = res.data;
|
||||
});
|
||||
}
|
||||
@@ -173,7 +163,7 @@ export default {
|
||||
border-bottom: 1px solid #dee0e2;
|
||||
padding-bottom: 10px;
|
||||
|
||||
.title-time{
|
||||
.title-time {
|
||||
display: flex;
|
||||
|
||||
div:first-child {
|
||||
|
||||
@@ -6,40 +6,56 @@
|
||||
<div class="menu-content">
|
||||
<div>
|
||||
<el-form :inline="true" :model="qo" class="demo-form-inline">
|
||||
<el-form-item>
|
||||
<el-input v-model="qo.LIKES_fid" placeholder="请输入Fid"></el-input>
|
||||
<el-form-item label="唯一标识:">
|
||||
<el-input v-model="qo.LIKES_fid" placeholder="请输入唯一标识" clearable style="width: 300px"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="el-icon-search" @click="qo.pageNo=1;queryData()">搜 索</el-button>
|
||||
<el-button type="primary" icon="el-icon-search" @click="queryDataById()">搜 索</el-button>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="queryData(-1)">上一页</el-button>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="queryData(1)">下一页</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<div style="margin: 0px 0 20px 0">
|
||||
<el-button type="primary" @click="createRow()">添加</el-button>
|
||||
<!-- <el-button type="primary" @click="createRow()" icon="el-icon-plus">添 加</el-button>-->
|
||||
<el-button type="primary" @click="downloadUser()" icon="el-icon-download">导出用户</el-button>
|
||||
<el-button type="primary" @click="showImportUserPage()" icon="el-icon-upload2">导入用户</el-button>
|
||||
</div>
|
||||
<div>
|
||||
<el-table :data="result.records" style="width: 100%">
|
||||
<el-table :data="result.records" style="width: 100%" v-loading="loading">
|
||||
<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="labels" label="标签">
|
||||
<el-table-column prop="UserId" label="唯一标识"></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 v-if="scope.row.Labels">
|
||||
<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>
|
||||
</template>
|
||||
<el-tag v-if="scope.row.labelsArr.length > 5">...</el-tag>
|
||||
</div>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="180">
|
||||
<el-table-column label="操作" width="240">
|
||||
<template slot-scope="scope">
|
||||
<el-button @click.native.prevent="feedbackHistory(scope.row)" type="text" size="small">
|
||||
反馈历史
|
||||
</el-button>
|
||||
<el-button @click.native.prevent="linkUser(scope.row)" type="text" size="small">
|
||||
关注用户
|
||||
</el-button>
|
||||
<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>
|
||||
<!-- <el-button @click.native.prevent="modifyRow(scope.row)" type="text" size="small">-->
|
||||
<!-- 编辑-->
|
||||
<!-- </el-button>-->
|
||||
<el-button @click.native.prevent="removeRow(scope.row)" type="text" size="small">
|
||||
删除
|
||||
</el-button>
|
||||
@@ -47,15 +63,6 @@
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<div class="page-box">
|
||||
<el-pagination background
|
||||
@current-change="handleCurrentChange"
|
||||
:current-page="qo.pageNo"
|
||||
:page-size="qo.pageSize"
|
||||
layout="total, prev, pager, next"
|
||||
:total="result.total">
|
||||
</el-pagination>
|
||||
</div>
|
||||
</div>
|
||||
<el-dialog
|
||||
:title="dialogName"
|
||||
@@ -75,9 +82,10 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import request from '@/utils/request';
|
||||
import request, {getBaseUrl} from '@/utils/request';
|
||||
|
||||
var _this;
|
||||
var _index = 0;
|
||||
export default {
|
||||
name: "userManage",
|
||||
data() {
|
||||
@@ -91,6 +99,8 @@ export default {
|
||||
records: [],
|
||||
total: 0
|
||||
},
|
||||
loading: false,
|
||||
cursorArr: [''], // 分页游标
|
||||
dialogName: '编辑',
|
||||
cmdDialogVisible: false,
|
||||
cmd: {},
|
||||
@@ -107,30 +117,71 @@ export default {
|
||||
if (_qo) {
|
||||
_this.qo = JSON.parse(_qo);
|
||||
}
|
||||
_this.queryData();
|
||||
_this.queryData(0);
|
||||
},
|
||||
methods: {
|
||||
queryData() {
|
||||
request({
|
||||
url: '/risk-user/query_pages',
|
||||
method: 'post',
|
||||
data: _this.qo
|
||||
}).then(res => {
|
||||
res.data.records.forEach(row => {
|
||||
row.labelsArr = row.labels ? row.labels.split(',') : [];
|
||||
queryDataById() {
|
||||
if (this.qo.LIKES_fid.length > 0) {
|
||||
this.loading = true;
|
||||
request({
|
||||
url: '/gorse/query_user/' + this.qo.LIKES_fid,
|
||||
method: 'get',
|
||||
}).then(res => {
|
||||
let user = res.data;
|
||||
if (!user) {
|
||||
_this.result.records = [];
|
||||
} else {
|
||||
_this.result.records = [user];
|
||||
}
|
||||
|
||||
this.loading = false;
|
||||
});
|
||||
_this.result.records = res.data.records;
|
||||
_this.result.total = res.data.total;
|
||||
} else {
|
||||
this.cursorArr = [''];
|
||||
this.queryData(1);
|
||||
}
|
||||
},
|
||||
queryData(index) { // index -1 上一页,0刷新, 1下一页
|
||||
this.loading = true;
|
||||
this.cursorArr = this.cursorArr.slice(0, this.cursorArr.length - 1 + index);
|
||||
this.cursorArr = this.cursorArr.length === 0 ? [''] : this.cursorArr;
|
||||
request({
|
||||
url: '/gorse/query_users?cursor=' + this.cursorArr[this.cursorArr.length - 1],
|
||||
method: 'get',
|
||||
}).then(res => {
|
||||
this.cursorArr.push(res.data.Cursor);
|
||||
_this.result.records = res.data.Users;
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
handleCurrentChange(val) {
|
||||
_this.qo.pageNo = val;
|
||||
_this.queryData();
|
||||
showImportUserPage() {
|
||||
_this.$router.push({
|
||||
path: "importUser"
|
||||
});
|
||||
},
|
||||
downloadUser() {
|
||||
window.open(getBaseUrl() + '/bulk/get_bulk/users');
|
||||
},
|
||||
feedbackHistory(item) {
|
||||
_this.$router.push({
|
||||
path: "feedbackHistory", query: {
|
||||
userId: item.UserId,
|
||||
cursorArr: JSON.stringify(_this.cursorArr)
|
||||
}
|
||||
});
|
||||
},
|
||||
linkUser(item) {
|
||||
_this.$router.push({
|
||||
path: "linkUser", query: {
|
||||
userId: item.UserId,
|
||||
qo: JSON.stringify(_this.qo)
|
||||
}
|
||||
});
|
||||
},
|
||||
similarUser(item) {
|
||||
_this.$router.push({
|
||||
path: "similarUser", query: {
|
||||
userId: item.fid,
|
||||
userId: item.UserId,
|
||||
qo: JSON.stringify(_this.qo)
|
||||
}
|
||||
});
|
||||
@@ -138,7 +189,7 @@ export default {
|
||||
recommendItem(item) {
|
||||
_this.$router.push({
|
||||
path: "recommendItem", query: {
|
||||
userId: item.fid,
|
||||
userId: item.UserId,
|
||||
qo: JSON.stringify(_this.qo)
|
||||
}
|
||||
});
|
||||
@@ -150,11 +201,11 @@ export default {
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
request({
|
||||
url: '/risk-user/remove/' + item.id,
|
||||
url: '/gorse/delete_user/' + item.UserId,
|
||||
method: 'post'
|
||||
}).then(res => {
|
||||
_this.$message.success("删除成功");
|
||||
_this.queryData();
|
||||
_this.queryData(0);
|
||||
});
|
||||
}).catch(() => {
|
||||
});
|
||||
@@ -187,7 +238,7 @@ export default {
|
||||
data: _this.cmd
|
||||
}).then(res => {
|
||||
_this.$message.success("编辑成功");
|
||||
_this.queryData();
|
||||
_this.queryData(0);
|
||||
_this.cmdDialogVisible = false;
|
||||
});
|
||||
} else { // 新建
|
||||
|
||||
263
web/src/components/menus/feedback/ImportFeedback.vue
Normal file
@@ -0,0 +1,263 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="menu-title">
|
||||
导入反馈
|
||||
<div class="icon icon-back" @click="backBtn">
|
||||
<i title="返回"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="block_box" style="margin-top: 20px;padding: 20px">
|
||||
<el-form ref="cmd" label-width="100px" :rules="rules" :model="cmd" :inline="true">
|
||||
<el-form-item label="文件" prop="file">
|
||||
<el-upload
|
||||
class="upload-demo"
|
||||
action="#"
|
||||
:auto-upload="false"
|
||||
accept=".csv"
|
||||
:on-change="handleFileChange"
|
||||
:limit="1"
|
||||
:show-file-list="false">
|
||||
<el-button size="small" type="primary">点击上传</el-button>
|
||||
<div slot="tip" class="el-upload__tip">只能上传csv文件</div>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
<br/>
|
||||
<el-form-item label="字段分隔符" prop="field">
|
||||
<el-input v-model="cmd.field" placeholder="请输入字段分隔符" style="width: 300px"
|
||||
@change="handleFieldChange"></el-input>
|
||||
</el-form-item>
|
||||
<br/>
|
||||
<el-form-item label="反馈类型" prop="labels">
|
||||
<el-select v-model="cmd.feedbackType" style="width: 300px" @change="refreshList">
|
||||
<template v-if="cmd.ifFirstHead">
|
||||
<el-option :value="index" :label="item" v-for="(item,index) in columnList" :key="index"></el-option>
|
||||
</template>
|
||||
<template v-if="!cmd.ifFirstHead">
|
||||
<el-option :value="index" :label="index" v-for="(item,index) in columnList" :key="index"></el-option>
|
||||
</template>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="用户ID" prop="labels">
|
||||
<el-select v-model="cmd.userId" style="width: 300px" @change="refreshList">
|
||||
<template v-if="cmd.ifFirstHead">
|
||||
<el-option :value="index" :label="item" v-for="(item,index) in columnList" :key="index"></el-option>
|
||||
</template>
|
||||
<template v-if="!cmd.ifFirstHead">
|
||||
<el-option :value="index" :label="index" v-for="(item,index) in columnList" :key="index"></el-option>
|
||||
</template>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<br/>
|
||||
<el-form-item label="物类ID" prop="labels">
|
||||
<el-select v-model="cmd.itemId" style="width: 300px" @change="refreshList">
|
||||
<template v-if="cmd.ifFirstHead">
|
||||
<el-option :value="index" :label="item" v-for="(item,index) in columnList" :key="index"></el-option>
|
||||
</template>
|
||||
<template v-if="!cmd.ifFirstHead">
|
||||
<el-option :value="index" :label="index" v-for="(item,index) in columnList" :key="index"></el-option>
|
||||
</template>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="日期">
|
||||
<el-select v-model="cmd.timestamp" style="width: 300px" @change="refreshList">
|
||||
<template v-if="cmd.ifFirstHead">
|
||||
<el-option :value="index" :label="item" v-for="(item,index) in columnList" :key="index"></el-option>
|
||||
</template>
|
||||
<template v-if="!cmd.ifFirstHead">
|
||||
<el-option :value="index" :label="index" v-for="(item,index) in columnList" :key="index"></el-option>
|
||||
</template>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<br/>
|
||||
<el-form-item label=" ">
|
||||
<el-checkbox label="第一行为表头" v-model="cmd.ifFirstHead" @change="refreshList"></el-checkbox>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-table :data="list" style="width: 100%" height="400" v-show="list.length > 0">
|
||||
<el-table-column type="index" label="行号" width="60"></el-table-column>
|
||||
<el-table-column prop="feedbackType" :label="'反馈类型('+(cmd.ifFirstHead ? columnList[cmd.feedbackType] : cmd.feedbackType)+')'"></el-table-column>
|
||||
<el-table-column prop="userId" :label="'用户ID('+(cmd.ifFirstHead ? columnList[cmd.userId] : cmd.userId)+')'"></el-table-column>
|
||||
<el-table-column prop="itemId" :label="'物类ID('+(cmd.ifFirstHead ? columnList[cmd.itemId] : cmd.itemId)+')'"></el-table-column>
|
||||
<el-table-column prop="timestamp"
|
||||
:label="'日期('+(cmd.ifFirstHead ? columnList[cmd.timestamp] : cmd.timestamp)+')'"></el-table-column>
|
||||
</el-table>
|
||||
<el-button type="primary" class="submit-btn" @click="confirmSubmit" :disabled="list.length === 0">确认提交
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import request from '@/utils/request';
|
||||
|
||||
var _this;
|
||||
export default {
|
||||
name: "ImportUser",
|
||||
data() {
|
||||
return {
|
||||
config: /* Papa Parse config object */ {
|
||||
delimiter: "", // auto-detect
|
||||
newline: "", // auto-detect
|
||||
quoteChar: '"',
|
||||
escapeChar: '"',
|
||||
header: true,
|
||||
dynamicTyping: true,
|
||||
preview: 0,
|
||||
encoding: "",
|
||||
delimitersToGuess: [',']
|
||||
// ?? callback function ??
|
||||
},
|
||||
cmd: {
|
||||
field: ',',
|
||||
userId: '',
|
||||
itemId: '',
|
||||
timestamp: '',
|
||||
feedbackType: '',
|
||||
ifFirstHead: true
|
||||
},
|
||||
file: [],
|
||||
originList: [], // 原始的可能包含表头的数据,默认存储最多21行(如果数据不止21行的话)
|
||||
list: [], // 页面table显示的数据
|
||||
columnList: [],// 上传csv的表头
|
||||
rules: {
|
||||
fid: [
|
||||
{required: true, message: '请选择文件'}
|
||||
],
|
||||
field: [
|
||||
{required: true, message: '字段分隔符不能为空'}
|
||||
],
|
||||
categories: [
|
||||
{required: true, message: '类别分隔符不能为空'}
|
||||
],
|
||||
},
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
_this = this;
|
||||
},
|
||||
methods: {
|
||||
handleFileChange(file, fileList) {
|
||||
_this.file = file.raw;
|
||||
if(_this.cmd.field.length > 0) {
|
||||
_this.handleFieldChange();
|
||||
}
|
||||
},
|
||||
handleFieldChange() {
|
||||
this.$papa.parse(_this.file, {
|
||||
delimiter: _this.cmd.field,
|
||||
complete: (results) => {
|
||||
_this.originList = results.data.slice(0, 21);
|
||||
// 提前填充一个默认的值给对应的ID列和标签列
|
||||
_this.prepareFieldAndLabels();
|
||||
_this.refreshList();
|
||||
}
|
||||
})
|
||||
},
|
||||
prepareFieldAndLabels() {
|
||||
_this.columnList = _this.originList[0];
|
||||
_this.cmd.feedbackType = 0;
|
||||
_this.cmd.userId = 1;
|
||||
_this.cmd.itemId = 2;
|
||||
_this.cmd.timestamp = 3;
|
||||
},
|
||||
refreshList() {
|
||||
// 处理原始数据,将行文本截取成数组放入list
|
||||
_this.list = [];
|
||||
if (_this.cmd.field.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (let i in _this.originList) {
|
||||
if (_this.cmd.ifFirstHead && i == 0) {
|
||||
// 第一行是表头,跳过list塞入
|
||||
continue;
|
||||
}
|
||||
let row = _this.originList[i];
|
||||
let errorFlag = false;
|
||||
|
||||
_this.list.push({
|
||||
userId: row[_this.cmd.userId],
|
||||
itemId: row[_this.cmd.itemId],
|
||||
feedbackType: row[_this.cmd.feedbackType],
|
||||
timestamp: row[_this.cmd.timestamp],
|
||||
});
|
||||
}
|
||||
},
|
||||
confirmSubmit() { // 提交确认
|
||||
this.$refs.cmd.validate((valid) => {
|
||||
let formData = new FormData();
|
||||
formData.append("sep", _this.cmd.field);
|
||||
formData.append("has-header", _this.cmd.ifFirstHead);
|
||||
formData.append("file", _this.file);
|
||||
let userIdIndex = _this.cmd.userId;
|
||||
let itemIdIndex = _this.cmd.itemId;
|
||||
let feedbackTypeIndex = _this.cmd.feedbackType;
|
||||
let timestampIndex = _this.cmd.timestamp;
|
||||
let _format = '';
|
||||
for (let i = 0; i <= Math.max(userIdIndex, itemIdIndex, feedbackTypeIndex, timestampIndex); i++) {
|
||||
if (i == userIdIndex) {
|
||||
_format += "u";
|
||||
} else if (i == itemIdIndex) {
|
||||
_format += "i";
|
||||
} else if (i == timestampIndex) {
|
||||
_format += "t";
|
||||
} else if (i == feedbackTypeIndex) {
|
||||
_format += "f";
|
||||
} else {
|
||||
_format += "_";
|
||||
}
|
||||
}
|
||||
formData.append("format", _format);
|
||||
request({
|
||||
url: '/gorse/bulk/feedback',
|
||||
method: 'put',
|
||||
data: formData
|
||||
}).then(res => {
|
||||
if(res.data && res.data.RowAffected) {
|
||||
_this.$message.success(`成功导入${res.data.RowAffected}条记录`);
|
||||
} else {
|
||||
_this.$message.warning("导入异常");
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
backBtn() {
|
||||
this.$router.push({
|
||||
path: "feedbackType", query: {
|
||||
qo: JSON.stringify({
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
LIKES_fid: '',
|
||||
})
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
}
|
||||
}
|
||||
</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;
|
||||
|
||||
}
|
||||
|
||||
.submit-btn {
|
||||
margin-left: auto;
|
||||
margin-top: 20px;
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
148
web/src/components/menus/item/FeedbackHistory.vue
Normal file
@@ -0,0 +1,148 @@
|
||||
<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">
|
||||
<div class="line-item-box">
|
||||
<div class="line-item" v-for="(item,index) in list" :key="index">
|
||||
<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: {},
|
||||
list: []
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
_this = this;
|
||||
_this.qo = _this.$route.query.qo;
|
||||
_this.gorseQo.userId = _this.$route.query.userId;
|
||||
_this.getFeedbackList();
|
||||
},
|
||||
methods: {
|
||||
getFeedbackList() {
|
||||
request({
|
||||
url: '/gorse/get_feedback_list/' + _this.gorseQo.userId + "/like",
|
||||
method: 'get'
|
||||
}).then(res => {
|
||||
res.data.forEach(row => {
|
||||
row.Labels = row.Item.Labels;
|
||||
row.ItemId = row.Item.ItemId;
|
||||
row.Comment = row.Item.Comment;
|
||||
if(_this.list.length < 20) {
|
||||
_this.list.push(row);
|
||||
}
|
||||
});
|
||||
});
|
||||
request({
|
||||
url: '/gorse/get_feedback_list/' + _this.gorseQo.userId + "/star",
|
||||
method: 'get'
|
||||
}).then(res => {
|
||||
res.data.forEach(row => {
|
||||
row.Labels = row.Item.Labels;
|
||||
row.ItemId = row.Item.ItemId;
|
||||
row.Comment = row.Item.Comment;
|
||||
if(_this.list.length < 20) {
|
||||
_this.list.push(row);
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
backBtn() {
|
||||
_this.$router.back();
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style src="../../../css/back.css" scoped></style>
|
||||
<style scoped lang="scss">
|
||||
|
||||
.block_box {
|
||||
margin: 25px 25px 0 25px;
|
||||
background: #FFFFFF;
|
||||
border-radius: 3px;
|
||||
height: calc(100% - 120px);
|
||||
|
||||
.title {
|
||||
border-bottom: 1px solid #ccc;
|
||||
padding: 15px 25px;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.demo-form-inline {
|
||||
padding: 25px 25px 0 25px;
|
||||
}
|
||||
|
||||
.line-item-box {
|
||||
height: calc(100% - 40px);
|
||||
overflow-y: auto;
|
||||
width: 100%;
|
||||
|
||||
.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>
|
||||
321
web/src/components/menus/item/ImportItem.vue
Normal file
@@ -0,0 +1,321 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="menu-title">
|
||||
导入条目
|
||||
<div class="icon icon-back" @click="backBtn">
|
||||
<i title="返回"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="block_box" style="margin-top: 20px;padding: 20px">
|
||||
<el-form ref="cmd" label-width="100px" :rules="rules" :model="cmd" :inline="true">
|
||||
<el-form-item label="文件" prop="file">
|
||||
<el-upload
|
||||
class="upload-demo"
|
||||
action="#"
|
||||
:auto-upload="false"
|
||||
accept=".csv"
|
||||
:on-change="handleFileChange"
|
||||
:limit="1"
|
||||
:show-file-list="false">
|
||||
<el-button size="small" type="primary">点击上传</el-button>
|
||||
<div slot="tip" class="el-upload__tip">只能上传csv文件</div>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
<br/>
|
||||
<el-form-item label="字段分隔符" prop="field">
|
||||
<el-input v-model="cmd.field" placeholder="请输入字段分隔符" style="width: 300px"
|
||||
@change="handleFieldChange"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="类别分隔符" prop="categories">
|
||||
<el-input v-model="cmd.categories" placeholder="请输入类别分隔符" style="width: 300px"></el-input>
|
||||
</el-form-item>
|
||||
<br/>
|
||||
<el-form-item label="唯一ID" prop="id">
|
||||
<el-select v-model="cmd.id" style="width: 300px" @change="refreshList">
|
||||
<template v-if="cmd.ifFirstHead">
|
||||
<el-option :value="index" :label="item" v-for="(item,index) in columnList" :key="index"></el-option>
|
||||
</template>
|
||||
<template v-if="!cmd.ifFirstHead">
|
||||
<el-option :value="index" :label="index" v-for="(item,index) in columnList" :key="index"></el-option>
|
||||
</template>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="是否隐藏" prop="labels">
|
||||
<el-select v-model="cmd.hidden" style="width: 300px" @change="refreshList">
|
||||
<template v-if="cmd.ifFirstHead">
|
||||
<el-option :value="index" :label="item" v-for="(item,index) in columnList" :key="index"></el-option>
|
||||
</template>
|
||||
<template v-if="!cmd.ifFirstHead">
|
||||
<el-option :value="index" :label="index" v-for="(item,index) in columnList" :key="index"></el-option>
|
||||
</template>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="类别" prop="labels">
|
||||
<el-select v-model="cmd.categoriesColumn" style="width: 300px" @change="refreshList">
|
||||
<template v-if="cmd.ifFirstHead">
|
||||
<el-option :value="index" :label="item" v-for="(item,index) in columnList" :key="index"></el-option>
|
||||
</template>
|
||||
<template v-if="!cmd.ifFirstHead">
|
||||
<el-option :value="index" :label="index" v-for="(item,index) in columnList" :key="index"></el-option>
|
||||
</template>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="日期" prop="labels">
|
||||
<el-select v-model="cmd.timestamp" style="width: 300px" @change="refreshList">
|
||||
<template v-if="cmd.ifFirstHead">
|
||||
<el-option :value="index" :label="item" v-for="(item,index) in columnList" :key="index"></el-option>
|
||||
</template>
|
||||
<template v-if="!cmd.ifFirstHead">
|
||||
<el-option :value="index" :label="index" v-for="(item,index) in columnList" :key="index"></el-option>
|
||||
</template>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="标签" prop="labels">
|
||||
<el-select v-model="cmd.labels" style="width: 300px" @change="refreshList">
|
||||
<template v-if="cmd.ifFirstHead">
|
||||
<el-option :value="index" :label="item" v-for="(item,index) in columnList" :key="index"></el-option>
|
||||
</template>
|
||||
<template v-if="!cmd.ifFirstHead">
|
||||
<el-option :value="index" :label="index" v-for="(item,index) in columnList" :key="index"></el-option>
|
||||
</template>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="描述" prop="labels">
|
||||
<el-select v-model="cmd.description" style="width: 300px" @change="refreshList">
|
||||
<template v-if="cmd.ifFirstHead">
|
||||
<el-option :value="index" :label="item" v-for="(item,index) in columnList" :key="index"></el-option>
|
||||
</template>
|
||||
<template v-if="!cmd.ifFirstHead">
|
||||
<el-option :value="index" :label="index" v-for="(item,index) in columnList" :key="index"></el-option>
|
||||
</template>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<br/>
|
||||
<el-form-item label=" ">
|
||||
<el-checkbox label="第一行为表头" v-model="cmd.ifFirstHead" @change="refreshList"></el-checkbox>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-table :data="list" style="width: 100%" height="400" v-show="list.length > 0">
|
||||
<el-table-column type="index" label="行号" width="60"></el-table-column>
|
||||
<el-table-column prop="id" :label="'ID('+(cmd.ifFirstHead ? columnList[cmd.id] : cmd.id)+')'"></el-table-column>
|
||||
<el-table-column prop="hidden"
|
||||
:label="'是否隐藏('+(cmd.ifFirstHead ? columnList[cmd.hidden] : cmd.hidden)+')'"></el-table-column>
|
||||
<el-table-column prop="categoriesColumn"
|
||||
:label="'类别('+(cmd.ifFirstHead ? columnList[cmd.categoriesColumn] : cmd.categoriesColumn)+')'">
|
||||
<template v-slot="scope">
|
||||
<el-tag v-for="item in scope.row.categoriesColumn" :key="item" v-show="item.length > 0">{{ item }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="timestamp"
|
||||
:label="'日期('+(cmd.ifFirstHead ? columnList[cmd.timestamp] : cmd.timestamp)+')'"></el-table-column>
|
||||
<el-table-column prop="labels" :label="'标签('+(cmd.ifFirstHead ? columnList[cmd.labels] : cmd.labels)+')'">
|
||||
<template v-slot="scope">
|
||||
<label style="color: red" v-if="scope.row.errorFlag">JSON格式化异常</label>
|
||||
<label v-if="!scope.row.errorFlag">{{ scope.row.labels }}</label>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="description"
|
||||
:label="'描述('+(cmd.ifFirstHead ? columnList[cmd.description] : cmd.description)+')'"></el-table-column>
|
||||
</el-table>
|
||||
<el-button type="primary" class="submit-btn" @click="confirmSubmit" :disabled="list.length === 0">确认提交
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import request from '@/utils/request';
|
||||
|
||||
var _this;
|
||||
export default {
|
||||
name: "ImportUser",
|
||||
data() {
|
||||
return {
|
||||
config: /* Papa Parse config object */ {
|
||||
delimiter: "", // auto-detect
|
||||
newline: "", // auto-detect
|
||||
quoteChar: '"',
|
||||
escapeChar: '"',
|
||||
header: true,
|
||||
dynamicTyping: true,
|
||||
preview: 0,
|
||||
encoding: "",
|
||||
delimitersToGuess: [',']
|
||||
// ?? callback function ??
|
||||
},
|
||||
cmd: {
|
||||
field: ',',
|
||||
categories: '|',
|
||||
id: '',
|
||||
hidden: '',
|
||||
timestamp: '',
|
||||
categoriesColumn: '',
|
||||
description: '',
|
||||
labels: '',
|
||||
ifFirstHead: true
|
||||
},
|
||||
file: [],
|
||||
originList: [], // 原始的可能包含表头的数据,默认存储最多21行(如果数据不止21行的话)
|
||||
list: [], // 页面table显示的数据
|
||||
columnList: [],// 上传csv的表头
|
||||
rules: {
|
||||
fid: [
|
||||
{required: true, message: '请选择文件'}
|
||||
],
|
||||
field: [
|
||||
{required: true, message: '字段分隔符不能为空'}
|
||||
],
|
||||
categories: [
|
||||
{required: true, message: '类别分隔符不能为空'}
|
||||
],
|
||||
},
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
_this = this;
|
||||
},
|
||||
methods: {
|
||||
handleFileChange(file, fileList) {
|
||||
_this.file = file.raw;
|
||||
if(_this.cmd.field.length > 0) {
|
||||
_this.handleFieldChange();
|
||||
}
|
||||
},
|
||||
handleFieldChange() {
|
||||
this.$papa.parse(_this.file, {
|
||||
delimiter: _this.cmd.field,
|
||||
complete: (results) => {
|
||||
_this.originList = results.data.slice(0, 21);
|
||||
// 提前填充一个默认的值给对应的ID列和标签列
|
||||
_this.prepareFieldAndLabels();
|
||||
_this.refreshList();
|
||||
}
|
||||
})
|
||||
},
|
||||
prepareFieldAndLabels() {
|
||||
_this.columnList = _this.originList[0];
|
||||
_this.cmd.id = 0;
|
||||
_this.cmd.hidden = 1;
|
||||
_this.cmd.categoriesColumn = 2;
|
||||
_this.cmd.timestamp = 3;
|
||||
_this.cmd.labels = 4;
|
||||
_this.cmd.description = 5;
|
||||
},
|
||||
refreshList() {
|
||||
// 处理原始数据,将行文本截取成数组放入list
|
||||
_this.list = [];
|
||||
if (_this.cmd.field.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (let i in _this.originList) {
|
||||
if (_this.cmd.ifFirstHead && i == 0) {
|
||||
// 第一行是表头,跳过list塞入
|
||||
continue;
|
||||
}
|
||||
let row = _this.originList[i];
|
||||
let errorFlag = false;
|
||||
|
||||
let _labels = row[_this.cmd.labels].replaceAll('""', "'");
|
||||
try {
|
||||
JSON.parse(_labels);
|
||||
} catch (e) {
|
||||
errorFlag = true;
|
||||
}
|
||||
let categoriesArr = row[_this.cmd.categoriesColumn].split(_this.cmd.categories);
|
||||
_this.list.push({
|
||||
id: row[_this.cmd.id],
|
||||
labels: _labels,
|
||||
hidden: row[_this.cmd.hidden],
|
||||
categoriesColumn: categoriesArr,
|
||||
timestamp: row[_this.cmd.timestamp],
|
||||
description: row[_this.cmd.description],
|
||||
errorFlag: errorFlag
|
||||
});
|
||||
}
|
||||
},
|
||||
confirmSubmit() { // 提交确认
|
||||
this.$refs.cmd.validate((valid) => {
|
||||
let formData = new FormData();
|
||||
formData.append("sep", _this.cmd.field);
|
||||
formData.append("has-header", _this.cmd.ifFirstHead);
|
||||
formData.append("label-sep", _this.cmd.categories);
|
||||
formData.append("file", _this.file);
|
||||
let idIndex = _this.cmd.id;
|
||||
let labelIndex = _this.cmd.labels;
|
||||
let hiddenIndex = _this.cmd.hidden;
|
||||
let categoriesColumnIndex = _this.cmd.categoriesColumn;
|
||||
let timestampIndex = _this.cmd.timestamp;
|
||||
let descriptionIndex = _this.cmd.description;
|
||||
let _format = '';
|
||||
for (let i = 0; i <= Math.max(idIndex, labelIndex, hiddenIndex, categoriesColumnIndex, timestampIndex, descriptionIndex); i++) {
|
||||
if (i == idIndex) {
|
||||
_format += "i";
|
||||
} else if (i == hiddenIndex) {
|
||||
_format += "h";
|
||||
} else if (i == categoriesColumnIndex) {
|
||||
_format += "c";
|
||||
} else if (i == timestampIndex) {
|
||||
_format += "t";
|
||||
} else if (i == labelIndex) {
|
||||
_format += "l";
|
||||
} else if (i == descriptionIndex) {
|
||||
_format += "d";
|
||||
} else {
|
||||
_format += "_";
|
||||
}
|
||||
}
|
||||
formData.append("format", _format);
|
||||
request({
|
||||
url: '/gorse/bulk/items',
|
||||
method: 'put',
|
||||
data: formData
|
||||
}).then(res => {
|
||||
if(res.data && res.data.RowAffected) {
|
||||
_this.$message.success(`成功导入${res.data.RowAffected}条记录`);
|
||||
} else {
|
||||
_this.$message.warning("导入异常");
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
backBtn() {
|
||||
this.$router.push({
|
||||
path: "entrysManage", query: {
|
||||
qo: JSON.stringify({
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
LIKES_fid: '',
|
||||
})
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
}
|
||||
}
|
||||
</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;
|
||||
|
||||
}
|
||||
|
||||
.submit-btn {
|
||||
margin-left: auto;
|
||||
margin-top: 20px;
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,13 +1,12 @@
|
||||
<template>
|
||||
<div style="height: 100%">
|
||||
<div class="menu-title">
|
||||
洞悉({{ gorseQo.userId }})
|
||||
查看推荐({{ 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>
|
||||
<div class="block_box">
|
||||
<el-form :inline="true" class="demo-form-inline">
|
||||
<el-form-item>
|
||||
<el-select v-model="gorseQo.recommendation" @change="getRecommendItem">
|
||||
@@ -15,7 +14,7 @@
|
||||
v-for="item in recommendList"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="categories">
|
||||
<el-form-item label="种类">
|
||||
<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"
|
||||
@@ -31,7 +30,7 @@
|
||||
</div>
|
||||
<div class="description">{{ item.Comment }}</div>
|
||||
<div class="labels">
|
||||
<el-tag v-for="la in item.Labels">{{ la }}</el-tag>
|
||||
<el-tag v-for="(la,index) in item.Labels" :key="index">{{ la }}</el-tag>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -57,19 +56,19 @@ export default {
|
||||
user: {},
|
||||
categoryList: [],
|
||||
recommendList: [{
|
||||
label: 'Recommendation',
|
||||
label: '默认推荐',
|
||||
value: '_'
|
||||
}, {
|
||||
label: 'Offline Recommendation',
|
||||
label: '离线推荐',
|
||||
value: 'offline'
|
||||
}, {
|
||||
label: 'Collaborative Recommendation',
|
||||
label: '协同推荐',
|
||||
value: 'collaborative'
|
||||
}, {
|
||||
label: 'Item-based Recommendation',
|
||||
label: '基于物品推荐',
|
||||
value: 'item_based'
|
||||
}, {
|
||||
label: 'User-based Recommendation',
|
||||
label: '基于用户推荐',
|
||||
value: 'user_based'
|
||||
}],
|
||||
list: []
|
||||
@@ -105,11 +104,7 @@ export default {
|
||||
});
|
||||
},
|
||||
backBtn() {
|
||||
this.$router.push({
|
||||
path: "userManage", query: {
|
||||
qo: _this.qo
|
||||
}
|
||||
});
|
||||
_this.$router.back();
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -118,10 +113,10 @@ export default {
|
||||
<style scoped lang="scss">
|
||||
|
||||
.block_box {
|
||||
margin: 25px;
|
||||
margin: 25px 25px 0 25px;
|
||||
background: #FFFFFF;
|
||||
border-radius: 3px;
|
||||
height: calc(100% - 160px);
|
||||
height: calc(100% - 120px);
|
||||
|
||||
.title {
|
||||
border-bottom: 1px solid #ccc;
|
||||
@@ -135,7 +130,7 @@ export default {
|
||||
}
|
||||
|
||||
.line-item-box {
|
||||
height: calc(100% - 140px);
|
||||
height: calc(100% - 88px);
|
||||
overflow-y: auto;
|
||||
|
||||
.line-item {
|
||||
|
||||
@@ -6,23 +6,23 @@
|
||||
<i title="返回"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="block_box" style="margin-top: 0">
|
||||
<div class="block_box" style="margin-top: 20px">
|
||||
<div class="title">信息</div>
|
||||
<div >
|
||||
<div>
|
||||
<el-form label-width="50px">
|
||||
<el-form-item label="时间">{{ item.createTime }}</el-form-item>
|
||||
<el-form-item label="时间">{{ item.Timestamp }}</el-form-item>
|
||||
<el-form-item label="类别">
|
||||
<template v-for="(tag,index) in item.categoriesArr">
|
||||
<template v-for="(tag,index) in item.Categories">
|
||||
<el-tag :key="index">{{ tag }}</el-tag>
|
||||
</template>
|
||||
</el-form-item>
|
||||
<el-form-item label="标签">
|
||||
<template v-for="(tag,index) in item.labelsArr">
|
||||
<template v-for="(tag,index) in item.Labels">
|
||||
<el-tag :key="index">{{ tag }}</el-tag>
|
||||
</template>
|
||||
</el-form-item>
|
||||
<el-form-item label="描述">
|
||||
{{ item.description }}
|
||||
{{ item.Comment }}
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
@@ -44,18 +44,22 @@
|
||||
<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 v-if="scope.row.Categories">
|
||||
<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>
|
||||
</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 v-if="scope.row.Labels">
|
||||
<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>
|
||||
</template>
|
||||
<el-tag v-if="scope.row.Labels.length > 5">...</el-tag>
|
||||
</div>
|
||||
</el-table-column>
|
||||
<el-table-column prop="Comment" label="描述">
|
||||
@@ -63,7 +67,7 @@
|
||||
{{ scope.row.Comment.substring(0, 100) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="Score" label="Score" width="100">
|
||||
<el-table-column prop="Score" label="相似度 [0, 1]" width="100">
|
||||
<template slot-scope="scope">
|
||||
{{ scope.row.Score.toFixed(5) }}
|
||||
</template>
|
||||
@@ -114,14 +118,9 @@ export default {
|
||||
},
|
||||
queryItem() {
|
||||
request({
|
||||
url: '/entrys/query_unique',
|
||||
method: 'post',
|
||||
data: {
|
||||
EQS_fid: _this.gorseQo.itemId
|
||||
}
|
||||
url: '/gorse/get_item/' + _this.gorseQo.itemId,
|
||||
method: 'get',
|
||||
}).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;
|
||||
});
|
||||
},
|
||||
|
||||
228
web/src/components/menus/user/ImportUser.vue
Normal file
@@ -0,0 +1,228 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="menu-title">
|
||||
导入用户
|
||||
<div class="icon icon-back" @click="backBtn">
|
||||
<i title="返回"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="block_box" style="margin-top: 20px;padding: 20px">
|
||||
<el-form ref="cmd" label-width="100px" :rules="rules" :model="cmd" :inline="true">
|
||||
<el-form-item label="文件" prop="file">
|
||||
<el-upload
|
||||
class="upload-demo"
|
||||
action="#"
|
||||
:auto-upload="false"
|
||||
accept=".csv"
|
||||
:on-change="handleFileChange"
|
||||
:limit="1"
|
||||
:show-file-list="false">
|
||||
<el-button size="small" type="primary">点击上传</el-button>
|
||||
<div slot="tip" class="el-upload__tip">只能上传csv文件</div>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
<br/>
|
||||
<el-form-item label="字段分隔符" prop="field">
|
||||
<el-input v-model="cmd.field" placeholder="请输入字段分隔符" style="width: 300px"
|
||||
@change="handleFieldChange"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="类别分隔符" prop="categories">
|
||||
<el-input v-model="cmd.categories" placeholder="请输入类别分隔符" style="width: 300px"></el-input>
|
||||
</el-form-item>
|
||||
<br/>
|
||||
<el-form-item label="唯一ID" prop="id">
|
||||
<el-select v-model="cmd.id" style="width: 300px" @change="refreshList">
|
||||
<template v-if="cmd.ifFirstHead">
|
||||
<el-option :value="index" :label="item" v-for="(item,index) in columnList" :key="index"></el-option>
|
||||
</template>
|
||||
<template v-if="!cmd.ifFirstHead">
|
||||
<el-option :value="index" :label="index" v-for="(item,index) in columnList" :key="index"></el-option>
|
||||
</template>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="标签" prop="labels">
|
||||
<el-select v-model="cmd.labels" style="width: 300px" @change="refreshList">
|
||||
<template v-if="cmd.ifFirstHead">
|
||||
<el-option :value="index" :label="item" v-for="(item,index) in columnList" :key="index"></el-option>
|
||||
</template>
|
||||
<template v-if="!cmd.ifFirstHead">
|
||||
<el-option :value="index" :label="index" v-for="(item,index) in columnList" :key="index"></el-option>
|
||||
</template>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<br/>
|
||||
<el-form-item label=" ">
|
||||
<el-checkbox label="第一行为表头" v-model="cmd.ifFirstHead" @change="refreshList"></el-checkbox>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-table :data="list" style="width: 100%" height="400" v-show="list.length > 0">
|
||||
<el-table-column type="index" label="行号" width="60"></el-table-column>
|
||||
<el-table-column prop="id" :label="'ID('+(cmd.ifFirstHead ? columnList[cmd.id] : cmd.id)+')'"></el-table-column>
|
||||
<el-table-column prop="labels" :label="'标签('+(cmd.ifFirstHead ? columnList[cmd.labels] : cmd.labels)+')'">
|
||||
<template v-slot="scope">
|
||||
<label style="color: red" v-if="scope.row.errorFlag">JSON格式化异常</label>
|
||||
<label v-if="!scope.row.errorFlag">{{ scope.row.labels }}</label>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-button type="primary" class="submit-btn" @click="confirmSubmit" :disabled="list.length === 0">确认提交</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import request from '@/utils/request';
|
||||
|
||||
var _this;
|
||||
export default {
|
||||
name: "ImportUser",
|
||||
data() {
|
||||
return {
|
||||
cmd: {
|
||||
field: ',',
|
||||
categories: '|',
|
||||
id: '',
|
||||
labels: '',
|
||||
ifFirstHead: true
|
||||
},
|
||||
file: [],
|
||||
originList: [], // 原始的可能包含表头的数据,默认存储最多21行(如果数据不止21行的话)
|
||||
list: [], // 页面table显示的数据
|
||||
columnList: [],// 上传csv的表头
|
||||
rules: {
|
||||
fid: [
|
||||
{required: true, message: '请选择文件'}
|
||||
],
|
||||
field: [
|
||||
{required: true, message: '字段分隔符不能为空'}
|
||||
],
|
||||
categories: [
|
||||
{required: true, message: '类别分隔符不能为空'}
|
||||
],
|
||||
},
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
_this = this;
|
||||
},
|
||||
methods: {
|
||||
handleFileChange(file, fileList) {
|
||||
_this.file = file.raw;
|
||||
if(_this.cmd.field.length > 0) {
|
||||
_this.handleFieldChange();
|
||||
}
|
||||
},
|
||||
handleFieldChange() {
|
||||
this.$papa.parse(_this.file, {
|
||||
delimiter: _this.cmd.field,
|
||||
complete: (results) => {
|
||||
_this.originList = results.data.slice(0, 21);
|
||||
// 提前填充一个默认的值给对应的ID列和标签列
|
||||
_this.prepareFieldAndLabels();
|
||||
_this.refreshList();
|
||||
}
|
||||
})
|
||||
},
|
||||
prepareFieldAndLabels() {
|
||||
_this.columnList = _this.originList[0];
|
||||
_this.cmd.id = 0;
|
||||
_this.cmd.labels = 1;
|
||||
},
|
||||
refreshList() {
|
||||
// 处理原始数据,将行文本截取成数组放入list
|
||||
_this.list = [];
|
||||
if (_this.cmd.field.length === 0) {
|
||||
return;
|
||||
}
|
||||
for (let i in _this.originList) {
|
||||
if (_this.cmd.ifFirstHead && i == 0) {
|
||||
// 第一行是表头,跳过list塞入
|
||||
continue;
|
||||
}
|
||||
let row = _this.originList[i];
|
||||
let errorFlag = false;
|
||||
try {
|
||||
JSON.parse(row[_this.cmd.labels]);
|
||||
} catch (e) {
|
||||
errorFlag = true;
|
||||
}
|
||||
_this.list.push({
|
||||
id: row[_this.cmd.id],
|
||||
labels: row[_this.cmd.labels],
|
||||
errorFlag: errorFlag
|
||||
});
|
||||
}
|
||||
},
|
||||
confirmSubmit() { // 提交确认
|
||||
this.$refs.cmd.validate((valid) => {
|
||||
let formData = new FormData();
|
||||
formData.append("sep", _this.cmd.field);
|
||||
formData.append("has-header", _this.cmd.ifFirstHead);
|
||||
formData.append("label-sep", _this.cmd.categories);
|
||||
formData.append("file", _this.file);
|
||||
let idIndex = _this.cmd.id;
|
||||
let labelIndex = _this.cmd.labels;
|
||||
let _format = '';
|
||||
for (let i = 0; i <= Math.max(idIndex, labelIndex); i++) {
|
||||
if (i == idIndex) {
|
||||
_format += "u";
|
||||
} else if (i == labelIndex) {
|
||||
_format += "l";
|
||||
} else {
|
||||
_format += "_";
|
||||
}
|
||||
}
|
||||
formData.append("format", _format);
|
||||
request({
|
||||
url: '/gorse/bulk/users',
|
||||
method: 'put',
|
||||
data: formData
|
||||
}).then(res => {
|
||||
if(res.data && res.data.RowAffected) {
|
||||
_this.$message.success(`成功导入${res.data.RowAffected}条记录`);
|
||||
} else {
|
||||
_this.$message.warning("导入异常");
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
backBtn() {
|
||||
this.$router.push({
|
||||
path: "userManage", query: {
|
||||
qo: JSON.stringify({
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
LIKES_fid: '',
|
||||
})
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
}
|
||||
}
|
||||
</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;
|
||||
|
||||
}
|
||||
|
||||
.submit-btn {
|
||||
margin-left: auto;
|
||||
margin-top: 20px;
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
122
web/src/components/menus/user/LinkUser.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: 10px">
|
||||
<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">Association 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="vid" label="UserId"></el-table-column>
|
||||
<el-table-column label="操作" width="210">
|
||||
<template slot-scope="scope">
|
||||
<el-button @click.native.prevent="recommendItem(scope.row)" type="text" size="small">
|
||||
查看推荐
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import request from '@/utils/request';
|
||||
|
||||
var _this;
|
||||
export default {
|
||||
name: "linkUser",
|
||||
data() {
|
||||
return {
|
||||
qo: "",
|
||||
userId: '',
|
||||
user: {},
|
||||
list: []
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
_this = this;
|
||||
_this.qo = _this.$route.query.qo;
|
||||
_this.userId = _this.$route.query.userId;
|
||||
_this.queryUser();
|
||||
_this.getLinkUser();
|
||||
},
|
||||
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;
|
||||
});
|
||||
},
|
||||
getLinkUser() {
|
||||
let space = 'user_relation';
|
||||
request({
|
||||
url: `/nebula_operate/findonepathbyidwithrelation/${space}/${_this.userId}`,
|
||||
method: 'post',
|
||||
data: {
|
||||
relations: ['edge_768395026']
|
||||
}
|
||||
}).then(res => {
|
||||
_this.list = res.data.nodes;
|
||||
});
|
||||
},
|
||||
recommendItem(item) {
|
||||
_this.$router.push({
|
||||
path: "recommendItem", query: {
|
||||
userId: item.vid,
|
||||
qo: JSON.stringify(_this.qo)
|
||||
}
|
||||
});
|
||||
},
|
||||
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>
|
||||
@@ -6,7 +6,7 @@
|
||||
<i title="返回"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="block_box" style="margin-top: 0">
|
||||
<div class="block_box" style="margin-top: 20px">
|
||||
<div class="title">信息</div>
|
||||
<div>
|
||||
<el-form label-width="100px">
|
||||
@@ -32,11 +32,18 @@
|
||||
<el-tag v-if="scope.row.labelsArr.length > 5">...</el-tag>
|
||||
</div>
|
||||
</el-table-column>
|
||||
<el-table-column prop="Score" label="Score">
|
||||
<el-table-column prop="Score" label="相似度 [0, 1]">
|
||||
<template slot-scope="scope">
|
||||
{{scope.row.Score.toFixed(5)}}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="210">
|
||||
<template slot-scope="scope">
|
||||
<el-button @click.native.prevent="recommendItem(scope.row)" type="text" size="small">
|
||||
查看推荐
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</div>
|
||||
@@ -91,6 +98,14 @@ export default {
|
||||
_this.list = res.data;
|
||||
});
|
||||
},
|
||||
recommendItem(item) {
|
||||
_this.$router.push({
|
||||
path: "recommendItem", query: {
|
||||
userId: item.UserId,
|
||||
qo: JSON.stringify(_this.qo)
|
||||
}
|
||||
});
|
||||
},
|
||||
backBtn() {
|
||||
this.$router.push({
|
||||
path: "userManage", query: {
|
||||
|
||||
@@ -10,6 +10,7 @@ div.icon {
|
||||
line-height: 50px;
|
||||
margin-right: 80px;
|
||||
margin-top: 9px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
div.icon i {
|
||||
@@ -20,6 +21,10 @@ div.icon i {
|
||||
vertical-align: sub;
|
||||
}
|
||||
|
||||
.icon-back {
|
||||
box-shadow: 0 2px 12px 0 rgba(0,0,0,.1);
|
||||
}
|
||||
|
||||
.icon-back i {
|
||||
background: url("../assets/image/icon/fanhui.png") no-repeat center/contain;
|
||||
}
|
||||
|
||||
@@ -21,11 +21,14 @@ import {getToken, setToken, removeToken} from '@/utils/auth'
|
||||
import '@/permission'
|
||||
import '@antv/x6-vue-shape'
|
||||
|
||||
import VuePapaParse from 'vue-papa-parse'
|
||||
|
||||
Vue.prototype.$echarts = echarts;
|
||||
|
||||
|
||||
Vue.use(ElementUI);
|
||||
Vue.use(VueQuillEditor);
|
||||
Vue.use(VuePapaParse);
|
||||
|
||||
Vue.config.productionTip = false;
|
||||
|
||||
|
||||
@@ -56,21 +56,41 @@ export default new Router({
|
||||
component: () => import('@/components/menus/EntrysManage')
|
||||
},
|
||||
{
|
||||
path: 'feedbackTypeManage',
|
||||
component: () => import('@/components/menus/FeedbackTypeManage')
|
||||
path: 'importItem',
|
||||
component: () => import('@/components/menus/item/ImportItem')
|
||||
},
|
||||
{
|
||||
path: 'feedbackType',
|
||||
component: () => import('@/components/menus/FeedbackType')
|
||||
},
|
||||
{
|
||||
path: 'importFeedback',
|
||||
component: () => import('@/components/menus/feedback/ImportFeedback')
|
||||
},
|
||||
{
|
||||
path: 'intelligenceRecommend',
|
||||
component: () => import('@/components/menus/IntelligenceRecommend')
|
||||
},
|
||||
{
|
||||
path: 'importUser',
|
||||
component: () => import('@/components/menus/user/ImportUser')
|
||||
},
|
||||
{
|
||||
path: 'similarUser',
|
||||
component: () => import('@/components/menus/user/SimilarUser')
|
||||
},
|
||||
{
|
||||
path: 'linkUser',
|
||||
component: () => import('@/components/menus/user/LinkUser')
|
||||
},
|
||||
{
|
||||
path: 'recommendItem',
|
||||
component: () => import('@/components/menus/item/RecommendItem')
|
||||
},
|
||||
{
|
||||
path: 'feedbackHistory',
|
||||
component: () => import('@/components/menus/item/FeedbackHistory')
|
||||
},
|
||||
{
|
||||
path: 'similarItem',
|
||||
component: () => import('@/components/menus/item/SimilarItem')
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import {login, loginUser, getInfoAdmin, logout, getInfo} from '@/api/user'
|
||||
import {getToken, setToken, removeToken} from '@/utils/auth'
|
||||
import {getToken, setToken, removeToken, getName, setName} from '@/utils/auth'
|
||||
import {resetRouter} from '@/router'
|
||||
|
||||
const getDefaultState = () => {
|
||||
return {
|
||||
token: getToken(),
|
||||
name: '',
|
||||
name: getName(),
|
||||
avatar: ''
|
||||
}
|
||||
}
|
||||
@@ -20,7 +20,7 @@ const mutations = {
|
||||
state.token = token
|
||||
},
|
||||
SET_NAME: (state, name) => {
|
||||
state.name = name
|
||||
state.name = name;
|
||||
},
|
||||
SET_AVATAR: (state, avatar) => {
|
||||
state.avatar = avatar
|
||||
@@ -34,8 +34,9 @@ const actions = {
|
||||
return new Promise((resolve, reject) => {
|
||||
login({username: username.trim(), password: password, type: type}).then(response => {
|
||||
const res = response;
|
||||
commit('SET_TOKEN', res.data);
|
||||
commit('SET_TOKEN', res.data.Authorization);
|
||||
setToken(res.data.Authorization);
|
||||
setName(res.data.user.realname);
|
||||
resolve(res)
|
||||
}).catch(error => {
|
||||
reject(error)
|
||||
@@ -53,7 +54,7 @@ const actions = {
|
||||
return reject('权限异常,请重新登录!')
|
||||
}
|
||||
|
||||
commit('SET_NAME', data.realName)
|
||||
commit('SET_NAME', data.realname)
|
||||
resolve(data)
|
||||
}).catch(error => {
|
||||
reject(error)
|
||||
|
||||