gitweixin
  • 首页
  • 小程序代码
    • 资讯读书
    • 工具类
    • O2O
    • 地图定位
    • 社交
    • 行业软件
    • 电商类
    • 互联网类
    • 企业类
    • UI控件
  • 大数据开发
    • Hadoop
    • Spark
    • Hbase
    • Elasticsearch
    • Kafka
    • Flink
    • 数据仓库
    • 数据挖掘
    • flume
    • Kafka
    • Hive
    • shardingsphere
    • solr
  • 开发博客
    • Android
    • php
    • python
    • 运维
    • 技术架构
    • 数据库
  • 程序员网赚
  • bug清单
  • 量化投资
  • 在线查询工具
    • 去行号
    • 在线时间戳转换工具
    • 免费图片批量修改尺寸在线工具
    • SVG转JPG在线工具

月度归档3月 2021

精品微信小程序开发门户,代码全部亲测可用

  • 首页   /  2021   /  
  • 3月
互联网类 3月 31,2021

语音跟读微信小程序代码

这个小程序是面向学生,学生可以听英语语音,然后跟读,把跟读录音提交到服务器。软件有增值部分,家长购买点评卡,老师可以对学生的发音进行点评。

//logs.js
var util = require('../../utils/util.js')
Page({
    progressTimer: null,
    data: {
        cs_id: 0,
        sub_cs_id: 0,
        readingInfo: [],
        '---音频相关---': '----',
        JFAudio: [],
        recording: false,
        currentProgress: 0
    },
    onPullDownRefresh: function () {
        wx.stopPullDownRefresh();
    },
    onLoad: function (obj) {
        //接收上一个页面传过来的参数
        if (obj && obj.sub_cs_id) {
            this.setData({
                cs_id: obj.cs_id,
                sub_cs_id: obj.sub_cs_id
            })
        }
    },
    onShow: function () {
        var that = this;
        that.getReadingInfo(function (data) {
            that.setData({
                readingInfo: data.readingInfo
            })
        })
    },
    getReadingInfo: function (cal) {
        var that = this;
        util.JFrequest({
            url: 'https://t.superabc.cn/c/os/reading/getreadinginfo',
            param : {
                'sub_cs_id': that.data.sub_cs_id,
                'cs_id': that.data.cs_id
            },
            success: function (res) {
                if (res && res.statusCode == 200 && res.data && res.data.code == 0) {
                    if (typeof cal == 'function') {
                        cal(res.data.data);
                    }
                } else {
                    console.log("请求数据失败,读取缓存");
                    //
                }
            }
        });
    },
    //点击提交作业
    tapSubmitReadingResult: function (e) {
        var that = this;
        var jfAudio = that.data.JFAudio;
        var audioUrlList = [];
        var len = jfAudio.length, successNum = 0;
        //如果音频数目不够,不让提交
        if (len < that.data.readingInfo.length) {
            wx.showToast({
                title: '请完成所有跟读再提交作业!',
                icon: 'success',
                duration: 1000
            });
            return false;
        }
        wx.showToast({
            title: '正在提交作业……',
            icon: 'loading',
            duration: 5000
        });
        for (var i = 0; i < len; i++) {
            (function (i) {
                console.log(jfAudio[i].tempFilePath);
                util.JFuploadfile({
                    url: 'https://t.superabc.cn/c/s/uploadwxappfile',
                    filePath: jfAudio[i].tempFilePath || '',
                    name: 'wx_file_' + i,
                    formData: {
                        'part_index': i,
                        'file_type': 3,
                        'file_prefix': 'wx_file_'
                    },
                    success: function (res) {
                        console.log(res);
                        var retData = JSON.parse(res.data);
                        if (retData && retData.code == 0) {
                            audioUrlList[i] = retData.data.url;
                            successNum++;
                        } else {
                            console.warn("上传失败!");
                        }
                        if (successNum == len) {
                            //加入跟读(报名 + 提交作业)
                            that.joinReading(audioUrlList, function (data) {
                                //提交作业成功,跳转到结果页
                                var record_id = data.joinRes.record_id;
                                wx.hideToast();
                                setTimeout(function () {
                                    wx.redirectTo({
                                        url: '../result/result?record_id=' + record_id
                                    });
                                },300);

                            });
                        }
                    }
                })
            })(i);
        }
    },
    //加入跟读
    joinReading: function (audioUrlList, cal) {
        var that = this;
        console.log(that.data.JFAudio);
        console.log(audioUrlList);
        util.JFrequest({
            url: 'https://t.superabc.cn/c/os/reading/joinreading',
            param: {
                'cs_id': that.data.cs_id,
                'sub_cs_id': that.data.sub_cs_id,
                'audio_list': audioUrlList
            },
            success: function (res) {
                if (res && res.statusCode == 200 && res.data && res.data.code == 0) {
                    if (typeof cal == 'function') {
                        cal(res.data.data);
                    }
                }else {
                    if(res.data.code == 600004){
                        wx.showToast({
                            title: res.data.err_msg,
                            icon: 'success',
                            duration: 500
                        });
                        setTimeout(function () {
                            wx.redirectTo({
                                url: '../course/course?cs_id=' + that.data.cs_id
                            });
                        },800);

                    }
                }
            },
            complete: function (res) {
                console.log(res);
            }
        });
    },
    //播放标准片段音
    tapPlayPartAudio: function (e) {
        var thisAudioId = 'partaudio-' + e.currentTarget.id;
        var thisAudioCtx = wx.createAudioContext(thisAudioId);
        thisAudioCtx.play();
    },
    emptyAudio: {
        'recording': null,
        'playing': null,
        'hasRecord': false,
        'tempFilePath': ''
    },
    //录音
    tapCompleteUserAudio: function (e, itemIndex) {
        var that = this;
        var readingItem;
        if (itemIndex) {
            readingItem = itemIndex;
        } else {
            readingItem = e.currentTarget.dataset.reading_item;
        }
        wx.stopRecord();
        that.updateJFAudio(readingItem, 'recording', false);
        that.setData({
            recording: false
        });
        clearInterval(that.progressTimer);
    },
    tapRecordUserAudio: function (e) {
        var that = this;
        var readingItem = e.currentTarget.dataset.reading_item;
        //当前所在页面
        var jfAudio = that.data.JFAudio;
        var curAudioModel = that.updateJFAudioModel(readingItem, jfAudio[readingItem]);
        //
        wx.showToast({
            title: '开始录音',
            icon: 'success',
            duration: 500
        });

        that.updateJFAudio(readingItem, 'recording', true);
        that.setData({
            recording: true
        });
        //更新进度条
        var size = 100;
        that.setData({
            currentProgress: 0
        });
        that.progressTimer = setInterval(function () {
            var num = Math.ceil(parseFloat(that.data.readingInfo[readingItem]['audio_duration']) * 1000);
            var newPro = that.data.currentProgress;
            newPro += size / num * 100;
            if (newPro >= 100) {
                that.setData({
                    currentProgress: 100
                });
                that.tapCompleteUserAudio(null, readingItem);
            } else {
                that.setData({
                    currentProgress: newPro
                });
            }

        }, size);
        //
        wx.startRecord({
            success: function (res) {
                that.updateJFAudio(readingItem, 'tempFilePath', res.tempFilePath);
                that.updateJFAudio(readingItem, 'hasRecord', true);
                //
                that.setData({
                    recording: false
                });
            },
            complete: function () {
                that.updateJFAudio(readingItem, 'recording', false);
                that.setData({
                    recording: false
                });
                clearInterval(that.progressTimer);
            },
            fail: function (err) {
                console.log(err);
            }
        })
    },
    //回放
    tapRePlayUserAudio: function (e) {
        var that = this;
        var readingItem = e.currentTarget.dataset.reading_item;
        //当前所在页面
        var jfAudio = that.data.JFAudio;
        wx.playVoice({
            filePath: jfAudio[readingItem].tempFilePath,
            success: function () {
                that.updateJFAudio(readingItem, 'playing', false);
            }
        })
    },

    //****封装一下**** start
    updateJFAudio: function (index, key, value) {
        var that = this;
        var jfAudio = that.data.JFAudio;
        jfAudio[index][key] = value;
        that.setData({
            JFAudio: jfAudio
        });
        return jfAudio;
    },
    updateJFAudioModel: function (index, model) {
        var that = this;
        var jfAudio = that.data.JFAudio;
        var _model = model || that.emptyAudio;
        jfAudio[index] = _model;
        that.setData({
            JFAudio: jfAudio
        });

        return _model;
    }
    //****封装一下**** end
});

下载地址:工程代码

作者 east
工具类 3月 30,2021

各国货币汇率微信小程序源代码

出国或做炒外汇时,要知道各国货币汇率。本小程序展示各个国家的国旗和国家名,点击其中一个国家时,可以实时知道当前这个国家的货币能换多少人民币。

//index.js
//获取应用实例
var util = require('../../utils/util.js')
var app = getApp()
 
Page({
  data: { 
    curDate: {},
    userInfo: {},
    myMainCur: {},
    mySelectCurs: {}
  },

  longtapFormSet: function(event) {
        var that = this

        wx.showActionSheet({
              itemList: ['设 '+event.currentTarget.dataset.text+' 为主货币?', '删除 '+event.currentTarget.dataset.text+'?'],
              success: function(res) {
                if (!res.cancel) {
                 if(res.tapIndex==0)
                 {
                      var temppp=that.data.myMainCur;

                      const length = that.data.mySelectCurs.length;
                      for (let i = 0; i < length; i++) 
                      {              
                          if(event.currentTarget.dataset.id==that.data.mySelectCurs[i].name)
                          {
                               that.data.myMainCur=that.data.mySelectCurs[i];
                               that.data.myMainCur.amount=temppp.amount;
                               that.data.mySelectCurs[i]=temppp;
                               break;
                           } 
                       }   
                       that.setData({
                                              mySelectCurs:that.data.mySelectCurs
                                  })   
                        that.setData({
                                              myMainCur:that.data.myMainCur
                                  })


                       wx.setStorage({
                                              key:"myMainCur",
                                              data:that.data.myMainCur
                       })

                       wx.setStorage({
                                              key:"mySelectCurs",
                                              data:that.data.mySelectCurs
                       })
                       
                     that.rateCount(that.data.myMainCur.amount);
                 }

                 if(res.tapIndex==1)
                 { 
                      wx.showModal({
                        title: '系统提示',
                        content: '确定要删除:'+event.currentTarget.dataset.text+'?',
                        success: function(res) {
                          if (res.confirm) {
                                  util.removeByValue(that.data.mySelectCurs,event.currentTarget.dataset.id);
                                          that.setData({
                                              mySelectCurs:that.data.mySelectCurs
                                  })

                                  wx.setStorage({
                                              key:"mySelectCurs",
                                              data:that.data.mySelectCurs
                                })
                          }
                        }
                      })
                 }
                }
              }
            })
  },

  //增加货币
  bindAddCur: function() {
      var thisUrl='../addCur/addCur'
      wx.navigateTo({
          url: thisUrl
      })
  },
  bindViewTap:function() {
  },

bindKeyInput: function(e) {
    var that = this
    that.data.myMainCur.amount=e.detail.value;
    wx.setStorage({
        key:"myMainCur",
        data:that.data.myMainCur
      })
      that.rateCount(that.data.myMainCur.amount);
    },

  rateCount: function(e) {
    var that = this
    // that.data.myMainCur.amount=e;
    // wx.setStorage({
    //     key:"myMainCur",
    //     data:that.data.myMainCur
    //   })

    const length = that.data.mySelectCurs.length;
    if(length>0)
    {
    var toss=that.data.mySelectCurs[0].name;
    for (let i = 1; i < length; i++) {
            toss=toss+","+that.data.mySelectCurs[i].name;
     }


    var jsonn=util.json2Form({
            "from":that.data.myMainCur.name,
            "tos":toss,
            "amount":e
            }); 

    var urll="https://wapp.talk-easy.cn/currency/getcurrencyrates?"+jsonn;

    console.info( 'urll:'+ urll); 

    wx.request( {  
      url:urll,  
     // data:jsonn,
      header: {  
        // 'Content-Type': 'application/json' 
     // "Content-Type": "application/x-www-form-urlencoded"  
      },  
      method: "GET",  
     
      success: function( res ) { 
          console.info(res.data );   
          for (let i = 0; i < length; i++) 
          {
             for (let j = 0; j < res.data.length; j++) 
             {
               if(res.data[j].name==that.data.mySelectCurs[i].name)
               {
                    that.data.mySelectCurs[i].rate=res.data[j].rate.toFixed(2);  
                    that.data.mySelectCurs[i].amount=res.data[j].amount.toFixed(2);  
                    continue;
               }
             }
          }

          that.setData({
            mySelectCurs:that.data.mySelectCurs
          })

          wx.setStorage({
              key:"mySelectCurs",
              data:that.data.mySelectCurs
          })
      },
      fail: function( res ) { 
          console.error( '网络请求失败' );   
      },
      complete: function( res ) {  
        if( res == null || res.data == null ) {  
            return;  
        }  
      }  
    }) 
   }
  }, 

 
  onLoad: function () {
    var that = this 

    that.setData({
          curDate:util.formatTime(new Date())
      }),
    //获取用户收藏的货币
    wx.getStorage({
          key: 'mySelectCurs',
          success: function(res) {
              that.setData({
                mySelectCurs:res.data
              })
          } 
        }),
    //获取用户主要的货币
    wx.getStorage({
          key: 'myMainCur',
          success: function(res) {
              that.setData({
                myMainCur:res.data
              })
          } 
        }),
 
    //调用应用实例的方法获取全局数据
    app.getUserInfo(function(userInfo){
          //更新数据
          that.setData({
            userInfo:userInfo
          })
      })

  },

  onReady:function(){
    // 页面渲染完成
  },
  onShow:function(){
    // 页面显示
    //获取用户收藏的货币
    var that = this
      wx.getStorage({
          key: 'mySelectCurs',
          success: function(res) {
              console.info( "onShow:", res.data);
              that.setData({
                mySelectCurs:res.data
              })
          } 
        })
  },
  onHide:function(){
    // 页面隐藏
  },
  onUnload:function(){
    // 页面关闭
  }
})

下载地址:工程代码

作者 east
大数据开发 3月 29,2021

FusionInsight HD客户端使用kerberos安全认证遇到坑

之前成功安装过一个华为FusionInsight HD的客户端,Hbase、Spark等都使用正常。由于项目需要,又在新的服务器安装新的 FusionInsight HD 客户端,没想到这次遇到很多坑。

重新找了一个新版本的 FusionInsight HD的客户端 。安装成功后,进行安装认证

kinit myAccount

提示:Client myAccount@hadoop.com not found in Kerberos database while getting inital credentials。

但如果 kinit admin,就不会出现上面的问题。

经过各种折腾,和服务同步时间,关闭防火墙,查找hosts是否修改正确,jdk版本是否兼容,以及配置是否正确。卸载HD客户端和重新安装。上面的错误消失了,但又出现各种奇奇怪怪问题,例如下面的:

Not attempting to re-login since the last re-login was attempted less than 600 seconds before

GSS inititate failed

运行Spark程序又遇到种种问题

Couldn’t bind no a random free port

Connection refused

Conn’t setup connection for hdfs/myAccount@hadoop.com

刚开始没有怀疑这个HD客户端的问题,总是以为自己没配置好,或者是HD集群的服务器需要把这个ip或账号加入名单,反复折腾了好久。跟之前安装正常的HD集群各种对比,除了版本不一样,别的都找不到有什么区别。甚至在这台安装正常的服务器重新装新的HD客户端,也是安全认证不了。

后来觉得,有可能是客户端问题,要重新找回之前版本或新版本HD客户端,果然装了一个最新版本HD客户端安全认证成功了,怀疑之前安全认证不成功的,可能是装了测试集群或测试版本的。没有myAccount这个账户,但是测试集群也有admin这个账户。

由于对原理等理解不透彻,网上遇到同类问题的人也少,出现问题先入为主,以为自己没配置好,好几次看到HD客户端和之前版本不一样,也没有怀疑到这方面上去。

作者 east
电商类 3月 28,2021

仿小红书购物推荐微信小程序

在这个工业发达社会,千千万万的商品存在信息过载,需要进行推荐。

功能:

商品图文,小清新风格

消息:动态显示用户喜欢某件商品。

<view class="wx-view_KHAWVZ" data-c_e_id="wx_viewb7dbd52e">
    <swiper autoplay="True" class="wx-swiper_Mn3JMs" data-c_e_id="wx_swiper43d9f094" indicator-dots="True" lower-threshold="50">
        <swiper-item class="c-full wx-swiper-item_F6vCx8" data-c_e_id="wx_swiper_item015a5cd2">
            <image bindtap="tap_d5808da3" class="wx-image_HsAX8s2" data-c_e_id="wx_image194006a3" mode="aspectFill" src="http://imgcdn.guoku.com/images/310/530f3b41bbe01ffa3a2a6292bd7a1a6b.jpg" style="background-image: url(http://imgcdn.guoku.com/images/310/530f3b41bbe01ffa3a2a6292bd7a1a6b.jpg); background-size: cover; background-position: center center; background-repeat: no-repeat; "/>
        </swiper-item>
        <swiper-item class="c-full wx-swiper-item_qGeJVI" data-c_e_id="wx_swiper_item1d2f7146">
            <image class="wx-image_HsAX8s2" data-c_e_id="wx_image735f46d5" mode="aspectFill" src="http://imgcdn.guoku.com/images/310/55ed0775d104b851e101d6d7ef658513.jpg" style="background-image: url(http://imgcdn.guoku.com/images/310/55ed0775d104b851e101d6d7ef658513.jpg); background-size: cover; background-position: center center; background-repeat: no-repeat; "/>
        </swiper-item>
    </swiper>
    <text class="c-block wx-text_V55JEt" data-c_e_id="wx_textbf43d609">日本姬弹簧草</text>
    <view class="wx-view_Ipiy3Y" data-c_e_id="wx_viewa6f000ae">
        <navigator class="wx-navigator_8s8V9p" data-c_e_id="wx_navigator66f8813b" hover-class="navigator-hover">
            <text class="c-block wx-text_EPMInA" data-c_e_id="wx_text50749bcb">¥167.00 去购买</text>
        </navigator>
        <view class="wx-view_q8yXI9" data-c_e_id="wx_view904ff1ed">
            <image class="wx-image_YAG40m" data-c_e_id="wx_image419ab42e" mode="aspectFit" src="http://qty83k.creatby.com/materials/origin/c5656ef00d38d89eae437c5a9102f8fa_origin.png" style="background-image: url(http://qty83k.creatby.com/materials/origin/c5656ef00d38d89eae437c5a9102f8fa_origin.png); background-size: contain; background-position: center center; background-repeat: no-repeat; "/>
        </view>
    </view>
    <view class="likelist" data-c_e_id="wx_view_4cc0358a">
        <navigator class="nav_likelistmore" data-c_e_id="wx_navigator_800a8601" hover-class="navigator-hover">
            <text class="c-block wx-text_t7lDiK" data-c_e_id="wx_textfcc12486">214人喜欢</text>
            <text class="c-block wx-text_t7lDiK2" data-c_e_id="wx_texted258fa6">❯</text>
        </navigator>
        <view class="uselinklist" data-c_e_id="wx_view_ccf230eb">
            <navigator class="nav_userlink" data-c_e_id="wx_navigator1586a87e" hover-class="navigator-hover">
                <view class="likeuser" data-c_e_id="wx_view2a69167c">
                    <image class="useravatar" data-c_e_id="wx_image96c6f1ad" mode="aspectFill" src="http://imgcdn.guoku.com/avatar/large/e1786c6ae7425a1dff35caf9612e2130" style="background-size: cover; background-position: center center; background-repeat: no-repeat; background-image: url(http://imgcdn.guoku.com/avatar/large/e1786c6ae7425a1dff35caf9612e2130); "/>
                </view>
            </navigator>
            <navigator class="nav_userlink" data-c_e_id="wx_navigatore7153e65" hover-class="navigator-hover">
                <view class="likeuser" data-c_e_id="wx_view7e9222ed">
                    <image class="useravatar" data-c_e_id="wx_imagea98d5f82" mode="aspectFill" src="http://imgcdn.guoku.com/avatar/50/large_125585_7fcdf62b995e69860ce24726ec645496.jpg" style="background-size: cover; background-position: center center; background-repeat: no-repeat; background-image: url(http://imgcdn.guoku.com/avatar/50/large_125585_7fcdf62b995e69860ce24726ec645496.jpg); "/>
                </view>
            </navigator>
            <navigator class="nav_userlink" data-c_e_id="wx_navigator223d3249" hover-class="navigator-hover">
                <view class="likeuser fm2" data-c_e_id="wx_view90e01b37">
                    <image class="useravatar" data-c_e_id="wx_imagedf491a62" mode="aspectFill" src="http://imgcdn.guoku.com/avatar/50/681eb4e30ac36d9481ea421c3fc61c6b.jpg" style="background-size: cover; background-position: center center; background-repeat: no-repeat; background-image: url(http://imgcdn.guoku.com/avatar/50/681eb4e30ac36d9481ea421c3fc61c6b.jpg); "/>
                </view>
            </navigator>
            <navigator class="nav_userlink" data-c_e_id="wx_navigator29a940dd" hover-class="navigator-hover">
                <view class="likeuser fm05" data-c_e_id="wx_viewa0e6dba2">
                    <image class="useravatar" data-c_e_id="wx_imageecdb2d3d" mode="aspectFill" src="http://imgcdn.guoku.com/avatar/50/0395a843ff604331e61571375e2bb602.jpg" style="background-size: cover; background-position: center center; background-repeat: no-repeat; background-image: url(http://imgcdn.guoku.com/avatar/50/0395a843ff604331e61571375e2bb602.jpg); "/>
                </view>
            </navigator>
            <navigator class="nav_userlink" data-c_e_id="wx_navigatora9244556" hover-class="navigator-hover">
                <view class="likeuser" data-c_e_id="wx_view18aad916">
                    <image class="useravatar" data-c_e_id="wx_image10b66a3c" mode="aspectFill" src="http://imgcdn.guoku.com/avatar/50/large_223609_a9ef3adbd523a0e2515b76e7ac82be72.jpe" style="background-size: cover; background-position: center center; background-repeat: no-repeat; background-image: url(http://imgcdn.guoku.com/avatar/50/large_223609_a9ef3adbd523a0e2515b76e7ac82be72.jpe); "/>
                </view>
            </navigator>
            <navigator class="nav_userlink" data-c_e_id="wx_navigatorf2373b98" hover-class="navigator-hover">
                <view class="likeuser" data-c_e_id="wx_view3ee2d903">
                    <image class="useravatar" data-c_e_id="wx_image43f6f60b" mode="aspectFill" src="http://imgcdn.guoku.com/avatar/128/589c0d8d2966eb20241a61564676b7f7.jpg" style="background-size: cover; background-position: center center; background-repeat: no-repeat; background-image: url(http://imgcdn.guoku.com/avatar/128/589c0d8d2966eb20241a61564676b7f7.jpg); "/>
                </view>
            </navigator>
            <navigator class="nav_userlink" data-c_e_id="wx_navigator78832b6c" hover-class="navigator-hover">
                <view class="likeuser" data-c_e_id="wx_view459d4944">
                    <image class="useravatar" data-c_e_id="wx_image09c11da9" mode="aspectFill" src="http://wx.qlogo.cn/mmopen/8uZyJIhsB4vLnWuKcuGZ1ag4uzVYgo3axoeQo75TibADQibSrCNLgFnLsSoXKB740r1qhWShAkeY65DXxSPudkjherh4dM9enx/0" style="background-size: cover; background-position: center center; background-repeat: no-repeat; background-image: url(http://wx.qlogo.cn/mmopen/8uZyJIhsB4vLnWuKcuGZ1ag4uzVYgo3axoeQo75TibADQibSrCNLgFnLsSoXKB740r1qhWShAkeY65DXxSPudkjherh4dM9enx/0); "/>
                </view>
            </navigator>
        </view>
    </view>
    <view class="commentlistwrap" data-c_e_id="wx_view_c359400f">
        <view class="wx-view_8NFuqw" data-c_e_id="wx_view_664566c4">
            <text class="c-block wx-text_t7lDiK" data-c_e_id="wx_text68f182cf">2人点评</text>
        </view>
        <view class="commentlistitem" data-c_e_id="wx_view_16d0f86f">
            <navigator class="nav_userlink" data-c_e_id="wx_navigator2ffed891" hover-class="navigator-hover">
                <view class="likeuser fm2" data-c_e_id="wx_viewd34d457a">
                    <image class="useravatar" data-c_e_id="wx_image7b2bd094" mode="aspectFill" src="http://imgcdn.guoku.com/avatar/50/681eb4e30ac36d9481ea421c3fc61c6b.jpg" style="background-size: cover; background-position: center center; background-repeat: no-repeat; background-image: url(http://imgcdn.guoku.com/avatar/50/681eb4e30ac36d9481ea421c3fc61c6b.jpg); "/>
                </view>
            </navigator>
            <view class="c-minheight wx-view_WnUrtw" data-c_e_id="wx_view_66505bdf">
                <view class="wx-view_F9ISUC" data-c_e_id="wx_view27217bec">
                    <navigator class="wx-navigator_wTcTS2" data-c_e_id="wx_navigator70eae9f8" hover-class="navigator-hover">
                        <text class="wx-text_71u3gA" data-c_e_id="wx_text5fe6919d">木芽</text>
                    </navigator>
                    <view class="wx-view_wrkAD7" data-c_e_id="wx_view_53be94ea">
                        <image class="wx-image_YoXk15" data-c_e_id="wx_image_d1caf161" src="http://qty83k.creatby.com/materials/origin/53a095f5786a4f0e1e50eea5ec5c84bc_origin.png"/>
                    </view>
                </view>
                <text class="c-block wx-text_kGXxsa" data-c_e_id="wx_text_39bacddb">在植觉买过东西,每一件都是用心之作。很喜欢植觉的调调,不争不抢。今天在这个app上无意中也看到了植觉小物,小确幸顿时溢满心间</text>
                <view class="comment_operate" data-c_e_id="wx_view_cf5ce19f">
                    <view class="wx-view_h6iSr9" data-c_e_id="wx_view3a8d0d4f">
                        <view class="commentlikebtn" data-c_e_id="wx_viewb3b5b6f1">
                            <image class="wx-image_YoXk15" data-c_e_id="wx_image0736d1e2" src="http://qty83k.creatby.com/materials/origin/2459ad45d8071985f1cf7f91f3b3df66_origin.png"/>
                        </view>
                        <view class="commentreplybtn" data-c_e_id="wx_view9909114c">
                            <image class="wx-image_YoXk15" data-c_e_id="wx_imagef86ae815" src="http://qty83k.creatby.com/materials/origin/0564a45ab780222757935674e13d6919_origin.png"/>
                        </view>
                    </view>
                    <text class="listitem_creattime" data-c_e_id="wx_text8c8804b3">2016.10.29</text>
                </view>
            </view>
        </view>
        <view class="commentlistitem" data-c_e_id="wx_view4daafd3b">
            <navigator class="nav_userlink" data-c_e_id="wx_navigator4581cf51" hover-class="navigator-hover">
                <view class="likeuser fm3" data-c_e_id="wx_view94910b5d">
                    <image class="useravatar" data-c_e_id="wx_imaged4532b14" mode="aspectFill" src="http://imgcdn.guoku.com/avatar/128/589c0d8d2966eb20241a61564676b7f7.jpg" style="background-size: cover; background-position: center center; background-repeat: no-repeat; background-image: url(http://imgcdn.guoku.com/avatar/128/589c0d8d2966eb20241a61564676b7f7.jpg); "/>
                </view>
            </navigator>
            <view class="c-minheight wx-view_WnUrtw" data-c_e_id="wx_viewc808f6b9">
                <view class="wx-view_F9ISUC" data-c_e_id="wx_view54c5a204">
                    <navigator class="wx-navigator_wTcTS2" data-c_e_id="wx_navigator9e12243f" hover-class="navigator-hover">
                        <text class="wx-text_71u3gA" data-c_e_id="wx_textf720176a">UPUP</text>
                    </navigator>
                    <view class="wx-view_wrkAD7" data-c_e_id="wx_viewd862c378"/>
                </view>
                <text class="c-block wx-text_kGXxsa" data-c_e_id="wx_texte7f2518b">所以说包装多重要,你普通卖花的能把弹簧草卖到这个价格吗?呵呵……</text>
                <view class="comment_operate" data-c_e_id="wx_view1ec2d46b">
                    <view class="wx-view_h6iSr9" data-c_e_id="wx_view126a4c3a">
                        <view class="commentlikebtn" data-c_e_id="wx_viewe2d39273">
                            <image class="wx-image_YoXk15" data-c_e_id="wx_image696d6d8f" src="http://qty83k.creatby.com/materials/origin/2459ad45d8071985f1cf7f91f3b3df66_origin.png"/>
                        </view>
                        <view class="commentreplybtn" data-c_e_id="wx_view5c7d06ea">
                            <image class="wx-image_YoXk15" data-c_e_id="wx_image23cd763a" src="http://qty83k.creatby.com/materials/origin/0564a45ab780222757935674e13d6919_origin.png"/>
                        </view>
                    </view>
                    <text class="listitem_creattime" data-c_e_id="wx_text7a845479">2016.10.29</text>
                </view>
            </view>
        </view>
        <button bindtap="tap_3013baf2" class="wx-button_KajNFH" data-c_act_id="M_c9c3eaf9a5124a1b" data-c_e_id="wx_button86aaad14" hover-class="button-hover" size="default" type="default">
            写点评
        </button>
    </view>
</view>
<view bindtap="tap_3ec69114" class="modalview {{wx_view_74a0d568.class}}" data-c_e_id="wx_view_74a0d568">
    <view bindtap="tap_22930b74" class="wx-view_m9HByj" data-c_e_id="wx_view_5a2e85c5">
        <view class="bottomGrayboder wx-view_vLuOu2" data-c_e_id="wx_view9b1b510b">
            <view bindtap="tap_e2bd485d" class="_other_text_d8PEVm" data-c_act_id="M_60265ef02e4cfe9b" data-c_e_id="_other_texta33bfdda">
                ×
            </view>
        </view>
        <textarea class="c-block c-fullwidth wx-textarea_9pwDc5" data-c_e_id="wx_textarea_ab411ba2" name="textarea1" placeholder="请输入点评" type="textarea"/>
        <button bindtap="tap_d6c84484" class="wx-button_V2eIJ4" data-c_act_id="M_17d89e86c5b99fa2" data-c_e_id="wx_button_84416317" hover-class="button-hover" size="mini" type="default">
            点 评
        </button>
    </view>
</view>

下载地址:工程代码

作者 east
互联网类 3月 27,2021

带富文本解析折线图的财经微信小程序

在微信小程序实现类似同花顺app的功能:

资讯列表:富文本,图文混排

统计:饼图、折线图统计

登录注册


var _charts = require('../plugins/charts')

var CHARTS = function () { }

//形成饼图
CHARTS.shapePie = function (params) {
    new _charts({
        canvasId: params.canvas_id,
        type: 'pie',
        series: params.data,
        width: params.width,
        height: 300,
        dataLabel: true
    });
}

//形成折线图
CHARTS.shapeLine = function (params) {
    new _charts({
        canvasId: params.canvas_id,
        type: 'line',
        categories: params.xcate,
        series: params.data,
        yAxis: {
            title: params.ytitle,
            format: function (val) {
                return val.toFixed(2);
            },
            min: 0
        },
        width: params.width,
        height: 200
    });
}

//形成环形图
CHARTS.shapeRing = function (params) {
    new _charts({
        canvasId: params.canvas_id,
        type: 'ring',
        series: params.data,
        width: params.width,
        height: 300,
        dataLabel: true
    });
}

module.exports = CHARTS;

var Promise = require('../plugins/bluebird.core.min.js')
var HtmlToJson = require('../plugins/html2wxml')

var MARS = function () { }

MARS.query = function (options) {
    return new Promise((resolve, reject) => {
        wx.request({
            url: options.url,
            data: Object.assign({}, options.data),
            header: { 'content-type': 'application/json' },
            success: resolve,
            fail: reject
        })
    })
}

MARS.result = function (options) {
    return this.query(options).then(res => res)
}

MARS.html2json = function (html) {
    if (arguments.length > 1) {
        throw new Error('params error');
    }
    let r = /\s+(?=<)/g;
    html = html.replace(r, '');
    let nhtml = HtmlToJson.html2json(html);
    return nhtml;
}

MARS.json2html = function (json) {
    if (arguments.length > 1) {
        throw new Error('params error');
    }
    return HtmlToJson.json2html(json);
}


module.exports = MARS
/*
 * charts for WeChat small app v1.0
 *
 * https://github.com/xiaolin3303/wx-charts
 * 2016-11-28
 *
 * Designed and built with all the love of Web
 */

'use strict';

var config = {
    yAxisWidth: 15,
    yAxisSplit: 5,
    xAxisHeight: 15,
    legendHeight: 15,
    yAxisTitleWidth: 15,
    padding: 12,
    columePadding: 10,
    fontSize: 10,
    dataPointShape: ['diamond', 'circle', 'triangle', 'rect'],
    colors: ['#7cb5ec', '#f7a35c', '#434348', '#90ed7d', '#f15c80', '#8085e9'],
    pieChartLinePadding: 25,
    pieChartTextPadding: 15
};

// Object.assign polyfill
// https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
function assign(target, varArgs) {
    if (target == null) {
        // TypeError if undefined or null
        throw new TypeError('Cannot convert undefined or null to object');
    }

    var to = Object(target);

    for (var index = 1; index < arguments.length; index++) {
        var nextSource = arguments[index];

        if (nextSource != null) {
            // Skip over if undefined or null
            for (var nextKey in nextSource) {
                // Avoid bugs when hasOwnProperty is shadowed
                if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
                    to[nextKey] = nextSource[nextKey];
                }
            }
        }
    }
    return to;
}

var util = {
    toFixed: function toFixed(num, limit) {
        limit = limit || 2;
        if (this.isFloat(num)) {
            num = num.toFixed(limit);
        }
        return num;
    },
    isFloat: function isFloat(num) {
        return num % 1 !== 0;
    },
    isSameSign: function isSameSign(num1, num2) {
        return Math.abs(num1) === num1 && Math.abs(num2) === num2 || Math.abs(num1) !== num1 && Math.abs(num2) !== num2;
    },
    isSameXCoordinateArea: function isSameXCoordinateArea(p1, p2) {
        return this.isSameSign(p1.x, p2.x);
    },
    isCollision: function isCollision(obj1, obj2) {
        obj1.end = {};
        obj1.end.x = obj1.start.x + obj1.width;
        obj1.end.y = obj1.start.y - obj1.height;
        obj2.end = {};
        obj2.end.x = obj2.start.x + obj2.width;
        obj2.end.y = obj2.start.y - obj2.height;
        var flag = obj2.start.x > obj1.end.x || obj2.end.x < obj1.start.x || obj2.end.y > obj1.start.y || obj2.start.y < obj1.end.y;

        return !flag;
    }
};

function findRange(num, type, limit) {
    if (isNaN(num)) {
        throw new Error('unvalid series data!');
    }
    limit = limit || 10;
    type = type ? type : 'upper';
    var multiple = 1;
    while (limit < 1) {
        limit *= 10;
        multiple *= 10;
    }
    if (type === 'upper') {
        num = Math.ceil(num * multiple);
    } else {
        num = Math.floor(num * multiple);
    }
    while (num % limit !== 0) {
        if (type === 'upper') {
            num++;
        } else {
            num--;
        }
    }

    return num / multiple;
}

function convertCoordinateOrigin(x, y, center) {
    return {
        x: center.x + x,
        y: center.y - y
    };
}

function avoidCollision(obj, target) {
    if (target) {
        // is collision test
        while (util.isCollision(obj, target)) {
            if (obj.start.x > 0) {
                obj.start.y--;
            } else if (obj.start.x < 0) {
                obj.start.y++;
            } else {
                if (obj.start.y > 0) {
                    obj.start.y++;
                } else {
                    obj.start.y--;
                }
            }
        }
    }
    return obj;
}

function fillSeriesColor(series, config) {
    var index = 0;
    return series.map(function (item) {
        if (!item.color) {
            item.color = config.colors[index];
            index = (index + 1) % config.colors.length;
        }
        return item;
    });
}

function getDataRange(minData, maxData) {
    var limit = 0;
    var range = maxData - minData;
    if (range >= 10000) {
        limit = 1000;
    } else if (range >= 1000) {
        limit = 100;
    } else if (range >= 100) {
        limit = 10;
    } else if (range >= 10) {
        limit = 5;
    } else if (range >= 1) {
        limit = 1;
    } else if (range >= 0.1) {
        limit = 0.1;
    } else {
        limit = 0.01;
    }
    return {
        minRange: findRange(minData, 'lower', limit),
        maxRange: findRange(maxData, 'upper', limit)
    };
}

function mesureText(text) {
    // wx canvas 未实现mesureText方法, 此处自行实现
    text = String(text);
    var text = text.split('');
    var width = 0;
    text.forEach(function (item) {
        if (/[a-zA-Z]/.test(item)) {
            width += 7;
        } else if (/[0-9]/.test(item)) {
            width += 5.5;
        } else if (/\./.test(item)) {
            width += 2.7;
        } else if (/-/.test(item)) {
            width += 3.25;
        } else if (/[\u4e00-\u9fa5]/.test(item)) {
            width += 10;
        } else if (/\(|\)/.test(item)) {
            width += 3.73;
        } else if (/\s/.test(item)) {
            width += 2.5;
        } else if (/%/.test(item)) {
            width += 8;
        } else {
            width += 10;
        }
    });
    return width;
}

function dataCombine(series) {
    return series.reduce(function (a, b) {
        return (a.data ? a.data : a).concat(b.data);
    }, []);
}

function getPieDataPoints(series) {
    var process = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;

    var count = 0;
    var _start_ = 0;
    series.forEach(function (item) {
        count += item.data;
    });
    series.forEach(function (item) {
        item._proportion_ = item.data / count * process;
    });
    series.forEach(function (item) {
        item._start_ = _start_;
        _start_ += 2 * item._proportion_ * Math.PI;
    });

    return series;
}

function getPieTextMaxLength(series) {
    series = getPieDataPoints(series);
    var maxLength = 0;
    series.forEach(function (item) {
        var text = item.format ? item.format(+item._proportion_.toFixed(2)) : util.toFixed(item._proportion_ * 100) + '%';
        maxLength = Math.max(maxLength, mesureText(text));
    });

    return maxLength;
}

function fixColumeData(points, eachSpacing, columnLen, index, config) {
    return points.map(function (item) {
        item.width = (eachSpacing - 2 * config.columePadding) / columnLen;
        item.x = item.x - eachSpacing / 2 + config.columePadding + (index + 0.5) * item.width;

        item.width = Math.round(item.width);
        item.x = Math.round(item.x);

        return item;
    });
}

function getXAxisPoints(categories, opts, config) {
    var yAxisTotleWidth = config.yAxisWidth + config.yAxisTitleWidth;
    var spacingValid = opts.width - 2 * config.padding - yAxisTotleWidth;
    var eachSpacing = Math.floor(spacingValid / categories.length);

    var xAxisPoints = [];
    var startX = config.padding + yAxisTotleWidth;
    var endX = opts.width - config.padding;
    categories.forEach(function (item, index) {
        xAxisPoints.push(startX + index * eachSpacing);
    });
    xAxisPoints.push(endX);

    return { xAxisPoints: xAxisPoints, startX: startX, endX: endX, eachSpacing: eachSpacing };
}

function getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config) {
    var process = arguments.length > 7 && arguments[7] !== undefined ? arguments[7] : 1;

    var points = [];
    var validHeight = opts.height - 2 * config.padding - config.xAxisHeight - config.legendHeight;
    data.forEach(function (item, index) {
        var point = {};
        point.x = xAxisPoints[index] + Math.round(eachSpacing / 2);
        var height = validHeight * (item - minRange) / (maxRange - minRange);
        height *= process;
        point.y = opts.height - config.xAxisHeight - config.legendHeight - Math.round(height) - config.padding;
        points.push(point);
    });

    return points;
}

function getYAxisTextList(series, opts, config) {
    var data = dataCombine(series);
    var minData = typeof opts.yAxis.min === 'number' ? opts.yAxis.min : Math.min.apply(this, data);
    var maxData = Math.max.apply(this, data);
    var dataRange = getDataRange(minData, maxData);
    var minRange = dataRange.minRange;
    var maxRange = dataRange.maxRange;

    var range = [];
    var eachRange = (maxRange - minRange) / config.yAxisSplit;

    for (var i = 0; i <= config.yAxisSplit; i++) {
        range.push(minRange + eachRange * i);
    }
    return range.reverse();
}

function calYAxisData(series, opts, config) {
    var ranges = getYAxisTextList(series, opts, config);
    var yAxisWidth = config.yAxisWidth;
    var rangesFormat = ranges.map(function (item) {
        item = util.toFixed(item, 2);
        item = opts.yAxis.format ? opts.yAxis.format(Number(item)) : item;
        yAxisWidth = Math.max(yAxisWidth, mesureText(item) + 5);
        return item;
    });

    return { rangesFormat: rangesFormat, ranges: ranges, yAxisWidth: yAxisWidth };
}

function drawPointShape(points, color, shape, context) {
    context.beginPath();
    context.setStrokeStyle("#ffffff");
    context.setLineWidth(1);
    context.setFillStyle(color);

    if (shape === 'diamond') {
        points.forEach(function (item, index) {
            context.moveTo(item.x, item.y - 4.5);
            context.lineTo(item.x - 4.5, item.y);
            context.lineTo(item.x, item.y + 4.5);
            context.lineTo(item.x + 4.5, item.y);
            context.lineTo(item.x, item.y - 4.5);
        });
    } else if (shape === 'circle') {
        points.forEach(function (item, index) {
            context.moveTo(item.x + 3.5, item.y);
            context.arc(item.x, item.y, 4, 0, 2 * Math.PI, false);
        });
    } else if (shape === 'rect') {
        points.forEach(function (item, index) {
            context.moveTo(item.x - 3.5, item.y - 3.5);
            context.rect(item.x - 3.5, item.y - 3.5, 7, 7);
        });
    } else if (shape === 'triangle') {
        points.forEach(function (item, index) {
            context.moveTo(item.x, item.y - 4.5);
            context.lineTo(item.x - 4.5, item.y + 4.5);
            context.lineTo(item.x + 4.5, item.y + 4.5);
            context.lineTo(item.x, item.y - 4.5);
        });
    }
    context.closePath();
    context.fill();
    context.stroke();
}

function drawPointText(points, series, config, context) {
    // 绘制数据文案
    var data = series.data;

    context.beginPath();
    context.setFontSize(config.fontSize);
    context.setFillStyle('#666666');
    points.forEach(function (item, index) {
        var formatVal = series.format ? series.format(data[index]) : data[index];
        context.fillText(formatVal, item.x - mesureText(formatVal) / 2, item.y - 2);
    });
    context.closePath();
    context.stroke();
}

function drawPieText(series, opts, config, context, radius, center) {
    var lineRadius = radius + config.pieChartLinePadding;
    var textRadius = lineRadius + config.pieChartTextPadding;
    var textObjectCollection = [];
    var lastTextObject = null;

    var seriesConvert = series.map(function (item) {
        var arc = 2 * Math.PI - (item._start_ + 2 * Math.PI * item._proportion_ / 2);
        var text = item.format ? item.format(+item._proportion_.toFixed(2)) : util.toFixed(item._proportion_ * 100) + '%';
        var color = item.color;
        return { arc: arc, text: text, color: color };
    });
    seriesConvert.forEach(function (item) {
        // line end
        var orginX1 = Math.cos(item.arc) * lineRadius;
        var orginY1 = Math.sin(item.arc) * lineRadius;

        // line start
        var orginX2 = Math.cos(item.arc) * radius;
        var orginY2 = Math.sin(item.arc) * radius;

        // text start
        var orginX3 = orginX1 >= 0 ? orginX1 + config.pieChartTextPadding : orginX1 - config.pieChartTextPadding;
        var orginY3 = orginY1;

        var textWidth = mesureText(item.text);
        var startY = orginY3;

        if (lastTextObject && util.isSameXCoordinateArea(lastTextObject.start, { x: orginX3 })) {
            if (orginX3 > 0) {
                startY = Math.min(orginY3, lastTextObject.start.y);
            } else if (orginX1 < 0) {
                startY = Math.max(orginY3, lastTextObject.start.y);
            } else {
                if (orginY3 > 0) {
                    startY = Math.max(orginY3, lastTextObject.start.y);
                } else {
                    startY = Math.min(orginY3, lastTextObject.start.y);
                }
            }
        }

        if (orginX3 < 0) {
            orginX3 -= textWidth;
        }

        var textObject = {
            lineStart: {
                x: orginX2,
                y: orginY2
            },
            lineEnd: {
                x: orginX1,
                y: orginY1
            },
            start: {
                x: orginX3,
                y: startY
            },
            width: textWidth,
            height: config.fontSize,
            text: item.text,
            color: item.color
        };

        lastTextObject = avoidCollision(textObject, lastTextObject);
        textObjectCollection.push(lastTextObject);
    });

    textObjectCollection.forEach(function (item) {
        var lineStartPoistion = convertCoordinateOrigin(item.lineStart.x, item.lineStart.y, center);
        var lineEndPoistion = convertCoordinateOrigin(item.lineEnd.x, item.lineEnd.y, center);
        var textPosition = convertCoordinateOrigin(item.start.x, item.start.y, center);
        context.setLineWidth(1);
        context.setFontSize(config.fontSize);
        context.beginPath();
        context.setStrokeStyle(item.color);
        context.setFillStyle(item.color);
        context.moveTo(lineStartPoistion.x, lineStartPoistion.y);
        var curveStartX = item.start.x < 0 ? textPosition.x + item.width : textPosition.x;
        var textStartX = item.start.x < 0 ? textPosition.x - 5 : textPosition.x + 5;
        context.quadraticCurveTo(lineEndPoistion.x, lineEndPoistion.y, curveStartX, textPosition.y);
        context.moveTo(lineStartPoistion.x, lineStartPoistion.y);
        context.stroke();
        context.closePath();
        context.beginPath();
        context.moveTo(textPosition.x + item.width, textPosition.y);
        context.arc(curveStartX, textPosition.y, 2, 0, 2 * Math.PI);
        context.closePath();
        context.fill();
        context.beginPath();
        context.setFillStyle('#666666');
        context.fillText(item.text, textStartX, textPosition.y + 3);
        context.closePath();
        context.stroke();

        context.closePath();
    });
}

function drawYAxisTitle(title, opts, config, context) {
    var startX = config.xAxisHeight + (opts.height - config.xAxisHeight - mesureText(title)) / 2;
    context.save();
    context.beginPath();
    context.setFontSize(config.fontSize);
    context.setFillStyle('#333333');
    context.translate(0, opts.height);
    context.rotate(-90 * Math.PI / 180);
    context.fillText(title, startX, config.padding + 0.5 * config.fontSize);
    context.stroke();
    context.closePath();
    context.restore();
}

function drawColumnDataPoints(series, opts, config, context) {
    var process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1;

    var _calYAxisData = calYAxisData(series, opts, config),
        ranges = _calYAxisData.ranges;

    var _getXAxisPoints = getXAxisPoints(opts.categories, opts, config),
        xAxisPoints = _getXAxisPoints.xAxisPoints,
        eachSpacing = _getXAxisPoints.eachSpacing;

    var minRange = ranges.pop();
    var maxRange = ranges.shift();
    var endY = opts.height - config.padding - config.xAxisHeight - config.legendHeight;

    series.forEach(function (eachSeries, seriesIndex) {
        var data = eachSeries.data;
        var points = getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process);
        points = fixColumeData(points, eachSpacing, series.length, seriesIndex, config);

        // 绘制柱状数据图
        context.beginPath();
        context.setFillStyle(eachSeries.color);
        points.forEach(function (item, index) {
            var startX = item.x - item.width / 2 + 1;
            var height = opts.height - item.y - config.padding - config.xAxisHeight - config.legendHeight;
            context.moveTo(startX, item.y);
            context.rect(startX, item.y, item.width - 2, height);
        });
        context.closePath();
        context.fill();
    });
    series.forEach(function (eachSeries, seriesIndex) {
        var data = eachSeries.data;
        var points = getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process);
        points = fixColumeData(points, eachSpacing, series.length, seriesIndex, config);
        if (opts.dataLabel !== false && process === 1) {
            drawPointText(points, eachSeries, config, context);
        }
    });
}

function drawAreaDataPoints(series, opts, config, context) {
    var process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1;

    var _calYAxisData2 = calYAxisData(series, opts, config),
        ranges = _calYAxisData2.ranges;

    var _getXAxisPoints2 = getXAxisPoints(opts.categories, opts, config),
        xAxisPoints = _getXAxisPoints2.xAxisPoints,
        eachSpacing = _getXAxisPoints2.eachSpacing;

    var minRange = ranges.pop();
    var maxRange = ranges.shift();
    var endY = opts.height - config.padding - config.xAxisHeight - config.legendHeight;

    series.forEach(function (eachSeries, seriesIndex) {
        var data = eachSeries.data;
        var points = getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process);

        // 绘制区域数据
        var firstPoint = points[0];
        var lastPoint = points[points.length - 1];
        context.beginPath();
        context.setStrokeStyle(eachSeries.color);
        context.setFillStyle(eachSeries.color);
        context.setGlobalAlpha(0.6);
        context.setLineWidth(2);
        context.moveTo(firstPoint.x, firstPoint.y);
        points.forEach(function (item, index) {
            if (index > 0) {
                context.lineTo(item.x, item.y);
            }
        });

        context.lineTo(lastPoint.x, endY);
        context.lineTo(firstPoint.x, endY);
        context.lineTo(firstPoint.x, firstPoint.y);
        context.closePath();
        context.fill();
        context.setGlobalAlpha(1);

        var shape = config.dataPointShape[seriesIndex % config.dataPointShape.length];
        drawPointShape(points, eachSeries.color, shape, context);
    });
    if (opts.dataLabel !== false && process === 1) {
        series.forEach(function (eachSeries, seriesIndex) {
            var data = eachSeries.data;
            var points = getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process);
            drawPointText(points, eachSeries, config, context);
        });
    }
}

function drawLineDataPoints(series, opts, config, context) {
    var process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1;

    var _calYAxisData3 = calYAxisData(series, opts, config),
        ranges = _calYAxisData3.ranges;

    var _getXAxisPoints3 = getXAxisPoints(opts.categories, opts, config),
        xAxisPoints = _getXAxisPoints3.xAxisPoints,
        eachSpacing = _getXAxisPoints3.eachSpacing;

    var minRange = ranges.pop();
    var maxRange = ranges.shift();

    series.forEach(function (eachSeries, seriesIndex) {
        var data = eachSeries.data;
        var points = getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process);

        // 绘制数据线
        context.beginPath();
        context.setStrokeStyle(eachSeries.color);
        context.setLineWidth(2);
        context.moveTo(points[0].x, points[0].y);
        points.forEach(function (item, index) {
            if (index > 0) {
                context.lineTo(item.x, item.y);
            }
        });
        context.moveTo(points[0].x, points[0].y);
        context.closePath();
        context.stroke();

        var shape = config.dataPointShape[seriesIndex % config.dataPointShape.length];
        drawPointShape(points, eachSeries.color, shape, context);
    });
    if (opts.dataLabel !== false && process === 1) {
        series.forEach(function (eachSeries, seriesIndex) {
            var data = eachSeries.data;
            var points = getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process);
            drawPointText(points, eachSeries, config, context);
        });
    }
}

function drawXAxis(categories, opts, config, context) {
    var _getXAxisPoints4 = getXAxisPoints(categories, opts, config),
        xAxisPoints = _getXAxisPoints4.xAxisPoints,
        startX = _getXAxisPoints4.startX,
        endX = _getXAxisPoints4.endX,
        eachSpacing = _getXAxisPoints4.eachSpacing;

    var startY = opts.height - config.padding - config.xAxisHeight - config.legendHeight;
    var endY = opts.height - config.padding - config.legendHeight;

    context.beginPath();
    context.setStrokeStyle("#cccccc");
    context.setLineWidth(1);
    context.moveTo(startX, startY);
    context.lineTo(endX, startY);
    xAxisPoints.forEach(function (item, index) {
        context.moveTo(item, startY);
        context.lineTo(item, endY);
    });
    context.closePath();
    context.stroke();

    context.beginPath();
    context.setFontSize(config.fontSize);
    context.setFillStyle('#666666');
    categories.forEach(function (item, index) {
        var offset = eachSpacing / 2 - mesureText(item) / 2;
        context.fillText(item, xAxisPoints[index] + offset, startY + config.fontSize + 5);
    });
    context.closePath();
    context.stroke();
}

function drawYAxis(series, opts, config, context) {
    var _calYAxisData4 = calYAxisData(series, opts, config),
        rangesFormat = _calYAxisData4.rangesFormat;

    var yAxisTotleWidth = config.yAxisWidth + config.yAxisTitleWidth;

    var spacingValid = opts.height - 2 * config.padding - config.xAxisHeight - config.legendHeight;
    var eachSpacing = Math.floor(spacingValid / config.yAxisSplit);
    var startX = config.padding + yAxisTotleWidth;
    var endX = opts.width - config.padding;
    var startY = config.padding;
    var endY = opts.height - config.padding - config.xAxisHeight - config.legendHeight;

    var points = [];
    for (var i = 0; i < config.yAxisSplit; i++) {
        points.push(config.padding + eachSpacing * i);
    }

    context.beginPath();
    context.setStrokeStyle("#cccccc");
    context.setLineWidth(1);
    points.forEach(function (item, index) {
        context.moveTo(startX, item);
        context.lineTo(endX, item);
    });
    context.closePath();
    context.stroke();
    context.beginPath();
    context.setFontSize(config.fontSize);
    context.setFillStyle('#666666');
    rangesFormat.forEach(function (item, index) {
        var pos = points[index] ? points[index] : endY;
        context.fillText(item, config.padding + config.yAxisTitleWidth, pos + 10);
    });
    context.closePath();
    context.stroke();

    if (opts.yAxis.title) {
        drawYAxisTitle(opts.yAxis.title, opts, config, context);
    }
}

function drawLegend(series, opts, config, context) {
    if (!opts.legend) {
        return;
    }
    var padding = 5;
    var width = 0;
    series.forEach(function (item) {
        item.name = item.name || 'undefined';
        width += 2 * padding + mesureText(item.name) + 22.5;
    });
    var startX = (opts.width - width) / 2 + padding;
    var startY = opts.height - config.legendHeight - 5;

    context.setFontSize(config.fontSize);
    series.forEach(function (item) {
        switch (opts.type) {
            case 'line':
                context.beginPath();
                context.setLineWidth(1);
                context.setStrokeStyle(item.color);
                context.moveTo(startX - 2, startY + 5);
                context.lineTo(startX + 17, startY + 5);
                context.stroke();
                context.closePath();
                context.beginPath();
                context.setLineWidth(1);
                context.setStrokeStyle('#ffffff');
                context.setFillStyle(item.color);
                context.moveTo(startX + 7.5, startY + 5);
                context.arc(startX + 7.5, startY + 5, 4, 0, 2 * Math.PI);
                context.fill();
                context.stroke();
                context.closePath();
                break;
            case 'pie':
            case 'ring':
                context.beginPath();
                context.setFillStyle(item.color);
                context.moveTo(startX + 7.5, startY + 5);
                context.arc(startX + 7.5, startY + 5, 7, 0, 2 * Math.PI);
                context.closePath();
                context.fill();
                break;
            default:
                context.beginPath();
                context.setFillStyle(item.color);
                context.moveTo(startX, startY);
                context.rect(startX, startY, 15, 10);
                context.closePath();
                context.fill();
        }
        startX += padding + 15;
        context.beginPath();
        context.setFillStyle('#333333');
        context.fillText(item.name, startX, startY + 9);
        context.closePath();
        context.stroke();
        startX += mesureText(item.name) + padding + 7.5;
    });
}
function drawPieDataPoints(series, opts, config, context) {
    var process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1;

    series = getPieDataPoints(series, process);
    var centerPosition = {
        x: opts.width / 2,
        y: (opts.height - config.legendHeight) / 2
    };
    var radius = Math.min(centerPosition.x - config.pieChartLinePadding - config.pieChartTextPadding - config._pieTextMaxLength_, centerPosition.y - config.pieChartLinePadding - config.pieChartTextPadding);
    if (opts.dataLabel) {
        radius -= 10;
    } else {
        radius -= 2 * config.padding;
    }
    series.forEach(function (eachSeries) {
        context.beginPath();
        context.setLineWidth(2);
        context.setStrokeStyle('#ffffff');
        context.setFillStyle(eachSeries.color);
        context.moveTo(centerPosition.x, centerPosition.y);
        context.arc(centerPosition.x, centerPosition.y, radius, eachSeries._start_, eachSeries._start_ + 2 * eachSeries._proportion_ * Math.PI);
        context.closePath();
        context.fill();
        context.stroke();
    });

    if (opts.type === 'ring') {
        context.beginPath();
        context.setFillStyle('#ffffff');
        context.moveTo(centerPosition.x, centerPosition.y);
        context.arc(centerPosition.x, centerPosition.y, radius * 0.6, 0, 2 * Math.PI);
        context.closePath();
        context.fill();
    }

    if (opts.dataLabel !== false && process === 1) {
        drawPieText(series, opts, config, context, radius, centerPosition);
    }
}

function drawCanvas(opts, context) {
    context.draw();
}

var Timing = {
    easeIn: function easeIn(pos) {
        return Math.pow(pos, 3);
    },

    easeOut: function easeOut(pos) {
        return Math.pow(pos - 1, 3) + 1;
    },

    easeInOut: function easeInOut(pos) {
        if ((pos /= 0.5) < 1) {
            return 0.5 * Math.pow(pos, 3);
        } else {
            return 0.5 * (Math.pow(pos - 2, 3) + 2);
        }
    },

    linear: function linear(pos) {
        return pos;
    }
};

function Animation(opts) {
    opts.duration = typeof opts.duration === 'undefined' ? 1000 : opts.duration;
    opts.timing = opts.timing || 'linear';

    var delay = 17;

    var createAnimationFrame = function createAnimationFrame() {
        if (typeof requestAnimationFrame !== 'undefined') {
            return requestAnimationFrame;
        } else if (typeof setTimeout !== 'undefined') {
            return function (step, delay) {
                setTimeout(function () {
                    var timeStamp = +new Date();
                    step(timeStamp);
                }, delay);
            };
        } else {
            return function (step) {
                step(null);
            };
        }
    };
    var animationFrame = createAnimationFrame();
    var startTimeStamp = null;
    function step(timestamp) {
        if (timestamp === null) {
            opts.onProcess && opts.onProcess(1);
            opts.onAnimationFinish && opts.onAnimationFinish();
            return;
        }
        if (startTimeStamp === null) {
            startTimeStamp = timestamp;
        }
        if (timestamp - startTimeStamp < opts.duration) {
            var process = (timestamp - startTimeStamp) / opts.duration;
            var timingFunction = Timing[opts.timing];
            process = timingFunction(process);
            opts.onProcess && opts.onProcess(process);
            animationFrame(step, delay);
        } else {
            opts.onProcess && opts.onProcess(1);
            opts.onAnimationFinish && opts.onAnimationFinish();
        }
    }

    animationFrame(step, delay);
}

function drawCharts(type, opts, config, context) {
    var series = opts.series;
    var categories = opts.categories;
    series = fillSeriesColor(series, config);

    var _calYAxisData = calYAxisData(series, opts, config),
        yAxisWidth = _calYAxisData.yAxisWidth;

    config.yAxisWidth = yAxisWidth;
    config._pieTextMaxLength_ = getPieTextMaxLength(series);

    var duration = opts.animation ? 1000 : 0;

    switch (type) {
        case 'line':
            Animation({
                timing: 'easeIn',
                duration: duration,
                onProcess: function onProcess(process) {
                    drawYAxis(series, opts, config, context);
                    drawXAxis(categories, opts, config, context);
                    drawLineDataPoints(series, opts, config, context, process);
                    drawLegend(opts.series, opts, config, context);
                    drawCanvas(opts, context);
                }
            });
            break;
        case 'column':
            Animation({
                timing: 'easeIn',
                duration: duration,
                onProcess: function onProcess(process) {
                    drawYAxis(series, opts, config, context);
                    drawXAxis(categories, opts, config, context);
                    drawColumnDataPoints(series, opts, config, context, process);
                    drawLegend(opts.series, opts, config, context);
                    drawCanvas(opts, context);
                }
            });
            break;
        case 'area':
            Animation({
                timing: 'easeIn',
                duration: duration,
                onProcess: function onProcess(process) {
                    drawYAxis(series, opts, config, context);
                    drawXAxis(categories, opts, config, context);
                    drawAreaDataPoints(series, opts, config, context, process);
                    drawLegend(opts.series, opts, config, context);
                    drawCanvas(opts, context);
                }
            });
            break;
        case 'ring':
        case 'pie':
            Animation({
                timing: 'easeInOut',
                duration: duration,
                onProcess: function onProcess(process) {
                    drawPieDataPoints(series, opts, config, context, process);
                    drawLegend(opts.series, opts, config, context);
                    drawCanvas(opts, context);
                }
            });
            break;
    }
}

var Charts = function Charts(opts) {
    opts.yAxis = opts.yAxis || {};
    opts.legend = opts.legend === false ? false : true;
    opts.animation = opts.animation === false ? false : true;
    var config$$1 = assign({}, config);
    config$$1.legendHeight = opts.legend ? config$$1.legendHeight : 0;
    config$$1.yAxisTitleWidth = opts.yAxis.title ? config$$1.yAxisTitleWidth : 0;
    config$$1.pieChartLinePadding = opts.dataLabel === false ? 0 : config$$1.pieChartLinePadding;
    config$$1.pieChartTextPadding = opts.dataLabel === false ? 0 : config$$1.pieChartTextPadding;

    var context = wx.createCanvasContext(opts.canvasId);

    drawCharts(opts.type, opts, config$$1, context);
};

module.exports = Charts;

下载地址:财经

作者 east
资讯读书 3月 26,2021

摇一摇切换文章微信小程序代码

当年,摇一摇功能让微信火了起来,赢得了跟米聊的战争。而摇一摇这个好用功能同样可以用来做读书类,摇一摇就切换文章,并带动态声效。

var util = require(‘../../utils/util.js’)
Page({
data: {
x:util.res[0].title,
y:util.res[0].summary,
z:util.res[0].img,
hidden: false,
last_update:0,
last_x:0,
last_y:0,
last_z:0
},
onReady: function (e) {
var determination = false
var that = this
function a(){
wx.onAccelerometerChange(function(res) {
var curTime = new Date().getTime()
var SHAKE_THRESHOLD = 60
var last_update = that.data.last_update
var len = util.res.length
var list = Math.floor(Math.random()*(len-1))
if ((curTime – last_update) > 100) {
var diffTime = curTime – last_update;
var speed = Math.abs(res.x + res.y + res.z – that.data.last_x – that.data.last_y – that.data.last_z) / diffTime * 10000;
if (speed > SHAKE_THRESHOLD && !determination) {
determination = true
determination = that.f(util.res[list])
}
that.setData({
last_update: curTime,
last_x: res.x,
last_y: res.y,
last_z: res.z
})
}
})
}
a()
},
f: function(res){
if(res.img){
this.setData({
x: res.title,
y: res.summary,
z: res.img,
hidden: false,
})
}else{
this.setData({
x: res.title,
y: res.summary,
hidden: true,
})
}
wx.playBackgroundAudio({
dataUrl: ‘http://fjyd.sc.chinaz.com/files/download/sound1/201410/5012.mp3’,
title: ‘weixin’
})
return false
}
})

下载地址:工程代码

作者 east
资讯读书 3月 25,2021

学日语五十音微信小程序代码

日语五十音,就像学中文的学拼音,是十分基础的。



//const Util = require('../../utils/util.js')
const Data = require('../../data.js')
Page({
  //data 将会以 JSON 的形式由逻辑层传至渲染层,所以其数据必须是可以转成 JSON 的格式:字符串,数字,布尔值,对象,数组。
  //此处 forfoot 用数据徐循环则没什么意思了 无法绑定 并 调用回调 data中也无法存function;
  data: {
    minHeight:'',
    mojiList:[],
    // fortest:'test',
    hiraganaShow:true,
    //无法操作dom 都需要靠data绑定
    changeKANAText:'あ',
    tabnow:'seionn',
    sannbunn:false
    // ,
    // forfoot:{
    //   tabBarList:[
    //     {
    //       text:'假名',
    //       tabCbName:'changeKANA'
    //       // ,
    //       // cbfn:function(Page){
    //       //     Page.setData({
    //       //       fortest: 'changeKANA'
    //       //     })
    //       // }
    //     },
    //     {
    //       text:'清音',
    //       tabCbName:'toSEIONN'
    //       // ,
    //       // cbfn:function(Page){
    //       //     Page.setData({
    //       //       fortest: 'toSEIONN'
    //       //     })
    //       // }
    //     },
    //     {
    //       text:'浊音',
    //       tabCbName:'toDAKUONN'
    //       // ,
    //       // cbfn:function(Page){
    //       //     Page.setData({
    //       //       fortest: 'toDAKUONN'
    //       //     })
    //       // }
    //     },
    //     {
    //       text:'拗音',
    //       tabCbName:'toYOUONN'
    //       // ,
    //       // cbfn:function(Page){
    //       //     Page.setData({
    //       //       fortest: 'toYOUONN'
    //       //     })
    //       // }
    //     }
    //   ]
    // }
  },
  onLoad: function () {
    let that = this;
    //获取系统信息
    wx.getSystemInfo({
      success: function(res) {
        that.setData({
          minHeight: res.windowHeight
        })
      }
    })
    that.setData({
      mojiList: Data.seionn
    })
    // for(let i of that.data.forfoot.tabBarList){
    //   console.log(i);
    //   Util.addEventHandleCb(that,i['tabCbName'],i['cbfn']);
    // }
  },
  //eventHandle  需在相应的Page定义中写上相应的事件处理函数...mdzz
  changeKANA(e){
    //e 不知道能咋用
    let show = this.data.hiraganaShow;
    this.setData({
      hiraganaShow: !show
    })  
    !show?this.setData({changeKANAText: 'あ'}):this.setData({changeKANAText: 'ア'})
  },
  toSEIONN(){
    this.setData({
      mojiList: Data.seionn,
      tabnow:'seionn',
      sannbunn:false
    })
  },
  toDAKUONN(){
    this.setData({
      mojiList: Data.dakuonn,
      tabnow:'dakuonn',
      sannbunn:false
    })
  },
  toYOUONN(){
    this.setData({
      mojiList: Data.youonn,
      tabnow:'youonn',
      sannbunn:true
    })
  }
})

下载地址:工程代码

作者 east
工具类 3月 24,2021

To do 清单列表微信小程序代码

在现在社会,注意力经常被各种电子屏分散。为了高效学习,可以把任务清单分成1个个To do清单列表,集中注意力完成一个个清单,然后在小程序打勾完成。而且对小程序的清单列表还设置了密码,防止秘密内容被别人看到。

下载地址:工程代码

作者 east
资讯读书 3月 21,2021

仿今日头条move css微信小程序代码

仿照今天头条,对栏目可以动态进行设置,并且有摇动,移动等动画效果。动画效果用的是css 的move元素。

下载地址:工程代码

作者 east
互联网类 3月 21,2021

LOL战绩查询微信小程序代码

这是一款功能齐全的微信小程序, 显示最新的英雄联盟视频; 可以模糊查询游戏,雷达图形统计游戏能力,统计最近常用的英雄。

下载地址:工程代码

作者 east
资讯读书 3月 20,2021

仿微信读书微信小程序

读书类的小程序是很常用的应用,而且很方便在微信群分享。

小程序的功能是图文混排的列表,用户可以搜索书单。点击列表进入书的详细页。

<view class="container">
    <loading hidden="{{hidden}}">加载中...</loading>
    <view class="book-detail">
        <image class="book-image" style="width:300px;height:393px;display:block;margin:10px auto;background-color: #eeeeee;" scaleToFill  src="{{info.Image}}"></image>
        <view class="books-item-txt">
            <view class="txt-title">
                <text>{{info.Title}}</text>
            </view>
            <view>
                <text style="color:#aaa;clear:both;">Published in {{info.Year}}</text>
            </view>
            <view class="txt-source">
                <text>{{info.SubTitle}}</text>
            </view>
            <view class="books-item-author">
                <image class="avatar" style="width:20px;height:20px;" aspectFit src="https://cdn1.iconfinder.com/data/icons/user-pictures/100/unknown-128.png"></image>
                <view class="author-txt">
                    <text style="margin-top:5px;">{{info.Author}}</text>
                    
                </view>
            </view>
        </view>

        <navigator class="book-download" url="{{info.Download}}">
            <icon type="download" size="30" class="download-icon"/>
            <text>Download This Book</text>
        </navigator>
    </view>
</view>

var API = require(‘../../utils/api.js’);
//获取应用实例
Page({
data: {
info:{},
hidden:false
},
onLoad: function (e) {
console.log(e)
this.fetchBookData(e.id)
},
//获取微信精选
fetchBookData: function(id){
let self = this;
wx.request({
url: API.ebookinfo(id),
success: function (res) {
self.setData({
info:res.data,
hidden: true
})
}
})
}
})

下载地址:工程

作者 east
Java 3月 16,2021

空间地理算法工具类

空间地理,常常需要计算2个地址是否是同个地址,2个坐标之间的直线距离。下面把这些常用算法进行封装。 2个地址是否是同个地址 的相似度算法,采用 余弦相似度用向量空间中两个向量夹角的余弦值作为衡量两个个体间差异的大小。相比距离度量,余弦相似度更加注重两个向量在方向上的差异,而非距离或长度上。 

public final class ScoreUtil {
    private static Logger log = LoggerFactory.getLogger(ScoreUtil.class);

    /** 乡镇附属词 */
    private static final String WORD_TYPE_4 = "乡,镇,街道办事处,街道办,街道";

    /** 社区居委附属词 */
    private static final String WORD_TYPE_5 = "社区,社区居民委员会,村民委员会,社区居村委,社区居委,居村委,居委会,村委会,委员会,居委,村委,委会,村";

    /** 路附属词 */
    private static final String WORD_TYPE_6 = "道路,路,大街,街,巷";

    /** 自定义地址唯一组合 */
    private static final String[] UNION_SIMILAR = { "1&2&4&6", "1&3&6", "1&3" };

    /**
     * 
     */
    private ScoreUtil() {
    }

    /**
     * 计算两个地址的相似度
     * 
     * @param sourceAddr 源地址
     * @param standAddr 标准地址
     * @return
     * @throws Exception
     */
    public static long score(String sourceAddr, String standAddr) throws Exception {
        Map<Integer, String> sourceWords = WordSolrUtil.splitAddressWordNames(sourceAddr);
        Map<Integer, String> standWords = WordSolrUtil.splitAddressWordNames(standAddr);
        if (standWords.size() == 0 || sourceWords.size() == 0) {
            return 0L;
        }
        Integer sourceWordMaxType = Collections.max(sourceWords.keySet());
        Integer standWordMaxType = Collections.max(standWords.keySet());
        String sourceWordStr = null;
        String standWordStr = null;
        // 命中的词类型组合
        StringBuilder matchType = new StringBuilder();
        for (int i = (standWordMaxType > sourceWordMaxType ? standWordMaxType : sourceWordMaxType); i >= 1; i--) {
            sourceWordStr = sourceWords.get(i);
            standWordStr = standWords.get(i);
            if (i == 4) {
                if (StringUtils.isNotBlank(sourceWordStr)) {
                    sourceWords.put(i, sourceWordStr.replaceFirst("[" + WORD_TYPE_4 + "]$", "") + "乡镇");
                }
                if (StringUtils.isNotBlank(standWordStr)) {
                    standWords.put(i, standWordStr.replaceFirst("[" + WORD_TYPE_4 + "]$", "") + "乡镇");
                }
            } else if (i == 5) {
                if (StringUtils.isNotBlank(sourceWordStr)) {
                    sourceWords.put(i, sourceWordStr.replaceAll("[" + WORD_TYPE_5 + "]", "") + "居村委");
                }
                if (StringUtils.isNotBlank(standWordStr)) {
                    standWords.put(i, standWordStr.replaceAll("[" + WORD_TYPE_5 + "]", "") + "居村委");
                }
            } else if (i == 6) {
                if (StringUtils.isNotBlank(sourceWordStr)) {
                    sourceWords.put(i, sourceWordStr.replaceFirst("[" + WORD_TYPE_6 + "]$", "") + "大道");
                }
                if (StringUtils.isNotBlank(standWordStr)) {
                    standWords.put(i, standWordStr.replaceFirst("[" + WORD_TYPE_6 + "]$", "") + "大道");
                }
            }

            // 字符串相似度大于0.9,则标记为命中
            if (strSimilarMatch(sourceWords.get(i), standWords.get(i)) >= 0.9) {
                matchType.append(i).append("&");
            }
        }

        // 用于比较的地址字符串
        StringBuilder sourceAddrCompareStr = new StringBuilder();
        StringBuilder standAddrCompareStr = new StringBuilder();
        filterAddrToEquivalent(sourceWords, standWords, sourceWordMaxType, standWordMaxType, matchType,
                sourceAddrCompareStr, standAddrCompareStr);
        log.debug("源地址过滤后:" + sourceAddrCompareStr.toString());
        log.debug("标地址过滤后:" + standAddrCompareStr.toString());

        return Math.round(linearSpaceVectorMacth(sourceAddrCompareStr.toString(), standAddrCompareStr.toString()));
    }

    /**
     * 根据配置信息及别名过滤两个地址为等价地址
     * 
     * @param sourceWords
     * @param standWords
     * @param sourceWordMaxType
     * @param standWordMaxType
     * @param matchType
     * @param sourceAddrCompareStr
     * @param standAddrCompareStr
     */
    private static void filterAddrToEquivalent(Map<Integer, String> sourceWords, Map<Integer, String> standWords,
            Integer sourceWordMaxType, Integer standWordMaxType, StringBuilder matchType,
            StringBuilder sourceAddrCompareStr, StringBuilder standAddrCompareStr) {
        // 命中的词
        String[] matchedType = matchType.toString().contains("&") ? matchType.toString().split("&", 0) : new String[0];
        Arrays.sort(matchedType, new Comparator<String>() {

            @Override
            public int compare(String o1, String o2) {
                if (StringUtils.isBlank(o1)) {
                    return 1;
                }
                if (StringUtils.isBlank(o2)) {
                    return -1;
                }
                if (o1.equals(o2)) {
                    return 0;
                }
                return Integer.parseInt(o1) > Integer.parseInt(o2) ? 1 : -1;
            }
        });

        // 根据配置,移除可忽略的词
        for (int i = 0; i < UNION_SIMILAR.length; i++) {
            boolean isMatchedWithConfig = true;
            if (UNION_SIMILAR[i].split("&").length >= matchedType.length) {
                // 判断命中的词组是否与配置指定的一致
                for (String type : matchedType) {
                    if (StringUtils.isNotBlank(type) && Arrays.binarySearch(UNION_SIMILAR[i].split("&"), type) < 0) {
                        isMatchedWithConfig = false;
                        break;
                    }
                }

            } else {
                for (String type : UNION_SIMILAR[i].split("&")) {
                    if (StringUtils.isNotBlank(type) && Arrays.binarySearch(matchedType, type) < 0) {
                        isMatchedWithConfig = false;
                        break;
                    }
                }
                if (isMatchedWithConfig) {
                    matchedType = UNION_SIMILAR[i].split("&");
                }
            }

            if (isMatchedWithConfig && matchedType.length > 0) {
                // 补上缺省的词
                for (int j = Integer.parseInt(matchedType[0]); j <= Integer
                        .parseInt(matchedType[matchedType.length - 1]); j++) {
                    if (Arrays.binarySearch(matchedType, String.valueOf(j)) < 0) {
                        if (sourceWords.keySet().contains(j)) {
                            standWords.put(j, sourceWords.get(j));
                        } else if (standWords.keySet().contains(j)) {
                            sourceWords.put(j, standWords.get(j));
                        }
                    }
                }
            }
        }

        // 组装地址词组为字符串信息
        for (int i = 1; i <= (standWordMaxType > sourceWordMaxType ? standWordMaxType : sourceWordMaxType); i++) {
            sourceAddrCompareStr.append(StringUtils.trimToEmpty(sourceWords.get(i)));
            standAddrCompareStr.append(StringUtils.trimToEmpty(standWords.get(i)));
        }
    }

    /**
     * 线性空间几何
     * 
     * @param source
     * @param target
     * @return
     */
    private static double linearSpaceVectorMacth(String source, String target) {
        Set<Character> set = new HashSet<Character>();
        for (char c : source.toCharArray()) {
            set.add(c);
        }
        for (char c : target.toCharArray()) {
            set.add(c);
        }
        Character[] targetA = set.toArray(new Character[] {});
        int[] sourceArg = parseAddrToSpaceVector(targetA, source);
        int[] targetArg = parseAddrToSpaceVector(targetA, target);
        return cos(sourceArg, targetArg) * 100;
    }

    /**
     * 计算空间向量夹角cos值
     * 
     * @param point1
     * @param point2
     * @return
     */
    private static double cos(int[] point1, int[] point2) {
        int count = 0;
        for (int i = 0; i < point1.length; i++) {
            count += point1[i] * point2[i];
        }

        double a1 = 0.0;
        for (int i = 0; i < point1.length; i++) {
            a1 += point1[i] * point1[i];
        }
        a1 = Math.sqrt(a1);

        double a2 = 0.0;
        for (int i = 0; i < point2.length; i++) {
            a2 += point2[i] * point2[i];
        }
        a2 = Math.sqrt(a2);

        return count / (a1 * a2);
    }

    /**
     * 解析地址为空间向量坐标
     * 
     * @param tag
     * @param str
     * @return
     */
    private static int[] parseAddrToSpaceVector(Character[] tag, String str) {
        int[] rs = new int[tag.length];
        int count = 0;
        int i = 0;
        for (char t : tag) {
            count = 0;
            for (char c : str.toCharArray()) {
                if (t == c) {
                    count++;
                }
            }
            rs[i] = count;
            i++;
        }
        return rs;
    }

    /**
     * 字符串相似度匹配
     * 
     * @param compare
     * @param to
     * @return
     */
    public static double strSimilarMatch(String compare, String to) {
        if (StringUtils.isBlank(compare) || StringUtils.isBlank(to)) {
            return 0;
        }
        // 字符串相似度比较
        int len1 = compare.length();
        int len2 = to.length();

        int[][] dif = new int[len1 + 1][len2 + 1];
        for (int a = 0; a <= len1; a++) {
            dif[a][0] = a;
        }
        for (int a = 0; a <= len2; a++) {
            dif[0][a] = a;
        }

        int temp;
        for (int i = 1; i <= len1; i++) {
            for (int j = 1; j <= len2; j++) {
                if (compare.charAt(i - 1) == to.charAt(j - 1)) {
                    temp = 0;
                } else {
                    temp = 1;
                }
                dif[i][j] = min(dif[i - 1][j - 1] + temp, dif[i][j - 1] + 1, dif[i - 1][j] + 1);
            }
        }
        return 1 - (double) dif[len1][len2] / Math.max(compare.length(), to.length());
    }

    /**
     * 查找集合最小值
     * 
     * @param is
     * @return
     */
    private static int min(int... is) {
        int min = Integer.MAX_VALUE;
        for (int i : is) {
            if (min > i) {
                min = i;
            }
        }
        return min;
    }
}
作者 east

1 2 … 4 下一个

关注公众号“大模型全栈程序员”回复“小程序”获取1000个小程序打包源码。回复”chatgpt”获取免注册可用chatgpt。回复“大数据”获取多本大数据电子书

标签

AIGC AI创作 bert chatgpt github GPT-3 gpt3 GTP-3 hive mysql O2O tensorflow UI控件 不含后台 交流 共享经济 出行 图像 地图定位 外卖 多媒体 娱乐 小程序 布局 带后台完整项目 开源项目 搜索 支付 效率 教育 日历 机器学习 深度学习 物流 用户系统 电商 画图 画布(canvas) 社交 签到 联网 读书 资讯 阅读 预订

官方QQ群

小程序开发群:74052405

大数据开发群: 952493060

近期文章

  • 详解Python当中的pip常用命令
  • AUTOSAR如何在多个供应商交付的配置中避免ARXML不兼容?
  • C++thread pool(线程池)设计应关注哪些扩展性问题?
  • 各类MCAL(Microcontroller Abstraction Layer)如何与AUTOSAR工具链解耦?
  • 如何设计AUTOSAR中的“域控制器”以支持未来扩展?
  • C++ 中避免悬挂引用的企业策略有哪些?
  • 嵌入式电机:如何在低速和高负载状态下保持FOC(Field-Oriented Control)算法的电流控制稳定?
  • C++如何在插件式架构中使用反射实现模块隔离?
  • C++如何追踪内存泄漏(valgrind/ASan等)并定位到业务代码?
  • C++大型系统中如何组织头文件和依赖树?

文章归档

  • 2025年6月
  • 2025年5月
  • 2025年4月
  • 2025年3月
  • 2025年2月
  • 2025年1月
  • 2024年12月
  • 2024年11月
  • 2024年10月
  • 2024年9月
  • 2024年8月
  • 2024年7月
  • 2024年6月
  • 2024年5月
  • 2024年4月
  • 2024年3月
  • 2023年11月
  • 2023年10月
  • 2023年9月
  • 2023年8月
  • 2023年7月
  • 2023年6月
  • 2023年5月
  • 2023年4月
  • 2023年3月
  • 2023年1月
  • 2022年11月
  • 2022年10月
  • 2022年9月
  • 2022年8月
  • 2022年7月
  • 2022年6月
  • 2022年5月
  • 2022年4月
  • 2022年3月
  • 2022年2月
  • 2022年1月
  • 2021年12月
  • 2021年11月
  • 2021年9月
  • 2021年8月
  • 2021年7月
  • 2021年6月
  • 2021年5月
  • 2021年4月
  • 2021年3月
  • 2021年2月
  • 2021年1月
  • 2020年12月
  • 2020年11月
  • 2020年10月
  • 2020年9月
  • 2020年8月
  • 2020年7月
  • 2020年6月
  • 2020年5月
  • 2020年4月
  • 2020年3月
  • 2020年2月
  • 2020年1月
  • 2019年7月
  • 2019年6月
  • 2019年5月
  • 2019年4月
  • 2019年3月
  • 2019年2月
  • 2019年1月
  • 2018年12月
  • 2018年7月
  • 2018年6月

分类目录

  • Android (73)
  • bug清单 (79)
  • C++ (34)
  • Fuchsia (15)
  • php (4)
  • python (43)
  • sklearn (1)
  • 云计算 (20)
  • 人工智能 (61)
    • chatgpt (21)
      • 提示词 (6)
    • Keras (1)
    • Tensorflow (3)
    • 大模型 (1)
    • 智能体 (4)
    • 深度学习 (14)
  • 储能 (44)
  • 前端 (4)
  • 大数据开发 (488)
    • CDH (6)
    • datax (4)
    • doris (30)
    • Elasticsearch (15)
    • Flink (78)
    • flume (7)
    • Hadoop (19)
    • Hbase (23)
    • Hive (40)
    • Impala (2)
    • Java (71)
    • Kafka (10)
    • neo4j (5)
    • shardingsphere (6)
    • solr (5)
    • Spark (99)
    • spring (11)
    • 数据仓库 (9)
    • 数据挖掘 (7)
    • 海豚调度器 (10)
    • 运维 (34)
      • Docker (3)
  • 小游戏代码 (1)
  • 小程序代码 (139)
    • O2O (16)
    • UI控件 (5)
    • 互联网类 (23)
    • 企业类 (6)
    • 地图定位 (9)
    • 多媒体 (6)
    • 工具类 (25)
    • 电商类 (22)
    • 社交 (7)
    • 行业软件 (7)
    • 资讯读书 (11)
  • 嵌入式 (70)
    • autosar (63)
    • RTOS (1)
    • 总线 (1)
  • 开发博客 (16)
    • Harmony (9)
  • 技术架构 (6)
  • 数据库 (32)
    • mongodb (1)
    • mysql (13)
    • pgsql (2)
    • redis (1)
    • tdengine (4)
  • 未分类 (6)
  • 程序员网赚 (20)
    • 广告联盟 (3)
    • 私域流量 (5)
    • 自媒体 (5)
  • 量化投资 (4)
  • 面试 (14)

功能

  • 登录
  • 文章RSS
  • 评论RSS
  • WordPress.org

All Rights Reserved by Gitweixin.本站收集网友上传代码, 如有侵犯版权,请发邮件联系yiyuyos@gmail.com删除.