海马遥控器匹配

1、把车停好,四门关好

2、熄火把钥匙,然后把左前门(驾驶室旁边主控门)开关三次

3、在三秒内插入钥匙并连续开关五次(不用起动发动机)

4、以上步骤在十秒内完成,拔出钥匙按旧遥控器上的开钥和关钥键,此时可听到遥控反应,遥控反应后再按新遥控器上的开钥和关钥,如果遥控器有反应则说明遥控匹配成功。

5、据说此方法可以用于福来美、普力马、海福星(未验证)

java使用jedis执行lua脚本

1、引入依赖

		<!-- Jedis -->
		<dependency>
			<groupId>redis.clients</groupId>
			<artifactId>jedis</artifactId>
		</dependency>

2、编写配置文件

#Redis
spring.redis.host=127.0.0.1
spring.redis.port=6379
spring.redis.database=3

spring.redis.password=
spring.redis.timeout=2000

#Jedis
#最大空闲数
spring.redis.jedis.pool.max-idle=6
#最大连接数
spring.redis.jedis.pool.max-active=10
#最小空闲数
spring.redis.jedis.pool.min-idle=2
#连接超时
spring.redis.jedis.pool.timeout=2000

3、编写配置类

package com.zero4j.config;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

@Configuration
public class JedisConfig {

    private Logger logger = LoggerFactory.getLogger(JedisConfig.class);

    @Value("${spring.redis.host}")
    private String host;

    @Value("${spring.redis.port}")
    private int port;

    @Value("${spring.redis.password}")
    private String password;
    @Value("${spring.redis.timeout}")
    private int timeout;

    @Value("${spring.redis.jedis.pool.max-active}")
    private int maxActive;

    @Value("${spring.redis.jedis.pool.max-idle}")
    private int maxIdle;

    @Value("${spring.redis.jedis.pool.min-idle}")
    private int minIdle;

    @Bean
    public JedisPool jedisPool(){

        JedisPoolConfig jedisPoolConfig=new JedisPoolConfig();
        jedisPoolConfig.setMaxIdle(maxIdle);
        jedisPoolConfig.setMinIdle(minIdle);
        jedisPoolConfig.setMaxTotal(maxActive);

        JedisPool jedisPool = new JedisPool(jedisPoolConfig,host,port,timeout,password);

        logger.info("JedisPool连接成功:"+host+"\t"+port);

        return jedisPool;
    }

}

4、实现业务逻辑

	@Autowired
	private JedisPool jedisPool;

 

		Jedis jedis = null;

		try {
			jedis = jedisPool.getResource();
			String poolId = "pool1";
			String poolLuaRedisKey = "cardLottery." + poolId + "-lua-shaKey";
			String poolLuaRedisValue = jedis.get(poolLuaRedisKey);
			byte[] shaKey = null;
			if(poolLuaRedisValue!=null){
				shaKey = poolLuaRedisValue.getBytes();
			}
			if (shaKey == null) {
				ClassPathResource cps = new ClassPathResource("lua/test.lua");
				InputStream in = cps.getInputStream();
				byte[] data = new byte[in.available()];
				in.read(data);
				shaKey = jedis.scriptLoad(data);
				jedis.set("cardLottery." + poolId + "-lua-shaKey", new String(shaKey));
			}

			System.out.println("本次执行的lua脚本的sha为:" + new String(shaKey));

			List<String> keys = new ArrayList<>();
			keys.add(poolId);
			keys.add("100");
			keys.add("0.5");
			List<String> vals = new ArrayList<>();
			for (int i = 0; i < 10; i++) {
				Date _startTime = new Date();
				Object result = jedis.evalsha(new String(shaKey), keys, vals);
				Date _endTime = new Date();
				long _timeCross = _endTime.getTime() - _startTime.getTime();
				System.out.println("lua的第" + (i + 1) + "次执行花了" + _timeCross + "毫秒,执行结果:" + result);
			}
		}catch(Exception e){
			e.printStackTrace();
		}finally {
			if(jedis!=null){
				jedis.close();
			}
		}

5、Lua脚本

local key = 'cardPool.'..KEYS[1]..'-bucket' -- redis中令牌桶对象的key
local initTokens = tonumber(KEYS[2]) -- {初始化时的令牌数}
local probability = tonumber(KEYS[3]) -- {中奖概率:小于0的数字(百分比概念)}

print(probability)

local bucket = redis.call('hgetall', key) -- 当前 key 的令牌桶对象
local currentTokens -- 当前token数量
local runCount -- 累计执行次数统计

-- 若当前桶未初始化,先初始化令牌桶
if table.maxn(bucket) == 0 then
    -- 初始桶内令牌
    currentTokens = initTokens
    runCount = 0
    redis.call('hset', key, 'stock', currentTokens)
    redis.call('hset', key, 'probability', probability)
    redis.call('hset', key, 'runCount', 0)
elseif table.maxn(bucket) == 6 then
    currentTokens = tonumber(bucket[2])
    probability = tonumber(bucket[4])
    runCount = tonumber(bucket[6])
end

-- 如果当前桶内令牌小于 0,抛出异常
assert(currentTokens >= 0)

redis.call('hset', key, 'runCount', runCount + 1)

if currentTokens == 0 then  -- 如果当前令牌 == 0, 返回false
    return -1
else    -- 如果当前令牌 大于 0, 则执行抽奖逻辑
    if probability<> nil or probability >= 1 or math.random() <= probability then -- 如果中奖概率大于或等于1,生成随机的小数如果在probability内,则中奖
        -- 更新当前桶内的令牌 -1, 返回true
        redis.call('hset', key, 'stock', currentTokens - 1)
        return 1
    else
        return 0
    end
end

注意:如果Lua脚本返回是true和false的类型,则jedis实际获得的值为1和null。

 

java使用lua脚本操作redis的相关笔记

Lua脚本

local key = 'cardPool.'..KEYS[1]..'-stock' -- redis中令牌桶对象的key
local initTokens = tonumber(KEYS[2]) -- {初始化时的库存数量}

local bucket = redis.call('hgetall', key) -- 当前 key 的令牌桶对象
local currentTokens -- 当前token数量
local runCount -- 累计运行次数统计

-- 若当前桶未初始化,先初始化令牌桶
if table.maxn(bucket) == 0 then
    -- 初始桶内令牌
    currentTokens = initTokens
    runCount = 0
elseif table.maxn(bucket) == 4 then
    currentTokens = tonumber(bucket[2])
    runCount = tonumber(bucket[4])
end

-- 如果当前桶内令牌小于 0,抛出异常
assert(currentTokens >= 0)

-- 如果当前令牌 == 0, 返回false
if currentTokens == 0 then
    redis.call('hset', key, 'tokensRemaining', currentTokens)
    redis.call('hset', key, 'runCount', runCount + 1)
    return false
else
    -- 如果当前令牌 大于 0, 更新当前桶内的令牌 -1, 返回true
    redis.call('hset', key, 'tokensRemaining', currentTokens - 1)
    redis.call('hset', key, 'runCount', runCount + 1)
    return true
end

JAVA运行Lua脚本:

		DefaultRedisScript<Boolean> redisScript = new DefaultRedisScript<>();
		redisScript.setScriptSource(new ResourceScriptSource(new ClassPathResource("lua/test.lua")));
		redisScript.setResultType(Boolean.class);

		Boolean result = true;
		long count = 0;
		do{
			Date _startTime = new Date();
			List<String> keys = Arrays.asList("pool1", "10000");
			try{
				result = redisTemplate.execute(redisScript, keys);
			}catch(Exception e){
				e.printStackTrace();
			}
			Date _endTime = new Date();
			long _timeCross = _endTime.getTime()- _startTime.getTime();
			count++;
			System.out.println("lua的第"+count+"次执行花了"+_timeCross+"毫秒");
		}while(result==true);

注意hgetall返回的redis变量读取方式

Restful 返回数据格式

返回数据的一般格式:

{
“code”: 1,
“mssage”: “返回的信息”,
“data”: {
“list”:[
{
“title”:”xxx”,
“contents”:”xxx”,
},{
“title”:”xxx”,
“contents”:”xxx”,
}
]
“total”:21,
},
“extra”: {},
“pageNum”: 3,
“pageSize”: 20,
“totalSize”: 235
}

code的一般含义

public enum ResultCode {

  /* 成功状态码 */
  SUCCESS(0, "成功"),

  /* 令牌失效 */
  TOKEN_INVALID(401,"令牌失效"),

  SERVER_ERROR(400, "服务器错误"),

  /*参数错误 10001-19999 */

  PARAM_IS_INVALID(10001, "参数无效"),
  PARAM_IS_BLANK(10002, "参数为空"),
  PARAM_TYPE_BIND_ERROR(10003, "参数类型错误"),
  PARAM_NOT_COMPLETE(10004, "参数缺失"),

  /* 用户错误:20001-29999*/
  USER_NOT_LOGGED_IN(20001, "用户未登录"),
  USER_LOGIN_ERROR(20002, "账号不存在或密码错误"),
  USER_ACCOUNT_FORBIDDEN(20003, "账号已被禁用"),
  USER_NOT_EXIST(20004, "用户不存在"),
  USER_HAS_EXISTED(20005, "用户已存在"),
  Cert_HAS_EXISTED(20006, "认证已存在"),


  /* 业务错误:30001-39999 */
  CREATE_FAIL(30001, "创建失败"),

  /* 系统错误:40001-49999 */
  SYSTEM_INNER_ERROR(40001, "系统繁忙,请稍后重试"),

  /* 数据错误:50001-599999 */
  RESULE_DATA_NONE(50001, "数据未找到"),
  DATA_IS_WRONG(50002, "数据有误"),
  DATA_ALREADY_EXISTED(50003, "数据已存在"),

  /* 接口错误:60001-69999 */
  INTERFACE_INNER_INVOKE_ERROR(60001, "内部系统接口调用异常"),
  INTERFACE_OUTTER_INVOKE_ERROR(60002, "外部系统接口调用异常"),
  INTERFACE_FORBID_VISIT(60003, "该接口禁止访问"),
  INTERFACE_ADDRESS_INVALID(60004, "接口地址无效"),
  INTERFACE_REQUEST_TIMEOUT(60005, "接口请求超时"),
  INTERFACE_EXCEED_LOAD(60006, "接口负载过高"),

  /* 权限错误:70001-79999 */
  PERMISSION_NO_ACCESS(70001, "只有标签 Owner ,才具备删除权限"),
  PERMISSION_NO_PHONE_ACCESS(70002,"此认证标签已有员工认证,不可以进行删除");
  
}

 

Vue3-cli/Ant-design-pro-vue修改运行在子路径上

版本依赖情况:

PS D:\suidian-yuexi\admin> npm list vue
npm WARN config global `--global`, `--local` are deprecated. Use `--location=global` instead.
vue-antd-pro@3.0.2 D:\suidian-yuexi\admin
+-- @ant-design-vue/pro-layout@1.0.13
| +-- vue-container-query@0.1.0
| | `-- vue@2.7.3 deduped
| +-- vue-copy-to-clipboard@1.0.3
| | `-- vue@2.7.3 deduped
| `-- vue@2.7.3 deduped
+-- @vue/cli-plugin-babel@4.5.19
| `-- @vue/babel-preset-app@4.5.19
|   +-- @vue/babel-preset-jsx@1.3.0
|   | `-- vue@2.7.3 deduped
|   `-- vue@2.7.3 deduped
+-- @vue/cli-plugin-unit-jest@4.5.19
| `-- vue-jest@3.0.7
|   `-- vue@2.7.3 deduped
+-- @vue/test-utils@1.3.0
| `-- vue@2.7.3 deduped
+-- ant-design-vue@1.7.8
| +-- @ant-design/icons-vue@2.0.0
| `-- vue@2.7.3 deduped
+-- viser-vue@2.4.8
| `-- vue@2.7.3 deduped
+-- vue-svg-component-runtime@1.0.1
| `-- vue@2.7.3 deduped
+-- vue-svg-icon-loader@2.1.1
| +-- vue-svg-component-builder@2.0.3
| | `-- vue@2.7.3 deduped
| `-- vue@2.7.3 deduped
+-- vue@2.7.3
`-- vuex@3.6.2
  `-- vue@2.7.3 deduped

PS D:\suidian-yuexi\admin> npm run serve
npm WARN config global `--global`, `--local` are deprecated. Use `--location=global` instead.

> vue-antd-pro@3.0.2 serve
> vue-cli-service serve

 

1、修改项目运行路径,打开vue.config.js文件,在vueConfig的json中增加:

publicPath: "/admin2/",

2、修改路由的基础路径,打开index.js文件,在createRouter的new Router对象时传入的json增加:

base: '/admin2',

3、重启服务即可

安装RabbitMQ

一、安装ERLANG

RabbitMQ依赖语言开发包ErLang,到http://www.erlang.org/downloads下载windows版本并安装,安装后需要配置环境变量:

1、增加系统变量:ERLANG_HOME=C:\Program Files\erl-23.0

2、在Path系统变量中增加:%ERLANG_HOME%\bin

然后在CMD中输入指令“erl”即可验证是否配置成功:

111

 

 

二、安装RabbitMQ

到https://www.rabbitmq.com/download.html下载windows版本病安装,安装后需要配置环境变量:

1、增加系统变量:RABBITMQ_SERVER=C:\Program Files\RabbitMQ Server\rabbitmq_server-3.8.3

2、在Path系统变量中增加:%RABBITMQ_SERVER%\sbin

三、激活RabbitMQ的WEB管理界面(可选)

打开CMD执行命令:rabbitmq-plugins.bat enable rabbitmq_management

222

执行成功后重启RabbitMQ服务(可到“服务”中重启,或在任务栏中也能找到相关菜单),然后访问网址:http://localhost:15672/

333

默认用户名/密码:guest/guest

登录后出现如下界面:

444

使用uniapp离线打包底座时获取getApplicationContext()的方法

在对应的类中静态引入以下方法即可:

import static io.dcloud.common.util.ReflectUtils.getApplicationContext;

然后再对应的业务逻辑中直接使用getApplicationContext()即可获取到。

事实上我用jd-gui查看其编译后代码,看见好像这种工具类也能自己写,其代码如下(未验证过):

import android.context.Context;

public static Context getApplicationContext(){
	Context context = null;
	try{
		Context = (Context)Class.forName("android.app.ActivityThread").getDeclaredMethod("currentApplication",new Class[0]).invoke((Object)null, new Object[0]);
	}catch(Exception e){
		null.printStackTrace();
	}
}

 

使用uniapp的安心打包制作ios安装文件时出现PKCS12 import (wrong password?)

假如你确定你的证书密码是对的,就是死活不成功,出现如下提示:

[Info] begin copyFile files to ipa...
[Info] begin replace files to ipa...
[Info] begin update mobileprovision to ipa...
[Info] begin outPut t_entitlements_full plist file...
[Info] begin outPut outPutEntitlements plist file...
[Info] begin verifyPlistFiles
[Info] begin update files to ipa...
[Info] begin createKeychain...
[Info] begin unlockKeychain...
[Info] begin setListKeychains...
[Info] begin importAppleCerts...
[Info] 1 certificate imported.
[Info] 1 certificate imported.
[Info] 1 certificate imported.
[Info] begin importSecurity...
[Error] security: SecKeychainItemImport: MAC verification failed during PKCS12 import (wrong password?)
[Error] importSecurity failed
[Info] Package make result:Failed.    Reason: 

那有可能是因为导出p12证书的时候密码过于简单,不符合要求,导致后续证书使用时的安检失败引起的。请重新导出新的、且符合密码强度要求的p12证书。

close