瀏覽代碼

add: watchlist列表添加v1

lvzhiqiang 2 年之前
父節點
當前提交
dd735f14a1

+ 120 - 0
src/main/java/top/lvzhiqiang/entity/CoinWatchlist.java

@@ -0,0 +1,120 @@
+package top.lvzhiqiang.entity;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+
+/**
+ * coin-自选清单表
+ *
+ * @author lvzhiqiang
+ * 2023/12/15 10:09
+ */
+@Data
+public class CoinWatchlist implements Serializable {
+
+    /**
+     * 主键
+     */
+    private Long id;
+
+    /**
+     * 名称
+     */
+    private String symbol;
+
+    /**
+     * 市场价格
+     */
+    private String markPrice;
+
+    /**
+     * 总市值
+     */
+    private BigDecimal totalMarketValue;
+    private String totalMarketValueStr;
+
+    /**
+     * 总市值排名
+     */
+    private Integer totalMarketRanking;
+
+    /**
+     * 赛道分类
+     */
+    private String trackCategory;
+
+    /**
+     * 历史最高价格
+     */
+    private String highestHistoricalPrice;
+
+    /**
+     * 历史最低价格
+     */
+    private String lowestHistoricalPrice;
+
+    /**
+     * 历史最高日期
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
+    private LocalDate highestHistoricalDate;
+
+    /**
+     * 历史最低日期
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
+    private LocalDate lowestHistoricalDate;
+
+    /**
+     * 涨幅倍数
+     */
+    private Integer increaseMultiple;
+
+    /**
+     * 发行日期
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
+    private LocalDate issuingDate;
+
+    /**
+     * 发行天数
+     */
+    private Integer issuingDays;
+
+    /**
+     * 采集URL
+     */
+    private String collectUrl;
+
+    /**
+     * 排序
+     */
+    private Integer sort;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+    /**
+     * 创建时间
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private LocalDateTime createTime;
+
+    /**
+     * 最后修改时间
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private LocalDateTime modifyTime;
+
+    /**
+     * 删除标志(1:正常,2:已删除)
+     */
+    private Integer deleteFlag;
+}

+ 1 - 0
src/main/java/top/lvzhiqiang/mapper/CoinApiConfigMapper.java

@@ -61,6 +61,7 @@ public interface CoinApiConfigMapper {
             "<if test=\"status != null \">" +
             "   and status = #{status}" +
             "</if>" +
+            " order by sort desc" +
             "</script>"})
     List<CoinApiConfig> findByParams(String nameCn, String url, Integer type, Integer type2, Integer status);
 }

+ 17 - 4
src/main/java/top/lvzhiqiang/mapper/CoinMapper.java

@@ -3,10 +3,8 @@ package top.lvzhiqiang.mapper;
 import org.apache.ibatis.annotations.Insert;
 import org.apache.ibatis.annotations.MapKey;
 import org.apache.ibatis.annotations.Select;
-import top.lvzhiqiang.entity.CoinHistoryOrder;
-import top.lvzhiqiang.entity.CoinMonitorCurrency;
-import top.lvzhiqiang.entity.CoinPubilcParams;
-import top.lvzhiqiang.entity.CoinTrader;
+import org.apache.ibatis.annotations.Update;
+import top.lvzhiqiang.entity.*;
 
 import java.util.List;
 import java.util.Map;
@@ -83,4 +81,19 @@ public interface CoinMapper {
 
     @Select("select concat(traderUid, '|', traderNickName) from coin_monitor_trader where delete_flag = '1'")
     List<String> findMonitorTraderList();
+
+    @Select({"<script>" +
+            "select *  from coin_watchlist WHERE delete_flag = 1" +
+            "<if test=\"keyword != null and keyword != ''\">" +
+            "   and name like concat('%',#{keyword},'%')" +
+            "</if>" +
+            " order by ${sortField} ${sort}" +
+            "</script>"})
+    List<CoinWatchlist> findWatchlistList(Map<String, Object> params);
+
+    @Update("update coin_watchlist set total_market_ranking=#{totalMarketRanking},total_market_value=#{totalMarketValue}," +
+            "mark_price=#{markPrice},highest_historical_price=#{highestHistoricalPrice},lowest_historical_price=#{lowestHistoricalPrice}," +
+            "highest_historical_date=#{highestHistoricalDate},lowest_historical_date=#{lowestHistoricalDate},increase_multiple=#{increaseMultiple}," +
+            "issuing_days=#{issuingDays},modify_time=now() where id = #{id}")
+    int updateCoinWatchlist(CoinWatchlist coinWatchlist);
 }

+ 75 - 0
src/main/java/top/lvzhiqiang/service/impl/CoinServiceImpl.java

@@ -25,6 +25,7 @@ import top.lvzhiqiang.config.WorkWeixinProperties;
 import top.lvzhiqiang.entity.CoinHistoryOrder;
 import top.lvzhiqiang.entity.CoinMonitorCurrency;
 import top.lvzhiqiang.entity.CoinTrader;
+import top.lvzhiqiang.entity.CoinWatchlist;
 import top.lvzhiqiang.mapper.CoinMapper;
 import top.lvzhiqiang.service.CoinService;
 import top.lvzhiqiang.util.*;
@@ -36,7 +37,9 @@ import java.math.RoundingMode;
 import java.security.InvalidKeyException;
 import java.text.DecimalFormat;
 import java.time.Duration;
+import java.time.LocalDate;
 import java.time.LocalDateTime;
+import java.time.temporal.ChronoUnit;
 import java.util.*;
 import java.util.concurrent.*;
 import java.util.function.Function;
@@ -93,6 +96,7 @@ public class CoinServiceImpl implements CoinService {
     private final ForkJoinPool forkJoinPool4 = new ForkJoinPool(16);
     private final ForkJoinPool forkJoinPool5 = new ForkJoinPool(16);
     private static final DecimalFormat df1 = new DecimalFormat("#,##0.00");
+    private static final DecimalFormat df2 = new DecimalFormat("#,##0");
 
     private static final WxCpServiceImpl wxCpService4News;
 
@@ -654,6 +658,63 @@ public class CoinServiceImpl implements CoinService {
             }
         }, 0, 3, TimeUnit.SECONDS);
 
+        // coingecko
+        scheduler.scheduleAtFixedRate(() -> {
+            Map<String, Object> params = new HashMap<>();
+            params.put("sortField", "create_time");
+            params.put("sort", "desc");
+            List<CoinWatchlist> watchlistList = coinMapper.findWatchlistList(params);
+
+            for (CoinWatchlist coinWatchlist : watchlistList) {
+                try {
+                    Thread.sleep(5000L);
+                } catch (InterruptedException e) {
+                    throw new RuntimeException(e);
+                }
+
+                try {
+                    Connection.Response response = JsoupUtil.requestBody(coinWatchlist.getCollectUrl(), JsoupUtil.HTTP_GET, InitRunner.proxy, new HashMap<>(), new HashMap<>());
+                    JSONObject jsonObject = JSONObject.parseObject(response.body());
+
+                    JSONObject marketData = jsonObject.getJSONObject("market_data");
+                    // 总市值排名
+                    Integer totalMarketRanking = marketData.getInteger("market_cap_rank");
+                    coinWatchlist.setTotalMarketRanking(totalMarketRanking);
+                    // 总市值
+                    BigDecimal totalMarketValue = marketData.getJSONObject("market_cap").getBigDecimal("usd");
+                    coinWatchlist.setTotalMarketValue(totalMarketValue);
+                    // 市场价格
+                    String markPrice = marketData.getJSONObject("current_price").getString("usd");
+                    coinWatchlist.setMarkPrice(markPrice);
+                    // 历史最高价格
+                    String highestHistoricalPrice = marketData.getJSONObject("ath").getString("usd");
+                    coinWatchlist.setHighestHistoricalPrice(highestHistoricalPrice);
+                    // 历史最高日期
+                    LocalDate highestHistoricalDate = LocalDate.parse(marketData.getJSONObject("ath_date").getString("usd"), DateUtils.utcTimeFormatter);
+                    coinWatchlist.setHighestHistoricalDate(highestHistoricalDate);
+                    // 历史最低价格
+                    String lowestHistoricalPrice = marketData.getJSONObject("atl").getString("usd");
+                    coinWatchlist.setLowestHistoricalPrice(lowestHistoricalPrice);
+                    // 历史最低日期
+                    LocalDate lowestHistoricalDate = LocalDate.parse(marketData.getJSONObject("atl_date").getString("usd"), DateUtils.utcTimeFormatter);
+                    coinWatchlist.setLowestHistoricalDate(lowestHistoricalDate);
+                    // 涨幅倍数
+                    BigDecimal increaseMultiple = new BigDecimal(highestHistoricalPrice).divide(new BigDecimal(lowestHistoricalPrice), 0, RoundingMode.HALF_UP);
+                    coinWatchlist.setIncreaseMultiple(increaseMultiple.intValue());
+                    // 发行日期
+                    // 发行天数
+                    if (coinWatchlist.getIssuingDate() != null) {
+                        long totalDays = ChronoUnit.DAYS.between(coinWatchlist.getIssuingDate(), LocalDate.now());
+                        coinWatchlist.setIssuingDays((int) totalDays);
+                    }
+
+                    coinMapper.updateCoinWatchlist(coinWatchlist);
+                } catch (Exception ex) {
+                    log.error("jsoup CoinWatchlist error,coinWatchlist={}", coinWatchlist, ex);
+                }
+            }
+        }, 0, 1, TimeUnit.HOURS);
+
         return null;
     }
 
@@ -938,6 +999,14 @@ public class CoinServiceImpl implements CoinService {
             renderMainSearch4TraderList(mixTraderList);
             //result = (JSONArray) JSON.toJSON(mixTraderList);
             return coinTraderPageInfo;
+        } else if (params.getString("nameEn").equals("watchlist")) {
+            PageHelper.startPage(params.getInteger("pageNo"), params.getInteger("pageSize"), true);
+            List<CoinWatchlist> watchlistList = coinMapper.findWatchlistList(params.toJavaObject(Map.class));
+
+            PageInfo<CoinWatchlist> watchlistPageInfo = new PageInfo<>(watchlistList);
+
+            renderMainSearch4Watchlist(watchlistList);
+            return watchlistPageInfo;
         } else if (params.getString("nameEn").equals("monitorCurrency")) {
             List<CoinMonitorCurrency> monitorCurrencyList = coinMapper.findMonitorCurrencyList();
 
@@ -971,6 +1040,12 @@ public class CoinServiceImpl implements CoinService {
         return result;
     }
 
+    private void renderMainSearch4Watchlist(List<CoinWatchlist> watchlistList) {
+        for (CoinWatchlist coinWatchlist : watchlistList) {
+            coinWatchlist.setTotalMarketValueStr(df2.format(coinWatchlist.getTotalMarketValue()));
+        }
+    }
+
     private void renderMainSearch4TraderList(List<CoinTrader> mixTraderList) {
         for (CoinTrader mixTrader : mixTraderList) {
 

+ 18 - 0
src/main/resources/static/coin.html

@@ -133,6 +133,24 @@
             <button class="apis-quiet-div-button1" slideDiv="apis-quiet-content">展开</button>
             <button class="apis-quiet-div-button2" slideDiv="apis-quiet-content">查询</button>
         </div>
+        <div id="apis-quiet-div-watchlist" style="display: none;">
+            <button class="apis-quiet-div-button3" slideDiv="apis-quiet-content" pageO="prev">上一页</button>
+            <button class="apis-quiet-div-button3" slideDiv="apis-quiet-content" pageO="next">下一页</button>
+            <input type="text" style="width: 100px;padding-top: 3px;" id="apis-quiet-div-watchlist-pageNo" value="1">
+            <input type="text" style="width: 100px;padding-top: 3px;" id="apis-quiet-div-watchlist-pageSize" disabled="disabled" value="30">
+            <input type="text" style="width: 100px;padding-top: 3px;" id="apis-quiet-div-watchlist-pages" disabled="disabled" value="999999">
+            <input type="text" style="width: 100px;padding-top: 3px;" id="apis-quiet-div-watchlist-keyword" placeholder="昵称关键词">
+            <select id="apis-quiet-div-watchlist-sortField" style="height: 24px;">
+                <option value="total_market_value">总市值</option>
+                <option value="total_market_ranking">总市值排名</option>
+                <option value="increase_multiple">涨幅倍数</option>
+                <option value="issuing_days">发行天数</option>
+            </select>
+            <select id="apis-quiet-div-watchlist-sort" style="height: 24px;">
+                <option value="desc">desc</option>
+                <option value="asc">asc</option>
+            </select>
+        </div>
         <div id="apis-quiet-div-traderList" style="display: none;">
             <button class="apis-quiet-div-button3" slideDiv="apis-quiet-content" pageO="prev">上一页</button>
             <button class="apis-quiet-div-button3" slideDiv="apis-quiet-content" pageO="next">下一页</button>

+ 7 - 1
src/main/resources/static/js/my-coin.js

@@ -265,6 +265,12 @@ function mainSearch(url, nameEn, slideDiv, needCustomFlag) {
         jsonData.sortField = $("#apis-quiet-div-traderList-sortField").val();
         jsonData.sort = $("#apis-quiet-div-traderList-sort").val();
         jsonData.canTrace = $("#apis-quiet-div-traderList-canTrace").val();
+    } else if (nameEn === 'watchlist') {
+        jsonData.pageNo = $("#apis-quiet-div-watchlist-pageNo").val();
+        jsonData.pageSize = $("#apis-quiet-div-watchlist-pageSize").val();
+        jsonData.keyword = $("#apis-quiet-div-watchlist-keyword").val();
+        jsonData.sortField = $("#apis-quiet-div-watchlist-sortField").val();
+        jsonData.sort = $("#apis-quiet-div-watchlist-sort").val();
     }
 
     $.ajax({
@@ -281,7 +287,7 @@ function mainSearch(url, nameEn, slideDiv, needCustomFlag) {
                     return;
                 }
 
-                if (nameEn === 'orderHistoryProductType' || nameEn === 'traderList') {
+                if (nameEn === 'orderHistoryProductType' || nameEn === 'traderList' || nameEn === 'watchlist') {
                     $("#apis-quiet-div-" + nameEn).find("input[id$=pages]").val(data.data.pages);
                     $('#' + slideDiv).find("span.contentSPAN").html(data.data.total);
                     data = data.data.list;

+ 4 - 1
src/test/java/Test.java

@@ -53,10 +53,13 @@ public class Test {
         //System.out.println(s1);
 
 
-        System.out.println((int)(0 + Math.random() * (2 - 0)));
+        System.out.println((int)(0 + Math.random() * (2)));
 
 
         LocalDateTime parse = LocalDateTime.parse("2022-09-16T16:29:04.467000+08:00", DateTimeFormatter.ISO_OFFSET_DATE_TIME);
         System.out.println(parse);
+
+        LocalDate highestHistoricalDate =  LocalDate.parse("2021-11-10T14:24:11.849Z",DateUtils.utcTimeFormatter);
+        System.out.println(highestHistoricalDate);
     }
 }

+ 71 - 0
src/test/java/top/lvzhiqiang/TestCoin.java

@@ -2,15 +2,27 @@ package top.lvzhiqiang;
 
 import com.alibaba.fastjson.JSONObject;
 import lombok.extern.slf4j.Slf4j;
+import org.jsoup.Connection;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import top.lvzhiqiang.entity.CoinWatchlist;
+import top.lvzhiqiang.mapper.CoinMapper;
 import top.lvzhiqiang.service.CoinService;
 import top.lvzhiqiang.util.DateUtils;
+import top.lvzhiqiang.util.JsoupUtil;
 
 import javax.annotation.Resource;
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.net.Proxy;
+import java.time.LocalDate;
 import java.time.LocalDateTime;
+import java.time.temporal.ChronoUnit;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 
 /**
  * 单元测试类
@@ -29,6 +41,8 @@ public class TestCoin {
 
     @Resource
     private CoinService coinService;
+    @Resource
+    private CoinMapper coinMapper;
 
     @Test
     public void testSyncData() {
@@ -54,4 +68,61 @@ public class TestCoin {
     public void testSyncData4TraderList() {
         coinService.syncData4TraderList();
     }
+
+    @Test
+    public void testSyncData4Watchlist() {
+        Map<String, Object> params = new HashMap<>();
+        params.put("sortField", "create_time");
+        params.put("sort", "desc");
+        List<CoinWatchlist> watchlistList = coinMapper.findWatchlistList(params);
+
+        for (CoinWatchlist coinWatchlist : watchlistList) {
+            try {
+                Thread.sleep(5000L);
+            } catch (InterruptedException e) {
+                throw new RuntimeException(e);
+            }
+
+            try {
+                Connection.Response response = JsoupUtil.requestBody(coinWatchlist.getCollectUrl(), JsoupUtil.HTTP_GET, Proxy.NO_PROXY, new HashMap<>(), new HashMap<>());
+                JSONObject jsonObject = JSONObject.parseObject(response.body());
+
+                JSONObject marketData = jsonObject.getJSONObject("market_data");
+                // 总市值排名
+                Integer totalMarketRanking = marketData.getInteger("market_cap_rank");
+                coinWatchlist.setTotalMarketRanking(totalMarketRanking);
+                // 总市值
+                BigDecimal totalMarketValue = marketData.getJSONObject("market_cap").getBigDecimal("usd");
+                coinWatchlist.setTotalMarketValue(totalMarketValue);
+                // 市场价格
+                String markPrice = marketData.getJSONObject("current_price").getString("usd");
+                coinWatchlist.setMarkPrice(markPrice);
+                // 历史最高价格
+                String highestHistoricalPrice = marketData.getJSONObject("ath").getString("usd");
+                coinWatchlist.setHighestHistoricalPrice(highestHistoricalPrice);
+                // 历史最高日期
+                LocalDate highestHistoricalDate = LocalDate.parse(marketData.getJSONObject("ath_date").getString("usd"), DateUtils.utcTimeFormatter);
+                coinWatchlist.setHighestHistoricalDate(highestHistoricalDate);
+                // 历史最低价格
+                String lowestHistoricalPrice = marketData.getJSONObject("atl").getString("usd");
+                coinWatchlist.setLowestHistoricalPrice(lowestHistoricalPrice);
+                // 历史最低日期
+                LocalDate lowestHistoricalDate = LocalDate.parse(marketData.getJSONObject("atl_date").getString("usd"), DateUtils.utcTimeFormatter);
+                coinWatchlist.setLowestHistoricalDate(lowestHistoricalDate);
+                // 涨幅倍数
+                BigDecimal increaseMultiple = new BigDecimal(highestHistoricalPrice).divide(new BigDecimal(lowestHistoricalPrice), 0, RoundingMode.HALF_UP);
+                coinWatchlist.setIncreaseMultiple(increaseMultiple.intValue());
+                // 发行日期
+                // 发行天数
+                if (coinWatchlist.getIssuingDate() != null) {
+                    long totalDays = ChronoUnit.DAYS.between(coinWatchlist.getIssuingDate(), LocalDate.now());
+                    coinWatchlist.setIssuingDays((int) totalDays);
+                }
+
+                coinMapper.updateCoinWatchlist(coinWatchlist);
+            } catch (Exception ex) {
+                ex.printStackTrace();
+            }
+        }
+    }
 }