From a84386f98cc752516d492222684d5c850c9c7a1e Mon Sep 17 00:00:00 2001
From: pjb <pjb123456>
Date: 星期一, 21 七月 2025 00:00:10 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/mdqzasrs' into mdqzasrs
---
src/main/java/com/zy/common/service/CommonService.java | 301 ++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 293 insertions(+), 8 deletions(-)
diff --git a/src/main/java/com/zy/common/service/CommonService.java b/src/main/java/com/zy/common/service/CommonService.java
index e659ad1..4a39889 100644
--- a/src/main/java/com/zy/common/service/CommonService.java
+++ b/src/main/java/com/zy/common/service/CommonService.java
@@ -3,29 +3,28 @@
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
-import com.core.common.Arith;
import com.core.common.Cools;
import com.core.exception.CoolException;
import com.zy.asrs.entity.*;
import com.zy.asrs.entity.result.FindLocNoAttributeVo;
-import com.zy.asrs.entity.result.KeyValueVo;
+import com.zy.asrs.mapper.LocMastMapper;
+import com.zy.asrs.mapper.WrkMastMapper;
import com.zy.asrs.service.*;
import com.zy.asrs.utils.Utils;
import com.zy.asrs.utils.VersionUtils;
import com.zy.common.model.LocTypeDto;
-import com.zy.common.model.Shelves;
import com.zy.common.model.StartupDto;
import com.zy.common.properties.SlaveProperties;
+import com.zy.common.web.param.SearchLocParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
-import java.time.LocalDate;
-import java.time.format.DateTimeFormatter;
-import java.time.temporal.ChronoUnit;
-import java.util.ArrayList;
-import java.util.List;
+import javax.annotation.Resource;
+import java.util.*;
+import java.util.stream.Collectors;
/**
* 璐ф灦鏍稿績鍔熻兘
@@ -57,6 +56,12 @@
private SlaveProperties slaveProperties;
@Autowired
private WrkDetlService wrkDetlService;
+
+ @Resource
+ private WrkMastMapper wrkMastMapper;
+
+ @Resource
+ private LocMastMapper locMastMapper;
/**
* 鐢熸垚宸ヤ綔鍙�
@@ -156,6 +161,286 @@
return null;
}
+ @Transactional(propagation = Propagation.REQUIRED)
+ public StartupDto getLocNoNew(Integer staDescId, Integer sourceStaNo, FindLocNoAttributeVo findLocNoAttributeVo, int locArea) {
+
+ // 鐩爣搴撲綅
+ LocMast locMast;
+
+ // 鍏ョ┖妗跺簱
+ if (staDescId == 1 && locArea == 2) {
+ List<WrkMast> wrkMastList = wrkMastMapper.selectLastInEmptyLoc(); // 鍓嶉潰鍏ョ┖妗跺簱鐨勪换鍔�(鏈墽琛屽爢鍨涙満鍏ュ簱)
+
+ if (wrkMastList.size() == 0) {
+ // 鍙栨柊搴撲綅缁勭殑绗竴涓簱浣�
+ List<LocMast> locMasts = locMastService.selectList(new EntityWrapper<LocMast>().eq("crn_no", 4).eq("loc_sts", "O"));
+ List<LocMast> collect = locMasts.stream().filter(locMast1 -> locMast1.getRow1() == 9 || locMast1.getRow1() == 11).collect(Collectors.toList());
+ List<LocMast> collect1 = locMasts.stream().filter(locMast1 -> locMast1.getRow1() == 10 || locMast1.getRow1() == 12).collect(Collectors.toList()); // 绗竴涓厛鏀捐繖涓ゆ帓
+ if (collect.size() == 0 || collect1.size() == 0) {
+ log.error("-----绌烘《搴撴棤绌哄簱浣�----");
+ throw new CoolException("绌烘《搴撴棤绌哄簱浣�");
+ }
+ // 鍙敤搴撲綅缁�
+ List<LocMast> locMastList = new ArrayList<>();
+ for(LocMast locMast1:collect) {
+ Optional<LocMast> first = collect1.stream().filter(locMast2 -> locMast1.getRow1() + 1 == locMast2.getRow1() && Objects.equals(locMast1.getLev1(), locMast2.getLev1())
+ && Objects.equals(locMast1.getBay1(), locMast2.getBay1())).findFirst();
+ first.ifPresent(locMastList::add);
+ }
+
+ if (locMastList.size() == 0) {
+ log.error("-----绌烘《搴撴棤瀵瑰簲绌虹┖妗剁粍----");
+ throw new CoolException("绌烘《搴撴棤瀵瑰簲绌虹┖妗剁粍");
+ }
+ String model = findLocNoAttributeVo.getModel(); // 褰撳墠妗剁被鍨�
+ if (model.equals("208L") && locMastList.size() <= 40 * 2 * 2) { // 鏈�涓婇潰涓�灞傚彧鑳芥斁208L锛屽簱浣嶅墿浣欓噺涓嶅鏃讹紝濡傛灉鏄�208L妗跺叆搴擄紝鍒欏厛浠庢渶椤跺眰鏀�
+ locMastList = locMastList.stream().sorted(Comparator.comparing(LocMast::getLev1).reversed().thenComparing(LocMast::getBay1).thenComparing(LocMast::getRow1)).collect(Collectors.toList());
+ } else {
+ locMastList = locMastList.stream().sorted(Comparator.comparing(LocMast::getLev1).thenComparing(LocMast::getBay1).thenComparing(LocMast::getRow1)).collect(Collectors.toList());
+ }
+ locMast = locMastList.get(0);
+
+ } else {
+ WrkMast wrkMast = wrkMastList.get(0); // 鏈�鍚庝竴涓叆绌烘《搴撲换鍔�
+ // 鍓嶄竴涓换鍔℃《绫诲瀷
+ String oldModel = wrkMast.getPdcType();
+ // 鍓嶄竴涓换鍔″熬鎵樻爣璇�
+ Integer oldCtnType = wrkMast.getCtnType();
+ // 褰撳墠妗剁被鍨�
+ String matnr = findLocNoAttributeVo.getMatnr();
+ if(findLocNoAttributeVo.getMatnr().equals(wrkMast.getPdcType())) { // 褰撳墠妗朵笌鍓嶆《鏄竴绉嶇被鍨�
+ // 褰撳墠妗剁被鍨嬬殑浠诲姟鏈夊嚑涓�
+ long count = wrkMastList.stream().filter(wrkMast1 -> wrkMast1.getPdcType().equals(matnr)).count();
+ if (count % 2 == 0) { // 鍋舵暟锛屽彇涓�缁勬柊搴撲綅
+ // 鍙栨柊搴撲綅缁勭殑绗竴涓簱浣�
+ List<LocMast> locMasts = locMastService.selectList(new EntityWrapper<LocMast>().eq("crn_no", 4).eq("loc_sts", "O"));
+ List<LocMast> collect = locMasts.stream().filter(locMast1 -> locMast1.getRow1() == 9 || locMast1.getRow1() == 11).collect(Collectors.toList());
+ List<LocMast> collect1 = locMasts.stream().filter(locMast1 -> locMast1.getRow1() == 10 || locMast1.getRow1() == 12).collect(Collectors.toList()); // 绗竴涓厛鏀捐繖涓ゆ帓
+ if (collect.size() == 0 || collect1.size() == 0) {
+ log.error("-----绌烘《搴撴棤绌哄簱浣�----");
+ throw new CoolException("绌烘《搴撴棤绌哄簱浣�");
+ }
+ // 鍙敤搴撲綅缁�
+ List<LocMast> locMastList = new ArrayList<>();
+ for(LocMast locMast1:collect) {
+ Optional<LocMast> first = collect1.stream().filter(locMast2 -> locMast1.getRow1() + 1 == locMast2.getRow1() && Objects.equals(locMast1.getLev1(), locMast2.getLev1())
+ && Objects.equals(locMast1.getBay1(), locMast2.getBay1())).findFirst();
+ first.ifPresent(locMastList::add);
+ }
+
+ if (locMastList.size() == 0) {
+ log.error("-----绌烘《搴撴棤瀵瑰簲绌虹┖妗剁粍----");
+ throw new CoolException("绌烘《搴撴棤瀵瑰簲绌虹┖妗剁粍");
+ }
+ String model = findLocNoAttributeVo.getModel(); // 褰撳墠妗剁被鍨�
+ if (model.equals("208L") && locMastList.size() <= 40 * 2 * 2) { // 鏈�涓婇潰涓�灞傚彧鑳芥斁208L锛屽簱浣嶅墿浣欓噺涓嶅鏃讹紝濡傛灉鏄�208L妗跺叆搴擄紝鍒欏厛浠庢渶椤跺眰鏀�
+ locMastList = locMastList.stream().sorted(Comparator.comparing(LocMast::getLev1).reversed().thenComparing(LocMast::getBay1).thenComparing(LocMast::getRow1)).collect(Collectors.toList());
+ } else {
+ locMastList = locMastList.stream().sorted(Comparator.comparing(LocMast::getLev1).thenComparing(LocMast::getBay1).thenComparing(LocMast::getRow1)).collect(Collectors.toList());
+ }
+ locMast = locMastList.get(0);
+ } else { // 濂囨暟锛屽彇鍓嶄竴搴撲綅瀵瑰簲鐨勭┖搴撲綅
+ String locNo = wrkMast.getLocNo();
+ int row = Integer.parseInt(locNo.substring(0, 2));
+ if(row == 10 || row == 12) {
+ String newLocNo =(row == 10 ? "09" : "11") + locNo.substring(2);
+ locMast = locMastService.selectOne(new EntityWrapper<LocMast>().eq("loc_no", newLocNo).eq("loc_sts","O"));
+ if (locMast == null) {
+ log.error("-----涓庡墠闈㈡《绫诲瀷涓�鏍凤紝鍓嶉潰璇ユ《绫诲瀷浠诲姟鏁版槸濂囨暟锛�10锛�12鎺�,浣嗘槸瀵瑰簲搴撲綅涓嶄负绌�----");
+ throw new CoolException("涓庡墠闈㈡《绫诲瀷涓�鏍凤紝鍓嶉潰璇ユ《绫诲瀷浠诲姟鏁版槸濂囨暟锛屾槸10锛�12鎺�,浣嗘槸瀵瑰簲搴撲綅涓嶄负绌�");
+ }
+ } else {
+ log.error("-----涓庡墠闈㈡《绫诲瀷涓�鏍凤紝鍓嶉潰璇ユ《绫诲瀷浠诲姟鏁版槸濂囨暟锛屼絾鏄笉鏄�10锛�12鎺�----");
+ throw new CoolException("涓庡墠闈㈡《绫诲瀷涓�鏍凤紝鍓嶉潰璇ユ《绫诲瀷浠诲姟鏁版槸濂囨暟锛屼絾鏄笉鏄�10锛�12鎺�");
+ }
+ }
+ } else { // 褰撳墠妗朵笌鍓嶆《涓嶆槸涓�绉嶇被鍨�
+ if(oldCtnType == 1) { // 鍓嶉潰鏄熬妗�
+ // 鍙栨柊搴撲綅缁勭殑绗竴涓簱浣�
+ List<LocMast> locMasts = locMastService.selectList(new EntityWrapper<LocMast>().eq("crn_no", 4).eq("loc_sts", "O"));
+ List<LocMast> collect = locMasts.stream().filter(locMast1 -> locMast1.getRow1() == 9 || locMast1.getRow1() == 11).collect(Collectors.toList());
+ List<LocMast> collect1 = locMasts.stream().filter(locMast1 -> locMast1.getRow1() == 10 || locMast1.getRow1() == 12).collect(Collectors.toList()); // 绗竴涓厛鏀捐繖涓ゆ帓
+ if (collect.size() == 0 || collect1.size() == 0) {
+ log.error("-----绌烘《搴撴棤绌哄簱浣�----");
+ throw new CoolException("绌烘《搴撴棤绌哄簱浣�");
+ }
+ // 鍙敤搴撲綅缁�
+ List<LocMast> locMastList = new ArrayList<>();
+ for(LocMast locMast1:collect) {
+ Optional<LocMast> first = collect1.stream().filter(locMast2 -> locMast1.getRow1() + 1 == locMast2.getRow1() && Objects.equals(locMast1.getLev1(), locMast2.getLev1())
+ && Objects.equals(locMast1.getBay1(), locMast2.getBay1())).findFirst();
+ first.ifPresent(locMastList::add);
+ }
+
+ if (locMastList.size() == 0) {
+ log.error("-----绌烘《搴撴棤瀵瑰簲绌虹┖妗剁粍----");
+ throw new CoolException("绌烘《搴撴棤瀵瑰簲绌虹┖妗剁粍");
+ }
+ String model = findLocNoAttributeVo.getModel(); // 褰撳墠妗剁被鍨�
+ if (model.equals("208L") && locMastList.size() <= 40 * 2 * 2) { // 鏈�涓婇潰涓�灞傚彧鑳芥斁208L锛屽簱浣嶅墿浣欓噺涓嶅鏃讹紝濡傛灉鏄�208L妗跺叆搴擄紝鍒欏厛浠庢渶椤跺眰鏀�
+ locMastList = locMastList.stream().sorted(Comparator.comparing(LocMast::getLev1).reversed().thenComparing(LocMast::getBay1).thenComparing(LocMast::getRow1)).collect(Collectors.toList());
+ } else {
+ locMastList = locMastList.stream().sorted(Comparator.comparing(LocMast::getLev1).thenComparing(LocMast::getBay1).thenComparing(LocMast::getRow1)).collect(Collectors.toList());
+ }
+ locMast = locMastList.get(0);
+ } else { // 鍓嶉潰涓嶆槸灏炬《
+ // 鍒ゆ柇鍓嶉潰鍏ョ┖妗跺簱浠诲姟鏁伴噺(鏈墽琛屽爢鍨涙満鍏ュ簱)
+ long count = wrkMastList.stream().filter(wrkMast1 -> wrkMast1.getPdcType().equals(oldModel)).count();
+ if (count % 2 == 0) { // 鍋舵暟锛屽彲浠ュ叆搴�
+ // 鍙栨柊搴撲綅缁勭殑绗竴涓簱浣�
+ List<LocMast> locMasts = locMastService.selectList(new EntityWrapper<LocMast>().eq("crn_no", 4).eq("loc_sts", "O"));
+ List<LocMast> collect = locMasts.stream().filter(locMast1 -> locMast1.getRow1() == 9 || locMast1.getRow1() == 11).collect(Collectors.toList());
+ List<LocMast> collect1 = locMasts.stream().filter(locMast1 -> locMast1.getRow1() == 10 || locMast1.getRow1() == 12).collect(Collectors.toList()); // 绗竴涓厛鏀捐繖涓ゆ帓
+ if (collect.size() == 0 || collect1.size() == 0) {
+ log.error("-----绌烘《搴撴棤绌哄簱浣�----");
+ throw new CoolException("绌烘《搴撴棤绌哄簱浣�");
+ }
+ // 鍙敤搴撲綅缁�
+ List<LocMast> locMastList = new ArrayList<>();
+ for(LocMast locMast1:collect) {
+ Optional<LocMast> first = collect1.stream().filter(locMast2 -> locMast1.getRow1() + 1 == locMast2.getRow1() && Objects.equals(locMast1.getLev1(), locMast2.getLev1())
+ && Objects.equals(locMast1.getBay1(), locMast2.getBay1())).findFirst();
+ first.ifPresent(locMastList::add);
+ }
+
+ if (locMastList.size() == 0) {
+ log.error("-----绌烘《搴撴棤瀵瑰簲绌虹┖妗剁粍----");
+ throw new CoolException("绌烘《搴撴棤瀵瑰簲绌虹┖妗剁粍");
+ }
+ String model = findLocNoAttributeVo.getModel(); // 褰撳墠妗剁被鍨�
+ if (model.equals("208L") && locMastList.size() <= 40 * 2 * 2) { // 鏈�涓婇潰涓�灞傚彧鑳芥斁208L锛屽簱浣嶅墿浣欓噺涓嶅鏃讹紝濡傛灉鏄�208L妗跺叆搴擄紝鍒欏厛浠庢渶椤跺眰鏀�
+ locMastList = locMastList.stream().sorted(Comparator.comparing(LocMast::getLev1).reversed().thenComparing(LocMast::getBay1).thenComparing(LocMast::getRow1)).collect(Collectors.toList());
+ } else {
+ locMastList = locMastList.stream().sorted(Comparator.comparing(LocMast::getLev1).thenComparing(LocMast::getBay1).thenComparing(LocMast::getRow1)).collect(Collectors.toList());
+ }
+ locMast = locMastList.get(0);
+ } else { // 濂囨暟锛屼笉鍙互鍏ュ簱
+ // 鑷姩缁欏墠闈换鍔¤ˉ灏炬《淇″彿
+ wrkMastService.updateCtnType(wrkMast);
+ log.error("-----涓庡墠闈㈡《绫诲瀷涓嶄竴鏍凤紝鍓嶉潰妗朵笉鏄熬妗讹紝鍓嶉潰璇ユ《绫诲瀷浠诲姟鏁颁笉鏄伓鏁帮紝涓嶈兘鍏ュ簱----");
+ throw new CoolException("涓庡墠闈㈡《绫诲瀷涓嶄竴鏍凤紝鍓嶉潰妗朵笉鏄熬妗讹紝鍓嶉潰璇ユ《绫诲瀷浠诲姟鏁颁笉鏄伓鏁帮紝涓嶈兘鍏ュ簱");
+ }
+ }
+ }
+ }
+
+ } else if ((staDescId == 1 && locArea == 1) || staDescId == 10) { // 婊℃澘鍏ユ垚鍝佸簱鎴栬�呯┖鏉垮叆鎴愬搧搴�
+
+ // 鍏ユ垚鍝佸簱鎽嗘斁瑙勫垯 鍒ゆ柇鍙敤鍫嗗灈鏈鸿嚜鍔�-鏃犳姤璀� 鎸夊眰鍒楁帓椤哄簭浠庝笅寰�涓婏紝浠庡墠寰�鍚庢帓 鍏堟繁搴撲綅鍦ㄦ祬搴撲綅 鏈�涓婇潰涓�灞傚彧鑳芥斁208L妗�(鍓╀綑搴撲綅杈惧埌涓�涓槇鍊�208L灏卞厛浠庢渶涓婇潰寮�濮嬫斁锛屼笅闈㈢暀缁欏叾浠栬揣鐗�-鍚庣画浼樺寲)
+
+ List<BasCrnp> basCrnps = basCrnpService.selectList(new EntityWrapper<BasCrnp>().eq("crn_sts", 3).eq("crn_err", 0).in("crn_no",1,2,3)
+ .eq("in_enable","Y"));
+ if (basCrnps.size() == 0) {
+ log.error("鍏ュ簱璇锋眰搴撲綅澶辫触锛屾病鏈夎仈鏈哄爢鍨涙満鎴栧爢鍨涙満寮傚父");
+ throw new CoolException("鍏ュ簱璇锋眰搴撲綅澶辫触锛屾病鏈夎仈鏈哄爢鍨涙満鎴栧爢鍨涙満寮傚父");
+ }
+
+ List<BasCrnp> basCrnpList = new ArrayList<>();
+ for(BasCrnp basCrnp: basCrnps) {
+ Integer count = locMastMapper.selectCount(new EntityWrapper<LocMast>().eq("crn_no", basCrnp.getCrnNo()).eq("loc_sts", "S"));
+ basCrnp.setWrkNo(count);
+ basCrnpList.add(basCrnp);
+ }
+
+ basCrnpList = basCrnpList.stream().sorted(Comparator.comparing(BasCrnp::getWrkNo).thenComparing(BasCrnp::getCrnNo,((o1, o2) -> {
+ // 瀹氫箟 2 鈫� 3 鈫� 1 鐨勪紭鍏堢骇
+ int order1 = getCustomOrder(o1);
+ int order2 = getCustomOrder(o2);
+ return Integer.compare(order1, order2);
+ }))).collect(Collectors.toList());
+
+ // 鍏ュ簱妗跺瀷
+ String model = findLocNoAttributeVo.getModel();
+
+ locMast = null;
+
+ for(BasCrnp basCrnp:basCrnpList) {
+ Integer crnNo = basCrnp.getCrnNo();
+ Wrapper<LocMast> wrapper = new EntityWrapper<LocMast>().eq("loc_sts", 'O')
+ .eq("crn_no", crnNo).orderBy("lev1").orderBy("bay1").orderBy("row1");
+ // 鍏ュ簱妗跺瀷鏄笉鏄�208L
+ if (model == null || !model.equals("208L")) {
+ wrapper.ne("lev1", 11);
+ }
+ if (crnNo == 1) {
+ wrapper.in("row1", 1, 4);
+ }
+ locMast = locMastService.selectOne(wrapper);
+ if (locMast != null) {
+ break;
+ }
+ // 娣卞簱浣嶆病鏈変簡鍒欒幏鍙栦竴涓祬搴撲綅
+ if (crnNo == 1) {
+ locMast = locMastService.selectOne(wrapper.in("row1", 2, 3));
+ if (locMast != null) {
+ int count = locMastService.selectCount(wrapper);
+ if (count <= 10) {
+ locMast = null;
+ } else {
+ break;
+ }
+ }
+ }
+ }
+
+ if (locMast == null) {
+ List<Integer> collect = basCrnps.stream().map(BasCrnp::getCrnNo).collect(Collectors.toList());
+ log.error("-----{}鍫嗗灈鏈哄簱浣嶄笉瓒�----",collect.toString());
+ throw new CoolException(collect.toString() + "鍫嗗灈鏈哄簱浣嶄笉瓒�");
+ }
+ } else {
+ log.error("鍏ュ簱绫诲瀷閿欒锛宻taDescId={}", staDescId);
+ throw new CoolException("鍏ュ簱绫诲瀷閿欒锛宻taDescId=" + staDescId);
+ }
+ // 杩斿洖dto
+ StartupDto startupDto = new StartupDto();
+ StaDesc staDesc = staDescService.selectOne(new EntityWrapper<StaDesc>()
+ .eq("type_no", staDescId)
+ .eq("stn_no", sourceStaNo)
+ .eq("crn_no", locMast.getCrnNo()));
+ if (Cools.isEmpty(staDesc)) {
+ log.error("type_no={},stn_no={},crn_no={}", staDescId, sourceStaNo, locMast.getCrnNo());
+ throw new CoolException("鍏ュ簱璺緞涓嶅瓨鍦�");
+ } else {
+ BasDevp staNo = basDevpService.selectById(staDesc.getCrnStn());
+ if (!staNo.getAutoing().equals("Y")) {
+ log.error("鐩爣绔�" + staDesc.getCrnStn() + "涓嶅彲鐢�");
+ throw new CoolException("鐩爣绔�" + staDesc.getCrnStn() + "涓嶅彲鐢�");
+ }
+ startupDto.setStaNo(staNo.getDevNo());
+ }
+
+ // 鐢熸垚宸ヤ綔鍙�
+ int workNo = getWorkNo(0);
+ startupDto.setWorkNo(workNo);
+ startupDto.setCrnNo(locMast.getCrnNo());
+ startupDto.setSourceStaNo(sourceStaNo);
+ startupDto.setLocNo(locMast.getLocNo());
+ return startupDto;
+ }
+
+ // 杈呭姪鏂规硶锛氬畾涔� crn_no 鐨勬帓搴忎紭鍏堢骇
+ private static int getCustomOrder(Integer crnNo) {
+ switch (crnNo) {
+ case 2: return 1; // 2 鎺掔涓�
+ case 3: return 2; // 3 鎺掔浜�
+ case 1: return 3; // 1 鎺掔涓�
+ default: return 4; // 鍏朵粬鍊兼帓鏈�鍚庯紙濡傛灉鏈夛級
+ }
+ }
+
+ @Transactional(propagation = Propagation.REQUIRED)
+ public StartupDto getLocNo(SearchLocParam param, Integer staNo) {
+
+ // 杩斿洖dto
+ StartupDto startupDto = new StartupDto();
+
+ startupDto.setWorkNo(getWorkNo(0)); // 宸ヤ綔鍙�
+ startupDto.setSourceStaNo(param.getSourceStaNo()); // 婧愮珯鐐�
+ startupDto.setStaNo(staNo); // 鐩爣绔欑偣
+ return startupDto;
+ }
+
/**
* 妫�绱㈠簱浣嶅彿
*
--
Gitblit v1.9.1