ソースを参照

chore: 更新modal样式

xyh 2 年 前
コミット
3efa1f148f

+ 6 - 10
cypress/e2e/storage.cy.ts

@@ -59,7 +59,7 @@ describe('库位管理', function() {
         MODAL_NAME = 'storage_modal',
         LABEL = '库位';
 
-  it.only('表格', function() {
+  it('表格', function() {
     validateTableList(TABLE_NAME);
 
     const validate = validateTableSearch(TABLE_NAME);
@@ -72,17 +72,17 @@ describe('库位管理', function() {
     validate('searchCode');
 
     cy.get('#filter_storageCode').clear();
-    cy.get('#filter_storageType').type('type');
+    selectClick('filter_storageType', 1);
     validate('searchType');
 
-    cy.get('#filter_storageType').clear();
+    selectClick('filter_storageType', 0);
     selectClick('filter_storageState', 1);
     validate('searchDisabled');
 
     validateExport();
   });
 
-  it('操作', function() {
+  it.only('操作', function() {
     const {validateAdd, validateEdit} = validatePut(
       MODAL_NAME,
       LABEL,
@@ -91,9 +91,7 @@ describe('库位管理', function() {
     validateAdd(function() {
       cy.getTestId('field_storageLocationCode').type('0001');
       cy.getTestId('field_storageLocationName').type('名称');
-      cy.getTestId('field_storageLocationType').type('类型');
-      cy.getTestId('field_storageWarehouseWhere').type('1号仓库');
-      cy.getTestId('field_storageCapacity').clear().type('5');
+      selectClick('select_storageLocationType', 0);
       selectClick('select_storageIsNotDisable', 1);
     });
 
@@ -103,9 +101,7 @@ describe('库位管理', function() {
 
       cy.getTestId('field_storageLocationCode').should('have.value', '0001');
       cy.getTestId('field_storageLocationName').should('have.value', '1号库位');
-      cy.getTestId('field_storageLocationType').should('have.value', '原材料库位');
-      cy.getTestId('field_storageWarehouseWhere').should('have.value', '1号仓库');
-      cy.getTestId('field_storageCapacity').should('have.value', '8');
+      validateSelect('select_storageLocationType', '原材料库位');
       validateSelect('select_storageIsNotDisable', '启用');
     });
 

+ 5 - 3
packages/app/src/components/modal/index.module.css

@@ -10,8 +10,8 @@
 }
 
 .dialog-title {
-  z-index: 2;
-  width: 400px;
+  z-index: 1;
+  width: 100%;
   padding: 46px 0 12px;
   font-size: 20px;
   text-align: center;
@@ -24,6 +24,7 @@
 .dialog-decorate {
   position: absolute;
   top: -40px;
+  left: calc(50% - 50px);
   z-index: 2;
   display: flex;
   justify-content: space-between;
@@ -68,6 +69,7 @@
   position: absolute;
   top: 22px;
   right: 22px;
+  z-index: 2;
   font-size: 24px;
   color: #d7d7d7;
   cursor: pointer;
@@ -82,7 +84,7 @@
   display: block;
   width: calc(100% - 40px);
   height: calc(100% - 89px);
-  padding: 0 0 30px 50px;
+  padding: 0 30px 30px;
   overflow: hidden;
 }
 

+ 5 - 2
packages/app/src/components/operation-field/Area.tsx

@@ -19,8 +19,11 @@ const OperationField: FC<Props> = function({
   height,
 }) {
   return (
-    <Row className='width-full'>
-      <Col span={14} offset={3}>
+    <Row className='width-full' gutter={12}>
+      <Col span={6} offset={2}>
+        <label className={css.textRight} htmlFor={`operation_${name}`}>{label}</label>
+      </Col>
+      <Col span={12}>
         <Controller
           name={name}
           control={control}

+ 2 - 2
packages/app/src/components/operation-field/Select.tsx

@@ -20,10 +20,10 @@ const ModalSelect: FC<Props> = function({
 }) {
   return (
     <Row className='full-width' gutter={12}>
-      <Col span={6}>
+      <Col span={6} offset={2}>
         <label className={css.textRight} htmlFor={`operation_${name}`}>{label}</label>
       </Col>
-      <Col span={18}>
+      <Col span={12}>
         <Controller
           name={name}
           control={control}

+ 2 - 2
packages/app/src/components/operation-field/field.tsx

@@ -22,10 +22,10 @@ const OperationField: FC<Props> = function({
 }) {
   return (
     <Row gutter={12}>
-      <Col span={6}>
+      <Col span={6} offset={2}>
         <label className={css.textRight} htmlFor={`operation_${name}`}>{label}</label>
       </Col>
-      <Col span={18}>
+      <Col span={12}>
         <Controller
           name={name}
           control={control}

+ 3 - 5
packages/app/src/hooks/useOptions/index.ts

@@ -1,7 +1,7 @@
 import {getAllRoleList, getAllStorage, getDictionaryOptions} from '@apis';
 import {BaseResult, DictionaryParamsType, StorageListData} from '@models';
 import {useQuery} from '@tanstack/react-query';
-import {useMemo} from 'react';
+import {useLatest} from 'ahooks';
 
 function useQueryOptions<T extends {id: number | string}>(
   options: {
@@ -13,9 +13,7 @@ function useQueryOptions<T extends {id: number | string}>(
 ) {
   const {findValue, fn, findName, addAll} = options ?? {};
 
-  const findValueFn = useMemo(function() {
-    return findValue;
-  }, []);
+  const findValueFn = useLatest(findValue);
 
   const {data} = useQuery(
     [fn.name, addAll, findValueFn],
@@ -26,7 +24,7 @@ function useQueryOptions<T extends {id: number | string}>(
         const list = data.data.map(function(value) {
           return {
             label: findName(value),
-            value: findValueFn ? findValueFn(value) : String(value.id),
+            value: findValueFn.current ? findValueFn.current?.(value) : String(value.id),
           };
         });
 

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

@@ -1,4 +1,7 @@
+/** 原材料入库流水 */
 export type WarehousingListData = {
+  /** 物料名称 */
+  materialName: string;
   /**
    * 容量
    */
@@ -50,3 +53,57 @@ export type WarehousingListData = {
    */
   wllbCode: string;
 };
+
+/** 原材料出库流水 */
+export type RawMaterialOutStreamListData = {
+  /** 物料名称 */
+  materialName: string;
+  /**
+   * 要货单id
+   */
+  askGoodsId: string;
+  /**
+  * 部门
+  */
+  department: string;
+  /**
+    * 出库数量
+    */
+  num: string;
+  /**
+    * 工序
+    */
+  process: string;
+  /**
+    * 生产日期
+    */
+  produc_date: string;
+  /**
+    * 生成日期
+    */
+  scrq: string;
+  /**
+    * 连翻号
+    */
+  serial: string;
+  /**
+  * 库位编号
+  */
+  storageLocationCode: string;
+  /**
+  * 供应商id
+  */
+  supplierId: string;
+  /**
+  * 类型
+  */
+  type: string;
+  /**
+  * 用户编号
+  */
+  userId: string;
+  /**
+  * 物料编号
+  */
+  wllbCode: string;
+};

+ 7 - 1
packages/app/src/pages/raw-in-stream/table/index.tsx

@@ -13,6 +13,12 @@ const columns: ColumnsType<WarehousingListData> = [
     key: 'wllbCode',
     width: 200,
   },
+  {
+    title: '物料名称',
+    dataIndex: 'materialName',
+    key: 'materialName',
+    width: 200,
+  },
   {
     title: '供应商名称',
     dataIndex: 'supplierName',
@@ -87,7 +93,7 @@ const TableList: FC = function() {
   return (
     <Card className='table-wrapper'>
       <Table
-        scrollX={1900}
+        scrollX={2100}
         data={data}
         count={count}
         pageContext={pageContext}

+ 38 - 0
packages/app/src/pages/raw-out-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-out-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-out-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(code, start, end);
+  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;

+ 28 - 0
packages/app/src/pages/raw-out-stream/index.tsx

@@ -0,0 +1,28 @@
+import {ChildrenFC} from '@utils';
+import {FC} from 'react';
+import {context, pageContext, searchContext, useContextReducer} from './context';
+import {PageProvider, SearchProvider} from '@components';
+import Filter from './filter';
+
+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 />
+          </section>
+        </SearchProvider>
+      </PageProvider>
+    </RawMaterialInStreamProvider>
+  );
+};
+
+export default RawMaterialInStream;

+ 11 - 8
packages/app/src/pages/role/table/pda-modal/Info.tsx

@@ -1,6 +1,7 @@
 import {FC} from 'react';
 import {useMenuList} from './hooks';
 import {Transfer} from 'antd';
+import css from './index.module.css';
 
 type Props = {
   selected: string[],
@@ -11,14 +12,16 @@ const Info: FC<Props> = function({selected, onChange}) {
   const data = useMenuList();
 
   return (
-    <Transfer
-      dataSource={data}
-      targetKeys={selected}
-      titles={['未选', '已选']}
-      rowKey={item => item.id}
-      render={item => item.name}
-      onChange={onChange}
-    />
+    <div className={css.treeWrapper}>
+      <Transfer
+        dataSource={data}
+        targetKeys={selected}
+        titles={['未选', '已选']}
+        rowKey={item => item.id}
+        render={item => item.name}
+        onChange={onChange}
+      />
+    </div>
   );
 };
 

+ 5 - 0
packages/app/src/pages/role/table/pda-modal/index.module.css

@@ -0,0 +1,5 @@
+.tree-wrapper {
+  display: flex;
+  justify-content: center;
+  padding-top: 24px;
+}

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

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

+ 2 - 2
packages/app/src/pages/storage/filter/index.tsx

@@ -7,8 +7,8 @@ import {searchContext} from '../context';
 
 const disableOptions = [
   {label: '全部', value: ''},
-  {label: '启用', value: '1'},
-  {label: '禁用', value: '0'},
+  {label: '', value: '1'},
+  {label: '', value: '0'},
 ];
 
 const Filter: FC = function() {

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

@@ -4,8 +4,8 @@ import {useFormInfoValue, useFormInstance} from './hooks';
 import {useDictionaryOptions} from '@hooks';
 
 const stateOptions = [
-  {value: '1', label: '启用'},
-  {value: '0', label: '禁用'},
+  {value: '1', label: ''},
+  {value: '0', label: ''},
 ];
 
 type Props = {

+ 3 - 1
packages/app/src/routes/name.ts

@@ -29,5 +29,7 @@ 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';
+/** 原料出库流水 */
+export const RAW_OUT_STREAM_PATH = '/stream/rawout';

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

@@ -12,6 +12,7 @@ import {
   NO_PERMISSION_PATH,
   PDA_MENU_PATH,
   RAW_IN_STREAM_PATH,
+  RAW_OUT_STREAM_PATH,
   RECEIVE_PATH,
   RECEIVE_TIMEOUT_PATH,
   ROLE_PATH,
@@ -51,6 +52,10 @@ const RawInStream = lazy(() => import(
   /* webpackChunkName: "rawInStream" */
   '@pages/raw-in-stream'
 ));
+const RawOutStream = lazy(() => import(
+  /* webpackChunkName: "rawOutStream" */
+  '@pages/raw-out-stream'
+));
 
 const routes: RouteObject[] = [
   {
@@ -70,6 +75,7 @@ const routes: RouteObject[] = [
       {path: RECEIVE_PATH, element: <Receive />},
       {path: RECEIVE_TIMEOUT_PATH, element: <ReceiveTimeout />},
       {path: RAW_IN_STREAM_PATH, element: <RawInStream />},
+      {path: RAW_OUT_STREAM_PATH, element: <RawOutStream />},
     ],
   },
   {path: LOGIN_PATH, element: <Login />},