瀏覽代碼

feat: 增加流水表

xyh 2 年之前
父節點
當前提交
77426be636

+ 1 - 0
packages/app/src/apis/index.ts

@@ -7,3 +7,4 @@ export * from './container';
 export * from './dictionary';
 export * from './material';
 export * from './receive';
+export * from './stream';

+ 25 - 0
packages/app/src/apis/stream.ts

@@ -0,0 +1,25 @@
+import {BaseListResult, GetWarehousingFlowingListParams, WarehousingListData} from '@models';
+import {request} from './request';
+
+/** 获取入库流水 */
+export function getWarehousingFlowList(
+  data: GetWarehousingFlowingListParams,
+): BaseListResult<WarehousingListData> {
+  return request({
+    method: 'GET',
+    data,
+    url: '/warehousing/warehousingFlowing',
+  });
+}
+
+/** 入库流水导出 */
+export function exportWarehousing(
+  data: GetWarehousingFlowingListParams,
+): any {
+  return request({
+    method: 'GET',
+    data,
+    url: '/warehousing/export',
+    skipError: true,
+  });
+}

+ 1 - 0
packages/app/src/components/filter-field/Date.tsx

@@ -31,6 +31,7 @@ const FilterTime: FC<Props> = function({
             name={name}
             value={value}
             onChange={onChange}
+            suffixIcon={null}
           />
         </Col>
       </Row>

+ 29 - 15
packages/app/src/hooks/useOptions/index.ts

@@ -1,20 +1,33 @@
 import {getAllRoleList, getAllStorage, getDictionaryOptions} from '@apis';
-import {BaseResult, DictionaryParamsType} from '@models';
+import {BaseResult, DictionaryParamsType, StorageListData} from '@models';
 import {useQuery} from '@tanstack/react-query';
+import {useMemo} from 'react';
 
 function useQueryOptions<T extends {id: number | string}>(
-  fn: () => BaseResult<T[]>,
-  findName: (state: T) => string,
-  addAll: boolean,
+  options: {
+    fn: () => BaseResult<T[]>,
+    findName: (state: T) => string,
+    addAll: boolean,
+    findValue?: (state: T) => string,
+  },
 ) {
+  const {findValue, fn, findName, addAll} = options ?? {};
+
+  const findValueFn = useMemo(function() {
+    return findValue;
+  }, []);
+
   const {data} = useQuery(
-    [fn.name, addAll],
+    [fn.name, addAll, findValueFn],
     async function() {
       const data = await fn();
 
       if (data.msg === '200') {
         const list = data.data.map(function(value) {
-          return {label: findName(value), value: String(value.id)};
+          return {
+            label: findName(value),
+            value: findValueFn ? findValueFn(value) : String(value.id),
+          };
         });
 
         if (addAll)
@@ -31,20 +44,21 @@ function useQueryOptions<T extends {id: number | string}>(
   return data;
 }
 
-export function useStorageOptions(addAll = false) {
-  return useQueryOptions(
-    getAllStorage,
-    state => state.storageLocationName,
+export function useStorageOptions(addAll = false, findValue?: (state: StorageListData) => string) {
+  return useQueryOptions({
+    fn: getAllStorage,
+    findName: state => state.storageLocationName,
     addAll,
-  );
+    findValue,
+  });
 }
 
 export function useRoleOptions(addAll = false) {
-  return useQueryOptions(
-    getAllRoleList,
-    state => state.roleName,
+  return useQueryOptions({
+    fn: getAllRoleList,
+    findName: state => state.roleName,
     addAll,
-  );
+  });
 }
 
 export function useDictionaryOptions(type: DictionaryParamsType, addAll = false) {

+ 1 - 0
packages/app/src/models/request/index.ts

@@ -15,3 +15,4 @@ export * from './container';
 export * from './dictionary';
 export * from './material';
 export * from './receive';
+export * from './stream';

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

@@ -0,0 +1,11 @@
+import {ListParams} from '.';
+
+/** 获取入库流水 */
+export type GetWarehousingFlowingListParams = {
+  /** 开始时间 */
+  startTime: string;
+  /** 结束时间 */
+  endTime: string;
+  /** 物料编号 */
+  wllbCode: string;
+} & ListParams;

+ 1 - 0
packages/app/src/models/response/index.ts

@@ -34,3 +34,4 @@ export * from './container';
 export * from './dictionary';
 export * from './material';
 export * from './receive';
+export * from './stream';

+ 51 - 0
packages/app/src/models/response/stream.ts

@@ -0,0 +1,51 @@
+export type WarehousingListData = {
+  /**
+   * 容量
+   */
+  capacity: string;
+  /**
+   * 部门
+   */
+  departmentName: string;
+  /**
+   * 工序
+   */
+  process: string;
+  /**
+   * 生产批次
+   */
+  producBatch: string;
+  /**
+   * 生产日期
+   */
+  producDate: string;
+  scrq: string;
+  /**
+   * 序列号
+   */
+  seq: string;
+  /**
+   * 连翻号
+   */
+  serial: string;
+  /**
+   * 库位名称
+   */
+  storageLocationName: string;
+  /**
+   * 供应商名称
+   */
+  supplierName: string;
+  /**
+   * 类型
+   */
+  type: string;
+  /**
+   * 用户名称
+   */
+  userName: string;
+  /**
+   * 物料编号
+   */
+  wllbCode: string;
+};

+ 4 - 1
packages/app/src/pages/matter/filter/index.tsx

@@ -5,7 +5,10 @@ import {FC} from 'react';
 import {useSearch} from './hooks';
 
 const Filter: FC = function() {
-  const storageOptions = useStorageOptions(true);
+  const storageOptions = useStorageOptions(
+    true,
+    state => state.storageLocationCode,
+  );
   const matterOptions = useDictionaryOptions('物料字典', true);
   const [{storage, matter}, onChange] = useFilterField({storage: '', matter: ''});
   const [isSearching, onSeach] = useSearch(storage, matter);

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

@@ -8,7 +8,7 @@ type Props = {id: string};
 const Info: FC<Props> = function({id}) {
   const control = useControl();
   const matterOtions = useDictionaryOptions('物料字典');
-  const storageOtions = useStorageOptions();
+  const storageOtions = useStorageOptions(false, state => state.storageLocationCode);
   useWatchId(id);
 
   return (

+ 38 - 0
packages/app/src/pages/raw-in-stream/context.ts

@@ -0,0 +1,38 @@
+import {createPageContext, createSearchContext} from '@hooks';
+import {useReducer} from 'react';
+import {createContext} from 'use-context-selector';
+
+export const pageContext = createPageContext();
+export const searchContext = createSearchContext();
+
+type State = {
+  startTime: string;
+  endTime: string;
+  wllbCode: string;
+};
+
+type Action = {type: 'SEARCH', payload: State};
+
+function initState(): State {
+  return {startTime: '', endTime: '', wllbCode: ''};
+}
+
+function reducer(state: State, action: Action): State {
+  const {type, payload} = action;
+
+  switch (type) {
+    case 'SEARCH':
+      return payload;
+    default:
+      return state;
+  }
+}
+
+export function useContextReducer() {
+  return useReducer(reducer, initState());
+}
+
+export const context = createContext<ReturnType<typeof useContextReducer>>([
+  initState(),
+  () => null,
+]);

+ 27 - 0
packages/app/src/pages/raw-in-stream/filter/hooks.ts

@@ -0,0 +1,27 @@
+import {useContextSection, useExportFile, usePage, useTableSearch} from '@hooks';
+import {context, pageContext, searchContext} from '../context';
+import {useContextSelector} from 'use-context-selector';
+import {exportWarehousing} from '@apis';
+
+export function useSearch(code: string, startTime: string, endTime: string) {
+  const [isSearching] = useTableSearch(searchContext);
+  const dispatch = useContextSection(context, state => state[1]);
+
+  function onSearch() {
+    dispatch({type: 'SEARCH', payload: {startTime, endTime, wllbCode: code}});
+  }
+
+  return [isSearching, onSearch] as const;
+}
+
+export function useExport() {
+  const params = useContextSelector(context, state => state[0]);
+  const [isExporting, mutate] = useExportFile(exportWarehousing);
+  const [{page, pageSize}] = usePage(pageContext);
+
+  function onExport() {
+    mutate({...params, page: String(page), limit: String(pageSize)});
+  }
+
+  return [isExporting, onExport] as const;
+}

+ 35 - 0
packages/app/src/pages/raw-in-stream/filter/index.tsx

@@ -0,0 +1,35 @@
+import {FilterButtonGroup, FilterDatePicker, FilterField} from '@components';
+import {useRangeDate} from '@hooks';
+import {Card, Row} from 'antd';
+import {FC, useState} from 'react';
+import {useExport, useSearch} from './hooks';
+
+const Filter: FC = function() {
+  const [{dates, start, end}, onDatesChange] = useRangeDate();
+  const [code, onCodeChange] = useState('');
+  const [isSearching, onSearch] = useSearch(start, end, code);
+  const [isExporting, onExport] = useExport();
+
+  return (
+    <Card>
+      <Row>
+        <FilterField name='rawMaterialCode' label='物料编号' value={code} onChange={onCodeChange} />
+        <FilterDatePicker
+          name='rawMaterialDates'
+          label='入库时间'
+          value={dates}
+          onChange={onDatesChange}
+        />
+        <FilterButtonGroup
+          offset={6}
+          onSearch={onSearch}
+          isSearching={isSearching}
+          onExport={onExport}
+          isExporting={isExporting}
+        />
+      </Row>
+    </Card>
+  );
+};
+
+export default Filter;

+ 30 - 0
packages/app/src/pages/raw-in-stream/index.tsx

@@ -0,0 +1,30 @@
+import {ChildrenFC} from '@utils';
+import {FC} from 'react';
+import {context, pageContext, searchContext, useContextReducer} from './context';
+import {PageProvider, SearchProvider} from '@components';
+import Filter from './filter';
+import TableList from './table';
+
+const RawMaterialInStreamProvider: ChildrenFC = function({children}) {
+  const {Provider} = context;
+  const state = useContextReducer();
+
+  return <Provider value={state}>{children}</Provider>;
+};
+
+const RawMaterialInStream: FC = function() {
+  return (
+    <RawMaterialInStreamProvider>
+      <PageProvider context={pageContext}>
+        <SearchProvider context={searchContext}>
+          <section className='content-main'>
+            <Filter />
+            <TableList />
+          </section>
+        </SearchProvider>
+      </PageProvider>
+    </RawMaterialInStreamProvider>
+  );
+};
+
+export default RawMaterialInStream;

+ 14 - 0
packages/app/src/pages/raw-in-stream/table/hooks.ts

@@ -0,0 +1,14 @@
+import {useContextSection, useQueryTableList} from '@hooks';
+import {context, pageContext, searchContext} from '../context';
+import {getWarehousingFlowList} from '@apis';
+
+export function useList() {
+  const params = useContextSection(context, state => state[0]);
+
+  return useQueryTableList({
+    queryFn: getWarehousingFlowList,
+    params,
+    pageContext,
+    searchContext,
+  });
+}

+ 10 - 0
packages/app/src/pages/raw-in-stream/table/index.tsx

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

+ 1 - 0
packages/app/src/pages/role/table/tree-modal/info/index.tsx

@@ -15,6 +15,7 @@ const TreeInfo: FC = function() {
       defaultExpandAll
       height={300}
       data-testid='role_tree'
+      style={{width: '240px'}}
     />
   );
 };

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

@@ -29,3 +29,5 @@ export const MATTER_PATH = '/matter';
 export const RECEIVE_PATH = '/receive';
 /** 超时采购单管理 */
 export const RECEIVE_TIMEOUT_PATH = '/receive/timeout';
+/** 入库流水 */
+export const RAW_IN_STREAM_PATH = '/stream/rawin';

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

@@ -11,6 +11,7 @@ import {
   MENU_PATH,
   NO_PERMISSION_PATH,
   PDA_MENU_PATH,
+  RAW_IN_STREAM_PATH,
   RECEIVE_PATH,
   RECEIVE_TIMEOUT_PATH,
   ROLE_PATH,
@@ -46,6 +47,10 @@ const ReceiveTimeout = lazy(() => import(
   /* webpackChunkName: "receiveTimeout" */
   '@pages/receive-timeout'
 ));
+const RawInStream = lazy(() => import(
+  /* webpackChunkName: "rawInStream" */
+  '@pages/raw-in-stream'
+));
 
 const routes: RouteObject[] = [
   {
@@ -64,6 +69,7 @@ const routes: RouteObject[] = [
       {path: MATTER_PATH, element: <Matter />},
       {path: RECEIVE_PATH, element: <Receive />},
       {path: RECEIVE_TIMEOUT_PATH, element: <ReceiveTimeout />},
+      {path: RAW_IN_STREAM_PATH, element: <RawInStream />},
     ],
   },
   {path: LOGIN_PATH, element: <Login />},