Browse Source

扫描库位后支持选择所存放的物料

lwx_dev
erdanergou 3 years ago
parent
commit
8f0fe0f33b
  1. 5
      src/main/java/com/dreamchaser/depository_manage/controller/DepositoryRecordController.java
  2. 19
      src/main/java/com/dreamchaser/depository_manage/controller/PageController.java
  3. 4
      src/main/java/com/dreamchaser/depository_manage/entity/ExcelInfoByInventory.java
  4. 4
      src/main/java/com/dreamchaser/depository_manage/mapper/MaterialMapper.java
  5. 2
      src/main/java/com/dreamchaser/depository_manage/mapper/MaterialMapper.xml
  6. 2
      src/main/java/com/dreamchaser/depository_manage/service/MaterialService.java
  7. 223
      src/main/java/com/dreamchaser/depository_manage/service/impl/DepositoryRecordServiceImpl.java
  8. 32
      src/main/java/com/dreamchaser/depository_manage/service/impl/ExcelServiceImpl.java
  9. 13
      src/main/java/com/dreamchaser/depository_manage/service/impl/MaterialServiceImpl.java
  10. 307
      src/main/resources/static/vuePage/index.vue
  11. 68
      src/main/resources/static/vuePage/scanCode.vue
  12. 1
      src/main/resources/templates/pages/application/application-out_min-mobile.html
  13. 364
      src/main/resources/templates/pages/scanQrCode/ScanBarOrQrCodeOut.html
  14. 53
      src/main/resources/templates/pages/scanQrCode/ScanBarOrQrCodeOut_selectMaterial.html
  15. 15
      target/classes/com/dreamchaser/depository_manage/mapper/DepositoryRecordMapper.xml
  16. 2
      target/classes/com/dreamchaser/depository_manage/mapper/MaterialMapper.xml
  17. 307
      target/classes/static/vuePage/index.vue
  18. 68
      target/classes/static/vuePage/scanCode.vue
  19. 1
      target/classes/templates/pages/application/application-out_min-mobile.html
  20. 364
      target/classes/templates/pages/scanQrCode/ScanBarOrQrCodeOut.html

5
src/main/java/com/dreamchaser/depository_manage/controller/DepositoryRecordController.java

@ -499,6 +499,8 @@ public class DepositoryRecordController {
UserByPort userByPort = LinkInterfaceUtil.FindUserById(applicationOutRecordPById.getApplicantId(),userToken);
// 创建展示对象
SimpleApplicationOutMinRecordP simpleApplicationOutMinRecordP = new SimpleApplicationOutMinRecordP(applicationOutMinById);
// 设置展示时的数量为申请数-已出库数
simpleApplicationOutMinRecordP.setQuantity(applicationOutMinById.getQuantity() - applicationOutMinById.getTrueOut());
// 获取申请的物料信息
Material materialById = materialService.findMaterialById(applicationOutMinById.getMid());
// 获取当前物料所存在的库位
@ -523,6 +525,8 @@ public class DepositoryRecordController {
UserByPort checker = LinkInterfaceUtil.FindUserById(checkId,userToken);
simpleApplicationOutMinRecordP.setCheckerName(checker.getName());
simpleApplicationOutMinRecordP.setPcode(placeByDid.getCode());
// 当已经完成出库时设置数量为出库数
simpleApplicationOutMinRecordP.setQuantity(applicationOutMinById.getQuantity());
}
List<MaterialAndProducedDate> materialAndProducedDateByMid = materialService.findMaterialAndProducedDateByMid(materialById.getId());
if (materialAndProducedDateByMid.size() > 0) {
@ -536,6 +540,7 @@ public class DepositoryRecordController {
}
}
}
simpleApplicationOutMinRecordP.setApplicantTime(DateUtil.TimeStampToDateTime(Long.valueOf(applicationOutRecordPById.getApplicantTime())));
simpleApplicationOutMinRecordP.setApplyRemark(applicationOutRecordPById.getApplyRemark());
simpleApplicationOutMinRecordP.setDepositoryId(depositoryRecordById.getId());

19
src/main/java/com/dreamchaser/depository_manage/controller/PageController.java

@ -1713,6 +1713,25 @@ public class PageController {
return mv;
}
// 用于展示当前库位所存在的物料
@GetMapping("/ScanBarOrQrCodeOut_selectMaterial")
public ModelAndView ScanBarOrQrCodeOut_selectMaterial(Integer pid,String mcode){
ModelAndView mv = new ModelAndView();
// 获取当前库位中
List<MaterialAndPlace> placeAndMaterialByPid = placeService.findPlaceAndMaterialByPid(pid);
// 用于存储物料id
List<Integer> midList = new ArrayList<>();
for (int i = 0; i < placeAndMaterialByPid.size(); i++) {
MaterialAndPlace materialAndPlace = placeAndMaterialByPid.get(i);
midList.add(materialAndPlace.getMid());
}
List<Material> materialByIds = materialService.findMaterialByIds(midList);
mv.addObject("materialList",materialByIds);
mv.addObject("mcode",mcode);
mv.setViewName("pages/scanQrCode/ScanBarOrQrCodeOut_selectMaterial");
return mv;
}
@GetMapping("/scanQrCodeTransfer")
public ModelAndView scanQrCodeTransfer(HttpServletRequest request) {
ModelAndView mv = new ModelAndView();

4
src/main/java/com/dreamchaser/depository_manage/entity/ExcelInfoByInventory.java

@ -30,6 +30,10 @@ public class ExcelInfoByInventory {
@ExcelProperty("物料名称")
private String mname;
/** 规格型号 */
@ExcelProperty("规格型号")
private String version;
/** 数量 */
@ExcelProperty(value = "数量")
@ExcelValid(message = "数量未填写")

4
src/main/java/com/dreamchaser/depository_manage/mapper/MaterialMapper.java

@ -131,10 +131,10 @@ public interface MaterialMapper {
/**
* 根据id批量查询库存信息
* @param ids 库存id集合
* @param list 库存id集合
* @return 库存信息
*/
Material findMaterialByIds(List<Integer> ids);
List<Material> findMaterialByIds(List<Integer> list);
/**
* 查询所有库存条数

2
src/main/java/com/dreamchaser/depository_manage/mapper/MaterialMapper.xml

@ -544,7 +544,7 @@
SELECT
<include refid="allColumns" />
FROM material m WHERE m.id IN
<foreach collection="ids" index="index" item="id" open="(" separator="," close=")">
<foreach collection="list" index="index" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</select>

2
src/main/java/com/dreamchaser/depository_manage/service/MaterialService.java

@ -102,7 +102,7 @@ public interface MaterialService {
* @param ids 库存id集合
* @return 库存信息
*/
Material findMaterialByIds(List<Integer> ids);
List<Material> findMaterialByIds(List<Integer> ids);
/**
* 查询所有库存条数

223
src/main/java/com/dreamchaser/depository_manage/service/impl/DepositoryRecordServiceImpl.java

@ -744,6 +744,10 @@ public class DepositoryRecordServiceImpl implements DepositoryRecordService {
int result = 0;
// 获取库存转移标志位
Integer istransfer = record.getIstransfer();
// 获取要出库的数量
Integer trueOut = ObjectFormatUtil.toInteger(param.get("trueOut"));
// 获取出库库位
Integer placeId = ObjectFormatUtil.toInteger(param.get("placeId"));
if (istransfer == 1) {// 如果是库存转移
@ -760,7 +764,7 @@ public class DepositoryRecordServiceImpl implements DepositoryRecordService {
placeAndMaterialByMidAndPid = placeMapper.findPlaceAndMaterialByMidAndPid(params);
if (placeAndMaterialByMidAndPid != null) {
// 如果当前库位存在该物料
if (placeAndMaterialByMidAndPid.getQuantity() < record.getQuantity()) {
if (placeAndMaterialByMidAndPid.getQuantity() < trueOut) {
// 如果当前库位数量不足
flag = false;
}
@ -778,7 +782,7 @@ public class DepositoryRecordServiceImpl implements DepositoryRecordService {
placeAndMaterialByMidAndPid = placeMapper.findPlaceAndMaterialByMidAndPid(params);
if (placeAndMaterialByMidAndPid != null) {
// 如果当前库位存在该物料
if (placeAndMaterialByMidAndPid.getQuantity() < record.getQuantity()) {
if (placeAndMaterialByMidAndPid.getQuantity() < trueOut) {
// 如果当前库位数量不足
flag = false;
}
@ -792,11 +796,11 @@ public class DepositoryRecordServiceImpl implements DepositoryRecordService {
// 获取出库物料具体信息
Material material = materialMapper.findMaterialById(applicationOutMinById.getMid());
// 如果物料数量可以出库并且库位数量充足
if (material.getQuantity() >= record.getQuantity() && flag) {
if (material.getQuantity() >= trueOut && flag) {
// 当前出库金额
Double sum = material.getPrice() * record.getQuantity();
Double sum = material.getPrice() * trueOut;
// 当前出库数量
Integer quantity = applicationOutMinById.getQuantity();
Integer quantity = trueOut;
material.setAmounts(material.getAmounts() - sum);
material.setQuantity(material.getQuantity() - quantity);
material.setNumberOfTemporary(material.getNumberOfTemporary() - quantity);
@ -821,121 +825,132 @@ public class DepositoryRecordServiceImpl implements DepositoryRecordService {
// 修改redis中本子订单完成人
// redisTemplate.opsForHash().put(redisMinRecordKey,"manager",userByPort.getId().toString());
// 获取当前订单中所有管理员
String manager = (String) redisTemplate.opsForHash().get(redisMinRecordKey, "manager");
String[] managerSplit = new String[0];
if (manager != null) {
// 获取其他管理员
managerSplit = manager.replace(userByPort.getId() + ",", "").split(",");
if (managerSplit.length == 0) {
managerSplit = new String[0];
// 修改当前已经出库的数量
applicationOutMinById.setTrueOut(trueOut+applicationOutMinById.getTrueOut());
if(applicationOutMinById.getQuantity() - applicationOutMinById.getTrueOut() > 0){
// 如果当前子订单中的物料并未完全出库
}else{
// 如果完成出库
// 获取当前订单中所有管理员
String manager = (String) redisTemplate.opsForHash().get(redisMinRecordKey, "manager");
String[] managerSplit = new String[0];
if (manager != null) {
// 获取其他管理员
managerSplit = manager.replace(userByPort.getId() + ",", "").split(",");
if (managerSplit.length == 0) {
managerSplit = new String[0];
}
}
}
for (int i = 0; i < managerSplit.length; i++) {
// 删除其他管理员的订单记录
String otherManager = "user:" + managerSplit[i];
String minRecord = (String) redisTemplate.opsForHash().get(otherManager, "minRecord");
// 删除其他管理员中当前已完成的订单
if (minRecord == null) {
continue;
for (int i = 0; i < managerSplit.length; i++) {
// 删除其他管理员的订单记录
String otherManager = "user:" + managerSplit[i];
String minRecord = (String) redisTemplate.opsForHash().get(otherManager, "minRecord");
// 删除其他管理员中当前已完成的订单
if (minRecord == null) {
continue;
}
minRecord = minRecord.replace(redisMinRecordKey + ",", "");
if (minRecord.length() == 2) {
// []
// 如果当前用户已经没有剩余订单,则删除
redisTemplate.delete(otherManager);
} else {
redisTemplate.opsForHash().put(otherManager, "minRecord", minRecord);
}
}
// 删除已完成的订单
redisTemplate.delete(redisMinRecordKey);
// 获取该用户在redis中的订单记录
String key = "user:" + userByPort.getId().toString();
// 获取当前用户所有订单
String minRecord = (String) redisTemplate.opsForHash().get(key, "minRecord");
// 删除用户中当前已完成的订单
minRecord = minRecord.replace(redisMinRecordKey + ",", "");
if (minRecord.length() == 2) {
// []
// 如果当前用户已经没有剩余订单,则删除
redisTemplate.delete(otherManager);
redisTemplate.delete("user:" + userByPort.getId());
} else {
redisTemplate.opsForHash().put(otherManager, "minRecord", minRecord);
redisTemplate.opsForHash().put(key, "minRecord", minRecord);
}
}
// 删除已完成的订单
redisTemplate.delete(redisMinRecordKey);
// 获取该用户在redis中的订单记录
String key = "user:" + userByPort.getId().toString();
// 获取当前用户所有订单
String minRecord = (String) redisTemplate.opsForHash().get(key, "minRecord");
// 删除用户中当前已完成的订单
minRecord = minRecord.replace(redisMinRecordKey + ",", "");
if (minRecord.length() == 2) {
// []
// 如果当前用户已经没有剩余订单,则删除
redisTemplate.delete("user:" + userByPort.getId());
} else {
redisTemplate.opsForHash().put(key, "minRecord", minRecord);
}
// 获取出库仓库信息
Depository depositoryRecordById = depositoryMapper.findDepositoryById(applicationOutMinById.getDepositoryId());
// 设置子订单新编码
// 获取主订单单号
StringBuilder code = new StringBuilder(record.getCode());
// 获取申请用户信息
UserByPort applicantUser = LinkInterfaceUtil.FindUserById(record.getApplicantId(), userByPort);
// 获取申请用户行政组织
Administration company = LinkInterfaceUtil.getCompany(applicantUser.getMaindeparment(), userByPort);
// 获取部门名称简写
String conpanyName = WordUtil.getPinYinHeadChar(company.getName());
// 获取仓库名称简写
String depositoryName = WordUtil.getPinYinHeadChar(depositoryRecordById.getDname());
// 获取部门名称在单号的起始位置
int index = code.indexOf(conpanyName);
// 生产新子订单编号
String newCode = code.replace(index, index + conpanyName.length(), depositoryName).toString();
// 设置完成人
applicationOutMinById.setCheckId(userByPort.getId());
// 设置新编码
applicationOutMinById.setCode(newCode);
// 设置新库位
applicationOutMinById.setPlaceId(placeId);
// 修改子订单
result += depositoryRecordMapper.updateApplicationOutRecordMin(applicationOutMinById);
String redisMainRecordKey = "record:" + record.getId(); // 设置redis中主订单键值
// 获取redis中主订单的所有子订单
String minRecordList = (String) redisTemplate.opsForHash().get(redisMainRecordKey, "minRecord");
// 获取所有子订单键值
String[] split = minRecordList.replace("[", "").replace("]", "").split(",");
int pass = 1; // 设置主订单最终状态
for (int i = 0; i < split.length; i++) {
// 获取所有子订单状态
String state = (String) redisTemplate.opsForHash().get(split[i], "state");
if ("1".equals(state)) {
// 如果有子订单未完成
pass = 3; // 设置主订单状态为处理中
break;
}
}
if (pass == 1) { // 如果最终状态为完成
Map<String, Object> map = new HashMap<>();
map.put("pass", pass);
map.put("id", record.getId());
// 修改状态为完成
depositoryRecordMapper.updateApplicationOutRecord(map);
// 将最终完成的订单抄送给仓储负责人
String depositoryManagerIds = record.getDepositoryManager();
String[] depositoryManagers = new String[0];
if (depositoryManagerIds != null) {
depositoryManagers = depositoryManagerIds.split(",");
// 获取出库仓库信息
Depository depositoryRecordById = depositoryMapper.findDepositoryById(applicationOutMinById.getDepositoryId());
// 设置子订单新编码
// 获取主订单单号
StringBuilder code = new StringBuilder(record.getCode());
// 获取申请用户信息
UserByPort applicantUser = LinkInterfaceUtil.FindUserById(record.getApplicantId(), userByPort);
// 获取申请用户行政组织
Administration company = LinkInterfaceUtil.getCompany(applicantUser.getMaindeparment(), userByPort);
// 获取部门名称简写
String conpanyName = WordUtil.getPinYinHeadChar(company.getName());
// 获取仓库名称简写
String depositoryName = WordUtil.getPinYinHeadChar(depositoryRecordById.getDname());
// 获取部门名称在单号的起始位置
int index = code.indexOf(conpanyName);
// 生产新子订单编号
String newCode = code.replace(index, index + conpanyName.length(), depositoryName).toString();
// 设置新编码
applicationOutMinById.setCode(newCode);
// 设置完成人
applicationOutMinById.setCheckId(userByPort.getId());
// 设置新库位
applicationOutMinById.setPlaceId(placeId);
String redisMainRecordKey = "record:" + record.getId(); // 设置redis中主订单键值
// 获取redis中主订单的所有子订单
String minRecordList = (String) redisTemplate.opsForHash().get(redisMainRecordKey, "minRecord");
// 获取所有子订单键值
String[] split = minRecordList.replace("[", "").replace("]", "").split(",");
int pass = 1; // 设置主订单最终状态
for (int i = 0; i < split.length; i++) {
// 获取所有子订单状态
String state = (String) redisTemplate.opsForHash().get(split[i], "state");
if ("1".equals(state)) {
// 如果有子订单未完成
pass = 3; // 设置主订单状态为处理中
break;
}
}
StringBuilder depositoryManagerByQyWx = new StringBuilder();
for (int i = 0; i < depositoryManagers.length; i++) {
Integer uid = ObjectFormatUtil.toInteger(depositoryManagers[i]);
UserByPort depositoryManager = LinkInterfaceUtil.FindUserById(uid, userByPort);
if (pass == 1) { // 如果最终状态为完成
Map<String, Object> map = new HashMap<>();
map.put("pass", pass);
map.put("id", record.getId());
// 修改状态为完成
depositoryRecordMapper.updateApplicationOutRecord(map);
// 将最终完成的订单抄送给仓储负责人
String depositoryManagerIds = record.getDepositoryManager();
String[] depositoryManagers = new String[0];
if (depositoryManagerIds != null) {
depositoryManagers = depositoryManagerIds.split(",");
}
StringBuilder depositoryManagerByQyWx = new StringBuilder();
for (int i = 0; i < depositoryManagers.length; i++) {
Integer uid = ObjectFormatUtil.toInteger(depositoryManagers[i]);
UserByPort depositoryManager = LinkInterfaceUtil.FindUserById(uid, userByPort);
// depositoryManagerByQyWx.append(depositoryManager.getWorkwechat()+",");
}
depositoryManagerByQyWx.append("PangFuZhen,");
JSONObject jsonObject = qyWxOperationService.sendCcMessageToUsers(depositoryManagerByQyWx.toString(), record.getId(), userAgent);
}
depositoryManagerByQyWx.append("PangFuZhen,");
JSONObject jsonObject = qyWxOperationService.sendCcMessageToUsers(depositoryManagerByQyWx.toString(), record.getId(), userAgent);
// 删除redis中本订单
redisTemplate.delete("record:" + record.getId());
// 删除redis中本订单
redisTemplate.delete("record:" + record.getId());
}
}
// 修改子订单
result += depositoryRecordMapper.updateApplicationOutRecordMin(applicationOutMinById);
// 如果是库存转移订单
Map<String, Object> map = new HashMap<>();
if (record.getIstransfer() == 1) {
map.put("quantity", record.getQuantity().toString());
map.put("quantity", trueOut.toString());
map.put("applicantId", record.getApplicantId());
map.put("minRecordId", applicationOutMinById.getId()); // 出库订单编号
transferMaterial(map);

32
src/main/java/com/dreamchaser/depository_manage/service/impl/ExcelServiceImpl.java

@ -227,13 +227,17 @@ public class ExcelServiceImpl implements ExcelService {
List<ExcelInfoByInventory> excelVos = new ArrayList<>();
// 判断当前库位码是否正确,并存入库位中
for (int i = 0; i < excelInfoByInventories.size(); i++) {
Material materialByCode = materialService.findMaterialByCode(excelInfoByInventories.get(i).getCode());
Map<String,Object> map = new HashMap<>();
map.put("code",materialByCode.getCode());
// 获取当前编码的库存 如果有库存,则跳过
materialService.findInventory(map);
String placeCode = excelInfoByInventories.get(i).getDepositoryCode();
Integer depositoryId = excelInfoByInventories.get(i).getDepositoryId();
// 获取当前库存记录
ExcelInfoByInventory excelInfoByInventory = excelInfoByInventories.get(i);
// 获取库存明细名称
String mname = excelInfoByInventory.getMname();
// 获取当前库存明细规格
String version = excelInfoByInventory.getVersion();
String placeCode = excelInfoByInventory.getDepositoryCode();
Integer depositoryId = excelInfoByInventory.getDepositoryId();
// 如果导入时输入库位信息
if (placeCode != null && !placeCode.isEmpty()) {
Map<String, Object> placeMap = new HashMap<>();
@ -245,26 +249,26 @@ public class ExcelServiceImpl implements ExcelService {
// 如果有库位
Place place = placeByCondition.get(0);
// 如果库位有物料且该库位存放的物料为当前物料
Integer quantity = ObjectFormatUtil.toInteger(excelInfoByInventories.get(i).getQuantity());
Integer quantity = ObjectFormatUtil.toInteger(excelInfoByInventory.getQuantity());
if (quantity > place.getMax() - place.getQuantity()) {
// 如果当前库位无法放下
String s = dataIndex.get(i);
String msg = s + "出现异常:" + excelInfoByInventories.get(i).getDepositoryCode() + " 该库位无法存放当前数目的物料";
String msg = s + "出现异常:" + excelInfoByInventory.getDepositoryCode() + " 该库位无法存放当前数目的物料";
errMsg.add(msg);
continue;
} else {
excelInfoByInventories.get(i).setDepositoryCode(place.getCode());
excelVos.add(excelInfoByInventories.get(i));
excelInfoByInventory.setDepositoryCode(place.getCode());
excelVos.add(excelInfoByInventory);
}
} else {
String s = dataIndex.get(i);
String msg = s + "出现异常:" + excelInfoByInventories.get(i).getDepositoryCode() + " 该仓库没有该库位";
String msg = s + "出现异常:" + excelInfoByInventory.getDepositoryCode() + " 该仓库没有该库位";
errMsg.add(msg);
continue;
}
} else { // 否则直接加入
excelInfoByInventories.get(i).setDepositoryCode("0"); // 设置默认库位
excelVos.add(excelInfoByInventories.get(i));
excelInfoByInventory.setDepositoryCode("0"); // 设置默认库位
excelVos.add(excelInfoByInventory);
}
}

13
src/main/java/com/dreamchaser/depository_manage/service/impl/MaterialServiceImpl.java

@ -392,11 +392,14 @@ public class MaterialServiceImpl implements MaterialService {
* @return 库存信息
*/
@Override
public Material findMaterialByIds(List<Integer> ids) {
Material material = materialMapper.findMaterialByIds(ids);
material.setPrice(material.getPrice() / 100);
material.setAmounts(material.getAmounts() / 100);
return material;
public List<Material> findMaterialByIds(List<Integer> ids) {
List<Material> materialList = materialMapper.findMaterialByIds(ids);
for (int i = 0; i < materialList.size(); i++) {
Material material = materialList.get(i);
materialList.get(i).setPrice(material.getPrice() / 100);
materialList.get(i).setAmounts(material.getAmounts() / 100);
}
return materialList;
}
/**

307
src/main/resources/static/vuePage/index.vue

@ -1,307 +0,0 @@
<template>
<div class="test">
<div class="fixBox">
<div class="iconBox"
@click="() => {
this.$router.history.go(-1);
}">
<i class="iconfont icon-fanhuitubiao"></i>
</div>
<div class="videoBox">
<div class="outVideo" v-if="isAnimation">
<video
autoPlay
ref="outVideo"
webkit-playsinline
x5-video-player-type="h5"
x5-video-player-fullscreen="true"
x-webkit-airplay="true"
playsinline
v-if="!trueFlag"
id="myVideo"
></video>
</div>
<div class="codebg" v-if="!trueFlag">
<div class="line"></div>
</div>
<canvas
id="qr-canvas"
style="width:6rem;height:6rem;"
ref="canvas"
></canvas>
</div>
</div>
</div>
</template>
<script>
import jsQR from "jsqr";
export default {
data() {
return {
photoBase: "",
trueFlag: false,
isAnimation: true
};
},
mounted() {
this.outvideo = this.$refs.outVideo;
this.cvsele = this.$refs.canvas;
this.canvas = this.cvsele.getContext("2d");
this.video = document.createElement("video");
this.$nextTick(() => {
this.getVideo();
});
},
methods: {
getVideo() {
let self = this;
try {
navigator.getUserMedia =
navigator.mediaDevices.getUserMedia ||
navigator.mediaDevices.webkitGetUserMedia ||
navigator.mediaDevices.mozGetUserMedia;
self.URL =
window.URL || window.webkitURL || window.mozURL || window.msURL;
if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
//console.log(navigator.mediaDevices.getUserMedia);
navigator.mediaDevices
.getUserMedia({
video: {facingMode: {exact: "environment"}}
// video: { facingMode: "environment" }
})
.then(stream => {
this.outvideo.srcObject = stream;
this.video.srcObject = stream;
this.video.setAttribute("playsinline", true);
this.video.setAttribute("webkit-playsinline", true);
this.video.addEventListener("loadedmetadata", () => {
this.$refs.outVideo.play();
this.video.play();
this.sweep();
});
setTimeout(() => {
this.$refs.outVideo.play();
this.video.play();
}, 150);
})
.catch(function (err) {
console.log(err);
alert("请允许网站使用您的摄像头权限");
self.$router.history.go(-1);
});
} else if (navigator.getUserMedia) {
navigator
.getUserMedia({
video: true
})
.then(stream => {
this.outvideo.srcObject = stream;
this.video.srcObject = stream;
this.video.setAttribute("playsinline", true);
this.video.setAttribute("webkit-playsinline", true);
this.video.addEventListener("loadedmetadata", () => {
this.$refs.outVideo.play();
this.video.play();
this.sweep();
});
setTimeout(() => {
this.$refs.outVideo.play();
this.video.play();
}, 150);
})
.catch(function (err) {
alert(err);
});
}
} catch (err) {
console.error(err);
}
},
sweep() {
if (this.video.readyState === this.video.HAVE_ENOUGH_DATA) {
const {videoWidth, videoHeight} = this.video;
this.cvsele.width = videoWidth;
this.cvsele.height = videoHeight;
this.canvas.drawImage(this.video, 0, 0, videoWidth, videoHeight);
try {
const img = this.canvas.getImageData(0, 0, videoWidth, videoHeight);
this.imgurl = img;
const obj = jsQR(img.data, img.width, img.height, {
inversionAttempts: "dontInvert"
});
console.log(obj);
if (obj) {
const loc = obj.location;
this.draw(loc.topLeftCorner, loc.topRightCorner);
this.draw(loc.topRightCorner, loc.bottomRightCorner);
this.draw(loc.bottomRightCorner, loc.bottomLeftCorner);
this.draw(loc.bottomLeftCorner, loc.topLeftCorner);
if (obj.data) {
console.info("识别结果:", obj.data);
this.isAnimation = false;
}
} else {
// console.error("");
}
} catch (err) {
// console.error("", err);
}
}
if (this.isAnimation) {
this.timer = requestAnimationFrame(() => {
this.sweep();
});
}
},
draw(begin, end) {
this.canvas.beginPath();
this.canvas.moveTo(begin.x, begin.y);
this.canvas.lineTo(end.x, end.y);
this.canvas.lineWidth = 3;
this.canvas.strokeStyle = "red";
this.canvas.stroke();
},
},
};
</script>
<style lang="scss" scoped>
.test {
width: 100vw;
height: 100vh;
overflow: hidden;
}
.biginSearch {
outline: none;
border: none;
width: 3.15rem;
height: 0.8rem;
background: var(--themeColorzc);
border-radius: 0.1rem;
color: #fff;
font-weight: 700;
margin-top: 0.3rem;
font-size: 0.3rem;
}
.fixBox {
position: fixed;
top: 0;
left: 0;
bottom: 0;
right: 0;
// background: rgba(47, 47, 47, 0.81);
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
.videoBox {
// border: 2px solid rgba(247, 241, 241, 0.81);
// width: 6rem;
// height: 6rem;
// overflow: hidden;
width: 100%;
height: 100%;
position: relative;
background-color: black;
.outVideo {
width: 100vw;
height: 100vh;
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
z-index: 999;
background-color: black;
video {
width: 100%;
height: 100%;
object-fit: fill;
}
}
}
canvas {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
.codebg {
position: absolute;
width: 6rem;
height: 6rem;
margin: 0px auto;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
z-index: 999;
/*此处为了居中*/
// background: url(img/ewm1.jpg) center top no-repeat;
/*二维码*/
}
.line {
position: absolute;
left: 0px;
z-index: 2;
height: 3px;
width: 6rem;
/* background: url(img/share/dapai.png) no-repeat; */
/*上下扫的线*/
background-color: var(--themeColorzc);
opacity: 0.5;
/*动画效果*/
animation: myScan 1s infinite alternate;
-webkit-animation: myScan 1s infinite alternate;
}
@keyframes myScan {
from {
top: 0px;
}
to {
top: 300px;
}
}
@font-face {
font-family: "iconfont"; /* Project id 2570754 */
src: url("//at.alicdn.com/t/font_2570754_w4gqnoegfag.woff2?t=1629957776725") format("woff2"),
url("//at.alicdn.com/t/font_2570754_w4gqnoegfag.woff?t=1629957776725") format("woff"),
url("//at.alicdn.com/t/font_2570754_w4gqnoegfag.ttf?t=1629957776725") format("truetype");
}
.iconfont {
font-family: "iconfont" !important;
font-size: 16px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.icon-fanhuitubiao:before {
font-size: 0.48rem;
color: #fff;
content: "\e65c";
}
.iconBox {
position: absolute;
top: 0.3rem;
left: 0.3rem;
}
</style>

68
src/main/resources/static/vuePage/scanCode.vue

@ -1,68 +0,0 @@
<template>
<div>
<p class="error">{{ error }}</p><!--错误信息-->
<p class="decode-result">扫描结果: <b>{{ result }}</b></p><!--扫描结果-->
<qrcode-stream @decode="onDecode" @init="onInit"/>
</div>
</template>
<script>
//
//cnpm install --save vue-qrcode-reader
//
import {QrcodeStream} from 'static/lib/vue-qrcode-reader';
export default {
//
name: "scanCode",
components: {QrcodeStream},
data() {
return {
result: '',//
error: '',//
}
},
methods: {
onDecode(result) {
alert(result);
this.result = result
},
async onInit(promise) {
try {
await promise
} catch (error) {
if (error.name === 'NotAllowedError') {
this.error = "ERROR: 您需要授予相机访问权限"
} else if (error.name === 'NotFoundError') {
this.error = "ERROR: 这个设备上没有摄像头"
} else if (error.name === 'NotSupportedError') {
this.error = "ERROR: 所需的安全上下文(HTTPS、本地主机)"
} else if (error.name === 'NotReadableError') {
this.error = "ERROR: 相机被占用"
} else if (error.name === 'OverconstrainedError') {
this.error = "ERROR: 安装摄像头不合适"
} else if (error.name === 'StreamApiNotSupportedError') {
this.error = "ERROR: 此浏览器不支持流API"
}
}
}
}
}
</script>
<style scoped>
.error {
font-weight: bold;
color: red;
}
</style>

1
src/main/resources/templates/pages/application/application-out_min-mobile.html

@ -59,7 +59,6 @@
var data = d.data;
if(state === "0") {
for (let i = 0; i < data.length; i++) {
console.log(data[i]);
let producedDate = data[i].producedDate === null?"":data[i].producedDate;
// 头部信息
lis.push('<li style="width:100%;">' +

364
src/main/resources/templates/pages/scanQrCode/ScanBarOrQrCodeOut.html

@ -23,7 +23,7 @@
<input id="id" style="display: none" th:value="${record.getId()}">
<input id="mcode" style="display: none" th:value="${materialById.getCode()}">
<input id="depositoryId" style="display: none" th:value="${record.getDepositoryId()}">
<input id="quantity" style="display: none" th:value="${record.getQuantity()}">
<input id="quantity" style="display: none" th:value="${record.getQuantity() - record.getTrueOut()}">
<div style="width: 500px" id="reader">
</div>
@ -38,6 +38,7 @@
// 先定义,用于弹出确定框
function isOutTrue() {
}
function outQuantityCheck() {
}
@ -53,7 +54,7 @@
parent.parent.parent.wx.scanQRCode({
desc: 'scanQRCode desc',
needResult: 1, // 默认为0,扫描结果由企业微信处理,1则直接返回扫描结果,
scanType: ["barCode","qrCode"], // 可以指定扫二维码还是条形码(一维码),默认二者都有
scanType: ["barCode", "qrCode"], // 可以指定扫二维码还是条形码(一维码),默认二者都有
success: function (res) {
// 回调
var result = res.resultStr;//当needResult为1时返回处理结果
@ -62,7 +63,7 @@
outboundLogic(req);
},
error: function(res) {
error: function (res) {
if (res.errMsg.indexOf('function_not_exist') > 0) {
alert('版本过低请升级')
}
@ -76,52 +77,52 @@
// 弹出出库确定弹出框
isOutTrue = function (req) {
var confirmIndex = layer.confirm("确定出库?", {
btn: ["确定", "取消"]
},
btn: ["确定", "取消"]
},
function () { // 如果确定出库
layui.$.ajax({
url: "/depositoryRecord/isCheckOut",
type: "post",
dataType: 'json',
data: JSON.stringify(req),
contentType: "application/json;charset=utf-8",
success: function (res) {
if (res.status === 200) {
// 如果出库成功
layer.msg("出库成功",
{
icon: 6,
time: 500
}
, function () {
layer.close(layer.index);
var index = parent.layer.getFrameIndex(window.name);
parent.layer.close(index);
layui.$.ajax({
url: "/depositoryRecord/isCheckOut",
type: "post",
dataType: 'json',
data: JSON.stringify(req),
contentType: "application/json;charset=utf-8",
success: function (res) {
if (res.status === 200) {
// 如果出库成功
layer.msg("出库成功",
{
icon: 6,
time: 500
}
, function () {
layer.close(layer.index);
var index = parent.layer.getFrameIndex(window.name);
parent.layer.close(index);
});
} else {
// 如果出库失败
layer.msg(res.statusInfo.detail + ",请重试");
depository = null;
material = null;
place = null;
// 继续扫描
html5QrCode.start({facingMode: {exact: "environment"}}, config, qrCodeSuccessCallback); // 继续扫描
return
}
});
} else {
// 如果出库失败
layer.msg(res.statusInfo.detail + ",请重试");
depository = null;
material = null;
place = null;
// 继续扫描
html5QrCode.start({facingMode: {exact: "environment"}}, config, qrCodeSuccessCallback); // 继续扫描
}
})
},
}
}
})
},
function () {
// 如果取消
depository = null;
material = null;
place = null;
layer.close(layer.index);
var index = parent.layer.getFrameIndex(window.name);
parent.layer.close(index);
}
// 如果取消
depository = null;
material = null;
place = null;
layer.close(layer.index);
var index = parent.layer.getFrameIndex(window.name);
parent.layer.close(index);
}
)
};
@ -140,8 +141,8 @@
if (flag === 0) {
// 如果是无效码
layer.confirm("扫描失败,是否重新扫描", {
btn: ["确定","取消"]
},function () {
btn: ["确定", "取消"]
}, function () {
parent.parent.parent.wx.scanQRCode({
desc: 'scanQRCode desc',
needResult: 1, // 默认为0,扫描结果由企业微信处理,1则直接返回扫描结果,
@ -154,19 +155,18 @@
outboundLogic(req);
}
})
},function () {
}, function () {
// 关闭当前页
var index = parent.layer.getFrameIndex(window.name);
parent.layer.close(index);
})
}
else if (flag === 1) {
} else if (flag === 1) {
// 如果是物料
material = data.material;
if (mcode !== material.code && Number(mcode) !== material.code && mcode !== material.code.toString()) {
if (mcode !== material.code && Number(mcode) !== material.code && mcode !== material.code.toString()) {
layer.confirm("出库物料不正确,请重新扫描", {
btn: ["确定","取消"]
}, function(){
btn: ["确定", "取消"]
}, function () {
material = null;
parent.parent.parent.wx.scanQRCode({
desc: 'scanQRCode desc',
@ -180,15 +180,14 @@
outboundLogic(req);
}
})
},
},
function () {
// 关闭当前页
var index = parent.layer.getFrameIndex(window.name);
parent.layer.close(index);
// 关闭当前页
var index = parent.layer.getFrameIndex(window.name);
parent.layer.close(index);
})
}
else {
})
} else {
if (depository !== null) { // 如果已经扫描仓库
if (depositoryId !== depository.did && Number(depositoryId) !== depository.did && depositoryId !== depository.did.toString()) {
// 如果扫描的仓库不是订单要求的仓库
@ -209,8 +208,7 @@
// 弹出确定框
outQuantityCheck(param);
}
}
else if (place != null) {
} else if (place != null) {
// 如果已经扫描库位
if (depositoryId !== place.did && Number(depositoryId) !== place.did && depositoryId !== place.did.toString()) {
// 如果当前仓库不是订单对应仓库
@ -243,14 +241,14 @@
// 弹出确定框
outQuantityCheck(param);
}
}
else {
} else {
var codeType = data.CodeType;
if(codeType === 1){
if (codeType === 1) {
qrCode = req.qrCode;
}else{
} else {
barCode = req.qrCode;
};
}
layer.confirm("请扫描仓库或库位", {
btn: ["扫描", "取消"]
}, function () { // 继续
@ -276,125 +274,141 @@
}
}
}
else if (flag === 2) {
// 如果扫描的为库位
place = data.place;// 将扫描结果保存到vue中
if ( material == null) {
// 如果还没有扫描物料
layer.confirm("请扫描物料", {
btn: ["扫描", "取消"]
}, function () { // 继续
layer.close(layer.index); // 关闭弹窗
parent.parent.parent.wx.scanQRCode({
desc: 'scanQRCode desc',
needResult: 1, // 默认为0,扫描结果由企业微信处理,1则直接返回扫描结果,
scanType: ["barCode","qrCode"], // 可以指定扫二维码还是条形码(一维码),默认二者都有
success: function (res) {
// 回调
var result = res.resultStr;//当needResult为1时返回处理结果
var req = {};
req.qrCode = result;
outboundLogic(req)
}
})
}, function () { // 取消
} else if (flag === 2) {
// 如果扫描的为库位
place = data.place;// 将扫描结果保存到vue中
if (material == null) {
// 如果还没有扫描物料
layer.confirm("是否进行扫描物料", {
btn: ["扫描", "选择"]
}, function () { // 继续
layer.close(layer.index); // 关闭弹窗
parent.parent.parent.wx.scanQRCode({
desc: 'scanQRCode desc',
needResult: 1, // 默认为0,扫描结果由企业微信处理,1则直接返回扫描结果,
scanType: ["barCode", "qrCode"], // 可以指定扫二维码还是条形码(一维码),默认二者都有
success: function (res) {
// 回调
var result = res.resultStr;//当needResult为1时返回处理结果
var req = {};
req.qrCode = result;
outboundLogic(req)
}
})
}, function () { // 取消
// 进行选择对应物料
layer.open({
title: '物料列表',
type: 2,
shade: 0.2,
maxmin: true,
shadeClose: true,
area: ['50%', '50%'],
content: '/ScanBarOrQrCodeOut_selectMaterial?pid=' + place.id+'&mcode='+mcode,
end: function () {
var param = {};
param.id = id;
param.placeId = place.id;
param.qrCode = qrCode;
param.barCode = barCode;
// 弹出确定框
outQuantityCheck(param);
}
})
/*var index = parent.layer.getFrameIndex(window.name);
parent.layer.close(index);*/
})
} else {
if (depositoryId !== place.did && Number(depositoryId) !== place.did && depositoryId !== place.did.toString()) {
// 如果当前仓库不是订单对应仓库
depository = null;
place = null;
layer.confirm("当前库位不符合要求,请移步至正确库位", {
btn: ["确定"]
}, function () {
// 关闭当前页
var index = parent.layer.getFrameIndex(window.name);
parent.layer.close(index);
})
} else if (place.mcodeList.indexOf(mcode) === -1) {
// 如果当前库位不存在该物料
depository = null;
place = null;
layer.confirm("出库库位不含该物料,请重新扫描", {
btn: ["确定"]
}, function () {
// 关闭当前页
var index = parent.layer.getFrameIndex(window.name);
parent.layer.close(index);
})
} else {
if (depositoryId !== place.did && Number(depositoryId) !== place.did && depositoryId !== place.did.toString()) {
// 如果当前仓库不是订单对应仓库
depository = null;
place = null;
layer.confirm("当前库位不符合要求,请移步至正确库位", {
btn: ["确定"]
}, function () {
// 关闭当前页
var index = parent.layer.getFrameIndex(window.name);
parent.layer.close(index);
})
} else if (place.mcodeList.indexOf(mcode) === -1) {
// 如果当前库位不存在该物料
depository = null;
place = null;
layer.confirm("出库库位不含该物料,请重新扫描", {
btn: ["确定"]
}, function () {
// 关闭当前页
var index = parent.layer.getFrameIndex(window.name);
parent.layer.close(index);
})
} else {
var param = {};
param.id = id;
param.placeId = place.id;
param.qrCode = qrCode;
param.barCode = barCode;
// 弹出确定框
outQuantityCheck(param);
}
var param = {};
param.id = id;
param.placeId = place.id;
param.qrCode = qrCode;
param.barCode = barCode;
// 弹出确定框
outQuantityCheck(param);
}
}
}
else if (flag === 3) {
} else if (flag === 3) {
// 如果是仓库
depository = data.depository;// 将扫描结果保存到vue中
if (material == null) {
// 如果还没有扫描物料
layer.confirm("请扫描物料", {
btn: ["扫描", "取消"]
}, function () { // 继续
layer.close(layer.index); // 关闭弹窗
parent.parent.parent.wx.scanQRCode({
desc: 'scanQRCode desc',
needResult: 1, // 默认为0,扫描结果由企业微信处理,1则直接返回扫描结果,
scanType: ["barCode","qrCode"], // 可以指定扫二维码还是条形码(一维码),默认二者都有
success: function (res) {
// 回调
var result = res.resultStr;//当needResult为1时返回处理结果
var req = {};
req.qrCode = result;
outboundLogic(req);
if (material == null) {
// 如果还没有扫描物料
layer.confirm("请扫描物料", {
btn: ["扫描", "取消"]
}, function () { // 继续
layer.close(layer.index); // 关闭弹窗
parent.parent.parent.wx.scanQRCode({
desc: 'scanQRCode desc',
needResult: 1, // 默认为0,扫描结果由企业微信处理,1则直接返回扫描结果,
scanType: ["barCode", "qrCode"], // 可以指定扫二维码还是条形码(一维码),默认二者都有
success: function (res) {
// 回调
var result = res.resultStr;//当needResult为1时返回处理结果
var req = {};
req.qrCode = result;
outboundLogic(req);
}
}
});
});
}, function () { // 取消
}, function () { // 取消
// 关闭当前页
var index = parent.layer.getFrameIndex(window.name);
parent.layer.close(index);
})
} else {
// 如果已经扫描物料
if (depositoryId !== depository.id && Number(depositoryId) !== depository.id && depositoryId !== depository.id.toString()) {
// 如果当前仓库不是订单对应仓库
depository = null;
place = null;
layer.confirm("当前仓库不符合要求,请移步至正确仓库", {
btn: ["确定"]
}, function () {
// 关闭当前页
var index = parent.layer.getFrameIndex(window.name);
parent.layer.close(index);
})
} else {
// 如果已经扫描物料
if (depositoryId !== depository.id && Number(depositoryId) !== depository.id && depositoryId !== depository.id.toString()) {
// 如果当前仓库不是订单对应仓库
depository = null;
place = null;
layer.confirm("当前仓库不符合要求,请移步至正确仓库", {
btn: ["确定"]
}, function () {
// 关闭当前页
var index = parent.layer.getFrameIndex(window.name);
parent.layer.close(index);
})
} else {
// 如果正确
var param = {};
param.id = id;
param.qrCode = qrCode;
param.barCode = barCode;
// 弹出确定框
outQuantityCheck(param);
// 如果正确
var param = {};
param.id = id;
param.qrCode = qrCode;
param.barCode = barCode;
// 弹出确定框
outQuantityCheck(param);
}
}
}
}
}
})
@ -405,17 +419,17 @@
formType: 0,
value: quantity,
title: '请输入出库数量',
}, function(value, index, elem){
if(value > quantity){
layer.msg("非法值,重新输入!",{
icon: 0,
time: 500
},
function () {
outQuantityCheck(req);
})
}else{
req.quantity = value;
}, function (value, index, elem) {
if (value > quantity) {
layer.msg("非法值,重新输入!", {
icon: 0,
time: 500
},
function () {
outQuantityCheck(req);
})
} else {
req.trueOut = value;
layer.close(index);
isOutTrue(req);
}

53
src/main/resources/templates/pages/scanQrCode/ScanBarOrQrCodeOut_selectMaterial.html

@ -0,0 +1,53 @@
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8">
<title>首页二</title>
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<link rel="stylesheet" href="/static/lib/layui-v2.6.3/css/layui.css" media="all">
<link rel="stylesheet" href="/static/lib/font-awesome-4.7.0/css/font-awesome.min.css" media="all">
<link rel="stylesheet" href="/static/css/public.css" media="all">
</head>
<body>
<input th:value="${mcode}" style="display:none;" id="mcode">
<div class="layui-btn-container">
<button class="layui-btn layui-btn-primary select_this" th:each="material,iterStar:${materialList}" th:value="${material.getCode()}"
th:text="${material.getMname()}">
<i class="layui-icon layui-icon-down layui-font-12"></i>
</button>
</div>
<script src="/static/lib/layui-v2.6.3/layui.js" charset="utf-8"></script>
<script src="/static/js/lay-config.js?v=1.0.4" charset="utf-8"></script>
<script>
layui.use(['layer'], function () {
var $ = layui.jquery,
layer = layui.layer;
let mcode = $("#mcode").val();
// 给每个按钮添加点击事件
$(".select_this").on("click",function () {
// 获取当前点击物料编码
var code = this.value;
// 获取当前点击物料名称
var mname = this.innerText;
if(code !== mcode){
// 如果点击的不是要出库的物料
layer.msg("请选择正确物料",{
icon:0,
time:500
},function () {
})
}else{
var index = parent.layer.getFrameIndex(window.name);
parent.layer.close(index);
}
})
})
</script>
</body>
</html>

15
target/classes/com/dreamchaser/depository_manage/mapper/DepositoryRecordMapper.xml

@ -142,7 +142,7 @@
</sql>
<sql id="ApplicationOutRecordMinInfo">
aorm.id,aorm.mid,aorm.depositoryId,aorm.placeId,aorm.quantity,aorm.code,aorm.checkId,aorm.parentId,aorm.transferId
aorm.id,aorm.mid,aorm.depositoryId,aorm.placeId,aorm.quantity,aorm.code,aorm.checkId,aorm.parentId,aorm.transferId,aorm.trueOut
</sql>
<!-- 查询所有数据行数 -->
<select id="findCount" resultType="integer">
@ -667,7 +667,7 @@
<!-- 插入一条出库子订单-->
<insert id="insertApplicationOutRecordMin" parameterType="map" useGeneratedKeys="true" keyProperty="id">
insert into application_out_record_min (id,mid,quantity,code,depositoryId,placeId,checkId,parentId,transferId)
insert into application_out_record_min (id,mid,quantity,code,depositoryId,placeId,checkId,parentId,transferId,trueOut)
values(
#{id},
#{mid},
@ -677,7 +677,8 @@
#{placeId},
#{checkId},
#{parentId},
#{transferId}
#{transferId},
#{trueOut}
)
</insert>
@ -734,6 +735,9 @@
<if test="parentId != null">
and aorm.parentId = #{parentId}
</if>
<if test="trueOut != null">
and arom.trueOut = #{trueOut}
</if>
</select>
@ -918,7 +922,10 @@
checkId = #{checkId},
</if>
<if test="parentId != null ">
parentId = #{parentId}
parentId = #{parentId},
</if>
<if test="trueOut != null">
trueOut = #{trueOut}
</if>
where id = #{id}

2
target/classes/com/dreamchaser/depository_manage/mapper/MaterialMapper.xml

@ -544,7 +544,7 @@
SELECT
<include refid="allColumns" />
FROM material m WHERE m.id IN
<foreach collection="ids" index="index" item="id" open="(" separator="," close=")">
<foreach collection="list" index="index" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</select>

307
target/classes/static/vuePage/index.vue

@ -1,307 +0,0 @@
<template>
<div class="test">
<div class="fixBox">
<div class="iconBox"
@click="() => {
this.$router.history.go(-1);
}">
<i class="iconfont icon-fanhuitubiao"></i>
</div>
<div class="videoBox">
<div class="outVideo" v-if="isAnimation">
<video
autoPlay
ref="outVideo"
webkit-playsinline
x5-video-player-type="h5"
x5-video-player-fullscreen="true"
x-webkit-airplay="true"
playsinline
v-if="!trueFlag"
id="myVideo"
></video>
</div>
<div class="codebg" v-if="!trueFlag">
<div class="line"></div>
</div>
<canvas
id="qr-canvas"
style="width:6rem;height:6rem;"
ref="canvas"
></canvas>
</div>
</div>
</div>
</template>
<script>
import jsQR from "jsqr";
export default {
data() {
return {
photoBase: "",
trueFlag: false,
isAnimation: true
};
},
mounted() {
this.outvideo = this.$refs.outVideo;
this.cvsele = this.$refs.canvas;
this.canvas = this.cvsele.getContext("2d");
this.video = document.createElement("video");
this.$nextTick(() => {
this.getVideo();
});
},
methods: {
getVideo() {
let self = this;
try {
navigator.getUserMedia =
navigator.mediaDevices.getUserMedia ||
navigator.mediaDevices.webkitGetUserMedia ||
navigator.mediaDevices.mozGetUserMedia;
self.URL =
window.URL || window.webkitURL || window.mozURL || window.msURL;
if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
//console.log(navigator.mediaDevices.getUserMedia);
navigator.mediaDevices
.getUserMedia({
video: {facingMode: {exact: "environment"}}
// video: { facingMode: "environment" }
})
.then(stream => {
this.outvideo.srcObject = stream;
this.video.srcObject = stream;
this.video.setAttribute("playsinline", true);
this.video.setAttribute("webkit-playsinline", true);
this.video.addEventListener("loadedmetadata", () => {
this.$refs.outVideo.play();
this.video.play();
this.sweep();
});
setTimeout(() => {
this.$refs.outVideo.play();
this.video.play();
}, 150);
})
.catch(function (err) {
console.log(err);
alert("请允许网站使用您的摄像头权限");
self.$router.history.go(-1);
});
} else if (navigator.getUserMedia) {
navigator
.getUserMedia({
video: true
})
.then(stream => {
this.outvideo.srcObject = stream;
this.video.srcObject = stream;
this.video.setAttribute("playsinline", true);
this.video.setAttribute("webkit-playsinline", true);
this.video.addEventListener("loadedmetadata", () => {
this.$refs.outVideo.play();
this.video.play();
this.sweep();
});
setTimeout(() => {
this.$refs.outVideo.play();
this.video.play();
}, 150);
})
.catch(function (err) {
alert(err);
});
}
} catch (err) {
console.error(err);
}
},
sweep() {
if (this.video.readyState === this.video.HAVE_ENOUGH_DATA) {
const {videoWidth, videoHeight} = this.video;
this.cvsele.width = videoWidth;
this.cvsele.height = videoHeight;
this.canvas.drawImage(this.video, 0, 0, videoWidth, videoHeight);
try {
const img = this.canvas.getImageData(0, 0, videoWidth, videoHeight);
this.imgurl = img;
const obj = jsQR(img.data, img.width, img.height, {
inversionAttempts: "dontInvert"
});
console.log(obj);
if (obj) {
const loc = obj.location;
this.draw(loc.topLeftCorner, loc.topRightCorner);
this.draw(loc.topRightCorner, loc.bottomRightCorner);
this.draw(loc.bottomRightCorner, loc.bottomLeftCorner);
this.draw(loc.bottomLeftCorner, loc.topLeftCorner);
if (obj.data) {
console.info("识别结果:", obj.data);
this.isAnimation = false;
}
} else {
// console.error("");
}
} catch (err) {
// console.error("", err);
}
}
if (this.isAnimation) {
this.timer = requestAnimationFrame(() => {
this.sweep();
});
}
},
draw(begin, end) {
this.canvas.beginPath();
this.canvas.moveTo(begin.x, begin.y);
this.canvas.lineTo(end.x, end.y);
this.canvas.lineWidth = 3;
this.canvas.strokeStyle = "red";
this.canvas.stroke();
},
},
};
</script>
<style lang="scss" scoped>
.test {
width: 100vw;
height: 100vh;
overflow: hidden;
}
.biginSearch {
outline: none;
border: none;
width: 3.15rem;
height: 0.8rem;
background: var(--themeColorzc);
border-radius: 0.1rem;
color: #fff;
font-weight: 700;
margin-top: 0.3rem;
font-size: 0.3rem;
}
.fixBox {
position: fixed;
top: 0;
left: 0;
bottom: 0;
right: 0;
// background: rgba(47, 47, 47, 0.81);
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
.videoBox {
// border: 2px solid rgba(247, 241, 241, 0.81);
// width: 6rem;
// height: 6rem;
// overflow: hidden;
width: 100%;
height: 100%;
position: relative;
background-color: black;
.outVideo {
width: 100vw;
height: 100vh;
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
z-index: 999;
background-color: black;
video {
width: 100%;
height: 100%;
object-fit: fill;
}
}
}
canvas {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
.codebg {
position: absolute;
width: 6rem;
height: 6rem;
margin: 0px auto;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
z-index: 999;
/*此处为了居中*/
// background: url(img/ewm1.jpg) center top no-repeat;
/*二维码*/
}
.line {
position: absolute;
left: 0px;
z-index: 2;
height: 3px;
width: 6rem;
/* background: url(img/share/dapai.png) no-repeat; */
/*上下扫的线*/
background-color: var(--themeColorzc);
opacity: 0.5;
/*动画效果*/
animation: myScan 1s infinite alternate;
-webkit-animation: myScan 1s infinite alternate;
}
@keyframes myScan {
from {
top: 0px;
}
to {
top: 300px;
}
}
@font-face {
font-family: "iconfont"; /* Project id 2570754 */
src: url("//at.alicdn.com/t/font_2570754_w4gqnoegfag.woff2?t=1629957776725") format("woff2"),
url("//at.alicdn.com/t/font_2570754_w4gqnoegfag.woff?t=1629957776725") format("woff"),
url("//at.alicdn.com/t/font_2570754_w4gqnoegfag.ttf?t=1629957776725") format("truetype");
}
.iconfont {
font-family: "iconfont" !important;
font-size: 16px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.icon-fanhuitubiao:before {
font-size: 0.48rem;
color: #fff;
content: "\e65c";
}
.iconBox {
position: absolute;
top: 0.3rem;
left: 0.3rem;
}
</style>

68
target/classes/static/vuePage/scanCode.vue

@ -1,68 +0,0 @@
<template>
<div>
<p class="error">{{ error }}</p><!--错误信息-->
<p class="decode-result">扫描结果: <b>{{ result }}</b></p><!--扫描结果-->
<qrcode-stream @decode="onDecode" @init="onInit"/>
</div>
</template>
<script>
//
//cnpm install --save vue-qrcode-reader
//
import {QrcodeStream} from 'static/lib/vue-qrcode-reader';
export default {
//
name: "scanCode",
components: {QrcodeStream},
data() {
return {
result: '',//
error: '',//
}
},
methods: {
onDecode(result) {
alert(result);
this.result = result
},
async onInit(promise) {
try {
await promise
} catch (error) {
if (error.name === 'NotAllowedError') {
this.error = "ERROR: 您需要授予相机访问权限"
} else if (error.name === 'NotFoundError') {
this.error = "ERROR: 这个设备上没有摄像头"
} else if (error.name === 'NotSupportedError') {
this.error = "ERROR: 所需的安全上下文(HTTPS、本地主机)"
} else if (error.name === 'NotReadableError') {
this.error = "ERROR: 相机被占用"
} else if (error.name === 'OverconstrainedError') {
this.error = "ERROR: 安装摄像头不合适"
} else if (error.name === 'StreamApiNotSupportedError') {
this.error = "ERROR: 此浏览器不支持流API"
}
}
}
}
}
</script>
<style scoped>
.error {
font-weight: bold;
color: red;
}
</style>

1
target/classes/templates/pages/application/application-out_min-mobile.html

@ -59,7 +59,6 @@
var data = d.data;
if(state === "0") {
for (let i = 0; i < data.length; i++) {
console.log(data[i]);
let producedDate = data[i].producedDate === null?"":data[i].producedDate;
// 头部信息
lis.push('<li style="width:100%;">' +

364
target/classes/templates/pages/scanQrCode/ScanBarOrQrCodeOut.html

@ -23,7 +23,7 @@
<input id="id" style="display: none" th:value="${record.getId()}">
<input id="mcode" style="display: none" th:value="${materialById.getCode()}">
<input id="depositoryId" style="display: none" th:value="${record.getDepositoryId()}">
<input id="quantity" style="display: none" th:value="${record.getQuantity()}">
<input id="quantity" style="display: none" th:value="${record.getQuantity() - record.getTrueOut()}">
<div style="width: 500px" id="reader">
</div>
@ -38,6 +38,7 @@
// 先定义,用于弹出确定框
function isOutTrue() {
}
function outQuantityCheck() {
}
@ -53,7 +54,7 @@
parent.parent.parent.wx.scanQRCode({
desc: 'scanQRCode desc',
needResult: 1, // 默认为0,扫描结果由企业微信处理,1则直接返回扫描结果,
scanType: ["barCode","qrCode"], // 可以指定扫二维码还是条形码(一维码),默认二者都有
scanType: ["barCode", "qrCode"], // 可以指定扫二维码还是条形码(一维码),默认二者都有
success: function (res) {
// 回调
var result = res.resultStr;//当needResult为1时返回处理结果
@ -62,7 +63,7 @@
outboundLogic(req);
},
error: function(res) {
error: function (res) {
if (res.errMsg.indexOf('function_not_exist') > 0) {
alert('版本过低请升级')
}
@ -76,52 +77,52 @@
// 弹出出库确定弹出框
isOutTrue = function (req) {
var confirmIndex = layer.confirm("确定出库?", {
btn: ["确定", "取消"]
},
btn: ["确定", "取消"]
},
function () { // 如果确定出库
layui.$.ajax({
url: "/depositoryRecord/isCheckOut",
type: "post",
dataType: 'json',
data: JSON.stringify(req),
contentType: "application/json;charset=utf-8",
success: function (res) {
if (res.status === 200) {
// 如果出库成功
layer.msg("出库成功",
{
icon: 6,
time: 500
}
, function () {
layer.close(layer.index);
var index = parent.layer.getFrameIndex(window.name);
parent.layer.close(index);
layui.$.ajax({
url: "/depositoryRecord/isCheckOut",
type: "post",
dataType: 'json',
data: JSON.stringify(req),
contentType: "application/json;charset=utf-8",
success: function (res) {
if (res.status === 200) {
// 如果出库成功
layer.msg("出库成功",
{
icon: 6,
time: 500
}
, function () {
layer.close(layer.index);
var index = parent.layer.getFrameIndex(window.name);
parent.layer.close(index);
});
} else {
// 如果出库失败
layer.msg(res.statusInfo.detail + ",请重试");
depository = null;
material = null;
place = null;
// 继续扫描
html5QrCode.start({facingMode: {exact: "environment"}}, config, qrCodeSuccessCallback); // 继续扫描
return
}
});
} else {
// 如果出库失败
layer.msg(res.statusInfo.detail + ",请重试");
depository = null;
material = null;
place = null;
// 继续扫描
html5QrCode.start({facingMode: {exact: "environment"}}, config, qrCodeSuccessCallback); // 继续扫描
}
})
},
}
}
})
},
function () {
// 如果取消
depository = null;
material = null;
place = null;
layer.close(layer.index);
var index = parent.layer.getFrameIndex(window.name);
parent.layer.close(index);
}
// 如果取消
depository = null;
material = null;
place = null;
layer.close(layer.index);
var index = parent.layer.getFrameIndex(window.name);
parent.layer.close(index);
}
)
};
@ -140,8 +141,8 @@
if (flag === 0) {
// 如果是无效码
layer.confirm("扫描失败,是否重新扫描", {
btn: ["确定","取消"]
},function () {
btn: ["确定", "取消"]
}, function () {
parent.parent.parent.wx.scanQRCode({
desc: 'scanQRCode desc',
needResult: 1, // 默认为0,扫描结果由企业微信处理,1则直接返回扫描结果,
@ -154,19 +155,18 @@
outboundLogic(req);
}
})
},function () {
}, function () {
// 关闭当前页
var index = parent.layer.getFrameIndex(window.name);
parent.layer.close(index);
})
}
else if (flag === 1) {
} else if (flag === 1) {
// 如果是物料
material = data.material;
if (mcode !== material.code && Number(mcode) !== material.code && mcode !== material.code.toString()) {
if (mcode !== material.code && Number(mcode) !== material.code && mcode !== material.code.toString()) {
layer.confirm("出库物料不正确,请重新扫描", {
btn: ["确定","取消"]
}, function(){
btn: ["确定", "取消"]
}, function () {
material = null;
parent.parent.parent.wx.scanQRCode({
desc: 'scanQRCode desc',
@ -180,15 +180,14 @@
outboundLogic(req);
}
})
},
},
function () {
// 关闭当前页
var index = parent.layer.getFrameIndex(window.name);
parent.layer.close(index);
// 关闭当前页
var index = parent.layer.getFrameIndex(window.name);
parent.layer.close(index);
})
}
else {
})
} else {
if (depository !== null) { // 如果已经扫描仓库
if (depositoryId !== depository.did && Number(depositoryId) !== depository.did && depositoryId !== depository.did.toString()) {
// 如果扫描的仓库不是订单要求的仓库
@ -209,8 +208,7 @@
// 弹出确定框
outQuantityCheck(param);
}
}
else if (place != null) {
} else if (place != null) {
// 如果已经扫描库位
if (depositoryId !== place.did && Number(depositoryId) !== place.did && depositoryId !== place.did.toString()) {
// 如果当前仓库不是订单对应仓库
@ -243,14 +241,14 @@
// 弹出确定框
outQuantityCheck(param);
}
}
else {
} else {
var codeType = data.CodeType;
if(codeType === 1){
if (codeType === 1) {
qrCode = req.qrCode;
}else{
} else {
barCode = req.qrCode;
};
}
layer.confirm("请扫描仓库或库位", {
btn: ["扫描", "取消"]
}, function () { // 继续
@ -276,125 +274,141 @@
}
}
}
else if (flag === 2) {
// 如果扫描的为库位
place = data.place;// 将扫描结果保存到vue中
if ( material == null) {
// 如果还没有扫描物料
layer.confirm("请扫描物料", {
btn: ["扫描", "取消"]
}, function () { // 继续
layer.close(layer.index); // 关闭弹窗
parent.parent.parent.wx.scanQRCode({
desc: 'scanQRCode desc',
needResult: 1, // 默认为0,扫描结果由企业微信处理,1则直接返回扫描结果,
scanType: ["barCode","qrCode"], // 可以指定扫二维码还是条形码(一维码),默认二者都有
success: function (res) {
// 回调
var result = res.resultStr;//当needResult为1时返回处理结果
var req = {};
req.qrCode = result;
outboundLogic(req)
}
})
}, function () { // 取消
} else if (flag === 2) {
// 如果扫描的为库位
place = data.place;// 将扫描结果保存到vue中
if (material == null) {
// 如果还没有扫描物料
layer.confirm("是否进行扫描物料", {
btn: ["扫描", "选择"]
}, function () { // 继续
layer.close(layer.index); // 关闭弹窗
parent.parent.parent.wx.scanQRCode({
desc: 'scanQRCode desc',
needResult: 1, // 默认为0,扫描结果由企业微信处理,1则直接返回扫描结果,
scanType: ["barCode", "qrCode"], // 可以指定扫二维码还是条形码(一维码),默认二者都有
success: function (res) {
// 回调
var result = res.resultStr;//当needResult为1时返回处理结果
var req = {};
req.qrCode = result;
outboundLogic(req)
}
})
}, function () { // 取消
// 进行选择对应物料
layer.open({
title: '物料列表',
type: 2,
shade: 0.2,
maxmin: true,
shadeClose: true,
area: ['50%', '50%'],
content: '/ScanBarOrQrCodeOut_selectMaterial?pid=' + place.id+'&mcode='+mcode,
end: function () {
var param = {};
param.id = id;
param.placeId = place.id;
param.qrCode = qrCode;
param.barCode = barCode;
// 弹出确定框
outQuantityCheck(param);
}
})
/*var index = parent.layer.getFrameIndex(window.name);
parent.layer.close(index);*/
})
} else {
if (depositoryId !== place.did && Number(depositoryId) !== place.did && depositoryId !== place.did.toString()) {
// 如果当前仓库不是订单对应仓库
depository = null;
place = null;
layer.confirm("当前库位不符合要求,请移步至正确库位", {
btn: ["确定"]
}, function () {
// 关闭当前页
var index = parent.layer.getFrameIndex(window.name);
parent.layer.close(index);
})
} else if (place.mcodeList.indexOf(mcode) === -1) {
// 如果当前库位不存在该物料
depository = null;
place = null;
layer.confirm("出库库位不含该物料,请重新扫描", {
btn: ["确定"]
}, function () {
// 关闭当前页
var index = parent.layer.getFrameIndex(window.name);
parent.layer.close(index);
})
} else {
if (depositoryId !== place.did && Number(depositoryId) !== place.did && depositoryId !== place.did.toString()) {
// 如果当前仓库不是订单对应仓库
depository = null;
place = null;
layer.confirm("当前库位不符合要求,请移步至正确库位", {
btn: ["确定"]
}, function () {
// 关闭当前页
var index = parent.layer.getFrameIndex(window.name);
parent.layer.close(index);
})
} else if (place.mcodeList.indexOf(mcode) === -1) {
// 如果当前库位不存在该物料
depository = null;
place = null;
layer.confirm("出库库位不含该物料,请重新扫描", {
btn: ["确定"]
}, function () {
// 关闭当前页
var index = parent.layer.getFrameIndex(window.name);
parent.layer.close(index);
})
} else {
var param = {};
param.id = id;
param.placeId = place.id;
param.qrCode = qrCode;
param.barCode = barCode;
// 弹出确定框
outQuantityCheck(param);
}
var param = {};
param.id = id;
param.placeId = place.id;
param.qrCode = qrCode;
param.barCode = barCode;
// 弹出确定框
outQuantityCheck(param);
}
}
}
else if (flag === 3) {
} else if (flag === 3) {
// 如果是仓库
depository = data.depository;// 将扫描结果保存到vue中
if (material == null) {
// 如果还没有扫描物料
layer.confirm("请扫描物料", {
btn: ["扫描", "取消"]
}, function () { // 继续
layer.close(layer.index); // 关闭弹窗
parent.parent.parent.wx.scanQRCode({
desc: 'scanQRCode desc',
needResult: 1, // 默认为0,扫描结果由企业微信处理,1则直接返回扫描结果,
scanType: ["barCode","qrCode"], // 可以指定扫二维码还是条形码(一维码),默认二者都有
success: function (res) {
// 回调
var result = res.resultStr;//当needResult为1时返回处理结果
var req = {};
req.qrCode = result;
outboundLogic(req);
if (material == null) {
// 如果还没有扫描物料
layer.confirm("请扫描物料", {
btn: ["扫描", "取消"]
}, function () { // 继续
layer.close(layer.index); // 关闭弹窗
parent.parent.parent.wx.scanQRCode({
desc: 'scanQRCode desc',
needResult: 1, // 默认为0,扫描结果由企业微信处理,1则直接返回扫描结果,
scanType: ["barCode", "qrCode"], // 可以指定扫二维码还是条形码(一维码),默认二者都有
success: function (res) {
// 回调
var result = res.resultStr;//当needResult为1时返回处理结果
var req = {};
req.qrCode = result;
outboundLogic(req);
}
}
});
});
}, function () { // 取消
}, function () { // 取消
// 关闭当前页
var index = parent.layer.getFrameIndex(window.name);
parent.layer.close(index);
})
} else {
// 如果已经扫描物料
if (depositoryId !== depository.id && Number(depositoryId) !== depository.id && depositoryId !== depository.id.toString()) {
// 如果当前仓库不是订单对应仓库
depository = null;
place = null;
layer.confirm("当前仓库不符合要求,请移步至正确仓库", {
btn: ["确定"]
}, function () {
// 关闭当前页
var index = parent.layer.getFrameIndex(window.name);
parent.layer.close(index);
})
} else {
// 如果已经扫描物料
if (depositoryId !== depository.id && Number(depositoryId) !== depository.id && depositoryId !== depository.id.toString()) {
// 如果当前仓库不是订单对应仓库
depository = null;
place = null;
layer.confirm("当前仓库不符合要求,请移步至正确仓库", {
btn: ["确定"]
}, function () {
// 关闭当前页
var index = parent.layer.getFrameIndex(window.name);
parent.layer.close(index);
})
} else {
// 如果正确
var param = {};
param.id = id;
param.qrCode = qrCode;
param.barCode = barCode;
// 弹出确定框
outQuantityCheck(param);
// 如果正确
var param = {};
param.id = id;
param.qrCode = qrCode;
param.barCode = barCode;
// 弹出确定框
outQuantityCheck(param);
}
}
}
}
}
})
@ -405,17 +419,17 @@
formType: 0,
value: quantity,
title: '请输入出库数量',
}, function(value, index, elem){
if(value > quantity){
layer.msg("非法值,重新输入!",{
icon: 0,
time: 500
},
function () {
outQuantityCheck(req);
})
}else{
req.quantity = value;
}, function (value, index, elem) {
if (value > quantity) {
layer.msg("非法值,重新输入!", {
icon: 0,
time: 500
},
function () {
outQuantityCheck(req);
})
} else {
req.trueOut = value;
layer.close(index);
isOutTrue(req);
}

Loading…
Cancel
Save