Browse Source

feat: 半成品入库单

xyh 2 năm trước cách đây
mục cha
commit
23b97095d6
29 tập tin đã thay đổi với 573 bổ sung22 xóa
  1. 44 3
      packages/app/src/apis/stream.ts
  2. 2 0
      packages/app/src/models/request/storage.ts
  3. 11 1
      packages/app/src/models/request/stream.ts
  4. 2 0
      packages/app/src/models/response/storage.ts
  5. 9 6
      packages/app/src/models/response/stream.ts
  6. 1 1
      packages/app/src/pages/goods/table/hooks.tsx
  7. 7 0
      packages/app/src/pages/semi-draw/context.ts
  8. 13 0
      packages/app/src/pages/semi-draw/filter/hooks.ts
  9. 25 0
      packages/app/src/pages/semi-draw/filter/index.tsx
  10. 22 0
      packages/app/src/pages/semi-draw/index.tsx
  11. 20 0
      packages/app/src/pages/semi-draw/table/hooks.tsx
  12. 9 0
      packages/app/src/pages/semi-draw/table/index.tsx
  13. 11 0
      packages/app/src/pages/semi-in-stream/context.ts
  14. 8 0
      packages/app/src/pages/semi-in-stream/filter/index.tsx
  15. 17 0
      packages/app/src/pages/semi-in-stream/index.tsx
  16. 1 1
      packages/app/src/pages/semi-report/context.ts
  17. 15 2
      packages/app/src/pages/semi-report/filter/hooks.ts
  18. 29 6
      packages/app/src/pages/semi-report/filter/index.tsx
  19. 6 1
      packages/app/src/pages/semi-report/index.tsx
  20. 86 0
      packages/app/src/pages/semi-report/table/hooks.tsx
  21. 30 0
      packages/app/src/pages/semi-report/table/index.tsx
  22. 17 0
      packages/app/src/pages/semi-report/table/modal/Info.tsx
  23. 104 0
      packages/app/src/pages/semi-report/table/modal/hooks.ts
  24. 40 0
      packages/app/src/pages/semi-report/table/modal/index.tsx
  25. 8 0
      packages/app/src/pages/storage/table/hooks.tsx
  26. 8 1
      packages/app/src/pages/storage/table/modal/Info.tsx
  27. 7 0
      packages/app/src/pages/storage/table/modal/hooks.ts
  28. 6 0
      packages/app/src/routes/name.ts
  29. 15 0
      packages/app/src/routes/routes.tsx

+ 44 - 3
packages/app/src/apis/stream.ts

@@ -3,6 +3,7 @@ import {
   BaseResult,
   GetNoticeListParams,
   GetRawOutListParams,
+  GetSemiManufacturesDrawList,
   GetWarehousingFlowingListParams,
   NoticeListData,
   RawMaterialOutStreamListData,
@@ -67,6 +68,15 @@ export function getNoticeList(data: GetNoticeListParams): BaseListResult<NoticeL
   });
 }
 
+/** 获取报工单详情 */
+export function getNoticeInfo(id: string): BaseListResult<NoticeListData> {
+  return request({
+    method: 'GET',
+    url: `${BASE_URL}/getNotice`,
+    data: {page: '1', limit: '1', id},
+  });
+}
+
 /** 半成品入库 */
 export function semiManufacturesAdd(data: SemiManufacturesAddParams): BaseResult {
   return request({
@@ -96,9 +106,7 @@ export function getSemiManufacturesInStream(
   });
 }
 
-/** 半成品入库流水导出
- *
- */
+/** 半成品入库流水导出 */
 export function exportSemiManufacturesInStream(
   data: GetWarehousingFlowingListParams,
 ): any {
@@ -108,3 +116,36 @@ export function exportSemiManufacturesInStream(
     data,
   });
 }
+
+/** 半成品出库物料列表 */
+export function getSemiManufacturesDrawList(
+  data: GetSemiManufacturesDrawList,
+): BaseListResult<any> {
+  return request({
+    method: 'GET',
+    url: 'askGoods/getGoodsHalf',
+    data,
+  });
+}
+
+/** 半成品出库流水列表 */
+export function getSemiManufacturesDrawStream(
+  data: GetWarehousingFlowingListParams,
+): BaseListResult<any> {
+  return request({
+    method: 'GET',
+    url: 'askGoods/getRemovalHalfProduct',
+    data,
+  });
+}
+
+/** 半成品出库流水导出 */
+export function exportSemiManufacturesDrawStream(
+  data: GetWarehousingFlowingListParams,
+): any {
+  return request({
+    method: 'GET',
+    url: 'askGoods/getRemovalHalfProductExcel',
+    data,
+  });
+}

+ 2 - 0
packages/app/src/models/request/storage.ts

@@ -22,6 +22,8 @@ export type AddStorageParams = {
   storageLocationType: string
   /** 是否是混合库位 */
   isNotDisable: string
+  /** 是否是产成品库位 */
+  isProduct: string
 };
 
 /** 修改仓库 */

+ 11 - 1
packages/app/src/models/request/stream.ts

@@ -17,7 +17,8 @@ export type GetNoticeListParams = {
   type: string;
   startTime: string;
   endTime: string;
-};
+  materialCode: string;
+} & ListParams;
 
 /** 半成品入库 */
 export type SemiManufacturesAddParams = {
@@ -55,3 +56,12 @@ export type SemiManufacturesOutParams = {
   /** 出库数量 */
   num: string;
 };
+
+/** 产成品/半成品出库物料列表 */
+export type GetSemiManufacturesDrawList = {
+  partType: '产成品' | '半成品',
+  /** 要货单id */
+  askGoodsId: string;
+  /** 生产订单号 */
+  productionCode: string;
+} & ListParams;

+ 2 - 0
packages/app/src/models/response/storage.ts

@@ -17,4 +17,6 @@ export type StorageListData = {
   storageLocationCapacity: string,
   /** 分类名称 */
   materialName: string,
+  /** 是否是产成品库位 */
+  isProduct: string,
 };

+ 9 - 6
packages/app/src/models/response/stream.ts

@@ -1,3 +1,4 @@
+
 /** 原材料入库流水 */
 export type WarehousingListData = {
   /** 物料名称 */
@@ -117,10 +118,12 @@ export type RawMaterialOutStreamListData = {
 
 /** 报工单数据 */
 export type NoticeListData = {
+  /** 所属公司 */
+  companyNumber: string;
   /**
  * 分录号
  */
-  entry_number: string;
+  entryNumber: string;
   /**
   * id
   */
@@ -128,7 +131,7 @@ export type NoticeListData = {
   /**
   * 物料id
   */
-  material_id: string;
+  materialId: string;
   /**
   * 物料名称
   */
@@ -136,11 +139,11 @@ export type NoticeListData = {
   /**
   * 計量單位id
   */
-  measurement_id: string;
+  measurementId: string;
   /**
   * 通知单id
   */
-  notice_id: string;
+  noticeId: string;
   /**
   * 数量
   */
@@ -148,7 +151,7 @@ export type NoticeListData = {
   /**
   * 生产批次
   */
-  production_code: string;
+  productionCode: string;
   /**
   * 状态
   */
@@ -156,7 +159,7 @@ export type NoticeListData = {
   /**
   * 入库数量
   */
-  warehousing_num: string;
+  warehousingNum?: string;
   /**
   * wbs
   */

+ 1 - 1
packages/app/src/pages/goods/table/hooks.tsx

@@ -44,6 +44,7 @@ export function useHandle() {
   const columns: ColumnsType<DictionaryData> = [
     {title: '物料名称', dataIndex: 'name', key: 'name'},
     {title: '物料编号', dataIndex: 'code', key: 'code'},
+    {title: '物料类别', dataIndex: 'partType', key: 'partType'},
     {title: '物料类型', dataIndex: 'materialType', key: 'materialType'},
     {title: '存储容量', dataIndex: 'size', key: 'size'},
     {
@@ -66,7 +67,6 @@ export function useHandle() {
       title: '操作',
       dataIndex: 'tldId',
       key: 'tldId',
-      width: 330,
       render(_, {tldId}) {
         return (
           <>

+ 7 - 0
packages/app/src/pages/semi-draw/context.ts

@@ -0,0 +1,7 @@
+import {createPageContext, createSearchContext, createTableSearchContext} from '@hooks';
+
+export const pageContext = createPageContext();
+export const searchContext = createSearchContext();
+
+export const contextState = {code: ''};
+export const context = createTableSearchContext(contextState);

+ 13 - 0
packages/app/src/pages/semi-draw/filter/hooks.ts

@@ -0,0 +1,13 @@
+import {useContextSection, useTableSearchState} from '@hooks';
+import {context, searchContext} from '../context';
+
+export function useSearch(code: string) {
+  const [isSearching] = useTableSearchState(searchContext);
+  const dispatch = useContextSection(context, state => state[1]);
+
+  function onSearch() {
+    dispatch({type: 'SEARCH', payload: {code}});
+  }
+
+  return [isSearching, onSearch] as const;
+}

+ 25 - 0
packages/app/src/pages/semi-draw/filter/index.tsx

@@ -0,0 +1,25 @@
+import {FilterField, FilterButtonGroup} from '@components';
+import {Card, Row} from 'antd';
+import {FC, useState} from 'react';
+import {useSearch} from './hooks';
+
+const Filter: FC = function() {
+  const [code, onCodeChange] = useState('');
+  const [isSearching, onSearch] = useSearch(code);
+
+  return (
+    <Card>
+      <Row>
+        <FilterField name='semiReportCode' label='生产单号' value={code} onChange={onCodeChange} />
+
+        <FilterButtonGroup
+          offset={12}
+          isSearching={isSearching}
+          onSearch={onSearch}
+        />
+      </Row>
+    </Card>
+  );
+};
+
+export default Filter;

+ 22 - 0
packages/app/src/pages/semi-draw/index.tsx

@@ -0,0 +1,22 @@
+import {PageProvider, SearchProvider, TableSearchProvider} from '@components';
+import {FC} from 'react';
+import {context, contextState, pageContext, searchContext} from './context';
+import Filter from './filter';
+import TableList from './table';
+
+const SemiDraw: FC = function() {
+  return (
+    <TableSearchProvider context={context} state={contextState}>
+      <PageProvider context={pageContext}>
+        <SearchProvider context={searchContext}>
+          <section className='content-main'>
+            <Filter />
+            <TableList />
+          </section>
+        </SearchProvider>
+      </PageProvider>
+    </TableSearchProvider>
+  );
+};
+
+export default SemiDraw;

+ 20 - 0
packages/app/src/pages/semi-draw/table/hooks.tsx

@@ -0,0 +1,20 @@
+import {useContextSection, useQueryTableList} from '@hooks';
+import {context, pageContext, searchContext} from '../context';
+import {getSemiManufacturesDrawList} from '@apis';
+
+export function useList() {
+  const params = useContextSection(context, function([{code}]) {
+    return {
+      partType: '半成品' as const,
+      productionCode: code,
+      askGoodsId: '',
+    };
+  });
+
+  return useQueryTableList({
+    queryFn: getSemiManufacturesDrawList,
+    params,
+    pageContext,
+    searchContext,
+  });
+}

+ 9 - 0
packages/app/src/pages/semi-draw/table/index.tsx

@@ -0,0 +1,9 @@
+import {FC} from 'react';
+import {useList} from './hooks';
+
+const TableList: FC = function() {
+  useList();
+  return <></>;
+};
+
+export default TableList;

+ 11 - 0
packages/app/src/pages/semi-in-stream/context.ts

@@ -0,0 +1,11 @@
+import {createPageContext, createSearchContext, createTableSearchContext} from '@hooks';
+
+export const pageContext = createPageContext();
+export const searchContext = createSearchContext();
+
+export const contextState = {
+  code: '',
+  startTime: '',
+  endTime: '',
+};
+export const context = createTableSearchContext(contextState);

+ 8 - 0
packages/app/src/pages/semi-in-stream/filter/index.tsx

@@ -0,0 +1,8 @@
+import css from './index.module.css';
+import {FC} from 'react';
+
+const Filter: FC = function() {
+  return <></>;
+};
+
+export default Filter;

+ 17 - 0
packages/app/src/pages/semi-in-stream/index.tsx

@@ -0,0 +1,17 @@
+import {PageProvider, SearchProvider, TableSearchProvider} from '@components';
+import {FC} from 'react';
+import {context, contextState, pageContext, searchContext} from './context';
+
+const SemiInStream: FC = function() {
+  return (
+    <TableSearchProvider context={context} state={contextState}>
+      <PageProvider context={pageContext}>
+        <SearchProvider context={searchContext}>
+          <section className='content-main' />
+        </SearchProvider>
+      </PageProvider>
+    </TableSearchProvider>
+  );
+};
+
+export default SemiInStream;

+ 1 - 1
packages/app/src/pages/semi-report/context.ts

@@ -3,5 +3,5 @@ import {createPageContext, createSearchContext, createTableSearchContext} from '
 export const pageContext = createPageContext();
 export const searchContext = createSearchContext();
 
-export const contextState = Object.freeze({type: '', startTime: '', endTime: ''});
+export const contextState = {type: '', code: '', startTime: '', endTime: ''};
 export const context = createTableSearchContext(contextState);

+ 15 - 2
packages/app/src/pages/semi-report/filter/hooks.ts

@@ -1,3 +1,16 @@
-import {useTableSearchState} from '@hooks';
-import {searchContext} from '../context';
+import {useContextSection, useTableSearchState} from '@hooks';
+import {context, searchContext} from '../context';
 
+export function useSearch(
+  {startTime, endTime, type, code}:
+  {startTime: string, endTime: string, type: string, code: string},
+) {
+  const [isSearching] = useTableSearchState(searchContext);
+  const dispatch = useContextSection(context, state => state[1]);
+
+  function onSearch() {
+    dispatch({type: 'SEARCH', payload: {startTime, endTime, type, code}});
+  }
+
+  return [isSearching, onSearch] as const;
+}

+ 29 - 6
packages/app/src/pages/semi-report/filter/index.tsx

@@ -1,23 +1,46 @@
-import {FilterButtonGroup, FilterDatePicker, FilterField} from '@components';
-import {useRangeDate} from '@hooks';
+import {FilterButtonGroup, FilterDatePicker, FilterField, FilterSelect} from '@components';
+import {useFilterField, useRangeDate} from '@hooks';
 import {Card, Row} from 'antd';
-import {FC, useState} from 'react';
+import {FC} from 'react';
+import {useSearch} from './hooks';
+
+const options = [
+  {label: '全部', value: ''},
+  {label: '未入库', value: '0'},
+  {label: '已入库', value: '1'},
+];
 
 const Filter: FC = function() {
   const [{dates, start, end}, onDatesChange] = useRangeDate();
-  const [type, onTypeChange] = useState('');
+  const [{type, code}, onChange] = useFilterField({code: '', type: ''});
+  const [isSearching, onSearch] = useSearch({startTime: start, endTime: end, type, code});
 
   return (
     <Card>
       <Row>
-        <FilterField name='semiReportType' label='状态' value={type} onChange={onTypeChange} />
+        <FilterField
+          name='semiReportCode'
+          label='物料编号'
+          value={code}
+          onChange={onChange('code')}
+        />
+        <FilterSelect
+          options={options}
+          name='semiReportType'
+          label='状态'
+          value={type}
+          onChange={onChange('type')}
+        />
         <FilterDatePicker
           name='rawMaterialDates'
           label='报工时间'
           value={dates}
           onChange={onDatesChange}
         />
-
+        <FilterButtonGroup
+          isSearching={isSearching}
+          onSearch={onSearch}
+        />
       </Row>
     </Card>
   );

+ 6 - 1
packages/app/src/pages/semi-report/index.tsx

@@ -1,13 +1,18 @@
 import {PageProvider, SearchProvider, TableSearchProvider} from '@components';
 import {FC} from 'react';
 import {context, contextState, pageContext, searchContext} from './context';
+import Filter from './filter';
+import TableList from './table';
 
 const SemiReport: FC = function() {
   return (
     <TableSearchProvider context={context} state={contextState}>
       <PageProvider context={pageContext}>
         <SearchProvider context={searchContext}>
-          <section className='content-main' />
+          <section className='content-main'>
+            <Filter />
+            <TableList />
+          </section>
         </SearchProvider>
       </PageProvider>
     </TableSearchProvider>

+ 86 - 0
packages/app/src/pages/semi-report/table/hooks.tsx

@@ -0,0 +1,86 @@
+import {useContextSection, useQueryTableList} from '@hooks';
+import {context, pageContext, searchContext} from '../context';
+import {getNoticeList} from '@apis';
+import {Button} from 'antd';
+import {ColumnsType} from 'antd/es/table';
+import {NoticeListData} from '@models';
+import {useBoolean} from 'ahooks';
+import {useState} from 'react';
+
+export function useList() {
+  const params = useContextSection(
+    context,
+    function([{code, startTime, endTime, type}]) {
+      return {startTime, endTime, type, materialCode: code};
+    },
+  );
+
+  return useQueryTableList({
+    queryFn: getNoticeList,
+    params,
+    pageContext,
+    searchContext,
+  });
+}
+
+function usePutIn() {
+  const [visible, {setTrue, setFalse}] = useBoolean(false);
+  const [state, setState] = useState('');
+
+  function onClick(id: string) {
+    return function() {
+      setTrue();
+      setState(id);
+    };
+  }
+
+  return [{visible, state}, {onClick, onClose: setFalse}] as const;
+}
+
+export function useHandle() {
+  const [{visible, state}, {onClick, onClose}] = usePutIn();
+
+  const columns: ColumnsType<NoticeListData> = [
+    {title: '物料名称', dataIndex: 'materialName', key: 'materialName'},
+    {title: '申请入库数量', dataIndex: 'num', key: 'num'},
+    {
+      title: '已入库数量',
+      dataIndex: 'warehousingNum',
+      key: 'warehousingNum',
+      render(_, {warehousingNum}) {
+        return warehousingNum ?? '0';
+      },
+    },
+    {title: '生产批次', dataIndex: 'productionCode', key: 'productionCode'},
+    {title: '分录号', dataIndex: 'entryNumber', key: 'entryNumber'},
+    {
+      title: '状态',
+      dataIndex: 'type',
+      key: 'type',
+      render(_, {type}) {
+        return type === '0' ? '未入库' : '已入库';
+      },
+    },
+    {
+      title: '操作',
+      dataIndex: 'id',
+      key: 'id',
+      render(_, {id, type}) {
+        return (
+          <>
+            <Button
+              type='link'
+              disabled={type !== '0'}
+              onClick={onClick(id)}
+            >
+              {type === '0' ? '入库' : '已入库'}
+            </Button>
+
+          </>
+        );
+      },
+    },
+  ];
+
+  return [{columns, visible, state}, {onClose}] as const;
+}

+ 30 - 0
packages/app/src/pages/semi-report/table/index.tsx

@@ -0,0 +1,30 @@
+import {FC} from 'react';
+import {useHandle, useList} from './hooks';
+import {Card} from 'antd';
+import {Table} from '@components';
+import {pageContext, searchContext} from '../context';
+import PutModal from './modal';
+
+const TableList: FC = function() {
+  const [{data, count}, {refetch}] = useList();
+  const [{columns, visible, state}, {onClose}] = useHandle();
+
+  return (
+    <>
+      <Card className='table-wrapper'>
+        <Table
+          data-testid='semi_report_table'
+          columns={columns}
+          data={data}
+          pageContext={pageContext}
+          searchContext={searchContext}
+          count={count}
+        />
+      </Card>
+
+      <PutModal visible={visible} onClose={onClose} onFetch={refetch} id={state} />
+    </>
+  );
+};
+
+export default TableList;

+ 17 - 0
packages/app/src/pages/semi-report/table/modal/Info.tsx

@@ -0,0 +1,17 @@
+import {ModalField} from '@components';
+import {FC} from 'react';
+import {useControl, useWatchId} from './hooks';
+
+type Props = {id: string};
+const Info: FC<Props> = function({id}) {
+  const control = useControl();
+  useWatchId(id);
+
+  return (
+    <>
+      <ModalField name='putInStoragenum' type='number' control={control} label='入库数量' />
+    </>
+  );
+};
+
+export default Info;

+ 104 - 0
packages/app/src/pages/semi-report/table/modal/hooks.ts

@@ -0,0 +1,104 @@
+import {getNoticeInfo, semiManufacturesAdd} from '@apis';
+import {yupResolver} from '@hookform/resolvers/yup';
+import {useQueryDataInfo} from '@hooks';
+import {NoticeListData} from '@models';
+import {userStore} from '@stores';
+import {useMutation, useQueryClient} from '@tanstack/react-query';
+import {message} from 'antd';
+import {useEffect} from 'react';
+import {useForm, useFormContext} from 'react-hook-form';
+import {number, object} from 'yup';
+import {useStore} from 'zustand';
+
+type FormState = {
+  putInStoragenum: number,
+};
+
+const validate = object({
+  putInStoragenum: number().typeError('请输入数字').min(1, '不能少于1个'),
+});
+
+function useQuery(onClose: () => void, onFetch: () => void) {
+  return useMutation({
+    mutationFn: semiManufacturesAdd,
+    onSuccess({msg}) {
+      if (msg === '200') {
+        onClose();
+        onFetch();
+        message.success('入库成功');
+      }
+    },
+  });
+}
+
+function useInfoData(id: string) {
+  const client = useQueryClient();
+
+  function getData() {
+    return client.getQueryData<NoticeListData>([getNoticeInfo.name, id]);
+  }
+
+  return getData;
+}
+
+export function useFormState(
+  {id, visible, onClose, onFetch}:
+  {id: string, visible: boolean, onClose: () => void, onFetch: () => void},
+) {
+  const formInstance = useForm<FormState>({
+    defaultValues: {
+      putInStoragenum: 0,
+    },
+    resolver: yupResolver(validate),
+  });
+  const {control, handleSubmit, clearErrors} = formInstance;
+
+  useEffect(function() {
+    if (visible)
+      clearErrors();
+  }, [clearErrors, visible]);
+
+  const {mutate, isLoading} = useQuery(onClose, onFetch);
+  const getInfoData = useInfoData(id);
+  const userId = useStore(userStore, state => String(state.id));
+
+  const onSubmit = handleSubmit(function({putInStoragenum}) {
+    const info = getInfoData();
+
+    if (!info)
+      message.error('未获取到信息');
+    else {
+      const {wllbClass, companyNumber, wbs, materialId, noticeId} = info;
+      mutate({
+        userId,
+        companyNumber,
+        wbs,
+        wllbClass,
+        noticeId,
+        materialId,
+        warehousingNum: String(putInStoragenum),
+      });
+    }
+  });
+
+  return [{control, isLoading, formInstance}, {onSubmit}] as const;
+}
+
+export function useControl() {
+  const {control} = useFormContext<FormState>();
+
+  return control;
+}
+
+export function useWatchId(id: string) {
+  const {setValue} = useFormContext<FormState>();
+  const data = useQueryDataInfo({
+    queryFn: getNoticeInfo,
+    params: [id],
+    enabled: Boolean(id),
+  });
+
+  useEffect(function() {
+    setValue('putInStoragenum', Number(data?.num ?? '0'));
+  }, [data, setValue]);
+}

+ 40 - 0
packages/app/src/pages/semi-report/table/modal/index.tsx

@@ -0,0 +1,40 @@
+import {ErrorBoundary, Loading, Modal} from '@components';
+import {FC, Suspense} from 'react';
+import {useFormState} from './hooks';
+import {FormProvider} from 'react-hook-form';
+import Info from './Info';
+
+type Props = {
+  visible: boolean,
+  id: string,
+  onClose: () => void,
+  onFetch: () => void,
+};
+
+const PutModal: FC<Props> = function({visible, onClose, onFetch, id}) {
+  const [
+    {formInstance, isLoading},
+    {onSubmit},
+  ] = useFormState({id, onClose, onFetch, visible});
+
+  return (
+    <Modal
+      visible={visible}
+      title='报工单入库'
+      onClose={onClose}
+      onSubmit={onSubmit}
+      testId='role_modal'
+      isLoading={isLoading}
+    >
+      <FormProvider {...formInstance}>
+        <ErrorBoundary>
+          <Suspense fallback={<Loading tip='正在获取信息' />}>
+            <Info id={id} />
+          </Suspense>
+        </ErrorBoundary>
+      </FormProvider>
+    </Modal>
+  );
+};
+
+export default PutModal;

+ 8 - 0
packages/app/src/pages/storage/table/hooks.tsx

@@ -81,6 +81,14 @@ export function useHandle(reftch: () => void) {
         return isNotDisable === '1' ? '是' : '否';
       },
     },
+    {
+      title: '是否是产成品库位',
+      dataIndex: 'isProduct',
+      key: 'isProduct',
+      render(_, {isProduct}) {
+        return isProduct === '1' ? '是' : '否';
+      },
+    },
     {title: '创建时间', dataIndex: 'createTime', key: 'createTime'},
     {
       title: '操作',

+ 8 - 1
packages/app/src/pages/storage/table/modal/Info.tsx

@@ -41,7 +41,14 @@ const StoreModalInfo: FC<Props> = function({id}) {
       <ModalSelect
         name='storageIsNotDisable'
         width='300px'
-        label='是否是混合库位'
+        label='混合库位'
+        control={control}
+        data={stateOptions}
+      />
+      <ModalSelect
+        name='storageIsProduct'
+        width='300px'
+        label='产成品库位'
         control={control}
         data={stateOptions}
       />

+ 7 - 0
packages/app/src/pages/storage/table/modal/hooks.ts

@@ -17,6 +17,8 @@ type FormState = {
   storageLocationType: string
   /** 是否是混合库位 */
   storageIsNotDisable: string
+  /** 是否产成品库位 */
+  storageIsProduct: string
 };
 
 const validate = object({
@@ -24,6 +26,7 @@ const validate = object({
   storageLocationName: string().required('请输入库位名称'),
   storageLocationType: string().required('请输入物料类型'),
   storageIsNotDisable: string().required('请选择是否是混合库位'),
+  storageIsProduct: string().required('请选择是否是产成品库位'),
 });
 
 function useAdd(onClose: () => void, onFetch: () => void) {
@@ -70,6 +73,7 @@ export function useFormState(
       storageLocationName: '',
       storageLocationType: '',
       storageIsNotDisable: '0',
+      storageIsProduct: '0',
     },
     resolver: yupResolver(validate),
   });
@@ -89,12 +93,14 @@ export function useFormState(
     storageLocationCode,
     storageLocationType,
     storageIsNotDisable,
+    storageIsProduct,
   }) {
     const params: AddStorageParams = {
       storageLocationName,
       storageLocationCode,
       storageLocationType,
       isNotDisable: storageIsNotDisable,
+      isProduct: storageIsProduct,
     };
 
     id
@@ -125,5 +131,6 @@ export function useFormInfoValue(id: string) {
     setValue('storageLocationName', data?.storageLocationName ?? '');
     setValue('storageLocationType', data?.storageLocationType ?? '');
     setValue('storageIsNotDisable', data?.isNotDisable ?? '0');
+    setValue('storageIsProduct', data?.isProduct ?? '0');
   }, [data, setValue]);
 }

+ 6 - 0
packages/app/src/routes/name.ts

@@ -33,3 +33,9 @@ export const RECEIVE_TIMEOUT_PATH = '/receive/timeout';
 export const RAW_IN_STREAM_PATH = '/stream/rawin';
 /** 原料出库流水 */
 export const RAW_OUT_STREAM_PATH = '/stream/rawout';
+/** 半成品报工单 */
+export const SEMI_REPORT_PATH = '/semi/report';
+/** 半成品领料单 */
+export const SEMI_DRAW_PATH = '/semi/draw';
+/** 半成品入库流水 */
+export const SEMI_IN_STREAM = '/stream/semiin';

+ 15 - 0
packages/app/src/routes/routes.tsx

@@ -16,6 +16,9 @@ import {
   RECEIVE_PATH,
   RECEIVE_TIMEOUT_PATH,
   ROLE_PATH,
+  SEMI_DRAW_PATH,
+  SEMI_IN_STREAM,
+  SEMI_REPORT_PATH,
   STORAGE_PATH,
   USER_PATH,
 } from './name';
@@ -56,6 +59,15 @@ const RawOutStream = lazy(() => import(
   /* webpackChunkName: "rawOutStream" */
   '@pages/raw-out-stream'
 ));
+const SemiReport = lazy(() => import(
+  /* webpackChunkName: "semiReposrt" */
+  '@pages/semi-report'
+));
+const SemiInStream = lazy(() => import(
+  /* webpackChunkName: "semiInStream" */
+  '@pages/semi-in-stream'
+));
+const SemiDraw = lazy(() => import(/* webpackChunkName: "semiDraw" */'@pages/semi-draw'));
 
 const routes: RouteObject[] = [
   {
@@ -76,6 +88,9 @@ const routes: RouteObject[] = [
       {path: RECEIVE_TIMEOUT_PATH, element: <ReceiveTimeout />},
       {path: RAW_IN_STREAM_PATH, element: <RawInStream />},
       {path: RAW_OUT_STREAM_PATH, element: <RawOutStream />},
+      {path: SEMI_REPORT_PATH, element: <SemiReport />},
+      {path: SEMI_DRAW_PATH, element: <SemiDraw />},
+      {path: SEMI_IN_STREAM, element: <SemiInStream />},
     ],
   },
   {path: LOGIN_PATH, element: <Login />},