Yansen 2 年前
父节点
当前提交
c858c69ba4

+ 3
- 1
.eslintrc 查看文件

@@ -2,6 +2,8 @@
2 2
   "extends": ["taro/react"],
3 3
   "rules": {
4 4
     "react/jsx-uses-react": "off",
5
-    "react/react-in-jsx-scope": "off"
5
+    "react/react-in-jsx-scope": "off",
6
+    "jsx-quotes": "off",
7
+    "no-unused-vars": "warn"
6 8
   }
7 9
 }

+ 1
- 1
project.config.json 查看文件

@@ -2,7 +2,7 @@
2 2
   "miniprogramRoot": "./dist",
3 3
   "projectname": "myApp",
4 4
   "description": "xiaofang",
5
-  "appid": "touristappid",
5
+  "appid": "wx1a0fa56e6d0b78b3",
6 6
   "setting": {
7 7
     "urlCheck": true,
8 8
     "es6": false,

+ 2
- 1
src/app.config.js 查看文件

@@ -5,9 +5,10 @@ export default {
5 5
   ],
6 6
   window: {
7 7
     backgroundTextStyle: 'light',
8
+    backgroundColor: '#F7F8FA',
8 9
     navigationBarBackgroundColor: '#fff',
9 10
     navigationBarTitleText: 'WeChat',
10
-    navigationBarTextStyle: 'black'
11
+    navigationBarTextStyle: 'black'    
11 12
   },
12 13
   tabBar: {
13 14
     list: [{

+ 9
- 0
src/app.less 查看文件

@@ -0,0 +1,9 @@
1
+page {
2
+  width: 100%;
3
+  height: 100%;
4
+  background-color: #F7F8FA;
5
+}
6
+
7
+form {
8
+  display: block;
9
+}

+ 31
- 0
src/components/Uploader.jsx 查看文件

@@ -0,0 +1,31 @@
1
+import React from 'react';
2
+import { Uploader } from '@antmjs/vantui';
3
+import upload from '@/services/upload';
4
+
5
+export default (props) => {
6
+
7
+  const { value, onChange } = props;
8
+
9
+  const fileList = React.useMemo(() => {
10
+    return value ? [{ url: value }] : []
11
+  }, [value]);
12
+  
13
+  const onAfterRead = (e) => {
14
+    const { file } = e.detail;
15
+    upload(file.url).then(v => onChange({ detail: v }));
16
+  }
17
+
18
+  const onDelete = () => {
19
+    onChange({ detail: undefined });
20
+  }
21
+
22
+  return (
23
+    <Uploader
24
+      multiple={false}
25
+      accept="image"
26
+      fileList={fileList}
27
+      onAfterRead={onAfterRead}
28
+      onDelete={onDelete}
29
+    />
30
+  )
31
+}

+ 103
- 4
src/pages/index/index.jsx 查看文件

@@ -1,13 +1,112 @@
1
-import { Component } from 'react'
2
-import { View } from '@tarojs/components'
3
-import { Button } from '@antmjs/vantui'
1
+import React from 'react';
2
+import Taro from '@tarojs/taro';
3
+import { View } from '@tarojs/components';
4
+import Uploader from '@/components/Uploader';
5
+import { Button, Form, FormItem, Radio, RadioGroup, Icon, Field } from '@antmjs/vantui';
6
+import { saveBind } from '@/services/bind';
7
+import useRequest from '@/utils/useRequest';
4 8
 import './index.less'
5 9
 
6 10
 export default (props) => {
11
+  const form = Form.useForm();
12
+
13
+  const [loading, request] = useRequest(saveBind);
14
+
15
+  const onScan = () => {
16
+    Taro.scanCode({
17
+      success: ({ result }) => {
18
+        form.setFieldsValue('deviceNo', result);
19
+      },
20
+      fail: (err) => {
21
+        console.error(err);
22
+      }
23
+    })
24
+  }
25
+
26
+  const onFinish = (errs, values) => {
27
+    console.log(errs, values);
28
+    if (!errs) {
29
+      request(values).then(res => {
30
+        Taro.switchTab({
31
+          url: '/pages/mine/index',
32
+        });
33
+      });
34
+    }
35
+  }
7 36
 
8 37
   return (
9 38
     <View>
10
-      <Button type="warning">123</Button>
39
+      <Form className="bind-form" form={form} onFinish={onFinish}>
40
+        <FormItem
41
+          required
42
+          label="设备类型"
43
+          name="deviceType"
44
+          validateTrigger="onBlur"
45
+        >
46
+          <RadioGroup direction="horizontal">
47
+            <Radio name="shensong" checkedColor="#07c160">深松</Radio>
48
+            <Radio name="feifang" checkedColor="#07c160">飞防</Radio>
49
+          </RadioGroup>
50
+        </FormItem>
51
+        <FormItem
52
+          required
53
+          label="设备编号"
54
+          name="deviceNo"
55
+          validateTrigger="onBlur"
56
+          renderRight={<View className='scan-btn' onClick={onScan} ><Icon name="scan" size="18px" /></View>}
57
+        >
58
+          <Field placeholder="请输入" clearable />
59
+        </FormItem>
60
+        <FormItem
61
+          required
62
+          label="农机编号"
63
+          name="machineryName"
64
+          validateTrigger="onBlur"
65
+        >
66
+          <Field placeholder="请输入" clearable />
67
+        </FormItem>
68
+        <FormItem
69
+          required
70
+          label="农机图片"
71
+          name="machineryThumb"
72
+        >
73
+          <Uploader />
74
+        </FormItem>
75
+        <FormItem
76
+          required
77
+          label="归 属 人"
78
+          name="userName"
79
+          validateTrigger="onBlur"
80
+        >
81
+          <Field placeholder="请输入" clearable />
82
+        </FormItem>
83
+        <FormItem
84
+          required
85
+          label="手 机 号"
86
+          name="phone"
87
+          validateTrigger="onBlur"
88
+        >
89
+          <Field placeholder="请输入" clearable />
90
+        </FormItem>
91
+        <FormItem
92
+          required
93
+          label="身 份 证"
94
+          name="idCard"
95
+          validateTrigger="onBlur"
96
+        >
97
+          <Field placeholder="请输入" clearable />
98
+        </FormItem>
99
+        <View className="submit-wrapper">
100
+          <Button
101
+            block
102
+            type="primary"
103
+            formType="submit"
104
+            loading={loading}
105
+          >
106
+            提交
107
+          </Button>
108
+        </View>
109
+      </Form>
11 110
     </View>
12 111
   )
13 112
 }

+ 30
- 0
src/pages/index/index.less 查看文件

@@ -0,0 +1,30 @@
1
+
2
+.bind-form {
3
+  background: #fff;
4
+  border-radius: 16px;
5
+  margin: 0 1em;
6
+  width: calc(100% - 2em);
7
+  overflow: hidden;
8
+
9
+  .scan-btn {
10
+    padding: 0 24px;
11
+  }
12
+
13
+  .submit-wrapper {
14
+    padding: 48px;
15
+  }
16
+  
17
+  .vant-form-formItem {
18
+    border-bottom: 1px solid rgb(235, 237, 240);
19
+  }
20
+
21
+  .van-field {
22
+    padding: 0;
23
+  }
24
+
25
+  .van-cell {
26
+    &::after {
27
+      border: 0;
28
+    }
29
+  }
30
+}

+ 3
- 0
src/services/bind.js 查看文件

@@ -0,0 +1,3 @@
1
+import request from "@/utils/request";
2
+
3
+export const saveBind = data => request('/tcBind', { method: 'post', data })

+ 5
- 0
src/services/upload.js 查看文件

@@ -0,0 +1,5 @@
1
+import { upload } from "@/utils/request";
2
+
3
+export default (filePath) => {
4
+  return upload('/image', filePath);
5
+}

+ 45
- 4
src/utils/request.js 查看文件

@@ -19,14 +19,46 @@ import Taro from '@tarojs/taro'
19 19
   return arr.filter(Boolean).join('&')
20 20
 }
21 21
 
22
+export function upload(url, tempFilePath) {
23
+  return new Promise((resolve, reject) => {
24
+    Taro.uploadFile({
25
+      // eslint-disable-next-line no-undef
26
+      url: `${HOST}/api/${url}`.replace('api//', 'api/'),
27
+      filePath: tempFilePath,
28
+      name: 'file',
29
+      success: (res) => {
30
+        const { data, code, message } = JSON.parse(res.data);
31
+        if (code === 1000) {
32
+          resolve(data);
33
+        } else {
34
+          reject(message);
35
+          Taro.showToast({
36
+            title: message,
37
+            icon: 'none',
38
+          })
39
+        }
40
+      },
41
+      fail: (err) => {
42
+        console.error(err);
43
+        const errMsg = err.message || err.msg || err.errMsg || err;
44
+        reject(errMsg);
45
+        Taro.showToast({
46
+          title: errMsg,
47
+          icon: 'none',
48
+        })
49
+      }
50
+    });
51
+  });
52
+}
53
+
22 54
 
23 55
 export default (url, options) => {
24
-  const { params, skipError, header, ...leftOptions } = options || {}
56
+  const { params, skipError, header, method = 'GET', ...leftOptions } = options || {}
25 57
   const queryStr = getQueryString(params)
26 58
 
27 59
   const urlWithParams = queryStr ? `${url}?${queryStr}` : url;
28 60
   // eslint-disable-next-line no-undef
29
-  const nwUrl = `${HOST}/api/${urlWithParams}`
61
+  const nwUrl = `${HOST}/api/${urlWithParams}`.replace('api//', 'api/');
30 62
 
31 63
   const authToken = Taro.getStorageSync('token')
32 64
   const tokenHeader = authToken ? { Authorization: authToken } : {}
@@ -39,6 +71,7 @@ export default (url, options) => {
39 71
     Taro.request({
40 72
       ...leftOptions,
41 73
       url: nwUrl,
74
+      method,
42 75
       header: nwHeader,
43 76
       success: (res) => {
44 77
         const { code, message, data, token } = res.data
@@ -48,7 +81,15 @@ export default (url, options) => {
48 81
         }
49 82
 
50 83
         if (code === 1000) {
51
-          resolve(data)
84
+          resolve(data);
85
+
86
+          if (['post', 'put', 'delete'].indexOf(method.toLocaleLowerCase()) > -1) {
87
+            Taro.showToast({
88
+              title: '操作成功',
89
+              icon: 'success',
90
+              duration: 2000
91
+            });            
92
+          }
52 93
 
53 94
         } else {
54 95
           if (!skipError) {
@@ -64,7 +105,7 @@ export default (url, options) => {
64 105
       fail: (err) => {
65 106
         console.error(err)
66 107
 
67
-        const message = err.message || err.errMsg || err
108
+        const message = err.message || err.errMsg || err || '服务不存在或异常'
68 109
 
69 110
         if (!skipError) {
70 111
           Taro.showToast({

+ 7
- 0
src/utils/useForceUpdate.js 查看文件

@@ -0,0 +1,7 @@
1
+import React from "react";
2
+
3
+export function useForceUpdate() {
4
+  const [, forceUpdate] = React.useReducer(x => x + 1, 0);
5
+
6
+  return forceUpdate;
7
+}

+ 20
- 0
src/utils/useRequest.js 查看文件

@@ -0,0 +1,20 @@
1
+import React from "react";
2
+
3
+export default function useRequest(api) {
4
+  const [loading, setLoading] = React.useState(false);
5
+
6
+  const request = React.useCallback((...args) => {
7
+    return new Promise((resovle, reject) => {
8
+      setLoading(true);
9
+      api(...args).then(res => {
10
+        setLoading(false);
11
+        resovle(res);
12
+      }).catch(er => {
13
+        reject(er);
14
+        setLoading(false);
15
+      })
16
+    });
17
+  }, [api]);
18
+
19
+  return [loading, request];
20
+}