|  |  |  | 
|---|
|  |  |  | const record = useRecordContext(); | 
|---|
|  |  |  | const notify = useNotify(); | 
|---|
|  |  |  | const refresh = useRefresh(); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | const [createDialog, setCreateDialog] = useState(false); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | return ( | 
|---|
|  |  |  | 
|---|
|  |  |  | setSelect(record) | 
|---|
|  |  |  | setEditDialog(true) | 
|---|
|  |  |  | }} | 
|---|
|  |  |  | omit={['id', 'createTime', 'createBy', 'memo', 'poDetlId', 'matnrId', 'asnId']} | 
|---|
|  |  |  | omit={['id', 'createTime', 'createBy', 'memo', 'poDetlId', 'purQty','purUnit','trackCode','packName','splrName','matnrId', 'asnId']} | 
|---|
|  |  |  | > | 
|---|
|  |  |  | <NumberField source="id" /> | 
|---|
|  |  |  | <NumberField source="asnId" label="table.field.outStockItem.asnId" /> | 
|---|
|  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | const filters = [ | 
|---|
|  |  |  | <SearchInput source="condition" alwaysOn />, | 
|---|
|  |  |  | <DateInput label='common.time.after' source="timeStart"  />, | 
|---|
|  |  |  | <DateInput label='common.time.before' source="timeEnd"  />, | 
|---|
|  |  |  | <DateInput label='common.time.after' source="timeStart" />, | 
|---|
|  |  |  | <DateInput label='common.time.before' source="timeEnd" />, | 
|---|
|  |  |  | <NumberInput source="orderId" label="table.field.stockItem.orderId" />, | 
|---|
|  |  |  | <TextInput source="orderCode" label="table.field.stockItem.orderCode" />, | 
|---|
|  |  |  | <TextInput source="sourceItemId" label="table.field.stockItem.sourceItemId" />, | 
|---|
|  |  |  | <TextInput source="matnrId" label="table.field.stockItem.matnrId" />, | 
|---|
|  |  |  | <TextInput source="matnrCode" label="table.field.stockItem.matnrCode" />, | 
|---|
|  |  |  | <TextInput source="maktx" label="table.field.stockItem.maktx" />, | 
|---|
|  |  |  | <TextInput source="locCode" label="table.field.loc.code" />, | 
|---|
|  |  |  | <TextInput source="barcode" label="table.field.task.barcode" />, | 
|---|
|  |  |  | <NumberInput source="anfme" label="table.field.stockItem.anfme" />, | 
|---|
|  |  |  | <TextInput source="stockUnit" label="table.field.stockItem.stockUnit" />, | 
|---|
|  |  |  | <NumberInput source="workQty" label="table.field.stockItem.workQty" />, | 
|---|
|  |  |  | 
|---|
|  |  |  | rowClick={(id, resource, record) => false} | 
|---|
|  |  |  | expand={false} | 
|---|
|  |  |  | expandSingle={true} | 
|---|
|  |  |  | omit={['id', 'createTime', 'orderId', 'sourceItemId', 'matnrId', 'createBy','barcode', 'splrCode', 'splrBatch', 'updateBy$', 'createBy$', 'memo']} | 
|---|
|  |  |  | omit={['id', 'createTime', 'orderId', 'sourceItemId', 'matnrId', 'purUnit','splrCode', 'purQty', 'createBy', 'packName', 'prodTime', 'splrName', 'splrCode', 'batch', 'packName', 'updateBy$', 'createBy$', 'memo']} | 
|---|
|  |  |  | > | 
|---|
|  |  |  | <NumberField source="id" /> | 
|---|
|  |  |  | <NumberField source="orderId" label="table.field.stockItem.orderId" /> | 
|---|
|  |  |  | 
|---|
|  |  |  | <NumberField source="anfme" label="table.field.stockItem.anfme" /> | 
|---|
|  |  |  | <TextField source="stockUnit" label="table.field.stockItem.stockUnit" /> | 
|---|
|  |  |  | <NumberField source="workQty" label="table.field.stockItem.workQty" /> | 
|---|
|  |  |  | <TextField source="locCode" label="table.field.loc.code" />, | 
|---|
|  |  |  | <TextField source="barcode" label="table.field.task.barcode" />, | 
|---|
|  |  |  | <NumberField source="purQty" label="table.field.stockItem.purQty" /> | 
|---|
|  |  |  | <TextField source="purUnit" label="table.field.stockItem.purUnit" /> | 
|---|
|  |  |  | <NumberField source="qty" label="table.field.stockItem.qty" /> | 
|---|
|  |  |  | 
|---|
|  |  |  | <TextField source="splrBatch" label="table.field.stockItem.splrBatch" /> | 
|---|
|  |  |  | <TextField source="splrName" label="table.field.stockItem.splrName" /> | 
|---|
|  |  |  | <TextField source="trackCode" label="table.field.stockItem.trackCode" /> | 
|---|
|  |  |  | <TextField source="barcode" label="table.field.stockItem.barcode" /> | 
|---|
|  |  |  | <TextField source="prodTime" label="table.field.stockItem.prodTime" /> | 
|---|
|  |  |  | <TextField source="packName" label="table.field.stockItem.packName" /> | 
|---|
|  |  |  | <TextField source="updateBy$" label="common.field.updateBy" /> | 
|---|
|  |  |  | 
|---|
|  |  |  | <DateField source="createTime" label="common.field.createTime" showTime /> | 
|---|
|  |  |  | <BooleanField source="statusBool" label="common.field.status" sortable={false} /> | 
|---|
|  |  |  | <TextField source="memo" label="common.field.memo" sortable={false} /> | 
|---|
|  |  |  | <WrapperField cellClassName="opt" label="common.field.opt"> | 
|---|
|  |  |  | <EditButton sx={{ padding: '1px', fontSize: '.75rem' }} /> | 
|---|
|  |  |  | <DeleteButton sx={{ padding: '1px', fontSize: '.75rem' }} mutationMode={OPERATE_MODE} /> | 
|---|
|  |  |  | </WrapperField> | 
|---|
|  |  |  | </StyledDatagrid> | 
|---|
|  |  |  | </List> | 
|---|
|  |  |  | <PageDrawer | 
|---|
|  |  |  | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | return ( | 
|---|
|  |  |  | record?.taskStatus == 198 && record?.taskType == 103 ? <ConfirmButton label={"toolbar.pick"} startIcon={<ColorizeOutlinedIcon />} onConfirm={pickClick} /> : <></> | 
|---|
|  |  |  | record?.taskStatus == 199 && record?.taskType == 103 ? <ConfirmButton label={"toolbar.pick"} startIcon={<ColorizeOutlinedIcon />} onConfirm={pickClick} /> : <></> | 
|---|
|  |  |  | ) | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | 
|---|
|  |  |  | } | 
|---|
|  |  |  | const http = async (sta, items) => { | 
|---|
|  |  |  | console.log(items); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | const filZores = items.filter(item => item.outQty  <= 0.0); | 
|---|
|  |  |  | const filter = items.filter(item => (item.outQty + item.workQty) > item.anfme); | 
|---|
|  |  |  | if (filter.length > 0) { | 
|---|
|  |  |  | if (filter.length > 0 || filZores.length > 0) { | 
|---|
|  |  |  | notify(translate('toolbar.request.error.out_stock_qty')) | 
|---|
|  |  |  | return | 
|---|
|  |  |  | } | 
|---|
|  |  |  | 
|---|
|  |  |  | import java.nio.charset.StandardCharsets; | 
|---|
|  |  |  | import java.security.MessageDigest; | 
|---|
|  |  |  | import java.security.NoSuchAlgorithmException; | 
|---|
|  |  |  | import java.util.ArrayList; | 
|---|
|  |  |  | import java.util.List; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | public class ChineseMD5Util { | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 对汉字字符串进行MD5加密 | 
|---|
|  |  |  | * @param input 要加密的汉字字符串 | 
|---|
|  |  |  | * @return 32位小写MD5哈希值 | 
|---|
|  |  |  | * @throws NoSuchAlgorithmException | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | public static String md5Chinese(String input) throws NoSuchAlgorithmException { | 
|---|
|  |  |  | if (input == null) { | 
|---|
|  |  |  | return null; | 
|---|
|  |  |  | public static List<Integer> getSelectedIndices(int[] arr) { | 
|---|
|  |  |  | List<Integer> indices = new ArrayList<>(); | 
|---|
|  |  |  | int index = 0; | 
|---|
|  |  |  | int step = 3; | 
|---|
|  |  |  | while (index < arr.length) { | 
|---|
|  |  |  | indices.add(index); | 
|---|
|  |  |  | index += step; | 
|---|
|  |  |  | step = (step == 3) ? 1 : 3; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | // 统一使用UTF-8编码 | 
|---|
|  |  |  | byte[] inputBytes = input.getBytes(StandardCharsets.UTF_8); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | MessageDigest md = MessageDigest.getInstance("MD5"); | 
|---|
|  |  |  | byte[] digest = md.digest(inputBytes); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | // 将字节数组转换为16进制字符串 | 
|---|
|  |  |  | StringBuilder sb = new StringBuilder(); | 
|---|
|  |  |  | for (byte b : digest) { | 
|---|
|  |  |  | sb.append(String.format("%02x", b)); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | return sb.toString(); | 
|---|
|  |  |  | return indices; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 验证汉字字符串与MD5哈希是否匹配 | 
|---|
|  |  |  | * @param input 要验证的汉字字符串 | 
|---|
|  |  |  | * @param md5Hash 存储的MD5哈希值 | 
|---|
|  |  |  | * @return 如果匹配返回true,否则false | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | public static boolean verifyChinese(String input, String md5Hash) { | 
|---|
|  |  |  | try { | 
|---|
|  |  |  | String computedHash = md5Chinese(input); | 
|---|
|  |  |  | return computedHash.equals(md5Hash.toLowerCase()); | 
|---|
|  |  |  | } catch (NoSuchAlgorithmException e) { | 
|---|
|  |  |  | // 理论上不会发生,因为MD5是Java标准库支持的 | 
|---|
|  |  |  | return false; | 
|---|
|  |  |  | public static Integer getNextSelectedValue(int[] arr, int inputIndex) { | 
|---|
|  |  |  | List<Integer> selectedIndices = getSelectedIndices(arr); | 
|---|
|  |  |  | int currentPos = selectedIndices.indexOf(inputIndex); | 
|---|
|  |  |  | if (currentPos != -1 && currentPos + 1 < selectedIndices.size()) { | 
|---|
|  |  |  | return arr[selectedIndices.get(currentPos + 1)]; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | return null; // 或按需处理 | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | public static void main(String[] args) { | 
|---|
|  |  |  | try { | 
|---|
|  |  |  | String chineseText = "你好,世界!"; | 
|---|
|  |  |  | int[] arr = {2, 5, 8, 10, 15, 20, 25, 30, 35, 40, 45, 50, 15, 40, 32, 48}; | 
|---|
|  |  |  | System.out.println("输入 0,输出: " + getNextSelectedValue(arr, 0)); // 10 | 
|---|
|  |  |  | System.out.println("输入 3,输出: " + getNextSelectedValue(arr, 3)); // 15 | 
|---|
|  |  |  | System.out.println("输入 4,输出: " + getNextSelectedValue(arr, 4)); // 30 | 
|---|
|  |  |  | System.out.println("输入 4,输出: " + getNextSelectedValue(arr, 5)); // 30 | 
|---|
|  |  |  |  | 
|---|
|  |  |  | // 加密 | 
|---|
|  |  |  | String md5Hash = md5Chinese(chineseText); | 
|---|
|  |  |  | System.out.println("原文: " + chineseText); | 
|---|
|  |  |  | System.out.println("MD5哈希: " + md5Hash); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | // 验证 | 
|---|
|  |  |  | boolean isValid = verifyChinese(chineseText, md5Hash); | 
|---|
|  |  |  | System.out.println("验证结果: " + (isValid ? "匹配" : "不匹配")); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | // 错误验证示例 | 
|---|
|  |  |  | boolean isWrongValid = verifyChinese("你好,世界!", md5Hash); | 
|---|
|  |  |  | System.out.println("错误文本验证: " + (isWrongValid ? "匹配" : "不匹配")); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | } catch (NoSuchAlgorithmException e) { | 
|---|
|  |  |  | e.printStackTrace(); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | 
|---|
|  |  |  | throw new CoolException("库存信息不存在!"); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | if (locItem.getOutQty().compareTo(0.0) < 0) { | 
|---|
|  |  |  | throw new CoolException("出库数里不能小于0!!"); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | if (locItem.getAnfme().compareTo(qty) < 0) { | 
|---|
|  |  |  | Double minusQty = Math.round((locItem.getAnfme() - locItem.getWorkQty()) * 10000) / 10000.0; | 
|---|
|  |  |  | item.setWorkQty(minusQty); | 
|---|
|  |  |  | 
|---|
|  |  |  | /**修改为库位状态为O.空库*/ | 
|---|
|  |  |  | if (!locService.update(new LambdaUpdateWrapper<Loc>() | 
|---|
|  |  |  | .set(Loc::getUseStatus, LocStsType.LOC_STS_TYPE_O.type) | 
|---|
|  |  |  | .set(Loc::getBarcode, null) | 
|---|
|  |  |  | .eq(Loc::getId, loc.getId()))) { | 
|---|
|  |  |  | throw new CoolException("库位状态修改失败!!"); | 
|---|
|  |  |  | } | 
|---|