Jelajahi Sumber

feat: 上传发货单ui

xyh 2 tahun lalu
induk
melakukan
65c09ced8a

+ 1 - 1
config/index.js

@@ -22,7 +22,7 @@ const config = {
   framework: 'react',
   compiler: 'webpack5',
   cache: {
-    enable: true, // Webpack 持久化缓存配置,建议开启。默认配置请参考:https://docs.taro.zone/docs/config-detail#cache
+    enable: false, // Webpack 持久化缓存配置,建议开启。默认配置请参考:https://docs.taro.zone/docs/config-detail#cache
   },
   alias: {
     '@styles': resolve(__dirname, '..', 'src/styles'),

+ 3 - 0
package.json

@@ -106,6 +106,8 @@
     "@tarojs/taro": "3.6.5",
     "ahooks": "^3.7.6",
     "classnames": "^2.3.2",
+    "dayjs": "^1.11.7",
+    "lodash-es": "^4.17.21",
     "react": "^18.2.0",
     "react-dom": "^18.2.0",
     "react-error-boundary": "^4.0.3",
@@ -142,6 +144,7 @@
     "husky": "^8.0.3",
     "lint-staged": "^13.2.1",
     "postcss": "^8.4.22",
+    "postcss-loader": "^7.2.4",
     "postcss-nesting": "^11.2.2",
     "prettier": "^2.8.7",
     "style-loader": "1.3.0",

+ 9 - 0
pnpm-lock.yaml

@@ -61,6 +61,12 @@ dependencies:
   classnames:
     specifier: ^2.3.2
     version: 2.3.2
+  dayjs:
+    specifier: ^1.11.7
+    version: 1.11.7
+  lodash-es:
+    specifier: ^4.17.21
+    version: 4.17.21
   react:
     specifier: ^18.2.0
     version: 18.2.0
@@ -165,6 +171,9 @@ devDependencies:
   postcss:
     specifier: ^8.4.22
     version: 8.4.22
+  postcss-loader:
+    specifier: ^7.2.4
+    version: 7.2.4(@types/node@18.15.11)(postcss@8.4.22)(ts-node@10.9.1)(typescript@5.0.4)(webpack@5.79.0)
   postcss-nesting:
     specifier: ^11.2.2
     version: 11.2.2(postcss@8.4.22)

+ 1 - 1
src/app.config.js

@@ -1,5 +1,5 @@
 export default defineAppConfig({
-  pages: ['pages/index/index'],
+  pages: ['pages/index/index', 'pages/deliver/index'],
   window: {
     backgroundTextStyle: 'light',
     navigationBarBackgroundColor: '#fff',

File diff ditekan karena terlalu besar
+ 1 - 0
src/assets/goods/complate.svg


File diff ditekan karena terlalu besar
+ 1 - 0
src/assets/goods/sending.svg


+ 1 - 0
src/components/index.js

@@ -0,0 +1 @@
+export {default as TextGroup} from './text-group';

+ 10 - 0
src/components/text-group/index.jsx

@@ -0,0 +1,10 @@
+import {Text, View} from '@tarojs/components';
+
+export default function Item({title, content}) {
+  return (
+    <View className='text-sm flex py-2'>
+      <Text className='w-20 text-gray-500'>{title}:</Text>
+      <Text className='flex-1 text-[#333] font-bold break-all'>{content}</Text>
+    </View>
+  );
+}

+ 40 - 0
src/pages/deliver/hooks.ts

@@ -0,0 +1,40 @@
+import {scanCode} from '@tarojs/taro';
+import {resolving} from '@utils';
+import dayjs from 'dayjs';
+import {useEffect, useState} from 'react';
+
+export function useGoodsInfo() {
+  const [state, setState] = useState({
+    goodsList: [],
+    customerNo: '',
+    truckNo: '',
+  });
+
+  function onScan() {
+    scanCode({scanType: ['qrCode']}).then(function (res) {
+      if (res.result) {
+        setState(resolving(res.result));
+      }
+    });
+  }
+
+  const [date, setDate] = useState('');
+
+  useEffect(
+    function () {
+      if (state.customerNo) {
+        setDate(dayjs().format('YYYY-MM-DD'));
+      }
+    },
+    [state.customerNo],
+  );
+
+  function onDateChagne(e) {
+    setDate(e.detail.value);
+  }
+
+  return [
+    {...state, date},
+    {onScan, onDateChagne},
+  ];
+}

+ 3 - 0
src/pages/deliver/index.config.js

@@ -0,0 +1,3 @@
+export default definePageConfig({
+  navigationBarTitleText: '发货',
+});

+ 65 - 0
src/pages/deliver/index.jsx

@@ -0,0 +1,65 @@
+import {Image, Text, View, Picker} from '@tarojs/components';
+import icon from '@assets/goods/sending.svg';
+import {Button} from '@nutui/nutui-react-taro';
+import {TextGroup as Item} from '@components';
+import {useGoodsInfo} from './hooks';
+import dayjs from 'dayjs';
+
+export default function DeliverGoods() {
+  const [{goodsList, customerNo, truckNo, date}, {onScan, onDateChagne}] =
+    useGoodsInfo();
+
+  return (
+    <View className='h-screen overflow-auto bg-gray-100 flex flex-col'>
+      <View className='py-4 bg-white'>
+        <Image src={icon} mode='widthFix' className='w-14 mx-auto' />
+
+        <Text className='px-3 text-center mt-2 block text-lg font-semibold text-[#333]'>
+          上传发货单
+        </Text>
+      </View>
+
+      <View className='mt-px bg-white px-4 py-2'>
+        <Item title='卡车号' content={truckNo} />
+        <Item title='客户号' content={customerNo} />
+        <Picker
+          mode='date'
+          value={date}
+          onChange={onDateChagne}
+          start={dayjs().format('YYYY-MM-DD')}
+        >
+          <Item title='到货时间' content={date} />
+        </Picker>
+      </View>
+
+      {goodsList.length > 0 ? (
+        <View className='mt-px bg-white p-4 mb-10'>
+          <Text className='text-lg font-semibold'>货品信息</Text>
+
+          <View className='mt-3'>
+            {goodsList.map(function ({no, num}) {
+              return (
+                <View
+                  key={no}
+                  className='border-0 border-b border-dashed border-gray-100 last:border-none'
+                >
+                  <Item title='品号' content={no} />
+                  <Item title='数量' content={Number(num)} />
+                </View>
+              );
+            })}
+          </View>
+        </View>
+      ) : null}
+
+      <View className='flex mt-auto justify-around pb-12'>
+        <Button className='w-36' onClick={onScan}>
+          扫码
+        </Button>
+        <Button type='primary' className='w-36' color='#58C6EA'>
+          发货
+        </Button>
+      </View>
+    </View>
+  );
+}

+ 7 - 6
src/pages/index/index.jsx

@@ -1,4 +1,4 @@
-import {View, Image, Text} from '@tarojs/components';
+import {View, Image, Text, Navigator} from '@tarojs/components';
 import classNames from 'classnames';
 import sendIcon from '@assets/sending.svg';
 import complateIcon from '@assets/complate.svg';
@@ -6,16 +6,17 @@ import orderIcon from '@assets/order.svg';
 import face from '@assets/face.svg';
 import Login from './login';
 import {useBoolean} from 'ahooks';
+import {DELIVER_GOODS_PATH} from '@routes';
 
 const btnList = [
   {
     title: '收发货',
     children: [
-      {title: '发货', icon: sendIcon},
-      {title: '收货', icon: complateIcon},
+      {title: '发货', icon: sendIcon, url: DELIVER_GOODS_PATH},
+      {title: '收货', icon: complateIcon, url: ''},
     ],
   },
-  {title: '历史记录', children: [{title: '订单', icon: orderIcon}]},
+  {title: '历史记录', children: [{title: '订单', icon: orderIcon, url: ''}]},
 ];
 
 export default function App() {
@@ -57,7 +58,7 @@ export default function App() {
               <View className='mt-3 grid grid-cols-4 grid-rows-1 gap-4'>
                 {el.children.map(function (item) {
                   return (
-                    <View key={item.title}>
+                    <Navigator url={item.url} key={item.title}>
                       <Image
                         src={item.icon}
                         className='w-8 h-8 mx-auto'
@@ -66,7 +67,7 @@ export default function App() {
                       <Text className='block text-center text-sm mt-2 text-[#666]'>
                         {item.title}
                       </Text>
-                    </View>
+                    </Navigator>
                   );
                 })}
               </View>

+ 1 - 0
src/routes/index.js

@@ -0,0 +1 @@
+export * from './name';

+ 2 - 0
src/routes/name.js

@@ -0,0 +1,2 @@
+/** 发货页面 */
+export const DELIVER_GOODS_PATH = '/pages/deliver/index';

+ 1 - 0
src/utils/index.js

@@ -0,0 +1 @@
+export * from './resolving';

+ 36 - 0
src/utils/resolving/index.js

@@ -0,0 +1,36 @@
+/**
+ * 识别二维码中的货品信息
+ * @param {string} code 二维码识别内容
+ */
+export function resolving(code) {
+  /**
+   * code -- 04170064500140000
+   * 11SW042400-15121M0001860SW042400-15821M0000840SW042400-18211M0001920SW042400-19021M0000080SW447140-12421M0000257
+   *
+   * 0417006 卡车号
+   * 4500140000 客户号
+   *
+   * 11 忽略不需要
+   *
+   * SW042400-15121M0001860
+   *
+   * SW042400-15121M 品号
+   * 0001860 数量
+   */
+
+  const [first, last] = code.split(' ');
+  const truckNo = first.slice(0, 7);
+  const customerNo = first.slice(7);
+
+  // 排除掉一开始的两位数
+  const goodsStr = last.slice(2);
+  const goodsList = goodsStr.match(/(.{22})/g).map(function (el) {
+    // 前15位是品号 后7位是数量
+    const no = el.slice(0, 15),
+      num = el.slice(15);
+
+    return {no, num};
+  });
+
+  return {truckNo, customerNo, goodsList};
+}