59 Commits
Author SHA1 Message Date
Dawn1Ocean 04e616c477 fix: mainpage avatar & layout 2024-05-10 12:54:21 +08:00
Dawn1Ocean 3242b16e3d fix: ticketList service 2024-05-10 12:41:02 +08:00
Dawn1Ocean 6f960d46a8 fix: default dutyRecoverTime 2024-05-10 12:04:21 +08:00
Dawn1Ocean 669896d253 fix: alter message when inDutyCnt === 0 2024-05-10 11:27:32 +08:00
Dawn1Ocean fc9347e7c1 fix: changestatus 2024-05-10 11:14:23 +08:00
Dawn1Ocean 96dc81bd82 fix: dutyinfo display in mainpage 2024-05-10 10:42:44 +08:00
Dawn_Ocean 54d9dc45b4 fix: comment type 2024-05-09 17:39:41 +08:00
Dawn_Ocean 206eb49893 add member/checklogin in getInfo 2024-05-09 17:33:53 +08:00
Dawn_Ocean 590db1f3fd fix: add space in my continuing tickets; dutyinfo data process 2024-05-09 17:08:56 +08:00
Dawn_Ocean 5cc3387008 fix: get ticket id from url: string -> number 2024-05-09 16:50:17 +08:00
Dawn_Ocean fbe7b9d7de fix: dutyinfo when in duty 2024-04-24 00:19:46 +08:00
Dawn_Ocean 7e3ad80121 fix: memberDutyInfo api; dutyInfo card in MainPage 2024-04-23 17:10:22 +08:00
Dawn1Ocean 0dc87d06d6 fix: dutyinfo display; relaunch to Loading page 2024-04-23 15:59:22 +08:00
Dawn1Ocean 86398ff9a9 fix: request without token; request before getting id in detailframework 2024-04-23 10:17:02 +08:00
Dawn1Ocean 8b2ed25109 fix: request before getting token 2024-04-22 21:05:27 +08:00
Dawn1Ocean fb9f4b4342 small changes to test with ate 2024-04-21 23:06:06 +08:00
Dawn1Ocean 3313307e84 fix: wrong api & services 2024-04-12 01:51:22 +08:00
Dawn1Ocean b68e3db0a3 add conclusion page 2024-04-12 01:42:54 +08:00
Dawn1Ocean d7cdf46026 fix askleave locale & layout 2024-04-12 01:11:07 +08:00
Dawn1Ocean 6325147e81 refactor PicUploader from TicketDetail/Comment 2024-04-12 00:35:45 +08:00
Dawn1Ocean be687d0372 add entry for conclusion page 2024-04-11 19:34:05 +08:00
Dawn1Ocean 0351819fa2 add confirm modal in AskLeave 2024-04-11 17:01:08 +08:00
Dawn_Ocean a12c69cdc0 add entry for AskLeave 2024-04-11 16:14:01 +08:00
Dawn_Ocean 1702b5aa6a add AskLeave page 2024-04-11 15:26:11 +08:00
Dawn_Ocean 952a6caa24 add askleave api&service 2024-04-11 09:13:27 +08:00
Dawn_Ocean d1d01f0ad1 add pic upload service 2024-04-08 18:57:13 +08:00
Dawn_Ocean 51407930bb add pic uploader in ticketnote 2024-04-08 18:48:09 +08:00
Dawn_Ocean 097f6832e3 refactor: split ExpandItem from Mainpage 2024-04-08 15:55:01 +08:00
Dawn_Ocean 4d6eca0434 add pic preview in ticketnote 2024-04-08 15:42:02 +08:00
Dawn_Ocean ab52ffe7ae add pic display in ticketnote 2024-04-08 14:56:51 +08:00
Dawn_Ocean c487187451 change ticketinfo api 2024-04-08 14:20:21 +08:00
Dawn_Ocean 3fd0ebf9c8 refactor: split comment layout from ticketdetail 2024-04-08 14:10:26 +08:00
Dawn1Ocean 7a198cfe03 change /duty/info api 2024-04-07 12:29:07 +08:00
Dawn1Ocean ff926676bd change mytickets mock; add ignore for eslint error: unused state for statusToBe in ticketdetail 2024-04-06 02:27:16 +08:00
Dawn1Ocean 01614c9163 add hint for mytickets in repairpage 2024-04-06 02:05:01 +08:00
Dawn1Ocean 3375e00b37 refactor state structure in ticketdetail 2024-04-06 01:47:12 +08:00
Dawn1Ocean b14d9c363d add locale for reminder 2024-04-05 23:37:52 +08:00
Dawn1Ocean 7f017a0b47 add reminder structure in ticketdetail 2024-04-05 21:34:13 +08:00
Dawn1Ocean 5ce1db7693 refactor api for dutyinfo 2024-04-04 01:39:58 +08:00
Dawn1Ocean d34564980f change index page layout 2024-04-03 20:53:05 +08:00
Dawn1Ocean 5bd07e0ca7 refactor plain-text 2024-04-03 20:41:20 +08:00
Dawn1Ocean a07545b841 change pagination to icon; change updatedutycnt text 2024-03-30 15:56:52 +08:00
Dawn1Ocean f592d87e17 optimize assets/icon structure 2024-03-29 23:08:45 +08:00
Dawn1Ocean ec3acd74e2 complete locale; optimize layout 2024-03-29 22:48:07 +08:00
Dawn1Ocean 2cd401409e add 404 page 2024-03-29 22:09:53 +08:00
Dawn1Ocean aad95000a8 add ping service 2024-03-29 21:33:30 +08:00
Dawn1Ocean 4ab1d5c89a feat: about page 2024-03-29 21:14:40 +08:00
Dawn1Ocean e19b4ccabd change logo src from local to evawiki 2024-03-29 20:53:36 +08:00
Dawn1Ocean 4feccbd442 optimize exception handling 2024-03-29 20:48:15 +08:00
Dawn1Ocean 59ee57827b add plain-text for QR Code scan 2024-03-28 22:53:13 +08:00
Dawn1Ocean 8a60d4c48f change stuid&passwd login to scan QR Code 2024-03-28 22:32:59 +08:00
Dawn1Ocean 7b62c5e473 add loading indicator 2024-03-27 14:58:35 +08:00
Dawn1Ocean e6ffd7d5d7 add search bar in ticketlist with service 2024-03-25 23:46:23 +08:00
Dawn1Ocean ff317c1cd2 add pagination in ticketlist 2024-03-25 23:33:23 +08:00
Dawn1Ocean 1cf16472d2 add ticketList page 2024-03-25 23:04:33 +08:00
Dawn1Ocean 079afea2e0 add ticketList in mainpage 2024-03-25 22:43:23 +08:00
Dawn1Ocean e1075c154b add ticketSearch & ticketsList api 2024-03-25 22:12:16 +08:00
Dawn1Ocean 2d148e7aa4 add other duty time display with mock 2024-03-24 20:33:02 +08:00
Dawn_Ocean c8dd8061b2 add card note for members in mainPage 2024-03-22 16:20:15 +08:00
106 changed files with 2835 additions and 664 deletions
+2 -1
View File
@@ -1,3 +1,4 @@
# 配置文档参考 https://taro-docs.jd.com/docs/next/env-mode-config # 配置文档参考 https://taro-docs.jd.com/docs/next/env-mode-config
TARO_APP_ID="wx636eb7cf2b84f305" TARO_APP_ID="wx636eb7cf2b84f305"
TARO_APP_API="http://127.0.0.1:9527" TARO_APP_API="https://ate.zjueva.net"
# TARO_APP_API="http://127.0.0.1:9527"
+1 -1
View File
@@ -1,2 +1,2 @@
TARO_APP_ID="wx636eb7cf2b84f305" TARO_APP_ID="wx636eb7cf2b84f305"
TARO_APP_API="" TARO_APP_API="https://ate.zjueva.net"
+160 -15
View File
@@ -36,7 +36,7 @@
### 值班信息 `GET /duty/info` ### 值班信息 `GET /duty/info`
#### 当前在值班 #### 当前在值班(正常值班时间)
data: data:
@@ -44,8 +44,29 @@ data:
{ {
"isInDuty": true, "isInDuty": true,
"inDutyCnt": 3, "inDutyCnt": 3,
"currentDuty": "2", "currentDuty": "1",
"place": "东三-204" "place": "", // 只有当 currentDuty 为 others 时,place 和 值班时间 才不为空
"otherDutyStart": "",
"otherDutyEnd": "",
"offDutyReason": "",
"dutyRecoverTime": ""
}
```
#### 当前在值班(其他值班时间)
data:
```json
{
"isInDuty": true,
"inDutyCnt": 3,
"currentDuty": "others",
"place": "蓝田", // 只有当 currentDuty 为 others 时,place 才不为空
"otherDutyStart": "2024-03-07T11:52:48.523303", // Timestamp
"otherDutyEnd": "2024-03-07T13:52:48.523303",
"offDutyReason": "",
"dutyRecoverTime": ""
} }
``` ```
@@ -56,11 +77,33 @@ data:
```json ```json
{ {
"isInDuty": false, "isInDuty": false,
"inDutyCnt": 0,
"currentDuty": "0", // '0' 代表正常值班时间下班,'others' 代表其他值班时间下班
"place": "",
"otherDutyStart": "",
"otherDutyEnd": "",
"offDutyReason": "学园维修", "offDutyReason": "学园维修",
"dutyRecoverTime": "下周一" "dutyRecoverTime": "下周一"
} }
``` ```
#### 当前值班暂停
data:
```json
{
"isInDuty": false,
"inDutyCnt": 0,
"currentDuty": "off", // 'off' 代表当前值班暂停
"place": "",
"otherDutyStart": "",
"otherDutyEnd": "",
"offDutyReason": "考试周",
"dutyRecoverTime": "下周一"
}
```
## 账号登陆 ## 账号登陆
### 微信小程序登陆 `POST /login` OK ### 微信小程序登陆 `POST /login` OK
@@ -205,7 +248,15 @@ Request
{ {
"token": "token_test", "token": "token_test",
"id": "id", "id": "id",
"content" : "为什么 PD 不能充电呢?" "content": "为什么 PD 不能充电呢?",
}
```
Data
```json
{
"id": "id", // 返回的是评论的 id
} }
``` ```
@@ -250,17 +301,47 @@ Request
```json ```json
{ {
"token": "token_test", "token": "token_test",
"id": "id", "id": "id"
} }
``` ```
### 获取七天内未完成工单 `POST /tickets/uncompleted` ### 获取七天内未完成工单 `GET /tickets/uncompleted`
Request Request
```json ```json
{ {
"token": "token_test", "token": "token_test",
"pageId": 1,
"count": 10,
"queryType": 0
}
```
### 获取所有预填写工单 `GET /tickets/list`
Request
```json
{
"token": "token_test",
"pageId": 1,
"count": 10,
"queryType": 0
}
```
### 查询预填写工单 `GET /tickets/search`
Request
```json
{
"token": "token_test",
"values": "test",
"pageId": 1,
"count": 10,
"queryType": 0
} }
``` ```
@@ -288,7 +369,8 @@ data (same as oreo):
"op": "宇航员", "op": "宇航员",
"type": 0, "type": 0,
"content": "", "content": "",
"createdTime": "2024-03-07T19:52:48.523305" "createdTime": "2024-03-07T19:52:48.523305",
"pic": [], // 只有当 type = 1 (评论) 时 pic 才有可能非空
}, },
{ {
"avatar": "https://....jpg", "avatar": "https://....jpg",
@@ -296,7 +378,8 @@ data (same as oreo):
"op": "宇航员", "op": "宇航员",
"type": 2, "type": 2,
"content": "1", "content": "1",
"createdTime": "2024-03-07T19:58:27.838816" "createdTime": "2024-03-07T19:58:27.838816",
"pic": [], // 只有当 type = 1 (评论) 时 pic 才有可能非空
}, },
{ {
"avatar": "https://....jpg", "avatar": "https://....jpg",
@@ -304,7 +387,8 @@ data (same as oreo):
"op": "宇航员", "op": "宇航员",
"type": 2, "type": 2,
"content": "4", "content": "4",
"createdTime": "2024-03-07T20:28:12.070707" "createdTime": "2024-03-07T20:28:12.070707",
"pic": [], // 只有当 type = 1 (评论) 时 pic 才有可能非空
}, },
{ {
"avatar": "https://....jpg", "avatar": "https://....jpg",
@@ -312,7 +396,20 @@ data (same as oreo):
"op": "宇航员", "op": "宇航员",
"type": 2, "type": 2,
"content": "5", "content": "5",
"createdTime": "2024-03-07T20:30:15.770486" "createdTime": "2024-03-07T20:30:15.770486",
"pic": [], // 只有当 type = 1 (评论) 时 pic 才有可能非空
},
{
"avatar": "https://....jpg",
"id": 21374,
"op": "宇航员",
"type": 1,
"content": "清灰换硅脂",
"createdTime": "2024-03-07T20:30:15.780486",
"pic": [
"https://....jpg",
...
]
} }
], ],
"accessories": [2], "accessories": [2],
@@ -329,10 +426,10 @@ Request
```json ```json
{ {
"token": "token_test", "token": "token_test",
"stuid": "3220101984", "code": "code_test",
"passwd": "sonvidiafuckyou"
} }
``` ```
这里的 code 是来源于小程序扫描统一身份认证生成的二维码
### 检查 token 是否登陆 `GET /member/checklogin?token={token}` OK ### 检查 token 是否登陆 `GET /member/checklogin?token={token}` OK
@@ -364,9 +461,14 @@ data:
```json ```json
{ {
"isInDuty": true, "isInDuty": true, // 指示成员其当前是否在值班
"inDutyCnt": 3, "inDutyCnt": 3,
"currentDuty": "2" "currentDuty": "others",
"place": "蓝田", // 只有当 currentDuty 为 others 时,place 才不为空
"otherDutyStart": "2024-03-07T11:52:48.523303", // Timestamp
"otherDutyEnd": "2024-03-07T13:52:48.523303",
"offDutyReason": "",
"dutyRecoverTime": ""
} }
``` ```
@@ -377,7 +479,50 @@ data:
```json ```json
{ {
"isInDuty": false, "isInDuty": false,
"offDutyReason": "学园维修", "inDutyCnt": 0,
"currentDuty": "off", // "0" => 正常值班下班,"others" => 其他值班下班,"off" => 值班暂停
"place": "", // 只有当 currentDuty 为 others 时,place 才不为空
"otherDutyStart": "",
"otherDutyEnd": "",
"offDutyReason": "期中考试周",
"dutyRecoverTime": "下周一" "dutyRecoverTime": "下周一"
} }
``` ```
### 成员请假 `POST /member/askleave`
Request
```json
{
"token": "token_test",
"week": "1",
"shift": "2",
"reason": "家庭原因",
"substitute": "晓洋" // 未找人代班则为空
}
```
### 值班总结上传 `POST /member/conclusion`
Request
```json
{
"token": "token_test",
"week": "2",
"shift": "3",
"conclusion": "周四第三班,一人请假,共收两台电脑,均劝退已取回。由上一班交接两台电脑,其中一台维修成功已取回,一台仍在维修。"
}
```
### 修改值班人数 `POST /member/dutycnt`
Request
```json
{
"token": "token_test",
"dutycnt": 5,
}
```
+48 -10
View File
@@ -1,22 +1,32 @@
import mytickets from './mytickets.json'; import mytickets from './mytickets.json';
import ticketInfo from './ticketInfo.json'; import ticketInfo from './ticketInfo.json';
import uncompleted from './uncompleted.json'; import uncompleted from './uncompleted.json';
import ticketsList from './ticketsList.json';
import ticketsSearch from './ticketSearch.json';
export default { export default {
'GET /ping': {
success: true,
data: {
msg: 'pong',
},
},
'GET /duty/info': { 'GET /duty/info': {
success: true, success: true,
data: { data: {
token: 'token_test',
isInDuty: true, isInDuty: true,
inDutyCnt: 3, inDutyCnt: 3,
currentDuty: '2', currentDuty: 'others',
place: '204', otherDutyStart: '2024-03-07T09:30:48.523303',
otherDutyEnd: '2024-03-07T13:30:48.523303',
place: '蓝田',
offDutyReason: '',
dutyRecoverTime: '',
}, },
}, },
'GET /user/info': { 'GET /user/info': {
success: true, success: true,
data: { data: {
token: 'token_test',
name: '马保国', name: '马保国',
phone: 13333333333, phone: 13333333333,
}, },
@@ -49,7 +59,9 @@ export default {
}, },
'POST /tickets/addnote': { 'POST /tickets/addnote': {
success: true, success: true,
data: {}, data: {
id: 114,
},
}, },
'POST /tickets/create': { 'POST /tickets/create': {
success: true, success: true,
@@ -84,6 +96,14 @@ export default {
success: true, success: true,
data: uncompleted, data: uncompleted,
}, },
'GET /tickets/list': {
success: true,
data: ticketsList,
},
'GET /tickets/search': {
success: true,
data: ticketsSearch,
},
'POST /member/logout': { 'POST /member/logout': {
success: true, success: true,
}, },
@@ -99,13 +119,19 @@ export default {
'GET /member/duty/info': { 'GET /member/duty/info': {
success: true, success: true,
data: { data: {
token: 'token_test',
isInDuty: true, isInDuty: true,
inDutyCnt: 6, inDutyCnt: 3,
currentDuty: '3', currentDuty: 'others',
place: '204', otherDutyStart: '2024-03-07T09:30:48.523303',
otherDutyEnd: '2024-03-07T13:30:48.523303',
place: '蓝田',
offDutyReason: '',
dutyRecoverTime: '',
}, },
}, },
'POST /member/askleave': {
success: true,
},
'POST /login': { 'POST /login': {
success: true, success: true,
data: { data: {
@@ -115,7 +141,19 @@ export default {
'GET /checklogin': { 'GET /checklogin': {
success: true, success: true,
data: { data: {
islogin: false, islogin: true,
}, },
}, },
'POST /upload/pic': {
success: true,
},
'POST /member/conclusion': {
success: true,
data: {
id: 514,
},
},
'POST /member/dutycnt': {
success: true,
},
}; };
+12 -1
View File
@@ -3,13 +3,24 @@
{ {
"id": 6830, "id": 6830,
"type": 1, "type": 1,
"status": 2, "status": 3,
"device": "主机", "device": "主机",
"deviceModel": "技嘉", "deviceModel": "技嘉",
"owner": "武技栏", "owner": "武技栏",
"phone": "18888888888", "phone": "18888888888",
"createdTime": "2024-03-06T19:49:27.043865", "createdTime": "2024-03-06T19:49:27.043865",
"isConfirmed": false "isConfirmed": false
},
{
"id": 6831,
"type": 1,
"status": 2,
"device": "ROG",
"deviceModel": "幻 14",
"owner": "晓洋",
"phone": "18888888887",
"createdTime": "2024-03-06T19:49:27.043865",
"isConfirmed": false
} }
] ]
} }
+22 -5
View File
@@ -8,7 +8,7 @@
"description": "清灰", "description": "清灰",
"workers": ["宇航员"], "workers": ["宇航员"],
"createdTime": "2024-03-07T19:52:48.523303", "createdTime": "2024-03-07T19:52:48.523303",
"status": 5, "status": 4,
"isConfirmed": false, "isConfirmed": false,
"notes": [ "notes": [
{ {
@@ -17,7 +17,8 @@
"op": "宇航员", "op": "宇航员",
"type": 0, "type": 0,
"content": "", "content": "",
"createdTime": "2024-03-07T19:52:48.523305" "createdTime": "2024-03-07T19:52:48.523305",
"pic": []
}, },
{ {
"avatar": "https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png", "avatar": "https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png",
@@ -25,7 +26,8 @@
"op": "宇航员", "op": "宇航员",
"type": 2, "type": 2,
"content": "1", "content": "1",
"createdTime": "2024-03-07T19:58:27.838816" "createdTime": "2024-03-07T19:58:27.838816",
"pic": []
}, },
{ {
"avatar": "https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png", "avatar": "https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png",
@@ -33,7 +35,8 @@
"op": "宇航员", "op": "宇航员",
"type": 2, "type": 2,
"content": "4", "content": "4",
"createdTime": "2024-03-07T20:28:12.070707" "createdTime": "2024-03-07T20:28:12.070707",
"pic": []
}, },
{ {
"avatar": "https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png", "avatar": "https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png",
@@ -41,7 +44,21 @@
"op": "宇航员", "op": "宇航员",
"type": 2, "type": 2,
"content": "5", "content": "5",
"createdTime": "2024-03-07T20:30:15.770486" "createdTime": "2024-03-07T20:30:15.770486",
"pic": []
},
{
"avatar": "https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png",
"id": 21374,
"op": "宇航员",
"type": 1,
"content": "清灰换硅脂",
"createdTime": "2024-03-07T20:30:15.780486",
"pic": [
"https://storage.360buyimg.com/mtd/home/111543234387022.jpg",
"https://storage.360buyimg.com/mtd/home/221543234387016.jpg",
"https://storage.360buyimg.com/mtd/home/331543234387025.jpg"
]
} }
], ],
"accessories": [2], "accessories": [2],
+119
View File
@@ -0,0 +1,119 @@
{
"pageIndex": 1,
"pageCount": 20,
"size": 10,
"queryType": 0,
"data": [
{
"id": 6830,
"type": 1,
"status": 2,
"device": "主机",
"deviceModel": "马嘉祺",
"owner": "马嘉祺",
"phone": "18888888888",
"createdTime": "2024-03-06T19:49:27.043865",
"isConfirmed": false
},
{
"id": 6831,
"type": 0,
"status": 0,
"device": "小米",
"deviceModel": "丁晨曦",
"owner": "丁晨曦",
"phone": "18888888887",
"createdTime": "2024-03-06T11:45:14.043865",
"isConfirmed": false
},
{
"id": 6832,
"type": 1,
"status": 1,
"device": "华硕",
"deviceModel": "宋亚轩",
"owner": "宋亚轩",
"phone": "18888888886",
"createdTime": "2024-03-06T19:48:27.043865",
"isConfirmed": false
},
{
"id": 6833,
"type": 1,
"status": 3,
"device": "联想",
"deviceModel": "刘耀文",
"owner": "刘耀文",
"phone": "18888888885",
"createdTime": "2024-03-06T14:49:27.043865",
"isConfirmed": false
},
{
"id": 6834,
"type": 1,
"status": 4,
"device": "ROG",
"deviceModel": "张震远",
"owner": "张震远",
"phone": "18888888884",
"createdTime": "2024-03-06T19:49:17.043865",
"isConfirmed": false
},
{
"id": 6835,
"type": 1,
"status": 5,
"device": "荣耀",
"deviceModel": "言好像",
"owner": "言好像",
"phone": "18888888883",
"createdTime": "2024-03-06T19:39:27.043865",
"isConfirmed": false
},
{
"id": 6836,
"type": 1,
"status": 6,
"device": "ROG",
"deviceModel": "何君琳",
"owner": "何君琳",
"phone": "18888888882",
"createdTime": "2024-03-06T09:49:27.043865",
"isConfirmed": false
},
{
"id": 6837,
"type": 1,
"status": 7,
"device": "EVA",
"deviceModel": "Echo",
"owner": "Echo",
"phone": "18888888881",
"createdTime": "2024-03-16T19:49:27.043865",
"isConfirmed": false
},
{
"id": 6838,
"type": 0,
"status": 2,
"device": "罗技",
"deviceModel": "SB",
"owner": "SB",
"phone": "18888888880",
"createdTime": "2024-04-06T19:49:27.043865",
"isConfirmed": false
},
{
"id": 6839,
"type": 0,
"status": 3,
"device": "HAL",
"deviceModel": "CNM",
"owner": "CNM",
"phone": "18888888877",
"createdTime": "2024-03-09T19:49:27.043865",
"isConfirmed": false
}
]
}
+97
View File
@@ -0,0 +1,97 @@
{
"pageIndex": 1,
"pageCount": 24,
"size": 8,
"queryType": 0,
"data": [
{
"id": 6830,
"type": 1,
"status": 2,
"device": "主机",
"deviceModel": "技嘉",
"owner": "武技栏",
"phone": "18888888888",
"createdTime": "2024-03-06T19:49:27.043865",
"isConfirmed": false
},
{
"id": 6831,
"type": 0,
"status": 0,
"device": "小米",
"deviceModel": "电风扇",
"owner": "丁真",
"phone": "18888888887",
"createdTime": "2024-03-06T11:45:14.043865",
"isConfirmed": false
},
{
"id": 6832,
"type": 1,
"status": 1,
"device": "华硕",
"deviceModel": "天选 3",
"owner": "西西弗",
"phone": "18888888886",
"createdTime": "2024-03-06T19:48:27.043865",
"isConfirmed": false
},
{
"id": 6833,
"type": 1,
"status": 3,
"device": "联想",
"deviceModel": "ThinkPad X1 Carbon",
"owner": "宇航员",
"phone": "18888888885",
"createdTime": "2024-03-06T14:49:27.043865",
"isConfirmed": false
},
{
"id": 6834,
"type": 1,
"status": 4,
"device": "ROG",
"deviceModel": "魔霸 7 Plus",
"owner": "约书亚",
"phone": "18888888884",
"createdTime": "2024-03-06T19:49:17.043865",
"isConfirmed": false
},
{
"id": 6835,
"type": 1,
"status": 5,
"device": "荣耀",
"deviceModel": "触屏笔记本",
"owner": "玉米",
"phone": "18888888883",
"createdTime": "2024-03-06T19:39:27.043865",
"isConfirmed": false
},
{
"id": 6836,
"type": 1,
"status": 6,
"device": "ROG",
"deviceModel": "幻 14",
"owner": "晓洋",
"phone": "18888888882",
"createdTime": "2024-03-06T09:49:27.043865",
"isConfirmed": false
},
{
"id": 6839,
"type": 0,
"status": 7,
"device": "HAL",
"deviceModel": "卡比手办",
"owner": "蘑菇云",
"phone": "18888888877",
"createdTime": "2024-03-09T19:49:27.043865",
"isConfirmed": false
}
]
}
+1 -1
View File
@@ -9,7 +9,7 @@
"enhance": false, "enhance": false,
"compileHotReLoad": false, "compileHotReLoad": false,
"postcss": false, "postcss": false,
"minified": false, "minified": true,
"babelSetting": { "babelSetting": {
"ignore": [], "ignore": [],
"disablePlugins": [], "disablePlugins": [],
+1 -1
View File
@@ -3,7 +3,7 @@
"projectname": "EVA-Notify", "projectname": "EVA-Notify",
"setting": { "setting": {
"compileHotReLoad": true, "compileHotReLoad": true,
"urlCheck": false, "urlCheck": true,
"bigPackageSizeSupport": true "bigPackageSizeSupport": true
} }
} }
+5
View File
@@ -1,5 +1,6 @@
export default defineAppConfig({ export default defineAppConfig({
pages: [ pages: [
'pages/Loading/Loading',
'pages/index/index', 'pages/index/index',
'pages/repair/repair', 'pages/repair/repair',
'pages/user/user', 'pages/user/user',
@@ -9,6 +10,10 @@ export default defineAppConfig({
'pages/user/report/report', 'pages/user/report/report',
'pages/user/member/member', 'pages/user/member/member',
'pages/TicketDetail/TicketDetail', 'pages/TicketDetail/TicketDetail',
'pages/TicketList/TicketList',
'pages/AskLeave/AskLeave',
'pages/Conclusion/Conclusion',
'pages/404/404',
], ],
window: { window: {
backgroundTextStyle: 'light', backgroundTextStyle: 'light',
+2 -19
View File
@@ -2,30 +2,13 @@ import { PropsWithChildren } from 'react';
import { useLaunch } from '@tarojs/taro'; import { useLaunch } from '@tarojs/taro';
import 'taro-ui/dist/style/index.scss'; import 'taro-ui/dist/style/index.scss';
import './app.scss'; import './app.scss';
import { checkLogin, checkToken } from './service/checkLogin'; import { pingAte } from './service/pingAte';
import wechatUser from './wechat';
import { loginAte } from './service/login';
import { getInfo } from './service/getInfo';
function App({ children }: PropsWithChildren<any>) { function App({ children }: PropsWithChildren<any>) {
useLaunch(() => { useLaunch(() => {
console.log('App launched.'); console.log('App launched.');
// if (checkLogin()) { pingAte();
// wechatUser.setToken(checkToken());
// if(getMemberInfo());
// } else {
// loginAte();
// }
checkLogin((success) => {
if (success) {
wechatUser.setToken(checkToken());
getInfo();
} else {
loginAte();
}
}); });
});
// children 是将要会渲染的页面 // children 是将要会渲染的页面
return children; return children;
} }
+1
View File
@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1710991023487" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="12657" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24"><path d="M512 42.666667q95.658667 0 182.485333 37.162667t149.674667 100.010667 100.010667 149.674667 37.162667 182.485333-37.162667 182.485333-100.010667 149.674667-149.674667 100.010667-182.485333 37.162667-182.485333-37.162667-149.674667-100.010667-100.010667-149.674667-37.162667-182.485333 37.162667-182.485333 100.010667-149.674667 149.674667-100.010667 182.485333-37.162667zM512 128q-77.994667 0-149.162667 30.506667t-122.496 81.834667-81.834667 122.496-30.506667 149.162667 30.506667 149.162667 81.834667 122.496 122.496 81.834667 149.162667 30.506667 149.162667-30.506667 122.496-81.834667 81.834667-122.496 30.506667-149.162667-30.506667-149.162667-81.834667-122.496-122.496-81.834667-149.162667-30.506667zM512 213.333333q17.664 0 30.165333 12.501333t12.501333 30.165333l0 238.336 115.669333 115.328q12.330667 12.330667 12.330667 30.336t-12.330667 30.336-30.336 12.330667-30.336-12.330667l-128-128q-12.330667-12.330667-12.330667-30.336l0-256q0-17.664 12.501333-30.165333t30.165333-12.501333z" fill="#E69966" p-id="12658"></path></svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

Before

Width:  |  Height:  |  Size: 746 B

After

Width:  |  Height:  |  Size: 746 B

-1
View File
@@ -1 +0,0 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1710604932901" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4288" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24"><path d="M512 121.6c217.6 0 390.4 172.8 390.4 390.4S729.6 902.4 512 902.4 121.6 729.6 121.6 512 294.4 121.6 512 121.6m0-89.6C246.4 32 32 249.6 32 512s217.6 480 480 480 480-217.6 480-480S774.4 32 512 32z" p-id="4289"></path><path d="M675.2 512H508.8V284.8c0-25.6-19.2-41.6-41.6-41.6H464c-25.6 0-41.6 19.2-41.6 41.6v272c0 25.6 19.2 41.6 41.6 41.6h214.4c25.6 0 44.8-22.4 44.8-44.8s-22.4-41.6-48-41.6z" p-id="4290"></path></svg>

Before

Width:  |  Height:  |  Size: 746 B

-1
View File
@@ -1 +0,0 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1709907392895" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="9700" width="48" height="48" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M512 32C246.4 32 32 246.4 32 512s214.4 480 480 480 480-214.4 480-480S777.6 32 512 32z m160 566.4c19.2 19.2 19.2 51.2 0 73.6-19.2 19.2-51.2 19.2-73.6 0L512 585.6 425.6 672c-19.2 19.2-51.2 19.2-73.6 0-19.2-19.2-19.2-51.2 0-73.6l86.4-86.4-86.4-86.4c-19.2-19.2-19.2-51.2 0-73.6 19.2-19.2 51.2-19.2 73.6 0l86.4 86.4 86.4-86.4c19.2-19.2 51.2-19.2 73.6 0 19.2 19.2 19.2 51.2 0 73.6L585.6 512l86.4 86.4z" p-id="9701" fill="#d4237a"></path></svg>

Before

Width:  |  Height:  |  Size: 768 B

-1
View File
@@ -1 +0,0 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1709907148592" class="icon" viewBox="0 0 1410 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4262" width="66.09375" height="48" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M385.420696 906.172765L1004.039509 20.583293a47.214703 47.214703 0 0 1 44.414648-20.276253c18.634842 1.448304 31.766129 10.524341 39.297309 27.035004a49.049221 49.049221 0 0 1-3.76559 49.145774L435.242346 1001.278045a49.531989 49.531989 0 0 1-31.669576 20.276253 44.800863 44.800863 0 0 1-36.207594-8.207055L18.806738 752.362906a48.469899 48.469899 0 0 1-18.05552-31.669576 47.311256 47.311256 0 0 1 9.076037-36.207594 44.028434 44.028434 0 0 1 31.669575-18.924502 49.918203 49.918203 0 0 1 36.207594 9.848465l307.716272 230.763066z m686.495982-461.622685a47.021595 47.021595 0 0 1-34.75929-13.517502 47.021595 47.021595 0 0 1-13.517502-34.75929c0-14.096823 4.441465-25.683253 13.517502-34.75929a47.021595 47.021595 0 0 1 34.75929-13.517502h289.660752c14.096823 0 25.5867 4.441465 34.75929 13.517502 8.979483 9.076037 13.517502 20.662467 13.517502 34.75929a47.021595 47.021595 0 0 1-13.517502 34.75929 47.021595 47.021595 0 0 1-34.75929 13.517502h-289.660752z m-193.107168 289.660752a47.021595 47.021595 0 0 1-34.75929-13.517502 47.021595 47.021595 0 0 1-13.517502-34.75929c0-14.096823 4.441465-25.683253 13.517502-34.75929a47.021595 47.021595 0 0 1 34.75929-13.517502h482.76792c14.096823 0 25.5867 4.441465 34.75929 13.517502 8.979483 9.076037 13.517502 20.662467 13.517502 34.75929a47.021595 47.021595 0 0 1-13.517502 34.75929 47.021595 47.021595 0 0 1-34.75929 13.517502h-482.76792z m-193.107168 289.660752a47.021595 47.021595 0 0 1-34.75929-13.517502 47.021595 47.021595 0 0 1-13.517502-34.75929c0-14.096823 4.441465-25.683253 13.517502-34.75929a47.021595 47.021595 0 0 1 34.75929-13.517502h675.875088c14.096823 0 25.5867 4.441465 34.75929 13.517502 8.979483 9.076037 13.517502 20.662467 13.517502 34.75929a47.021595 47.021595 0 0 1-13.517502 34.75929 47.021595 47.021595 0 0 1-34.75929 13.517502h-675.875088z" p-id="4263" fill="#8a8a8a"></path></svg>

Before

Width:  |  Height:  |  Size: 2.1 KiB

-1
View File
@@ -1 +0,0 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1709907302076" class="icon" viewBox="0 0 1026 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7483" width="48.09375" height="48" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M123.252 739.482L406.85 455.885l-60.34-60.34-287.64 287.64c-30.893 30.894-31.708 80.946-0.814 111.84l177.279 177.278c30.863 30.864 80.945 30.08 111.84-0.814l287.609-287.61-60.34-60.34-283.597 283.597-167.654-167.654z" p-id="7484" fill="#8a8a8a"></path><path d="M717.75 223.245l65.107-65.348 122.58 121.374-62.331 62.572-109.064 44.56a81.444 81.444 0 0 0-27.274 18.404L562.013 553.183l61.064 59.616 144.122-147.742 109.034-44.531a80.337 80.337 0 0 0 26.67-17.8l123.364-123.848-243.863-241.45L656.686 163.69c-7.452 7.452-13.365 16.382-17.408 26.097l-44.56 107.616-136.972 137.574 60.46 60.22 137.605-138.209c7.482-7.482 13.366-16.382 17.438-26.127l44.47-107.646z" p-id="7485" fill="#8a8a8a"></path><path d="M351.156 295.623L746.713 691.18q30.17 30.17 0 60.34t-60.34 0L290.816 355.962q-30.17-30.17 0-60.34t60.34 0zM222.24 728.35a42.667 42.667 0 0 1 60.31 1.055l24.739 25.584a42.667 42.667 0 0 1-61.366 59.254l-24.74-25.644a42.624 42.624 0 0 1 1.027-60.28z" p-id="7486" fill="#8a8a8a"></path></svg>

Before

Width:  |  Height:  |  Size: 1.3 KiB

-1
View File
@@ -1 +0,0 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1709907338992" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8608" width="48" height="48" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M832 0H192C85.952 0 0 86.016 0 192v640a192 192 0 0 0 192 192h640a192 192 0 0 0 192-192V192c0-105.984-85.952-192-192-192z m64 832c0 35.392-28.608 64-64 64H192a64 64 0 0 1-64-64V192c0-35.328 28.672-64 64-64h640a64 64 0 0 1 64 64v640zM669.376 330.88L443.136 557.12l-90.56-90.496c-24.96-25.024-65.472-25.024-90.496 0s-25.024 65.536 0 90.496l135.808 135.744a63.936 63.936 0 0 0 90.496 0l271.488-271.488c25.024-25.024 25.024-65.472 0-90.496s-65.472-25.024-90.496 0z" p-id="8609" fill="#12c53d"></path></svg>

Before

Width:  |  Height:  |  Size: 832 B

+1
View File
@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1711724022815" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7442" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M512 85.333333c235.648 0 426.666667 191.061333 426.666667 426.666667s-191.018667 426.666667-426.666667 426.666667S85.333333 747.605333 85.333333 512 276.352 85.333333 512 85.333333z m0 71.125334c-196.053333 0-355.541333 159.488-355.541333 355.541333 0 196.053333 159.488 355.541333 355.541333 355.541333 196.053333 0 355.541333-159.488 355.541333-355.541333 0-196.053333-159.488-355.541333-355.541333-355.541333zM480 256a32 32 0 0 1 31.701333 27.648L512 288V512h138.666667a32 32 0 0 1 4.352 63.701333l-4.352 0.298667h-170.666667a32 32 0 0 1-31.701333-27.648l-0.298667-4.352v-256a32 32 0 0 1 32-32z" fill="#bfbfbf" p-id="7443"></path></svg>

After

Width:  |  Height:  |  Size: 972 B

+1
View File
@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1711724082044" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8459" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M572.341333 512l268.490667-268.501333a42.666667 42.666667 0 0 0-59.274667-61.376c-0.362667 0.341333-0.704 0.693333-1.056 1.045333L512 451.658667 243.509333 183.168a42.666667 42.666667 0 0 0-60.341333 60.330667L451.669333 512 183.168 780.501333a42.666667 42.666667 0 0 0 59.669333 61.002667l0.672-0.672L512 572.341333l268.501333 268.490667C788.832 849.162667 799.754667 853.333333 810.666667 853.333333s21.845333-4.170667 30.165333-12.501333a42.666667 42.666667 0 0 0 0-60.330667L572.341333 512z" p-id="8460" fill="#d81e06"></path></svg>

After

Width:  |  Height:  |  Size: 869 B

+1
View File
@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1711724278042" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="11057" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M756.821333 256C691.541333 203.264 601.472 170.666667 512 170.666667a341.333333 341.333333 0 1 0 341.333333 341.333333 42.666667 42.666667 0 0 1 85.333334 0c0 235.648-191.018667 426.666667-426.666667 426.666667S85.333333 747.648 85.333333 512 276.352 85.333333 512 85.333333c108.757333 0 217.898667 39.082667 298.666667 104.490667V128a42.666667 42.666667 0 0 1 85.333333 0v170.666667a42.666667 42.666667 0 0 1-42.666667 42.666666h-170.666666a42.666667 42.666667 0 0 1 0-85.333333h74.154666z" p-id="11058" fill="#f0d323"></path></svg>

After

Width:  |  Height:  |  Size: 867 B

+1
View File
@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1711724571236" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="15667" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M223.579432 955.45963a24.234651 24.234651 0 0 1-3.071998-1.979732 508.995927 508.995927 0 0 1-184.319877-185.616943 34.133311 34.133311 0 0 1 12.561058-46.557836 33.655444 33.655444 0 0 1 46.694369 12.561058 440.25144 440.25144 0 0 0 159.880427 160.767893 15.223457 15.223457 0 0 1 2.525865 1.365333c12.424525 6.826662 24.917317 13.653324 37.751441 19.455987A443.733038 443.733038 0 0 0 701.582313 127.726848l-4.64213-2.662398-4.369064-2.389332H692.16152a444.347437 444.347437 0 0 0-423.867451 0l-1.365333 0.682666-3.618131 1.979732-5.188263 2.935465A440.114907 440.114907 0 0 0 95.852584 290.406206a33.723711 33.723711 0 0 1-46.694369 12.561059 34.133311 34.133311 0 0 1-12.561058-46.694369A512.477525 512.477525 0 0 1 695.233517 47.854901a0.682666 0.682666 0 0 0 0.546133 0c1.365332 0.682666 2.525865 1.365332 3.891198 1.843199a511.658326 511.658326 0 0 1-1.365333 925.35405l-1.228799 0.682666-3.618131 1.570132a505.71913 505.71913 0 0 1-176.947082 45.329037 492.065805 492.065805 0 0 1-37.614908 1.433599 507.835395 507.835395 0 0 1-255.317163-68.607954z" fill="#bfbfbf" p-id="15668"></path><path d="M539.176022 288.358208a231.492112 231.492112 0 0 1 163.498557 283.169944 34.133311 34.133311 0 0 1-41.847439 24.098118 34.133311 34.133311 0 0 1-24.098117-41.779173A162.952425 162.952425 0 1 0 437.117423 669.012887a34.133311 34.133311 0 0 1 24.098117 41.847439 34.133311 34.133311 0 0 1-41.779172 24.098117 231.219046 231.219046 0 1 1 119.739654-446.600235z" fill="#bfbfbf" p-id="15669"></path></svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1711723813811" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4236" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M800 288a47.84 47.84 0 0 0-33.936 14.064L432 636.112 257.936 462.064a48 48 0 1 0-67.872 67.872l208 208c8.688 8.688 20.688 14.064 33.936 14.064s25.248-5.376 33.936-14.064l368-368A48 48 0 0 0 800 288z" fill="#bfbfbf" p-id="4237"></path></svg>

After

Width:  |  Height:  |  Size: 573 B

+1
View File
@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1711724195931" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="9893" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M800 288a47.84 47.84 0 0 0-33.936 14.064L432 636.112 257.936 462.064a48 48 0 1 0-67.872 67.872l208 208c8.688 8.688 20.688 14.064 33.936 14.064s25.248-5.376 33.936-14.064l368-368A48 48 0 0 0 800 288z" fill="#14ca20" p-id="9894"></path></svg>

After

Width:  |  Height:  |  Size: 573 B

+1
View File
@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1711521868832" class="icon" viewBox="0 0 1025 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1603" xmlns:xlink="http://www.w3.org/1999/xlink" width="200.1953125" height="200"><path d="M982.668821 313.74918c-25.810101-60.752236-62.714-115.373446-109.685763-162.346233-46.972787-46.971763-101.593997-83.875662-162.346233-109.685763C647.666853 14.966132 580.925912 1.401699 512.268258 1.401699S376.868639 14.966132 313.898667 41.717184c-60.752236 25.810101-115.373446 62.714-162.346233 109.685763-46.971763 46.972787-83.875662 101.593997-109.685763 162.346233C15.115619 376.719151 1.551186 443.460092 1.551186 512.118771S15.115619 647.517366 41.866671 710.487337c25.810101 60.75326 62.714 115.37447 109.685763 162.346233 46.971763 46.972787 101.592974 83.876686 162.346233 109.685763 62.969971 26.752076 129.710912 40.316509 198.369591 40.316509s135.398595-13.564433 198.368567-40.316509c60.75326-25.809077 115.37447-62.712976 162.346233-109.685763 46.972787-46.971763 83.876686-101.592974 109.685763-162.346233 26.752076-62.969971 40.316509-129.710912 40.316509-198.368567S1009.419873 376.719151 982.668821 313.74918zM937.435615 691.271058c-23.333323 54.923257-56.71096 104.317532-99.204249 146.811845-42.494313 42.493289-91.888588 75.870926-146.811845 99.204249-56.8584 24.155503-117.133505 36.403219-179.152287 36.403219-62.018782 0-122.293887-12.247716-179.152287-36.403219-54.923257-23.333323-104.317532-56.71096-146.810821-99.204249-42.493289-42.494313-75.870926-91.888588-99.204249-146.811845C62.944374 634.412658 50.697682 574.136529 50.697682 512.118771c0-62.018782 12.247716-122.293887 36.403219-179.152287 23.333323-54.923257 56.709936-104.317532 99.204249-146.810821s91.888588-75.870926 146.810821-99.204249c56.8584-24.155503 117.133505-36.403219 179.152287-36.403219 62.017758 0 122.292863 12.247716 179.152287 36.403219 54.923257 23.333323 104.317532 56.709936 146.810821 99.204249 42.494313 42.493289 75.870926 91.888588 99.205273 146.810821 24.155503 56.8584 36.403219 117.134529 36.403219 179.152287S961.591118 634.412658 937.435615 691.271058z" fill="#ffffff" p-id="1604"></path><path d="M704.62457 319.769626c-9.997216-9.996192-26.203273-9.996192-36.199466 0L512.382933 475.810773 356.341786 319.769626c-9.996192-9.996192-26.204297-9.996192-36.199466 0-9.996192 9.996192-9.996192 26.203273 0 36.199466l156.041147 156.041147L320.14232 668.05241c-9.996192 9.997216-9.996192 26.204297 0 36.199466 4.997584 4.998608 11.549426 7.496888 18.100245 7.496888s13.101637-2.49828 18.100245-7.496888l156.041147-156.041147L668.424081 704.251876c4.998608 4.998608 11.548403 7.496888 18.100245 7.496888s13.101637-2.49828 18.100245-7.496888c9.996192-9.996192 9.996192-26.203273 0-36.199466L548.583423 512.011263l156.041147-156.041147C714.620762 345.973923 714.620762 329.765818 704.62457 319.769626z" fill="#ffffff" p-id="1605"></path></svg>

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

@@ -9,7 +9,7 @@ import {
import pt from '@/plain-text'; import pt from '@/plain-text';
import { RequestState } from '@/service'; import { RequestState } from '@/service';
import { getTicketInfo } from '@/service/ticketsInfo'; import { getTicketInfo } from '@/service/ticketsInfo';
import { AtCard, AtSteps } from 'taro-ui'; import { AtActivityIndicator, AtCard, AtSteps, AtToast } from 'taro-ui';
import NoteList from '../NoteList/NoteList'; import NoteList from '../NoteList/NoteList';
interface StepItemData { interface StepItemData {
@@ -66,9 +66,21 @@ export default class DetailFramework extends Component<
render(): ReactNode { render(): ReactNode {
if (this.state.rs.loading) { if (this.state.rs.loading) {
return <View>Loading</View>; return (
} else if (!this.state.rs.success) { <AtActivityIndicator
return <View>Request failed</View>; mode='center'
content={pt.get().actIndicator.loading}
></AtActivityIndicator>
);
}
if (!this.state.rs.success) {
return (
<AtToast
isOpened
text={pt.get().toast.error}
icon='close-circle'
></AtToast>
);
} }
const elements: ShowElements = { const elements: ShowElements = {
@@ -97,7 +109,7 @@ export default class DetailFramework extends Component<
marginLeft: '3%', marginLeft: '3%',
}} }}
> >
<AtCard isFull title={pt.get().ticketDetail.descTitle}> <AtCard isFull title={pt.get().ticketDetail.desc.title}>
<View className='at-article__h3'> <View className='at-article__h3'>
{this.state.ticketInfo.description} {this.state.ticketInfo.description}
</View> </View>
@@ -148,12 +160,13 @@ export default class DetailFramework extends Component<
notelist: this.props.isInfoShow['notelist'] ? ( notelist: this.props.isInfoShow['notelist'] ? (
this.props.isInfoShow['showAllNotes'] ? ( this.props.isInfoShow['showAllNotes'] ? (
<View style={{ padding: '20rpx' }}> <View style={{ padding: '20rpx' }}>
<NoteList noteList={this.state.notes} /> <NoteList noteList={this.state.notes} showPic />
</View> </View>
) : ( ) : (
<View style={{ padding: '20rpx' }}> <View style={{ padding: '20rpx' }}>
<NoteList <NoteList
noteList={[this.state.notes[this.state.notes.length - 1]]} noteList={[this.state.notes[this.state.notes.length - 1]]}
showPic={false}
/> />
</View> </View>
) )
@@ -0,0 +1,3 @@
export default {
component: true,
};
+31
View File
@@ -0,0 +1,31 @@
import { View } from '@tarojs/components';
import { Component, ReactNode } from 'react';
import { AtAccordion } from 'taro-ui';
export class ExpandItem extends Component {
state = {
open: false,
};
props = {
title: '',
content: <View></View>,
};
handleClick(value: boolean) {
this.setState({ open: value });
}
render(): ReactNode {
return (
<View>
<AtAccordion
open={this.state.open}
onClick={this.handleClick.bind(this)}
title={this.props.title}
>
{this.props.content}
</AtAccordion>
</View>
);
}
}
+51 -9
View File
@@ -3,40 +3,75 @@ import { Component, ReactNode } from 'react';
import { TicketNote, StatusStr } from '@/pages/TicketDetail/TicketNote'; import { TicketNote, StatusStr } from '@/pages/TicketDetail/TicketNote';
import pt from '@/plain-text'; import pt from '@/plain-text';
import { timeFormat } from '@/utils'; import { timeFormat } from '@/utils';
import Taro from '@tarojs/taro';
import './NoteCard.scss'; import './NoteCard.scss';
interface NoteCardProps { interface NoteCardProps {
note: TicketNote; note: TicketNote;
showPic: boolean;
} }
export default class NoteCard extends Component<NoteCardProps, {}> { export default class NoteCard extends Component<NoteCardProps, {}> {
props: Readonly<NoteCardProps> = { props: Readonly<NoteCardProps> = {
note: new TicketNote(), note: new TicketNote(),
showPic: true,
}; };
render(): ReactNode { render(): ReactNode {
var message = ''; let message = '';
let pic: string[] = [];
const note = this.props.note; const note = this.props.note;
const td = pt.get().ticketDetail; const td = pt.get().ticketDetail;
const createMessage = td.createTicketMessage; const createMessage = td.comment.createTicketMessage;
const modifyMessage = td.statusModifyMessage; const modifyMessage = td.statusModifyMessage;
const prefix = td.statusModifyPrefix; const prefix = td.comment.statusModifyPrefix;
switch (note.type) { switch (note.type) {
case 0: case 0:
message = createMessage; message = createMessage;
break; break;
case 1: case 1:
message = note.content; message = pt.get().ticketDetail.comment.picked;
break; break;
case 2: case 2:
message = prefix + modifyMessage.get(note.content as StatusStr) || ''; message = prefix + modifyMessage.get(note.content as StatusStr) || '';
break; break;
case 3:
message = note.content;
pic = note.pic;
break;
} }
const showPicDetail = (url: string) => {
Taro.previewImage({
current: url,
urls: [url],
});
};
const notePicRenderer = (
<View>
<View className='at-row' style={{ marginLeft: '30rpx' }}>
{pic.map((url, idx) => (
<View className='at-col at-col-4' key={idx}>
<Image
style='width: 160rpx; height: 160rpx;'
src={url}
mode='aspectFit'
onClick={showPicDetail.bind(this, url)}
/>
</View>
))}
</View>
</View>
);
return ( return (
<View className='at-row at-row__align--center'> <View className='at-row at-row__align--start'>
<View className='at-col at-col-1 at-col--auto'> <View
className='at-col at-col-1 at-col--auto'
style={{ marginTop: '80rpx' }}
>
<Image <Image
style='width: 70rpx; height: 70rpx; border-radius: 35px;' style='width: 70rpx; height: 70rpx; border-radius: 35px;'
src={note.avatar} src={note.avatar}
@@ -44,14 +79,21 @@ export default class NoteCard extends Component<NoteCardProps, {}> {
/> />
</View> </View>
<View <View
className='at-col' className='at-col at-col--wrap'
style={{ marginTop: '40rpx', marginBottom: '40rpx' }} style={{
marginTop: '40rpx',
marginBottom: '40rpx',
wordBreak: 'normal',
}}
> >
<View className='at-article__p'>{note.op}</View> <View className='at-article__p'>{note.op}</View>
<View className='at-article__info'> <View className='at-article__info'>
{note.createdTime.format(timeFormat)} {note.createdTime.format(timeFormat)}
</View> </View>
<View className='at-article__h3'>{message}</View> <View className='at-article__h3' style={{ marginBottom: '20rpx' }}>
{message}
</View>
{this.props.showPic ? notePicRenderer : null}
</View> </View>
</View> </View>
); );
+3 -1
View File
@@ -7,11 +7,13 @@ import pt from '@/plain-text';
interface NoteListProps { interface NoteListProps {
noteList: Array<TicketNote>; noteList: Array<TicketNote>;
showPic: boolean;
} }
export default class NoteList extends Component<NoteListProps, {}> { export default class NoteList extends Component<NoteListProps, {}> {
props: Readonly<NoteListProps> = { props: Readonly<NoteListProps> = {
noteList: [], noteList: [],
showPic: true,
}; };
render(): ReactNode { render(): ReactNode {
return ( return (
@@ -23,7 +25,7 @@ export default class NoteList extends Component<NoteListProps, {}> {
/> />
{this.props.noteList.map((note, idx) => ( {this.props.noteList.map((note, idx) => (
<View key={idx}> <View key={idx}>
<NoteCard note={note} /> <NoteCard note={note} showPic={this.props.showPic} />
</View> </View>
))} ))}
</View> </View>
@@ -0,0 +1,3 @@
export default {
component: true,
};
@@ -0,0 +1,66 @@
import { picUpload } from '@/service/picUpload';
import { View } from '@tarojs/components';
import Taro from '@tarojs/taro';
import { Component, ReactNode } from 'react';
import { AtImagePicker } from 'taro-ui';
import { File } from 'taro-ui/types/image-picker';
const reLaunchInterval = 1000;
interface PicUploaderState {
files: File[];
}
interface PicUploaderProps {
source: string;
id: number;
superId?: number;
}
export default class PicUploader extends Component<
PicUploaderProps,
PicUploaderState
> {
state = {
files: [] as File[],
};
onUpload() {
if (this.state.files.length !== 0) {
for (let file of this.state.files) {
picUpload(this, file.url);
}
}
if (this.props.source == 'comment') {
setTimeout(() => {
Taro.reLaunch({
url: '/pages/TicketDetail/TicketDetail?id=' + this.props.superId,
});
}, reLaunchInterval);
} else if (this.props.source == 'conclusion') {
setTimeout(() => {
Taro.reLaunch({
url: '/pages/index/index',
});
}, reLaunchInterval);
}
}
handlePicChange(files: File[]) {
this.setState({
files: files,
});
return files;
}
render(): ReactNode {
return (
<View>
<AtImagePicker
showAddBtn={this.state.files.length !== 3}
count={3}
files={this.state.files}
sizeType={['compressed']}
onChange={this.handlePicChange.bind(this)}
/>
</View>
);
}
}
@@ -1,9 +1,10 @@
import { AtListItem } from 'taro-ui'; import { AtListItem } from 'taro-ui';
import repair from '@/assets/icons/MyTickets/repair.svg'; import create from '@/assets/icons/TicketState/create.svg';
import finished from '@/assets/icons/MyTickets/finished.svg'; import repair from '@/assets/icons/TicketState/repair.svg';
import tick from '@/assets/icons/MyTickets/tick.svg'; import success from '@/assets/icons/TicketState/success.svg';
import fail from '@/assets/icons/MyTickets/fail.svg'; import fail from '@/assets/icons/TicketState/fail.svg';
import clock from '@/assets/icons/MyTickets/clock.svg'; import refuse from '@/assets/icons/TicketState/refuse.svg';
import retrieve from '@/assets/icons/TicketState/retrieve.svg';
import pt from '@/plain-text'; import pt from '@/plain-text';
import Taro from '@tarojs/taro'; import Taro from '@tarojs/taro';
import { FixStatus } from '@/common'; import { FixStatus } from '@/common';
@@ -29,14 +30,14 @@ export class TicketListItem {
this.status = status; this.status = status;
this.createAt = createAt; this.createAt = createAt;
this.iconMap = new Map<FixStatus, string>([ this.iconMap = new Map<FixStatus, string>([
[0, repair], [0, create],
[1, repair], [1, repair],
[2, clock], [2, refuse],
[3, finished], [3, retrieve],
[4, clock], [4, success],
[5, tick], [5, retrieve],
[6, clock], [6, fail],
[7, fail], [7, retrieve],
]); ]);
} }
+3
View File
@@ -0,0 +1,3 @@
export default definePageConfig({
usingComponents: {},
});
View File
+35
View File
@@ -0,0 +1,35 @@
import { Component, ReactNode } from 'react';
import { View } from '@tarojs/components';
import Taro from '@tarojs/taro';
import pt from '@/plain-text';
import PageFooter from '@/components/PageFooter/PageFooter';
import './404.scss';
export default class NotFoundPage extends Component {
componentDidMount(): void {
Taro.setNavigationBarTitle({
title: pt.get().navBar.notFound,
});
}
render(): ReactNode {
return (
<View>
<View
className='page-title'
style={{ marginTop: '150rpx', marginBottom: '240rpx' }}
>
<View className='at-article__h1' style={{ fontWeight: 'bold' }}>
{pt.get().notFound.title.ZhCn}
</View>
<View className='at-article__h2'>{pt.get().notFound.desc.ZhCn}</View>
<View style={{ height: '150rpx' }}></View>
<View className='at-article__h1' style={{ fontWeight: 'bold' }}>
{pt.get().notFound.title.EnUs}
</View>
<View className='at-article__h2'>{pt.get().notFound.desc.EnUs}</View>
</View>
<PageFooter />
</View>
);
}
}
+3
View File
@@ -0,0 +1,3 @@
export default definePageConfig({
usingComponents: {},
});
View File
+187
View File
@@ -0,0 +1,187 @@
import {
AtTextarea,
AtButton,
AtForm,
AtMessage,
AtInput,
AtList,
AtListItem,
AtModal,
} from 'taro-ui';
import { Component, ReactNode } from 'react';
import Taro from '@tarojs/taro';
import pt from '@/plain-text';
import { Picker, View } from '@tarojs/components';
import { askLeave } from '@/service/askleave';
import './AskLeave.scss';
const submitInterval = 5000;
export default class AskLeavePage extends Component {
state = {
isLoading: false,
isDisable: false,
showModal: false,
range: [pt.get().askLeave.shift.week, pt.get().askLeave.shift.shift],
shift: [0, 0],
reason: '',
substitute: '',
};
componentDidMount(): void {
Taro.setNavigationBarTitle({
title: pt.get().navBar.askLeave,
});
}
onShiftSelect(event) {
this.setState({
shift: event.detail.value,
});
console.log(event);
}
onModalClose() {
this.setState({
showModal: false,
});
setTimeout(() => {
this.setState({
isDisable: false,
});
}, submitInterval);
}
onModalCancel() {
this.setState({
showModal: false,
});
setTimeout(() => {
this.setState({
isDisable: false,
});
}, submitInterval);
}
onModalConfirm() {
this.setState({
showModal: false,
});
askLeave(this);
setTimeout(() => {
this.setState({
isDisable: false,
});
}, submitInterval);
}
handleReasonChange(reason: string) {
this.setState({
reason,
});
}
handleSubstituteChange(substitute: string) {
this.setState({
substitute,
});
}
onSubmit() {
this.setState({
isDisable: true,
});
if (this.state.reason == '') {
Taro.atMessage({
message: pt.get().button.submitText.blank,
type: 'error',
});
setTimeout(() => {
this.setState({
isDisable: false,
});
}, submitInterval);
return;
}
if (this.state.substitute == '') {
this.setState({
showModal: true,
});
return;
}
askLeave(this);
setTimeout(() => {
this.setState({
isDisable: false,
});
}, submitInterval);
}
render(): ReactNode {
return (
<View style={{ marginTop: '30rpx', width: '94%', marginLeft: '3%' }}>
<AtMessage />
<AtModal
isOpened={this.state.showModal}
title={pt.get().askLeave.modal.title}
cancelText={pt.get().modal.cancel}
confirmText={pt.get().modal.confirm}
onClose={this.onModalClose.bind(this)}
onCancel={this.onModalCancel.bind(this)}
onConfirm={this.onModalConfirm.bind(this)}
content={pt.get().askLeave.modal.content}
/>
<AtForm onSubmit={this.onSubmit.bind(this)}>
<View style={{ width: '98%', marginLeft: '1%' }}>
<Picker
mode='multiSelector'
range={this.state.range}
onChange={this.onShiftSelect.bind(this)}
value={this.state.shift}
>
<AtList>
<AtListItem
title={pt.get().askLeave.shift.title}
extraText={
pt.get().askLeave.shift.week[this.state.shift[0]] +
pt.get().askLeave.shift.shift[this.state.shift[1]]
}
/>
</AtList>
</Picker>
</View>
<View
className='at-article__h3'
style={{ marginTop: '20rpx', marginBottom: '20rpx' }}
>
{pt.get().askLeave.reason.title}
</View>
<AtTextarea
value={this.state.reason}
onChange={this.handleReasonChange.bind(this)}
maxLength={200}
placeholder={pt.get().askLeave.reason.placeHolder}
/>
<AtInput
name='substitute'
title={pt.get().askLeave.substitute.title}
type='text'
placeholder={pt.get().askLeave.substitute.placeHolder}
value={this.state.substitute}
onChange={this.handleSubstituteChange.bind(this)}
/>
<View>
<AtButton
loading={this.state.isLoading}
formType='submit'
type='primary'
disabled={this.state.isDisable}
>
{pt.get().button.buttonText.submit}
</AtButton>
</View>
</AtForm>
</View>
);
}
}
@@ -0,0 +1,3 @@
export default definePageConfig({
usingComponents: {},
});
+129
View File
@@ -0,0 +1,129 @@
import {
AtTextarea,
AtButton,
AtForm,
AtMessage,
AtList,
AtListItem,
} from 'taro-ui';
import React, { Component, ReactNode } from 'react';
import Taro from '@tarojs/taro';
import pt from '@/plain-text';
import { Picker, View } from '@tarojs/components';
import PicUploader from '@/components/PicUploader/PicUploader';
import { conclude } from '@/service/conclude';
import './Conclusion.scss';
const submitInterval = 5000;
export default class ConclusionPage extends Component {
state = {
isLoading: false,
isDisable: false,
conclusion: '',
conclusionId: 0,
range: [pt.get().askLeave.shift.week, pt.get().askLeave.shift.shift],
shift: [0, 0],
};
componentDidMount(): void {
Taro.setNavigationBarTitle({
title: pt.get().navBar.conclusion,
});
}
uploaderRef = React.createRef<PicUploader>();
handleConclusionChange(conclusion: string) {
this.setState({
conclusion,
});
}
onShiftSelect(event) {
this.setState({
shift: event.detail.value,
});
console.log(event);
}
onSubmit() {
this.setState({
isDisable: true,
});
if (this.state.conclusion == '') {
Taro.atMessage({
message: pt.get().button.submitText.blank,
type: 'error',
});
setTimeout(() => {
this.setState({
isDisable: false,
});
}, submitInterval);
return;
}
conclude(this);
this.uploaderRef.current?.onUpload();
setTimeout(() => {
this.setState({
isDisable: false,
});
}, submitInterval);
}
render(): ReactNode {
return (
<View style={{ marginTop: '30rpx', width: '94%', marginLeft: '3%' }}>
<AtMessage />
<AtForm onSubmit={this.onSubmit.bind(this)}>
<View style={{ width: '98%', marginLeft: '1%' }}>
<Picker
mode='multiSelector'
range={this.state.range}
onChange={this.onShiftSelect.bind(this)}
value={this.state.shift}
>
<AtList>
<AtListItem
title={pt.get().askLeave.shift.title}
extraText={
pt.get().askLeave.shift.week[this.state.shift[0]] +
pt.get().askLeave.shift.shift[this.state.shift[1]]
}
/>
</AtList>
</Picker>
</View>
<View
className='at-article__h3'
style={{ marginTop: '20rpx', marginBottom: '20rpx' }}
>
{pt.get().conclusion.title}
</View>
<AtTextarea
value={this.state.conclusion}
onChange={this.handleConclusionChange.bind(this)}
maxLength={200}
height={400}
placeholder={pt.get().conclusion.placeHolder}
/>
<PicUploader
ref={this.uploaderRef}
source='conclusion'
id={this.state.conclusionId}
/>
<View>
<AtButton
loading={this.state.isLoading}
formType='submit'
type='primary'
disabled={this.state.isDisable}
>
{pt.get().button.buttonText.submit}
</AtButton>
</View>
</AtForm>
</View>
);
}
}
+3
View File
@@ -0,0 +1,3 @@
export default definePageConfig({
usingComponents: {},
});
View File
+30
View File
@@ -0,0 +1,30 @@
import { AtActivityIndicator } from 'taro-ui';
import { Component, ReactNode } from 'react';
import Taro from '@tarojs/taro';
import pt from '@/plain-text';
import { View } from '@tarojs/components';
import wechatUser from '@/wechat';
import './Loading.scss';
export default class LoadingPage extends Component {
componentDidMount(): void {
Taro.setNavigationBarTitle({
title: pt.get().navBar.loading,
});
if (wechatUser.getToken()) {
Taro.reLaunch({
url: '/pages/index/index',
});
}
}
render(): ReactNode {
return (
<View>
<AtActivityIndicator
mode='center'
content={pt.get().actIndicator.loading}
></AtActivityIndicator>
</View>
);
}
}
+101
View File
@@ -0,0 +1,101 @@
import { ExpandItem } from '@/components/ExpandItem/ExpandItem';
import PicUploader from '@/components/PicUploader/PicUploader';
import pt from '@/plain-text';
import { submitComment } from '@/service/submitComment';
import { View } from '@tarojs/components';
import Taro from '@tarojs/taro';
import React, { Component, ReactNode } from 'react';
import { AtButton, AtForm, AtTextarea } from 'taro-ui';
const submitInterval = 5000;
export interface commentData {
content: string;
id: number;
}
export class Comment extends Component {
state = {
isLoading: false,
isDisable: false,
comment: '',
commentId: 0,
};
uploaderRef = React.createRef<PicUploader>();
props = {
setFloatLayout: (_: boolean) => {},
id: 0,
didMount: false,
};
handleCommentChange(comment: string) {
this.setState({
comment: comment,
});
return comment;
}
onCommentSubmit() {
this.setState({
isDisable: true,
});
this.props.setFloatLayout(false);
if (this.state.comment == '') {
Taro.atMessage({
message: pt.get().button.submitText.blank,
type: 'error',
});
setTimeout(() => {
this.setState({
isDisable: false,
});
}, submitInterval);
return;
}
submitComment(this);
this.uploaderRef.current?.onUpload();
setTimeout(() => {
this.setState({
isDisable: false,
});
}, submitInterval);
}
render(): ReactNode {
return this.props.didMount ? (
<AtForm onSubmit={this.onCommentSubmit.bind(this)}>
<AtTextarea
value={this.state.comment}
onChange={this.handleCommentChange.bind(this)}
maxLength={200}
height='400rpx'
placeholder={pt.get().ticketDetail.comment.placeholder}
/>
<ExpandItem
title={pt.get().ticketDetail.comment.uploadPic.title}
content={
<PicUploader
ref={this.uploaderRef}
source='comment'
superId={this.props.id}
id={this.state.commentId}
/>
}
/>
<AtButton
loading={this.state.isLoading}
disabled={this.state.isDisable}
formType='submit'
type='primary'
>
{pt.get().button.buttonText.submit}
</AtButton>
<View style={{ marginBottom: '20rpx' }}></View>
</AtForm>
) : (
<View></View>
);
}
}
+389 -136
View File
@@ -6,15 +6,14 @@ import {
AtActionSheet, AtActionSheet,
AtActionSheetItem, AtActionSheetItem,
AtButton, AtButton,
AtCheckbox,
AtFloatLayout, AtFloatLayout,
AtForm, AtForm,
AtMessage, AtMessage,
AtModal, AtModal,
AtTextarea,
} from 'taro-ui'; } from 'taro-ui';
import DetailFramework from '@/components/DetailFramework/DetailFramework'; import DetailFramework from '@/components/DetailFramework/DetailFramework';
import PageFooter from '@/components/PageFooter/PageFooter'; import PageFooter from '@/components/PageFooter/PageFooter';
import { submitComment } from '@/service/submitComment';
import Taro from '@tarojs/taro'; import Taro from '@tarojs/taro';
import wechatUser from '@/wechat'; import wechatUser from '@/wechat';
import { addToOreo } from '@/service/addToOreo'; import { addToOreo } from '@/service/addToOreo';
@@ -22,139 +21,270 @@ import { pickTicket } from '@/service/pickTicket';
import { retrieve } from '@/service/retrieve'; import { retrieve } from '@/service/retrieve';
import { changeStatus } from '@/service/changeStatus'; import { changeStatus } from '@/service/changeStatus';
import { getDisable } from '@/service/getDisable'; import { getDisable } from '@/service/getDisable';
import { StatusStr } from './TicketNote';
import { Comment } from './Comment';
const submitInterval = 5000; const submitInterval = 5000;
interface TicketDetailState { interface TicketDetailState {
id: number; id: number;
isMember: boolean; isMember: boolean;
showOreoModal: boolean; show: {
showCommentLayout: boolean; modal: {
showRetrieveModal: boolean; oreo: boolean;
showStatusSheet: boolean; retrieve: boolean;
showPickModal: boolean; pick: boolean;
comment: string; };
isOreoLoading: boolean; layout: {
isOreoDisable: boolean; comment: boolean;
isOreoDisable_main: boolean; reminder: boolean;
isPickLoading: boolean; };
isPickDisable: boolean; actionSheet: {
isPickDisable_main: boolean; status: boolean;
isRetrieveLoading: boolean; };
isRetrieveDisable: boolean; };
isRetrieveDisable_main: boolean; isLoading: {
isStatusLoading: boolean; oreo: boolean;
isStatusDisable: boolean; pick: boolean;
isCommentLoading: boolean; retrieve: boolean;
isCommentDisable: boolean; comment: boolean;
isCommentDisable_main: boolean; status: boolean;
reminder: boolean;
framework: boolean;
};
isDisable: {
oreo: boolean;
pick: boolean;
retrieve: boolean;
comment: boolean;
status: boolean;
reminder: boolean;
};
isDisable_main: {
oreo: boolean;
pick: boolean;
retrieve: boolean;
comment: boolean;
};
reminderList: Array<number>;
statusToBe: number;
} }
export default class TicketDetail extends Component<{}, TicketDetailState> { export default class TicketDetail extends Component<{}, TicketDetailState> {
state: Readonly<TicketDetailState> = { state: Readonly<TicketDetailState> = {
id: 0, id: 0,
isMember: false, isMember: false,
showOreoModal: false, show: {
showCommentLayout: false, modal: {
showRetrieveModal: false, oreo: false,
showStatusSheet: false, retrieve: false,
showPickModal: false, pick: false,
comment: '', },
isOreoLoading: false, layout: {
isOreoDisable: false, comment: false,
isOreoDisable_main: false, reminder: false,
isPickLoading: false, },
isPickDisable: false, actionSheet: {
isPickDisable_main: false, status: false,
isRetrieveLoading: false, },
isRetrieveDisable: false, },
isRetrieveDisable_main: false, isLoading: {
isStatusLoading: false, oreo: false,
isStatusDisable: false, pick: false,
isCommentLoading: false, retrieve: false,
isCommentDisable: false, comment: false,
isCommentDisable_main: false, status: false,
reminder: false,
framework: true,
},
isDisable: {
oreo: false,
pick: false,
retrieve: false,
comment: false,
status: false,
reminder: false,
},
isDisable_main: {
oreo: false,
pick: false,
retrieve: false,
comment: false,
},
reminderList: [],
// eslint-disable-next-line react/no-unused-state
statusToBe: 0,
}; };
componentDidMount(): void { componentDidMount(): void {
const { router } = getCurrentInstance(); const { router } = getCurrentInstance();
const id = router?.params.id as number; const id = Number(router?.params.id);
this.setState({ this.setState({
id: id, id: id,
isMember: wechatUser.getAccess(), isMember: wechatUser.getAccess(),
}); });
getDisable(this, id); getDisable(this, id);
this.setState({
isLoading: {
...this.state.isLoading,
framework: false,
},
});
} }
onAddToOreo(): void { onAddToOreo(): void {
this.setState({ this.setState({
showOreoModal: true, show: {
...this.state.show,
modal: {
...this.state.show.modal,
oreo: true,
},
},
}); });
} }
onAddComment(): void { onAddComment(): void {
this.setState({ this.setState({
showCommentLayout: true, show: {
...this.state.show,
layout: {
...this.state.show.layout,
comment: true,
},
},
}); });
} }
onRetrieved(): void { onRetrieved(): void {
this.setState({ this.setState({
showRetrieveModal: true, show: {
...this.state.show,
modal: {
...this.state.show.modal,
retrieve: true,
},
},
}); });
} }
onPick(): void { onPick(): void {
this.setState({ this.setState({
showPickModal: true, show: {
...this.state.show,
modal: {
...this.state.show.modal,
pick: true,
},
},
}); });
} }
onChangeStatus(): void { onChangeStatus(): void {
this.setState({ this.setState({
showStatusSheet: true, show: {
...this.state.show,
actionSheet: {
...this.state.show.actionSheet,
status: true,
},
},
}); });
} }
handleOreoCancel(): void { handleOreoCancel(): void {
this.setState({ this.setState({
showOreoModal: false, show: {
...this.state.show,
modal: {
...this.state.show.modal,
oreo: false,
},
},
}); });
} }
handleCommentCancel(): void { handleCommentCancel(): void {
this.setState({ this.setState({
showCommentLayout: false, show: {
...this.state.show,
layout: {
...this.state.show.layout,
comment: false,
},
},
});
}
handleReminderCancel(): void {
this.setState({
show: {
...this.state.show,
layout: {
...this.state.show.layout,
reminder: false,
},
},
}); });
} }
handleRetrieveCancel(): void { handleRetrieveCancel(): void {
this.setState({ this.setState({
showRetrieveModal: false, show: {
...this.state.show,
modal: {
...this.state.show.modal,
retrieve: false,
},
},
}); });
} }
handleStatusCancel(): void { handleStatusCancel(): void {
this.setState({ this.setState({
showStatusSheet: false, show: {
...this.state.show,
actionSheet: {
...this.state.show.actionSheet,
status: false,
},
},
}); });
} }
handlePickCancel(): void { handlePickCancel(): void {
this.setState({ this.setState({
showPickModal: false, show: {
...this.state.show,
modal: {
...this.state.show.modal,
pick: false,
},
},
}); });
} }
handleOreoConfirm(): void { handleOreoConfirm(): void {
this.setState({ this.setState({
isOreoDisable: true, isDisable: {
showOreoModal: false, ...this.state.isDisable,
oreo: true,
},
show: {
...this.state.show,
modal: {
...this.state.show.modal,
oreo: false,
},
},
}); });
addToOreo(this); addToOreo(this);
setTimeout(() => { setTimeout(() => {
this.setState({ this.setState({
isOreoDisable: false, isDisable: {
...this.state.isDisable,
oreo: false,
},
}); });
}, submitInterval); }, submitInterval);
return; return;
@@ -162,13 +292,25 @@ export default class TicketDetail extends Component<{}, TicketDetailState> {
handleRetrieveConfirm(): void { handleRetrieveConfirm(): void {
this.setState({ this.setState({
isRetrieveDisable: true, isDisable: {
showRetrieveModal: false, ...this.state.isDisable,
retrieve: true,
},
show: {
...this.state.show,
modal: {
...this.state.show.modal,
retrieve: false,
},
},
}); });
retrieve(this); retrieve(this);
setTimeout(() => { setTimeout(() => {
this.setState({ this.setState({
isRetrieveDisable: false, isDisable: {
...this.state.isDisable,
retrieve: false,
},
}); });
}, submitInterval); }, submitInterval);
return; return;
@@ -176,64 +318,159 @@ export default class TicketDetail extends Component<{}, TicketDetailState> {
handlePickConfirm(): void { handlePickConfirm(): void {
this.setState({ this.setState({
isPickDisable: true, isDisable: {
showPickModal: false, ...this.state.isDisable,
pick: true,
},
show: {
...this.state.show,
modal: {
...this.state.show.modal,
pick: false,
},
},
}); });
pickTicket(this); pickTicket(this);
setTimeout(() => { setTimeout(() => {
this.setState({ this.setState({
isPickDisable: false, isDisable: {
...this.state.isDisable,
pick: false,
},
}); });
}, submitInterval); }, submitInterval);
return; return;
} }
handleStatusChange(status: number): void { handleStatusChange(status: number): void {
if (status >= 3 && status <= 7) {
this.setState({ this.setState({
showStatusSheet: false, isDisable: {
isStatusDisable: true, ...this.state.isDisable,
status: true,
},
show: {
...this.state.show,
actionSheet: {
...this.state.show.actionSheet,
status: false,
},
layout: {
...this.state.show.layout,
reminder: true,
},
},
// eslint-disable-next-line react/no-unused-state
statusToBe: status,
});
} else {
this.setState({
isDisable: {
...this.state.isDisable,
status: true,
},
show: {
...this.state.show,
actionSheet: {
...this.state.show.actionSheet,
status: false,
},
},
// eslint-disable-next-line react/no-unused-state
statusToBe: status,
}); });
changeStatus(this, status); changeStatus(this, status);
}
setTimeout(() => { setTimeout(() => {
this.setState({ this.setState({
isStatusDisable: false, isDisable: {
...this.state.isDisable,
status: false,
},
}); });
}, submitInterval); }, submitInterval);
return; return;
} }
handleCommentChange(comment: string) { setFloatLayout(show: boolean) {
this.setState({ this.setState({
comment: comment, show: {
...this.state.show,
layout: {
...this.state.show.layout,
comment: show,
},
},
}); });
return comment;
} }
onCommentSubmit() { handleReminderChange(reminderList: Array<number>) {
this.setState({ this.setState({
isCommentDisable: true, reminderList: reminderList,
showCommentLayout: false, });
return reminderList;
}
onReminderSubmit() {
if (
this.state.reminderList.includes(1) &&
this.state.reminderList.includes(3)
) {
this.setState({
isDisable: {
...this.state.isDisable,
reminder: true,
},
show: {
...this.state.show,
layout: {
...this.state.show.layout,
reminder: false,
},
},
});
changeStatus(this, this.state.statusToBe);
} else {
this.setState({
isDisable: {
...this.state.isDisable,
reminder: true,
},
}); });
if (this.state.comment == '') {
Taro.atMessage({ Taro.atMessage({
message: pt.get().button.submitText.blank, message: pt.get().ticketDetail.reminder.error,
type: 'error', type: 'error',
}); });
setTimeout(() => {
this.setState({
isCommentDisable: false,
});
}, submitInterval);
return;
} }
submitComment(this);
setTimeout(() => { setTimeout(() => {
this.setState({ this.setState({
isCommentDisable: false, isDisable: {
...this.state.isDisable,
reminder: false,
},
}); });
}, submitInterval); }, submitInterval);
} }
reminderOption = [
{
value: 0,
label: pt.get().ticketDetail.reminder.r0,
},
{
value: 1,
label: pt.get().ticketDetail.reminder.r1,
},
{
value: 2,
label: pt.get().ticketDetail.reminder.r2,
},
{
value: 3,
label: pt.get().ticketDetail.reminder.r3,
},
];
render(): ReactNode { render(): ReactNode {
const middleButton = this.state.isMember ? ( const middleButton = this.state.isMember ? (
<View> <View>
@@ -246,14 +483,14 @@ export default class TicketDetail extends Component<{}, TicketDetailState> {
style={{ marginLeft: '20rpx', paddingRight: '10rpx', width: '50%' }} style={{ marginLeft: '20rpx', paddingRight: '10rpx', width: '50%' }}
> >
<AtButton <AtButton
loading={this.state.isPickLoading} loading={this.state.isLoading.pick}
disabled={ disabled={
this.state.isPickDisable || this.state.isPickDisable_main this.state.isDisable.pick || this.state.isDisable_main.pick
} }
type='secondary' type='secondary'
onClick={this.onPick.bind(this)} onClick={this.onPick.bind(this)}
> >
{pt.get().ticketDetail.pick} {pt.get().ticketDetail.button.pick}
</AtButton> </AtButton>
</View> </View>
<View <View
@@ -261,14 +498,14 @@ export default class TicketDetail extends Component<{}, TicketDetailState> {
style={{ marginLeft: '20rpx', paddingRight: '10rpx', width: '50%' }} style={{ marginLeft: '20rpx', paddingRight: '10rpx', width: '50%' }}
> >
<AtButton <AtButton
loading={this.state.isOreoLoading} loading={this.state.isLoading.oreo}
disabled={ disabled={
this.state.isOreoDisable || this.state.isOreoDisable_main this.state.isDisable.oreo || this.state.isDisable_main.oreo
} }
type='primary' type='primary'
onClick={this.onAddToOreo.bind(this)} onClick={this.onAddToOreo.bind(this)}
> >
{pt.get().ticketDetail.addToOreo} {pt.get().ticketDetail.button.addToOreo}
</AtButton> </AtButton>
</View> </View>
</View> </View>
@@ -281,12 +518,12 @@ export default class TicketDetail extends Component<{}, TicketDetailState> {
style={{ marginLeft: '20rpx', paddingRight: '10rpx', width: '50%' }} style={{ marginLeft: '20rpx', paddingRight: '10rpx', width: '50%' }}
> >
<AtButton <AtButton
loading={this.state.isStatusLoading} loading={this.state.isLoading.status}
disabled={this.state.isStatusDisable} disabled={this.state.isDisable.status}
type='primary' type='primary'
onClick={this.onChangeStatus.bind(this)} onClick={this.onChangeStatus.bind(this)}
> >
{pt.get().ticketDetail.status.button} {pt.get().ticketDetail.button.status}
</AtButton> </AtButton>
</View> </View>
<View <View
@@ -295,13 +532,14 @@ export default class TicketDetail extends Component<{}, TicketDetailState> {
> >
<AtButton <AtButton
disabled={ disabled={
this.state.isCommentDisable || this.state.isCommentDisable_main this.state.isDisable.comment ||
this.state.isDisable_main.comment
} }
loading={this.state.isCommentLoading} loading={this.state.isLoading.comment}
type='secondary' type='secondary'
onClick={this.onAddComment.bind(this)} onClick={this.onAddComment.bind(this)}
> >
{pt.get().ticketDetail.addNote} {pt.get().ticketDetail.button.addNote}
</AtButton> </AtButton>
</View> </View>
</View> </View>
@@ -316,14 +554,15 @@ export default class TicketDetail extends Component<{}, TicketDetailState> {
style={{ marginLeft: '20rpx', paddingRight: '10rpx', width: '50%' }} style={{ marginLeft: '20rpx', paddingRight: '10rpx', width: '50%' }}
> >
<AtButton <AtButton
loading={this.state.isRetrieveLoading} loading={this.state.isLoading.retrieve}
disabled={ disabled={
this.state.isRetrieveDisable || this.state.isRetrieveDisable_main this.state.isDisable.retrieve ||
this.state.isDisable_main.retrieve
} }
type='primary' type='primary'
onClick={this.onRetrieved.bind(this)} onClick={this.onRetrieved.bind(this)}
> >
{pt.get().ticketDetail.tookAway} {pt.get().ticketDetail.button.tookAway}
</AtButton> </AtButton>
</View> </View>
<View <View
@@ -332,18 +571,38 @@ export default class TicketDetail extends Component<{}, TicketDetailState> {
> >
<AtButton <AtButton
disabled={ disabled={
this.state.isCommentDisable || this.state.isCommentDisable_main this.state.isDisable.comment || this.state.isDisable_main.comment
} }
loading={this.state.isCommentLoading} loading={this.state.isLoading.comment}
type='secondary' type='secondary'
onClick={this.onAddComment.bind(this)} onClick={this.onAddComment.bind(this)}
> >
{pt.get().ticketDetail.addNote} {pt.get().ticketDetail.button.addNote}
</AtButton> </AtButton>
</View> </View>
</View> </View>
); );
const actionSheetItemList: Array<StatusStr> = [
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
];
const sheetItemsRenderer = actionSheetItemList.map((item, idx) => (
<AtActionSheetItem
key={idx}
onClick={this.handleStatusChange.bind(this, idx)}
>
{pt.get().ticketDetail.statusModifyMessage.get(item)}
</AtActionSheetItem>
));
const isInfoShow = { const isInfoShow = {
device: true, device: true,
createdTime: true, createdTime: true,
@@ -352,13 +611,14 @@ export default class TicketDetail extends Component<{}, TicketDetailState> {
current: true, current: true,
notelist: true, notelist: true,
showAllNotes: true, showAllNotes: true,
pic: true,
}; };
return ( return (
<View> <View>
<AtMessage /> <AtMessage />
<AtModal <AtModal
isOpened={this.state.showOreoModal} isOpened={this.state.show.modal.oreo}
title={pt.get().modal.addToOreo.title} title={pt.get().modal.addToOreo.title}
cancelText={pt.get().modal.cancel} cancelText={pt.get().modal.cancel}
confirmText={pt.get().modal.confirm} confirmText={pt.get().modal.confirm}
@@ -367,7 +627,7 @@ export default class TicketDetail extends Component<{}, TicketDetailState> {
content={pt.get().modal.addToOreo.content} content={pt.get().modal.addToOreo.content}
/> />
<AtModal <AtModal
isOpened={this.state.showRetrieveModal} isOpened={this.state.show.modal.retrieve}
title={pt.get().modal.retrieve.title} title={pt.get().modal.retrieve.title}
cancelText={pt.get().modal.cancel} cancelText={pt.get().modal.cancel}
confirmText={pt.get().modal.confirm} confirmText={pt.get().modal.confirm}
@@ -376,7 +636,7 @@ export default class TicketDetail extends Component<{}, TicketDetailState> {
content={pt.get().modal.retrieve.content} content={pt.get().modal.retrieve.content}
/> />
<AtModal <AtModal
isOpened={this.state.showPickModal} isOpened={this.state.show.modal.pick}
title={pt.get().modal.pick.title} title={pt.get().modal.pick.title}
cancelText={pt.get().modal.cancel} cancelText={pt.get().modal.cancel}
confirmText={pt.get().modal.confirm} confirmText={pt.get().modal.confirm}
@@ -385,60 +645,53 @@ export default class TicketDetail extends Component<{}, TicketDetailState> {
content={pt.get().modal.pick.content} content={pt.get().modal.pick.content}
/> />
<AtFloatLayout <AtFloatLayout
isOpened={this.state.showCommentLayout} isOpened={this.state.show.layout.comment}
title={pt.get().ticketDetail.comment.title} title={pt.get().ticketDetail.comment.title}
onClose={this.handleCommentCancel.bind(this)} onClose={this.handleCommentCancel.bind(this)}
> >
<AtForm onSubmit={this.onCommentSubmit.bind(this)}> <Comment
<AtTextarea setFloatLayout={this.setFloatLayout.bind(this)}
value={this.state.comment} id={this.state.id}
onChange={this.handleCommentChange.bind(this)} didMount={this.state.show.layout.comment}
maxLength={200}
height='400rpx'
placeholder={pt.get().ticketDetail.comment.placeholder}
/> />
<AtButton formType='submit' type='primary'> </AtFloatLayout>
<AtFloatLayout
isOpened={this.state.show.layout.reminder}
title={pt.get().ticketDetail.reminder.title}
onClose={this.handleReminderCancel.bind(this)}
>
<AtForm onSubmit={this.onReminderSubmit.bind(this)}>
<AtCheckbox
options={this.reminderOption}
selectedList={this.state.reminderList}
onChange={this.handleReminderChange.bind(this)}
/>
<AtButton
loading={this.state.isLoading.reminder}
formType='submit'
type='primary'
disabled={this.state.isDisable.reminder}
>
{pt.get().button.buttonText.submit} {pt.get().button.buttonText.submit}
</AtButton> </AtButton>
</AtForm> </AtForm>
</AtFloatLayout> </AtFloatLayout>
<AtActionSheet <AtActionSheet
isOpened={this.state.showStatusSheet} isOpened={this.state.show.actionSheet.status}
cancelText={pt.get().ticketDetail.status.cancel} cancelText={pt.get().ticketDetail.status.cancel}
title={pt.get().ticketDetail.status.title} title={pt.get().ticketDetail.status.title}
onCancel={this.handleStatusCancel.bind(this)} onCancel={this.handleStatusCancel.bind(this)}
onClose={this.handleStatusCancel.bind(this)} onClose={this.handleStatusCancel.bind(this)}
> >
<AtActionSheetItem onClick={this.handleStatusChange.bind(this, 0)}> {sheetItemsRenderer}
{pt.get().ticketDetail.status.status0}
</AtActionSheetItem>
<AtActionSheetItem onClick={this.handleStatusChange.bind(this, 1)}>
{pt.get().ticketDetail.status.status1}
</AtActionSheetItem>
<AtActionSheetItem onClick={this.handleStatusChange.bind(this, 2)}>
{pt.get().ticketDetail.status.status2}
</AtActionSheetItem>
<AtActionSheetItem onClick={this.handleStatusChange.bind(this, 3)}>
{pt.get().ticketDetail.status.status3}
</AtActionSheetItem>
<AtActionSheetItem onClick={this.handleStatusChange.bind(this, 4)}>
{pt.get().ticketDetail.status.status4}
</AtActionSheetItem>
<AtActionSheetItem onClick={this.handleStatusChange.bind(this, 5)}>
{pt.get().ticketDetail.status.status5}
</AtActionSheetItem>
<AtActionSheetItem onClick={this.handleStatusChange.bind(this, 6)}>
{pt.get().ticketDetail.status.status6}
</AtActionSheetItem>
<AtActionSheetItem onClick={this.handleStatusChange.bind(this, 7)}>
{pt.get().ticketDetail.status.status7}
</AtActionSheetItem>
</AtActionSheet> </AtActionSheet>
{!this.state.isLoading.framework && (
<DetailFramework <DetailFramework
middleButton={middleButton} middleButton={middleButton}
id={this.state.id} id={this.state.id}
isInfoShow={isInfoShow} isInfoShow={isInfoShow}
/> />
)}
<PageFooter /> <PageFooter />
</View> </View>
); );
+3 -2
View File
@@ -16,9 +16,10 @@ export class TicketNote {
avatar: string; avatar: string;
id: number; id: number;
op: string; op: string;
type: 0 | 1 | 2; type: 0 | 1 | 2 | 3;
content: string; content: string;
createdTime: moment.Moment; createdTime: moment.Moment;
pic: string[];
} }
export class ShowElements { export class ShowElements {
@@ -30,4 +31,4 @@ export class ShowElements {
notelist: JSX.Element; notelist: JSX.Element;
} }
export type StatusStr = '1' | '2' | '3' | '4' | '5'; export type StatusStr = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7';
@@ -0,0 +1,3 @@
export default definePageConfig({
usingComponents: {},
});
+109
View File
@@ -0,0 +1,109 @@
import { Component, ReactNode } from 'react';
import { View } from '@tarojs/components';
import {
AtActivityIndicator,
AtList,
AtPagination,
AtSearchBar,
AtToast,
} from 'taro-ui';
import Taro from '@tarojs/taro';
import moment from 'moment';
import pt from '@/plain-text';
import PageFooter from '@/components/PageFooter/PageFooter';
import { RequestState } from '@/service';
import { getTicketList, searchTicketList } from '@/service/ticketList';
import { TicketListItem } from '@/components/TicketListItem/TicketListItem';
import './TicketList.scss';
interface TicketListState {
fixList: Array<TicketListItem>;
rs: RequestState;
currentPage: number;
totalPage: number;
pageSize: number;
search: string;
}
export default class TicketListPage extends Component<{}, TicketListState> {
state = {
fixList: [new TicketListItem(0, '', '', 1, moment())],
rs: new RequestState(),
currentPage: 1,
totalPage: 1,
pageSize: 8,
search: '',
};
componentDidMount(): void {
Taro.setNavigationBarTitle({
title: pt.get().navBar.ticketList,
});
getTicketList(this);
}
onPageChange(): void {
this.setState({
rs: new RequestState(),
});
getTicketList(this);
}
onSearchChange(search): void {
this.setState({
search: search,
});
return search;
}
onActionClick(): void {
this.setState({
rs: new RequestState(),
});
searchTicketList(this);
}
render(): ReactNode {
if (this.state.rs.loading) {
return (
<AtActivityIndicator
mode='center'
content={pt.get().actIndicator.loading}
></AtActivityIndicator>
);
}
if (!this.state.rs.success) {
return (
<AtToast
isOpened
text={pt.get().toast.error}
icon='close-circle'
></AtToast>
);
}
const fixListRenderer = this.state.fixList.map((item) => item.render());
return (
<View>
<View style={{ marginTop: '20rpx', marginBottom: '20rpx' }}>
<AtSearchBar
actionName={pt.get().ticketList.search}
value={this.state.search}
onChange={this.onSearchChange.bind(this)}
onActionClick={this.onActionClick.bind(this)}
/>
</View>
<AtList>{fixListRenderer}</AtList>
<View style={{ marginTop: '40rpx' }}>
<AtPagination
icon
total={this.state.totalPage}
pageSize={this.state.pageSize}
current={this.state.currentPage}
onPageChange={this.onPageChange.bind(this)}
></AtPagination>
</View>
<PageFooter />
</View>
);
}
}
+41 -13
View File
@@ -4,31 +4,35 @@ import { AtTimeline } from 'taro-ui';
import pt from '@/plain-text'; import pt from '@/plain-text';
import tick from '@/assets/icons/MainPage/tick.svg'; import tick from '@/assets/icons/MainPage/tick.svg';
import cross from '@/assets/icons/MainPage/cross.svg'; import cross from '@/assets/icons/MainPage/cross.svg';
import clock from '@/assets/icons/MemberPage/clock.svg'; import clock from '@/assets/icons/MainPage/offduty.svg';
import wechatUser from '@/wechat'; import wechatUser from '@/wechat';
import moment from 'moment';
export class DutyData { export class DutyData {
constructor() { constructor() {
this.isInDuty = false; this.isInDuty = false;
this.inDutyCnt = 3; this.inDutyCnt = 3;
this.currentDuty = '2'; this.currentDuty = '1';
this.offDutyReason = '学园维修'; this.otherDutyStart = '2024-03-07T13:30:48.523303';
this.dutyRecoverTime = '下周一'; this.otherDutyEnd = '2024-03-07T16:00:48.523303';
this.dutyRecoverTime = '13:30';
this.place = '东三-204'; this.place = '东三-204';
} }
isInDuty: boolean; isInDuty: boolean;
inDutyCnt?: number; inDutyCnt: number;
currentDuty?: 'off' | '1' | '2' | '3' | 'others'; currentDuty: 'off' | '0' | '1' | '2' | '3' | 'others';
offDutyReason?: string; otherDutyStart: string;
dutyRecoverTime?: string; otherDutyEnd: string;
offDutyReason: string;
dutyRecoverTime: string;
place: string; place: string;
} }
class Card extends Component { class Card extends Component {
props = { props = {
isInDuty: false, isInDuty: false,
place: '东三-204', place: pt.get().common.place,
}; };
render(): ReactNode { render(): ReactNode {
const inDuty = this.props.isInDuty; const inDuty = this.props.isInDuty;
@@ -85,8 +89,18 @@ export class DutyInfo extends Component {
<Card isInDuty={data.isInDuty} place={data.place} /> <Card isInDuty={data.isInDuty} place={data.place} />
<AtTimeline <AtTimeline
items={[ items={[
{ title: od.reason(data.offDutyReason as string) }, {
{ title: od.recoverTime(data.dutyRecoverTime as string) }, title:
data.currentDuty == '0'
? od.reason(pt.get().common.offDutyReason)
: od.reason(data.offDutyReason as string),
},
{
title:
data.currentDuty == '0'
? od.recoverTime(pt.get().common.dutyRecoverTime)
: od.recoverTime(data.dutyRecoverTime as string),
},
]} ]}
/> />
</View> </View>
@@ -101,8 +115,22 @@ export class DutyInfo extends Component {
<Card isInDuty={data.isInDuty} place={data.place} /> <Card isInDuty={data.isInDuty} place={data.place} />
<AtTimeline <AtTimeline
items={[ items={[
{ title: id.currentDutyText(data.currentDuty || 'off') }, {
{ title: id.inDutyCnt(data.inDutyCnt as number) }, title:
data.currentDuty == 'others'
? id.currentDutyText('others') +
moment(data.otherDutyStart).format('H:mm') +
' - ' +
moment(data.otherDutyEnd).format('H:mm')
: id.currentDutyText(data.currentDuty || 'off'),
},
{
title: id.inDutyCnt(
data.inDutyCnt === 0
? pt.get().common.zeroMemberOnDuty
: data.inDutyCnt.toString(),
),
},
]} ]}
/> />
</View> </View>
+31 -8
View File
@@ -1,34 +1,57 @@
import React from 'react'; import React from 'react';
import { View, Image } from '@tarojs/components'; import { View, Image } from '@tarojs/components';
import { AtButton } from 'taro-ui';
import pt from '@/plain-text'; import pt from '@/plain-text';
import logo from '@/assets/images/UserPage/logo.png';
import wechatUser from '@/wechat'; import wechatUser from '@/wechat';
import Taro from '@tarojs/taro';
const logo = 'https://wiki.zjueva.net/images/evalogo_hd.png';
export default class TitleCard extends React.Component { export default class TitleCard extends React.Component {
onAskLeave() {
Taro.redirectTo({
url: '/pages/AskLeave/AskLeave',
});
}
render(): React.ReactNode { render(): React.ReactNode {
const mainPage = pt.get().mainPage; const mainPage = pt.get().mainPage;
const memberPage = pt.get().memberPage; const memberPage = pt.get().memberPage;
return ( return (
<View className='at-row at-row__align--center'> <View className='at-row at-row__align--center at-row__justify--start'>
<View className='at-col at-col-1 at-col--auto'> <View className='at-col at-col-1 at-col--auto'>
<Image <Image
style='width: 100rpx; height: 100rpx; margin-left: 30rpx;' style='width: 100rpx; height: 100rpx; margin-left: 30rpx; border-radius: 50rpx'
src={wechatUser.getAccess() ? wechatUser.getInfo().avatar : logo} src={wechatUser.getAccess() ? wechatUser.getInfo().avatar : logo}
mode='aspectFit' mode='aspectFit'
/> />
</View> </View>
<View className='page-title'> <View
className={
wechatUser.getAccess()
? 'at-col page-title at-col-1 at-col--auto'
: 'at-col page-title at-col-10 at-col--wrap'
}
>
<View className='at-article__h1' style={{ fontWeight: 'bold' }}> <View className='at-article__h1' style={{ fontWeight: 'bold' }}>
{wechatUser.getAccess() {wechatUser.getAccess()
? memberPage.mainTitleLine + wechatUser.getInfo().name ? memberPage.titleLine.main.index + wechatUser.getInfo().name
: mainPage.mainTitleLine} : mainPage.titleLine.main}
</View> </View>
<View className='at-article__h2'> <View className='at-article__h2'>
{wechatUser.getAccess() {wechatUser.getAccess()
? memberPage.subTitleLine ? memberPage.titleLine.sub.index
: mainPage.subTitleLine} : mainPage.titleLine.sub}
</View> </View>
</View> </View>
{wechatUser.getAccess() ? (
<View className='at-col at-col-1 at-col--auto'>
<AtButton type='secondary' onClick={this.onAskLeave}>
{pt.get().mainPage.askLeave}
</AtButton>
</View>
) : (
<View></View>
)}
</View> </View>
); );
} }
+67 -37
View File
@@ -1,7 +1,16 @@
import { View } from '@tarojs/components'; import { View } from '@tarojs/components';
import { Component, ReactNode } from 'react'; import { Component, ReactNode } from 'react';
import Taro from '@tarojs/taro'; import Taro from '@tarojs/taro';
import { AtCard, AtAccordion, AtInputNumber, AtButton, AtList } from 'taro-ui'; import {
AtCard,
AtInputNumber,
AtButton,
AtList,
AtListItem,
AtActivityIndicator,
AtToast,
} from 'taro-ui';
import clockIcon from '@/assets/icons/MainPage/clock.svg';
import type CustomTabBar from '@/custom-tab-bar'; import type CustomTabBar from '@/custom-tab-bar';
import PageFooter from '@/components/PageFooter/PageFooter'; import PageFooter from '@/components/PageFooter/PageFooter';
import pt from '@/plain-text'; import pt from '@/plain-text';
@@ -13,6 +22,7 @@ import { getMemberDutyInfo } from '@/service/memberDutyInfo';
import { getUncompletedTicketList } from '@/service/uncompletedTicket'; import { getUncompletedTicketList } from '@/service/uncompletedTicket';
import { changeDutyCnt } from '@/service/changeDutyCount'; import { changeDutyCnt } from '@/service/changeDutyCount';
import { TicketListItem } from '@/components/TicketListItem/TicketListItem'; import { TicketListItem } from '@/components/TicketListItem/TicketListItem';
import { ExpandItem } from '@/components/ExpandItem/ExpandItem';
import './index.scss'; import './index.scss';
import TitleCard from './TitleCard'; import TitleCard from './TitleCard';
import { DutyInfo, DutyData } from './DutyInfo'; import { DutyInfo, DutyData } from './DutyInfo';
@@ -37,39 +47,10 @@ function mainPageCard(c: CardContent): JSX.Element {
); );
} }
class ExpandItem extends Component {
state = {
open: false,
};
props = {
title: '',
content: <View></View>,
};
handleClick(value: boolean) {
this.setState({ open: value });
}
render(): ReactNode {
return (
<View>
<AtAccordion
open={this.state.open}
onClick={this.handleClick.bind(this)}
title={this.props.title}
>
{this.props.content}
</AtAccordion>
</View>
);
}
}
interface MainPageState { interface MainPageState {
fixList: Array<TicketListItem>; fixList: Array<TicketListItem>;
rs: RequestState; rs: RequestState;
dutyData: DutyData; dutyData: DutyData;
inDutyCnt: number;
dutyInfoCard: CardContent; dutyInfoCard: CardContent;
stepInfoCard: CardContent; stepInfoCard: CardContent;
tipsInfoCard: CardContent; tipsInfoCard: CardContent;
@@ -80,7 +61,6 @@ interface MainPageState {
export default class MainPage extends Component<{}, MainPageState> { export default class MainPage extends Component<{}, MainPageState> {
state = { state = {
dutyData: new DutyData(), dutyData: new DutyData(),
inDutyCnt: 0,
dutyInfoCard: { dutyInfoCard: {
title: '', title: '',
note: '', note: '',
@@ -106,11 +86,9 @@ export default class MainPage extends Component<{}, MainPageState> {
}; };
componentDidMount(): void { componentDidMount(): void {
const ptPage = wechatUser.getAccess() ? 'mainPage' : 'memberPage'; const ptPage = wechatUser.getAccess() ? 'memberPage' : 'mainPage';
this.setState({ this.setState({
dutyData: new DutyData(), dutyData: new DutyData(),
inDutyCnt: 0,
dutyInfoCard: { dutyInfoCard: {
title: pt.get()[ptPage].cardTitle.dutyInfo, title: pt.get()[ptPage].cardTitle.dutyInfo,
note: pt.get()[ptPage].cardTips.dutyInfo, note: pt.get()[ptPage].cardTips.dutyInfo,
@@ -149,7 +127,10 @@ export default class MainPage extends Component<{}, MainPageState> {
handleCnt(inDutyCnt: number) { handleCnt(inDutyCnt: number) {
this.setState({ this.setState({
dutyData: {
...this.state.dutyData,
inDutyCnt: inDutyCnt, inDutyCnt: inDutyCnt,
},
}); });
return inDutyCnt; return inDutyCnt;
} }
@@ -166,14 +147,37 @@ export default class MainPage extends Component<{}, MainPageState> {
}, submitInterval); }, submitInterval);
} }
ticketListPage() {
Taro.navigateTo({
url: '/pages/TicketList/TicketList',
});
}
conclusionPage() {
Taro.navigateTo({
url: '/pages/Conclusion/Conclusion',
});
}
render(): ReactNode { render(): ReactNode {
const mainPage = pt.get().mainPage; const mainPage = pt.get().mainPage;
const memberPage = pt.get().memberPage; const memberPage = pt.get().memberPage;
if (this.state.rs.loading) { if (this.state.rs.loading) {
return <View>loading</View>; return (
<AtActivityIndicator
mode='center'
content={pt.get().actIndicator.loading}
></AtActivityIndicator>
);
} }
if (!this.state.rs.success) { if (!this.state.rs.success) {
return <View>Failed</View>; return (
<AtToast
isOpened
text={pt.get().toast.error}
icon='close-circle'
></AtToast>
);
} }
const fixListRenderer = this.state.fixList.map((item) => item.render()); const fixListRenderer = this.state.fixList.map((item) => item.render());
return ( return (
@@ -187,6 +191,7 @@ export default class MainPage extends Component<{}, MainPageState> {
<ExpandItem <ExpandItem
title={memberPage.expandTitle.admin} title={memberPage.expandTitle.admin}
content={ content={
<View style={{ marginBottom: '40rpx' }}>
<View <View
style={{ style={{
display: 'flex', display: 'flex',
@@ -212,7 +217,7 @@ export default class MainPage extends Component<{}, MainPageState> {
min={0} min={0}
max={10} max={10}
step={1} step={1}
value={this.state.inDutyCnt} value={this.state.dutyData.inDutyCnt}
onChange={this.handleCnt.bind(this)} onChange={this.handleCnt.bind(this)}
/> />
</View> </View>
@@ -228,6 +233,12 @@ export default class MainPage extends Component<{}, MainPageState> {
</AtButton> </AtButton>
</View> </View>
</View> </View>
<View>
<AtButton type='primary' onClick={this.conclusionPage}>
{pt.get().button.indexText.conclusion}
</AtButton>
</View>
</View>
} }
/> />
) : ( ) : (
@@ -239,7 +250,26 @@ export default class MainPage extends Component<{}, MainPageState> {
/> />
</View> </View>
{wechatUser.getAccess() ? ( {wechatUser.getAccess() ? (
<View style={{ marginTop: '40rpx' }}>
<View
className='at-article__h3'
style={{ marginBottom: '20rpx', fontWeight: 'bold' }}
>
{(this.state.fixList.length === 0
? memberPage.ticketList.nohint
: '') + memberPage.ticketList.hint}
</View>
<AtList>{fixListRenderer}</AtList> <AtList>{fixListRenderer}</AtList>
<AtList>
<AtListItem
title={pt.get().memberPage.ticketList.title}
note={pt.get().memberPage.ticketList.note}
arrow='right'
thumb={clockIcon}
onClick={this.ticketListPage}
/>
</AtList>
</View>
) : ( ) : (
<View></View> <View></View>
)} )}
+20 -6
View File
@@ -184,11 +184,18 @@ export default class RepairPage extends Component<{}, RepairPageState> {
} }
render(): ReactNode { render(): ReactNode {
const ticketsRenderer = const hasContinuingticket = this.state.currentTicketsIdName.length !== 0;
this.state.currentTicketsIdName.length !== 0 ? ( const ticketsRenderer = hasContinuingticket ? (
this.state.currentTicketsIdName.map((pair, idx) => ( <View>
<View
className='at-article__h3'
style={{ marginBottom: '20rpx', fontWeight: 'bold' }}
>
{pt.get().repairPage.currentTicket.hint}
</View>
{this.state.currentTicketsIdName.map((pair, idx) => (
<View key={idx} style={{ marginBottom: '20rpx' }}>
<AtCard <AtCard
key={idx}
title={pair.values().next().value} //pair.keys().next().value == ticket['device'] + ' ' + ticket['deviceModel'] title={pair.values().next().value} //pair.keys().next().value == ticket['device'] + ' ' + ticket['deviceModel']
extra={pt.get().repairPage.currentTicket.extra} extra={pt.get().repairPage.currentTicket.extra}
onClick={() => { onClick={() => {
@@ -210,9 +217,16 @@ export default class RepairPage extends Component<{}, RepairPageState> {
middleButton={middleButton} middleButton={middleButton}
/> />
</AtCard> </AtCard>
)) </View>
))}
</View>
) : ( ) : (
<View></View> <View
className='at-article__h3'
style={{ marginBottom: '20rpx', fontWeight: 'bold' }}
>
{pt.get().repairPage.currentTicket.nohint}
</View>
); );
return ( return (
<View style={{ width: '94%', marginLeft: '3%' }}> <View style={{ width: '94%', marginLeft: '3%' }}>
+17 -5
View File
@@ -2,6 +2,7 @@ import { Component, ReactNode } from 'react';
import { Image, View } from '@tarojs/components'; import { Image, View } from '@tarojs/components';
import Taro from '@tarojs/taro'; import Taro from '@tarojs/taro';
import pt from '@/plain-text'; import pt from '@/plain-text';
import PageFooter from '@/components/PageFooter/PageFooter';
import './about.scss'; import './about.scss';
export default class AboutPage extends Component { export default class AboutPage extends Component {
@@ -14,7 +15,10 @@ export default class AboutPage extends Component {
return ( return (
<View> <View>
<View <View
style={{ marginTop: '60rpx', marginBottom: '60rpx' }} style={{
marginTop: '200rpx',
marginBottom: '60rpx',
}}
className='at-row at-row__align--start' className='at-row at-row__align--start'
> >
<View className='at-col at-col-1 at-col--auto'> <View className='at-col at-col-1 at-col--auto'>
@@ -24,7 +28,10 @@ export default class AboutPage extends Component {
mode='aspectFit' mode='aspectFit'
/> />
</View> </View>
<View className='at-article at-col'> <View
className='at-article at-col at-col--wrap'
style={{ wordBreak: 'normal' }}
>
<View className='at-article__h1'> <View className='at-article__h1'>
{pt.get().aboutPage.dean.nickname} {pt.get().aboutPage.dean.nickname}
</View> </View>
@@ -40,17 +47,20 @@ export default class AboutPage extends Component {
</View> </View>
</View> </View>
<View <View
style={{ marginTop: '60rpx', marginBottom: '60rpx' }} style={{ marginTop: '100rpx', marginBottom: '60rpx' }}
className='at-row at-row__align--start' className='at-row at-row__align--start'
> >
<View className='at-col at-col-1 at-col--auto'> <View className='at-col at-col-1 at-col--auto'>
<Image <Image
style='width: 240rpx; height: 240rpx; margin-left: 60rpx; margin-right: 30rpx; margin-top: 30rpx; border-radius: 120rpx' style='width: 240rpx; height: 240rpx; margin-left: 60rpx; margin-right: 30rpx; margin-top: 30rpx; border-radius: 120rpx'
src='https://wiki.zjueva.net/images/1/10/%E5%A4%B4%E5%83%8F.jpg?20240319171222' src='https://static.fracher21.top/head.jpg'
mode='aspectFit' mode='aspectFit'
/> />
</View> </View>
<View className='at-article at-col'> <View
className='at-article at-col at-col--wrap'
style={{ wordBreak: 'normal' }}
>
<View className='at-article__h1'> <View className='at-article__h1'>
{pt.get().aboutPage.fracher.nickname} {pt.get().aboutPage.fracher.nickname}
</View> </View>
@@ -65,6 +75,8 @@ export default class AboutPage extends Component {
</View> </View>
</View> </View>
</View> </View>
<View style={{ height: '200rpx' }}></View>
<PageFooter />
</View> </View>
); );
} }
+22 -52
View File
@@ -1,5 +1,5 @@
import { Component, ReactNode } from 'react'; import { Component, ReactNode } from 'react';
import { AtForm, AtInput, AtButton, AtMessage } from 'taro-ui'; import { AtButton, AtMessage } from 'taro-ui';
import Taro from '@tarojs/taro'; import Taro from '@tarojs/taro';
import pt from '@/plain-text'; import pt from '@/plain-text';
import { memberLogin, memberLogout } from '@/service/memberLogin'; import { memberLogin, memberLogout } from '@/service/memberLogin';
@@ -11,8 +11,6 @@ const logInterval = 5000;
export default class UserMemberPage extends Component { export default class UserMemberPage extends Component {
state = { state = {
stuid: '',
passwd: '',
isLoading: false, isLoading: false,
isDisable: false, isDisable: false,
}; };
@@ -21,34 +19,11 @@ export default class UserMemberPage extends Component {
title: pt.get().navBar.user.memberLogin, title: pt.get().navBar.user.memberLogin,
}); });
} }
handleChangeStuid(stuid: string) {
this.setState({ onLogin() {
stuid: stuid,
});
return stuid;
}
handleChangePasswd(passwd: string) {
this.setState({
passwd: passwd,
});
return passwd;
}
onSubmit() {
this.setState({ this.setState({
isDisable: true, isDisable: true,
}); });
if (this.state.stuid == '' || this.state.passwd == '') {
Taro.atMessage({
message: pt.get().button.submitText.blank,
type: 'error',
});
setTimeout(() => {
this.setState({
isDisable: false,
});
}, logInterval);
return;
}
memberLogin(this); memberLogin(this);
setTimeout(() => { setTimeout(() => {
this.setState({ this.setState({
@@ -72,40 +47,35 @@ export default class UserMemberPage extends Component {
render(): ReactNode { render(): ReactNode {
return !wechatUser.getAccess() ? ( return !wechatUser.getAccess() ? (
<View style={{ marginTop: '30rpx', width: '94%', marginLeft: '3%' }}> <View style={{ marginTop: '30rpx', width: '94%', marginLeft: '3%' }}>
<AtForm onSubmit={this.onSubmit.bind(this)}>
<AtMessage /> <AtMessage />
<AtInput <View className='page-title' style={{ marginBottom: '40rpx' }}>
required <View className='at-article__h1' style={{ fontWeight: 'bold' }}>
name='stuid' {pt.get().memberPage.titleLine.main.login}
title={pt.get().memberPage.stuidText.title} </View>
type='number' <View className='at-article__h2'>
clear {pt.get().memberPage.titleLine.sub.login}
placeholder={pt.get().memberPage.stuidText.placeholder} </View>
value={this.state.stuid} </View>
onChange={this.handleChangeStuid.bind(this)}
/>
<AtInput
clear
required
name='name'
title={pt.get().memberPage.passwdText.title}
type='password'
placeholder={pt.get().memberPage.passwdText.placeholder}
value={this.state.passwd}
onChange={this.handleChangePasswd.bind(this)}
/>
<AtButton <AtButton
loading={this.state.isLoading} loading={this.state.isLoading}
formType='submit'
type='primary' type='primary'
disabled={this.state.isDisable} disabled={this.state.isDisable}
onClick={this.onLogin.bind(this)}
> >
{pt.get().button.buttonText.login} {pt.get().button.memberText.auth}
</AtButton> </AtButton>
</AtForm>
</View> </View>
) : ( ) : (
<View style={{ marginTop: '30rpx', width: '94%', marginLeft: '3%' }}> <View style={{ marginTop: '30rpx', width: '94%', marginLeft: '3%' }}>
<AtMessage />
<View className='page-title' style={{ marginBottom: '40rpx' }}>
<View className='at-article__h1' style={{ fontWeight: 'bold' }}>
{pt.get().memberPage.titleLine.main.logout}
</View>
<View className='at-article__h2'>
{pt.get().memberPage.titleLine.sub.logout}
</View>
</View>
<AtButton type='primary' onClick={this.onLogout.bind(this)}> <AtButton type='primary' onClick={this.onLogout.bind(this)}>
{pt.get().button.buttonText.logout} {pt.get().button.buttonText.logout}
</AtButton> </AtButton>
+14 -3
View File
@@ -1,6 +1,6 @@
import { Component, ReactNode } from 'react'; import { Component, ReactNode } from 'react';
import { View } from '@tarojs/components'; import { View } from '@tarojs/components';
import { AtList } from 'taro-ui'; import { AtActivityIndicator, AtList, AtToast } from 'taro-ui';
import Taro from '@tarojs/taro'; import Taro from '@tarojs/taro';
import moment from 'moment'; import moment from 'moment';
import pt from '@/plain-text'; import pt from '@/plain-text';
@@ -29,10 +29,21 @@ export default class MyTicketPage extends Component<{}, MyTicketState> {
render(): ReactNode { render(): ReactNode {
if (this.state.rs.loading) { if (this.state.rs.loading) {
return <View>loading</View>; return (
<AtActivityIndicator
mode='center'
content={pt.get().actIndicator.loading}
></AtActivityIndicator>
);
} }
if (!this.state.rs.success) { if (!this.state.rs.success) {
return <View>Failed</View>; return (
<AtToast
isOpened
text={pt.get().toast.error}
icon='close-circle'
></AtToast>
);
} }
const fixListRenderer = this.state.fixList.map((item) => item.render()); const fixListRenderer = this.state.fixList.map((item) => item.render());
return ( return (
+1 -2
View File
@@ -64,6 +64,7 @@ export default class ReportPage extends Component {
<AtMessage /> <AtMessage />
<AtTextarea <AtTextarea
value={this.state.report} value={this.state.report}
height={400}
onChange={this.handleChange.bind(this)} onChange={this.handleChange.bind(this)}
maxLength={200} maxLength={200}
placeholder={pt.get().reportPage.placeHolderText} placeholder={pt.get().reportPage.placeHolderText}
@@ -74,7 +75,6 @@ export default class ReportPage extends Component {
style={{ style={{
marginTop: '30rpx', marginTop: '30rpx',
marginRight: '10rpx', marginRight: '10rpx',
marginLeft: '10rpx',
width: '50%', width: '50%',
}} }}
> >
@@ -86,7 +86,6 @@ export default class ReportPage extends Component {
className='at-col' className='at-col'
style={{ style={{
marginTop: '30rpx', marginTop: '30rpx',
marginRight: '10rpx',
marginLeft: '10rpx', marginLeft: '10rpx',
width: '50%', width: '50%',
}} }}
+4 -4
View File
@@ -9,11 +9,11 @@ import userIcon from '@/assets/icons/UserPage/user.svg';
import clockIcon from '@/assets/icons/UserPage/clock.svg'; import clockIcon from '@/assets/icons/UserPage/clock.svg';
import messageIcon from '@/assets/icons/UserPage/message.svg'; import messageIcon from '@/assets/icons/UserPage/message.svg';
import pt, { Lang } from '@/plain-text'; import pt, { Lang } from '@/plain-text';
import logo from '@/assets/images/UserPage/logo.png';
import { setLocaleData } from '@/service/localeData'; import { setLocaleData } from '@/service/localeData';
import wechatUser from '@/wechat'; import wechatUser from '@/wechat';
import './user.scss'; import './user.scss';
const logo = 'https://wiki.zjueva.net/images/evalogo_hd.png';
const memberClickTimes = 7; const memberClickTimes = 7;
export default class UserPage extends Component { export default class UserPage extends Component {
@@ -43,9 +43,9 @@ export default class UserPage extends Component {
if (this.state.clicks < 3) { if (this.state.clicks < 3) {
this.setState({ this.setState({
toastText: toastText:
pt.get().userPage.memberEntry.front + pt.get().userPage.memberEntry.prefix +
(this.state.clicks + 1).toString() + // React State's feature (this.state.clicks + 1).toString() + // React State's feature
pt.get().userPage.memberEntry.behind, pt.get().userPage.memberEntry.affix,
isToastOpen: true, isToastOpen: true,
}); });
if (this.state.clicks == 0) { if (this.state.clicks == 0) {
@@ -123,7 +123,7 @@ export default class UserPage extends Component {
className='at-row at-row__justify--center at-row__align--center' className='at-row at-row__justify--center at-row__align--center'
style='height:120rpx;color:#696969;' style='height:120rpx;color:#696969;'
> >
<Text style={{ fontSize: '32rpx' }}> EVA Notify v1.0.0</Text> <Text style={{ fontSize: '32rpx' }}> EVA Eta v1.1.0</Text>
</View> </View>
<AtList> <AtList>
<AtListItem <AtListItem
+21
View File
@@ -0,0 +1,21 @@
export interface NotFoundText {
title: {
ZhCn: string;
EnUs: string;
};
desc: {
ZhCn: string;
EnUs: string;
};
}
export const notFound: NotFoundText = {
title: {
ZhCn: '啊哦...请求出错了...',
EnUs: 'Oops...Network Error...',
},
desc: {
ZhCn: '请确保处于校网环境后,点击右上角 "...-重新进入小程序"!',
EnUs: 'Please make sure you\'re in ZJU\'s school network environment and then click on the top right corner "... - re-enter the applet"!',
},
};
+4 -4
View File
@@ -23,8 +23,8 @@ export const aboutPageZhCn: AboutPageText = {
fracher: { fracher: {
nickname: '宇航员', nickname: '宇航员',
username: '@ FrozenArcher', username: '@ FrozenArcher',
status: 'Ate 总设计, Eta 合作贡献者', status: 'Ate 总设计, 项目合作贡献者',
note: '6~', note: 'React 真是太有意思了',
}, },
}; };
@@ -38,7 +38,7 @@ export const aboutPageEnUs: AboutPageText = {
fracher: { fracher: {
nickname: 'Fracher', nickname: 'Fracher',
username: '@ FrozenArcher', username: '@ FrozenArcher',
status: "Ate's General Designer, Eta's Contributor", status: "Ate's General Designer, Project's Contributor",
note: '6~', note: 'React is so fun',
}, },
}; };
+11
View File
@@ -0,0 +1,11 @@
export interface ActIndicatorText {
loading: string;
}
export const actIndicatorZhCn: ActIndicatorText = {
loading: '加载中...',
};
export const actIndicatorEnUs: ActIndicatorText = {
loading: 'Loading...',
};
+60
View File
@@ -0,0 +1,60 @@
export interface AskLeaveText {
modal: {
title: string;
content: string;
};
shift: {
title: string;
week: string[];
shift: string[];
};
reason: {
title: string;
placeHolder: string;
};
substitute: {
title: string;
placeHolder: string;
};
}
export const askLeaveZhCn: AskLeaveText = {
modal: {
title: '确认无代班?',
content: '值班人数少于 4 时须填写代班人员。请假记录将会被上传保存!',
},
shift: {
title: '值班时间',
week: ['周一', '周二', '周三', '周四', '周五', '周六', '周日'],
shift: ['第一班', '第二班', '第三班'],
},
reason: {
title: '请假原因',
placeHolder: '请在此说明请假原因',
},
substitute: {
title: '替班人员',
placeHolder: '人数少于 4 时必填!',
},
};
export const askLeaveEnUs: AskLeaveText = {
modal: {
title: 'Confirm no substitute?',
content:
'Must have substitute if members are less than 4! The ticket will be uploaded and saved!',
},
shift: {
title: 'Duty time',
week: ['Mon.', 'Tue.', 'Wed.', 'Thu.', 'Fri.', 'Sat.', 'Sun.'],
shift: ['1st Shift', '2nd Shift', '3rd Shift'],
},
reason: {
title: 'Reason',
placeHolder: 'Leave your reason for leaving here',
},
substitute: {
title: 'Substitute',
placeHolder: 'Must have if members are less than 4!',
},
};
+21
View File
@@ -10,6 +10,13 @@ export interface ButtonText {
error: string; error: string;
blank: string; blank: string;
}; };
memberText: {
auth: string;
};
indexText: {
conclusion: string;
askLeave: string;
};
loginText: { loginText: {
success: string; success: string;
error: string; error: string;
@@ -33,6 +40,13 @@ export const buttonZhCn: ButtonText = {
error: '提交失败:', error: '提交失败:',
blank: '请填写完整!', blank: '请填写完整!',
}, },
memberText: {
auth: '协会统一身份认证登录',
},
indexText: {
conclusion: '提交值班总结',
askLeave: '我要请假',
},
loginText: { loginText: {
success: '登录成功', success: '登录成功',
error: '登录失败', error: '登录失败',
@@ -56,6 +70,13 @@ export const buttonEnUs: ButtonText = {
error: 'Error: ', error: 'Error: ',
blank: 'Please fill in the blanks!', blank: 'Please fill in the blanks!',
}, },
memberText: {
auth: 'EVA Auth Login Entry',
},
indexText: {
conclusion: 'Submit Duty Conclusion',
askLeave: 'Ask for Leave',
},
loginText: { loginText: {
success: 'Login Success', success: 'Login Success',
error: 'Login Failed', error: 'Login Failed',
+16
View File
@@ -0,0 +1,16 @@
export interface ConclusionText {
title: string;
placeHolder: string;
}
export const conclusionTextZhCn: ConclusionText = {
title: '值班总结',
placeHolder:
'请在此填写完整的值班情况,包括:几人请假;收到几台电脑;后续的处理情况;上一班交接的电脑情况;下一班对接的电脑情况;另外,请拍照记录值班桌整理情况',
};
export const conclusionTextEnUs: ConclusionText = {
title: 'Duty Conclusion',
placeHolder:
'Please fill in the complete duty situation here, including: how many people were on leave; how many computers were received; how the follow-up was handled; how the computers were handed over by the previous shift; how the computers were docked by the next shift; Also, please take photos to document the organization of the duty desk',
};
+28 -12
View File
@@ -1,6 +1,10 @@
export interface MainPageText { export interface MainPageText {
mainTitleLine: string; askLeave: string;
subTitleLine: string; conclusion: string;
titleLine: {
main: string;
sub: string;
};
cardTitle: { cardTitle: {
dutyInfo: string; dutyInfo: string;
stepInfo: string; stepInfo: string;
@@ -31,15 +35,19 @@ export interface MainPageText {
}; };
inDuty: { inDuty: {
title: string; title: string;
currentDutyText: (c: 'off' | '1' | '2' | '3' | 'others') => string; currentDutyText: (c: 'off' | '0' | '1' | '2' | '3' | 'others') => string;
inDutyCnt: (n: number) => string; inDutyCnt: (n: string) => string;
}; };
}; };
} }
export const mainPageZhCn: MainPageText = { export const mainPageZhCn: MainPageText = {
mainTitleLine: '您好,这里是E志者协会', askLeave: '我要请假',
subTitleLine: '维修请至【东三-204】实验室', conclusion: '提交值班总结',
titleLine: {
main: '您好,这里是E志者协会',
sub: '维修请至【东三-204】实验室',
},
cardTitle: { cardTitle: {
dutyInfo: '值班情况', dutyInfo: '值班情况',
stepInfo: '维修步骤', stepInfo: '维修步骤',
@@ -82,7 +90,9 @@ export const mainPageZhCn: MainPageText = {
currentDutyText: (c) => { currentDutyText: (c) => {
switch (c) { switch (c) {
case 'off': case 'off':
return '当前未值班'; return '暂停值班';
case '0':
return '休息中';
case '1': case '1':
return '第一班 13:30-16:00'; return '第一班 13:30-16:00';
case '2': case '2':
@@ -90,7 +100,7 @@ export const mainPageZhCn: MainPageText = {
case '3': case '3':
return '第三班 18:00-20:30'; return '第三班 18:00-20:30';
case 'others': case 'others':
return '其他值班时间,见通知'; return '当班 ';
} }
}, },
inDutyCnt: (n) => '当前值班人数:' + n, inDutyCnt: (n) => '当前值班人数:' + n,
@@ -99,8 +109,12 @@ export const mainPageZhCn: MainPageText = {
}; };
export const mainPageEnUs: MainPageText = { export const mainPageEnUs: MainPageText = {
mainTitleLine: 'Hi! This is EVA.', askLeave: 'Absence',
subTitleLine: 'For maintenance, please go to [204 Lab, E3 building]', conclusion: 'Submit Duty Conclusion',
titleLine: {
main: 'Hi! This is EVA.',
sub: 'For maintenance, please go to [204 Lab, E3 building]',
},
cardTitle: { cardTitle: {
dutyInfo: 'Duty Situation', dutyInfo: 'Duty Situation',
stepInfo: 'Maintenance Steps', stepInfo: 'Maintenance Steps',
@@ -143,7 +157,9 @@ export const mainPageEnUs: MainPageText = {
currentDutyText: (c) => { currentDutyText: (c) => {
switch (c) { switch (c) {
case 'off': case 'off':
return 'Currently not on duty'; return 'Duty paused';
case '0':
return 'Normal Shift';
case '1': case '1':
return '1st Shift 13:30-16:00'; return '1st Shift 13:30-16:00';
case '2': case '2':
@@ -151,7 +167,7 @@ export const mainPageEnUs: MainPageText = {
case '3': case '3':
return '3rd Shift 18:00-20:30'; return '3rd Shift 18:00-20:30';
case 'others': case 'others':
return 'Other duty time, see notice'; return 'Current Shift ';
} }
}, },
inDutyCnt: (n) => 'EVA members on duty: ' + n, inDutyCnt: (n) => 'EVA members on duty: ' + n,
+62 -21
View File
@@ -1,6 +1,16 @@
export interface MemberPageText { export interface MemberPageText {
mainTitleLine: string; titleLine: {
subTitleLine: string; main: {
index: string;
login: string;
logout: string;
};
sub: {
index: string;
login: string;
logout: string;
};
};
cardTitle: { cardTitle: {
dutyInfo: string; dutyInfo: string;
stepInfo: string; stepInfo: string;
@@ -18,9 +28,6 @@ export interface MemberPageText {
title: string; title: string;
placeholder: string; placeholder: string;
}; };
uncompletedTicket: {
extra: string;
};
dutyCard: { dutyCard: {
offDuty: { offDuty: {
title: string; title: string;
@@ -50,18 +57,34 @@ export interface MemberPageText {
}; };
stepList: Array<{ title: string }>; stepList: Array<{ title: string }>;
tipsList: Array<{ title: string }>; tipsList: Array<{ title: string }>;
ticketList: {
nohint: string;
hint: string;
title: string;
note: string;
};
} }
export const memberPageZhCn: MemberPageText = { export const memberPageZhCn: MemberPageText = {
mainTitleLine: '您好,', titleLine: {
subTitleLine: '祝你满绩每一天', main: {
index: '您好,',
login: '协会成员登录入口',
logout: '协会成员登出',
},
sub: {
index: '祝你满绩每一天',
login: '请使用 EVA 统一身份认证,登录后点击下方按钮以扫描二维码',
logout: '登出后须扫码重新登录!',
},
},
cardTitle: { cardTitle: {
dutyInfo: '值班情况', dutyInfo: '值班情况',
stepInfo: '维修步骤', stepInfo: '维修步骤',
tipsInfo: '注意事项', tipsInfo: '注意事项',
}, },
dutyCount: { dutyCount: {
button: '更新值班人数', button: '更新',
text: '当前值班人数:', text: '当前值班人数:',
}, },
stuidText: { stuidText: {
@@ -72,9 +95,6 @@ export const memberPageZhCn: MemberPageText = {
title: '密码', title: '密码',
placeholder: '与 EVA 统一身份认证一致', placeholder: '与 EVA 统一身份认证一致',
}, },
uncompletedTicket: {
extra: '详细信息',
},
dutyCard: { dutyCard: {
offDuty: { offDuty: {
title: '空闲', title: '空闲',
@@ -106,8 +126,8 @@ export const memberPageZhCn: MemberPageText = {
admin: '组长管理入口', admin: '组长管理入口',
}, },
cardTips: { cardTips: {
dutyInfo: '提示:可以先前往【维修】页面在线上预填写工单!', dutyInfo: '提示:如果有事不能值班,请及时请假!',
stepInfo: '提示:请在 20:30 之前取走自己的物品哦!', stepInfo: '提示:维修完成请清点机主物品!',
tipsInfo: '', tipsInfo: '',
}, },
extraInfo: { extraInfo: {
@@ -127,18 +147,35 @@ export const memberPageZhCn: MemberPageText = {
{ title: '离开 204 前清点好维修物资!' }, { title: '离开 204 前清点好维修物资!' },
{ title: '螺丝上了吗?电源排线插了吗?' }, { title: '螺丝上了吗?电源排线插了吗?' },
], ],
ticketList: {
nohint: '暂无',
hint: '七日内未完成工单',
title: '预填写工单列表',
note: '在这里查看所有的预填写工单!',
},
}; };
export const memberPageEnUs: MemberPageText = { export const memberPageEnUs: MemberPageText = {
mainTitleLine: 'Hi! ', titleLine: {
subTitleLine: 'Have a great day!', main: {
index: 'Hi! ',
login: 'EVA Member Entry',
logout: 'EVA Member Logout',
},
sub: {
index: 'Have a great day!',
login:
'Please use EVA Auth, log in and click the button below to scan the QR code',
logout: 'After logging out, scan the code again to log back in!',
},
},
cardTitle: { cardTitle: {
dutyInfo: 'Duty Situation', dutyInfo: 'Duty Situation',
stepInfo: 'Maintenance Steps', stepInfo: 'Maintenance Steps',
tipsInfo: 'Tips', tipsInfo: 'Tips',
}, },
dutyCount: { dutyCount: {
button: 'Update Duty Count', button: 'Update',
text: 'The duty count: ', text: 'The duty count: ',
}, },
stuidText: { stuidText: {
@@ -149,9 +186,6 @@ export const memberPageEnUs: MemberPageText = {
title: 'Password', title: 'Password',
placeholder: 'Consistent with EVA Auth', placeholder: 'Consistent with EVA Auth',
}, },
uncompletedTicket: {
extra: 'Details',
},
dutyCard: { dutyCard: {
offDuty: { offDuty: {
title: 'Off Duty', title: 'Off Duty',
@@ -183,8 +217,9 @@ export const memberPageEnUs: MemberPageText = {
admin: 'Entry for admin', admin: 'Entry for admin',
}, },
cardTips: { cardTips: {
dutyInfo: '提示:可以先前往【维修】页面在线上预填写工单!', dutyInfo:
stepInfo: '提示:请在 20:30 之前取走自己的物品哦!', "Tips: If you can't be on duty, please ask for an excused absence!",
stepInfo: "Tips: Inventory owner's belongings after maintenance!",
tipsInfo: '', tipsInfo: '',
}, },
extraInfo: { extraInfo: {
@@ -207,4 +242,10 @@ export const memberPageEnUs: MemberPageText = {
{ title: '204 is a laboratory. Do not eat inside.' }, { title: '204 is a laboratory. Do not eat inside.' },
{ title: 'Are the screws on? Is the power cable plugged in?' }, { title: 'Are the screws on? Is the power cable plugged in?' },
], ],
ticketList: {
nohint: 'N/A ',
hint: 'Uncompleted tickets in 7 days',
title: 'Pre-filling ticket list',
note: 'Browse for all pre-filling tickets here!',
},
}; };
+15
View File
@@ -1,5 +1,10 @@
export interface NavBarTitle { export interface NavBarTitle {
notFound: string;
loading: string;
ticketDetail: string; ticketDetail: string;
ticketList: string;
askLeave: string;
conclusion: string;
user: { user: {
myTicket: string; myTicket: string;
report: string; report: string;
@@ -11,7 +16,12 @@ export interface NavBarTitle {
} }
export const navBarTitleZhCn: NavBarTitle = { export const navBarTitleZhCn: NavBarTitle = {
notFound: '连接失败',
loading: '加载中',
ticketDetail: '工单详情', ticketDetail: '工单详情',
ticketList: '所有工单',
askLeave: '请假单填写',
conclusion: '值班总结',
user: { user: {
myTicket: '我的工单', myTicket: '我的工单',
report: '意见反馈', report: '意见反馈',
@@ -23,7 +33,12 @@ export const navBarTitleZhCn: NavBarTitle = {
}; };
export const navBarTitleEnUs: NavBarTitle = { export const navBarTitleEnUs: NavBarTitle = {
notFound: 'Failed',
loading: 'Loading',
ticketDetail: 'Ticket Detail', ticketDetail: 'Ticket Detail',
ticketList: 'All Tickets',
askLeave: 'Ask for leave',
conclusion: 'Duty Conclusion',
user: { user: {
myTicket: 'My Tickets', myTicket: 'My Tickets',
report: 'Report', report: 'Report',
+6
View File
@@ -4,6 +4,8 @@ export interface RepairPageText {
title: string; title: string;
note: string; note: string;
extra: string; extra: string;
hint: string;
nohint: string;
}; };
typeText: { typeText: {
computer: string; computer: string;
@@ -51,6 +53,8 @@ export const repairPageZhCn: RepairPageText = {
title: '', title: '',
note: '', note: '',
extra: '详细信息', extra: '详细信息',
hint: '我正在进行的工单',
nohint: '暂无进行中的工单',
}, },
typeText: { typeText: {
computer: '电脑', computer: '电脑',
@@ -98,6 +102,8 @@ export const repairPageEnUs: RepairPageText = {
title: '', title: '',
note: '', note: '',
extra: 'Details', extra: 'Details',
hint: 'My continuing tickets',
nohint: 'No continuing tickets',
}, },
typeText: { typeText: {
computer: 'Computer', computer: 'Computer',
+63 -39
View File
@@ -6,35 +6,43 @@ type StatusStr = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7';
export interface TicketDetailText { export interface TicketDetailText {
stepItems: Array<StepItem>; stepItems: Array<StepItem>;
createTicketMessage: string;
statusModifyPrefix: string;
statusModifyMessage: Map<StatusStr, string>; statusModifyMessage: Map<StatusStr, string>;
descTitle: string; desc: {
title: string;
};
divider: string; divider: string;
info: { info: {
title: string; title: string;
extra: string; extra: string;
}; };
button: {
tookAway: string; tookAway: string;
addToOreo: string; addToOreo: string;
addNote: string; addNote: string;
pick: string; pick: string;
status: string;
};
reminder: {
title: string;
error: string;
r0: string;
r1: string;
r2: string;
r3: string;
};
comment: { comment: {
title: string; title: string;
placeholder: string; placeholder: string;
picked: string;
createTicketMessage: string;
statusModifyPrefix: string;
uploadPic: {
title: string;
};
}; };
status: { status: {
button: string;
title: string; title: string;
cancel: string; cancel: string;
status0: string;
status1: string;
status2: string;
status3: string;
status4: string;
status5: string;
status6: string;
status7: string;
}; };
} }
@@ -45,8 +53,6 @@ export const ticketDetailZhCn: TicketDetailText = {
{ title: '待取回' }, { title: '待取回' },
{ title: '工单完成' }, { title: '工单完成' },
], ],
createTicketMessage: '创建了维修',
statusModifyPrefix: '将维修状态改为:',
statusModifyMessage: new Map<StatusStr, string>([ statusModifyMessage: new Map<StatusStr, string>([
['0', '已创建/交接中'], ['0', '已创建/交接中'],
['1', '维修中'], ['1', '维修中'],
@@ -57,32 +63,42 @@ export const ticketDetailZhCn: TicketDetailText = {
['6', '维修翻车待取回'], ['6', '维修翻车待取回'],
['7', '维修翻车已取回'], ['7', '维修翻车已取回'],
]), ]),
descTitle: '问题描述', desc: {
divider: '评论 / 状态', title: '问题描述',
},
info: { info: {
title: '机主姓名', title: '机主姓名',
extra: '联系方式', extra: '联系方式',
}, },
divider: '评论 / 状态',
button: {
tookAway: '我已取回', tookAway: '我已取回',
addToOreo: '加入 Oreo', addToOreo: '加入 Oreo',
addNote: '添加评论', addNote: '添加评论',
pick: '认领', pick: '认领',
status: '改变状态',
},
comment: { comment: {
title: '添加评论', title: '添加评论',
picked: '认领了维修',
placeholder: '可以在这里交流机器情况、维修进度、提出问题~', placeholder: '可以在这里交流机器情况、维修进度、提出问题~',
createTicketMessage: '创建了维修',
statusModifyPrefix: '将维修状态改为:',
uploadPic: {
title: '上传说明图片处',
},
},
reminder: {
title: '注意事项!',
error: '请重新确认机器状况!',
r0: '是否进行维修?',
r1: '螺丝是否装回?排线是否插好?',
r2: '维修后机器是否已正常运行?',
r3: '随机附件是否已经归还?',
}, },
status: { status: {
button: '改变工单状态',
title: '请选择要改变成为的状态', title: '请选择要改变成为的状态',
cancel: '取消', cancel: '取消',
status0: '已创建/交接中',
status1: '维修中',
status2: '劝退待取回',
status3: '劝退已取回',
status4: '维修成功待取回',
status5: '维修成功已取回',
status6: '维修翻车待取回',
status7: '维修翻车已取回',
}, },
}; };
@@ -93,8 +109,6 @@ export const ticketDetailEnUs: TicketDetailText = {
{ title: 'Finished' }, { title: 'Finished' },
{ title: 'Retrieved' }, { title: 'Retrieved' },
], ],
createTicketMessage: 'Created ticket',
statusModifyPrefix: 'Modified repair status to: ',
statusModifyMessage: new Map<StatusStr, string>([ statusModifyMessage: new Map<StatusStr, string>([
['0', 'Created / Handovering'], ['0', 'Created / Handovering'],
['1', 'Repairing'], ['1', 'Repairing'],
@@ -105,32 +119,42 @@ export const ticketDetailEnUs: TicketDetailText = {
['6', 'Pending Retrieval (Failed)'], ['6', 'Pending Retrieval (Failed)'],
['7', 'Retrieved (Failed)'], ['7', 'Retrieved (Failed)'],
]), ]),
descTitle: 'Description', desc: {
divider: 'Comment / Status', title: 'Description',
},
info: { info: {
title: 'Name', title: 'Name',
extra: 'Contact', extra: 'Contact',
}, },
divider: 'Comment / Status',
button: {
tookAway: 'Already retrieved', tookAway: 'Already retrieved',
addToOreo: 'Add to Oreo', addToOreo: 'Add to Oreo',
addNote: 'Comment', addNote: 'Comment',
pick: 'Pick', pick: 'Pick',
status: 'Change status',
},
comment: { comment: {
title: 'Add Comment', title: 'Add comment',
picked: 'Picked this ticket',
placeholder: placeholder:
'You can exchange information the device, the progress of repairs, and ask questions here.', 'You can exchange information the device, the progress of repairs, and ask questions here.',
createTicketMessage: 'Created ticket',
statusModifyPrefix: 'Modified repair status to: ',
uploadPic: {
title: 'Upload description images',
},
},
reminder: {
title: 'Reminder',
error: 'Please re-confirm the status of the device!',
r0: 'Is the maintenance performed?',
r1: 'Are the srews on? Is the power cable plugged in?',
r2: 'Did the device operate well after maintenance?',
r3: 'Are the attachments reverted?',
}, },
status: { status: {
button: 'Modify Status',
title: 'Please select the status you want to modify to', title: 'Please select the status you want to modify to',
cancel: 'Cancel', cancel: 'Cancel',
status0: 'Created / Handovering',
status1: 'Repairing',
status2: 'Pending Retrieval (Refused)',
status3: 'Retrieved (Refused)',
status4: 'Pending Retrieval (Finished)',
status5: 'Retrieved (Finished)',
status6: 'Pending Retrieval (Failed)',
status7: 'Retrieved (Failed)',
}, },
}; };
+3
View File
@@ -3,6 +3,7 @@ import { FixStatus } from '@/common';
export interface TicketListText { export interface TicketListText {
createdAt(time: string): string; createdAt(time: string): string;
statusMap: Map<FixStatus, string>; statusMap: Map<FixStatus, string>;
search: string;
} }
export const ticketListZhCn: TicketListText = { export const ticketListZhCn: TicketListText = {
@@ -19,6 +20,7 @@ export const ticketListZhCn: TicketListText = {
[6, '维修翻车待取回'], [6, '维修翻车待取回'],
[7, '维修翻车已取回'], [7, '维修翻车已取回'],
]), ]),
search: '搜索',
}; };
export const ticketListEnUs: TicketListText = { export const ticketListEnUs: TicketListText = {
@@ -35,4 +37,5 @@ export const ticketListEnUs: TicketListText = {
[6, 'Pending Retrieval (Failed)'], [6, 'Pending Retrieval (Failed)'],
[7, 'Retrieved (Failed)'], [7, 'Retrieved (Failed)'],
]), ]),
search: 'search',
}; };
+11
View File
@@ -0,0 +1,11 @@
export interface ToastText {
error: string;
}
export const toastZhCn: ToastText = {
error: '获取失败',
};
export const toastEnUs: ToastText = {
error: 'Request Failed',
};
+6 -6
View File
@@ -1,7 +1,7 @@
export interface UserPageText { export interface UserPageText {
memberEntry: { memberEntry: {
front: string; prefix: string;
behind: string; affix: string;
}; };
ticketColumn: { ticketColumn: {
title: string; title: string;
@@ -27,8 +27,8 @@ export interface UserPageText {
export const userPageZhCn: UserPageText = { export const userPageZhCn: UserPageText = {
memberEntry: { memberEntry: {
front: '再点击 ', prefix: '再点击 ',
behind: ' 次以进入协会成员登录页面', affix: ' 次以进入协会成员登录页面',
}, },
ticketColumn: { ticketColumn: {
title: '我的工单', title: '我的工单',
@@ -54,8 +54,8 @@ export const userPageZhCn: UserPageText = {
export const userPageEnUs: UserPageText = { export const userPageEnUs: UserPageText = {
memberEntry: { memberEntry: {
front: 'Click ', prefix: 'Click ',
behind: ' more times to enter member login page', affix: ' more times to enter member login page',
}, },
ticketColumn: { ticketColumn: {
title: 'My Tickets', title: 'My Tickets',
+17 -1
View File
@@ -1,17 +1,33 @@
import { Moment } from 'moment'; import moment, { Moment } from 'moment';
const dutyStart = moment().format('YYYY-MM-DD').toString() + ' 13:30:00';
export interface CommonText { export interface CommonText {
createdAtText(time: Moment): string; createdAtText(time: Moment): string;
offDutyReason: string;
place: string;
dutyRecoverTime: string;
zeroMemberOnDuty: string;
} }
export const commonTextZhCn: CommonText = { export const commonTextZhCn: CommonText = {
createdAtText(time: Moment): string { createdAtText(time: Moment): string {
return '创建于 ' + time.format('YYYY-MM-DD HH:mm'); return '创建于 ' + time.format('YYYY-MM-DD HH:mm');
}, },
offDutyReason: '正常值班下班',
place: '204',
dutyRecoverTime: moment().isBefore(dutyStart) ? '今天 13:30' : '明天 13:30',
zeroMemberOnDuty: '待更新',
}; };
export const commonTextEnUs: CommonText = { export const commonTextEnUs: CommonText = {
createdAtText(time: Moment): string { createdAtText(time: Moment): string {
return 'Created at ' + time.format('YYYY-MM-DD HH:mm'); return 'Created at ' + time.format('YYYY-MM-DD HH:mm');
}, },
offDutyReason: 'Normal Shift',
place: 'E3-204',
dutyRecoverTime: moment().isBefore(dutyStart)
? '13:30 Today'
: '13:30 Tomorrow',
zeroMemberOnDuty: 'Wait for update',
}; };
+28
View File
@@ -18,6 +18,19 @@ import {
import { CommonText, commonTextEnUs, commonTextZhCn } from './common'; import { CommonText, commonTextEnUs, commonTextZhCn } from './common';
import { TipsText, tipsEnUs, tipsZhCn } from './Tips'; import { TipsText, tipsEnUs, tipsZhCn } from './Tips';
import { ModalText, modalEnUs, modalZhCn } from './Modal'; import { ModalText, modalEnUs, modalZhCn } from './Modal';
import { ToastText, toastEnUs, toastZhCn } from './Toast';
import {
ActIndicatorText,
actIndicatorEnUs,
actIndicatorZhCn,
} from './ActIndicator';
import { NotFoundText, notFound } from './404';
import { AskLeaveText, askLeaveEnUs, askLeaveZhCn } from './AskLeave';
import {
ConclusionText,
conclusionTextEnUs,
conclusionTextZhCn,
} from './Conclusion';
interface TextRecord { interface TextRecord {
common: CommonText; common: CommonText;
@@ -36,6 +49,11 @@ interface TextRecord {
ticketDetail: TicketDetailText; ticketDetail: TicketDetailText;
tips: TipsText; tips: TipsText;
modal: ModalText; modal: ModalText;
toast: ToastText;
actIndicator: ActIndicatorText;
notFound: NotFoundText;
askLeave: AskLeaveText;
conclusion: ConclusionText;
} }
const textZhCn: TextRecord = { const textZhCn: TextRecord = {
@@ -55,6 +73,11 @@ const textZhCn: TextRecord = {
ticketDetail: ticketDetailZhCn, ticketDetail: ticketDetailZhCn,
tips: tipsZhCn, tips: tipsZhCn,
modal: modalZhCn, modal: modalZhCn,
toast: toastZhCn,
actIndicator: actIndicatorZhCn,
notFound: notFound,
askLeave: askLeaveZhCn,
conclusion: conclusionTextZhCn,
}; };
const textEnUs: TextRecord = { const textEnUs: TextRecord = {
@@ -74,6 +97,11 @@ const textEnUs: TextRecord = {
ticketDetail: ticketDetailEnUs, ticketDetail: ticketDetailEnUs,
tips: tipsEnUs, tips: tipsEnUs,
modal: modalEnUs, modal: modalEnUs,
toast: toastEnUs,
actIndicator: actIndicatorEnUs,
notFound: notFound,
askLeave: askLeaveEnUs,
conclusion: conclusionTextEnUs,
}; };
// type Lang = 'zh_CN' | 'en_US' | ...; // type Lang = 'zh_CN' | 'en_US' | ...;
+14 -5
View File
@@ -6,7 +6,10 @@ import { getUrl } from '.';
export function addToOreo(that: TicketDetail) { export function addToOreo(that: TicketDetail) {
that.setState({ that.setState({
isOreoLoading: true, isLoading: {
...that.state.isLoading,
oreo: true,
},
}); });
Taro.request({ Taro.request({
url: getUrl('/tickets/addtooreo'), url: getUrl('/tickets/addtooreo'),
@@ -19,7 +22,10 @@ export function addToOreo(that: TicketDetail) {
.then((res) => { .then((res) => {
console.log(res.data); console.log(res.data);
that.setState({ that.setState({
isOreoLoading: false, isLoading: {
...that.state.isLoading,
oreo: false,
},
}); });
Taro.atMessage({ Taro.atMessage({
message: pt.get().button.submitText.success, message: pt.get().button.submitText.success,
@@ -27,12 +33,15 @@ export function addToOreo(that: TicketDetail) {
}); });
}) })
.catch((err) => { .catch((err) => {
console.log(err); console.log(err.errMsg);
that.setState({ that.setState({
isOreoLoading: false, isLoading: {
...that.state.isLoading,
oreo: false,
},
}); });
Taro.atMessage({ Taro.atMessage({
message: pt.get().button.submitText.error + err.toString(), message: pt.get().button.submitText.error + err.errMsg,
type: 'error', type: 'error',
}); });
}); });
+49
View File
@@ -0,0 +1,49 @@
import AskLeavePage from '@/pages/AskLeave/AskLeave';
import Taro from '@tarojs/taro';
import pt from '@/plain-text';
import wechatUser from '@/wechat';
import { getUrl } from '.';
const reLaunchInterval = 1000;
export function askLeave(that: AskLeavePage) {
that.setState({
isLoading: true,
});
Taro.request({
url: getUrl('/member/askleave'),
method: 'POST',
data: {
token: wechatUser.getToken(),
week: (that.state.shift[0] + 1).toString(),
shift: (that.state.shift[1] + 1).toString(),
reason: that.state.reason,
substitute: that.state.substitute,
},
})
.then((res) => {
console.log(res.data);
that.setState({
isLoading: false,
});
Taro.atMessage({
message: pt.get().button.submitText.success,
type: 'success',
});
setTimeout(() => {
Taro.reLaunch({
url: '/pages/index/index',
});
}, reLaunchInterval);
})
.catch((err) => {
console.log(err.errMsg);
that.setState({
isLoading: false,
});
Taro.atMessage({
message: pt.get().button.submitText.error + err.errMsg,
type: 'error',
});
});
}
+4 -4
View File
@@ -11,11 +11,11 @@ export function changeDutyCnt(that: MainPage) {
isLoading: true, isLoading: true,
}); });
Taro.request({ Taro.request({
url: getUrl('/tickets/addtooreo'), url: getUrl('/member/dutycnt'),
method: 'POST', method: 'POST',
data: { data: {
token: wechatUser.getToken(), token: wechatUser.getToken(),
dutyCnt: that.state.inDutyCnt, dutyCnt: that.state.dutyData.inDutyCnt,
}, },
}) })
.then((res) => { .then((res) => {
@@ -34,12 +34,12 @@ export function changeDutyCnt(that: MainPage) {
}, reLaunchInterval); }, reLaunchInterval);
}) })
.catch((err) => { .catch((err) => {
console.log(err); console.log(err.errMsg);
that.setState({ that.setState({
isLoading: false, isLoading: false,
}); });
Taro.atMessage({ Taro.atMessage({
message: pt.get().button.submitText.error + err.toString(), message: pt.get().button.submitText.error + err.errMsg,
type: 'error', type: 'error',
}); });
}); });
+14 -5
View File
@@ -8,7 +8,10 @@ const reLaunchInterval = 1000;
export function changeStatus(that: TicketDetail, status: number) { export function changeStatus(that: TicketDetail, status: number) {
that.setState({ that.setState({
isStatusLoading: true, isLoading: {
...that.state.isLoading,
status: true,
},
}); });
Taro.request({ Taro.request({
url: getUrl('/tickets/update'), url: getUrl('/tickets/update'),
@@ -22,7 +25,10 @@ export function changeStatus(that: TicketDetail, status: number) {
.then((res) => { .then((res) => {
console.log(res.data); console.log(res.data);
that.setState({ that.setState({
isStatusLoading: false, isLoading: {
...that.state.isLoading,
status: false,
},
}); });
Taro.atMessage({ Taro.atMessage({
message: pt.get().button.submitText.success, message: pt.get().button.submitText.success,
@@ -35,12 +41,15 @@ export function changeStatus(that: TicketDetail, status: number) {
}, reLaunchInterval); }, reLaunchInterval);
}) })
.catch((err) => { .catch((err) => {
console.log(err); console.log(err.errMsg);
that.setState({ that.setState({
isStatusLoading: false, isLoading: {
...that.state.isLoading,
status: false,
},
}); });
Taro.atMessage({ Taro.atMessage({
message: pt.get().button.submitText.error + err.toString(), message: pt.get().button.submitText.error + err.errMsg,
type: 'error', type: 'error',
}); });
}); });
+1 -1
View File
@@ -35,7 +35,7 @@ export function checkToken(): string {
return ''; return '';
} }
} catch (err) { } catch (err) {
console.log(err); console.log(err.errMsg);
return ''; return '';
} }
} }
+42
View File
@@ -0,0 +1,42 @@
import ConclusionPage from '@/pages/Conclusion/Conclusion';
import Taro from '@tarojs/taro';
import pt from '@/plain-text';
import wechatUser from '@/wechat';
import { getUrl } from '.';
export function conclude(that: ConclusionPage) {
that.setState({
isLoading: true,
});
Taro.request({
url: getUrl('/member/conclusion'),
method: 'POST',
data: {
token: wechatUser.getToken(),
conclusion: that.state.conclusion,
week: (that.state.shift[0] + 1).toString(),
shift: (that.state.shift[1] + 1).toString(),
},
})
.then((res) => {
console.log(res.data);
that.setState({
isLoading: false,
conclusionId: res.data.data.id,
});
Taro.atMessage({
message: pt.get().button.submitText.success,
type: 'success',
});
})
.catch((err) => {
console.log(err.errMsg);
that.setState({
isLoading: false,
});
Taro.atMessage({
message: pt.get().button.submitText.error + err.errMsg,
type: 'error',
});
});
}
+3 -1
View File
@@ -16,6 +16,7 @@ export function getCurrentTicket(that: RepairPage) {
.then((res) => { .then((res) => {
const data = res.data.data; const data = res.data.data;
let newIdNameList: Array<Map<number, string>> = []; let newIdNameList: Array<Map<number, string>> = [];
if (data.list.length !== 0) {
data.list.map((ticket: TicketListItem) => { data.list.map((ticket: TicketListItem) => {
if ( if (
ticket['status'] !== 3 && ticket['status'] !== 3 &&
@@ -29,6 +30,7 @@ export function getCurrentTicket(that: RepairPage) {
); );
} }
}); });
}
that.setState({ that.setState({
currentTicketsIdName: newIdNameList, currentTicketsIdName: newIdNameList,
}); });
@@ -36,7 +38,7 @@ export function getCurrentTicket(that: RepairPage) {
.catch((err) => { .catch((err) => {
console.log(err); console.log(err);
Taro.atMessage({ Taro.atMessage({
message: pt.get().button.submitText.error + err.toString(), message: pt.get().button.submitText.error + err.errMsg,
type: 'error', type: 'error',
}); });
}); });
+24 -11
View File
@@ -1,6 +1,7 @@
import MainPage from '@/pages/index'; import MainPage from '@/pages/index';
import Taro from '@tarojs/taro'; import Taro from '@tarojs/taro';
import wechatUser from '@/wechat'; import wechatUser from '@/wechat';
import pt from '@/plain-text';
import { getUrl } from '.'; import { getUrl } from '.';
export function getDutyInfo(that: MainPage) { export function getDutyInfo(that: MainPage) {
@@ -20,35 +21,47 @@ export function getDutyInfo(that: MainPage) {
return; return;
} }
const data = res.data.data; const data = res.data.data;
if (data.isInDuty) {
that.setState({ that.setState({
rs: former.trans(true), rs: former.trans(true),
dutyData: data,
});
if (!data.isInDuty) {
that.setState({
dutyData: { dutyData: {
isInDuty: data.isInDuty, ...data,
inDutyCnt: data.inDutyCnt, offDutyReason: pt.get().common.offDutyReason,
currentDuty: data.currentDuty,
place: data.place,
}, },
}); });
if (data.currentDuty === '0') {
that.setState({
dutyData: {
...data,
place: pt.get().common.place,
offDutyReason: pt.get().common.offDutyReason,
dutyRecoverTime: pt.get().common.dutyRecoverTime,
},
});
}
} else { } else {
that.setState({ that.setState({
rs: former.trans(true),
dutyData: { dutyData: {
isInDuty: data.isInDuty, ...data,
offDutyReason: data.offDutyReason, place: pt.get().common.place,
dutyRecoverTime: data.dutyRecoverTime,
place: data.place,
}, },
}); });
} }
}) })
.catch((err) => { .catch((err) => {
console.log(err); console.log(err.errMsg);
let former = that.state.rs; let former = that.state.rs;
that.setState({ that.setState({
rs: former.trans(false), rs: former.trans(false),
dutyData: { dutyData: {
isInDuty: false, isInDuty: false,
inDutyCnt: 0,
currentDuty: '0',
otherDutyStart: '',
otherDutyEnd: '',
offDutyReason: '获取失败!Network Error!', offDutyReason: '获取失败!Network Error!',
dutyRecoverTime: '获取失败!Network Error!', dutyRecoverTime: '获取失败!Network Error!',
place: '204', place: '204',
+14 -8
View File
@@ -9,25 +9,31 @@ export function getDisable(that: TicketDetail, id: number) {
method: 'GET', method: 'GET',
data: { data: {
id: id, id: id,
token: wechatUser.getToken(),
}, },
}) })
.then((res) => { .then((res) => {
const data = res.data.data; const data = res.data.data;
let isDisable_main = that.state.isDisable_main;
if (data.status === 3 || data.status === 5 || data.status === 7) { if (data.status === 3 || data.status === 5 || data.status === 7) {
that.setState({ isDisable_main.retrieve = true;
isRetrieveDisable_main: true, isDisable_main.comment = true;
isCommentDisable_main: true,
});
} }
if (wechatUser.getAccess()) { if (wechatUser.getAccess()) {
if (data.workers.includes(wechatUser.getInfo().name)) { if (data.workers.includes(wechatUser.getInfo().name)) {
isDisable_main.pick = true;
}
}
that.setState({ that.setState({
isPickDisable_main: true, isDisable_main: {
...that.state.isDisable_main,
retrieve: isDisable_main.retrieve,
comment: isDisable_main.comment,
pick: isDisable_main.pick,
},
}); });
}
}
}) })
.catch((reason) => { .catch((reason) => {
console.error(reason); console.log(reason.errMsg);
}); });
} }
+2 -2
View File
@@ -6,7 +6,7 @@ import { getLocaleData } from './localeData';
export function getInfo() { export function getInfo() {
Taro.request({ Taro.request({
url: getUrl('/member/login'), url: getUrl('/member/checklogin'),
method: 'POST', method: 'POST',
data: { data: {
token: wechatUser.getToken(), token: wechatUser.getToken(),
@@ -42,6 +42,6 @@ export function getInfo() {
getLocaleData(); getLocaleData();
}) })
.catch((err) => { .catch((err) => {
console.log(err); console.log(err.errMsg);
}); });
} }
+4 -2
View File
@@ -21,12 +21,14 @@ export function loginAte() {
data: data.token, data: data.token,
}); });
wechatUser.setToken(data.token); wechatUser.setToken(data.token);
Taro.reLaunch({
url: '/pages/index/index',
});
getLocaleData(); getLocaleData();
}) })
.catch((err) => { .catch((err) => {
console.log(err); console.log(err.errMsg);
}); });
getLocaleData();
} else { } else {
console.log('Login Failed: ' + res.errMsg); console.log('Login Failed: ' + res.errMsg);
} }
+18 -14
View File
@@ -1,6 +1,7 @@
import MainPage from '@/pages/index'; import MainPage from '@/pages/index';
import Taro from '@tarojs/taro'; import Taro from '@tarojs/taro';
import wechatUser from '@/wechat'; import wechatUser from '@/wechat';
import pt from '@/plain-text';
import { getUrl } from '.'; import { getUrl } from '.';
export function getMemberDutyInfo(that: MainPage) { export function getMemberDutyInfo(that: MainPage) {
@@ -13,32 +14,35 @@ export function getMemberDutyInfo(that: MainPage) {
}) })
.then((res) => { .then((res) => {
const data = res.data.data; const data = res.data.data;
if (data.isInDuty) {
that.setState({ that.setState({
dutyData: { dutyData: data,
isInDuty: data.isInDuty,
inDutyCnt: data.inDutyCnt,
currentDuty: data.currentDuty,
place: data.place,
},
inDutyCnt: data.inDutyCnt,
}); });
} else { if (!data.isInDuty) {
that.setState({ that.setState({
dutyData: { dutyData: {
isInDuty: data.isInDuty, ...data,
offDutyReason: data.offDutyReason, offDutyReason: pt.get().common.offDutyReason,
dutyRecoverTime: data.dutyRecoverTime, },
place: data.place, });
if (data.currentDuty === '0') {
that.setState({
dutyData: {
...data,
place: pt.get().common.place,
}, },
}); });
} }
}
}) })
.catch((err) => { .catch((err) => {
console.log(err); console.log(err.errMsg);
that.setState({ that.setState({
dutyData: { dutyData: {
isInDuty: false, isInDuty: false,
inDutyCnt: 0,
currentDuty: '0',
otherDutyStart: '',
otherDutyEnd: '',
offDutyReason: '获取失败!Network Error!', offDutyReason: '获取失败!Network Error!',
dutyRecoverTime: '获取失败!Network Error!', dutyRecoverTime: '获取失败!Network Error!',
place: '204', place: '204',
+19 -6
View File
@@ -8,13 +8,15 @@ export function memberLogin(that: UserMemberPage) {
that.setState({ that.setState({
isLoading: true, isLoading: true,
}); });
Taro.scanCode({
onlyFromCamera: true,
success: (re) => {
Taro.request({ Taro.request({
url: getUrl('/member/login'), url: getUrl('/member/login'),
method: 'POST', method: 'POST',
data: { data: {
token: wechatUser.getToken(), token: wechatUser.getToken(),
name: that.state.stuid, code: re.result,
phone: that.state.passwd,
}, },
}) })
.then((res) => { .then((res) => {
@@ -40,15 +42,26 @@ export function memberLogin(that: UserMemberPage) {
} }
}) })
.catch((err) => { .catch((err) => {
console.log(err); console.log(err.errMsg);
that.setState({ that.setState({
isLoading: false, isLoading: false,
}); });
Taro.atMessage({ Taro.atMessage({
message: pt.get().button.loginText.error + err.toString(), message: pt.get().button.loginText.error + err.errMsg,
type: 'error', type: 'error',
}); });
}); });
},
fail: (err) => {
that.setState({
isLoading: false,
});
Taro.atMessage({
message: pt.get().button.loginText.error + err.errMsg,
type: 'error',
});
},
});
} }
export function memberLogout(that: UserMemberPage) { export function memberLogout(that: UserMemberPage) {
@@ -77,12 +90,12 @@ export function memberLogout(that: UserMemberPage) {
}); });
}) })
.catch((err) => { .catch((err) => {
console.log(err); console.log(err.errMsg);
that.setState({ that.setState({
isLoading: false, isLoading: false,
}); });
Taro.atMessage({ Taro.atMessage({
message: pt.get().button.logoutText.error + err.toString(), message: pt.get().button.logoutText.error + err.errMsg,
type: 'error', type: 'error',
}); });
}); });
+1 -1
View File
@@ -47,6 +47,6 @@ export function getMyTicketList(that: MyTicketPage) {
that.setState({ that.setState({
rs: former.trans(false), rs: former.trans(false),
}); });
console.log(reason); console.log(reason.errMsg);
}); });
} }
+35
View File
@@ -0,0 +1,35 @@
import PicUploader from '@/components/PicUploader/PicUploader';
import Taro from '@tarojs/taro';
import pt from '@/plain-text';
import wechatUser from '@/wechat';
import { randomString } from '@/utils/random';
import { getUrl } from '.';
const randomLength = 8;
export function picUpload(that: PicUploader, file: string) {
Taro.uploadFile({
url: getUrl('/upload/pic'),
filePath: file,
name: randomString(randomLength),
formData: {
token: wechatUser.getToken(),
source: that.props.source,
id: that.props.id,
},
})
.then((res) => {
console.log(res.data);
Taro.atMessage({
message: pt.get().button.submitText.success,
type: 'success',
});
})
.catch((err) => {
console.log(err.errMsg);
Taro.atMessage({
message: pt.get().button.submitText.error + err.errMsg,
type: 'error',
});
});
}
+14 -5
View File
@@ -8,7 +8,10 @@ const reLaunchInterval = 1000;
export function pickTicket(that: TicketDetail) { export function pickTicket(that: TicketDetail) {
that.setState({ that.setState({
isPickLoading: true, isLoading: {
...that.state.isLoading,
pick: true,
},
}); });
Taro.request({ Taro.request({
url: getUrl('/tickets/pick'), url: getUrl('/tickets/pick'),
@@ -21,7 +24,10 @@ export function pickTicket(that: TicketDetail) {
.then((res) => { .then((res) => {
console.log(res.data); console.log(res.data);
that.setState({ that.setState({
isPickLoading: false, isLoading: {
...that.state.isLoading,
pick: false,
},
}); });
Taro.atMessage({ Taro.atMessage({
message: pt.get().button.submitText.success, message: pt.get().button.submitText.success,
@@ -34,12 +40,15 @@ export function pickTicket(that: TicketDetail) {
}, reLaunchInterval); }, reLaunchInterval);
}) })
.catch((err) => { .catch((err) => {
console.log(err); console.log(err.errMsg);
that.setState({ that.setState({
isPickLoading: false, isLoading: {
...that.state.isLoading,
pick: false,
},
}); });
Taro.atMessage({ Taro.atMessage({
message: pt.get().button.submitText.error + err.toString(), message: pt.get().button.submitText.error + err.errMsg,
type: 'error', type: 'error',
}); });
}); });
+31
View File
@@ -0,0 +1,31 @@
import Taro from '@tarojs/taro';
import wechatUser from '@/wechat';
import { getUrl } from '.';
import { checkLogin, checkToken } from './checkLogin';
import { loginAte } from './login';
import { getInfo } from './getInfo';
export function pingAte() {
Taro.request({
url: getUrl('/ping'),
method: 'GET',
data: {},
})
.then((res) => {
console.log(res.data);
checkLogin((success) => {
if (success) {
wechatUser.setToken(checkToken());
getInfo();
} else {
loginAte();
}
});
})
.catch((err) => {
console.log(err.errMsg);
Taro.reLaunch({
url: '/pages/404/404',
});
});
}
+2 -2
View File
@@ -27,12 +27,12 @@ export function reportMessage(that: ReportPage) {
}); });
}) })
.catch((err) => { .catch((err) => {
console.log(err); console.log(err.errMsg);
that.setState({ that.setState({
isLoading: false, isLoading: false,
}); });
Taro.atMessage({ Taro.atMessage({
message: pt.get().button.submitText.error + err.toString(), message: pt.get().button.submitText.error + err.errMsg,
type: 'error', type: 'error',
}); });
}); });
+14 -5
View File
@@ -8,7 +8,10 @@ const reLaunchInterval = 1000;
export function retrieve(that: TicketDetail) { export function retrieve(that: TicketDetail) {
that.setState({ that.setState({
isRetrieveLoading: true, isLoading: {
...that.state.isLoading,
retrieve: true,
},
}); });
Taro.request({ Taro.request({
url: getUrl('/tickets/retrieve'), url: getUrl('/tickets/retrieve'),
@@ -21,7 +24,10 @@ export function retrieve(that: TicketDetail) {
.then((res) => { .then((res) => {
console.log(res.data); console.log(res.data);
that.setState({ that.setState({
isRetrieveLoading: false, isLoading: {
...that.state.isLoading,
retrieve: false,
},
}); });
Taro.atMessage({ Taro.atMessage({
message: pt.get().button.submitText.success, message: pt.get().button.submitText.success,
@@ -34,12 +40,15 @@ export function retrieve(that: TicketDetail) {
}, reLaunchInterval); }, reLaunchInterval);
}) })
.catch((err) => { .catch((err) => {
console.log(err); console.log(err.errMsg);
that.setState({ that.setState({
isRetrieveLoading: false, isLoading: {
...that.state.isLoading,
retrieve: false,
},
}); });
Taro.atMessage({ Taro.atMessage({
message: pt.get().button.submitText.error + err.toString(), message: pt.get().button.submitText.error + err.errMsg,
type: 'error', type: 'error',
}); });
}); });
+11 -16
View File
@@ -1,45 +1,40 @@
import TicketDetail from '@/pages/TicketDetail/TicketDetail'; import { Comment } from '@/pages/TicketDetail/Comment';
import Taro from '@tarojs/taro'; import Taro from '@tarojs/taro';
import pt from '@/plain-text'; import pt from '@/plain-text';
import wechatUser from '@/wechat'; import wechatUser from '@/wechat';
import { getUrl } from '.'; import { getUrl } from '.';
const reLaunchInterval = 1000; export function submitComment(that: Comment) {
export function submitComment(that: TicketDetail) {
that.setState({ that.setState({
isCommentLoading: true, isLoading: true,
}); });
Taro.request({ Taro.request({
url: getUrl('/report'), url: getUrl('/tickets/addnote'),
method: 'POST', method: 'POST',
data: { data: {
token: wechatUser.getToken(), token: wechatUser.getToken(),
comment: that.state.comment, content: that.state.comment,
id: that.props.id,
}, },
}) })
.then((res) => { .then((res) => {
console.log(res.data); console.log(res.data);
that.setState({ that.setState({
isCommentLoading: false, isLoading: false,
commentId: res.data.data.id,
}); });
Taro.atMessage({ Taro.atMessage({
message: pt.get().button.submitText.success, message: pt.get().button.submitText.success,
type: 'success', type: 'success',
}); });
setTimeout(() => {
Taro.reLaunch({
url: '/pages/TicketDetail/TicketDetail?id=' + that.state.id,
});
}, reLaunchInterval);
}) })
.catch((err) => { .catch((err) => {
console.log(err); console.log(err.errMsg);
that.setState({ that.setState({
isCommentLoading: false, isLoading: false,
}); });
Taro.atMessage({ Taro.atMessage({
message: pt.get().button.submitText.error + err.toString(), message: pt.get().button.submitText.error + err.errMsg,
type: 'error', type: 'error',
}); });
}); });

Some files were not shown because too many files have changed in this diff Show More