12
skyouc
2025-09-09 1cfaf4b8f5dbf8324e6ac22cfda31d2873014e42
12
5个文件已修改
2个文件已添加
534 ■■■■■ 已修改文件
pom.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-admin/src/views/loc/locCheck/index.vue 328 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/controller/LocController.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/controller/OutController.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/entity/param/CheckOutParam.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/manage/OutManage.java 146 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/service/impl/MobileServiceImpl.java 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pom.xml
@@ -70,6 +70,11 @@
                <artifactId>springfox-boot-starter</artifactId>
                <version>3.0.0</version>
            </dependency>
            <dependency>
                <groupId>org.redisson</groupId>
                <artifactId>redisson</artifactId>
                <version>3.11.1</version>
            </dependency>
        </dependencies>
    </dependencyManagement>
zy-asrs-admin/src/views/loc/locCheck/index.vue
New file
@@ -0,0 +1,328 @@
<script setup>
import { getCurrentInstance, ref, computed, reactive } from 'vue';
import { useRouter } from "vue-router";
import { get, post, postBlob } from '@/utils/request.js'
import { message, Modal } from 'ant-design-vue';
import { logout } from '@/config.js';
import { formatMessage } from '@/utils/localeUtils.js';
import useTableSearch from '@/utils/tableUtils.jsx';
const context = getCurrentInstance()?.appContext.config.globalProperties;
const router = useRouter();
const TABLE_KEY = 'table-locDetl';
let currentPage = 1;
let pageSize = 10;
const searchInput = ref("")
const orderBy = ref({});
const searchParam = ref({
  locNo: null,
  matnr: null,
  orderNo: null,
  batch: null,
  tagId: null,
  orderType: null,
})
const editChild = ref(null)
const state = reactive({
  selectedRowKeys: [],
  loading: false,
  columns: [],
});
let tableData = ref([]);
getColumns();
getPage();
const {
  getColumnSearchProps,
  handleResizeColumn,
} = useTableSearch();
const hasSelected = computed(() => state.selectedRowKeys.length > 0);
const start = () => {
  state.loading = true;
  // ajax request after empty completing
  setTimeout(() => {
    state.loading = false;
    state.selectedRowKeys = [];
  }, 1000);
};
const onSelectChange = selectedRowKeys => {
  // console.log('selectedRowKeys changed: ', selectedRowKeys);
  state.selectedRowKeys = selectedRowKeys;
};
const handleTableChange = (pagination, filters, sorter) => {
  if (sorter != null) {
    if (sorter?.order == "ascend") {
      orderBy.__v_raw = { order: "asc", field: "createTime" }
    } else if (sorter?.order == "descend") {
      orderBy.__v_raw = { order: "desc", field: "createTime" }
    }
  }
  getPage()
}
state.columns = [
  // {
  //   title: formatMessage('db.man_loc_detl.loc_id', '库位'),
  //   dataIndex: 'locId$',
  //   width: 140,
  //   ellipsis: true,
  //   ...getColumnSearchProps('locId$'),
  // },
  {
    title: formatMessage('db.man_loc_detl.loc_no', '库位号'),
    dataIndex: 'locNo',
    width: 140,
    ellipsis: true,
    ...getColumnSearchProps('locNo'),
  },
  {
    title: formatMessage('db.man_loc_detl.loc_type', '库位状态'),
    dataIndex: 'locStsId$',
    width: 140,
    ellipsis: true,
    ...getColumnSearchProps('type$'),
  },
  {
    title: formatMessage('db.man_loc_detl.matnr', '排'),
    dataIndex: 'row1',
    width: 140,
    ellipsis: true,
    ...getColumnSearchProps('row1'),
  },
  {
    title: formatMessage('db.man_loc_detl.maktx', '列'),
    dataIndex: 'bay1',
    width: 140,
    ellipsis: true,
    ...getColumnSearchProps('bay1'),
  },
  {
    title: formatMessage('db.man_loc_detl.specs', '层'),
    dataIndex: 'lev1',
    width: 140,
    ellipsis: true,
    ...getColumnSearchProps('lev1'),
  },
  {
    title: formatMessage('db.man_loc_detl.model', '型号'),
    dataIndex: 'barcode',
    width: 140,
    ellipsis: true,
    ...getColumnSearchProps('model'),
  },
    {
    title: formatMessage('db.man_loc_detl.create_time', '创建时间'),
    dataIndex: 'createTime$',
    width: 140,
    ellipsis: true,
    ...getColumnSearchProps('createTime$'),
  },
  {
    title: formatMessage('db.man_loc_detl.update_time', '修改时间'),
    dataIndex: 'updateTime$',
    width: 140,
    ellipsis: true,
    ...getColumnSearchProps('updateTime$'),
  },
      {
    title: formatMessage('db.man_loc_detl.update_by', '创建人员'),
    dataIndex: 'createBy$',
    width: 140,
    ellipsis: true,
    ...getColumnSearchProps('createBy$'),
  },
  {
    title: formatMessage('db.man_loc_detl.update_by', '修改人员'),
    dataIndex: 'updateBy$',
    width: 140,
    ellipsis: true,
    ...getColumnSearchProps('updateBy$'),
  },
  {
    title: formatMessage('db.man_loc_detl.memo', '备注'),
    dataIndex: 'memo',
    width: 140,
    ellipsis: true,
    ...getColumnSearchProps('memo'),
  },
  {
    title: formatMessage('common.operation', '操作'),
    name: 'oper',
    dataIndex: 'oper',
    key: 'oper',
    width: 140,
    fixed: 'right',
  },
];
//加载扩展字段
async function getColumns() {
  let fieldResp = await post('/api/matField/list', {
    unique: 1,
    fieldType: 1
  })
  let fieldResult = fieldResp.data;
  let tmp = state.columns;
  if (fieldResult.code == 200) {
    let data = fieldResult.data;
    data.forEach((item) => {
      tmp.push({
        title: formatMessage(item.language, item.describe),
        name: item.name,
        dataIndex: item.name,
        key: item.name,
        width: 140,
      })
    })
    state.columns = tmp;
  } else if (result.code === 401) {
    message.error(result.msg);
    logout()
  } else {
    message.error(result.msg);
  }
}
function getPage() {
  state.loading = true;
  post('/api/auto/loc/page', {
    orderBy: orderBy.__v_raw,
    current: currentPage,
    pageSize: pageSize,
    condition: searchInput.value,
    _param: searchParam.value,
  }).then((resp) => {
    let result = resp.data;
    if (result.code == 200) {
      let data = result.data;
      tableData.value = data;
      state.loading = false;
    } else if (result.code === 401) {
      message.error(result.msg);
      logout()
    } else {
      message.error(result.msg);
    }
  })
}
const handleEdit = (item) => {
  let content = "是否确认生成-->出库任务!!"
  let type = 2
  if (item?.locNo.indexOf("B") >= 0 || item?.locNo.indexOf("C") >= 0) {
    content = "是否确认生成-->拣货单!!"
    type = 1
  }
  Modal.confirm({
    title: formatMessage('page.delete', '出库'),
    content: formatMessage('page.delete.confirm', content),
    maskClosable: true,
    onOk: async () => {
      const hide = message.loading(formatMessage('common.loading', '请求中'));
      try {
        let params = {
          outType: type,
          id: item?.id,
        }
        post('/api/out/check/locs/stock', params).then(resp => {
          let result = resp.data;
          if (result.code === 200) {
            message.success(result.msg);
          } else {
            message.error(result.msg);
          }
          getPage()
          hide()
        })
      } catch (error) {
        message.error(formatMessage('common.fail', '请求失败'));
      }
    },
  });
  // editChild.value.open = true;
  // editChild.value.formData = item == null ? editChild.value.initFormData : JSON.parse(JSON.stringify(item));
  // editChild.value.isSave = item == null;
}
const handleExport = async (intl) => {
  postBlob('/api/locDetl/export', {
    condition: searchInput.value,
    _param: searchParam.value,
  }).then(result => {
    const blob = new Blob([result.data], { type: 'application/vnd.ms-excel' });
    window.location.href = window.URL.createObjectURL(blob);
    return true;
  })
};
const onSearch = () => {
  currentPage = 1;
  getPage()
}
const onPageChange = (page, size) => {
  currentPage = page;
  pageSize = size;
  getPage();
}
const total = computed(() => tableData.value?.records?.reduce((sum, item) => sum + item.anfme, 0))
</script>
<script>
export default {
  name: '盘点出库',
}
</script>
<template>
  <div>
    <EditView ref="editChild" @tableReload="handleTableReload" />
    <div class="table-header">
      <div>
        <a-input v-model:value="searchParam.locNo" :placeholder="formatMessage('page.locDetl.locNo.input', '请输入库位号')"
          style="width: 140px;margin-right: 10px;" />
        <a-input v-model:value="searchParam.barcode" :placeholder="formatMessage('page.locDetl.matnr.input', '请输入托盘码')"
          style="width: 140px;margin-right: 10px;" />
        <a-input-search v-model:value="searchInput" :placeholder="formatMessage('page.input', '请输入')"
          style="width: 200px;" @search="onSearch" />
      </div>
      <div class="table-header-right">
        <!-- <a-button @click="handleEdit(null)" type="primary">{{ formatMessage('page.add', '添加') }}</a-button> -->
        <a-button @click="handleExport">{{ formatMessage('page.export', '导出') }}</a-button>
      </div>
    </div>
    <a-table :row-selection="{ selectedRowKeys: state.selectedRowKeys, onChange: onSelectChange }"
      :data-source="tableData.records" :defaultExpandAllRows="false" :key="TABLE_KEY" rowKey="id"
      :pagination="{ total: tableData.total, onChange: onPageChange }" @change="handleTableChange"
      :scroll="{ y: 768, scrollToFirstRowOnChange: true }" :columns="state.columns" @resizeColumn="handleResizeColumn"
      :loading="state.loading">
      <template #bodyCell="{ column, text, record }">
        <template v-if="column.dataIndex === 'oper'">
          <div style="display: flex;justify-content: space-evenly;">
            <a-button type="link" primary @click="handleEdit(record)">{{ formatMessage('page.edit', '盘点出库')
            }}</a-button>
          </div>
        </template>
      </template>
      <!-- <template #footer>
        <div>
          <span>当前页总量:{{ total }}</span>
        </div>
      </template> -->
    </a-table>
  </div>
</template>
<style></style>
zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/controller/LocController.java
@@ -1,6 +1,7 @@
package com.zy.asrs.wms.asrs.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zy.asrs.framework.common.Cools;
import com.zy.asrs.framework.common.R;
@@ -41,6 +42,17 @@
        return R.ok().add(locService.page(pageParam, pageParam.buildWrapper(true)));
    }
    @PreAuthorize("hasAuthority('asrs:loc:list')")
    @PostMapping("/auto/loc/page")
    public R autoPage(@RequestBody Map<String, Object> map) {
        BaseParam baseParam = buildParam(map, BaseParam.class);
        PageParam<Loc, BaseParam> pageParam = new PageParam<>(baseParam, Loc.class);
        QueryWrapper<Loc> wrapper = pageParam.buildWrapper(true);
        wrapper.eq("loc_sts_id", 1).notLike("barcode", "PK");
        return R.ok().add(locService.page(pageParam, wrapper));
    }
    @PreAuthorize("hasAuthority('asrs:loc:list')")
    @PostMapping("/loc/list")
    @CacheData(tableName = {"man_loc"})
zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/controller/OutController.java
@@ -142,6 +142,16 @@
        return R.ok();
    }
    @PostMapping("/out/check/locs/stock")
    @OperationLog("盘点出库")
    public R checkOut(@RequestBody CheckOutParam param) {
        if (Objects.isNull(param)) {
            throw new CoolException("参数不能为空!!");
        }
        outManage.outCheckStock(param);
        return R.ok();
    }
    @PostMapping("/out/wave/generate")
    @OperationLog("生成波次")
    @Transactional
zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/entity/param/CheckOutParam.java
New file
@@ -0,0 +1,21 @@
package com.zy.asrs.wms.asrs.entity.param;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
@Data
@Accessors(chain = true)
@ApiModel(value = "CheckOutParam", description = "盘点出库参数")
public class CheckOutParam {
    @ApiModelProperty("出站口")
    private Integer outSite;
    @ApiModelProperty("出库类型: 1.拣货单, 2. 任务档 ")
    private Integer outType;
    @ApiModelProperty("库位ID")
    private Long id;
}
zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/manage/OutManage.java
@@ -1495,7 +1495,133 @@
            outFlatStock(param);
        } else {
            //生成任务档
            generateTask(param);
            generateTask(param, null);
        }
    }
    /**
     * @author Ryan
     * @date 2025/9/9
     * @description: 盘点出库
     * @version 1.0
     */
    @Transactional(rollbackFor = Exception.class)
    public void outCheckStock(CheckOutParam checkParams) {
        //生成任务档
        generateCheckTask(checkParams, "check");
    }
    /**
     * @author Ryan
     * @date 2025/9/9
     * @description: 生成盘点出库任务
     * @version 1.0
     */
    @Transactional(rollbackFor = Exception.class)
    public void generateCheckTask(CheckOutParam outParam, String type) {
        Loc loc = locService.getById(outParam.getId());
        if (Objects.isNull(loc)) {
            throw new CoolException("库位不存在!!");
        }
        List<LocDetl> detls = locDetlService.list(new LambdaQueryWrapper<LocDetl>().eq(LocDetl::getLocId, loc.getId()));
        for (LocDetl detl : detls) {
            List<OrderOutMergeDto> orders = new ArrayList<>();
            if (Objects.isNull(detl)) {
                continue;
            }
            OrderOutMergeDto outMergeParam = new OrderOutMergeDto();
            outMergeParam.setAnfme(detl.getAnfme());
            outMergeParam.setLocNo(detl.getLocNo());
            outMergeParam.setLocDetlId(detl.getId());
            outMergeParam.setLocId(detl.getLocId());
            outMergeParam.setMatnr(detl.getMatnr());
            outMergeParam.setBatch(detl.getBatch());
            orders.add(outMergeParam);
            Map<Long, List<OrderOutMergeDto>> listMap = orders.stream().collect(Collectors.groupingBy(OrderOutMergeDto::getLocId));
            //根据库位ID分组
            //生成拣货单明细
            for (Map.Entry<Long, List<OrderOutMergeDto>> entry : listMap.entrySet()) {
                List<OrderOutMergeDto> list = entry.getValue();
                OrderOutMergeDto param = list.stream().findFirst().get();
                List<CacheSite> sites = cacheSiteService.list(new LambdaQueryWrapper<CacheSite>()
                        .isNotNull(CacheSite::getOrderId));
                if (!sites.isEmpty()) {
                    Map<String, Long> longMap = sites.stream().collect(Collectors.groupingBy(CacheSite::getChannel, Collectors.counting()));
                    Map.Entry<String, Long> entry1 = longMap.entrySet().stream().min(Map.Entry.comparingByValue()).get();
                    param.setPortSite(entry1.getKey());
                } else {
                    CacheSite cacheSite = cacheSiteService.getOne(new LambdaQueryWrapper<CacheSite>().last("limit 1"));
                    param.setPortSite(cacheSite.getChannel());
                }
                if (!loc.getLocStsId().equals(LocStsType.F.val())) {
                    throw new CoolException(loc.getLocNo() + "库位状态异常");
                }
                OperationPort operationPort = operationPortService
                        .getOne(new LambdaQueryWrapper<OperationPort>()
                                .eq(OperationPort::getFlag, param.getPortSite()));
                if (Objects.isNull(operationPort)) {
                    throw new CoolException("作业口不存在");
                }
                Task task = new Task();
                task.setTaskSts(TaskStsType.GENERATE_OUT.id);
                // 107 盘点出库
                long taskType = 107L;
                task.setTaskType(taskType);
                task.setTaskNo(workService.generateTaskNo(taskType));
                task.setIoPri(workService.generateIoPri(taskType));
                task.setOriginLoc(loc.getLocNo());
                task.setTargetSite(operationPort.getFlag());
                task.setBarcode(loc.getBarcode());
                boolean res = taskService.save(task);
                if (!res) {
                    throw new CoolException("保存工作档失败");
                }
                for (OrderOutMergeDto merge : list) {
                    LocDetl locDetl = locDetlService.getById(merge.getLocDetlId());
                    if (locDetl == null) {
                        throw new CoolException("明细不存在");
                    }
                    TaskDetl taskDetl = new TaskDetl();
                    taskDetl.sync(locDetl);
                    taskDetl.setId(null);
                    taskDetl.setTaskId(task.getId());
                    taskDetl.setTaskNo(task.getTaskNo());
                    taskDetl.setAnfme(merge.getAnfme());
                    taskDetl.setStock(locDetl.getAnfme());
                    taskDetl.setOrderId(null);
                    taskDetl.setOrderNo(null);
                    if (!taskDetlService.save(taskDetl)) {
                        throw new CoolException("保存工作档明细失败");
                    }
                    List<LocDetlField> locDetlFields = locDetlFieldService
                            .list(new LambdaQueryWrapper<LocDetlField>()
                                    .eq(LocDetlField::getDetlId, locDetl.getId()));
                    for (LocDetlField locDetlField : locDetlFields) {
                        TaskDetlField taskDetlField = new TaskDetlField();
                        taskDetlField.sync(locDetlField);
                        taskDetlField.setId(null);
                        taskDetlField.setDetlId(taskDetl.getId());
                        boolean taskDetlFieldSave = taskDetlFieldService.save(taskDetlField);
                        if (!taskDetlFieldSave) {
                            throw new CoolException("明细扩展生成失败");
                        }
                    }
                }
                //库位F => R
                loc.setLocStsId(LocStsType.R.val());
                loc.setUpdateTime(new Date());
                boolean locUpdate = locService.updateById(loc);
                if (!locUpdate) {
                    throw new CoolException("库位状态更新失败");
                }
            }
        }
    }
@@ -1507,7 +1633,7 @@
     * @description: 手动出库生成任务
     */
    @Transactional(rollbackFor = Exception.class)
    public void generateTask(StockOutParam outParam) {
    public void generateTask(StockOutParam outParam, String type) {
        for (LocDetl outLocDetl : outParam.getLocDetls()) {
            List<OrderOutMergeDto> orders = new ArrayList<>();
            LocDetl detl = locDetlService.getOne(new LambdaQueryWrapper<LocDetl>().eq(LocDetl::getId, outLocDetl.getId()));
@@ -1558,14 +1684,24 @@
                if (Objects.isNull(operationPort)) {
                    throw new CoolException("作业口不存在");
                }
                //101 全拖出库   103 拣货出库
                long taskType = all ? 101L : 103L;
                Task task = new Task();
                task.setTaskNo(workService.generateTaskNo(taskType));
                task.setTaskSts(TaskStsType.GENERATE_OUT.id);
                if (Objects.isNull(type)) {
                    //101 全拖出库   103 拣货出库
                    long taskType = all ? 101L : 103L;
                task.setTaskType(taskType);
                    task.setTaskNo(workService.generateTaskNo(taskType));
                task.setIoPri(workService.generateIoPri(taskType));
                } else {
                    // 107 盘点出库
                    long taskType = 107L;
                    task.setTaskType(taskType);
                    task.setTaskNo(workService.generateTaskNo(taskType));
                    task.setIoPri(workService.generateIoPri(taskType));
                }
                task.setOriginLoc(loc.getLocNo());
                task.setTargetSite(operationPort.getFlag());
                task.setBarcode(loc.getBarcode());
zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/service/impl/MobileServiceImpl.java
@@ -444,12 +444,12 @@
                throw new CoolException("订单播种位绑定失败!!");
            }
//            if (!waveSeedMapper.update(new LambdaUpdateWrapper<WaveSeed>()
//                    .eq(WaveSeed::getOrderNo, order.getOrderNo())
//                    .set(WaveSeed::getSiteId, siteNo.getId())
//                    .set(WaveSeed::getSiteNo, siteNo.getSiteNo()))) {
//                throw new CoolException("播种站点更新失败!!");
//            }
            if (!waveSeedMapper.update(new LambdaUpdateWrapper<WaveSeed>()
                    .eq(WaveSeed::getOrderNo, order.getOrderNo())
                    .set(WaveSeed::getSiteId, siteNo.getId())
                    .set(WaveSeed::getSiteNo, siteNo.getSiteNo()))) {
                throw new CoolException("播种站点更新失败!!");
            }
            //绑定成功,播种墙亮灯
            sowLightMange(siteNo.getSiteNo(), order, "LIGHT");
        } else {