Forráskód Böngészése

update:自选币种支持多用户v1

tujidelv 1 éve
szülő
commit
1d166bdc8b

+ 1 - 0
pom.xml

@@ -77,6 +77,7 @@
         <dependency>
             <groupId>mysql</groupId>
             <artifactId>mysql-connector-java</artifactId>
+            <version>8.0.17</version>
         </dependency>
         <!--lombok-->
         <dependency>

+ 31 - 6
src/main/java/top/lvzhiqiang/controller/CoinController.java

@@ -44,8 +44,12 @@ public class CoinController {
      * 2023/9/5 15:23
      */
     @PostMapping("/findApiConfig")
-    public List<CoinApiConfig> findApiConfig() {
-        List<CoinApiConfig> all = coinApiConfigService.findByParams(null, null, null, null, 1);
+    public List<CoinApiConfig> findApiConfig(String userName) {
+        if (userName == null) {
+            throw new ParameterException("用户名为空!");
+        }
+
+        List<CoinApiConfig> all = coinApiConfigService.findByParams(null, null, null, null, 1, userName);
 
         return all;
     }
@@ -130,25 +134,34 @@ public class CoinController {
      */
     @RequestMapping("/insertOrUpdateWatchlist")
     @ResponseBody
-    public R insertOrUpdateWatchlist(String symbol, String trackCategory, String trackCategory2, String issuingDate, Long cmcId, String coingeckoId, String coingeckoUrl, String feixiaohaoUrl, Integer filterFlag, String crudType) {
+    public R insertOrUpdateWatchlist(String symbol, String trackCategory, String trackCategory2, String issuingDate, Long cmcId, String coingeckoId, String coingeckoUrl, String feixiaohaoUrl, Integer filterFlag, String crudType, String userName) {
         if (StringUtils.isEmpty(crudType)) {
             throw new ParameterException("crudType为空!");
         }
 
+        if (StringUtils.isEmpty(userName)) {
+            throw new ParameterException("userName为空!");
+        } else {
+            JSONObject coinUser = coinMapper.findUserByUsername(userName);
+            if (coinUser == null) {
+                throw new ParameterException("用户不存在!");
+            }
+        }
+
         if (StringUtils.isEmpty(symbol)) {
             throw new ParameterException("symbol为空!");
         }
 
         if ("1".equals(crudType)) {
             // 新增
-            if (StringUtils.isEmpty(trackCategory) || StringUtils.isEmpty(issuingDate) || null == cmcId || StringUtils.isEmpty(coingeckoId) || null == filterFlag) {
+            if (StringUtils.isEmpty(issuingDate) || null == cmcId || StringUtils.isEmpty(coingeckoId) || null == filterFlag) {
                 throw new ParameterException("参数为空!");
             }
 
             CoinWatchlist coinWatchlist = new CoinWatchlist();
             coinWatchlist.setSymbol(symbol.trim());
-            coinWatchlist.setTrackCategory(trackCategory);
-            coinWatchlist.setTrackCategory2(trackCategory2);
+            coinWatchlist.setTrackCategory(StringUtils.isEmpty(trackCategory) ? "" : trackCategory);
+            coinWatchlist.setTrackCategory2(StringUtils.isEmpty(trackCategory2) ? "" : trackCategory2);
             coinWatchlist.setIssuingDate(LocalDate.parse(issuingDate, DateUtils.dateFormatter));
             coinWatchlist.setCmcId(cmcId);
             coinWatchlist.setCoingeckoId(coingeckoId);
@@ -215,4 +228,16 @@ public class CoinController {
 
         coinService.monitorAlarm(sb.delete(sb.length() - 1, sb.length()).toString(), CoinServiceImpl.JOB_ALARM_MODE_CHAT_BOT);
     }
+
+    @PostMapping("/login")
+    public Object login(String username, String password) {
+        if (StringUtils.isEmpty(username)) {
+            throw new ParameterException("用户名不能为空!");
+        }
+        if (StringUtils.isEmpty(password)) {
+            throw new ParameterException("密码不能为空");
+        }
+
+        return coinService.login(username, password);
+    }
 }

+ 2 - 0
src/main/java/top/lvzhiqiang/entity/CoinApiConfig.java

@@ -88,4 +88,6 @@ public class CoinApiConfig implements Serializable {
     private List<JSONObject> exchangeCategoryList;
 
     private List<JSONObject> categoryList;
+
+    private String userType;
 }

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

@@ -74,6 +74,15 @@ public interface CoinApiConfigMapper {
             "GROUP BY M.trackCategory " +
             "ORDER BY COUNT(M.trackCategory) DESC")
     List<String> findTrackCategoryList();
+
+    @Select("SELECT M.trackCategory " +
+            "FROM (SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(cw.track_category, ',', B.HELP_TOPIC_ID + 1), ',', - 1) AS trackCategory " +
+            "      FROM coin_watchlist_user cw " +
+            "               JOIN MYSQL.HELP_TOPIC B " +
+            "                    ON B.HELP_TOPIC_ID < (LENGTH(cw.track_category) - LENGTH(REPLACE(cw.track_category, ',', '')) + 1) where user_id = #{userId}) M " +
+            "GROUP BY M.trackCategory " +
+            "ORDER BY COUNT(M.trackCategory) DESC")
+    List<String> findTrackCategoryListByUserId(Integer userId);
     @Select("SELECT M.trackCategory " +
             "FROM (SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(cw.track_category2, ',', B.HELP_TOPIC_ID + 1), ',', - 1) AS trackCategory " +
             "      FROM coin_watchlist cw " +
@@ -83,6 +92,15 @@ public interface CoinApiConfigMapper {
             "ORDER BY COUNT(M.trackCategory) DESC")
     List<String> findTrackCategory2List();
 
+    @Select("SELECT M.trackCategory " +
+            "FROM (SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(cw.track_category2, ',', B.HELP_TOPIC_ID + 1), ',', - 1) AS trackCategory " +
+            "      FROM coin_watchlist_user cw " +
+            "               JOIN MYSQL.HELP_TOPIC B " +
+            "                    ON B.HELP_TOPIC_ID < (LENGTH(cw.track_category2) - LENGTH(REPLACE(cw.track_category2, ',', '')) + 1) where user_id = #{userId}) M " +
+            "GROUP BY M.trackCategory " +
+            "ORDER BY COUNT(M.trackCategory) DESC")
+    List<String> findTrackCategory2ListByUserId(Integer userId);
+
     @Select("select style_name from coin_color_style where delete_flag = 1")
     List<String> findColorStyleList();
 

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

@@ -140,6 +140,47 @@ public interface CoinMapper {
             "</script>"})
     List<CoinWatchlist> findWatchlistList2(Map<String, Object> params);
 
+    @Select({"<script>" +
+            "select cwu.id,cw.cmc_id,cwu.symbol,cw.mark_price,cw.price_change_percentage_24h,cw.total_market_value," +
+            "cw.total_market_ranking,cwu.track_category,cwu.track_category2,cw.highest_historical_price,cw.ath_change_percentage," +
+            "cw.lowest_historical_price,cw.atl_change_percentage,cw.highest_historical_date,cw.lowest_historical_date,cw.increase_multiple," +
+            "cwu.issuing_date,cwu.issuing_days,cw.coingecko_id,cw.coingecko_url,cw.cmc_url,cw.feixiaohao_url,cwu.score,cwu.sort," +
+            "cwu.remark,cwu.filter_flag,cwu.create_time,cw.modify_time,cwu.delete_flag" +
+            " from coin_watchlist_user cwu "+
+            "left join coin_watchlist cw on cwu.symbol=cw.symbol " +
+            "left join coin_watchlist_other cwo on cwu.symbol=cwo.symbol WHERE cwu.user_id = #{userId} and cwu.delete_flag = 1" +
+            "<if test=\"keyword != null and keyword != ''\">" +
+            "   and cwu.symbol like concat('%',#{keyword},'%')" +
+            "</if>" +
+            "<if test=\"symbol != null and symbol != ''\">" +
+            "   and cwu.symbol = #{symbol}" +
+            "</if>" +
+            "<if test=\"filterField != null and filterField != ''\">" +
+            "   and cwu.filter_flag = #{filterField}" +
+            "</if>" +
+            "<if test=\"trackCategoryField != null and trackCategoryField != ''\">" +
+            "   and cwu.track_category like concat('%',#{trackCategoryField},'%')" +
+            "</if>" +
+            "<if test=\"trackCategory2Field != null and trackCategory2Field != ''\">" +
+            "   and cwu.track_category2 like concat('%',#{trackCategory2Field},'%')" +
+            "</if>" +
+            "<if test=\"cexFilterField != null and cexFilterField != ''\">" +
+            "   <choose>" +
+            "       <when test=\" cexFilterName == 'cwo.cex_spot' \">" +
+            "           and substring(cwo.cex_spot,#{cexFilterIndex},1) = '1'" +
+            "       </when>" +
+            "       <otherwise>" +
+            "           and substring(cwo.cex_perpetual,#{cexFilterIndex},1) = '1'" +
+            "       </otherwise>" +
+            "   </choose>" +
+            "</if>" +
+            " order by " +
+            "<foreach collection='sortField' item='sf' index=\"index\" separator=\",\">" +
+            "   ${sf} ${sort}" +
+            " </foreach>" +
+            "</script>"})
+    List<CoinWatchlist> findWatchlistList2ByUserId(Map<String, Object> params);
+
     @Update("update coin_watchlist set cmc_id=#{cmcId},total_market_ranking=#{totalMarketRanking},total_market_value=#{totalMarketValue}," +
             "mark_price=#{markPrice},price_change_percentage_24h=#{priceChangePercentage24h},highest_historical_price=#{highestHistoricalPrice},ath_change_percentage=#{athChangePercentage},atl_change_percentage=#{atlChangePercentage},lowest_historical_price=#{lowestHistoricalPrice}," +
             "highest_historical_date=#{highestHistoricalDate},lowest_historical_date=#{lowestHistoricalDate},increase_multiple=#{increaseMultiple}," +
@@ -337,4 +378,13 @@ public interface CoinMapper {
             " </foreach>" +
             "</script>"})
     List<BookmarkInfo> findBookmarkList(Map<String, Object> params);
+
+    @Select("select 1 from coin_users where username = #{username} and password = #{password} and delete_flag = 1")
+    Integer existUserByUsernameAndPassword(String username, String password);
+
+    @Select("select 1 from coin_users where username = #{userName} and delete_flag = 1")
+    Integer existUserByUsername(String userName);
+
+    @Select("select * from coin_users where username = #{userName} and delete_flag = 1")
+    JSONObject findUserByUsername(String userName);
 }

+ 1 - 1
src/main/java/top/lvzhiqiang/service/CoinApiConfigService.java

@@ -36,5 +36,5 @@ public interface CoinApiConfigService {
      *
      * @return
      */
-    List<CoinApiConfig> findByParams(String nameCn, String url, Integer type, Integer type2, Integer status);
+    List<CoinApiConfig> findByParams(String nameCn, String url, Integer type, Integer type2, Integer status, String userName);
 }

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

@@ -61,4 +61,6 @@ public interface CoinService {
     void initWatchlist(CoinWatchlist coinWatchlist);
 
     Object getCurrentHoldingTotalAmout(JSONObject params);
+
+    Object login(String username, String password);
 }

+ 19 - 4
src/main/java/top/lvzhiqiang/service/impl/CoinApiConfigServiceImpl.java

@@ -1,8 +1,11 @@
 package top.lvzhiqiang.service.impl;
 
+import com.alibaba.fastjson.JSONObject;
 import org.springframework.stereotype.Service;
 import top.lvzhiqiang.entity.CoinApiConfig;
+import top.lvzhiqiang.exception.ParameterException;
 import top.lvzhiqiang.mapper.CoinApiConfigMapper;
+import top.lvzhiqiang.mapper.CoinMapper;
 import top.lvzhiqiang.service.CoinApiConfigService;
 import top.lvzhiqiang.util.StringUtils;
 
@@ -22,6 +25,9 @@ public class CoinApiConfigServiceImpl implements CoinApiConfigService {
     @Resource
     private CoinApiConfigMapper coinApiConfigMapper;
 
+    @Resource
+    private CoinMapper coinMapper;
+
     /**
      * 删除所有
      */
@@ -56,12 +62,21 @@ public class CoinApiConfigServiceImpl implements CoinApiConfigService {
      * @return
      */
     @Override
-    public List<CoinApiConfig> findByParams(String nameCn, String url, Integer type, Integer type2, Integer status) {
-        List<CoinApiConfig> coinApiConfigList = coinApiConfigMapper.findByParams(nameCn, url, type, type2, status);
+    public List<CoinApiConfig> findByParams(String nameCn, String url, Integer type, Integer type2, Integer status, String userName) {
+        JSONObject coinUser = coinMapper.findUserByUsername(userName);
+        if (coinUser == null) {
+            throw new ParameterException("用户不存在!");
+        }
+
+        String userType = coinUser.getString("user_type");
+        Integer userId = coinUser.getInteger("id");
+        List<CoinApiConfig> coinApiConfigList_ = coinApiConfigMapper.findByParams(nameCn, url, type, type2, status);
+        List<CoinApiConfig> coinApiConfigList = coinApiConfigList_.stream().filter(obj -> obj.getUserType().contains(userType)).collect(Collectors.toList());
+
         for (CoinApiConfig coinApiConfig : coinApiConfigList) {
             if (coinApiConfig.getNameEn().equals("watchlist")) {
-                List<String> trackCategoryList = coinApiConfigMapper.findTrackCategoryList().stream().filter(StringUtils::isNotEmpty).collect(Collectors.toList());
-                List<String> trackCategory2List = coinApiConfigMapper.findTrackCategory2List().stream().filter(StringUtils::isNotEmpty).collect(Collectors.toList());
+                List<String> trackCategoryList = coinApiConfigMapper.findTrackCategoryListByUserId(userId).stream().filter(StringUtils::isNotEmpty).collect(Collectors.toList());
+                List<String> trackCategory2List = coinApiConfigMapper.findTrackCategory2ListByUserId(userId).stream().filter(StringUtils::isNotEmpty).collect(Collectors.toList());
                 coinApiConfig.setTrackCategoryList(trackCategoryList);
                 coinApiConfig.setTrackCategory2List(trackCategory2List);
             } else if (coinApiConfig.getNameEn().equals("image")) {

+ 24 - 5
src/main/java/top/lvzhiqiang/service/impl/CoinServiceImpl.java

@@ -24,8 +24,10 @@ import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.StopWatch;
 import top.lvzhiqiang.config.InitRunner;
 import top.lvzhiqiang.config.WorkWeixinProperties;
+import top.lvzhiqiang.dto.R;
 import top.lvzhiqiang.entity.*;
 import top.lvzhiqiang.exception.BusinessException;
+import top.lvzhiqiang.exception.ParameterException;
 import top.lvzhiqiang.mapper.CoinApiConfigMapper;
 import top.lvzhiqiang.mapper.CoinMapper;
 import top.lvzhiqiang.mapper.MusicInfoMapper;
@@ -1030,6 +1032,16 @@ public class CoinServiceImpl implements CoinService {
         return totalAmout;
     }
 
+    @Override
+    public Object login(String username, String password) {
+        Integer exist = coinMapper.existUserByUsernameAndPassword(username, password);
+        if (exist != null) {
+            return R.ok().data("success");
+        } else {
+            return R.error().message("用户名或者密码错误!");
+        }
+    }
+
     private void initCexSpotFlag(Map<String, CoinWatchlistOther> coinWatchlistOtherMap4Symbol) {
         // spot
         String coingeckoExchangeTickersUrl = InitRunner.dicCodeMap.get("coingecko_exchange_tickers_url").getCodeValue();
@@ -1631,6 +1643,13 @@ public class CoinServiceImpl implements CoinService {
             //result = (JSONArray) JSON.toJSON(mixTraderList);
             return coinTraderPageInfo;
         } else if (params.getString("nameEn").equals("watchlist")) {
+            JSONObject coinUser = coinMapper.findUserByUsername(params.getString("userName"));
+            if (coinUser == null) {
+                throw new ParameterException("用户不存在!");
+            }
+            Integer userId = coinUser.getInteger("id");
+            params.put("userId",userId);
+
             PageHelper.startPage(params.getInteger("pageNo"), params.getInteger("pageSize"), true);
 
             if (params.containsKey("sortField")) {
@@ -1643,11 +1662,11 @@ public class CoinServiceImpl implements CoinService {
                 params.put("cexFilterIndex", cexFilterFieldArr[1]);
             }
 
-            List<CoinWatchlist> watchlistList = coinMapper.findWatchlistList2(params.toJavaObject(Map.class));
+            List<CoinWatchlist> watchlistList = coinMapper.findWatchlistList2ByUserId(params.toJavaObject(Map.class));
 
             PageInfo<CoinWatchlist> watchlistPageInfo = new PageInfo<>(watchlistList);
 
-            renderMainSearch4Watchlist(watchlistList);
+            renderMainSearch4Watchlist(watchlistList, userId);
             return watchlistPageInfo;
         } else if (params.getString("nameEn").equals("image")) {
             PageHelper.startPage(params.getInteger("pageNo"), params.getInteger("pageSize"), true);
@@ -1821,13 +1840,13 @@ public class CoinServiceImpl implements CoinService {
         }
     }
 
-    private void renderMainSearch4Watchlist(List<CoinWatchlist> watchlistList) {
+    private void renderMainSearch4Watchlist(List<CoinWatchlist> watchlistList, Integer userId) {
         BigDecimal bigDecimal10000 = new BigDecimal("10000");
 
         List<String> popularTrackCategoryList = Arrays.asList("DePIN", "AI", "RWA", "大饼生态", "以太Layer-2", "Restaking再质押", "NFT|链游|元宇宙", "WEB3社交");
         // 赛道分类预处理
-        List<String> trackCategoryList = coinApiConfigMapper.findTrackCategoryList().stream().filter(StringUtils::isNotEmpty).collect(Collectors.toList());
-        List<String> trackCategory2List = coinApiConfigMapper.findTrackCategory2List().stream().filter(StringUtils::isNotEmpty).collect(Collectors.toList());
+        List<String> trackCategoryList = coinApiConfigMapper.findTrackCategoryListByUserId(userId).stream().filter(StringUtils::isNotEmpty).collect(Collectors.toList());
+        List<String> trackCategory2List = coinApiConfigMapper.findTrackCategory2ListByUserId(userId).stream().filter(StringUtils::isNotEmpty).collect(Collectors.toList());
         Map<String, String> trackCategoryMap = new HashMap<>();
         Map<String, String> trackCategory2Map = new HashMap<>();
         List<String> colorList = coinApiConfigMapper.findColorStyleList();

+ 3 - 3
src/main/resources/static/coin.html

@@ -332,12 +332,12 @@
             </select>
             <select id="apis-quiet-div-watchlist-sortField" style="height: 24px;">
                 <option value="cw.price_change_percentage_24h">24H涨跌幅</option>
-                <option value="cw.score,cw.price_change_percentage_24h">优先级</option>
+                <option value="cwu.score,cw.price_change_percentage_24h">优先级</option>
                 <option value="cw.total_market_value">流通市值</option>
                 <option value="cw.total_market_ranking">市值排名</option>
                 <option value="cw.increase_multiple">涨幅倍数</option>
-                <option value="cw.issuing_days">发行天数</option>
-                <option value="cw.create_time">创建日期</option>
+                <option value="cwu.issuing_days">发行天数</option>
+                <option value="cwu.create_time">创建日期</option>
             </select>
             <select id="apis-quiet-div-watchlist-sort" style="height: 24px;">
                 <option value="desc">desc</option>

+ 34 - 10
src/main/resources/static/js/login.js

@@ -4,16 +4,40 @@ $(function () {
         document.getElementById("my").classList.remove("dynamic_hide");
     }
 
-    $("#login").click(function (){
-        var username = hex_md5(document.getElementById("username").value);
-        var password = hex_md5(document.getElementById("password").value);
-        if (username == '21232f297a57a5a743894a0e4a801fc3' && password == '6bdc78fa33715593f40ff3f61ea87e9d') {
-            setCookie("flag", "1");
-            document.getElementById("my").classList.remove("dynamic_hide");
-            document.getElementById("logindiv").classList.add("dynamic_hide");
-        } else {
-            alert("用户名或密码错误!");
-        }
+    $("#login").click(function () {
+        let username_ = document.getElementById("username").value;
+        let password_ = document.getElementById("password").value;
+        var password = password_ != '' ? hex_md5(password_) : "";
+
+        $.ajax({
+            url: "coin/login", //请求的url地址
+            dataType: "json", //返回格式为json
+            data: {
+                "username": username_,
+                "password": password
+            }, //参数值
+            type: "post", //请求方式
+            async: false, //请求是否异步,默认为异步,这也是ajax重要特性
+            success: function (data) {
+                //请求成功时处理
+                if (data != null && $.trim(data) != "" && data.success) {
+                    setCookie("flag", "1");
+                    setCookie("username", username_);
+                    document.getElementById("my").classList.remove("dynamic_hide");
+                    document.getElementById("logindiv").classList.add("dynamic_hide");
+                } else {
+                    alert(data.message);
+                }
+            },
+            beforeSend: function () {
+            },
+            complete: function () {
+            },
+            error: function (data) {
+                //请求出错处理
+                console.log("登录异常!");
+            }
+        });
     });
 });
 

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

@@ -129,8 +129,11 @@ function initOther4Select() {
     $.ajax({
         url: "coin/findApiConfig", //请求的url地址
         dataType: "json", //返回格式为json
+        data: {
+            "userName": getCookie('username')
+        }, //参数值
         type: "post", //请求方式
-        contentType: "application/json;charset=utf-8",
+        //contentType: "application/json;charset=utf-8",
         async: false, //请求是否异步,默认为异步,这也是ajax重要特性
         success: function (data) {
             //请求成功时处理
@@ -226,7 +229,7 @@ function initOther4Select() {
         },
         error: function (data) {
             //请求出错处理
-            //alert('error:' + data);
+            alert('error:' + data);
         }
     });
 }
@@ -476,6 +479,7 @@ function mainSearch(url, nameEn, slideDiv, typetype, needCustomFlag) {
         jsonData.trackCategoryField = $("#apis-quiet-div-watchlist-trackCategoryField").val();
         jsonData.trackCategory2Field = $("#apis-quiet-div-watchlist-trackCategory2Field").val();
         jsonData.cexFilterField = $("#apis-quiet-div-watchlist-cexFilterField").val();
+        jsonData.userName = getCookie('username');
     } else if (nameEn === 'image') {
         jsonData.pageNo = $("#apis-quiet-div-image-pageNo").val();
         jsonData.pageSize = $("#apis-quiet-div-image-pageSize").val();
@@ -1053,6 +1057,7 @@ function uploadMusicsSubmit(){
 
 function insertOrUpdateWatchlistSubmit(){
     var fromData = new FormData($("#insertOrUpdateWatchlist")[0]);
+    formData.append("userName", getCookie('username'));
     $.ajax({
         url: "coin/insertOrUpdateWatchlist", //请求的url地址
         dataType: "json", //返回格式为json