Yansen 2 년 전
부모
커밋
f1fe867674

+ 0
- 1
src/app.config.js 파일 보기

@@ -21,7 +21,6 @@ export default defineAppConfig({
21 21
     'pages/reset-password/index',
22 22
     'pages/check/list/index',
23 23
     'pages/check/loc/list/index',
24
-    'pages/check/loc/edit/index',
25 24
     'pages/check/edit/index',
26 25
   ],
27 26
   window: {

+ 0
- 26
src/pages/check/edit/components/Choice.jsx 파일 보기

@@ -1,26 +0,0 @@
1
-import React from 'react';
2
-import { View } from '@tarojs/components';
3
-import { Radio, RadioGroup, Row, Col, CellGroup, Cell } from '@antmjs/vantui'
4
-import style from './choice.module.less';
5
-
6
-export default (props) => {
7
-  const { value } = props;
8
-  return (
9
-    <CellGroup className={style['cell']}>
10
-      <Cell title="测评内容" border={false} size="large" />
11
-      <Cell className={style['text']} title="在显著位置看到市民公约或居民公约展示" border={false} />
12
-      <Row>
13
-        <Col offset="3" span="12">
14
-          <RadioGroup value={value}>
15
-            <Cell border={false}>
16
-              <Radio checkedColor="var(--main-bg-color)">A.符合</Radio>
17
-            </Cell>
18
-            <Cell border={false} className={style['radio']}>
19
-              <Radio checkedColor="var(--main-bg-color)">B.不符合</Radio>
20
-            </Cell>
21
-          </RadioGroup>
22
-        </Col>
23
-      </Row>
24
-    </CellGroup>
25
-  )
26
-}

+ 65
- 0
src/pages/check/edit/components/Footer/index.jsx 파일 보기

@@ -0,0 +1,65 @@
1
+import React from 'react';
2
+import Taro from '@tarojs/taro';
3
+import { View } from '@tarojs/components';
4
+import { Button } from '@antmjs/vantui';
5
+import QuSelect from '../QuSelect';
6
+import style from './style.module.less';
7
+
8
+export default (props) => {
9
+  const { value, list, readonly, onChange, onSubmit } = props;
10
+
11
+  const [isPrev, isFinished] = React.useMemo(() => {
12
+    const total = list?.length || 0;
13
+
14
+    return [
15
+      value > 0,
16
+      value >= total - 1,
17
+    ]
18
+  }, [value, list]);
19
+
20
+  const onPrev = () => {
21
+    onChange(value - 1);
22
+  }
23
+
24
+  const onNext = () => {
25
+    if (isFinished) {
26
+      onSubmit()
27
+    } else {
28
+      onChange(value + 1);
29
+    }
30
+  }
31
+  
32
+  return (
33
+    <View className={style['qu-footer-wrapper']}>
34
+      {
35
+        !readonly && value > -1 && (
36
+          <View className={style['qu-footer-sel']}>
37
+            <QuSelect
38
+              value={value}
39
+              list={list}
40
+              onChange={onChange}
41
+            />
42
+          </View>
43
+        )
44
+      }
45
+      <View className={style['qu-footer-act']}>
46
+        {
47
+          isPrev && <Button type="primary" block plain hairline style={{flex: 1}} onClick={onPrev}>上一题</Button>
48
+        }
49
+        {
50
+          value == -1 ? (
51
+            <Button type="primary" block style={{flex: 1, marginLeft: isPrev ? '1em' : 0 }} onClick={onNext}>
52
+              {readonly ? '查看测评' : '开始测评'}
53
+            </Button>
54
+          ) : (
55
+            !(readonly && isFinished) && (
56
+              <Button type="primary" block style={{flex: 1, marginLeft: isPrev ? '1em' : 0 }} onClick={onNext}>
57
+                {isFinished ? '提交' : '下一题'}
58
+              </Button>
59
+              )
60
+          )
61
+        }
62
+      </View>
63
+    </View>
64
+  )
65
+}

+ 21
- 0
src/pages/check/edit/components/Footer/style.module.less 파일 보기

@@ -0,0 +1,21 @@
1
+
2
+.qu-footer-wrapper {
3
+  width: 100%;
4
+  overflow: hidden;
5
+  padding: var(--main-space) 0;
6
+  background: #fff;
7
+  display: flex;
8
+  align-items: center;
9
+
10
+  .qu-footer-sel {
11
+    flex: none;
12
+    margin-right: 2em;
13
+  }
14
+
15
+  .qu-footer-act {
16
+    flex: 1;
17
+    display: flex;
18
+    overflow: hidden;
19
+    padding: 0 var(--main-space);
20
+  }
21
+}

+ 61
- 0
src/pages/check/edit/components/LocForm.jsx 파일 보기

@@ -0,0 +1,61 @@
1
+import React from 'react';
2
+import Taro from '@tarojs/taro';
3
+import { View } from '@tarojs/components';
4
+import { CellGroup, Cell, Field } from '@antmjs/vantui';
5
+import Map from '@/components/map';
6
+import { getTaCheckItemAnswer } from '@/services/tacheckitem';
7
+import mapIcon from '@/assets/icons/marker.png';
8
+
9
+export default (props) => {
10
+  const { checkItemInfo, checkType, answer, readonly, onChange, onLoadingChange } = props;
11
+
12
+  const [loc, setLoc] = React.useState();
13
+
14
+  const setLoading = (v) => {
15
+    if (onLoadingChange) {
16
+      onLoadingChange(v)
17
+    }
18
+  }
19
+  
20
+  const setFieldChange = (key, val) => {
21
+    onChange({
22
+      location: loc,
23
+      ...answer || {},
24
+      [key]: val,
25
+    })
26
+  }
27
+
28
+  // 获取答题主记录信息
29
+  React.useEffect(() => {
30
+    if (checkItemInfo?.itemId) {
31
+      setLoading(true);
32
+      getTaCheckItemAnswer(checkItemInfo?.itemId).then((res) => {
33
+        if (res) {
34
+          onChange(res);
35
+        }
36
+        setLoading(false);
37
+      }).catch(() => {
38
+        setLoading(false);
39
+      });
40
+    }
41
+  }, [checkItemInfo?.itemId])
42
+  
43
+  return (
44
+    <View>
45
+      <Map location={answer?.location} onLocChange={setLoc} />
46
+      <CellGroup>
47
+        <Cell
48
+          title="点位"
49
+          value={checkItemInfo?.name}
50
+        />
51
+        <Field
52
+          readonly={readonly}
53
+          placeholder={checkType == 'loc' ? '请输入地址' : '请填写小区名称'}
54
+          value={answer?.addr}
55
+          leftIcon={mapIcon}
56
+          onChange={e => setFieldChange('addr', e.detail)}
57
+        />
58
+      </CellGroup>
59
+    </View>
60
+  )
61
+}

+ 68
- 0
src/pages/check/edit/components/QuSelect/index.jsx 파일 보기

@@ -0,0 +1,68 @@
1
+import React from 'react';
2
+import Taro from '@tarojs/taro';
3
+import { View, Text } from '@tarojs/components';
4
+import { Popup, Cell, Icon } from '@antmjs/vantui';
5
+import RatioView from '@/components/RatioView';
6
+import style from './style.module.less';
7
+
8
+const Bar = (props) => {
9
+  const {cursor, total, onClick} =  props;
10
+
11
+  const handleClick = (e) => {
12
+    if (onClick) {
13
+      onClick(e);
14
+    }
15
+  }
16
+
17
+  return (
18
+    <View className={style['qu-board-title']} onClick={handleClick}>
19
+      <Icon name="weapp-nav" size={60} color="var(--main-bg-color)" />
20
+      <Text>{cursor + 1}</Text>
21
+      <Text> / </Text>
22
+      <Text>{total}</Text>
23
+    </View>
24
+  )
25
+}
26
+
27
+
28
+export default (props) => {
29
+  const { value = 0, list, onChange } = props;
30
+
31
+  const [show, setShow] = React.useState(false);
32
+
33
+  const handleClick = (e, inx) => {
34
+    e.stopPropagation();
35
+    setShow(false);
36
+
37
+    if (onChange) {
38
+      onChange(inx);
39
+    }
40
+  }
41
+  
42
+  return (
43
+    <View className={style['qu-board-bar']}>
44
+      <Bar cursor={value} total={list?.length} onClick={() => setShow(true)} />
45
+      <Popup position="bottom" show={show} onClose={() => setShow(false)}>
46
+        <View className={style['qu-board-wrapper']}>
47
+          <Bar cursor={value} total={list?.length} />
48
+          <View className={style['qu-board-bd']}>
49
+            {
50
+              list?.map((it, inx) => {
51
+                const cls = [
52
+                  style['qu-board-bd-item'],
53
+                  it?.finished ? style['qu-board-bd-active'] : false,
54
+                ].filter(Boolean).join(' ')
55
+
56
+                return (
57
+                  <RatioView key={inx}>
58
+                    <View className={cls} onClick={e => handleClick(e, inx)}>{inx + 1}</View>
59
+                  </RatioView>
60
+                )
61
+              })
62
+            }
63
+          </View>
64
+        </View>
65
+      </Popup>
66
+    </View>
67
+  )
68
+}

+ 50
- 0
src/pages/check/edit/components/QuSelect/style.module.less 파일 보기

@@ -0,0 +1,50 @@
1
+.qu-board-bar {
2
+  display: inline-block;
3
+}
4
+
5
+.qu-board-title {
6
+  font-size: 28px;
7
+  color: #999;
8
+  font-weight: bold;
9
+  display: flex;
10
+  align-items: center;
11
+  padding: 0 var(--main-space);
12
+
13
+  & > text {
14
+    line-height: 3em;
15
+    &:first-of-type {
16
+      margin-left: 0.6em;
17
+    }
18
+  }
19
+}
20
+
21
+.qu-board-wrapper {
22
+  background: #fff;
23
+
24
+  .qu-board-bd {
25
+    padding: var(--main-space) calc(var(--main-space) * 2);
26
+    display: grid;
27
+    grid-template-columns: repeat(5, 1fr);
28
+    row-gap: 36px;
29
+    column-gap: 36px;
30
+
31
+    .qu-board-bd-item {
32
+      width: 100%;
33
+      height: 100%;
34
+      border-radius: 50%;
35
+      overflow: hidden;
36
+      display: grid;
37
+      place-items: center;
38
+      font-size: 30px;
39
+      color: #666;
40
+      font-weight: bold;
41
+      border: 2px solid var(--main-bg-color);
42
+
43
+      &.qu-board-bd-active {
44
+        color: #fff;
45
+        border: 2px solid transparent;
46
+        background-color: var(--main-bg-color);
47
+      }
48
+    }
49
+  }
50
+}

+ 107
- 0
src/pages/check/edit/components/Question.jsx 파일 보기

@@ -0,0 +1,107 @@
1
+import React from 'react';
2
+import Taro from '@tarojs/taro';
3
+import { View, RichText, Text } from '@tarojs/components';
4
+import { CellGroup, Cell, Field, Radio, RadioGroup, Button } from '@antmjs/vantui';
5
+import Uploader from '@/components/Uploader/index';
6
+import { getTaCheckAnswerItem } from '@/services/tacheckansweritem';
7
+
8
+
9
+export default (props) => {
10
+  const { quInfo, answerItem, readonly, onChange, onLoadingChange } = props;
11
+
12
+  const setLoading = (v) => {
13
+    if (onLoadingChange) {
14
+      onLoadingChange(v);
15
+    }
16
+  }
17
+
18
+  const setFieldChange = (key, val) => {
19
+    if (readonly) return;
20
+
21
+    onChange({
22
+      ...(answerItem || {}),
23
+      quId: quInfo.quId,
24
+      [key]: val,
25
+    })
26
+  }
27
+
28
+  React.useEffect(() => {
29
+    if (quInfo?.quId) {
30
+      setLoading(true);
31
+      getTaCheckAnswerItem({ quId: quInfo.quId, isMine: true }).then(res => {
32
+        if (res && res[0]) {
33
+          onChange(res[0]);
34
+        }
35
+        setLoading(false);
36
+      }).catch(() => {
37
+        setLoading(false);
38
+      });
39
+    }
40
+  }, [quInfo?.quId]);
41
+  
42
+  return (
43
+    <View>
44
+      <RadioGroup value={answerItem?.answerCode}>
45
+        <CellGroup>
46
+          <Cell
47
+            border={false}
48
+            renderTitle={(
49
+              <View style={{fontWeight: 'bold'}}>
50
+                <Text>{quInfo?.sortNo}、</Text>
51
+                <Text>{quInfo?.title}</Text>
52
+              </View>
53
+            )}
54
+          />
55
+          {
56
+            quInfo?.quType == 'fill' && (
57
+              <Field
58
+                label="答案:"
59
+                clearable
60
+                readonly={readonly}
61
+                value={answerItem?.answer}
62
+                placeholder="填写数字"
63
+                renderButton={quInfo?.fillUnit}
64
+                onChange={(e) => setFieldChange('answer', e.detail - 0)}
65
+              />
66
+            )
67
+          }
68
+          {
69
+            (quInfo?.answerList || []).map((it) => {              
70
+              return (
71
+                <Cell
72
+                  key={it.answerId}
73
+                  title={it.answer}
74
+                  clickable
75
+                  border={false}
76
+                  onClick={() => setFieldChange('answerCode', it.answerCode)}
77
+                  renderRightIcon={<Radio checkedColor="var(--main-bg-color)" readonly={readonly} name={it.answerCode}></Radio>}
78
+                />
79
+              );
80
+            })
81
+          }
82
+        </CellGroup>
83
+      </RadioGroup>
84
+      <CellGroup style={{marginTop: '20px'}}>
85
+        <Cell title="测评标准" />
86
+        <Cell
87
+          renderTitle={
88
+            <RichText nodes={quInfo?.stand} />
89
+          }
90
+        />
91
+      </CellGroup>
92
+      <CellGroup style={{marginTop: '20px'}}>        
93
+        <Cell title="拍照或视频" border={false} />
94
+
95
+        <Cell
96
+          renderTitle={
97
+            <Uploader
98
+              disabled={readonly}
99
+              value={answerItem?.attachList}
100
+              onChange={e => setFieldChange('attachList',e)}
101
+            />
102
+          }
103
+        />
104
+      </CellGroup>
105
+    </View>
106
+  )
107
+}

+ 0
- 13
src/pages/check/edit/components/choice.module.less 파일 보기

@@ -1,13 +0,0 @@
1
-.cell {
2
-  margin-bottom: 40px;
3
-  .text {
4
-    text-align: center;
5
-    color: var(--main-bg-color);
6
-    padding-top: 0px;
7
-    padding-bottom: 0px;
8
-  }
9
-  .radio {
10
-    padding-top: 0px;
11
-    margin-bottom: 40px;
12
-  }
13
-}

+ 3
- 3
src/pages/check/edit/index.config.js 파일 보기

@@ -1,4 +1,4 @@
1
-// eslint-disable-next-line no-undef
2
-export default definePageConfig({
3
-  navigationBarTitleText: '实地测评'
1
+// eslint-disable-next-line no-undef
2
+export default definePageConfig({
3
+  navigationBarTitleText: '实地测评'
4 4
 })

+ 250
- 252
src/pages/check/edit/index.jsx 파일 보기

@@ -1,252 +1,250 @@
1
-import React from 'react';
2
-import Map from '@/components/map';
3
-import Page from '@/layouts/index';
4
-import { Button, Field, Cell, CellGroup, Row, Col, Image } from '@antmjs/vantui';
5
-import mapIcon from '@/assets/icons/marker.png';
6
-import LocType from '@/components/LocType';
7
-import { View, Input } from '@tarojs/components';
8
-import Uploader from '@/components/Uploader/index';
9
-import ScrollPage from '@/components/ScrollPage/index';
10
-import icon from '@/assets/icons/box.png';
11
-import Choice from "./components/Choice";
12
-
13
-export default (props) => {
14
-  const {
15
-    issue,
16
-    readOnly,
17
-    showOrg,
18
-    showExpireDate,
19
-    renderFields,
20
-    renderAction,
21
-  } = props;
22
-
23
-  const [inx, setInx] = React.useState(-1);
24
-
25
-  const num = 1;
26
-  const count = 15;
27
-
28
-  const [formData, setFormData] = React.useState({
29
-    typeId: undefined,
30
-    typeName: undefined,
31
-    locId: undefined,
32
-    locName: undefined,
33
-    location: undefined,
34
-    addr: undefined,
35
-    content: undefined,
36
-    attachList: [],
37
-  });
38
-
39
-  const [showLocType, setShowLocType] = React.useState(false);
40
-  const [evaluationPage, setEvaluationPage] = React.useState(true);
41
-  const [evaluationPage2, setEvaluationPage2] = React.useState(false);
42
-  const [evaluationPage3, setEvaluationPage3] = React.useState(false);
43
-  const [scrollPage, setScrollPage] = React.useState(false);
44
-
45
-  const onLocTypeChange = (_, it) => {
46
-    setFormData({
47
-      ...formData,
48
-      locId: it.typeId,
49
-      locName: it.name,
50
-    });
51
-    setShowLocType(false);
52
-  }
53
-
54
-  const setFieldChange = (field, value) => {
55
-    setFormData({
56
-      ...formData,
57
-      [field]: value,
58
-    })
59
-  }
60
-
61
-  const onChangePage = () => {
62
-    setEvaluationPage(false);
63
-    setEvaluationPage2(true);
64
-  }
65
-
66
-  const onChangePage2 = () => {
67
-    setEvaluationPage2(false);
68
-    setEvaluationPage3(true);
69
-  }
70
-
71
-  const onChangePage3 = () => {
72
-    setEvaluationPage3(false);
73
-    setScrollPage(true);
74
-  }
75
-
76
-  return (
77
-    <>
78
-      <Page>
79
-        {
80
-          evaluationPage && (<>
81
-            <LocType
82
-              show={showLocType}
83
-              value={formData.addr}
84
-              onCancel={() => setShowLocType(false)}
85
-              onChange={onLocTypeChange}
86
-            />
87
-            <Map location={formData.location} />
88
-            <CellGroup>
89
-              <Cell
90
-                title="点位"
91
-                isLink
92
-                value={formData.locName}
93
-                onClick={() => !readOnly && setShowLocType(true)}
94
-              />
95
-              <Field
96
-                placeholder="请输入地址"
97
-                value={formData.addr}
98
-                leftIcon={mapIcon}
99
-              // readonly={readOnly}
100
-              // onChange={e => setFieldChange('addr', e.detail)}
101
-              />
102
-            </CellGroup>
103
-
104
-            <CellGroup style={{ padding: 'var(--main-space)', position: 'relative', top: '330px' }}>
105
-              <Button
106
-                type="primary"
107
-                block
108
-                onClick={onChangePage}
109
-              >
110
-                下一步
111
-              </Button>
112
-            </CellGroup>
113
-          </>)
114
-        }
115
-
116
-        {
117
-          evaluationPage2 && (
118
-            <View style={{ flex: '1' }}>
119
-
120
-              <Choice />
121
-
122
-              <CellGroup>
123
-                <Cell title="评测标准" border={false} size="large" />
124
-                <Row>
125
-                  <Col offset="2" span="20">
126
-                    <Cell
127
-                      title="
128
-                  在显著位置看到市民公约或居民公约展示"
129
-                      border={false}
130
-                      style={{ paddingTop: '0px' }}
131
-                    />
132
-                  </Col>
133
-                </Row>
134
-              </CellGroup>
135
-
136
-              <CellGroup style={{ marginTop: '20px' }}>
137
-                <Cell title="拍照" border={false} size="large" />
138
-
139
-                <Cell
140
-                  renderTitle={
141
-                    <Uploader
142
-                      value={formData.attachList}
143
-                      disabled={readOnly}
144
-                      onChange={e => setFieldChange('attachList', e)}
145
-                    />
146
-                  }
147
-                />
148
-              </CellGroup>
149
-
150
-              <View style={{ position: 'relative', marginBottom: '20px', flex: 'none' }}>
151
-                <View style={{ position: 'absolute', width: '100%', top: '100px' }}>
152
-                  <CellGroup style={{ marginTop: '20px', padding: 'var(--main-space)' }}>
153
-                    <Button
154
-                      type="primary"
155
-                      block
156
-                      onClick={onChangePage2}
157
-                    >
158
-                      下一题
159
-                    </Button>
160
-                  </CellGroup>
161
-
162
-                  <CellGroup>
163
-                    <Cell
164
-                      style={{ textAlign: 'right' }}
165
-                    >
166
-                      <Image src={icon} width="25px" height="25px"
167
-                        style={{ verticalAlign: 'middle', marginRight: '10px' }}
168
-                      />
169
-                      {num + '/' + count}
170
-                    </Cell>
171
-                  </CellGroup>
172
-                </View>
173
-              </View>
174
-            </View>)
175
-        }
176
-
177
-        {
178
-          evaluationPage3 && (
179
-            <ScrollPage>
180
-              <CellGroup>
181
-                <Cell title="测评内容" border={false} size="large" style={{ paddingBottom: '0px' }} />
182
-                <View style={{ padding: 'var(--main-space)', paddingTop: '0px' }}>
183
-                  <View style={{ padding: 'var(--main-space)', fontSize: '14px', color: 'var(--main-bg-color)' }}>
184
-                    垃圾乱扔,乱张贴(具体标准),测评结果:<Input type="text" style={{ width: '45px', display: 'inline-block', verticalAlign: 'middle' }} />处。(此处填写数字)
185
-                  </View>
186
-                </View>
187
-              </CellGroup>
188
-
189
-              <CellGroup>
190
-                <Cell title="评测标准" border={false} size="large" />
191
-                <Row>
192
-                  <Col offset="2" span="20">
193
-                    <Cell
194
-                      title="
195
-                    (1)每看到1处垃圾乱扔(1平方米以内的垃圾算作1处)计为1处;
196
-                    (2)每看到1处乱张贴乱涂写乱刻画《1平米内出现的算作1 处在统一设置的信息栏中张贴的小广告不算作失分点)计为1处;
197
-                    (3)每看到建筑物外立面的1处大面积破损污损《高3米以上、宽2米以上)计为1处。"
198
-                      border={false}
199
-                      style={{ paddingTop: '0px' }}
200
-                    />
201
-                  </Col>
202
-                </Row>
203
-              </CellGroup>
204
-
205
-              <CellGroup style={{ marginTop: '20px' }}>
206
-                <Cell title="拍照" border={false} size="large" />
207
-
208
-                <Cell
209
-                  renderTitle={
210
-                    <Uploader
211
-                      value={formData.attachList}
212
-                      disabled={readOnly}
213
-                      onChange={e => setFieldChange('attachList', e)}
214
-                    />
215
-                  }
216
-                />
217
-              </CellGroup>
218
-
219
-              <CellGroup style={{ marginTop: '20px', padding: 'var(--main-space)' }}>
220
-                <Row>
221
-                  <Col offset="1" span="10">
222
-                    <Button
223
-                      type="primary"
224
-                      block
225
-                    >
226
-                      上一题
227
-                    </Button>
228
-                  </Col>
229
-                  <Col offset="2" span="10">
230
-                    <Button
231
-                      type="primary"
232
-                      block
233
-                      onClick={onChangePage3}
234
-                    >
235
-                      下一题
236
-                    </Button>
237
-                  </Col>
238
-                </Row>
239
-              </CellGroup>
240
-            </ScrollPage>)
241
-        }
242
-      </Page >
243
-      <View>
244
-        {
245
-          scrollPage && (
246
-            <ScrollPage />
247
-          )
248
-        }
249
-      </View>
250
-    </>
251
-  )
252
-}
1
+import React from 'react';
2
+import Taro from '@tarojs/taro';
3
+import { View, ScrollView } from '@tarojs/components';
4
+import { Notify } from '@antmjs/vantui';
5
+import Page from '@/layouts/index';
6
+import {
7
+  getTaCheckItemById,
8
+  getTaCheckItemByCheck,
9
+  preCheck,
10
+  getTaCheckItemAnswer,
11
+  putTaCheckItemAnswer,
12
+} from '@/services/tacheckitem';
13
+import { getTaCheckItemQu } from '@/services/tacheckitemqu';
14
+import VABC from '@/components/VABC';
15
+import { ROLE_INSPECTOR } from '@/utils/user';
16
+import LocForm from './components/LocForm';
17
+import Question from './components/Question';
18
+import Footer from './components/Footer/index';
19
+
20
+export default (props) => {
21
+
22
+  const router = Taro.useRouter();
23
+  const { id, checkId, typ } = router.params;
24
+
25
+  const [loading, setLoading] = React.useState(false);
26
+  const [readonly, setReadonly] = React.useState(false);
27
+  const [checkItemInfo, setCheckItemInfo] = React.useState();
28
+  const [quList, setQuList] = React.useState([]);
29
+  const [index, setIndex] = React.useState(-1);
30
+  const [answer, setAnswer] = React.useState();
31
+
32
+  React.useMemo(() => {
33
+    if (typ == 'loc') {
34
+      Taro.setNavigationBarTitle('实地测评');
35
+    } else {
36
+      Taro.setNavigationBarTitle('调查问卷');
37
+    }
38
+  }, [typ]);
39
+
40
+  const onIndexChange = (n) => {
41
+    if (index == -1 && n != -1) {
42
+      if (!readonly) {
43
+        if (!answer?.addr) {
44
+          Notify.show({
45
+            message: typ == 'loc' ? '请填写地址' : '请填写小区名称',
46
+            type: 'warning',
47
+          })
48
+          return;
49
+        }
50
+        if (!answer?.location) {
51
+          Notify.show({
52
+            message: '未能获取定位信息, 请重试',
53
+            type: 'warning',
54
+          })
55
+          return;
56
+        }
57
+      }
58
+    }
59
+
60
+    setIndex(n);
61
+  }
62
+
63
+  const onAnswerItemChange = (answerItem, quInfo) => {
64
+    if (!answerItem) return;
65
+
66
+    const an = {...(answer || {})}
67
+    const answerItemList = an.answerItemList || []
68
+
69
+    if ((answerItem.answerCode || answerItem.answer) &&
70
+      answerItem.attachList?.length) {
71
+        // 说明这一题已经回答完毕
72
+        quInfo.finished = true
73
+      } else {
74
+        quInfo.finished = false
75
+      }
76
+    
77
+    // 更新问题列表中是否作答的标志位
78
+    setQuList(quList.map(x => x.quId == quInfo.quId ? quInfo : x));
79
+
80
+    if (answerItemList.length) {
81
+      let found = false;
82
+      an.answerItemList = answerItemList.map(x => {
83
+        if (x.quId == answerItem.quId) {
84
+          found = true;
85
+          return answerItem;
86
+        } else {
87
+          return x;
88
+        }
89
+      });
90
+
91
+      if (!found) {
92
+        answerItemList.push(answerItem);
93
+        an.answerItemList = answerItemList;
94
+      }
95
+    } else {
96
+      answerItemList.push(answerItem);
97
+      an.answerItemList = answerItemList;
98
+    }
99
+
100
+    setAnswer(an);
101
+  }
102
+
103
+  // 作答
104
+  const onSubmit = () => {
105
+    if (readonly) return;
106
+
107
+    const finished = quList.filter(x => x.finished).length == quList.length;
108
+    if (!answer || !answer.answerItemList || !finished) {
109
+      Notify.show({
110
+        message: '请作答完成所有题目',
111
+        type: 'warning',
112
+      })
113
+      return;
114
+    }
115
+
116
+    setLoading(true);
117
+    putTaCheckItemAnswer(id, answer).then(() => {
118
+      setLoading(false);
119
+      const t = setTimeout(() => {
120
+        clearTimeout(t);
121
+        Taro.navigateBack({delta: 1});
122
+      }, 1000);      
123
+    }).catch(() => {
124
+      setLoading(false);
125
+    });
126
+  }
127
+  
128
+  // 查询当前测评点位主记录
129
+  React.useEffect(() => {
130
+    if (id) {
131
+      setLoading(true);
132
+      getTaCheckItemById(id).then(res => {
133
+        setLoading(false);
134
+        setCheckItemInfo(res);
135
+      }).catch(() => {
136
+        setLoading(false);
137
+      });
138
+    }
139
+  }, [id]);
140
+  
141
+  // 查询当前测评调查问卷主记录
142
+  React.useEffect(() => {
143
+    if (checkId && typ == 'survey') {
144
+      setLoading(true);
145
+      getTaCheckItemByCheck(checkId, typ).then(res => {
146
+        setLoading(false);
147
+        setCheckItemInfo(res);
148
+      }).catch(() => {
149
+        setLoading(false);
150
+      });
151
+    }
152
+  }, [checkId, typ]);
153
+
154
+  // 查询其他信息
155
+  React.useEffect(() => {
156
+    if (checkItemInfo?.itemId) {
157
+      const { itemId } = checkItemInfo;
158
+      setLoading(true);
159
+      
160
+      preCheck(itemId, { noSuccesTip: true }).then((checkRes) => {
161
+        if (checkRes.errorCode < 0) {
162
+          setLoading(false);
163
+          Notify.show({
164
+            message: checkRes.message,
165
+            type: 'warning',
166
+          })
167
+  
168
+          Taro.navigateBack({delta: 1})
169
+          return;
170
+        }
171
+  
172
+        if (checkRes.errorCode > 0) {
173
+          setReadonly(true);
174
+          // Notify.show({
175
+          //   message: checkRes.message,
176
+          //   type: 'warning',
177
+          // })
178
+        }
179
+        
180
+        // 查询我的答案
181
+        getTaCheckItemAnswer(itemId).then(setAnswer);
182
+    
183
+        // 查询当前测评主记录的所有问题
184
+        getTaCheckItemQu({pageSize: 200, itemId}).then(res => {
185
+          setLoading(false);
186
+          setQuList(res.records || []);
187
+        }).catch(() => {
188
+          setLoading(false);
189
+        });
190
+
191
+      }).catch(() => {
192
+        setLoading(false);
193
+      });
194
+    }
195
+  }, [checkItemInfo]);
196
+  
197
+  return (
198
+    <Page loading={loading} roles={[ROLE_INSPECTOR]}>
199
+      <VABC
200
+        footer={(
201
+          <Footer
202
+            value={index}
203
+            readonly={readonly}
204
+            list={quList}
205
+            onChange={onIndexChange}
206
+            onSubmit={onSubmit}
207
+          />
208
+        )}
209
+      >
210
+        <ScrollView scrollY style={{height: '100%'}}>
211
+        {
212
+          index == -1 && (
213
+            <LocForm
214
+              checkType={typ}
215
+              readonly={readonly}
216
+              checkItemInfo={checkItemInfo}
217
+              answer={answer}
218
+              onChange={setAnswer}
219
+              onLoadingChange={setLoading}
220
+            />
221
+          )
222
+        }
223
+        {
224
+          quList.map((x, inx) => {
225
+            const answerItem = answer?.answerItemList?.filter(y => y.quId == x.quId)[0];
226
+
227
+            return (
228
+              index == inx && (
229
+                <Question
230
+                  key={x.quId}
231
+                  cursor={inx}
232
+                  readonly={readonly}
233
+                  quInfo={x}
234
+                  answerItem={answerItem}
235
+                  total={quList?.length}
236
+                  onChange={e => onAnswerItemChange(e, x)}
237
+                  onPrev={() => onIndexChange(null, -1)}
238
+                  onNext={() => onIndexChange(null, 1)}
239
+                  onLoadingChange={setLoading}
240
+                />
241
+              )
242
+            )
243
+          })
244
+        }
245
+          
246
+        </ScrollView>
247
+      </VABC>
248
+    </Page>
249
+  )
250
+}

+ 4
- 0
src/pages/check/list/index.jsx 파일 보기

@@ -16,6 +16,10 @@ export default (props) => {
16 16
       Taro.navigateTo({
17 17
         url: `/pages/check/loc/list/index?checkId=${item.checkId}`
18 18
       })
19
+    } else {
20
+      Taro.navigateTo({
21
+        url: `/pages/check/edit/index?checkId=${item.checkId}&typ=${typ}`
22
+      })
19 23
     }
20 24
   }
21 25
 

+ 10
- 7
src/pages/check/loc/list/index.jsx 파일 보기

@@ -1,10 +1,11 @@
1 1
 import React from 'react';
2 2
 import Taro from '@tarojs/taro';
3 3
 import { View } from '@tarojs/components';
4
-import { Cell, Icon } from '@antmjs/vantui';
4
+import { Cell, Tag } from '@antmjs/vantui';
5 5
 import Page from '@/layouts/index';
6 6
 import PowerList from '@/components/PowerList';
7 7
 import { getTaCheckItem } from '@/services/tacheckitem';
8
+import { ROLE_INSPECTOR } from '@/utils/user';
8 9
 
9 10
 export default (props) => {
10 11
 
@@ -22,24 +23,26 @@ export default (props) => {
22 23
 
23 24
   const onClick = (item) => {
24 25
     Taro.navigateTo({
25
-      url: `/pages/check/loc/edit/index?id=${item.itemId}`
26
+      url: `/pages/check/edit/index?id=${item.itemId}&typ=${item.itemType}`
26 27
     })
27 28
   }
28 29
   
29 30
   return (
30
-    <Page loading={loading}>
31
+    <Page loading={loading} roles={[ROLE_INSPECTOR]}>
31 32
       <PowerList
32 33
         request={getTaCheckItem}
33 34
         params={params}
34 35
         renderItem={item => (
35 36
           <Cell
37
+            isLink
36 38
             key={item.itemId}
37 39
             title={item.name}
38
-            renderRightIcon={(
39
-              <Icon name={item.readonly ? 'link-o' : 'arrow'} />
40
-            )}
41 40
             onClick={() => onClick(item)}
42
-          />
41
+          >
42
+            {
43
+              item.readonly ? <Tag color="var(--main-bg-color)">已答完</Tag> : null
44
+            }
45
+          </Cell>
43 46
         )}
44 47
         onLoadingChange={setLoading}
45 48
       />

+ 6
- 1
src/services/tacheckitem.js 파일 보기

@@ -38,4 +38,9 @@ export const getTaCheckItemAnswer = (id) => request(`/api/taCheckItem/${id}/answ
38 38
 /*
39 39
  * 获取当前答案
40 40
  */
41
-export const putTaCheckItemAnswer = (id, data) => request(`/api/taCheckItem/${id}/answer`, { method: 'put', data });
41
+export const putTaCheckItemAnswer = (id, data) => request(`/api/taCheckItem/${id}/answer`, { method: 'put', data });
42
+
43
+/*
44
+ * 通过测评ID获取测评ITEM
45
+ */
46
+export const getTaCheckItemByCheck = (checkId, typ) => request(`/api/taCheck/${checkId}/item/${typ}`);