‘新闻杂谈’ 分类下的所有文章
202411 月20

网站被攻击了

来源IP :114.226.31.36,一直刷我流量,一个小时干掉8G。

还好我有短信提醒。

昨天把这个IP拉黑后,今天又换成 114.226.31.26 来刷,只好把这个网段拉黑,然后持续监测。

不知道对方什么目的,来搞我这个小网站。

20248 月26

中国历史一图流

转自:

20208 月21

BudWk 国产开源Java微服务分布式框架在智慧燃气行业的应用

燃气公司现状及痛点

  • 燃气表品牌多、型号多、计费类型多,厂家附送系统各自独立且无法自动对账,导致账目误差时有出现,实际经营情况无法实时掌握。
  • 物联网智能表具原来越多,物联网设备本身的安全监测是当前的核心问题,且因设备厂家、型号多样化,设备的统一接入、监控就尤为重要。
  • 从市场拓展到客户服务无法全流程业务管控、联动和监督,导致物资储备、施工安排、工程监督等无法根据实际情况实时管控,用户开户、移表等服务无法高效响应和调度。

BudWk微服务解决方案

  • IC卡表的统一集成

使用 WPF + CefSharp 技术,C/S客户端 + B/S浏览器的组合,利用客户端实现IC卡读写器的集成开发,实现IC卡表的读写功能,利用B/S浏览器,将营收系统嵌入浏览器,实现WEB营收业务代码热更新、数据统一管理等功能。

  • 物联网表的统一集成

抽象设备接入层,实现电信AEP平台、移动OneNET、厂家物联网平台等平台接入,实现 NB-IOT/MQTT/HTTP 等协议的适配和转换,将各表厂繁杂不一的数据格式转换为本平台统一数据格式,并利用规则引擎技术,实现数据的智能化处理。

  • 计费类型的统一集成

系统内置预付费、后付费、表端计费等计费类型,支持“购气/退气”和“充值/退费”等业务形态,支持阶梯计价、区域计价等价格规则。

  • 工单系统的统一集成

燃气报装、报修、维修、安检等业务流程标准化、制度化,通过流程配置、节点配置、权限配置等,实现业务工单的动态分配和统一管理。

后端技术框架

采用 BudWk 国产微服务分布式架构,基于 nutzboot + dubbo + nacos + druid 技术体系,核心框架为国产开源框架 nutzboot,采用 Sa-Token权限系统及JWT。根据业务划分微服务模块,如:

  • Sys – 系统及权限模块
  • Cms – 内容及资讯模块
  • Wx – 微信服务模块
  • Dev – 物联网表接入模块
  • Gas – 营收业务模块
  • WebAPI – 后端服务API模块
  • OpenAPI – 第三方服务API模块

前端技术框架

采用 Vite + Vue3 + ElementPlus 常用组合,前后端分离开发模式,封装集成多语言、路由、权限控制、文件上传等功能。

BudWk微服务分布式框架介绍

BudWk(原名NutzWk)发展自2010年,2012年开始用于商业项目,至今已服务于全国各地公司大大小小数千个项目,行业涉及政务、电商、物联网等,随着个人经验积累及从事行业的不同分别发布了1.x至8.x多个版本,您可以根据项目规模选择不同版本。本项目案例众多,省厅级项目、市级平台、大数据项目、电商平台、物联网平台等等。

https://demo.budwk.com V8演示地址

https://nutzwk.wizzer.cn V5演示地址

https://budwk.com 官网及开发指南

20177 月4

分享:微信电子导航DEMO

后台JAVA代码:

 

package cn.wizzer.app.web.modules.controllers.front.wx;

import cn.wizzer.app.web.commons.base.Globals;
import cn.wizzer.app.wx.modules.services.WxAddressService;
import cn.wizzer.app.wx.modules.services.WxConfigService;
import org.nutz.dao.Cnd;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.json.Json;
import org.nutz.lang.Lang;
import org.nutz.lang.Strings;
import org.nutz.lang.util.NutMap;
import org.nutz.log.Log;
import org.nutz.log.Logs;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.weixin.at.impl.MemoryJsapiTicketStore;
import org.nutz.weixin.spi.WxApi2;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

/**
 * Created by wizzer on 2017/6/27.
 */
@IocBean
@At("/public/wx/add")
public class AddController {
    private static final Log log = Logs.get();
    @Inject
    private WxConfigService wxConfigService;
    @Inject
    private WxAddressService wxAddressService;

    @At("/index/?")
    @Ok("beetl:/public/add/index.html")
    public void index(String wxid,HttpServletRequest req, HttpSession session) {
        WxApi2 wxApi2 = wxConfigService.getWxApi2(wxid);
        if (Lang.isEmpty(Globals.memoryJsapiTicketStore.get(wxid))) {
            Globals.memoryJsapiTicketStore.put(wxid, new MemoryJsapiTicketStore());
        }
        MemoryJsapiTicketStore memoryJsapiTicketStore = Globals.memoryJsapiTicketStore.get(wxid);
        wxApi2.setJsapiTicketStore(memoryJsapiTicketStore);
        String url = "http://" + Globals.AppDomain + Globals.AppBase + "/public/wx/add/index/"+wxid;
        NutMap jsConfig = wxApi2.genJsSDKConfig(url, "getLocation");

        req.setAttribute("list", wxAddressService.query(Cnd.orderBy().asc("opAt")));
        req.setAttribute("jsConfig", Json.toJson(jsConfig));
    }
}

前台代码:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>电子导航</title>

    <link rel="stylesheet" type="text/css" href="${base!}/assets/public/wx/add/css/css.css"/>
    <link rel="stylesheet" href="${base!}/assets/public/wx/add/css/zepto.mdatetimer.css">
    <meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport"/>
    <meta content="yes" name="apple-mobile-web-app-capable"/>
    <meta content="black" name="apple-mobile-web-app-status-bar-style"/>
    <meta name="format-detection" content="telephone=no"/>
    <meta name="format-detection" content="email=no"/>
    <meta name="msapplication-tap-highlight" content="no">
    <meta charset="utf-8">
    <script type="text/javascript">
        var base = '${base!}';
    </script>
    <script type="text/javascript" src="${base!}/assets/public/wx/add/js/zepto.js"></script>
    <script type="text/javascript" src="${base!}/assets/public/wx/add/js/zepto.mdatetimer.js"></script>
    <script src="https://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>

</head>
<body>
<header class="ds-head">
    <h1>公司检索</h1>
</header>
<div class="time">
    <div class="time-li round-a"><span>公司名称:</span><input id="name"  type="text"
                                                          value=""/></div>
    <div class="btn"><input id="btn" type="button" value="立即查询" class="round-a"/></div>

    <div class="time-li round-a"><span>当前位置:</span><input id="longitude"  type="text"
                                                          value="" readonly/><input id="latitude"  type="text"
                                                                                    value="" readonly/></div>
</div>
<ul class="earn">
    <%for(o in list){%>
    <li class="earn-li">
        <dl>
            <dt class="cf2"><span class="earn-lil">${oLP.index}、${o.name} </span></dt>
            <dd class="cf2"><span class="earn-lil">lng:${o.lng}, lat:${o.lat}</span></dd>
            <dd class="cf2">
                <span><button onclick="goTo('walk','${o.name}','${o.lng}','${o.lat}');">步行</button></span>
                <span><button onclick="goTo('drive','${o.name}','${o.lng}','${o.lat}');">驾车</button></span>
                </dd>
            </dl>
        </li>
    <%}elsefor{%>
    没有检索到结果
    <%}%>
</ul>
<script language="JavaScript">
    function goTo(type,name,lng,lat) {
        var longitude=$("#longitude").val();
        var latitude=$("#latitude").val();
        window.location.href="http://apis.map.qq.com/uri/v1/routeplan?type="+type+"&from=我的位置&fromcoord="+latitude+","+longitude+"&to="+name+"&tocoord="+lat+","+lng+"&policy=1&referer=电子导航";

    //window.location.href="http://api.map.baidu.com/direction?origin=latlng:"+latitude+","+longitude+"|name:我的位置&destination=latlng:"+lat+","+lng+"|name:"+name+"&mode=driving&region=合肥&output=html&src=电子导航";
    }
    wx.config(${jsConfig});
    wx.ready(function(){
        wx.getLocation({
            type: 'gcj02', // 默认为wgs84的gps坐标,如果要返回直接给openLocation用的火星坐标,可传入'gcj02'
            success: function (res) {
                var latitude = res.latitude; // 纬度,浮点数,范围为90 ~ -90
                var longitude = res.longitude; // 经度,浮点数,范围为180 ~ -180。
                var speed = res.speed; // 速度,以米/每秒计
                var accuracy = res.accuracy; // 位置精度
                $("#latitude").val(latitude);
                $("#longitude").val(longitude);
            }
        });
    });
</script>
</body>
</html>
20166 月17

新标致408:刷发动机及变速箱程序实现刹车控制发动机启停

标致408  1.8L自豪版 2015年4月购

一、刷发动机及变速箱程序流程

1、等待发动机冷却

2、刷程序(发动机和变速箱程序要同时升级)

整个过程一个半小时,师傅说刷程序是连法国服务器的,因网络原因可能会有几率刷成“砖”,成砖车就比较杯具了要放4s店一夜等修复。

因为时差的原因,法国服务器周末可能停机,所以想刷程序的车友可以在 周一下午至周五 到店,刷程序是免费的。

我是一次性成功的,比较幸运~~~

 

二、刷过之后的效果

1、爽

2、非常爽

3、特点就是轻踩刹车停下来的时候,启停不会工作,车停下来后如果刹车踩到底发动机也还会停止

4、重踩刹车(刹车踩到底)停车,发动机直接停止

5、如果开空调的话,最好还是关闭启停吧,因为发动机停止后还会自动开启

 

堵车的时候可以轻踩刹车停车,如果等的时间比较长,这个时候把刹车踩到底发动机就停了,真正的智能启停,启停掌握在驾驶者脚上,爽啊。。

以前是上车就把启停功能关闭,现在再也不用那么麻烦了。。。

 

合肥标致新408车友群 :163280775

下面是车友分享的演示视频:

20165 月18

Node.js 企业级开发框架

基于Sails.js MVC框架,路由自动映射,完善的权限控制体系,优美的后台界面。

集成最基础的通用功能:

系统(机构管理、用户管理、角色管理、菜单管理、定时任务、数据库备份、IP访问控制、登录日志等)

CMS(站点管理、栏目管理、内容管理、广告及链接等)

微信(会员列表、微信消息、群发消息、自动回复、关键词回复、帐号配置、菜单配置等)

 

演示地址:http://www.nodeshop.cn

联系方式:QQ  1162-4317   (备注nodejs)

 

界面截图:

QQ截图20160518095645

2

201511 月20

Node.js:集成百度编辑器的上传功能

Ueditor1.4.3.1版本,仅贴了图片上传代码,其他自己加。。。

/**
 * Created by root on 11/16/15.
 */
var fs = require('fs-extra');
var moment = require("moment");
module.exports = {
  index: function (req, res) {
    if (req.session.auth && !req.session.user.disabled) {
      var action = req.query.action;
      //加载配置文件
      fs.readFile(sails.config.appPath + '/assets/plugins/ueditor/node/config.json', 'utf8', function (err, config_txt) {
        var config = JSON.parse(config_txt);
        switch (action) {
          case 'config':
            return res.send(config_txt);
            break;
          case 'uploadimage':

            req.file('Filedata').upload({
              maxBytes: config.imageMaxSize
            }, function (err, uploadedFiles) {
              if (err)return res.json({state: sails.__('file.upload.err')});
              var filename = uploadedFiles[0].filename;
              var type = uploadedFiles[0].type;
              var fd = uploadedFiles[0].fd;
              var size = uploadedFiles[0].size;
              console.log('uploadimage:::' + JSON.stringify(uploadedFiles));
              if(config.imageAllowFiles.indexOf(fd.substring(fd.lastIndexOf('.')))<0)
                return res.json({state: sails.__('file.upload.err')});
              var file = fd.substring(fd.lastIndexOf('/'));
              var newPath = sails.config.system.AppBase + sails.config.system.UploadPath + "/image/" + moment().format("YYYYMMDD") + file;

              fs.copy(fd, sails.config.appPath + newPath, function (err) {
                if (err)return res.json({state: sails.__('file.upload.err')});
                return res.json({state: 'SUCCESS', url: newPath, title: filename, original: filename, type: type, size: size});
              })

            });
            break;
        }
      });
    } else {
      return res.json({state: sails.__('private.forbidden'), url: '', title: '', original: '', type: '', size: 0});
    }
  }
};
20156 月11

Nutz:集成 CXF Webservice [通过cxf-servlet.xml配置文件]

pom.xml

	<!--CXF START-->
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-api</artifactId>
            <version>2.7.15</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-frontend-jaxws</artifactId>
            <version>2.7.15</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-bindings-soap</artifactId>
            <version>2.7.15</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-transports-http</artifactId>
            <version>2.7.15</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-ws-security</artifactId>
            <version>2.7.15</version>
        </dependency>
        <dependency>
           <groupId>org.springframework</groupId>
           <artifactId>spring-web</artifactId>
           <version>4.1.5.RELEASE</version>
        </dependency>
        <!--CXF END-->

web.xml

    <servlet>
        <servlet-name>CXFServlet</servlet-name>
        <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>CXFServlet</servlet-name>
        <url-pattern>/webservice/*</url-pattern>
    </servlet-mapping>

cxf-servlet.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:jaxws="http://cxf.apache.org/jaxws"
       xmlns:soap="http://cxf.apache.org/bindings/soap"
       xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/bindings/soap http://cxf.apache.org/schemas/configuration/soap.xsd
http://cxf.apache.org/jaxws
http://cxf.apache.org/schemas/jaxws.xsd">

    <!-- IP地址输入拦截器 -->
    <bean id="ipAddressInInterceptor"
          class="com.auto.webservice.servlet.IpAddressInInterceptor" />

    <jaxws:server id="workflow" serviceClass="com.auto.webservice.server.WorkflowService" address="/workflow">
        <jaxws:serviceBean>
            <bean class="com.auto.webservice.server.WorkflowServiceImpl" />
        </jaxws:serviceBean>
    </jaxws:server>
</beans>

接口类
WorkflowService.java

package com.auto.webservice.server;

import org.nutz.json.Json;

import javax.jws.WebService;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by wizzer on 15-4-13.
 */
@WebService(targetNamespace = "http://server.webservice.auto.com/", name = "workflowServicePortType")
public interface WorkflowService {

    @WebResult(name = "return")
    @Action(input = "urn:start", output = "urn:startResponse")
    @RequestWrapper(localName = "start")
    @WebMethod(action = "urn:start")
    @ResponseWrapper(localName = "startResponse")
    String start(@WebParam(name = "flowKey") String flowKey, @WebParam(name = "userId") String userId);//启动流程
}

实现类

WorkflowServiceImpl.java
package com.auto.webservice.server;

import org.activiti.engine.*;
import org.activiti.engine.form.FormProperty;
import org.activiti.engine.form.StartFormData;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.activiti.engine.task.TaskQuery;
import org.nutz.dao.Dao;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.json.Json;
import org.nutz.json.JsonFormat;
import org.nutz.lang.Strings;
import org.nutz.log.Log;
import org.nutz.log.Logs;
import org.nutz.mvc.Mvcs;

import javax.jws.WebService;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by wizzer on 15-4-13.
 */
@IocBean(name = "workflowService")
@WebService
public class WorkflowServiceImpl implements WorkflowService {
    private final Log log = Logs.get();
    FormService formService=Mvcs.ctx().getDefaultIoc().get(FormService.class);
    IdentityService identityService=Mvcs.ctx().getDefaultIoc().get(IdentityService.class);
    RuntimeService runtimeService=Mvcs.ctx().getDefaultIoc().get(RuntimeService.class);
    TaskService taskService=Mvcs.ctx().getDefaultIoc().get(TaskService.class);
    RepositoryService repositoryService=Mvcs.ctx().getDefaultIoc().get(RepositoryService.class);

    /**
     * 启动一个流程
     *
     * @param flowKey 流程模型key
     * @param userId  用户ID
     * @return
     */
    public String start(String flowKey, String userId) {
        Map<String, Object> map = new HashMap<String, Object>();
        try {
            if (!Strings.isEmpty(userId)) {
                identityService.setAuthenticatedUserId(userId);
            }
            ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(flowKey);
            map.put("errcode", 0);
            map.put("errmsg", "");
            map.put("processInstanceId", processInstance.getId());
        } catch (Exception e) {
            log.error("WebServcice启动流程出错", e);
            map.put("errcode", 1);
            map.put("errmsg", e.getMessage());
        } finally {
            identityService.setAuthenticatedUserId(null);
        }
        return Json.toJson(map, JsonFormat.compact());
    }


}
 
/**
 * IP地址拦截器
 *
 * @author Sunshine
 */

public class IpAddressInInterceptor extends AbstractPhaseInterceptor {
    private final Log log = Logs.get();

    public IpAddressInInterceptor() {
        super(Phase.RECEIVE);
    }

    public void handleMessage(Message message) throws Fault {
        HttpServletRequest request = (HttpServletRequest) message.get(AbstractHTTPDestination.HTTP_REQUEST);
        //获取所有的白名单访问主机
        UserInfoServiceImpl userInfoService = Mvcs.ctx().getDefaultIoc().get(UserInfoServiceImpl.class);
        List hostList = userInfoService.queryHostListByType("w");
        // 取客户端IP地址
        String ipAddress = request.getRemoteAddr();
        // 如果允许访问的集合非空,继续处理,否则认为全部IP地址均合法
        if (!hostList.isEmpty()) {
            boolean contains = false;
            for (ListInfo hostInfo : hostList) {
                log.debug("hostInfo:" + hostInfo.getIpaddress() + "|ipAddress:" + ipAddress);
                if (hostInfo.getIpaddress().equals(ipAddress)) {
                    contains = true;
                    break;
                }
            }
            if (!contains) {
                throw new Fault(new IllegalAccessException("IP address " + ipAddress + " is not allowed"));
            }
        }
    }

}
20151 月28

Nutz:通过Java代码生成表格图片

效果图:

i

源码不解释:

 private void ResultToJpg(List<Map> list, String title, HttpServletResponse response) {
        BufferedImage image;
        int totalrow = list.size();
        int totalcol = 7;
        int imageWidth = 640;
        int rowheight = 40;
        int imageHeight = totalrow * rowheight + 105;
        int startHeight = 20;
        int startWidth = 10;
        int colwidth = (int) ((imageWidth - 20) / totalcol);
        int colwidth2 = (int) ((imageWidth - 20) / (totalcol + 1));
        image = new BufferedImage(imageWidth, imageHeight, BufferedImage.TYPE_INT_RGB);
        Graphics2D graphics = (Graphics2D) image.getGraphics();
        graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        graphics.setColor(Color.WHITE);
        graphics.fillRect(0, 0, imageWidth, imageHeight);
        Font font = new Font("微软雅黑", Font.BOLD, 20);
        graphics.setFont(font);
        graphics.setColor(new Color(112, 48, 158));
        graphics.drawString(Strings.sNull(title), startWidth, startHeight + 10);
        font = new Font("微软雅黑", Font.PLAIN, 13);
        graphics.setColor(new Color(99, 99, 99));
        graphics.setFont(font);
        String subtitle1 = "欢迎访问";
        graphics.drawString(subtitle1, startWidth, startHeight + 30);
        font = new Font("Arial, Helvetica, sans-serif", Font.BOLD, 13);
        graphics.setColor(new Color(112, 48, 158));
        graphics.setFont(font);
        String subtitle2 = "inm.xuetang.cn";
        graphics.drawString(subtitle2, startWidth + 60, startHeight + 30);
        font = new Font("微软雅黑", Font.PLAIN, 13);
        graphics.setColor(new Color(99, 99, 99));
        graphics.setFont(font);
        String subtitle3 = "冲榜、制榜!";
        graphics.drawString(subtitle3, startWidth + 165, startHeight + 30);
        //画首行
        graphics.setColor(new Color(112, 48, 158));
        graphics.fillRect(startWidth, startHeight + rowheight, imageWidth - 20, rowheight);
        font = new Font("微软雅黑", Font.PLAIN, 12);
        graphics.setColor(Color.WHITE);
        graphics.setFont(font);
        graphics.drawString("#", startWidth + 10, startHeight + rowheight * 2 - 15);
        graphics.drawString("公众号", startWidth + colwidth - 10, startHeight + rowheight * 2 - 15);
        //画表头
        String[] headCells = {"发布", "总阅读数", "  头条", " 平均 ", "总点赞数", " WCI"};
        for (int m = 0; m < headCells.length; m++) {
            graphics.drawString(headCells[m].toString(), startWidth + colwidth2 * m + colwidth * 2, startHeight + rowheight * 2 - 15);
        }
        //画行
        for (int j = 0; j < totalrow; j++) {
            if (j % 2 == 0) {
                graphics.setColor(new Color(255, 255, 255));
            } else {
                graphics.setColor(new Color(238, 238, 238));
            }
            graphics.fillRect(startWidth, startHeight + (j + 1) * rowheight + 40, imageWidth - 20, startHeight + (j + 1) * rowheight);
            font = new Font("微软雅黑", Font.BOLD, 12);
            graphics.setColor(new Color(112, 48, 158));
            graphics.setFont(font);
            graphics.drawString(String.valueOf(j + 1), startWidth + 10, startHeight + (j + 3) * rowheight - 15);
            Map map = list.get(j);
            font = new Font("微软雅黑", Font.PLAIN, 12);
            graphics.setColor(new Color(0, 0, 0));
            graphics.setFont(font);
            graphics.drawString(Strings.sNull(map.get("wx_nickname")), startWidth + (colwidth / 2) - 10, startHeight + (j + 3) * rowheight - 25);
            graphics.drawString(Strings.sNull(map.get("wx_name")), startWidth + (colwidth / 2) - 10, startHeight + (j + 3) * rowheight - 10);
            graphics.drawString(Strings.sNull(map.get("url_times")) + "/" + Strings.sNull(map.get("url_num")), startWidth + colwidth2 + colwidth + 10, startHeight + (j + 3) * rowheight - 15);
            if (NumberUtils.toInt(Strings.sNull(map.get("url_num_10w"))) > 0) {
                String readnum_all = Strings.sNull(map.get("readnum_all"));
                int t = NumberUtils.toInt(readnum_all.substring(readnum_all.length() - 4, readnum_all.length() - 3));
                if (t > 0) {
                    readnum_all = readnum_all.substring(0, readnum_all.length() - 4) + "." + String.valueOf(t);
                } else {
                    readnum_all = readnum_all.substring(0, readnum_all.length() - 4);
                }
                graphics.drawString(readnum_all + "万+", startWidth + colwidth2 + colwidth * 2 + 5, startHeight + (j + 3) * rowheight - 15);
            } else {
                graphics.drawString(Strings.sNull(map.get("readnum_all")), startWidth + colwidth2 + colwidth * 2 + 5, startHeight + (j + 3) * rowheight - 15);
            }
            if (NumberUtils.toInt(Strings.sNull(map.get("url_times_readnum"))) > 100000) {
                String url_times_readnum = Strings.sNull(map.get("url_times_readnum"));
                int t = NumberUtils.toInt(url_times_readnum.substring(url_times_readnum.length() - 4, url_times_readnum.length() - 3));
                if (t > 0) {
                    url_times_readnum = url_times_readnum.substring(0, url_times_readnum.length() - 4) + "." + String.valueOf(t);
                } else {
                    url_times_readnum = url_times_readnum.substring(0, url_times_readnum.length() - 4);
                }
                graphics.drawString(url_times_readnum+"万+", startWidth + colwidth2 + colwidth * 3 - 5, startHeight + (j + 3) * rowheight - 15);
            } else {
                graphics.drawString(Strings.sNull(map.get("url_times_readnum")), startWidth + colwidth2 + colwidth * 3 - 5, startHeight + (j + 3) * rowheight - 15);
            }
            if (NumberUtils.toInt(Strings.sNull(map.get("readnum_av"))) > 100000) {
                String readnum_av = Strings.sNull(map.get("readnum_av"));
                int t = NumberUtils.toInt(readnum_av.substring(readnum_av.length() - 4, readnum_av.length() - 3));
                if (t > 0) {
                    readnum_av = readnum_av.substring(0, readnum_av.length() - 4) + "." + String.valueOf(t);
                } else {
                    readnum_av = readnum_av.substring(0, readnum_av.length() - 4);
                }
                graphics.drawString(readnum_av+"万+", startWidth + colwidth2 + colwidth * 4 - 15, startHeight + (j + 3) * rowheight - 15);
            } else {
                graphics.drawString(Strings.sNull(map.get("readnum_av")), startWidth + colwidth2 + colwidth * 4 - 15, startHeight + (j + 3) * rowheight - 15);

            }
            graphics.drawString(Strings.sNull(map.get("likenum_all")), startWidth + colwidth2 + colwidth * 5 - 20, startHeight + (j + 3) * rowheight - 15);
            graphics.drawString(Strings.sNull(map.get("wci")), startWidth + colwidth2 + colwidth * 6 - 40, startHeight + (j + 3) * rowheight - 15);
        }
        //末行
        graphics.setColor(Color.WHITE);
        graphics.fillRect(startWidth, startHeight + (totalrow + 1) * rowheight + 40, imageWidth - 20, startHeight + (totalrow + 1) * rowheight);
        try {
            response.setContentType("image/png");
            OutputStream out = response.getOutputStream();
            ImageIO.write(image, "png", out);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

 

20151 月3

微信:最近开发了个微信弹幕软件

关注微信,发送弹幕到电影院大屏幕,后台有审核和黑名单功能。

弹幕字体随机、颜色随机、大小随机、位置随机,都可以设置。

测试效果和当天影院现场图片:

1 2 3

201411 月14

Java:数字补零

String str = String.format(“%010d”, 1212);

201411 月10

Temp

ComboIocLoader loader = new ComboIocLoader(
new String[]{
“*org.nutz.ioc.loader.json.JsonLoader”, “ioc/”,
“*org.nutz.ioc.loader.annotation.AnnotationIocLoader”, “cn.xuetang”}
);
ioc = new NutIoc(loader);
dao = ioc.get(Dao.class);

 

201411 月10

Mysql:截取字符串

SELECT SUBSTRING_INDEX(SUBSTRING(url,LOCATE(“sn=”,url)+3),’&’,1),url FROM wx_kw_url_1111

20148 月25

Nutz:代码生成器开源了

项目地址: https://github.com/Wizzercn/NutzCodematic

 

Nutz 代码生成器:

可以生成Pojo类、Action类;

支持MySQL、Oracle、MS SQL2000、ODBC等;

classes是在jdk1.7下编译,可以直接双击 run.bat 运行。

迟迟没放出来的原因是代码写的太烂……

20144 月8

Nutz:结合Jedis实现Redis消息订阅和缓存队列(支持自动重连)

仅作参考。
编辑配置Nutz redis配置文件:

var ioc = {
        jedisConfig : {
            type : 'cn.xuetang.common.redis.JedisConfig',
            fields : {
                maxTotal : 200,
                maxIdle : 10,
                maxWaitMillis:10001,
                testOnBorrow:true,
                redisUrl:'127.0.0.1',
                redisPort:6379,
                redisTimeout:1000
            }
        }
}
package cn.xuetang.common.redis;

/**
 * Created by Wizzer on 14-4-8.
 */
public class JedisConfig {
    private int maxTotal;
    private int maxIdle;
    private int maxWaitMillis;
    private boolean testOnBorrow;
    private String redisUrl;
    private int redisPort;
    private int redisTimeout;//redis断开后自动重新连接间隔时间

    public int getMaxTotal() {
        return maxTotal;
    }

    public void setMaxTotal(int maxTotal) {
        this.maxTotal = maxTotal;
    }

    public int getMaxIdle() {
        return maxIdle;
    }

    public void setMaxIdle(int maxIdle) {
        this.maxIdle = maxIdle;
    }

    public int getMaxWaitMillis() {
        return maxWaitMillis;
    }

    public void setMaxWaitMillis(int maxWaitMillis) {
        this.maxWaitMillis = maxWaitMillis;
    }

    public boolean isTestOnBorrow() {
        return testOnBorrow;
    }

    public void setTestOnBorrow(boolean testOnBorrow) {
        this.testOnBorrow = testOnBorrow;
    }

    public String getRedisUrl() {
        return redisUrl;
    }

    public void setRedisUrl(String redisUrl) {
        this.redisUrl = redisUrl;
    }

    public int getRedisPort() {
        return redisPort;
    }

    public void setRedisPort(int redisPort) {
        this.redisPort = redisPort;
    }

    public int getRedisTimeout() {
        return redisTimeout;
    }

    public void setRedisTimeout(int redisTimeout) {
        this.redisTimeout = redisTimeout;
    }
}

Nutz入口类加载配置文件,config路径:

@Modules(scanPackage=true)
@Ok("raw")
@Fail("http:500")
@IocBy(type=ComboIocProvider.class,args={
	"*org.nutz.ioc.loader.json.JsonLoader","config",
	"*org.nutz.ioc.loader.annotation.AnnotationIocLoader","cn.xuetang"})
@SetupBy(value=StartSetup.class)
@UrlMappingBy(value=UrlMappingSet.class)
public class MainModule {
}

初始化配置参数,新建订阅消息处理线程:

    public static JedisConfig REDIS_CONFIG;
    //声明全局的redis连接池
    public static ShardedJedisPool SHARDEDJEDIS_POOL=null;
    public static JedisPool JEDIS_POOL=null;

    public static void InitRedisConfig() {//初始化redis
        REDIS_CONFIG = Mvcs.ctx.getDefaultIoc().get(JedisConfig.class);
        JedisPoolUtil jedisPoolUtil=new JedisPoolUtil();
        SHARDEDJEDIS_POOL = jedisPoolUtil.getShardedJedisPool();
        JEDIS_POOL = jedisPoolUtil.getJedisPool();
    }

    new Thread(Mvcs.getIoc().get(ImageTask.class)).start();

 
创建Jedis连接池工具类:

package cn.xuetang.common.redis;

import cn.xuetang.common.config.Globals;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.JedisShardInfo;
import redis.clients.jedis.ShardedJedisPool;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by Wizzer on 14-4-8.
 */
public class MyJedis {
    private String redisUrl;
    private int redisPort;
    public JedisPoolConfig jedisPoolConfig(){
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setMaxTotal(Globals.REDIS_CONFIG.getMaxTotal());
        jedisPoolConfig.setMaxIdle(Globals.REDIS_CONFIG.getMaxIdle());
        jedisPoolConfig.setMaxWaitMillis(Globals.REDIS_CONFIG.getMaxWaitMillis());
        jedisPoolConfig.setTestOnBorrow(Globals.REDIS_CONFIG.isTestOnBorrow());
        return jedisPoolConfig;
    }
    public JedisShardInfo jedisShardInfo(){
        return new JedisShardInfo(redisUrl, redisPort);
    }
    public JedisPool jedisPool(){
        return new JedisPool(jedisPoolConfig(),redisUrl, redisPort);
    }
    public ShardedJedisPool shardedJedisPool(){
        this.redisUrl=Globals.REDIS_CONFIG.getRedisUrl();
        this.redisPort=Globals.REDIS_CONFIG.getRedisPort();
        List<JedisShardInfo> jedisList = new ArrayList<JedisShardInfo>();
        jedisList.add(jedisShardInfo());
        return new ShardedJedisPool(jedisPoolConfig(), jedisList);
    }

}

实现自己的监听类:

package cn.xuetang.common.redis;

import org.nutz.log.Log;
import org.nutz.log.Logs;
import redis.clients.jedis.JedisPubSub;

/**
 * 订阅监听类
 * Created by Wizzer on 14-4-8.
 */
public class MyJedisListenter extends JedisPubSub {
    private final static Log log = Logs.get();
    // 取得订阅的消息后的处理
    public void onMessage(String channel, String message) {
        log.info(channel + "=" + message);
    }

    // 初始化订阅时候的处理
    public void onSubscribe(String channel, int subscribedChannels) {
        log.info(channel + "=" + subscribedChannels);
    }

    // 取消订阅时候的处理
    public void onUnsubscribe(String channel, int subscribedChannels) {
        log.info(channel + "=" + subscribedChannels);
    }

    // 初始化按表达式的方式订阅时候的处理
    public void onPSubscribe(String pattern, int subscribedChannels) {
        log.info(pattern + "=" + subscribedChannels);
    }

    // 取消按表达式的方式订阅时候的处理
    public void onPUnsubscribe(String pattern, int subscribedChannels) {
        log.info(pattern + "=" + subscribedChannels);
    }

    // 取得按表达式的方式订阅的消息后的处理
    public void onPMessage(String pattern, String channel, String message) {
        log.info(pattern + "=" + channel + "=" + message);
    }
}

 
获取单例Jedis连接池:

package cn.xuetang.common.redis;

import cn.xuetang.common.config.Globals;
import org.nutz.log.Log;
import org.nutz.log.Logs;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.ShardedJedisPool;

import java.util.Date;

/**
 * Created by Wizzer on 14-4-8.
 */
public class JedisPoolUtil {
    private final static Log log = Logs.get();

    public synchronized ShardedJedisPool getShardedJedisPool() {
        if (Globals.SHARDEDJEDIS_POOL == null) {
            MyJedis myJedis=new MyJedis();
            Globals.SHARDEDJEDIS_POOL = myJedis.shardedJedisPool();
        }
        return Globals.SHARDEDJEDIS_POOL;
    }

    public synchronized JedisPool getJedisPool() {
        if (Globals.JEDIS_POOL== null) {
            MyJedis myJedis=new MyJedis();
            Globals.JEDIS_POOL = myJedis.jedisPool();
        }
        return Globals.JEDIS_POOL;
    }
}

数据入列同时发布订阅消息:

ShardedJedis shardedJedis=Globals.SHARDEDJEDIS_POOL.getResource();
                txt.put("appid", appInfo.getId());
                shardedJedis.lpush("image", Json.toJson(txt));
                Jedis jedis=Globals.JEDISPOOL.getResource();
                jedis.publish("newimage","true");

 

处理订阅消息的类:

 

package cn.xuetang.common.task;

import cn.xuetang.common.action.BaseAction;
import cn.xuetang.common.config.Globals;
import cn.xuetang.common.redis.MyJedisListenter;
import cn.xuetang.common.util.DateUtil;
import cn.xuetang.modules.baby.bean.Baby_image;
import cn.xuetang.modules.baby.bean.Baby_info;
import cn.xuetang.modules.user.bean.User_conn_wx;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.json.Json;
import org.nutz.lang.Strings;
import org.nutz.log.Log;
import org.nutz.log.Logs;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.ShardedJedis;

import java.util.*;

/**
 * Created by Wizzer on 14-3-31.
 */
@IocBean
public class ImageTask extends BaseAction implements Runnable {
    @Inject
    protected Dao dao;
    private final static Log log = Logs.get();

    public void run() {
        try {
            log.info("ImageTask start!");
            final JedisPoolUtil jedisPoolUtil = new JedisPoolUtil();
            boolean isEnable = false;
            while (!isEnable) {
                try {
                    jedisPoolUtil.getShardedJedisPool().getResource();
                    isEnable = true;
                } catch (Exception e) {
                    log.info("The redis connection is not successful,wait " + Globals.REDIS_CONFIG.getRedisTimeout() + "ms try again.");

                }
                try {
                    wait(Globals.REDIS_CONFIG.getRedisTimeout());
                } catch (Exception e) {

                }
            }
            final ShardedJedis shardedJedis = jedisPoolUtil.getShardedJedisPool().getResource();
            final Jedis jedis = jedisPoolUtil.getJedisPool().getResource();
            MyJedisListenter listenter = new MyJedisListenter() {
                @Override
                public void onMessage(String channel, String message) {
                    //业务代码具体实现
                    while (shardedJedis.exists("image")) {
                        String data = shardedJedis.rpop("image");
                    }
                }
            };
            jedis.subscribe(listenter, "newimage");

        } catch (Exception e) {
            log.error(e);
        }

    }

}

 

 

20144 月8

Nutz:POST数据的常用方法

 Request req = Request.create("http://127.0.0.1/api/user/sendtext?mykey=" + mykey, Request.METHOD.POST);
                            JsonFormat jsonFormat=new JsonFormat();
                            jsonFormat.setAutoUnicode(true);//防止中文乱码,以unicode编码,根据需要设置
                            req.setData(Json.toJson(map,jsonFormat));
                            req.getHeader().set("Content-Type","application/octet-stream");//设置以字节流传送数据
                            Response resp = Sender.create(req).send();
                            if (resp.isOK()) {
                                log.info(resp.getContent());

                            }



201212 月5

建设方案:12329公积金电话热线语音平台

2012年9月28日,中华人民共和国住房和城乡建设部下发《关于开通12329住房公积金热线的通知》,这也苦了我们搞软件开发的程序猿们,在这里简单谈谈12329热线的建设方案。

电话热线平台其核心无非是语音自助查询和人工电话接听了,目前各地市基本上都有网上查询系统,也有一部分有自己的语音热线平台,如何充分利用现有资源实现和满足通知要求,值得思考。

 图片源自:12329住房公积金热线服务导则

方案1:

在满足《12329住房公积金热线服务导则》要求的原则下,充分利用住房公积金管理中心现有资源,结合12345等其他热线平台,实现12329热线功能。

即:

对于本市12345热线平台和原公积金热线都是我们公司做的话,做整合是比较理想的方案,但这里有一些问题需解决:

1)两个热线运销商不一,需协调选择最优方案;

2)12345和公积金分属不同部门单位,需地市政府协调资源;

3)从12329转出12345需要知道来源直接接入坐席,则12329需保持通话,运营商是收费的;

4)在12345热线不能判断公众是选择个人业务还是单位业务;

等等。

方案2:

自建一套全新的语音平台,我公司与语音设备长期合作,已配套开发出热线业务处理平台,短信、电话、微博、传真、三方通话等等,IVR流程开发、公积金查询系统接口开发、订制功能开发等不在话下。

公司网站:http://www.hfits.com.cn

201112 月20

安徽电信20M光纤宽带可以预约办理了!

据咨询,199¥套餐赠送的200¥话费可以抵扣3G上网流量。
目前使用的套餐为集团用户:149¥-20¥的4M宽带+50¥包3G流量=每个月179¥
升级后为:199¥20M宽带赠送200¥话费可抵扣3G流量~~

月基本费 宽带 iTV 国内话费
+点对点短信
固话资费 手机资费
199元 20M
(744小时)
送全年iTV
免费观看
(标清)
送200元话费
套餐内最多3部手机
和1部固话共享
区内市话:前3分钟0.2元
以后0.1元/分钟
区间市话:0.2元/分钟
长途直拨:0.29元/分钟 
市话0.15元/分钟
长途直拨:0.29元/分钟
漫游:0.29元/分钟
全国接听免费
299元 送400元话费
套餐内最多3部手机
和1部固话共享
399元 送600元话费
套餐内最多3部手机
和1部固话共享
599元 送全年iTV
免费观看
(高清)
送900元话费
套餐内最多3部手机
和1部固话共享

月上网流量:以上套餐都为100M/卡

预约登记

 
 
 
 
201112 月19

灵验:69岁现象?

【灵验:69岁现象?】:金正日(1942-2011),69岁;卡扎菲(1942-2011),69岁;萨达姆(1937-2006),69岁;苏联(1922-1991),69岁。2018… …        @李以亮

201112 月17

全体中国人民的2011年终总结,太强悍了,不服不行!!

 

全体中国人民的2011年终总结,太强悍了,不服不行!!!

来源: 方一明的日志 

2011总结

 
    跟往年一样,这是蛋疼的一年,坑爹的一年,杯具的一年,纠结的一年。
    这一年,“我爸是李刚”拉开了中国人拚爹的序幕,大量的富二代官二代用他们的行动告诉我们:人生最重要的不是你所朝的方向,而是取决于你是谁的精子。
    这一年,重庆的打黑运动让我们明白:电视上经常看到的那些衣着光鲜,人模狗样的公仆,他们往往在下一刻就变成了黑老大。而你是公仆还是黑社会,关键看你有没有站错队。
    这一年,日本9.0级地震震垮了核电站,也震碎了国人愚昧的神经,那些买不起房而被迫单身的人们,因为手里有几袋碘盐而变得奇货可居。
    这一年,地球将模式调成了震动,上帝的子民失去了他的辟佑陷入苦海,但在中国,人们在电视上看到玉树和云南大爱不断升华,党领导人民战胜了一次又一次天灾。多难,但并没兴邦。
    这一年,国与民争利达到高潮,财政收入连创新高,人民饭碗却营养不良。GDP世界第二,百姓收入勉强苟活,房事彻底沦为多数人的浮云。而盛会,依然在一个叫隆重的地方举行。
    这一年,苹果砸中牛顿沉寂数百年后,以数码产品的姿态席卷全球。世界上最遥远的距离是:我们一起出门,你去买苹果四代,而我却只能买四袋苹果。
 
    这一年,谢霆锋终于意识到自己对柏芝的了解始终超越不了天涯上的民工,于是他放弃了。我固执的认为他一定看到了杂谈那个万人景仰的回复。男人,无论好坏,都翻不过那道绿帽砌成的坎,有的秋后算帐,有的立马摊牌。
    这一年,芙蓉姐姐从大S变成了小S,凤姐的绿卡让我们彻底断了成功可以复制的念想。但不管是李宇春,还是曾轶可,都是我的哥,我的哥。。
    这一年,曾经风靡万千少女,改进社会风气,提高青少年内涵,成就中国互联网第一个PS狂欢的小胖,他结婚了。都说快乐不会是永久的,所以你不可能永远保持单身。
    这一年,南科大45名学子以非暴力不合作表达了对中国教育的鄙视,一潭死水总算荡起了一丝波浪。但死水原本就不应该有波浪,所以,他们在潭中注满了水泥。
    这一年,药家鑫让那些被车撞倒的人,拼出考公务员的力量爬起来,然后跑掉,甚至连别人汽车的损失都来不及赔。
    这一年,转基因和地沟油让中国人坚信他们是核战争最后的幸存者。在网上,他们表达吐血身亡的语句变成了:遂吐3公升地沟油而亡。
    这一年,李昌奎废除了大理国的死刑,以丧尽天良的兽行救活了他的同类,或者说,那个叫赛锐的同类以通天的手腕救活了他。这已经不重要了,中国的法律本身只具有观赏性,那些在文革中双手沾满同胞鲜血的侩子手今天照居庙堂之上,就注定了杀人偿命不过是老祖宗目光短浅的一句呻吟。
    这一年,唱红治愈了不孕,还成为精神病院最有效的治疗手段,而监狱里,住满了共产主义接班人。
    这一年,西门庆发现了武大郎阳痿的秘密,用实际行动霸占了金莲,一向对内要钱不要脸对外要脸不要钱的武大郎当即采用了3种方式表达抗议,赢得赞誉一片:大郎家祖产多,从不跟周围邻里那帮小气鬼一般见识。
    这一年,各地下雨全是100年不遇,武汉的海景超过公交成为新的城市名片。成都,长沙,南京纷纷在报纸上表示自己是特大号护舒宝,流量再多也不用担心,随即就被老天爷一个无情的耳光扇过去。。分析认为:此护舒宝为山寨品,也就是:made in china。
    这一年,共和国的脊梁被草根唾骂,原因在于草根们把共和国的脊梁当成了中国脊梁。
    这一年,绿皮火车见到了蒸汽火车,感叹世间人情冷暖,我们终究都逃不过鸟尽弓藏的命运。开明的蒸汽火车说:历史的车轮在前进,我们都尽到了自己所处位置的责任,现在是高铁的时代了,你再不退下就是开历史的倒车,中国人民才被历史的车轮碾过,还没爬起来,一回头却看见你在倒车,你叫他们情何以堪呐。
    这一年,高铁恍如一夜之间长满祖国各地,人们用高于普车数倍的价格向铁道部购买时间,而那些时间充裕的人因普车的取消也不得不买几个小时,然后在目的地玩手机来消磨时间。
    这一年,号称世界领先的动车出轨了,人们悲怆的发现,吃的,住的,坐的竟没有一种让人蛋定,以河蟹着称的媒体也开始草泥马了,在经历了出事→微博讨论→小秘书删帖→微博疯狂讨论→小秘书来不及删帖→问责呐喊声四起→传统媒体跟进→微博谣言四起→政府辟谣→产生新的流行语→李承鹏发文→韩寒发文→讽刺段子出炉→五毛辟谣搅混水→讨论进入高潮→总理现身→微博一片体贴谅解→和谐,删帖,噤声→搞笑段子出炉→下次。。。后,酱油瓶仍旧在手,真相的高度永远高于酱油瓶的高度,对于善良的中国人来说,打酱油比抢碘盐还来得更轻松和毫无风险。
    这一年,黑社会败给了社会黑,社会黑又催生了黑监狱,黑监狱关的却不是黑社会。黑社会说:监狱,本就是黑色,黑夜给了中国黑色的监狱,它们却用来禁锢冤屈。
    这一年,灰太郎对喜洋洋说:我咬你,你不要动,我们要和谐。
    这一年,五毛依旧凶猛,天涯沦落的不仅是国关,还有八卦。而在杂谈,五毛还是一如既往的苦逼。
    这一年,人民仍然相信,皇帝是好的,中央是清白的,坏的只是地方。当不公降临在他身上时,他最期待的不是改良制度,而是渴望清官。
    这一年,雷公也成了弱势群体,悲催的替铁道部背了黑锅。当我们在盘点中国事故责任人时,发现他们分别是临时工、临时工、临时工。。。还有雷公,这时玉帝大叫道:他也是临时工。
    这一年,央视和百度,一个婊子一个奴才,为争牌坊打起来了。请问你支持谁?—-废话,当然是支持google。那么假如央视和百度同时落水,你是去吃火锅还是去K歌?—-废话,当然是掏出鸡鸡往水里尿尿。
    这一年,我想对日本人说:不用担心,你们的国家不会抛弃你们!最后我要对中国人民说:不要幻想太多,你只能靠自己。