154 Commits
Author SHA1 Message Date
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
Dawn_Ocean 24f71ed997 fix status display bug in detailframework 2024-03-22 15:58:53 +08:00
Dawn_Ocean 97a8d0570a add button disable in ticketdetail with relavant services 2024-03-22 15:36:18 +08:00
Dawn1Ocean f3f5be793b refactor: merge index & member page 2024-03-22 10:23:39 +08:00
Dawn_Ocean a7c96b2e8c change token_test to wechatUser 2024-03-21 14:38:40 +08:00
Dawn_Ocean 7d1ae68643 change icons to svg in userpage 2024-03-21 11:24:02 +08:00
Dawn_Ocean 3de05c7cfc add avatar in notecard 2024-03-21 11:08:10 +08:00
Dawn_Ocean 7ae5d8758a add requestSubscribeMessage & templateId on ticket submit 2024-03-21 10:48:27 +08:00
Dawn1Ocean 16cb2362e6 banned /user/inform for members 2024-03-20 23:30:53 +08:00
Dawn1Ocean 42ee477ec4 add pre-filling info in repair page 2024-03-20 23:26:54 +08:00
Dawn1Ocean 5b08555359 fix relaunch logic in app.ts 2024-03-20 23:20:39 +08:00
Dawn1Ocean 574d3692cd fix checklogin & getinfo in app.ts 2024-03-20 22:58:03 +08:00
Dawn1Ocean 1f0d4881f3 remove newcomment api 2024-03-20 21:21:23 +08:00
Dawn1Ocean aff74acc1f add /member/checklogin api 2024-03-20 20:04:19 +08:00
Dawn1Ocean 456c891ca6 fix login logic @ app.ts 2024-03-20 14:37:42 +08:00
Dawn1Ocean 952c230148 add about page structure 2024-03-20 01:45:22 +08:00
Dawn1Ocean 9f77cb0f2a add local storage of token and services 2024-03-20 01:00:50 +08:00
Dawn1Ocean f2f4929fc9 add api for login & checklogin 2024-03-19 23:45:16 +08:00
Dawn1Ocean 5c78139d5a add /member/login service; beautify member page with name&avatar 2024-03-19 23:39:01 +08:00
Dawn1Ocean 4f914a7563 beautify ui: /user/member; divider in ticketdetail 2024-03-19 23:07:28 +08:00
Dawn1Ocean 239d4f0c7c change tab-bar logic 2024-03-19 22:54:35 +08:00
Dawn_Ocean db11f03bda add place in mainpage 2024-03-19 22:46:42 +08:00
Dawn_Ocean 56ec1827ca add place in api /duty/info 2024-03-19 21:45:39 +08:00
Dawn1Ocean d705970d1f beautify /user/inform /user/report ui 2024-03-19 19:42:29 +08:00
Dawn1Ocean 2ef04b96a1 add relaunch after change inDutyCnt 2024-03-19 19:19:59 +08:00
Dawn1Ocean 599166e603 add change inDutyCnt button and service 2024-03-19 19:12:33 +08:00
Dawn1Ocean 787b37fc42 beautify member page layout 2024-03-19 17:35:59 +08:00
Dawn1Ocean 3c2b613d87 add support for rendering ui on various devices 2024-03-19 11:31:23 +08:00
Dawn1Ocean f20a38af9b beautify ui; fix current ticket card title display bug 2024-03-19 02:19:39 +08:00
Dawn1Ocean 31d7aea480 beautify ui! 2024-03-19 00:14:13 +08:00
Dawn_Ocean 3db6425dc3 add relaunch ticketdetail after changing it 2024-03-18 14:56:02 +08:00
Dawn_Ocean cd3064c90f add relaunch ticketdetail after changing it 2024-03-18 14:55:27 +08:00
Dawn_Ocean 4640f89ea8 add changeStatus service 2024-03-18 14:40:03 +08:00
Dawn_Ocean 3d5cd6c8da add retrieve in service 2024-03-18 14:22:49 +08:00
Dawn_Ocean 7ced70ab21 fix Fixstatus; add support to all statuses 2024-03-18 14:08:52 +08:00
Dawn_Ocean 2398644cc3 add pickTicket in service 2024-03-18 13:44:39 +08:00
Dawn_Ocean 501f27bfbb add addToOreo in service 2024-03-18 13:39:15 +08:00
Dawn1Ocean e39e8d4e13 update mock 2024-03-17 18:34:58 +08:00
Dawn_Ocean 7cf2cbb798 add en_US localization 2024-03-17 11:34:14 +08:00
Dawn_Ocean d525f0288b add owner's info in ticketdetail 2024-03-17 02:05:08 +08:00
Dawn_Ocean 7f345af777 change README.md 2024-03-17 01:29:56 +08:00
Dawn_Ocean 563a0c42ea add memberpage layout 2024-03-17 01:00:06 +08:00
Dawn_Ocean cce351750d add confirm modal for buttons in ticketdetail 2024-03-16 16:45:41 +08:00
Dawn1Ocean ac9645b987 add comment floatlayout in ticketdetail 2024-03-15 22:19:30 +08:00
Dawn_Ocean e7b0b3239e add modal in ticketdetail-addtooreo 2024-03-15 15:48:19 +08:00
Dawn_Ocean b41498976e add blank judgement; fixed setstate in render bug 2024-03-15 14:28:26 +08:00
Dawn1Ocean 6b554196b3 add blank judgement for forms; fixing setstate bug in detailframework 2024-03-15 13:42:16 +08:00
Dawn1Ocean 2d5ce655ef add member status judgement 2024-03-15 01:58:59 +08:00
Dawn1Ocean 5614ce5818 add uncompleted ticket list in member page 2024-03-15 00:54:05 +08:00
Dawn1Ocean fc3ef61e5d add entry for ticket detail in current ticket card 2024-03-14 23:55:51 +08:00
Dawn1Ocean 60f10eaa8f add random tips on currentTicket card 2024-03-14 23:30:48 +08:00
Dawn_Ocean 9931b23337 wrap up detailframework in atcard in repair page 2024-03-14 16:51:21 +08:00
Dawn_Ocean 84507f7214 refactor ticketListItem 2024-03-14 12:09:51 +08:00
Dawn_Ocean 802d008767 refactor DetailFramework and service/ticketsInfo; create currentTicket service 2024-03-14 11:40:59 +08:00
Dawn_Ocean c070b356fe refactor DetailFramework and service/ticketsInfo 2024-03-14 10:42:30 +08:00
Dawn_Ocean b1c0e5d8b1 Merge branch 'dev' into mgy 2024-03-14 09:03:00 +08:00
Dawn1Ocean e82225ecbc add english localization 2024-03-13 17:09:22 +08:00
Dawn1Ocean df71ebf219 change logo, README.md 2024-03-13 16:23:09 +08:00
fracher 0dac2ad185 refactor ticket detail 2024-03-12 23:01:24 +08:00
Dawn1Ocean e1c3b464a6 change prettier format 2024-03-12 21:55:53 +08:00
Dawn1Ocean e11a58dbb5 change format option 2024-03-12 21:50:23 +08:00
Dawn1Ocean 5bafff52ad optimize layout of index page 2024-03-12 20:33:29 +08:00
Dawn1Ocean d83136a69c add uncompleted ticket mock; fix logo.png: compressed 2024-03-12 19:48:49 +08:00
Dawn1Ocean b243fc5e4c fix submit logic of repair page 2024-03-12 19:15:49 +08:00
Dawn_Ocean 2f6b98b43f fix AtMessage bug in repair page 2024-03-12 18:34:44 +08:00
Dawn_Ocean 6cd27cce10 add card-viewer to repair page 2024-03-12 17:08:32 +08:00
fracher 7810cbaca1 refactor request state 2024-03-12 15:44:35 +08:00
fracher 0120da0760 add ticket detail button 2024-03-12 14:33:40 +08:00
fracher f17bfa2a9e refactor note card to component 2024-03-12 13:28:20 +08:00
fracher 2e2629fe0a add common text 2024-03-12 12:48:58 +08:00
fracher eea622b657 add ticket detail localization 2024-03-12 12:38:04 +08:00
fracher cd076cd5a4 render basic data in ticket detail 2024-03-12 12:14:45 +08:00
fracher a1aa63635f Merge branch 'yhy' into dev 2024-03-12 02:27:02 +08:00
Dawn1Ocean 946a312c61 add request to repair page 2024-03-12 02:25:58 +08:00
fracher 388814f9d9 add ticket detail data 2024-03-12 02:23:11 +08:00
Dawn1Ocean 9bd6c8f1b4 Merge branch 'dev' into mgy 2024-03-12 01:47:15 +08:00
Dawn1Ocean 551d93c8b5 add repair page 2024-03-12 01:45:25 +08:00
fracher 32ce506764 add steps 2024-03-12 01:12:56 +08:00
fracher eaa22dcaa5 refactor user and app service 2024-03-12 00:34:58 +08:00
fracher 9c6cbd91ff rename files 2024-03-11 23:12:41 +08:00
fracher 6583b51750 refactor mainpage service 2024-03-11 23:08:27 +08:00
fracher dd56725575 refactor main page service 2024-03-11 22:57:12 +08:00
fracher 2fd629d479 start refactor 2024-03-11 22:19:32 +08:00
fracher d5b8af7d7b Merge branch 'yhy' into dev 2024-03-11 21:29:56 +08:00
fracher aa334d3f93 nav bar title localization 2024-03-11 21:28:33 +08:00
Dawn_Ocean 7aaad7563f add request to index page 2024-03-11 21:27:11 +08:00
fracher 4d6a769fea add entrance to ticket detail 2024-03-11 20:48:25 +08:00
Dawn_Ocean afdedea344 add member page & tabbar item 2024-03-11 19:22:51 +08:00
Dawn_Ocean 2920059ffa merging all into dev 2024-03-11 14:17:57 +08:00
Dawn_Ocean d2de74578b Merge branch 'yhy' into dev 2024-03-11 14:13:39 +08:00
Dawn_Ocean ac23f88cdd add member login mock 2024-03-11 14:03:23 +08:00
Dawn_Ocean e1e998628f remove reset button from inform page 2024-03-11 13:55:54 +08:00
Dawn_Ocean 806e7a393c add member login page 2024-03-11 13:52:09 +08:00
Dawn_Ocean fd6a60d1d3 add route for memberlogin page 2024-03-11 11:59:12 +08:00
Dawn_Ocean 36a9a35886 add member login entry in user page 2024-03-11 11:58:12 +08:00
fracher 51106ead5e add request to mytickets 2024-03-11 11:36:51 +08:00
fracher 4e31eb70e2 add ticket list 2024-03-11 11:15:02 +08:00
Dawn_Ocean dd770b8ece add inform page request 2024-03-08 22:45:40 +08:00
Dawn_Ocean b174304d74 fix mock file structure 2024-03-08 22:27:13 +08:00
fracher cc5af58155 import moment.js 2024-03-08 22:10:17 +08:00
Dawn_Ocean 88cdb6cb92 add report request 2024-03-08 21:44:21 +08:00
Dawn_Ocean 00977db512 add locale request 2024-03-08 21:24:08 +08:00
Dawn_Ocean 1907f1e967 optimize userpage layout 2024-03-08 16:41:53 +08:00
Dawn_Ocean 39dd945020 optimize pagefooter layout 2024-03-08 16:32:05 +08:00
Dawn_Ocean b603ad24b3 add logo & version in user page 2024-03-08 15:51:27 +08:00
Dawn_Ocean dd07c1da10 add mock apis 2024-03-08 14:56:48 +08:00
fracher a7fd2b2856 Merge branch 'yhy' into dev
merge api doc into dev
2024-03-08 00:04:20 +08:00
fracher 0baf91fadf add api doc 2024-03-08 00:01:32 +08:00
Dawn_Ocean c756e74778 remove oreo id from service 2024-03-07 23:54:59 +08:00
Dawn_Ocean 133d60375a remove settings page 2024-03-07 23:50:32 +08:00
Dawn_Ocean bea23f4705 move about page to user page 2024-03-07 21:47:16 +08:00
Dawn_Ocean 229dffa9a1 fix eslint warnings & errors; add .eslintignore 2024-03-07 21:16:46 +08:00
Dawn_Ocean 74f644b3ee optimize pt structure 2024-03-07 20:41:46 +08:00
Dawn_Ocean 0a98ea71ac add partial localization for inform page 2024-03-07 14:49:54 +08:00
Dawn_Ocean 1a30ff6def add partial localization support for report page 2024-03-07 14:38:37 +08:00
Dawn_Ocean 3232994fb2 add localization for settings page 2024-03-07 14:30:45 +08:00
Dawn_Ocean d995c6ed43 add localization for tab-bar 2024-03-07 14:21:55 +08:00
Dawn_Ocean 6cbd6685bc add language switch in settings page 2024-03-07 14:07:38 +08:00
Dawn_Ocean c63b7fcca8 add en_US structure for plain-text 2024-03-07 11:45:34 +08:00
Dawn_Ocean 34c3753d2c add plain-text support for user page 2024-03-07 11:32:37 +08:00
Dawn_Ocean a5aa10d6f4 add user page footer 2024-03-07 11:14:33 +08:00
Dawn_Ocean f37af7dacd optimize form submit logic 2024-03-07 01:40:11 +08:00
Dawn_Ocean 21e21f272f add about page 2024-03-07 01:18:13 +08:00
Dawn_Ocean a408ac9e39 add myticket page 2024-03-07 01:07:33 +08:00
Dawn_Ocean 162b7a7d09 add report page; optimize style 2024-03-07 00:52:14 +08:00
Dawn_Ocean 54091bb6b3 merging 2024-03-06 21:49:35 +08:00
Dawn_Ocean 098ddd3c13 Merge branch 'dev' into yhy 2024-03-06 21:45:28 +08:00
Dawn_Ocean 64e4b8d6bd fix unused components 2024-03-06 21:44:45 +08:00
fracher 349f125404 update duty info card 2024-03-06 20:57:52 +08:00
fracher d9d005986e refactor main page 2024-03-06 19:45:30 +08:00
fracher 7cd56d7c79 move card text to PlainText 2024-03-06 15:53:13 +08:00
fracher ff880de466 dutycard add data 2024-03-06 15:13:35 +08:00
fracher 11f16b6b06 remove format for project config
remove format for project config
2024-03-06 14:11:30 +08:00
fracher 5f2e66546c add request support 2024-03-06 14:04:17 +08:00
fracher 20b9016f51 change main page layout 2024-03-06 00:14:23 +08:00
fracher 08401dd64d add global plain text to main page 2024-03-06 00:02:41 +08:00
fracher a9d9415def add global plain text 2024-03-06 00:02:00 +08:00
Dawn_Ocean 0841fc91fc add userinfo page 2024-03-05 21:57:54 +08:00
127 changed files with 41950 additions and 36139 deletions
+1
View File
@@ -1,2 +1,3 @@
# 配置文档参考 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"
+1
View File
@@ -1 +1,2 @@
TARO_APP_ID="wx636eb7cf2b84f305" TARO_APP_ID="wx636eb7cf2b84f305"
TARO_APP_API="https://ate.zjueva.net"
+19
View File
@@ -0,0 +1,19 @@
config
.husky
**/.gitignore
dist/
deploy_versions/
.temp/
.rn_temp/
node_modules/
.DS_Store
.swc
.husky
.prettierignore
.env.*
**/*.json
**/*.svg
**/*.scss
**/*.md
*.config.js
index.html
+5 -2
View File
@@ -1,4 +1,5 @@
/**/.gitignore .eslintignore
**/.gitignore
dist/ dist/
deploy_versions/ deploy_versions/
.temp/ .temp/
@@ -8,4 +9,6 @@ node_modules/
.swc .swc
.husky .husky
.prettierignore .prettierignore
.env.* .env.*
project.*.json
**/*.svg
+1 -1
View File
@@ -5,7 +5,7 @@
"semi": true, "semi": true,
"singleQuote": true, "singleQuote": true,
"proseWrap": "preserve", "proseWrap": "preserve",
"arrowParens": "avoid", "arrowParens": "always",
"bracketSpacing": true, "bracketSpacing": true,
"jsxSingleQuote": true, "jsxSingleQuote": true,
"endOfLine": "auto" "endOfLine": "auto"
+29 -15
View File
@@ -10,25 +10,25 @@
1. 能看到现在维修状况:有几台正在维修,有几个人值班(空闲状态) 1. 能看到现在维修状况:有几台正在维修,有几个人值班(空闲状态)
2. 能看到自己机器的维修情况:维修进度、评论等 2. 能看到自己机器的维修情况:维修进度、评论等
1. 使用手机号确定id 1. 使用手机号查询工单
## 互动 ## 互动
1. 提醒:当修好之后会向你发送信息,提醒来取 1. 提醒:当修好(工单状态改变为待取回)之后会向你发送信息,提醒来取
2. 线上答疑:协会成员登录账号,看到机主提出的问题可以回答(暂定由值班组长管理) 2. 线上答疑:协会成员登录账号(通过 EVA Auth 授权),看到机主提出的问题可以回答(暂定由值班组长管理)
1. 公开答疑仅回复能不能修,更复杂的问题推荐其来204 1. 公开答疑仅回复能不能修,更复杂的问题推荐其来204
2. 当自己的机器正在维修时,可以与维修人员交流进度和问题等 2. 当自己的机器正在维修时,可以与维修人员交流进度和问题等
3. (暂定)答疑功能使用预填写工单、工单的评论实现 3. 答疑功能使用预填写工单的评论实现
## 信息展示 ## 信息展示
1. 展示协会值班时间(现在是否在值班),若不在值班显示预计值班时间、不值班的原因等 1. 展示协会值班时间(现在是否在值班),若不在值班显示预计值班时间、不值班的原因
2. 展示维修流程,包括注意事项等 2. 展示维修流程,包括注意事项等
1. 戴尔、Surface等不拆 1. 戴尔、Surface等不拆
2. 数据备份提醒 2. 数据备份提醒
3. 不收礼物 3. 不收礼物
4. 不要在204饮食 4. 不要在204饮食
3. (备选)其他语言本地化 3. 其他语言本地化
## 面向协会成员 ## 面向协会成员
@@ -42,13 +42,13 @@
## 对接 ## 对接
1. 与EVA统一身份认证对接 1. 与 EVA 统一身份认证对接
1. 协会成员登录入口 1. 协会成员登录入口
2. 个人信息同步 2. 个人信息同步
2. 与Oreo对接 2. 与 Oreo 对接
1. 维修工单列表查看 1. 维修工单列表查看:七天内未取回的工单
2. 将预填写工单加入Oreo 2. 将预填写工单加入 Oreo
3. 防恶意行为 3. 防恶意行为(尚未设置)
1. 工单填写间隔限制为【1】分钟 1. 工单填写间隔限制为【1】分钟
2. 一个人一天最多能创建【10】个预填写工单 2. 一个人一天最多能创建【10】个预填写工单
3. 黑名单机制 3. 黑名单机制
@@ -58,18 +58,32 @@
## 主页 ## 主页
1. 信息显示 1. 信息显示
1. 不显示是哪一班,只显示今日值班时间
2. (协会成员)相关信息 2. (协会成员)相关信息
3. 提醒事项 3. 提醒事项
4. 如何联系到协会 4. 如何联系到协会
## 维修 ## 维修
1. (面向机主)预填写工单 1. 预填写工单
2. 维修进度提示 2. 正在进行工单的展示
3. (面向协会成员)维修列表
## 成员
1. 最近七天内未取回的工单列表
2. 值班组长上传本班相关信息
3. 现在自己是否要值班(值班时间显示)
4. 提醒事项
## 我的 ## 我的
1. 更改手机号等个人信息(手机号可以填写多个) 1. 更改手机号、姓名(手机号暂时只能填写一个)
2. (备选)修改用户名、头像 2. (备选)修改用户名、头像
3. 设置真名(可帮助预填写工单) 3. 设置真名(可帮助预填写工单)
# 主席团管理页面
1. 值班表导入、更新
2. 成员权限管理
3. 特殊维修时间(如学园维修)、值班信息更新
+428
View File
@@ -0,0 +1,428 @@
# 接口文档
## 基本格式
### 成功响应格式
```json
{
"success": true,
"data": {
"foo": "bar"
}
}
```
**NOTE:** 若无特殊说明,`POST`请求的响应`data`字段为空(`{}`),可以不用管。
### 失败响应格式
```json
{
"success": false,
"err": "some error"
}
```
### `GET`请求默认格式(若无特殊说明)
```json
{
"token": "token_test"
}
```
## 主页面
### 值班信息 `GET /duty/info`
#### 当前在值班(正常值班时间)
data:
```json
{
"isInDuty": true,
"inDutyCnt": 3,
"currentDuty": "2",
"place": "东三-204",
"otherDutyTime": ""
}
```
#### 当前在值班(其他值班时间)
data:
```json
{
"isInDuty": true,
"inDutyCnt": 3,
"currentDuty": "others",
"place": "蓝田",
"otherDutyTime": "9:30-11:30"
}
```
#### 当前未值班
data:
```json
{
"isInDuty": false,
"offDutyReason": "学园维修",
"dutyRecoverTime": "下周一"
}
```
## 账号登陆
### 微信小程序登陆 `POST /login` OK
- Request
```json
{
"code": "wechat_login_code"
}
```
- Response
```json
{
"success": true,
"token": "your_token"
}
```
### 检查 token 是否登陆 `GET /checklogin?token={token}` OK
```json
{
"islogin": true
}
```
- Response
```json
{
"success": true,
"token": "your_token"
}
```
## 用户页面
### 个人信息 `GET /user/info`
data:
```json
{
"name": "马保国",
"phone": "13333333333"
}
```
### 修改个人信息 `POST /user/update`
Request body:
```json
{
"name": "宇航员",
"phone": "1233333210"
}
```
### 本地化设置
#### 获取本地化设置 `GET /user/locale/get`
data:
```json
{
"lang": "zh_CN"
}
```
#### 更新本地化设置 `POST /user/locale/update`
Request body:
```json
{
"lang": "en_US"
}
```
### 意见反馈 `POST /report`
Request body:
```json
{
"token": "token_test",
"content": "aaa bbbb ccccc"
}
```
### 我的工单(查询)`GET /user/mytickets`
data (same as oreo):
```json
{
"list": [
{
"id": 6830,
"type": 1,
"status": 5,
"device": "主机",
"deviceModel": "技嘉",
"owner": "武技栏",
"phone": "18888888888",
"createdTime": "2024-03-06T19:49:27.043865",
"isConfirmed": false
}
]
}
```
## 工单详情
### 创建工单 `POST /tickets/create`
Request
```json
{
"token": "token_test",
"type": 1, // 电器是0,电脑是1(bushi)
"device": "华硕",
"deviceModel": "天选3",
"owner": "西西弗",
"phone": "12333333333",
"description": "没法用pd充电",
"accessories": [0]
}
```
### 添加评论 `POST /tickets/addnote`
Request
```json
{
"token": "token_test",
"id": "id",
"content" : "为什么 PD 不能充电呢?"
}
```
### 加入 Oreo `POST /tickets/addtooreo`
Request
```json
{
"token": "token_test",
"id": 4234
}
```
### 认领工单 `POST /tickets/pick`
Request
```json
{
"token": "token_test",
"id": 4234
}
```
### 更新工单状态 `POST /tickets/update`
Request
```json
{
"token": "token_test",
"id": "id",
"status": 3
}
```
### 确认已取回 `POST /tickets/retrieve`
Request
```json
{
"token": "token_test",
"id": "id"
}
```
### 获取七天内未完成工单 `GET /tickets/uncompleted`
Request
```json
{
"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
}
```
### 工单信息 `GET /tickets/info?id={id}`
data (same as oreo):
```json
{
"id": 6847,
"type": 1,
"device": "华硕",
"deviceModel": "灵耀X14",
"owner": "唐姐姐",
"phone": "15555555555",
"description": "清灰",
"workers": [],
"createdTime": "2024-03-07T19:52:48.523303",
"status": 5,
"isConfirmed": false,
"notes": [
{
"avatar": "https://....jpg",
"id": 21368,
"op": "宇航员",
"type": 0,
"content": "",
"createdTime": "2024-03-07T19:52:48.523305"
},
{
"avatar": "https://....jpg",
"id": 21370,
"op": "宇航员",
"type": 2,
"content": "1",
"createdTime": "2024-03-07T19:58:27.838816"
},
{
"avatar": "https://....jpg",
"id": 21373,
"op": "宇航员",
"type": 2,
"content": "4",
"createdTime": "2024-03-07T20:28:12.070707"
},
{
"avatar": "https://....jpg",
"id": 21374,
"op": "宇航员",
"type": 2,
"content": "5",
"createdTime": "2024-03-07T20:30:15.770486"
}
],
"accessories": [2],
"picked": false
}
```
## 成员相关
### 成员登录 `POST /member/login`
Request
```json
{
"token": "token_test",
"code": "code_test",
}
```
这里的 code 是来源于小程序扫描统一身份认证生成的二维码
### 检查 token 是否登陆 `GET /member/checklogin?token={token}` OK
data
```json
{
"avatar": "https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png",
"name": "宇航员",
"phone": "13311451419",
}
```
### 成员登出 `POST /member/logout`
Request
```json
{
"token": "token_test"
}
```
### 成员值班信息 `GET /member/duty/info`
#### 当前在值班
data:
```json
{
"isInDuty": true,
"inDutyCnt": 3,
"currentDuty": "2"
}
```
#### 当前未值班
data:
```json
{
"isInDuty": false,
"offDutyReason": "学园维修",
"dutyRecoverTime": "下周一"
}
```
+136 -3
View File
@@ -1,5 +1,138 @@
export default { import mytickets from './mytickets.json';
'GET /api/user/1': {}, import ticketInfo from './ticketInfo.json';
import uncompleted from './uncompleted.json';
import ticketsList from './ticketsList.json';
import ticketsSearch from './ticketSearch.json';
'POST /api/upload': {}, export default {
'GET /ping': {
success: true,
data: {
msg: 'pong',
},
},
'GET /duty/info': {
success: true,
data: {
token: 'token_test',
isInDuty: true,
inDutyCnt: 3,
currentDuty: 'others',
otherDutyTime: '9:30-11:30',
place: '蓝田',
},
},
'GET /user/info': {
success: true,
data: {
token: 'token_test',
name: '马保国',
phone: 13333333333,
},
},
'POST /user/update': {
success: true,
data: {},
},
'GET /user/locale/get': {
success: true,
data: {
lang: 'zh_CN',
},
},
'POST /user/locale/update': {
success: true,
data: {},
},
'POST /report': {
success: true,
data: {},
},
'GET /user/mytickets': {
success: true,
data: mytickets,
},
'GET /tickets/info': {
success: true,
data: ticketInfo,
},
'POST /tickets/addnote': {
success: true,
data: {},
},
'POST /tickets/create': {
success: true,
data: {},
},
'POST /tickets/addtooreo': {
success: true,
data: {},
},
'POST /tickets/pick': {
success: true,
data: {},
},
'POST /tickets/update': {
success: true,
data: {},
},
'POST /tickets/retrieve': {
success: true,
data: {},
},
'POST /member/login': {
success: true,
data: {
avatar:
'https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png',
name: '宇航员',
phone: '13311451419',
},
},
'GET /tickets/uncompleted': {
success: true,
data: uncompleted,
},
'GET /tickets/list': {
success: true,
data: ticketsList,
},
'GET /tickets/search': {
success: true,
data: ticketsSearch,
},
'POST /member/logout': {
success: true,
},
'POST /member/checklogin': {
success: true,
data: {
avatar:
'https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png',
name: '宇航员',
phone: '13311451419',
},
},
'GET /member/duty/info': {
success: true,
data: {
token: 'token_test',
isInDuty: true,
inDutyCnt: 6,
currentDuty: '3',
place: '204',
},
},
'POST /login': {
success: true,
data: {
token: '__token_test_zjueva1984__',
},
},
'GET /checklogin': {
success: true,
data: {
islogin: false,
},
},
}; };
+15
View File
@@ -0,0 +1,15 @@
{
"list": [
{
"id": 6830,
"type": 1,
"status": 2,
"device": "主机",
"deviceModel": "技嘉",
"owner": "武技栏",
"phone": "18888888888",
"createdTime": "2024-03-06T19:49:27.043865",
"isConfirmed": false
}
]
}
+49
View File
@@ -0,0 +1,49 @@
{
"id": 6830,
"type": 1,
"device": "华硕",
"deviceModel": "灵耀X14",
"owner": "唐姐姐",
"phone": "15555555555",
"description": "清灰",
"workers": ["宇航员"],
"createdTime": "2024-03-07T19:52:48.523303",
"status": 5,
"isConfirmed": false,
"notes": [
{
"avatar": "https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png",
"id": 21368,
"op": "宇航员",
"type": 0,
"content": "",
"createdTime": "2024-03-07T19:52:48.523305"
},
{
"avatar": "https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png",
"id": 21370,
"op": "宇航员",
"type": 2,
"content": "1",
"createdTime": "2024-03-07T19:58:27.838816"
},
{
"avatar": "https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png",
"id": 21373,
"op": "宇航员",
"type": 2,
"content": "4",
"createdTime": "2024-03-07T20:28:12.070707"
},
{
"avatar": "https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png",
"id": 21374,
"op": "宇航员",
"type": 2,
"content": "5",
"createdTime": "2024-03-07T20:30:15.770486"
}
],
"accessories": [2],
"picked": false
}
+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
}
]
}
+15
View File
@@ -0,0 +1,15 @@
{
"list": [
{
"id": 6832,
"type": 1,
"status": 2,
"device": "ROG",
"deviceModel": "幻 14 2022",
"owner": "晓洋",
"phone": "18888888887",
"createdTime": "2024-03-07T11:45:14.191981",
"isConfirmed": false
}
]
}
+35929 -35876
View File
File diff suppressed because it is too large Load Diff
+102 -98
View File
@@ -1,100 +1,104 @@
{ {
"name": "eva-notify", "name": "eva-notify",
"version": "1.0.0", "version": "1.0.0",
"private": true, "private": true,
"description": "A Wechat miniprogram project of EVA platform", "description": "A Wechat miniprogram project of EVA platform",
"templateInfo": { "templateInfo": {
"name": "default", "name": "default",
"typescript": true, "typescript": true,
"css": "Sass", "css": "Sass",
"framework": "React" "framework": "React"
}, },
"scripts": { "scripts": {
"build:weapp": "taro build --type weapp", "build:weapp": "taro build --type weapp",
"build:swan": "taro build --type swan", "build:swan": "taro build --type swan",
"build:alipay": "taro build --type alipay", "build:alipay": "taro build --type alipay",
"build:tt": "taro build --type tt", "build:tt": "taro build --type tt",
"build:h5": "taro build --type h5", "build:h5": "taro build --type h5",
"build:rn": "taro build --type rn", "build:rn": "taro build --type rn",
"build:qq": "taro build --type qq", "build:qq": "taro build --type qq",
"build:jd": "taro build --type jd", "build:jd": "taro build --type jd",
"build:quickapp": "taro build --type quickapp", "build:quickapp": "taro build --type quickapp",
"build:harmony-hybrid": "taro build --type harmony-hybrid", "build:harmony-hybrid": "taro build --type harmony-hybrid",
"dev:weapp": "npm run build:weapp -- --watch", "dev:weapp": "npm run build:weapp -- --watch --mode dev",
"dev:swan": "npm run build:swan -- --watch", "dev:swan": "npm run build:swan -- --watch",
"dev:alipay": "npm run build:alipay -- --watch", "dev:alipay": "npm run build:alipay -- --watch",
"dev:tt": "npm run build:tt -- --watch", "dev:tt": "npm run build:tt -- --watch",
"dev:h5": "npm run build:h5 -- --watch", "dev:h5": "npm run build:h5 -- --watch",
"dev:rn": "npm run build:rn -- --watch", "dev:rn": "npm run build:rn -- --watch",
"dev:qq": "npm run build:qq -- --watch", "dev:qq": "npm run build:qq -- --watch",
"dev:jd": "npm run build:jd -- --watch", "dev:jd": "npm run build:jd -- --watch",
"dev:quickapp": "npm run build:quickapp -- --watch", "dev:quickapp": "npm run build:quickapp -- --watch",
"dev:harmony-hybrid": "npm run build:harmony-hybrid -- --watch", "dev:harmony-hybrid": "npm run build:harmony-hybrid -- --watch",
"test": "jest", "test": "jest",
"prepare": "husky install" "prepare": "husky install"
}, },
"browserslist": [ "browserslist": [
"last 3 versions", "last 3 versions",
"Android >= 4.1", "Android >= 4.1",
"ios >= 8" "ios >= 8"
], ],
"author": "", "author": "",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.21.5", "@babel/runtime": "^7.21.5",
"@tarojs/components": "3.6.24", "@tarojs/components": "3.6.24",
"@tarojs/helper": "3.6.24", "@tarojs/helper": "3.6.24",
"@tarojs/plugin-framework-react": "3.6.24", "@tarojs/plugin-framework-react": "3.6.24",
"@tarojs/plugin-mock": "^0.0.9", "@tarojs/plugin-platform-alipay": "3.6.24",
"@tarojs/plugin-platform-alipay": "3.6.24", "@tarojs/plugin-platform-harmony-hybrid": "3.6.24",
"@tarojs/plugin-platform-harmony-hybrid": "3.6.24", "@tarojs/plugin-platform-jd": "3.6.24",
"@tarojs/plugin-platform-jd": "3.6.24", "@tarojs/plugin-platform-qq": "3.6.24",
"@tarojs/plugin-platform-qq": "3.6.24", "@tarojs/plugin-platform-swan": "3.6.24",
"@tarojs/plugin-platform-swan": "3.6.24", "@tarojs/plugin-platform-tt": "3.6.24",
"@tarojs/plugin-platform-tt": "3.6.24", "@tarojs/plugin-platform-weapp": "3.6.24",
"@tarojs/plugin-platform-weapp": "3.6.24", "@tarojs/react": "3.6.24",
"@tarojs/react": "3.6.24", "@tarojs/runtime": "3.6.24",
"@tarojs/runtime": "3.6.24", "@tarojs/shared": "3.6.24",
"@tarojs/shared": "3.6.24", "@tarojs/taro": "3.6.24",
"@tarojs/taro": "3.6.24", "moment": "^2.30.1",
"react": "^18.0.0", "process": "^0.11.10",
"react-dom": "^18.0.0", "react": "^18.0.0",
"taro-ui": "^3.3.0" "react-dom": "^18.0.0",
}, "taro-ui": "^3.3.0"
"devDependencies": { },
"@babel/core": "^7.8.0", "devDependencies": {
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.5", "@babel/core": "^7.8.0",
"@tarojs/cli": "3.6.24", "@pmmmwh/react-refresh-webpack-plugin": "^0.5.5",
"@tarojs/plugin-platform-h5": "^3.6.24", "@tarojs/cli": "3.6.24",
"@tarojs/taro-loader": "3.6.24", "@tarojs/plugin-mock": "^0.0.9",
"@tarojs/test-utils-react": "^0.1.1", "@tarojs/plugin-platform-h5": "3.6.24",
"@tarojs/webpack5-runner": "3.6.24", "@tarojs/taro-loader": "3.6.24",
"@types/jest": "^29.3.1", "@tarojs/test-utils-react": "^0.1.1",
"@types/node": "^18.15.11", "@tarojs/webpack5-runner": "3.6.24",
"@types/react": "^18.0.0", "@types/jest": "^29.3.1",
"@types/sass": "^1.43.1", "@types/node": "^18.15.11",
"@types/webpack-env": "^1.13.6", "@types/react": "^18.0.0",
"@typescript-eslint/eslint-plugin": "^6.2.0", "@types/sass": "^1.43.1",
"@typescript-eslint/parser": "^6.2.0", "@types/webpack-env": "^1.13.6",
"babel-preset-taro": "3.6.24", "@typescript-eslint/eslint-plugin": "^6.2.0",
"eslint": "^8.12.0", "@typescript-eslint/parser": "^6.2.0",
"eslint-config-taro": "3.6.24", "babel-preset-taro": "3.6.24",
"eslint-plugin-import": "^2.12.0", "eslint": "^8.12.0",
"eslint-plugin-prettier": "^5.1.3", "eslint-config-taro": "3.6.24",
"eslint-plugin-react": "^7.8.2", "eslint-plugin-import": "^2.12.0",
"eslint-plugin-react-hooks": "^4.2.0", "eslint-plugin-prettier": "^5.1.3",
"husky": "^9.0.11", "eslint-plugin-react": "^7.8.2",
"jest": "^29.3.1", "eslint-plugin-react-hooks": "^4.2.0",
"jest-environment-jsdom": "^29.5.0", "husky": "^9.0.11",
"lint-staged": "^15.2.2", "jest": "^29.3.1",
"postcss": "^8.4.18", "jest-environment-jsdom": "^29.5.0",
"react-refresh": "^0.11.0", "lint-staged": "^15.2.2",
"stylelint": "^14.4.0", "mockjs": "^1.1.0",
"ts-node": "^10.9.1", "postcss": "^8.4.18",
"tsconfig-paths-webpack-plugin": "^4.1.0", "react-refresh": "^0.11.0",
"typescript": "^5.1.0", "stylelint": "^14.4.0",
"webpack": "5.78.0" "ts-node": "^10.9.1",
}, "tsconfig-paths-webpack-plugin": "^4.1.0",
"lint-staged": { "typescript": "^5.1.0",
"*": "prettier --write" "webpack": "5.78.0"
} },
"lint-staged": {
"*.ts": "prettier --write",
"*.tsx": "prettier --write"
}
} }
+3 -1
View File
@@ -2,6 +2,8 @@
"description": "项目私有配置文件。此文件中的内容将覆盖 project.config.json 中的相同字段。项目的改动优先同步到此文件中。详见文档:https://developers.weixin.qq.com/miniprogram/dev/devtools/projectconfig.html", "description": "项目私有配置文件。此文件中的内容将覆盖 project.config.json 中的相同字段。项目的改动优先同步到此文件中。详见文档:https://developers.weixin.qq.com/miniprogram/dev/devtools/projectconfig.html",
"projectname": "EVA-Notify", "projectname": "EVA-Notify",
"setting": { "setting": {
"compileHotReLoad": true "compileHotReLoad": true,
"urlCheck": false,
"bigPackageSizeSupport": true
} }
} }
+7 -1
View File
@@ -3,8 +3,14 @@ export default defineAppConfig({
'pages/index/index', 'pages/index/index',
'pages/repair/repair', 'pages/repair/repair',
'pages/user/user', 'pages/user/user',
'pages/user/myTicket/myTicket',
'pages/user/inform/inform', 'pages/user/inform/inform',
'pages/user/settings/settings', 'pages/user/about/about',
'pages/user/report/report',
'pages/user/member/member',
'pages/TicketDetail/TicketDetail',
'pages/TicketList/TicketList',
'pages/404/404',
], ],
window: { window: {
backgroundTextStyle: 'light', backgroundTextStyle: 'light',
+2 -1
View File
@@ -2,12 +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 { pingAte } from './service/pingAte';
function App({ children }: PropsWithChildren<any>) { function App({ children }: PropsWithChildren<any>) {
useLaunch(() => { useLaunch(() => {
console.log('App launched.'); console.log('App launched.');
pingAte();
}); });
// 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

+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="1709729147345" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7587" width="32" height="32" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M960 170.56L869.44 80 512 437.44 154.56 80 64 170.56 421.44 528 64 885.44l90.56 90.56L512 618.56 869.44 976 960 885.44 602.56 528 960 170.56z" p-id="7588" fill="#d4237a"></path></svg>

After

Width:  |  Height:  |  Size: 514 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="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>

After

Width:  |  Height:  |  Size: 746 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="1709729289782" class="icon" viewBox="0 0 1418 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8708" width="44.3125" height="32" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M491.191709 1023.803077L0.136305 539.63733l111.888035-110.273886 379.167369 373.89186L1305.549204 0.433064 1417.437238 110.706951 491.191709 1023.803077z" p-id="8709" fill="#12c53d"></path></svg>

After

Width:  |  Height:  |  Size: 531 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="1710232513408" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4296" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24"><path d="M816.672 937.344c-8.192 0-16.384-3.136-22.624-9.376l-213.952-213.952c-12.512-12.512-12.512-32.736 0-45.248s32.736-12.512 45.248 0l191.328 191.328 33.408-33.376-190.848-190.848c-12.512-12.512-12.512-32.736 0-45.248s32.736-12.512 45.248 0l213.472 213.472c6.016 6.016 9.376 14.112 9.376 22.624s-3.36 16.64-9.376 22.624l-78.656 78.624C833.024 934.208 824.832 937.344 816.672 937.344z" fill="#5C636E" p-id="4297"></path><path d="M590.752 128c0-0.032 0-0.064 0-0.064 1.472-4.16 2.048-8.352 1.792-12.512 0 0 0 0 0 0 0 0-0.032-0.064-0.032-0.096-0.256-4.128-1.312-8.096-3.104-11.776-0.352-0.704-0.896-1.248-1.28-1.92-1.632-2.848-3.456-5.472-5.952-7.712-0.928-0.864-2.08-1.376-3.136-2.112-1.92-1.376-3.616-3.008-5.888-3.968-0.608-0.256-1.248-0.384-1.888-0.608-0.032 0-0.064-0.032-0.096-0.032-114.144-46.624-243.808-20.704-331.072 66.592C239.328 154.528 239.04 155.584 238.336 156.416 237.472 157.12 236.448 157.408 235.648 158.208L73.664 319.552c-6.016 6.016-9.408 14.144-9.408 22.656s3.36 16.64 9.376 22.656l98.304 98.304c6.016 6.016 14.144 9.376 22.624 9.376s16.64-3.36 22.624-9.376l56.032-56.032 68.192 68.224c6.24 6.24 14.432 9.376 22.624 9.376s16.384-3.136 22.624-9.376c12.512-12.48 12.512-32.736 0-45.248l-90.816-90.848c-12.512-12.512-32.736-12.512-45.248 0L194.56 395.296l-52.992-53.024 139.264-138.72c0.832-0.8 1.12-1.888 1.824-2.752 0.864-0.704 1.92-0.992 2.72-1.824 40-39.936 91.296-63.072 144.864-68.768-2.208 1.664-4.384 3.392-6.56 5.12-8.96 6.784-17.632 14.016-25.664 22.048-0.544 0.544-0.736 1.248-1.216 1.824-19.232 19.36-35.936 41.024-49.568 64.512-2.464 4.224-4.768 8.448-7.008 12.736l0.416 0.224c-12.288 24.64-12.288 53.664 0.48 78.144 1.536 2.944 3.52 5.504 5.76 7.744 0.768 0.96 1.088 2.112 1.984 2.976l70.432 70.464c6.24 6.24 14.432 9.376 22.624 9.376s16.384-3.136 22.624-9.376c12.512-12.48 12.512-32.736 0-45.248l-67.072-67.072c-2.624-6.112-2.688-13.024 0.448-18.976 0.16-0.288 0.128-0.608 0.256-0.896 1.44-2.656 2.848-5.344 4.384-7.968 11.008-18.944 24.48-36.448 40.064-52.032 4.096-4.096 8.608-7.648 12.96-11.456 30.144-25.28 67.232-40.864 106.816-43.136 0.576-0.032 1.056-0.352 1.632-0.416 3.616-0.384 7.104-1.184 10.368-2.72 0.512-0.256 0.896-0.64 1.376-0.896 3.168-1.696 6.048-3.776 8.512-6.496 0.256-0.288 0.384-0.64 0.608-0.928 2.08-2.464 4.128-4.928 5.44-8.064C590.624 129.12 590.528 128.544 590.752 128z" fill="#5C636E" p-id="4298"></path><path d="M289.536 960.032c-28.384 0-56.928-6.368-82.624-18.432-9.408-4.448-16.096-13.184-17.888-23.456-1.792-10.24 1.504-20.736 8.896-28.128l88.064-88.096-33.056-33.024-87.52 87.488c-7.424 7.424-18.048 10.848-28.384 8.832-10.336-1.888-19.104-8.704-23.392-18.304-32.736-72.64-17.088-159.072 38.944-215.104 50.048-50.08 126.048-68.384 193.952-47.04l238.688-238.72c-21.28-67.712-3.648-143.264 47.04-193.952 36.128-36.16 84.256-56.064 135.456-56.064 27.264 0 54.816 5.92 79.648 17.12 9.568 4.32 16.448 13.056 18.304 23.392 1.92 10.336-1.408 20.96-8.832 28.384l-88.8 88.8 33.024 33.056 89.376-89.344c7.392-7.392 17.92-10.72 28.128-8.896 10.272 1.792 19.04 8.48 23.456 17.888 34.496 73.376 19.424 160.96-37.536 217.92-36.096 36.096-84.128 56-135.296 56-20.704 0-41.536-3.392-61.216-9.952l-237.12 237.12c22.688 68.48 5.44 145.024-46.048 196.544C388.736 940.16 340.672 960.032 289.536 960.032zM282.592 895.84c36.352 2.112 71.36-11.392 96.992-37.024 37.952-37.952 47.936-96.384 24.864-145.408-5.76-12.224-3.232-26.72 6.336-36.256l266.816-266.848c9.536-9.536 24.032-12.032 36.256-6.336 47.936 22.56 108 12.544 145.408-24.864 25.952-25.92 38.784-61.408 36.992-96.96l-72.576 72.544c-6.016 6.016-14.112 9.376-22.624 9.376l0 0c-8.512 0-16.64-3.36-22.624-9.376L700.16 276.416c-12.512-12.512-12.512-32.736 0-45.248l71.04-71.04c-35.072-0.896-68.8 12.384-93.696 37.28-37.92 37.92-48.064 94.272-25.856 143.552 5.44 12.128 2.848 26.368-6.56 35.776l-267.936 267.968c-9.376 9.376-23.648 11.936-35.776 6.56-47.68-21.504-106.624-11.104-143.584 25.856-25.504 25.536-38.464 59.392-37.408 93.856l69.92-69.92c12.512-12.512 32.736-12.512 45.248 0l78.304 78.272c6.016 6.016 9.376 14.112 9.376 22.624 0 8.48-3.36 16.64-9.376 22.624L282.592 895.84z" fill="#5C636E" p-id="4299"></path></svg>

After

Width:  |  Height:  |  Size: 4.3 KiB

+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

+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="1709817911051" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4420" width="24" height="24" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M523.52 965.12a448 448 0 1 1 448-448 448 448 0 0 1-448 448z m0-832a384 384 0 1 0 384 384 384 384 0 0 0-384-384z" p-id="4421" fill="#c89bc7"></path><path d="M523.52 772.16a32 32 0 0 1-32-32V448a32 32 0 0 1 64 0v292.8a32 32 0 0 1-32 31.36z" p-id="4422" fill="#c89bc7"></path><path d="M523.52 293.12m-48 0a48 48 0 1 0 96 0 48 48 0 1 0-96 0Z" p-id="4423" fill="#c89bc7"></path></svg>

After

Width:  |  Height:  |  Size: 710 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="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

+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="1710991348108" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="26534" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24"><path d="M512 512m-48 0a48 48 0 1 0 96 0 48 48 0 1 0-96 0Z" p-id="26535" fill="#9ACD32"></path><path d="M712 512m-48 0a48 48 0 1 0 96 0 48 48 0 1 0-96 0Z" p-id="26536" fill="#9ACD32"></path><path d="M312 512m-48 0a48 48 0 1 0 96 0 48 48 0 1 0-96 0Z" p-id="26537" fill="#9ACD32"></path><path d="M925.2 338.4c-22.6-53.7-55-101.9-96.3-143.3-41.3-41.3-89.5-73.8-143.3-96.3C630.6 75.7 572.2 64 512 64h-2c-60.6 0.3-119.3 12.3-174.5 35.9-53.3 22.8-101.1 55.2-142 96.5-40.9 41.3-73 89.3-95.2 142.8-23 55.4-34.6 114.3-34.3 174.9 0.3 69.4 16.9 138.3 48 199.9v152c0 25.4 20.6 46 46 46h152.1c61.6 31.1 130.5 47.7 199.9 48h2.1c59.9 0 118-11.6 172.7-34.3 53.5-22.3 101.6-54.3 142.8-95.2 41.3-40.9 73.8-88.7 96.5-142 23.6-55.2 35.6-113.9 35.9-174.5 0.3-60.9-11.5-120-34.8-175.6z m-151.1 438C704 845.8 611 884 512 884h-1.7c-60.3-0.3-120.2-15.3-173.1-43.5l-8.4-4.5H188V695.2l-4.5-8.4C155.3 633.9 140.3 574 140 513.7c-0.4-99.7 37.7-193.3 107.6-263.8 69.8-70.5 163.1-109.5 262.8-109.9h1.7c50 0 98.5 9.7 144.2 28.9 44.6 18.7 84.6 45.6 119 80 34.3 34.3 61.3 74.4 80 119 19.4 46.2 29.1 95.2 28.9 145.8-0.6 99.6-39.7 192.9-110.1 262.7z" p-id="26538" fill="#9ACD32"></path></svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

+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="1710990953433" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="11565" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24"><path d="M510 64.4c-246.5 0-447.6 200-447.6 447.6 0 246.5 200 447.6 447.6 447.6 246.5 0 447.6-200 447.6-447.6 0-246.5-200.1-447.6-447.6-447.6z m0 831.9c-212.3 0-384.3-172-384.3-384.3s172-384.3 384.3-384.3 384.3 172 384.3 384.3-172 384.3-384.3 384.3z m229.1-181.2c-18.4-70.4-67.9-125.5-131.2-153.6 48-30.6 79.6-84.2 79.6-144.9 0-94.9-77.1-172-172-172s-172 77.1-172 172c0 61.2 31.6 114.8 79.6 144.9-63.8 27.6-113.3 83.2-131.7 153.6-4.1 16.3 5.6 33.2 21.9 37.3 2.6 0.5 5.1 1 7.7 1 13.8 0 26-9.2 29.6-23 19.4-75 87.3-127.1 164.3-127.1S660 655.4 679.4 730.4c4.1 16.3 20.9 26 37.3 21.9 16.8-4 27-20.9 22.4-37.2zM515.6 305.8c61.2 0 110.7 49.5 110.7 110.7s-49.5 110.7-110.7 110.7-110.7-49.5-110.7-110.7 49.5-110.7 110.7-110.7z" p-id="11566" fill="#78A4FA"></path></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

+11
View File
@@ -0,0 +1,11 @@
export type FixStatus = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7;
export const defaultAvatar =
'https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png';
export const tmplIds = ['hbblqs928F2kd1s0IR_pDIAjYrNscUmz6tv6NZKsctM'];
export type Info = {
phone: string;
name: string;
};
@@ -0,0 +1,3 @@
export default {
component: true,
};
@@ -0,0 +1,189 @@
import { View } from '@tarojs/components';
import { Component, ReactNode } from 'react';
import Taro from '@tarojs/taro';
import {
ShowElements,
TicketInfo,
TicketNote,
} from '@/pages/TicketDetail/TicketNote';
import pt from '@/plain-text';
import { RequestState } from '@/service';
import { getTicketInfo } from '@/service/ticketsInfo';
import { AtActivityIndicator, AtCard, AtSteps, AtToast } from 'taro-ui';
import NoteList from '../NoteList/NoteList';
interface StepItemData {
title: string;
}
interface DetailFrameworkState {
current: number;
items: Array<StepItemData>;
ticketInfo: TicketInfo;
notes: Array<TicketNote>;
rs: RequestState;
}
interface DetailFrameworkProps {
middleButton: JSX.Element;
id: number;
isInfoShow: { [key: string]: boolean };
}
export default class DetailFramework extends Component<
DetailFrameworkProps,
DetailFrameworkState
> {
state = {
current: 0,
items: [],
ticketInfo: new TicketInfo(),
notes: [new TicketNote()],
rs: new RequestState(),
};
componentDidMount(): void {
const navBar = pt.get().navBar;
Taro.setNavigationBarTitle({
title: navBar.ticketDetail,
});
getTicketInfo(this, this.props.id);
}
props: Readonly<DetailFrameworkProps> = {
middleButton: <View></View>,
id: 0,
isInfoShow: {
device: true,
createdTime: true,
description: true,
current: true,
notelist: true,
showAllNotes: true,
info: true,
},
};
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 elements: ShowElements = {
device: this.props.isInfoShow['device'] ? (
<View className='at-article__h1'>
{this.state.ticketInfo.device +
' ' +
this.state.ticketInfo.deviceModel}
</View>
) : (
<View></View>
),
createdTime: this.props.isInfoShow['createdTime'] ? (
<View className='at-article__info'>
{pt.get().common.createdAtText(this.state.ticketInfo.createdTime)}
</View>
) : (
<View></View>
),
description: this.props.isInfoShow['description'] ? (
<View
style={{
paddingTop: '20rpx',
paddingBottom: '20rpx',
width: '94%',
marginLeft: '3%',
}}
>
<AtCard isFull title={pt.get().ticketDetail.descTitle}>
<View className='at-article__h3'>
{this.state.ticketInfo.description}
</View>
</AtCard>
</View>
) : (
<View></View>
),
info: this.props.isInfoShow['info'] ? (
<View
style={{
paddingTop: '20rpx',
paddingBottom: '20rpx',
width: '94%',
marginLeft: '3%',
}}
>
<AtCard
isFull
title={pt.get().ticketDetail.info.title}
extra={pt.get().ticketDetail.info.extra}
extraStyle={{ fontSize: '32rpx', marginRight: '40rpx' }}
>
<View style={{ display: 'flex' }}>
<View className='at-article__h3'>
{this.state.ticketInfo.info.name}
</View>
<View style={{ marginLeft: 'auto' }} className='at-article__h3'>
{this.state.ticketInfo.info.phone}
</View>
</View>
</AtCard>
</View>
) : (
<View></View>
),
current: this.props.isInfoShow['current'] ? (
<View style={{ padding: '20rpx' }}>
<AtSteps
items={this.state.items}
current={this.state.current}
onChange={() => {}}
/>
</View>
) : (
<View></View>
),
notelist: this.props.isInfoShow['notelist'] ? (
this.props.isInfoShow['showAllNotes'] ? (
<View style={{ padding: '20rpx' }}>
<NoteList noteList={this.state.notes} />
</View>
) : (
<View style={{ padding: '20rpx' }}>
<NoteList
noteList={[this.state.notes[this.state.notes.length - 1]]}
/>
</View>
)
) : (
<View></View>
),
};
return (
<View>
{elements.device}
{elements.createdTime}
{elements.description}
{elements.info}
{elements.current}
{this.props.middleButton}
{elements.notelist}
</View>
);
}
}
@@ -0,0 +1,3 @@
export default {
component: true,
};
+63
View File
@@ -0,0 +1,63 @@
import { Image, View } from '@tarojs/components';
import { Component, ReactNode } from 'react';
import { TicketNote, StatusStr } from '@/pages/TicketDetail/TicketNote';
import pt from '@/plain-text';
import { timeFormat } from '@/utils';
import './NoteCard.scss';
interface NoteCardProps {
note: TicketNote;
}
export default class NoteCard extends Component<NoteCardProps, {}> {
props: Readonly<NoteCardProps> = {
note: new TicketNote(),
};
render(): ReactNode {
var message = '';
const note = this.props.note;
const td = pt.get().ticketDetail;
const createMessage = td.createTicketMessage;
const modifyMessage = td.statusModifyMessage;
const prefix = td.statusModifyPrefix;
switch (note.type) {
case 0:
message = createMessage;
break;
case 1:
message = note.content;
break;
case 2:
message = prefix + modifyMessage.get(note.content as StatusStr) || '';
break;
}
return (
<View className='at-row at-row__align--center'>
<View className='at-col at-col-1 at-col--auto'>
<Image
style='width: 70rpx; height: 70rpx; border-radius: 35px;'
src={note.avatar}
mode='aspectFit'
/>
</View>
<View
className='at-col at-col--wrap'
style={{
marginTop: '40rpx',
marginBottom: '40rpx',
wordBreak: 'normal',
}}
>
<View className='at-article__p'>{note.op}</View>
<View className='at-article__info'>
{note.createdTime.format(timeFormat)}
</View>
<View className='at-article__h3'>{message}</View>
</View>
</View>
);
}
}
@@ -0,0 +1,3 @@
export default {
component: true,
};
+32
View File
@@ -0,0 +1,32 @@
import { Component, ReactNode } from 'react';
import NoteCard from '@/components/NoteCard/NoteCard';
import { TicketNote } from '@/pages/TicketDetail/TicketNote';
import { View } from '@tarojs/components';
import { AtDivider } from 'taro-ui';
import pt from '@/plain-text';
interface NoteListProps {
noteList: Array<TicketNote>;
}
export default class NoteList extends Component<NoteListProps, {}> {
props: Readonly<NoteListProps> = {
noteList: [],
};
render(): ReactNode {
return (
<View>
<AtDivider
fontColor='#CCC'
content={pt.get().ticketDetail.divider}
height={20}
/>
{this.props.noteList.map((note, idx) => (
<View key={idx}>
<NoteCard note={note} />
</View>
))}
</View>
);
}
}
+16 -4
View File
@@ -1,12 +1,24 @@
import { View } from '@tarojs/components'; import { View, Text } from '@tarojs/components';
import { AtDivider } from 'taro-ui'; import { AtDivider } from 'taro-ui';
import pt from '@/plain-text';
export default () => { export default () => {
const blankHeight = 120; const blankHeightUpper = '30rpx';
const blankHeightLower = '220rpx';
return ( return (
<View> <View>
<AtDivider content='EVA Notify' fontColor='#dddddd' lineColor='#dddddd' /> <View style={{ height: blankHeightUpper }}></View>
<View style={{ height: blankHeight }}></View> <View>
<AtDivider
content={pt.get().pageFooter.dividerText}
fontColor='#dddddd'
lineColor='#dddddd'
/>
</View>
<View className='at-row at-row__justify--center'>
<Text style='color:#dddddd; fontSize:32rpx'>© 2024 EVA Tech</Text>
</View>
<View style={{ height: blankHeightLower }}></View>
</View> </View>
); );
}; };
@@ -0,0 +1,3 @@
export default {
component: true,
};
@@ -0,0 +1,61 @@
import { AtListItem } from 'taro-ui';
import create from '@/assets/icons/TicketState/create.svg';
import repair from '@/assets/icons/TicketState/repair.svg';
import success from '@/assets/icons/TicketState/success.svg';
import fail from '@/assets/icons/TicketState/fail.svg';
import refuse from '@/assets/icons/TicketState/refuse.svg';
import retrieve from '@/assets/icons/TicketState/retrieve.svg';
import pt from '@/plain-text';
import Taro from '@tarojs/taro';
import { FixStatus } from '@/common';
export class TicketListItem {
id: number;
brand: string;
model: string;
status: FixStatus;
createAt: moment.Moment;
iconMap: Map<FixStatus, string>;
constructor(
id: number,
brand: string,
model: string,
status: FixStatus,
createAt: moment.Moment,
) {
this.id = id;
this.brand = brand;
this.model = model;
this.status = status;
this.createAt = createAt;
this.iconMap = new Map<FixStatus, string>([
[0, create],
[1, repair],
[2, refuse],
[3, retrieve],
[4, success],
[5, retrieve],
[6, fail],
[7, retrieve],
]);
}
render(): JSX.Element {
const tl = pt.get().ticketList;
return (
<AtListItem
title={this.brand + ' ' + this.model}
note={tl.createdAt(this.createAt.format('YYYY-MM-DD HH:mm'))}
extraText={tl.statusMap.get(this.status)}
arrow='right'
thumb={this.iconMap.get(this.status)}
onClick={() => {
Taro.navigateTo({
url: '/pages/TicketDetail/TicketDetail?id=' + this.id,
});
}}
/>
);
}
}
+52 -30
View File
@@ -1,45 +1,67 @@
import { Component, ReactNode } from 'react'; import { Component, ReactNode } from 'react';
import { AtTabBar } from 'taro-ui'; import { AtTabBar } from 'taro-ui';
import Taro from '@tarojs/taro'; import Taro from '@tarojs/taro';
import pt from '@/plain-text';
import wechatUser from '@/wechat';
import 'taro-ui/dist/style/index.scss'; import 'taro-ui/dist/style/index.scss';
import './index.scss'; import './index.scss';
const navList: Array<Taro.TabBarItem> = [ const navList: () => Array<Taro.TabBarItem> = () => {
{ return [
pagePath: '/pages/index/index', {
text: '主页', pagePath: '/pages/index/index',
}, text: pt.get().tabBar.indexText,
{ },
pagePath: '/pages/repair/repair', {
text: '维修', pagePath: '/pages/repair/repair',
}, text: pt.get().tabBar.repairText,
{ },
pagePath: '/pages/user/user', {
text: '我的', pagePath: '/pages/user/user',
}, text: pt.get().tabBar.userText,
]; },
];
};
const tabList = () => {
return wechatUser.getAccess()
? [
{
title: pt.get().tabBar.memberText,
iconType: 'sketch',
},
{
title: pt.get().tabBar.repairText,
iconType: 'settings',
},
{
title: pt.get().tabBar.userText,
iconType: 'user',
},
]
: [
{
title: pt.get().tabBar.indexText,
iconType: 'home',
},
{
title: pt.get().tabBar.repairText,
iconType: 'settings',
},
{
title: pt.get().tabBar.userText,
iconType: 'user',
},
];
};
export default class Index extends Component { export default class Index extends Component {
state = { state = {
selected: 0, selected: 0,
tabList: [
{
title: '主页',
iconType: 'home',
},
{
title: '维修',
iconType: 'settings',
},
{
title: '我的',
iconType: 'user',
},
],
}; };
handleClick(idx: number) { handleClick(idx: number) {
this.switchTab(idx, navList[idx].pagePath); this.switchTab(idx, navList()[idx].pagePath);
} }
switchTab(idx: number, url: string) { switchTab(idx: number, url: string) {
@@ -57,7 +79,7 @@ export default class Index extends Component {
return ( return (
<AtTabBar <AtTabBar
fixed fixed
tabList={this.state.tabList} tabList={tabList()}
onClick={this.handleClick.bind(this)} onClick={this.handleClick.bind(this)}
current={this.state.selected} current={this.state.selected}
/> />
@@ -1,4 +1,3 @@
export default definePageConfig({ export default definePageConfig({
navigationBarTitleText: '设置',
usingComponents: {}, 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.titleZhCn}
</View>
<View className='at-article__h2'>{pt.get().notFound.descZhCn}</View>
<View style={{ height: '150rpx' }}></View>
<View className='at-article__h1' style={{ fontWeight: 'bold' }}>
{pt.get().notFound.titleEnUs}
</View>
<View className='at-article__h2'>{pt.get().notFound.descEnUs}</View>
</View>
<PageFooter />
</View>
);
}
}
@@ -0,0 +1,3 @@
export default definePageConfig({
usingComponents: {},
});
+446
View File
@@ -0,0 +1,446 @@
import { Component, ReactNode } from 'react';
import { View } from '@tarojs/components';
import { getCurrentInstance } from '@tarojs/runtime';
import pt from '@/plain-text';
import {
AtActionSheet,
AtActionSheetItem,
AtButton,
AtFloatLayout,
AtForm,
AtMessage,
AtModal,
AtTextarea,
} from 'taro-ui';
import DetailFramework from '@/components/DetailFramework/DetailFramework';
import PageFooter from '@/components/PageFooter/PageFooter';
import { submitComment } from '@/service/submitComment';
import Taro from '@tarojs/taro';
import wechatUser from '@/wechat';
import { addToOreo } from '@/service/addToOreo';
import { pickTicket } from '@/service/pickTicket';
import { retrieve } from '@/service/retrieve';
import { changeStatus } from '@/service/changeStatus';
import { getDisable } from '@/service/getDisable';
const submitInterval = 5000;
interface TicketDetailState {
id: number;
isMember: boolean;
showOreoModal: boolean;
showCommentLayout: boolean;
showRetrieveModal: boolean;
showStatusSheet: boolean;
showPickModal: boolean;
comment: string;
isOreoLoading: boolean;
isOreoDisable: boolean;
isOreoDisable_main: boolean;
isPickLoading: boolean;
isPickDisable: boolean;
isPickDisable_main: boolean;
isRetrieveLoading: boolean;
isRetrieveDisable: boolean;
isRetrieveDisable_main: boolean;
isStatusLoading: boolean;
isStatusDisable: boolean;
isCommentLoading: boolean;
isCommentDisable: boolean;
isCommentDisable_main: boolean;
}
export default class TicketDetail extends Component<{}, TicketDetailState> {
state: Readonly<TicketDetailState> = {
id: 0,
isMember: false,
showOreoModal: false,
showCommentLayout: false,
showRetrieveModal: false,
showStatusSheet: false,
showPickModal: false,
comment: '',
isOreoLoading: false,
isOreoDisable: false,
isOreoDisable_main: false,
isPickLoading: false,
isPickDisable: false,
isPickDisable_main: false,
isRetrieveLoading: false,
isRetrieveDisable: false,
isRetrieveDisable_main: false,
isStatusLoading: false,
isStatusDisable: false,
isCommentLoading: false,
isCommentDisable: false,
isCommentDisable_main: false,
};
componentDidMount(): void {
const { router } = getCurrentInstance();
const id = router?.params.id as number;
this.setState({
id: id,
isMember: wechatUser.getAccess(),
});
getDisable(this, id);
}
onAddToOreo(): void {
this.setState({
showOreoModal: true,
});
}
onAddComment(): void {
this.setState({
showCommentLayout: true,
});
}
onRetrieved(): void {
this.setState({
showRetrieveModal: true,
});
}
onPick(): void {
this.setState({
showPickModal: true,
});
}
onChangeStatus(): void {
this.setState({
showStatusSheet: true,
});
}
handleOreoCancel(): void {
this.setState({
showOreoModal: false,
});
}
handleCommentCancel(): void {
this.setState({
showCommentLayout: false,
});
}
handleRetrieveCancel(): void {
this.setState({
showRetrieveModal: false,
});
}
handleStatusCancel(): void {
this.setState({
showStatusSheet: false,
});
}
handlePickCancel(): void {
this.setState({
showPickModal: false,
});
}
handleOreoConfirm(): void {
this.setState({
isOreoDisable: true,
showOreoModal: false,
});
addToOreo(this);
setTimeout(() => {
this.setState({
isOreoDisable: false,
});
}, submitInterval);
return;
}
handleRetrieveConfirm(): void {
this.setState({
isRetrieveDisable: true,
showRetrieveModal: false,
});
retrieve(this);
setTimeout(() => {
this.setState({
isRetrieveDisable: false,
});
}, submitInterval);
return;
}
handlePickConfirm(): void {
this.setState({
isPickDisable: true,
showPickModal: false,
});
pickTicket(this);
setTimeout(() => {
this.setState({
isPickDisable: false,
});
}, submitInterval);
return;
}
handleStatusChange(status: number): void {
this.setState({
showStatusSheet: false,
isStatusDisable: true,
});
changeStatus(this, status);
setTimeout(() => {
this.setState({
isStatusDisable: false,
});
}, submitInterval);
return;
}
handleCommentChange(comment: string) {
this.setState({
comment: comment,
});
return comment;
}
onCommentSubmit() {
this.setState({
isCommentDisable: true,
showCommentLayout: false,
});
if (this.state.comment == '') {
Taro.atMessage({
message: pt.get().button.submitText.blank,
type: 'error',
});
setTimeout(() => {
this.setState({
isCommentDisable: false,
});
}, submitInterval);
return;
}
submitComment(this);
setTimeout(() => {
this.setState({
isCommentDisable: false,
});
}, submitInterval);
}
render(): ReactNode {
const middleButton = this.state.isMember ? (
<View>
<View
className='at-row'
style={{ paddingTop: '20rpx', paddingBottom: '20rpx', width: '100%' }}
>
<View
className='at-col'
style={{ marginLeft: '20rpx', paddingRight: '10rpx', width: '50%' }}
>
<AtButton
loading={this.state.isPickLoading}
disabled={
this.state.isPickDisable || this.state.isPickDisable_main
}
type='secondary'
onClick={this.onPick.bind(this)}
>
{pt.get().ticketDetail.pick}
</AtButton>
</View>
<View
className='at-col'
style={{ marginLeft: '20rpx', paddingRight: '10rpx', width: '50%' }}
>
<AtButton
loading={this.state.isOreoLoading}
disabled={
this.state.isOreoDisable || this.state.isOreoDisable_main
}
type='primary'
onClick={this.onAddToOreo.bind(this)}
>
{pt.get().ticketDetail.addToOreo}
</AtButton>
</View>
</View>
<View
className='at-row'
style={{ paddingTop: '20rpx', paddingBottom: '40rpx', width: '100%' }}
>
<View
className='at-col'
style={{ marginLeft: '20rpx', paddingRight: '10rpx', width: '50%' }}
>
<AtButton
loading={this.state.isStatusLoading}
disabled={this.state.isStatusDisable}
type='primary'
onClick={this.onChangeStatus.bind(this)}
>
{pt.get().ticketDetail.status.button}
</AtButton>
</View>
<View
className='at-col'
style={{ marginLeft: '20rpx', paddingRight: '10rpx', width: '50%' }}
>
<AtButton
disabled={
this.state.isCommentDisable || this.state.isCommentDisable_main
}
loading={this.state.isCommentLoading}
type='secondary'
onClick={this.onAddComment.bind(this)}
>
{pt.get().ticketDetail.addNote}
</AtButton>
</View>
</View>
</View>
) : (
<View
className='at-row'
style={{ paddingTop: '20rpx', paddingBottom: '40rpx', width: '100%' }}
>
<View
className='at-col'
style={{ marginLeft: '20rpx', paddingRight: '10rpx', width: '50%' }}
>
<AtButton
loading={this.state.isRetrieveLoading}
disabled={
this.state.isRetrieveDisable || this.state.isRetrieveDisable_main
}
type='primary'
onClick={this.onRetrieved.bind(this)}
>
{pt.get().ticketDetail.tookAway}
</AtButton>
</View>
<View
className='at-col'
style={{ marginRight: '20rpx', paddingLeft: '10rpx', width: '50%' }}
>
<AtButton
disabled={
this.state.isCommentDisable || this.state.isCommentDisable_main
}
loading={this.state.isCommentLoading}
type='secondary'
onClick={this.onAddComment.bind(this)}
>
{pt.get().ticketDetail.addNote}
</AtButton>
</View>
</View>
);
const isInfoShow = {
device: true,
createdTime: true,
description: true,
info: wechatUser.getAccess() ? true : false,
current: true,
notelist: true,
showAllNotes: true,
};
return (
<View>
<AtMessage />
<AtModal
isOpened={this.state.showOreoModal}
title={pt.get().modal.addToOreo.title}
cancelText={pt.get().modal.cancel}
confirmText={pt.get().modal.confirm}
onCancel={this.handleOreoCancel.bind(this)}
onConfirm={this.handleOreoConfirm.bind(this)}
content={pt.get().modal.addToOreo.content}
/>
<AtModal
isOpened={this.state.showRetrieveModal}
title={pt.get().modal.retrieve.title}
cancelText={pt.get().modal.cancel}
confirmText={pt.get().modal.confirm}
onCancel={this.handleRetrieveCancel.bind(this)}
onConfirm={this.handleRetrieveConfirm.bind(this)}
content={pt.get().modal.retrieve.content}
/>
<AtModal
isOpened={this.state.showPickModal}
title={pt.get().modal.pick.title}
cancelText={pt.get().modal.cancel}
confirmText={pt.get().modal.confirm}
onCancel={this.handlePickCancel.bind(this)}
onConfirm={this.handlePickConfirm.bind(this)}
content={pt.get().modal.pick.content}
/>
<AtFloatLayout
isOpened={this.state.showCommentLayout}
title={pt.get().ticketDetail.comment.title}
onClose={this.handleCommentCancel.bind(this)}
>
<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}
/>
<AtButton formType='submit' type='primary'>
{pt.get().button.buttonText.submit}
</AtButton>
</AtForm>
</AtFloatLayout>
<AtActionSheet
isOpened={this.state.showStatusSheet}
cancelText={pt.get().ticketDetail.status.cancel}
title={pt.get().ticketDetail.status.title}
onCancel={this.handleStatusCancel.bind(this)}
onClose={this.handleStatusCancel.bind(this)}
>
<AtActionSheetItem onClick={this.handleStatusChange.bind(this, 0)}>
{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>
<DetailFramework
middleButton={middleButton}
id={this.state.id}
isInfoShow={isInfoShow}
/>
<PageFooter />
</View>
);
}
}
+33
View File
@@ -0,0 +1,33 @@
import { FixStatus, Info } from '@/common';
export class TicketInfo {
id: number;
type: 0 | 1;
device: string;
deviceModel: string;
description: string;
createdTime: moment.Moment;
status: FixStatus;
info: Info;
workers: string[];
}
export class TicketNote {
avatar: string;
id: number;
op: string;
type: 0 | 1 | 2;
content: string;
createdTime: moment.Moment;
}
export class ShowElements {
device: JSX.Element;
createdTime: JSX.Element;
description: JSX.Element;
info: JSX.Element;
current: JSX.Element;
notelist: JSX.Element;
}
export type StatusStr = '1' | '2' | '3' | '4' | '5';
@@ -0,0 +1,3 @@
export default definePageConfig({
usingComponents: {},
});
+108
View File
@@ -0,0 +1,108 @@
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
total={this.state.totalPage}
pageSize={this.state.pageSize}
current={this.state.currentPage}
onPageChange={this.onPageChange.bind(this)}
></AtPagination>
</View>
<PageFooter />
</View>
);
}
}
+126
View File
@@ -0,0 +1,126 @@
import { Component, ReactNode } from 'react';
import { View, Image } from '@tarojs/components';
import { AtTimeline } from 'taro-ui';
import pt from '@/plain-text';
import tick from '@/assets/icons/MainPage/tick.svg';
import cross from '@/assets/icons/MainPage/cross.svg';
import clock from '@/assets/icons/MainPage/offduty.svg';
import wechatUser from '@/wechat';
export class DutyData {
constructor() {
this.isInDuty = false;
this.inDutyCnt = 3;
this.currentDuty = '2';
this.otherDutyTime = '9:30-11:30';
this.offDutyReason = '学园维修';
this.dutyRecoverTime = '下周一';
this.place = '东三-204';
}
isInDuty: boolean;
inDutyCnt?: number;
currentDuty?: 'off' | '1' | '2' | '3' | 'others';
otherDutyTime?: string;
offDutyReason?: string;
dutyRecoverTime?: string;
place: string;
}
class Card extends Component {
props = {
isInDuty: false,
place: '东三-204',
};
render(): ReactNode {
const inDuty = this.props.isInDuty;
const place = this.props.place;
const dc = pt.get().mainPage.dutyCard;
const title = inDuty ? dc.inDuty.title : dc.offDuty.title;
const iconsrc = inDuty ? tick : wechatUser.getAccess() ? clock : cross;
return (
<View>
<View
style={{
display: 'flex',
alignItems: 'center',
marginBottom: '40rpx',
}}
>
<Image
src={iconsrc}
style={{
width: '48rpx',
height: '48rpx',
}}
/>
<View
style={{
marginLeft: '20rpx',
fontSize: '60rpx',
fontWeight: 'bold',
}}
>
{'[' + place + '] ' + title}
</View>
</View>
</View>
);
}
}
export class DutyInfo extends Component {
state: {
isLoading: false;
isDisable: false;
};
props = {
data: new DutyData(),
};
offDutyContent(): ReactNode {
const data = this.props.data;
const od = pt.get().mainPage.dutyCard.offDuty;
return (
<View>
<Card isInDuty={data.isInDuty} place={data.place} />
<AtTimeline
items={[
{ title: od.reason(data.offDutyReason as string) },
{ title: od.recoverTime(data.dutyRecoverTime as string) },
]}
/>
</View>
);
}
inDutyContent(): ReactNode {
const data = this.props.data;
const id = pt.get().mainPage.dutyCard.inDuty;
return (
<View>
<Card isInDuty={data.isInDuty} place={data.place} />
<AtTimeline
items={[
{
title:
data.currentDuty == 'others'
? id.currentDutyText('others') + data.otherDutyTime
: id.currentDutyText(data.currentDuty || 'off'),
},
{ title: id.inDutyCnt(data.inDutyCnt as number) },
]}
/>
</View>
);
}
render(): ReactNode {
if (this.props.data.isInDuty) {
return this.inDutyContent();
} else {
return this.offDutyContent();
}
}
}
+37
View File
@@ -0,0 +1,37 @@
import { Component, ReactNode } from 'react';
import { View } from '@tarojs/components';
import { AtTimeline } from 'taro-ui';
import pt from '@/plain-text';
import wechatUser from '@/wechat';
export class StepInfo extends Component {
render(): ReactNode {
return (
<View>
<AtTimeline
items={
wechatUser.getAccess()
? pt.get().memberPage.stepList
: pt.get().mainPage.stepList
}
></AtTimeline>
</View>
);
}
}
export class TipsInfo extends Component {
render(): ReactNode {
return (
<View>
<AtTimeline
items={
wechatUser.getAccess()
? pt.get().memberPage.tipsList
: pt.get().mainPage.tipsList
}
></AtTimeline>
</View>
);
}
}
+36
View File
@@ -0,0 +1,36 @@
import React from 'react';
import { View, Image } from '@tarojs/components';
import pt from '@/plain-text';
import wechatUser from '@/wechat';
const logo = 'https://wiki.zjueva.net/images/evalogo_hd.png';
export default class TitleCard extends React.Component {
render(): React.ReactNode {
const mainPage = pt.get().mainPage;
const memberPage = pt.get().memberPage;
return (
<View className='at-row at-row__align--center'>
<View className='at-col at-col-1 at-col--auto'>
<Image
style='width: 100rpx; height: 100rpx; margin-left: 30rpx;'
src={wechatUser.getAccess() ? wechatUser.getInfo().avatar : logo}
mode='aspectFit'
/>
</View>
<View className='page-title'>
<View className='at-article__h1' style={{ fontWeight: 'bold' }}>
{wechatUser.getAccess()
? memberPage.mainTitleLine + wechatUser.getInfo().name
: mainPage.mainTitleLine}
</View>
<View className='at-article__h2'>
{wechatUser.getAccess()
? memberPage.subTitleLine
: mainPage.subTitleLine}
</View>
</View>
</View>
);
}
}
+214 -76
View File
@@ -1,23 +1,47 @@
import { View, Text } 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, AtTimeline, AtAccordion } from 'taro-ui'; import {
AtCard,
AtAccordion,
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 { getDutyInfo } from '@/service/dutyInfo';
import { RequestState } from '@/service';
import moment from 'moment';
import wechatUser from '@/wechat';
import { getMemberDutyInfo } from '@/service/memberDutyInfo';
import { getUncompletedTicketList } from '@/service/uncompletedTicket';
import { changeDutyCnt } from '@/service/changeDutyCount';
import { TicketListItem } from '@/components/TicketListItem/TicketListItem';
import './index.scss'; import './index.scss';
import TitleCard from './TitleCard';
import { DutyInfo, DutyData } from './DutyInfo';
import { StepInfo, TipsInfo } from './StepTipsInfo';
interface CardContent { const submitInterval = 5000;
class CardContent {
title: string; title: string;
note: string; note: string;
extra: JSX.Element | string; extra: JSX.Element | string;
content: JSX.Element; content: () => JSX.Element;
} }
function mainPageCard(c: CardContent): JSX.Element { function mainPageCard(c: CardContent): JSX.Element {
return ( return (
<View style={{ marginTop: 10 }}> <View style={{ marginTop: '20rpx', marginBottom: '40rpx' }}>
<AtCard note={c.note} extra={c.extra} title={c.title}> <AtCard note={c.note} extra={c.extra} title={c.title}>
{c.content} {c.content()}
</AtCard> </AtCard>
</View> </View>
); );
@@ -51,72 +75,79 @@ class ExpandItem extends Component {
} }
} }
class DutyInfo extends Component { interface MainPageState {
render(): ReactNode { fixList: Array<TicketListItem>;
return ( rs: RequestState;
<View> dutyData: DutyData;
<Text>x人在岗</Text> inDutyCnt: number;
</View> dutyInfoCard: CardContent;
); stepInfoCard: CardContent;
} tipsInfoCard: CardContent;
isLoading: boolean;
isDisable: boolean;
} }
class StepInfo extends Component { export default class MainPage extends Component<{}, MainPageState> {
render(): ReactNode {
return (
<View>
<AtTimeline
items={[
{ title: '线上填写工单' },
{ title: '去东三-204教室维修电脑' },
{ title: '等待电脑维修' },
{ title: '维修结束,取回电脑' },
]}
></AtTimeline>
</View>
);
}
}
class TipsInfo extends Component {
render(): ReactNode {
return (
<View>
<AtTimeline
items={[
{ title: '戴尔、Surface、外星人、苹果电脑不能拆机哦~' },
{ title: '数据无价,请随时做好数据备份哦~' },
{ title: '204也是实验室,请遵守实验室纪律,请勿饮食~' },
{ title: '我们是志愿服务,不收任何礼物哦~' },
]}
></AtTimeline>
</View>
);
}
}
export default class Index extends Component {
state = { state = {
dutyData: new DutyData(),
inDutyCnt: 0,
dutyInfoCard: { dutyInfoCard: {
title: '204值班情况', title: '',
note: 'Tips', note: '',
extra: '额外信息', extra: '',
content: <DutyInfo />, content: () => <></>,
}, },
stepInfoCard: { stepInfoCard: {
title: '维修步骤', title: '',
note: 'Tips 请在20:30以前取走自己的物品哦', note: '',
extra: '额外信息', extra: '',
content: <StepInfo />, content: () => <></>,
}, },
tipsInfoCard: { tipsInfoCard: {
title: '注意事项', title: '',
note: 'Tips', note: '',
extra: '额外信息', extra: '',
content: <TipsInfo />, content: () => <></>,
}, },
fixList: [new TicketListItem(0, '', '', 1, moment())],
rs: new RequestState(),
isLoading: false,
isDisable: false,
}; };
componentDidMount(): void {
const ptPage = wechatUser.getAccess() ? 'memberPage' : 'mainPage';
this.setState({
dutyData: new DutyData(),
inDutyCnt: 0,
dutyInfoCard: {
title: pt.get()[ptPage].cardTitle.dutyInfo,
note: pt.get()[ptPage].cardTips.dutyInfo,
extra: pt.get()[ptPage].extraInfo.dutyInfo,
content: () => <DutyInfo data={this.state.dutyData} />,
},
stepInfoCard: {
title: pt.get()[ptPage].cardTitle.stepInfo,
note: pt.get()[ptPage].cardTips.stepInfo,
extra: pt.get()[ptPage].extraInfo.dutyInfo,
content: () => <StepInfo />,
},
tipsInfoCard: {
title: pt.get()[ptPage].cardTitle.tipsInfo,
note: pt.get()[ptPage].cardTips.tipsInfo,
extra: pt.get()[ptPage].extraInfo.dutyInfo,
content: () => <TipsInfo />,
},
});
if (wechatUser.getAccess()) {
getMemberDutyInfo(this);
getUncompletedTicketList(this);
} else {
getDutyInfo(this);
}
}
// 以下是TabBar相关 // 以下是TabBar相关
pageCtx = Taro.getCurrentInstance().page; pageCtx = Taro.getCurrentInstance().page;
componentDidShow() { componentDidShow() {
@@ -125,25 +156,132 @@ export default class Index extends Component {
} }
// 以上是TabBar相关 // 以上是TabBar相关
handleCnt(inDutyCnt: number) {
this.setState({
inDutyCnt: inDutyCnt,
});
return inDutyCnt;
}
onChangeCnt() {
this.setState({
isDisable: true,
});
changeDutyCnt(this);
setTimeout(() => {
this.setState({
isDisable: false,
});
}, submitInterval);
}
ticketListPage() {
Taro.navigateTo({
url: '/pages/TicketList/TicketList',
});
}
render(): ReactNode { render(): ReactNode {
const mainPage = pt.get().mainPage;
const memberPage = pt.get().memberPage;
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 ( return (
<View> <View>
<View className='page-title'> <TitleCard />
<View className='at-article__h1'>您好,这里是E志者协会。</View> <View style={{ width: '94%', marginLeft: '3%' }}>
<View className='at-article__h1'>维修请移步东三-204教室。</View> <View style={{ marginTop: '60rpx' }}>
{mainPageCard(this.state.dutyInfoCard)}
{mainPageCard(this.state.tipsInfoCard)}
{wechatUser.getAccess() && this.state.dutyData.isInDuty ? (
<ExpandItem
title={memberPage.expandTitle.admin}
content={
<View
style={{
display: 'flex',
alignItems: 'center',
marginBottom: '40rpx',
}}
>
<View
className='.at-article__h3'
style={{
marginTop: '40rpx',
}}
>
{pt.get().memberPage.dutyCount.text}
</View>
<View
style={{
marginTop: '40rpx',
}}
>
<AtInputNumber
type='number'
min={0}
max={10}
step={1}
value={this.state.inDutyCnt}
onChange={this.handleCnt.bind(this)}
/>
</View>
<View style={{ marginLeft: 'auto', marginTop: '40rpx' }}>
<AtButton
type='secondary'
size='small'
loading={this.state.isLoading}
disabled={this.state.isDisable}
onClick={this.onChangeCnt.bind(this)}
>
{pt.get().memberPage.dutyCount.button}
</AtButton>
</View>
</View>
}
/>
) : (
<View></View>
)}
<ExpandItem
title={mainPage.expandTitle.stepInfo}
content={mainPageCard(this.state.stepInfoCard)}
/>
</View>
{wechatUser.getAccess() ? (
<View>
<AtList>{fixListRenderer}</AtList>
<AtList>
<AtListItem
title={pt.get().mainPage.ticketList.title}
note={pt.get().mainPage.ticketList.note}
arrow='right'
thumb={clockIcon}
onClick={this.ticketListPage}
/>
</AtList>
</View>
) : (
<View></View>
)}
<PageFooter />
</View> </View>
<View style={{ marginTop: 30 }}>
{mainPageCard(this.state.dutyInfoCard)}
<ExpandItem
title='查看维修步骤'
content={mainPageCard(this.state.stepInfoCard)}
/>
<ExpandItem
title='查看注意事项'
content={mainPageCard(this.state.tipsInfoCard)}
/>
</View>
<PageFooter />
</View> </View>
); );
} }
+293 -5
View File
@@ -1,10 +1,76 @@
import { View, Text } 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 type CustomTabBar from '../../custom-tab-bar'; import {
AtForm,
AtInput,
AtButton,
AtCheckbox,
AtCard,
AtSegmentedControl,
AtMessage,
} from 'taro-ui';
import pt from '@/plain-text';
import PageFooter from '@/components/PageFooter/PageFooter';
import { submitTicket } from '@/service/submitTicket';
import type CustomTabBar from '@/custom-tab-bar';
import repairLogo from '@/assets/icons/RepairPage/repair.svg';
import DetailFramework from '@/components/DetailFramework/DetailFramework';
import { getCurrentTicket } from '@/service/currentTicket';
import { randomInt } from '@/utils/random';
import wechatUser from '@/wechat';
import './repair.scss'; import './repair.scss';
export default class RepairPage extends Component { interface RepairPageState {
type: 0 | 1;
device: string;
deviceModel: string;
owner: string;
phone: string;
description: string;
isLoading: boolean;
isDisable: boolean;
checkedList: Array<number>;
currentTicketsIdName: Array<Map<number, string>>;
}
const submitInterval = 5000;
const middleButton = <View></View>;
const isInfoShow = {
device: false,
createdTime: true,
description: false,
current: true,
notelist: true,
showAllNotes: false,
};
export default class RepairPage extends Component<{}, RepairPageState> {
state = {
type: 1 as 0 | 1,
device: '',
deviceModel: '',
owner: wechatUser.getInfo().name,
phone: wechatUser.getInfo().phone,
description: '',
isLoading: false,
isDisable: true,
checkedList: [0],
currentTicketsIdName: [] as Array<Map<number, string>>,
};
componentDidMount(): void {
getCurrentTicket(this);
setTimeout(() => {
this.setState({
isDisable: false,
});
}, submitInterval);
}
// 以下是TabBar相关 // 以下是TabBar相关
pageCtx = Taro.getCurrentInstance().page; pageCtx = Taro.getCurrentInstance().page;
componentDidShow() { componentDidShow() {
@@ -13,10 +79,232 @@ export default class RepairPage extends Component {
} }
// 以上是TabBar相关 // 以上是TabBar相关
handleTypeChange(type: 0 | 1) {
this.setState({
type: type,
});
return type;
}
handleDeviceChange(device: string) {
this.setState({
device: device,
});
return device;
}
handleDeviceModelChange(deviceModel: string) {
this.setState({
deviceModel: deviceModel,
});
return deviceModel;
}
handleOwnerChange(owner: string) {
this.setState({
owner: owner,
});
return owner;
}
handlePhoneChange(phone: string) {
this.setState({
phone: phone,
});
return phone;
}
handleDescriptionChange(description: string) {
this.setState({
description: description,
});
return description;
}
checkboxOption = [
{
value: 0,
label: pt.get().repairPage.checkboxText.none,
},
{
value: 1,
label: pt.get().repairPage.checkboxText.usbDisk,
},
{
value: 2,
label: pt.get().repairPage.checkboxText.mouseOrReceiver,
},
{
value: 3,
label: pt.get().repairPage.checkboxText.powerAdapter,
},
{
value: 4,
label: pt.get().repairPage.checkboxText.others.label,
desc: pt.get().repairPage.checkboxText.others.desc,
},
];
handleCheckboxChange(checkedList: Array<number>) {
this.setState({
checkedList: checkedList,
});
return checkedList;
}
onSubmit() {
this.setState({
isDisable: true,
});
if (
this.state.description == '' ||
this.state.device == '' ||
this.state.deviceModel == '' ||
this.state.owner == '' ||
this.state.phone == '' ||
this.state.checkedList.length === 0
) {
Taro.atMessage({
message: pt.get().button.submitText.blank,
type: 'error',
});
setTimeout(() => {
this.setState({
isDisable: false,
});
}, submitInterval);
return;
}
submitTicket(this);
setTimeout(() => {
this.setState({
isDisable: false,
});
}, submitInterval);
}
render(): ReactNode { render(): ReactNode {
const ticketsRenderer =
this.state.currentTicketsIdName.length !== 0 ? (
this.state.currentTicketsIdName.map((pair, idx) => (
<AtCard
key={idx}
title={pair.values().next().value} //pair.keys().next().value == ticket['device'] + ' ' + ticket['deviceModel']
extra={pt.get().repairPage.currentTicket.extra}
onClick={() => {
Taro.navigateTo({
url:
'/pages/TicketDetail/TicketDetail?id=' +
pair.keys().next().value,
});
}}
note={
pt.get().tips.tipsText[
randomInt(0, pt.get().tips.tipsText.length - 1)
]
}
>
<DetailFramework
id={pair.keys().next().value} //pair.keys().next().value == id
isInfoShow={isInfoShow}
middleButton={middleButton}
/>
</AtCard>
))
) : (
<View></View>
);
return ( return (
<View> <View style={{ width: '94%', marginLeft: '3%' }}>
<Text>Repair Page</Text> <AtMessage />
<View
style={{
marginTop: '20rpx',
marginBottom: '40rpx',
}}
>
{ticketsRenderer}
</View>
<AtCard
note={pt.get().repairPage.cardText.note}
title={pt.get().repairPage.cardText.title}
thumb={repairLogo}
>
<AtForm onSubmit={this.onSubmit.bind(this)}>
<AtSegmentedControl
values={[
pt.get().repairPage.typeText.appliance,
pt.get().repairPage.typeText.computer,
]}
onClick={this.handleTypeChange.bind(this)}
current={this.state.type}
/>
<AtInput
clear
required
name='device'
title={pt.get().repairPage.deviceText.title}
type='text'
placeholder={pt.get().repairPage.deviceText.placeholder}
value={this.state.device}
onChange={this.handleDeviceChange.bind(this)}
/>
<AtInput
clear
required
name='deviceModel'
title={pt.get().repairPage.deviceModelText.title}
type='text'
placeholder={pt.get().repairPage.deviceModelText.placeholder}
value={this.state.deviceModel}
onChange={this.handleDeviceModelChange.bind(this)}
/>
<AtInput
clear
required
name='owner'
title={pt.get().repairPage.ownerText.title}
type='text'
placeholder={pt.get().repairPage.ownerText.placeholder}
value={this.state.owner}
onChange={this.handleOwnerChange.bind(this)}
/>
<AtInput
clear
required
name='phone'
title={pt.get().repairPage.phoneText.title}
type='number'
placeholder={pt.get().repairPage.phoneText.placeholder}
value={this.state.phone}
onChange={this.handlePhoneChange.bind(this)}
/>
<AtInput
clear
required
name='description'
title={pt.get().repairPage.descriptionText.title}
type='text'
placeholder={pt.get().repairPage.descriptionText.placeholder}
value={this.state.description}
onChange={this.handleDescriptionChange.bind(this)}
/>
<AtCheckbox
options={this.checkboxOption}
selectedList={this.state.checkedList}
onChange={this.handleCheckboxChange.bind(this)}
/>
<AtButton
loading={this.state.isLoading}
formType='submit'
type='primary'
disabled={this.state.isDisable}
>
{pt.get().button.buttonText.submit}
</AtButton>
</AtForm>
</AtCard>
<PageFooter />
</View> </View>
); );
} }
+3
View File
@@ -0,0 +1,3 @@
export default definePageConfig({
usingComponents: {},
});
View File
+83
View File
@@ -0,0 +1,83 @@
import { Component, ReactNode } from 'react';
import { Image, View } from '@tarojs/components';
import Taro from '@tarojs/taro';
import pt from '@/plain-text';
import PageFooter from '@/components/PageFooter/PageFooter';
import './about.scss';
export default class AboutPage extends Component {
componentDidMount(): void {
Taro.setNavigationBarTitle({
title: pt.get().navBar.user.about,
});
}
render(): ReactNode {
return (
<View>
<View
style={{
marginTop: '200rpx',
marginBottom: '60rpx',
}}
className='at-row at-row__align--start'
>
<View className='at-col at-col-1 at-col--auto'>
<Image
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'
mode='aspectFit'
/>
</View>
<View
className='at-article at-col at-col--wrap'
style={{ wordBreak: 'normal' }}
>
<View className='at-article__h1'>
{pt.get().aboutPage.dean.nickname}
</View>
<View className='at-article__h3'>
{pt.get().aboutPage.dean.username}
</View>
<View className='at-article__p'>
{pt.get().aboutPage.dean.status}
</View>
<View className='at-article__info'>
{pt.get().aboutPage.dean.note}
</View>
</View>
</View>
<View
style={{ marginTop: '100rpx', marginBottom: '60rpx' }}
className='at-row at-row__align--start'
>
<View className='at-col at-col-1 at-col--auto'>
<Image
style='width: 240rpx; height: 240rpx; margin-left: 60rpx; margin-right: 30rpx; margin-top: 30rpx; border-radius: 120rpx'
src='https://static.fracher21.top/head.jpg'
mode='aspectFit'
/>
</View>
<View
className='at-article at-col at-col--wrap'
style={{ wordBreak: 'normal' }}
>
<View className='at-article__h1'>
{pt.get().aboutPage.fracher.nickname}
</View>
<View className='at-article__h3'>
{pt.get().aboutPage.fracher.username}
</View>
<View className='at-article__p'>
{pt.get().aboutPage.fracher.status}
</View>
<View className='at-article__info'>
{pt.get().aboutPage.fracher.note}
</View>
</View>
</View>
<View style={{ height: '200rpx' }}></View>
<PageFooter />
</View>
);
}
}
+93 -2
View File
@@ -1,10 +1,101 @@
import { View } from '@tarojs/components';
import { Component, ReactNode } from 'react'; import { Component, ReactNode } from 'react';
import { AtForm, AtInput, AtButton, AtMessage } from 'taro-ui';
import { View } from '@tarojs/components';
import Taro from '@tarojs/taro'; import Taro from '@tarojs/taro';
import pt from '@/plain-text';
import { updateUserInfo } from '@/service/userData';
import wechatUser from '@/wechat';
import './inform.scss'; import './inform.scss';
const submitInterval = 5000;
export default class InformPage extends Component { export default class InformPage extends Component {
state = {
phone: wechatUser.getInfo().phone,
name: wechatUser.getInfo().name,
isLoading: false,
isDisable: false,
};
componentDidMount(): void {
Taro.setNavigationBarTitle({
title: pt.get().navBar.user.inform,
});
}
handleChangePhone(phone: string) {
this.setState({
phone: phone,
});
return phone;
}
handleChangeName(name: string) {
this.setState({
name: name,
});
return name;
}
onSubmit() {
this.setState({
isDisable: true,
});
if (this.state.name == '' || this.state.phone == '') {
Taro.atMessage({
message: pt.get().button.submitText.blank,
type: 'error',
});
setTimeout(() => {
this.setState({
isDisable: false,
});
}, submitInterval);
return;
}
updateUserInfo(this);
setTimeout(() => {
this.setState({
isDisable: false,
});
}, submitInterval);
}
render(): ReactNode { render(): ReactNode {
return <View></View>; return (
<View style={{ marginTop: '30rpx', width: '94%', marginLeft: '3%' }}>
<AtForm onSubmit={this.onSubmit.bind(this)}>
<AtMessage />
<AtInput
clear
required
name='phone'
title={pt.get().informPage.phoneText.title}
type='number'
placeholder={pt.get().informPage.phoneText.placeholder}
value={this.state.phone}
onChange={this.handleChangePhone.bind(this)}
/>
<AtInput
required
clear
name='name'
title={pt.get().informPage.nameText.title}
type='text'
placeholder={pt.get().informPage.nameText.placeholder}
value={this.state.name}
onChange={this.handleChangeName.bind(this)}
/>
<View style={{ marginTop: '30rpx' }}>
<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
+85
View File
@@ -0,0 +1,85 @@
import { Component, ReactNode } from 'react';
import { AtButton, AtMessage } from 'taro-ui';
import Taro from '@tarojs/taro';
import pt from '@/plain-text';
import { memberLogin, memberLogout } from '@/service/memberLogin';
import wechatUser from '@/wechat';
import { View } from '@tarojs/components';
import './member.scss';
const logInterval = 5000;
export default class UserMemberPage extends Component {
state = {
isLoading: false,
isDisable: false,
};
componentDidMount(): void {
Taro.setNavigationBarTitle({
title: pt.get().navBar.user.memberLogin,
});
}
onLogin() {
this.setState({
isDisable: true,
});
memberLogin(this);
setTimeout(() => {
this.setState({
isDisable: false,
});
}, logInterval);
}
onLogout() {
this.setState({
isDisable: true,
});
memberLogout(this);
setTimeout(() => {
this.setState({
isDisable: false,
});
}, logInterval);
}
render(): ReactNode {
return !wechatUser.getAccess() ? (
<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.loginMainTitleLine}
</View>
<View className='at-article__h2'>
{pt.get().memberPage.loginSubTitleLine}
</View>
</View>
<AtButton
loading={this.state.isLoading}
type='primary'
disabled={this.state.isDisable}
onClick={this.onLogin.bind(this)}
>
{pt.get().button.memberText.auth}
</AtButton>
</View>
) : (
<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.logoutMainTitleLine}
</View>
<View className='at-article__h2'>
{pt.get().memberPage.logoutSubTitleLine}
</View>
</View>
<AtButton type='primary' onClick={this.onLogout.bind(this)}>
{pt.get().button.buttonText.logout}
</AtButton>
</View>
);
}
}
@@ -0,0 +1,3 @@
export default definePageConfig({
usingComponents: {},
});
+55
View File
@@ -0,0 +1,55 @@
import { Component, ReactNode } from 'react';
import { View } from '@tarojs/components';
import { AtActivityIndicator, AtList, AtToast } from 'taro-ui';
import Taro from '@tarojs/taro';
import moment from 'moment';
import pt from '@/plain-text';
import { RequestState } from '@/service';
import { getMyTicketList } from '@/service/myTicket';
import { TicketListItem } from '@/components/TicketListItem/TicketListItem';
import './myTicket.scss';
interface MyTicketState {
fixList: Array<TicketListItem>;
rs: RequestState;
}
export default class MyTicketPage extends Component<{}, MyTicketState> {
state = {
fixList: [new TicketListItem(0, '', '', 1, moment())],
rs: new RequestState(),
};
componentDidMount(): void {
Taro.setNavigationBarTitle({
title: pt.get().navBar.user.myTicket,
});
getMyTicketList(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>
<AtList>{fixListRenderer}</AtList>
</View>
);
}
}
+3
View File
@@ -0,0 +1,3 @@
export default definePageConfig({
usingComponents: {},
});
View File
+108
View File
@@ -0,0 +1,108 @@
import { AtTextarea, AtButton, AtForm, AtMessage } from 'taro-ui';
import { Component, ReactNode } from 'react';
import Taro from '@tarojs/taro';
import pt from '@/plain-text';
import { reportMessage } from '@/service/report';
import { View } from '@tarojs/components';
import './report.scss';
const submitInterval = 5000;
export default class ReportPage extends Component {
state = {
report: '',
isLoading: false,
isDisable: false,
};
componentDidMount(): void {
Taro.setNavigationBarTitle({
title: pt.get().navBar.user.report,
});
}
handleChange(report: string) {
this.setState({
report,
});
}
onSubmit() {
this.setState({
isDisable: true,
});
if (this.state.report == '') {
Taro.atMessage({
message: pt.get().button.submitText.blank,
type: 'error',
});
setTimeout(() => {
this.setState({
isDisable: false,
});
}, submitInterval);
return;
}
reportMessage(this);
setTimeout(() => {
this.setState({
isDisable: false,
});
}, submitInterval);
}
onReset() {
this.setState({
report: '',
});
}
render(): ReactNode {
return (
<View style={{ marginTop: '30rpx', width: '94%', marginLeft: '3%' }}>
<AtForm
onSubmit={this.onSubmit.bind(this)}
onReset={this.onReset.bind(this)}
>
<AtMessage />
<AtTextarea
value={this.state.report}
onChange={this.handleChange.bind(this)}
maxLength={200}
placeholder={pt.get().reportPage.placeHolderText}
/>
<View className='at-row'>
<View
className='at-col'
style={{
marginTop: '30rpx',
marginRight: '10rpx',
marginLeft: '10rpx',
width: '50%',
}}
>
<AtButton formType='reset' type='secondary'>
{pt.get().button.buttonText.reset}
</AtButton>
</View>
<View
className='at-col'
style={{
marginTop: '30rpx',
marginRight: '10rpx',
marginLeft: '10rpx',
width: '50%',
}}
>
<AtButton
loading={this.state.isLoading}
formType='submit'
type='primary'
disabled={this.state.isDisable}
>
{pt.get().button.buttonText.submit}
</AtButton>
</View>
</View>
</AtForm>
</View>
);
}
}
-10
View File
@@ -1,10 +0,0 @@
import { View } from '@tarojs/components';
import { Component, ReactNode } from 'react';
import Taro from '@tarojs/taro';
import './settings.scss';
export default class SettingsPage extends Component {
render(): ReactNode {
return <View></View>;
}
}
+143 -13
View File
@@ -1,11 +1,33 @@
import { View } from '@tarojs/components'; import { AtList, AtListItem, AtToast } from 'taro-ui';
import { Component, ReactNode } from 'react'; import { Component, ReactNode } from 'react';
import { View, Picker, Image, Text } from '@tarojs/components';
import Taro from '@tarojs/taro'; import Taro from '@tarojs/taro';
import type CustomTabBar from '../../custom-tab-bar'; import type CustomTabBar from '@/custom-tab-bar';
import PageFooter from '@/components/PageFooter/PageFooter';
import aboutIcon from '@/assets/icons/UserPage/about.svg';
import userIcon from '@/assets/icons/UserPage/user.svg';
import clockIcon from '@/assets/icons/UserPage/clock.svg';
import messageIcon from '@/assets/icons/UserPage/message.svg';
import pt, { Lang } from '@/plain-text';
import { setLocaleData } from '@/service/localeData';
import wechatUser from '@/wechat';
import './user.scss'; import './user.scss';
import { AtList, AtListItem } from 'taro-ui';
const logo = 'https://wiki.zjueva.net/images/evalogo_hd.png';
const memberClickTimes = 7;
export default class UserPage extends Component { export default class UserPage extends Component {
state = {
selector: ['简体中文', 'English'],
selectorChecked: {
zh_CN: '简体中文',
en_US: 'English',
}[pt.getCurLang()],
clicks: memberClickTimes,
isToastOpen: false,
toastText: '',
};
// 以下是TabBar相关 // 以下是TabBar相关
pageCtx = Taro.getCurrentInstance().page; pageCtx = Taro.getCurrentInstance().page;
componentDidShow() { componentDidShow() {
@@ -14,38 +36,146 @@ export default class UserPage extends Component {
} }
// 以上是TabBar相关 // 以上是TabBar相关
onTapImage = () => {
this.setState({
clicks: this.state.clicks - 1,
});
if (this.state.clicks < 3) {
this.setState({
toastText:
pt.get().userPage.memberEntry.front +
(this.state.clicks + 1).toString() + // React State's feature
pt.get().userPage.memberEntry.behind,
isToastOpen: true,
});
if (this.state.clicks == 0) {
this.setState({
isToastOpen: false,
clicks: memberClickTimes,
});
Taro.navigateTo({
url: '/pages/user/member/member',
});
}
}
};
showLangDict: Record<string, Lang> = {
简体中文: 'zh_CN',
English: 'en_US',
};
onSelect = (e: { detail: { value: string | number } }) => {
this.setState({
selectorChecked: this.state.selector[e.detail.value],
});
let currentLang = this.showLangDict[this.state.selector[e.detail.value]];
pt.setLang(currentLang);
setLocaleData(currentLang);
Taro.reLaunch({
url: '/pages/user/user',
});
};
myTicketPage() {
Taro.navigateTo({
url: '/pages/user/myTicket/myTicket',
});
}
informPage() { informPage() {
Taro.navigateTo({ Taro.navigateTo({
url: '/pages/user/inform/inform', url: '/pages/user/inform/inform',
}); });
} }
settingsPage() { reportPage() {
Taro.navigateTo({ Taro.navigateTo({
url: '/pages/user/settings/settings', url: '/pages/user/report/report',
});
}
aboutPage() {
Taro.navigateTo({
url: '/pages/user/about/about',
}); });
} }
render(): ReactNode { render(): ReactNode {
return ( return (
<View> <View>
<View
className='at-row at-row__justify--center at-row__align--end'
style='height:220rpx;'
>
<Image
onTap={this.onTapImage}
style='width: 200rpx;height: 200rpx;'
src={logo}
mode='aspectFit'
/>
</View>
<AtToast
isOpened={this.state.isToastOpen}
text={this.state.toastText}
></AtToast>
<View
className='at-row at-row__justify--center at-row__align--center'
style='height:120rpx;color:#696969;'
>
<Text style={{ fontSize: '32rpx' }}> EVA Eta v1.0.0</Text>
</View>
<AtList> <AtList>
<AtListItem <AtListItem
title='我的信息' title={pt.get().userPage.ticketColumn.title}
note='能帮助亦可更好地找到你哦!' note={pt.get().userPage.ticketColumn.note}
arrow='right' arrow='right'
iconInfo={{ size: 25, color: '#78A4FA', value: 'user' }} thumb={clockIcon}
onClick={this.informPage} onClick={this.myTicketPage}
/> />
{wechatUser.getAccess() ? (
<View></View>
) : (
<AtListItem
title={pt.get().userPage.infoColumn.title}
note={pt.get().userPage.infoColumn.note}
arrow='right'
thumb={userIcon}
onClick={this.informPage}
/>
)}
<AtListItem <AtListItem
title='设置' title={pt.get().userPage.reportColumn.title}
note='配置小程序' note={pt.get().userPage.reportColumn.note}
extraText='' extraText=''
arrow='right' arrow='right'
iconInfo={{ size: 25, color: '#FF4949', value: 'filter' }} thumb={messageIcon}
onClick={this.settingsPage} onClick={this.reportPage}
/> />
<AtListItem
title={pt.get().userPage.aboutColumn.title}
note={pt.get().userPage.aboutColumn.note}
extraText=''
arrow='right'
thumb={aboutIcon}
onClick={this.aboutPage}
/>
<View style={{ height: '40rpx' }}></View>
<Picker
mode='selector'
range={this.state.selector}
onChange={this.onSelect}
>
<AtList>
<AtListItem
title='语言 / Language'
extraText={this.state.selectorChecked}
/>
</AtList>
</Picker>
</AtList> </AtList>
<PageFooter />
</View> </View>
); );
} }
+14
View File
@@ -0,0 +1,14 @@
export interface NotFoundText {
titleZhCn: string;
titleEnUs: string;
descZhCn: string;
descEnUs: string;
}
export const notFound: NotFoundText = {
titleZhCn: '啊哦...请求出错了...',
descZhCn: '请确保处于校网环境后,点击右上角 "...-重新进入小程序"!',
titleEnUs: 'Oops...Network Error...',
descEnUs:
'Please make sure you\'re in ZJU\'s school network environment and then click on the top right corner "... - re-enter the applet"!',
};
+44
View File
@@ -0,0 +1,44 @@
export interface AboutPageText {
dean: {
nickname: string;
username: string;
status: string;
note: string;
};
fracher: {
nickname: string;
username: string;
status: string;
note: string;
};
}
export const aboutPageZhCn: AboutPageText = {
dean: {
nickname: '晓洋',
username: '@ Dawn_Ocean',
status: 'Eta & Tea 总设计',
note: '摸鱼与开发叠加态',
},
fracher: {
nickname: '宇航员',
username: '@ FrozenArcher',
status: 'Ate 总设计, 项目合作贡献者',
note: 'React 真是太有意思了',
},
};
export const aboutPageEnUs: AboutPageText = {
dean: {
nickname: 'Dean Ma',
username: '@ Dawn_Ocean',
status: "Eta & Tea's General Designer",
note: 'Struggling between developing & laziness',
},
fracher: {
nickname: 'Fracher',
username: '@ FrozenArcher',
status: "Ate's General Designer, Project's Contributor",
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...',
};
+77
View File
@@ -0,0 +1,77 @@
export interface ButtonText {
buttonText: {
submit: string;
reset: string;
login: string;
logout: string;
};
submitText: {
success: string;
error: string;
blank: string;
};
memberText: {
auth: string;
};
loginText: {
success: string;
error: string;
fail: string;
};
logoutText: {
success: string;
error: string;
};
}
export const buttonZhCn: ButtonText = {
buttonText: {
submit: '提交',
reset: '清空',
login: '登录',
logout: '登出',
},
submitText: {
success: '提交成功',
error: '提交失败:',
blank: '请填写完整!',
},
memberText: {
auth: '协会统一身份认证登录',
},
loginText: {
success: '登录成功',
error: '登录失败',
fail: '请检查用户名或密码!',
},
logoutText: {
success: '登出成功',
error: '登出失败',
},
};
export const buttonEnUs: ButtonText = {
buttonText: {
submit: 'Submit',
reset: 'Reset',
login: 'Login',
logout: 'Logout',
},
submitText: {
success: 'Success',
error: 'Error: ',
blank: 'Please fill in the blanks!',
},
memberText: {
auth: 'EVA Auth Login Entry',
},
loginText: {
success: 'Login Success',
error: 'Login Failed',
fail: 'Please check username or password!',
},
logoutText: {
success: 'Logout Success',
error: 'Logout Failed',
},
};
+32
View File
@@ -0,0 +1,32 @@
export interface InformPageText {
phoneText: {
title: string;
placeholder: string;
};
nameText: {
title: string;
placeholder: string;
};
}
export const informPageZhCn: InformPageText = {
phoneText: {
title: '手机号码',
placeholder: '便于查询工单',
},
nameText: {
title: '真实姓名',
placeholder: '必填,与工单绑定',
},
};
export const informPageEnUs: InformPageText = {
phoneText: {
title: 'Phone',
placeholder: 'Used for querying tickets',
},
nameText: {
title: 'Real Name',
placeholder: '(Required) Bounded to your ticket',
},
};
+173
View File
@@ -0,0 +1,173 @@
export interface MainPageText {
mainTitleLine: string;
subTitleLine: string;
cardTitle: {
dutyInfo: string;
stepInfo: string;
tipsInfo: string;
};
cardTips: {
dutyInfo: string;
stepInfo: string;
tipsInfo: string;
};
extraInfo: {
dutyInfo: string;
stepInfo: string;
tipsInfo: string;
};
expandTitle: {
stepInfo: string;
tipsInfo: string;
};
stepList: Array<{ title: string }>;
tipsList: Array<{ title: string }>;
ticketList: {
title: string;
note: string;
};
dutyCard: {
offDuty: {
title: string;
reason: (s: string) => string;
recoverTime: (t: string) => string;
};
inDuty: {
title: string;
currentDutyText: (c: 'off' | '1' | '2' | '3' | 'others') => string;
inDutyCnt: (n: number) => string;
};
};
}
export const mainPageZhCn: MainPageText = {
mainTitleLine: '您好,这里是E志者协会',
subTitleLine: '维修请至【东三-204】实验室',
cardTitle: {
dutyInfo: '值班情况',
stepInfo: '维修步骤',
tipsInfo: '注意事项',
},
cardTips: {
dutyInfo: '提示:可以先前往【维修】页面在线上预填写工单!',
stepInfo: '提示:请在 20:30 之前取走自己的物品哦!',
tipsInfo: '',
},
extraInfo: {
dutyInfo: '',
stepInfo: '',
tipsInfo: '',
},
expandTitle: {
stepInfo: '查看维修步骤',
tipsInfo: '查看注意事项',
},
stepList: [
{ title: '线上填写工单' },
{ title: '去【东三-204】实验室维修电脑' },
{ title: '等待电脑维修' },
{ title: '维修结束,取回电脑' },
],
tipsList: [
{ title: '戴尔/外星人、Surface、苹果电脑不能拆哦~' },
{ title: '数据无价,请随时做好数据备份哦~' },
{ title: '204 也是实验室,请勿在内饮食~' },
{ title: '我们是志愿服务,不收取任何礼物哦~' },
],
ticketList: {
title: '预填写工单列表',
note: '在这里查看所有的预填写工单!',
},
dutyCard: {
offDuty: {
title: '未值班',
reason: (s) => '值班停止原因:' + s,
recoverTime: (t) => '恢复值班时间:' + t,
},
inDuty: {
title: '值班中',
currentDutyText: (c) => {
switch (c) {
case 'off':
return '当前未值班';
case '1':
return '第一班 13:30-16:00';
case '2':
return '第二班 16:00-18:00';
case '3':
return '第三班 18:00-20:30';
case 'others':
return '当班 ';
}
},
inDutyCnt: (n) => '当前值班人数:' + n,
},
},
};
export const mainPageEnUs: MainPageText = {
mainTitleLine: 'Hi! This is EVA.',
subTitleLine: 'For maintenance, please go to [204 Lab, E3 building]',
cardTitle: {
dutyInfo: 'Duty Situation',
stepInfo: 'Maintenance Steps',
tipsInfo: 'Tips',
},
cardTips: {
dutyInfo: 'Tips: Please go to [Repair] and filling out tickets online.',
stepInfo: 'Tips: Please retrieve your devices before 20:30!',
tipsInfo: '',
},
expandTitle: {
stepInfo: 'Check for maintenance steps',
tipsInfo: 'Check for tips',
},
extraInfo: {
dutyInfo: '',
stepInfo: '',
tipsInfo: '',
},
stepList: [
{ title: 'Filling out tickets online' },
{ title: 'Go to [204 Lab, E3 building] for maintenance' },
{ title: 'Waiting for the device maintenance' },
{ title: 'The maintenance is over, retrieve the device' },
],
tipsList: [
{ title: 'Dell/Alienware, Surface, Apple cannot be dissassembled.' },
{ title: 'Data is priceless, please backup your data at any time!' },
{ title: '204 is also a laboratory. Do not eat inside.' },
{ title: 'We are volunteers and do not take any gifts.' },
],
ticketList: {
title: 'Pre-filling ticket list',
note: 'Browse for all pre-filling tickets here!',
},
dutyCard: {
offDuty: {
title: 'Off Duty',
reason: (s) => 'Reason for cessation of duty: ' + s,
recoverTime: (t) => 'Resumption of duty: ' + t,
},
inDuty: {
title: 'On Duty',
currentDutyText: (c) => {
switch (c) {
case 'off':
return 'Currently not on duty';
case '1':
return '1st Shift 13:30-16:00';
case '2':
return '2nd Shift 16:00-18:00';
case '3':
return '3rd Shift 18:00-20:30';
case 'others':
return 'Current Shift ';
}
},
inDutyCnt: (n) => 'EVA members on duty: ' + n,
},
},
};
+224
View File
@@ -0,0 +1,224 @@
export interface MemberPageText {
mainTitleLine: string;
subTitleLine: string;
loginMainTitleLine: string;
loginSubTitleLine: string;
logoutMainTitleLine: string;
logoutSubTitleLine: string;
cardTitle: {
dutyInfo: string;
stepInfo: string;
tipsInfo: string;
};
dutyCount: {
button: string;
text: string;
};
stuidText: {
title: string;
placeholder: string;
};
passwdText: {
title: string;
placeholder: string;
};
uncompletedTicket: {
extra: string;
};
dutyCard: {
offDuty: {
title: string;
reason: (s: string) => string;
recoverTime: (t: string) => string;
};
inDuty: {
title: string;
currentDutyText: (c: 'off' | '1' | '2' | '3' | 'others') => string;
inDutyCnt: (n: number) => string;
};
};
expandTitle: {
stepInfo: string;
tipsInfo: string;
admin: string;
};
cardTips: {
dutyInfo: string;
stepInfo: string;
tipsInfo: string;
};
extraInfo: {
dutyInfo: string;
stepInfo: string;
tipsInfo: string;
};
stepList: Array<{ title: string }>;
tipsList: Array<{ title: string }>;
}
export const memberPageZhCn: MemberPageText = {
mainTitleLine: '您好,',
subTitleLine: '祝你满绩每一天',
loginMainTitleLine: '协会成员登录入口',
loginSubTitleLine: '请使用 EVA 统一身份认证,登录后点击下方按钮以扫描二维码',
logoutMainTitleLine: '协会成员登出',
logoutSubTitleLine: '登出后须扫码重新登录!',
cardTitle: {
dutyInfo: '值班情况',
stepInfo: '维修步骤',
tipsInfo: '注意事项',
},
dutyCount: {
button: '更新值班人数',
text: '当前值班人数:',
},
stuidText: {
title: '学号',
placeholder: '与统一身份认证学号一致',
},
passwdText: {
title: '密码',
placeholder: '与 EVA 统一身份认证一致',
},
uncompletedTicket: {
extra: '详细信息',
},
dutyCard: {
offDuty: {
title: '空闲',
reason: (s) => '未值班原因:' + s,
recoverTime: (t) => '恢复值班时间:' + t,
},
inDuty: {
title: '值班中',
currentDutyText: (c) => {
switch (c) {
case 'off':
return '当前未值班';
case '1':
return '第一班 13:30-16:00';
case '2':
return '第二班 16:00-18:00';
case '3':
return '第三班 18:00-20:30';
case 'others':
return '其他值班时间,见通知';
}
},
inDutyCnt: (n) => '当前值班人数:' + n,
},
},
expandTitle: {
stepInfo: '查看维修步骤',
tipsInfo: '查看注意事项',
admin: '组长管理入口',
},
cardTips: {
dutyInfo: '提示:如果有事不能值班,请及时请假!',
stepInfo: '提示:维修完成请清点机主物品!',
tipsInfo: '',
},
extraInfo: {
dutyInfo: '',
stepInfo: '',
tipsInfo: '',
},
stepList: [
{ title: '机主线上填写工单,审核接取维修后加入 Oreo' },
{ title: '进行维修工作,认领工单,通过小程序与机主交流' },
{ title: '维修结束,清点机主物品,待机主取回' },
{ title: '机主取回机器确认无误后,修改工单状态' },
],
tipsList: [
{ title: '戴尔/外星人、Surface、苹果电脑不能拆机' },
{ title: '数据无价,请提醒机主随时做好数据备份' },
{ title: '离开 204 前清点好维修物资!' },
{ title: '螺丝上了吗?电源排线插了吗?' },
],
};
export const memberPageEnUs: MemberPageText = {
mainTitleLine: 'Hi! ',
subTitleLine: 'Have a great day!',
loginMainTitleLine: 'EVA Member Entry',
loginSubTitleLine:
'Please use EVA Auth, log in and click the button below to scan the QR code',
logoutMainTitleLine: 'EVA Member Logout',
logoutSubTitleLine: 'After logging out, scan the code again to log back in!',
cardTitle: {
dutyInfo: 'Duty Situation',
stepInfo: 'Maintenance Steps',
tipsInfo: 'Tips',
},
dutyCount: {
button: 'Update Duty Count',
text: 'The duty count: ',
},
stuidText: {
title: 'Student ID',
placeholder: 'Consistent with EVA Auth',
},
passwdText: {
title: 'Password',
placeholder: 'Consistent with EVA Auth',
},
uncompletedTicket: {
extra: 'Details',
},
dutyCard: {
offDuty: {
title: 'Off Duty',
reason: (s) => 'Off duty reason: ' + s,
recoverTime: (t) => 'Resumption of duty: ' + t,
},
inDuty: {
title: 'On Duty',
currentDutyText: (c) => {
switch (c) {
case 'off':
return 'Currently not on duty';
case '1':
return '1st Shift 13:30-16:00';
case '2':
return '2nd Shift 16:00-18:00';
case '3':
return '3rd Shift 18:00-20:30';
case 'others':
return 'Other duty hours, see notice';
}
},
inDutyCnt: (n) => 'EVA members on duty: ' + n,
},
},
expandTitle: {
stepInfo: 'Check for maintenance steps',
tipsInfo: 'Check for tips',
admin: 'Entry for admin',
},
cardTips: {
dutyInfo:
"Tips: If you can't be on duty, please ask for an excused absence!",
stepInfo: "Tips: Inventory owner's belongings after maintenance!",
tipsInfo: '',
},
extraInfo: {
dutyInfo: '',
stepInfo: '',
tipsInfo: '',
},
stepList: [
{ title: 'The owner fills out ticket online. Add it to Oreo after audit.' },
{ title: 'Repair, pick the ticket, and communicate with the owner online' },
{
title:
"Maintenance completed, inventory owner's belongings and await retrieving",
},
{ title: 'Modify the work order status after the owner retrieves.' },
],
tipsList: [
{ title: 'Dell/Alienware, Surface, Apple cannot be dissassembled.' },
{ title: 'Please remind the owner to backup data at any time!' },
{ title: '204 is a laboratory. Do not eat inside.' },
{ title: 'Are the screws on? Is the power cable plugged in?' },
],
};
+52
View File
@@ -0,0 +1,52 @@
export interface ModalText {
pick: {
title: string;
content: string;
};
addToOreo: {
title: string;
content: string;
};
retrieve: {
title: string;
content: string;
};
cancel: string;
confirm: string;
}
export const modalZhCn: ModalText = {
pick: {
title: '认领此工单',
content: '工单可多人认领!认领后将无法撤销!',
},
addToOreo: {
title: '将工单加入 Oreo',
content: '确认加入 Oreo?加入后将无法撤回!',
},
retrieve: {
title: '机器取回确认',
content: '确认该机器已取回?取回后工单完成,将无法添加评论!',
},
cancel: '取消',
confirm: '确认',
};
export const modalEnUs: ModalText = {
pick: {
title: 'Pick this ticket',
content:
'Tickets can be claimed by multiple members! Once claimed, it will not be able to be revoked!',
},
addToOreo: {
title: 'Add ticket to Oreo',
content: 'Once Confirmed, the change will be irrevocably!',
},
retrieve: {
title: 'Confirm the retrieving',
content:
'Once Confirmed, the ticket will be closed and cannot add any comment!',
},
cancel: 'Cancel',
confirm: 'Confirm',
};
+41
View File
@@ -0,0 +1,41 @@
export interface NavBarTitle {
notFound: string;
ticketDetail: string;
ticketList: string;
user: {
myTicket: string;
report: string;
memberLogin: string;
inform: string;
about: string;
member: string;
};
}
export const navBarTitleZhCn: NavBarTitle = {
notFound: '连接失败',
ticketDetail: '工单详情',
ticketList: '所有工单',
user: {
myTicket: '我的工单',
report: '意见反馈',
inform: '我的信息',
about: '关于我们',
memberLogin: '协会成员登录',
member: '协会成员',
},
};
export const navBarTitleEnUs: NavBarTitle = {
notFound: 'Failed',
ticketDetail: 'Ticket Detail',
ticketList: 'All Tickets',
user: {
myTicket: 'My Tickets',
report: 'Report',
inform: 'Information',
about: 'About us',
memberLogin: 'Member login',
member: 'Member Page',
},
};
+11
View File
@@ -0,0 +1,11 @@
export interface PageFooterText {
dividerText: string;
}
export const pageFooterZhCn: PageFooterText = {
dividerText: 'EVA Notify',
};
export const pageFooterEnUs: PageFooterText = {
dividerText: 'EVA Notify',
};
+140
View File
@@ -0,0 +1,140 @@
export interface RepairPageText {
currentTicket: {
errorMessage: string;
title: string;
note: string;
extra: string;
};
typeText: {
computer: string;
appliance: string;
};
deviceText: {
title: string;
placeholder: string;
};
deviceModelText: {
title: string;
placeholder: string;
};
ownerText: {
title: string;
placeholder: string;
};
phoneText: {
title: string;
placeholder: string;
};
descriptionText: {
title: string;
placeholder: string;
};
checkboxText: {
none: string;
usbDisk: string;
mouseOrReceiver: string;
powerAdapter: string;
others: {
label: string;
desc: string;
};
};
cardText: {
note: string;
title: string;
};
}
export const repairPageZhCn: RepairPageText = {
currentTicket: {
errorMessage: '未获取到工单!',
title: '',
note: '',
extra: '详细信息',
},
typeText: {
computer: '电脑',
appliance: '电器',
},
deviceText: {
title: '设备品牌',
placeholder: '如:ROG',
},
deviceModelText: {
title: '设备型号',
placeholder: '如:幻 14 2022',
},
ownerText: {
title: '机主姓名',
placeholder: '如:晓洋',
},
phoneText: {
title: '联系方式',
placeholder: '如:18888888888',
},
descriptionText: {
title: '问题描述',
placeholder: '如:无法登入校内网站',
},
checkboxText: {
none: '无附件',
usbDisk: 'U 盘',
mouseOrReceiver: '鼠标/接收器',
powerAdapter: '电源适配器',
others: {
label: '其他',
desc: '请于评论中详述',
},
},
cardText: {
note: '工单描述请尽量简短哦!',
title: '预填写工单',
},
};
export const repairPageEnUs: RepairPageText = {
currentTicket: {
errorMessage: 'Cannot get the ticket!',
title: '',
note: '',
extra: 'Details',
},
typeText: {
computer: 'Computer',
appliance: 'Appliance',
},
deviceText: {
title: 'Brand',
placeholder: 'e.g. ROG',
},
deviceModelText: {
title: 'Device Model',
placeholder: 'e.g. Zephyrus G14 2022',
},
ownerText: {
title: 'Name',
placeholder: 'e.g. Dean Ma',
},
phoneText: {
title: 'Tel',
placeholder: 'e.g. 18888888888',
},
descriptionText: {
title: 'Problem Description',
placeholder: 'e.g. ZJUWLAN inaccessable',
},
checkboxText: {
none: 'None',
usbDisk: 'USB Disk',
mouseOrReceiver: 'Mouse/Receiver',
powerAdapter: 'Power Adapter',
others: {
label: 'Others',
desc: 'Please elaborate in the comments',
},
},
cardText: {
note: 'Please keep the ticket description as short as possible',
title: 'Pre-filling working tickets',
},
};
+13
View File
@@ -0,0 +1,13 @@
export interface ReportPageText {
placeHolderText: string;
}
export const reportPageZhCn: ReportPageText = {
placeHolderText:
'无论是有关于小程序的建议,还是关于E志者协会的建议,都可以提出来哦!',
};
export const reportPageEnUs: ReportPageText = {
placeHolderText:
'Feel free to post your suggestions about the weapp or about us!',
};
+20
View File
@@ -0,0 +1,20 @@
export interface TabBarText {
indexText: string;
repairText: string;
userText: string;
memberText: string;
}
export const tabBarZhCn: TabBarText = {
indexText: '主页',
repairText: '维修',
userText: '我的',
memberText: '管理',
};
export const tabBarEnUs: TabBarText = {
indexText: 'Home',
repairText: 'Repair',
userText: 'Account',
memberText: 'Member',
};
+136
View File
@@ -0,0 +1,136 @@
interface StepItem {
title: string;
}
type StatusStr = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7';
export interface TicketDetailText {
stepItems: Array<StepItem>;
createTicketMessage: string;
statusModifyPrefix: string;
statusModifyMessage: Map<StatusStr, string>;
descTitle: string;
divider: string;
info: {
title: string;
extra: string;
};
tookAway: string;
addToOreo: string;
addNote: string;
pick: string;
comment: {
title: string;
placeholder: string;
};
status: {
button: string;
title: string;
cancel: string;
status0: string;
status1: string;
status2: string;
status3: string;
status4: string;
status5: string;
status6: string;
status7: string;
};
}
export const ticketDetailZhCn: TicketDetailText = {
stepItems: [
{ title: '创建成功' },
{ title: '维修中' },
{ title: '待取回' },
{ title: '工单完成' },
],
createTicketMessage: '创建了维修',
statusModifyPrefix: '将维修状态改为:',
statusModifyMessage: new Map<StatusStr, string>([
['0', '已创建/交接中'],
['1', '维修中'],
['2', '劝退待取回'],
['3', '劝退已取回'],
['4', '维修成功待取回'],
['5', '维修成功已取回'],
['6', '维修翻车待取回'],
['7', '维修翻车已取回'],
]),
descTitle: '问题描述',
divider: '评论 / 状态',
info: {
title: '机主姓名',
extra: '联系方式',
},
tookAway: '我已取回',
addToOreo: '加入 Oreo',
addNote: '添加评论',
pick: '认领',
comment: {
title: '添加评论',
placeholder: '可以在这里交流机器情况、维修进度、提出问题~',
},
status: {
button: '改变工单状态',
title: '请选择要改变成为的状态',
cancel: '取消',
status0: '已创建/交接中',
status1: '维修中',
status2: '劝退待取回',
status3: '劝退已取回',
status4: '维修成功待取回',
status5: '维修成功已取回',
status6: '维修翻车待取回',
status7: '维修翻车已取回',
},
};
export const ticketDetailEnUs: TicketDetailText = {
stepItems: [
{ title: 'Created' },
{ title: 'Repairing' },
{ title: 'Finished' },
{ title: 'Retrieved' },
],
createTicketMessage: 'Created ticket',
statusModifyPrefix: 'Modified repair status to: ',
statusModifyMessage: new Map<StatusStr, string>([
['0', 'Created / Handovering'],
['1', 'Repairing'],
['2', 'Pending Retrieval (Refused)'],
['3', 'Retrieved (Refused)'],
['4', 'Pending Retrieval (Finished)'],
['5', 'Retrieved (Finished)'],
['6', 'Pending Retrieval (Failed)'],
['7', 'Retrieved (Failed)'],
]),
descTitle: 'Description',
divider: 'Comment / Status',
info: {
title: 'Name',
extra: 'Contact',
},
tookAway: 'Already retrieved',
addToOreo: 'Add to Oreo',
addNote: 'Comment',
pick: 'Pick',
comment: {
title: 'Add Comment',
placeholder:
'You can exchange information the device, the progress of repairs, and ask questions here.',
},
status: {
button: 'Modify Status',
title: 'Please select the status you want to modify to',
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)',
},
};
+41
View File
@@ -0,0 +1,41 @@
import { FixStatus } from '@/common';
export interface TicketListText {
createdAt(time: string): string;
statusMap: Map<FixStatus, string>;
search: string;
}
export const ticketListZhCn: TicketListText = {
createdAt: (time) => {
return '创建于' + ' ' + time;
},
statusMap: new Map([
[0, '已创建/交接中'],
[1, '维修中'],
[2, '劝退待取回'],
[3, '劝退已取回'],
[4, '维修成功待取回'],
[5, '维修成功已取回'],
[6, '维修翻车待取回'],
[7, '维修翻车已取回'],
]),
search: '搜索',
};
export const ticketListEnUs: TicketListText = {
createdAt: (time) => {
return 'Created at' + ' ' + time;
},
statusMap: new Map([
[0, 'Created / Handovering'],
[1, 'Repairing'],
[2, 'Pending Retrieval (Refused)'],
[3, 'Retrieved (Refused)'],
[4, 'Pending Retrieval (Finished)'],
[5, 'Retrieved (Finished)'],
[6, 'Pending Retrieval (Failed)'],
[7, 'Retrieved (Failed)'],
]),
search: 'search',
};
+25
View File
@@ -0,0 +1,25 @@
export interface TipsText {
tipsText: Array<string>;
}
export const tipsZhCn: TipsText = {
tipsText: [
'提示:请在 20:30 之前取走自己的物品哦!',
'提示:戴尔/外星人、Surface、苹果电脑不能拆机哦~',
'提示:数据无价,请随时做好数据备份哦~',
'提示:204 也是实验室,请勿在内饮食~',
'提示:我们是志愿服务,不收取任何礼物哦~',
'提示:无论是有关于小程序的建议,还是关于E志者协会的建议,都可以在【意见反馈】处提出来哦!',
],
};
export const tipsEnUs: TipsText = {
tipsText: [
'Tips: Please retrieve your devices before 20:30!',
'Tips: Dell/Alienware, Surface, Apple cannot be dissassembled.',
'Tips: Data is priceless, please backup your data at any time!',
'Tips: 204 is also a laboratory. Do not eat inside.',
'Tips: We are volunteers and do not take any gifts.',
'Tips: Feel free to post your suggestions about the weapp or about us at [Account-Report]!',
],
};
+11
View File
@@ -0,0 +1,11 @@
export interface ToastText {
error: string;
}
export const toastZhCn: ToastText = {
error: '获取失败',
};
export const toastEnUs: ToastText = {
error: 'Request Failed',
};
+80
View File
@@ -0,0 +1,80 @@
export interface UserPageText {
memberEntry: {
front: string;
behind: string;
};
ticketColumn: {
title: string;
note: string;
};
infoColumn: {
title: string;
note: string;
};
settingsColumn: {
title: string;
note: string;
};
reportColumn: {
title: string;
note: string;
};
aboutColumn: {
title: string;
note: string;
};
}
export const userPageZhCn: UserPageText = {
memberEntry: {
front: '再点击 ',
behind: ' 次以进入协会成员登录页面',
},
ticketColumn: {
title: '我的工单',
note: '在这里查看历史工单!',
},
infoColumn: {
title: '我的信息',
note: '能帮助亦可更好地找到你哦!',
},
settingsColumn: {
title: '应用设置',
note: '在这里配置小程序',
},
reportColumn: {
title: '意见反馈',
note: '有什么想说的都可以告诉亦可哦!',
},
aboutColumn: {
title: '关于我们',
note: '查看开发者信息',
},
};
export const userPageEnUs: UserPageText = {
memberEntry: {
front: 'Click ',
behind: ' more times to enter member login page',
},
ticketColumn: {
title: 'My Tickets',
note: 'View the history of your tickets here!',
},
infoColumn: {
title: 'My Information',
note: 'It will help us contact you!',
},
settingsColumn: {
title: 'Settings',
note: 'Configure the applet here!',
},
reportColumn: {
title: 'Report',
note: 'Let us know if you have any suggestions!',
},
aboutColumn: {
title: 'About Us',
note: 'View developer information.',
},
};
+17
View File
@@ -0,0 +1,17 @@
import { Moment } from 'moment';
export interface CommonText {
createdAtText(time: Moment): string;
}
export const commonTextZhCn: CommonText = {
createdAtText(time: Moment): string {
return '创建于 ' + time.format('YYYY-MM-DD HH:mm');
},
};
export const commonTextEnUs: CommonText = {
createdAtText(time: Moment): string {
return 'Created at ' + time.format('YYYY-MM-DD HH:mm');
},
};
+129
View File
@@ -0,0 +1,129 @@
import { PageFooterText, pageFooterZhCn, pageFooterEnUs } from './PageFooter';
import { MainPageText, mainPageZhCn, mainPageEnUs } from './MainPage';
import { UserPageText, userPageZhCn, userPageEnUs } from './UserPage';
import { TabBarText, tabBarEnUs, tabBarZhCn } from './TabBar';
import { ReportPageText, reportPageEnUs, reportPageZhCn } from './ReportPage';
import { InformPageText, informPageZhCn, informPageEnUs } from './InformPage';
import { AboutPageText, aboutPageEnUs, aboutPageZhCn } from './AboutPage';
import { ButtonText, buttonEnUs, buttonZhCn } from './Button';
import { MemberPageText, memberPageEnUs, memberPageZhCn } from './MemberPage';
import { TicketListText, ticketListEnUs, ticketListZhCn } from './TicketList';
import { NavBarTitle, navBarTitleEnUs, navBarTitleZhCn } from './NavBarTitle';
import { RepairPageText, repairPageEnUs, repairPageZhCn } from './RepairPage';
import {
TicketDetailText,
ticketDetailEnUs,
ticketDetailZhCn,
} from './TicketDetail';
import { CommonText, commonTextEnUs, commonTextZhCn } from './common';
import { TipsText, tipsEnUs, tipsZhCn } from './Tips';
import { ModalText, modalEnUs, modalZhCn } from './Modal';
import { ToastText, toastEnUs, toastZhCn } from './Toast';
import {
ActIndicatorText,
actIndicatorEnUs,
actIndicatorZhCn,
} from './ActIndicator';
import { NotFoundText, notFound } from './404';
interface TextRecord {
common: CommonText;
pageFooter: PageFooterText;
mainPage: MainPageText;
userPage: UserPageText;
tabBar: TabBarText;
reportPage: ReportPageText;
informPage: InformPageText;
aboutPage: AboutPageText;
button: ButtonText;
memberPage: MemberPageText;
ticketList: TicketListText;
navBar: NavBarTitle;
repairPage: RepairPageText;
ticketDetail: TicketDetailText;
tips: TipsText;
modal: ModalText;
toast: ToastText;
actIndicator: ActIndicatorText;
notFound: NotFoundText;
}
const textZhCn: TextRecord = {
common: commonTextZhCn,
pageFooter: pageFooterZhCn,
mainPage: mainPageZhCn,
userPage: userPageZhCn,
tabBar: tabBarZhCn,
reportPage: reportPageZhCn,
informPage: informPageZhCn,
aboutPage: aboutPageZhCn,
button: buttonZhCn,
memberPage: memberPageZhCn,
ticketList: ticketListZhCn,
navBar: navBarTitleZhCn,
repairPage: repairPageZhCn,
ticketDetail: ticketDetailZhCn,
tips: tipsZhCn,
modal: modalZhCn,
toast: toastZhCn,
actIndicator: actIndicatorZhCn,
notFound: notFound,
};
const textEnUs: TextRecord = {
common: commonTextEnUs,
pageFooter: pageFooterEnUs,
mainPage: mainPageEnUs,
userPage: userPageEnUs,
tabBar: tabBarEnUs,
reportPage: reportPageEnUs,
informPage: informPageEnUs,
aboutPage: aboutPageEnUs,
button: buttonEnUs,
memberPage: memberPageEnUs,
ticketList: ticketListEnUs,
navBar: navBarTitleEnUs,
repairPage: repairPageEnUs,
ticketDetail: ticketDetailEnUs,
tips: tipsEnUs,
modal: modalEnUs,
toast: toastEnUs,
actIndicator: actIndicatorEnUs,
notFound: notFound,
};
// type Lang = 'zh_CN' | 'en_US' | ...;
export type Lang = 'zh_CN' | 'en_US';
class PlainText {
private readonly textZhCn: TextRecord;
private readonly textEnUs: TextRecord;
private lang: Lang;
constructor() {
this.textZhCn = textZhCn;
this.textEnUs = textEnUs;
this.lang = 'zh_CN';
}
setLang(lang: Lang) {
this.lang = lang;
}
get(): TextRecord {
if (this.lang == 'zh_CN') {
return this.textZhCn;
} else if (this.lang == 'en_US') {
return this.textEnUs;
}
return this.textZhCn;
}
getCurLang(): Lang {
return this.lang;
}
}
const pt = new PlainText();
export default pt;
+39
View File
@@ -0,0 +1,39 @@
import TicketDetail from '@/pages/TicketDetail/TicketDetail';
import Taro from '@tarojs/taro';
import pt from '@/plain-text';
import wechatUser from '@/wechat';
import { getUrl } from '.';
export function addToOreo(that: TicketDetail) {
that.setState({
isOreoLoading: true,
});
Taro.request({
url: getUrl('/tickets/addtooreo'),
method: 'POST',
data: {
token: wechatUser.getToken(),
id: that.state.id,
},
})
.then((res) => {
console.log(res.data);
that.setState({
isOreoLoading: false,
});
Taro.atMessage({
message: pt.get().button.submitText.success,
type: 'success',
});
})
.catch((err) => {
console.log(err.errMsg);
that.setState({
isOreoLoading: false,
});
Taro.atMessage({
message: pt.get().button.submitText.error + err.errMsg,
type: 'error',
});
});
}

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