Эх сурвалжийг харах

add:watchlist增加详情查看v1

lvzhiqiang 2 жил өмнө
parent
commit
ee7d56c8eb

+ 20 - 0
pom.xml

@@ -127,6 +127,26 @@
             <version>262</version>
             <scope>test</scope>
         </dependency>
+
+        <!--Markdown转Html-->
+        <!-- https://mvnrepository.com/artifact/org.commonmark/commonmark -->
+        <dependency>
+            <groupId>org.commonmark</groupId>
+            <artifactId>commonmark</artifactId>
+            <version>0.21.0</version>
+        </dependency>
+        <!--扩展 标题-->
+        <dependency>
+            <groupId>org.commonmark</groupId>
+            <artifactId>commonmark-ext-heading-anchor</artifactId>
+            <version>0.21.0</version>
+        </dependency>
+        <!--扩展 表格-->
+        <dependency>
+            <groupId>org.commonmark</groupId>
+            <artifactId>commonmark-ext-gfm-tables</artifactId>
+            <version>0.21.0</version>
+        </dependency>
     </dependencies>
 
     <build>

+ 10 - 1
src/main/java/top/lvzhiqiang/controller/CoinController.java

@@ -1,8 +1,8 @@
 package top.lvzhiqiang.controller;
 
-import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import org.springframework.web.bind.annotation.*;
+import top.lvzhiqiang.dto.R;
 import top.lvzhiqiang.entity.CoinApiConfig;
 import top.lvzhiqiang.exception.ParameterException;
 import top.lvzhiqiang.service.CoinApiConfigService;
@@ -72,4 +72,13 @@ public class CoinController {
 
         return coinService.orderDetail2(orderId, symbol);
     }
+
+    @GetMapping("/watchlistDetail/{symbol}")
+    public Object watchlistDetail(@PathVariable String symbol) {
+        if (StringUtils.isEmpty(symbol)) {
+            throw new ParameterException("symbol不能为空!");
+        }
+
+        return R.ok().data(coinService.watchlistDetail(symbol));
+    }
 }

+ 3 - 0
src/main/java/top/lvzhiqiang/mapper/CoinMapper.java

@@ -102,4 +102,7 @@ public interface CoinMapper {
             "highest_historical_date=#{highestHistoricalDate},lowest_historical_date=#{lowestHistoricalDate},increase_multiple=#{increaseMultiple}," +
             "issuing_days=#{issuingDays},modify_time=now() where id = #{id}")
     int updateCoinWatchlist(CoinWatchlist coinWatchlist);
+
+    @Select("select * from coin_watchlist where symbol = #{symbol}")
+    CoinWatchlist findWatchlistBySymbol(String symbol);
 }

+ 2 - 0
src/main/java/top/lvzhiqiang/service/CoinService.java

@@ -40,4 +40,6 @@ public interface CoinService {
     void syncData4TraderList();
 
     void syncData4TraderListSub(JSONArray dataList);
+
+    String watchlistDetail(String symbol);
 }

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

@@ -26,6 +26,7 @@ import top.lvzhiqiang.entity.CoinHistoryOrder;
 import top.lvzhiqiang.entity.CoinMonitorCurrency;
 import top.lvzhiqiang.entity.CoinTrader;
 import top.lvzhiqiang.entity.CoinWatchlist;
+import top.lvzhiqiang.exception.BusinessException;
 import top.lvzhiqiang.mapper.CoinMapper;
 import top.lvzhiqiang.service.CoinService;
 import top.lvzhiqiang.util.*;
@@ -201,6 +202,16 @@ public class CoinServiceImpl implements CoinService {
         coinMapper.insertMixTradeList(parseMixTradeList(dataList));
     }
 
+    @Override
+    public String watchlistDetail(String symbol) {
+        CoinWatchlist coinWatchlist = coinMapper.findWatchlistBySymbol(symbol);
+        if (coinWatchlist == null) {
+            throw new BusinessException(1, "symbol不存在!");
+        }
+
+        return MarkdownToHtmlUtils.markdownToHtmlExtensions(coinWatchlist.getRemark());
+    }
+
     private List<CoinTrader> parseMixTradeList(JSONArray dataList) {
         List<CoinTrader> mixTraderList = JSONArray.parseArray(dataList.toJSONString(), CoinTrader.class);
         mixTraderList.stream().forEach(e -> {

+ 87 - 0
src/main/java/top/lvzhiqiang/util/MarkdownToHtmlUtils.java

@@ -0,0 +1,87 @@
+package top.lvzhiqiang.util;
+
+import org.commonmark.Extension;
+import org.commonmark.ext.gfm.tables.TableBlock;
+import org.commonmark.ext.gfm.tables.TablesExtension;
+import org.commonmark.ext.heading.anchor.HeadingAnchorExtension;
+import org.commonmark.node.Link;
+import org.commonmark.node.Node;
+import org.commonmark.parser.Parser;
+import org.commonmark.renderer.html.AttributeProvider;
+import org.commonmark.renderer.html.HtmlRenderer;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Markdown转Html
+ */
+public class MarkdownToHtmlUtils {
+
+    /**
+     * markdown格式转换成HTML格式
+     *
+     * @param markdown
+     * @return
+     */
+    public static String markdownToHtml(String markdown) {
+        if (StringUtils.isEmpty(markdown)) {
+            return "";
+        }
+
+        Parser parser = Parser.builder().build();
+        Node document = parser.parse(markdown);
+        HtmlRenderer renderer = HtmlRenderer.builder().build();
+        return renderer.render(document);
+    }
+
+    /**
+     * 增加扩展[标题锚点,表格生成]
+     * Markdown转换成HTML
+     *
+     * @param markdown
+     * @return
+     */
+    public static String markdownToHtmlExtensions(String markdown) {
+        if (StringUtils.isEmpty(markdown)) {
+            return "";
+        }
+
+        //h标题生成id
+        Set<Extension> headingAnchorExtensions = Collections.singleton(HeadingAnchorExtension.create());
+        //转换table的HTML
+        List<Extension> tableExtension = Collections.singletonList(TablesExtension.create());
+        Parser parser = Parser.builder().extensions(tableExtension).build();
+        Node document = parser.parse(markdown);
+        HtmlRenderer renderer = HtmlRenderer.builder()
+                .extensions(headingAnchorExtensions)
+                .extensions(tableExtension)
+                .attributeProviderFactory(context -> new CustomAttributeProvider())
+                .build();
+        return renderer.render(document);
+    }
+
+    /**
+     * 处理标签的属性
+     */
+    static class CustomAttributeProvider implements AttributeProvider {
+        @Override
+        public void setAttributes(Node node, String tagName, Map<String, String> attributes) {
+            //改变a标签的target属性为_blank
+            if (node instanceof Link) {
+                attributes.put("target", "_blank");
+            }
+            if (node instanceof TableBlock) {
+                attributes.put("class", "ui celled table");
+            }
+        }
+    }
+
+    public static void main(String[] args) throws IOException {
+        String src = "# 一、标题\n ## 1.测试\n ```这是一段测试的文本```";
+        System.out.println(markdownToHtmlExtensions(src));
+    }
+}

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

@@ -21,6 +21,49 @@
     .dynamic_hide {
         display: block;
     }
+
+    #bigpreview {
+        display: none;
+        position: absolute;
+        z-index: 999;
+        margin: auto;
+        top: 50%;
+        left: 50%;
+        transform: translate(-50%, -50%);
+        background-color: rgba(0, 0, 0, 0.4);
+        border: 1px solid #888;
+        width: 50%;
+        height: 50%;
+    }
+
+    .bigpreview-content {
+        overflow: auto;
+        height: calc(100% - 40px);
+    }
+
+    .bigpreview-close {
+        color: #ddd;
+        height: 40px;
+        font-size: 28px;
+        font-weight: bold;
+    }
+
+    .bigpreview-close:hover, .bigpreview-close:focus {
+        color: black;
+        text-decoration: none;
+        cursor: pointer;
+    }
+
+    .bigpreview-loading {
+        text-align: center;
+        display: none;
+        position: absolute;
+        z-index: 999;
+        margin: auto;
+        top: 50%;
+        left: 50%;
+        transform: translate(-50%, -25%);
+    }
 </style>
 <script type="text/javascript">
     function show() {
@@ -232,5 +275,14 @@
         </table>
     </div>
 </div>
+
+<div id="bigpreview">
+    <div class="bigpreview-loading"><img src='cover/loading.gif'></div>
+    <div class="bigpreview-close">
+        <div style="float: left;">详情</div>
+        <div style="float: right;"><img src="cover/close.svg"></div>
+    </div>
+    <div class="bigpreview-content"></div>
+</div>
 </body>
 </html>

+ 1 - 0
src/main/resources/static/cover/close.svg

@@ -0,0 +1 @@
+<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1703060051386" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4211" width="32" height="32" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M580.198 509.487l176.777-176.776L686.265 262 509.486 438.777 332.711 262 262 332.71l176.777 176.777L262 686.264l70.71 70.71 176.777-176.776 176.777 176.777 70.71-70.71-176.776-176.778zM512 962C263.472 962 62 760.528 62 512S263.472 62 512 62s450 201.472 450 450-201.472 450-450 450z" fill="#1AA5FF" p-id="4212"></path></svg>

+ 53 - 0
src/main/resources/static/js/my-coin.js

@@ -207,6 +207,9 @@ function handleSelectChange(objj) {
             $.each(returnEn, function (index, obj) {
                 theadStr += '<th returnEn="' + obj + '">' + returnCn[index] + '</th>';
             });
+            if (nameEn === 'watchlist') {
+                theadStr += '<th>操作</th>';
+            }
 
             $(obj).parent("div").next("div").find("span.contentSPAN").html('0');
             $(obj).parent("div").next("div").find("tr.contentTH").html(theadStr);
@@ -335,6 +338,13 @@ function mainSearch(url, nameEn, slideDiv, needCustomFlag) {
                         var objContent = dataDetail.hasOwnProperty(obj) ? dataDetail[obj] : '--';
                         str += '<td' + objStyle + '>' + objContent + '</td>';
                     });
+
+                    if (nameEn === 'watchlist') {
+                        str += '<td style="padding: 0px 10px 0px 10px;">';
+                        str += '<button class="apis-quiet-div-watchlist-detail" symbolName="' + dataDetail.symbol + '">详情</button>';
+                        str += '</td>';
+                    }
+
                     str += '</tr>';
                 }
 
@@ -363,4 +373,47 @@ function initContentEvent() {
     if ($(".apis-move-div-input1").val().length === 0) {
         $("title").html('Coin主页');
     }
+
+    $(".apis-quiet-div-watchlist-detail").click(function () {
+        if ($("#bigpreview").css("display") === 'none') {
+            $("#bigpreview").css("display", "block");
+        } else if ($("#bigpreview").css("display") === 'block') {
+            $("#bigpreview").css("display", "none");
+        }
+
+        $("#bigpreview").find(".bigpreview-close").click(function () {
+            if ($("#bigpreview").css("display") === 'none') {
+                $("#bigpreview").css("display", "block");
+            } else if ($("#bigpreview").css("display") === 'block') {
+                $("#bigpreview").css("display", "none");
+            }
+            $(this).unbind("click");
+        });
+
+        $.ajax({
+            url: "coin/watchlistDetail/" + $(this).attr("symbolName"), //请求的url地址
+            type: "get", //请求方式
+            async: true, //请求是否异步,默认为异步,这也是ajax重要特性
+            success: function (data) {
+                //请求成功时处理
+                if (data != null && $.trim(data) != "" && data.success) {
+                    data = data.data;
+                    $(".bigpreview-content").html(data);
+                } else {
+                    //alert(data.message);
+                }
+            },
+            beforeSend: function () {
+                $(".bigpreview-content").html("");
+                $(".bigpreview-loading").css("display", "block");
+            },
+            complete: function () {
+                $(".bigpreview-loading").css("display", "none");
+            },
+            error: function (data) {
+                //请求出错处理
+                alert('error:' + data);
+            }
+        });
+    });
 }