import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import org.apache.tomcat.util.codec.binary.Base64;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import net.sf.json.JSONObject;
/**
* @ClassName: ScanController
* @Description: (扫码登录)
* @date 2019年7月11日 上午10:15:48
* @version V1.0
*
*/
@Controller
@RequestMapping("/zhbpappscan")
public class ScanController{
@Autowired
private RedisUtil rs;
@Autowired
private ScanService scanService;
/**
* 二维码 扫码登录 存储三分钟
*/
@Value("${zhbp.redis.auth.code.three}")
private long authCodeThree;
/**
* @param @return 设定文件
* @return ResponseEntity<Object> 返回类型
* @throws
* @Title: createQRCode
* @Description: (生成二维码并将uuid存储到redis中)
*/
@RequestMapping("/qrcode")
@ResponseBody
public JSONObject createQRCode() {
Map<String, Object>map = new HashMap<>();
map.put("status", 1);
map.put("reason", "成功");
map.put("data", 0);
String uuid = UUID.randomUUID().toString();
//组装二维码内容 1,uuid=xxxx
String text = Const.QRCODE_DOMAIN + "?type=" + Const.QRCODE_TYPE + "&uuid=" + uuid;
int width = 300;
int height = 300;
String format = "png";
Map<String, Object> uuidMap = new HashMap<>();
uuidMap.put("userId", "0");
//是否扫码 0未扫码,1扫码
uuidMap.put("isAppScan", "0");
try {
Map<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>();
hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
// hints.put(EncodeHintType.MARGIN, 1);
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H); // 容错率
BitMatrix bitMatrix = new MultiFormatWriter().encode(text, BarcodeFormat.QR_CODE, width, height, hints);
ByteArrayOutputStream bao = new ByteArrayOutputStream();
MatrixToImageWriter.writeToStream(bitMatrix, format, bao);
bao.toByteArray();
Base64 encoder = new Base64();
String img = encoder.encodeAsString(bao.toByteArray());
QrCodeResponse qrCodeResponse = new QrCodeResponse();
qrCodeResponse.setUuid(uuid);
qrCodeResponse.setImg(img);
rs.addMap(Const.QECODE + uuid, uuidMap);
rs.expire(Const.QECODE + uuid, authCodeThree);
map.put("data", qrCodeResponse);
} catch (WriterException e) {
map.put("status", -1000);
map.put("reason", "参数有误");
e.printStackTrace();
} catch (IOException e) {
map.put("status", -1000);
map.put("reason", "参数有误");
e.printStackTrace();
}
return JSONObject.fromObject(map);
}
/**
* @param @param uuid
* @param @return 设定文件
* @return ResponseEntity<Object> 返回类型
* @throws
* @Title: cleanRedisQrcode
* @Description: (扫码后未确认返回二维码登录时重置)
*/
@RequestMapping("/resetQrcode")
@ResponseBody
public JSONObject resetQrcode(String uuid) {
Map<String, Object>map = new HashMap<>();
map.put("status", 1);
map.put("reason", "成功");
map.put("data", 0);
try {
Object uuidExist = rs.getMapField(Const.QECODE + uuid, "userId", Object.class);
if (null == uuidExist) {
map.put("status", -6371);
map.put("reason", "redis中uuid不存在");
} else {
//扫描成功标识,用该标识展示“请在手机上确认登录”界面
rs.addMap(Const.QECODE + uuid, "isAppScan", "0");
}
} catch (Exception e) {
e.printStackTrace();
map.put("status", -6379);
map.put("reason", "uuid保存到redis中异常");
}
return JSONObject.fromObject(map);
}
/**
* @param @param uuid
* @param @param status 无值 或者 0的时候 返回扫过的状态 1的时候 不返回
* @param @return 设定文件
* @return ResponseEntity<Object> 返回类型
* @throws
* @Title: pool
* @Description: (检查二维码是否被扫描)
*/
@RequestMapping("/pool")
@ResponseBody
public JSONObject pool(String uuid, Integer status) {
Map<String, Object>map = new HashMap<>();
Map<String, Object>userInfoMap = new HashMap<>();
map.put("status", 1);
map.put("reason", "成功");
map.put("data", 0);
userInfoMap.put("userId", "");
userInfoMap.put("userName", "");
userInfoMap.put("portrait", "");
map.put("userInfo",userInfoMap);
//计时
int time = 0;
while (true) {
time++;
Map<String, Object> ad = rs.mget(Const.QECODE + uuid, Object.class);
if (ad == null || ad.size() == 0) {
//点击刷新 3代表超时,页面点击刷新
map.put("data", 3);
return JSONObject.fromObject(map);
}
if (ad != null && !("0".equals(ad.get("userId")))) {
//app扫过 并且登录 使用userId 生成token
int n = scanService.getUserInfo(Integer.parseInt(ad.get("userId").toString()));
if (n == 1) {
//登录后信息
map.put("userInfo", scanService.getLoginInfo(Integer.parseInt(ad.get("userId").toString())));
//2 代表成功登录状态
map.put("data", 2);
return JSONObject.fromObject(map);
} else {
//3代表 刷新
map.put("data", 3);
return JSONObject.fromObject(map);
}
}
if (ad != null && "1".equals(ad.get("isAppScan"))) {
//app扫过
if (status == null || status.intValue() == 0) {
//1 是 app扫过,弹出选择登录 还是 取消
map.put("data", 1);
return JSONObject.fromObject(map);
}
}
if (time >= 10) {
//保持10秒
map.put("data", 0);
return JSONObject.fromObject(map);
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
/**
* @param @param uuid
* @param @param userId
* @param @return 设定文件
* @return ResponseEntity<Object> 返回类型
* @throws
* @Title: login
* @Description: (app按钮 : 允许登录)
*/
@RequestMapping("/appScanLogin")
@ResponseBody
public JSONObject appScanLogin(String uuid, String userId) {
Map<String, Object>map = new HashMap<>();
map.put("status", 1);
map.put("reason", "成功");
map.put("data", 0);
Map<String, Object> ad = rs.mget(Const.QECODE + uuid, Object.class);
if (null == ad||ad.isEmpty()) {
map.put("status", -1021);
map.put("reason", "请重新扫码");
} else {
//如果isAppScan状态是1才可以登录
if (ad.get("isAppScan") != null && "1".equals(ad.get("isAppScan"))) {
rs.addMap(Const.QECODE + uuid, "userId", userId);
}
}
return JSONObject.fromObject(map);
}
/**
* 功能描述:退出
*
* @param uuid
* @param userId
* @return: org.springframework.http.ResponseEntity<java.lang.Object>
*/
@RequestMapping(value = "/appScanCancel")
@ResponseBody
public JSONObject appScanCancel(String uuid, String userId) {
Map<String, Object>map = new HashMap<>();
map.put("status", 1);
map.put("reason", "成功");
try {
Map<String, Object> ad = rs.mget(Const.QECODE + uuid, Object.class);
if (null == ad || ad.isEmpty()) {
map.put("status", -1021);
map.put("reason", "请重新扫码");
}
//如果 isAppScan=1 则移除
if (ad.get("isAppScan") != null && "1".equals(ad.get("isAppScan"))) {
rs.del(Const.QECODE + uuid);
}
} catch (Exception e) {
e.printStackTrace();
map.put("status", -1021);
map.put("reason", "请重新扫码");
}
return JSONObject.fromObject(map);
}
/**
* @param uuid
* @param userId
* @return ResponseEntity<Object> 返回类型
* @Title: appScanEnd
* @Description: (app扫描二维码后)
*/
@RequestMapping("/appScanPrevious")
@ResponseBody
public JSONObject appScanPrevious(@RequestParam(value = "uuid", required = true) String uuid,
@RequestParam(value = "userId", required = true) String userId) {
Map<String, Object>map = new HashMap<>();
map.put("status", 1);
map.put("reason", "成功");
map.put("data", 0);
try {
Object uuidExist = rs.getMapField(Const.QECODE + uuid, "userId", Object.class);
if (null == uuidExist) {
map.put("status", -6371);
map.put("reason", "redis中uuid不存在");
} else {
//扫描成功标识,用该标识展示“请在手机上确认登录”界面
rs.addMap(Const.QECODE + uuid, "isAppScan", "1");
}
} catch (Exception e) {
e.printStackTrace();
map.put("status", -6379);
map.put("reason", "uuid保存到redis中异常");
}
return JSONObject.fromObject(map);
}
}